From 40ab1463c3da0c844eedba5c5f52d5ef8af322c4 Mon Sep 17 00:00:00 2001 From: Philip Lampkin Date: Sat, 24 Apr 2021 12:07:04 -0500 Subject: terminology update --- digital-driver/firmware/TinyWireS/usiTwiSlave.c | 748 ------------------------ 1 file changed, 748 deletions(-) delete mode 100644 digital-driver/firmware/TinyWireS/usiTwiSlave.c (limited to 'digital-driver/firmware/TinyWireS/usiTwiSlave.c') diff --git a/digital-driver/firmware/TinyWireS/usiTwiSlave.c b/digital-driver/firmware/TinyWireS/usiTwiSlave.c deleted file mode 100644 index a263184..0000000 --- a/digital-driver/firmware/TinyWireS/usiTwiSlave.c +++ /dev/null @@ -1,748 +0,0 @@ -/******************************************************************************** - -USI TWI Slave driver. - -Created by Donald R. Blake. donblake at worldnet.att.net -Adapted by Jochen Toppe, jochen.toppe at jtoee.com - ---------------------------------------------------------------------------------- - -Created from Atmel source files for Application Note AVR312: Using the USI Module -as an I2C slave. - -This program is free software; you can redistribute it and/or modify it under the -terms of the GNU General Public License as published by the Free Software -Foundation; either version 2 of the License, or (at your option) any later -version. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A -PARTICULAR PURPOSE. See the GNU General Public License for more details. - ---------------------------------------------------------------------------------- - -Change Activity: - - Date Description - ------ ------------- - 16 Mar 2007 Created. - 27 Mar 2007 Added support for ATtiny261, 461 and 861. - 26 Apr 2007 Fixed ACK of slave address on a read. - 04 Jul 2007 Fixed USISIF in ATtiny45 def - 12 Dev 2009 Added callback functions for data requests - 06 Feb 2016 Minor change to allow mutli-byte requestFrom() from master. - 10 Feb 2016 Simplied RX/TX buffer code and allowed use of full buffer. - 13 Feb 2016 Made USI_RECEIVE_CALLBACK() callback fully interrupt-driven - 12 Dec 2016 Added support for ATtiny167 - 23 Dec 2017 Fixed repeated restart (which broke when making receive callback - interrupt-driven) - -********************************************************************************/ - - -/******************************************************************************** - includes -********************************************************************************/ - -#include -#include - -#include "usiTwiSlave.h" -//#include "../common/util.h" - - -/******************************************************************************** - device dependent defines -********************************************************************************/ - -#if defined( __AVR_ATtiny167__ ) -# define DDR_USI DDRB -# define PORT_USI PORTB -# define PIN_USI PINB -# define PORT_USI_SDA PB0 -# define PORT_USI_SCL PB2 -# define PIN_USI_SDA PINB0 -# define PIN_USI_SCL PINB2 -# define USI_START_COND_INT USISIF -# define USI_START_VECTOR USI_START_vect -# define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect -#endif - -#if defined( __AVR_ATtiny2313__ ) -# define DDR_USI DDRB -# define PORT_USI PORTB -# define PIN_USI PINB -# define PORT_USI_SDA PB5 -# define PORT_USI_SCL PB7 -# define PIN_USI_SDA PINB5 -# define PIN_USI_SCL PINB7 -# define USI_START_COND_INT USISIF -# define USI_START_VECTOR USI_START_vect -# define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect -#endif - -#if defined(__AVR_ATtiny84__) | \ - defined(__AVR_ATtiny44__) -# define DDR_USI DDRA -# define PORT_USI PORTA -# define PIN_USI PINA -# define PORT_USI_SDA PORTA6 -# define PORT_USI_SCL PORTA4 -# define PIN_USI_SDA PINA6 -# define PIN_USI_SCL PINA4 -# define USI_START_COND_INT USISIF -# define USI_START_VECTOR USI_START_vect -# define USI_OVERFLOW_VECTOR USI_OVF_vect -#endif - -#if defined( __AVR_ATtiny25__ ) | \ - defined( __AVR_ATtiny45__ ) | \ - defined( __AVR_ATtiny85__ ) -# define DDR_USI DDRB -# define PORT_USI PORTB -# define PIN_USI PINB -# define PORT_USI_SDA PB0 -# define PORT_USI_SCL PB2 -# define PIN_USI_SDA PINB0 -# define PIN_USI_SCL PINB2 -# define USI_START_COND_INT USISIF -# define USI_START_VECTOR USI_START_vect -# define USI_OVERFLOW_VECTOR USI_OVF_vect -#endif - -#if defined( __AVR_ATtiny26__ ) -# define DDR_USI DDRB -# define PORT_USI PORTB -# define PIN_USI PINB -# define PORT_USI_SDA PB0 -# define PORT_USI_SCL PB2 -# define PIN_USI_SDA PINB0 -# define PIN_USI_SCL PINB2 -# define USI_START_COND_INT USISIF -# define USI_START_VECTOR USI_STRT_vect -# define USI_OVERFLOW_VECTOR USI_OVF_vect -#endif - -#if defined( __AVR_ATtiny261__ ) | \ - defined( __AVR_ATtiny461__ ) | \ - defined( __AVR_ATtiny861__ ) -# define DDR_USI DDRB -# define PORT_USI PORTB -# define PIN_USI PINB -# define PORT_USI_SDA PB0 -# define PORT_USI_SCL PB2 -# define PIN_USI_SDA PINB0 -# define PIN_USI_SCL PINB2 -# define USI_START_COND_INT USISIF -# define USI_START_VECTOR USI_START_vect -# define USI_OVERFLOW_VECTOR USI_OVF_vect -#endif - -#if defined( __AVR_ATmega165__ ) | \ - defined( __AVR_ATmega325__ ) | \ - defined( __AVR_ATmega3250__ ) | \ - defined( __AVR_ATmega645__ ) | \ - defined( __AVR_ATmega6450__ ) | \ - defined( __AVR_ATmega329__ ) | \ - defined( __AVR_ATmega3290__ ) -# define DDR_USI DDRE -# define PORT_USI PORTE -# define PIN_USI PINE -# define PORT_USI_SDA PE5 -# define PORT_USI_SCL PE4 -# define PIN_USI_SDA PINE5 -# define PIN_USI_SCL PINE4 -# define USI_START_COND_INT USISIF -# define USI_START_VECTOR USI_START_vect -# define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect -#endif - -#if defined( __AVR_ATmega169__ ) -# define DDR_USI DDRE -# define PORT_USI PORTE -# define PIN_USI PINE -# define PORT_USI_SDA PE5 -# define PORT_USI_SCL PE4 -# define PIN_USI_SDA PINE5 -# define PIN_USI_SCL PINE4 -# define USI_START_COND_INT USISIF -# define USI_START_VECTOR USI_START_vect -# define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect -#endif - -// These macros make the stop condition detection code more readable. -#define USI_PINS_SCL_SDA ( ( 1 << PIN_USI_SDA ) | ( 1 << PIN_USI_SCL ) ) -#define USI_PINS_SDA ( 1 << PIN_USI_SDA ) -#define USI_PINS_SCL ( 1 << PIN_USI_SCL ) - -/******************************************************************************** - - functions implemented as macros - -********************************************************************************/ - -#define SET_USI_TO_SEND_ACK( ) \ -{ \ - /* prepare ACK, ack is a zero */ \ - USIDR = 0; \ - /* set SDA as output */ \ - DDR_USI |= ( 1 << PORT_USI_SDA ); \ - /* clear all interrupt flags, except Start Cond */ \ - USISR = \ - ( 0 << USI_START_COND_INT ) | \ - ( 1 << USIOIF ) | ( 1 << USIPF ) | \ - ( 1 << USIDC )| \ - /* set USI counter to shift 1 bit */ \ - ( 0x0E << USICNT0 ); \ -} - -#define SET_USI_TO_READ_ACK( ) \ -{ \ - /* set SDA as input */ \ - DDR_USI &= ~( 1 << PORT_USI_SDA ); \ - /* prepare ACK */ \ - USIDR = 0; \ - /* clear all interrupt flags, except Start Cond */ \ - USISR = \ - ( 0 << USI_START_COND_INT ) | \ - ( 1 << USIOIF ) | \ - ( 1 << USIPF ) | \ - ( 1 << USIDC ) | \ - /* set USI counter to shift 1 bit */ \ - ( 0x0E << USICNT0 ); \ -} - -#define SET_USI_TO_TWI_START_CONDITION_MODE( ) \ -{ \ - USICR = \ - /* enable Start Condition Interrupt, disable Overflow Interrupt */ \ - ( 1 << USISIE ) | ( 0 << USIOIE ) | \ - /* set USI in Two-wire mode, no USI Counter overflow hold */ \ - ( 1 << USIWM1 ) | ( 0 << USIWM0 ) | \ - /* Shift Register Clock Source = External, positive edge */ \ - /* 4-Bit Counter Source = external, both edges */ \ - ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) | \ - /* no toggle clock-port pin */ \ - ( 0 << USITC ); \ - USISR = \ - /* clear all interrupt flags, except Start Cond */ \ - ( 0 << USI_START_COND_INT ) | ( 1 << USIOIF ) | ( 1 << USIPF ) | \ - ( 1 << USIDC ) | ( 0x0 << USICNT0 ); \ -} - -#define SET_USI_TO_SEND_DATA( ) \ -{ \ - /* set SDA as output */ \ - DDR_USI |= ( 1 << PORT_USI_SDA ); \ - /* clear all interrupt flags, except Start Cond */ \ - USISR = \ - ( 0 << USI_START_COND_INT ) | ( 1 << USIOIF ) | ( 1 << USIPF ) | \ - ( 1 << USIDC) | \ - /* set USI to shift out 8 bits */ \ - ( 0x0 << USICNT0 ); \ -} - -#define SET_USI_TO_READ_DATA( ) \ -{ \ - /* set SDA as input */ \ - DDR_USI &= ~( 1 << PORT_USI_SDA ); \ - /* clear all interrupt flags, except Start Cond */ \ - USISR = \ - ( 0 << USI_START_COND_INT ) | ( 1 << USIOIF ) | \ - ( 1 << USIPF ) | ( 1 << USIDC ) | \ - /* set USI to shift out 8 bits */ \ - ( 0x0 << USICNT0 ); \ -} - -#define USI_RECEIVE_CALLBACK() \ -{ \ - if (usi_onReceiverPtr) \ - { \ - if (usiTwiAmountDataInReceiveBuffer()) \ - { \ - usi_onReceiverPtr(usiTwiAmountDataInReceiveBuffer()); \ - } \ - } \ -} - -#define USI_REQUEST_CALLBACK() \ -{ \ - if(usi_onRequestPtr) usi_onRequestPtr(); \ -} - -/******************************************************************************** - - typedef's - -********************************************************************************/ - -typedef enum -{ - USI_SLAVE_CHECK_ADDRESS = 0x00, - USI_SLAVE_SEND_DATA = 0x01, - USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA = 0x02, - USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA = 0x03, - USI_SLAVE_REQUEST_DATA = 0x04, - USI_SLAVE_GET_DATA_AND_SEND_ACK = 0x05 -} overflowState_t; - - - -/******************************************************************************** - - local variables - -********************************************************************************/ - -static uint8_t slaveAddress; -static uint8_t sleep_enable_bit; -static uint8_t in_transaction; -static volatile overflowState_t overflowState; - - -static uint8_t rxBuf[ TWI_RX_BUFFER_SIZE ]; -static volatile uint8_t rxHead; -static volatile uint8_t rxTail; -static volatile uint8_t rxCount; - -static uint8_t txBuf[ TWI_TX_BUFFER_SIZE ]; -static volatile uint8_t txHead; -static volatile uint8_t txTail; -static volatile uint8_t txCount; - - - -/******************************************************************************** - - local functions - -********************************************************************************/ - -// flushes the TWI buffers - -static void flushTwiBuffers( void ) -{ - rxTail = 0; - rxHead = 0; - rxCount = 0; - txTail = 0; - txHead = 0; - txCount = 0; -} // end flushTwiBuffers - - - -/******************************************************************************** - - public functions - -********************************************************************************/ - -// initialise USI for TWI slave mode - -void usiTwiSlaveInit( uint8_t ownAddress ) -{ - // initialize the TX and RX buffers to empty - flushTwiBuffers( ); - - slaveAddress = ownAddress; - - // In Two Wire mode (USIWM1, USIWM0 = 1X), the slave USI will pull SCL - // low when a start condition is detected or a counter overflow (only - // for USIWM1, USIWM0 = 11). This inserts a wait state. SCL is released - // by the ISRs (USI_START_vect and USI_OVERFLOW_vect). - - // Set SCL and SDA as output - DDR_USI |= ( 1 << PORT_USI_SCL ) | ( 1 << PORT_USI_SDA ); - - // set SCL high - PORT_USI |= ( 1 << PORT_USI_SCL ); - - // set SDA high - PORT_USI |= ( 1 << PORT_USI_SDA ); - - // Set SDA as input - DDR_USI &= ~( 1 << PORT_USI_SDA ); - - USICR = - // enable Start Condition Interrupt - ( 1 << USISIE ) | - // disable Overflow Interrupt - ( 0 << USIOIE ) | - // set USI in Two-wire mode, no USI Counter overflow hold - ( 1 << USIWM1 ) | ( 0 << USIWM0 ) | - // Shift Register Clock Source = external, positive edge - // 4-Bit Counter Source = external, both edges - ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) | - // no toggle clock-port pin - ( 0 << USITC ); - - // clear all interrupt flags and reset overflow counter - - USISR = ( 1 << USI_START_COND_INT ) | ( 1 << USIOIF ) | ( 1 << USIPF ) | ( 1 << USIDC ); - - // The 'in_transaction' variable remembers if the usiTwiSlave driver is in the middle of - // an i2c transaction. Initialize it to zero - in_transaction = 0; - -} // end usiTwiSlaveInit - - -bool usiTwiDataInTransmitBuffer(void) -{ - - // return 0 (false) if the receive buffer is empty - return txCount; - -} // end usiTwiDataInTransmitBuffer - - -// put data in the transmission buffer, wait if buffer is full - -void usiTwiTransmitByte( uint8_t data ) -{ - - // wait for free space in buffer - while ( txCount == TWI_TX_BUFFER_SIZE) ; - - // store data in buffer - txBuf[ txHead ] = data; - txHead = ( txHead + 1 ) & TWI_TX_BUFFER_MASK; - txCount++; - -} // end usiTwiTransmitByte - - -// return a byte from the receive buffer, wait if buffer is empty - -uint8_t usiTwiReceiveByte( void ) -{ - uint8_t rtn_byte; - - // wait for Rx data - while ( !rxCount ); - - rtn_byte = rxBuf [ rxTail ]; - // calculate buffer index - rxTail = ( rxTail + 1 ) & TWI_RX_BUFFER_MASK; - rxCount--; - - // return data from the buffer. - return rtn_byte; - -} // end usiTwiReceiveByte - - -uint8_t usiTwiAmountDataInReceiveBuffer(void) -{ - return rxCount; -} - - -/******************************************************************************** - - USI Start Condition ISR - -********************************************************************************/ - -ISR( USI_START_VECTOR ) -{ - uint8_t usi_pins; - // http://www.atmel.com/webdoc/AVRLibcReferenceManual/group__avr__interrupts.html - - // Notes about ISR. The compiler in the Arduino IDE handles some of the - // basic ISR plumbing (unless the "ISR_NAKED" attribute is applied). - // * The AVR processor resets the SREG.I bit when jumping into an ISR - // * The compiler automatically adds code to save SREG - // * < user's ISR code goes here > - // * The compiler automatically adds code to restore SREG - // * The compiler automatically uses the RETI instruction to return from the ISR. - // The RETI instruction enables interrupts after the return from ISR. - // The compiler behavior can be altered with attributes into the ISR declaration; - // however, the description above is the default. - - // cli() call is not necessary. Processor disables interrupts when - // jumping to an ISR - - // no need to save the SREG. The compiler does this automatically when using the - // ISR construct without modifying attributes. - - if ( !in_transaction ) - { - // remeber the sleep enable bit when entering the ISR - sleep_enable_bit = MCUCR & ( 1 << SE ); - - // clear the sleep enable bit to prevent the CPU from entering sleep mode while executing this ISR. - MCUCR &= ~( 1 << SE ); - } - - // set default starting conditions for new TWI package - overflowState = USI_SLAVE_CHECK_ADDRESS; - - // set SDA as input - DDR_USI &= ~( 1 << PORT_USI_SDA ); - - // the start condition is that the master pulls SDA low. - - // wait for SCL to go low to ensure the Start Condition has completed (the - // start detector will hold SCL low ) - if a Stop Condition arises then leave - // the interrupt to prevent waiting forever - don't use USISR to test for Stop - // Condition as in Application Note AVR312 because the Stop Condition Flag is - // going to be set from the last TWI sequence - - // while SCL is high and SDA is low - while ( ( usi_pins = PIN_USI & USI_PINS_SCL_SDA ) == USI_PINS_SCL ); - - // if SDA line was low at SCL edge, then start condition occurred - if ( !( usi_pins & USI_PINS_SDA ) ) - { - // a Stop Condition did not occur - - // Execute callback if this is a repeated start - if (in_transaction) - { - USI_RECEIVE_CALLBACK(); - } - - USICR = - // keep Start Condition Interrupt enabled to detect RESTART - ( 1 << USISIE ) | - // enable Overflow Interrupt - ( 1 << USIOIE ) | - // set USI in Two-wire mode, hold SCL low on USI Counter overflow - ( 1 << USIWM1 ) | ( 1 << USIWM0 ) | - // Shift Register Clock Source = External, positive edge - // 4-Bit Counter Source = external, both edges - ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) | - // no toggle clock-port pin - ( 0 << USITC ); - - //remember that the USI is in a valid i2c transaction - in_transaction = 1; - - } - else - { - // a Stop Condition did occur - - USICR = - // enable Start Condition Interrupt - ( 1 << USISIE ) | - // disable Overflow Interrupt - ( 0 << USIOIE ) | - // set USI in Two-wire mode, no USI Counter overflow hold - ( 1 << USIWM1 ) | ( 0 << USIWM0 ) | - // Shift Register Clock Source = external, positive edge - // 4-Bit Counter Source = external, both edges - ( 1 << USICS1 ) | ( 0 << USICS0 ) | ( 0 << USICLK ) | - // no toggle clock-port pin - ( 0 << USITC ); - - //no longer in valid i2c transaction - in_transaction = 0; - // restore the sleep enable bit - MCUCR |= sleep_enable_bit; - - } // end if - - USISR = - // clear interrupt flags - resetting the Start Condition Flag will - // release SCL - ( 1 << USI_START_COND_INT ) | ( 1 << USIOIF ) | - ( 1 << USIPF ) |( 1 << USIDC ) | - // set USI to sample 8 bits (count 16 external SCL pin toggles) - ( 0x0 << USICNT0); - - // no need to restore the SREG. The compiler does this automatically when using the - // ISR construct without modifying attributes. - - // The compiler automatically uses an RETI instruction to return when using the - // ISR construct without modifying attributes. - -} // end ISR( USI_START_VECTOR ) - - - -/******************************************************************************** - - USI Overflow ISR - -Handles all the communication. - -Only disabled when waiting for a new Start Condition. - -********************************************************************************/ - -ISR( USI_OVERFLOW_VECTOR ) -{ - uint8_t finished; - uint8_t usi_pins; - - // http://www.atmel.com/webdoc/AVRLibcReferenceManual/group__avr__interrupts.html - - // Notes about ISR. The compiler in the Arduino IDE handles some of the - // basic ISR plumbing. - // * The AVR processor resets the SREG.I bit when jumping into an ISR - // * The compiler automatically adds code to save the SREG - // * < user's ISR code goes here > - // * The compiler automatically adds code to restore the SREG - // * The compiler automatically uses the RETI instruction to return from the ISR. - // The RETI insturction enables interrupts after the return from ISR. - // The compiler behavior can be altered with attributes into the ISR declaration; - // however, the description above is the default. - - // cli() call is not necessary. Processor disables interrupts when - // jumping to an ISR - - // no need to save the SREG. The compiler does this automatically when using the - // ISR construct without modifying attributes. - - // The ISR is only ever entered because the ISR(USI_START_VECTOR) interrupt - // routine ran first. That routine saved the sleep mode and disabled sleep. - - // Most of the time this routine exits, it has setup the USI to shift in/out bits - // and is expected to re-entered because of the USI overflow interrupt. Track whether or - // not the transaction is completely finished. - finished = 0; - - - switch ( overflowState ) - { - - // Address mode: check address and send ACK (and next USI_SLAVE_SEND_DATA) if OK, - // else reset USI - case USI_SLAVE_CHECK_ADDRESS: - if ( ( USIDR == 0 ) || ( ( USIDR >> 1 ) == slaveAddress) ) - { - if ( USIDR & 0x01 ) - { - overflowState = USI_SLAVE_SEND_DATA; - } - else - { - overflowState = USI_SLAVE_REQUEST_DATA; - } // end if - - // ack the start frame - // sets up the USI to pull SDA low and clock one bit (two edges) - SET_USI_TO_SEND_ACK( ); - } - else - { - SET_USI_TO_TWI_START_CONDITION_MODE( ); - finished = 1; - } - break; - - // master-read / slave-send: check reply and goto USI_SLAVE_SEND_DATA if OK, - // else reset USI - case USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA: - // Execute request callback for each byte requested, as this is the intended - // behavior of this library - USI_REQUEST_CALLBACK(); - if ( USIDR ) - { - // if NACK, the master does not want more data - SET_USI_TO_TWI_START_CONDITION_MODE( ); - finished = 1; - break; - } - // from here we just drop straight into USI_SLAVE_SEND_DATA if the - // master sent an ACK - - // copy data from buffer to USIDR and set USI to shift byte - // next USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA - case USI_SLAVE_SEND_DATA: - // Get data from Buffer - if ( txCount ) - { - USIDR = txBuf[ txTail ]; - txTail = ( txTail + 1 ) & TWI_TX_BUFFER_MASK; - txCount--; - - overflowState = USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA; - SET_USI_TO_SEND_DATA( ); - } - else - { - // the buffer is empty - SET_USI_TO_READ_ACK( ); // This might be neccessary sometimes see http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=805227#805227 - SET_USI_TO_TWI_START_CONDITION_MODE( ); - } // end if - break; - - // set USI to sample reply from master - // next USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA - case USI_SLAVE_REQUEST_REPLY_FROM_SEND_DATA: - overflowState = USI_SLAVE_CHECK_REPLY_FROM_SEND_DATA; - SET_USI_TO_READ_ACK( ); - break; - - // master-send / slave-receive: set USI to sample data from master, next - // USI_SLAVE_GET_DATA_AND_SEND_ACK - case USI_SLAVE_REQUEST_DATA: - overflowState = USI_SLAVE_GET_DATA_AND_SEND_ACK; - SET_USI_TO_READ_DATA( ); - - // with the SET_USI_TO_READ_DATA() macro call above, the USI has - // been setup to catch the next byte if the master sends one. - // while that's going on, look for a stop condition here which - // is when the SDA line goes high after the SCL line; - - // wait until SCL goes high - while ( ! ( ( usi_pins = PIN_USI & USI_PINS_SCL_SDA ) & USI_PINS_SCL ) ); - - // if SDA line was high at SCL edge, then not a stop condition - if ( usi_pins & USI_PINS_SDA ) - break; - - // wait until SCL goes low or SDA goes high - while ( ( usi_pins = PIN_USI & USI_PINS_SCL_SDA ) == USI_PINS_SCL ); - - // if both SCL and SDA are high, then stop condition occurred - if ( usi_pins == USI_PINS_SCL_SDA ) - { - USI_RECEIVE_CALLBACK(); - SET_USI_TO_TWI_START_CONDITION_MODE( ); - finished = 1; - } - - break; - - // copy data from USIDR and send ACK - // next USI_SLAVE_REQUEST_DATA - case USI_SLAVE_GET_DATA_AND_SEND_ACK: - // put data into buffer - // check buffer size - if ( rxCount < TWI_RX_BUFFER_SIZE ) - { - rxBuf[ rxHead ] = USIDR; - rxHead = ( rxHead + 1 ) & TWI_RX_BUFFER_MASK; - rxCount++; - } else { - // overrun - // drop data - } - // next USI_SLAVE_REQUEST_DATA - overflowState = USI_SLAVE_REQUEST_DATA; - SET_USI_TO_SEND_ACK( ); - break; - - } // end switch - - if (finished) - { - //no longer in valid i2c transaction - in_transaction = 0; - // restore the sleep enable bit - // note that this allows sleep -- it does not cause sleep - MCUCR |= sleep_enable_bit; - } - - // no need to restore the SREG. The compiler does this automatically when using the - // ISR construct without modifying attributes. - - // The compiler automatically uses an RETI instruction to return when using the - // ISR construct without modifying attributes. - -} // end ISR( USI_OVERFLOW_VECTOR ) -- cgit v1.2.3