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-3ource 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!