« Return to Thread: MSCAN problem

Re: MSCAN problem

by Steve Letkeman-5 :: Rate this Message:

Reply to Author | View in Thread

yes, it did work on hardware.  Is it possible you have a hardware rec
pin issue? That
would explain the correct Ack on the bus and the continuous sending.  Is
there any
pin routing involved in your scheme, maybe?
S


Johannes Schmid wrote:

>
>
> Hi!
>
> Thanks, I think I found this in the mailing list archive before because
> this was the code I started from. I had to change some names because
> register definition were a bit different (only one MSCAN, so CAN0CTL
> becomes CANCTL, etc.) and we use short identifiers (11 bit) but in the
> end I implemented exactly this.
>
> Did this work correctly for you on real hardware?
>
> Thanks,
> Johannes
>
> Am Mittwoch, den 06.05.2009, 15:23 -0600 schrieb Steve Letkeman:
> >
> >
> > 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>
> > > <mailto:johannes.schmid%40octanes.de>
> > > > > 0179 / 1674917
> > > > >
> > > > >
> > > >
> > > >
> > > >
> > > >
> > > >
> > > --
> > > 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
>
>

 « Return to Thread: MSCAN problem