EmbeddedRelated.com
Forums
Memfault Beyond the Launch

CAN trouble on MC9212DP256B board

Started by Ashwin March 30, 2006
I am trying to communicate with another development board running at
40MHz. I want to light up the LED0 of PORT B if the code enters the
receive ISR to start with and would like to store and display the
received data somehow on the motorola board. It is not happening. Any
suggestions? This is the snippet of the ISR. I am compiling it using
Metrowerks Code Warrior.
#include /* common defines and macros */
#include /* derivative information */
...
...
void interrupt CAN0RxISR(void)
{
unsigned char length, index;
unsigned char rxdata[8];
DDRB_BIT0 = 1;

PORTB_BIT0 = 0;
length = (CAN0RXDLR & 0x0F);
for (index=0; index
rxdata[index] = *(&CAN0RXDSR0 + index); /* Get received data */
}

CAN0RFLG = 0x01; /* Clear RXF */
}
...
...

Yahoo! Groups Links
Hi,

Have you set up the mask and acceptance registers (CANIDMR0-7,
CANIDAR0-7, CANIDAC)?
Instead of your ISR routine, you'd rather post your CAN init code.

Zoltan

--- In 6..., "Ashwin" wrote:
>
> I am trying to communicate with another development board running at
> 40MHz. I want to light up the LED0 of PORT B if the code enters the
> receive ISR to start with and would like to store and display the
> received data somehow on the motorola board. It is not happening. Any
> suggestions? This is the snippet of the ISR. I am compiling it using
> Metrowerks Code Warrior.

Yahoo! Groups Links
Hello Zlilinszkyz,

Here is the program running on the Motorola board:

#include /* common defines and macros */
#include /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12dp256b"

#define ST_ID_100 0x20000000
#define ERR_BUFFER_FULL 1
#define NO_ERR 0

/* Acceptance Code Definitions */
#define ACC_CODE_ID100 0x2000
#define ACC_CODE_ID100_HIGH ((ACC_CODE_ID100&0xFF00)>>8)
#define ACC_CODE_ID100_LOW (ACC_CODE_ID100&0x00FF)

/* Mask Code Definitions */
#define MASK_CODE_ST_ID 0x0007
#define MASK_CODE_ST_ID_HIGH ((MASK_CODE_ST_ID&0xFF00)>>8)
#define MASK_CODE_ST_ID_LOW (MASK_CODE_ST_ID&0xFF)

void CANinit(void);
unsigned char CANSendFrame (unsigned char priority,
unsigned char length, unsigned char
*txdata);

void CANinit(void)
{
CAN0CTL0 = 0x01;
while (! (CAN0CTL1 & 0x01) ) { }

CAN0CTL1 = 0x80;
CAN0BTR0 = 0xC7;
CAN0BTR1 = 0x3A;

/* Acceptance Filters
CAN0IDAC = 0x10;
CAN0IDAR0 = ACC_CODE_ID100_HIGH;
CAN0IDMR0 = MASK_CODE_ST_ID_HIGH;
CAN0IDAR1 = ACC_CODE_ID100_LOW;
CAN0IDMR1 = MASK_CODE_ST_ID_LOW;
CAN0IDAC = 0x10; // Set four 16-bit Filters
CAN0IDAR2 = 0x00; // 16-bit Filter 1
CAN0IDMR2 = MASK_CODE_ST_ID_HIGH; // Accepts Standard Data Frame Msg
CAN0IDAR3 = 0x00; // with ID 0x100
CAN0IDMR3 = MASK_CODE_ST_ID_LOW;
CAN0IDAR4 = 0x00; // 16-bit Filter 2
CAN0IDMR4 = MASK_CODE_ST_ID_HIGH; // Accepts Standard Data Frame Msg
CAN0IDAR5 = 0x00; // with ID 0x100
CAN0IDMR5 = MASK_CODE_ST_ID_LOW; //
CAN0IDAR6 = 0x00; // 16-bit Filter 3
CAN0IDMR6 = MASK_CODE_ST_ID_HIGH; // Accepts Standard Data Frame Msg
CAN0IDAR7 = 0x00; // with ID 0x100
CAN0IDMR7 = MASK_CODE_ST_ID_LOW; */

CAN0CTL0 = 0x00;
while ((CAN0CTL1 & 0x00) != 0) { }
}

unsigned char CANSendFrame (unsigned char priority,
unsigned char length, unsigned char *txdata)
{
unsigned char txbuffer;
int index;

if ( !CAN0TFLG)
return ERR_BUFFER_FULL;

CAN0TBSEL = CAN0TFLG;
txbuffer = CAN0TBSEL;

//*( ( unsigned long *) ( (unsigned long) (& CAN0TXIDR0) ) ) = id;
CAN0TXIDR0 = 0x20000000;

for (index = 0; index < length; index++)
{
*(& CAN0TXDSR0 + index) = txdata[index];
}

CAN0TXDLR = length;
CAN0TXTBPR = priority;
CAN0TFLG = txbuffer;

while ( ( CAN0TFLG & txbuffer) != txbuffer);
}

void interrupt CAN0RxISR(void)
{
unsigned char length, index;
unsigned char rxdata[8];
DDRB_BIT0 = 1;

PORTB_BIT0 = 0;
length = (CAN0RXDLR & 0x0F);
for (index=0; index
rxdata[index] = *(&CAN0RXDSR0 + index); /* Get received data */
}

CAN0RFLG = 0x01; /* Clear RXF */
}

void main ( )
{
unsigned char errorflag = NO_ERR;
//unsigned char txbuff [ ] = "ABCDEFGH";
//unsigned int i;

CANinit ( );
while ( ! (CAN0CTL0 & 0x10) );

CAN0RFLG = 0xC3;
CAN0RIER = 0x01;

/*for (; ;)
{
errorflag = CANSendFrame( 0x00, sizeof(txbuff)-1,txbuff);
for(i=0;i<10000;i++);
}*/

}

Can you explain what the mask registers actuatlly do? Is it neccessary
at all? what about the filters? Thanks.

Yahoo! Groups Links
Hey Zsilinszkyz,

This is the entire code:

#include /* common defines and macros */
#include /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12dp256b"

#define ST_ID_100 0x20000000
#define ERR_BUFFER_FULL 1
#define NO_ERR 0

/* Acceptance Code Definitions */
#define ACC_CODE_ID100 0x2000
#define ACC_CODE_ID100_HIGH ((ACC_CODE_ID100&0xFF00)>>8)
#define ACC_CODE_ID100_LOW (ACC_CODE_ID100&0x00FF)

/* Mask Code Definitions */
#define MASK_CODE_ST_ID 0x0007
#define MASK_CODE_ST_ID_HIGH ((MASK_CODE_ST_ID&0xFF00)>>8)
#define MASK_CODE_ST_ID_LOW (MASK_CODE_ST_ID&0xFF)

void CANinit(void);
unsigned char CANSendFrame (unsigned char priority,
unsigned char length, unsigned char
*txdata);

void CANinit(void)
{
CAN0CTL0 = 0x01;
while (! (CAN0CTL1 & 0x01) ) { }

CAN0CTL1 = 0x80;
CAN0BTR0 = 0xC7;
CAN0BTR1 = 0x3A;

// Acceptance Filters
CAN0IDAC = 0x10;
CAN0IDAR0 = ACC_CODE_ID100_HIGH;
CAN0IDMR0 = MASK_CODE_ST_ID_HIGH;
CAN0IDAR1 = ACC_CODE_ID100_LOW;
CAN0IDMR1 = MASK_CODE_ST_ID_LOW;
CAN0IDAC = 0x10; // Set four 16-bit Filters
CAN0IDAR2 = 0x00; // 16-bit Filter 1
CAN0IDMR2 = MASK_CODE_ST_ID_HIGH; // Accepts Standard Data Frame Msg
CAN0IDAR3 = 0x00; // with ID 0x100
CAN0IDMR3 = MASK_CODE_ST_ID_LOW;
CAN0IDAR4 = 0x00; // 16-bit Filter 2
CAN0IDMR4 = MASK_CODE_ST_ID_HIGH; // Accepts Standard Data Frame Msg
CAN0IDAR5 = 0x00; // with ID 0x100
CAN0IDMR5 = MASK_CODE_ST_ID_LOW; //
CAN0IDAR6 = 0x00; // 16-bit Filter 3
CAN0IDMR6 = MASK_CODE_ST_ID_HIGH; // Accepts Standard Data Frame Msg
CAN0IDAR7 = 0x00; // with ID 0x100
CAN0IDMR7 = MASK_CODE_ST_ID_LOW;

CAN0CTL0 = 0x00;
while ((CAN0CTL1 & 0x00) != 0) { }
}

unsigned char CANSendFrame (unsigned char priority,
unsigned char length, unsigned char *txdata)
{
unsigned char txbuffer;
int index;

if ( !CAN0TFLG)
return ERR_BUFFER_FULL;

CAN0TBSEL = CAN0TFLG;
txbuffer = CAN0TBSEL;

//*( ( unsigned long *) ( (unsigned long) (& CAN0TXIDR0) ) ) = id;
CAN0TXIDR0 = 0x20000000;

for (index = 0; index < length; index++)
{
*(& CAN0TXDSR0 + index) = txdata[index];
}

CAN0TXDLR = length;
CAN0TXTBPR = priority;
CAN0TFLG = txbuffer;

while ( ( CAN0TFLG & txbuffer) != txbuffer);
}

void interrupt CAN0RxISR(void)
{
unsigned char length, index;
unsigned char rxdata[8];
DDRB_BIT0 = 1;

PORTB_BIT0 = 0;
length = (CAN0RXDLR & 0x0F);
for (index=0; index
rxdata[index] = *(&CAN0RXDSR0 + index); /* Get received data */
}

CAN0RFLG = 0x01; /* Clear RXF */
}

void main ( )
{
unsigned char errorflag = NO_ERR;
//unsigned char txbuff [ ] = "ABCDEFGH";
//unsigned int i;

CANinit ( );
while ( ! (CAN0CTL0 & 0x10) );

CAN0RFLG = 0xC3;
CAN0RIER = 0x01;

/*for (; ;)
{
errorflag = CANSendFrame( 0x00, sizeof(txbuff)-1,txbuff);
for(i=0;i<10000;i++);
}*/

}

Can you explain what the mask registers do and what about the filters?
thanks.

Yahoo! Groups Links
Hi Ashwin

while ((CAN0CTL1 & 0x00) != 0) { }

...makes no sense. ANDing a zero to a number is always zero.

Try to use defines to better understand your code 6 months down the road
when you've moved on to another project and completely forgotten how
things worked. You can use the following:

> #define bit(x) (1 << (x))
>
> /*
> ** MSCAN Control 0 Register (CANxCTL0)
> */
> #define INITRQ bit(0) /* Initialization Mode Request */
> #define SLPRQ bit(1) /* Sleep Mode Request - not reset by init
> mode */
> #define WUPE bit(2) /* Wake-Up Enable - not reset by init
> mode */
> #define TIME bit(3) /* Timer Enable */
> #define SYNCH bit(4) /* Synchronized Status */
> #define CSWAI bit(5) /* CAN Stops in Wait Mode */
> #define RXACT bit(6) /* Receiver Active Status */
> #define RXFRM bit(7) /* Received Frame Flag */
>
> /*
> ** MSCAN Control 1 Register (CANxCTL1)
> */
> #define INITAK bit(0) /* Initialization Mode Acknowledge */
> #define SLPAK bit(1) /* Sleep Mode Acknowledge */
> #define WUPM bit(2) /* Wake-Up Mode */
> #define LISTEN bit(4) /* Listen Only Mode */
> #define LOOPB bit(5) /* Loop Back Self Test Mode */
> #define CLKSRC bit(6) /* MSCAN Clock Source */
> #define CANE bit(7) /* MSCAN Enable */

Bitfield unions work well too. It comes down to personal preference.

The broken code segment would now look like this:

CAN0CTL0 &=~ INITRQ;
while (CAN0CTL1 & INITAK);

-rob

Ashwin wrote:

> Hello Zlilinszkyz,
>
> Here is the program running on the Motorola board:
>
> #include /* common defines and macros */
> #include /* derivative information */
> #pragma LINK_INFO DERIVATIVE "mc9s12dp256b"
>
> #define ST_ID_100 0x20000000
> #define ERR_BUFFER_FULL 1
> #define NO_ERR 0
>
> /* Acceptance Code Definitions */
> #define ACC_CODE_ID100 0x2000
> #define ACC_CODE_ID100_HIGH ((ACC_CODE_ID100&0xFF00)>>8)
> #define ACC_CODE_ID100_LOW (ACC_CODE_ID100&0x00FF)
>
> /* Mask Code Definitions */
> #define MASK_CODE_ST_ID 0x0007
> #define MASK_CODE_ST_ID_HIGH ((MASK_CODE_ST_ID&0xFF00)>>8)
> #define MASK_CODE_ST_ID_LOW (MASK_CODE_ST_ID&0xFF)
>
> void CANinit(void);
> unsigned char CANSendFrame (unsigned char priority,
> unsigned char length, unsigned char
> *txdata);
>
> void CANinit(void)
> {
> CAN0CTL0 = 0x01;
> while (! (CAN0CTL1 & 0x01) ) { }
>
> CAN0CTL1 = 0x80;
> CAN0BTR0 = 0xC7;
> CAN0BTR1 = 0x3A;
>
> /* Acceptance Filters
> CAN0IDAC = 0x10;
> CAN0IDAR0 = ACC_CODE_ID100_HIGH;
> CAN0IDMR0 = MASK_CODE_ST_ID_HIGH;
> CAN0IDAR1 = ACC_CODE_ID100_LOW;
> CAN0IDMR1 = MASK_CODE_ST_ID_LOW;
> CAN0IDAC = 0x10; // Set four 16-bit Filters
> CAN0IDAR2 = 0x00; // 16-bit Filter 1
> CAN0IDMR2 = MASK_CODE_ST_ID_HIGH; // Accepts Standard Data Frame Msg
> CAN0IDAR3 = 0x00; // with ID 0x100
> CAN0IDMR3 = MASK_CODE_ST_ID_LOW;
> CAN0IDAR4 = 0x00; // 16-bit Filter 2
> CAN0IDMR4 = MASK_CODE_ST_ID_HIGH; // Accepts Standard Data Frame Msg
> CAN0IDAR5 = 0x00; // with ID 0x100
> CAN0IDMR5 = MASK_CODE_ST_ID_LOW; //
> CAN0IDAR6 = 0x00; // 16-bit Filter 3
> CAN0IDMR6 = MASK_CODE_ST_ID_HIGH; // Accepts Standard Data Frame Msg
> CAN0IDAR7 = 0x00; // with ID 0x100
> CAN0IDMR7 = MASK_CODE_ST_ID_LOW; */
>
> CAN0CTL0 = 0x00;
> while ((CAN0CTL1 & 0x00) != 0) { }
> }
>
> unsigned char CANSendFrame (unsigned char priority,
> unsigned char length, unsigned char *txdata)
> {
> unsigned char txbuffer;
> int index;
>
> if ( !CAN0TFLG)
> return ERR_BUFFER_FULL;
>
> CAN0TBSEL = CAN0TFLG;
> txbuffer = CAN0TBSEL;
>
> //*( ( unsigned long *) ( (unsigned long) (& CAN0TXIDR0) ) ) = id;
> CAN0TXIDR0 = 0x20000000;
>
> for (index = 0; index < length; index++)
> {
> *(& CAN0TXDSR0 + index) = txdata[index];
> }
>
> CAN0TXDLR = length;
> CAN0TXTBPR = priority;
> CAN0TFLG = txbuffer;
>
> while ( ( CAN0TFLG & txbuffer) != txbuffer);
> }
>
> void interrupt CAN0RxISR(void)
> {
> unsigned char length, index;
> unsigned char rxdata[8];
> DDRB_BIT0 = 1;
>
> PORTB_BIT0 = 0;
> length = (CAN0RXDLR & 0x0F);
> for (index=0; index >
> rxdata[index] = *(&CAN0RXDSR0 + index); /* Get received data */
> }
>
> CAN0RFLG = 0x01; /* Clear RXF */
> }
>
> void main ( )
> {
> unsigned char errorflag = NO_ERR;
> //unsigned char txbuff [ ] = "ABCDEFGH";
> //unsigned int i;
>
> CANinit ( );
> while ( ! (CAN0CTL0 & 0x10) );
>
> CAN0RFLG = 0xC3;
> CAN0RIER = 0x01;
>
> /*for (; ;)
> {
> errorflag = CANSendFrame( 0x00, sizeof(txbuff)-1,txbuff);
> for(i=0;i<10000;i++);
> }*/
>
> }
>
> Can you explain what the mask registers actuatlly do? Is it neccessary
> at all? what about the filters? Thanks.
>
> SPONSORED LINKS
> Fast track
>
> Microcontrollers
>
> Technical support
> Intel microprocessors
> YAHOO! GROUPS LINKS
>
>
>

Yahoo! Groups Links
Hello Robert,

Thanks for pointing that out to me. After years of MATLAB, I seem to
have lost my touch with C. Anyway, I will incorporate your method in
my revised code. However, I have a doubt with what you gave me...

CAN0CTL0 &=~ INITRQ;
while (CAN0CTL1 & INITAK);

For one, what does &=~ signify? I assumed you would just use the operator.

Secondly, if I understand the initialization procedure right, after
the first command, you poll the INITAK bit of CAN0CTL1 until it goes
to 1, which means it is 0 till then. When you AND that with INITAK it
will be 0 and will break the loop the very first time. Right? So,
shouldn't it be

while (!(CAN0CTL1 & INITAK)); or while (CAN0CTL1 & INITAK != 1)

If this is taken care of, is the rest of the code regarding the
receiving aspect still good? I am not interested in the sending part
from the Motorola as of now.

Yahoo! Groups Links
Ashwin wrote this message on Fri, Mar 31, 2006 at 21:15 -0000:
> Thanks for pointing that out to me. After years of MATLAB, I seem to
> have lost my touch with C. Anyway, I will incorporate your method in
> my revised code. However, I have a doubt with what you gave me...
>
> CAN0CTL0 &=~ INITRQ;
> while (CAN0CTL1 & INITAK);
>
> For one, what does &=~ signify? I assumed you would just use the > operator.

better grouped as:
CAN0CTL0 &= (~INITRQ);

~ is the not operator, changes binary 0110101 into 1001010... then:
a &= b;
is equal to:
a = a & b;

so, that above statement clears (unsets) the INITRQ bit(s) of CAN0CTL0...

--
John-Mark Gurney Voice: +1 415 225 5579

"All that I will do, has been done, All that I have, has not."

Yahoo! Groups Links
Ashwin wrote:
> Hello Robert,
>
> Thanks for pointing that out to me. After years of MATLAB, I seem to
> have lost my touch with C. Anyway, I will incorporate your method in
> my revised code. However, I have a doubt with what you gave me...
>
> CAN0CTL0 &=~ INITRQ;
> while (CAN0CTL1 & INITAK);
>
> For one, what does &=~ signify? I assumed you would just use the > operator.
>

As John-Mark pointed out, This clears the INITRQ bit of Control 0
Register. Writing a zero will do if you don't care to keep any of the
other bits set. Once you get the hang of bit twiddling, this terse
style becomes second nature. Whitespace arrangement is always debatable
- precedence is not.

> Secondly, if I understand the initialization procedure right, after
> the first command, you poll the INITAK bit of CAN0CTL1 until it goes
> to 1, which means it is 0 till then. When you AND that with INITAK it
> will be 0 and will break the loop the very first time. Right? So,
> shouldn't it be
>
> while (!(CAN0CTL1 & INITAK)); or while (CAN0CTL1 & INITAK != 1)
>

Au contraire - The code is waiting for the CAN module to exit
initialization mode. When the INITAK bit of CAN0CTL1 becomes zero, the
CAN module can operate normally. The line states that we shall loop
here as long as CAN0CTL1 & INITAK is a true condition (logic 1) or in
other words, as long as INITAK is set.

You are confused about the difference between the & bitwise operator and
the &= assignment operator. a &= b is the same as a = a & b however
a & b by itself is simply a result in an accumulator that isn't
necessarily assigned to any memory location. In this case the
accumulator result of the a & b operation is checked to see if all 8
bits are zero or not.

The following is from my assembler listing (ICC12V6). My code is a bit
different in that I use a pointer to the register so that all 5 DP256
modules can share the 'canExitInitMode' func.

0B9D L250:
0B9D .dbline 1157
0B9D L251:
0B9D .dbline 1157
0B9D ; while (dev->module->CTL1 & INITAK);
0B9D EDE30002 ldy [2,x]
0BA1 0F410102 brclr 1,y,#1,X17
0BA5 20F6 bra L250
0BA7 X17:

As you can see, the while loop is compiled to a brclr loop. Assembler
never lies.

The MSCAN module is not as simple as SPI or SCI but it isn't rocket
science. The Freescale docs provide everything you need.

-rob

Yahoo! Groups Links
I am still unable to receive data from the host microcontroller via
the CAN bus. The below code resides on my mc9s12dp256b chip. The host
is operating at a clock freq of 40MHz. The PORTB BIT0 glows indicating
that the Initialization was done. However, the PORTB BIT1 does not
glow indicating that the ISR is not being triggered. I don't know what
to do:

#include /* common defines and macros */
#include /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12dp256b"

/* Acceptance Code Definitions */
#define ACC_CODE_ID100 0x2000
#define ACC_CODE_ID100_HIGH ((ACC_CODE_ID100&0xFF00)>>8)
#define ACC_CODE_ID100_LOW (ACC_CODE_ID100&0x00FF)

/* Mask Code Definitions */
#define MASK_CODE_ST_ID 0x0007
#define MASK_CODE_ST_ID_HIGH ((MASK_CODE_ST_ID&0xFF00)>>8)
#define MASK_CODE_ST_ID_LOW (MASK_CODE_ST_ID&0xFF)

#define bit(x) (1 << (x))

#define INITRQ bit(0);
#define INITAK bit(0);
#define CANE bit(7);

void CANinit(void)
{
CAN0CTL0 = INITRQ;

CAN0CTL1 = CANE;
CAN0BTR0 = 0xC7;
CAN0BTR1 = 0x3A;

// Acceptance Filters
CAN0IDAC = 0x10;
CAN0IDAR0 = ACC_CODE_ID100_HIGH;
CAN0IDMR0 = MASK_CODE_ST_ID_HIGH;
CAN0IDAR1 = ACC_CODE_ID100_LOW;
CAN0IDMR1 = MASK_CODE_ST_ID_LOW;
CAN0IDAC = 0x10; // Set four 16-bit Filters
CAN0IDAR2 = 0x00; // 16-bit Filter 1
CAN0IDMR2 = MASK_CODE_ST_ID_HIGH; // Accepts Standard Data
Frame Msg
CAN0IDAR3 = 0x00; // with ID 0x100
CAN0IDMR3 = MASK_CODE_ST_ID_LOW;
CAN0IDAR4 = 0x00; // 16-bit Filter 2
CAN0IDMR4 = MASK_CODE_ST_ID_HIGH; // Accepts Standard Data
Frame Msg
CAN0IDAR5 = 0x00; // with ID 0x100
CAN0IDMR5 = MASK_CODE_ST_ID_LOW; //
CAN0IDAR6 = 0x00; // 16-bit Filter 3
CAN0IDMR6 = MASK_CODE_ST_ID_HIGH; // Accepts Standard Data
Frame Msg
CAN0IDAR7 = 0x00; // with ID 0x100
CAN0IDMR7 = MASK_CODE_ST_ID_LOW;

CAN0CTL0 = 0x00;

while ((CAN0CTL1 & INITAK));
DDRB_BIT0 = 1;
PORTB_BIT0 = 0;
}

void interrupt CAN0RxISR(void)
{
DDRB_BIT1 = 1;
PORTB_BIT1 = 0;

unsigned char length, index;
unsigned char rxdata[8];

length = (CAN0RXDLR & 0x0F);
for (index=0; index rxdata[index] = *(&CAN0RXDSR0 + index); /* Get received data */
}

CAN0RFLG = 0x01; /* Clear RXF */
}

void main ( )
{
CANinit ( );

CAN0RFLG = 0xC3;
CAN0RIER = 0x01;
}

Yahoo! Groups Links
I am still unable to receive data from the host microcontroller via
the CAN bus. The below code resides on my mc9s12dp256b chip. The PORTB
BIT0 glows indicating that the Initialization was done. However, the
PORTB BIT1 does not glow indicating that the ISR is not being triggered.

I am connecting the RX and TX wires from the host controller into the
corresponding pins of the CAN controller chip on the board. Is that
the way to go?
#include /* common defines and macros */
#include /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12dp256b"

/* Acceptance Code Definitions */
#define ACC_CODE_ID100 0x2000
#define ACC_CODE_ID100_HIGH ((ACC_CODE_ID100&0xFF00)>>8)
#define ACC_CODE_ID100_LOW (ACC_CODE_ID100&0x00FF)

/* Mask Code Definitions */
#define MASK_CODE_ST_ID 0x0007
#define MASK_CODE_ST_ID_HIGH ((MASK_CODE_ST_ID&0xFF00)>>8)
#define MASK_CODE_ST_ID_LOW (MASK_CODE_ST_ID&0xFF)

#define bit(x) (1 << (x))

#define INITRQ bit(0);
#define INITAK bit(0);
#define CANE bit(7);

void CANinit(void)
{
CAN0CTL0 = INITRQ;

CAN0CTL1 = CANE;
CAN0BTR0 = 0xC7;
CAN0BTR1 = 0x3A;

// Acceptance Filters
CAN0IDAC = 0x10;
CAN0IDAR0 = ACC_CODE_ID100_HIGH;
CAN0IDMR0 = MASK_CODE_ST_ID_HIGH;
CAN0IDAR1 = ACC_CODE_ID100_LOW;
CAN0IDMR1 = MASK_CODE_ST_ID_LOW;
CAN0IDAC = 0x10; // Set four 16-bit Filters
CAN0IDAR2 = 0x00; // 16-bit Filter 1
CAN0IDMR2 = MASK_CODE_ST_ID_HIGH; // Accepts Standard Data
Frame Msg
CAN0IDAR3 = 0x00; // with ID 0x100
CAN0IDMR3 = MASK_CODE_ST_ID_LOW;
CAN0IDAR4 = 0x00; // 16-bit Filter 2
CAN0IDMR4 = MASK_CODE_ST_ID_HIGH; // Accepts Standard Data
Frame Msg
CAN0IDAR5 = 0x00; // with ID 0x100
CAN0IDMR5 = MASK_CODE_ST_ID_LOW; //
CAN0IDAR6 = 0x00; // 16-bit Filter 3
CAN0IDMR6 = MASK_CODE_ST_ID_HIGH; // Accepts Standard Data
Frame Msg
CAN0IDAR7 = 0x00; // with ID 0x100
CAN0IDMR7 = MASK_CODE_ST_ID_LOW;

CAN0CTL0 = 0x00;

while ((CAN0CTL1 & INITAK));
DDRB_BIT0 = 1;
PORTB_BIT0 = 0;
}

void interrupt CAN0RxISR(void)
{
DDRB_BIT1 = 1;
PORTB_BIT1 = 0;

unsigned char length, index;
unsigned char rxdata[8];

length = (CAN0RXDLR & 0x0F);
for (index=0; index rxdata[index] = *(&CAN0RXDSR0 + index); /* Get received data */
}

CAN0RFLG = 0x01; /* Clear RXF */
}

void main ( )
{
CANinit ( );

CAN0RFLG = 0xC3;
CAN0RIER = 0x01;
}

Memfault Beyond the Launch