2022-01-27 02:20 AM
I have two STM32 based development boards and would like to get CAN example (slightly modified) to work with a simple data packet of 2 bytes sent from one board to the other. But I detect no valid CAN frame on the bus.
The setup is taken from here:
STM32F7 as CAN network master:
Code Source:
1. Code is executed on Nucleo-F756 board
2. Default GPIOused by example failed to work
GPIOA - PA11 (CAN TX)
GPIOA - PA12 (CAN RX)
---->Solder bridge SB132 and SB133 for USB_DP+ and USB_DP- are removed
3. GPIO pins PD0 and PD1 are used instead of PA11 and PA12.
4. CAN error frame is seen for the first three transmissions (inspected using logic analyzer) then nothing
gets transferred and so all three mailbox gets filled
modified main.c for bypassing the usage of the USER/Tamper button and the code sends data frame every 10ms.
STM32F4 as CAN network slave:
Code source:
1. Code is executed on F4-Discovery board
I have attached the code snippet for master/sender (F7) and slave/receiver (F4)
/************************** MASTER CODE ********************/
#define CANx CAN1
#define CANx_CLK_ENABLE() __HAL_RCC_CAN1_CLK_ENABLE()
#define CANx_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
#define CANx_FORCE_RESET() __HAL_RCC_CAN1_FORCE_RESET()
#define CANx_RELEASE_RESET() __HAL_RCC_CAN1_RELEASE_RESET()
/* Definition for CANx Pins */
#define CANx_TX_PIN GPIO_PIN_1
#define CANx_TX_GPIO_PORT GPIOD
#define CANx_TX_AF GPIO_AF9_CAN1
#define CANx_RX_PIN GPIO_PIN_0
#define CANx_RX_GPIO_PORT GPIOD
#define CANx_RX_AF GPIO_AF9_CAN1
/* Definition for CAN's NVIC */
#define CANx_RX_IRQn CAN1_RX0_IRQn
#define CANx_RX_IRQHandler CAN1_RX0_IRQHandler
static void MPU_Config(void);
void SystemClock_Config(void);
static void Error_Handler(void);
static void CPU_CACHE_Enable(void);
static void CAN_Config(void);
uint8_t TxData[8];
uint8_t RxData[8];
uint32_t TxMailbox;
uint8_t ubKeyNumber = 0x0;
CAN_TxHeaderTypeDef TxHeader;
CAN_RxHeaderTypeDef RxHeader;
uint8_t count=0;
CAN_HandleTypeDef Can1Handle;
void main(void){
MPU_Config();
CPU_CACHE_Enable();
HAL_Init();
SystemClock_Config();
while (1)
{
/* Set the data to be transmitted */
TxData[0] = count++;
TxData[1] = count++;
HAL_StatusTypeDef status;
/* Start the Transmission process */
status = HAL_CAN_AddTxMessage(&Can1Handle, &TxHeader, TxData, &TxMailbox);
if ( status!= HAL_OK){
//Debug code
}
else if(status ==HAL_OK){
//Debug code
}
HAL_Delay(10);
}
}
static void CAN_Config(void){
GPIO_InitTypeDef GPIO_InitStruct;
CANx_CLK_ENABLE();
CANx_GPIO_CLK_ENABLE();
GPIO_InitStruct.Pin = CANx_TX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Alternate = CANx_TX_AF;
HAL_GPIO_Init(CANx_TX_GPIO_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = CANx_RX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Alternate = CANx_RX_AF;
HAL_GPIO_Init(CANx_RX_GPIO_PORT, &GPIO_InitStruct);
/******************* CAN **********************/
CAN_FilterTypeDef sFilterConfig;
Can1Handle.Instance = CANx;
Can1Handle.Init.TimeTriggeredMode = DISABLE;
Can1Handle.Init.AutoBusOff = DISABLE;
Can1Handle.Init.AutoWakeUp = DISABLE;
Can1Handle.Init.AutoRetransmission = ENABLE;
Can1Handle.Init.ReceiveFifoLocked = DISABLE;
Can1Handle.Init.TransmitFifoPriority = DISABLE;
Can1Handle.Init.Mode = CAN_MODE_NORMAL;
Can1Handle.Init.SyncJumpWidth = CAN_SJW_1TQ;
Can1Handle.Init.TimeSeg1 = CAN_BS1_6TQ;
Can1Handle.Init.TimeSeg2 = CAN_BS2_2TQ;
Can1Handle.Init.Prescaler = 6;
if (HAL_CAN_Init(&Can1Handle) != HAL_OK){
Error_Handler();
}
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
if (HAL_CAN_ConfigFilter(&Can1Handle, &sFilterConfig) != HAL_OK){
Error_Handler();
}
if (HAL_CAN_Start(&Can1Handle) != HAL_OK){
Error_Handler();
}
if (HAL_CAN_ActivateNotification(&Can1Handle, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK){
Error_Handler();
}
TxHeader.StdId = 0x321;
TxHeader.ExtId = 0x01;
TxHeader.RTR = CAN_RTR_DATA;
TxHeader.IDE = CAN_ID_STD;
TxHeader.DLC = 2;
TxHeader.TransmitGlobalTime = DISABLE;
}
/************* SLAVE CODE ***************/
#define CANx CAN1
#define CANx_CLK_ENABLE() __HAL_RCC_CAN1_CLK_ENABLE()
#define CANx_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
#define CANx_FORCE_RESET() __HAL_RCC_CAN1_FORCE_RESET()
#define CANx_RELEASE_RESET() __HAL_RCC_CAN1_RELEASE_RESET()
/* Definition for USARTx Pins */
#define CANx_TX_PIN GPIO_PIN_1
#define CANx_TX_GPIO_PORT GPIOD
#define CANx_TX_AF GPIO_AF9_CAN1
#define CANx_RX_PIN GPIO_PIN_0
#define CANx_RX_GPIO_PORT GPIOD
#define CANx_RX_AF GPIO_AF9_CAN1
/* Definition for CAN's NVIC */
#define CANx_RX_IRQn CAN1_RX0_IRQn
#define CANx_RX_IRQHandler CAN1_RX0_IRQHandler
uint8_t ubKeyNumber = 0x0;
CAN_HandleTypeDef CanHandle;
CAN_TxHeaderTypeDef TxHeader;
CAN_RxHeaderTypeDef RxHeader;
uint8_t TxData[8];
uint8_t RxData[8];
uint32_t TxMailbox;
static void SystemClock_Config(void);
static void Error_Handler(void);
static void CAN_Config(void);
void main(void)
{
HAL_Init();
SystemClock_Config();
CAN_Config();
/* Infinite loop */
while (1){
HAL_Delay(500);
}
}
static void CAN_Config(void){
GPIO_InitTypeDef GPIO_InitStruct;
CANx_CLK_ENABLE();
CANx_GPIO_CLK_ENABLE();
GPIO_InitStruct.Pin = CANx_TX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Alternate = CANx_TX_AF;
HAL_GPIO_Init(CANx_TX_GPIO_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = CANx_RX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Alternate = CANx_RX_AF;
HAL_GPIO_Init(CANx_RX_GPIO_PORT, &GPIO_InitStruct);
HAL_NVIC_SetPriority(CANx_RX_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(CANx_RX_IRQn);
/********************** CAN ***********************/
CAN_FilterTypeDef sFilterConfig;
CanHandle.Instance = CANx;
CanHandle.Init.TimeTriggeredMode = DISABLE;
CanHandle.Init.AutoBusOff = DISABLE;
CanHandle.Init.AutoWakeUp = DISABLE;
CanHandle.Init.AutoRetransmission = ENABLE;
CanHandle.Init.ReceiveFifoLocked = DISABLE;
CanHandle.Init.TransmitFifoPriority = DISABLE;
CanHandle.Init.Mode = CAN_MODE_NORMAL;
CanHandle.Init.SyncJumpWidth = CAN_SJW_1TQ;
CanHandle.Init.TimeSeg1 = CAN_BS1_4TQ;
CanHandle.Init.TimeSeg2 = CAN_BS2_2TQ;
CanHandle.Init.Prescaler = 6;
if (HAL_CAN_Init(&CanHandle) != HAL_OK){
Error_Handler();
}
sFilterConfig.FilterBank = 1;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
if (HAL_CAN_ConfigFilter(&CanHandle, &sFilterConfig) != HAL_OK){
Error_Handler();
}
if (HAL_CAN_Start(&CanHandle) != HAL_OK){
Error_Handler();
}
if (HAL_CAN_ActivateNotification(&CanHandle, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK){
Error_Handler();
}
TxHeader.StdId = 0x321;
TxHeader.ExtId = 0x01;
TxHeader.RTR = CAN_RTR_DATA;
TxHeader.IDE = CAN_ID_STD;
TxHeader.DLC = 2;
TxHeader.TransmitGlobalTime = DISABLE;
}
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan){
if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK) {
Error_Handler();
}
if ((RxHeader.StdId == 0x321) && (RxHeader.IDE == CAN_ID_STD) && (RxHeader.DLC == 2)){
ubKeyNumber = RxData[0];
}
}
Please let me know where the issue could be, and it would be a great help.
Thanks in advance.
2022-01-27 10:00 AM
Dear @Community member ,
You said that you are using STM32f756 Nucleo/F4 Disco boards and in your code you are configuring CAN in normal mode.
So the question are:
What about your hardware? How did you connect the two boards? Are you using CAN transceivers?
SofLit
2022-01-27 11:21 PM
I'm using a CAN transceiver module based on SN65HVD230 from Texas Instruments as shown below
and the following is the CAN transceiver module schematic (from the internet)
Regarding the CAN operating mode, I believe CAN_MODE_NORMAL is the only useful mode in order to exchange messages between nodes.
I also tried bypassing the CAN transceiver module by connecting CAN_Tx and CAN_Rx (sender) to CAN_Rx and CAN_Tx (receiver) respectively, but nothing seems to work out.
2022-01-28 12:32 AM
Hello,
Regarding your schematics (the first figure):
1- Did you connect RS pin (Standby mode) of your transceivers to the ground?
2- It's not necessary to common ground the boards. CAN uses differential signaling method.
Regarding the CAN operating mode, I believe CAN_MODE_NORMAL is the only useful mode in order to exchange messages between nodes.
-> Yes. But since there is no transceivers available on Nucleo boards, I suspected you did connect the boards directly Rx to Tx which will not working. CAN is not UART or SPI ;) .
I also tried bypassing the CAN transceiver module by connecting CAN_Tx and CAN_Rx (sender) to CAN_Rx and CAN_Tx (receiver) respectively, but nothing seems to work out.
-> This is what I suspected as I said in the previous statement ;). Transceivers are a must in normal mode.
SofLit
2022-01-28 08:55 PM
1- Did you connect RS pin (Standby mode) of your transceivers to the ground?
>> Yes the Rs pin is pulled down to the ground via a 10Kohm resistor within the module, please refer to the schematic of the module from the previous reply ( I have checked the board and it does have a pull-down resistor as mentioned)
2- It's not necessary to common ground the boards. CAN uses differential signaling method.
>> Yes, but still, it's good to have one and it avoids an unknown.
CAN Tx/Rx pairs were connected directly as a last bid after all trials with CAN transceivers in place.
2022-02-01 12:28 AM
Hello,
Check your connections continuity... and check bitrates parameters of your F7 and F4 devices.
"it's good to have one and it avoids an unknown."
--> it won't solve anything.. bits are seen differentially between CAN_L and CAN_H.
SofLit
2022-02-07 11:08 PM
Hi,
I got the CAN peripheral to work across boards, there was an issue with the CAN transceiver SN65HVD230 and when replaced with TJA1051 CAN transceiver from Nexperia it worked.
Thank you so much.
2022-02-08 12:40 AM
Hello,
It seems the module featuring SN65HVD230 transceiver has issues. Someone else in the community faced the same issue: https://community.st.com/s/question/0D53W00001LSWnASAX/stm32f769idisco-using-can-interface-over-arduino-connector