/*******************************************************************************
* Freescale Semiconductor Inc.
* (c) Copyright 2004-2005 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
********************************************************************************
Services performed by FREESCALE in this matter are performed AS IS and without 
any warranty. CUSTOMER retains the final decision relative to the total design 
and functionality of the end product. FREESCALE neither guarantees nor will be 
held liable by CUSTOMER for the success of this project.
FREESCALE DISCLAIMS ALL WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY INCLUDING, 
BUT NOT LIMITED TO, IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR 
A PARTICULAR PURPOSE ON ANY HARDWARE, SOFTWARE OR ADVISE SUPPLIED TO THE PROJECT
BY FREESCALE, AND OR NAY PRODUCT RESULTING FROM FREESCALE SERVICES. IN NO EVENT
SHALL FREESCALE BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF 
THIS AGREEMENT.

CUSTOMER agrees to hold FREESCALE harmless against any and all claims demands or 
actions by anyone on account of any damage, or injury, whether commercial, 
contractual, or tortuous, rising directly or indirectly as a result of an advise
or assistance supplied CUSTOMER in connection with product, services or goods 
supplied under this Agreement.
********************************************************************************
* File      main.c
* Owner     Ladislav
* Version   1.0
* Date      Oct-13-2014
* Classification   General Business Information
* Brief     Test 8x8 CAN filter in loopback mode
********************************************************************************
                 TECHNICAL SUPPORT - SOFTWARE EXAMPLE
********************************************************************************
* Detailed Description:
*
* The CAN sends extended IDs to wake another board up from the CAN sleep and 
* MCU STOP modes
* CAN setup: 125kbps, 1sample/bit, 8MHz ext osc as CAN clock source, 
*            loop  disabled, CAN interface (TJA1040)
* Diodes at PT4~7 toggles before the frame is Tx to wake another device ups
*     
* - tested on: TWR-S12G128
* - OSCCLK = 8MHz oscillator, BUSCLK = 24MHz set by means of PLL in PEE mode
* - Reference to documentation: MC9S12GRMV1 Rev.1.01
********************************************************************************
Revision History:
Version  Date         Author  Description of Changes
1.0      Oct-13-2014  Ladislav  Initial version
*******************************************************************************/
                         
#include <hidef.h>       // common defines and macros       
#include "derivative.h"  // derivative-specific definitions 
#include "comdef.h"      // my common definitions           
/*******************************************************************************
* Local function prototypes
*******************************************************************************/
static void delay(ULONG ii);
static void setPEEmodeBUSCLK(UBYTE _synr, UBYTE _refdv, UBYTE _postdiv);
/*******************************************************************************
* Local module variables
*******************************************************************************/
static UBYTE TXmsgIDE,   TXmsglen,   TXmsgRTR,   TXmsgprty;
static ULONG TXmsgid;
static UBYTE TXmsgdata0, TXmsgdata1, TXmsgdata2, TXmsgdata3;
static UBYTE TXmsgdata4, TXmsgdata5, TXmsgdata6, TXmsgdata7;
/*******************************************************************************
Function Name : PLL_LockIsr
Engineer      : Ladislav
Date          : NOV/28/2011
Parameters    : NONE
Modifies      : NONE
Returns       : NONE
Notes         : The interrupt function used (if necessary) if the PLL lock 
                status has changed
Issues        : NONE
*******************************************************************************/
#pragma CODE_SEG NON_BANKED
interrupt 28 void PLL_LockIsr(void)
{
  if(CPMUFLG_LOCK == 0)  {    /*do something here*/  }
  else                   {    /*do something here*/  }
}
#pragma CODE_SEG DEFAULT
/*******************************************************************************
Function Name : setPEEmodeBUSCLK
Engineer      : Ladislav
Date          : NOV/28/2011
Parameters    : NONE
Modifies      : NONE
Returns       : NONE
Notes         : Changes BUSCLK
Issues        : NONE
*******************************************************************************/
void setPEEmodeBUSCLK(UBYTE _synr, UBYTE _refdv, UBYTE _postdiv)
{
 CPMUSYNR    = _synr;
 CPMUREFDIV  = _refdv;
 CPMUPOSTDIV = _postdiv;   
  
 CPMUOSC_OSCE = 1; //enable external oscillator OSCE
    
 while(!CPMUFLG_UPOSC)
  {
    CPMUARMCOP=0x55;CPMUARMCOP=0xAA; // kick the dog if enabled
  };    
 while(!CPMUFLG_LOCK)
  {
    CPMUARMCOP=0x55;CPMUARMCOP=0xAA; // kick the dog if enabled
  };    
 
  //--- select clocks ------------
 
 CPMUCLKS = 0B10000000;           // bus=fPLL/2; COP is clocked from OSCCLK
 if(CPMUCLKS != 0B10000011)       // After writing CPMUCLKS register, it is 
  {                               // recommended to read back CPMUCLKS register 
                                  // to be sure that write of PLLSEL,RTIOSCSEL,
     asm nop;                     // COPOSCSEL0 and COPOSCSEL1 was successful.
  }
 asm nop;
 //-------------------------------
}
/*******************************************************************************
Function Name : delay
Engineer      : Ladislav
Date          : Oct-13-2014
Parameters    : ULONG ii
Modifies      : NONE
Returns       : NONE
Notes         : Short delay - hard loop.
Issues        : NONE
*******************************************************************************/
static void delay(ULONG ii)
{
  unsigned long i;    
  
  for( i = 0; i < ii; i++ )   asm nop;        
}
/*******************************************************************************
Function Name : main
Engineer      : Ladislav
Date          : Oct-13-2014
Parameters    : NONE
Modifies      : NONE
Returns       : NONE
Notes         : Main function.
Issues        : NONE
*******************************************************************************/
void main(void) 
{
 UWORD i;
 UBYTE data=1;
 ULONG idX = 0x11111111;
 UBYTE tbuf_n_empty_flag = 0;
 
 //--- set BUSCLK ----------------
 setPEEmodeBUSCLK(0x02, 0x80, 0x00);// 24MHz BUSCLK from 8 MHZ oscclk, PEE mode
 
 ECLKCTL_NECLK = 0; // BUSCLK visible at PB0

 //--- enable STOP mode ----------
 asm ANDCC #0x7F

 //--- set PORTs -----------------
 DDRT  = 0xF0;                    // PORT T4~7 an output port - diodes
 PTT  |= 0xF0;                    // Toggle diodes at PTT4~7
 PTT  &= 0x0F;

 //--- set CAN -------------------
 //.................................
 // 125kbps, 1sample/bit, 8MHz ext osc as CAN clock source, loop  disabled
 // CAN interface (TJA1040)
 //.................................

 CANCTL0 = CANCTL0_INITRQ_MASK;
 while(!CANCTL1_INITAK);
 
 CANCTL1  = CANCTL1_CANE_MASK;    // Enables MSCAN, Oscillator Clock, 
                                  // Loop Enabled/Disabled and Normal Operation
                                  // WUPM = 0; 0 MSCAN wakes up on any dominant 
                                  // level on the CAN bus
 CANBTR0  = 0xC3;                 //
 CANBTR1  = 0x67;                 //

 CANCTL0  = 0B00000000;  		  		// restart MSCAN
                                  // RXFRM RXACT CSWAI SYNCH
                                  // TIME WUPE SLPRQ INITRQ
 
 while(CANCTL1 & CANCTL1_INITAK_MASK);   // wait for Initialization Mode exit
 while(!(CANCTL0 & CANCTL0_SYNCH_MASK)); // wait for synch. with the CAN bus
 //-------------------------------
 EnableInterrupts;
 //-------------------------------
 for(;;)
  {
   //--- toggle diodes -----------
   for(i=0; i<5; i++)
    {
     PTT  |= 0xF0;                // Toggle diodes at PTT4~7
     delay(0x1FFFFUL);
     PTT  &= 0x0F;
     delay(0x1FFFFUL);
    }
	 //--- extended id, CAN0 Tx ----
  
   while(!(CANTFLG & (0x01<<tbuf_n_empty_flag))) // find empty transmit buffer
    {
      tbuf_n_empty_flag ++;
      if(tbuf_n_empty_flag == 3) tbuf_n_empty_flag=0;
    }

   CANTBSEL  = 0x01 << tbuf_n_empty_flag;   // select found empty transmit buffer

   TXmsgid  = idX;
   TXmsgRTR = 0; 
   TXmsgIDE = 1;
   TXmsglen = 8;       
   TXmsgprty= 3;
   TXmsgdata0= data++;
   TXmsgdata1= data++;
   TXmsgdata2= data++;
   TXmsgdata3= data++;
   TXmsgdata4= data++;
   TXmsgdata5= data++;
   TXmsgdata6= data++;
   TXmsgdata7= data++;

   // extended identifier adjustment
   CANTXIDR0 = (UBYTE)(TXmsgid>>21);      // insert ID MSB
   CANTXIDR1 = (((UBYTE)(TXmsgid>>13)) & 0xE0) + (((UBYTE)(TXmsgid>>15)) & 0x07);
   CANTXIDR2 = (UBYTE)(TXmsgid>>7);
   CANTXIDR3 = ((UBYTE)(TXmsgid<<1)) & 0xFE;
   
   CANTXIDR1 |= 0B00011000;               // SRR=1, IDE=1 for extended ID

   if(TXmsgRTR) CANTXIDR3 |= 0x01;        // set/clear = remote/data frame RTR
  
   CANTXDSR0 = TXmsgdata0;
   CANTXDSR1 = TXmsgdata1;
   CANTXDSR2 = TXmsgdata2;
   CANTXDSR3 = TXmsgdata3;
   CANTXDSR4 = TXmsgdata4;
   CANTXDSR5 = TXmsgdata5;
   CANTXDSR6 = TXmsgdata6;
   CANTXDSR7 = TXmsgdata7;

   CANTXDLR  = TXmsglen;									// set message data length
   CANTXTBPR = TXmsgprty;								  // set message internal priority 
   CANTFLG   = (0x01<<tbuf_n_empty_flag); // clear flag to send message
	 //-----------------------------
   idX=(idX+1) & 0x1FFFFFFFL;
	 //-----------------------------
   delay(0x5FFFFFUL);
  }
 //-------------------------------
}
/*******************************************************************************
The Answer to the Ultimate Question of Life, the Universe, and Everything is: 42
(Douglas Adams - The Hitchhiker's Guide to the Galaxy)
*******************************************************************************/


















