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.

TMS570LS3137: Issue with CAN interruptions

Part Number: TMS570LS3137

Hello,

I have troubles trying to make work the CAN interruption.

Interruptions work fine if I configure either standard or extended CAN ID through the HAL. However, if I want to change from standard to extended CAN or from extended to standard through code, the CAN interrupt stops working. I have made two functions that help me to change from one format to another by receiving a command by SCI (UART).

With the logic analyzer I have verified that the frames are sent in the corresponding formats, but the interrupt is not triggered.

I attach below the code of both functions.

//Set standard ID for some CAN interface
void standardId(canBASE_t *canREG)
{
    /** - Initialize message 1
    *     - Wait until IF1 is ready for use
    *     - Set message mask
    *     - Set message control word
    *     - Set message arbitration
    *     - Set IF1 control byte
    *     - Set IF1 message number
    */
    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
    while ((canREG->IF1STAT & 0x80U) ==0x80U)
    {
    } /* Wait */


    canREG->IF1MSK  = 0xC0000000U | (uint32)((uint32)((uint32)0x00000000U & (uint32)0x000007FFU) << (uint32)18U);
    canREG->IF1ARB  = (uint32)0x80000000U | (uint32)0x00000000U | (uint32)0x20000000U | (uint32)((uint32)((uint32)1U & (uint32)0x000007FFU) << (uint32)18U);
    canREG->IF1MCTL = 0x00001000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U;
    canREG->IF1CMD  = (uint8) 0xF8U;
    canREG->IF1NO   = 1U;
}

//Set extended ID for some CAN interface
void extendedId(canBASE_t *canREG)
{
    /** - Setup control register
    *     - Disable automatic wakeup on bus activity
    *     - Local power down mode disabled
    *     - Disable DMA request lines
    *     - Enable global Interrupt Line 0 and 1
    *     - Disable debug mode
    *     - Release from software reset
    *     - Enable/Disable parity or ECC
    *     - Enable/Disable auto bus on timer
    *     - Setup message completion before entering debug state
    *     - Setup normal operation mode
    *     - Request write access to the configuration registers
    *     - Setup automatic retransmission of messages
    *     - Disable error interrupts
    *     - Disable status interrupts
    *     - Enter initialization mode
    */
    canREG->CTL = (uint32)0x00000000U
              | (uint32)0x00000020U
              | (uint32)((uint32)0x00000005U << 10U)
              | 0x00020043U;

    /** - Initialize message 1
    *     - Wait until IF1 is ready for use
    *     - Set message mask
    *     - Set message control word
    *     - Set message arbitration
    *     - Set IF1 control byte
    *     - Set IF1 message number
    */
    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
    while ((canREG->IF1STAT & 0x80U) ==0x80U)
    {
    } /* Wait */


    canREG->IF1MSK  = 0xC0000000U | (uint32)((uint32)((uint32)0x00000000U & (uint32)0x1FFFFFFFU) << (uint32)0U);
    canREG->IF1ARB  = (uint32)0x80000000U | (uint32)0x40000000U | (uint32)0x20000000U | (uint32)((uint32)((uint32)1U & (uint32)0x1FFFFFFFU) << (uint32)0U);
    canREG->IF1MCTL = 0x00001000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U;
    canREG->IF1CMD  = (uint8) 0xF8U;
    canREG->IF1NO   = 1U;

    /** - Leave configuration and initialization mode  */
    canREG->CTL &= ~(uint32)(0x00000041U);
}

Thanks a lot and regards,

Leandro

  • The standardID() function doesn't enable the CAN interrupt and the CAN module is still in initialization mode.

  • Please post your main() function.

  • Hello QJ,

    I realized that my mistake was working with the wrong registry. Now it works correctly (at least for now). Anyway I leave the main and a function called sysInit() that initializes the interfaces. Thank you.

    main() function:

    int main(void)
    {
    /* USER CODE BEGIN (3) */
        sysInit();  //System initialization.
        osInit();   //Operative System initialization.
    
        /* Run forever */
        while(1);
    
    /* USER CODE END */
    
        return 0;
    }

    sysInit() function:

    /********************
     * sysInit function *
     ********************/
    void sysInit()
    {
        uint8_t generic = 0;
        sciInit();                                      //SCI initialization.
        canInit();                                      //CAN initialization.
        spiInit();                                      //SPI initialization.
    
        //Enable interrupts:
        _enable_interrupt_();                           //General interrupt flag.
        //Enable SCI interrupt:
        sciEnableNotification(scilinREG,SCI_RX_INT);    //Enable SCI interrupt by Rx.
        //Enable CAN interrupt:
        canEnableErrorNotification(canREG2);            //Enable canREG2 interrupt.
        canEnableErrorNotification(canREG3);            //Enable canREG3 interrupt.
    
        sciReceive(scilinREG,1, (unsigned char *)&generic);
    
        sciSend(scilinREG, 37, (unsigned char *)"Initializing system. Please wait...\r\n");
        gioInit();                                      //GIO module initialization.
        gioSetDirection(hetPORT1, 1 << 15);             //Enable N2HET1[15] as output. This is the output signal to the external watch-dog.
        gioSetDirection(spiPORT3, 0x11);                //to set the SPI3NCS[0] to output direction. The SPI3NCS[0] is the bit0 of SPIPC1 register.
                                                        //to set the SPI3NCS[4] to output direction. The SPI3NCS[4] is the bit4 of SPIPC1 register.
        gioSetDirection(mibspiPORT5, 0 <<9);
        gioSetDirection(mibspiPORT1, 0 <<1);
        gioSetBit(spiPORT3, 0, 1);                      //Disable External memories SPI communication
        gioSetBit(spiPORT3, 4, 1);                      //Disable External memories SPI communication
    
        sExtMem(0);                                     //Set external memory U22 in low power mode.
        sExtMem(4);                                     //Set external memory U23 in low power mode.
    
        sciSend(scilinREG, 27, (unsigned char *)"\t************************\r\n");
        sciSend(scilinREG, 27, (unsigned char *)"\tLabOSat-02 [OBC] OS V1.0\r\n");
        sciSend(scilinREG, 27, (unsigned char *)"\t************************\r\n");
        sciSend(scilinREG, 1, (unsigned char *)"\n");
        sciSend(scilinREG, 14, (unsigned char *)"Developers: \r\n");
        sciSend(scilinREG, 30, (unsigned char *)"\t Gagliardi Leandro Luciano \r\n");
        sciSend(scilinREG, 22, (unsigned char *)"\t Di Nardo Federico \r\n");
        sciSend(scilinREG, 1, (unsigned char *)"\n");
    }

    I merged both function in only one called sizeId(). It works fine for now :).

    void sizeId(canBASE_t *canREG, bool size)
    {
        /** - Setup control register
        *     - Disable automatic wakeup on bus activity
        *     - Local power down mode disabled
        *     - Disable DMA request lines
        *     - Enable global Interrupt Line 0 and 1
        *     - Disable debug mode
        *     - Release from software reset
        *     - Enable/Disable parity or ECC
        *     - Enable/Disable auto bus on timer
        *     - Setup message completion before entering debug state
        *     - Setup normal operation mode
        *     - Request write access to the configuration registers
        *     - Setup automatic retransmission of messages
        *     - Disable error interrupts
        *     - Disable status interrupts
        *     - Enter initialization mode
        */
        canREG->CTL = (uint32)0x00000000U
                  | (uint32)0x00000020U
                  | (uint32)((uint32)0x00000005U << 10U)
                  | 0x00020043U;
    
        /** - Initialize message 1
        *     - Wait until IF1 is ready for use
        *     - Set message mask
        *     - Set message control word
        *     - Set message arbitration
        *     - Set IF1 control byte
        *     - Set IF1 message number
        */
        /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
        while ((canREG->IF1STAT & 0x80U) ==0x80U)
        {
        } /* Wait */
    
        switch (size)
        {
        case false:
            if(canREG == canREG2)
            {
                canREG2->IF2MSK  = 0xC0000000U | (uint32)((uint32)((uint32)0x00000000U & (uint32)0x000007FFU) << (uint32)18U);
                canREG2->IF2ARB  = (uint32)0x80000000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)((uint32)((uint32)2U & (uint32)0x000007FFU) << (uint32)18U);
                canREG2->IF2MCTL = 0x00001000U | (uint32)0x00000400U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U;
                canREG2->IF2CMD  = (uint8) 0xF8U;
                canREG2->IF2NO   = 2U;
            }else if (canREG == canREG3)
            {
                canREG3->IF1MSK  = 0xC0000000U | (uint32)((uint32)((uint32)0x00000000U & (uint32)0x000007FFU) << (uint32)18U);
                canREG3->IF1ARB  = (uint32)0x80000000U | (uint32)0x00000000U | (uint32)0x20000000U | (uint32)((uint32)((uint32)1U & (uint32)0x000007FFU) << (uint32)18U);
                canREG3->IF1MCTL = 0x00001000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U;
                canREG3->IF1CMD  = (uint8) 0xF8U;
                canREG3->IF1NO   = 1U;
            }
            break;
        case true:
            if(canREG == canREG2)
            {
                canREG2->IF2MSK  = 0xC0000000U | (uint32)((uint32)((uint32)0x00000000U & (uint32)0x1FFFFFFFU) << (uint32)0U);
                canREG2->IF2ARB  = (uint32)0x80000000U | (uint32)0x40000000U | (uint32)0x00000000U | (uint32)((uint32)((uint32)2U & (uint32)0x1FFFFFFFU) << (uint32)0U);
                canREG2->IF2MCTL = 0x00001000U | (uint32)0x00000400U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U;
                canREG2->IF2CMD  = (uint8) 0xF8U;
                canREG2->IF2NO   = 2U;
            }else if (canREG == canREG3)
            {
                canREG3->IF1MSK  = 0xC0000000U | (uint32)((uint32)((uint32)0x00000000U & (uint32)0x1FFFFFFFU) << (uint32)0U);
                canREG3->IF1ARB  = (uint32)0x80000000U | (uint32)0x40000000U | (uint32)0x20000000U | (uint32)((uint32)((uint32)1U & (uint32)0x1FFFFFFFU) << (uint32)0U);
                canREG3->IF1MCTL = 0x00001000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)0x00000000U | (uint32)8U;
                canREG3->IF1CMD  = (uint8) 0xF8U;
                canREG3->IF1NO   = 1U;
            }
    
            break;
        default:
            break;
        }
        /** - Leave configuration and initialization mode  */
        canREG->CTL &= ~(uint32)(0x00000041U);
    
        canEnableErrorNotification(canREG2);            //Enable canREG2 interrupt.
        canEnableErrorNotification(canREG3);            //Enable canREG3 interrupt.
    }

    Regards,

    Leandro

  • Hi Leandro,

    I realized that my mistake was working with the wrong registry.

    Good to hear that your code is working.

    --

    Thanks & Regards,

    Jagadish.