i2c_slave.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652
  1. /*
  2. * USI I2C bus slave
  3. *
  4. * Copyright (c) 2016-2018 Michael Buesch <m@bues.ch>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. */
  20. #include "i2c_slave.h"
  21. #include "util.h"
  22. #include <string.h>
  23. #include <avr/io.h>
  24. #include <avr/interrupt.h>
  25. #define SDA_PORT PORTB
  26. #define SDA_PIN PINB
  27. #define SDA_DDR DDRB
  28. #define SDA_BIT PB0
  29. #define SCL_PORT PORTB
  30. #define SCL_PIN PINB
  31. #define SCL_DDR DDRB
  32. #define SCL_BIT PB2
  33. #ifndef I2CS_MAX_NR_SLAVES
  34. # error "I2CS_MAX_NR_SLAVES is not defined"
  35. #endif
  36. #ifndef I2CS_EXPECTED_KHZ
  37. # error "I2CS_EXPECTED_KHZ is not defined"
  38. #endif
  39. enum i2cs_state {
  40. I2CS_STATE_ADDR, /* Handle received address */
  41. I2CS_STATE_PREP_SND, /* Prepare sending of data */
  42. I2CS_STATE_PREP_RCV, /* Prepare receiving of data */
  43. I2CS_STATE_SND, /* Data was sent */
  44. I2CS_STATE_RCV, /* Handle received data */
  45. I2CS_STATE_RCVPROC, /* Process received data */
  46. I2CS_STATE_RCV_ACK, /* Handle received ack after sent data */
  47. };
  48. #define I2CS_NO_ADDR 0xFFu
  49. #define I2CS_NO_SLAVE 0xFFu
  50. static enum i2cs_state _used i2cs_state;
  51. static uint8_t _used i2cs_addrs[I2CS_MAX_NR_SLAVES];
  52. static uint8_t _used i2cs_active_slave;
  53. static uint8_t _used i2cs_rx_byte;
  54. static bool i2cs_had_start;
  55. static const struct i2c_slave_ops __flash _used *i2cs_ops[I2CS_MAX_NR_SLAVES];
  56. #ifdef I2CS_CLKSTRETCH_WORKAROUND
  57. /* Raspberry Pi I2C clock stretching bug workaround. */
  58. static void clkstretch_timer_init(void)
  59. {
  60. TCCR0B = 0u;
  61. TCNT0 = 0u;
  62. OCR0A = 0u;
  63. OCR0B = 0u;
  64. TIMSK &= (uint8_t)~((1u << OCIE0A) | (1u << OCIE0B) | (1u << TOIE0));
  65. TIFR = (1u << OCF0A) | (1u << OCF0B) | (1u << TOV0);
  66. /* Normal mode, prescaler 8. */
  67. build_assert(F_CPU == 16000000UL);
  68. GTCCR &= (uint8_t)(~(1u << PSR0) & 0xFFu);
  69. GTCCR &= (uint8_t)(~(1u << TSM) & 0xFFu);
  70. TCCR0A = (0u << COM0A1) | (0u << COM0A0) |
  71. (0u << COM0B1) | (0u << COM0B0) |
  72. (0u << WGM01) | (0u << WGM00);
  73. TCCR0B = (0u << FOC0A) | (0u << FOC0B) |
  74. (0u << WGM02) |
  75. (0u << CS02) | (1u << CS01) | (0u << CS00);
  76. #define TCNT0_KHZ 2000u
  77. }
  78. /* Prepare the clock stretching workaround timer.
  79. * r31 is the only register allowed to be clobbered.
  80. * Everything else (including SREG) must be left untouched!
  81. */
  82. #define CLKSTRETCH_TIMER_PREPARE() \
  83. " ldi r31, %[_STRETCH_TIMER_PRELOAD] \n" \
  84. " out %[_TCNT0], r31 \n" \
  85. " ldi r31, (1 << %[_TOV0]) \n" \
  86. " out %[_TIFR], r31 \n"
  87. /* Wait until we are in the safe range. */
  88. #define CLKSTRETCH_TIMER_WAIT() \
  89. "1: in r31, %[_TIFR] \n" \
  90. " sbrs r31, %[_TOV0] \n" \
  91. " rjmp 1b \n"
  92. #else /* I2CS_CLKSTRETCH_WORKAROUND */
  93. static void clkstretch_timer_init(void) { }
  94. #define CLKSTRETCH_TIMER_PREPARE() ""
  95. #define CLKSTRETCH_TIMER_WAIT() ""
  96. #define TCNT0_KHZ 0u
  97. #endif /* I2CS_CLKSTRETCH_WORKAROUND */
  98. #define USICR_BASE ( \
  99. (1u << USISIE) | \
  100. (0u << USIOIE) | \
  101. (1u << USIWM1) | \
  102. (0u << USIWM0) | \
  103. (1u << USICS1) | \
  104. (0u << USICS0) | \
  105. (0u << USICLK) | \
  106. (0u << USITC) \
  107. )
  108. #define USISR_BASE ( \
  109. (0u << USISIF) | \
  110. (1u << USIOIF) | \
  111. (1u << USIPF) | \
  112. (0u << USICNT2) | \
  113. (0u << USICNT1) | \
  114. (0u << USICNT0) \
  115. )
  116. ISR(USI_START_vect)
  117. {
  118. memory_barrier();
  119. SDA_DDR &= (uint8_t)~(1u << SDA_BIT);
  120. /* Wait for SCL low (or stop condition). */
  121. while ((SCL_PIN & (1u << SCL_BIT)) &&
  122. !((SDA_PIN & (1u << SDA_BIT)))) {
  123. /* Wait.
  124. * We depend on the WDT to restart the MCU, if this loop never
  125. * terminates due to external issues.
  126. */
  127. }
  128. /* Check whether we do not have a stop condition. */
  129. if (!(SDA_PIN & (1u << SDA_BIT))) {
  130. /* Enable counter overflow interrupt. */
  131. USICR = USICR_BASE | (1u << USIOIE) | (0u << USIWM0);
  132. }
  133. USISR = USISR_BASE | (1u << USISIF) | (1u << USICNT0);
  134. i2cs_state = I2CS_STATE_ADDR;
  135. i2cs_active_slave = I2CS_NO_SLAVE;
  136. i2cs_had_start = true;
  137. memory_barrier();
  138. }
  139. static uint8_t _used slaveop_transmit(void)
  140. {
  141. const struct i2c_slave_ops __flash *ops;
  142. uint8_t data;
  143. ops = i2cs_ops[i2cs_active_slave];
  144. data = ops->transmit(i2cs_had_start);
  145. i2cs_had_start = false;
  146. return data;
  147. }
  148. static uint8_t _used slaveop_receive(uint8_t data)
  149. {
  150. const struct i2c_slave_ops __flash *ops;
  151. bool continue_rx;
  152. ops = i2cs_ops[i2cs_active_slave];
  153. continue_rx = ops->receive(i2cs_had_start, data);
  154. i2cs_had_start = false;
  155. return continue_rx ? 1u : 0u;
  156. }
  157. /* Save all caller-saved regs, except r0 and SREG. */
  158. #define SAVE_CALLER_REGS() \
  159. " push r18 \n" \
  160. " push r19 \n" \
  161. " push r20 \n" \
  162. " push r21 \n" \
  163. " push r22 \n" \
  164. " push r23 \n" \
  165. " push r24 \n" \
  166. " push r25 \n" \
  167. " push r26 \n" \
  168. " push r27 \n" \
  169. " push r30 \n" \
  170. " push r31 \n"
  171. /* Restore all caller-saved regs, except r0 and SREG. */
  172. #define RESTORE_CALLER_REGS() \
  173. " pop r31 \n" \
  174. " pop r30 \n" \
  175. " pop r27 \n" \
  176. " pop r26 \n" \
  177. " pop r25 \n" \
  178. " pop r24 \n" \
  179. " pop r23 \n" \
  180. " pop r22 \n" \
  181. " pop r21 \n" \
  182. " pop r20 \n" \
  183. " pop r19 \n" \
  184. " pop r18 \n"
  185. #define IN_CONSTR_BASE \
  186. [_SREG] "I" (_SFR_IO_ADDR(SREG)), \
  187. [_TCNT0] "I" (_SFR_IO_ADDR(TCNT0)), \
  188. [_TIFR] "I" (_SFR_IO_ADDR(TIFR)), \
  189. [_TOV0] "M" (TOV0), \
  190. [_STRETCH_TIMER_PRELOAD] "M" (256u - ((TCNT0_KHZ / I2CS_EXPECTED_KHZ) + 1u)), \
  191. [_USIDR] "I" (_SFR_IO_ADDR(USIDR)), \
  192. [_USICR] "I" (_SFR_IO_ADDR(USICR)), \
  193. [_USISR] "I" (_SFR_IO_ADDR(USISR)), \
  194. [_SDA_DDR] "I" (_SFR_IO_ADDR(SDA_DDR)), \
  195. [_SDA_BIT] "M" (SDA_BIT), \
  196. [_SCL_PIN] "I" (_SFR_IO_ADDR(SCL_PIN)), \
  197. [_SCL_BIT] "M" (SCL_BIT), \
  198. [_STATE_ADDR] "M" (I2CS_STATE_ADDR), \
  199. [_STATE_PREP_SND] "M" (I2CS_STATE_PREP_SND), \
  200. [_STATE_PREP_RCV] "M" (I2CS_STATE_PREP_RCV), \
  201. [_STATE_SND] "M" (I2CS_STATE_SND), \
  202. [_STATE_RCV] "M" (I2CS_STATE_RCV), \
  203. [_STATE_RCVPROC] "M" (I2CS_STATE_RCVPROC), \
  204. [_STATE_RCV_ACK] "M" (I2CS_STATE_RCV_ACK), \
  205. [_I2CS_NO_SLAVE] "M" (I2CS_NO_SLAVE)
  206. static void _naked _used switch_to_start_condition_state(void)
  207. {
  208. __asm__ __volatile__(
  209. " ; Set USI to wait for start condition. \n"
  210. " ldi r31, %[_cr_scond] \n"
  211. " out %[_USICR], r31 \n"
  212. " ldi r31, %[_sr_scond] \n"
  213. " out %[_USISR], r31 \n"
  214. " \n"
  215. " ; Reset active slave index. \n"
  216. " ldi r31, %[_I2CS_NO_SLAVE] \n"
  217. " sts i2cs_active_slave, r31 \n"
  218. " \n"
  219. " rjmp isr_ovf_ret \n"
  220. : /* outputs */
  221. : /* inputs */
  222. IN_CONSTR_BASE,
  223. [_cr_scond] "M" (USICR_BASE | (0u << USIOIE) | (0u << USIWM0)),
  224. [_sr_scond] "M" (USISR_BASE | (0u << USISIF) | (0u << USICNT0))
  225. : /* clobbers */
  226. "memory"
  227. );
  228. unreachable();
  229. }
  230. #define CHECK_ONE_ADDR(index) \
  231. " lds r31, i2cs_addrs + " tostr(index) " \n" \
  232. " cp r31, __tmp_reg__ \n" \
  233. " ldi r31, " tostr(index) " \n" \
  234. " breq handle_addr \n" \
  235. static void _naked _used handle_state_addr(void)
  236. {
  237. __asm__ __volatile__(
  238. " ; Read the received address. \n"
  239. " in r30, %[_USIDR] \n"
  240. " \n"
  241. " ; Check if the address is ours. \n"
  242. " mov __tmp_reg__, r30 \n"
  243. " lsr __tmp_reg__ \n"
  244. #if I2CS_MAX_NR_SLAVES >= 1
  245. CHECK_ONE_ADDR(0)
  246. #endif
  247. #if I2CS_MAX_NR_SLAVES >= 2
  248. CHECK_ONE_ADDR(1)
  249. #endif
  250. #if I2CS_MAX_NR_SLAVES >= 3
  251. CHECK_ONE_ADDR(2)
  252. #endif
  253. #if I2CS_MAX_NR_SLAVES >= 4
  254. # error "I2CS_MAX_NR_SLAVES is too big"
  255. #endif
  256. " \n"
  257. " ; Unknown address. \n"
  258. " rjmp switch_to_start_condition_state \n"
  259. " \n"
  260. "handle_addr: \n"
  261. " ; Save the slave index. \n"
  262. " sts i2cs_active_slave, r31 \n"
  263. " \n"
  264. " ; Wait for SCK low \n"
  265. "1: sbic %[_SCL_PIN], %[_SCL_BIT] \n"
  266. " rjmp 1b \n"
  267. " \n"
  268. " ; Set SDA low for ACK. \n"
  269. " out %[_USIDR], __zero_reg__ \n"
  270. " sbi %[_SDA_DDR], %[_SDA_BIT] \n"
  271. " \n"
  272. " ; Set USI to send ACK. \n"
  273. " ldi r31, %[_cr_ack] \n"
  274. " out %[_USICR], r31 \n"
  275. " ldi r31, %[_sr_ack] \n"
  276. " out %[_USISR], r31 \n"
  277. " \n"
  278. " ; Set the next state. \n"
  279. " ldi r31, %[_STATE_PREP_SND] \n"
  280. " sbrs r30, 0 ; Check R/W bit \n"
  281. " ldi r31, %[_STATE_PREP_RCV] \n"
  282. " sts i2cs_state, r31 \n"
  283. " \n"
  284. " rjmp isr_ovf_ret \n"
  285. : /* outputs */
  286. : /* inputs */
  287. IN_CONSTR_BASE,
  288. [_cr_ack] "M" (USICR_BASE | (1u << USIOIE) | (1u << USIWM0)),
  289. [_sr_ack] "M" (USISR_BASE | (0u << USISIF) | (14u << USICNT0))
  290. : /* clobbers */
  291. "memory"
  292. );
  293. unreachable();
  294. }
  295. static void _naked _used handle_state_prep_snd(void)
  296. {
  297. __asm__ __volatile__(
  298. SAVE_CALLER_REGS()
  299. " \n"
  300. " ; Call the slave op to get the next TX byte. \n"
  301. " rcall slaveop_transmit \n"
  302. " \n"
  303. " ; Write the TX byte to USI. \n"
  304. " out %[_USIDR], r24 \n"
  305. " \n"
  306. " ; Enable SDA driver. \n"
  307. " sbi %[_SDA_DDR], %[_SDA_BIT] \n"
  308. " \n"
  309. RESTORE_CALLER_REGS()
  310. " \n"
  311. CLKSTRETCH_TIMER_WAIT()
  312. " \n"
  313. " ; Set USI to send data \n"
  314. " ldi r31, %[_cr_send] \n"
  315. " out %[_USICR], r31 \n"
  316. " ldi r31, %[_sr_send] \n"
  317. " out %[_USISR], r31 \n"
  318. " ; Write counter again to make sure it's \n"
  319. " ; written after the pos. SCL edge. \n"
  320. " out %[_USISR], r31 \n"
  321. " \n"
  322. " ; Set the next state \n"
  323. " ldi r31, %[_STATE_SND] \n"
  324. " sts i2cs_state, r31 \n"
  325. " \n"
  326. " rjmp isr_ovf_ret \n"
  327. : /* outputs */
  328. : /* inputs */
  329. IN_CONSTR_BASE,
  330. [_cr_send] "M" (USICR_BASE | (1u << USIOIE) | (0u << USIWM0)),
  331. [_sr_send] "M" (USISR_BASE | (0u << USISIF) | (2u << USICNT0))
  332. : /* clobbers */
  333. "memory"
  334. );
  335. unreachable();
  336. }
  337. static void _naked _used handle_state_prep_rcv(void)
  338. {
  339. __asm__ __volatile__(
  340. " ; Stop pulling SDA. \n"
  341. " cbi %[_SDA_DDR], %[_SDA_BIT] \n"
  342. " \n"
  343. CLKSTRETCH_TIMER_WAIT()
  344. " \n"
  345. " ; Set USI to read data \n"
  346. " ldi r31, %[_cr_rddata] \n"
  347. " out %[_USICR], r31 \n"
  348. " ldi r31, %[_sr_rddata] \n"
  349. " out %[_USISR], r31 \n"
  350. " ; Write counter again to make sure it's \n"
  351. " ; written after the pos. SCL edge. \n"
  352. " out %[_USISR], r31 \n"
  353. " \n"
  354. " ; Set the next state \n"
  355. " ldi r31, %[_STATE_RCV] \n"
  356. " sts i2cs_state, r31 \n"
  357. " \n"
  358. " rjmp isr_ovf_ret \n"
  359. : /* outputs */
  360. : /* inputs */
  361. IN_CONSTR_BASE,
  362. [_cr_rddata] "M" (USICR_BASE | (1u << USIOIE) | (0u << USIWM0)),
  363. [_sr_rddata] "M" (USISR_BASE | (0u << USISIF) | (2u << USICNT0))
  364. : /* clobbers */
  365. "memory"
  366. );
  367. unreachable();
  368. }
  369. static void _naked _used handle_state_rcv(void)
  370. {
  371. __asm__ __volatile__(
  372. " ; Get the received data \n"
  373. " in r30, %[_USIDR] \n"
  374. " \n"
  375. " ; Wait for SCK low \n"
  376. "1: sbic %[_SCL_PIN], %[_SCL_BIT] \n"
  377. " rjmp 1b \n"
  378. " \n"
  379. " ; Store the received byte for later processing. \n"
  380. " ; Can't process it now due to possible \n"
  381. " ; Raspi SCL stretch bug. \n"
  382. " sts i2cs_rx_byte, r30 \n"
  383. " \n"
  384. " ; Set SDA low for ACK. \n"
  385. " out %[_USIDR], __zero_reg__ \n"
  386. " sbi %[_SDA_DDR], %[_SDA_BIT] \n"
  387. " \n"
  388. " ; Set USI to send ack. \n"
  389. " ldi r31, %[_cr_ack] \n"
  390. " out %[_USICR], r31 \n"
  391. " ldi r31, %[_sr_ack] \n"
  392. " out %[_USISR], r31 \n"
  393. " \n"
  394. " ; Set the next state \n"
  395. " ldi r31, %[_STATE_RCVPROC] \n"
  396. " sts i2cs_state, r31 \n"
  397. " \n"
  398. " rjmp isr_ovf_ret \n"
  399. : /* outputs */
  400. : /* inputs */
  401. IN_CONSTR_BASE,
  402. [_cr_ack] "M" (USICR_BASE | (1u << USIOIE) | (1u << USIWM0)),
  403. [_sr_ack] "M" (USISR_BASE | (0u << USISIF) | (14u << USICNT0))
  404. : /* clobbers */
  405. "memory"
  406. );
  407. unreachable();
  408. }
  409. static void _naked _used handle_state_rcvproc(void)
  410. {
  411. __asm__ __volatile__(
  412. SAVE_CALLER_REGS()
  413. " \n"
  414. " ; Call the slave op to receive the byte. \n"
  415. " lds r24, i2cs_rx_byte \n"
  416. " rcall slaveop_receive \n"
  417. " mov __tmp_reg__, r24 \n"
  418. " \n"
  419. RESTORE_CALLER_REGS()
  420. " \n"
  421. " ; If 'continue-rx' is set, prepare next RX \n"
  422. " sbrc __tmp_reg__, 0 \n"
  423. " rjmp handle_state_prep_rcv \n"
  424. " \n"
  425. " ; We expect a new address transmission. \n"
  426. " \n"
  427. " ; Stop pulling SDA. \n"
  428. " cbi %[_SDA_DDR], %[_SDA_BIT] \n"
  429. " \n"
  430. CLKSTRETCH_TIMER_WAIT()
  431. " \n"
  432. " ; Set USI to read addr \n"
  433. " ldi r31, %[_cr_addrread] \n"
  434. " out %[_USICR], r31 \n"
  435. " ldi r31, %[_sr_addrread] \n"
  436. " out %[_USISR], r31 \n"
  437. " ; Write counter again to make sure it's \n"
  438. " ; written after the pos. SCL edge. \n"
  439. " out %[_USISR], r31 \n"
  440. " \n"
  441. " ; Set the next state \n"
  442. " ldi r31, %[_STATE_ADDR] \n"
  443. " sts i2cs_state, r31 \n"
  444. " \n"
  445. " rjmp isr_ovf_ret \n"
  446. : /* outputs */
  447. : /* inputs */
  448. IN_CONSTR_BASE,
  449. [_cr_addrread] "M" (USICR_BASE | (1u << USIOIE) | (0u << USIWM0)),
  450. #if 0
  451. [_sr_addrread] "M" (USISR_BASE | (0u << USISIF) | (2u << USICNT0))
  452. #else
  453. [_sr_addrread] "M" (USISR_BASE | (0u << USISIF) | (1u << USICNT0))
  454. #endif
  455. : /* clobbers */
  456. "memory"
  457. );
  458. unreachable();
  459. }
  460. static void _naked _used handle_state_snd(void)
  461. {
  462. __asm__ __volatile__(
  463. " ; Release SDA. \n"
  464. " cbi %[_SDA_DDR], %[_SDA_BIT] \n"
  465. " \n"
  466. " ; Wait for SCK low \n"
  467. "1: sbic %[_SCL_PIN], %[_SCL_BIT] \n"
  468. " rjmp 1b \n"
  469. " \n"
  470. " ; Set USI to read ack \n"
  471. " ldi r31, %[_cr_rdack] \n"
  472. " out %[_USICR], r31 \n"
  473. " ldi r31, %[_sr_rdack] \n"
  474. " out %[_USISR], r31 \n"
  475. " \n"
  476. " ; Set the next state \n"
  477. " ldi r31, %[_STATE_RCV_ACK] \n"
  478. " sts i2cs_state, r31 \n"
  479. " \n"
  480. " rjmp isr_ovf_ret \n"
  481. : /* outputs */
  482. : /* inputs */
  483. IN_CONSTR_BASE,
  484. [_cr_rdack] "M" (USICR_BASE | (1u << USIOIE) | (1u << USIWM0)),
  485. [_sr_rdack] "M" (USISR_BASE | (0u << USISIF) | (14u << USICNT0))
  486. : /* clobbers */
  487. "memory"
  488. );
  489. unreachable();
  490. }
  491. static void _naked _used handle_state_rcv_ack(void)
  492. {
  493. __asm__ __volatile__(
  494. " ; Read the state of SDA to get ACK/NACK \n"
  495. " in r30, %[_USIDR] \n"
  496. " \n"
  497. " ; Check whether we have ACK or NACK \n"
  498. " andi r30, 0x01 \n"
  499. " brne chk_reply_got_nack \n"
  500. " \n"
  501. " ; We got an ACK. \n"
  502. " ; Just directly go to send. \n"
  503. " rjmp handle_state_prep_snd \n"
  504. " \n"
  505. "chk_reply_got_nack: \n"
  506. " rjmp switch_to_start_condition_state \n"
  507. : /* outputs */
  508. : /* inputs */
  509. IN_CONSTR_BASE
  510. : /* clobbers */
  511. "memory"
  512. );
  513. unreachable();
  514. }
  515. static uint16_t _used state_handlers[] = {
  516. [I2CS_STATE_ADDR] = (uint16_t)&handle_state_addr,
  517. [I2CS_STATE_PREP_SND] = (uint16_t)&handle_state_prep_snd,
  518. [I2CS_STATE_PREP_RCV] = (uint16_t)&handle_state_prep_rcv,
  519. [I2CS_STATE_SND] = (uint16_t)&handle_state_snd,
  520. [I2CS_STATE_RCV] = (uint16_t)&handle_state_rcv,
  521. [I2CS_STATE_RCVPROC] = (uint16_t)&handle_state_rcvproc,
  522. [I2CS_STATE_RCV_ACK] = (uint16_t)&handle_state_rcv_ack,
  523. };
  524. ISR(USI_OVF_vect, ISR_NAKED)
  525. {
  526. __asm__ __volatile__(
  527. " push r31 \n"
  528. CLKSTRETCH_TIMER_PREPARE()
  529. " in r31, %[_SREG] \n"
  530. " push r31 \n"
  531. " push __tmp_reg__ \n"
  532. " push __zero_reg__ \n"
  533. " push r30 \n"
  534. " clr __zero_reg__ \n"
  535. " \n"
  536. " ; Branch to the current state handler. \n"
  537. " ldi r30, lo8(state_handlers) \n"
  538. " ldi r31, hi8(state_handlers) \n"
  539. " lds __tmp_reg__, i2cs_state \n"
  540. " lsl __tmp_reg__ \n"
  541. " add r30, __tmp_reg__ \n"
  542. " adc r31, __zero_reg__ \n"
  543. " ld __tmp_reg__, Z+ \n"
  544. " ld r31, Z \n"
  545. " mov r30, __tmp_reg__ \n"
  546. " ijmp \n"
  547. " \n"
  548. "isr_ovf_ret: \n"
  549. " pop r30 \n"
  550. " pop __zero_reg__ \n"
  551. " pop __tmp_reg__ \n"
  552. " pop r31 \n"
  553. " out %[_SREG], r31 \n"
  554. " pop r31 \n"
  555. " reti \n"
  556. : /* outputs */
  557. : /* inputs */
  558. IN_CONSTR_BASE
  559. : /* clobbers */
  560. "memory"
  561. );
  562. unreachable();
  563. }
  564. void i2cs_add_slave(uint8_t addr, const struct i2c_slave_ops __flash *ops)
  565. {
  566. uint8_t i;
  567. for (i = 0u; i < ARRAY_SIZE(i2cs_addrs); i++) {
  568. if (i2cs_addrs[i] == I2CS_NO_ADDR) {
  569. i2cs_addrs[i] = addr;
  570. i2cs_ops[i] = ops;
  571. break;
  572. }
  573. }
  574. }
  575. void i2cs_init(void)
  576. {
  577. i2cs_state = I2CS_STATE_ADDR;
  578. i2cs_active_slave = I2CS_NO_SLAVE;
  579. i2cs_had_start = false;
  580. memset(i2cs_addrs, I2CS_NO_ADDR, sizeof(i2cs_addrs));
  581. clkstretch_timer_init();
  582. /* SDA */
  583. SDA_PORT |= (1u << SDA_BIT);
  584. SDA_DDR &= (uint8_t)~(1u << SDA_BIT);
  585. /* SCL */
  586. SCL_PORT |= (1u << SCL_BIT);
  587. SCL_DDR |= (1u << SCL_BIT);
  588. /* Initialize USI in TWI slave mode. */
  589. USICR = USICR_BASE | (0u << USIOIE) | (0u << USIWM0);
  590. USISR = USISR_BASE | (1u << USISIF) | (0u << USICNT0);
  591. }