Skip to main content
Suat Berkant Gulen
Associate II
October 2, 2017
Question

How can fix CAN Receive problem in Normal Mode

  • October 2, 2017
  • 6 replies
  • 2982 views
Posted on October 02, 2017 at 20:28

Hi,

I try to communicate via CAN. I can transmit data to PCAN but i can't receive in Normal Mode. When i use Loopback, i can receive data. Please Help me.. My configuration is here

/* CAN1 init function */

static void MX_CAN1_Init(void)

{

CAN_FilterConfTypeDef sFilterConfig;

static CanTxMsgTypeDef TxMessage;

static CanRxMsgTypeDef RxMessage;

/*♯♯-1- Configure the CAN peripheral ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

hcan1.Instance = CANx;

hcan1.pTxMsg = &TxMessage;

hcan1.pRxMsg = &RxMessage;

hcan1.Init.TTCM = DISABLE;

hcan1.Init.ABOM = DISABLE;

hcan1.Init.AWUM = DISABLE;

hcan1.Init.NART = DISABLE;

hcan1.Init.RFLM = DISABLE;

hcan1.Init.TXFP = DISABLE;

hcan1.Init.Mode = CAN_MODE_NORMAL;

hcan1.Init.SJW = CAN_SJW_1TQ;

hcan1.Init.BS1 = CAN_BS1_6TQ;

hcan1.Init.BS2 = CAN_BS2_7TQ;

hcan1.Init.Prescaler = 4;

if (HAL_CAN_Init(&hcan1) != HAL_OK)

{

/* Initialization Error */

Error_Handler();

}

/*♯♯-2- Configure the CAN Filter ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

sFilterConfig.FilterNumber = 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_FIFO0;

sFilterConfig.FilterActivation = ENABLE;

sFilterConfig.BankNumber = 0;

if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)

{

/* Filter configuration Error */

Error_Handler();

}

/*♯♯-3- Configure Transmission process ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

hcan1.pTxMsg->StdId = 0x321;

hcan1.pTxMsg->ExtId = 0x01;

hcan1.pTxMsg->RTR = CAN_RTR_DATA;

hcan1.pTxMsg->IDE = CAN_ID_STD;

hcan1.pTxMsg->DLC = 2;

}

And i use these functions to enable them:

if (HAL_CAN_Receive_IT(&hcan1, CAN_FIFO0) != HAL_OK)

{

/* Reception Error */

Error_Handler();

}

//////////////////////////////////////////////////////////////////////////////////////////////////

if (HAL_CAN_Transmit(&hcan1, 10) != HAL_OK)

{

/* Transmission Error */

Error_Handler();

}

My MspDeInit functions :

void HAL_CAN_MspInit(CAN_HandleTypeDef *hcan)

{

   GPIO_InitTypeDef GPIO_InitStruct;

   *♯♯-1- Enable peripherals and GPIO Clocks ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

   /* CAN1 Periph clock enable */

   CANx_CLK_ENABLE();

   /   * Enable GPIO clock ****************************************/

   CANx_GPIO_CLK_ENABLE();

   /*♯♯-2- Configure peripheral GPIO ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

   /* CAN1 TX GPIO pin configuration */

   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_PULLUP;

   GPIO_InitStruct.Alternate = CANx_TX_AF;

   HAL_GPIO_Init(CANx_TX_GPIO_PORT, &GPIO_InitStruct);

   /* CAN1 RX GPIO pin configuration */

   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_PULLUP;

   GPIO_InitStruct.Alternate = CANx_RX_AF;

   HAL_GPIO_Init(CANx_RX_GPIO_PORT, &GPIO_InitStruct);

   /*♯♯-3- Configure the NVIC ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

   /* NVIC configuration for CAN1 Reception complete interrupt */

   HAL_NVIC_SetPriority(CANx_RX_IRQn, 2, 0);

   HAL_NVIC_EnableIRQ(CANx_RX_IRQn);

}

void HAL_CAN_MspDeInit(CAN_HandleTypeDef *hcan)

{

   /*♯♯-1- Reset peripherals ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

   CANx_FORCE_RESET();

   CANx_RELEASE_RESET();

   /*♯♯-2- Disable peripherals and GPIO Clocks ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

   /* De-initialize the CAN1 TX GPIO pin */

   HAL_GPIO_DeInit(CANx_TX_GPIO_PORT, CANx_TX_PIN);

   /* De-initialize the CAN1 RX GPIO pin */

   HAL_GPIO_DeInit(CANx_RX_GPIO_PORT, CANx_RX_PIN);

   /*♯♯-4- Disable the NVIC for CAN reception ♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯♯*/

   HAL_NVIC_DisableIRQ(CANx_RX_IRQn);

}

#stm32f7
This topic has been closed for replies.

6 replies

Tesla DeLorean
Guru
October 2, 2017
Posted on October 02, 2017 at 23:23

What part are you using? What are the bus speeds? What is the CAN speed of the device sending you data?

What transceiver are you using? Is that enabled properly? Any board/design details you can share?

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Suat Berkant Gulen
Associate II
October 3, 2017
Posted on October 03, 2017 at 08:18

We use can transciever on board which is SN65HVD233MD.. My can bus speed is 1M/bit. I can transmit but can't receive.. I completely close filter. 

When i send message from PCAN-View, my interrupt not triggered and Status is ''Bus-Off''

0690X00000608PYQAY.png
Tesla DeLorean
Guru
October 5, 2017
Posted on October 05, 2017 at 16:52

Your settings are almost certainly NOT 1Mbit/s

What is the APB clock for the CAN peripheral?

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
T J
Senior III
October 2, 2017
Posted on October 03, 2017 at 00:43

hcan1.Init.ABOM = DISABLE;   <- this should be enable to enable bus recovery if a fault is detected.

your filters are enabled but no bits are set.

You have blocked receiving all addresses.

Tesla DeLorean
Guru
October 3, 2017
Posted on October 03, 2017 at 01:10

>>your filters are enabled but no bits are set. You have blocked receiving all addresses.

You sure? ID & 0 == 0 is true for all patterns

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
T J
Senior III
October 3, 2017
Posted on October 03, 2017 at 01:30

not sure, but it works if you set the filters.

by default maybe the filters should be all FF to enable all addresses.

maybe if you don't want to filter, then you could disable the feature. sFilterConfig.FilterActivation = DISABLE;

T J
Senior III
October 3, 2017
Posted on October 03, 2017 at 10:11

in the initialization, I use:

/* Enable Transmit mailbox empty Interrupt */
 __HAL_CAN_ENABLE_IT (&hcan1, CAN_IT_TME); //!< Transmit mailbox empty interrupt //
 __HAL_CAN_ENABLE_IT (&hcan1, CAN_IT_FMP0); //!< FIFO 0 message pending interrupt //
 __HAL_CAN_ENABLE_IT (&hcan1, CAN_IT_FMP1); //!< FIFO 1 message pending interrupt //
�?�?�?�?�?

in the Rx0 interrupt:

within the interrupt, I fill in a canRxMsg[table] for use in the foreground. probably under 10uSec within the interrupt.

/**
* @brief This function handles CAN1 RX0 interrupts.
*/
void CAN1_RX0_IRQHandler(void)
{
 /* USER CODE BEGIN CAN1_RX0_IRQn 0 */
 //CAN_Rx0_IRQFlag = true;
 //CAN_IRQFlag = true;
 checkCanRxFifos(); // data received before Hal can use it below.
 // this way we get the data and the interrupt stays enabled.
 /* USER CODE END CAN1_RX0_IRQn 0 */
 HAL_CAN_IRQHandler(&hcan1);
 /* USER CODE BEGIN CAN1_RX0_IRQn 1 */
 /* USER CODE END CAN1_RX0_IRQn 1 */
}
void checkCanRxFifos(void) {
 int readCanBytecount;
 char canFifo1FullFlag = CAN1->RF1R & CAN_RF1R_FMP1;
 if (canFifo1FullFlag) {
 {
 readCanBytecount = (CAN1->sFIFOMailBox[1].RDTR & 0x0f);
 canRxMsgBottomWord[canRxMsgIN] = CAN1->sFIFOMailBox[1].RDLR; // load all eight bytes in 2 cycles
 canRxMsgTopWord [canRxMsgIN] = CAN1->sFIFOMailBox[1].RDHR;
 canRxMsgID[canRxMsgIN] = CAN1->sFIFOMailBox[1].RIR >> 21;
 CAN1->RF1R |= CAN_RF1R_RFOM1; // release FIFO 
 canRxMsgLength[canRxMsgIN] = readCanBytecount;// was 0x10+ to signify FIFO1
 ++canRxMsgIN &= 0x3F;// 64 entries only
 canRxMsgTableEMPTY = false;
 if (canRxMsgIN == canRxMsgOUT) canRxMsgTableFULL = true;
 }
 CAN1->IER |= CAN_IER_FMPIE1; // (11)Set FIFO1 message pending IT enable 
 }
 char canFifo0FullFlag = CAN1->RF0R & CAN_RF0R_FMP0;
 if (canFifo0FullFlag) {
.
.
.
.
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

fabio frasi
Associate II
October 5, 2017
Posted on October 05, 2017 at 14:03

If using interrupt must to use interrupt sender

// MUST USE THIS LINE OF CODE

while(CAN_busy_check(&hcan1) == 1)HAL_Delay(1);      

hcan1.pTxMsg->StdId = 12345;

hcan1.pTxMsg->DLC = 2;

hcan1.pTxMsg->Data[0]=1;

hcan1.pTxMsg->Data[0]=2;

if(HAL_CAN_Transmit_IT(&hcan1) != HAL_OK)

fabio frasi
Associate II
October 5, 2017
Posted on October 05, 2017 at 14:06

Can init for you 500kbit

static void MX_CAN1_Init(void)

{

  hcan1.pTxMsg = &TxMessage1;

  hcan1.pRxMsg = &RxMessage1;

    

  hcan1.Instance = CAN1;

  hcan1.Init.Prescaler = 5;

  hcan1.Init.Mode = CAN_MODE_NORMAL;

  hcan1.Init.SJW = CAN_SJW_1TQ;

  hcan1.Init.BS1 = CAN_BS1_12TQ;

  hcan1.Init.BS2 = CAN_BS2_5TQ;

  hcan1.Init.TTCM = DISABLE;

  hcan1.Init.ABOM = DISABLE;

  hcan1.Init.AWUM = DISABLE;

  hcan1.Init.NART = DISABLE;

  hcan1.Init.RFLM = DISABLE;

  hcan1.Init.TXFP = DISABLE;

 

    if (HAL_CAN_Init(&hcan1) != HAL_OK)

  {

    Error_Handler();

  }

 

    sFilterConfig1.FilterNumber = 1;

  sFilterConfig1.FilterMode = CAN_FILTERMODE_IDMASK;

  sFilterConfig1.FilterScale = CAN_FILTERSCALE_32BIT;

  sFilterConfig1.FilterIdHigh = 0x0000;

  sFilterConfig1.FilterIdLow = 0x0000;

  sFilterConfig1.FilterMaskIdHigh = 0x0000;

  sFilterConfig1.FilterMaskIdLow = 0x0000;

  sFilterConfig1.FilterFIFOAssignment = 0;

  sFilterConfig1.FilterActivation = ENABLE;

  sFilterConfig1.BankNumber = 14;

 

if(HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig1) != HAL_OK)while(1);

if(HAL_CAN_Receive_IT(&hcan1, CAN_FIFO0) != HAL_OK) while(1);

    

    

    hcan1.pTxMsg->StdId = 0x00;

    hcan1.pTxMsg->ExtId = 0x00;

    hcan1.pTxMsg->RTR = CAN_RTR_DATA;

    hcan1.pTxMsg->IDE = CAN_ID_STD;

    hcan1.pTxMsg->DLC = 8;

}

Tesla DeLorean
Guru
October 5, 2017
Posted on October 05, 2017 at 16:51

Probably NOT 500k in this case.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
T J
Senior III
October 5, 2017
Posted on October 06, 2017 at 01:19

You wont be able to receive anything if ABOM is not set.

to enable automatic bus-off management, set the hcan1.Init.ABOM= ENABLE

to be sure, you should disable the filters too:   sFilterConfig1.FilterActivation = DISABLE

to check the final baud rate, transmit something and check the Scope.

I used CubeMx to calculate the baud settings.

I used CanDo hardware to transmit every 10mSec, then I made the receiver work first.

Tesla DeLorean
Guru
October 6, 2017
Posted on October 06, 2017 at 01:35

>>I used CanDo hardware to transmit every 10mSec, then I made the receiver work first.

Very good advice

>>I used CubeMx to calculate the baud settings.

It's not complicated, and easier than scoping

CAN Rate = ((APBClock / Prescaler) / (x + y + z))   where the sum is of the bit quanta widths

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
T J
Senior III
October 6, 2017
Posted on October 06, 2017 at 01:39

its so nice to see the scope running.

You can see if the data is clean, you can check the leading edges, its well recommended.

a 4 channel Color Scope like TDS2024 is a minimum level of scope for a professional engineer.