AnsweredAssumed Answered

STM32F303K8 CAN Init failure on all modes

Question asked by Troyer.Tyler on Apr 1, 2016
Latest reply on Apr 1, 2016 by Clive One
That's right, the very same acknowledgement error found during calls to

CAN_init(CAN1, &CAN);

is found waiting on the INACK bit to be cleared. And yes, the CAN clocks are turned on. This error is normally attributed to the microcontroller not being connected to an actual BUS where another node can ACK, and where the bx_Can module waits to find 11 successive recessive bits on the bus.

So that's where we have LoopBack mode come in, yes?

Well it turns out this same error happens on ALL modes on the bx_CAN module.
The same is true whether the board is connected to an active, working CAN network I have setup here, or if the thing is in standalone LoopBack mode, or any other mode for that matter.

I figured I would see what the problem is, by printing all the status registers with calls after the timeout, they look like this:

01.printf("\tESR \t\t\t\t= %u\r\n", CAN1->ESR);
02.printf("\tFlags \t\t\t\t= %u\r\n", CAN_GetFlagStatus(CAN1, CAN_FLAG_LEC));
03.printf("\tError Warning \t\t\t= %u\r\n", CAN_GetFlagStatus(CAN1, CAN_FLAG_EWG));
04.printf("\tError Passive \t\t\t= %u\r\n", CAN_GetFlagStatus(CAN1, CAN_FLAG_EPV));
05.printf("\tBus-off \t\t\t= %u\r\n", CAN_GetFlagStatus(CAN1, CAN_FLAG_BOF));
06.printf("\tLast Error Code \t\t= %u\r\n", CAN_GetLastErrorCode(CAN1));
07.printf("\tReceive Error Counter \t\t= %u\r\n", CAN_GetReceiveErrorCounter(CAN1));
08.printf("\tTransmit Error Counter \t\t= %u\r\n%s", CAN_GetLSBTransmitErrorCounter(CAN1), none);
09.printf("\nExecution halted\r\n");

But alas, ALL values printed here return zero. Apparently, there is no error.  :/

I can see that single INACK bit being held high in the debugging mode in Keil's "Peripheral viewer" and all. I'm using Win7, and Keil V5.16a on an STM32F303k8 nucleo-32, with only one option for CAN tx/rx pinouts (PA11/PA12). The standard peripheral library used here is the F3 version 1.2.3

01.#define CAN_TX  GPIO_Pin_12
02.#define CAN_RX  GPIO_Pin_11
03. 
04.uint8_t can_init(void)
05.{
06.    uint8_t status = 0;
07.     
08.    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
09.    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
10.     
11.    GPIO_PinAFConfig(GPIOA, CAN_TX, GPIO_AF_9);
12.    GPIO_PinAFConfig(GPIOA, CAN_RX, GPIO_AF_9);
13.     
14.    GPIO_InitTypeDef GPIO_InitStruct;
15.    GPIO_InitStruct.GPIO_Pin = CAN_TX|CAN_RX;
16.    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
17.    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
18.    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
19.    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
20.    GPIO_Init(GPIOA, &GPIO_InitStruct);
21.     
22.    CAN_InitTypeDef CAN;
23.    CAN_DeInit(CAN1);
24.    CAN_StructInit(&CAN);
25.     
26.    CAN.CAN_Prescaler = 4;
27.     
28.    //#define CAN_Mode_Normal             ((uint8_t)0x00)  /*!< normal mode */
29.    //#define CAN_Mode_LoopBack           ((uint8_t)0x01)  /*!< loopback mode */
30.    //#define CAN_Mode_Silent             ((uint8_t)0x02)  /*!< silent mode */
31.    //#define CAN_Mode_Silent_LoopBack    ((uint8_t)0x03)  /*!< loopback combined with silent mode */
32.    CAN.CAN_Mode = CAN_Mode_LoopBack;
33. 
34.    // for 250k @ 18MHz
35.    CAN.CAN_SJW = CAN_SJW_2tq;
36.    CAN.CAN_BS1 = CAN_BS1_15tq;
37.    CAN.CAN_BS2 = CAN_BS2_2tq;
38.    CAN.CAN_TTCM = DISABLE;
39.    CAN.CAN_ABOM = DISABLE;
40.    CAN.CAN_AWUM = DISABLE;
41.    CAN.CAN_NART = DISABLE;
42.    CAN.CAN_RFLM = DISABLE;
43.    CAN.CAN_TXFP = DISABLE;
44.    status = CAN_Init(CAN1, &CAN);
45.     
46.    CAN_FilterInitTypeDef FilterSet;
47.    FilterSet.CAN_FilterIdHigh = 0x0000;
48.    FilterSet.CAN_FilterIdLow = 0x0000;
49.    FilterSet.CAN_FilterMaskIdHigh = 0x0000;
50.    FilterSet.CAN_FilterMaskIdLow = 0x0000;
51.    FilterSet.CAN_FilterFIFOAssignment = 0;
52.    FilterSet.CAN_FilterNumber = 0;
53.    FilterSet.CAN_FilterMode = CAN_FilterMode_IdMask;
54.    FilterSet.CAN_FilterScale = CAN_FilterScale_32bit;
55.    FilterSet.CAN_FilterActivation = ENABLE;
56.    CAN_FilterInit(&FilterSet);
57.     
58.    return status;
59.}


01.int main(void)
02.{
03.    RCC_ClocksTypeDef SYS_Clocks;
04.    RCC_GetClocksFreq(&SYS_Clocks);
05. 
06.    if(SysTick_Config(SYS_Clocks.HCLK_Frequency / 1000))
07.    {
08.        while(1);
09.    }
10.     
11.    init_USART();
12.    clr_term();
13.    printf("%sLIDAR CAN Node 0V2 - Target: STMicroelectronics STM32F303K8T6 36 MHz    \r\n%s", "\033[44;51;37m", none);
14.    printf("\nGetting clocks..\r\n");
15.    printf("\r\nSYSCLK:%dM\r\n",SYS_Clocks.SYSCLK_Frequency/1000000);
16.    printf("HCLK:%dM\r\n",SYS_Clocks.HCLK_Frequency/1000000);
17.    printf("PCLK1:%dM\r\n",SYS_Clocks.PCLK1_Frequency/1000000);
18.    printf("PCLK2:%dM\r\n",SYS_Clocks.PCLK2_Frequency/1000000);
19.    printf("Setting up CAN Peripheral... \r\n");
20.    if(can_init() == CAN_InitStatus_Failed)
21.    {
22.        printf("%sCan init failure.\r\n\n", cyan);
23.        printf("\tESR \t\t\t\t= %u\r\n", CAN1->ESR);
24.        printf("\tFlags \t\t\t\t= %u\r\n", CAN_GetFlagStatus(CAN1, CAN_FLAG_LEC));
25.        printf("\tError Warning \t\t\t= %u\r\n", CAN_GetFlagStatus(CAN1, CAN_FLAG_EWG));
26.        printf("\tError Passive \t\t\t= %u\r\n", CAN_GetFlagStatus(CAN1, CAN_FLAG_EPV));
27.        printf("\tBus-off \t\t\t= %u\r\n", CAN_GetFlagStatus(CAN1, CAN_FLAG_BOF));
28.        printf("\tLast Error Code \t\t= %u\r\n", CAN_GetLastErrorCode(CAN1));
29.        printf("\tReceive Error Counter \t\t= %u\r\n", CAN_GetReceiveErrorCounter(CAN1));
30.        printf("\tTransmit Error Counter \t\t= %u\r\n%s", CAN_GetLSBTransmitErrorCounter(CAN1), none);
31.        printf("\nExecution halted\r\n");
32.        while(1);
33.    }
34.    printf("Done!\r\n");
35.}

The only thing left I can think of, is the pin configuration. But, it seems right to me. In fact, removing the Push-Pull configuration doesn't change anything since I've already set the pin to AF_Mode.

Any ideas here? I'm hoping it's blatantly obvious. I got the CAN network up and running on the F446RE nucleo no problem, but the F3 is proving to be a cranky device.

Thanks for the input all, let me know if you see anything suspicious in my code!

Outcomes