2019-02-13 02:49 AM
typedef enum
{
HAL_OK = 0x00U,
HAL_ERROR = 0x01U,
HAL_BUSY = 0x02U,
HAL_TIMEOUT = 0x03U,
} HAL_StatusTypeDef;
This is the actual defintion of the HAL_StatusTypeDef. Other status codes are defined in other modules headers like this:
#define HAL_CAN_ERROR_TIMEOUT (0x00020000U)
In System Workbench, using GCC, this leads to the following warning, as soon as you check against that specific ERROR:
...Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_can.h:269:39: warning: large integer implicitly truncated to unsigned type [-Woverflow]
At first, it is only a warning but I would expect, that it will lead to wired problems, if you try to handle errors correctly.
I suggest, simply adding a dummy value to the enum typedef to force GCC to choose an integer type of the appropriate size like this in stm32f4xx_hal_def.h:
typedef enum
{
HAL_OK = 0x00U,
HAL_ERROR = 0x01U,
HAL_BUSY = 0x02U,
HAL_TIMEOUT = 0x03U,
HAL_STATUS_MAX = 0xFFFFFFFFU
} HAL_StatusTypeDef;
2019-02-13 04:32 AM
stm32f4xx_hal_can.h:269
typedef struct __CAN_HandleTypeDef
{
CAN_TypeDef *Instance; /*!< Register base address */
CAN_InitTypeDef Init; /*!< CAN required parameters */
__IO HAL_CAN_StateTypeDef State; /*!< CAN communication state */
__IO uint32_t ErrorCode; /*!< CAN Error code.
This is not HAL_StatusTypeDef
Have you tried
#define HAL_CAN_ERROR_TIMEOUT ((uint32_t) (0x00020000U))
to check the compiler warning?
2019-02-13 04:37 AM
HAL_StatusTypeDef BSP_CAN_ReceiveMessage(
CAN_RxHeaderTypeDef* canHeader, uint8_t* canData, uint32_t timeout)
{
HAL_StatusTypeDef canStatus = HAL_ERROR;
uint32_t startTime = HAL_GetTick(), endTime;
endTime = startTime + timeout;
while(HAL_GetTick() < endTime) {
canStatus = HAL_CAN_GetRxMessage(
&hcan1, CAN_RX_FIFO0, canHeader, canData);
if(canStatus == HAL_OK)
return canStatus;
}
return canStatus;
}
//.... and here comes the problematic part...
do {
status = BSP_CAN_ReceiveMessage(&header, &data, 1000);
} while((status == HAL_CAN_ERROR_TIMEOUT) && (++i < 10));
//....
After digging a bit around, I realized, that HAL_CAN_GetRxMessage() is never assigning the timeout error constant to the Status type :(