2019-02-11 05:46 AM
I am stuck with a really weird issue while using time of flight sensor VL53L0x - 200 cm and
VL6180x - 60 cm. I have two st boards, STM32F446 Nucleo and STM32F767 Nucleo. I have written the libraries for both the time of flight sensors on STM32F767 Nucleo. But while i was trying to implement the same library on STM32F446 Nucleo it doesn't work.
While looking for solution i found there is a problem with I2C. In F7 everything is fine and it returns HAL_OK. But in F4 it returns 'HAL_ERROR'. By it I mean this function.
HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
Pastebin link for library files
https://pastebin.com/z15btwTD - vl6180.c
https://pastebin.com/62XYxUVx - vl6180.h
Ofcourse in vl6180.h i have changed #include "stm32f7xx.h" to #include "stm32f4xx.h" while using for STM32F446 Nucleo . And i am using I2C1 in both the boards. But i have tried other I2C's too but they all end up in same problem. Hal library is generated using CubeMx and Attolic True Studio is the IDE.
The same thing is happening for VL53L0X Sensor.
Any suggestion would be really appreciated.
Regards.
2019-02-11 05:54 AM
Scope the SCL to determine/confirm operational speed. Consider using a logic analyzer to confirm I2C bus behaviour and anomalies.
Make sure to fully initialize all fields of I2C structures when configuring across multiple device families.
2019-02-11 06:24 AM
I have initialized both the board in I2C fast mode. 400KHz. Using scope, the operational speed of STM32F7 (Where code is working) is around 320KHz and in STM32F4 (Where code is not working) is around 340KHz.
I2C initialization on STM32F7(Working)
void MX_I2C1_Init(void)
{
hi2c1.Instance = I2C1;
hi2c1.Init.Timing = 0x00501B60;
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_DISABLE;
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, 0) != HAL_OK)
{
Error_Handler();
}
}
I2C initialization on STM32F4(not working)
void MX_I2C1_Init(void)
{
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 400000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
}
}
2019-02-11 07:52 AM
From this particular part of the
HAL_I2C_Master_Transmit()
function returns
HAL_ERROR
if(I2C_MasterRequestWrite(hi2c, DevAddress, Timeout, tickstart) != HAL_OK)
{
if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
{
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
//HAL_GPIO_TogglePin(BLUE_GPIO_Port, BLUE_Pin);
return HAL_ERROR;
}
else
{
/* Process Unlocked */
__HAL_UNLOCK(hi2c);
return HAL_TIMEOUT;
}
}
2019-02-11 08:32 AM
Watch that callbacks occur under interrupt context, if the device is locked consider if other code is inducing a race condition. ie precipitating an interrupt before exiting and unlocking.