/************************************************/
/* Demo Program For ET-BASE PIC40/4550(ICSP)    */
/* MCU Control : PIC18F4550                     */
/*             : Run 48MHz(X-TAL 8.00MHz + PLL) */
/* Compiler    : C18 Version 3.41               */
/* Function    : ADC Adjust Delay Blink LED     */
/************************************************/

/** C O N F I G U R A T I O N   B I T S ******************************/
//ETT:ET-BASE PIC40/4550(PIC18F4550) 
#pragma config PLLDIV   = 2         	// (8 MHz crystal on ET-BASE PIC18 board)
#pragma config CPUDIV   = OSC1_PLL2    	// [Primary Oscillator Src: /1][96 MHz PLL Src: /2] 
#pragma config USBDIV   = 2             // Clock source from 96MHz PLL/2
#pragma config FOSC     = HSPLL_HS		// Clock Source = HS+PLL
#pragma config FCMEN    = OFF			// Fail-Safe Clock Monitor disabled
#pragma config IESO     = OFF			// Oscillator Switchover mode disabled
#pragma config PWRT     = ON			// Power-up Timer Enable
#pragma config BOR      = ON			// Brown-out Reset enabled in hardware only (SBOREN is disabled) 
#pragma config BORV     = 0				// Brown-out Reset Voltage = Maximum setting
#pragma config VREGEN   = ON      		// USB Voltage Regulator
#pragma config WDT      = OFF			// WDT disabled (control is placed on the SWDTEN bit) 
#pragma config WDTPS    = 32768			// Watchdog Timer Postscale = 1:32768	
#pragma config CCP2MX   = OFF  			// CCP2 input/output is multiplexed with RB3 
#pragma config PBADEN   = OFF			// PORTB<4:0> pins are configured as digital I/O on Reset
#pragma config LPT1OSC  = OFF			// Timer1 configured for higher power operation 
#pragma config MCLRE    = ON			// MCLR pin enabled; RE3 input pin disabled
#pragma config STVREN   = ON			// Stack full/underflow will cause Reset
#pragma config LVP      = OFF			// Single-Supply ICSP disabled
#pragma config ICPRT    = ON            // ***Enable In-Circuit Debug/Programming***
#pragma config XINST    = OFF       	// Extended Instruction Set
#pragma config DEBUG    = ON            // Background debugger enabled, RB6 and RB7 are dedicated to In-Circuit Debug 

//Disable All Protect
#pragma config CP0      = OFF			// Block 0 (000800-001FFFh) is not code-protected
#pragma config CP1      = OFF			// Block 1 (002000-003FFFh) is not code-protected
#pragma config CP2      = OFF			// Block 2 (004000-005FFFh) is not code-protected
#pragma config CP3      = OFF			// Block 3 (006000-007FFFh) is not code-protected
#pragma config CPB      = OFF			// Boot block (000000-0007FFh) is not code-protected
#pragma config CPD      = OFF			// Data EEPROM is not code-protected 
#pragma config WRT0     = OFF			// Block 0 (000800-001FFFh) is not write-protected
#pragma config WRT1     = OFF			// Block 1 (002000-003FFFh) is not write-protected
#pragma config WRT2     = OFF			// Block 2 (004000-005FFFh) is not write-protected
#pragma config WRT3     = OFF			// Block 3 (006000-007FFFh) is not write-protected
#pragma config WRTC     = OFF			// Configuration registers (300000-3000FFh) are not write-protected
#pragma config WRTB     = OFF       	// Boot block (000000-0007FFh) is not write-protected 
#pragma config WRTD     = OFF			// Data EEPROM is not write-protected
#pragma config EBTR0    = OFF			// Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks
#pragma config EBTR1    = OFF			// Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks
#pragma config EBTR2    = OFF			// Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks 
#pragma config EBTR3    = OFF			// Block 3 (006000-007FFFh) is not protected from table reads executed in other blocks
#pragma config EBTRB    = OFF			// Boot block (000000-0007FFh) is not protected from table reads executed in other blocks
//ETT:ET-BASE PIC40/4550(PIC18F4550)

/** I N C L U D E S **************************************************/
#include "p18f4550.h"
#include "delays.h"
#include "GenericTypeDefs.h"

/** POT(RA0)*******************************************************/
#define InitPOT()          {ADCON1bits.PCFG = 14;TRISAbits.TRISA0=1;}

/** SWITCH(RA1)****************************************************/
#define InitSwitch1()      {TRISAbits.TRISA1=1;}
#define sw1                PORTAbits.RA1
 
/** LED(RA2)*******************************************************/
#define InitLED1()         {LATAbits.LATA2=0; TRISAbits.TRISA2=0;}	
#define LED1               LATAbits.LATA2    
#define LED1_On()          LED1 = 1;    
#define LED1_Off()         LED1 = 0;
#define LED1_Toggle()      LED1 = !LED1;

/** Run 48.00 MHz **************************************************/
#define CLOCK_FREQ 		   48000000   
#define GetSystemClock()   48000000

/** VARIABLES ******************************************************/
#pragma udata
BYTE delay_led;

/** PRIVATE PROTOTYPES *********************************************/
void ADC_Init(void);
unsigned char ADC_Convert(void);

#pragma romdata
const rom unsigned char LED_Level[8] = {0b00000001,0b00000011,0b00000111,0b00001111,
									    0b00011111,0b00111111,0b01111111,0b11111111};
/** DECLARATIONS ***************************************************/
#pragma code
void main (void)
{
  ADCON1bits.PCFG = 14;					// RA0 = ADC Only
  ADC_Init();							// Init ADC	
  InitLED1();							// Initial LED = Output
  LED1_On();							// Default LED1 = ON

  //BarGraph LED Display ADC Level
  TRISD = 0b00000000;     	            // PORTD bits 7:0 are all outputs (0)

  while (1)
  {
    LED1_Toggle();						// Toggle LED
    delay_led = ADC_Convert();			// Get ADC Result to Delay LED Blink Value
    LATD = ~LED_Level[delay_led/32];    // RD[7...0] Display BarGraph LED Level   

    if(delay_led==0)					// Minimum Delay = 1 
    { 
      delay_led=1;
    }
    
    //Blick Delay = [50 x 10,000(Tcy)] + [1..255 x 10,000(Tcy)]
    Delay10KTCYx(50);					// Base Delay = 50 x 10,000(Tcy)
    Delay10KTCYx(delay_led); 			// Variable Delay = 1..255 x 10,000(Tcy)
  }	
}

// initialize the Analog-To-Digital converter.
void ADC_Init(void)
{ 
  ADCON2bits.ADFM = 0; 					// ADC Result = Left justified
  ADCON2bits.ACQT = 7;					// ADC Acquisition Time = 20TAD(xx111xxx)
  ADCON2bits.ADCS = 6;	                // ADC Conversion Clock=Fosc/64(xxxxx110)
  
  ADCON1bits.VCFG = 0;					// ADC Vref(+)...Vref(-) = VDD...VSS(xx00xxxx)
  ADCON1bits.PCFG = 14;	                // AN0 = Analog (xxxx1110)
                       
  ADCON0bits.CHS = 0; 					// Select ADC Channel = AN0 (xx0000xx)
  ADCON0bits.ADON = 1;                  // Start ADC  
}

// start an ADC conversion and return the 8 most-significant bits of the result
unsigned char ADC_Convert(void)
{ 
    ADCON0bits.GO_DONE = 1;             // start conversion
    while (ADCON0bits.GO_DONE == 1);    // wait for it to complete
    return ADRESH;              	 	// return high byte of result
}
