2018-06-25 08:34 AM
Hello,
I'm trying to configure the CAN-bus peripheral in loopback mode so I can later develop a real network. I'm using the Nucleo L432KC board and my clock is 32MHz.
My problem is that I can't send any messages andHAL_CAN_GetTxMailboxesFreeLevel() always returns 3 even without trying to send messages. Every time I try to send a message the code simply blocks and it does not enter the _Error_Handler() function. TheHAL_CAN_GetState() function returnsHAL_CAN_STATE_LISTENING.
I based my code on the example provided my ST in the HAL library (CAN_Networking).
Can you help me discovering what's wrong with this code?
Here is the CAN-bus configuration function:
static void MX_CAN1_Init(void)
{
CAN_FilterTypeDef sFilterConfig;
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 8;
hcan1.Init.Mode = CAN_MODE_LOOPBACK;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_13TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;
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__);
}
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
if(HAL_CAN_ConfigFilter(&hcan1,&sFilterConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
if(HAL_CAN_Start(&hcan1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
TxHeader.StdId = 0x321;
TxHeader.ExtId = 0x01;
TxHeader.RTR = CAN_RTR_DATA;
TxHeader.IDE = CAN_ID_STD;
TxHeader.DLC = 2; //length
TxHeader.TransmitGlobalTime = DISABLE;
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
Here is the RX interrupt handler:
void HAL_CAN_RxFifo0MsgPendingMessage(CAN_HandleTypeDef *hcan)
{
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_3);
if(HAL_CAN_GetRxMessage(hcan,CAN_RX_FIFO0,&RxHeader,RxData) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
if((RxHeader.StdId == 0x321) && (RxHeader.DLC == 2))
{
can_msg_received = 1;
}
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
And here is part of the main code in which I try to send messages:
(...)
CAN_HandleTypeDef hcan1;
(...)
CAN_TxHeaderTypeDef TxHeader;
CAN_RxHeaderTypeDef RxHeader;
uint8_t TxData[8];
uint8_t RxData[8];
uint32_t TxMailbox;
(...)
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART2_UART_Init();
//MX_TIM2_Init();
MX_I2C1_SMBUS_Init();
MX_I2C3_Init();
MX_CAN1_Init();
(...)
while (1)
{
millis = HAL_GetTick();
if (millis-last_millis > 1000)
{
last_millis = millis;
(...)
TxData[0] = (uint8_t)((mymlx90614->IR_raw & 0xFF00) >> 8);
TxData[1] = (uint8_t)(mymlx90614->IR_raw & 0xFF);
return_value = HAL_CAN_GetState(&hcan1);
while((return_value == HAL_CAN_STATE_READY) && (return_value == HAL_CAN_STATE_LISTENING));
mailbox_level = HAL_CAN_GetTxMailboxesFreeLevel(&hcan1);
sprintf(msg_send,'CAN Mailbox Level: %ld\r\n',mailbox_level);
HAL_UART_Transmit(&huart2, (uint8_t*)msg_send, strlen(msg_send), 0xFFFF);
if(HAL_CAN_AddTxMessage(&hcan1,&TxHeader,TxData,&TxMailbox) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
if(can_msg_received == 1)
{
can_msg_received = 0;
sprintf(msg_send,'CAN Message Received: %X %X\r\n',RxData[0],RxData[1]);
HAL_UART_Transmit(&huart2, (uint8_t*)msg_send, strlen(msg_send), 0xFFFF);
}
}
return(0);
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
stm32l4xx_hal_msp.c
(...)
void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hcan->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspInit 0 */
/* USER CODE END CAN1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_CAN1_CLK_ENABLE();
/**CAN1 GPIO Configuration
PA11 ------> CAN1_RX
PA12 ------> CAN1_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* CAN1 interrupt Init */
HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
/* USER CODE BEGIN CAN1_MspInit 1 */
/* USER CODE END CAN1_MspInit 1 */
}
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
(...)�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
Thank you for you help.
Miguel
#can #can-bus2018-06-26 06:35 AM
this is how I transmit.
if ((CAN->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) // (1)
{
CAN->sTxMailBox[0].TDTR = canTxMsgLength[canTxMsgOUT]; // (2) length CAN->sTxMailBox[0].TDLR = canTxMsgBottomWord[canTxMsgOUT]; // (3) 4bytes CAN->sTxMailBox[0].TDHR = canTxMsgTopWord[canTxMsgOUT]; // (3) 4bytes CAN->sTxMailBox[0].TIR = ((uint32_t)canTxMsgID[canTxMsgOUT] << 21 | CAN_TI0R_TXRQ); // (4) send it now if the line is idle2018-06-26 09:43 AM
Thank you! I'll give it a look! But the mailboxes seem to be full even before I send any message.
Also, I'm using the newer CAN API and I'd like to know what is wrong with my code.
Thank you anyway!