cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F303K8 CAN Init failure on all modes

troyerta
Associate II
Posted on April 01, 2016 at 16:47

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:


printf(''\tESR \t\t\t\t= %u\r\n'', CAN1->ESR);

printf(''\tFlags \t\t\t\t= %u\r\n'', CAN_GetFlagStatus(CAN1, CAN_FLAG_LEC));

printf(''\tError Warning \t\t\t= %u\r\n'', CAN_GetFlagStatus(CAN1, CAN_FLAG_EWG));

printf(''\tError Passive \t\t\t= %u\r\n'', CAN_GetFlagStatus(CAN1, CAN_FLAG_EPV));

printf(''\tBus-off \t\t\t= %u\r\n'', CAN_GetFlagStatus(CAN1, CAN_FLAG_BOF));

printf(''\tLast Error Code \t\t= %u\r\n'', CAN_GetLastErrorCode(CAN1));

printf(''\tReceive Error Counter \t\t= %u\r\n'', CAN_GetReceiveErrorCounter(CAN1));

printf(''\tTransmit Error Counter \t\t= %u\r\n%s'', CAN_GetLSBTransmitErrorCounter(CAN1), none);

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


#define CAN_TX GPIO_Pin_12

#define CAN_RX GPIO_Pin_11


uint8_t can_init(void)

{

uint8_t status = 0;


RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);


GPIO_PinAFConfig(GPIOA, CAN_TX, GPIO_AF_9);

GPIO_PinAFConfig(GPIOA, CAN_RX, GPIO_AF_9);


GPIO_InitTypeDef GPIO_InitStruct;

GPIO_InitStruct.GPIO_Pin = CAN_TX|CAN_RX;

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;

GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;

GPIO_Init(GPIOA, &GPIO_InitStruct);


CAN_InitTypeDef CAN;

CAN_DeInit(CAN1);

CAN_StructInit(&CAN);


CAN.CAN_Prescaler = 4;


//#define CAN_Mode_Normal ((uint8_t)0x00) /*!< normal mode */

//#define CAN_Mode_LoopBack ((uint8_t)0x01) /*!< loopback mode */

//#define CAN_Mode_Silent ((uint8_t)0x02) /*!< silent mode */

//#define CAN_Mode_Silent_LoopBack ((uint8_t)0x03) /*!< loopback combined with silent mode */

CAN.CAN_Mode = CAN_Mode_LoopBack;


// for 250k @ 18MHz

CAN.CAN_SJW = CAN_SJW_2tq;

CAN.CAN_BS1 = CAN_BS1_15tq;

CAN.CAN_BS2 = CAN_BS2_2tq;

CAN.CAN_TTCM = DISABLE;

CAN.CAN_ABOM = DISABLE;

CAN.CAN_AWUM = DISABLE;

CAN.CAN_NART = DISABLE;

CAN.CAN_RFLM = DISABLE;

CAN.CAN_TXFP = DISABLE;

status = CAN_Init(CAN1, &CAN);


CAN_FilterInitTypeDef FilterSet;

FilterSet.CAN_FilterIdHigh = 0x0000;

FilterSet.CAN_FilterIdLow = 0x0000;

FilterSet.CAN_FilterMaskIdHigh = 0x0000;

FilterSet.CAN_FilterMaskIdLow = 0x0000;

FilterSet.CAN_FilterFIFOAssignment = 0;

FilterSet.CAN_FilterNumber = 0;

FilterSet.CAN_FilterMode = CAN_FilterMode_IdMask;

FilterSet.CAN_FilterScale = CAN_FilterScale_32bit;

FilterSet.CAN_FilterActivation = ENABLE;

CAN_FilterInit(&FilterSet);


return status;

}


int main(void)

{

RCC_ClocksTypeDef SYS_Clocks;

RCC_GetClocksFreq(&SYS_Clocks);


if(SysTick_Config(SYS_Clocks.HCLK_Frequency / 1000))

{

while(1);

}


init_USART();

clr_term();

printf(''%sLIDAR CAN Node 0V2 - Target: STMicroelectronics STM32F303K8T6 36 MHz \r\n%s'', ''\033[44;51;37m'', none);

printf(''\nGetting clocks..\r\n'');

printf(''\r\nSYSCLK:%dM\r\n'',SYS_Clocks.SYSCLK_Frequency/1000000);

printf(''HCLK:%dM\r\n'',SYS_Clocks.HCLK_Frequency/1000000);

printf(''PCLK1:%dM\r\n'',SYS_Clocks.PCLK1_Frequency/1000000);

printf(''PCLK2:%dM\r\n'',SYS_Clocks.PCLK2_Frequency/1000000); 

printf(''Setting up CAN Peripheral... \r\n'');

if(can_init() == CAN_InitStatus_Failed)

{

printf(''%sCan init failure.\r\n\n'', cyan);

printf(''\tESR \t\t\t\t= %u\r\n'', CAN1->ESR);

printf(''\tFlags \t\t\t\t= %u\r\n'', CAN_GetFlagStatus(CAN1, CAN_FLAG_LEC));

printf(''\tError Warning \t\t\t= %u\r\n'', CAN_GetFlagStatus(CAN1, CAN_FLAG_EWG));

printf(''\tError Passive \t\t\t= %u\r\n'', CAN_GetFlagStatus(CAN1, CAN_FLAG_EPV));

printf(''\tBus-off \t\t\t= %u\r\n'', CAN_GetFlagStatus(CAN1, CAN_FLAG_BOF));

printf(''\tLast Error Code \t\t= %u\r\n'', CAN_GetLastErrorCode(CAN1));

printf(''\tReceive Error Counter \t\t= %u\r\n'', CAN_GetReceiveErrorCounter(CAN1));

printf(''\tTransmit Error Counter \t\t= %u\r\n%s'', CAN_GetLSBTransmitErrorCounter(CAN1), none);

printf(''\nExecution halted\r\n'');

while(1);

}

printf(''Done!\r\n'');

}

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!
3 REPLIES 3
Posted on April 01, 2016 at 17:10

Any ideas here? I'm hoping it's blatantly obvious.

Well AFConfig needs PinSource indexes, not Pin bit masks.

And the bit rate looks to compute out at 236842.11 baud

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
troyerta
Associate II
Posted on April 01, 2016 at 19:21

I see, so I was mis-using the AF_Config() function. Well it seems to get back initialization now, so that's excellent!

Whay did you use to calculate the bit timing? I've been using the calculator here: http://www.bittiming.can-wiki.info/

which generates BTR register values (minus the mode bits in the MSB places), for many different CAN modules including the ST bx_can module, (see one of the options available in the dropdown menu. I used the site to get my F4s running at a nice and even 250k, which was verified on the scope, so while I have yet to verify the bit timing on this F3 device, (won't happen for a few more hours), how did you get such a weird bit rate?

APB1 = 18 MHz

The table says:

BitRate;Accuracy;PreScalar;NumberOfTimeQuanta;Seg1;Seg2;SamplePointAt;CAN_BTR

250 0.00 4 18 15 2 88.9 0x001e0003

250 0.00 6 12 10 1 91.7 0x00090005

250 0.00 8 9 7 1 88.9 0x00060007

250 0.00 9 8 6 1 87.5 0x00050008

Posted on April 01, 2016 at 19:40

(18,000,000 / 4) / (2 + 15 + 2)

4,500,000 / 19

236842.10526315789473684210526316

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..