I2C slave-RX plus master transmit = LOCKED

Discussions and support about ChibiOS/HAL, the MCU Hardware Abstraction Layer.
Post Reply
chibby314
Posts: 3
Joined: Tue Feb 24, 2015 12:00 am

I2C slave-RX plus master transmit = LOCKED

Post 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
steved
Posts: 834
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 12 times
Been thanked: 138 times

Re: I2C slave-RX plus master transmit = LOCKED

Post 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.
chibby314
Posts: 3
Joined: Tue Feb 24, 2015 12:00 am

Re: I2C slave-RX plus master transmit = LOCKED

Post 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
genosensor
Posts: 65
Joined: Thu Oct 03, 2013 1:06 am
Has thanked: 1 time
Been thanked: 1 time

Re: I2C slave-RX plus master transmit = LOCKED

Post 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!!
crispus
Posts: 24
Joined: Sat Aug 27, 2016 10:14 am
Has thanked: 4 times
Been thanked: 3 times

Re: I2C slave-RX plus master transmit = LOCKED

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