This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RM46L852: about CAN interrupt setting

Part Number: RM46L852
Other Parts Discussed in Thread: HALCOGEN

Hello!

I am using "RM46L852".

I must use the receive interrupt of CAN communication.
However, I did not get the results I wanted.

"HALCOGEN" is used to set as below,
I checked the contents of "can.c, can.h, sys_vim.c, and sys_vim.h" in the generated code and copied the related parts to my project.

Please let me know if you have any files you need to check in addition to the above mentioned files.

If you have an example that uses receive interrupts, please share. I think that will help me.

  • Hello Wooyonng,

    Your HALCoGen configuration looks good, it should generate CAN driver (can.c) with ISR as:

    #pragma CODE_STATE(can1LowLevelInterrupt, 32)

    #pragma INTERRUPT(can1LowLevelInterrupt, IRQ)

    /* SourceId : CAN_SourceId_021 */

    /* DesignId : CAN_DesignId_019 */

    /* Requirements : HL_SR221, HL_SR223 */

    void can1LowLevelInterrupt(void)

    {

       uint32 messageBox = canREG1->INT >> 16U;

    /* USER CODE BEGIN (44) */

    /* USER CODE END */

       /** - Setup IF1 for clear pending interrupt flag */

       /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */

       while ((canREG1->IF1STAT & 0x80U) ==0x80U)

       {

       } /* Wait */

       canREG1->IF1CMD = 0x08U;

       /*SAFETYMCUSW 93 S MR: 6.1,6.2,10.1,10.2,10.3,10.4 <APPROVED> "LDRA Tool issue" */

       canREG1->IF1NO  = (uint8) messageBox;

       /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */

       while ((canREG1->IF1STAT & 0x80U) ==0x80U)

       {

       } /* Wait */

       canREG1->IF1CMD = 0x87U;

       canMessageNotification(canREG1, messageBox);

    /* USER CODE BEGIN (45) */

    /* USER CODE END */

    In your main function, please enable IRQ interrupt using:

        _enable_interrupt_();

    or

    _enable_IRQ();

    The HALCoGen has a CAN example using interrupt:

      

  • The generated code is the same as your code.

    The contents of the main function.
    I can not see the problem.

    void main (void)
    {
    / * USER CODE BEGIN (3) * /
    canInit ();
    gioInit ();
    spiInit ();
    hetInit ();
    adcInit ();


         _enable_interrupt_ ();


    canEnableErrorNotification (canREG1);


    / * Enable CPU Interrupt through CPSR * /
    _enable_IRQ ();


    Is there any other file generated by HOLCOGEN than "can.c, can.h, sys_vim.c, and sys_vim.h"?
  • Hello Wooyoung,

    Please add a breakpoint in CAN ISR (can.c) to check if there is interrupt generated. Or you can add canMessageNotification() to check if there is RX interrupt:

    The following notification is from the sample code:

    /* can interrupt notification */
    /* Note-You need to remove canMessageNotification from notification.c to avoid redefinition */
    void canMessageNotification(canBASE_t *node, uint32 messageBox)
    {
    /* node 1 - transfer request */
    if(node==canREG1)
    {
    tx_done=1; /* confirm transfer request */
    }

    /* node 2 - receive complete */
    if(node==canREG2)
    {
    while(!canIsRxMessageArrived(canREG2, canMESSAGE_BOX1));
    canGetData(canREG2, canMESSAGE_BOX1, rx_ptr); /* copy to RAM */
    rx_ptr +=8;
    }

    /* Note: since only message box 1 is used on both nodes we dont check it here.*/
    }
  • Thank you for answer.

    I checked it by adding a breakpoint to the "void can1LowLevelInterrupt (void)" function, but it does not enter this function.

    However, when the following function is executed in the main function, the value comes in Rx Data.

    Can1RxID = canGetID(canREG1, canMESSAGE_BOX5);
    //while(!canIsRxMessageArrived(canREG1, canMESSAGE_BOX5));
    canGetData(canREG1, canMESSAGE_BOX5, canRxData);

    Also, when you uncomment "// while (! CanIsRxMessageArrived (canREG1, canMESSAGE_BOX5));", you will end up in an infinite loop here.

    Communication is normally performed, but no interruption occurs.

    I think there is a problem with the interrupt settings, but I do not know which part.

  • For interrupts:

    1. CPU level: _enable_IRQ() to enable the IRQ interrupt (I bit in CPSR register)
    2. VIM level: check the channel 16 or/and 29 for CAN1 high and low interrupt
    3. Module level: enable the RX interrupt (high or low, should be same as in step 2)

    Pretty straight forward. Can you check the registers if they are set correctly?

    Regards,
    QJ