//main.c
#include <ioavr.h>
#include <inavr.h>
#include "TWI_Slave.h"
// Sample TWI transmission commands
#define TWI_CMD_MASTER_WRITE 0x10
#define TWI_CMD_MASTER_READ 0x20
// The AVR can be waken up by a TWI address match from all sleep modes,
// But it only wakes up from other TWI interrupts when in idle mode.
// If POWER_MANAGEMENT_ENABLED is defined the device will enter power-down
// mode when waiting for a new command and enter idle mode when waiting
// for TWI receives and transmits to finish.
#define POWER_MANAGEMENT_ENABLED
// When there has been an error, this function is run and takes care of it
unsigned char TWI_Act_On_Failure_In_Last_Transmission ( unsigned char TWIerrorMsg );
void main( void )
{
unsigned char messageBuf[TWI_BUFFER_SIZE];
unsigned char TWI_slaveAddress;
// LED feedback port - connect port B to the STK500 LEDS
DDRB = 0xFF; // Set to ouput
PORTB = 0x55; // Startup pattern
// Own TWI slave address
TWI_slaveAddress = 0x10;
// Initialise TWI module for slave operation. Include address and/or enable General Call.
TWI_Slave_Initialise( (unsigned char)((TWI_slaveAddress<<TWI_ADR_BITS) | (TRUE<<TWI_GEN_BIT) ));
__enable_interrupt();
// Start the TWI transceiver to enable reseption of the first command from the TWI Master.
TWI_Start_Transceiver();
// This example is made to work together with the AVR315 TWI Master application note. In adition to connecting the TWI
// pins, also connect PORTB to the LEDS. The code reads a message as a TWI slave and acts according to if it is a
// general call, or an address call. If it is an address call, then the first byte is considered a command byte and
// it then responds differently according to the commands.
// This loop runs forever. If the TWI is busy the execution will just continue doing other operations.
for(;;)
{
#ifdef POWER_MANAGEMENT_ENABLED
// Sleep while waiting for TWI transceiver to complete or waiting for new commands.
// If we have data in the buffer, we can't enter sleep because we have to take care
// of it first.
// If the transceiver is busy, we enter idle mode because it will wake up by all TWI
// interrupts.
// If the transceiver not is busy, we can enter power-down mode because next receive
// should be a TWI address match and it wakes the device up from all sleep modes.
if( ! TWI_statusReg.RxDataInBuf ) {
if(TWI_Transceiver_Busy()) {
MCUCR = (1<<SE)|(0<<SM2)|(0<<SM1)|(0<<SM0); // Enable sleep with idle mode
} else {
MCUCR = (1<<SE)|(0<<SM2)|(1<<SM1)|(0<<SM0); // Enable sleep with power-down mode
}
__sleep();
} else {
__no_operation(); // There is data in the buffer, code below takes care of it.
}
#else // No power management
// Here you can add your own code that should be run while waiting for the TWI to finish
__no_operation(); // Put own code here.
#endif |