Skip to main content
DFeng.2
Associate
September 14, 2024
Question

STM32WB55CG I2C MASTER COMMUNICATION FAILURE

  • September 14, 2024
  • 1 reply
  • 660 views

 

Hi,

I'm trying to read battery information from a BMS chip (I2C slave) via I2C.  And I also tried to capture the clock signal on SCL with scope but it failed.  This chip is already used in our other project with another MCU.  This is my first time to use STM32WB55CG. Could you help me with the issue, please?

Here's my screenshot of I2C register.

I2C_Registers.PNG

Here's my source code for I2C.

static void MX_I2C_Init(void)
{
    hi2c1.Instance = I2C1;
    //hi2c1.Init.Timing = 0x00000E14;
    hi2c1.Init.Timing = 0x00707CBB;   // 100kHz
    hi2c1.Init.OwnAddress1 = 0;
    hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
    hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
    hi2c1.Init.OwnAddress2 = 0;
    hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
    hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
    hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_ENABLE;
    if (HAL_I2C_Init(&hi2c1) != HAL_OK)
    {
        Error_Handler();
    }
 
    /** Configure Analogue filter
    */
    if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
    {
        Error_Handler();
    }
 
    /** Configure Digital filter
    */
    if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0x0) != HAL_OK)
    {
        Error_Handler();
    }
 
    /** I2C Enable Fast Mode Plus
    */
    //HAL_I2CEx_EnableFastModePlus(I2C_FASTMODEPLUS_I2C1);
}
 
 
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
    GPIO_InitTypeDef gpio_init_struct = {0};
 
    if (hi2c->Instance == I2C1)
    {
        RCC_PeriphCLKInitTypeDef  RCC_PeriphCLKInitStruct;
  
        /*##-1- Configure the I2C clock source. The clock is derived from the SYSCLK #*/
        RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2C1;
        RCC_PeriphCLKInitStruct.I2c1ClockSelection = RCC_I2C1CLKSOURCE_SYSCLK;
        HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct);
 
        __HAL_RCC_GPIOA_CLK_ENABLE();
        /**I2C1 GPIO Configuration
        PA9     ------> I2C1_SCL
        PA10    ------> I2C1_SDA
        */
        gpio_init_struct.Pin = GPIO_PIN_9 | GPIO_PIN_10;
        gpio_init_struct.Mode = GPIO_MODE_AF_OD;
        gpio_init_struct.Pull = GPIO_PULLUP;
        gpio_init_struct.Speed = GPIO_SPEED_FREQ_LOW;
        gpio_init_struct.Alternate = GPIO_AF4_I2C1;
        HAL_GPIO_Init(GPIOA, &gpio_init_struct);
 
        /* Peripheral clock enable */
        __HAL_RCC_I2C1_CLK_ENABLE();
 
        /* I2C1 DMA Init */
        /* I2C1_TX Init */
        hdma_i2c1_tx.Instance = DMA1_Channel1;
        hdma_i2c1_tx.Init.Request = DMA_REQUEST_I2C1_TX;
        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_LOW;
        if (HAL_DMA_Init(&hdma_i2c1_tx) != HAL_OK)
        {
            Error_Handler();
        }
        __HAL_LINKDMA(hi2c, hdmatx, hdma_i2c1_tx);
 
        /* I2C1_RX Init */
        hdma_i2c1_rx.Instance = DMA1_Channel2;
        hdma_i2c1_rx.Init.Request = DMA_REQUEST_I2C1_RX;
        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_HIGH;
        if (HAL_DMA_Init(&hdma_i2c1_rx) != HAL_OK)
        {
            Error_Handler();
        }
        __HAL_LINKDMA(hi2c, hdmarx, hdma_i2c1_rx);
 
        /* I2C1 interrupt Init */
        HAL_NVIC_SetPriority(I2C1_EV_IRQn, 0, 0);
        HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);
        HAL_NVIC_SetPriority(I2C1_ER_IRQn, 0, 0);
        HAL_NVIC_EnableIRQ(I2C1_ER_IRQn);
    }
}
 
/**
  * @brief This function handles DMA1 channel1 global interrupt.
  */
void DMA1_Channel1_IRQHandler(void)
{
    HAL_DMA_IRQHandler(&hdma_i2c1_tx);
}
 
/**
  * @brief This function handles DMA1 channel2 global interrupt.
  */
void DMA1_Channel2_IRQHandler(void)
{
    HAL_DMA_IRQHandler(&hdma_i2c1_rx);
}
 
static bool XXXXXX_Read_Incremental(uint8_t cmd, uint8_t *pData, uint8_t len)
{
    bool ret = false;
 
    do
    {
        //if (HAL_I2C_Master_Transmit_DMA(&hi2c1, (uint16_t)I2C_ADDRESS_WR, &cmd, 1) != HAL_OK)
        if (HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)I2C_ADDRESS_WR, &cmd, 1, cI2C_TRANSFER_TIMEOUT) != HAL_OK)
        {
            Error_Handler();
            break;
        }
        /*##- Wait for the end of the transfer #################################*/  
        while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY);
 
        //if (HAL_I2C_Master_Receive_DMA(&hi2c1, (uint16_t)I2C_ADDRESS_RD, (uint8_t *)pData, len) != HAL_OK)
        if (HAL_I2C_Master_Receive(&hi2c1, (uint16_t)I2C_ADDRESS_RD, (uint8_t *)pData, len, cI2C_TRANSFER_TIMEOUT) != HAL_OK)
        {
            Error_Handler();
            break;
        }
 
        /*##- Wait for the end of the transfer #################################*/  
        while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY);
 
ret = true;
    } while(0);
 
    return ret;
}
 
 
 
 

1 reply

STTwo-32
Technical Moderator
September 26, 2024

Hello @DFeng.2 

For the Implementation of the I2C on the STM32WB55CG, you may want to take a look at the examples Here. They should be really helpful. 

Best Regards.

STTwo-32