/** * \brief Notification of Last byte is transmitted * * \param none. */ static void twi_slave_last_byte_write_done(void) { slave_transfer.state = TWI_IDLE; slave_transfer.status = TWI_STATUS_TX_COMPLETE; twi_slave_enable(); }
/** * \brief Resets the slave state and status to initial for next * transmission/reception */ void twi_slave_status_reset(void) { slave_transfer.state = TWI_IDLE; slave_transfer.status = TWI_STATUS_NO_STATE; twi_mode = SLAVE; twi_slave_enable(); }
int main(void) { // Set clock @ 8Mhz CPU_PRESCALE(1); sei(); twi_slave_init(); twi_slave_enable(); for (;;); }
/** * \internal * * \brief TWI Interrupt Handler */ static void twi_interrupt_handler(void) { uint8_t status; status = TWI_TWSR_STATUS_MASK; switch (status) { case TWS_START: /*A START condition has been transmitted.*/ case TWS_RSTART: /*A repeated START condition has been *transmitted.*/ twi_master_start(); break; case TWS_MT_SLA_ACK: /*SLA+W has been transmitted; ACK has *been received.*/ case TWS_MT_DATA_ACK: /*Data byte has been transmitted; ACK has *been received.*/ twi_master_write_done(); break; case TWS_BUSERROR: /*Bus error due to illegal START or STOP * condition.*/ case TWS_MT_SLA_NACK: /*SLA+W has been transmitted; NOT ACK has *been received.*/ case TWS_MT_DATA_NACK: /*Data byte has been transmitted; NOT ACK *has been received.*/ case TWS_MR_SLA_NACK: /*SLA+R has been transmitted; NOT ACK has *been received.*/ twi_master_bus_reset(); master_transfer.status = ERR_IO_ERROR; break; case TWS_MR_SLA_ACK: /*SLA+R has been transmitted; ACK has been *received.*/ twi_master_addr_ack(); break; case TWS_MR_DATA_ACK: /*Data byte has been received; ACK has been *returned.*/ twi_master_read_done(twi_read_byte()); break; case TWS_MR_DATA_NACK: /*Data byte has been received; NOT ACK has *been returned.*/ twi_master_read_last_byte(twi_read_byte()); break; case TWS_M_ARB_LOST: /*Arbitration lost in SLA+W or data bytes *(Transmitter); Arbitration lost in SLA+R or *NOT ACK bit (Receiver).*/ /* If arbitration lost indicate to application to decide either * switch to Slave mode or wait until the bus is free and transmit * a new START condition */ master_transfer.state = TWI_IDLE; master_transfer.status = ERR_BUSY; twi_master_busy = false; break; case TWS_ST_SLA_ACK: /* Own SLA+R has been received; ACK has been * returned */ case TWS_ST_SLA_ACK_M_ARB_LOST: /* ! Arbitration lost in SLA+R/W as Master; *own SLA+R has been received; *ACK has been returned */ slave_transfer.data_count = 0; /* Set buffer pointer to first data * location */ case TWS_ST_DATA_ACK: /* Data byte in TWDR has been transmitted; * ACK has been received */ twi_slave_data_write(); slave_transfer.state = TWI_PROCESS; break; case TWS_ST_DATA_NACK: /* Data byte in TWDR has been transmitted; * NACK has been received. */ /* I.e. this could be the end of the * transmission. */ twi_slave_last_byte_write_done(); break; case TWS_SR_GEN_ACK: /* General call address has been received; * ACK has been returned */ case TWS_SR_GEN_ACK_M_ARB_LOST: /* ! Arbitration lost in SLA+R/W as Master; * General call address has been received; * ACK has been returned */ case TWS_SR_SLA_ACK: /* Own SLA+W has been received ACK has been * returned */ case TWS_SR_SLA_ACK_M_ARB_LOST: /* ! Arbitration lost in SLA+R/W as Master; * own SLA+W has been received; * ACK has been returned */ slave_transfer.data_count = 0; /* Set buffer pointer to first data * location */ twi_slave_enable(); slave_transfer.state = TWI_PROCESS; break; case TWS_SR_SLA_DATA_ACK: /* Previously addressed with own SLA+W; data * has been received; ACK has been returned */ case TWS_SR_GEN_DATA_ACK: /* Previously addressed with general call; * data has been received; ACK has been * returned */ twi_slave_data_read(twi_read_byte()); slave_transfer.state = TWI_PROCESS; break; case TWS_SR_STOP_RESTART: /* A STOP condition or repeated START * condition has been received while still * addressed as Slave */ /* Enter not addressed mode and listen to address match */ slave_transfer.state = TWI_IDLE; slave_transfer.status = TWI_STATUS_RX_COMPLETE; twi_slave_enable(); break; case TWS_SR_SLA_DATA_NACK: /* Previously addressed with own SLA+W; data * has been received; NOT ACK has been * returned */ case TWS_SR_GEN_DATA_NACK: /* Previously addressed with general call; * data has been received; NOT ACK has been * returned */ case TWS_ST_DATA_ACK_LAST_BYTE: /* Last data byte in TWDR has been * transmitted (TWEA = ; ACK has * been received */ twi_slave_bus_reset(); slave_transfer.status = TWI_STATUS_IO_ERROR; break; default: if(twi_mode == MASTER) { master_transfer.state = TWI_IDLE; master_transfer.status = ERR_PROTOCOL; twi_master_busy = false; } else { slave_transfer.status = TWI_STATUS_PROTOCOL_ERROR; /* Store TWI State as * errormessage, operation also * clears the Success bit */ slave_transfer.state = TWI_IDLE; twi_slave_enable(); } break; } }
/** * \brief Read received data * * \param data - Contains data read from twi bus to be written to data receive *buffer. */ static void twi_slave_data_read(uint8_t data) { slave_transfer.data_buffer->rx_buffer[slave_transfer.data_count++] = data; twi_slave_enable(); }
/** * \brief writing an byte to TWI. * * \param data - contains the data to transmitted ro master. */ static inline void twi_slave_write_byte(uint8_t data) { TWDR = data; twi_slave_enable(); }