Doubt on I2C LLD
Posted: Fri Mar 24, 2017 12:06 am
I am doubting the implementation of the AVR I2C LLD here. I run the testhal example, where the designated address is 0x50. However, on an oscilloscope, I found that 0xA0 was used as address. The IRQ is kind of big so I need some more time processing, but I do find a suspicious line:
Which is exactly what makes 0x50 to be 0xA0. I don't know why it is there (without digging into the TWI docs), but it looks like the source of problems.
BTW, this is a snippet that allows full frequency range of AVR TWI/I2C, I modified from the ChibiOS 16.something.
Code: Select all
TWDR = (i2cp->addr << 1);
Which is exactly what makes 0x50 to be 0xA0. I don't know why it is there (without digging into the TWI docs), but it looks like the source of problems.
BTW, this is a snippet that allows full frequency range of AVR TWI/I2C, I modified from the ChibiOS 16.something.
Code: Select all
void i2c_lld_start(I2CDriver *i2cp) {
uint32_t clock_speed = 100000;
// uint32_t clock_speed = 1000;
/* TODO: Test TWI without external pull-ups (use internal) */
if (i2cp->config != NULL)
clock_speed = i2cp->config->clock_speed;
uint32_t bdiv = ((F_CPU / clock_speed) - 16 ) / 2;
if (bdiv < 256) {
/* Configure prescaler to 1 */
TWSR &= 0xF8;
TWBR = bdiv;
}
else if (bdiv < 1024) {
/* Prescale 4.*/
TWSR &= 0xF9;
TWSR |= 0x01;
TWBR = bdiv / 4;
}
else if (bdiv < 4096) {
TWSR &= 0xFA;
TWSR |= 0x02;
TWBR = bdiv / 16;
}
else {
TWSR &= 0xFB;
TWSR |= 0x03;
TWBR = bdiv / 64;
}
/* Configure baudrate */
// TWBR = ((F_CPU / clock_speed) - 16) / 2;
}