/************************************************/
/* Demo Program For ET-BASE PIC40/46K80(ICSP)   */
/* MCU Control : PIC18F46K80                    */
/*             : 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/46K80(PIC18F46K80) 
#pragma config RETEN    = ON            // Ultra low-power regulator is Enabled (Controlled by SRETEN bit)
#pragma config INTOSCSEL = LOW          // LF-INTOSC in Low-power mode during Sleep
#pragma config SOSCSEL  = LOW           // Low Power SOSC circuit selected
#pragma config XINST    = OFF           // Disabled Extended Instruction Set
 
#pragma config FOSC     = INTIO1        // Internal RC oscillator, CLKOUT function on OSC2
#pragma config PLLCFG   = ON            // Oscillator multiplied by 4
#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     = 0             // VBOR set to 3.0V V nominal
#pragma config BORPWR   = LOW           // BORMV set to low power level
#pragma config WDTEN    = OFF           // Watch dog timer is always disabled. SWDTEN has no effect.
#pragma config WDTPS    = 1048576       // 1:1048576
#pragma config CANMX    = PORTB         // ECAN TX and RX pins are located on RB2 and RB3, respectively
#pragma config MSSPMSK  = MSK7          // 7 Bit address masking mode
#pragma config MCLRE    = ON            // MCLR Enabled, RG5 Disabled
#pragma config STVREN   = ON            // Enabled Stack Overflow Reset
#pragma config BBSIZ    = BB2K          // 2K word Boot Block size

//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/46K80(PIC18F46K80)

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

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

/** SWITCH(RA1)****************************************************/
#define InitSwitch1()     {ANCON0bits.ANSEL1=0;TRISAbits.TRISA1=1;}
#define sw1                PORTAbits.RA1
 
/** LED(RA2)*******************************************************/
#define InitLED1()        {ANCON0bits.ANSEL2=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 PIC18F46K80 Oscillator : Run 64MHz from Internal 16MHz + PLL(4)
  OSCCONbits.IRCF = 7;					// HF-INTOSC output frequency is used (16 MHz)	
  OSCCONbits.OSTS = 0;					// Oscillator Start-up Timer (OST) time-out is running
  OSCCONbits.HFIOFS = 1;				// HF-INTOSC oscillator frequency is stable
  OSCCONbits.SCS = 0;					// HF-INTOSC with PLL. Defined by the FOSC<3:0> Configuration bits, CONFIG1H<3:0>.)
  OSCTUNEbits.PLLEN = 1;  				// x4 PLL enabled = 64MHz

  ANCON0bits.ANSEL2 = 0;                // RA2 = Digital 
  ANCON0bits.ANSEL1 = 0;                // RA1 = Digital 
  ANCON0bits.ANSEL0 = 1;				// RA0 = ADC
  
  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)
{ 
  ANCON0bits.ANSEL0 = 1;				// RA0 = ADC
  TRISAbits.TRISA0=1;					// RA0 = Input Analog

  ADCON2bits.ADFM=0; 					// Result Format 0 = Left justified
  ADCON2bits.ACQT=7; 					// Acquisition time 7 = 20TAD 
  ADCON2bits.ADCS=6; 					// Clock conversion bits 6= FOSC/64

  ADCON1bits.VCFG = 0; 					// Vref+ = AVdd
  ADCON1bits.VNCFG = 0; 				// Vref- = AVss
  ADCON1bits.CHSN = 0; 					// Select ADC Negative Channel = AVSS
  
  ADCON0bits.CHS = 0;					// ADC Channel Input = AN0
  ADCON0bits.ADON = 1; 					// Turn on ADC
}

// start an ADC conversion and return the 8 most-significant bits of the result
unsigned char ADC_Convert(void)
{ 
  unsigned char result,adc_sign;
  
  ADCON0bits.GO = 1;              		// Start Conversion  
  while (ADCON0bits.NOT_DONE == 1);   	// wait for it to complete

  result = ADRESH;
  adc_sign = ADRESL & 0x01;				// adjust -result to Zero			
  if (adc_sign != 0)
  {
    result = 0;
  }

  return result;              	 		// return high byte of result
}

