this was the code I started from. I had to change some names because
>
>
> ok, I thought it was important to cover the basics first as you just
> never know
> where a person is starting from. Here is some very old and outdated
> code
> but it may point you in the right direction...
> Steve
>
> // This file may be freely distributed as long as this header remains
> // intact in order to encourage you to visit our web site
> // at www.zanthic.com home of the CAN-4-USB interface
> // This simple program was written as a quick and easy
>
> // example of initializing and testing the msCAN port (V2.14)
> // on an MC9S12 processor. No warranty implied or given.
> // This program was written as a single file for
> // simplicity and only some of the registers are included.
> // Written by Steve Letkeman Feb 2004
>
> // compiled using the ICC12 compiler from imagecraft
> (www.imagecraft.com)
> // Vector file not included but only contains two entries, start at
> 0xFFFE
> // and the CAN0 receive interrupt vector pointing to CAN_Receive()
>
> // sends CAN ID 1 (29 bit) at power up and receives ID 2 (29 bit) and
> // echos back to ID 1 when received
>
> #define CAN0CTL0 *(unsigned char volatile *)(0x0140)
> #define CAN0CTL1 *(unsigned char volatile *)(0x0141)
> #define CAN0BTR0 *(unsigned char volatile *)(0x0142)
> #define CAN0BTR1 *(unsigned char volatile *)(0x0143)
> #define CAN0RFLG *(unsigned char volatile *)(0x0144)
> #define CAN0RIER *(unsigned char volatile *)(0x0145)
> #define CAN0TFLG *(unsigned char volatile *)(0x0146)
> //#define CAN0TIER *(unsigned char volatile *)(0x0147)
> //#define CAN0TARQ *(unsigned char volatile *)(0x0148)
> //#define CAN0TAAK *(unsigned char volatile *)(0x0149)
> #define CAN0TBSEL *(unsigned char volatile *)(0x014A)
> #define CAN0IDAC *(unsigned char volatile *)(0x014B)
> //#define CAN0RXERR *(unsigned char volatile *)(0x014E)
> //#define CAN0TXERR *(unsigned char volatile *)(0x014F)
> #define CAN0IDAR0 *(unsigned char volatile *)(0x0150)
> #define CAN0IDAR1 *(unsigned char volatile *)(0x0151)
> #define CAN0IDAR2 *(unsigned char volatile *)(0x0152)
> #define CAN0IDAR3 *(unsigned char volatile *)(0x0153)
> #define CAN0IDMR0 *(unsigned char volatile *)(0x0154)
> #define CAN0IDMR1 *(unsigned char volatile *)(0x0155)
> #define CAN0IDMR2 *(unsigned char volatile *)(0x0156)
> #define CAN0IDMR3 *(unsigned char volatile *)(0x0157)
> #define CAN0IDAR4 *(unsigned char volatile *)(0x0158)
> #define CAN0IDAR5 *(unsigned char volatile *)(0x0159)
> #define CAN0IDAR6 *(unsigned char volatile *)(0x015A)
> #define CAN0IDAR7 *(unsigned char volatile *)(0x015B)
> #define CAN0IDMR4 *(unsigned char volatile *)(0x015C)
> #define CAN0IDMR5 *(unsigned char volatile *)(0x015D)
> #define CAN0IDMR6 *(unsigned char volatile *)(0x015E)
> #define CAN0IDMR7 *(unsigned char volatile *)(0x015F)
> #define CAN0RXFG (unsigned char volatile *)(0x0160)
> #define CAN0TXFG (unsigned char volatile *)(0x0170)
>
> #define CANE 0x80
> #define INITAK 1
> #define INITRQ 1
> #define SLPRQ 2
> #define SLPAK 2
>
> void SendCANMessage(unsigned char NumBytes, unsigned char *BufPntr);
> void CANInit(void);
>
> void main(void)
> {
> unsigned char BufPntr[8];
>
> CANInit();
>
> asm("cli");
>
> BufPntr[0]=0x11;
> BufPntr[1]=0x22;
> BufPntr[2]=0x33;
> BufPntr[3]=0x44;
> BufPntr[4]=0x55;
> BufPntr[5]=0x66;
> BufPntr[6]=0x77;
> BufPntr[7]=0x88;
>
> SendCANMessage(8, BufPntr); // send a CAN packet
> with 8 bytes of data
>
> while(1); // wait here for
> receive interupt
>
> }
>
> //
> #############################################################################
>
> // Incoming CAN messages will be caught here
> #pragma interrupt_handler CAN_Receive
> void CAN_Receive(void)
> {
> unsigned char Temp[8];
>
> Temp[0]=*(CAN0RXFG+4); // Grab the first data byte
> // currently no checking for
> number of bytes etc
> SendCANMessage(1, Temp); // send it back
>
> CAN0RFLG |=1; // clear rec flag
> }
>
> //
> #############################################################################
>
> void SendCANMessage(unsigned char NumBytes, unsigned char *BufPntr)
> {
> unsigned char NACAN,C;
>
> while(!CAN0TFLG); // wait for
> available buffer
> NACAN=CAN0TFLG; // get the
> next available CAN buffer
> CAN0TBSEL=NACAN;
>
> *(CAN0TXFG+0)=0x00; // set the
> transmit ID
> *(CAN0TXFG+1)=0x08; // extended ID
> (29 bit)
> *(CAN0TXFG+2)=0x00;
> *(CAN0TXFG+3)=0x02; //
> ID=00-00-00-01
>
> if (NumBytes>8) NumBytes=8;
> for (C=0;C<NumBytes;C++)
> *(CAN0TXFG+4+C)=*BufPntr++; // store the data
>
> *(CAN0TXFG+0x0C)=NumBytes; // set number of
> bytes to send
>
> NACAN=CAN0TBSEL;
> CAN0TFLG =NACAN; // transmit
> }
>
> //
> #############################################################################
>
> void CANInit(void)
> {
> CAN0CTL0 |= INITRQ; // set
> INITRQ, this will also set INITAK
> while (!(CAN0CTL1 & INITAK)); // wait for init
> mode to occur
>
> CAN0CTL1 = CANE; // Set CANE just
> in case this is the first time after reset
>
> CAN0BTR0=0x03;
> CAN0BTR1=0x32; // for a CAN
> Baud of 500kbps at 16Mhz crystal
>
> CAN0IDMR0=0x00;
> CAN0IDMR1=0x08; //IDE=1
> CAN0IDMR2=0x00;
> CAN0IDMR3=0x00;
>
> CAN0IDAR0=0x00;
> CAN0IDAR1=0x18; // SRR&IDE=1
> CAN0IDAR2=0x00;
> CAN0IDAR3=0x04; // ID=2, remote
> frame (bit 0)=0
>
> // set the second filter to must match 0xFFFFFFFF
> CAN0IDMR4=0;
> CAN0IDMR5=8; //IDE=1
> CAN0IDMR6=0;
> CAN0IDMR7=0;
> CAN0IDAR4=0xFF;
> CAN0IDAR5=0xFF;
> CAN0IDAR6=0xFF;
> CAN0IDAR7=0xFF;
>
> CAN0IDAC=0; // set filters to
> 2 32 bit acceptance filters
>
> CAN0CTL0 &= ~INITRQ; // clear
> INITRQ
> while (CAN0CTL1 & INITAK);
>
> CAN0CTL1 |= CANE; // Set CANE
> just in case this is the first time after reset
> CAN0RIER |= 1; // enable
> receive interrupt
>
> }
>
> Johannes Schmid wrote:
> >
> >
> > Hi!
> >
> > > I didn't look over your code but your comments about the message
> > > continuing to
> > > send caught my attention. This might be an obvious question, but
> do
> > > you
> > > have
> > > at least two CAN nodes on the network? CAN is not like RS232 where
> you
> > > can just send a message to nobody, you must have another node with
> > > the
> > > correct
> > > settings for the message to be ACK'd. It also requires a properly
> > > terminated
> > > network, two 120 ohm resistors on each end and a common ground.
> Maybe
> > > these have been covered but they are worth mentioning just in
> case...
> >
> > Yes, we have two terminations and tried with various nodes. As
> already
> > said, we also checked the ACK on the Bus using a scope. The other
> nodes
> > are known to work flawlessly as well as the Peak PCAN usb Dongle we
> use.
> >
> > I was also suspected the ACK first but seems that this isn't the
> problem
> > (or the MSCAN does not recognize the ACK for some reason).
> >
> > Regards,
> > Johannes
> >
> > > --
> > > Steven D. Letkeman BSc.
> > > Zanthic Technologies Inc.
> > > www.zanthic.com Embedded micro-controllers and CAN interfaces
> > >
> > > Johannes Schmid wrote:
> > > >
> > > >
> > > > Hi everybody!
> > > >
> > > > I have a problem using the CAN-Bus interface of the HCS12 used
> in
> > > the
> > > > MicroSquirt(tm) ECU we use on our Formula race car.
> > > >
> > > > Following the various data sheets I came up with the following
> code:
> > > >
> > > > void CanInit(void)
> > > > {
> > > > /* Set up CAN communications */
> > > > /* Enable CAN, set Init mode so can change registers */
> > > > CANCTL1 |= 0x80;
> > > > CANCTL0 |= 0x01;
> > > >
> > > > while(!(CANCTL1 & 0x01))
> > > > ; // make sure in init mode
> > > >
> > > > /* Set Can enable, use IPBusclk (24 MHz),clear rest */
> > > > CANCTL1 = 0xC0;
> > > > /* Set timing for .5Mbits/ sec */
> > > > CANBTR0 = 0xC2; /* SJW=4,BR Prescaler= 3(24MHz CAN clk) */
> > > > CANBTR1 = 0x1C; /* Set time quanta: tseg2 =2,tseg1=13
> > > > (16 Tq total including sync seg (=1)) */
> > > >
> > > > CANIDAC &= ~0x30; /* no filters */
> > > >
> > > > /* clear init mode */
> > > > CANCTL0 &= 0xFE;
> > > > /* wait for synch to bus */
> > > > while(!(CANCTL0 & 0x10));
> > > >
> > > > /* no xmit yet */
> > > > CANTIER = 0x00;
> > > > /* clear RX flag to ready for CAN recv interrupt */
> > > > CANRFLG = 0xC3;
> > > > /* set CAN rcv full interrupt bit */
> > > > CANRIER = 0x01;
> > > > return;
> > > > }
> > > >
> > > > void CanSend(CAN_message* msg)
> > > > {
> > > > unsigned char txbuffer, i;
> > > > static unsigned char flag = 1;
> > > >
> > > > if (!flag)
> > > > return;
> > > > flag = 0;
> > > >
> > > > if (!CANTFLG)
> > > > return; // everything is more important than messages from the
> > > > ECU, so just drop out if we cannot send
> > > >
> > > > CANTBSEL = CANTFLG; // Select free buffer to use
> > > > txbuffer = CANTBSEL; // backup buffer
> > > >
> > > > CAN_TB0_IDR0 = (unsigned char) msg->id >> 3; // higher 8 bits of
> id
> > > > CAN_TB0_IDR1 = (unsigned char) msg->id << 5; // lower 3 bits of
> id;
> > > > CAN_TB0_IDR1 &= ~(0x18); // Set to standard frames (IDE = 0)
> > > > CAN_TB0_IDR2 = 0;
> > > > CAN_TB0_IDR3 = 0;
> > > >
> > > > for (i = 0; i < msg->length; i++) {
> > > > *(&CAN_TB0_DSR0 + i) = msg->data[i];
> > > > }
> > > >
> > > > CAN_TB0_DLR = msg->length; // Set length
> > > > CAN_TB0_TBPR = 0; // priority
> > > >
> > > > // Send message
> > > > CANTFLG = txbuffer;
> > > > }
> > > >
> > > > However, when I send a single CAN message, MSCAN floods the
> CAN-Bus
> > > with
> > > > messages (sending probably any us) and never stops. I checked on
> the
> > > > osci and there is an ACK on the bus so I guess everything should
> be
> > > > fine. Do I need to clear some buffer to make it stop sending
> > > messages?
> > > >
> > > > Thanks a lot for your help
> > > >
> > > > Johannes
> > > >
> > > > --
> > > > Johannes Schmid
> > > > High-Octane-Motorsports
> > > > Teamleiter Elektronik
> > > >
johannes.schmid@... <mailto:johannes.schmid%
> 40octanes.de>
> > <mailto:johannes.schmid%40octanes.de>
> > > > 0179 / 1674917
> > > >
> > > >
> > >
> > >
> > >
> > >
> > >
> > --
> > Johannes Schmid
> > High-Octane-Motorsports
> > Teamleiter Elektronik
> >
johannes.schmid@... <mailto:johannes.schmid%40octanes.de>
> > 0179 / 1674917
> >
> >
>
>
>
>
>