2024-05-16 02:11 AM - last edited on 2024-05-16 02:22 AM by SofLit
Hello All !
I have an issue with the CAN bus on STM32F042G6. I am using PA11 and PA12 Pins. Here is the configuration part with a 48MHz internal clock :
static void MX_CAN_Init(void)
{
/* USER CODE BEGIN CAN_Init 0 */
/* USER CODE END CAN_Init 0 */
/* USER CODE BEGIN CAN_Init 1 */
/* USER CODE END CAN_Init 1 */
hcan.Instance = CAN;
hcan.Init.Prescaler = 23;
hcan.Init.Mode = CAN_MODE_NORMAL;
hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan.Init.TimeSeg1 = CAN_BS1_5TQ;
hcan.Init.TimeSeg2 = CAN_BS2_6TQ;
hcan.Init.TimeTriggeredMode = DISABLE;
hcan.Init.AutoBusOff = DISABLE;
hcan.Init.AutoWakeUp = DISABLE;
hcan.Init.AutoRetransmission = DISABLE;
hcan.Init.ReceiveFifoLocked = DISABLE;
hcan.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN_Init 2 */
/* USER CODE END CAN_Init 2 */
}
Here is the remap done by STCube :
void HAL_MspInit(void)
{
/* USER CODE BEGIN MspInit 0 */
/* USER CODE END MspInit 0 */
__HAL_RCC_SYSCFG_CLK_ENABLE();
__HAL_RCC_PWR_CLK_ENABLE();
/* System interrupt init*/
__HAL_REMAP_PIN_ENABLE(HAL_REMAP_PA11_PA12);
/* USER CODE BEGIN MspInit 1 */
/* USER CODE END MspInit 1 */
}
void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hcan->Instance==CAN)
{
/* USER CODE BEGIN CAN_MspInit 0 */
/* USER CODE END CAN_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_CAN1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**CAN GPIO Configuration
PA11 ------> CAN_RX
PA12 ------> CAN_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_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_CAN;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN CAN_MspInit 1 */
/* USER CODE END CAN_MspInit 1 */
}
}
I can write with the CAN bus it works (verified with oscillo), here is the code for the writing part :
int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_CAN_Init();
MX_CRC_Init();
/* USER CODE BEGIN 2 */
if(HAL_CAN_Start(&hcan) != HAL_OK)
Error_Handler();
TxHeader.StdId = 0x446;
TxHeader.ExtId = 0x01;
TxHeader.RTR = CAN_RTR_DATA;
TxHeader.IDE = CAN_ID_STD;
TxHeader.DLC = 2;
CAN_FilterTypeDef canfilterconfig;
canfilterconfig.FilterActivation = CAN_FILTER_ENABLE;
canfilterconfig.FilterBank = 18; // which filter bank to use from the assigned ones
canfilterconfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
canfilterconfig.FilterIdHigh = 0x446<<5;
canfilterconfig.FilterIdLow = 0;
canfilterconfig.FilterMaskIdHigh = 0x446<<5;
canfilterconfig.FilterMaskIdLow = 0x0000;
canfilterconfig.FilterMode = CAN_FILTERMODE_IDMASK;
canfilterconfig.FilterScale = CAN_FILTERSCALE_32BIT;
canfilterconfig.SlaveStartFilterBank = 20;
HAL_CAN_ConfigFilter(&hcan, &canfilterconfig);
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
HAL_Delay(500);
HAL_CAN_AddTxMessage(&hcan, &TxHeader, txData, &mail_box);
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
This part is ok !
So now I tried to read the frame sent with this code :
int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_CAN_Init();
MX_CRC_Init();
/* USER CODE BEGIN 2 */
if(HAL_CAN_Start(&hcan) != HAL_OK)
Error_Handler();
TxHeader.StdId = 0x446;
TxHeader.ExtId = 0x01;
TxHeader.RTR = CAN_RTR_DATA;
TxHeader.IDE = CAN_ID_STD;
TxHeader.DLC = 2;
CAN_FilterTypeDef canfilterconfig;
canfilterconfig.FilterActivation = CAN_FILTER_ENABLE;
canfilterconfig.FilterBank = 18; // which filter bank to use from the assigned ones
canfilterconfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
canfilterconfig.FilterIdHigh = 0x446<<5;
canfilterconfig.FilterIdLow = 0;
canfilterconfig.FilterMaskIdHigh = 0x446<<5;
canfilterconfig.FilterMaskIdLow = 0x0000;
canfilterconfig.FilterMode = CAN_FILTERMODE_IDMASK;
canfilterconfig.FilterScale = CAN_FILTERSCALE_32BIT;
canfilterconfig.SlaveStartFilterBank = 20; // how many filters to assign to the CAN1 (master can)
HAL_CAN_ConfigFilter(&hcan, &canfilterconfig);
//activate Int
if (HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING ) != HAL_OK)
{
Error_Handler();
}
while(1)
{
}
}
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, Rx); //Receive CAN bus message to canRX buffer
}
I don't understand why but it is impossible for me to go in the HAL_CAN_RxFifo0MsgPendingCallback function when a message is received. I checkes the RX Pin with an oscilloscope and the CAN frame is correct on this Pin...
I hope it is clear enough... Do you have any advise to help me ?
I looked everywhere in the datasheet and on forums but impossible to make it works...??
Thank you in advance :).
Tonave
Solved! Go to Solution.
2024-05-16 02:54 AM - edited 2024-05-16 02:55 AM
Ok let's keep the config in the loopback mode for the moment and be sure Rx pin is configured in Pull-up.
Forget about normal mode for the moment.
Could you also share your ioc and main files?
2024-05-16 02:21 AM
Hello,
What do you mean by "So now I tried to read the frame sent with this code :" ? are you looping back the message you're sending externally to the Rx pin?
2024-05-16 02:26 AM
Hello,
Thanks for your answer. I tried both solutions :
1- Try in loopback mode
2- Try to connect another board to the can bus in order to read.
In any case same result, doesn't work... I am going to be crazy with this CAN bus ^^
Tonave
2024-05-16 02:38 AM
Hello,
There is an issue with your filter bank config.
Your device is STM32F042 having only one CAN instance which is CAN1 so you have only 14 filters available and you set your filter bank as follwoing:
canfilterconfig.FilterBank = 18; // which filter bank to use from the assigned ones
canfilterconfig.SlaveStartFilterBank = 20; // how many filters to assign to the CAN1 (master can)
As if you copied this config from another project using a device having two CAN instances.
So try the following config:
canfilterconfig.FilterBank = 0;
canfilterconfig.SlaveStartFilterBank = 14;
2024-05-16 02:49 AM
Thank you again for your answer.
Unfortunately same result... I tried to do a very simple project with only CAN bus, so I have nothing more... I don't know where this issue come from.
It is like if the Rx Pin is not well configured or there is an issue with the interrupt...??
Tonave
2024-05-16 02:53 AM
2024-05-16 02:54 AM - edited 2024-05-16 02:55 AM
Ok let's keep the config in the loopback mode for the moment and be sure Rx pin is configured in Pull-up.
Forget about normal mode for the moment.
Could you also share your ioc and main files?
2024-05-16 03:24 AM
To be honest, you are a hero ! ;)
I just change RX pin to pull up and everything works... I provide you the files.
Thank you very much for your help.
One more question, is it necessary to put Rx pin in pull up configuration in Loopback and slave mode ?
As I said, it is a really simple project just with CAN Bus in order to understand what was wrong...
Tonave
2024-05-16 03:38 AM - edited 2024-05-16 04:03 AM
Hello,
You're welcome.
Yes in loopback mode you need to set the Rx pin to Pull-up. Note this is for STM32 MCUs featuring bxCAN. For FDCAN I think this is not the case ..
Meanwhile I didn't understand what do you mean by "slave mode"?
Did you succeed the reception in normal mode? normally when you succeed in loopback mode, there is no more issue with the filters but with HW config ..
2024-05-16 04:59 AM
Just to explain you a little bit more.
I have one master on the CAN line and many slaves. So, when I sent the CAN frames with one slave, I wasn't able to interrupt the SW. No, as it works in Normal (what I called slave mode) and loop mode, I wanted to know if the Rx Pin should be always pulled up ?
I will try in both config now (just change this parameter) and I will see :)
Tonave