text: /********************************************************************
   Software License Agreement:
  
   The software supplied herewith by Microchip Technology Incorporated
   (the "Company") for its PIC(R) Microcontroller is intended and
   supplied to you, the Company's customer, for use solely and
   exclusively on Microchip PIC Microcontroller products. The
   software is owned by the Company and/or its supplier, and is
   protected under applicable copyright laws. All rights are reserved.
   Any use in violation of the foregoing restrictions may subject the
   user to criminal sanctions under applicable laws, as well as to
   civil liability for the breach of the terms and conditions of this
   license.
  
   THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES,
   WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
   TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
   PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
   IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
   CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
   *******************************************************************/
  
  #include <xc.h>
  #include <system.h>
  #include <system_config.h>
  #include <usb/usb.h>
  #include <print_lcd.h>
  #include <leds.h>
  #include <buttons.h>
  #include <adc.h>
  
  /** CONFIGURATION Bits **********************************************/
  // FICD
  #pragma config ICS = PGD1               // ICD Communication Channel Select bits (Communicate on PGEC1 and PGED1)
  #pragma config RSTPRI = PF              // Reset Target Vector Select bit (Device will obtain reset instruction from Primary flash)
  #pragma config JTAGEN = OFF             // JTAG Enable bit (JTAG is disabled)
  
  // FPOR
  #pragma config FPWRT = PWR128           // Power-on Reset Timer Value Select bits (128ms)
  #pragma config BOREN = OFF              // Brown-out Reset (BOR) Detection Enable bit (BOR is disabled)
  #pragma config ALTI2C1 = OFF            // Alternate I2C pins for I2C1 (SDA1/SCK1 pins are selected as the I/O pins for I2C1)
  #pragma config ALTI2C2 = OFF            // Alternate I2C pins for I2C2 (SDA2/SCK2 pins are selected as the I/O pins for I2C2)
  
  // FWDT
  #pragma config WDTPOST = PS32768        // Watchdog Timer Postscaler Bits (1:32,768)
  #pragma config WDTPRE = PR128           // Watchdog Timer Prescaler bit (1:128)
  #pragma config PLLKEN = ON              // PLL Lock Wait Enable bit (Clock switch to PLL source will wait until the PLL lock signal is valid.)
  #pragma config WINDIS = OFF             // Watchdog Timer Window Enable bit (Watchdog Timer in Non-Window mode)
  #pragma config FWDTEN = OFF             // Watchdog Timer Enable bit (Watchdog timer enabled/disabled by user software)
  
  // FOSC
  #pragma config POSCMD = HS              // Primary Oscillator Mode Select bits (HS Crystal Oscillator Mode)
  #pragma config OSCIOFNC = ON            // OSC2 Pin Function bit (OSC2 is general purpose digital I/O pin)
  #pragma config IOL1WAY = OFF            // Peripheral pin select configuration (Allow multiple reconfigurations)
  #pragma config FCKSM = CSDCMD           // Clock Switching Mode bits (Both Clock switching and Fail-safe Clock Monitor are disabled)
  
  // FOSCSEL
  #pragma config FNOSC = PRIPLL           // Initial Oscillator Source Selection Bits (Primary Oscillator (XT, HS, EC) with PLL)
  #pragma config IESO = OFF               // Two-speed Oscillator Start-up Enable bit (Start up with user-selected oscillator source)
  
  // FGS
  #pragma config GWRP = OFF               // General Segment Write-Protect bit (General Segment may be written)
  #pragma config GSS = OFF                // General Segment Code-Protect bit (General Segment Code protect is disabled)
  #pragma config GSSK = OFF               // General Segment Key bits (General Segment Write Protection and Code Protection is Disabled)
  
  // FAS
  #pragma config AWRP = OFF               // Auxiliary Segment Write-protect bit (Auxiliary program memory is not write-protected)
  #pragma config APL = OFF                // Auxiliary Segment Code-protect bit (Aux Flash Code protect is disabled)
  #pragma config APLK = OFF               // Auxiliary Segment Key bits (Aux Flash Write Protection and Code Protection is Disabled)
  
  /*********************************************************************
  * Function: void SYSTEM_Initialize( SYSTEM_STATE state )
  *
  * Overview: Initializes the system.
  *
  * PreCondition: None
  *
  * Input:  SYSTEM_STATE - the state to initialize the system into
  *
  * Output: None
  *
  ********************************************************************/
  void SYSTEM_Initialize( SYSTEM_STATE state )
  {
      switch(state)
      {
          case SYSTEM_STATE_USB_HOST:
              ANSELA = 0x0000;
              ANSELB = 0x0000;
              ANSELC = 0x0000;
              ANSELD = 0x0000;
              ANSELE = 0x0000;
              ANSELG = 0x0000;
  
              // Configure the device PLL to obtain 60 MIPS operation. The crystal
              // frequency is 8MHz. Divide 8MHz by 2, multiply by 60 and divide by
              // 2. This results in Fosc of 120MHz. The CPU clock frequency is
              // Fcy = Fosc/2 = 60MHz. Wait for the Primary PLL to lock and then
              // configure the auxilliary PLL to provide 48MHz needed for USB
              // Operation.
  
              PLLFBD = 58;                        /* M  = 60  */
              CLKDIVbits.PLLPOST = 0;             /* N1 = 2   */
              CLKDIVbits.PLLPRE = 0;              /* N2 = 2   */
              OSCTUN = 0;
  
              /*	Initiate Clock Switch to Primary
               *	Oscillator with PLL (NOSC= 0x3)*/
              __builtin_write_OSCCONH(0x03);
              __builtin_write_OSCCONL(0x01);
  
              while (OSCCONbits.COSC != 0x3);
  
              // Configuring the auxiliary PLL, since the primary
              // oscillator provides the source clock to the auxiliary
              // PLL, the auxiliary oscillator is disabled. Note that
              // the AUX PLL is enabled. The input 8MHz clock is divided
              // by 2, multiplied by 24 and then divided by 2. Wait till
              // the AUX PLL locks.
  
              ACLKCON3 = 0x24C1;
              ACLKDIV3 = 0x7;
  
              ACLKCON3bits.ENAPLL = 1;
              while(ACLKCON3bits.APLLCK != 1);
  
              PRINT_SetConfiguration(PRINT_CONFIGURATION_LCD);
  
              break;
              
          case SYSTEM_STATE_USB_HOST_HID_KEYBOARD:
              LED_Enable(LED_USB_HOST_HID_KEYBOARD_DEVICE_READY);
  
              PRINT_SetConfiguration(PRINT_CONFIGURATION_LCD);
              LCD_CursorEnable(true);
  
              TIMER_SetConfiguration(TIMER_CONFIGURATION_1MS);
  
              break;
      }
  }
  
  void __attribute__((interrupt,auto_psv)) _USB1Interrupt()
  {
          USB_HostInterruptHandler();
  }
  