I2C Problem with STM32F4DISCOVERY in v2.4.0
Posted: Tue Mar 20, 2012 2:25 pm
I tried to read the ID-Register from the audio-dac (CS43L22) on the discovery board which is connected to the i2c1 on the stm32f4.
During this i encounterd three problems:
1. you cant receive exactly 1 byte. 0 and >1 works - i think this is a bug in i2c_lld_master_transmit_timeout:
this fails if rxbytes is exactly 1.
2. if i send only one byte it sends two bytes where the second one is 0x00.
the second time you send one byte it sends 0x00 first and then the byte you inteded to send.
the third time is like the fist again and so on...
3. if you send 2 or more bytes it works correctly the fist time you call i2cMasterTransmit.
the second time it sends (assuming you send 3 bytes) 0x00, 0x04, 0x00.
the third time is like the first again and so on...
I used a logic analyzer to watch what it sends and receives and made a screenshot of the 2. problem:

In my code example i send 1 byte two times (if you repeat this the result repeats).
Then i send 3 bytes (2 times).
main.c:
So i was wondering why this is, because with the i2c driver in 2.3.4 it worked.
Andi
During this i encounterd three problems:
1. you cant receive exactly 1 byte. 0 and >1 works - i think this is a bug in i2c_lld_master_transmit_timeout:
Code: Select all
chDbgCheck(((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL))),
"i2c_lld_master_transmit_timeout");
this fails if rxbytes is exactly 1.
2. if i send only one byte it sends two bytes where the second one is 0x00.
the second time you send one byte it sends 0x00 first and then the byte you inteded to send.
the third time is like the fist again and so on...
3. if you send 2 or more bytes it works correctly the fist time you call i2cMasterTransmit.
the second time it sends (assuming you send 3 bytes) 0x00, 0x04, 0x00.
the third time is like the first again and so on...
I used a logic analyzer to watch what it sends and receives and made a screenshot of the 2. problem:

In my code example i send 1 byte two times (if you repeat this the result repeats).
Then i send 3 bytes (2 times).
main.c:
Code: Select all
#include "ch.hpp"
#include "hal.h"
using namespace chibios_rt;
static const I2CConfig i2cfg =
{
OPMODE_I2C,
100000,
STD_DUTY_CYCLE,
};
int main(void)
{
halInit();
System::Init();
i2cStart(&I2CD1, &i2cfg);
while (TRUE) {
unsigned char addr = 0x94;
unsigned char rxdata[] = {0, 0};
unsigned char regAddr[] = {0x01, 0xFE, 0xFF};
((*(volatile uint32_t*)0x40020C14)) |= (1<<(4)); //chip select for audio-dac
i2cAcquireBus(&I2CD1);
i2cMasterTransmit(&I2CD1, addr >> 1, regAddr, 1, rxdata, 2);
i2cReleaseBus(&I2CD1);
regAddr[0] = 0x01; //just to make sure
i2cAcquireBus(&I2CD1);
i2cMasterTransmit(&I2CD1, addr >> 1, regAddr, 1, rxdata, 2);
i2cReleaseBus(&I2CD1);
i2cAcquireBus(&I2CD1);
i2cMasterTransmit(&I2CD1, addr >> 1, regAddr, 3, rxdata, 2);
i2cReleaseBus(&I2CD1);
regAddr[0] = 0x01; //just to make sure
i2cAcquireBus(&I2CD1);
i2cMasterTransmit(&I2CD1, addr >> 1, regAddr, 3, rxdata, 2);
i2cReleaseBus(&I2CD1);
chThdSleepMilliseconds(10);
}
}
So i was wondering why this is, because with the i2c driver in 2.3.4 it worked.
Andi