cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103RBT6 CAN bus heavy issue

B C
Associate II
Posted on April 23, 2018 at 17:15

Hello everyone, I am trying to configure my CAN on my OLIMEXINO STM32 board : 

https://www.olimex.com/Products/Duino/STM32/OLIMEXINO-STM32/

  (with a STM32F103RBT6 �C), but it just won't work ...

I'm using a PCAN USB to communicate between my PC and my board, but there is no data exchange between my board and my computer. The Pcan software is sending me a 'bus heavy' flag and I don't know why.

Here is my code : 

int nb_trames = 4;

int ID[8] = {0x06, 0x11, 0x12, 0x13, 0x14,0x15,0x16,0x17};

Tab_TxMessages = malloc(nb_trames * sizeof(CanTxMsgTypeDef));

...

while (1)

{

   int cpt = 0 ;

   for (cpt = 0 ; cpt < nb_trames ; cpt++)

      {

      Tab_TxMessages[cpt].StdId = ID[cpt];

      Tab_TxMessages[cpt].IDE = 0;

      Tab_TxMessages[cpt].RTR = 0;

      Tab_TxMessages[cpt].DLC = 8;

      Tab_TxMessages[cpt].Data[0] = cpt;

      Tab_TxMessages[cpt].Data[1] = cpt+1;

      Tab_TxMessages[cpt].Data[2] = cpt+2;

      Tab_TxMessages[cpt].Data[3] = cpt+3;

      Tab_TxMessages[cpt].Data[4] = cpt+4;

      Tab_TxMessages[cpt].Data[5] = cpt+5;

      Tab_TxMessages[cpt].Data[6] = cpt+6;

      Tab_TxMessages[cpt].Data[7] = cpt+7;

      HAL_CAN_Transmit(&hcan, HAL_MAX_DELAY);

      HAL_Delay(1);

      }

}

(don't know how to properly format it though, if anyone can help...)

The issue is not coming from the 120 Ohm (I set the jumper correctly on the board). However it might come from the way I configure my CAN bus : 

void MX_CAN_Init(void)

{

hcan.Instance = CAN1;

hcan.Init.Prescaler = 4;

hcan.Init.Mode = CAN_MODE_NORMAL;

hcan.Init.SJW = CAN_SJW_1TQ;

hcan.Init.BS1 = CAN_BS1_8TQ;

hcan.Init.BS2 = CAN_BS2_8TQ;

hcan.Init.TTCM = DISABLE;

hcan.Init.ABOM = DISABLE;

hcan.Init.AWUM = DISABLE;

hcan.Init.NART = DISABLE;

hcan.Init.RFLM = DISABLE;

hcan.Init.TXFP = DISABLE;

if (HAL_CAN_Init(&hcan) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

}

I have no idea how to correctly configure it, so if anyone dare to explain, that might help solve the issue..

Thank you for the help !

#pcan #can-interface #olimex #stm32f103rbt6
33 REPLIES 33
Posted on April 24, 2018 at 10:34

Go with the debugger and inspect the CAN device status when the code get stuck (register TSR is essential).

Posted on April 24, 2018 at 11:12

So when it get stuck, TSR = 0x19000008 

it means that : - No transmit request pending for mailbox 1 and 2

- CODE : 01

- Transmission error for mailbox 0 (and obviously last transmission not OK)

Another register changes when it gets stuck : MSR = 0x108 (sometimes 0xD08 or 0xC08)

0x108 means that : 

- The CAN hardware is currently transmitter

- This bit is set by hardware to signal that a SOF bit has been detected while the CAN

hardware was in Sleep mode. Setting this bit generates a status change interrupt if the

WKUIE bit in the CAN_IER register is set.

This bit is cleared by software.

0xD08 means that : 

-CAN_RX pin is '1'

-The value of RX on the last sample point (current received bit value) is also '1'

- and same thing as 0x108

0xc08 means that : 

-CAN_RX pin is '1'

-The value of RX on the last sample point (current received bit value) is also '1'

- This bit is set by hardware to signal that a SOF bit has been detected while the CAN

hardware was in Sleep mode. Setting this bit generates a status change interrupt if the

WKUIE bit in the CAN_IER register is set.

This bit is cleared by software.
Posted on April 24, 2018 at 11:36

So the controller detects a transmit error.

One explanation could be that the controller failed to read back from Rx the level forced on Tx.

Can you check CAN_CTRL signal ?

If I remember correctly, the other end must acknowledge the message, so you have to make sure that speed is ok ? Did you changed your settings (BS1, BS2) ?

Posted on April 24, 2018 at 11:52

I don't find any CAN_CTRL register, so I guess you mean CAN_MCR (Master Control Register). 

It's value is : 0x10040

- CAN reception/transmission frozen during debug. Reception FIFOs can still be

accessed/controlled normally.

- master reset : normal operation

- Time Triggered Communication mode disabled.

- The Bus-Off state is left automatically by hardware once 128 occurrences of 11 recessive

bits have been monitored.

- The Sleep mode is left on software request by clearing the SLEEP bit of the CAN_MCR

register.

- The CAN hardware will automatically retransmit the message until it has been

successfully transmitted according to the CAN standard.

- Receive FIFO not locked on overrun. Once a receive FIFO is full the next incoming

message will overwrite the previous one.

- This bit controls the transmission order when several mailboxes are pending at the same

time.

0: Priority driven by the identifier of the message

- not in sleep mode

yes, I tried with your settings (BS1 11 TQ and BS2 6 TQ) and tried with mine (8 TQ and 8 TQ), the only difference there is is that with your settings my CAN monitor on my computer directly says BUSHEAVY and with my settings it says OK for a while and the BUSHEAVY, but on both cases no data is being transmitted.

EDIT : It's the ABOM bit that appears to drive the BUSHEAVY thing, if I disable it it stays on OK state. However I still don't receive any data 

Speed is also ok, tried with both 1Mb/s and 500 kb/s, nothing changes.

Posted on April 24, 2018 at 12:22

I can't find how to do it (other than checking it on the board with an oscilloscope but I don't have one ..)

T J
Lead
Posted on April 24, 2018 at 17:11

drop your speed down below the normal maximum of 250KHz, after you have it working, then you can try to go faster.

HAL_DELAY (1)  is that 1 mS ?

can you wait a little bit longer, what is the hurry ?

after you get it working, you can work on the slow bits..

where are you up to ?

You should be working on the receiver first..

Can you receive ?

Drop your speed and recheck.

B C
Associate II
Posted on April 24, 2018 at 17:21

T J wrote:

HAL_DELAY (1)  is that 1 mS ?

can you wait a little bit longer, what is the hurry ?

Yes it's 1 ms, there was no hurry, actually I tried commenting it after posting here, but nothing changed.

I tried with 250 kb/s but nothing changed, also changed the delay to 100 ms, same result.

I haven't tried receiving yet, but I'll give it a go

T J wrote:

where are you up to ?

What do you mean ? In the project ? I am basically just trying to send a bunch of data over CAN that's all.

Posted on April 24, 2018 at 17:36

Stick to 250KHz or below to start,

make the receiver work first.

here is my receiver section outside the cube init

I use 32bit frame buffers, so the interrupt time is much reduced.

caninit:

    __HAL_CAN_ENABLE_IT(&hcan, CAN_IT_FMP1);

    __HAL_CAN_ENABLE_IT(&hcan, CAN_IT_FMP0);

void CEC_CAN_IRQHandler(void) {

    /* USER CODE BEGIN CEC_CAN_IRQn 0 */

    CAN_IRQFlag = true;

    checkCanRxFifos();

    /* USER CODE END CEC_CAN_IRQn 0 */

    HAL_CAN_IRQHandler(&hcan);

    /* USER CODE BEGIN CEC_CAN_IRQn 1 */

    /* USER CODE END CEC_CAN_IRQn 1 */

}

void checkCanRxFifos(void) {

    

    int readCanBytecount;

    

    char canFifo1FullFlag = CAN->RF1R & CAN_RF1R_FMP1;

    if (canFifo1FullFlag) {

        {

            readCanBytecount = (CAN->sFIFOMailBox[1].RDTR & 0x0f);   

            canRxMsgBottomWord[canRxMsgIN]    = CAN->sFIFOMailBox[1].RDLR;

            canRxMsgTopWord[canRxMsgIN]    = CAN->sFIFOMailBox[1].RDHR;

            canRxMsgID[canRxMsgIN] = CAN->sFIFOMailBox[1].RIR >> 21;

            CAN->RF1R |= CAN_RF1R_RFOM1;                           // release FIFO

            canRxMsgLength[canRxMsgIN] =    readCanBytecount;  

            canRxMsgIN++;

            canRxMsgIN &= 0x3F;       // 64 entries only

            canRxMsgTableEMPTY = false;

            if (canRxMsgIN == canRxMsgOUT) canRxMsgTableFULL = true;

        }

        CAN->IER |= CAN_IER_FMPIE1;                              // (11)        Set FIFO1 message pending IT enable

    }

    char canFifo0FullFlag = CAN->RF0R & CAN_RF0R_FMP0;

    if (canFifo0FullFlag) {

        {

            readCanBytecount         = (CAN->sFIFOMailBox[0].RDTR & 0x0f);    

            canRxMsgBottomWord[canRxMsgIN]    = CAN->sFIFOMailBox[0].RDLR;

            canRxMsgTopWord[canRxMsgIN]    = CAN->sFIFOMailBox[0].RDHR;

            uint32_t canRxmsgID =  CAN->sFIFOMailBox[0].RIR >> 21;

            CAN->RF0R |= CAN_RF0R_RFOM0;                          // release FIFO

            if(canRxMsgTableFULL) {    

                canRxMsgTableOverflow = true;   // now dump new frame...

            }else {

                canRxMsgID[canRxMsgIN] = canRxmsgID;

                canRxMsgLength[canRxMsgIN] = readCanBytecount;       

                canRxMsgIN++;

                canRxMsgIN &= 0x3F;      // 64 entries only

                canRxMsgTableEMPTY = false;

                if (canRxMsgIN == canRxMsgOUT)

                    canRxMsgTableFULL = true;

            }

            

            //length = sprintf(string + length,'%08X, %08X :W',canFifoBuf.d32[0],canFifoBuf.d32[1]);

            //            for( int i = 0; i < readCanBytecount; i++){            

            //                canRxBuffer[canRxpointerIN++] =  canFifoBuf.d8[i];            

            //                canRxpointerIN &= 0xFF;

            //                if (canRxpointerIN == canRxpointerOUT )        CanRxbufferOverrun = true;

            //                //length += sprintf(string + length,'%02X, ',canFifoBuf.d8[i]);

            //            }

            //sprintf(string + length -2,'\n\r');        // remove 2 bytes, the last comma and space

            

        }

        CAN->IER |= CAN_IER_FMPIE0;          // (11)        Set FIFO1 message pending IT enable

    }

    //            if (length >0)  puts(string);

}

B C
Associate II
Posted on April 25, 2018 at 12:30

I am facing the same issue when I try to do the receive part, it gets stuck within the same kind of loop : 

while(__HAL_CAN_MSG_PENDING(hcan, FIFONumber) == 0U)

{

   /* Check for the Timeout */

   if(Timeout != HAL_MAX_DELAY)

   {

      if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))

      {

         hcan->State = HAL_CAN_STATE_TIMEOUT;

         /* Process unlocked */

         __HAL_UNLOCK(hcan);

         return HAL_TIMEOUT;

      }

   }

}
B C
Associate II
Posted on April 25, 2018 at 14:56

I just figured that whenever my bus is OK in PCANview, if I try to send any data through it (via the computer) it gets in 'bus-off' state..