CAN  Transmission problem

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

CAN  Transmission problem

Jump to solution
2,823 Views
SARY
Contributor III

Hi guys

    sorry my message box was empyty. I am working on Freescale 16-bit microcontroller MC9S12XHz512.I am tryinyg to implement CAN on it. But only its reception part is working.I want to transmit data on CAN.

    Does anyone know what are the register setting for that or is there any sample code available n where?If anyone has any idea Plz reply me as soon as possible.

 

SARY 

Labels (1)
0 Kudos
1 Solution
950 Views
SARY
Contributor III

hi

CANTx flag and register are fine .nway I have solved my problem .Now I can transmit data whenever I want.Thanks for ur reply.NowI can mark it as solved.

View solution in original post

0 Kudos
9 Replies
950 Views
kef
Specialist I
Just a guess, is CANCTL1 register LISTEN bit set? CAN module won't transmit any message when LISTEN=1.
0 Kudos
950 Views
SARY
Contributor III

hi Kef

thanks for the reply.But no that bit is zero.here is some part of code.

 

 CAN0CTL0_INITRQ = 1;
  while((CAN0CTL1&1)==0);
  
CAN0CTL1 = 0xC0;    //Enable MSCAN with bus clk, wake up enable
 
  CAN0BTR0 = 0x04;    //SJW=1 and Tq freq=4MHz
  CAN0BTR1 = 0x1C;    //1bit time =(PS*(1+13+2))/fclk =(5*16)/20M=4us =250 kbps (1bit=16Tq)
  CAN0IDAC = 0x00;    //Two 32 bit accept filters
 
  //Bank 1
  CAN0IDAR0 = 0;
  CAN0IDAR1 = 0x08;//Match IDE bit=1 to support only EXT ID
  CAN0IDAR2 = 0;
  CAN0IDAR3 = 0;   //Match RTR bit=0 to support only DATA FRAME
 
  //Bank 2
  CAN0IDAR4 = 0;
  CAN0IDAR5 = 0x08;//Match IDE bit=1
  CAN0IDAR6 = 0;
  CAN0IDAR7 = 0;   //Match RTR bit=0

  //if MR_bit=1, don't check corres. AR_bit and accept that bit always
  //if MR_bit=0, check corres. AR_bit and accept that bit only if it matches
 
  //Bank 1
  CAN0IDMR0 = 0xFF;
  CAN0IDMR1 = 0xF7;//Match IDE bit for accepting Extended ID only (no std frame)
  CAN0IDMR2 = 0xFF;
  CAN0IDMR3 = 0xFE;//Match RTR bit for accepting DATA frames only (no remote frame)
 
  //Bank 2
  CAN0IDMR4 = 0xFF;
  CAN0IDMR5 = 0xF7;
  CAN0IDMR6 = 0xFF;
  CAN0IDMR7 = 0xFE;

   
  CAN0CTL0 = 0x00;            /* Exit initialization mode request */
  while (CAN0CTL1_INITAK)
     ;                /* Wait for normal mode */
                  
  while(!(CAN0CTL0_SYNCH))
      ;                   /* Wait for CAN synchronization */
  
  CAN0RFLG_RXF = 1;       /* Clear receiver flags */                                  
  CAN0RIER_RXFIE = 1;

 

 

I dont know but may be transmit interrupt has  to be defined at some address .I dont know where to define that.Right now i have defined it  like

#pragma CODE_SEG __NEAR_SEG NON_BANKED

void interrupt 5 knopp()

{
    unsigned char  u8TxBuffer = {0},u8Length=8;
    unsigned long u32ID=0x18FEF100;

    unsigned char  u8TxData[8]={ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18};
 
    unsigned char u8Index;
   
   
   // if (!CAN0TFLG)              /* Retrun if Transmit Buffer is full */
     //   return ERR_BUFFER_FULL;

    CAN0TBSEL = CAN0TFLG;       /* Select lowest empty buffer */
    u8TxBuffer = CAN0TBSEL;  /* Backup selected buffer */
    *((unsigned long *) ((unsigned long)(&CAN0TXIDR0)))= u32ID;   /* Load Id to IDR Registers */
       
        /* Load data to Data Segment Registers */
        for (u8Index=0;u8Index<u8Length;u8Index++) {
            *(&CAN0TXDSR0 + u8Index) = u8TxData[u8Index]; 
        }

    CAN0TXDLR = 8;   /* Set Data Length Code */
    CAN0TXTBPR = 1;    /* Set Priority */

    CAN0TFLG = u8TxBuffer;  /* Start transmission */
               
        while ( (CAN0TFLG & u8TxBuffer) != u8TxBuffer);
          /* Wait for Transmission completion */
 

}
for testing purpose and i am forcefully setting CAN0TFLG flag in main loop.should it work.

waitig for reply

SARY

0 Kudos
950 Views
kef
Specialist I

I dont know but may be transmit interrupt has  to be defined at some address .I dont know where to define that.Right now i have defined it  like

 

You could set  CAN0 TX interrupt vector like this:

 

#pragma CODE_SEG __NEAR_SEG NON_BANKED

void interrupt VectorNumber_Vcan0tx knopp(void)

{

...

}

#pragma CODE_SEG DEFAULT

 

What's inside your knopp routine should force CAN module to send message.

0 Kudos
950 Views
SARY
Contributor III

I have tried dat but it does not got to the interrupt function.What I m doing now is I hav defined a function like

int interrupt_5_knopp()

n wen I want to tx data on CAN I just call these function.Though its working but is it the right method?n also if I want to test some request type of PGN to which an Engine ECU should respond .How can I test that wd no ECUs in my Lab.I mean wat data should a cAT analzing tool must send.

I just want to check dat both tx n rx part of CAN should work fine n simultaneously.

SARY

0 Kudos
950 Views
SARY
Contributor III

Hi Kef 

     I am facing one problem with the code .I am sending PGN no. as unsigned long and putting it in the register like

u32ID=0x18FEF100;

 *((unsigned long *) ((unsigned long)(&CAN0TXIDR0)))= u32ID;

Is it right method or I hav to make some conversions.

because PGN No. I m recieving on CAT(I+ME) software tool is different it is 0x031F7880.

what may be the  problem ,in the coding part or CAN software tool.

do reply if you have any idea.

 

SARY

 

0 Kudos
949 Views
kef
Specialist I

Who is PGN and what is dat, n, hav etc? I don't understand. Well, maybe it's because English is not my native language.

Did you enable CAN TX interrupt? If not, then no wonder your ISR doesn't get called.

 

You wrote that calling int interrupt_5_knopp() works. Then you should mark this thread as solved or change somehow the subject line. Is right to call knopp directly or to convert it to ISR, it's up to you and your program requirements. CAN TX ISR is neede only when it's necessary to stream few CAN messages. You may wait in your main thread, you may also put messages to FIFO queue and let CAN TX interrupt to send data from FIFO.

 

I don't know either what's in your u32ID variable. Is it CAN ID or CAN ID converted to MSCAN CANIDRx registers ID bits layout. If you won't to know how to convert CAN ID to MSCAN CANIDRx bits, then you should open your S12XHZ datasheet and study  

Figure 14-25. Receive/Transmit Message Buffer — Standard Identifier Mapping

and

Figure 14-24. Receive/Transmit Message Buffer — Extended Identifier Mapping

 

It's a pity figure 14-24 is not as clear as figure 14-25. But if you compare contents of IDR0-IDR3 registers in both figures, then you should understand how to calculate IDRx bits from CAN ID when trasmitting and how to calculate CAN ID from IDRx bits on receive.

 

Regards

0 Kudos
950 Views
SARY
Contributor III

hi

PGN mean parameter group number or id of a CAN message.I have enabled all CAN Tx interrupt .But its not working.

I cant mark it as slolved ,because still I am not able to receive correct PGN(CAN Identifier) which I am transmitting.I want to transmit Trip Reset command and I am sending it in a unsigned long format .

i.e.  

  *((unsigned long*) ((unsigned long)(&CAN0TXIDR0)))= 0x18DE0000;

But what I have received on my CAT tool(CAN analzing tool ) is different.I cant test that on Engine ECU right now.So I just want to know wats the problem.

Is the CAT tool is showing wrong data or coding part has some problem.

I hope now you understand my problem.

SARY

0 Kudos
949 Views
kef
Specialist I

First you say you can't transmit. Then you say you can trasmit, but can't trigger TX interrupt. Can = solved, isn't it? :smileyhappy:

 

Like I wrote already, you should check CANxxIDRx ID bits layout. Those figures explain where every CAN message ID bit goes in CANxxIDRx registers and in CAN acceptance registers. Of course when you want to send message with some ID, you can't simply

 

 *((unsigned long*) &CAN0TXIDR0)= ID;

 

It should be something like this (not tested):

 

CAN0TXIDR0 = (char)(ID >> 21);

CAN0TXIDR1 = (char) (

                                   ((ID >> (18-5)) & 0xE0)

                                 | ((ID >> 15) & 7)

                                 | 0x18

                              );

CAN0TXIDR2 = (char)(ID >> 7);

CAN0TXIDR3 = (char)(ID << 1);

 

0 Kudos
951 Views
SARY
Contributor III

hi

CANTx flag and register are fine .nway I have solved my problem .Now I can transmit data whenever I want.Thanks for ur reply.NowI can mark it as solved.

0 Kudos