i2c hangs when reading just one byte
Moderators: RoccoMarco, lbednarz, tfAteba
Re: i2c hangs when reading just one byte
I have never touch that semaphore by hands. Only I2C driver touches them when I am acquiring/releasing I2C bus from my code.
- Giovanni
- Site Admin
- Posts: 14891
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: i2c hangs when reading just one byte
Is it possible that the thread waiting on the semaphore is waked not using a semaphore primitive but chSchReadyI() or chSchWakeup() or chThdResumeI() etc? Doing so would leave the semaphore out of synchronization with its queue.
Giovanni
Giovanni
- Giovanni
- Site Admin
- Posts: 14891
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: i2c hangs when reading just one byte
Also, could you try to enable mutexes and see if there is still the problem?
Giovanni
Giovanni
Re: i2c hangs when reading just one byte
I do not call that functions by hands, but I2C driver uses chSchReadyI() to wakeup thread in case of errors or transfer finishing.
When mutexes enabled than problem does not appear (run from 9pm to 7am this night)
When mutexes enabled than problem does not appear (run from 9pm to 7am this night)
- Giovanni
- Site Admin
- Posts: 14891
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: i2c hangs when reading just one byte
This is very strange.
Could you try with semaphores again but without calling I2C from within the mutual exclusion zone? Put inside some random sleeps.
A bug in the I2C could make the driver wakeup a thread using chScrReadyI() that already exited the I2C driver and is waiting on the semaphore instead. A late interrupt or something like that, it would be a good idea to check the driver state from ISRs with an assertion to verify this hypothesis.
BTW, I am thinking to remove the timeout handling from the I2C API and put it as a configuration parameter, this way not all implementations would have to implement it, this is just a workaround on that I2C defects.
Giovanni
Could you try with semaphores again but without calling I2C from within the mutual exclusion zone? Put inside some random sleeps.
A bug in the I2C could make the driver wakeup a thread using chScrReadyI() that already exited the I2C driver and is waiting on the semaphore instead. A late interrupt or something like that, it would be a good idea to check the driver state from ISRs with an assertion to verify this hypothesis.
BTW, I am thinking to remove the timeout handling from the I2C API and put it as a configuration parameter, this way not all implementations would have to implement it, this is just a workaround on that I2C defects.
Giovanni
Re: i2c hangs when reading just one byte
Giovanni wrote:try with semaphores again but without calling I2C from within the mutual exclusion zone?
Can not understand you. Could you explain it using my code from https://github.com/barthess/u/tree/master/soft/firmware
or post patch or changed files here.
P.S.
Interesting idea. Can you connect to my OpenOCD remotely from internet for debugging? Is it possible?
Re: i2c hangs when reading just one byte
barthess wrote:P.S.
Interesting idea. Can you connect to my OpenOCD remotely from internet for debugging? Is it possible?
I have done this already, and it works well.
Re: i2c hangs when reading just one byte
I apparently have the same problem. When I try to run following code on L3G4200 gyroscope the program will hang on second call of i2cMasterTransmit function. When I set number of bytes to read to 0 or 2 then the program works. During the program hang the SDA and SCL lines are pulled down to GND by MCU.
Environment: STM32F100C4, ChibiOs 2.4.2
Environment: STM32F100C4, ChibiOs 2.4.2
Code: Select all
int main(void) {
halInit();
chSysInit();
palSetPadMode(GPIOA, 2, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
sdStart(&SD2, NULL);
palSetPadMode(GPIOB, 6, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);
palSetPadMode(GPIOB, 7, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);
i2cCFG.clock_speed = 10000;
i2cCFG.duty_cycle = STD_DUTY_CYCLE;
i2cCFG.op_mode = OPMODE_I2C;
i2cStart(&I2CD1, &i2cCFG);
while (TRUE) {
#define L3G4200_I2C_ADDRESS (0xD0 >> 1)
uint8_t reg_addr;
uint8_t buff[3];
reg_addr = 0x0F; //WHO_AM_I register address
i2cMasterTransmit(&I2CD1, L3G4200_I2C_ADDRESS, ®_addr, 1, buff, 1);
chprintf((BaseChannel *)&SD2, "%x\n", buff[0]);
chThdSleepMilliseconds(333);
}
}
Re: i2c hangs when reading just one byte
1) There is no possible to read single byte on F1x platform.
2) Enable all debug options in chconf.h and you will get panic on attempt of single byte reading.
2) Enable all debug options in chconf.h and you will get panic on attempt of single byte reading.
Re: i2c hangs when reading just one byte
Allright thanks for reply. I would definitely expect some note with big red exclamation mark in documentation. This issue is in my opinion too serious to be left undocumented. What about devices expecting only 1 byte read? Where is the problem anyway? In reference manual I clearly see the sequence for 1 byte reading.