cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 I2C HAL slave receive callback not called

Arete sw
Associate II
Posted on July 22, 2017 at 02:47

I find when I make a call to HAL_I2C_Slave_Receive_IT it returns HAL_OK but it never manages to call the callback function, my HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *I2cHandle) implementation.

Using a logic analyzer, I find that the device never acks the address and instead holds the clock line low till the device is reset.

I find if I use the synchronous api, HAL_I2C_Slave_Receive it ACKs and get's data just fine.

Also I am using the latest version of the STM32CubeMX + Keil ARM-MDK.

Any ideas? Thanks

13 REPLIES 13
Posted on July 26, 2017 at 01:47

So here is the result: 

I2C1IRQ_handler --> HAL_I2C_EV_IRQHandler --> I2C_SLAVE_ISR_IT --> I2C_ITAddrCplt: which does nothing because the hi2c's state is 0x22 (HAL_I2C_STATE_BUSY_RX) instead of HAL_I2C_STATE_LISTEN.

I have external pull-ups on SDA and SCL.

Thanks.

Posted on July 27, 2017 at 02:12

I found that in I2C_ITSlaveCplt hi2c->XferCount is not 0 so it sets the error as HAL_I2C_ERROR_AF. The comments around the code says, 'All data are not transferred, so set error code accordingly'. I am not really sure what this means.

Posted on July 27, 2017 at 02:58

It seems like this code in stm32f0xx_hal_i2c.c is the culprit,

starting at line 4058:

  /* All data are not transferred, so set error code accordingly */

if(hi2c->XferCount != 0U)

{

      /* Set ErrorCode corresponding to a Non-Acknowledge */

      hi2c->ErrorCode |= HAL_I2C_ERROR_AF;

}

I believe this check is not working as intended. If i remove it, everything works. It seems like there is an issue checking inequality between the two data types.

Posted on July 27, 2017 at 12:29

This means that not all information you tried to receive received!!

you put at HAL_I2C_Slave_Receive_IT(I2cHandle, (uint8_t *)aRxBuffer, RXBUFFERSIZE);

Means that RXBUFFERSIZE is bigger than the bytes you received , so adjust buffersize according the bytes you want to receive

A different aproximation is to wait for a fixed size 'header' which contains the length of a future transaction.

Also ,dont call transaction functions  inside callbacks , you will face lock situations