__interrupt void USI_TXRX(void) { switch(__even_in_range(i2c_state,12)) { case I2C_IDLE: break; case I2C_START: // generate start condition USISRL = 0x00; USICTL0 |= (USIGE|USIOE); USICTL0 &= ~USIGE; i2c_prepare_data_xmit_recv(); break; case I2C_PREPARE_ACKNACK: // prepare to receive ACK/NACK USICTL0 &= ~USIOE; // SDA = input USICNT |= 0x01; // Bit counter=1, receive (N)Ack bit i2c_state = I2C_HANDLE_RXTX; // Go to next state: check ACK/NACK and continue xmitting/receiving if necessary break; case I2C_HANDLE_RXTX: // Process Address Ack/Nack & handle data TX if((USISRL & BIT0) != 0) { // did we get a NACK? i2c_prepare_stop(); } else { i2c_prepare_data_xmit_recv(); } break; case I2C_RECEIVED_DATA: // received data, send ACK/NACK *i2c_receive_buffer = USISRL; i2c_receive_buffer++; USICTL0 |= USIOE; // SDA = output if(i2c_sequence_length > 0) { // If this is not the last byte USISRL = 0x00; // ACK i2c_state = I2C_HANDLE_RXTX; // Go to next state: data/rcv again } else { // last byte: send NACK USISRL = 0xff; // NACK i2c_state = I2C_PREPARE_STOP; // stop condition is next } USICNT |= 0x01; // Bit counter = 1, send ACK/NACK bit break; case I2C_PREPARE_STOP: // prepare stop condition i2c_prepare_stop(); // prepare stop, go to state 14 next break; case I2C_STOP: // Generate Stop Condition USISRL = 0x0FF; // USISRL = 1 to release SDA USICTL0 |= USIGE; // Transparent latch enabled USICTL0 &= ~(USIGE|USIOE); // Latch/SDA output disabled i2c_state = I2C_IDLE; // Reset state machine for next xmt if(i2c_wakeup_sr_bits) { _bic_SR_register_on_exit(i2c_wakeup_sr_bits); // exit active if prompted to } break; } USICTL1 &= ~USIIFG; // Clear pending flag }
//#pragma vector = USI_VECTOR //__interrupt void USI_TXRX(void) inline void i2c_state_machine_interrupt() { // switch(__even_in_range(i2c_state,12)) { switch(i2c_state) { case I2C_IDLE: break; case I2C_START_XMIT: // start condition was sent along with address /* USISRL = 0x00; USICTL0 |= (USIGE|USIOE); USICTL0 &= ~USIGE;*/ i2c_prepare_data_xmit_recv(); break; case I2C_START_RECV: // start condition was sent along with address /* USISRL = 0x00; USICTL0 |= (USIGE|USIOE); USICTL0 &= ~USIGE;*/ if((UCB0STAT & UCNACKIFG) != 0) { // did we get a NACK? if so, do a stop UCB0STAT &= ~UCNACKIFG; i2c_send_stop(); } else { // if we got an ACK, then continue sending all data i2c_prepare_data_xmit_recv(); } break; /*case I2C_PREPARE_ACKNACK: // prepare to receive ACK/NACK USICTL0 &= ~USIOE; // SDA = input USICNT |= 0x01; // Bit counter=1, receive (N)Ack bit i2c_state = I2C_HANDLE_RXTX; // Go to next state: check ACK/NACK and continue xmitting/receiving if necessary break;*/ case I2C_HANDLE_TX: // Process Address Ack/Nack & handle data TX if((UCB0STAT & UCNACKIFG) != 0) { // did we get a NACK? if so, do a stop UCB0STAT &= ~UCNACKIFG; i2c_send_stop(); } else { // if we got an ACK, then continue sending all data i2c_prepare_data_xmit_recv(); } break; /* case I2C_RECEIVED_DATA: // received data, send ACK/NACK *i2c_receive_buffer = UCB0RXBUF; i2c_receive_buffer++; //USICTL0 |= USIOE; // SDA = output if(i2c_sequence_length > 1) { // If this is not the last byte USISRL = 0x00; // ACK i2c_state = I2C_HANDLE_RX; // Go to next state: data/rcv again } else { // last byte: send NACK USISRL = 0xff; // NACK i2c_state = I2C_PREPARE_STOP; // stop condition is next } USICNT |= 0x01; // Bit counter = 1, send ACK/NACK bit break; */ /* case I2C_PREPARE_STOP: // prepare stop condition i2c_prepare_stop(); // prepare stop, go to state 14 next break; */ /*case I2C_STOP: // Generate Stop Condition USISRL = 0x0FF; // USISRL = 1 to release SDA USICTL0 |= USIGE; // Transparent latch enabled USICTL0 &= ~(USIGE+USIOE); // Latch/SDA output disabled i2c_state = I2C_IDLE; // Reset state machine for next xmt if(i2c_wakeup_sr_bits) { //_bic_SR_register_on_exit(i2c_wakeup_sr_bits); // exit active if prompted to _BIC_SR_IRQ(i2c_wakeup_sr_bits); } break;*/ } //USICTL1 &= ~USIIFG; // Clear pending flag }