msCAN on mc9s12dp512 chip

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

msCAN on mc9s12dp512 chip

2,356 Views
dan23
Contributor III

Hello,

 

I’m using the HCS12 TB with the mc9s12dp512 chip and I want to use the msCAN feature on the chip.

 

Does anyone has an example how to initialize CAN0 to send and receive messages from and to another HCS12 TB.

 

It would be great if there was also an example how I can send and receive a massage. I want to use the receive interrupt to read a message.

 

I’ve a code but it isn’t working and I don’t understand the msCAN feature completely.

I’m testing it with the loop back option in the CAN0CTL1 register. And when this is working I want to test it between 2 MCU’s. Eventually I want to communicate between 3 HCS12 T-Boards.

 

Thanks in advance.

Greetings dan23    

Labels (1)
Tags (1)
0 Kudos
5 Replies

533 Views
dan23
Contributor III

Hello,

 

 sorry for my late response.

 

I’ve managed to send a message from one node to another node. I forgot to close the CAN line with resistors.

 

Thanks anyway for your help.

 

Greetings dan23  

0 Kudos

533 Views
dan23
Contributor III

Hello,

 

I’ve already 3 HCS12 T-boards with the mc9s12Dp512 chip in my possession. So switching to another chip isn’t an option.  

 

msCAN is working now on 1 board when I use the loop back mode.

 

It isn’t working when I want to communicate between 2 HCS12 boards. Is it a wrong initialization for CAN0?

 

void SetCan0(void)

{

  CAN0CTL1_CANE = 1;    //enable CAN, required after reset

  //----------------------------------------------------------------

  CAN0CTL0_INITRQ = 1;     //MSCAN in Initialization Mode.

  while(!CAN0CTL1_INITAK); //The registers CANCTL1, CANBTR0, CANBTR1,      

                           //CANIDAC, CANIDAR0-7, CANIDMR0-7 can

                           //only be written by the CPU when the MSCAN

                           //is in Initialization Mode.

  //----------------------------------------------------------------

  //Initialization Mode

  CAN0CTL1 = 0xC0;         //The MSCAN module is enabled.

                           //The MSCAN clock source is the Bus Clock.

                           //Loop Back Self Test disabled with 0xC0 and

                           //enabled with 0xE0

  CAN0BTR0 = 0x08; //SJW 1 Tq clock cycles

                   //Prescaler value (8)

  CAN0BTR1 = 0x14; //One sample per bit.

                   //Time Segment 2 = 2 Tq clock cycle

                   //Time Segment 1 = 5 Tq clock cycle

 

    //For standard identifiers, only the first two (CANIDAR0/1,     

    //CANIDMR0/1) are applied

  CAN0IDMR0 = 0b00000000;

  CAN0IDMR1 = 0b00011111;

 

  CAN0IDAR0 = 0b00100010;

  CAN0IDAR1 = 0b00000000;

 

  CAN0IDAC = 0x10; //Four 16 bit Acceptance Filters 

  //----------------------------------------------------------------

  CAN0CTL0_INITRQ = 0;    //MSCAN in Normal operation.                 

  while(CAN0CTL1_INITAK); //following reg can only be written by the  

                          //CPU when the MSCAN out of Initialization    

                          //Mode.

  //----------------------------------------------------------------

  //Normal operation.

  CAN0CTL0 = 0x00; //The module is not affected during Wait Mode.                  

                   //Disable internal MSCAN timer.

                   //Wake-Up disabled The MSCAN ignores traffic on CAN.

                   //Running The MSCAN functions normally.

  CAN0RIER = 0x01; //A receive buffer full (successful message

                   //reception) event causes a receiver interrupt  

                   //request.

  CAN0TBSEL = 0x01; //TX0 message Buffer is selected, if lowest

                    //numbered bit.

                                                                                                                                  

}

 

greetings dan23

0 Kudos

533 Views
Lundin
Senior Contributor IV
The sleep mode approach in my code isn't needed unless you wish to re-init the MSCAN in runtime, ie call the init function more than once. Sleep mode makes any current CAN traffic to end smoothly, so your node doesn't bring the whole CAN-bus down.

Apart from that, I can't see any issues in your code.

---

What is "not working"? Is the code not compiling, is there no CAN traffic on the MCU pin or on the tranceiver pin, does the MCU halt and catch fire? Please specify.

Very common errors are:
- No CAN-bus terminition.
- Just one single working node on the bus.
- Messed up mask & filter settings. Don't touch these before you have the communication up and running.
0 Kudos

533 Views
Lundin
Senior Contributor IV
Here's an init snippet from my MSCAN-driver. I'm using a macro that makes it possible to pick which CAN port to use, hence the "reg_" in front of the register names.

I put the module to sleep mode before setting anything. This was advised in some app note, in case the code is called more than once from the program.


  reg_CANCTL1(port) = CANE;                      /* can enable (write once), no special modes */
 
  /* Note! CANE must be set before sleep mode can be entered */
 

  reg_CANCTL0(port) |= SLPRQ;                    /* sleep mode */
  reg_CANCTL0(port) |= INITRQ;                   /* init mode  */
  {
    while((reg_CANCTL1(port) & SLPAK)==0)        /* wait until CPU enters sleep mode. */
    {
      ;
    }
   
   
    reg_CANCTL1(port) |= CLKSRC;                 /* clksrc=bus */

    *(uint16*)&reg_CANBTR0(port) = baudrate;

    if(filter != NULL)
    {
      if(filter->type == BASIC_CAN)
      {
        reg_CANIDAC(port) = 0x10;                /* 4 x 16-bit filters */
      }
      else /* type == EXTENDED_CAN */
      {
        reg_CANIDAC(port) = 0x00;                /* 2 x 32-bit filters */
      }
     
      *(uint32*)&reg_CANIDAR0(port) = filter->id_accept._32bit[0];
      *(uint32*)&reg_CANIDAR4(port) = filter->id_accept._32bit[1];
     
      *(uint32*)&reg_CANIDMR0(port) = filter->id_mask._32bit[0];
      *(uint32*)&reg_CANIDMR4(port) = filter->id_mask._32bit[1];
   
    } /* if(filter != NULL) */
  }
  reg_CANCTL0(port) &= ~SLPRQ;                   /* leave sleep mode   */
  reg_CANCTL0(port) &= ~INITRQ;                  /* leave init mode    */

  if(useRxInterrupt)
  {
    reg_CANRIER(port) = RXFIE;
  }


  while ((reg_CANCTL1(port) & (SLPAK|INITAK)) > 0)   /* wait until CAN is running */
  {
    ;
  }
0 Kudos

533 Views
panzer40
Contributor I
Hi, I working in comunication MCU to MCU too, I´m working with two mc9s12xdt512 trying to comunicate by mscan, but it doesn´t work yet. I recomend the AN3034, and AN1798.
 
Message Edited by t.dowe on 2009-10-22 09:19 AM
0 Kudos