Page 1 of 1

I2C slave-RX plus master transmit = LOCKED

Posted: Tue Feb 24, 2015 6:30 pm
by chibby314
Hi!

I'm using the i2c-slave patch from http://forum.chibios.org/phpbb/viewtopic.php?f=2&t=1502&start=40#p18502 thread on the STM32F4 with ChibiOS 3.

Slave-RX works so far.
Only sometimes i get a problem when sending, and the other master supposedly sends at the same time (?).

I call i2cMasterTransmitTimeout(..) wich calls i2c_lld_master_transmit_timeout(..). The Function returns with MSG_TIMEOUT.
now the following code is called:

Code: Select all

if (rdymsg == MSG_TIMEOUT)
  i2cp->state = I2C_LOCKED
else
  i2cp->state = I2C_READY;

which keeps me in a locked state.

How to recover from such an error? After the state is I2C_LOCKED nothing ever will reset it again!!
The I2C registers MSL (master mode), BUSY and TRA (transmitter mode) are SET!

Best,
Peter

Re: I2C slave-RX plus master transmit = LOCKED

Posted: Tue Feb 24, 2015 9:50 pm
by steved
If you're using both master and slave modes on the same port, I guess that counts as 'multimaster' mode - there may well be special actions you need to take to gain control of the bus before acting as a master - not something I've looked in to. May also be some clues in genosensor's repository.

I've had no problem using the code with two I2C ports active, one in master and one in slave mode; the slave port was pretty busy.

Re: I2C slave-RX plus master transmit = LOCKED

Posted: Wed Feb 25, 2015 12:01 am
by chibby314
Besides some "special actions" i'd have to take (?) .. How can it be, that the library locks itself out if an error happens??
Nothing can lift that I2C_LOCKED state! I can't even de-init the driver, because of an assertion on that state.

The mentioned git repo at https://github.com/brentr/ChibiOS-RT/tree/esp3g uses the same code - i couldn't make out any differences on the first look.
Slave mode on it's own works flawlessly. But it must be possible to act both, as a receiver and a transmitter on a multimaster-bus!

Best,
Peter

Re: I2C slave-RX plus master transmit = LOCKED

Posted: Sun Jan 31, 2016 9:05 am
by genosensor
Sorry, I just found this query...
One calls i2cStart() to recover from an I2C_TIMEOUT error in master mode.
Here's the relevant code fragment from a working multi-master application:

Code: Select all

    err = i2cMasterTransmitTimeout(&elfI2C, replyDstAdr,
            txBody, replyLen, crcBuf, 1, replyTimeout);
    switch (err) {
      case I2C_OK:
        if (*crcBuf == CRC8ok)
          return err;
        break;
      case I2C_ERROR:
        dbgPrint("I2C reply to 0x%02x failed, errMask = 0x%02x",
                      replyDstAdr, i2cGetErrors(&elfI2C));
        chThdSleepMilliseconds(2);
        break;
      case I2C_TIMEOUT:
        dbgPrint("I2C reply to 0x%02x timed-out", replyDstAdr);
        i2cStart(&elfI2C, &slaveI2Cconfig);   //unlock the driver!!
        break;
      default:
        dbgPrint("i2cMasterTransmit returned unknown error code:  %d", err);
        i2cStart(&elfI2C, &slaveI2Cconfig);  //restart the driver!!

Re: I2C slave-RX plus master transmit = LOCKED

Posted: Mon Jun 12, 2017 9:44 am
by crispus
I have same problem with F2 board (Nucleo-F207ZG) (ChibiOS - the current github master branch) and a BM085 sensor. Sometimes I receive a timeout.
Is this the recommended approach to recover from the locked state?

genosensor wrote:

Code: Select all

    err = i2cMasterTransmitTimeout(&elfI2C, replyDstAdr,
            txBody, replyLen, crcBuf, 1, replyTimeout);
    switch (err) {
    ...
      case I2C_TIMEOUT:
        dbgPrint("I2C reply to 0x%02x timed-out", replyDstAdr);
        i2cStart(&elfI2C, &slaveI2Cconfig);   //unlock the driver!!
        break;
    ...