STM32F4 I2C Not Recognizing Ack
Posted: Sat Jul 23, 2016 8:02 am
I am developing code for an STM32F405 controller to communicate with a Wireless Wii Nunchuk through I2C (I2CD1). I am unable to get ChibiOS to report a successful transaction; I2CGetErrors keeps returning 4 for No Ack. Scoping the lines, everything is getting sent as expected, and the ACK bit is low on the 9th rising edge of SCL, so I think the slave is responding. The microcontroller does not recognize the ACK bit.
Relevant initialization code:
#define I2C_DEV I2CD1
#define I2C_GPIO GPIOB
#define I2C_SCL_PIN 6
#define I2C_SDA_PIN 7
static i2caddr_t addr = 0x52;
static const I2CConfig i2ccfg = {
OPMODE_I2C,
100000,
STD_DUTY_CYCLE,
};
void comm_nunchuk_init(void)
{
i2cAcquireBus(&I2C_DEV);
palSetPadMode(I2C_GPIO, I2C_SCL_PIN,
PAL_MODE_ALTERNATE(4) |
PAL_STM32_OTYPE_OPENDRAIN |
PAL_STM32_OSPEED_MID1);
palSetPadMode(I2C_GPIO, I2C_SDA_PIN,
PAL_MODE_ALTERNATE(4) |
PAL_STM32_OTYPE_OPENDRAIN |
PAL_STM32_OSPEED_MID1);
i2cStart(&I2C_DEV, &i2ccfg);
i2cReleaseBus(&I2C_DEV);
}
Sending code:
txbuf[0] = 0xF0;
txbuf[1] = 0x55;
i2cAcquireBus(&I2C_DEV);
status = i2cMasterTransmitTimeout(&I2C_DEV, addr, txbuf, 2, rxbuf, 0, tmo);
i2cReleaseBus(&I2C_DEV);
Status is always -2 and the error code is 4. I have 4.7k pullup resistors on each line.
I also noticed that if there was actually no ACK bit (i.e. the slave is disconnected) the I2C bus would stop after sending the slave address. However, in my case, it sends the address and both bytes (three sets of 9 SCL clocks), all with ACK bits being low on the 9th clock, but still returns a No Ack error. Why would it report no ack when SDA is low on the 9th rising edge of SCL? Any guidance would be appreciated.
Relevant initialization code:
#define I2C_DEV I2CD1
#define I2C_GPIO GPIOB
#define I2C_SCL_PIN 6
#define I2C_SDA_PIN 7
static i2caddr_t addr = 0x52;
static const I2CConfig i2ccfg = {
OPMODE_I2C,
100000,
STD_DUTY_CYCLE,
};
void comm_nunchuk_init(void)
{
i2cAcquireBus(&I2C_DEV);
palSetPadMode(I2C_GPIO, I2C_SCL_PIN,
PAL_MODE_ALTERNATE(4) |
PAL_STM32_OTYPE_OPENDRAIN |
PAL_STM32_OSPEED_MID1);
palSetPadMode(I2C_GPIO, I2C_SDA_PIN,
PAL_MODE_ALTERNATE(4) |
PAL_STM32_OTYPE_OPENDRAIN |
PAL_STM32_OSPEED_MID1);
i2cStart(&I2C_DEV, &i2ccfg);
i2cReleaseBus(&I2C_DEV);
}
Sending code:
txbuf[0] = 0xF0;
txbuf[1] = 0x55;
i2cAcquireBus(&I2C_DEV);
status = i2cMasterTransmitTimeout(&I2C_DEV, addr, txbuf, 2, rxbuf, 0, tmo);
i2cReleaseBus(&I2C_DEV);
Status is always -2 and the error code is 4. I have 4.7k pullup resistors on each line.
I also noticed that if there was actually no ACK bit (i.e. the slave is disconnected) the I2C bus would stop after sending the slave address. However, in my case, it sends the address and both bytes (three sets of 9 SCL clocks), all with ACK bits being low on the 9th clock, but still returns a No Ack error. Why would it report no ack when SDA is low on the 9th rising edge of SCL? Any guidance would be appreciated.