/*****************************************************************************/
/* FILE NAME: main.c                            COPYRIGHT (c) Freescale 2010 */
/*                                                       All Rights Reserved */
/*  									     								 */
/* MPC5668 Example Projects Suite					     					 */
/* ADC/PWM Examples							     							 */
/*									        								 */
/* Revision History							        						 */
/*      Rev: 1.0 		Author:	Martin Vaupel	DATE: 11/10/2010     		 */
/*									     									 */
/* Example demonstrates the use of ADC and the eMIOS of MPC5668. The user    */
/* can influence the brightness of an LED using the potentimeter as an     */
/* input to the ADC. Its result changes the PWMs duty cycle affecting the    */
/* LEDs brightness.							     							 */
/*									   		 								 */
/*****************************************************************************/

/***************************** Includes **************************************/
#include "mpc5668.h"
/***************************** Global variables ******************************/
	uint32_t adc_result;	
/***************************** Function Prototypes ***************************/
void initADC(void);
void initEMIOS(void);
void initEMIOSch1(void);
void initEMIOSch23(void);


/********************************* Main **************************************/
void main (void) 
{
	SIU.SYSCLK.B.SYSCLKSEL = 0x1;	/* Select crystal as CLK Source - 40MHz */
 
	initADC();
	initEMIOS();
	initEMIOSch1();
	initEMIOSch23();
	
    ADC.MCR.B.NSTART = 1; 								/* start conversion */

	while (1)
	{    
		adc_result = ADC.PRECDATAREG[0].R - 0x80000;	/* read conversion */
		EMIOS.CH[1].CADR.R = adc_result; 				/* will be 0 to 1023 */
	    EMIOS.CH[1].CSR.B.FLAG = 1;						/* clear flag */
	    EMIOS.CH[1].CSR.B.OVR = 1;						/* clear overrun */
	} 
}/* end of main() */

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

void initADC(void) 
{
    ADC.MCR.B.PWDN = 0;		/* ADC enable */
    ADC.MCR.B.MODE = 1; 	/* scan mode */
    ADC.MCR.B.TRGEN = 0;	/* start by SW */
    ADC.NCMR0.B.CH0 = 1;	/* mask enable for channel0 */
    SIU.PCR[0].B.PA=1; 		/* alt func on PA0 = AN0 - analog input from pot */
}

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 */
}

void initEMIOSch1(void)     		/* EMIOS CH 1: Output Pulse Width Modulation (OPWMB) */
{      
	EMIOS.CH[1].CBDR.R = 1023;    	/* 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;	/* Output Pulse Width Modulation Buffered (flag on B1 match) */
	SIU.PCR[110].R = 0x0600;      	/* Initialize pad for eMIOS chan. 1 output -> PG14 */
}

void initEMIOSch23(void)      		/* EMIOS CH 23: Modulus Up Counter */
{
	EMIOS.CH[23].CADR.R = 1023;   	/* 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 */
}
