//#pragma LINK_INFO DERIVATIVE "mc9s12p128"

/******************************************************************************
													            Copyright (c) Freescale 2009
File Name    : $RCSfile: main.c,v $

Current Revision :	$Revision: 1.0 $

PURPOSE: main program entry.                       
                                                                          
                                                                       
DESCRIPTION:  function main() providing initial program entry.
              function PutChar() - Transmits a character
              function GetChar() - Receives a character
              function DisplayString() - Transmits a character string
              function EchoGetChar() - Receives a character and echos it back
              function DisplayInt() - Transmits an integer
              function DisplayByte() - Transmits a byte
              function char Number_2_ASCII() - converts a number into ASCII code
              function char ASCII_2_Number() - converst ASCII code into a number
                                                         
                                                                          
UPDATE HISTORY                                                            
REV  AUTHOR    DATE        DESCRIPTION OF CHANGE                          
---  ------    --------    ---------------------                          
1.0  r28318    09/06/09    - initial coding

     *******************************************************************
     * File created by: Freescale East Kilbride MSG Applications Group *
     *******************************************************************

                                                                          
******************************************************************************/
/*===========================================================================*/
/* Freescale reserves the right to make changes without further notice to any*/
/* product herein to improve reliability, function, or design. Freescale does*/
/* not assume any  liability arising  out  of the  application or use of any */
/* product,  circuit, or software described herein;  neither  does it convey */
/* any license under its patent rights  nor the  rights of others.  Freescale*/
/* products are not designed, intended,  or authorized for use as components */
/* in  systems  intended  for  surgical  implant  into  the  body, or  other */
/* applications intended to support life, or  for any  other application  in */
/* which the failure of the Freescale product  could create a situation where*/
/* personal injury or death may occur. Should Buyer purchase or use Freescale*/
/* products for any such intended  or unauthorized  application, Buyer shall */
/* indemnify and  hold  Freescale  and its officers, employees, subsidiaries,*/
/* affiliates,  and distributors harmless against all claims costs, damages, */
/* and expenses, and reasonable  attorney  fees arising  out of, directly or */
/* indirectly,  any claim of personal injury  or death  associated with such */
/* unintended or unauthorized use, even if such claim alleges that  Freescale*/
/* was negligent regarding the  design  or manufacture of the part. Freescale*/
/* and the Freescale logo* are registered trademarks of Freescale Ltd.       */
/*****************************************************************************/

/************************* Include Files *************************************/
/*general includes */
#include <hidef.h>  /* also includes boolean definitions in stdtypes.h     */
#include <MC9S12P128.h>     /* derivative information */
#include "target.h" 
#include "S12P_peripherals.h" /* includes peripherals definitions and FSL data types */


/************************* typedefs ******************************************/

/************************* #defines ******************************************/

/************************* Constants *****************************************/
#pragma CONST_SEG DEFAULT

/************************* Global Variables **********************************/
#pragma DATA_SEG DEFAULT

/************************* function prototypes *******************************/
#pragma CODE_SEG DEFAULT
/************************* Functions *****************************************/
#pragma CODE_SEG DEFAULT

void PutChar (char);
char GetChar(void);
void DisplayString (signed char *textPointer);
char EchoGetChar(void);
void DisplayInt(unsigned int number, unsigned char field );
void DisplayByte (unsigned char displayByte);
unsigned char Number_2_ASCII(unsigned char Nibble);
unsigned char ASCII_2_Number(unsigned char ascii_char);

/************************* Macros *****************************************/
#define FF DisplayString("\f")
#define LF DisplayString("\r\n")

/******************************************************************************
Function Name  : main
Engineer       : r28318	
Date           : 09/06/09
Parameters     : NONE
Returns        : NONE
Notes          : main routine called by Startup.c. 
******************************************************************************/


void main(void) {
   char RegisterCase;
   unsigned int BaudRatePrescaler, x,y;

   unsigned long Baud_Rate = 9600;
//   unsigned long Baud_Rate = 19200;
//   unsigned long Baud_Rate = 38400;
//   unsigned long Baud_Rate = 57600;
  
     
      /* initialise the system clock - 32MHz Bus CLK, 4MHz Crystal */
	 CPMUCLKS_PLLSEL = 1; /*select the PLL as the clock source */
	 CPMUOSC = 0xC8;
   while(!CPMUFLG_UPOSC);	/* wait for OSC to stabilise */
   CPMUREFDIV = ((REFCLK_RANGE<<6) | (PLL_DIVIDER-1));       /* Reference Clock / 1 = 4MHz */
   CPMUSYNR = ((VCO_RANGE<<6) | (PLL_MULTIPLIER-1));         /* configure the PLL  x 16 = 64MHz VCO */
   CPMUPOSTDIV = (PLL_POSTDIVIDER-1);      /* Post divider / 1 = 32MHz Bus CLK */
   while(!CPMUFLG_LOCK)	/* wait for PLL to lock */
   {
   }
	 

   /* Calculate the prescaler required to achieve the baud rate */
   /* Prescaler = Bus Clock / 16 x Baud Rate */

   BaudRatePrescaler = (unsigned int)(32000000 / (16 * Baud_Rate));

   /* Configure the SCI to Tx and Rx using the defined Baud Rate */
   /* Data Bits = 8 */
   /* Parity = None */
   /* Start Bits = 1 */
   /* Stop Bits = 1 */

   /* Set the Baud Rate */
   SCIBDH = (unsigned char)((BaudRatePrescaler>>8));
   SCIBDL = (unsigned char)(BaudRatePrescaler);
   
 	 SCICR1 = 0x00;  /* 8 Data Bits, 1 Start Bit, 1 Stop Bit, No Parity */

 	 SCICR2 = 0x0C;  /* Enable Tx and Rx */

   /* SCIASR1, SCIACR1, SCIACR2, SCISR1, SCISR2, SCIDRH & SCIDRL left at default values */

   FF;
   while(1)
   {
   DisplayString("DEMOS12PFAME Serial Communications Interface Demo");
   LF;
   LF;
   DisplayString("Register Configuration for ");
   DisplayInt((unsigned int)Baud_Rate,0);
   DisplayString(" Baud Rate");
   LF;
   LF;
   DisplayString("Select Register to display");
   LF;
   LF;
   DisplayString("  0 - SCIBDH    1 - SCIBDL");
   LF;
   DisplayString("  2 - SCICR1    3 - SCIASR1");
   LF;
   DisplayString("  4 - SCIACR1   5 - SCIACR2");
   LF;
   DisplayString("  6 - SCICR2    7 - SCISR1");
   LF;
   DisplayString("  8 - SCISR2    9 - SCIDRH");
   LF;
   DisplayString("  A - SCIDRL");
   LF;
   LF;
   DisplayString("Enter: ");
   RegisterCase = EchoGetChar();
   LF;
   LF;
   
   switch (RegisterCase) 
    {
      case '0':
         DisplayString("SCIBDH = ");
         DisplayByte(SCIBDH);
         LF;
      break;

      case '1':
         DisplayString("SCIBDL = ");
         DisplayByte(SCIBDL);
         LF;
      break;
      
      case '2':
         DisplayString("SCICR1 = ");
         DisplayByte(SCICR1);
         LF;
      break;
      case '3':
         SCISR2_AMAP = 1;
         DisplayString("SCIASR1 = ");
         DisplayByte(SCIASR1);
         LF;
         SCISR2_AMAP = 0;
      break;
      case '4':
         SCISR2_AMAP = 1;
         DisplayString("SCIACR1 = ");
         DisplayByte(SCIACR1);
         LF;
         SCISR2_AMAP = 0;
      break;
      case '5':
         SCISR2_AMAP = 1;
         DisplayString("SCIACR2 = ");
         DisplayByte(SCIACR2);
         LF;
         SCISR2_AMAP = 0;
      break;
      case '6':
         DisplayString("SCICR2 = ");
         DisplayByte(SCICR2);
         LF;
      break;
      case '7':
         DisplayString("SCISR1 = ");
         DisplayByte(SCISR1);
         LF;
      break;
      case '8':
         DisplayString("SCISR2 = ");
         DisplayByte(SCISR2);
         LF;
      break;
      case '9':
         DisplayString("SCIDRH = ");
         DisplayByte(SCIDRH);
         LF;
      break;
      case 'A':
         DisplayString("SCIDRL = ");
         DisplayByte(SCIDRL);
         LF;
      break;
      default:
         DisplayString("Invalid choice. Please try again");
         LF;
    }

   /* Wait to display register contents */
   for (x=0; x<3000; x++)
	 {	
 		 for (y=0; y<2000; y++)
		 {} 
   }

   FF;   
             
   }
}

/******************************************************************************
Function Name	:	PutChar
Engineer		:	r32151
Date			:	22/01/02

Parameters		:	character to be output to SCI
Returns			:	NONE
Notes			:	Transmits a character on SCI
******************************************************************************/
void PutChar(char ch) 
{
	/* check SCI transmit data register is empty */
	while(SCISR1_TDRE == 0)
	{
	}	
	SCIDRL = ch;	
}

/******************************************************************************
Function Name	:	GetChar
Engineer		:	r32151
Date			:	04/11/02

Parameters		:	NONE
Returns			:	character received by SCI
Notes			:	Receives a character on SCI
******************************************************************************/
char GetChar(void) 
{
	/* check SCI0 transmit data register is empty */
	while(SCISR1_RDRF == 0)
	{
	}	
	return(SCIDRL);	
}

/******************************************************************************
Function Name	:	DisplayString
Engineer		:	r58711
Date			:	14/02/02

Parameters		:	textString[]
Returns			:	NONE
Notes			:	Transmits text string as ASCII to SCI
******************************************************************************/
void DisplayString (signed char *textPointer)
{
		/* while not end of string */
	while(*textPointer != 0)
	{	
			/* write the character to the SCI interface */
		PutChar(*textPointer);
			/* increment to point at the next character in the string */
		textPointer++;
	}	
}

/******************************************************************************
Function Name	:	EchoGetChar
Engineer		:	r32151
Date			:	04/11/02

Parameters		:	NONE
Returns			:	character received by SCI
Notes			:	Receives a character on SCI and transmits it back out
******************************************************************************/
char EchoGetChar(void) 
{
		/* check SCI receive data register is empty */
	while(SCISR1_RDRF == 0)
	{
	}	
	/* Echo the received character back */
	PutChar(SCIDRL);
	/* return the received character */
	return(SCIDRL);	
}

/******************************************************************************
Function Name	:	DisplayInt
Engineer		:	r32151
Date			:	04/09/02

Parameters		:	int count value to display; unsigned char field width
Returns			:	NONE
Notes			:	Transmits Int variable to SCI after conversion to ASCII
            Effectively performs a number to string conversion and then outputs
            the string.
					  If field width = 0 then the int is displayed left justified with
					  leading zeros supressed.
					  If field width = 1-5 then lowest n digits are displayed with leading 
					  zeros.
					  This routine does not check that the field size is valid.					
******************************************************************************/
void DisplayInt(unsigned int number, unsigned char field ) 
{
	char buf[6];
	char i = 5;

	buf[i] = 0;
			/* for upto 10 digits : max value for long = 4294967296 */
			/* using a do while loop to take care of the number = 0 */
	do
	{
				/* convert least significant character of the int into ascii -> string buffer */
		buf[--i] = (char)(number % 10) + '0';
				/* moves next digit to least significant position */
		number /= 10;
	} while (number != 0); 
				/* if field width is less than number of digits only o/p field width of string */
	if ((field < (5-i)) && (field != 0))
		i = 5 - field;
				/* if field width is more than number of digits add leading zeros */
	if (field > (5-i))
	{
		while ((5-i) < field)
	    {
				/* add leading zeros */ 
		buf[--i] = '0';
		}
	}
	DisplayString(&buf[i] );	
}

/******************************************************************************
Function Name	:	DisplayByte
Engineer		:	r58711
Date			:	14/02/02

Parameters		:	displayByte
Returns			:	NONE
Notes			:	Transmits Byte variable to SCI after conversion to ASCII
******************************************************************************/
void DisplayByte (unsigned char displayByte)
{
	unsigned char upperNibble, lowerNibble;
		/* Split data into nibbles for ASCII conversion */
	upperNibble = ((displayByte & 0xF0)>>4); 
	lowerNibble = (displayByte & 0x0F);
		/* Pass nibbles to SCI after passing for conversion to ASCII */
	PutChar(Number_2_ASCII(upperNibble));
	PutChar(Number_2_ASCII(lowerNibble));
}

/******************************************************************************
Function Name	:	Number_2_ASCII
Engineer		:	r58711
Date			:	15.11.01

Parameters		:	Nibble of binary data (0000 to 1111) (unsigned char)
Returns			:	ASCII code for nibble (unsigned char)
*******************************************************************************/
unsigned char Number_2_ASCII(unsigned char Nibble)
{	
	/* If nibble is less than 9 (ie. a number) */
	if (Nibble <= 0x09) 
		/* Return the ASCII code for this number */
		return (Nibble + 0x30); 
	else
		/* Return the ASCII code for this letter */
		return (Nibble + 0x37); 
} 

/******************************************************************************
Function Name	:	ASCII_2_Number
Engineer		:	r58711
Date			:	15.11.01

Parameters		:	ASCII data byte (unsigned char)
Returns			:	numeric equivalent (unsigned char) of ASCII code 
*******************************************************************************/
unsigned char ASCII_2_Number(unsigned char ascii_char)
{
  byte number;	
	/* If character is 9 or less (ie. a number) */
	number = ascii_char - 0x30; 
	/* If character is greater than 9 (ie. hex number A,B,C,D,E,F) */
	if (number > 0x09) number -= 0x07;
	/* If chracter is greater than 9 and lower case (ie. hex number a,b,c,d,e,f) */
  if (number > 0x0F) number -= 0x20;	
  /* If charcter is non-numeric default to 0 */
  if (number > 0x0F) number = 0;
	return (number); 
} 

