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: Bootloader initializes Can Bus, then Application attempts to but fails

Part Number: RM46L852
Other Parts Discussed in Thread: HALCOGEN

My Boot loader sets up the CAN1 device using the following code:

   canREG1->CTL = 0x00000000U | 0x00000000U | 0x00021443U;  /* both IE0, IE1 are 1*/

    /** - Clear all pending error flags and reset current status */
    canREG1->ES = 0x0000031FU;

    /** - Assign interrupt level for messages */
    canREG1->INTMUXx[0U] = 0x00000011U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U;

    canREG1->INTMUXx[1U] = 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U
            | 0x00000000U;

Then once the bootloader is done the application it loads runs the following:

    /** - 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
    */
    canREG1->CTL = (uint32)0x00000200U 
                 | (uint32)0x00000000U 
                 | (uint32)((uint32)0x00000005U  << 10U) //0x1400
                 | (uint32)0x00020043U;
            //0x021643
    /** - Clear all pending error flags and reset current status */
    canREG1->ES |= 0xFFFFFFFFU;

    /** - Assign interrupt level for messages */
    canREG1->INTMUXx[0U] = (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U;

    canREG1->INTMUXx[1U] = (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U
                         | (uint32)0x00000000U;

    /** - Setup auto bus on timer period */
    canREG1->ABOTR = (uint32)16000000U;

But the application can not use the can bus. Both go one to make calls for each message box to complete configuration. The application will work if I load it directly without the bootloader. It seems like there is some sort of reset on the CAN devce i need to trigger but i don't know what that is. Can you help?

  • Hello Casey,

    Do you use the sys_startup.c generated through HALCoGen for the application? _c_int00() initializes the MCU register, MCU SRAM, and peripheral RAM. When code jump to the application, the CAN module is initialized for application.

  • Yes I do. and we call the generated canInit when starting our application.

  • I found two things that might help:

    The clock settings are different between the bootloader and the application, 

    and the bootloader does not use the caninit above, it uses

    static void
    CANInit(canBASE_t *node)
    {
        uint32_t iMsg;
    
    //    // Place CAN controller in init state, regardless of previous state.  This
    //    // will put the controller in idle, and allow the message object RAM to be
    //    // programmed.
    //    node->CTL = 0x00000000U | 0x00000000U | 0x00021443U;  /* both IE0, IE1 are 1*/
    //
    //    // - Clear all pending error flags and reset current status
    //    node->ES = 0x0000031FU;
    
        node->CTL = 0x00000200U
                        | 0x00000000U
                        | (0x00000005U  << 10U)
                        | 0x00020043U;
    
           /** - Clear all pending error flags and reset current status */
        node->ES |= 0xFFFFFFFFU;
    
        // - Assign interrupt level for messages
        node->INTMUXx[0U] = 0x00000000U;
        node->INTMUXx[1U] = 0x00000000U;
    
        // Setup auto bus on timer pewriod
        node->ABOTR = 16000000U;
    
        // Loop through to program all 32 message objects
        for(iMsg = 1; iMsg <= 64; iMsg++)
        {
            while (node->IF1STAT & 0x80);
    
            node->IF1CMD  = (CAN_IFCMD_WRNRD | CAN_IFCMD_ARB | CAN_IFCMD_CONTROL);
            node->IF1ARB  = 0x0;
            node->IF1MCTL = 0x0;
            node->IF1NO   = iMsg;
        }
    
        // Baud rate = 1000/[(Tseg1+Tseg2+1)*(15+1)/fosc]=1000/(8*16/16)=125khz
        //assume the VCLK is 80MHz
        if (CAN_BIT_RATE == 125000)
            node->BTR =      (1U              << 16U) |
            ((3U - 1U)          << 12U) |
            (((3U + 1U) - 1U) << 8U)  |
            ((3U - 1U)          << 6U)  |
            15U;
        else if (CAN_BIT_RATE == 250000)
            node->BTR =     (0U              << 16U) |
            ((6U - 1U)          << 12U) |
            (((3U + 6U) - 1U) << 8U)  |
            ((4U - 1U)          << 6U)  |
            19U;
        else if (CAN_BIT_RATE == 500000)
            node->BTR =     (0U             << 16U) |
            ((2U - 1U)       << 12U) |
            (((3U + 2U) - 1U) << 8U)  |
            ((2U - 1U)       << 6U)  |
            19U;
    
        else if (CAN_BIT_RATE == 750000)
            node->BTR =    (0U              << 16U) |
            ((2U - 1U)          << 12U) |
            (((7U + 2U) - 1U) << 8U)  |
            ((2U - 1U)          << 6U)  |
            8U;
        else if (CAN_BIT_RATE == 1000000)
            node->BTR =     (0U              << 16U) |
            ((1U - 1U)          << 12U) |
            (((7U + 1U) - 1U) << 8U)  |
            ((1U - 1U)          << 6U)  |
            7U;
    /*
    
        node->TIOC = 0x0000004CU;
        node->RIOC = 0x00000048U;
        node->CTL &= ~0x00000041U;
    */
        /** - Setup IF1 for data transmission
          *     - Wait until IF1 is ready for use
          *     - Set IF1 control byte
          */
          /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
          while ((node->IF1STAT & 0x80U) ==0x80U)
          {
          } /* Wait */
          node->IF1CMD  = 0x87U;
    
          /** - Setup IF2 for reading data
          *     - Wait until IF1 is ready for use
          *     - Set IF1 control byte
          */
          /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Potentially infinite loop found - Hardware Status check for execution sequence" */
          while ((node->IF2STAT & 0x80U) ==0x80U)
          {
          } /* Wait */
          node->IF2CMD = 0x17U;
    
          /** - Setup bit timing
          *     - Setup baud rate prescaler extension
          *     - Setup TSeg2
          *     - Setup TSeg1
          *     - Setup sample jump width
          *     - Setup baud rate prescaler
          */
    
    
    
           /** - CAN1 Port output values */
          node->TIOC =  (1U  << 18U )
                         | (0U  << 17U )
                         | (0U  << 16U )
                         | (1U  << 3U )
                         | (1U  << 2U )
                         | (1U << 1U );
    
          node->RIOC =  (1U  << 18U )
                         | (0U  << 17U )
                         | (0U  << 16U )
                         | (1U  << 3U )
                         | (0U  << 2U )
                         | (0U <<1U );
    //      node->TIOC = 0x0000004CU;
    //          node->RIOC = 0x00000048U;
          /** - Leave configuration and initialization mode  */
             node->CTL &= ~(0x00000041U);
    
    
    
    }

  • I eventually found that the clock settings in the bootloader were different than the clock settings in the application. It did not seem to change all of them. once I made the application use similar timing I started getting messages, but now the application sends 1 to 4 messages every time it is only supposed to send one. what would cause a duplicate message transmission if the the other node on the bus is receiving the message?

  • According to the CAN Specification, the DCAN provides a mechanism to automatically retransmit frames that have lost arbitration or have been disturbed by errors during transmission.

    By default, this automatic retransmission is enabled. It can be disabled by setting bit DAR (Disable Automatic Retransmission) in CAN Control Regis