Forums

LPC2378 on Olimex board: CAN transmission problem

Started by stefan_bluhm October 7, 2011
Hi all,

I am very new to microprocessor development and am still figuring out the way things work on the LPC2378 as well as the Olimex board. So up front apologies for "stupid" questions. I am also not expecting answers but hints on how things could work (although answers are obviously appreciated :) ).

What I am trying to do is to transmit CAN data from the Olimex LPC2378 to a second CAN adapter. My setup is as follows:

Olimex LPC2378 board CAN port connected to a CANUSB adapter which in turn is connected to the PC. The Olimex should have a 120 Ohm Resistor on the board which is enabled. I put another 120 Ohm resistor across the cable fixes.

The PC is not receiving any data from the LPC.

1) can anyone please send me a working binary for the Olimex LPC 2378 which is sending any data to the CAN bus? This way I can verify/confirm my environment setup.

2) can you maybe spot why my code is not working? I tried different combinations of BTR but I am not sure why it is not working. The buffer seems to fill the first time it goes into that loop and it just never submits or can't submit.

Thank you for your help and ideas,

Stefan
#include "LPC23xx.h"
#include "type.h"
#include "irq.h"
#include "target.h"

#define SoftwareInterrupt asm (" swi #02")
#define CR 0x0D

int cansendchar(void);
void init_can (void);
/**********************************************************
MAIN
**********************************************************/

int main (void) {

long j=0; // loop counter (stack variable)
SoftwareInterrupt;
PINSEL4 = 0x00100000; //Enable the EXTINT1 interrupt

VICIntSelect = 0x00004000;
VICIntEnable = 0x00004000; //enable interrupt

init_can();
// set io pins for led P1.19
IODIR1 |= 0x00080000; // pin P1.19 is an output
IOSET1 = 0x00080000; // led on
IOCLR1 = 0x00080000; // led ofF

// endless loop to toggle the red LED P0.19
j = 0;
while (1)
{
if( j == 100000 ) {
IOCLR1 = 0x00080000;
cansendchar();
}
if( j == 200000 ) {
IOSET1 = 0x00080000;
j = 0;
}
j = j + 1;
}
return (0);
}
void init_can (void) { /* Initialize Serial Interface */
// Configure CAN 2
PINSEL0 |= 0x200; // P0.4 = RD2 (10)
PINSEL0 |= 0x800; // P0.5 = TD2 (10)
PINMODE0 |= 0x800; // PORT0 pin 4 on-chip pull-up/down resistor control. 100000000000
PINMODE0 |= 0x2000; // PORT0 pin 5 on-chip pull-up/down resistor control. 10000000000000
PCONP |= 0x4000; // Enable Power to CAN2 on bit 14 ( On reset, CAN1/2 are disabled )
PCONP |= 0x2000; // Enable Power to CAN1 on bit 13 ( On reset, CAN1/2 are disabled )
PCONP |= 0x6000; // Enable Power to CAN1+2 on bit 14 ( On reset, CAN1/2 are disabled )
PCLKSEL0 |= 0x8000000; // (01) Peripheral clock selection for CAN1 on bit 27:26
PCLKSEL0 |= 0x20000000; // (01) Peripheral clock selection for CAN2 on bit 29:28
PCLKSEL0 |= 0x80000000; // (01) Peripheral clock selection for ACF on bit 31:30

// Clock must be set?
CAN2MOD |= 0x00000001; //Set CAN controller 2 into reset
CAN2IER = 0; // Disable Receive Interrupt
CAN2GSR = 0; // Reset error counter when CANxMOD is in reset
CLKSRCSEL = 0x01; // Selects the main oscillator as the PLL clock source.
CAN2BTR = 0x0B | 0x05<<16 | 0x02<< 20; // baud rate divider | TESG1 | TESG2

// CAN2BTR = 0x001C001D; // baud rate divider | TESG1 | TESG2 (125k)
CAN2BTR = 0x001CC00F;
CAN2MOD = 0x00000000; //Release CAN controller 2
// End Configure CAN 2

}

int cansendchar(void) {
unsigned int val; // variable for CAN data
val = 55;
/* check, if buffer is ready (previous Tx completed) */
if ((CAN2SR & 0x4) != 0) {
CAN2TFI1 = 0x00040000; //Set DLC to 4 bytes
CAN2TID1 = 0x00000002; //Set address to 2 Standard Frame
CAN2TDA1 = val; // Copy value into first four bytes
CAN2TDB1 = val; // Copy value into second four bytes
/* start transmission */
CAN2CMR = 0x21; //0x30; //0x21; //0x30; //0x20;
return 0; /* OK */
}
if ((CAN2SR & 0x4) == 0) {

return -1; /* busy */
}
return 0; /* OK */
}

An Engineer's Guide to the LPC2100 Series

--- In l..., "stefan_bluhm" wrote:
>
> Hi all,
>
> I am very new to microprocessor development and am still figuring out the way things work on the LPC2378 as well as the Olimex board. So up front apologies for "stupid" questions. I am also not expecting answers but hints on how things could work (although answers are obviously appreciated :) ).
>
> What I am trying to do is to transmit CAN data from the Olimex LPC2378 to a second CAN adapter. My setup is as follows:
>
> Olimex LPC2378 board CAN port connected to a CANUSB adapter which in turn is connected to the PC. The Olimex should have a 120 Ohm Resistor on the board which is enabled. I put another 120 Ohm resistor across the cable fixes.
>
> The PC is not receiving any data from the LPC.
>

Trying to debug your code should not be your first step - you have a system that you should break into pieces to find out in which bit the problem is.

Get a storage scope and check to see if any data is appearing on the bus. If it is, capture it and check the bit width to verify the speed. If you don't do this, you could spend weeks fiddling with your code only to eventually find CANLO and CANHI are reversed in the connector :((

First time I used CANBUS, I miscalculated the register values and the tx was at twice the rate I thought it was. I only found this out when I scoped the line and measured the bit width.

Perhaps your code is working!

Rgds,
Martin

Hi Martin,

thank you for your suggestion. I guess I have to digg my old oscilloscope out again.

You don't happen to have a binary version of can transmitting application?

Best wishes,

Stefan
--- In l..., "mjames_doveridge" wrote:
>
> --- In l..., "stefan_bluhm" wrote:
> >
> > Hi all,
> >
> > I am very new to microprocessor development and am still figuring out the way things work on the LPC2378 as well as the Olimex board. So up front apologies for "stupid" questions. I am also not expecting answers but hints on how things could work (although answers are obviously appreciated :) ).
> >
> > What I am trying to do is to transmit CAN data from the Olimex LPC2378 to a second CAN adapter. My setup is as follows:
> >
> > Olimex LPC2378 board CAN port connected to a CANUSB adapter which in turn is connected to the PC. The Olimex should have a 120 Ohm Resistor on the board which is enabled. I put another 120 Ohm resistor across the cable fixes.
> >
> > The PC is not receiving any data from the LPC.
> > Trying to debug your code should not be your first step - you have a system that you should break into pieces to find out in which bit the problem is.
>
> Get a storage scope and check to see if any data is appearing on the bus. If it is, capture it and check the bit width to verify the speed. If you don't do this, you could spend weeks fiddling with your code only to eventually find CANLO and CANHI are reversed in the connector :((
>
> First time I used CANBUS, I miscalculated the register values and the tx was at twice the rate I thought it was. I only found this out when I scoped the line and measured the bit width.
>
> Perhaps your code is working!
>
> Rgds,
> Martin
>

--- In l..., "stefan_bluhm" wrote:
>
> Hi Martin,
>
> thank you for your suggestion. I guess I have to digg my old oscilloscope out again.
>
> You don't happen to have a binary version of can transmitting application?
>

Sorry, no. My CAN source is C++ and integrated into a multithreaded system with UART, serial UI, SD-card, keypad etc etc. It could not be compiled on its own because it sucks in too much gunge.

Rgds,
Martin

Dear Martin,

the least I liked your suggestion (to digg out my old parallel port PC scope, old computer, getting to run Windows software on linux...), the most impactful it was.

I created the same data on the CAN bus with the LPC2378, then as well with the CANUSB adapter. Both signals looked identical apart from that the CANUSB signal was time wise ~50s shorter than the LPC one (probably enough to make a the receiving end fall over) (bus speed is 125kbps).

So this seems to be a similar problem as you described. The speed is not as it should be.

My question is: How do you set the register values properly? Do you have some working example? I thought I have mine calculated properly (obviously not...). I also tried other examples from sample codes and also the calculation examples from Insider's Guide to the NXP LPC2300. Some don't give a proper signal at all, and only one of the examples gave the visually correct signal (just not speed it seems).

Do you have/use a calculation Excel or something like that? I can't believe that this is that complicated, that programmers have to verify the signal with a scope whenever they develop. There are only a few variations on the CAN bus speeds, so I would expect an easy register lookup table.

Thanks a lot for your thoughts,

Stefan