/*******************************************************************************
* Freescale Semiconductor Inc.
* (c) Copyright 2012 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 ORE ADVISE SUPPLIED TO A 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 R62780
* Version 1.0 // version 0.x is reserved for development phase and
// should not be placed in the repository
* Date Dec-11-2012
* Classification General Business Information/Internal Use Only/Confidential Proprietary
* Brief Brief description of the file
********************************************************************************
* Detailed Description:
* Software periodically sends/receives (depends on CAN_node value) CAN frame. 
* Software suppose using of two S12G boards
*
* Results are sent over SCI module
*
* CANCLK = OSCCLK = 8MHz, bitrate = 500kbps
* The only one data byte is Rx, Tx
* 
* Don't forget install jumpers at JP4 and JP6 connectors on TWR boards
*  
*
* TEST BUSS OFF by connecting CANH and CANL on the board (JP6)
* - BUSS OFF is reported to the SCI
* - BOHOLD bit is used to check BUSS OFF status (enabled by bit BORM) 
*
*
* The code is common for both transmitter and receiver. Just change definition
*  bellow to select which part of the code will be loaded to the board
*
* Tested on: TWR-S12G128, 
* - OSCCLK = 8MHz oscillator, BUSCLK = 24MHz set by means of PLL in PEE mode
* - One board programmed as transmitter and the other one as receiver. 
* - Serial cable is connected to the transmitter board. Vizualized are sent and
*   received. (echoed data from receiver)
*   
* - Reference to documentation: MC9S12GRMV1 Rev.1.01
********************************************************************************
Revision History:
Version Date Author Description of Changes
1.0 Mar/12/2014 R62780 Initial Version
*******************************************************************************/
#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */
#include "can_S12G.h"
#include "stdio.h"
#include "map.h"

// define else TRANSMITTER or RECEIVER
//#define RECEIVER
#define TRANSMITTER
#define ECHO         // if defined receiver echoes data

UBYTE CAN_id = 0x00;         // the only one id is used for simplicity
UBYTE CAN_data_lenght = 1;   // the only one number is TX/Rx for simplicity

UBYTE data = 0x00;
SBYTE txt[100];

//==============================================================================

#if defined(TRANSMITTER) && defined(RECEIVER)
#error "IT IS NOT ALLOWED TO DEFINE BOTH TRANSMITTER AND RECEIVER AT SAME TIME"
#endif

#if !defined(TRANSMITTER) && !defined(RECEIVER)
#error "THERE MUST BE ELSE TRANSMITTER OR RECEIVER DEFINED"
#endif

//==============================================================================
// SCI0 initialization
//==============================================================================
void  SCI0_Init(void)
{
 //----- BR = BUSCLK / (16*Baud rate) = 24,000,000 / (16*9600) = 0x9C -----
                                            //------------------------------------------------------
   SCI0BD  = 0x9C;                          // prescaller value (depends on module clock frequency) 
                                            // prescaller = 0x9C   9600Bd  (24MHz bus clock is set)
                                            //------------------------------------------------------
   SCI0CR1 = 0x44;                          // Loops sciswai rsrc   m    wake  ilt   pe    pt       
                                            // 0-LOOPS=RSRC=0 => 1 Single-wire mode with Rx input connected to TXD
                                            // 0-SCI dis. in wait mode                              
                                            // 0-if RSRC=1-RxTx intern. connected if loops=1                  
                                            // 0-start+8 data+1 stop bit                          
                                            // 0-IDLE mark wake up                                  
                                            // 1-idle char. bit count begins after stop bit         
                                            // 0-parity fction disabled                             
                                            // 0-odd parity                                       
                                            //------------------------------------------------------
   SCI0CR2 = 0x08;                          // tie   tcie    rie  ilie   te    re   rwu   sbk       
                                            // 0-Tx empty intr disabled                             
                                            // 0-Tx complete intr disabled                          
                                            // 0-Rx full + OverRun interrupts
                                            // 0-idle line intr disabled                            
                                            // 1-transmitter enabled
                                            // 0-receiver disabled
                                            // 0-receiver normal operation                                   
                                            // 0-no break characters                                
                                            //------------------------------------------------------
}
//==============================================================================

//==============================================================================
// SCI send text
//==============================================================================
void send_text(SBYTE *str)
{
  UBYTE i;
  i=0;
  while(str[i]!='\0')
    {
     while(!SCI0SR1_TC);                    // write data to SCI (clear TC) 
     SCI0DRL = str[i];
     i++;
    }
}
//==============================================================================

//==============================================================================
// delay loop
//==============================================================================
void delay(void)
{
 ULONG  i;
 for(i=0;i<0x7FFFF;i++) asm nop;
}
//==============================================================================

//==============================================================================
// Get CAN message
//==============================================================================
void RxMsgOnCAN(void)
{
   while(!MSCANCheckRcvdMsg());           // wait till mesage is not received
   if(MSCANGetMsg(&canRxMsg))             // get message
    {if(canRxMsg.id == CAN_id && canRxMsg.RTR == 0) // check message id
      {
        (void)sprintf(txt,"received: 0x%02X \n\r",canRxMsg.data[0]);
         send_text(txt);
      }
    }
}

//==============================================================================
//void SetPEEmodeBUSCLK(UBYTE _synr, UBYTE _refdv, UBYTE _postdiv)
//==============================================================================
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 strongly
  {                         // recommended to read back CPMUCLKS register 
                            // to make sure that write of PLLSEL, RTIOSCSEL,
     asm nop;               // COPOSCSEL0 and COPOSCSEL1 was successful.
  }
 asm nop;
 //--------------------------------------
}

//==============================================================================
// main loop
//==============================================================================
void main(void) 
{  

 SetPEEmodeBUSCLK(0x02, 0x80, 0x00); // 24MHz BUSCLK from 8 MHZ oscclk, PEE mode
 
 PER01AD = 0xFFFF;                      // to enable UART transceiver on the board
  
 SCI0_Init();
 send_text("\r\n\r\nHELLO, I AM ALIVE....\r\n\r\n");
 
 DDRT  = 0xF0;                          // PORT T is an output port for LEDs
  
 init_CAN(0xC0, 0xD8, 0);               // 500fbps, loop disabled  (TJA1041T)


 CANRIER = 0B01010100;     // 01 no wake-up, status change isr enable,
                           // 01 bus off trigger
                           // 01 bus off trigger
                           // 00 no overrun isr, no receiver full isr
 CANRFLG = 0xC3;           // clear all flags
 EnableInterrupts;
                                         
  for(;;) 
   {
  

#ifdef RECEIVER
      RxMsgOnCAN();                        // CAN receive function
 
#ifdef ECHO
      // echo data if required

      createMessage(&canTxMsg,canRxMsg.id,0,CAN_data_lenght,3,canRxMsg.data[0],0,0,0,0,0,0,0);  //buf,id,RTR,len,prty,d0,d1,d2,d3,d4,d5,d6,d7
      (void) MSCANSendMsg(&canTxMsg);            //buf :send message
      (void)sprintf(txt,"sent: 0x%02X \r\n",data);
      send_text(txt);

#endif //ECHO
#endif //RECEIVER

#ifdef TRANSMITTER
      createMessage(&canTxMsg,CAN_id,0,CAN_data_lenght,3,data,0,0,0,0,0,0,0);  //buf,id,RTR,len,prty,d0,d1,d2,d3,d4,d5,d6,d7
      (void) MSCANSendMsg(&canTxMsg);            // buf :send message
   
      (void)sprintf(txt,"sent: 0x%02X \r\n",data);
      send_text(txt);

#ifdef ECHO      
      // get echoed data
      RxMsgOnCAN();                        // CAN receive function !!!!!!!!!!!!!!!!
#endif
   
      data++;
      delay(); 
#endif //TRANSMITTER


   // _FEED_COP();                         //kick the dog
  }
}
//*******************************************************************************/
#pragma CODE_SEG NON_BANKED
//.........................
interrupt 37 void CAN_ErrorsIsr(void)
{
 UINT i;

 (void)sprintf(txt,"CANRFLG = 0x%02X\n\r",CANRFLG);
 send_text(txt);


 CANRFLG = 0xC3; //clear all flags
 asm nop;       
 //----------------------------
 if(CANMISC_BOHOLD)     // is CAN in the BUSSOFF state?
  {                     // note that BORM is set in CANCTL1

    (void)sprintf(txt,"CAN BUSS OFF \n\r");
    send_text(txt);
    
    CANMISC_BOHOLD = 1; // start synchronization
    i=0xFFFF;
    do
      {
       i--; 
      }
    while(!CANCTL0_SYNCH && i>0); // waits for MSCAN synchro. with the CAN bus
    
    if(!i)
      {
        //timeout, bus not synchronized, if necessary do something
        asm nop;
      }
    else
      {
        //bus synchronized
        asm nop;
      }
  }
 else
  {
    // another event depending on TSTAT and RSTAT setup
    // do something
    asm nop;
  } 
}
//.........................
#pragma CODE_SEG DEFAULT
//*******************************************************************************
