/************************************************/
/* Demo Program For ET-BASE PIC40/46K22(ICSP)   */
/* MCU Control : PIC18F46K22                    */
/*             : Run 64MHz(Internal 16MHz+4PLL) */
/* 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/46K22(PIC18F46K22) 
#pragma config FOSC     = INTIO7        // Internal oscillator block, CLKOUT function on OSC2
#pragma config PLLCFG   = ON          	// Oscillator multiplied by 4
#pragma config PRICLKEN = ON        	// Primary clock is always enabled
#pragma config FCMEN    = ON            // Fail-Safe Clock Monitor enabled
#pragma config IESO     = ON            // Oscillator Switchover mode enabled
#pragma config PWRTEN   = ON          	// Power up timer enabled 
#pragma config BOREN    = SBORDIS       // Brown-out Reset enabled in hardware only (SBOREN is disabled)
#pragma config BORV     = 285           // VBOR set to 2.85 V nominal
#pragma config WDTEN    = OFF           // Watch dog timer is always disabled. SWDTEN has no effect.
#pragma config WDTPS    = 32768         // 1:32768
#pragma config CCP2MX   = PORTB3        // CCP2 input/output is multiplexed with RB3
#pragma config PBADEN   = OFF           // PORTB<5:0> pins are configured as digital I/O on Reset
#pragma config CCP3MX   = PORTB5        // P3A/CCP3 input/output is multiplexed with RB5
#pragma config HFOFST   = OFF           // HFINTOSC output and ready status are delayed by the oscillator stable status
#pragma config T3CMX    = PORTB5        // T3CKI is on RB5 
#pragma config P2BMX    = PORTD2        // P2B is on RD2
#pragma config MCLRE    = EXTMCLR       // MCLR pin enabled, RE3 input pin disabled 
#pragma config LVP      = ON            // Single-Supply ICSP enabled if MCLRE is also 1
#pragma config XINST    = OFF           // Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
#pragma config DEBUG    = ON            // Enabled

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

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

/** POT(RA0)*******************************************************/
#define InitPOT()         {ANSELAbits.ANSA0=1;TRISAbits.TRISA0=1;}

/** SWITCH(RA1)****************************************************/
#define InitSwitch1()     {ANSELAbits.ANSA1=0;TRISAbits.TRISA1=1;}
#define sw1                PORTAbits.RA1
 
/** LED(RA2)*******************************************************/
#define InitLED1()        {ANSELAbits.ANSA2=0;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 64.00 MHz **************************************************/
#define CLOCK_FREQ 		   64000000   
#define GetSystemClock()   64000000

/** 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)
{
  //Config PIC18F46K22 Oscillator : Run 64MHz from Internal 16MHz + PLL(4)
  OSCCONbits.IRCF = 7;					// Internal RC Oscillator Frequency = HFINTOSC – (16 MHz)
  OSCCONbits.OSTS = 0;					// Oscillator Start-up Time-out = Device is running from the internal oscillator (HFINTOSC, MFINTOSC or LFINTOSC)
  OSCCONbits.HFIOFS = 1;				// HFINTOSC frequency is stable
  OSCCONbits.SCS = 0;					// Primary clock (determined by FOSC<3:0> in CONFIG1H).
  OSCTUNEbits.PLLEN = 1;  				// x4 PLL enabled = 64MHz

  ANSELAbits.ANSA2 = 0;					// RA2 = Digital
  ANSELAbits.ANSA1 = 0; 				// RA1 = Digital
  ANSELAbits.ANSA0 = 1;					// RA0 = Analog

  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;
    }
    //Blink 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
  ADCON2bits.ADCS = 6;					// ADC Conversion Clock=Fosc/64
               
  ADCON1bits.PVCFG = 0;					// ADC VREF+ connected to internal signal, AVDD
  ADCON1bits.NVCFG = 0;					// ADC VREF- connected to internal signal, AVSS
  
  ADCON0bits.CHS = 0;					// Select ADC Channel = AN0
  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 = 1;              		// Start Conversion  
  while (ADCON0bits.NOT_DONE == 1);   	// wait for it to complete
  return ADRESH;              	 		// return high byte of result
}
