2020-02-12 07:49 AM
Hello, I have configured project in CubeMx for above mentioned board using HAL library with 2 UART lines and CAN.
CAN line connected to Kvasar CAN dongle via this transciever https://www.ti.com/lit/ds/symlink/tcan1042-q1.pdf. While CAN transmit works perfectly, reception does not work at all. No interrupts for CAN FIFO message pending or any errors generated. Checked during debug mode in registers also. Termination resistor is also used.
Checked Rx line from transceiver to the board and CANH/CANL. Singals are present. Interrupts are enabled as well.
Code for main:
int main(void)
{
/* USER CODE BEGIN 1 */
CAN_TxHeaderTypeDef can_tx_header =
{0x6Fu, 0u, CAN_ID_STD, CAN_RTR_DATA, 2u, DISABLE};
/* Set the data to be transmitted */
TxData[0] = ubKeyNumber;
TxData[1] = 0xAD;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_CAN1_Init();
MX_TIM16_Init();
MX_USART1_UART_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
// CM_CAN_config();
CM_UART_init_IT();
CM_Set_PortB_Pin(GPIO_PIN_3);
CM_Set_PortB_Pin(GPIO_PIN_5);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3);
/* CAN sample code (does not work) */
/* Start the Transmission process */
if (HAL_CAN_AddTxMessage(&hcan1, &can_tx_header, TxData, &TxMailbox) != HAL_OK)
{
/* Transmission request Error */
Error_Handler();
}
HAL_Delay(500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSICalibrationValue = 0;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_8;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
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_0) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_USART2;
PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/** Configure the main internal regulator output voltage
*/
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
{
Error_Handler();
}
}
CAN init:
static void CM_CAN_SetFilter(CAN_HandleTypeDef * hcan);
/* USER CODE END 0 */
CAN_HandleTypeDef hcan1;
/* CAN1 init function */
void MX_CAN1_Init(void)
{
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 4;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_11TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_4TQ;
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();
}
HAL_CAN_Start(&hcan1);
if(HAL_CAN_ActivateNotification(&hcan1, (CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_RX_FIFO1_MSG_PENDING
| CAN_IT_ERROR | CAN_IT_TX_MAILBOX_EMPTY | CAN_IT_ERROR_WARNING | CAN_IT_ERROR_PASSIVE | CAN_IT_BUSOFF)) != HAL_OK)
{
Error_Handler();
}
}
void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(canHandle->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspInit 0 */
/* USER CODE END CAN1_MspInit 0 */
/* CAN1 clock enable */
__HAL_RCC_CAN1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**CAN1 GPIO Configuration
PA11 ------> CAN1_RX
PA12 ------> CAN1_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* CAN1 interrupt Init */
HAL_NVIC_SetPriority(CAN1_TX_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN1_TX_IRQn);
HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
HAL_NVIC_SetPriority(CAN1_SCE_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn);
/* USER CODE BEGIN CAN1_MspInit 1 */
/* Set filter */
CM_CAN_SetFilter(canHandle);
/* USER CODE END CAN1_MspInit 1 */
}
}
void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
{
if(canHandle->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspDeInit 0 */
/* USER CODE END CAN1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_CAN1_CLK_DISABLE();
/**CAN1 GPIO Configuration
PA11 ------> CAN1_RX
PA12 ------> CAN1_TX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
/* CAN1 interrupt Deinit */
HAL_NVIC_DisableIRQ(CAN1_TX_IRQn);
HAL_NVIC_DisableIRQ(CAN1_RX0_IRQn);
HAL_NVIC_DisableIRQ(CAN1_RX1_IRQn);
HAL_NVIC_DisableIRQ(CAN1_SCE_IRQn);
/* USER CODE BEGIN CAN1_MspDeInit 1 */
/* USER CODE END CAN1_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
static void CM_CAN_SetFilter(CAN_HandleTypeDef * hcan)
{
CAN_FilterTypeDef CAN_FilterInitStructure;
/* Default filter - accept all to CAN_FIFO*/
//CAN_InitStructure.CAN_Mode = CAN_OperatingMode_Initialization;
CAN_FilterInitStructure.FilterActivation = DISABLE; // Disable filter
CAN_FilterInitStructure.FilterBank = 0; // 0..13 for CAN1, 14..27 for CAN2
CAN_FilterInitStructure.FilterFIFOAssignment = CAN_FILTER_FIFO0;
CAN_FilterInitStructure.FilterMode = CAN_FILTERMODE_IDMASK;
CAN_FilterInitStructure.FilterScale = CAN_FILTERSCALE_32BIT;
CAN_FilterInitStructure.FilterIdHigh = 0x0000;
CAN_FilterInitStructure.FilterIdLow = 0x0000;
CAN_FilterInitStructure.FilterMaskIdHigh = 0x0000;
CAN_FilterInitStructure.FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.FilterActivation = ENABLE;
HAL_CAN_ConfigFilter(hcan, &CAN_FilterInitStructure);
};
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
CAN_RxHeaderTypeDef can_rx_msg_header;
uint8_t data[8] = {0};
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3);
if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &can_rx_msg_header, data) == HAL_OK)
{
HAL_UART_Transmit_IT(&huart1, data, (sizeof(data) / sizeof(uint8_t)));
}
}
interrupt handlers are standard generated by CubeMX for 4 interrupt vectors.
One thing I found during debug is that FINIT bit in CAN_FMR register is always 1 and in the manual there is a note: "Note: When FINIT=1, CAN reception is deactivated."
page 1622. I have tried to set it to 0 during debug, but no changes. From the other hand HAL driver should care about it anyway.
Any suggestions?
2020-02-13 06:09 AM
Problem solved.
The cause was incorrect initialization sequence, particularly filters were initialized before CAN went to state READY.
NOTE! I have seen in couple of threads about filters suggestion to not initialize it all. However, this is not the case. IN fact not initializing filter will lead to disabled Rx line.
2020-02-13 06:16 AM
First figure out why FINIT bit stays set always, after solving that it might work allready. Like you said you won't receive anything while it's set.
You can step throught the function which sets filter with debugger and look what happens.