LPC17xx CAN on 100kbit/s on IRC

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC17xx CAN on 100kbit/s on IRC

602 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by harmjan on Wed Jul 25 07:12:16 MST 2012
Hello all,

I am writing a CAN bootloader for the LPC1769, to keep the code as generic as possible I don't want to use external components such as an external oscillator. The user manual says you should be able to get 100 kbit/s on the IRC oscillator. I am getting 100.45 kbit/s according to my logic analyzer while I get a "true" 100 kbit/s when using the external oscillator of the LPCXpresso.

I have been trying to get this working for a while but on my current setup I still get a deviation high enough to lose a bit over a long message. The following are my settings and my reasoning behind those settings:
For the CAN baudrate did I use a TESG1=15 and TESG2=6. These values come from the workings baudrate from the LPCXpresso with external oscillator and a driver library I found online. According to the user manual my bittime should now be:

t_{nominal bittime} = ( TESG1 + TESG2 + 3 ) * t_{CAN clock}

Since I want a nominal bittime of 1/100000 I derived i needed a CAN clock of 2.4Mhz.

Then I choose an f_{CCO} of 480Mhz. It was between 275Mhz and 550Mhz which the user manual said was necessary and it was easy to divide back to 2.4Mhz. I used the spreadsheet from http://ics.nxp.com/support/documents/microcontrollers/xls/lpc17xx.pll.calculator.xls to calculate an the PLL0 multiplier (60) and pre-divider (1). I used the advised CPU divider of 5 so I have a CPU clock of 96Mhz. The PCLKSEL0 for the CAN2 and CANAF is divide by 1. The CAN baudrate prescaler is then 40, which should give me a CAN clock of 2.4Mhz.

Is the internal oscillator not precise enough to give me a good CAN baudrate? If it is not what is the change of failed communications with this setup? I want to load about 170 nodes on a CAN bus with this baudrate. If the internal oscillators differ won't it work or will the difference be the same on all the nodes?

Here is the code I use to setup the clock:
/**
 * Initialize the PLL0 to get a better frequency out
 * of the internal oscillator.
 */
void initClock( void ) {
    // Do this here because of errata sheet of the processor,
    // you need to set the PCLKSEL before enabling PLL0
    LPC_SC->PCLKSEL0 &= ~(3<<28); // Clear the 2 CAN clock divider bits for can peripheral 2
    LPC_SC->PCLKSEL0 |= (1<<28);  // Set the clock divider for CAN peripheral 2 to 1,
                                  // so the main clock is the CAN clock
    LPC_SC->PCLKSEL0 &= ~(3<<30); // Clear the 2 clock divider bits for the can acceptance filter
    LPC_SC->PCLKSEL0 |= (1<<30);  // Set the clock divider for acceptance filter to 1

    // Folow the setup sequence from the user manual

    // Disconnect PLL0 if it was connected
    if( LPC_SC->PLL0STAT & (1<<25) )
    {
        LPC_SC->PLL0CON &= ~(1<<1);
        clockFeed();
    }

    // Disable PLL0
    LPC_SC->PLL0CON = 0;
    clockFeed();

    // Set the CPU divider to 1
    LPC_SC->CCLKCFG = 0;

    // Set the clock source for PLL0 to the IRC
    LPC_SC->CLKSRCSEL = 0;

    // Set the Multiplier for PLL0 and load it into
    // PLL0 via a feed
    LPC_SC->PLL0CFG  = 59;
    clockFeed();

    // Enable PLL0
    LPC_SC->PLL0CON  = (1<<0); // Enable the PLL0
    clockFeed();

    // Set the CPU divide to the divider you are going
    // to use with the PLL0 connected
    LPC_SC->CCLKCFG  = 4;

    // Wait for the PLL0 to lock on the frequency
    while( !(LPC_SC->PLL0STAT & (1<<26)) );

    // Connect PLL0 to the CPU block
    LPC_SC->PLL0CON  = (1<<0) | (1<<1); // Connect the PLL0 (and keep enabled)
    clockFeed();
}
And here is the code I use to initialize the CAN:
/**
 * Setup the CAN peripheral.
 *
 * The pins for the 2th CAN peripheral are set to the right
 * mode, the power and clock are setup for the CAN peripheral
 * and CAN peripheral 2 is cleared and setup (timing and such).
 */
void initCan( void ) {
    // Set the processor pins to the correct mode
    LPC_PINCON->PINSEL0 &= ~(0x2<<8);  // Reset the function of Pin 0.4
    LPC_PINCON->PINSEL0 |= (0x2<<8);   // Set the function of Pin 0.4 to RD2
    LPC_PINCON->PINSEL0 &= ~(0x2<<10); // Reset the function of Pin 0.5
    LPC_PINCON->PINSEL0 |= (0x2<<10);  // Set the function of Pin 0.5 to TD2

    // Setup the power and clock for the peripheral
    LPC_SC->PCONP    |= (1<<14);  // Set the power bit for CAN peripheral 2

    // Setup peripheral related settings
    LPC_CAN2->MOD = 0x1; // Set the CAN peripheral in reset mode so you can change values
    LPC_CAN2->IER = 0x0; // Turn off all CAN related interrupts, they would not fire anyway
    LPC_CAN2->GSR = 0x0; // Set the error counters to 0
    // Clear everything you can via the command register
    LPC_CAN2->CMR = (0x1<<1) | // Abort transmission bit
                    (0x1<<2) | // Release receive buffer
                    (0x1<<3);  // Clear data overrun bit

    LPC_CAN2->BTR = 0xEFC027; // Set the bit rate of the CAN peripheral to 100kbit/s
                              // BRP   = 40
                              // SJW   = 3
                              // TESG1 = 15
                              // TESG2 = 6
                              // SAM   = 1

    LPC_CAN2->MOD = 0; // Enable the CAN peripheral again

    LPC_CANAF->AFMR |= (1<<1); // Set the acceptance filter in bypass mode
}
Thanks in advance.
0 Kudos
2 Replies

478 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by NXP_Europe on Wed Jul 25 13:40:26 MST 2012
Hi Harmjan,

Suggestion is use an Xtal. The IRC is simple not accurate enough. Too many possible variations.

What is the distance to the node which is far away most?
How did you connect all the nodes? Line network or branches?
0 Kudos

478 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Polux rsv on Wed Jul 25 07:42:33 MST 2012
On another recent post, it was said that the IRC is 1% precision, even up to 3% worst case. Is 97 to 103 kbit/s acceptable by all CAN devices ?

Angelo
0 Kudos