/* 
Main.c
Larry Knight
MainBrain32
Revision 1.7 2022
PIC32MX795F512L-80I/PF
PIC32MX695F512L-80I/PF
*/
//Required Headers
#include <xc.h>
#include <sys/attribs.h>
#include "sys/kmem.h"
#include <stdint.h>

//Application Headers
#include "ADC.h"
#include "Binary2ASCIIHex.h"
#include "Globals.h"
#include "HX8357B.h"
#include "LED_Port.h"
#include "PMP.h"
#include "REN70V05.h"
#include "RTC.h"
#include "Screens.h"
#include "Flash.h"
#include "Timers.h"
#include "Binary2ASCIIBCD.h"
#include "Delay.h"
#include "Strings.h"
#include "Interrupts.h"
#include "SplashImage.h"
#include "USB.h"

#pragma config FMIIEN = OFF             // Ethernet RMII/MII Enable (MII Enabled)
#pragma config FETHIO = OFF             // Ethernet I/O Pin Select (Default Ethernet I/O)
#pragma config FUSBIDIO = OFF           // USB USID Selection (Controlled by the USB Module)
#pragma config FVBUSONIO = OFF          // USB VBUS ON Selection (Controlled by USB Module)
#pragma config FNOSC = PRIPLL           // Oscillator Selection Bits 
#pragma config POSCMOD = EC             // Primary Oscillator Configuration
#pragma config FPLLIDIV = DIV_5         // PLL Input Divider
#pragma config FSOSCEN = ON             // Secondary Oscillator Enable (Disabled)
#pragma config FPLLMUL = MUL_20         // PLL Multiplier 
#pragma config FPLLODIV = DIV_1         // System PLL Output Clock Divider 
#pragma config FPBDIV = DIV_1           // Peripheral Clock Divisor 
#pragma config UPLLIDIV = DIV_5         // USB PLL Input Divider
#pragma config UPLLEN = ON              // USB PLL Enable (Enabled)
#pragma config IESO = OFF               // Internal/External Switch Over (Enabled)
#pragma config OSCIOFNC = ON            // CLKO Output Signal Active on the OSCO Pin 
#pragma config WDTPS = PS1              // Watchdog Timer Postscaler (1:1048576)
#pragma config FWDTEN = OFF             // Watchdog Timer Enable (WDT Disabled (SWDTEN Bit Controls))
#pragma config FCKSM = CSDCMD           // Clock Switching and Monitor Selection (Clock Switch Enable, FSCM Enabled)
#pragma config DEBUG = OFF              // Background Debugger
#pragma config FSRSSEL = PRIORITY_7     // All interrupt priorities are assigned to a shadow register set
#pragma config ICESEL = ICS_PGx1 

void USBInit(void);
void DisplayData(void);

void main()
{    
    //Wait for PLL Lock
    while(!OSCCONbits.SLOCK);
    
    SYSKEY = 0x0;               // ensure OSCCON is locked
    SYSKEY = 0xAA996655;        // Write Key1 to SYSKEY
    SYSKEY = 0x556699AA;        // Write Key2 to SYSKEY

    //enable secondary oscillator
    OSCCONbits.SOSCEN = 1;    
    //wait for warm up
    while(OSCCONbits.SOSCRDY == 0);
    
    //Data Memory SRAM wait states: Default Setting = 1; set it to 0
    BMXCONbits.BMXWSDRM = 0;

    //Flash PM Wait States: MX Flash runs at 2 wait states @ 80 MHz
    CHECONbits.PFMWS = 2;

    //Prefetch-cache: Enable prefetch for cacheable PFM instructions
    CHECONbits.PREFEN = 1;

    //Disable JTAG Port
    DDPCONbits.JTAGEN = 0;
    
    //Set the Core Timer compare value
    //10 interrupts per second
    CorTimer_Compare = 4800000;
    _CP0_SET_COMPARE(CorTimer_Compare);
    
    //Setup the GPO-2 pins as inputs
    //GP0
    TRISCbits.TRISC15 = 1;
    //GP1
    TRISAbits.TRISA15 = 1;
    //GP2
    TRISDbits.TRISD8 = 1;
    
    //Initialize the LED Data Port
    LED_Port_Init();

    //Beep speaker
    TRISDbits.TRISD14 = 0;
    int i;
    for(i=0;i<200;i++)
    {
        PORTDbits.RD14 = 0;
        Delay(20000);
        PORTDbits.RD14 = 1;
        Delay(20000);
    }

    //Initialize the Interrupts
    Interrupts_Init();

    //Initialize the Parallel Master Port
    PMP_Init();
    
    //Initialize the Dual Port SRAM
    REN70V05_Init();
    
    //Test SRAM
    memtest_70V05();
    
    //Initialize the ADC
    ADC_Init();
   
    //Initialize Timers
    Timer2_Init();
    Timer3_Init();
    Timer4_Init();
    Timer5_Init();
    
    //Initialize Flash Memory
    Flash_Init();

    //get number of used bytes
    unsigned d = PMADDR;
    Flash_Get_Bytes_Used();
    PMADDR = d;
    
    //Initialize the Display
    HX8357B_Init();            
    
    //control is with a P-channel MOSFET
    //so the higher the number, the dimmer
    //the screen
    Backlight_Control(5);
                
    //RTC_Init
    RTC_Init();
        
    //Clear the Core Timer
    _CP0_SET_COUNT(0);
        
    //Global Enable IUnterrupts
    __builtin_enable_interrupts();  
    
    //Clear the Screen
    HX8357B_CLRSCN(0xffff);
    
    //Turn on the Display
    HX8357B_DISPON();

//    //Load Splash Image
//    HX8357B_CASET(0, 479);
//    HX8357B_RASET(120, 170);
//    HX8357B_RAMWR();
//
//    //Data
//    //RF3 = D/C 1=Data, 0=Command
//    PORTFbits.RF3 = 1;                    
//    for(int i=0;i<=23040; i++)
//    {
//        PMDIN = ~SplashImage[i*2];
//        while(PMMODEbits.BUSY == 1);    
//    }

    //Select Display (/CS)    
    PORTFbits.RF13 = 0;
    
//    Speaker_Control(10000);
//    LongDelay(1);
//    Speaker_Control(0);
    
    //Show the splash screen for 5 seconds
    //LongDelay(5);
    //Home_Screen();
         //USB Init
    TRISFbits.TRISF8 = 0;
    //setup my pointer
//    pBDT = (uint32_t *)addr;

    USBInit();

//    BDT[0] = 0x400084;
//    while(BDT[0] != 0x080034);
//    BDT[4] = 0x1800c4;
////    while(BDT[4] = 0x180084);
//    BDT[6] = 0x430084;
            
       
    // USB_Screen();   
     //Oscillator_Screen();
    
    while(1)
    {
        DisplayData();

//******************************************************************************        
//DEFAULT STATE                                                                *
//******************************************************************************        
        if(USB_STATE == DEFAULT)
        {
            //turn off interrupts
            IEC1bits.USBIE = 0;
            
            //SETUP
            if(PID == 0x0d)
            {
                //GET_CONFIGURATION
                if(bRequest == 0x08)
                {
                    BDT[0].UOWN = 1;
                    //send the configuration descriptor
                    BDT[5].FULL_DWORD = ((uint32_t)&configDescriptor[0] & 0x1fffffff);
                    BDT[4].FULL_DWORD = 0x350040;
                    BDT[4].UOWN = 1;
                }
                
                //GET_DESCRPTOR
                if(bRequest == 0x06)
                {
                    BDT[2].UOWN = 1;
                    //send the device descriptor
                    BDT[5].FULL_DWORD = ((uint32_t)&device_dsc[0] & 0x1fffffff);
                    BDT[4].FULL_DWORD = 0x180000;
                    BDT[4].DATA0 = 1;
                    BDT[4].UOWN = 1;
                }

                //SET_ADDRESS
                if(bRequest == 0x05)
                {
                    BDT[0].UOWN = 1;
                    BDT[2].UOWN = 1;
                     //Send acknowledge
                    BDT[5].FULL_DWORD = ((uint32_t)&EP0_0_Buffer[0] & 0x1fffffff);
                    BDT[4].FULL_DWORD = 0x000004;
                    BDT[4].UOWN = 1;
                    
                    BDT[7].FULL_DWORD = ((uint32_t)&EP0_0_Buffer[0] & 0x1fffffff);
                    BDT[6].FULL_DWORD = 0x000004;
                    BDT[6].UOWN = 1;
                    
                    USB_STATE = ADDRESS;
                }
            }
            //enable packets
            U1CONbits.PKTDIS = 0;
            
            IEC1bits.USBIE = 1;
        }

//******************************************************************************
//ADDRESS STATE                                                                *
//******************************************************************************        
        if(USB_STATE == ADDRESS)
        {
            //U1ADDR = wValue;
//            BDT[2].UOWN = 1;
//            DisplayData();
        }
    }
}

void USBInit(void)
{
    USB_STATE = DETACHED;

    //Set BDT address Registers
    U1BDTP3 = (((uint32_t)KVA_TO_PA(addr)) >> 24); 
    U1BDTP2 = (((uint32_t)KVA_TO_PA(addr)) >> 16); 
    U1BDTP1 = (((uint32_t)KVA_TO_PA(addr)) >> 8);
    
    //USBDisableInterrupts();
    IEC1bits.USBIE = 0;

    //Clear USB error flags
    U1EIR = 0;
    //Clear USB interrupts
    U1IR = 0xffff;
    //Clear endpoint registers
    U1EP0 = 0;

    //turn on module
    U1PWRCbits.USBPWR = 1;
    
//  wait for bus to stabilize
//* After enabling the USB module, it takes some time for the
//* voltage on the D+ or D- line to rise high enough to get out
//* of the SE0 condition. The USB Reset interrupt should not be
//* unmasked until the SE0 condition is cleared. This helps
//* prevent the firmware from misinterpreting this unique event
//* as a USB bus reset from the USB host.
    while(U1CONbits.SE0);
   
    //clear reset interrupt
    U1IR = 0;
    
    //USB priority
    IPC11bits.USBIP = 7;
    IPC11bits.USBIS = 3;
    
    //enable interrupts
    IEC1bits.USBIE = 1;
    
    //USB Interrupt enables
    U1IEbits.URSTIE = 1;
    U1IEbits.UERRIE = 1;
    U1IEbits.SOFIE = 1;
    U1IEbits.TRNIE = 1;
    U1IEbits.IDLEIE = 1;
    U1IEbits.STALLIE = 1;

    //clear the reset interrupt flag
    U1IRbits.URSTIF = 1;

    //Setup EP0
    U1EP0bits.EPRXEN = 1;
    U1EP0bits.EPTXEN = 1;
    U1EP0bits.EPHSHK = 1;

    //Setup EP1
    U1EP1bits.EPRXEN = 1;
    U1EP1bits.EPTXEN = 0;
    U1EP1bits.EPHSHK = 0;
    
    //Setup EP2
    U1EP2bits.EPRXEN = 0;
    U1EP2bits.EPTXEN = 1;
    U1EP2bits.EPHSHK = 0;
    
    // Enable module & attach to bus
    while(!U1CONbits.USBEN)
    {
        U1CONbits.USBEN = 1;
    }

    U1OTGCONbits.DPPULUP = 1;
    U1OTGCONbits.OTGEN = 1;

    //Device is attached and ready to enumerate

}

//USB
void __ISR(45, IPL7SRS) USB_Srvc(void)
{
    if(U1IRbits.URSTIF)
    {
//        PORTCbits.RC4 = 1;
        ResetCount++;
        USB_STATE = DEFAULT;
        U1CONbits.PPBRST = 1;

        //EP0 OUT EVEN
        BDT[0].FULL_DWORD = 0x400004;
        BDT[1].FULL_DWORD = ((uint32_t)&EP0_0_Buffer[0] & 0x1fffffff);

        //EP0 OUT ODD
        BDT[2].FULL_DWORD = 0x400004;
        BDT[3].FULL_DWORD = ((uint32_t)&EP0_1_Buffer[0] & 0x1fffffff);

        //EP0 IN EVEN
        BDT[4].FULL_DWORD = 0x400004;
        BDT[5].FULL_DWORD = ((uint32_t)&EP0_2_Buffer[0] & 0x1fffffff);

        //EP0 IN ODD
        BDT[6].FULL_DWORD = 0x400004;
        BDT[7].FULL_DWORD = ((uint32_t)&EP0_3_Buffer[0] & 0x1fffffff);

        //Start the processing
        BDT[0].FULL_DWORD = 0x400084;
        
        U1CONbits.PPBRST = 0;
        
        U1IRbits.URSTIF = 1;
    }
    
    if(U1IRbits.UERRIF)
    {
//        PORTCbits.RC3 = 1;
        U1IRbits.UERRIF = 1;
    }
    
    if(U1IRbits.SOFIF)
    {
//        PORTCbits.RC2 = 1;
        U1IRbits.SOFIF = 1;
    }
      
    if(U1IRbits.TRNIF)
    {
//        PORTCbits.RC1 = 1;
        TRNIFCount++;
//        if(TRNIFCount == 1)
//        {
//            DisplayData();
//            while(1);
//        }
        
        PID = BDT[0].FULL_DWORD & 0x3f;
        PID = PID >> 2;
        //Get bmRequestType
        bmRequestType = EP0_0_Buffer[0];
        //get bRequest
        bRequest = EP0_0_Buffer[1];
        //Get wValue
        wValue = EP0_0_Buffer[2];
        
//        DebugPacketData();

        U1IRbits.TRNIF = 1;
    }
    
    if(U1IRbits.IDLEIF)
    {
//        PORTDbits.RD2 = 1;
//        BDT[4] = 0x1800c4;
        U1IRbits.IDLEIF = 1;
    }
    
    if(U1IRbits.STALLIF)
    {
//        PORTGbits.RG13 = 1;
        U1IRbits.STALLIF = 1;
    }
    
    IFS1bits.USBIF = 0;
}

void DebugPacketData(void)
{
    fore_color = 0;
    back_color = 0xffff;
        
    ///////////////////////////////////////////////
    //EP0 Even Out
    ///////////////////////////////////////////////
    //pBDT = pBDT + 100;
    
    for(i=0;i<=7;i++)
    {   
        Binary2ASCIIHex((uint8_t)EP0_0_Buffer[i]);
        WriteChar(hchar, vchar, d_hex[1], 0x203F);  
        WriteChar(hchar, vchar, d_hex[0], 0x203F);
        
        hchar = hchar + 10;
        
        if(hchar > 350)
        {
            hchar = 10;
            vchar = vchar + 20;
        }
    }
    
}

void DisplayData(void)
{
    fore_color = 0;
    back_color = 0xffff;
        
    //BDT base address
    hchar = 200;
    vchar = 10;
    WriteChar(hchar, vchar, 0x42, fore_color);    
    WriteChar(hchar, vchar, 0x44, fore_color);    
    WriteChar(hchar, vchar, 0x54, fore_color);    
    WriteChar(hchar, vchar, 0x3a, fore_color);
    
    Binary2ASCIIHex((uint32_t)&BDT[0]);
    WriteChar(hchar, vchar, d_hex[7], 0x203F);  
    WriteChar(hchar, vchar, d_hex[6], 0x203F);
    WriteChar(hchar, vchar, d_hex[5], 0x203F);  
    WriteChar(hchar, vchar, d_hex[4], 0x203F);
    WriteChar(hchar, vchar, d_hex[3], 0x203F);  
    WriteChar(hchar, vchar, d_hex[2], 0x203F);
    WriteChar(hchar, vchar, d_hex[1], 0x203F);  
    WriteChar(hchar, vchar, d_hex[0], 0x203F);

    //Base address registers
    hchar = 10;
    vchar = 10;
    WriteChar(hchar, vchar, 0x55, fore_color);    
    WriteChar(hchar, vchar, 0x31, fore_color);    
    WriteChar(hchar, vchar, 0x42, fore_color);    
    WriteChar(hchar, vchar, 0x44, fore_color);    
    WriteChar(hchar, vchar, 0x54, fore_color);    
    WriteChar(hchar, vchar, 0x50, fore_color);    
    WriteChar(hchar, vchar, 0x33, fore_color);    
    WriteChar(hchar, vchar, 0x3a, fore_color);  

    Binary2ASCIIHex(U1BDTP3);
    WriteChar(hchar, vchar, d_hex[1], 0x203F);  
    WriteChar(hchar, vchar, d_hex[0], 0x203F);

    hchar = 10;
    vchar = 30;
    WriteChar(hchar, vchar, 0x55, fore_color);    
    WriteChar(hchar, vchar, 0x31, fore_color);    
    WriteChar(hchar, vchar, 0x42, fore_color);    
    WriteChar(hchar, vchar, 0x44, fore_color);    
    WriteChar(hchar, vchar, 0x54, fore_color);    
    WriteChar(hchar, vchar, 0x50, fore_color);    
    WriteChar(hchar, vchar, 0x32, fore_color);    
    WriteChar(hchar, vchar, 0x3a, fore_color);  

    Binary2ASCIIHex(U1BDTP2);
    WriteChar(hchar, vchar, d_hex[1], 0x203F);  
    WriteChar(hchar, vchar, d_hex[0], 0x203F);

    hchar = hchar + 20;
    vchar = 30;
    WriteChar(hchar, vchar, 0x52, fore_color);    
    WriteChar(hchar, vchar, 0x65, fore_color);    
    WriteChar(hchar, vchar, 0x73, fore_color);    
    WriteChar(hchar, vchar, 0x65, fore_color);    
    WriteChar(hchar, vchar, 0x74, fore_color);    
    WriteChar(hchar, vchar, 0x73, fore_color);    
    WriteChar(hchar, vchar, 0x3a, fore_color);  

    Binary2ASCIIHex(TRNIFCount);
    WriteChar(hchar, vchar, d_hex[1], 0x203F);  
    WriteChar(hchar, vchar, d_hex[0], 0x203F);

    hchar = hchar + 20;
    vchar = 30;
    WriteChar(hchar, vchar, 0x54, fore_color);    
    WriteChar(hchar, vchar, 0x52, fore_color);    
    WriteChar(hchar, vchar, 0x4e, fore_color);    
    WriteChar(hchar, vchar, 0x49, fore_color);    
    WriteChar(hchar, vchar, 0x46, fore_color);    
    WriteChar(hchar, vchar, 0x73, fore_color);    
    WriteChar(hchar, vchar, 0x3a, fore_color);  

    Binary2ASCIIHex(ResetCount);
    WriteChar(hchar, vchar, d_hex[1], 0x203F);  
    WriteChar(hchar, vchar, d_hex[0], 0x203F);

    hchar = 10;
    vchar = 50;
    WriteChar(hchar, vchar, 0x55, fore_color);    
    WriteChar(hchar, vchar, 0x31, fore_color);    
    WriteChar(hchar, vchar, 0x42, fore_color);    
    WriteChar(hchar, vchar, 0x44, fore_color);    
    WriteChar(hchar, vchar, 0x54, fore_color);    
    WriteChar(hchar, vchar, 0x50, fore_color);    
    WriteChar(hchar, vchar, 0x31, fore_color);    
    WriteChar(hchar, vchar, 0x3a, fore_color);  

    Binary2ASCIIHex(U1BDTP1);
    WriteChar(hchar, vchar, d_hex[1], 0x203F);  
    WriteChar(hchar, vchar, d_hex[0], 0x203F);

    hchar = 10;
    vchar = 75;
    WriteChar(hchar, vchar, 0x55, fore_color);    
    WriteChar(hchar, vchar, 0x31, fore_color);    
    WriteChar(hchar, vchar, 0x49, fore_color);    
    WriteChar(hchar, vchar, 0x52, fore_color);    
    WriteChar(hchar, vchar, 0x3a, fore_color);  

    Binary2ASCIIHex(U1IR);
    WriteChar(hchar, vchar, d_hex[1], 0x203F);  
    WriteChar(hchar, vchar, d_hex[0], 0x203F);


    //Interrupt error register U1EIR
    hchar = 150;
    vchar = 75;

    WriteChar(hchar, vchar, 0x55, fore_color);    
    WriteChar(hchar, vchar, 0x31, fore_color);    
    WriteChar(hchar, vchar, 0x45, fore_color);    
    WriteChar(hchar, vchar, 0x49, fore_color);    
    WriteChar(hchar, vchar, 0x52, fore_color);    
    WriteChar(hchar, vchar, 0x3a, fore_color);  

    Binary2ASCIIHex(U1EIR);
    WriteChar(hchar, vchar, d_hex[1], 0x203F);  
    WriteChar(hchar, vchar, d_hex[0], 0x203F);

    //Status register U1STAT
    hchar = 300;
    vchar = 75;

    WriteChar(hchar, vchar, 0x55, fore_color);    
    WriteChar(hchar, vchar, 0x31, fore_color);    
    WriteChar(hchar, vchar, 0x53, fore_color);    
    WriteChar(hchar, vchar, 0x54, fore_color);    
    WriteChar(hchar, vchar, 0x41, fore_color);    
    WriteChar(hchar, vchar, 0x54, fore_color);    
    WriteChar(hchar, vchar, 0x3a, fore_color);  

    Binary2ASCIIHex(U1STAT);
    WriteChar(hchar, vchar, d_hex[1], 0x203F);  
    WriteChar(hchar, vchar, d_hex[0], 0x203F);

    //Address register U1ADDR
    hchar = 10;
    vchar = 100;

    WriteChar(hchar, vchar, 0x55, fore_color);    
    WriteChar(hchar, vchar, 0x31, fore_color);    
    WriteChar(hchar, vchar, 0x41, fore_color);    
    WriteChar(hchar, vchar, 0x44, fore_color);    
    WriteChar(hchar, vchar, 0x44, fore_color);    
    WriteChar(hchar, vchar, 0x52, fore_color);    
    WriteChar(hchar, vchar, 0x3a, fore_color);  

    Binary2ASCIIHex(U1ADDR);
    WriteChar(hchar, vchar, d_hex[1], 0x203F);  
    WriteChar(hchar, vchar, d_hex[0], 0x203F);
    
    //Address register U1ADDR
    hchar = 180;
    vchar = 100;

    WriteChar(hchar, vchar, 0x55, fore_color);    
    WriteChar(hchar, vchar, 0x31, fore_color);    
    WriteChar(hchar, vchar, 0x45, fore_color);    
    WriteChar(hchar, vchar, 0x50, fore_color);    
    WriteChar(hchar, vchar, 0x30, fore_color);    
    WriteChar(hchar, vchar, 0x3a, fore_color);  

    Binary2ASCIIHex(U1EP0);
    WriteChar(hchar, vchar, d_hex[1], 0x203F);  
    WriteChar(hchar, vchar, d_hex[0], 0x203F);
    
    //Address register U1ADDR
    hchar = 350;
    vchar = 100;

    WriteChar(hchar, vchar, 0x55, fore_color);    
    WriteChar(hchar, vchar, 0x31, fore_color);    
    WriteChar(hchar, vchar, 0x43, fore_color);    
    WriteChar(hchar, vchar, 0x4f, fore_color);    
    WriteChar(hchar, vchar, 0x4e, fore_color);    
    WriteChar(hchar, vchar, 0x3a, fore_color);  

    Binary2ASCIIHex(U1CON);
    WriteChar(hchar, vchar, d_hex[1], 0x203F);  
    WriteChar(hchar, vchar, d_hex[0], 0x203F);
    
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
    //EP0-0 OUT EVEN BD
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
    hchar = 10;
    vchar = 140;

    WriteChar(hchar, vchar, 0x45, fore_color);    
    WriteChar(hchar, vchar, 0x50, fore_color);    
    WriteChar(hchar, vchar, 0x30, fore_color);    
    WriteChar(hchar, vchar, 0x2d, fore_color);    
    WriteChar(hchar, vchar, 0x30, fore_color);    
    WriteChar(hchar, vchar, 0x3a, fore_color);  

    Binary2ASCIIHex(BDT[0].FULL_DWORD);
    WriteChar(hchar, vchar, d_hex[7], 0x203F);  
    WriteChar(hchar, vchar, d_hex[6], 0x203F);
    WriteChar(hchar, vchar, d_hex[5], 0x203F);  
    WriteChar(hchar, vchar, d_hex[4], 0x203F);
    WriteChar(hchar, vchar, d_hex[3], 0x203F);  
    WriteChar(hchar, vchar, d_hex[2], 0x203F);
    WriteChar(hchar, vchar, d_hex[1], 0x203F);  
    WriteChar(hchar, vchar, d_hex[0], 0x203F);
    
    hchar = hchar + 20;
    Binary2ASCIIHex(BDT[1].FULL_DWORD);
    WriteChar(hchar, vchar, d_hex[7], 0x203F);  
    WriteChar(hchar, vchar, d_hex[6], 0x203F);
    WriteChar(hchar, vchar, d_hex[5], 0x203F);  
    WriteChar(hchar, vchar, d_hex[4], 0x203F);
    WriteChar(hchar, vchar, d_hex[3], 0x203F);  
    WriteChar(hchar, vchar, d_hex[2], 0x203F);
    WriteChar(hchar, vchar, d_hex[1], 0x203F);  
    WriteChar(hchar, vchar, d_hex[0], 0x203F);

    //EP0-1 OUT ODD BD
    hchar = 10;
    vchar = 160;

    WriteChar(hchar, vchar, 0x45, fore_color);    
    WriteChar(hchar, vchar, 0x50, fore_color);    
    WriteChar(hchar, vchar, 0x30, fore_color);    
    WriteChar(hchar, vchar, 0x2d, fore_color);    
    WriteChar(hchar, vchar, 0x31, fore_color);    
    WriteChar(hchar, vchar, 0x3a, fore_color);  

    Binary2ASCIIHex(BDT[2].FULL_DWORD);
    WriteChar(hchar, vchar, d_hex[7], 0x203F);  
    WriteChar(hchar, vchar, d_hex[6], 0x203F);
    WriteChar(hchar, vchar, d_hex[5], 0x203F);  
    WriteChar(hchar, vchar, d_hex[4], 0x203F);
    WriteChar(hchar, vchar, d_hex[3], 0x203F);  
    WriteChar(hchar, vchar, d_hex[2], 0x203F);
    WriteChar(hchar, vchar, d_hex[1], 0x203F);  
    WriteChar(hchar, vchar, d_hex[0], 0x203F);

    hchar = hchar + 20;
    Binary2ASCIIHex(BDT[3].FULL_DWORD);
    WriteChar(hchar, vchar, d_hex[7], 0x203F);  
    WriteChar(hchar, vchar, d_hex[6], 0x203F);
    WriteChar(hchar, vchar, d_hex[5], 0x203F);  
    WriteChar(hchar, vchar, d_hex[4], 0x203F);
    WriteChar(hchar, vchar, d_hex[3], 0x203F);  
    WriteChar(hchar, vchar, d_hex[2], 0x203F);
    WriteChar(hchar, vchar, d_hex[1], 0x203F);  
    WriteChar(hchar, vchar, d_hex[0], 0x203F);

    //EP0-2 IN EVEN BD
    hchar = 10;
    vchar = 180;

    WriteChar(hchar, vchar, 0x45, fore_color);    
    WriteChar(hchar, vchar, 0x50, fore_color);    
    WriteChar(hchar, vchar, 0x30, fore_color);    
    WriteChar(hchar, vchar, 0x2d, fore_color);    
    WriteChar(hchar, vchar, 0x32, fore_color);    
    WriteChar(hchar, vchar, 0x3a, fore_color);  

    Binary2ASCIIHex(BDT[4].FULL_DWORD);
    WriteChar(hchar, vchar, d_hex[7], 0x203F);  
    WriteChar(hchar, vchar, d_hex[6], 0x203F);
    WriteChar(hchar, vchar, d_hex[5], 0x203F);  
    WriteChar(hchar, vchar, d_hex[4], 0x203F);
    WriteChar(hchar, vchar, d_hex[3], 0x203F);  
    WriteChar(hchar, vchar, d_hex[2], 0x203F);
    WriteChar(hchar, vchar, d_hex[1], 0x203F);  
    WriteChar(hchar, vchar, d_hex[0], 0x203F);

    hchar = hchar + 20;
    Binary2ASCIIHex(BDT[5].FULL_DWORD);
    WriteChar(hchar, vchar, d_hex[7], 0x203F);  
    WriteChar(hchar, vchar, d_hex[6], 0x203F);
    WriteChar(hchar, vchar, d_hex[5], 0x203F);  
    WriteChar(hchar, vchar, d_hex[4], 0x203F);
    WriteChar(hchar, vchar, d_hex[3], 0x203F);  
    WriteChar(hchar, vchar, d_hex[2], 0x203F);
    WriteChar(hchar, vchar, d_hex[1], 0x203F);  
    WriteChar(hchar, vchar, d_hex[0], 0x203F);

    //EP0-3 IN ODD BD
    hchar = 10;
    vchar = 200;

    WriteChar(hchar, vchar, 0x45, fore_color);    
    WriteChar(hchar, vchar, 0x50, fore_color);    
    WriteChar(hchar, vchar, 0x30, fore_color);    
    WriteChar(hchar, vchar, 0x2d, fore_color);    
    WriteChar(hchar, vchar, 0x33, fore_color);    
    WriteChar(hchar, vchar, 0x3a, fore_color);  

    Binary2ASCIIHex(BDT[6].FULL_DWORD);
    WriteChar(hchar, vchar, d_hex[7], 0x203F);  
    WriteChar(hchar, vchar, d_hex[6], 0x203F);
    WriteChar(hchar, vchar, d_hex[5], 0x203F);  
    WriteChar(hchar, vchar, d_hex[4], 0x203F);
    WriteChar(hchar, vchar, d_hex[3], 0x203F);  
    WriteChar(hchar, vchar, d_hex[2], 0x203F);
    WriteChar(hchar, vchar, d_hex[1], 0x203F);  
    WriteChar(hchar, vchar, d_hex[0], 0x203F);

    hchar = hchar + 20;
    Binary2ASCIIHex(BDT[7].FULL_DWORD);
    WriteChar(hchar, vchar, d_hex[7], 0x203F);  
    WriteChar(hchar, vchar, d_hex[6], 0x203F);
    WriteChar(hchar, vchar, d_hex[5], 0x203F);  
    WriteChar(hchar, vchar, d_hex[4], 0x203F);
    WriteChar(hchar, vchar, d_hex[3], 0x203F);  
    WriteChar(hchar, vchar, d_hex[2], 0x203F);
    WriteChar(hchar, vchar, d_hex[1], 0x203F);  
    WriteChar(hchar, vchar, d_hex[0], 0x203F);

    //EP0-0 Buffer
    hchar = 10;
    vchar = 230;

    ///////////////////////////////////////////////
    //EP0 Even Out
    ///////////////////////////////////////////////
    //pBDT = pBDT + 100;
    
    for(i=0;i<=7;i++)
    {   
        Binary2ASCIIHex((uint8_t)EP0_0_Buffer[i]);
        WriteChar(hchar, vchar, d_hex[1], 0x203F);  
        WriteChar(hchar, vchar, d_hex[0], 0x203F);
        
        hchar = hchar + 10;
        
        if(hchar > 350)
        {
            hchar = 10;
            vchar = vchar + 20;
        }
    }
    
    hchar = 10;
    vchar = 250;
    ///////////////////////////////////////////////
    //EP0 Odd Out
    ///////////////////////////////////////////////
    for(i=0;i<=7;i++)
    {   
        Binary2ASCIIHex((uint8_t)EP0_1_Buffer[i]);
        WriteChar(hchar, vchar, d_hex[1], 0x203F);  
        WriteChar(hchar, vchar, d_hex[0], 0x203F);
        
        hchar = hchar + 10;
        
        if(hchar > 350)
        {
            hchar = 10;
            vchar = vchar + 20;
        }
    }
    
    hchar = 10;
    vchar = 275;
    ///////////////////////////////////////////////
    //bRequest
    ///////////////////////////////////////////////
    WriteChar(hchar, vchar, 0x62, 0);  
    WriteChar(hchar, vchar, 0x52, 0);
    WriteChar(hchar, vchar, 0x65, 0);  
    WriteChar(hchar, vchar, 0x71, 0);  
    WriteChar(hchar, vchar, 0x3a, 0);
    
    Binary2ASCIIHex(bRequest);
    WriteChar(hchar, vchar, d_hex[1], 0x203F);  
    WriteChar(hchar, vchar, d_hex[0], 0x203F);
        
    hchar = hchar + 10;
    ///////////////////////////////////////////////
    //PID
    ///////////////////////////////////////////////
    WriteChar(hchar, vchar, 0x50, 0);  
    WriteChar(hchar, vchar, 0x49, 0);
    WriteChar(hchar, vchar, 0x44, 0);  
    WriteChar(hchar, vchar, 0x3a, 0);
    
    Binary2ASCIIHex((uint8_t)PID);
    WriteChar(hchar, vchar, d_hex[1], 0x203F);  
    WriteChar(hchar, vchar, d_hex[0], 0x203F);
    
    hchar = hchar + 10;
    ///////////////////////////////////////////////
    //wValue
    ///////////////////////////////////////////////
    WriteChar(hchar, vchar, 0x77, 0);  
    WriteChar(hchar, vchar, 0x56, 0);  
    WriteChar(hchar, vchar, 0x61, 0);  
    WriteChar(hchar, vchar, 0x6c, 0);  
    WriteChar(hchar, vchar, 0x75, 0);
    WriteChar(hchar, vchar, 0x65, 0);  
    WriteChar(hchar, vchar, 0x3a, 0);
    
    Binary2ASCIIHex((uint8_t)wValue);
    WriteChar(hchar, vchar, d_hex[1], 0x203F);  
    WriteChar(hchar, vchar, d_hex[0], 0x203F);

//    hchar = hchar + 10;
//    ///////////////////////////////////////////////
//    //dump
//    ///////////////////////////////////////////////
//    WriteChar(hchar, vchar, 0x64, 0);  
//    WriteChar(hchar, vchar, 0x75, 0);  
//    WriteChar(hchar, vchar, 0x6d, 0);
//    WriteChar(hchar, vchar, 0x70, 0);  
//    WriteChar(hchar, vchar, 0x3a, 0);
//    
//    Binary2ASCIIHex(addr);
//    WriteChar(hchar, vchar, d_hex[1], 0x203F);  
//    WriteChar(hchar, vchar, d_hex[0], 0x203F);
//
}