I have the following problem:
I want to make two AVR Atmega 328P-Pu communicating together with I2C
- No1 is Master (I2C address :0x01)
- No2 is Slave (I2C address :0x02)
On slave answer to general call is enabled (address 0x00) and it works. Or, at least I can see that it enters the ISR(TWI_vect) on the slave with the code further below.
However when trying to call the salve with it's own address (0x02) it won't respond. Everything else remains the same (circuit, pull-up resistors etc.)
Moreover, trying to bomb the bus with calls to all possible address up to 128 does not yield response from slave.
I am sure it is a silly mistake somewhere but running out of idea as of why it is like that. Any help welcome.
On Master
I2C communication is initiated like that
uint8_t i2c_start(uint8_t address)
{
// reset TWI control register
TWCR = 0;
// transmit START condition
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
// wait for end of transmission
while( !(TWCR & (1<<TWINT)) );
// check if the start condition was successfully transmitted
if((TWSR & 0xF8) != TW_START){ return 1; }
// load slave address into data register
TWDR = address;
// start transmission of address
TWCR = (1<<TWINT) | (1<<TWEN);
// wait for end of transmission
while( !(TWCR & (1<<TWINT)) );
// check if the device has acknowledged the READ / WRITE mode
uint8_t twst = TW_STATUS & 0xF8;
if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 2;
return 0;
}
In the Master's main call is made like that
uint8_t address=1;
addr=address<<1;
i2c_start(addr|I2C_WRITE); // I2C_WRITE =0x00
On slave
void I2C_init(uint8_t address){
// load address into TWI address register
TWAR = (address << 1);
TWAR = (1<<TWGCE); //respond to general call ! WARNING
// set the TWCR to enable address matching and enable TWI, clear TWINT, enable TWI interrupt
TWCR=0x0; //WARNING
TWCR = (1<<TWIE) | (1<<TWEA) | (1<<TWINT) | (1<<TWEN);
}
The main on the slave looks like that
I2C_init(slaveaddress);
sei();
LED_PORT_DDR |= _BV(LED_BIT);
for(;;){
wdt_reset();
if(debug==1) //Debug is set to 1 in the ISR(TWI_vect)
{
LED_PORT_OUTPUT |= _BV(LED_BIT); //set to 1 e.g
}
}