2021-03-05 12:26 AM
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,
/* 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 !
2021-03-05 01:08 AM
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.
2021-03-05 01:41 AM
Hi,
Please see this post: https://community.st.com/s/question/0D53W0000080SyvSAE/get-no-coomunication-via-fdcan1-on-stm32g431rb-nucleo-board
Best regards,
Slawek
2021-03-05 06:26 AM
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?