2020-07-08 06:09 AM
Hardware: STM32MP157C-DK2, VL6180 breakout from Sparkfun
Software: CubeMX IDE (1.3.0), buildroot (following the guide from Bootlin here)
I'm trying to use the M4 core to communicate with an I2C sensor. I successfully talked with the sensor on the Linux side so I'm confident the wiring and hardware is good.
I edited the DTS to enable the m4_i2c5 per the example provided by ST.
&m4_i2c5 {
pinctrl-names = "rproc_default";
pinctrl-0 = <&i2c5_pins_a>;
status = "okay";
};
I've also tried many variations of the following, with and without pinctrl statements:
&i2c5 {
status = "disabled";
};
&m4_i2c5 {
status = "okay";
};
From CubeMX IDE:
Main initialization and while(1):
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_I2C5_Init();
/* USER CODE BEGIN 2 */
gpio_init_structure.Pin = GPIO_PIN_7 ;
gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP;
gpio_init_structure.Pull = GPIO_PULLUP;
gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOH, &gpio_init_structure);
HAL_GPIO_WritePin(GPIOH,GPIO_PIN_7,GPIO_PIN_SET);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_Delay(1000);
HAL_GPIO_TogglePin(GPIOH, GPIO_PIN_7);
scan_i2c(&hi2c5, i2c_addresses);
}
/* USER CODE END 3 */
}
I2C initialization code generated by CubeMX:
static void MX_I2C5_Init(void)
{
/* USER CODE BEGIN I2C5_Init 0 */
/* USER CODE END I2C5_Init 0 */
/* USER CODE BEGIN I2C5_Init 1 */
/* USER CODE END I2C5_Init 1 */
hi2c5.Instance = I2C5;
hi2c5.Init.Timing = 0x40505874;
hi2c5.Init.OwnAddress1 = 0;
hi2c5.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c5.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c5.Init.OwnAddress2 = 0;
hi2c5.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c5.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c5.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c5) != HAL_OK)
{
Error_Handler();
}
/** Configure Analogue filter
*/
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c5, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
Error_Handler();
}
/** Configure Digital filter
*/
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c5, 0) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN I2C5_Init 2 */
/* USER CODE END I2C5_Init 2 */
}
Function scanning for I2C devices (confirmed working with F0 Nucleo board):
void scan_i2c(I2C_HandleTypeDef *hi2c, uint8_t * addr)
{
uint8_t t_count=0;
for (int i=1; i<128; i++)
{
HAL_StatusTypeDef result = HAL_I2C_IsDeviceReady(hi2c, (uint16_t)(i<<1), 2, 2);
if (result == HAL_OK){
addr[t_count] = i;
t_count++;
}
}
}
Here is the ...IsDeviceReady()chunk that I timeout on:
HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)
{
uint32_t tickstart;
__IO uint32_t I2C_Trials = 0UL;
FlagStatus tmp1;
FlagStatus tmp2;
if (hi2c->State == HAL_I2C_STATE_READY)
{
if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
{
return HAL_BUSY;
}
/* Process Locked */
__HAL_LOCK(hi2c);
hi2c->State = HAL_I2C_STATE_BUSY;
hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
do
{
/* Generate Start */
hi2c->Instance->CR2 = I2C_GENERATE_START(hi2c->Init.AddressingMode, DevAddress);
/* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
/* Wait until STOPF flag is set or a NACK flag is set*/
tickstart = HAL_GetTick();
tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF);
tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF);
while ((tmp1 == RESET) && (tmp2 == RESET))
{
if (Timeout != HAL_MAX_DELAY)
{
if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
{
/* Update I2C state */
hi2c->State = HAL_I2C_STATE_READY;
/* Update I2C error code */
hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT;
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_ERROR;
}
}
Any suggestions would be appreciated. From trying to get LD7 to blink I see that CubeMX is not taking care of all initialization. Could I need to do some manual initialization of the I2C5 peripheral?
Thank you
Solved! Go to Solution.
2020-07-08 06:44 PM
Do clocks get enabled and pins initialized correctly in HAL_I2C_MspInit?
A timeout could mean the SCL line is being held low. Can you verify the bus is free?
2020-07-08 06:44 PM
Do clocks get enabled and pins initialized correctly in HAL_I2C_MspInit?
A timeout could mean the SCL line is being held low. Can you verify the bus is free?
2020-07-09 04:40 AM
Solved.
The problem was that CubeMX chose A1/Z1 for I2C5, whereas the pins I'm actually using are A11/A12. After remapping the pins in CubeMX I can see the sensor on the I2C bus. I was thinking that the A7 core was taking care of pin selection because in the DTS I called out certain pins. Apparently that is not the case.
Thanks for the response. Chalk up another win for following basic directions :)