io.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. #ifndef FAKE_IO_H_
  2. #define FAKE_IO_H_
  3. #include <endian.h>
  4. #include <stdint.h>
  5. #include <mutex>
  6. template <typename T> class FakeIO
  7. {
  8. public:
  9. FakeIO(const T &init_value = 0)
  10. : m_init_value(init_value)
  11. , m_reg(init_value)
  12. , m_read_hook(NULL)
  13. , m_read_hook_running(false)
  14. , m_write_hook(NULL)
  15. , m_write_hook_running(false)
  16. {
  17. }
  18. virtual ~FakeIO()
  19. {
  20. }
  21. void reset()
  22. {
  23. m_reg = m_init_value;
  24. m_read_hook = NULL;
  25. m_read_hook_running = false;
  26. m_write_hook = NULL;
  27. m_write_hook_running = false;
  28. }
  29. FakeIO & operator=(const T &other)
  30. {
  31. std::lock_guard<std::recursive_mutex> locker(m_mutex);
  32. T prev_value = m_reg;
  33. m_reg = other;
  34. call_write_hook(prev_value);
  35. return *this;
  36. }
  37. FakeIO & operator|=(const T &other)
  38. {
  39. std::lock_guard<std::recursive_mutex> locker(m_mutex);
  40. T prev_value = m_reg;
  41. m_reg |= other;
  42. call_write_hook(prev_value);
  43. return *this;
  44. }
  45. FakeIO & operator&=(const T &other)
  46. {
  47. std::lock_guard<std::recursive_mutex> locker(m_mutex);
  48. T prev_value = m_reg;
  49. m_reg &= other;
  50. call_write_hook(prev_value);
  51. return *this;
  52. }
  53. operator T()
  54. {
  55. std::lock_guard<std::recursive_mutex> locker(m_mutex);
  56. call_read_hook();
  57. return m_reg;
  58. }
  59. volatile uint8_t * low_byte()
  60. {
  61. #if __BYTE_ORDER == __LITTLE_ENDIAN
  62. return reinterpret_cast<volatile uint8_t *>(&m_reg) + 0;
  63. #else
  64. return reinterpret_cast<volatile uint8_t *>(&m_reg) + 1;
  65. #endif
  66. }
  67. volatile uint8_t * high_byte()
  68. {
  69. #if __BYTE_ORDER == __LITTLE_ENDIAN
  70. return reinterpret_cast<volatile uint8_t *>(&m_reg) + 1;
  71. #else
  72. return reinterpret_cast<volatile uint8_t *>(&m_reg) + 0;
  73. #endif
  74. }
  75. void set_read_hook(void (*read_hook)(FakeIO<T> &io))
  76. {
  77. m_read_hook = read_hook;
  78. }
  79. void set_write_hook(void (*write_hook)(FakeIO<T> &io, T prev_value))
  80. {
  81. m_write_hook = write_hook;
  82. }
  83. protected:
  84. void call_read_hook()
  85. {
  86. if (m_read_hook && !m_read_hook_running) {
  87. m_read_hook_running = true;
  88. m_read_hook(*this);
  89. m_read_hook_running = false;
  90. }
  91. }
  92. void call_write_hook(T prev_value)
  93. {
  94. if (m_write_hook && !m_write_hook_running) {
  95. m_write_hook_running = true;
  96. m_write_hook(*this, prev_value);
  97. m_write_hook_running = false;
  98. }
  99. }
  100. protected:
  101. std::recursive_mutex m_mutex;
  102. T m_init_value;
  103. volatile T m_reg;
  104. void (*m_read_hook)(FakeIO<T> &io);
  105. bool m_read_hook_running;
  106. void (*m_write_hook)(FakeIO<T> &io, T prev_value);
  107. bool m_write_hook_running;
  108. };
  109. void fakeio_reset_all(void);
  110. #define _SFR_ADDR(x) (static_cast<void *>(&(x)))
  111. #define _MMIO_BYTE(x) (*(static_cast<FakeIO<uint8_t> *>(x)))
  112. typedef void * sfr_addr_t;
  113. #define sfr_addr_t sfr_addr_t
  114. extern FakeIO<uint8_t> MCUCSR;
  115. #define MCUCSR MCUCSR
  116. #define MCUSR MCUCSR
  117. #define PB0 0
  118. #define PB1 1
  119. #define PB2 2
  120. #define PB3 3
  121. #define PB4 4
  122. #define PB5 5
  123. #define PB6 6
  124. #define PB7 7
  125. extern FakeIO<uint8_t> PORTB;
  126. #define PORTB PORTB
  127. #define PC0 0
  128. #define PC1 1
  129. #define PC2 2
  130. #define PC3 3
  131. #define PC4 4
  132. #define PC5 5
  133. #define PC6 6
  134. #define PC7 7
  135. extern FakeIO<uint8_t> PORTC;
  136. #define PORTC PORTC
  137. #define PD0 0
  138. #define PD1 1
  139. #define PD2 2
  140. #define PD3 3
  141. #define PD4 4
  142. #define PD5 5
  143. #define PD6 6
  144. #define PD7 7
  145. extern FakeIO<uint8_t> PORTD;
  146. #define PORTD PORTD
  147. #define DDB0 0
  148. #define DDB1 1
  149. #define DDB2 2
  150. #define DDB3 3
  151. #define DDB4 4
  152. #define DDB5 5
  153. #define DDB6 6
  154. #define DDB7 7
  155. extern FakeIO<uint8_t> DDRB;
  156. #define DDRB DDRB
  157. #define DDC0 0
  158. #define DDC1 1
  159. #define DDC2 2
  160. #define DDC3 3
  161. #define DDC4 4
  162. #define DDC5 5
  163. #define DDC6 6
  164. #define DDC7 7
  165. extern FakeIO<uint8_t> DDRC;
  166. #define DDRC DDRC
  167. #define DDD0 0
  168. #define DDD1 1
  169. #define DDD2 2
  170. #define DDD3 3
  171. #define DDD4 4
  172. #define DDD5 5
  173. #define DDD6 6
  174. #define DDD7 7
  175. extern FakeIO<uint8_t> DDRD;
  176. #define DDRD DDRD
  177. #define PINB0 0
  178. #define PINB1 1
  179. #define PINB2 2
  180. #define PINB3 3
  181. #define PINB4 4
  182. #define PINB5 5
  183. #define PINB6 6
  184. #define PINB7 7
  185. extern FakeIO<uint8_t> PINB;
  186. #define PINB PINB
  187. #define PINC0 0
  188. #define PINC1 1
  189. #define PINC2 2
  190. #define PINC3 3
  191. #define PINC4 4
  192. #define PINC5 5
  193. #define PINC6 6
  194. #define PINC7 7
  195. extern FakeIO<uint8_t> PINC;
  196. #define PINC PINC
  197. #define PIND0 0
  198. #define PIND1 1
  199. #define PIND2 2
  200. #define PIND3 3
  201. #define PIND4 4
  202. #define PIND5 5
  203. #define PIND6 6
  204. #define PIND7 7
  205. extern FakeIO<uint8_t> PIND;
  206. #define PIND PIND
  207. #define OCIE0B 2
  208. #define OCIE0A 1
  209. #define TOIE0 0
  210. extern FakeIO<uint8_t> TIMSK0;
  211. #define TIMSK0 TIMSK0
  212. #define OCF0B 2
  213. #define OCF0A 1
  214. #define TOV0 0
  215. extern FakeIO<uint8_t> TIFR0;
  216. #define TIFR0 TIFR0
  217. #define ICIE1 5
  218. #define OCIE1B 2
  219. #define OCIE1A 1
  220. #define TOIE1 0
  221. extern FakeIO<uint8_t> TIMSK1;
  222. #define TIMSK1 TIMSK1
  223. #define ICF1 5
  224. #define OCF1B 2
  225. #define OCF1A 1
  226. #define TOV1 0
  227. extern FakeIO<uint8_t> TIFR1;
  228. #define TIFR1 TIFR1
  229. #define SREG_C 0
  230. #define SREG_Z 1
  231. #define SREG_N 2
  232. #define SREG_V 3
  233. #define SREG_S 4
  234. #define SREG_H 5
  235. #define SREG_T 6
  236. #define SREG_I 7
  237. extern FakeIO<uint8_t> SREG;
  238. #define SREG SREG
  239. #define COM0A1 7
  240. #define COM0A0 6
  241. #define COM0B1 5
  242. #define COM0B0 4
  243. #define WGM01 1
  244. #define WGM00 0
  245. #define FOC0A 7
  246. #define FOC0B 6
  247. #define WGM02 3
  248. #define CS02 2
  249. #define CS01 1
  250. #define CS00 0
  251. #define COM1A1 7
  252. #define COM1A0 6
  253. #define COM1B1 5
  254. #define COM1B0 4
  255. #define WGM11 1
  256. #define WGM10 0
  257. #define ICNC1 7
  258. #define ICES1 6
  259. #define WGM13 4
  260. #define WGM12 3
  261. #define CS12 2
  262. #define CS11 1
  263. #define CS10 0
  264. #define FOC1A 7
  265. #define FOC1B 6
  266. extern FakeIO<uint8_t> OCR0A;
  267. #define OCR0A OCR0A
  268. extern FakeIO<uint8_t> OCR0B;
  269. #define OCR0B OCR0B
  270. extern FakeIO<uint8_t> TCNT0;
  271. #define TCNT0 TCNT0
  272. extern FakeIO<uint8_t> TCCR0A;
  273. #define TCCR0A TCCR0A
  274. extern FakeIO<uint8_t> TCCR0B;
  275. #define TCCR0B TCCR0B
  276. extern FakeIO<uint16_t> OCR1A;
  277. #define OCR1A OCR1A
  278. extern FakeIO<uint16_t> OCR1B;
  279. #define OCR1B OCR1B
  280. extern FakeIO<uint16_t> ICR1;
  281. #define ICR1 ICR1
  282. extern FakeIO<uint8_t> TCNT1;
  283. #define TCNT1 TCNT1
  284. extern FakeIO<uint8_t> TCCR1A;
  285. #define TCCR1A TCCR1A
  286. extern FakeIO<uint8_t> TCCR1B;
  287. #define TCCR1B TCCR1B
  288. extern FakeIO<uint8_t> TCCR1C;
  289. #define TCCR1C TCCR1C
  290. #define EEPM1 5
  291. #define EEPM0 4
  292. #define EERIE 3
  293. #define EEMPE 2
  294. #define EEPE 1
  295. #define EERE 0
  296. extern FakeIO<uint8_t> EECR;
  297. #define EECR EECR
  298. extern FakeIO<uint8_t> EEDR;
  299. #define EEDR EEDR
  300. typedef uintptr_t ee_addr_t;
  301. #define ee_addr_t ee_addr_t
  302. extern FakeIO<ee_addr_t> EEAR;
  303. #define EEAR EEAR
  304. #define E2END 0x3FF
  305. extern FakeIO<uint16_t> ADC;
  306. #define ADC ADC
  307. #define ADCW ADC
  308. #define ADCL (*(ADC.low_byte()))
  309. #define ADCH (*(ADC.high_byte()))
  310. #define ADEN 7
  311. #define ADSC 6
  312. #define ADATE 5
  313. #define ADIF 4
  314. #define ADIE 3
  315. #define ADPS2 2
  316. #define ADPS1 1
  317. #define ADPS0 0
  318. extern FakeIO<uint8_t> ADCSRA;
  319. #define ADCSRA ADCSRA
  320. #define ACME 6
  321. #define ADTS2 2
  322. #define ADTS1 1
  323. #define ADTS0 0
  324. extern FakeIO<uint8_t> ADCSRB;
  325. #define ADCSRB ADCSRB
  326. #define REFS1 7
  327. #define REFS0 6
  328. #define ADLAR 5
  329. #define MUX3 3
  330. #define MUX2 2
  331. #define MUX1 1
  332. #define MUX0 0
  333. extern FakeIO<uint8_t> ADMUX;
  334. #define ADMUX ADMUX
  335. #define ADC5D 5
  336. #define ADC4D 4
  337. #define ADC3D 3
  338. #define ADC2D 2
  339. #define ADC1D 1
  340. #define ADC0D 0
  341. extern FakeIO<uint8_t> DIDR0;
  342. #define DIDR0 DIDR0
  343. #define AIN1D 1
  344. #define AIN0D 0
  345. extern FakeIO<uint8_t> DIDR1;
  346. #define DIDR1 DIDR1
  347. #define RXC0 7
  348. #define TXC0 6
  349. #define UDRE0 5
  350. #define FE0 4
  351. #define DOR0 3
  352. #define UPE0 2
  353. #define U2X0 1
  354. #define MPCM0 0
  355. extern FakeIO<uint8_t> UCSR0A;
  356. #define UCSR0A UCSR0A
  357. #define RXCIE0 7
  358. #define TXCIE0 6
  359. #define UDRIE0 5
  360. #define RXEN0 4
  361. #define TXEN0 3
  362. #define UCSZ02 2
  363. #define RXB80 1
  364. #define TXB80 0
  365. extern FakeIO<uint8_t> UCSR0B;
  366. #define UCSR0B UCSR0B
  367. #define UMSEL01 7
  368. #define UMSEL00 6
  369. #define UPM01 5
  370. #define UPM00 4
  371. #define USBS0 3
  372. #define UCSZ01 2
  373. #define UDORD0 2
  374. #define UCSZ00 1
  375. #define UCPHA0 1
  376. #define UCPOL0 0
  377. extern FakeIO<uint8_t> UCSR0C;
  378. #define UCSR0C UCSR0C
  379. extern FakeIO<uint16_t> UBRR0;
  380. #define UBRR0 UBRR0
  381. #define UBRR0L (*(UBRR0.low_byte()))
  382. #define UBRR0H (*(UBRR0.high_byte()))
  383. extern FakeIO<uint8_t> UDR0;
  384. #define UDR0 UDR0
  385. #endif /* FAKE_IO_H_ */