2019-07-22 04:27 AM
Edit: HAL_CAN_Start() and configuring the CAN filter correctly fixed it.
Hi, I am trying to read CAN messages sent by a device, but are not able to.
Hardware setup should be correct, my setup works when testing with a program using mBed OS, messages are correctly received.
Some notes:
Code(irrelevant code removed, msp at the end):
#include "main.h"
#include <stdio.h>
CAN_HandleTypeDef hcan1;
UART_HandleTypeDef huart3;
CAN_TxHeaderTypeDef TxHeader;
CAN_RxHeaderTypeDef RxHeader;
uint8_t TxData[8];
uint8_t RxData[8];
uint32_t TxMailbox;
char msg[50];
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART3_UART_Init(void);
static void MX_CAN1_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART3_UART_Init();
MX_CAN1_Init();
uint8_t TestData[7];
while (1)
{
sprintf(msg,"Waiting for message\r\n");
HAL_UART_Transmit(&huart3,(uint8_t*)msg,sizeof(msg),HAL_MAX_DELAY);
if (HAL_CAN_GetRxFifoFillLevel(&hcan1, CAN_RX_FIFO0) > 0)
{
HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &RxHeader, TestData);
HAL_UART_Transmit(&huart3, "Can Message recieved\n\r", 22, 10);
}
HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &RxHeader, TestData);
sprintf(msg,"Message: %x\r\n", TestData[0]);
HAL_UART_Transmit(&huart3,(uint8_t*)msg,sizeof(msg),HAL_MAX_DELAY);
HAL_Delay(500);
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
HAL_PWR_EnableBkUpAccess();
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 96;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 4;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
if (HAL_PWREx_EnableOverDrive() != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
{
Error_Handler();
}
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART3|RCC_PERIPHCLK_CLK48;
PeriphClkInitStruct.Usart3ClockSelection = RCC_USART3CLKSOURCE_PCLK1;
PeriphClkInitStruct.Clk48ClockSelection = RCC_CLK48SOURCE_PLL;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
}
static void MX_CAN1_Init(void)
{
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 12;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_2TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_10TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_5TQ;
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();
}
}
static void MX_GPIO_Init(void)
{
lots of code
}
void Error_Handler(void)
{
}
/* hal_msp.c */
void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hcan->Instance==CAN1)
{
__HAL_RCC_CAN1_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
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(GPIOD, &GPIO_InitStruct);
}
}
Solved! Go to Solution.
2019-07-22 06:20 AM
Did you call HAL_CAN_Start() somewhere in your code?
Also uint8_t TestData[7] should be uint8_t TestData[8].
If you are using CubeMX you could have a look into:
STM32Cube/Repository/STM32Cube_FW_F7_V.15.0/Projects/STM32F723E-Discovery/Examples/CAN/CAN_Loopback/Src/main.c
for comparison.
2019-07-22 04:50 AM
Hello tor7767,
How did you setup the BTR register?
Maybe MX_CAN1_Init() resets your configuration,
since it clearly doesnt meet your setup of 250kbps, Sampling point 70%, SJW 2 Tq
2019-07-22 05:04 AM
My mistake, I posted wrong MX_CAN1_init. The correct one(which does not work) is
static void MX_CAN1_Init(void)
{
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 12;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_2TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_10TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_5TQ;
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();
}
}
2019-07-22 06:20 AM
Did you call HAL_CAN_Start() somewhere in your code?
Also uint8_t TestData[7] should be uint8_t TestData[8].
If you are using CubeMX you could have a look into:
STM32Cube/Repository/STM32Cube_FW_F7_V.15.0/Projects/STM32F723E-Discovery/Examples/CAN/CAN_Loopback/Src/main.c
for comparison.
2019-07-22 07:02 AM
I added HAL_CAN_Start() and now I can find seemingly correct data in the corresponding receive registers(Rl0R/RDL0R/RDH0R) when running in debug.
The data is still not read with HAL_CAN_GetRxMessage and HAL_CAN_GetRxFifoFillLevel. I will try to add a proper CAN filter.
2023-01-28 02:30 AM
hey @Tor Egil Øvernes , does it work now? Could you please share the working code...