i2c hangs when reading just one byte

ChibiOS public support forum for all topics not covered by a specific support forum.

Moderators: RoccoMarco, lbednarz, tfAteba

User avatar
barthess
Posts: 861
Joined: Wed Dec 08, 2010 7:55 pm
Been thanked: 7 times

Re: i2c hangs when reading just one byte

Post by barthess »

I have never touch that semaphore by hands. Only I2C driver touches them when I am acquiring/releasing I2C bus from my code.
User avatar
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

Post by Giovanni »

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
User avatar
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

Post by Giovanni »

Also, could you try to enable mutexes and see if there is still the problem?

Giovanni
User avatar
barthess
Posts: 861
Joined: Wed Dec 08, 2010 7:55 pm
Been thanked: 7 times

Re: i2c hangs when reading just one byte

Post by barthess »

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)
User avatar
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

Post by Giovanni »

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
User avatar
barthess
Posts: 861
Joined: Wed Dec 08, 2010 7:55 pm
Been thanked: 7 times

Re: i2c hangs when reading just one byte

Post by barthess »

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?
mabl
Posts: 417
Joined: Tue Dec 21, 2010 10:19 am
Been thanked: 1 time

Re: i2c hangs when reading just one byte

Post by mabl »

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.
User avatar
nosense
Posts: 22
Joined: Mon Oct 08, 2012 7:15 pm

Re: i2c hangs when reading just one byte

Post by nosense »

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

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, &reg_addr, 1, buff, 1);

      chprintf((BaseChannel *)&SD2, "%x\n", buff[0]);
      chThdSleepMilliseconds(333);
   }
}
User avatar
barthess
Posts: 861
Joined: Wed Dec 08, 2010 7:55 pm
Been thanked: 7 times

Re: i2c hangs when reading just one byte

Post by barthess »

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.
User avatar
nosense
Posts: 22
Joined: Mon Oct 08, 2012 7:15 pm

Re: i2c hangs when reading just one byte

Post by nosense »

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.
Post Reply