Picadae hardware and control code
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

usiTwiSlave.c 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  1. /********************************************************************************
  2. USI TWI Slave driver.
  3. Created by Donald R. Blake. donblake at worldnet.att.net
  4. Adapted by Jochen Toppe, jochen.toppe at jtoee.com
  5. ---------------------------------------------------------------------------------
  6. Created from Atmel source files for Application Note AVR312: Using the USI Module
  7. as an I2C slave.
  8. This program is free software; you can redistribute it and/or modify it under the
  9. terms of the GNU General Public License as published by the Free Software
  10. Foundation; either version 2 of the License, or (at your option) any later
  11. version.
  12. This program is distributed in the hope that it will be useful, but WITHOUT ANY
  13. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  14. PARTICULAR PURPOSE. See the GNU General Public License for more details.
  15. ---------------------------------------------------------------------------------
  16. Change Activity:
  17. Date Description
  18. ------ -------------
  19. 16 Mar 2007 Created.
  20. 27 Mar 2007 Added support for ATtiny261, 461 and 861.
  21. 26 Apr 2007 Fixed ACK of slave address on a read.
  22. 04 Jul 2007 Fixed USISIF in ATtiny45 def
  23. 12 Dev 2009 Added callback functions for data requests
  24. 06 Feb 2015 Minor change to allow mutli-byte requestFrom() from master.
  25. 10 Feb 2015 Simplied RX/TX buffer code and allowed use of full buffer.
  26. 12 Dec 2016 Added support for ATtiny167
  27. ********************************************************************************/
  28. /********************************************************************************
  29. includes
  30. ********************************************************************************/
  31. #include <stddef.h>
  32. #include <avr/io.h>
  33. #include <avr/interrupt.h>
  34. #include "usiTwiSlave.h"
  35. //#include "../common/util.h"
  36. //request_func_t _onTwiDataRequest = NULL;
  37. request_func_t usi_onRequestPtr = NULL;
  38. receive_func_t usi_onReceiverPtr = NULL;
  39. /********************************************************************************
  40. device dependent defines
  41. ********************************************************************************/
  42. #if defined( __AVR_ATtiny167__ )
  43. # define DDR_USI DDRB
  44. # define PORT_USI PORTB
  45. # define PIN_USI PINB
  46. # define PORT_USI_SDA PB0
  47. # define PORT_USI_SCL PB2
  48. # define PIN_USI_SDA PINB0
  49. # define PIN_USI_SCL PINB2
  50. # define USI_START_COND_INT USISIF
  51. # define USI_START_VECTOR USI_START_vect
  52. # define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect
  53. #endif
  54. #if defined( __AVR_ATtiny2313__ )
  55. # define DDR_USI DDRB
  56. # define PORT_USI PORTB
  57. # define PIN_USI PINB
  58. # define PORT_USI_SDA PB5
  59. # define PORT_USI_SCL PB7
  60. # define PIN_USI_SDA PINB5
  61. # define PIN_USI_SCL PINB7
  62. # define USI_START_COND_INT USISIF
  63. # define USI_START_VECTOR USI_START_vect
  64. # define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect
  65. #endif
  66. #if defined(__AVR_ATtiny84__) | \
  67. defined(__AVR_ATtiny44__)
  68. # define DDR_USI DDRA
  69. # define PORT_USI PORTA
  70. # define PIN_USI PINA
  71. # define PORT_USI_SDA PORTA6
  72. # define PORT_USI_SCL PORTA4
  73. # define PIN_USI_SDA PINA6
  74. # define PIN_USI_SCL PINA4
  75. # define USI_START_COND_INT USISIF
  76. # define USI_START_VECTOR USI_START_vect
  77. # define USI_OVERFLOW_VECTOR USI_OVF_vect
  78. #endif
  79. #if defined( __AVR_ATtiny25__ ) | \
  80. defined( __AVR_ATtiny45__ ) | \
  81. defined( __AVR_ATtiny85__ )
  82. # define DDR_USI DDRB
  83. # define PORT_USI PORTB
  84. # define PIN_USI PINB
  85. # define PORT_USI_SDA PB0
  86. # define PORT_USI_SCL PB2
  87. # define PIN_USI_SDA PINB0
  88. # define PIN_USI_SCL PINB2
  89. # define USI_START_COND_INT USISIF
  90. # define USI_START_VECTOR USI_START_vect
  91. # define USI_OVERFLOW_VECTOR USI_OVF_vect
  92. #endif
  93. #if defined( __AVR_ATtiny26__ )
  94. # define DDR_USI DDRB
  95. # define PORT_USI PORTB
  96. # define PIN_USI PINB
  97. # define PORT_USI_SDA PB0
  98. # define PORT_USI_SCL PB2
  99. # define PIN_USI_SDA PINB0
  100. # define PIN_USI_SCL PINB2
  101. # define USI_START_COND_INT USISIF
  102. # define USI_START_VECTOR USI_STRT_vect
  103. # define USI_OVERFLOW_VECTOR USI_OVF_vect
  104. #endif
  105. #if defined( __AVR_ATtiny261__ ) | \
  106. defined( __AVR_ATtiny461__ ) | \
  107. defined( __AVR_ATtiny861__ )
  108. # define DDR_USI DDRB
  109. # define PORT_USI PORTB
  110. # define PIN_USI PINB
  111. # define PORT_USI_SDA PB0
  112. # define PORT_USI_SCL PB2
  113. # define PIN_USI_SDA PINB0
  114. # define PIN_USI_SCL PINB2
  115. # define USI_START_COND_INT USISIF
  116. # define USI_START_VECTOR USI_START_vect
  117. # define USI_OVERFLOW_VECTOR USI_OVF_vect
  118. #endif
  119. #if defined( __AVR_ATmega165__ ) | \
  120. defined( __AVR_ATmega325__ ) | \
  121. defined( __AVR_ATmega3250__ ) | \
  122. defined( __AVR_ATmega645__ ) | \
  123. defined( __AVR_ATmega6450__ ) | \
  124. defined( __AVR_ATmega329__ ) | \
  125. defined( __AVR_ATmega3290__ )
  126. # define DDR_USI DDRE
  127. # define PORT_USI PORTE
  128. # define PIN_USI PINE
  129. # define PORT_USI_SDA PE5
  130. # define PORT_USI_SCL PE4
  131. # define PIN_USI_SDA PINE5
  132. # define PIN_USI_SCL PINE4
  133. # define USI_START_COND_INT USISIF
  134. # define USI_START_VECTOR USI_START_vect
  135. # define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect
  136. #endif
  137. #if defined( __AVR_ATmega169__ )
  138. # define DDR_USI DDRE
  139. # define PORT_USI PORTE
  140. # define PIN_USI PINE
  141. # define PORT_USI_SDA PE5
  142. # define PORT_USI_SCL PE4
  143. # define PIN_USI_SDA PINE5
  144. # define PIN_USI_SCL PINE4
  145. # define USI_START_COND_INT USISIF
  146. # define USI_START_VECTOR USI_START_vect
  147. # define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect
  148. #endif
  149. /********************************************************************************
  150. functions implemented as macros
  151. ********************************************************************************/
  152. #define SET_USI_TO_SEND_ACK( ) \
  153. { \
  154. /* prepare ACK */ \
  155. USIDR = 0; \
  156. /* set SDA as output */ \
  157. DDR_USI |= ( 1 << PORT_USI_SDA ); \
  158. /* clear all interrupt flags, except Start Cond */ \
  159. USISR = \
  160. ( 0 << USI_START_COND_INT ) | \
  161. ( 1 << USIOIF ) | ( 1 << USIPF ) | \
  162. ( 1 << USIDC )| \
  163. /* set USI counter to shift 1 bit */ \
  164. ( 0x0E << USICNT0 ); \
  165. }
  166. #define SET_USI_TO_READ_ACK( ) \
  167. { \
  168. /* set SDA as input */ \
  169. DDR_USI &= ~( 1 << PORT_USI_SDA ); \
  170. /* prepare ACK */ \
  171. USIDR = 0; \
  172. /* clear all interrupt flags, except Start Cond */ \
  173. USISR = \
  174. ( 0 << USI_START_COND_INT ) | \
  175. ( 1 << USIOIF ) | \
  176. ( 1 << USIPF ) | \
  177. ( 1 << USIDC ) | \
  178. /* set USI counter to shift 1 bit */ \
  179. ( 0x0E << USICNT0 ); \
  180. }
  181. #define SET_USI_TO_TWI_START_CONDITION_MODE( ) \
  182. { \
  183. USICR = \
  184. /* enable Start Condition Interrupt, disable Overflow Interrupt */ \
  185. ( 1 << USISIE ) | ( 0 << USIOIE ) | \
  186. /* set USI in Two-wire mode, no USI Counter overflow hold */ \
  187. ( 1 << USIWM1 ) | ( 0 << USIWM0 ) | \
  188. /* Shift Register Clock Source = External, positive edge */ \
  189. /* 4-Bit Counter Source = external, both edges */ \
  190. ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) | \
  191. /* no toggle clock-port pin */ \
  192. ( 0 << USITC ); \
  193. USISR = \
  194. /* clear all interrupt flags, except Start Cond */ \
  195. ( 0 << USI_START_COND_INT ) | ( 1 << USIOIF ) | ( 1 << USIPF ) | \
  196. ( 1 << USIDC ) | ( 0x0 << USICNT0 ); \
  197. }
  198. #define SET_USI_TO_SEND_DATA( ) \
  199. { \
  200. /* set SDA as output */ \
  201. DDR_USI |= ( 1 << PORT_USI_SDA ); \
  202. /* clear all interrupt flags, except Start Cond */ \
  203. USISR = \
  204. ( 0 << USI_START_COND_INT ) | ( 1 << USIOIF ) | ( 1 << USIPF ) | \
  205. ( 1 << USIDC) | \
  206. /* set USI to shift out 8 bits */ \
  207. ( 0x0 << USICNT0 ); \
  208. }
  209. #define SET_USI_TO_READ_DATA( ) \
  210. { \
  211. /* set SDA as input */ \
  212. DDR_USI &= ~( 1 << PORT_USI_SDA ); \
  213. /* clear all interrupt flags, except Start Cond */ \
  214. USISR = \
  215. ( 0 << USI_START_COND_INT ) | ( 1 << USIOIF ) | \
  216. ( 1 << USIPF ) | ( 1 << USIDC ) | \
  217. /* set USI to shift out 8 bits */ \
  218. ( 0x0 << USICNT0 ); \
  219. }
  220. #define USI_RECEIVE_CALLBACK() \
  221. { \
  222. if (usi_onReceiverPtr) \
  223. { \
  224. if (usiTwiAmountDataInReceiveBuffer()) \
  225. { \
  226. usi_onReceiverPtr(usiTwiAmountDataInReceiveBuffer()); \
  227. } \
  228. } \
  229. }
  230. #define ONSTOP_USI_RECEIVE_CALLBACK() \
  231. { \
  232. if (USISR & ( 1 << USIPF )) \
  233. { \
  234. USI_RECEIVE_CALLBACK(); \
  235. } \
  236. }
  237. #define USI_REQUEST_CALLBACK() \
  238. { \
  239. USI_RECEIVE_CALLBACK(); \
  240. if(usi_onRequestPtr) usi_onRequestPtr(); \
  241. }
  242. /********************************************************************************
  243. typedef's
  244. ********************************************************************************/
  245. typedef enum
  246. {
  247. USI_SLAVE_CHECK_ADDRESS = 0x00,
  248. USI_SLAVE_SEND_DATA = 0x01,
  249. USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA = 0x02,
  250. USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA = 0x03,
  251. USI_SLAVE_REQUEST_DATA = 0x04,
  252. USI_SLAVE_GET_DATA_AND_SEND_ACK = 0x05
  253. } overflowState_t;
  254. /********************************************************************************
  255. local variables
  256. ********************************************************************************/
  257. static uint8_t slaveAddress;
  258. static volatile overflowState_t overflowState;
  259. static uint8_t rxBuf[ TWI_RX_BUFFER_SIZE ];
  260. static volatile uint8_t rxHead;
  261. static volatile uint8_t rxTail;
  262. static volatile uint8_t rxCount;
  263. static uint8_t txBuf[ TWI_TX_BUFFER_SIZE ];
  264. static volatile uint8_t txHead;
  265. static volatile uint8_t txTail;
  266. static volatile uint8_t txCount;
  267. /********************************************************************************
  268. local functions
  269. ********************************************************************************/
  270. // flushes the TWI buffers
  271. static
  272. void
  273. flushTwiBuffers(
  274. void
  275. )
  276. {
  277. rxTail = 0;
  278. rxHead = 0;
  279. rxCount = 0;
  280. txTail = 0;
  281. txHead = 0;
  282. txCount = 0;
  283. } // end flushTwiBuffers
  284. /********************************************************************************
  285. public functions
  286. ********************************************************************************/
  287. // initialise USI for TWI slave mode
  288. void
  289. usiTwiSlaveInit(
  290. uint8_t ownAddress
  291. )
  292. {
  293. flushTwiBuffers( );
  294. slaveAddress = ownAddress;
  295. // In Two Wire mode (USIWM1, USIWM0 = 1X), the slave USI will pull SCL
  296. // low when a start condition is detected or a counter overflow (only
  297. // for USIWM1, USIWM0 = 11). This inserts a wait state. SCL is released
  298. // by the ISRs (USI_START_vect and USI_OVERFLOW_vect).
  299. // Set SCL and SDA as output
  300. DDR_USI |= ( 1 << PORT_USI_SCL ) | ( 1 << PORT_USI_SDA );
  301. // set SCL high
  302. PORT_USI |= ( 1 << PORT_USI_SCL );
  303. // set SDA high
  304. PORT_USI |= ( 1 << PORT_USI_SDA );
  305. // Set SDA as input
  306. DDR_USI &= ~( 1 << PORT_USI_SDA );
  307. USICR =
  308. // enable Start Condition Interrupt
  309. ( 1 << USISIE ) |
  310. // disable Overflow Interrupt
  311. ( 0 << USIOIE ) |
  312. // set USI in Two-wire mode, no USI Counter overflow hold
  313. ( 1 << USIWM1 ) | ( 0 << USIWM0 ) |
  314. // Shift Register Clock Source = external, positive edge
  315. // 4-Bit Counter Source = external, both edges
  316. ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) |
  317. // no toggle clock-port pin
  318. ( 0 << USITC );
  319. // clear all interrupt flags and reset overflow counter
  320. USISR = ( 1 << USI_START_COND_INT ) | ( 1 << USIOIF ) | ( 1 << USIPF ) | ( 1 << USIDC );
  321. } // end usiTwiSlaveInit
  322. bool usiTwiDataInTransmitBuffer(void)
  323. {
  324. // return 0 (false) if the receive buffer is empty
  325. return txCount;
  326. } // end usiTwiDataInTransmitBuffer
  327. // put data in the transmission buffer, wait if buffer is full
  328. void
  329. usiTwiTransmitByte(
  330. uint8_t data
  331. )
  332. {
  333. // kpl uint8_t tmphead;
  334. // wait for free space in buffer
  335. while ( txCount == TWI_TX_BUFFER_SIZE) ;
  336. // store data in buffer
  337. txBuf[ txHead ] = data;
  338. txHead = ( txHead + 1 ) & TWI_TX_BUFFER_MASK;
  339. txCount++;
  340. } // end usiTwiTransmitByte
  341. // return a byte from the receive buffer, wait if buffer is empty
  342. uint8_t
  343. usiTwiReceiveByte(
  344. void
  345. )
  346. {
  347. uint8_t rtn_byte;
  348. // wait for Rx data
  349. while ( !rxCount );
  350. rtn_byte = rxBuf [ rxTail ];
  351. // calculate buffer index
  352. rxTail = ( rxTail + 1 ) & TWI_RX_BUFFER_MASK;
  353. rxCount--;
  354. // return data from the buffer.
  355. return rtn_byte;
  356. } // end usiTwiReceiveByte
  357. uint8_t usiTwiAmountDataInReceiveBuffer(void)
  358. {
  359. return rxCount;
  360. }
  361. /********************************************************************************
  362. USI Start Condition ISR
  363. ********************************************************************************/
  364. ISR( USI_START_VECTOR )
  365. {
  366. /*
  367. // This triggers on second write, but claims to the callback there is only *one* byte in buffer
  368. ONSTOP_USI_RECEIVE_CALLBACK();
  369. */
  370. /*
  371. // This triggers on second write, but claims to the callback there is only *one* byte in buffer
  372. USI_RECEIVE_CALLBACK();
  373. */
  374. // set default starting conditions for new TWI package
  375. overflowState = USI_SLAVE_CHECK_ADDRESS;
  376. // set SDA as input
  377. DDR_USI &= ~( 1 << PORT_USI_SDA );
  378. // wait for SCL to go low to ensure the Start Condition has completed (the
  379. // start detector will hold SCL low ) - if a Stop Condition arises then leave
  380. // the interrupt to prevent waiting forever - don't use USISR to test for Stop
  381. // Condition as in Application Note AVR312 because the Stop Condition Flag is
  382. // going to be set from the last TWI sequence
  383. while (
  384. // SCL his high
  385. ( PIN_USI & ( 1 << PIN_USI_SCL ) ) &&
  386. // and SDA is low
  387. !( ( PIN_USI & ( 1 << PIN_USI_SDA ) ) )
  388. );
  389. if ( !( PIN_USI & ( 1 << PIN_USI_SDA ) ) )
  390. {
  391. // a Stop Condition did not occur
  392. USICR =
  393. // keep Start Condition Interrupt enabled to detect RESTART
  394. ( 1 << USISIE ) |
  395. // enable Overflow Interrupt
  396. ( 1 << USIOIE ) |
  397. // set USI in Two-wire mode, hold SCL low on USI Counter overflow
  398. ( 1 << USIWM1 ) | ( 1 << USIWM0 ) |
  399. // Shift Register Clock Source = External, positive edge
  400. // 4-Bit Counter Source = external, both edges
  401. ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) |
  402. // no toggle clock-port pin
  403. ( 0 << USITC );
  404. }
  405. else
  406. {
  407. // a Stop Condition did occur
  408. USICR =
  409. // enable Start Condition Interrupt
  410. ( 1 << USISIE ) |
  411. // disable Overflow Interrupt
  412. ( 0 << USIOIE ) |
  413. // set USI in Two-wire mode, no USI Counter overflow hold
  414. ( 1 << USIWM1 ) | ( 0 << USIWM0 ) |
  415. // Shift Register Clock Source = external, positive edge
  416. // 4-Bit Counter Source = external, both edges
  417. ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) |
  418. // no toggle clock-port pin
  419. ( 0 << USITC );
  420. } // end if
  421. USISR =
  422. // clear interrupt flags - resetting the Start Condition Flag will
  423. // release SCL
  424. ( 1 << USI_START_COND_INT ) | ( 1 << USIOIF ) |
  425. ( 1 << USIPF ) |( 1 << USIDC ) |
  426. // set USI to sample 8 bits (count 16 external SCL pin toggles)
  427. ( 0x0 << USICNT0);
  428. } // end ISR( USI_START_VECTOR )
  429. /********************************************************************************
  430. USI Overflow ISR
  431. Handles all the communication.
  432. Only disabled when waiting for a new Start Condition.
  433. ********************************************************************************/
  434. ISR( USI_OVERFLOW_VECTOR )
  435. {
  436. switch ( overflowState )
  437. {
  438. // Address mode: check address and send ACK (and next USI_SLAVE_SEND_DATA) if OK,
  439. // else reset USI
  440. case USI_SLAVE_CHECK_ADDRESS:
  441. if ( ( USIDR == 0 ) || ( ( USIDR >> 1 ) == slaveAddress) )
  442. {
  443. if ( USIDR & 0x01 )
  444. {
  445. USI_REQUEST_CALLBACK();
  446. overflowState = USI_SLAVE_SEND_DATA;
  447. }
  448. else
  449. {
  450. overflowState = USI_SLAVE_REQUEST_DATA;
  451. } // end if
  452. SET_USI_TO_SEND_ACK( );
  453. }
  454. else
  455. {
  456. SET_USI_TO_TWI_START_CONDITION_MODE( );
  457. }
  458. break;
  459. // Master write data mode: check reply and goto USI_SLAVE_SEND_DATA if OK,
  460. // else reset USI
  461. case USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA:
  462. if ( USIDR )
  463. {
  464. // if NACK, the master does not want more data
  465. SET_USI_TO_TWI_START_CONDITION_MODE( );
  466. return;
  467. }
  468. // from here we just drop straight into USI_SLAVE_SEND_DATA if the
  469. // master sent an ACK
  470. // copy data from buffer to USIDR and set USI to shift byte
  471. // next USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA
  472. case USI_SLAVE_SEND_DATA:
  473. // Get data from Buffer
  474. if ( txCount )
  475. {
  476. USIDR = txBuf[ txTail ];
  477. txTail = ( txTail + 1 ) & TWI_TX_BUFFER_MASK;
  478. txCount--;
  479. }
  480. else
  481. {
  482. // the buffer is empty
  483. SET_USI_TO_READ_ACK( ); // This might be neccessary sometimes see http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=805227#805227
  484. SET_USI_TO_TWI_START_CONDITION_MODE( );
  485. return;
  486. } // end if
  487. overflowState = USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA;
  488. SET_USI_TO_SEND_DATA( );
  489. break;
  490. // set USI to sample reply from master
  491. // next USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA
  492. case USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA:
  493. overflowState = USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA;
  494. SET_USI_TO_READ_ACK( );
  495. break;
  496. // Master read data mode: set USI to sample data from master, next
  497. // USI_SLAVE_GET_DATA_AND_SEND_ACK
  498. case USI_SLAVE_REQUEST_DATA:
  499. overflowState = USI_SLAVE_GET_DATA_AND_SEND_ACK;
  500. SET_USI_TO_READ_DATA( );
  501. break;
  502. // copy data from USIDR and send ACK
  503. // next USI_SLAVE_REQUEST_DATA
  504. case USI_SLAVE_GET_DATA_AND_SEND_ACK:
  505. // put data into buffer
  506. // check buffer size
  507. if ( rxCount < TWI_RX_BUFFER_SIZE )
  508. {
  509. rxBuf[ rxHead ] = USIDR;
  510. rxHead = ( rxHead + 1 ) & TWI_RX_BUFFER_MASK;
  511. rxCount++;
  512. } else {
  513. // overrun
  514. // drop data
  515. }
  516. // next USI_SLAVE_REQUEST_DATA
  517. overflowState = USI_SLAVE_REQUEST_DATA;
  518. SET_USI_TO_SEND_ACK( );
  519. break;
  520. } // end switch
  521. } // end ISR( USI_OVERFLOW_VECTOR )