1
\$\begingroup\$

I'm trying to interface with NXP device using I2C. I'm initializing it that way

/* I2C3 init function */
static void MX_I2C3_Init(void)
{

    hi2c3.Instance = I2C3;
    hi2c3.Init.ClockSpeed = 100000;
    hi2c3.Init.DutyCycle = I2C_DUTYCYCLE_2;
    hi2c3.Init.OwnAddress1 = 0;
    hi2c3.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
    hi2c3.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
    hi2c3.Init.OwnAddress2 = 0;
    hi2c3.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
    hi2c3.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
    if (HAL_I2C_Init(&hi2c3) != HAL_OK)
    {
      Error_Handler();
    }


}

I'm using DMA RX for I2C.

unsigned int axI2CWriteRead(unsigned char bus_unused_param, unsigned char addr,
                            unsigned char *pTx, unsigned short txLen,
                            unsigned char *pRx, unsigned short *pRxLen)
{
    extern I2C_HandleTypeDef hi2c3;
    bool recv_length = false;
    HAL_StatusTypeDef status;

    *pRxLen = 0;
    memset(pRx, 0, 2);
    uint8_t rxData[255] = {0};

    status = HAL_I2C_Master_Sequential_Transmit_IT(&hi2c3, 0x90, pTx, txLen, I2C_FIRST_FRAME);

    if (status != HAL_OK)
        return I2C_FAILED;

    while (HAL_I2C_GetState(&hi2c3) != HAL_I2C_STATE_READY)
        ;

    readblock = true;
    readblock_length = 0;
    status = HAL_I2C_Master_Sequential_Receive_IT(&hi2c3, 0x90, rxData, 255, I2C_LAST_FRAME);

The problem it gets stuck in that line:

while (HAL_I2C_GetState(&hi2c3) != HAL_I2C_STATE_READY) ;

I have defined the interrupt handelers here

/**
  * @brief This function handles DMA1 stream2 global interrupt.
  */
void DMA1_Stream2_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Stream2_IRQn 0 */

  /* USER CODE END DMA1_Stream2_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_i2c3_rx);
  /* USER CODE BEGIN DMA1_Stream2_IRQn 1 */

  /* USER CODE END DMA1_Stream2_IRQn 1 */
}


    void I2C3_EV_IRQHandler(void)
    {
      /* USER CODE BEGIN I2C3_EV_IRQn 0 */

      /* USER CODE END I2C3_EV_IRQn 0 */
      HAL_I2C_EV_IRQHandler(&hi2c3);
      /* USER CODE BEGIN I2C3_EV_IRQn 1 */

      /* USER CODE END I2C3_EV_IRQn 1 */
    }

    /**
    * @brief This function handles I2C3 error interrupt.
    */
    void I2C3_ER_IRQHandler(void)
    {
      /* USER CODE BEGIN I2C3_ER_IRQn 0 */

      /* USER CODE END I2C3_ER_IRQn 0 */
      HAL_I2C_ER_IRQHandler(&hi2c3);
      /* USER CODE BEGIN I2C3_ER_IRQn 1 */

      /* USER CODE END I2C3_ER_IRQn 1 */
    }

The interrupt request I2C3_EV_IRQHandler is getting fired, but after it the DMA interrupt is not called at all.

\$\endgroup\$
  • \$\begingroup\$ Can you provide us with more details: 1. What device processor is the master what device processor is the slave? 2. Data structure for hi2c3 3. What is the code for HAL_I2C_GetState and related functions? \$\endgroup\$ – SpinlockData May 15 at 17:30
  • \$\begingroup\$ HAL code is function call , after function call,after function call, its very inefficient. If the user had used register access code i could help, because I have had a lot of problems with stm32 i2c in some of their microcontrollers and I have resolved them using DMA. I would say check the registers to see what interrupts are enabled in debug mode. But dont try to run any real i2c code in debug mode, it always gives issues and hangs somewhere, At least in Keil. \$\endgroup\$ – Edwin Fairchild May 15 at 17:41
  • \$\begingroup\$ master is STM32F407, slave is AT71CH secure element. \$\endgroup\$ – andreahmed May 15 at 20:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.