MSCAN12 Configuration

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

MSCAN12 Configuration

4,573 Views
andrea_olivieri
Contributor I
I've to write a MSCAN12 fw for S12DJ256B controller.
In order to test if my low level SW is correctly I've connected MSCAN12 Controller 0 (As Tx Node) whith MSCAN12 Controller 4 (As Rx Node).
Source should be provided by Processor Expert Tool but the code inside each function is empty cause I hven't got any licence for advanced beans and I haven't got so mutch money to buy one. I tried to fill in the unavailable code functions of my app. and as soon I wrote all code needed I played it, and (of course) it doesn't work. By app's behavior seems the transmitter node (MSCAN12 Controller 0) whork good but the receiver (MSCAN12 Controller 4) doesn't work correctly.
Basically i need to check whith U where I wrong. In the following I wrote the main topic about the involved source code.
  • step-1:
    As soon the application get into main() function, MCU start to configure his internal peripherals by calling "PE_low_level_init()" function...
void main(void)
{
 /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
 PE_low_level_init();
 ...
  • step-2: Inside "PE_low_level_init()" ther's configuration code for MSCAN12 (Caontroller 0 and 4).
    Configuration is done by calling "CAN_Controller_0_Init" and "CAN_Controller_4_Init".
    NOTE: Respect to the original implementation of those function Processor Expert doesn't accept any parameter. But i need to allow a runtime initialization,where it must be a way to change bus speed as well, and this feature isn't provided by Processor Expert (It Allow U to set bus timing parameters once by using a Bit timing Wizard)...
void PE_low_level_init(void)
{
 /* Common initialization of the CPU registers */
 ...
 /* ###  "CAN_Controller_0" init code ... */
 CAN_Controller_0_Init(0x0,0x10/*8 if ck = 16Mhz*/,0x6,0x7);
 /* ###  "CAN_Controller_4" init code ... */
 CAN_Controller_4_Init(0x0,0x10/*8 if ck = 16Mhz*/,0x6,0x7);
 ...

  • step-3:smileyfrustrated:ource code inside "CAN_Controller_0" and "CAN_Controller" is the same (the only difference is the address space used to configure both controllers 0 and 4), so I'll show U the Source code for CAN_Controlloer_0 bean.
    Init function get parameters to set default CAN bus speed (125Kbps) and manteins the peripheral disabled as well...
void CAN_Controller_0_Init(byte clkSrc,byte brpReg,byte tSegReg1,byte tSegReg2)
{
 EnUser = FALSE; /*Variable "EnUser" is defined locally by Processor Expert*/
 EnEvent= FALSE; /*Variable "EnUser" is defined locally by Processor Expert*/
 Cksrc=clkSrc;     /*"CkSrc " is defined locally by myself*/
 bTQnt = brpReg - 1;/*"bTQnt " is defined locally by myself*/
 tSeg1 = tSegReg1;  /*"tSeg1 " is defined locally by myself*/
 tSeg2 = tSegReg2;  /*"tSeg2 " is defined locally by myself*/
 prty = 0;                    /*"prty " is defined locally by myself*/
 HWEnDi();
 ...
  • step-4:Here we've got source code for "HWEnDi()" function.
    Peripheral is not enabled by the application so, in this moment, the situation it doesn't change.
    and both controller still disabled...
static void HWEnDi(void)
{
 /*if peripheral have to be enabled*/
 if(EnUser)
 {
  ...
 }
 else /*if peripheral have to be Disabled*/
 {
   /*If there's any transmit process in progress, the app. have to wait his completion*/
   while(CAN0TFLG_TXE == 0x00){};
   /*Init Mode Req*/
   if(!CAN4CTL1_INITAK)
   {
     CAN4CTL0_INITRQ = 1;
     /*Waiting for Init Mode Entry Request ACK*/
     while(CAN4CTL1_INITAK != 1){};
   }
   /*CAN4CTL1*/
   CAN4CTL1_CANE     = 0;/* MSCAN12 off*/
 }
 return;
}
  • step-5 Next Step in Main function is to Enable the peripheral, as it's be shown below, there are:
    "CAN_Controller_0_Enable()" calling (Main function).
    "CAN_Controller_0_Enable()" definition...
 
void main(void)
{
 ...
 /*** End of Processor Expert internal initialization.                    ***/
 length = sizeof(msgData);
 /*Write your code here*/
 (void)CAN_Controller_0_Enable();
 (void)CAN_Controller_0_EnableEvent();
 (void)CAN_Controller_4_Enable();
 (void)CAN_Controller_4_EnableEvent();
 ...
}
...
byte CAN_Controller_0_Enable(void)
{
 /*if MSCAN12 Controller 0 isn't already on*/
 if(!EnUser)
 {
   EnUser = TRUE;
   HWEnDi();
 }
 return ERR_OK;
}
...
byte CAN_Controller_0_EnableEvent(void)
{
 EnEvent = TRUE;/*Not Used anywere (at this moment)*/
 return ERR_OK;
}
 
  • step-6: Configuration for CAN Controller 0.
static void HWEnDi(void)
{
 /*if peripheral have to be enabled*/
 if(EnUser)
 {
   /*If there's any transmit process in progress...*/
   while(CAN0TFLG_TXE == 0x00){};
   {
     /*Init Mode Entry Req*/
     CAN0CTL0_INITRQ = 1;
     /*Waiting for Init Mode Entry Request ACK*/
     while(CAN0CTL1_INITAK != 1){};
     {
        /*CANE=1,CLKsrc=X,LOOPB=0,LISTEN=0,Bit3=X,WUPM=0,SLPAK=0,INITAK=1*/
       CAN0CTL1 = 0x80;/*MSCAN12 on*/
       CAN0CTL1_CLKsrc=CkSrc;
       /*CAN0BTR0, CAN0BTR1*/
      CAN0BTR0_BRP = bTQnt;
      CAN0BTR0_SJW = 3;
      CAN0BTR1_TSEG_10 = tSeg1;
      CAN0BTR1_TSEG_20 = tSeg2;
      /*IDAM = 0 (default), Each frame may be received*/
      CAN0IDMR0 = 0xff;
      CAN0IDMR1 = 0xff;
      CAN0IDMR2 = 0xff;
      CAN0IDMR3 = 0xff;
      CAN0IDMR4 = 0xff;
      CAN0IDMR5 = 0xff;
      CAN0IDMR6 = 0xff;
      CAN0IDMR7 = 0xff;
          CAN0IDAC_IDAM = 0;
     }
     /*Init Mode Exit Req*/
     CAN4CTL0_INITRQ = 0;
     /*Waiting for Init Mode Exit Request ACK*/
     while(CAN4CTL1_INITAK != 0){};
   }
   /*Reset CAN0RFLG*/
   CAN0RFLG = 0xc3;
   /*RXFIE = 1 Int Rx Frame Enabled,
     OVRIE = 0 Int Ovr Disabled,
     TSTATE = X,
     RSTATE = X,
     CSCIE = 0 Int Status Change Disabled,
     WUPIE = 0 No Wake-Up Interrupt (WUPE = 0 No Wake-Up)*/
   CAN4RIER = 0x01;
 }
 else /*if peripheral have to be Disabled*/
 {
  ...
 }
 return;
}
  • step-7: Sending Routine (MSCAN12 Controller used for this task is Controller 0).
    Routine calling is performed in main function.
byte CAN_Controller_0_SendFrame(
                 byte BufferNum,
                 dword MessageID,
                 byte FrameType,
                 byte Length,
                 byte *Data)
{
 static unsigned short i;
 static byte bufIndex;
 
 i = 0;
 /*Se la periferica è abilitata*/
 if(EnUser)
 {
   /*If Length is OK*/
   if(Length>8)
     return ERR_VALUE;
   /*Waiting for available Tx buffer*/
   while(!CAN0TFLG){};
   /*CCR Saving*/
   EnterCritical();
   /*Tx Buffer Selection*/
   CAN0TBSEL = BufferNum;
   bufIndex = CAN0TBSEL;
   /*ID Setting (STANDARD_FORMAT)*/
   CAN0TXIDR0 = (byte)(MessageID>>3);
   CAN0TXIDR1 = (byte)(MessageID<<5);
   CAN0TXIDR1_IDE = 0;
   if(FrameType == DATA_FRAME)
   {
     /*Frame type setting DATA FRAME*/
     CAN0TXIDR1_SRR = 0;
     /*Data Length Setting*/
     CAN0TXDLR = Length;
     /*Data Field Setting*/
     for(i=0;i<Length;i++){
       (*(&CAN0TXDSR0+i))=(*(Data + i));
     }     
   }
   else
     /*Frame Type Setting REMOTE FRAME*/
     CAN0TXIDR1_SRR = 1;
   /*Pryority Setting*/
   if((prty+1)%0xff == 0){
     while(CAN0TFLG_TXE == 0x07){};
     prty = 0x00;
     CAN0TXTBPR = prty;
   }
   else
     CAN0TXTBPR = ++prty;
   /*CCR Recovery*/
   ExitCritical();
   /*Start Trasmission*/
   CAN0TFLG &= ~bufIndex;
   CAN0TIER = bufIndex;
   return ERR_OK;   
 }
 else
 {
   /*Error: MSCA12 Not Enabled*/
   return ERR_DISABLED;
 }   
}
 
  • step-8:ISR function (performed for MSCAN12 Controller 4).
 
__interrupt void CAN_Controller_4_FullRxBuffer(void)
{
 unsigned int bufferIndex;
 /*CCR Saving*/
 EnterCritical();
 /*TErr Saving*/
 /*TODO*/
 /*Error Flag Resetting*/
 /*TODO*/
 /*TErr Checking*/
   /*if Overrun => Ret (Err = OVERRUN_ERR)*/
   /*if CRC     => Ret (Err = ERR_CRC)*/
   /*....*/
   /*TODO*/
   /*....*/
 /*End Checking*/ 
 /*ID,SRR,IDE,RTR Saving*/
 rxIDBuffer[lastRxBuffer] = 0;
 rxIDBuffer[lastRxBuffer] |= CAN4RXIDR0;
 rxIDBuffer[lastRxBuffer] <<= 8;
 rxIDBuffer[lastRxBuffer] |= CAN4RXIDR1;
 rxIDBuffer[lastRxBuffer] <<= 8;
 rxIDBuffer[lastRxBuffer] |= CAN4RXIDR2;
 rxIDBuffer[lastRxBuffer] <<= 8;
 rxIDBuffer[lastRxBuffer] |= CAN4RXIDR3;
 /*Length Saving*/
 reDataLength[lastRxBuffer] =
   (((!CAN4RXIDR1_IDE)&&(!CAN4RXIDR1_SRR))||
    ((CAN4RXIDR1_IDE)&&(!CAN4RXIDR3_RTR)))—
    (CAN4RXDLR):
    (0);
 /*DSRx Saving*/
 for(bufferIndex = 0; bufferIndex < reDataLength[lastRxBuffer]; bufferIndex++)
   rxDataBuffer[lastRxBuffer][bufferIndex] = *(&CAN4RXDSR0 + bufferIndex);
 /*Incremento del puntatore alla coda di Rx per il basso livello*/  
 lastRxBuffer = (lastRxBuffer++)%8;
 /*CCR Recovery*/
 ExitCritical();
 /*Reset del flag RXFRM*/
 CAN0CTL0_RXFRM = 1; 
 /*Local Rx Buffer Depletion*/
 CAN_Controller_4_OnFullRxBuffer();
 /*RXF Resetting*/
 CAN0RFLG_RXF = 1;
 return;
}
 
Application seems to work correctly since /*ID,SRR,IDE,RTR Saving*/ (shown above).
I don't know whi but all data i try to read are not correct. Wath I have to do in order to fix my problem.
Thanks in advance.
Andrea Olivieri (In Italy it's a male name).
Bye!
 
Labels (1)
0 Kudos
8 Replies

727 Views
Lundin
Senior Contributor IV
Umm... as I said, I didn't look at the code, I simply assumed that you used the same code to init CAN0 and CAN4. After taking a look at the code, it doesn't seem to be the case. Perhaps there is CAN-related code you didn't post?

If not... try to enable the CAN4 module? Might be good...
And then set up all other CAN registers needed...
And perhaps throw out that bean-bag...

Regarding the PTM: if several peripherals are enabled at once and mapped to the same pin, they take precedence as follows: ByteFlight (highest prio) then CAN, then BDLC then GPIO (lowest prio).
0 Kudos

727 Views
pammu
Contributor I
Andrea,
 
Regarding port mapping, you need to do seprate initialization for the ports using the MODRR only if the default communication interface for the port is not what you want. For eg: by default the PORT S pins maybe configured for SCI. In that you dont have to initialize anything. But if the default is different and if you want to use the same port for SCI then, you have to re-initialize it using the MODRR register. You will find more details in the Port Integration Module Datasheet.
0 Kudos

727 Views
andrea_olivieri
Contributor I
Hi guys!
Well...In order to use:
  • PM0 as RxCAN0
  • PM1 as TxCAN0
  • PJ6 as RxCAN4
  • PJ7 as TxCAN4

I've configured MODRR = 0;

It seems as correct but it doesn't work anymore. What can I do?...

 

0 Kudos

727 Views
andrea_olivieri
Contributor I
Referring to DOC #S12DT256PIMV3/D ("Mc9S12Dt256 Port Integration module Block Guide V03.04").
Does Pim Used in Mc9S12DT256 is ifferent by the other one in Mc9S12Dj256.
I'm asking this beucase I need to use BDLC Module (in order to control also J1850 VPW Bus), as well as MsCAN12 Module (In order to control CAN Bus).  Unfortunately in Port M Register Section (3.1.3) it does not appear any indication abouth it. I've  tryed to find related documentation, but i just attain #S12DT256PIMV3/D paper.
0 Kudos

727 Views
J2MEJediMaster
Specialist I
You may want to downlad the MC9S12XDP512V2.pdf data sheet which covers most of the HCS12 derivatives. It covers port M for a S12XDQ256, which might be similar to your part. Caution: it's a big download at 4+ MB.
 
---Tom
0 Kudos

727 Views
Lundin
Senior Contributor IV
I didn't check your code, but since you have CAN0 but not CAN4 running, I suspect it might be the MODRR register causing trouble. This register is used to map peripherals like CAN and SPI between various ports. Unless you are writing to this register, look it up in the "Port Integration Module" manual. Since you are using one of them 'DJ' processors, it is possible that the Byteflight is mapped to the same pins as the CAN4.
0 Kudos

727 Views
andrea_olivieri
Contributor I
Are U meaning I Have to configure it?
Eg: If I'm using SCI as Asincronus Serial I have to do the following by using Port S Rather than M (as I have to do for SCI) :...
 
void PE_low_level_init(void)
{
 /* Common initialization of the CPU registers */
 ...
 /* ### MC9S12DJ256_80 "Cpu" init code ... */
 /* ### Asynchro serial "AS1" init code ... */
 DDRS &= ~1;
 PTS |= 2;
 DDRS |= 2;
 AS1_Init();
 INTCR_IRQEN = 0;                     /* Disable the IRQ interrupt. IRQ interrupt is enabled after CPU reset by default. */
 __EI();                              /* Enable interrupts */
}
0 Kudos

727 Views
Lundin
Senior Contributor IV
Not sure what that code has to do with anything...

Read about MODRR in the manual. If it is applicable to your application or whether the magical beans know about that register or not, I don't know.

(But then I wouldn't trust a bag of beans to write the code for me. :smileyhappy:)
0 Kudos