title: STM32F4 as I2C Slave. Why "void I2C1_ER_IRQHandler(void)" is executed after "HAL_I2C_Slave_Transmit_DMA"?
body: <p>I am using I2C bus as SLAVE mode in a STM32F411RE. The master is an arduino board.</p>
  
  <p>The configuration is working well because I see thougth master serial (arduino) and STstudio (STM32F411) that all the frames are OK and thrue oscilloscope. </p>
  
  <p>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 next link:</p>
  
  <p><a href="https://drive.google.com/file/d/1-W5Z2nsvLNj6PE1TT9eDCDdYvFpnis8g/view?usp=sharing" rel="nofollow noreferrer">https://drive.google.com/file/d/1-W5Z2nsvLNj6PE1TT9eDCDdYvFpnis8g/view?usp=sharing</a>
  <a href="https://drive.google.com/file/d/14JkeAw2If3v0A71V9-KQasH9rK3PRm3H/view?usp=sharing" rel="nofollow noreferrer">https://drive.google.com/file/d/14JkeAw2If3v0A71V9-KQasH9rK3PRm3H/view?usp=sharing</a>
  <a href="https://drive.google.com/file/d/1Te2F8aNnvkqUSnfRK5UOO-qKabLXXv1D/view?usp=sharing" rel="nofollow noreferrer">https://drive.google.com/file/d/1Te2F8aNnvkqUSnfRK5UOO-qKabLXXv1D/view?usp=sharing</a> </p>
  
  <p>you can download 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</p>
  
  <p>The SLAVE main function and calls are as follows:</p>
  
  <pre><code>#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(&amp;hi2c1, (uint8_t *)aRxBuffer, BUFFERSIZE_RX) != HAL_OK)
      {
          Error_Handler();
      }
      while (1)
      {}
  }
  
  void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c)
  {
      if(HAL_I2C_GetState(&amp;hi2c1) == HAL_I2C_STATE_READY)
      {
          if(HAL_I2C_Slave_Receive_DMA(&amp;hi2c1, (uint8_t *)aRxBuffer, BUFFERSIZE_RX) != HAL_OK)
          {
              Error_Handler();
          }
      }
  }
  
  void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)      
  {
      if(HAL_I2C_GetState(&amp;hi2c1) == HAL_I2C_STATE_READY)
      {
          if(HAL_I2C_Slave_Transmit_DMA(&amp;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(&amp;hi2c1);
   HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_2);
  }
  </code></pre>
  
  <p>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.</p>
  
  <p>The Arduino Master only sends the following functions:</p>
  
  <pre><code>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…     
  }
  </code></pre>
  
  <p>I have tested I2C in interruption mode and the same thing happens… communications works but always the I2C1_ER_IRQHandler is called.</p>
  
  <p>I am completely lost, any help or comment are really appreciate!!!</p>
  
  <p>Sorry for the long post.</p>
  
  <p>P.D. HAL_I2C_ErrorCallback never called, so i suppose that it is OK.</p>
  
  <p>Best regards.</p>
  
  <p>Alejandro</p>
  
  <p>PD2: SPI GPIO and DMA configuration:</p>
  
  <pre><code>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 &lt;&lt; 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(&amp;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-&gt;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, &amp;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(&amp;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(&amp;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);
    }
  }
  </code></pre>