• AVR Freaks

Hot!PIC18F26k83 ECAN Error Counters not being reset after entering Config Mode

Author
steven.heitbrink@gmail.com
New Member
  • Total Posts : 9
  • Reward points : 0
  • Joined: 2016/02/17 15:20:38
  • Location: 0
  • Status: offline
2019/05/14 18:13:29 (permalink)
0

PIC18F26k83 ECAN Error Counters not being reset after entering Config Mode

Hi
 
I'm having a problem in that I cannot get the error counters to reset and leave an error state by re-initializing the CAN controller. In section 34.2.1 it states:
 
"The error counters are cleared and the interrupt flags remain unchanged."
 
Am I missing something? After getting some TX errors from not being on a bus I recalling my initialization function which enters into Config Mode. But the errors are not cleared.  The only way I have found to clear the error is to do a total processor reset. 
#1

4 Replies Related Threads

    tam07
    New Member
    • Total Posts : 29
    • Reward points : 0
    • Joined: 2016/04/04 18:39:11
    • Location: 0
    • Status: offline
    Re: PIC18F26k83 ECAN Error Counters not being reset after entering Config Mode 2019/05/15 00:10:48 (permalink)
    0
    Hi Steven,
     
    Are you using MCC to generate your code? Can you post your code, please?
     
    Thanks,
    Tam
    #2
    steven.heitbrink@gmail.com
    New Member
    • Total Posts : 9
    • Reward points : 0
    • Joined: 2016/02/17 15:20:38
    • Location: 0
    • Status: offline
    Re: PIC18F26k83 ECAN Error Counters not being reset after entering Config Mode 2019/05/15 11:36:18 (permalink)
    0
    Hi Tam
     
    Here is a stripped down version of the what I'm doing. I think I also make have modified the MCC CAN initialization to keep it in Config mode until I decide what state to put it in. 
     
    It looks like the failure to reset the CAN happens when we take the CAN controller thru the following states:
     
    CAN_Normal_Mode -> CAN_Silent_Mode-> CAN_Disabled_Mode -> uC_Sleep -> ECAN_Initialize(); -> Silent Mode
     
    I can get it to work properly if I put it in do the CAN_Normal mode right before I go into CAN_Disable mode and sleep the whole processor. 
     
    Here is the main processor code that demonstrate the CAN not being reset: 
     

    //--------------------------------main.c-----------------------------------------------------
    #include "mcc_generated_files/mcc.h"
    #include <stdio.h>

    void debounceCallback();
    void tmr0_10msCallback();

    /** @breif configures the lsm9ds1 IMU
     * @returns 1 if successful 0 if failure
     */
    bool configImuInterrupt();


    void waitForCanDone(int8_t txBuffer);//!<breif waits for CAN transmission to complete,or be aborted before exiting
    void safeSleep();//!< \brief waits for all the non CAN based peripherals to finish before going to sleep

    /** @brief reads the interrupt registers via i2c thereby clearing them
     * @returns read result read of INT_GEN_SRC_XL
     */
    uint8_t clearImuInterrupts();


    void printIMU();//!< \brief if there is accelerometer data ready, print it, called after readIMU,

    void readIMU();//!< \brief uses a interrupt based read of the IMUs accelerometer registers


    uint8_t timer1SecFlag=0;//!< \brief flag that is set once a second.
    uint16_t tmr0_10msCount=0;//!< \brief a timer that is incremented once every 10ms and is left to overflow continously

    uint8_t buttonDownFlag=0;
    uint8_t buttonState=1;
    uint8_t buttonDownCount=0;

    uint8_t accelBuff[6]={0,0,0,0,0,0};//!< \brief global array used to store data from a non-blocking i2c read

    LSM9DS9Class imu;//!< \brief structure that stores the entire state of the imu taken from the orginal LSM9DS9 class

    /*
                             Main application
     */
    void main(void)
    {
        uCAN_MSG canMsg;
        
        int8_t txBufferIndex;
        
        // Initialize the device
        SYSTEM_Initialize();

        TMR0_SetInterruptHandler(tmr0_10msCallback);
        
        // enable CAN interrupt
        PIE5bits.RXB0IE=1;

        // If using interrupts in PIC18 High/Low Priority Mode you need to enable the Global High and Low Interrupts
        // If using interrupts in PIC Mid-Range Compatibility Mode you need to enable the Global Interrupts
        // Use the following macros to:

        // Enable high priority global interrupts
        INTERRUPT_GlobalInterruptHighEnable();

        // Enable low priority global interrupts.
        INTERRUPT_GlobalInterruptLowEnable();
       
        printf("\n\rCAN TEST\n\r");
        
        CAN_nEna_SetHigh();
        canGotoSilentMode();
        
        // Disable high priority global interrupts
        //INTERRUPT_GlobalInterruptHighDisable();
        
        // Disable low priority global interrupts.
        //INTERRUPT_GlobalInterruptLowDisable();
        
        TMR0_StartTimer();
        //IOC interrupt is enabled in SYSTEM_Initialize
        TMR1_StartTimer();
      
        canMsg.frame.idType=dSTANDARD_CAN_MSG_ID_2_0B;
        canMsg.frame.id=0x123;
        canMsg.frame.dlc=0x4;
        canMsg.frame.data0=0xA1;
        canMsg.frame.data1=0xBA;
        canMsg.frame.data3=0xD0;
        canMsg.frame.data4=0xBE;
        canMsg.frame.data5=0xEF;
        
        
        while (1)
        {
             printf("\n\r");
            CAN_nEna_SetLow();
            canGotoNormalMode();
            while(!CAN_transmit(&canMsg,&txBufferIndex));
            waitForCanDone(txBufferIndex);
            
            canGotoSilentMode();
            
            CAN_nEna_SetHigh();
            CAN_sleep();
            
            safeSleep();
            //while(!timer1SecFlag); //wait for 1 sec
            //timer1SecFlag=0;
            
            printf("TX Error Count:0x%x\n\r",TXERRCNT);
            if(TXERRCNT>0x70){
                //canGotoNormalMode();
                ECAN_Initialize();
                printf("TX Error Count After re-initialization :0x%x\n\r",TXERRCNT);
                canGotoSilentMode();
                printf("TX Error Count After going silent :0x%x\n\r",TXERRCNT);
            }
     
        }
           
    }


    void tmr0_10msCallback(){
        static int8_t count=0;
        count++;
        tmr0_10msCount++;
        if (count>=100){
            timer1SecFlag=1;
            count=0;
        }
    }

    void debounceCallback(){
        if (BUTTON_PORT==0){
            if (buttonState==1){
                buttonDownCount++;
                if (buttonDownCount==10){
                    buttonState=0;
                    buttonDownFlag=1;
                    buttonDownCount=0;
                }
            }
        }else{
            buttonState=1;
            buttonDownCount=0;
        }
    }
    void safeSleep(){
        while (!checkUart1TxDone());
        while (i2c1NonBlockingRxLockFlag);
        SLEEP();
    }



    void waitForCanDone(int8_t txBuffer){
        switch(txBuffer){
            case 0:
                while(TXB0CONbits.TXREQ){
                    if(COMSTATbits.TXWARN || COMSTATbits.TXBP){
                        CANCONbits.ABAT=1;
                        printf("CAN network error aborting TX\n\r");
                    }
                }
                break;
            case 1:
                while(TXB1CONbits.TXREQ){
                    if(COMSTATbits.TXWARN || COMSTATbits.TXBP){
                        CANCONbits.ABAT=1;
                        printf("CAN network error aborting TX\n\r");
                    }
                }
                break;
            case 2:
                while(TXB2CONbits.TXREQ){
                    if(COMSTATbits.TXWARN || COMSTATbits.TXBP){
                        CANCONbits.ABAT=1;
                        printf("CAN network error aborting TX\n\r");
                    }
                }
                break;
                
        };
    }
     

     
    //--------------ecan.h

    #include
    #include



    Global Defines

    */
    typedef union {

        struct {
            uint8_t idType;
            uint32_t id;
            uint8_t dlc;
            uint8_t data0;
            uint8_t data1;
            uint8_t data2;
            uint8_t data3;
            uint8_t data4;
            uint8_t data5;
            uint8_t data6;
            uint8_t data7;
        } frame;
        uint8_t array[14];
    } uCAN_MSG;

    /**
     Defines
    */

    #define dSTANDARD_CAN_MSG_ID_2_0B 1
    #define dEXTENDED_CAN_MSG_ID_2_0B 2

    extern volatile uint32_t canMsgCount;

    /**
      Section: CAN APIs
    */

    /**
        @Summary
            Initializes the ECAN module.

        @Description
            This routine sets all the set parameters to the ECAN module.

        @Preconditions
            None

        @Param
            None
      
        @Returns
            None
     
        @Example
            
            ECAN_Initialize();
            
    */
    void ECAN_Initialize(void);
    /**
                                                                               
        @Summary
            CAN_sleep

        @Description
            Puts the CAN module to sleep

        @Param
            None

        @Returns
            1 if success, 0 if failed to sleep due to Rxed message
     *
                                                         
    */

    uint8_t CAN_sleep(void);

    /**
        @Summary
            CAN_transmit

        @Description
            Transmits out sCAN_MSG

        @Param tempCanMsg Pointer to a sCAN_MSG
        @Param will right the index of the used to transmit if completed successfully else will return -1

        @Returns
            True or False if message was loaded to transmit buffer

        @Example
            
            uCAN_MSG txMessage;
            CAN_transmit(&txMessage);
            
    */
    uint8_t CAN_transmit(uCAN_MSG *tempCanMsg,int8_t *txBufferUsed);


    /**

     @Summary
      CAN_receive

     @Description
      Receives CAN messages

     @Param
      Pointer to a sCAN_MSG

     @Returns
      True or False for a new message
      
     @Example
      
      uCAN_MSG rxMessage;
      CAN_receive(&rxMessage);
      
                                                                                 
    */
    uint8_t CAN_receive(uCAN_MSG *tempCanMsg);

    /**
     
     @Summary
      CAN_messagesInBuffer
     
     @Description
      Checks to see how many messages are in the buffer
     
     @Param
      None

     @Returns
      Returns total number of messages in the buffers

     @Example
      
      uint8_t nrMsg;
      nrMsg = CAN_messagesInBuffer();
      
    */
    uint8_t CAN_messagesInBuffer(void);

    /**

     @Summary
      CAN_isBusOff

     @Description
      Checks to see if module is busoff

     @Param
      None

     @Returns
      True if module is in Busoff, False is if it is not

     @Example
      
      uint8_t busOff;
      busOff = CAN_isBusOff();
      
                                                      
    */

    uint8_t CAN_isBusOff(void);

    /**

     @Summary
      CAN_isRXErrorPassive

     @Description
      Checks to see if module is RX Error Passive
            
     @Param
      None
     
     @Returns
       True if module is in RX Error Passive, False is if it is not

      @Example
      
      uint8_t errRxPasive;
      errRxPasive = CAN_isRXErrorPassive();
      
                                                        
     */
     
    uint8_t CAN_isRXErrorPassive(void);

    /**

     @Summary
      CAN_isTXErrorPassive

     @Description
      Checks to see if module is TX Error Passive

     @Param
      None

     @Returns
      True if module is in TX Error Passive, False is if it is not

     @Example
      
      uint8_t errTxPasive;
      errTxPasive = CAN_isTXErrorPassive();
      

    */

    uint8_t CAN_isTXErrorPassive(void);

    /**

     @Summary
      canGoNormalMode

     
         @Description
            puts the CAN module in normal mode where it can send and receive messages

     @Param
      None

     @Returns
      None

    */
    void canGotoNormalMode(void);


    /**

     @Summary
      canGoSilentMode

        @Description
            puts the CAN module in silent mode where will recieve valid can messages but cannot send or ACK

     @Param
      None

     @Returns
      None

    */
    void canGotoSilentMode(void);

    void canGotoConfigMode(void);


    /**

     @Summary
      checkCanWake

     
     * @Description
            checks a flag to

     @Param
      None

     @Returns
      None

    */
    uint8_t checkCanWake(void);

     
     
    //---------------ecan.c
    #include <xc.h>
    #include "ecan.h"
    #include "interrupt_manager.h"
    #include "pin_manager.h"
    #include "../system.h"
    #include <stdio.h>


    volatile uint32_t canMsgCount=0;
    volatile uint8_t canWakeFlag=0;

    /**
        Local Functions
    */
    static uint32_t convertReg2ExtendedCANid(uint8_t tempRXBn_EIDH, uint8_t tempRXBn_EIDL, uint8_t tempRXBn_SIDH, uint8_t tempRXBn_SIDL);
    static uint32_t convertReg2StandardCANid(uint8_t tempRXBn_SIDH, uint8_t tempRXBn_SIDL);
    static void convertCANid2Reg(uint32_t tempPassedInID, uint8_t canIdType, uint8_t *passedInEIDH, uint8_t *passedInEIDL, uint8_t *passedInSIDH, uint8_t *passedInSIDL);

    void __interrupt(irq(RXB0IF),base(8)) ECAN_ISR_ECAN_RXB0I()
    {
        canMsgCount++;
        RXB0CONbits.RXFUL = 0;
        PIR5bits.RXB0IF = 0;
        INDICATOR_Toggle();
    }
         
    void __interrupt(irq(WAKIF),base(8)) ECAN_ISR_ECAN_WAKI()
    {
        canWakeFlag=1;
        PIR5bits.WAKIF = 0;
    }
         
    void ECAN_Initialize(void)
    {
        CANCON = 0x80;
        while (0x80 != (CANSTAT & 0xE0)); // wait until ECAN is in config mode
        
        /**
        Mode 0
        */
        ECANCON = 0x00;
        
        /**
        Initialize CAN I/O
        */
        CIOCON = 0x00;
        
        /**
        Mask and Filter definitions
        ........................................................
        CAN ID ID Type Mask Filter Buffer
        ........................................................
        0x0 SID Acceptance Mask 0 Filter 0 RXB0
        0xFF SID Acceptance Mask 0 Filter 1 RXB0
        ........................................................
        */
     
    /**
        Initialize Receive Masks
    */
        RXM0EIDH = 0x00;
        RXM0EIDL = 0x00;
        RXM0SIDH = 0x00;
        RXM0SIDL = 0x08;
        RXM1EIDH = 0xFF;
        RXM1EIDL = 0xFF;
        RXM1SIDH = 0xFF;
        RXM1SIDL = 0xE3;
     
        /**
        Initialize Receive Filters
        */
        RXF0EIDH = 0x00;
        RXF0EIDL = 0x00;
        RXF0SIDH = 0x00;
        RXF0SIDL = 0x00;
        RXF1EIDH = 0x00;
        RXF1EIDL = 0x00;
        RXF1SIDH = 0x1F;
        RXF1SIDL = 0x08;
        RXF2EIDH = 0x00;
        RXF2EIDL = 0x00;
        RXF2SIDH = 0x00;
        RXF2SIDL = 0x00;
        RXF3EIDH = 0x00;
        RXF3EIDL = 0x00;
        RXF3SIDH = 0x00;
        RXF3SIDL = 0x00;
        RXF4EIDH = 0x00;
        RXF4EIDL = 0x00;
        RXF4SIDH = 0x00;
        RXF4SIDL = 0x00;
        RXF5EIDH = 0x00;
        RXF5EIDL = 0x00;
        RXF5SIDH = 0x00;
        RXF5SIDL = 0x00;

        /**
        Initialize CAN Timings
        */
        
       /**
     Baud rate: 500kbps
     System frequency: 8000000
        ECAN clock frequency: 8000000
     Time quanta: 8
     Sample point: 1-1-4-2
     Sample point: 75%
     */
        
        BRGCON1 = 0x40;
        BRGCON2 = 0x98;
        BRGCON3 = 0x01;
    }


    /**
      Section: CAN APIs
    */

    uint8_t CAN_sleep(void)
    {
        canWakeFlag=0;
        PIR5bits.WAKIF = 0; // clear CAN bus wakeup interrupt
        PIE5bits.WAKIE = 1; // Enable CAN bus activity wakeup
        CANCON = 0x20; // request disable mode
        while ((CANSTAT & 0xE0) != 0x20){ // wait until ECAN is in disable mode
            if(canWakeFlag) return 0;
        }//Wake up from sleep should set the CAN module straight into Normal mode
        return 1;
    }

    uint8_t CAN_transmit(uCAN_MSG *tempCanMsg,int8_t *txBufferUsed) {
        uint8_t tempEIDH = 0;
        uint8_t tempEIDL = 0;
        uint8_t tempSIDH = 0;
        uint8_t tempSIDL = 0;

        uint8_t returnValue = 0;
        *txBufferUsed=-1;

        if (TXB0CONbits.TXREQ != 1)
        {
            convertCANid2Reg(tempCanMsg->frame.id, tempCanMsg->frame.idType, &tempEIDH, &tempEIDL, &tempSIDH, &tempSIDL);

            TXB0EIDH = tempEIDH;
            TXB0EIDL = tempEIDL;
            TXB0SIDH = tempSIDH;
            TXB0SIDL = tempSIDL;
            TXB0DLC = tempCanMsg->frame.dlc;
            TXB0D0 = tempCanMsg->frame.data0;
            TXB0D1 = tempCanMsg->frame.data1;
            TXB0D2 = tempCanMsg->frame.data2;
            TXB0D3 = tempCanMsg->frame.data3;
            TXB0D4 = tempCanMsg->frame.data4;
            TXB0D5 = tempCanMsg->frame.data5;
            TXB0D6 = tempCanMsg->frame.data6;
            TXB0D7 = tempCanMsg->frame.data7;

            TXB0CONbits.TXREQ = 1; //Set the buffer to transmit
            returnValue = 1;
            *txBufferUsed = 0;
            
        }
        else if (TXB1CONbits.TXREQ != 1)
        {

            convertCANid2Reg(tempCanMsg->frame.id, tempCanMsg->frame.idType, &tempEIDH, &tempEIDL, &tempSIDH, &tempSIDL);

            TXB1EIDH = tempEIDH;
            TXB1EIDL = tempEIDL;
            TXB1SIDH = tempSIDH;
            TXB1SIDL = tempSIDL;
            TXB1DLC = tempCanMsg->frame.dlc;
            TXB1D0 = tempCanMsg->frame.data0;
            TXB1D1 = tempCanMsg->frame.data1;
            TXB1D2 = tempCanMsg->frame.data2;
            TXB1D3 = tempCanMsg->frame.data3;
            TXB1D4 = tempCanMsg->frame.data4;
            TXB1D5 = tempCanMsg->frame.data5;
            TXB1D6 = tempCanMsg->frame.data6;
            TXB1D7 = tempCanMsg->frame.data7;

            TXB1CONbits.TXREQ = 1; //Set the buffer to transmit
            *txBufferUsed=1;
            returnValue = 1;
        }
        else if (TXB2CONbits.TXREQ != 1)
        {

            convertCANid2Reg(tempCanMsg->frame.id, tempCanMsg->frame.idType, &tempEIDH, &tempEIDL, &tempSIDH, &tempSIDL);

            TXB2EIDH = tempEIDH;
            TXB2EIDL = tempEIDL;
            TXB2SIDH = tempSIDH;
            TXB2SIDL = tempSIDL;
            TXB2DLC = tempCanMsg->frame.dlc;
            TXB2D0 = tempCanMsg->frame.data0;
            TXB2D1 = tempCanMsg->frame.data1;
            TXB2D2 = tempCanMsg->frame.data2;
            TXB2D3 = tempCanMsg->frame.data3;
            TXB2D4 = tempCanMsg->frame.data4;
            TXB2D5 = tempCanMsg->frame.data5;
            TXB2D6 = tempCanMsg->frame.data6;
            TXB2D7 = tempCanMsg->frame.data7;

            TXB2CONbits.TXREQ = 1; //Set the buffer to transmit
            *txBufferUsed=2;
            returnValue = 1;
        }

        return (returnValue);
    }

    uint8_t CAN_receive(uCAN_MSG *tempCanMsg)
    {
        uint8_t returnValue = 0;

             //check which buffer the CAN message is in
        if (RXB0CONbits.RXFUL != 0) //CheckRXB0
        {
            if ((RXB0SIDL & 0x08) == 0x08) //If Extended Message
            {
                //message is extended
                tempCanMsg->frame.idType = (uint8_t) dEXTENDED_CAN_MSG_ID_2_0B;
                tempCanMsg->frame.id = convertReg2ExtendedCANid(RXB0EIDH, RXB0EIDL, RXB0SIDH, RXB0SIDL);
            }
            else
            {
                //message is standard
                tempCanMsg->frame.idType = (uint8_t) dSTANDARD_CAN_MSG_ID_2_0B;
                tempCanMsg->frame.id = convertReg2StandardCANid(RXB0SIDH, RXB0SIDL);
            }

            tempCanMsg->frame.dlc = RXB0DLC;
            tempCanMsg->frame.data0 = RXB0D0;
            tempCanMsg->frame.data1 = RXB0D1;
            tempCanMsg->frame.data2 = RXB0D2;
            tempCanMsg->frame.data3 = RXB0D3;
            tempCanMsg->frame.data4 = RXB0D4;
            tempCanMsg->frame.data5 = RXB0D5;
            tempCanMsg->frame.data6 = RXB0D6;
            tempCanMsg->frame.data7 = RXB0D7;
            RXB0CONbits.RXFUL = 0;
            returnValue = 1;
        }
        else if (RXB1CONbits.RXFUL != 0) //CheckRXB1
        {
            if ((RXB1SIDL & 0x08) == 0x08) //If Extended Message
            {
                //message is extended
                tempCanMsg->frame.idType = (uint8_t) dEXTENDED_CAN_MSG_ID_2_0B;
                tempCanMsg->frame.id = convertReg2ExtendedCANid(RXB1EIDH, RXB1EIDL, RXB1SIDH, RXB1SIDL);
            }
            else
            {
                //message is standard
                tempCanMsg->frame.idType = (uint8_t) dSTANDARD_CAN_MSG_ID_2_0B;
                tempCanMsg->frame.id = convertReg2StandardCANid(RXB1SIDH, RXB1SIDL);
            }

            tempCanMsg->frame.dlc = RXB1DLC;
            tempCanMsg->frame.data0 = RXB1D0;
            tempCanMsg->frame.data1 = RXB1D1;
            tempCanMsg->frame.data2 = RXB1D2;
            tempCanMsg->frame.data3 = RXB1D3;
            tempCanMsg->frame.data4 = RXB1D4;
            tempCanMsg->frame.data5 = RXB1D5;
            tempCanMsg->frame.data6 = RXB1D6;
            tempCanMsg->frame.data7 = RXB1D7;
            RXB1CONbits.RXFUL = 0;
            returnValue = 1;
        }
        return (returnValue);
    }

    uint8_t CAN_messagesInBuffer(void)
    {
        uint8_t messageCount = 0;
        if (RXB0CONbits.RXFUL != 0) //CheckRXB0
        {
            messageCount++;
        }
        if (RXB1CONbits.RXFUL != 0) //CheckRXB1
        {
            messageCount++;
        }

        return (messageCount);
    }

    uint8_t CAN_isBusOff(void)
    {
        uint8_t returnValue = 0;

        //COMSTAT bit 5 TXBO: Transmitter Bus-Off bit
        //1 = Transmit error counter > 255
        //0 = Transmit error counter less then or equal to 255

        if (COMSTATbits.TXBO == 1) {
            returnValue = 1;
        }
        return (returnValue);
    }

    uint8_t CAN_isRXErrorPassive(void)
    {
        uint8_t returnValue = 0;

        //COMSTAT bit 3 RXBP: Receiver Bus Passive bit
        //1 = Receive error counter > 127
        //0 = Receive error counter less then or equal to 127

        if (COMSTATbits.RXBP == 1) {
            returnValue = 1;
        }
        return (returnValue);
    }

    uint8_t CAN_isTXErrorPassive(void)
    {
        uint8_t returnValue = 0;

        //COMSTAT bit 4 TXBP: Transmitter Bus Passive bit
        //1 = Transmit error counter > 127
        //0 = Transmit error counter less then or equal to 127

        if (COMSTATbits.TXBP == 1)
        {
            returnValue = 1;
        }
        return (returnValue);
    }

    /**
    Internal functions
    */


    static uint32_t convertReg2ExtendedCANid(uint8_t tempRXBn_EIDH, uint8_t tempRXBn_EIDL, uint8_t tempRXBn_SIDH, uint8_t tempRXBn_SIDL)
    {
        uint32_t returnValue = 0;
        uint32_t ConvertedID = 0;
        uint8_t CAN_standardLo_ID_lo2bits;
        uint8_t CAN_standardLo_ID_hi3bits;

        CAN_standardLo_ID_lo2bits = (uint8_t)(tempRXBn_SIDL & 0x03);
        CAN_standardLo_ID_hi3bits = (uint8_t)(tempRXBn_SIDL >> 5);
        ConvertedID = (uint32_t)(tempRXBn_SIDH << 3);
        ConvertedID = ConvertedID + CAN_standardLo_ID_hi3bits;
        ConvertedID = (ConvertedID << 2);
        ConvertedID = ConvertedID + CAN_standardLo_ID_lo2bits;
        ConvertedID = (ConvertedID << 8);
        ConvertedID = ConvertedID + tempRXBn_EIDH;
        ConvertedID = (ConvertedID << 8);
        ConvertedID = ConvertedID + tempRXBn_EIDL;
        returnValue = ConvertedID;
        return (returnValue);
    }

    static uint32_t convertReg2StandardCANid(uint8_t tempRXBn_SIDH, uint8_t tempRXBn_SIDL)
    {
        uint32_t returnValue = 0;
        uint32_t ConvertedID;
        //if standard message (11 bits)
        //EIDH = 0 + EIDL = 0 + SIDH + upper three bits SIDL (3rd bit needs to be clear)
        //1111 1111 111
        ConvertedID = (uint32_t)(tempRXBn_SIDH << 3);
        ConvertedID = ConvertedID + (uint32_t)(tempRXBn_SIDL >> 5);
        returnValue = ConvertedID;
        return (returnValue);
    }

    static void convertCANid2Reg(uint32_t tempPassedInID, uint8_t canIdType, uint8_t *passedInEIDH, uint8_t *passedInEIDL, uint8_t *passedInSIDH, uint8_t *passedInSIDL)
    {
        uint8_t wipSIDL = 0;

        if (canIdType == dEXTENDED_CAN_MSG_ID_2_0B) {

            //EIDL
            *passedInEIDL = 0xFF & tempPassedInID; //CAN_extendedLo_ID_TX1 = &HFF And CAN_UserEnter_ID_TX1
            tempPassedInID = tempPassedInID >> 8; //CAN_UserEnter_ID_TX1 = CAN_UserEnter_ID_TX1 >> 8

            //EIDH
            *passedInEIDH = 0xFF & tempPassedInID; //CAN_extendedHi_ID_TX1 = &HFF And CAN_UserEnter_ID_TX1
            tempPassedInID = tempPassedInID >> 8; //CAN_UserEnter_ID_TX1 = CAN_UserEnter_ID_TX1 >> 8

            //SIDL
            //push back 5 and or it
            wipSIDL = 0x03 & tempPassedInID;
            tempPassedInID = tempPassedInID << 3; //CAN_UserEnter_ID_TX1 = CAN_UserEnter_ID_TX1 << 3
            wipSIDL = (0xE0 & tempPassedInID) + wipSIDL;
            wipSIDL = (uint8_t)(wipSIDL + 0x08); // TEMP_CAN_standardLo_ID_TX1 = TEMP_CAN_standardLo_ID_TX1 + &H8
            *passedInSIDL = (uint8_t)(0xEB & wipSIDL); //CAN_standardLo_ID_TX1 = &HEB And TEMP_CAN_standardLo_ID_TX1

            //SIDH
            tempPassedInID = tempPassedInID >> 8;
            *passedInSIDH = 0xFF & tempPassedInID;
        }
        else //(canIdType == dSTANDARD_CAN_MSG_ID_2_0B)
        {
            *passedInEIDH = 0;
            *passedInEIDL = 0;
            tempPassedInID = tempPassedInID << 5;
            *passedInSIDL = 0xFF & tempPassedInID;
            tempPassedInID = tempPassedInID >> 8;
            *passedInSIDH = 0xFF & tempPassedInID;
        }
    }

    void canGotoNormalMode(void){
        CANCON = 0x00;
        while (0x00 != (CANSTAT & 0xE0)); // wait until ECAN is in Normal mode
        
    }

    void canGotoSilentMode(void){
        CANCON = 0x60;
        while (0x60 != (CANSTAT & 0xE0)); // wait until ECAN is in Silent mode
        
    }
    void canGotoConfigMode(){
        CANCON=0x80;
        while (0x80 != (CANSTAT & 0x80)); // wait until ECAN is in Config mode mode
    }

    uint8_t checkCanWake(void){
        if (canWakeFlag){
            canWakeFlag=0;
            return 1;
        }
        return 0;
    }

    bool checkCanRxOverflow(){
        //check if there is an overflow, in CAN MODE zero it will set these bits independently
        if (COMSTATbits.RXB0OVFL || COMSTATbits.RXB1OVFL){
            printf("CAN RX Buffer overflow\n\r");
            COMSTATbits.RXB0OVFL=0;
            COMSTATbits.RXB1OVFL=0;
            return 1;
        }
        return 0;
    }

    #3
    tam07
    New Member
    • Total Posts : 29
    • Reward points : 0
    • Joined: 2016/04/04 18:39:11
    • Location: 0
    • Status: offline
    Re: PIC18F26k83 ECAN Error Counters not being reset after entering Config Mode 2019/05/22 03:23:54 (permalink)
    0
    Hello Steven,
     
    It looks like TXERRORCNT is not cleared even after configuration mode.
     
    I suspect that when CAN_Silent_Mode is removed from the sequence, no transmit errors are detected in the bus. TXERRORCNT therefore never incremented, that's why the UART transmits TX error count of 0x00 after re-initialization.
     
    Perhaps the configuration mode should only be called once during initialization. I'm not really sure about this and I have yet to confirm.
     
    Regards,
    Tam
    #4
    steven.heitbrink@gmail.com
    New Member
    • Total Posts : 9
    • Reward points : 0
    • Joined: 2016/02/17 15:20:38
    • Location: 0
    • Status: offline
    Re: PIC18F26k83 ECAN Error Counters not being reset after entering Config Mode 2019/05/23 15:39:28 (permalink)
    0
    Thanks for looking at this TAM. 
     
    It sounds like if it is a bug, its an esoteric one, that I can avoid. 
    #5
    Jump to:
    © 2019 APG vNext Commercial Version 4.5