Skip to main content
KMiko.1
Associate II
March 5, 2021
Question

CAN programming question

  • March 5, 2021
  • 2 replies
  • 6242 views

Hi !

I'm new in the STM32 world ! So, sorry if my questions are stupid. I work on CAN with the example : FDCAN Classic Frame Networking.

I want to know if in this example that I modified slightly,

  • HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TxData) is use to send a message ?
  • HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs) is use to receive ? or it is HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader, RxData) ?
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include <stdbool.h>
 
 
/* Private includes ----------------------------------------------------------*/
 
 
/* Private typedef -----------------------------------------------------------*/
 
 
/* Private define ------------------------------------------------------------*/
 
#define KEY_PRESSED GPIO_PIN_RESET
#define KEY_NOT_PRESSED GPIO_PIN_SET
 
 
 
/* Private macro -------------------------------------------------------------*/
 
 
 
/* Private variables ---------------------------------------------------------*/
 
	FDCAN_HandleTypeDef hfdcan1;
	FDCAN_RxHeaderTypeDef RxHeader;
	FDCAN_TxHeaderTypeDef TxHeader;
	
	uint8_t ubKeyNumber = 0x0;
	uint8_t RxData[8];
	uint8_t TxData[8];
 
 
/* Private function prototypes -----------------------------------------------*/
	
	void SystemClock_Config(void);
	static void MX_GPIO_Init(void);
	static void MX_FDCAN1_Init(void);
	static void FDCAN_Config(void);
	static void LED_Display(uint8_t LedStatus);
 
 
 
/* Private user code ---------------------------------------------------------*/
 
	
 
/**
 * @brief The application entry point.
 * @retval int
 */
int main(void)
{
 
 HAL_Init();/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 SystemClock_Config();/* Configure the system clock */
 
 /* Configure User push-button in interrupt mode */
 BSP_PB_Init(BUTTON_USER, BUTTON_MODE_GPIO);
 BSP_LED_Init(LED1); /* Configure LED1, LED2, LED3 and LED4 */
 BSP_LED_Init(LED2);
 BSP_LED_Init(LED3);
 BSP_LED_Init(LED4);
 
 
 /* Initialize all configured peripherals */
 MX_GPIO_Init();																						// GPIO Init
 MX_FDCAN1_Init();																						// FDCAN1 Init
 FDCAN_Config();																						// Configure the FDCAN peripheral
 
 
 
 /* Infinite loop */
 while (1)
 {
	 
	 // Check Power supply CAN DATA
	 _Bool checkPSS = PowerSupply_Security();				// Check CAN security message
 
 // Set the data to be transmitted
 TxHeader.Identifier = 0x321;																	// ID
 TxHeader.IdType = FDCAN_STANDARD_ID;															// ID type
 TxHeader.TxFrameType = FDCAN_DATA_FRAME;														// Frame type
 TxHeader.DataLength = FDCAN_DLC_BYTES_8;														// Data length
 TxData[0] = 0xAA;
 TxData[1] = 0xAD;
 TxData[2] = 0xAD;
 TxData[3] = 0xAD;
 TxData[4] = 0xAD;
 TxData[5] = 0xAD;
 TxData[6] = 0xAD;
 TxData[7] = 0xAD;
 
 // Start the Transmission process
 if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TxData) != HAL_OK) {
 Error_Handler();																				// Transmission request Error
 }
 
 HAL_Delay(10);
 
 while (BSP_PB_GetState(BUTTON_USER) != KEY_NOT_PRESSED)
 {
 }
 }
}
 
/**
 * @brief System Clock Configuration
 * @retval None
 */
void SystemClock_Config(void)
{
 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
 
 /** Configure the main internal regulator output voltage
 */
 HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
 /** Initializes the RCC Oscillators according to the specified parameters
 * in the RCC_OscInitTypeDef structure.
 */
 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
 RCC_OscInitStruct.HSIState = RCC_HSI_ON;
 RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
 RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV2;
 RCC_OscInitStruct.PLL.PLLN = 20;
 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
 RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
 RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
 {
 Error_Handler();
 }
 /** Initializes the CPU, AHB and APB buses clocks
 */
 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_DIV1;
 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
 {
 Error_Handler();
 }
 /** Initializes the peripherals clocks
 */
 PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_FDCAN;
 PeriphClkInit.FdcanClockSelection = RCC_FDCANCLKSOURCE_PCLK1;
 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
 {
 Error_Handler();
 }
}
 
/**
 * @brief FDCAN1 Initialization Function
 * @param None
 * @retval None
 */
static void MX_FDCAN1_Init(void)
{
 
 /* USER CODE BEGIN FDCAN1_Init 0 */
 
 /* USER CODE END FDCAN1_Init 0 */
 
 /* USER CODE BEGIN FDCAN1_Init 1 */
 
 /* USER CODE END FDCAN1_Init 1 */
 hfdcan1.Instance = FDCAN1;
 hfdcan1.Init.ClockDivider = FDCAN_CLOCK_DIV1;
 hfdcan1.Init.FrameFormat = FDCAN_FRAME_FD_BRS;
 hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
 hfdcan1.Init.AutoRetransmission = ENABLE;
 hfdcan1.Init.TransmitPause = ENABLE;
 hfdcan1.Init.ProtocolException = DISABLE;
 hfdcan1.Init.NominalPrescaler = 1;
 hfdcan1.Init.NominalSyncJumpWidth = 16;
 hfdcan1.Init.NominalTimeSeg1 = 63;
 hfdcan1.Init.NominalTimeSeg2 = 16;
 hfdcan1.Init.DataPrescaler = 1;
 hfdcan1.Init.DataSyncJumpWidth = 4;
 hfdcan1.Init.DataTimeSeg1 = 5;
 hfdcan1.Init.DataTimeSeg2 = 4;
 hfdcan1.Init.StdFiltersNbr = 1;
 hfdcan1.Init.ExtFiltersNbr = 0;
 hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
 if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN FDCAN1_Init 2 */
 
 /* USER CODE END FDCAN1_Init 2 */
 
}
 
/**
 * @brief GPIO Initialization Function
 * @param None
 * @retval None
 */
static void MX_GPIO_Init(void)
{
 
 /* GPIO Ports Clock Enable */
 __HAL_RCC_GPIOB_CLK_ENABLE();
 
}
 
/* USER CODE BEGIN 4 */
 
/**
 * @brief Configures the FDCAN.
 * @param None
 * @retval None
 */
static void FDCAN_Config(void)
{
	
 FDCAN_FilterTypeDef sFilterConfig;
 
 /* Configure Rx filter */
 sFilterConfig.IdType = FDCAN_STANDARD_ID;
 sFilterConfig.FilterIndex = 0;
 sFilterConfig.FilterType = FDCAN_FILTER_MASK;
 sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
 sFilterConfig.FilterID1 = 0x321;
 sFilterConfig.FilterID2 = 0x7FF;
 
 if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK) {
 Error_Handler();
 }
 
 /* Configure global filter: Filter all remote frames with STD and EXT ID Reject non matching frames with STD ID and EXT ID */
 if (HAL_FDCAN_ConfigGlobalFilter(&hfdcan1, FDCAN_REJECT, FDCAN_REJECT, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE) != HAL_OK) {
 Error_Handler();
 }
 
 /* Start the FDCAN module */
 if (HAL_FDCAN_Start(&hfdcan1) != HAL_OK) {
 Error_Handler();
 }
 
 if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK) {
 Error_Handler();
 }
 
 /* Prepare Tx Header */
 TxHeader.Identifier = 0x321;
 TxHeader.IdType = FDCAN_STANDARD_ID;
 TxHeader.TxFrameType = FDCAN_DATA_FRAME;
 TxHeader.DataLength = FDCAN_DLC_BYTES_2;
 TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
 TxHeader.BitRateSwitch = FDCAN_BRS_OFF;
 TxHeader.FDFormat = FDCAN_CLASSIC_CAN;
 TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
 TxHeader.MessageMarker = 0;
}
 
/**
 * @brief Rx FIFO 0 callback.
 * @param hfdcan: pointer to an FDCAN_HandleTypeDef structure that contains
 * the configuration information for the specified FDCAN.
 * @param RxFifo0ITs: indicates which Rx FIFO 0 interrupts are signalled.
 * This parameter can be any combination of @arg FDCAN_Rx_Fifo0_Interrupts.
 * @retval None
 */
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
 if((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET)
 {
 /* Retrieve Rx messages from RX FIFO0 */
 if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
 {
 Error_Handler();
 }
 
 /* Display LEDx */
 if ((RxHeader.Identifier == 0x321) && (RxHeader.IdType == FDCAN_STANDARD_ID) && (RxHeader.DataLength == FDCAN_DLC_BYTES_2))
 {
 ubKeyNumber = RxData[0];
 }
 }
}
 
 
 
/**
 * @brief This function is executed in case of error occurrence.
 * @retval None
 */
void Error_Handler(void)
{
 /* USER CODE BEGIN Error_Handler_Debug */
 /* User can add his own implementation to report the HAL error return state */
 /* Turn LED1, LED2, LED3 and LED4 on */
 BSP_LED_On(LED1);
 BSP_LED_On(LED2);
 BSP_LED_On(LED3);
 BSP_LED_On(LED4);
 
 while(1){}
}

Thank you !

This topic has been closed for replies.

2 replies

Ozone
Principal
March 5, 2021

To be honest, I did not work with the CAN interface of STM32 MCUs, and definitely not with HAL/Cube.

But almost all vendors have the same Bosch IP licensed, only the register interface differs.

You cannot "crack down" on the bus directly, because CAN is message/ID arbitrated, and has no master/slave organisation.

Instead, you have FIFOs for Tx and FIFOs or "mailboxes" for Rx.

HAL_FDCAN_AddMessageToTxFifoQ() is supposedly a function to add a message to the send queue.

HAL_FDCAN_RxFifo0Callback() would be a callback function for a CAN Rx event, and HAL_FDCAN_GetRxMessage() a function to retrieve one message.

Be careful with callback functions, they are called within interrupt context and can easily mess up the application timing.

KMiko.1
KMiko.1Author
Associate II
March 5, 2021

ok so if i understand correctly the best thing to do is to remove the callback function.

I have a device which sends continuous functions and another which waits for a frame to send its response. To avoid problems I would like not to store the received messages, that is to say that I ignore the messages then by entering a function I will read the data (id) that I need then exit, is it possible? does the HAL_FDCAN_GetRxMessage () function look good?

ah and why don't you work with HAL CUBE?

SKacp.1
Associate
March 5, 2021