2017-08-16 12:39 PM
Hello,
I'm working with STM32F0 and CAN communication, sometimes the CAN peripheral stops, doesn't send or receive messages.
In the past I asked the same issue and the answer was that it could be the HAL_LOCK funtion and it will be fix in the next revision. My version of stm32f0xx_hal_can.c is * @version V1.4.0, and now I've updated to V1.8, but the problem still happens.
Has anyone experienced this problem? How can I fix it?
Thanks.
#can #busy #stm322017-08-16 01:00 PM
So is it due to the software lock/mutex? or not?
Do the CAN peripheral registers look normal, or are they flagging errors, or stuffed FIFOs?
>>How can I fix it?
The entire library is provided in source form, dig into it a little, if it is a lock issue, check that you and the library properly bracket the usages, and there are no return paths that fail to release it.
2017-08-16 03:15 PM
Thanks for reply Clive,
So is it due to the software lock/mutex? or not?No, is in normal operation.
Do the CAN peripheral registers look normal, or are they flagging errors, or stuffed FIFOs?I have a CAN analyser and osciloscope plugged in and doesn't show any error. How can I check if the FIFOs are stuffed?
Debbuging the mcu, the error returned in the function HAL_CAN_Receive_IT is HAL_CAN_STATE_BUSY_RX0, and stay there forever...
2017-08-16 03:23 PM
>>I have a CAN analyser and osciloscope plugged in and doesn't show any error.
Ok, but that's a bit external facing, the software is likely reflecting an internal state, and you'll need to look within the part rather than without.
>>How can I check if the FIFOs are stuffed?
You would need to inspect the internal CAN peripheral registers more directly, the Reference Manual describes the bulk of these, but is a bit opaque due to ST using third-party IP for the bxCAN implementation.
I'd probably use the printf() method to dump internal state, but a peripheral view in the debugger might also provide some insight at the expense of being a bit invasive.
2017-08-16 03:28 PM
Start by inspecting these registers
CAN1->CAN_MSR
CAN1->CAN_TSR
CAN1->CAN_RF0R
CAN1->CAN_RF1R
Make sure the interrupt and callback functions are completing quickly and not blocking, or missing packets.
2017-08-16 05:34 PM
You could set the ABOM bit for a quick and dirty test and see whether that resolves it.
(Automatic bus off management -> auto restart in case of bus failure).
2017-08-17 06:47 AM
I've checked this register when the can frame is ok and not, and the difference was basically in the CAN_IER register:
frame ok: CAN_IER = 1000111100000010
frame nok: CAN_IER = 1000111100000000
FMPIE0: No interrupt generated when state of FMP[1:0] bits are not 00b.
2017-08-17 06:59 AM
Thanks for help Valentin,
I will set ABOM bit and verify if the problem continues.
Something that is strange is if I use the function if (HAL_CAN_Transmit(&CanHandle, CANTIMEOUT) != HAL_OK) to send can messages sometimes I get problems to send, so I changed to if (HAL_CAN_Transmit_IT(&CanHandle) != HAL_OK). With this I haven't problems anymore, but the receive one continues.
Below is my code basically:
void CAN_Init(unsigned long baudrate)
{ /* Enable CAN module */ __HAL_RCC_CAN1_CLK_ENABLE();/* if we have a wrong baudrate value */
if((baudrate!=CAN250KBPS) || (baudrate!=CAN1000KBPS)) baudrate=CAN250KBPS; CAN_FilterConfTypeDef sFilterConfig; static CanTxMsgTypeDef TxMessage; static CanRxMsgTypeDef RxMessage;/* How to calculate Quantum time */
/* CAN_BitRate = CAN_CLK / (CAN_Prescaler * (CAN_SJW + CAN_BS1 + CAN_BS2)) */ /* 250kbps = 48MHz / ( 12 * ( 1 + 7 + 8 )) */ /* 1000kbps = 48MHz / ( 3 * ( 1 + 7 + 8 )) */ /*♯♯-1- Configure the CAN peripheral ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/ CanHandle.Instance = CAN; CanHandle.pTxMsg = &TxMessage; CanHandle.pRxMsg = &RxMessage; CanHandle.Init.TTCM = DISABLE; CanHandle.Init.ABOM = DISABLE; CanHandle.Init.AWUM = DISABLE; CanHandle.Init.NART = DISABLE; CanHandle.Init.RFLM = DISABLE; CanHandle.Init.TXFP = ENABLE; CanHandle.Init.Mode = CAN_MODE_NORMAL; CanHandle.Init.SJW = CAN_SJW_1TQ; CanHandle.Init.BS1 = CAN_BS1_7TQ; CanHandle.Init.BS2 = CAN_BS2_8TQ; CanHandle.Init.Prescaler = baudrate;if (HAL_CAN_Init(&CanHandle) != HAL_OK)
{ /* Initiliazation Error */ Error_Handler(); }/*♯♯-2- Configure the CAN Filter ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/
sFilterConfig.FilterNumber = 0; sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; sFilterConfig.FilterIdHigh = 0x0000; sFilterConfig.FilterIdLow = 0x0000; sFilterConfig.FilterMaskIdHigh = 0x0000; sFilterConfig.FilterMaskIdLow = 0x0000; sFilterConfig.FilterFIFOAssignment = 0; sFilterConfig.FilterActivation = ENABLE; sFilterConfig.BankNumber = 14;if (HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig) != HAL_OK)
{ /* Filter configuration Error */ Error_Handler(); }/*♯♯-3- Configure Transmission process ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/
CanHandle.pTxMsg->StdId = 0x321; CanHandle.pTxMsg->ExtId = 0x01; CanHandle.pTxMsg->RTR = CAN_RTR_DATA; CanHandle.pTxMsg->IDE = CAN_ID_EXT; CanHandle.pTxMsg->DLC = 8; /*♯♯-3- Configure the NVIC ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/ /* NVIC configuration for CAN1 Reception complete interrupt */ HAL_NVIC_SetPriority(CANx_RX_IRQn, 1, 0); HAL_NVIC_EnableIRQ(CANx_RX_IRQn); /*♯♯-4- Start the Reception process and enable reception interrupt ♯♯♯♯♯♯♯♯♯*/ if (HAL_CAN_Receive_IT(&CanHandle, CAN_FIFO0) != HAL_OK) { /* Reception Error */ Error_Handler(); }}To transmit:
if (HAL_CAN_Transmit_IT(&CanHandle) != HAL_OK)
{}To receive:
if (HAL_CAN_Receive_IT(CanHandle2, CAN_FIFO0) != HAL_OK)
{}
2017-08-17 07:44 AM
You could set the ABOM bit for a quick and dirty test and see whether that resolves it.
(Automatic bus off management -> auto restart in case of bus failure).
I've tested with ABOM enabled but the problem continues. The receive process stops receive messages. It seems like not a CAN bus problem, but something in the firmware/interruption.
2017-08-17 12:41 PM
Any other idea? Thanks