EmbeddedRelated.com
Forums

Driver CAN problem olimex LPC2129

Started by zied130187 January 5, 2011
after, i have connected :

PIN2 CAN1(DB9) to PIN2 CAN2(DB9) and
PIN7 CAN1(DB9) to PIN7 CAN2(DB9)

i have tested this driver CAN to send data from CAN2 to CAN1

but i don't receive the CAN frame and the program don't enter
on the interrupt RXCAN.

thank you to help me , to found the problem.

in my kit the quartz is 14,7456 MHz
i have used 14,7456*(3/4) = 11,0592 MHz to have the error tolerance
0.53%, i know that i must to use 12MHz to have 0% error
but i can't change at the present because i have buyed this kit
and i have a quartz 14.7456 MHz.
Well, i have calculated the best value of CCLK to have a best error
tolerance with this quartz and i have found that 11.0592 MHz is the
best. i give you all calculation of TSEG1,TSEG2,SJW and BRP.
in my code
this my code :

/*
**-------------------------
** BITRATE calculation
** IAR Kickstart kit Olimex P-2129 Frequency 14.7456 MHz
**
** FreqCAN = 125 kb/s
**
** CLK = 14745600 * 3 = 44.2368 MHz
** (VPBDIV=0) -> PCLK = CLK/4 = 11.0592 MHz
**
**
** SJW = 0 , TSEG1 = 7 , TSEG2 = 1
** ==> sampling point = ([(SJW+1)+(TSEG1+1)]/[(SJW+1)+(TSEG1+1)+(TSEG2+1)])* 100
** = ([(0+1)+(7+1)]/[(0+1)+(7+1)+(1+1)])*100 = 81.81%
**
** QUANTAValue = 1 + (Tseg1+1) + (Tseg2+1)= 11
**
** BRP = (Fpclk/(CANBitRate * QUANTAValue)) - 1
**
** CANBTR register setting (C1BTR and C2BTR)
** SAM=0 Bus is sampled once
** TSEG1 = 7
** TSEG2 = 1
** SJW = 0
**
** BRP = [FPCLK/(CANBitRate * QUANTAValue)]-1
** BRP = [11059200/(125000*11)] - 1 = = 7.043 =~ 7
**
** BitRate = Fpclk/ ((BRP+1) * QUANTAValue) = 11059200/((7+1)*11) = 125.672 Kb/s
**
** error tolerance = (((desired bitrate/calculated bitrate)*100)-100)*(-1)
** = (((125/125.672)*100)-100)*(-1) = 0.53%
**
** 250kb/s ==> BRP = 3.0215 =~ 3
** BitRate = 251.345 Kb/s
** error tolerance = (((250/251.345)*100)-100)*(-1)= 0.53%
**
** 500kb/s ==> BRP = 1.0107 =~ 1
** BitRate = 502.609 Kb/s
** error tolerance = (((500/502.609)*100)-100)*(-1)= 0.52%
**
** 1000kb/s ==> BRP = 0.00538 =~ 0
** Bitrate = 1005.381 Kb/s
** error tolerance = 0.53%
**
**-------------------------*/

/**
* Bit Timing Values for 11.0592 MHz pclk frequency
*/ // TSEG1 ,TSEG2 ,BRP
#define BITRATE125K11_0592MHZ 0x00170007 // (7 ,1 ,7)
#define BITRATE250K11_0592MHZ 0x00170003 // (7 ,1 ,3)
#define BITRATE500K11_0592MHZ 0x00170001 // (7 ,1 ,1)
#define BITRATE1000K11_0592MHZ 0x00170000 // (7 ,1 ,0)

#include
#include "hardware.h"
#include

#define wait 500000 //count to give delay

#define StandardFilter0 (*((volatile unsigned long *) 0xE0038000))
#define StandardFilter1 (*((volatile unsigned long *) 0xE0038004))
void CAN1IRQ(void);
void can_baudrate(int i);

typedef struct
{
unsigned long TFI;
unsigned long ID;
unsigned long data[2];
}MSG_CAN;
void filter(void)
{
AFMR = 0x00000001; // Disable the Acceptance filters to allow setup of the
table
StandardFilter0 = 0x00000002;
StandardFilter1 = 0x00000004;
SFF_sa = 0x00000000; // Set start address of Standard table
SFF_GRP_sa = 0x00000008; // Set start address of Standard group table
EFF_sa = 0x00000008; // Set start address of Extended table
EFF_GRP_sa = 0x00000008; // Set start address of Extended group table
ENDofTable = 0x00000008; // Set end of table address
AFMR = 0x00000000; // Enable Acceptance filters
}
void delay(void)
{
int i;
for(i=0;i }

void CAN1IRQ(void)
{

int j,i;
unsigned long int DA = C1RDA;
unsigned long int DB = C1RDB;

for (i=0;i<4;i++)
{
printf("dataA %d = %ld\n",i,DA);
DA>8;
}

for (i=0;i<4;i++)
{
printf("dataB %d = %ld\n",i,DB);
DB>8;
}
for (j = 0x010000; j <= 0x800000; j <<= 1) // Blink LED 0,1,2,3,4,5,6
{
A_LED1_ON; // Turn on LED
delay(); // call wait function
A_LED1_OFF; // Turn off LED
delay();
}
for (j = 0x800000; j >= 0x010000; j >>=1 ) // Blink LED
7,6,5,4,3,2,1
{
A_LED2_ON; // Turn on LED
delay(); // call wait function
A_LED2_OFF; // Turn off LED
delay();
}

C1CMR=0X00000004; // release the Rx buffer

VICVectAddr = 0; /* Acknowledge Interrupt */
}

void can2tx(MSG_CAN* ptr)
{
while(!(C2SR&0X00000004)); //See if Tx Buffer 1 is free

C2TFI1=ptr->TFI;
C2TID1=ptr->ID;
C2TDA1=ptr->data[0];
C2TDB1=ptr->data[1];

C2CMR=0x00000001; // Select Tx Buffer 1 for transmission + message is
queued for transmission
}

void can_init(void)
{
C1MOD=0x000000001; C2MOD=0X00000001; // Reset Mode CAN operation is
disabled,
// and writable registers can
be written
can_baudrate(125); // for 125k bit rate
PINSEL1|=0X00054000; // select can1 rx , can2 rx and tx (0000 0000 0000 0101
0100 0000 0000 0000)

C1IER=0X00000001; // enable can1 rx interrupt

C1MOD=0X00000000; C2MOD=0X00000000; // the CAN Controller operates

VICVectAddr0=(U32)CAN1IRQ; // assign address of isr to vic 0
channel
VICVectCntl0=0X00000003A;

VICIntSelect = 0;
VICIntEnable=0X04000000; // enable can1 rx interrupt
}

void can_baudrate(int i)
{
switch (i)
{
case 125:
C1BTR=BITRATE125K11_0592MHZ; C2BTR=BITRATE125K11_0592MHZ;
break;
case 250:
C1BTR=BITRATE250K11_0592MHZ; C2BTR=BITRATE250K11_0592MHZ;
break;
case 500:
C1BTR=BITRATE500K11_0592MHZ; C2BTR=BITRATE500K11_0592MHZ;
break;
case 1000:
C1BTR=BITRATE1000K11_0592MHZ; C2BTR=BITRATE1000K11_0592MHZ;
break;
default :
break;
}
}

int main()
{
__disable_interrupt();
CPUinit();
// 11-bits, RTR=0, DLC is 8 bytes
/* static*/ MSG_CAN temp
={0x00080000,0x00000002,0xABCDEFAA,0x24842484};
// CAN ID //data A //data B
can_init();
filter();
__enable_interrupt();
can2tx(&temp);
can2tx(&temp);
while(1);
// return 0;
}

****************
* hardware.c
*************
/*------\
-------------*/
#pragma vector=0x18
__irq __arm void irq_handler(void)
{
void (*interrupt_function)();
U16 vector;

vector = VICVectAddr; // GET VECTOR ADDRESS FROM VIC
CONTROLLER
interrupt_function = (void(*)())vector;

(*interrupt_function)(); // Call vectored interrupt function.

VICVectAddr= 0; // Clear interrupt in VIC.
}
/*------\
-------------*/
void delay_ms(U32 del)
{
del = del * 3000; // 1del * 3000 = 1ms
while (--del!=0);
}
/*------\
-------------*/
void CPUinit(void)
{
//See PLL calculations in #define section at top of this file 14.7456MHz * 3
=> CCLK = 44.2368
PLLCFG_bit.MSEL=2;
PLLCFG_bit.PSEL=2; //See PLL calculations in #define section at top of this
file
PLLFEED=0xAA;
PLLFEED=0x55;
PLLCON_bit.PLLE=1; // Enable the PLL
PLLFEED=0xAA;
PLLFEED=0x55;
while(!(PLLSTAT & PLOCK)); // Wait for PLL to lock
PLLCON=0x00000003; // connect the PLL as the main clock source
PLLFEED=0xAA;
PLLFEED=0x55;
//Init MAM & Flash memory fetch
MAMCR_bit.MODECTRL=2; //MAM functions fully enabled.
MAMTIM_bit.CYCLES=4; //Flash access time 4CCLK
//See PLL calculations in #define section at top of this file => PCLK CCLK/4 = 11.0592 MHz
VPBDIV_bit.VPBDIV=0;

//GPIO init
// A_PULL_UP;

//IODIR in binary 0000 0001 0000 0000 0011 0000 0000 0000 ...P0.12, P0.13
are output(LEDs) also TD2
IO0DIR=0x01003000;

//PINSEL0 in binary 0000 0000 0000 0101 0000 0000 0000 0101
PINSEL0=0; // P0 lower 16 bits all GPIO
PINSEL1=0; //P0 upper 16 bits all GPIO

A_LED1_OFF;
A_LED2_OFF;
VICProtection = 0;
}

//*********************************************
thank you my friends to help me !!

An Engineer's Guide to the LPC2100 Series

My last post was a clue to point you in the right direction!

Are you happy you've set the pins up correctly? .... Clue .. Take a closer look and read my last post!

To solve embedded problems you must be able to methodically debug ... That means starting from the hardware configuration upwards!

Simon

--- In l..., "zied130187" wrote:
>
> hello,
>
> thank you for your response
>
>
> --- In l..., "simonb65" wrote:
> >
> > Where do you set PINSEL so that the pins use the CAN peripherals? >and do you set both RX and TX for CAN1 and CAN2 .....
>
> i have set PINSEL in can_init()
>
> void can_init(void)
> {
> ....
> can_baudrate(125); // for 125k bit rate
> PINSEL1|=0X00054000; // select can1 rx , can2 rx and tx (0000 0000 0000 0101
> 0100 0000 0000 0000)
> .....
>
> }
> > even though you only receive on one channel, it has to acknowledge
> > the message by transmitting back!!!! Have you read how CAN works??!
>
> yes i read the protocol CAN.
> well , i must to add the interrupt function receive CAN2
> and the function transmit CAN1 ?
>
> but what is the form of frame i must to send.
>
> my data is :
>
> MSG_CAN temp ={0x00080000,0x00000002,0xABCDEFAA,0x24842484};
> thank you
>

hello,

thank you for your response

--- In l..., "simonb65" wrote:
>
> Where do you set PINSEL so that the pins use the CAN peripherals? >and do you set both RX and TX for CAN1 and CAN2 .....

i have set PINSEL in can_init()

void can_init(void)
{
....
can_baudrate(125); // for 125k bit rate
PINSEL1|=0X00054000; // select can1 rx , can2 rx and tx (0000 0000 0000 0101
0100 0000 0000 0000)
.....

}
> even though you only receive on one channel, it has to acknowledge
> the message by transmitting back!!!! Have you read how CAN works??!

yes i read the protocol CAN.
well , i must to add the interrupt function receive CAN2
and the function transmit CAN1 ?

but what is the form of frame i must to send.

my data is :

MSG_CAN temp ={0x00080000,0x00000002,0xABCDEFAA,0x24842484};
thank you

why you're laughing at me ?!

i'am not happy and i'am not sad ,
it's normally to configure correctly or no !

you just to read the datasheet and applicate.

i post my question to help me.

i am a beginner with BUS CAN
and i need some peoples to resolve with me some problem.

thank you for your helpfullness

I'm not laughing at you! I am simply asking you questions in the hope that you may see the answer for yourself and learn by methodically working this out. You will not get far in any engineering job unless you can problem solve.

This is nothing to do with CANbus, this is 'basic' first step embedded engineering.

As I said, Start from the ground up ... don't look at the details of CAN and message packets until you have the hardware wired and CONFIGURED correctly (another BIG hint).

It took me about 30 seconds to see the problem, I am not going to do the work for you, but I will help you to solve problems by pointing you in the right direction. All you need to do is to read the comments I post, understand them, understand the problem and the solution will be obvious.

Just put some thought into it.

Simon.

--- In l..., "zied130187" wrote:
> why you're laughing at me ?!
>
> i'am not happy and i'am not sad ,
> it's normally to configure correctly or no !
>
> you just to read the datasheet and applicate.
>
> i post my question to help me.
>
> i am a beginner with BUS CAN
> and i need some peoples to resolve with me some problem.
>
> thank you for your helpfullness
>

The 'other' way to solve this problem is to use Google and search for 'lpc2129 CAN example code'.

I tried that and found:
http://gandalf.arubi.uni-kl.de/avr_projects/arm_projects/#lpc_can1

There is a complete CAN example for the LPC2129 and the GCC toolchain. Regardless of the toolchain, it just makes sense to start with code that probably works.

Read the one paragraph write-up and follow the link for the code files.

Richard

hello i want some advice regarding the code of uart like we can on and off
some loads L1 L2 L3 L4, with the I2c, or the computer input plz suggest me..
--
with regard's
jagannath ojha ( R & D Dept.)
DCD pvt ltd NOIDA -59
On Thu, 2011-01-06 at 19:18 +0530, jagannath ojha wrote:
> hello i want some advice regarding the code of uart like we can on and
> off some loads L1 L2 L3 L4, with the I2c, or the computer input plz
> suggest me..

I (or I might write "we") have no clue what you are
talking about. What is it that you are asking, certainly
not us doing your job, right ?
I would like to suggest to you : use Google !

roelof

On 01/06/2011 04:44 PM, roelof 't Hooft wrote:
> On Thu, 2011-01-06 at 19:18 +0530, jagannath ojha wrote:
> >
> >
> > hello i want some advice regarding the code of uart like we can on and
> > off some loads L1 L2 L3 L4, with the I2c, or the computer input plz
> > suggest me..
>
> I (or I might write "we") have no clue what you are
> talking about.

However, whatever it is he is talking about, I/we can reckon that it has
nothing to do with "Driver CAN problem olimex LPC2129".

--

Timo
On Thu, 2011-01-06 at 16:52 +0200, Timo wrote:
> However, whatever it is he is talking about, I/we can reckon that it has
> nothing to do with "Driver CAN problem olimex LPC2129".

I noticed that when I clicked the send button
otherwise I would have said something about hijacking
a thread :-)

roelof