/*****************************************************************************/
/* FILE NAME: main.c                            COPYRIGHT (c) Freescale 2010 */
/*                                                       All Rights Reserved */
/*  																		 */
/* MPC5668 Example Projects Suite											 */
/* eMIOS Examples - Derived from AN2865										 */
/*																			 */
/* Revision History															 */
/* 		Rev: 1.0 		Author:	Steven McLaughlin  		DATE: 20/07/2010 	 */
/*																			 */
/* Example demostrates the eMIOS200 module by utilising the OPWM and IPWM    */
/* functions. A 1kHz pulse is generated and output on PG14 (eMIOS ch1) and   */
/* the pulse width (500us) is read on PG15 (eMIOS ch0). PE1 is connected     */
/* to an LED to notify when the correct pulse width has been measured.       */
/*****************************************************************************/

/***************************** Includes **************************************/
#include "mpc5668.h"
/***************************** Global variables ******************************/
	uint32_t pulse_width, count;
/***************************** Function Prototypes ***************************/
void initEMIOSch0(void);
void initEMIOSch1(void);
void initEMIOSch23(void);
void initEMIOS(void);

/********************************** Main *************************************/
void main (void) 
{
	SIU.SYSCLK.B.SYSCLKSEL = 0x1;					/* Select crystal as CLK Source - 40MHz */

	/* --------------------ENABLE CLKOUT------------------------------------ */
	SIU.PCR[153].R = 0x060C; 						/* CLKOUT - PK9 */
	SIU.ECCR.B.ECDF = 0;     						/* CLKOUT = Set to 0 for sys freq. */
	SIU.ECCR.B.ECEN = 1; 							/* enable CLKOUT */
	/* ------------------LED and Switch port init----------------------- */
	SIU.PCR[65].R=0x0200;							/* OBE on PE1 - LED connection */
	SIU.GPDO[65].R = 0x01; 
	
	initEMIOS();
	initEMIOSch0();
	initEMIOSch1();	
	initEMIOSch23();

	while (1)
	{
		while (!EMIOS.CH[0].CSR.B.FLAG);			/* Wait for flag to be set */
		pulse_width = EMIOS.CH[0].CBDR.R;			/* read pulse width from register B */

		if (pulse_width = EMIOS.CH[1].CADR.R)   	/* Compare measured width at ch1 with original */
		{
			for (count=0; count<100000; count++);	/* loops to toggle PE1, pulse width is correct */
			SIU.GPDO[65].R = 0x01;
			for (count=0; count<100000; count++);
			SIU.GPDO[65].R = 0x00;
		}

		/* Clear flags and overruns */
		EMIOS.CH[0].CSR.B.FLAG = 1;
		EMIOS.CH[1].CSR.B.FLAG = 1;
		EMIOS.CH[0].CSR.B.OVR = 1;
		EMIOS.CH[1].CSR.B.OVR = 1;
	}
}/* end of main() */	

/**************************** Functions*******************************************/

void initEMIOSch23(void)         					/* EMIOS CH 23: Modulus Up Counter */
{
	EMIOS.CH[23].CADR.R = 999;       				/* Period will be 999+1 = 1000 clocks (1 msec) */
	EMIOS.CH[23].CCR.B.MODE = 0x50;  				/* Modulus Counter Buffered (MCB) */
	EMIOS.CH[23].CCR.B.BSL = 0x3;	   				/* Use internal counter */
	EMIOS.CH[23].CCR.B.UCPRE=0;	   					/* Set channel prescaler to divide by 1 */
	EMIOS.CH[23].CCR.B.FREN = 1; 	   				/* Freeze channel counting when in debug mode */
	EMIOS.CH[23].CCR.B.UCPREN = 1;   				/* Enable prescaler; uses default divide by 1 */
}

void initEMIOSch0(void) 							/* EMIOS CH 0: Input Pulse Width Measurement (IPWM) */
{
	EMIOS.CH[0].CCR.B.BSL = 0x0;	 				/* Use counter bus A (default) */ 
	EMIOS.CH[0].CCR.B.EDPOL = 1;	   				/* Polarity-leading edge sets output/trailing clears */
	EMIOS.CH[0].CCR.B.EDSEL = 1;	   				/* internal counter trigger by both edges */
	EMIOS.CH[0].CCR.B.MODE = 0x04;   				/* Input pulse width measurement */
	SIU.PCR[111].R = 0x0500;          				/* Initialize pad for eMIOS chan. 0 input */
}

void initEMIOSch1(void)     						/* EMIOS CH 1: Output Pulse Width Modulation (OPWMB) */
{      
  EMIOS.CH[1].CADR.R = 500;        					/* Leading edge when channel counter bus=500 */
  EMIOS.CH[1].CBDR.R = 999;        					/* Trailing edge when channel's counter bus=999 */
  EMIOS.CH[1].CCR.B.BSL = 0x0;	   					/* Use counter bus A (default) */
  EMIOS.CH[1].CCR.B.EDPOL = 1;	   					/* Polarity-leading edge sets output/trailing clears */
  EMIOS.CH[1].CCR.B.MODE = 0x60;   					/* MPC551x, MPC563x: Mode is OPWM Buffered */
  SIU.PCR[110].R = 0x0600;          				/* Initialize pad for eMIOS chan. 1 output */
}

void initEMIOS(void)
{
  EMIOS.MCR.B.GPRE= 39;     						/* Divide 40 MHz sysclk by 39+1 = 40 for 1MHz eMIOS clk */
  EMIOS.MCR.B.GPREN = 1;							/* Enable eMIOS clock */
  EMIOS.MCR.B.GTBE = 1;								/* Enable global time base */
  EMIOS.MCR.B.FRZ = 1;								/* Enable stopping channels when in debug mode */
}