cancel
Showing results for 
Search instead for 
Did you mean: 

CAN BUS and stuff bits

varani luciano
Associate III

Hello,

I'm using a ST32F466 trying to connect a personal board to a PEAK analizer.

The code is generated in part by MS32Cube, and in part by me on TrueStudio 9.2 using HAL libraries.

After setting the CAN1, (HAL_CAN_MspInit()), I have configured the CANHeader (configCANHeader()), the filter (configCANFilter())

I start the CAN (HAL_CAN_Start()), and activate IRQ on

-- Transmission complete,

-- SCE

-- Reception

Every second I try to send a frame using HAL_CAN_AddTxMessage().

Everithing seem correct if I send frames with NO SUFF BITS ( for example 8 times 0x55).

If I try to send frames with many STUFF BITS (for example 8 times 0x50) after first attempt (correct), an ERROR FRAME IS GENERATED and in the ESR register I find LEC=3

The tracks I have registered are on the micro, before the level transceiver.

Some idea?

The code in the main:

int main(void)

{

 HAL_Init();

 SystemClock_Config();

 MX_CAN1_Init();

 configCANHeader();     /* CAN Header*/

 configCANFilter();     /* CAN Filter*/

 HAL_CAN_Start(&hcan1);

 HAL_CAN_ActivateNotification(&hcan1,CAN_IT_TX_MAILBOX_EMPTY);  /*IRQ transmission enabled*/

 HAL_CAN_ActivateNotification(&hcan1,CAN_IT_LAST_ERROR_CODE);   /*IRQ SCE enabled*/

 HAL_CAN_ActivateNotification(&hcan1,CAN_IT_RX_FIFO0_MSG_PENDING);/*IRQ reception enabled*/

 while (1)

     {

    HAL_Delay(1000);

    for(uint8_t i=0;i<8;i++)

       TxData[i]=0x55; //in this case transmission is correct

    HAL_CAN_AddTxMessage(&hcan1, &TxHeader,TxData, &TxMailBox);

     }

 }

The code for initialization:

void MX_CAN1_Init(void)

{

 hcan1.Instance = CAN1;

 hcan1.Init.Prescaler = 12;               //f BUS =45Mhz  250.000 BPS

 hcan1.Init.Mode = CAN_MODE_NORMAL;

 hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;  //from 1 to 4

 hcan1.Init.TimeSeg1 = CAN_BS1_12TQ;      //from 1 to 16

 hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;       //from 1 to 8

 hcan1.Init.TimeTriggeredMode = DISABLE;

 hcan1.Init.AutoBusOff = DISABLE;

 hcan1.Init.AutoWakeUp = ENABLE;

 hcan1.Init.AutoRetransmission = DISABLE;

 hcan1.Init.ReceiveFifoLocked = DISABLE;

 hcan1.Init.TransmitFifoPriority = DISABLE;

 if (HAL_CAN_Init(&hcan1) != HAL_OK)

 {

   Error_Handler();

 }

}

void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)

{

 GPIO_InitTypeDef GPIO_InitStruct = {0};

 if(canHandle->Instance==CAN1)

 {

   HAL_RCC_CAN1_CLK_ENABLED++;

   if(HAL_RCC_CAN1_CLK_ENABLED==1){

     __HAL_RCC_CAN1_CLK_ENABLE();

   }

   __HAL_RCC_GPIOA_CLK_ENABLE();

   GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;

   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

   GPIO_InitStruct.Pull = GPIO_NOPULL;

   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_SCE_IRQn, 0, 0);

   HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn);

   HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 0, 2);

   HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);

 }

}

code for header:

void configCANHeader(void)

   {

   TxHeader.DLC=8;            /* Specifies the length of the frame that will be transmitted.

                                This parameter must be a number between Min_Data = 0 and Max_Data = 8. */

   TxHeader.IDE=CAN_ID_STD;   /* Standard Id    11 bit*/

   TxHeader.RTR=CAN_RTR_DATA; /* Specifies the type of frame for the message that will be transmitted.

                                 CAN_RTR_DATA (0x00000000U=Data frame) or CAN_RTR_REMOTE (0x00000002U=Remote frame) */

   TxHeader.StdId=0x5B9;      /* Specifies the standard identifier. This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF. */

                               /*on 11 bit-->> 101 1011 1010 = 0x5B9*/

   }

coide for the filter:

void configCANFilter(void)

   {

    sFilterConfig.FilterFIFOAssignment=CAN_FILTER_FIFO0;

    sFilterConfig.FilterIdHigh=245<<5; //0001 1110 1010 0000

    sFilterConfig.FilterIdLow=0;       //quindi su 32 bit 0001 1110 1010 0000 0000 0000 0000 0000

    sFilterConfig.FilterMaskIdHigh=0;

    sFilterConfig.FilterMaskIdLow=0;    //mask su 32 bit 0000 0000 0000 0000 0000 0000 0000 0000

    sFilterConfig.FilterScale=CAN_FILTERSCALE_32BIT;

    sFilterConfig.FilterActivation=ENABLE;

    HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig);

   }

5 REPLIES 5
turboscrew
Senior III

Have you tried with loopback?

varani luciano
Associate III

If I try to connect CAN1 to CAN2 in the same board ( is not a real loopback) , using two different transceiver, everirhing seems go right....

In this case the system use the same clock source.

Now I try a real loopback, thank you..

lv

T J
Lead

Make sure you have the CanRx pin pulled up if there is no Transceiver connected.

varani luciano
Associate III

Many thanks to all.

The transceiver is mounted on the card so I don't think there is a problem. As turboscrew suggested, I tried loopback and the reception is correct. So I think I have a problem with clock frequency or timing (SJW, BS1, BS2) although, for the latter, I've tried many different solutions.

I still don't understand, if I try to transmit 8 tumes 0x50, why the first frame is received correctly. In the event of an error the TEC register reports 8 errors , therefore an error for each byte. Note: the micro is a 446 ; nervous ....

varani luciano
Associate III

Solution.

Changing quartz .