EmbeddedRelated.com
Forums

CAN on MCB2300 with rowley

Started by Martijn Broens May 30, 2009
Hi all,

I'm trying to port a keil exampole project o rowley but i dont get the ISR. i.e. if i use the following code to setup the CAN (CAN1 on p0.0 & p0.1) and i have an other board transmitiing CAN msg from port 1 to port 2 i can see data on the RX line behind the TJA1040 on this board. so data is being received. The other board is receiveing correctly (an other MCB2300 with KEIL CAN example compiled with KEIL is running).

If i now set a breakpoint in the CAN_Handler than i would espect to get there. but it never breaks there???

does anyone have some suggestions??

thanks Martijn
/*****************************************************************************
** Function name: CAN_Handler
**
** Descriptions: CAN interrupt handler
**
** parameters: None
** Returned value: None
**
*****************************************************************************/
void CAN_Handler(void)
{
//IENABLE; /* handles nested interrupt */

CANStatus = CANRxSR;
if ( CANStatus & (1 << 8) )
{
CAN1RxCount++;
CAN_ISR_Rx1();
}
if ( CANStatus & (1 << 9) )
{
CAN2RxCount++;
CAN_ISR_Rx2();
}
if ( CAN1GSR & (1 << 6 ) )
{
/* The error count includes both TX and RX */
CAN1ErrCount = (CAN1GSR >> 16 );
}
if ( CAN2GSR & (1 << 6 ) )
{
/* The error count includes both TX and RX */
CAN2ErrCount = (CAN2GSR >> 16 );
}
//IDISABLE;
//VICVectAddr = 0; /* Acknowledge Interrupt */
return;
}

DWORD CAN_Init( DWORD can_btr )
{
CAN1RxDone = CAN2RxDone = FALSE;

PCONP |= (1 << 13) | (1 << 14); // Enable clock to the peripheral

PINSEL0 &= ~0x00000F0F;
PINSEL0 |= 0x00000A05; // port0.0~1, function 0x01, port0.4~5, function 0x10

CAN1MOD = CAN2MOD = 1; // Reset CAN
CAN1IER = CAN2IER = 0; // Disable Receive Interrupt
CAN1GSR = CAN2GSR = 0; // Reset error counter when CANxMOD is in reset

CAN1BTR = CAN2BTR = can_btr;
CAN1MOD = CAN2MOD = 0x0; // CAN in normal operation mode

// Install CAN interrupt handler
ctl_set_isr(23, 1, CTL_ISR_TRIGGER_FIXED, CAN_Handler, 0);
ctl_unmask_isr(23);
CAN1IER = CAN2IER = 0x01; // Enable receive interrupts
return( TRUE );
}

An Engineer's Guide to the LPC2100 Series

A few thoughts...

Proper termination is important for CAN

Enable all CAN interrupts..even error interrupts. This will tell you if
you are at the correct baud or not.

I didn't look through your code because you didn't give me a PO yet
> Hi all,
>
> I'm trying to port a keil exampole project o rowley but i dont get the
> ISR. i.e. if i use the following code to setup the CAN (CAN1 on p0.0 &
> p0.1) and i have an other board transmitiing CAN msg from port 1 to port 2
> i can see data on the RX line behind the TJA1040 on this board. so data is
> being received. The other board is receiveing correctly (an other MCB2300
> with KEIL CAN example compiled with KEIL is running).
>
> If i now set a breakpoint in the CAN_Handler than i would espect to get
> there. but it never breaks there???
>
> does anyone have some suggestions??
>
> thanks Martijn
> /*****************************************************************************
> ** Function name: CAN_Handler
> **
> ** Descriptions: CAN interrupt handler
> **
> ** parameters: None
> ** Returned value: None
> **
> *****************************************************************************/
> void CAN_Handler(void)
> {
> //IENABLE; /* handles nested interrupt */
>
> CANStatus = CANRxSR;
> if ( CANStatus & (1 << 8) )
> {
> CAN1RxCount++;
> CAN_ISR_Rx1();
> }
> if ( CANStatus & (1 << 9) )
> {
> CAN2RxCount++;
> CAN_ISR_Rx2();
> }
> if ( CAN1GSR & (1 << 6 ) )
> {
> /* The error count includes both TX and RX */
> CAN1ErrCount = (CAN1GSR >> 16 );
> }
> if ( CAN2GSR & (1 << 6 ) )
> {
> /* The error count includes both TX and RX */
> CAN2ErrCount = (CAN2GSR >> 16 );
> }
> //IDISABLE;
> //VICVectAddr = 0; /* Acknowledge Interrupt */
> return;
> }
>
> DWORD CAN_Init( DWORD can_btr )
> {
> CAN1RxDone = CAN2RxDone = FALSE;
>
> PCONP |= (1 << 13) | (1 << 14); // Enable clock to the peripheral
>
> PINSEL0 &= ~0x00000F0F;
> PINSEL0 |= 0x00000A05; // port0.0~1, function 0x01, port0.4~5, function
> 0x10
>
> CAN1MOD = CAN2MOD = 1; // Reset CAN
> CAN1IER = CAN2IER = 0; // Disable Receive Interrupt
> CAN1GSR = CAN2GSR = 0; // Reset error counter when CANxMOD is in reset
>
> CAN1BTR = CAN2BTR = can_btr;
> CAN1MOD = CAN2MOD = 0x0; // CAN in normal operation mode
>
> // Install CAN interrupt handler
> ctl_set_isr(23, 1, CTL_ISR_TRIGGER_FIXED, CAN_Handler, 0);
> ctl_unmask_isr(23);
> CAN1IER = CAN2IER = 0x01; // Enable receive interrupts
> return( TRUE );
> }

Hi Martijn,

unfortunately I don't work with this Rowley thing, but the WinArm
port is working without problems. You should include
VICVectAddr = 0; /* Acknowledge Interrupt */
again, it's surprisingly important to ack the interrupt.
But that's not solving your problem. If your CAN transceivers are
at P0.0-P0.1 and P0.4-P0.5 (=MCB2300/LPC2368) your PINSEL0 is OK.
What about acceptance filter? Did you bypass it somewhere
with CAN_SetACCF(ACCF_BYPASS); ?
Don't know if your Rowley interrupt handler installation is working,
but if try to transmit a message and control it with a scope
(for correct BitRate) your problem should be this installation.

Hope this helps,
Gerd

> > Hi all,
> >
> > I'm trying to port a keil exampole project o rowley but i dont get the
> > ISR. i.e. if i use the following code to setup the CAN (CAN1 on p0.0 &
> > p0.1) and i have an other board transmitiing CAN msg from port 1 to port 2
> > i can see data on the RX line behind the TJA1040 on this board. so data is
> > being received. The other board is receiveing correctly (an other MCB2300
> > with KEIL CAN example compiled with KEIL is running).
> >
> > If i now set a breakpoint in the CAN_Handler than i would espect to get
> > there. but it never breaks there???
> >
> > does anyone have some suggestions??
> >
> > thanks Martijn
> >
> >
> > /*****************************************************************************
> > ** Function name: CAN_Handler
> > **
> > ** Descriptions: CAN interrupt handler
> > **
> > ** parameters: None
> > ** Returned value: None
> > **
> > *****************************************************************************/
> > void CAN_Handler(void)
> > {
> > //IENABLE; /* handles nested interrupt */
> >
> > CANStatus = CANRxSR;
> > if ( CANStatus & (1 << 8) )
> > {
> > CAN1RxCount++;
> > CAN_ISR_Rx1();
> > }
> > if ( CANStatus & (1 << 9) )
> > {
> > CAN2RxCount++;
> > CAN_ISR_Rx2();
> > }
> > if ( CAN1GSR & (1 << 6 ) )
> > {
> > /* The error count includes both TX and RX */
> > CAN1ErrCount = (CAN1GSR >> 16 );
> > }
> > if ( CAN2GSR & (1 << 6 ) )
> > {
> > /* The error count includes both TX and RX */
> > CAN2ErrCount = (CAN2GSR >> 16 );
> > }
> > //IDISABLE;
> > //VICVectAddr = 0; /* Acknowledge Interrupt */
> > return;
> > }
> >
> > DWORD CAN_Init( DWORD can_btr )
> > {
> > CAN1RxDone = CAN2RxDone = FALSE;
> >
> > PCONP |= (1 << 13) | (1 << 14); // Enable clock to the peripheral
> >
> > PINSEL0 &= ~0x00000F0F;
> > PINSEL0 |= 0x00000A05; // port0.0~1, function 0x01, port0.4~5, function
> > 0x10
> >
> > CAN1MOD = CAN2MOD = 1; // Reset CAN
> > CAN1IER = CAN2IER = 0; // Disable Receive Interrupt
> > CAN1GSR = CAN2GSR = 0; // Reset error counter when CANxMOD is in reset
> >
> > CAN1BTR = CAN2BTR = can_btr;
> > CAN1MOD = CAN2MOD = 0x0; // CAN in normal operation mode
> >
> > // Install CAN interrupt handler
> > ctl_set_isr(23, 1, CTL_ISR_TRIGGER_FIXED, CAN_Handler, 0);
> > ctl_unmask_isr(23);
> > CAN1IER = CAN2IER = 0x01; // Enable receive interrupts
> > return( TRUE );
> > }
> >
>

Hi Gerd, Dave,

Thanks for the responses. I'm guessing it ghas soething to do with the ISR
installation. I'll focus on that. Good idead to enable the error isr aswell.
I just assumed, and yes asumtion is the mother of all f.ups, that since the
code was running under keil on the mcb2300. that after doeing the
modifications I did the code would run. Did that severl times for usart, spi
I2C and they all worke fine but than that's common stuff to me CAN is new.

Anyways, I'll enable all isr and give tham the proper rotines for it. And
I'll also try to send some data since that is polled. Seems like a good
approach.

For the termination resistors. Yes. Each node has it's own 60R resistor
between CANx and mid. So that should be fine. (teste that with routing the
RX line of this board to an other board (keil code) and than it runs so that
piece of the HW is working correctly. I't is something with the code setup.
For sure.

Acceptance filters are off. Indeed but that can't bethe reason right? I mean
I'll first need to get an ISR before goeing furter or is the acceptance
filter a hw implementation before the ISR is generated?? Actually it doesnot
matter since the same code compiled by keil is working..

no I'll start all over must be something with the code setup.

Thanks guys

Martijn

_____

From: l... [mailto:l...] On Behalf Of
Gerd
Sent: zondag 31 mei 2009 8:52
To: l...
Subject: [lpc2000] Re: CAN on MCB2300 with rowley

Hi Martijn,

unfortunately I don't work with this Rowley thing, but the WinArm
port is working without problems. You should include
VICVectAddr = 0; /* Acknowledge Interrupt */
again, it's surprisingly important to ack the interrupt.
But that's not solving your problem. If your CAN transceivers are
at P0.0-P0.1 and P0.4-P0.5 (=MCB2300/LPC2368) your PINSEL0 is OK.
What about acceptance filter? Did you bypass it somewhere
with CAN_SetACCF(ACCF_BYPASS); ?
Don't know if your Rowley interrupt handler installation is working,
but if try to transmit a message and control it with a scope
(for correct BitRate) your problem should be this installation.

Hope this helps,
Gerd

> > Hi all,
> >
> > I'm trying to port a keil exampole project o rowley but i dont get the
> > ISR. i.e. if i use the following code to setup the CAN (CAN1 on p0.0 &
> > p0.1) and i have an other board transmitiing CAN msg from port 1 to port
2
> > i can see data on the RX line behind the TJA1040 on this board. so data
is
> > being received. The other board is receiveing correctly (an other
MCB2300
> > with KEIL CAN example compiled with KEIL is running).
> >
> > If i now set a breakpoint in the CAN_Handler than i would espect to get
> > there. but it never breaks there???
> >
> > does anyone have some suggestions??
> >
> > thanks Martijn
> >
> >
> >
/***************************************************************************
**
> > ** Function name: CAN_Handler
> > **
> > ** Descriptions: CAN interrupt handler
> > **
> > ** parameters: None
> > ** Returned value: None
> > **
> >
****************************************************************************
*/
> > void CAN_Handler(void)
> > {
> > //IENABLE; /* handles nested interrupt */
> >
> > CANStatus = CANRxSR;
> > if ( CANStatus & (1 << 8) )
> > {
> > CAN1RxCount++;
> > CAN_ISR_Rx1();
> > }
> > if ( CANStatus & (1 << 9) )
> > {
> > CAN2RxCount++;
> > CAN_ISR_Rx2();
> > }
> > if ( CAN1GSR & (1 << 6 ) )
> > {
> > /* The error count includes both TX and RX */
> > CAN1ErrCount = (CAN1GSR >> 16 );
> > }
> > if ( CAN2GSR & (1 << 6 ) )
> > {
> > /* The error count includes both TX and RX */
> > CAN2ErrCount = (CAN2GSR >> 16 );
> > }
> > //IDISABLE;
> > //VICVectAddr = 0; /* Acknowledge Interrupt */
> > return;
> > }
> >
> > DWORD CAN_Init( DWORD can_btr )
> > {
> > CAN1RxDone = CAN2RxDone = FALSE;
> >
> > PCONP |= (1 << 13) | (1 << 14); // Enable clock to the peripheral
> >
> > PINSEL0 &= ~0x00000F0F;
> > PINSEL0 |= 0x00000A05; // port0.0~1, function 0x01, port0.4~5, function
> > 0x10
> >
> > CAN1MOD = CAN2MOD = 1; // Reset CAN
> > CAN1IER = CAN2IER = 0; // Disable Receive Interrupt
> > CAN1GSR = CAN2GSR = 0; // Reset error counter when CANxMOD is in reset
> >
> > CAN1BTR = CAN2BTR = can_btr;
> > CAN1MOD = CAN2MOD = 0x0; // CAN in normal operation mode
> >
> > // Install CAN interrupt handler
> > ctl_set_isr(23, 1, CTL_ISR_TRIGGER_FIXED, CAN_Handler, 0);
> > ctl_unmask_isr(23);
> > CAN1IER = CAN2IER = 0x01; // Enable receive interrupts
> > return( TRUE );
> > }
> >
>