Subversion Repositories group.electronics

Rev

Details | Last modification | View Log | RSS feed

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