2018-11-20 12:00 AM
I have implemented a CAN controller on the STM32F4 where it successfully transmits a SOF bit, but then the bus stays idle for the rest of the message. The values loaded into the registers are all correct and verified that they have been successfully copied into the registers, but they never get transmitted.
The CAN and associated GPIO init is as follows:
//can init
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 16;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_1TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_1TQ;
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = DISABLE;
hcan1.Init.AutoWakeUp = DISABLE;
hcan1.Init.AutoRetransmission = DISABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = DISABLE;
if(HAL_CAN_Init(&hcan1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
//...
//gpio init for can1
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
I then generate 2 "modules" which are just generic arbitrary CAN message structures
CAN_TxHeaderTypeDef module;
module.StdId = 0b11001001000; //arbitrary id, just used to verify message correctness
module.ExtId = 0; //std message anyways, unimportant field
module.IDE = CAN_ID_STD; //message id type
module.DLC = 8; //sending 8 bytes of data in this frame
module.RTR = CAN_RTR_DATA; //data frame
module.TransmitGlobalTime = DISABLE;
CAN_TxHeaderTypeDef module2;
module2.StdId = 0b00110110111;
module2.ExtId = 0;
module2.IDE = CAN_ID_STD;
module2.DLC = 8;
module2.RTR = CAN_RTR_DATA;
module2.TransmitGlobalTime = DISABLE;
Then I fill two buffers with numbers 0-7 (buffer1) and 8-15 (buffer2)
I then call HAL_CAN_Start(&hcan1) to start the CAN controller. My while loop is as follows:
while (1)
{
HAL_CAN_AddTxMessage(&hcan1, &module, buffer1, &txMailbox);
while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) == 0U);
HAL_Delay(500);
HAL_CAN_AddTxMessage(&hcan1, &module2, buffer2, &txMailbox);
while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) == 0U);
HAL_Delay(500);
}
HAL_CAN_AddTxMessage(...) fills a free mailbox with all the message information and sets the hardware bit to transmit. The output is being monitored and as soon as this bit is set is cleared by hardware (as it should) and the SOF is transmitted alone with no data. The blocking while is to wait for a free mailbox at which point it tries to send another message.
I can verify that the values I fill out in the structs and buffers are being properly copied into the registers, and the transmission clearly begins because the SOF bit is transmitted on the bus, but I can't figure out why the data is not being transmitted as well.
Can anyone see what's wrong with this? I believe it is an issue with my hardware initialization on the controller but that's only because I don't see what could be wrong with the software. Please tell me if this is wrong though!! Thank you very much.