cancel
Showing results for 
Search instead for 
Did you mean: 

CAN Bus Comminucation

Ramazan Gülcan
Associate III
Posted on March 08, 2018 at 10:32

Hi,

Do you have an example of CAN BUS Communication can be done with the current version HAL and CubeMx?

Regards

Ramazan

#can-bus

Note: this post was migrated and contained many threaded conversations, some content may be missing.
29 REPLIES 29
Posted on March 09, 2018 at 14:51

Thanks for the answer.

Good works.

Regards

Ramazan

Posted on March 13, 2018 at 11:15

I have got one doubt. I am using stm32f767BI microcontroller which have 3 CAN buses.

Should we need to select different 'Bank number' for each of CAN bus or is it fine to use same bank number?

Should we need to follow any guidelines in selection of bank number?

Regards

Gowtham Kalangi

Posted on March 14, 2018 at 00:38

I believe the different CAN BUS Modules use different bank numbers,

please check the Reference Manual for details..

Posted on March 29, 2018 at 11:30

One question: why is it necessary insert '__HAL_UNLOCK(&hcan1);' in 'CAN1_RX0_IRQHandler' routine?

Posted on March 29, 2018 at 11:58

Hello Luca,

Good question. Thanks for it, because it is important to know the background.

The reason is quite simple. It is a bug discovered in CAN library not only for L4, but also for other STM32 families. Normally HAL should unlock CAN automatically, but in many cases it wasn't and as a result after reception of first message CAN peripheral stopped to receive incoming messages. The easiest solution was to add __HAL_UNLOCK(&hcan1);

This issue was discovered already some time ago, so it could be that it is already fixed and calling unlcok macro is not needed anymore.

Regards

Szymon

Posted on March 29, 2018 at 13:01

Thank you for your reply.

I'm testing one application with 3 differente device that send random data with random timeout (from 1 to 10 ms): two with two STM32L433 nucleo and one with STM32F446 nucleo and with TJA1044GT NXP transceiver. I enabled RX, TX and Error interrupt and I manage all counters of packets and errors (for report) inside interrupt (if I use the interrupt routine only for set flag and sent/read data from MainLoop, I lose some packets).

If I do not insert '__HAL_UNLOCK(&hcan1);' instruction in RX and Error ISR, I lose many packets sent by others devices.

Furthermore, with a send-timeout from 1ms to 10ms inside RX and Error interrupt routines, I have to (in this order):

- __HAL_UNLOCK(&hcan1);

- HAL_CAN_Receive_IT(&hcan1,CAN_FIFO0);

- manage data received or errors

otherwise many packets will be lost and many errors will be generated.

Posted on March 29, 2018 at 17:21

I have a doubt about CAN library: the routine that manage the Rx interrupt release the FIFO with '__HAL_CAN_FIFO_RELEASE' macro but, if the FMPx value is greater that 1 and no other interrupt occour, the other pending messages in the FIFO are not read.

Is it correct my consideration? Is it a bug or I have to use in different way the libraries?

I'm using two different devices: STM32F446 and STM32L433.
Posted on March 30, 2018 at 01:08

I pull the data from the fifos before HAL gets to it.

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;          // to signify FIFO0

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

}

Posted on March 30, 2018 at 10:14

One question: if 'canFifo1FullFlag ' or 'canFifo0FullFlag' are greater than 1 you read however only the first message and you have to wait next interrupt to read the remaining messages, is it correct?

Posted on March 30, 2018 at 11:13

actually, if any FiFo has data, I grab it here, before HAL sees it.

HAL remains happy and enabled with HAL_OK status.

I pull the data from the peripheral using 32bit arrays for speed, in and out under 20uS

at 250 KHz from the CanDo unit, I didnt drop a frame on the '091, 48MHz chip.

I use a foreground process like a state machine, I pick up the data there.