cancel
Showing results for 
Search instead for 
Did you mean: 

I2C slave transmit in interrupt mode

SZank
Associate II

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

0 REPLIES 0