Skip to main content
SZank
Associate II
January 18, 2019
Question

I2C slave transmit in interrupt mode

  • January 18, 2019
  • 0 replies
  • 1058 views

Hi all,

I do have a problem with I2C slave transmit mode. Everytime the master (in my case an FTDI FT4222) starts a read access I get the error ACKNOLEDGE FAILURE.

If I just transmit from a PC to the STM32 everything works fine and I receive the correct bytes. I had a look with the debugger.

My sequence for reading is the following

  1. transmit one byte from master to slave, this byte is interpreted as register address
  2. the master initiates a read request by having the RW bit set
  3. Here the STM32 goes into the Error ISR with the above failure

As I interpret the behaviour I think that it is a logical problem and not a problem related to signal integrity because receiving bytes from master is very robust.

In the datasheet I found the following:

0690X000006D9aoQAC.png

So I added use the following source code in case a STOP interrupt is given (just a code snippet):

 // STOPF set (for transmitter and receiver)
 else if(((sr1itflags & I2C_FLAG_STOPF) != RESET) && ((itsources & I2C_IT_EVT) != RESET))
 {
 /* Disable EVT, BUF and ERR interrupt */
 __HAL_I2C_DISABLE_IT(&hi2c2, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR);
 __HAL_I2C_CLEAR_STOPFLAG(&hi2c2);
 /* Disable Acknowledge */
 hi2c2.Instance->CR1 &= ~I2C_CR1_ACK;
 
 // just do the following in case of a receive
 if (hi2c2_ext.MasterTransferDirection == I2C_DIRECTION_TRANSMIT) {
 /* Store Last receive data if any */
 if(__HAL_I2C_GET_FLAG(&hi2c2, I2C_FLAG_BTF) == SET)
 {
 /* Read data from DR */
 receiveBuffer[rxBytePosition] = hi2c2.Instance->DR;
 rxBytePosition++;
 }
 
 /* Store Last receive data if any */
 if(__HAL_I2C_GET_FLAG(&hi2c2, I2C_FLAG_RXNE) == SET)
 {
 /* Read data from DR */
 receiveBuffer[rxBytePosition] = hi2c2.Instance->DR;
 rxBytePosition++;
 }
 
 hi2c2_ext.bytesReceived = rxBytePosition;
 // after each STOP: index for the transmit buffer is resetted
 hi2c2_ext.txIndex = 0;
 rxBytePosition = 0;
 // decode and save the address globally
 i2c_set_rxInfo(receiveBuffer);
 // if the payload size is zero, we just received an address
 // preparation for transmitting information to master
 if (hi2c2_ext.payloadSize == 0) {
 prepare_txBuffer_top();
 }
 // set ready to 1
 hi2c2_ext.m2s_Ready = 1;
 } else {
 // STM32 was in mode receiver => clear AF (userguide page 845 - EV3-2)
 hi2c2.Instance->SR1 &= ~I2C_FLAG_AF;
 }
 }

But without success, the AF is set once again. :(

Furthermore from times to times (for now I ignore the error) I get the following:

0690X000006D9bNQAS.png

The 1/2 is in hexadecimal 0xAB. I assigned 0x55 as slave address. With the one Bit bitshift (7bit address) this is 0xAA and with the read bit set, this is 0xAB. It seems to me the STM32 is sending the first byte (address + RW bit) back to the master.

I really hope anybody does have any hints on this.

Kind regards

Sebastian

This topic has been closed for replies.