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