MCF51JM128 CAN tx issues

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

MCF51JM128 CAN tx issues

1,795 Views
ElBonte
Contributor I

I'm writing a CAN transmit function and I'm having problems with the wrong data being transmitted onto the bus.  The data that is transmitted on to the bus (and received when in loopback mode) is not what I am writing into the IDR0..3, DSR0..7, and DLR registers.  I can scope the tx line and see the data transmitted is, indeed, what is being received in loopback mode: the wrong data.

 

I'm using Codewarrior V6.2 and the DEMOJM board.  The tx function follows:

 

 

 

void CAN_send_bytes(N_AI_t N_AI, N_data_t* data, signed int len)
{
  char *dataptr;
  volatile char temp0, temp1, temp2, temp3;
 
DisableInterrupts;
//standard (11-bit) addressing only
    temp0 = (char)( N_AI.CANID >> 3 );
    temp1 = (char)( N_AI.CANID << 5 );
    temp1 &= ~0x10;//    CANRIDR1_IDE = 0;
   
    if(N_AI.RTR)
      temp1 |= 0x08;
    else
      temp1 &= ~0x08;
   
    temp2 = 0;
    temp3 = 0;
   
    CANRIDR0 = temp0;
    CANRIDR1 = temp1;
    CANRIDR2 = temp2;
    CANRIDR3 = temp3;

    CANRDLR = 8;//(char)len + 1; //data + 1 N_PCI byte
   
    temp0 = (char)(len & 0x0F);
    CANRDSR0 = temp0;
   
    dataptr = (char*)&CANRDSR1;
   
    while(len--)   
    {
      *dataptr = *data;
      ++dataptr;
      ++data;
    }

  do
  {
    CANTBSEL = CANTFLG;
  }while(!CANTBSEL); //select available transmit register.  keep looping until one is available.
 
  CANTFLG = CANTBSEL;
EnableInterrupts; 
}

I think that I'm using the process stated in the Functional Description and Programmer's Model sections of the data sheet.  Any ideas on where I'm going wrong?

 

 

Message Edited by ElBonte on 2009-02-24 04:13 PM
Labels (1)
0 Kudos
7 Replies

599 Views
kef
Specialist I

This should be done before accessing TX message buffer, not after:

 

  do
  {
    CANTBSEL = CANTFLG;
  }while(!CANTBSEL); //select available transmit register. 

 

CANTBSEL is used to map one of 3 TX buffers to the memory map. So you should first set up CANTBSEL, fill TX buffer (DSRx, IDRx, DLC registers), then clear TX flag like you do CANTFLG=CANTBSEL.

 

0 Kudos

599 Views
ElBonte
Contributor I
OK, I must've misunderstood how the buffering mechanism works.  I'll try that now.  Thank you.
0 Kudos

599 Views
ElBonte
Contributor I

No luck with that last effort.  I simplified the function to just write constants to the CANRIDRx and CANRDSRx registers as follows:

 

void CAN_send_bytes(N_AI_t N_AI, N_data_t* data, signed int len){  char *dataptr;  volatile char temp0, temp1, temp2, temp3;    do  {    CANTBSEL = CANTFLG;  }while(!CANTBSEL); //select available transmit register.  keep looping until one is available.  CANRIDR0 = 0x55;  CANRIDR1 = 0x55;  CANRIDR2 = 0x55;  CANRIDR3 = 0x55;  CANRDSR0 = 0xAA;  CANRDSR1 = 0xAA;  CANRDSR2 = 0xAA;  CANRDSR3 = 0xAA;  CANRDSR4 = 0xAA;  CANRDSR5 = 0xAA;  CANRDSR6 = 0xAA;  CANRDSR7 = 0xAA;  CANRDLR  = 8;    CANTFLG = CANTBSEL;}

 The frame that is received in loopback mode has CANRIDR0 = 0x92 and CANRIDR1 = 0xF0, CANRDSR0 = 0x69 and CANRDSR1 = 0x4D.  CANRDLR is always 12 (0xC).  Other registers are random.

 

Any other suggestions?  I'm running out of ideas as to what I could be doing wrong and how to debug this.

 

 

0 Kudos

599 Views
kef
Specialist I

Don't know why IDR0 and DLC differ, but please don't compare DSR. You are sending 11bit-ID message with RTR set, so no data is sent.

Do you read all messages from receive queue? Is RXF=0 before you send your message, and RXF=1 after?

Message Edited by kef on 2009-02-24 10:02 PM
0 Kudos

599 Views
ElBonte
Contributor I

Understood on not comparing DSR, as the (corrupt) received data indicates it isn't a a data frame.

 

I am receiving the frame using the CANrx interrupt, so the flag must be getting set by the CAN module.  Just to double-check, I checked the RXF before the CANTFLG=CANTBSEL; line and the flag is cleared.  There is only one frame in the receive FIFO for each frame I attempt to send.

 

Just for reference, the frame I am trying to send (at least prior to the last post) has the ID = 0x7DF, IDE=0, and RTR=0 and DLR = 8.

 

Thanks, by the way, for the help.

0 Kudos

599 Views
ElBonte
Contributor I
OK, figured it out.  I was writing to the CAN rx registers (CANRDRx, CANRIDx, and CANRDLR) which was, of course, doing nothing.  I am now correctly writing to the transmit registers (CANTDRx, CANTIDx, and CANTDLR, respectively).  I never connected the R in those register names with "Receive".
0 Kudos

599 Views
kef
Specialist I
Wow. Didn't notice R vs T in register names. Full MSCAN module register names differ slightly from family to family, so I didn't check if all letters are OK :smileyhappy:. Hope receive is working OK now.
0 Kudos