AnsweredAssumed Answered

I2C Slave Transmitter Can't Transmit Last Byte Correctly

Question asked by Slimsly on Feb 16, 2016
Hello,

I have been trying to get I2C in STM32F4Discovery Board to work properly but it is proven difficult. The STM32F4Discovery is acting as a slave receiver/ transmitter and STM32F103 Board acting as Master Receiver/Transmitter.

It works well in slave receiver but acting weird in slave transmitter mode.
In the Slave transmitter mode, it is suppose to transfer 2 byte of data. The first Byte is correct but the last byte is wrong as shown in the logic analyzer screen capture.I will be at my code and point me in the right direction. glad if some one look i2c_slavetransmit.jpg
Slave Transmitter Screen Shot (Last Byte Wrong 255 instead of 28)
i2c_slavereceive.jpg
Slave Receiver ok
---------I2C Config-----------------------
void I2C2_Config(void) {
    I2C_InitTypeDef I2C_InitStructure;
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
    
    /* Enable I2C1 reset state */
    RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE);
    /* Release I2C1 from reset state */
    RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, DISABLE);

    I2C_DeInit(I2C2);
  I2C_SoftwareResetCmd(I2C2, ENABLE);
  I2C_SoftwareResetCmd(I2C2, DISABLE);
    
    /* Initialize I2C peripheral */
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
  I2C_InitStructure.I2C_OwnAddress1 = 0xA0;
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStructure.I2C_ClockSpeed = CLOCKSPEED;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_Cmd(I2C2, ENABLE);                  // Enable I2C2        
    I2C_Init(I2C2, &I2C_InitStructure);
        
    I2C_StretchClockCmd(I2C2, ENABLE);
    
    //setup interrupts
    I2C_ITConfig(I2C2, I2C_IT_ERR | I2C_IT_EVT | I2C_IT_BUF, ENABLE);
                                                     
}
-------------------I2C Interrupt Handler-----------------------------------------
static volatile uint8_t MC2TxBuffer[2] = {20, 28};

void I2C2_EV_IRQHandler(void) {
 static uint8_t Tx_Id = 0;
 static uint8_t Rx_Id = 0;    
 volatile uint32_t Event = 0;
 volatile uint32_t temp;
    
 GPIO_WriteBit(GPIOD, GPIO_Pin_12, Bit_SET);    
    
 //Clear AF from slave-transmission end
 if (I2C_GetITStatus(I2C2, I2C_IT_AF) != RESET) {
         I2C_ClearITPendingBit(I2C2, I2C_IT_AF);
  }    
    Event = I2C_GetLastEvent(I2C2 );
    switch (Event) {
        // Slave Receive
        case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:// If ADDR = 1: EV1    
               /* Clear ADDR by reading SR1, then SR2 */
                 temp = I2C2->SR1;
         temp = I2C2->SR2;    
             /* Initialize the transmit/receive counters for next transmission/reception using Interrupt */
             Tx_Id = 0;
         Rx_Id = 0;
                 break;
        
        case I2C_EVENT_SLAVE_BYTE_RECEIVED:    // If RXNE = 1: EV2
                 MC2RxBuffer[Rx_Id++] = I2C2->DR;
                 break;
        
        case I2C_EVENT_SLAVE_STOP_DETECTED:   // If STOPF =1: EV4 (Slave has detected a STOP condition on the bus    
               /* Clear STOPF by reading SR1, then writing CR1 */
                 temp = I2C2->SR1;
                 I2C2->CR1 |= 0x1;
                 break;    
        
        // Slave Transmit
        case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:// If ADDR = 1: EV1    
               /* Clear ADDR by reading SR1, then SR2 */
                 temp = I2C2->SR1;
         temp = I2C2->SR2;    
             /* Initialize the transmit/receive counters for next transmission/reception using Interrupt */
             I2C2->DR = MC2TxBuffer[0];
             GPIO_WriteBit(GPIOD, GPIO_Pin_12, Bit_RESET);        
                 break;    
        
        case I2C_EVENT_SLAVE_BYTE_TRANSMITTED: // If TXNE = 1: EV3_2
                 I2C2->DR = MC2TxBuffer[1];
             break;
    }
    //GPIO_WriteBit(GPIOD, GPIO_Pin_12, Bit_RESET);
}
---------------- I2C MASTER TRANSMIT AND RECEIVE FROM "Release Notes for AN2824 "STM32F10xxx I2C optimized examples" -------------

 I2C_Master_BufferWrite(I2C1, Buffer_Tx1, 2, DMA, 0xA0);    
 I2C_Master_BufferRead(I2C1, Buffer_Tx1, 2, DMA, 0xA0);

Outcomes