CAN not working on STM32L431RCT6
"Board A" is a previous revision that used STM32F103C8T6 to communicate with a device over CAN. It works great.
"Board B" is a new revision of the same board, but I migrated to STM32L431RCT6 because I needed more IO and it was readily available. Long story short, I can't get the MCU to do anything on its CAN interface.
I thought maybe I missed something when porting the code over, but I tried creating a new CubeIDE project that just sends and receives, but I get nothing.
The CAN transceiver itself is working fine. With another host transmitting on the bus I can see a nice clean signal on the RX pin (PB8) with 3.0V peaks. However, nothing shows up in the RX FIFO.
Likewise, when the MCU is asked to transmit, nothing shows up on the TX pin (PB9).
The CAN peripheral is configured like so. I'm running the bus at 250kb/s and the MCU is clocked at 80MHz.
void MX_CAN1_Init(void)
{
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 20;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_9TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_6TQ;
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();
}
}
void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(canHandle->Instance==CAN1)
{
__HAL_RCC_CAN1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**CAN1 GPIO Configuration
PB8 ------> CAN1_RX
PB9 ------> CAN1_TX
*/
GPIO_InitStruct.Pin = CAN_RX_Pin|CAN_TX_Pin;
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(GPIOB, &GPIO_InitStruct);
HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
}
}
The filter is created and notification requests set up:
uint32_t setup(void)
{
can_tx_header.IDE = CAN_ID_STD; // 11-bit ID
can_tx_header.RTR = CAN_RTR_DATA; // Normal data
can_tx_header.TransmitGlobalTime = DISABLE;
CAN_FilterTypeDef can_filter;
can_filter.FilterBank = 0;
can_filter.FilterMode = CAN_FILTERMODE_IDMASK;
can_filter.FilterScale = CAN_FILTERSCALE_32BIT;
can_filter.FilterIdHigh = 0x0000;
can_filter.FilterIdLow = 0x0000;
can_filter.FilterMaskIdHigh = 0x0000;
can_filter.FilterMaskIdLow = 0x0000;
can_filter.FilterFIFOAssignment = CAN_RX_FIFO0;
can_filter.FilterActivation = CAN_FILTER_ENABLE;
can_filter.SlaveStartFilterBank = 14;
if (HAL_CAN_ConfigFilter(hcan, &can_filter) != HAL_OK)
return HAL_CAN_GetError(hcan);
if (HAL_CAN_Start(hcan) != HAL_OK)
return HAL_CAN_GetError(hcan);
if (HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
return HAL_CAN_GetError(hcan);
return HAL_OK;
}(This is in a class, hcan == &hcan1)
I have no reason to believe this is interrupt-related. The interrupts are configured in the NVIC and function names match those in the startup file. Also other interrupts work OK. Also polling the interface does not yield any data, and again, transmitting does not yield results.
I am regularly checking HAL_CAN_GetState(&hcan1) but it does not return any errors.
Any ideas are welcome.
