problem sending data on s08 can

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

problem sending data on s08 can

2,122 Views
Pinak
Contributor II

I am using s08dz48 controller.

I have configured CAN module to transmit data.

Below are the settings

OSC CLK=4M, No PLL used

clk to CAN from OSC.

CAN configured at 250KBPS

 

CAN module is working and I am able to send required data bytes(0 to 7) on bus.

The problem is that I am receiving garbage data OR 0x00 on bus.

 

This is because the the transmit data registers does not cantain the desired value.

This can be seen in debug window, whenever data is assigned to CANtxdata register, it does not get loaded to cantxdata register.

 

Is there any problem with clock.

 

Thanks in advance.

 

Labels (1)
Tags (2)
0 Kudos
Reply
9 Replies

1,766 Views
mauricio2346
Contributor II

Hi Folks!. i been working for a while with a JM128 Coldfire V1 microcontroller.  this time, i need to talk with a MPPT module that uses CAN to send telemetry information (temperature, current, voltage, etc.).  i used as template a CAN library made to HCS08 microcontrollers.  if i made polling over nodes ID, i can get the whole think work flawless.  but, this MPPT module needs a remote frame request to send its data trought the bus.

how can i get this to work? its just as easy as setting RTR bit to 1?

this is my routine.

CAN initialization routine (using 12Mhz external oscillator, i get 10.66 us bit time or 93.75kbits/s of baudrate.)

void CAN_Init(unsigned char loopback){

  CANCTL0 |= CANCTL0_INITRQ_MASK; // Solicitud para entrar en modo Inicialización.

  while(!CANCTL1_INITAK);         // Espere hasta que entre en modo Inicializacion

 

 

  if(loopback & 0x01 == 0x01){

    CANCTL1 = CANCTL1_CANE_MASK | CANCTL1_LOOPB_MASK;   //Si está activado modo LoopBack.

  }

  else{

    CANCTL1 = CANCTL1_CANE_MASK;   //Modo normal activado

  }

 

  CANBTR0 = 0xC7; // Ajuste el preescaler del modulo.

 

  // One sample per bit, TSEG1 = 10, and TSEG2 = 3.

  // CANBTR1 = 0x3A; 

  CANBTR1_SAMP = 0;

  CANBTR1_TSEG_10 = 10;

  CANBTR1_TSEG_20 = 3;

  CANIDAC = 0x10; // seleccione cuatro filtros de 16 bits.

  CANIDAR0 = 0x00; // Borre los registros de filtros.

  CANIDAR1 = 0x00;

  CANIDAR2 = 0x00;

  CANIDAR3 = 0x00;

  CANIDAR4 = 0x00;

  CANIDAR5 = 0x00;

  CANIDAR6 = 0x00;

  CANIDAR7 = 0x00;

  CANIDMR0 = 0xff; // Acepte todos los mensajes de entrada

  CANIDMR1 = 0xff; 

  CANIDMR2 = 0xff;

  CANIDMR3 = 0xff;

  CANIDMR4 = 0xff;

  CANIDMR5 = 0xff;

  CANIDMR6 = 0xff;

  CANIDMR7 = 0xff;

  CANCTL0 &= ~CANCTL0_INITRQ_MASK; // Solicitar salida del modo de inicializacion.

  while(CANCTL1_INITAK);  // espere hasta que MSCAN entre en modo normal

  while(!CANCTL0_SYNCH); // espere hasta que MSCAN se sincronice con bus.

 

  // Reset the receiver wake-up, CAN status change, overrun,

  // and receiver full interrupt flags.

  CANRFLG |= CANRFLG_WUPIF_MASK;

  CANRFLG |= CANRFLG_CSCIF_MASK;

  CANRFLG |= CANRFLG_OVRIF_MASK;

  CANRFLG |= CANRFLG_RXF_MASK;

 

  // Enable the receive buffer full interrupt.

  CANRIER |= CANRIER_RXFIE_MASK;

 

}

CAN Send routine:

unsigned char CAN_Send(unsigned long id, unsigned char priority, unsigned char length, unsigned char *txdata) {   

  unsigned char index;

  unsigned char txbuffer = {0};

 

  if(!CANTFLG){                // Están llenos los buses de salida???

    return CAN_BUFFER_FULL;

  }

 

  CANTBSEL = CANTFLG; // Seleccione el buffer numerado más pequeño

  txbuffer = CANTBSEL;

  CANTIDR0 = (id >> 3) & 0xff;  // Cargue el identificador en los registros IDR.

  CANTIDR1 = (id & 0x07) << 5;

  /************/

  CANTIDR3_RTR=1;    

  /***********/ 

  for(index = 0; index < length; index++) { //Cargue el dato en el buffer de datos.

    *(&CANTDSR0 + index) = txdata[index];

  }

 

  CANTDLR = length; //ajuste la longitud del mensaje

  CANTTBPR = priority; // ajuste la prioridad del mensaje

  CANTFLG = txbuffer; //Baje la bandera de transmision del buffer.  1= baja bandera.

              

  while((CANTFLG & txbuffer) != txbuffer); //espere hasta que se transmita el dato.

  return CAN_NO_ERROR;  //si el mensaje llegó, avise que no hubo error.

}

any help?

regards;

Mauricio

0 Kudos
Reply

1,766 Views
Lundin
Senior Contributor IV

Messages sent out from a MSCAN node are not received by the same node. In a real application, it doesn't make sense to listen to your own messages. For debugging and self test purposes only, there is a "loop back" mode which causes the sent messages to appear in the rx buffers. Unless you have enabled loop back, you will never receive the sent messages.

If you can verify that the messages are sent correctly (with an external CAN listener), then there cannot be any problems with your clock or baudrate settings. I don't understand what you mean with "the transmit data registers does not contain the desired value".

0 Kudos
Reply

1,766 Views
Pinak
Contributor II

Hello Daniel,

I am not testing CAN in loopback mode, I am sending data on bus & have connected can analyzer on the other side. I am also able to send data on to the bus.

The registers I mentioned above are the CANTDSR0-CANTDSR7. Whatever data I assign to these registers doesnt gets store there and ultimately I dont receive it.

i.e CANTDSR0=can_data[0], then the data in var can_data[0] is not assigned to CANTDSR0, and after the above line of code CANTDSR0 still contains 0x00.

Any help.

0 Kudos
Reply

1,766 Views
kef
Specialist I

I guess you didn't select any TX buffer. CANTDSRx is writeable and readable only when one of CANTBSEL bits in is set.

0 Kudos
Reply

1,766 Views
Pinak
Contributor II

Before transmitting I am polling till I find empty tx buf. When I have  got that,
then only I put data in data seg register. But still I am not able to receive
the data.

Thanks in advance.

0 Kudos
Reply

1,766 Views
StenS
Contributor III

Perhaps you should show us your code, so it would be easier for us to understand what you are doing? There is no need for polling for an empty tx-buf, just check that CANTLG is non-zero and then assign CANTBSEL = CANTFLG. You can't write to any CAN buffer resigster before doing so.

Sten

0 Kudos
Reply

1,766 Views
Pinak
Contributor II

Hello Sten,

Below is the code through which I select tx buf and then write data in data seg register,

/****************************************************************************

x=0;

while(!(CANTFLG & (0x01<<x)))   // find free buf

{

       x++;

       if(x == 3)

        x=0;

CANTBSEL = 0x01<<x;

0 Kudos
Reply

1,766 Views
admin
Specialist II

This piece of code doesn't demonstrate your problem. Where are accesses to xxxTDSRx?

Do you wonder if S08DZ CAN is working? Yes, it is fine.

0 Kudos
Reply

1,766 Views
StenS
Contributor III

Try this approach instead:

if (CANTFLG) {     // any transmit buffer empty?

   CANTBSEL = CANTFLG;     // select first empty transmit buffer

   // write IDR-, DLR- and DSR-registers

   CANTFLG = CANTBSEL;     // Transmit!

}

else // no vacant transmit buffer; do the appropiate action (wait or put message in software buffer)


Sten

0 Kudos
Reply