2016-04-01 07:47 AM
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!
2016-04-01 08:10 AM
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 baud2016-04-01 10:21 AM
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 MHzThe table says:BitRate;Accuracy;PreScalar;NumberOfTimeQuanta;Seg1;Seg2;SamplePointAt;CAN_BTR250 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
2016-04-01 10:40 AM
(18,000,000 / 4) / (2 + 15 + 2)
4,500,000 / 19236842.10526315789473684210526316