cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 as I2C Slave. Why “void I2C1_ER_IRQHandler(void)�? is executed after “HAL_I2C_Slave_Transmit_DMA�??

de Haro Carbonell
Associate III

I am using I2C bus as SLAVE mode in a STM32F411RE. The master is an arduino board.

The configuration is working well because I see thougth master serial (arduino) and STstudio (STM32F411) that all the frames are OK and thrue oscilloscope.

I noticed that I2C1_ER_IRQHandler function is triggered every time the slave finishes its TX transmission (Master receive that transmision and finishes with NACK and STOP BIT). In the attached pictures, you can see the SDA signal and GPIO PIN 2 which toggles within I2C1_ER_IRQHandler function. ¿could be related to the Slave (stm32) is receiving NACK at the end of thanssmission? see pictures

The SLAVE main function and calls are as follows:

#define BUFFERSIZE_RX 0x03 // Master sends 3 bytes

#define BUFFERSIZE_TX 0x04 //Master is waiting for 4 bytes

uint8_t aRxBuffer[BUFFERSIZE_RX];

uint8_t aTxBuffer[BUFFERSIZE_TX];

int main(void)

{

   …uC INITIALIZATION

   if(HAL_I2C_Slave_Receive_DMA(&hi2c1, (uint8_t *)aRxBuffer, BUFFERSIZE_RX) != HAL_OK)

   {

      Error_Handler();

   }

   while (1)

   {}

}

void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c)

{

   if(HAL_I2C_GetState(&hi2c1) == HAL_I2C_STATE_READY)

   {

      if(HAL_I2C_Slave_Receive_DMA(&hi2c1, (uint8_t *)aRxBuffer, BUFFERSIZE_RX) != HAL_OK)

      {

         Error_Handler();

      }

   }

}

void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)

{

   if(HAL_I2C_GetState(&hi2c1) == HAL_I2C_STATE_READY)

   {

      if(HAL_I2C_Slave_Transmit_DMA(&hi2c1, (uint8_t*)aTxBuffer, BUFFERSIZE_TX)!= HAL_OK)

      {

         Error_Handler();

      }

   }

}

void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)

{

   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET);

}

void I2C1_ER_IRQHandler(void)

{

   HAL_I2C_ER_IRQHandler(&hi2c1);

   HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_2);

}

I2C and DMA configuration is as the STM32Cube_FW_F4_V1.24.0 examples, but if you need them I can send them as well.

The Arduino Master only sends the following functions:

void loop()

{

   Wire.beginTransmission(address);

   Wire.write((uint8_t)M_TX_1);

   Wire.write((uint8_t)M_TX_2);

   Wire.write((uint8_t)M_TX_3);

   Wire.endTransmission();

   delay(1);

   Wire.requestFrom(address, (uint8_t)4);

   M_RX_1 = Wire.read();

   M_RX_2 = Wire.read();

   M_RX_3 = Wire.read();

   M_RX_4 = Wire.read();

   … Serial prints and so on…

}

I have tested I2C in interruption mode and the same thing happens… communications works but always the I2C1_ER_IRQHandler is called.

I am completely lost, any help or comment are really appreciate!!!

Sorry for the long post.

P.D. HAL_I2C_ErrorCallback never called, so i suppose that it is OK.

Best regards.

Alejandro

PD2: SPI GPIO and DMA configuration:

static void MX_I2C1_Init(void)

{

   hi2c1.Instance = I2C1;

   hi2c1.Init.ClockSpeed = 100000;

   //hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;

   hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_16_9; // Modificacion

   hi2c1.Init.OwnAddress1 = SLAVEADDRESS << 1; // Modificacion

   hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;

   hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;

   hi2c1.Init.OwnAddress2 = 0;

   //hi2c1.Init.OwnAddress2 = 0x06; // Modificacion

   hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;

   hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;

   if (HAL_I2C_Init(&hi2c1) != HAL_OK)

   {

      Error_Handler();

   }

}

static void MX_DMA_Init(void)

{

   __HAL_RCC_DMA1_CLK_ENABLE();

   HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 1);

   HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);

   HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 2);

   HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);

}

void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)

{

   GPIO_InitTypeDef GPIO_InitStruct = {0};

   if(hi2c->Instance==I2C1)

   {

   __HAL_RCC_GPIOB_CLK_ENABLE();

   GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;

   GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;

   GPIO_InitStruct.Pull = GPIO_PULLUP;

   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

   GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;

   HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

   __HAL_RCC_I2C1_CLK_ENABLE();

   hdma_i2c1_rx.Instance = DMA1_Stream0;

   hdma_i2c1_rx.Init.Channel = DMA_CHANNEL_1;

   hdma_i2c1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;

   hdma_i2c1_rx.Init.PeriphInc = DMA_PINC_DISABLE;

   hdma_i2c1_rx.Init.MemInc = DMA_MINC_ENABLE;

   hdma_i2c1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;

   hdma_i2c1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;

   hdma_i2c1_rx.Init.Mode = DMA_NORMAL;

   hdma_i2c1_rx.Init.Priority = DMA_PRIORITY_LOW;

   hdma_i2c1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;

   hdma_i2c1_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;

   hdma_i2c1_rx.Init.MemBurst = DMA_MBURST_INC4;

   hdma_i2c1_rx.Init.PeriphBurst = DMA_PBURST_INC4;

   if (HAL_DMA_Init(&hdma_i2c1_rx) != HAL_OK)

   {

      Error_Handler();

   }

   __HAL_LINKDMA(hi2c,hdmarx,hdma_i2c1_rx);

   hdma_i2c1_tx.Instance = DMA1_Stream1;

   hdma_i2c1_tx.Init.Channel = DMA_CHANNEL_0;

   hdma_i2c1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;

   hdma_i2c1_tx.Init.PeriphInc = DMA_PINC_DISABLE;

   hdma_i2c1_tx.Init.MemInc = DMA_MINC_ENABLE;

   hdma_i2c1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;

   hdma_i2c1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;

   hdma_i2c1_tx.Init.Mode = DMA_NORMAL;

   hdma_i2c1_tx.Init.Priority = DMA_PRIORITY_HIGH;

   hdma_i2c1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;

   hdma_i2c1_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;

   hdma_i2c1_tx.Init.MemBurst = DMA_MBURST_INC4;

   hdma_i2c1_tx.Init.PeriphBurst = DMA_PBURST_INC4;

   if (HAL_DMA_Init(&hdma_i2c1_tx) != HAL_OK)

   {

      Error_Handler();

   }

   __HAL_LINKDMA(hi2c,hdmatx,hdma_i2c1_tx);

   HAL_NVIC_SetPriority(I2C1_EV_IRQn, 0, 3);

   HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);

   HAL_NVIC_SetPriority(I2C1_ER_IRQn, 0, 2);

   HAL_NVIC_EnableIRQ(I2C1_ER_IRQn);

   }

}

0 REPLIES 0