cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F030/103 I2C slave not returning to listen state (0x28) after transaction

debugging
Lead

Edits: see updates below for listen state

Generated code using the latest CubeIDE . I2C_GetMode is always 00h. Under which conditions does this mode value change to "slave" and how to move it into slave mode ?

    mode = HAL_I2C_GetMode (&hi2c1);

    // HAL I2C Mode value coding follow below described bitmap :

    // b7 (not used) x : Should be set to 0

    // b6 0 : None 1 : Memory (HAL I2C communication is in Memory Mode)

    // b5 0 : None 1 : Slave (HAL I2C communication is in Slave Mode)

    // b4 0 : None 1 : Master (HAL I2C communication is in Master Mode)

    // b3-b2-b1-b0 (not used) xxxx : Should be set to 0000

HAL_I2C_GetState (&hi2c1); returns 0x28 (Listening and IP initialized and ready to use) A call to HAL_I2C_Slave_Receive_IT returns 0x02 (busy) - not sure how to clear this ?

Reference: UM1785

1 ACCEPTED SOLUTION

Accepted Solutions
5 REPLIES 5
KnarfB
Principal III

Many thanks, I finally figured out that mode changed from 0x00 to x020 upon the Listencallback. (here is little to non documentation about this) I am trying to use non sequential transfers. I got so far to have reliable repeated transfer from the master to the slave working with IT (non sequential) but only when calling HAL_I2C_Slave_Receive_IT at the end of HAL_I2C_SlaveRxCpltCallback. However, the problem now is that the I2C interface does not return to listen state (0x28) after HAL_I2C_SlaveRxCpltCallback even adding HAL_I2C_EnableListen_IT(hi2c) at the end of HAL_I2C_SlaveRxCpltCallback but stays in state 0x20.The master may switch from a write to a read, so the slave must be able to return to listen mode to get the direction of the next transaction. I tested this on an STM32F103 as well.

debugging
Lead

0690X00000BwZFVQA3.png0690X00000BwZFQQA3.png0690X00000BwZFLQA3.pngAfter 4 days debugging no progress, it seems the problem still remains that the state never returns to listen state after HAL_I2C_SlaveRxCpltCallback but remains in 0x20 after 0x22 which occurs after 0x28 . After using a logic analyzer, the first transactions on the wire level is ACK and the correct data is received. Since the state does not return to listen, there is no AddrrCallback event generated on the 2nd transfer and thus no data of the 2nd transaction is received but the controller still ACKS the transfer and the data. The 3rd transaction is NACK'ed. All transaction from the master are the same (loop) from a RPI3, Pull-ups are on the SCL/SDA lines. The result as above is always the same.

The intention is to do all transactions using IT events and nothing in the main loop in contrast to what done in all the STM32 Cube samples. Perhaps my understanding of the HAL functions is wrong or this is not possible ? Adding HAL_I2C_EnableListen_IT(hi2c); in any of the callback does not fix this. Enabling or disabling stretch mode make no differences. Also changed from 100Khz to 50Khz clock, result is still the same. There ia delay between the transfers of the master (> 500msec). I've used many different I2C devices in this same RPI3 without any issues.

Code flow :

1.in main loop - start Listen

 __HAL_I2C_ENABLE_IT(&hi2c1, I2C_IT_EVT | I2C_IT_ERR );

 HAL_I2C_EnableListen_IT (&hi2c1);

2. in HAL_I2C_AddrCallback check the address and find the direction requested by the master

3. In HAL_I2C_ListenCpltCallback , if the direction is TRANSMIT, call HAL_I2C_Slave_Receive_IT with the buffer and length (1 here)

4.In HAL_I2C_SlaveRxCpltCallback save the received data (in this case 1 byte)

> This all goes fine for the 1st transaction, however from here HAL_I2C_GetState (&hi2c1) is always 0x20.

Device ID   : 0x0410 (STM32F10xxx Medium-density)

 There are many errata's for F series and I2C. but none seem related to this. Is the STM32 I2C slave functionality and HAL still buggish ?

https://github.com/stm32duino/Arduino_Core_STM32/issues/463

http://www.chibios.com/forum/viewtopic.php?t=560

https://electronics.stackexchange.com/questions/272427/stm32-busy-flag-is-set-after-i2c-initialization

https://www.st.com/content/ccc/resource/technical/document/errata_sheet/f5/50/c9/46/56/db/4a/f6/CD00197763.pdf/files/CD00197763.pdf/jcr:content/translations/en.CD00197763.pdf

What was supposed to be a "quick" project to use an STM32 has a I2C slave is becoming a major challenge.

It was the CLK stretching from the PI that caused some of the problems. After disabling this on the F103, disabling interrupts and all callbacks I could send thousands of 1, 2 more than 20 bytes (or more) transaction from the PI to the F103 and all we're ACKed correctly so the NACK problem is resolved and trandaction on the line flow correctly. After putting back the callbacks and enabling the EV interrupts, now weird problem: HAL_I2C_SlaveRxCpltCallback is only called at every even transaction (2,4,6,8) and this iswhere the data is saved, and HAL_I2C_AddrCallback+ HAL_I2C_ListenCpltCallback at every odd (1,3,5..) ttranasction, no matter how many bytes the master sends or specified in HAL_I2C_Slave_Receive_IT. Thus only half of the data is received from the master on the slave. The master however sees all transactions being ACK'ed correctly (on a logic analyzer) . Upon the odd transaction the state change from 0x28 to 0x22 (instead of going back to 28) and at the even from 0x22 to 0x28. So there is something funny in the software. It's strange that there is no sample code from ST using the HAL with interrupts using the callbacks. (is I2C IT perhaps just broken ?) This is the 5th day and now close to giving up to get my life back. Changed the speed on master and slave to 20Khz and no effect, changed pull up to several different values (and none), also has no effect

debugging
Lead

CLOSED - Thanks to knarfB for the code snippets