cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 HAL_CAN_Transmit always returns TIMEOUT (HAL_CAN_STATE_TIMEOUT)

Michel Keijzers
Associate III
Posted on October 19, 2017 at 11:11

(note this is my first question on ST community If I can do anything to improve the question, please let me know).

Setup

I am using an STM32F103C8T6 (aka Blue Pill).

With the STM32Cube I set CAN_RX to PB8 and CAN_TX9 to PB9 (these are defaults/nonchangeable).

The generated CAN settings are:

 hcan.Instance = CAN1;
 hcan.Init.Prescaler = 16;
 hcan.Init.Mode = CAN_MODE_NORMAL;
 hcan.Init.SJW = CAN_SJW_1TQ;
 hcan.Init.BS1 = CAN_BS1_4TQ;
 hcan.Init.BS2 = CAN_BS2_5TQ;
 hcan.Init.TTCM = DISABLE;
 hcan.Init.ABOM = DISABLE;
 hcan.Init.AWUM = DISABLE;
 hcan.Init.NART = DISABLE;
 hcan.Init.RFLM = DISABLE;
 hcan.Init.TXFP = DISABLE;�?�?�?�?�?�?�?�?�?�?�?�?

Program

(removed STM HAL generated comments blocks)

 int main(void)
 {
 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();
 
 /* Configure the system clock */
 SystemClock_Config();
 
 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_CAN_Init();
 
 /* USER CODE BEGIN 2 */
 hcan.pRxMsg = &_rxMessage;
 hcan.pTxMsg = &_txMessage;
 
 _sFilterConfig.FilterActivation = ENABLE;
 _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.BankNumber = 14;
 if (HAL_CAN_ConfigFilter(&hcan, &_sFilterConfig) != HAL_OK)
 {
 Error_Handler();
 }
 
 hcan.pTxMsg->StdId = 0x321;
 hcan.pTxMsg->ExtId = 0x01;
 hcan.pTxMsg->RTR = CAN_RTR_DATA;
 hcan.pTxMsg->IDE = CAN_ID_STD;
 hcan.pTxMsg->DLC = 2;
 hcan.pTxMsg->Data[0] = 0;
 while (1)
 {
 hcan.pTxMsg->Data[0]++;
 
 if (HAL_CAN_Transmit(&hcan, 10) != HAL_OK)
 {
 Error_Handler();
 }
 HAL_Delay(1000);
 
 if (HAL_CAN_Receive_IT(&hcan, CAN_FIFO0) != HAL_OK)
 {
 Error_Handler();
 }
 
 }
 }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Loopback mode

When I use loopback mode:

hcan.Init.Mode = CAN_MODE_LOOPBACK

instead of Normal mode, I can transmit and receive messages (and the hcan shows the correct data in the received message).

Problem

However, in Normal mode (as shown in the code fragment above) I always get a timeout in the next command:

if (HAL_CAN_Transmit(&hcan, 10) != HAL_OK)

The function returns: HAL_CAN_STATE_TIMEOUT

All initialization seems to be ok (all functions return HAL_OK).

Analysis

What I tried was:

- Using another STM32: no difference

- Using another transceiver: no difference - Played a bit with the SJW/BS1/BS2 time quantities: no difference - Making sure the time quantities were equal - Playing with different data values and filters: no difference - Checked the output of PB9 (CAN transmit): it seems not to change at all (so this is a problem): no difference - Removing the wire from GPIO PB9 (CAN Tx) to the TX of my CAN transceiver : no difference. - Checking the Transmit is cancelled (which is needed and was an old bug, but has already been fixed by the HAL library I'm using).

Observations

- ESR is 111110000000000001010111, which means LEC[2:0] (see [Reference manual, page 682][1]), is 101 which is Bit dominant error

- BTR is 11101010000000001001111, which means bit 30 LKBM: Loop back Mode (debug) is 1, which is strange because in the setup I assigned CAN_MODE_NORMAL. - Directly after the command, the State is HAL_CAN_STATE_TIMEOUT, the Lock is HAL_UNLOCKED, the ErrorCode is 0.

Questions

1. Why do I get a timeout? I'm having a hard time trying to find more to check what I already did. What bothers me is that the PB9 GPIO does not change, so I'm sure it's a software problem, but since there is no error code (it's 0) and initialization is OK, I'm getting out of clues.

Related question:

2. Am I in loopback mode or not (according to the Setup I put CAN_MODE_NORMAL, but the BTR bit 30: LKBM shows otherwise.

[1]:

http://www.st.com/content/ccc/resource/technical/document/reference_manual/59/b9/ba/7f/11/af/43/d5/CD00171pdf/files/CD00171pdf/jcr:content/translations/en.CD00171pdf

#can #stm32f103 #stm32cube
23 REPLIES 23
Posted on October 23, 2017 at 00:43

Turvey.Clive.002

I found something stupid: my CAN receiver works on 5V and my STM32 is 3.3V, so I added a voltage supply that gives 5V and use that for the CAN transceivers (and connecting all grounds together). But still no difference. I ordered specifically 3.3V CAN transceivers and will try again when they arrive (can take some time).

brucegong
Associate II
Posted on May 02, 2018 at 18:57

stm32f103c8t6 + cubemx的can通信,我�到过和你�其类似的问题,已�解决。我在此记录我的解决过程,希望对你有帮助:

第一个é�?™è¯¯ï¼šç�?¨äº†é»˜è®¤çš„CAN_TXå’ŒCAN_RX。开å�‘æ�¿ä¸Šå·²ç»�将这两个引脚分é…�给了USB接å�£ã€‚而ä¸�?USB上连ç�?µé˜»ç­‰å…ƒä»¶éƒ½å·²ç»�有了,å¤�ç�?¨èµ·æ�¥ä¼šå¾ˆéº»çƒ¦ï¼Œæ‰€ä»¥åº�?该将CAN进行remap,转到PB8å’ŒPB9。(很显然,这一步你已ç»�å�šäº†ï¼‰

第二个é�?™è¯¯ï¼šæˆ‘ç�?¨çš„第一å�—å¼€å�‘æ�¿ï¼ŒPB8å’ŒPB9的两个引脚,ä¾�然没安排å�šäº†å…¶ä»–ç�?¨é€�?。这是我自己没ä»�?细看开å�‘æ�¿åŽŸç�†å›¾çš„å�Žæžœã€‚事已至此,ä¸�å¾—ä¸�æ�¢ä¸€ä¸ªæ›´ç®€æ´�çš„å¼€å�‘æ�¿äº†ã€‚

第三个é�?™è¯¯ï¼šcané…�置的时候,没有开å�¯SCE中断,以å�ŠRX0中断。当然,中é€�?还出现了给CANæ�?¶å�‘器ç�?¨3.3Vä¾›ç�?µçš„低级é�?™è¯¯ã€‚

然�,我就进入了如楼主所�述的状�。

实际上这时候我é�‡åˆ°çš„是第0个é�?™è¯¯ï¼š

使ç�?¨cubeMX,我选择了freeos,开å�¯äº†can+master(PB8+PB9)。ç�?±äºŽæˆ‘需è¦�ç�?¨st-link进行调试,所以SYS分æ�?¯æˆ‘设置为“serial wireâ€�,并选择了TIM4作为定时器时钟æº�。然å�Žç�?±äºŽå…¶ä»–功能的需è¦�,我开å�¯äº†PB3 PB4 PB5 PB6四个GPIO模å¼�â€�?â€�?â€�?â€�?è¿™ç§�é…�置的å�Žæžœå°±æ˜¯SYS分æ�?¯ä¸Šå‡ºçŽ°äº†ä¸€ä¸ªé»„色感å�¹å�·ã€‚

真正解决关é�?®é—®é¢˜çš„步骤,就是å�–消掉PB3 PB4 PB5 PB6的使ç�?¨ï¼ŒæŠŠå®ƒä»¬æ�¢å¤�æˆ�默认的reset状æ€�,SYS上的黄色感å�¹å�·å°±æ¶ˆå¤±äº†ã€‚å†�å¾€å�Žå°±ä¸€åˆ‡æ­£å¸¸äº†ã€‚

Posted on May 03, 2018 at 01:37

did you get this running ?

ABOM should be enabled.

Posted on May 06, 2018 at 19:34

To the above replies(write in Chinese), I made the following clarification: My project was not completely successful. It seems  there is a bug in the HAL library .

Hardware configuration : stm32f103c8t6 processor, using cubeMX generated project, stm32F1 cube version number 1.6.1. Two TJA1050 work as CAN tranceiver.

The test proccedure is: Device A and Device B are interconnected. A initiates the first session and sends the numbers 0 to B. While B received the message, B sends 1 to A, and A sends 2 to B again... and so on.

The test result: A power on first, then ,B power on, and B can receive the message sent by A. B can send a message, debugtrace on B show success, but A can not receive the message

                      If B power on first and then A power on, B will not receive A message. Since the first message was initiated by A, there was no result in this round of testing.

                     

With the same hardware, a simple test program was written using the std library. The test target was exactly the same as above. The test was completely successful.
Posted on May 11, 2018 at 00:45

Make sure the two boards never transmit the same MsgID.

make sure ABOM is enabled

Posted on May 11, 2018 at 15:00

I don't think ABOM = ENABLE is necessary.

I changed the 'ping-pong procedure' ,it works like this:

A send '0' to B

if A received '1',A send '2' to B

or A will send another '0' after few seconds.

Once B received '0',B reply '1' to A.If B received '2',B reply '3' to A ,like 'Ping-Pong test'

Debug trace on B, I can see B received many '0' ,and B try to send '1' to A.HAL_CAN_Transmit_IT orHAL_CAN_Transmit returns OK, but A receive nothing.

I will try your suggestion.But it seems could hardly to be succeed.

======================================

test faild

code in Attach.

readme.txt will tell you how to build and test

________________

Attachments :

Src.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006Hxdq&d=%2Fa%2F0X0000000b0P%2FaWDD42Azorv0fh8l75LjtiEnKTKsTuQoTGhgmTEgkH4&asPdf=false
Posted on May 12, 2018 at 00:07

do you have a scope ?

can you check that both units are transmitting first ?

Posted on May 12, 2018 at 02:16

I have no scope.

I just use debug trace ,set a break point on the send or receive function,and watching the message.

Trace on device B while A is running free    or  trace on device A while B is running free.

The same way ,using std library ,ping-pong test works.

Posted on May 12, 2018 at 06:32

I use a TDS2024, a 4ch color scope, excellent unit.

You need a scope for low level drivers.

Posted on May 12, 2018 at 13:07

ABOM should be enabled

Do you have another CanBus peripheral ?

I purchased a CanDo unit and transmitted every second to get the receiver code running first.

Then I worked on the Tx side.

My receiving code runs under interrupt control, but the transmit code doesn't.