cancel
Showing results for 
Search instead for 
Did you mean: 

CAN example for STM32f756 Nucleo doesn't work.

MC.3
Associate

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:

https://github.com/STMicroelectronics/STM32CubeF7/tree/master/Projects/STM32756G_EVAL/Examples/CAN/CAN_Networking

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:

https://github.com/STMicroelectronics/STM32CubeF4/tree/master/Projects/STM324xG_EVAL/Examples/CAN/CAN_Networking

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.

7 REPLIES 7
SofLit
ST Employee

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

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Madhan
Associate II

I'm using a CAN transceiver module based on SN65HVD230 from Texas Instruments as shown below

0693W00000JNeZcQAL.png 

and the following is the CAN transceiver module schematic (from the internet)

0693W00000JNeZmQAL.png 

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.

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

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

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.

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

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

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.

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

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.