/************************************************/
/* Demo Program For ET-BASE PIC40/46K22(ICSP)   */
/* MCU Control : PIC18F46K22                    */
/*             : Run 64MHz(Internal 16MHz+PLL)  */ 
/* Compiler    : PIC-CCS Version 4.120          */
/* Function    : QC Test Hardware Board         */
/************************************************/
#include <18F46K22.h>
#include <stdlib.h>

// Fuses: PIC18F46K22(CCS Compiler)
//////// Fuses: LP,XT,HSH,HSM,ECH,ECH_IO,RC,RC_IO,INTRC_IO,INTRC,ECM,ECM_IO
//////// Fuses: ECL,ECL_IO,NOPLLEN,PLLEN,PRIMARY_SW,PRIMARY_ON,NOFCMEN,FCMEN
//////// Fuses: NOIESO,IESO,PUT,NOPUT,NOBROWNOUT,BROWNOUT_SW,BROWNOUT_NOSL
//////// Fuses: BROWNOUT,BORV45,BORV42,BORV27,BORV20,NOWDT,WDT_NOSLEEP
//////// Fuses: WDT_SW,WDT,WDT1,WDT2,WDT4,WDT8,WDT16,WDT32,WDT64,WDT128
//////// Fuses: WDT256,WDT512,WDT1024,WDT2048,WDT4096,WDT8192,WDT16384
//////// Fuses: WDT32768,CCP2B3,CCP2C1,NOPBADEN,PBADEN,CCP3E0,CCP3B5
//////// Fuses: NOHFOFST,HFOFST,TIMER3B5,TIMER3C0,CCP2C0,CCP2D2,NOMCLR,MCLR
//////// Fuses: NOSTVREN,STVREN,NOLVP,LVP,NOXINST,XINST,DEBUG,NODEBUG
//////// Fuses: PROTECT,NOPROTECT,CPB,NOCPB,CPD,NOCPD,WRT,NOWRT,WRTC,NOWRTC
//////// Fuses: WRTB,NOWRTB,WRTD,NOWRTD,EBTR,NOEBTR,EBTRB,NOEBTRB

//Select Jumper RA6,RA7(XTAL/GPIO) = GPIO
#fuses INTRC_IO,NOWDT,NOPROTECT,NODEBUG,PLLEN                                 // Ineternal 16MHz + PLL(4) = 64MHz 
#use delay(clock=64000000)

/* Config and Enable Hardware UART1(RC6=TX1,RC7=RX1 */
#use rs232(uart1, baud=9600, stream=CH1)

/* Config and Enable Software UART2(RC0=TX2,RC1=RX2 */
#define TX2 PIN_C0                                                            // RC0 = TXD
#define RX2 PIN_C1                                                            // RC1 = RXD

//ADC0:RA0:VR1 -> Demo Test ADC
#define ADC0_PIN    PIN_A0                                                    //ADC0(VR1)

//SW1
#define SW1         PIN_A1                                                    // Switch SW1  

//LED Status(Actin High)
#define LED         PIN_A2                                                    // LED Selftest

//LED Barfraph Display Scale ADC Result
const unsigned char Bargraph_LED[8] =
{
  0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF                              // 8 Bit LED Test
};

const unsigned char TestPort_LED[8] =
{
  0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80                              // 8 Bit LED Test
};

void test_adc(void);
void test_sw1(void);
void test_led(void);
void test_gpio(void);
void test_uart2(void);

/****************/
/* Main Program */
/****************/
void main() 
{  
  char rx_buff;
  
  setup_oscillator(OSC_16MHZ|OSC_PLL_ON);                                     // Sets the Internal Oscillator to 64MHz (PLL Enabled)  
  
  //Defaul All GPIO = Input
  set_tris_a(0b11111111);                                                     // RA[7..0] = Input
  set_tris_b(0b11111111);                                                     // RB[7..0] = Input
  set_tris_c(0b11111111);                                                     // RC[7..0] = Input
  set_tris_d(0b11111111);                                                     // RD[7..0] = Input
  set_tris_e(0b11111111);                                                     // RE[2..0] = Input  
  delay_ms(500);                                                              //Power-On Delay
  
  //Start-Up UART1
  fprintf(CH1,"\n\n\n\r");
  fprintf(CH1,"===================================\n\r"); 
  fprintf(CH1,"QC Test : ET-BASE PIC40/46K22(ICSP)\n\r");
  fprintf(CH1,"Run 64MHz(Internal 16MHz + PLL[4])\n\r");  
  fprintf(CH1,"===================================\n\r"); 
  fprintf(CH1,"1. TEST VR1(RA0/VR1)\n\r"); 
  fprintf(CH1,"2. TEST SW1(RA1/SW1)\n\r"); 
  fprintf(CH1,"3. TEST LED(RA2/LED)\n\r");
  fprintf(CH1,"4. TEST All GPIO\n\r"); 
  fprintf(CH1,"5. Test UART2(Software UART)\n\r"); 
  fprintf(CH1,"===================================\n\r"); 
  fprintf(CH1,"UART1>");
 
  while(true)
  { 
    //Verify & Echo UART1
    if(kbhit(CH1))
    {
      rx_buff = fgetc(CH1);
      if (rx_buff == 0x0D)
      {
        fprintf(CH1,"\n\n\n\r");
        fprintf(CH1,"===================================\n\r"); 
        fprintf(CH1,"QC Test : ET-BASE PIC40/46K22(ICSP)\n\r");
        fprintf(CH1,"Run 64MHz(Internal 16MHz + PLL[4])\n\r");  
        fprintf(CH1,"===================================\n\r"); 
        fprintf(CH1,"1. TEST VR1(RA0/VR1)\n\r"); 
        fprintf(CH1,"2. TEST SW1(RA1/SW1)\n\r"); 
        fprintf(CH1,"3. TEST LED(RA2/LED)\n\r");
        fprintf(CH1,"4. TEST All GPIO\n\r"); 
        fprintf(CH1,"5. Test UART2(Software UART)\n\r"); 
        fprintf(CH1,"===================================\n\r"); 
        fprintf(CH1,"UART1>");
      }
      else 
      {
        switch (rx_buff) 
        {
          case 0x31: fprintf(CH1,"1\n\r");
                     fprintf(CH1,"\n\r");
                     fprintf(CH1,"===================================\n\r"); 
                     fprintf(CH1," Test VR1 : Display ADC on Port-RD \n\r"); 
                     fprintf(CH1,"===================================\n\r"); 
                     test_adc();
                     break;

          case 0x32: fprintf(CH1,"2\n\r");
                     fprintf(CH1,"\n\r");
                     fprintf(CH1,"===================================\n\r"); 
                     fprintf(CH1," Test SW1 : Toggle LED On/OFF\n\r"); 
                     fprintf(CH1,"===================================\n\r"); 
                     test_sw1();
                     break;
                     
          case 0x33: fprintf(CH1,"3\n\r");
                     fprintf(CH1,"\n\r");
                     fprintf(CH1,"===================================\n\r"); 
                     fprintf(CH1," Test LED : Blinking LED\n\r"); 
                     fprintf(CH1,"===================================\n\r"); 
                     test_led();
                     break;

          case 0x34: fprintf(CH1,"4\n\r");
                     fprintf(CH1,"\n\r");
                     fprintf(CH1,"===================================\n\r"); 
                     fprintf(CH1," Test All GPIO By LED Output\n\r"); 
                     fprintf(CH1," RA[0..7]\n\r"); 
                     fprintf(CH1," RB[0..7]\n\r"); 
                     fprintf(CH1," RC[0..5,7] : RC6 Reserve For RX1\n\r"); 
                     fprintf(CH1," RD[0..7]\n\r"); 
                     fprintf(CH1," RE[0..2]\n\r"); 
                     fprintf(CH1,"===================================\n\r"); 
                     test_gpio();
                     break;           

          case 0x35: fprintf(CH1,"5\n\r");
                     fprintf(CH1,"\n\r");
                     fprintf(CH1,"===================================\n\r"); 
                     fprintf(CH1," Test UART2(Software UART)\n\r");                      
                     fprintf(CH1,"===================================\n\r"); 
                     fprintf(CH1,"Press SW1 For Start Test\n\r"); 
                     test_uart2();
                     break;   
                     
          default  : break;
                      
        }
      }
    }      
  }  
}

//Test RA0:AN0
void test_adc()
{
  int8 AN0_Value;

  //Defaul All GPIO = Input
  set_tris_a(0b11111111);                                                     // RA[7..0] = Input
  set_tris_b(0b11111111);                                                     // RB[7..0] = Input
  set_tris_c(0b11111111);                                                     // RC[7..0] = Input
  set_tris_d(0b11111111);                                                     // RD[7..0] = Input
  set_tris_e(0b11111111);                                                     // RE[2..0] = Input 
  
  output_float(ADC0_PIN);                                                     // ADC Input
  setup_adc_ports(sAN0);                                                      // Assign Analog pin
  setup_adc(ADC_CLOCK_INTERNAL);                                                                          
  
  //Used RD[7..0]= Bargraph Display
  set_tris_d(0b00000000);                                                     // RD[7..0]=Output
  
  while(true)
  { 
    set_adc_channel(0);                                                       // Select Channel AN0
    delay_us(10);                                                             // Wait Multiplex Stable     
    AN0_Value = read_adc();                                                   // Read adc channel 0 

    fprintf(CH1,"ADC[0] : AN0 = %3u \r",AN0_Value);
    output_d(~Bargraph_LED[AN0_Value/32]);
    delay_ms(250);
  }  
}

//Test RA1:SW1
void test_sw1()
{
  //Defaul All GPIO = Input
  set_tris_a(0b11111111);                                                     // RA[7..0] = Input
  set_tris_b(0b11111111);                                                     // RB[7..0] = Input
  set_tris_c(0b11111111);                                                     // RC[7..0] = Input
  set_tris_d(0b11111111);                                                     // RD[7..0] = Input
  set_tris_e(0b11111111);                                                     // RE[2..0] = Input 
  
  SETUP_ADC_PORTS(NO_ANALOGS); 
  output_drive(LED);                                                          // LED Drive Pin = Output
  output_float(SW1);                                                          // SW1 Read Pin = Input
  output_low(LED);                                                            // Default LED = OFF  
  
  while(true)
  {   
    while(input(SW1));                                                        // Wait SW1 Press(Low)
    delay_ms(10);
    
    output_toggle(LED);                                                       // Toggle LED
    
    while(!input(SW1));                                                       // Wait SW1 Release(High)
    delay_ms(10);                                                                   
  }  
}

//Test RA2:LED
void test_led()
{
  //Defaul All GPIO = Input
  set_tris_a(0b11111111);                                                     // RA[7..0] = Input
  set_tris_b(0b11111111);                                                     // RB[7..0] = Input
  set_tris_c(0b11111111);                                                     // RC[7..0] = Input
  set_tris_d(0b11111111);                                                     // RD[7..0] = Input
  set_tris_e(0b11111111);                                                     // RE[2..0] = Input 
  output_drive(LED);                                                          //LED Drive Pin = Output
                        
  while(true)
  {     
    output_toggle(LED);                                                       // Toggle ON/OFF LED
    delay_ms(500);                  
  }  
}

//Test All GPIO
void test_gpio()
{
  unsigned char count;
  
  SETUP_ADC_PORTS(NO_ANALOGS); 
  set_tris_a(0b00000000);                                                     // RA[7..0]=Output
  set_tris_b(0b00000000);                                                     // RB[7..0]=Output
  set_tris_c(0b01000000);                                                     // RC[7,5..0]=Output
  set_tris_d(0b00000000);                                                     // RD[7..0]=Output
  set_tris_e(0b11111000);                                                     // RE[2..0]=Output
                        
  while(true)
  {    
    for(count = 0; count < 8; count++)                                        // 8 Bit LED 
    {    
      output_a(~TestPort_LED[count]);    
      output_b(~TestPort_LED[count]);
      output_c(~TestPort_LED[count]);
      output_d(~TestPort_LED[count]);
      output_e(~TestPort_LED[count]);
      delay_ms(500);                             
    }  
  }
}

//Test UART2(Software UART on RC0,RC1)
void test_uart2()
{
  char rx_buff;
  
  //Defaul All GPIO = Input
  set_tris_a(0b11111111);                                                     // RA[7..0] = Input
  set_tris_b(0b11111111);                                                     // RB[7..0] = Input
  set_tris_c(0b11111111);                                                     // RC[7..0] = Input
  set_tris_d(0b11111111);                                                     // RD[7..0] = Input
  set_tris_e(0b11111111);                                                     // RE[2..0] = Input 
  output_drive(TX2);
  output_float(RX2);
  
  #use rs232(baud=9600, xmit=TX2, rcv=RX2,stream=CH2)
  
  SETUP_ADC_PORTS(NO_ANALOGS); 
  output_drive(LED);                                                          // LED Drive Pin = Output
  output_float(SW1);                                                          // SW1 Read Pin = Input
  output_low(LED);                                                            // Default LED = OFF  
  delay_ms(500);                                                              //Power-On Delay
  
  //Wait SW1 Press Start Test UART2   
  while(input(SW1));                                                          // Wait SW1 Press(Low)
  delay_ms(10);
    
  //Start-Up UART2
  fprintf(CH2,"\n\n\n\r");
  fprintf(CH2,"===================================\n\r"); 
  fprintf(CH2," Test UART2 : Software UART\n\r"); 
  fprintf(CH2,"===================================\n\r");     
  fprintf(CH2,"UART2>");
  
  while(true)
  { 
    //Verify & Echo UART2
    if(kbhit(CH2))
    {
      rx_buff = fgetc(CH2);
      if (rx_buff == 0x0D)
      {
        fprintf(CH2,"\n\r");
        fprintf(CH2,"===================================\n\r"); 
        fprintf(CH2," Test UART2 : Software UART\n\r"); 
        fprintf(CH2,"===================================\n\r");     
        fprintf(CH2,"UART2>");
      }
      else 
      {
        fputc(rx_buff,CH2);                                                   // Echo Received Characters      
      }
    }  
  }  
}

