Subversion Repositories group.electronics

Rev

Rev 134 | Details | Compare with Previous | Last modification | View Log | RSS feed

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