• AVR Freaks

Hot!dsPIC33CH CAN FD module won't exit configuration mode

Author
turnipRustler
New Member
  • Total Posts : 1
  • Reward points : 0
  • Joined: 2019/04/23 03:33:48
  • Location: 0
  • Status: offline
2019/06/12 06:54:13 (permalink)
0

dsPIC33CH CAN FD module won't exit configuration mode

Hi all,
 
I'm developing on a dsPIC33CH128MP505, and am having trouble working with the CAN FD module. 
 
I am somewhat confident that I have configured the clock stuff correctly, after which I activate the can clock generator, the module, and enter configuration mode successfully. However, after setting a few other things that must be set in configuration mode, it will not got back in to any other mode. A code snippet is shown below.
 

//Set up pins as not analogue
ANSELCbits.ANSELC1 = 0; //CAN RX
ANSELCbits.ANSELC2 = 0; //CAN TX

//Set pins as input/output (possibly unnecessary)
TRISCbits.TRISC1 = 1; //RX is input
TRISCbits.TRISC2 = 0; //TX is output
LATCbits.LATC2 = 1; //TX output is low

//Remap RP for CAN on those pins
__builtin_write_RPCON(0x0000); //Unlock PPS
RPINR26bits.CAN1RXR = 0x31; //CAN RX
RPOR9bits.RP50R = 0x15; //CAN TX
__builtin_write_RPCON(0x0800); //Re lock control registers (based on possibly erroneous unlocking earlier)

//Set some clock stuff
C1CONLbits.CLKSEL = 0x1; //Set clock source the CAN clock generator
CANCLKCONbits.CANCLKSEL = 0x5; //Set clock source to PLL VCO/4 (PLL VCO is 720MHz for 90MHz instruction clock)
CANCLKCONbits.CANCLKDIV = 0x23; //Set clock divider to 36
//This should result in a frequency of 5MHz from a 720MHz primary clock PLL VCO
CANCLKCONbits.CANCLKEN = 0x1; //Enable CAN clock generator
C1CONLbits.CON = 1; //Enable CAN module


//Ensure the CAN module is in config mode
C1CONHbits.REQOP = 4; //Set to config mode
while(C1CONHbits.OPMOD != 4){
//Wait for mode change (if required)
}

//Set operational frequency at 500kbps for both nominal bit rate and data bit rate
C1NBTCFGHbits.BRP = 0x0; //Set baud rate prescaler to 1 (nominal)
C1NBTCFGHbits.TSEG1 = 0x7; //TSEG1 = 8TQ (nominal)
C1NBTCFGLbits.TSEG2 = 0x0; //TSEG2 = 1TQ (nominal)
C1NBTCFGLbits.SJW = 0x0; //Synchonisation jump width = 1TQ (nominal)
C1DBTCFGHbits.BRP = 0x0; //Set baud rate prescaler to 1 (data)
C1DBTCFGHbits.TSEG1 = 0x7; //TSEG1 = 8TQ (data)
C1DBTCFGLbits.TSEG2 = 0x0; //TSEG2 = 1TQ (data)
C1DBTCFGLbits.SJW = 0x0; //Synchonisation jump width = 1TQ (data)

//Configure some stuff I don't completely understand from an example
C1TDCH = 0x0002; //TDCMOD is Auto
C1TDCL = 0x1F00;

// Configure CANFD module to enable Transmit Queue and BRS
C1CONLbits.BRSDIS = 0x0;
C1CONHbits.STEF = 0x0; //Don't save transmitted messages in TEF
C1CONHbits.TXQEN = 0x1;

// Configure TXQ to transmit 1 message
C1TXQCONHbits.FSIZE = 0x0; // single message
C1TXQCONHbits.PLSIZE = 0x7; // 64 bytes of data
// Configure FIFO1 to transmit 2 messages
C1FIFOCON1Hbits.FSIZE = 0x1; //2 messages
C1FIFOCON1Hbits.PLSIZE = 0x2; //16 bytes of data
C1FIFOCON1Lbits.TXEN = 0x1; // Set TXEN bit ,transmit fifo
 
// Place the CAN module in Normal  mode.
C1CONHbits.REQOP = 0x0;
while(C1CONHbits.OPMOD != 0x0);  //Idle until mode change, hangs here until watchdog timeout.

 
The microcontroller CAN Tx/Rx lines are connected to an NXP TJA1052i isolated transceiver with a 120Ω termination resistors between CAN high and CAN low. The datasheet does state that the bus needs be seen as idle to exit config mode, but surely this should be the case here: CAN Rx is high just as one might expect when the bus is recessive. Have also tried putting known good CAN devices on the bus, talking and otherwise with no change in results.
 
Just wondering if anyone has any inspired suggestions or has come across the same sort of problem themselves.
 
Thanks in advance.
#1

6 Replies Related Threads

    du00000001
    Just Some Member
    • Total Posts : 3065
    • Reward points : 0
    • Joined: 2016/05/03 13:52:42
    • Location: Germany
    • Status: offline
    Re: dsPIC33CH CAN FD module won't exit configuration mode 2019/06/13 13:08:37 (permalink)
    0
    While I have no experience with this specific CAN controller, still a very basic remark:
    with the CAN controllers I learned to know intimately, I wouldn't have dared to set messages to TX during configuration. Might be, this hinders the controller to enter normal operation.

    PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
    #2
    Stampede
    Super Member
    • Total Posts : 400
    • Reward points : 0
    • Joined: 2006/10/04 05:59:28
    • Location: Germany
    • Status: offline
    Re: dsPIC33CH CAN FD module won't exit configuration mode 2019/06/20 01:02:55 (permalink)
    5 (1)
    Hi,
     
    I also switched to the new dsPIC with the CAN FD module. I was struggling first with wrong clocking, ended up with PLL VCO/3 @ 90MIPS. The only way I would make the init routine stuck at the end when it's supposed to go back into normal mode, was a wrong configuration of the IO. It seems to happen when the (incorrectly )assigned RX Pin is reading 0 all the time, i guess the CAN FD then assumes the bus is busy and won't switch into normal mode.
     
    Besides this, I think the CAN FD needs to run at much more than 5MHz, iirc the datasheets states 20, 40 or 80Mhz.
     

        C1CONLbits.CON = 0;
        C1CONLbits.CLKSEL = 0;          // FCAN is source
        /* Enable the CANFD module */
        C1CONLbits.CON = 1;

        /* Place CAN module in configuration mode */
        C1CONHbits.REQOP = 4;
        while( C1CONHbits.OPMOD != 4);

        Ecan1ClkInit(CanBus1_Timing);
        
        /* Initialize the C1FIFOBA with the start address of the CAN FIFO message buffer area. */
        C1FIFOBAL = (unsigned int)&ecan1msgBuf;  

        // Configure CANFD module to enable Transmit Queue and BRS
        C1CONLbits.BRSDIS = 0;          // 0 = Bit Rate Switching depends on BRS in the transmit message object
        C1CONLbits.ISOCRCEN = 1;        // 1 = Includes stuff bit count in CRC field and uses non-zero CRC initialization vector
        C1CONLbits.PXEDIS = 1;          // 1 = Protocol exception is treated as a form error
        C1CONHbits.TXBWS = 3;           // Transmit Bandwidth Sharing bits
        C1CONHbits.STEF = 0;            // 0 = Do not Save transmitted messages in TEF    
        C1CONHbits.TXQEN = 1;           // 1 = Enables Transmit Message Queue (TXQ) and reserves space in RAM
        
        /* Configure FIFO1 to transmit 8 messages*/
        C1FIFOCON1Hbits.FSIZE = 0x7;    // 8 messages
        C1FIFOCON1Hbits.PLSIZE = 0x7;   // 64 bytes of data
        C1FIFOCON1Hbits.TXAT = 0;       // 00 = Disables retransmission attempts  
        C1FIFOCON1Hbits.TXPRI = 0;      // 00000 = Lowest message priority
        C1FIFOCON1Lbits.TXEN = 0x1;     // Set TXEN bit ,transmit fifo

        /* Configure FIFO2 to Receive 8 messages*/
        C1FIFOCON2Hbits.FSIZE = 0x7;    // 2 messages
        C1FIFOCON2Hbits.PLSIZE = 0x7;   // 64 bytes of data
        C1FIFOCON2Lbits.TXEN = 0x0;     // Receive fifo    
        
        /* Configure filter 0 and MASK 0 to accept any message */
        C1FLTCON0Lbits.FLTEN0 = 0;      // Disnable the filter 0
        C1FLTCON0Lbits.F0BP = 2;        // message stored in FIFO2
        C1FLTCON0Lbits.FLTEN0 = 1;

        /* Enter Normal Mode */
        C1CONHbits.REQOP = 0;           // 2 for loopback mode
        while( C1CONHbits.OPMOD != 0 );

    #3
    JPortici
    Super Member
    • Total Posts : 773
    • Reward points : 0
    • Joined: 2012/11/17 06:27:45
    • Location: Grappaland
    • Status: offline
    Re: dsPIC33CH CAN FD module won't exit configuration mode 2019/06/20 02:00:54 (permalink)
    0
    +1 on stampede. The module has to be clocked correctly (i normally use 80MHz, derived from AFPLL)
     
    Follow the reference manual to the letter. There are configuration examples you can copy and paste. This module is rather complex compared to the previous CAN controllers in dsPICs (and they weren't simple either)
     
    There are some gotchas that aren't clearly marked in the datasheet or reference manual. Look for my threads here (i had issues due to the wrong alignment of the FIFO in GP ram and a confirmed compiler bug that misuse the new bitfield instructions at certain times, forcing me to use __attribute__((optimize(0))) in functions that manipulate the CAN FIFO area)
    #4
    Stampede
    Super Member
    • Total Posts : 400
    • Reward points : 0
    • Joined: 2006/10/04 05:59:28
    • Location: Germany
    • Status: offline
    Re: dsPIC33CH CAN FD module won't exit configuration mode 2019/06/20 03:08:59 (permalink)
    0
    Jack_M
    Follow the reference manual to the letter. There are configuration examples you can copy and paste. This module is rather complex compared to the previous CAN controllers in dsPICs (and they weren't simple either)

    Agreed.
     
    Jack_M
    There are some gotchas that aren't clearly marked in the datasheet or reference manual. Look for my threads here (i had issues due to the wrong alignment of the FIFO in GP ram and a confirmed compiler bug that misuse the new bitfield instructions at certain times, forcing me to use __attribute__((optimize(0))) in functions that manipulate the CAN FIFO area)

    Can you clearify this? I haven't had any problems with the compiler, using -Os for my dsPIC CAN FD framework.
    #5
    JPortici
    Super Member
    • Total Posts : 773
    • Reward points : 0
    • Joined: 2012/11/17 06:27:45
    • Location: Grappaland
    • Status: offline
    Re: dsPIC33CH CAN FD module won't exit configuration mode 2019/06/20 04:20:31 (permalink)
    0
    in short
     
    1) the FIFO structure needs to be 4-byte aligned -> https://www.microchip.com/forums/m1094322.aspx
    It's not explicitely said in the reference manual (or it wasn't when i was writing my library. Ticket opened, it's in the limbo. let's see if it will be added)
     
    2) I was able to trigger a compiler bug that affect only dsPIC33C because it's related to the new bitfield instructions. Byte mode instructions were used incorrectly which lead to loss of data (i.e: wanted to send ID 7DF, would send ID 07F)
    The bug was configrmed by the compiler team but at this moment i have no idea of how it was caused and if it will be solved, but the official solution for now is to force optimization to zero -> https://www.microchip.com/forums/m1094183.aspx
    post edited by JPortici - 2019/06/20 04:22:28
    #6
    Stampede
    Super Member
    • Total Posts : 400
    • Reward points : 0
    • Joined: 2006/10/04 05:59:28
    • Location: Germany
    • Status: offline
    Re: dsPIC33CH CAN FD module won't exit configuration mode 2019/06/20 04:31:37 (permalink)
    0
    Hi,
     
    1) in the reference manual for CAN FD, dated 01/30/2019. I think they had the align(4) since longer.
     

     
    #include <xc.h>
    /* This code example demonstrates a method to configure the CAN FD module to transmit Standard and
    Extended ID CAN FD messages. This uses CAN1, TXQ and FIFO1. TXQ size is 1 and FIFO1 size is 2. */
    /* Include fuse configuration code here. */
    #define MAX_WORDS 100
    unsigned int __attribute__((aligned(4)))CanTxBuffer[MAX_WORDS];
    /*Data structure to implement a CANFD message buffer. */
    /* CANFD Message Time Stamp */
    typedef unsigned long CANFD_MSG_TIMESTAMP;
    /* CAN TX Message Object Control*/
    typedef struct _CANFD_TX_MSGOBJ_CTRL {
    unsigned DLC:4;
    unsigned IDE:1;
    unsigned RTR:1;
    unsigned BRS:1;
    unsigned FDF:1;
    unsigned ESI:1;
    unsigned SEQ:23;
    unsigned unimplemented1:16;
    } CANFD_TX_MSGOBJ_CTRL;
    /* CANFD TX Message ID*/
    typedef struct _CANFD_MSGOBJ_ID {
    unsigned SID:11;
    unsigned long EID:18;
    unsigned SID11:1;
    unsigned unimplemented1:2;
    } CANFD_MSGOBJ_ID;
     

     
    2). These weird bitfields are a must apperantly and also given in the datasheet. Looking at your sample code, in T3 the unimplemented:16 seems to be missing.
    This is how i use the CAN FD messages:

     
    / *****************************************************************************
        /*Data structure to implement a CANFD message buffer. */
        /* CANFD Message Time Stamp */
        typedef unsigned long CANFD_MSG_TIMESTAMP;
        typedef struct _CANFD_MSGOBJ_ID
        {
            unsigned SID:11;
            unsigned long EID:18;
            unsigned SID11:1;
            unsigned unimplemented1:2;
        } CAN_MSGOBJ_ID;
        
        /* CANFD TX Message Object Control*/
        typedef struct _CAN_TX_MSGOBJ_CTRL
        {
            unsigned DLC:4;
            unsigned IDE:1;
            unsigned RTR:1;
            unsigned BRS:1;
            unsigned FDF:1;
            unsigned ESI:1;
            unsigned SEQ:7;
            unsigned unimplemented1:16;
        } CAN_TX_MSGOBJ_CTRL;
        
        /* CANFD RX Message Object Control*/
        typedef struct _CANFD_RX_MSGOBJ_CTRL
        {
            unsigned DLC:4;
            unsigned IDE:1;
            unsigned RTR:1;
            unsigned BRS:1;
            unsigned FDF:1;
            unsigned ESI:1;
            unsigned unimplemented1:2;
            unsigned FilterHit:5;
            unsigned unimplemented2:16;
        } CAN_RX_MSGOBJ_CTRL;
        // *****************************************************************************
        /* message structure in RAM */
        typedef struct
        {
            /* Control object: DLC etc. */
            CAN_TX_MSGOBJ_CTRL Ctrl;
            /* Can ID to be used */
            uint32_t Id;
            /* Can Bus to be used */
            uint8_t     Bus;        
            /* Ticks since last time msg was sent / received */
            uint16_t    CanTick;
            /* send interval */
            uint16_t    CanSendInterval;
            /* callback function (if needed) */
            CallBackFnct MsgCallback;
            /* Msg Status */
            MSGSTATUS    MessageStatus;
            /* ECAN buffer being used to reference the message */
            #ifndef CAN_BUS_1_FD
            uint8_t     Buffer;
            uint8_t     FrameType;
            uint8_t     MessageType;
            #endif
            /* message data */
            #ifdef CAN_BUS_1_FD
            union {
                uint8_t B[64];  // Data buffer in Bytes (8 bits)
                uint16_t H[32]; // Data buffer in Half-words (16 bits)
                uint32_t W[16]; // Data buffer in words (32 bits)
                uint64_t R[8]; // Data buffer in words (32 bits)
            } Data;
            #else
            union {
                uint8_t B[8];  // Data buffer in Bytes (8 bits)
                uint16_t H[4]; // Data buffer in Half-words (16 bits)
                uint32_t W[2]; // Data buffer in words (32 bits)
                uint64_t R; // Data buffer in words (32 bits)
            } Data;         
            #endif
        } CAN_TX_MSG;

        /* message structure in RAM */
        typedef struct
        {
            /* Can DLC to be used */
            uint32_t Id;
            /* Can Bus to be used */
            uint8_t     Bus;        
            /* Ticks since last time msg was sent / received */
            uint16_t    CanTick;
            /* send interval */
            uint16_t    CanSendInterval;
            /* callback function (if needed) */
            CallBackFnct MsgCallback;
            /* Msg Status */
            MSGSTATUS    MessageStatus;
            /* Control object: DLC etc. */
            CAN_RX_MSGOBJ_CTRL Ctrl;
            #ifndef CAN_BUS_1_FD
            uint8_t     Buffer;
            uint8_t     FrameType;
            uint8_t     MessageType;
            #endif
            /* message data */
            #ifdef CAN_BUS_1_FD
            union {
                uint8_t B[64];  // Data buffer in Bytes (8 bits)
                uint16_t H[32]; // Data buffer in Half-words (16 bits)
                uint32_t W[16]; // Data buffer in words (32 bits)
                uint64_t R[8]; // Data buffer in words (32 bits)
            } Data;
            #else
            union {
                uint8_t B[8];  // Data buffer in Bytes (8 bits)
                uint16_t H[4]; // Data buffer in Half-words (16 bits)
                uint32_t W[2]; // Data buffer in words (32 bits)
                uint64_t R; // Data buffer in words (32 bits)
            } Data;         
            #endif
        } CAN_RX_MSG; 
     

     
    This works with XC16 V1.35 and V1.36B in -Os and -O0. Other are untested.
    post edited by Stampede - 2019/06/20 04:35:55
    #7
    Jump to:
    © 2019 APG vNext Commercial Version 4.5