2020-12-08 07:32 PM
Hello,
I am trying to set up a CAN interrupt base communication system and it seems that IRQ handler is never called.
Debugger goes through the CAN1_TX and then back to main function, so IRq is never called.
USART output:
[2020-12-08_21:19:01:191] AFTER 50.
[2020-12-08_21:19:01:191]SYSCLK : 100000000Hz
[2020-12-08_21:19:01:191]HCLK : 50000000Hz
[2020-12-08_21:19:01:191]PCLK1 : 25000000Hz
[2020-12-08_21:19:01:191]PCLK2 : 50000000Hz
[2020-12-08_21:19:01:191] BEFORE TX CALL.
[2020-12-08_21:19:01:191] After TX call.
[2020-12-08_21:19:01:191] END of program.
Main:
#include "main.h"
#include <string.h>
#include <stdio.h>
TIM_HandleTypeDef htim2;
UART_HandleTypeDef huart2;
FDCAN_HandleTypeDef CAN1;
void SystemClock_Config_HSE(uint16_t Clock_Freq);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_TIM2_Init(void);
void GPIO_Init(void);
void CAN1_Init(void);
void CAN1_TX(void);
void CAN1_RX(void);
void CAN_Filter_Config(void);
void HAL_FDCAN_TxEventFifoCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes);
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs);
void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef *hfdcan);
char *user_data = "Hello world, I made it using STM32 ARM Cortex M7!\r\n";
char msg[100];
int main(void)
{
HAL_Init();
SystemClock_Config_HSE(SYS_CLOCK_FREQ_50_MHZ);
MX_GPIO_Init();
GPIO_Init();
MX_USART2_UART_Init();
MX_TIM2_Init();
user_data = " AFTER 50.\r\n";
if (HAL_UART_Transmit(&huart2,(uint8_t*)user_data,strlen(user_data), HAL_MAX_DELAY) != HAL_OK)
{
Error_Handler();
}
memset(msg,0,sizeof(msg));
sprintf(msg,"SYSCLK : %ldHz\r\n",HAL_RCC_GetSysClockFreq());
HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
memset(msg,0,sizeof(msg));
sprintf(msg,"HCLK : %ldHz\r\n",HAL_RCC_GetHCLKFreq());
HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
memset(msg,0,sizeof(msg));
sprintf(msg,"PCLK1 : %ldHz\r\n",HAL_RCC_GetPCLK1Freq());
HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
memset(msg,0,sizeof(msg));
sprintf(msg,"PCLK2 : %ldHz\r\n",HAL_RCC_GetPCLK2Freq());
HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
CAN1_Init();
CAN_Filter_Config();
if (HAL_FDCAN_Start(&CAN1) != HAL_OK)
{
Error_Handler();
}
if (HAL_FDCAN_ConfigInterruptLines(&CAN1, FDCAN_IT_TX_COMPLETE | FDCAN_IT_RX_BUFFER_NEW_MESSAGE, FDCAN_INTERRUPT_LINE0) != HAL_OK)
{
Error_Handler();
}
if (HAL_FDCAN_ActivateNotification(&CAN1, FDCAN_IT_TX_COMPLETE | FDCAN_IT_TX_FIFO_EMPTY | FDCAN_IT_TX_EVT_FIFO_FULL | FDCAN_IT_TX_EVT_FIFO_NEW_DATA | FDCAN_IT_BUS_OFF | FDCAN_IT_RX_BUFFER_NEW_MESSAGE | FDCAN_IT_RX_FIFO0_NEW_MESSAGE | FDCAN_IT_RX_FIFO1_NEW_MESSAGE, FDCAN_TX_BUFFER0 | FDCAN_TX_BUFFER1) != HAL_OK)
{
Error_Handler();
}
user_data = " BEFORE TX CALL.\r\n";
if (HAL_UART_Transmit(&huart2,(uint8_t*)user_data,strlen(user_data), HAL_MAX_DELAY) != HAL_OK)
{
Error_Handler();
}
CAN1_TX();
user_data = " After TX call.\r\n";
if (HAL_UART_Transmit(&huart2,(uint8_t*)user_data,strlen(user_data), HAL_MAX_DELAY) != HAL_OK)
{
Error_Handler();
}
uint8_t Loop_Count = 0;
while (Loop_Count < 5)
{
Loop_Count++;
}
user_data = " END of program.\r\n";
if (HAL_UART_Transmit(&huart2,(uint8_t*)user_data,strlen(user_data), HAL_MAX_DELAY) != HAL_OK)
{
Error_Handler();
}
}
void SystemClock_Config_HSE(uint16_t Clock_Freq)
{
RCC_OscInitTypeDef OSC_Init;
RCC_ClkInitTypeDef clk_init;
uint8_t FLatency = 0;
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
OSC_Init.OscillatorType = RCC_OSCILLATORTYPE_HSE;
OSC_Init.HSEState = RCC_HSE_ON;
OSC_Init.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
OSC_Init.PLL.PLLState = RCC_PLL_ON;
OSC_Init.PLL.PLLSource = RCC_PLLSOURCE_HSE;
switch(Clock_Freq)
{
case SYS_CLOCK_FREQ_50_MHZ:
{
OSC_Init.PLL.PLLM = 1;
OSC_Init.PLL.PLLN = 25;
OSC_Init.PLL.PLLP = 2;
OSC_Init.PLL.PLLQ = 3;
OSC_Init.PLL.PLLR = 2;
clk_init.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | \
RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | \
RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
clk_init.SYSCLKDivider = RCC_SYSCLK_DIV2;
clk_init.AHBCLKDivider = RCC_HCLK_DIV1;
clk_init.APB3CLKDivider = RCC_APB3_DIV1;
clk_init.APB1CLKDivider = RCC_APB1_DIV2;
clk_init.APB2CLKDivider = RCC_APB2_DIV1;
clk_init.APB4CLKDivider = RCC_APB4_DIV1;
FLatency = FLASH_ACR_LATENCY_0WS;
break;
}
default:
return;
}
if (HAL_RCC_OscConfig(&OSC_Init) != HAL_OK)
{
Error_Handler();
}
if(HAL_RCC_ClockConfig(&clk_init, FLatency) != HAL_OK)
{
Error_Handler();
}
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
}
void CAN1_Init(void)
{
CAN1.Instance = FDCAN1;
CAN1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
CAN1.Init.Mode = FDCAN_MODE_EXTERNAL_LOOPBACK; // EXTERNAL Means FDCAN treats its own transmitted messages as received
// messages
CAN1.Init.AutoRetransmission = ENABLE;
CAN1.Init.TransmitPause = DISABLE;
CAN1.Init.ProtocolException = DISABLE;
// Setting values for 500k bps
CAN1.Init.NominalPrescaler = 3;
CAN1.Init.NominalSyncJumpWidth = 1;
CAN1.Init.NominalTimeSeg1 = 2;
CAN1.Init.NominalTimeSeg2 = 2;
CAN1.Init.DataPrescaler = 3;
CAN1.Init.DataSyncJumpWidth = 1;
CAN1.Init.DataTimeSeg1 = 2;
CAN1.Init.DataTimeSeg2 = 2;
CAN1.Init.MessageRAMOffset = 0;
CAN1.Init.StdFiltersNbr = 10;
CAN1.Init.ExtFiltersNbr = 0;
CAN1.Init.RxBuffersNbr = 64;
CAN1.Init.RxFifo0ElmtsNbr = 64;
CAN1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_32;
CAN1.Init.RxFifo1ElmtsNbr = 64;
CAN1.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_32;
CAN1.Init.RxBuffersNbr = 64;
CAN1.Init.RxBufferSize = FDCAN_DATA_BYTES_32;
CAN1.Init.TxBuffersNbr = 32;
CAN1.Init.TxEventsNbr = 32;
CAN1.Init.TxFifoQueueElmtsNbr = 32;
CAN1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
CAN1.Init.TxElmtSize = FDCAN_DATA_BYTES_16;
if (HAL_FDCAN_Init(&CAN1) != HAL_OK)
{
Error_Handler();
}
}
void CAN1_TX(void)
{
FDCAN_TxHeaderTypeDef TX_Header;
uint8_t CAN_Msg_Ptr[5] = {'H', 'E', 'L', 'L', 'R'};
TX_Header.DataLength = 1;
TX_Header.Identifier = 0x7DF;
TX_Header.IdType = FDCAN_STANDARD_ID;
TX_Header.TxFrameType = FDCAN_DATA_FRAME;
TX_Header.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
TX_Header.BitRateSwitch = FDCAN_BRS_OFF;
TX_Header.FDFormat = FDCAN_CLASSIC_CAN;
//TX_Header.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
TX_Header.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
TX_Header.MessageMarker = 0x00;
///*
if( HAL_FDCAN_AddMessageToTxBuffer(&CAN1, &TX_Header, CAN_Msg_Ptr, FDCAN_TX_BUFFER0) != HAL_OK)
{
Error_Handler();
}
//while(HAL_FDCAN_IsTxBufferMessagePending(&CAN1, FDCAN_TX_BUFFER0));
//*/
}
void CAN_Filter_Config(void)
{
FDCAN_FilterTypeDef CAN1_Filter_Init;
CAN1_Filter_Init.IdType = FDCAN_STANDARD_ID;
CAN1_Filter_Init.FilterIndex = 0;
CAN1_Filter_Init.FilterType = FDCAN_FILTER_MASK;
CAN1_Filter_Init.FilterConfig = FDCAN_FILTER_TO_RXBUFFER;
CAN1_Filter_Init.FilterID1 = 0x0000;
CAN1_Filter_Init.FilterID2 = 0x0000;
CAN1_Filter_Init.RxBufferIndex = 0;
CAN1_Filter_Init.IsCalibrationMsg = 0;
if (HAL_FDCAN_ConfigFilter(&CAN1, &CAN1_Filter_Init) != HAL_OK)
{
Error_Handler();
}
}
void HAL_FDCAN_TxEventFifoCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes)
{
user_data = " FIFO CAN Message transmitted.\r\n";
if (HAL_UART_Transmit(&huart2,(uint8_t*)user_data,strlen(user_data), HAL_MAX_DELAY) != HAL_OK)
{
Error_Handler();
}
}
void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes)
{
user_data = " Buffer CAN Message transmitted.\r\n";
if (HAL_UART_Transmit(&huart2,(uint8_t*)user_data,strlen(user_data), HAL_MAX_DELAY) != HAL_OK)
{
Error_Handler();
}
}
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
FDCAN_RxHeaderTypeDef RX_Header;
uint8_t Rcvd_msg[5];
if( HAL_FDCAN_GetRxMessage(&CAN1, FDCAN_RX_FIFO0, &RX_Header, Rcvd_msg) != HAL_OK)
{
Error_Handler();
}
memset(msg,0,sizeof(msg));
sprintf(msg,"Message received : %s\r\n",Rcvd_msg);
HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
}
void HAL_FDCAN_RxBufferNewMessageCallback(FDCAN_HandleTypeDef *hfdcan)
{
FDCAN_RxHeaderTypeDef RX_Header;
uint8_t Rcvd_msg[5];
if( HAL_FDCAN_GetRxMessage(&CAN1, FDCAN_RX_BUFFER0, &RX_Header, Rcvd_msg) != HAL_OK)
{
Error_Handler();
}
memset(msg,0,sizeof(msg));
sprintf(msg,"Message received : %s\r\n",Rcvd_msg);
HAL_UART_Transmit(&huart2,(uint8_t*)msg,strlen(msg),HAL_MAX_DELAY);
}
void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef *hfdcan)
{
user_data = "CAN BUS ERROR\r\n";
HAL_UART_Transmit(&huart2,(uint8_t*)user_data,strlen(user_data), HAL_MAX_DELAY);
while(1)
{
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_14);
HAL_Delay(500);
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_14);
HAL_Delay(500);
}
}
Solved! Go to Solution.
2020-12-27 07:25 PM
After days of troubleshooting I discovered that not all system clocks work with CAN, SYSCLK 24 MHz and HCLK 12 MHZ worked for me, but 100 MHz did not. Is there a section in user manual or datasheet to find out these details instead of trial and error?
Also bellow lines have to be included in the systemclock function.
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the peripherals clocks
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_FDCAN;
PeriphClkInit.FdcanClockSelection = RCC_FDCANCLKSOURCE_PLL;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
2020-12-27 07:25 PM
After days of troubleshooting I discovered that not all system clocks work with CAN, SYSCLK 24 MHz and HCLK 12 MHZ worked for me, but 100 MHz did not. Is there a section in user manual or datasheet to find out these details instead of trial and error?
Also bellow lines have to be included in the systemclock function.
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the peripherals clocks
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_FDCAN;
PeriphClkInit.FdcanClockSelection = RCC_FDCANCLKSOURCE_PLL;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}