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.
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;
}