I2C slave timeout problem?

The official pyboard running MicroPython.
This is the reference design and main target board for MicroPython.
You can buy one at the store.
Target audience: Users with a pyboard.
Post Reply
Neil
Posts: 15
Joined: Tue Jul 14, 2015 8:51 pm

I2C slave timeout problem?

Post by Neil » Wed Apr 06, 2016 1:20 pm

Hi All,

I am writing a program that is intended to recieve I2C data from some marine electronic equipment. The intended target for the I2C data is a remote repeater screen, however I have decoded the output and can then use this data for my own purposes.

In general everything works well, I setup the pyboard I2C device as a slave with the correct address and receive the data without problem. However, as I am collating information from a range of devices I am attempting to build more resilience into the system should data from one device not be available. To achieve this I was trying to add a timeout to my I2C receive command so that if the data was not recieved in 250ms (the master device sends new data every 100ms regardless of if there are any listening devices). However, the recv command does not appear to respect the timeout keyword and in fact in my own timing tests it actually timesout after 10000ms and not the 5000ms default.

I guess the questions are,
  • * am I doing something stupid,
    * is this expected behaviour for a slave device?
    * is this not yet implimented?

Neil
Posts: 15
Joined: Tue Jul 14, 2015 8:51 pm

Re: I2C slave timeout problem?

Post by Neil » Wed Apr 06, 2016 1:55 pm

So after some code digging, I think I may have answered my own question to a degree. Thats not to say I understand the answer, or that it is entirely helpful, please excuse the rambling.

From digging in the c code it would appear that there are 2 receive commands that can be called:
from micropython/stmhal/hal/f4/src/stm32f4xx_hal_i2c.c

Code: Select all

HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout)
HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size)
with only the non DMA one using the timeout parameter, the DMA one has a deafult 10s timeout as I found in my code.

These are called from micropython/stmhal/i2c.c

Code: Select all

        if (query_irq() == IRQ_STATE_DISABLED) {
            status = HAL_I2C_Slave_Receive(self->i2c, (uint8_t*)vstr.buf, vstr.len, args[2].u_int);
        } else {
            status = HAL_I2C_Slave_Receive_DMA(self->i2c, (uint8_t*)vstr.buf, vstr.len);
        }
So I tried to force the code into using the first method with the timeout with the following code:

Code: Select all

            irq_state = pyb.disable_irq()
            self.data = self.I2C.recv(self.packet_size, timeout=250)
            pyb.enable_irq(irq_state)
However, this does not result in a timeout after 250ms as expected, it in fact leads to no timeout at all and the pyboard eventually disconnects from the controlling serial connection.

So further questions, is there something wrong with my method of accessing the non DMA I2C recieve command? or if not would a workaround be to create a custom build changing the default DMA timeout from 10000ms to something much shorter? and if I did this would there be other consequences for this decision?

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: I2C slave timeout problem?

Post by pythoncoder » Thu Apr 07, 2016 6:35 am

I'm guessing here but disabling irq's for any significant time is rather drastic: perhaps it cattles the timing mechanism?
Peter Hinch
Index to my micropython libraries.

Neil
Posts: 15
Joined: Tue Jul 14, 2015 8:51 pm

Re: I2C slave timeout problem?

Post by Neil » Thu Apr 07, 2016 8:39 am

As an update I have changed the timeout in the c code and created a custom build, as far as I can see the timeout I changed only affects slave I2C DMA functions.

Code: Select all

#define I2C_TIMEOUT_ADDR_SLAVE    ((uint32_t)250)  /* now 250ms was 10 s  */


everything seems to operate as intended so hopefully will turn out to be an acceptable workaround for my purposes.

Post Reply