2016-04-01 7: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'');
#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'');
}2016-04-01 8: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