Thread: Converting a circulating mouse pointer to use a Potentionmeter

  1. #1
    Registered User
    Join Date
    Oct 2006
    Posts
    13

    Question Converting a circulating mouse pointer to use a Potentionmeter

    I've bought a Development tool from Microchip which allows me to program my own USB interfaces. The Development board (PICDEM FS USB) from microchip has a potentiometer on board and comes with a number of Firmwares

    I'm trying to integrate two pieces of code together so that i can get a mouse pointer to move from right to left using a potentiometer.
    The first piece of code contains a program which orders the mouse pointer to move in circles (Although i have already been integrating the Potentionmeter components from the other code) The second is a program which determines the potentiometer position / resistance where feedback is provided in the form of an on screen graphical user interface.

    I think i need to do something like do an A/D convert, then change the A/D result to a value between -127~127,for 10bit A/D using this formula to convert itA/D result)*256/1024-127.Then send this value to buffer[1] (The X Vector) in file user_mouse.c, and set buffer[2]=0.

    But i am not sure how to write this into my code, and the structure which it requires...

    This is the Mouse Code:-
    Code:
    /** I N C L U D E S **********************************************************/
    #include <p18cxxx.h>
    #include <usart.h>
    #include "system\typedefs.h"
    
    #include "system\usb\usb.h"
    
    #include "io_cfg.h"             // I/O pin mapping
    #include "user\user_mouse.h"
    
    /** V A R I A B L E S ********************************************************/
    #pragma udata  			// not sure what udata does???
    byte old_sw2,old_sw3;
    
    BOOL emulate_mode;
    rom signed char dir_table[]={-8,-8,-8, 0, 8, 8, 8, 0};
    byte movement_length;
    byte vector = 0;
    char buffer[3]; // buffer is a char buffer and is 3 in size
    
    /** P R I V A T E  P R O T O T Y P E S ***************************************/
    void BlinkUSBStatus(void);
    BOOL Switch2IsPressed(void);
    BOOL Switch3IsPressed(void); //function returns a Boolean value (1 or 0)
    void ReadPOT(void);
    void Emulate_Mouse(void);
    
    /** D E C L A R A T I O N S **************************************************/
    #pragma code
    void UserInit(void)
    {
        mInitAllLEDs();
        mInitAllSwitches();
        old_sw2 = sw2;
        old_sw3 = sw3;
    
        buffer[0]=0;
        buffer[1]=0;
        buffer[2]=0;
        buffer[3]=0;
        
        emulate_mode = TRUE;
    }//end UserInit
    
    /******************************************************************************
     * Function:        void ProcessIO(void)
     *
     * PreCondition:    None
     *
     * Input:           None
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This function is a place holder for other user routines.
     *                  It is a mixture of both USB and non-USB tasks.
     *
     * Note:            None
     *****************************************************************************/
    void ProcessIO(void)
    {   
        BlinkUSBStatus();
        // User Application USB tasks
        if((usb_device_state < CONFIGURED_STATE)||(UCONbits.SUSPND==1)) return;
    
        if(Switch3IsPressed())
            emulate_mode = !emulate_mode; //emulate_mode = Not emulate_mode
        
        Emulate_Mouse(); // if switch 3 is pressed on demo board it calls Emulate_Mouse Function prototyped below
        
    }//end ProcessIO
    
    void Emulate_Mouse(void) // void at beginning shows that function does not return a value
    {						 // void in brackets shows that function does not receive a value
    						 // Function Prototype
        if(emulate_mode == TRUE) // if emulate_mode has returned a value == to TRUE
        {						 // then do inside if statement
            if(movement_length > 14) // if movement_length > 14 do this statement
            {
                buffer[0] = 0; // 0 is put into buffer position 0
                //vector is a byte and is initiated to 0
    			buffer[1] = dir_table[vector & 0x07];           // X-Vector
    // takes value from a direction table, the position in the table is dictated by
    // the vector ANDED with hexadecimal 7 (This loops between positions 0 to 7)
                buffer[2] = dir_table[(vector+2) & 0x07];       // Y-Vector
    // for the Y direction 2 is added to the vector which means that when buffer pos 1 (X direction)is 
    // at dir_table value 7 buffer pos 2 is at dir_table value 1 (Y direction)     
    			vector++; // vector keeps incrementing (Isn't that dangerous ? when will it stop ?)
                movement_length = 0;
            }//end if(movement_length < 14)
        } // otherwise do this else statement
        else
            buffer[0] = buffer[1] = buffer[2] = 0; // set all buffers to zero
    
        if(!mHIDTxIsBusy()) // if transmit channel is not busy then do rest of if statement
        {
            HIDTxReport(buffer,3); // HIDTxReport takes two input arguments,
    		// The values in the buffer array and the byte length
            movement_length++; // increment movement_length (What is movement length?) is this a delay?
        }//end if(mHIDIsPutReportReady())
    }//end Emulate_Mouse
    
    void ReadPOT(void)
    {
        ADCON0bits.GO = 1;              // Start AD conversion
        while(ADCON0bits.NOT_DONE);     // Wait for conversion
        return;
    }//end ReadPOT
    /******************************************************************************
     * Function:        void BlinkUSBStatus(void)
     *
     * PreCondition:    None
     *
     * Input:           None
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        BlinkUSBStatus turns on and off LEDs corresponding to
     *                  the USB device state.
     *
     * Note:            mLED macros can be found in io_cfg.h
     *                  usb_device_state is declared in usbmmap.c and is modified
     *                  in usbdrv.c, usbctrltrf.c, and usb9.c
     *****************************************************************************/
    void BlinkUSBStatus(void)
    {
        static word led_count=0;
        
        if(led_count == 0)led_count = 10000U;
        led_count--;
    
        #define mLED_Both_Off()         {mLED_1_Off();mLED_2_Off();}
        #define mLED_Both_On()          {mLED_1_On();mLED_2_On();}
        #define mLED_Only_1_On()        {mLED_1_On();mLED_2_Off();}
        #define mLED_Only_2_On()        {mLED_1_Off();mLED_2_On();}
    
        if(UCONbits.SUSPND == 1)
        {
            if(led_count==0)
            {
                mLED_1_Toggle();
                mLED_2 = mLED_1;        // Both blink at the same time
            }//end if
        }
        else
        {
            if(usb_device_state == DETACHED_STATE)
            {
                mLED_Both_Off();
            }
            else if(usb_device_state == ATTACHED_STATE)
            {
                mLED_Both_On();
            }
            else if(usb_device_state == POWERED_STATE)
            {
                mLED_Only_1_On();
            }
            else if(usb_device_state == DEFAULT_STATE)
            {
                mLED_Only_2_On();
            }
            else if(usb_device_state == ADDRESS_STATE)
            {
                if(led_count == 0)
                {
                    mLED_1_Toggle();
                    mLED_2_Off();
                }//end if
            }
            else if(usb_device_state == CONFIGURED_STATE)
            {
                if(led_count==0)
                {
                    mLED_1_Toggle();
                    mLED_2 = !mLED_1;       // Alternate blink                
                }//end if
            }//end if(...)
        }//end if(UCONbits.SUSPND...)
    
    }//end BlinkUSBStatus
    
    BOOL Switch2IsPressed(void) // Function Returns a Boolean
    {
        if(sw2 != old_sw2) // if sw2 is not equal to old sw then do statement, ie if pressed.
        {
            old_sw2 = sw2;                  // Save new value
            if(sw2 == 0)                    // If pressed
                return TRUE;                // Was pressed
        }//end if
        return FALSE;                       // Was not pressed
    }//end Switch2IsPressed
    
    BOOL Switch3IsPressed(void) // Function Returns a Boolean
    {
        if(sw3 != old_sw3)
        {
            old_sw3 = sw3;                  // Save new value
            if(sw3 == 0)                    // If pressed
                return TRUE;                // Was pressed
        }//end if
        return FALSE;                       // Was not pressed
    }//end Switch3IsPressed
    
    /** EOF user_mouse.c *********************************************************/
    this is the Potentiometer Code etc...

    Code:
    /** I N C L U D E S **********************************************************/
    #include <p18cxxx.h>
    #include <usart.h>
    #include "system\typedefs.h"
    
    #include "system\usb\usb.h"
    
    #include "io_cfg.h"             // I/O pin mapping
    #include "user\user.h"
    #include "user\temperature.h"
    
    /** V A R I A B L E S ********************************************************/
    #pragma udata
    byte old_sw2,old_sw3;
    byte counter;
    byte trf_state;
    byte temp_mode;
    
    DATA_PACKET dataPacket;
    
    byte pTemp;                     // Pointer to current logging position, will
                                    // loop to zero once the max index is reached
    byte valid_temp;                // Keeps count of the valid data points
    word temp_data[30];             // 30 points of data
    
    // Timer0 - 1 second interval setup.
    // Fosc/4 = 12MHz
    // Use /256 prescalar, this brings counter freq down to 46,875 Hz
    // Timer0 should = 65536 - 46875 = 18661 or 0x48E5
    #define TIMER0L_VAL         0xE5
    #define TIMER0H_VAL         0x48
    
    /** P R I V A T E  P R O T O T Y P E S ***************************************/
    
    void BlinkUSBStatus(void);
    BOOL Switch2IsPressed(void);
    BOOL Switch3IsPressed(void);
    void ResetTempLog(void);
    void ReadPOT(void);
    void ServiceRequests(void);
    
    // For board testing purpose only
    void PICDEMFSUSBDemoBoardTest(void);
    
    /** D E C L A R A T I O N S **************************************************/
    #pragma code
    void UserInit(void)
    {
        mInitAllLEDs();
        mInitAllSwitches();
        old_sw2 = sw2;
        old_sw3 = sw3;
        
        InitTempSensor();
        mInitPOT();
        ADCON2bits.ADFM = 1;   // ADC result right justified
      
        ResetTempLog();
        temp_mode = TEMP_REAL_TIME;
        
        /* Init Timer0 for data logging interval (every 1 second) */
        T0CON = 0b10010111;
        //T0CONbits.T08BIT = 0;       // 16-bit mode
        //T0CONbits.T0CS = 0;         // Select Fosc/4
        //T0CONbits.PSA = 0;          // Assign prescalar (default is /256)
        /* Timer0 is already enabled by default */
    }//end UserInit
    
    
    /******************************************************************************
     * Function:        void ProcessIO(void)
     *
     * PreCondition:    None
     *
     * Input:           None
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This function is a place holder for other user routines.
     *                  It is a mixture of both USB and non-USB tasks.
     *
     * Note:            None
     *****************************************************************************/
    void ProcessIO(void)
    {   
        BlinkUSBStatus();
        // User Application USB tasks
        if((usb_device_state < CONFIGURED_STATE)||(UCONbits.SUSPND==1)) return;
        
        ServiceRequests();
    
        if(temp_mode == TEMP_LOGGING)
        {
            if(INTCONbits.TMR0IF == 1)
            {
                INTCONbits.TMR0IF = 0;          // Clear flag
                TMR0H = TIMER0H_VAL;
                TMR0L = TIMER0L_VAL;            // Reinit timer value;
    
                if(AcquireTemperature())
                {
                    temp_data[pTemp] = temperature._word;
                    
                    // First update valid_temp
                    if(valid_temp < 30)         // 30 data points max
                        valid_temp++;
                        
                    // Next update pTemp
                    if(pTemp == 29)
                        pTemp = 0;
                    else
                        pTemp++;
                }//end if
            }//end if
        }//end if
    }//end ProcessIO
    
    void ResetTempLog(void)
    {
        pTemp = 0;
        valid_temp = 0;
    }//end ResetLog
    
    void ReadPOT(void)
    {
        ADCON0bits.GO = 1;              // Start AD conversion
        while(ADCON0bits.NOT_DONE);     // Wait for conversion
        return;
    }//end ReadPOT
    
    void ServiceRequests(void)
    {
        byte index;
        
        if(USBGenRead((byte*)&dataPacket,sizeof(dataPacket)))
        {
            counter = 0;
            switch(dataPacket.CMD)
            {
                case READ_VERSION:
                    //dataPacket._byte[1] is len
                    dataPacket._byte[2] = MINOR_VERSION;
                    dataPacket._byte[3] = MAJOR_VERSION;
                    counter=0x04;
                    break;
    
                case ID_BOARD:
                    counter = 0x01;
                    if(dataPacket.ID == 0)
                    {
                        mLED_3_Off();mLED_4_Off();
                    }
                    else if(dataPacket.ID == 1)
                    {
                        mLED_3_Off();mLED_4_On();
                    }
                    else if(dataPacket.ID == 2)
                    {
                        mLED_3_On();mLED_4_Off();
                    }
                    else if(dataPacket.ID == 3)
                    {
                        mLED_3_On();mLED_4_On();
                    }
                    else
                        counter = 0x00;
                    break;
    
                case UPDATE_LED:
                    // LED1 & LED2 are used as USB event indicators.
                    if(dataPacket.led_num == 3)
                    {
                        mLED_3 = dataPacket.led_status;
                        counter = 0x01;
                    }//end if
                    else if(dataPacket.led_num == 4)
                    {
                        mLED_4 = dataPacket.led_status;
                        counter = 0x01;
                    }//end if else
                    break;
                    
                case SET_TEMP_REAL:
                    temp_mode = TEMP_REAL_TIME;
                    ResetTempLog();
                    counter = 0x01;
                    break;
    
                case RD_TEMP:
                    if(AcquireTemperature())
                    {
                        dataPacket.word_data = temperature._word;
                        counter=0x03;
                    }//end if
                    break;
    
                case SET_TEMP_LOGGING:
                    temp_mode = TEMP_LOGGING;
                    ResetTempLog();
                    counter=0x01;
                    break;
    
                case RD_TEMP_LOGGING:
                    counter = (valid_temp<<1)+2;  // Update count in byte
                    dataPacket.len = (valid_temp<<1);
    
                    for(index = valid_temp; index > 0; index--)
                    {
                        if(pTemp == 0)
                            pTemp = 29;
                        else
                            pTemp--;
                        dataPacket._word[index] = temp_data[pTemp];
                    }//end for
                    
                    ResetTempLog();             // Once read, log will restart
                    break;
    
                case RD_POT: // Comes from PC Software
                    ReadPOT();
                    dataPacket._byte[1] = ADRESL;
                    dataPacket._byte[2] = ADRESH;
                    counter=0x03;
                    break;
                    
                case RESET:
                    Reset();
                    break;
                    
                default:
                    break;
            }//end switch()
            if(counter != 0)
            {
                if(!mUSBGenTxIsBusy())
                    USBGenWrite((byte*)&dataPacket,counter);
            }//end if
        }//end if
    
    }//end ServiceRequests
    
    /******************************************************************************
     * Function:        void BlinkUSBStatus(void)
     *
     * PreCondition:    None
     *
     * Input:           None
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        BlinkUSBStatus turns on and off LEDs corresponding to
     *                  the USB device state.
     *
     * Note:            mLED macros can be found in io_cfg.h
     *                  usb_device_state is declared in usbmmap.c and is modified
     *                  in usbdrv.c, usbctrltrf.c, and usb9.c
     *****************************************************************************/
    void BlinkUSBStatus(void)
    {
        static word led_count=0;
        
        if(led_count == 0)led_count = 10000U;
        led_count--;
    
        #define mLED_Both_Off()         {mLED_1_Off();mLED_2_Off();}
        #define mLED_Both_On()          {mLED_1_On();mLED_2_On();}
        #define mLED_Only_1_On()        {mLED_1_On();mLED_2_Off();}
        #define mLED_Only_2_On()        {mLED_1_Off();mLED_2_On();}
    
        if(UCONbits.SUSPND == 1)
        {
            if(led_count==0)
            {
                mLED_1_Toggle();
                mLED_2 = mLED_1;        // Both blink at the same time
            }//end if
        }
        else
        {
            if(usb_device_state == DETACHED_STATE)
            {
                mLED_Both_Off();
                
                PICDEMFSUSBDemoBoardTest();
            }
            else if(usb_device_state == ATTACHED_STATE)
            {
                mLED_Both_On();
            }
            else if(usb_device_state == POWERED_STATE)
            {
                mLED_Only_1_On();
            }
            else if(usb_device_state == DEFAULT_STATE)
            {
                mLED_Only_2_On();
            }
            else if(usb_device_state == ADDRESS_STATE)
            {
                if(led_count == 0)
                {
                    mLED_1_Toggle();
                    mLED_2_Off();
                }//end if
            }
            else if(usb_device_state == CONFIGURED_STATE)
            {
                if(led_count==0)
                {
                    mLED_1_Toggle();
                    mLED_2 = !mLED_1;       // Alternate blink                
                }//end if
            }//end if(...)
        }//end if(UCONbits.SUSPND...)
    
    }//end BlinkUSBStatus
    
    BOOL Switch2IsPressed(void)
    {
        if(sw2 != old_sw2)
        {
            old_sw2 = sw2;                  // Save new value
            if(sw2 == 0)                    // If pressed
                return TRUE;                // Was pressed
        }//end if
        return FALSE;                       // Was not pressed
    }//end Switch2IsPressed
    
    BOOL Switch3IsPressed(void)
    {
        if(sw3 != old_sw3)
        {
            old_sw3 = sw3;                  // Save new value
            if(sw3 == 0)                    // If pressed
                return TRUE;                // Was pressed
        }//end if
        return FALSE;                       // Was not pressed
    }//end Switch3IsPressed
    
    void TXbyte(byte data)
    {
        while(TXSTAbits.TRMT==0);
        TXREG = data;
    }//end TXbyte
    
    void PICDEMFSUSBDemoBoardTest(void)
    {
        byte temp;
        
        //PICDEM FS USB Demo Board Test Procedure:
        if(Switch2IsPressed())
        {
            //LEDs and push buttons testing
            mLED_1_On();
            while(!Switch2IsPressed());
            mLED_1_Off();
            mLED_2_On();
            while(!Switch3IsPressed());
            mLED_2_Off();
            mLED_3_On();
            while(!Switch3IsPressed());
            mLED_3_Off();
            mLED_4_On();
            while(!Switch3IsPressed());
            mLED_4_Off();
            
            //RS-232 Setup
            SSPCON1 = 0;        // Make sure SPI is disabled
            TRISCbits.TRISC7=1; // RX
            TRISCbits.TRISC6=0; // TX
            SPBRG = 0x71;
            SPBRGH = 0x02;      // 0x0271 for 48MHz -> 19200 baud
            TXSTA = 0x24;       // TX enable BRGH=1
            RCSTA = 0x90;       // continuous RX
            BAUDCON = 0x08;     // BRG16 = 1
            temp = RCREG;       // Empty buffer
            temp = RCREG;       // Empty buffer
            
            //RS-232 Tx & Rx Tests
            while(!Switch3IsPressed());
            TXbyte('R');
            TXbyte('S');
            TXbyte('-');
            TXbyte('2');
            TXbyte('3');
            TXbyte('2');
            TXbyte(' ');
            TXbyte('T');
            TXbyte('X');
            TXbyte(' ');
            TXbyte('T');
            TXbyte('e');
            TXbyte('s');
            TXbyte('t');
            TXbyte(' ');
            TXbyte('O');
            TXbyte('K');
            TXbyte(',');
            TXbyte(' ');
            TXbyte('P');
            TXbyte('r');
            TXbyte('e');
            TXbyte('s');
            TXbyte('s');
            TXbyte(' ');
            TXbyte('"');
            TXbyte('r');
            TXbyte('"');
            TXbyte(',');
            while(PIR1bits.RCIF==0);        //Wait for data from RS232
            if(RCREG == 'r')
            {
                TXbyte(' ');
                TXbyte('R');
                TXbyte('X');
                TXbyte(' ');
                TXbyte('T');
                TXbyte('e');
                TXbyte('s');
                TXbyte('t');
                TXbyte(' ');
                TXbyte('O');
                TXbyte('K');
            }//end if
            UserInit();                     //Re-initialize default user fw
            //Test phase 1 done
        }//end if
    }//end PICDEMFSUSBDemoBoardTest()
    
    /** EOF user.c ***************************************************************/
    This is the Human Interface Device C File... which is in the mouse workspace

    Code:
    /** I N C L U D E S **********************************************************/
    #include <p18cxxx.h>
    #include "system\typedefs.h"
    #include "system\usb\usb.h"
    
    #ifdef USB_USE_HID
    
    /** V A R I A B L E S ********************************************************/
    #pragma udata
    byte idle_rate;
    byte active_protocol;               // [0] Boot Protocol [1] Report Protocol
    byte hid_rpt_rx_len;
    
    /** P R I V A T E  P R O T O T Y P E S ***************************************/
    void HIDGetReportHandler(void);
    void HIDSetReportHandler(void);
    
    /** D E C L A R A T I O N S **************************************************/
    #pragma code
    
    /** C L A S S  S P E C I F I C  R E Q ****************************************/
    /******************************************************************************
     * Function:        void USBCheckHIDRequest(void)
     *
     * PreCondition:    None
     *
     * Input:           None
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This routine checks the setup data packet to see if it
     *                  knows how to handle it
     *
     * Note:            None
     *****************************************************************************/
    void USBCheckHIDRequest(void)
    {
        if(SetupPkt.Recipient != RCPT_INTF) return;
        if(SetupPkt.bIntfID != HID_INTF_ID) return;
        
        /*
         * There are two standard requests that hid.c may support.
         * 1. GET_DSC(DSC_HID,DSC_RPT,DSC_PHY);
         * 2. SET_DSC(DSC_HID,DSC_RPT,DSC_PHY);
         */
        if(SetupPkt.bRequest == GET_DSC)
        {
            switch(SetupPkt.bDscType)
            {
                case DSC_HID:
                    ctrl_trf_session_owner = MUID_HID;
                    mUSBGetHIDDscAdr(pSrc.bRom);        // See usbcfg.h
                    wCount._word = sizeof(USB_HID_DSC);
                    break;
                case DSC_RPT:
                    ctrl_trf_session_owner = MUID_HID;
                    mUSBGetHIDRptDscAdr(pSrc.bRom);     // See usbcfg.h
                    mUSBGetHIDRptDscSize(wCount._word); // See usbcfg.h
                    break;
                case DSC_PHY:
                    // ctrl_trf_session_owner = MUID_HID;
                    break;
            }//end switch(SetupPkt.bDscType)
            usb_stat.ctrl_trf_mem = _ROM;
        }//end if(SetupPkt.bRequest == GET_DSC)
        
        if(SetupPkt.RequestType != CLASS) return;
        switch(SetupPkt.bRequest)
        {
            case GET_REPORT:
                HIDGetReportHandler();
                break;
            case SET_REPORT:
                HIDSetReportHandler();            
                break;
            case GET_IDLE:
                ctrl_trf_session_owner = MUID_HID;
                pSrc.bRam = (byte*)&idle_rate;      // Set source
                usb_stat.ctrl_trf_mem = _RAM;       // Set memory type
                LSB(wCount) = 1;                    // Set data count
                break;
            case SET_IDLE:
                ctrl_trf_session_owner = MUID_HID;
                idle_rate = MSB(SetupPkt.W_Value);
                break;
            case GET_PROTOCOL:
                ctrl_trf_session_owner = MUID_HID;
                pSrc.bRam = (byte*)&active_protocol;// Set source
                usb_stat.ctrl_trf_mem = _RAM;       // Set memory type
                LSB(wCount) = 1;                    // Set data count
                break;
            case SET_PROTOCOL:
                ctrl_trf_session_owner = MUID_HID;
                active_protocol = LSB(SetupPkt.W_Value);
                break;
        }//end switch(SetupPkt.bRequest)
    
    }//end USBCheckHIDRequest
    
    void HIDGetReportHandler(void)
    {
        // ctrl_trf_session_owner = MUID_HID;
    }//end HIDGetReportHandler
    
    void HIDSetReportHandler(void)
    {
        // ctrl_trf_session_owner = MUID_HID;
        // pDst.bRam = (byte*)&hid_report_out;
    }//end HIDSetReportHandler
    
    /** U S E R  A P I ***********************************************************/
    
    /******************************************************************************
     * Function:        void HIDInitEP(void)
     *
     * PreCondition:    None
     *
     * Input:           None
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        HIDInitEP initializes HID endpoints, buffer descriptors,
     *                  internal state-machine, and variables.
     *                  It should be called after the USB host has sent out a
     *                  SET_CONFIGURATION request.
     *                  See USBStdSetCfgHandler() in usb9.c for examples.
     *
     * Note:            None
     *****************************************************************************/
    void HIDInitEP(void)
    {   
        hid_rpt_rx_len =0;
        
        HID_UEP = EP_OUT_IN|HSHK_EN;                // Enable 2 data pipes
        
        HID_BD_OUT.Cnt = sizeof(hid_report_out);    // Set buffer size
        HID_BD_OUT.ADR = (byte*)&hid_report_out;    // Set buffer address
        HID_BD_OUT.Stat._byte = _USIE|_DAT0|_DTSEN; // Set status
    
        /*
         * Do not have to init Cnt of IN pipes here.
         * Reason:  Number of bytes to send to the host
         *          varies from one transaction to
         *          another. Cnt should equal the exact
         *          number of bytes to transmit for
         *          a given IN transaction.
         *          This number of bytes will only
         *          be known right before the data is
         *          sent.
         */
        HID_BD_IN.ADR = (byte*)&hid_report_in;      // Set buffer address
        HID_BD_IN.Stat._byte = _UCPU|_DAT1;         // Set status
    
    }//end HIDInitEP
    
    /******************************************************************************
     * Function:        void HIDTxReport(char *buffer, byte len)
     *
     * PreCondition:    mHIDTxIsBusy() must return false.
     *
     *                  Value of 'len' must be equal to or smaller than
     *                  HID_INT_IN_EP_SIZE
     *                  For an interrupt endpoint, the largest buffer size is
     *                  64 bytes.
     *
     * Input:           buffer  : Pointer to the starting location of data bytes
     *                  len     : Number of bytes to be transferred
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        Use this macro to transfer data located in data memory.
     *
     *                  Remember: mHIDTxIsBusy() must return false before user
     *                  can call this function.
     *                  Unexpected behavior will occur if this function is called
     *                  when mHIDTxIsBusy() == 0
     *
     *                  Typical Usage:
     *                  if(!mHIDTxIsBusy())
     *                      HIDTxReport(buffer, 3);
     *
     * Note:            None
     *****************************************************************************/
    void HIDTxReport(char *buffer, byte len)
    {
    	byte i;
    	
        /*
         * Value of len should be equal to or smaller than HID_INT_IN_EP_SIZE.
         * This check forces the value of len to meet the precondition.
         */
    	if(len > HID_INT_IN_EP_SIZE)
    	    len = HID_INT_IN_EP_SIZE;
    
       /*
        * Copy data from user's buffer to dual-ram buffer
        */
        for (i = 0; i < len; i++)
        	hid_report_in[i] = buffer[i];
    
        HID_BD_IN.Cnt = len;
        mUSBBufferReady(HID_BD_IN);
    
    }//end HIDTxReport
    
    /******************************************************************************
     * Function:        byte HIDRxReport(char *buffer, byte len)
     *
     * PreCondition:    Value of input argument 'len' should be smaller than the
     *                  maximum endpoint size responsible for receiving report
     *                  data from USB host for HID class.
     *                  Input argument 'buffer' should point to a buffer area that
     *                  is bigger or equal to the size specified by 'len'.
     *
     * Input:           buffer  : Pointer to where received bytes are to be stored
     *                  len     : The number of bytes expected.
     *
     * Output:          The number of bytes copied to buffer.
     *
     * Side Effects:    Publicly accessible variable hid_rpt_rx_len is updated
     *                  with the number of bytes copied to buffer.
     *                  Once HIDRxReport is called, subsequent retrieval of
     *                  hid_rpt_rx_len can be done by calling macro
     *                  mHIDGetRptRxLength().
     *
     * Overview:        HIDRxReport copies a string of bytes received through
     *                  USB HID OUT endpoint to a user's specified location. 
     *                  It is a non-blocking function. It does not wait
     *                  for data if there is no data available. Instead it returns
     *                  '0' to notify the caller that there is no data available.
     *
     * Note:            If the actual number of bytes received is larger than the
     *                  number of bytes expected (len), only the expected number
     *                  of bytes specified will be copied to buffer.
     *                  If the actual number of bytes received is smaller than the
     *                  number of bytes expected (len), only the actual number
     *                  of bytes received will be copied to buffer.
     *****************************************************************************/
    byte HIDRxReport(char *buffer, byte len)
    {
        hid_rpt_rx_len = 0;
        
        if(!mHIDRxIsBusy())
        {
            /*
             * Adjust the expected number of bytes to equal
             * the actual number of bytes received.
             */
            if(len > HID_BD_OUT.Cnt)
                len = HID_BD_OUT.Cnt;
            
            /*
             * Copy data from dual-ram buffer to user's buffer
             */
            for(hid_rpt_rx_len = 0; hid_rpt_rx_len < len; hid_rpt_rx_len++)
                buffer[hid_rpt_rx_len] = hid_report_out[hid_rpt_rx_len];
    
            /*
             * Prepare dual-ram buffer for next OUT transaction
             */
            HID_BD_OUT.Cnt = sizeof(hid_report_out);
            mUSBBufferReady(HID_BD_OUT);
        }//end if
        
        return hid_rpt_rx_len;
        
    }//end HIDRxReport
    
    #endif //def USB_USE_HID
    
    /** EOF hid.c ***************************************************************/
    and this is the generic.c file

    Code:
    /** I N C L U D E S **********************************************************/
    #include <p18cxxx.h>
    #include "system\typedefs.h"
    #include "system\usb\usb.h"
    
    #ifdef USB_USE_GEN
    
    /** V A R I A B L E S ********************************************************/
    #pragma udata
    byte usbgen_rx_len;
    
    /** P R I V A T E  P R O T O T Y P E S ***************************************/
    
    /** D E C L A R A T I O N S **************************************************/
    #pragma code
    
    /** U S E R  A P I ***********************************************************/
    
    /******************************************************************************
     * Function:        void USBGenInitEP(void)
     *
     * PreCondition:    None
     *
     * Input:           None
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        USBGenInitEP initializes generic endpoints, buffer
     *                  descriptors, internal state-machine, and variables.
     *                  It should be called after the USB host has sent out a
     *                  SET_CONFIGURATION request.
     *                  See USBStdSetCfgHandler() in usb9.c for examples.
     *
     * Note:            None
     *****************************************************************************/
    void USBGenInitEP(void)
    {   
        usbgen_rx_len = 0;
        
        USBGEN_UEP = EP_OUT_IN|HSHK_EN;             // Enable 2 data pipes
    
        /*
         * Do not have to init Cnt of IN pipes here.
         * Reason:  Number of bytes to send to the host
         *          varies from one transaction to
         *          another. Cnt should equal the exact
         *          number of bytes to transmit for
         *          a given IN transaction.
         *          This number of bytes will only
         *          be known right before the data is
         *          sent.
         */
        USBGEN_BD_OUT.Cnt = sizeof(usbgen_out);     // Set buffer size
        USBGEN_BD_OUT.ADR = (byte*)&usbgen_out;     // Set buffer address
        USBGEN_BD_OUT.Stat._byte = _USIE|_DAT0|_DTSEN;// Set status
    
        USBGEN_BD_IN.ADR = (byte*)&usbgen_in;      // Set buffer address
        USBGEN_BD_IN.Stat._byte = _UCPU|_DAT1;      // Set buffer status
    
    }//end USBGenInitEP
    
    /******************************************************************************
     * Function:        void USBGenWrite(byte *buffer, byte len)
     *
     * PreCondition:    mUSBGenTxIsBusy() must return false.
     *
     *                  Value of 'len' must be equal to or smaller than
     *                  USBGEN_EP_SIZE
     *                  For an interrupt/bulk endpoint, the largest buffer size is
     *                  64 bytes.
     *
     * Input:           buffer  : Pointer to the starting location of data bytes
     *                  len     : Number of bytes to be transferred
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        Use this macro to transfer data located in data memory.
     *
     *                  Remember: mUSBGenTxIsBusy() must return false before user
     *                  can call this function.
     *                  Unexpected behavior will occur if this function is called
     *                  when mUSBGenTxIsBusy() != 0
     *
     *                  Typical Usage:
     *                  if(!mUSBGenTxIsBusy())
     *                      USBGenWrite(buffer, 3);
     *
     * Note:            None
     *****************************************************************************/
    void USBGenWrite(byte *buffer, byte len)
    {
    	byte i;
    	
        /*
         * Value of len should be equal to or smaller than USBGEN_EP_SIZE.
         * This check forces the value of len to meet the precondition.
         */
    	if(len > USBGEN_EP_SIZE)
    	    len = USBGEN_EP_SIZE;
    
       /*
        * Copy data from user's buffer to dual-ram buffer
        */
        for (i = 0; i < len; i++)
        	usbgen_in[i] = buffer[i];
    
        USBGEN_BD_IN.Cnt = len;
        mUSBBufferReady(USBGEN_BD_IN);
    
    }//end USBGenWrite
    
    /******************************************************************************
     * Function:        byte USBGenRead(byte *buffer, byte len)
     *
     * PreCondition:    Value of input argument 'len' should be smaller than the
     *                  maximum endpoint size responsible for receiving report
     *                  data from USB host for HID class.
     *                  Input argument 'buffer' should point to a buffer area that
     *                  is bigger or equal to the size specified by 'len'.
     *
     * Input:           buffer  : Pointer to where received bytes are to be stored
     *                  len     : The number of bytes expected.
     *
     * Output:          The number of bytes copied to buffer.
     *
     * Side Effects:    Publicly accessible variable usbgen_rx_len is updated
     *                  with the number of bytes copied to buffer.
     *                  Once USBGenRead is called, subsequent retrieval of
     *                  usbgen_rx_len can be done by calling macro
     *                  mUSBGenGetRxLength().
     *
     * Overview:        USBGenRead copies a string of bytes received through
     *                  the OUT endpoint to a user's specified location. 
     *                  It is a non-blocking function. It does not wait
     *                  for data if there is no data available. Instead it returns
     *                  '0' to notify the caller that there is no data available.
     *
     * Note:            If the actual number of bytes received is larger than the
     *                  number of bytes expected (len), only the expected number
     *                  of bytes specified will be copied to buffer.
     *                  If the actual number of bytes received is smaller than the
     *                  number of bytes expected (len), only the actual number
     *                  of bytes received will be copied to buffer.
     *****************************************************************************/
    byte USBGenRead(byte *buffer, byte len)
    {
        usbgen_rx_len = 0;
        
        if(!mUSBGenRxIsBusy())
        {
            /*
             * Adjust the expected number of bytes to equal
             * the actual number of bytes received.
             */
            if(len > USBGEN_BD_OUT.Cnt)
                len = USBGEN_BD_OUT.Cnt;
            
            /*
             * Copy data from dual-ram buffer to user's buffer
             */
            for(usbgen_rx_len = 0; usbgen_rx_len < len; usbgen_rx_len++)
                buffer[usbgen_rx_len] = usbgen_out[usbgen_rx_len];
    
            /*
             * Prepare dual-ram buffer for next OUT transaction
             */
            USBGEN_BD_OUT.Cnt = sizeof(usbgen_out);
            mUSBBufferReady(USBGEN_BD_OUT);
        }//end if
        
        return usbgen_rx_len;
        
    }//end USBGenRead
    
    #endif //def USB_USE_GEN
    
    /** EOF usbgen.c *************************************************************/
    Any Help Much appreciated...

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Do you think you could ask a more focussed question rather than dumping several thousand lines of code on the message board?

    Like focus on one issue at once?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Oct 2006
    Posts
    13

    Question Focused Question 1

    ok - Sure, sorry about the long code, it was just to make sure everything was there...

    There's this bit of code here:-

    Code:
    void ReadPOT(void)
    {
        ADCON0bits.GO = 1;              // Start AD conversion
        while(ADCON0bits.NOT_DONE);     // Wait for conversion
        return;
    }//end ReadPOT
    which does a analogue to digital conversion and returns a value from a Potentiometer...

    and this bit of code here:-
    Code:
    buffer[1] = dir_table[vector & 0x07];           // X-Vector
    when a value is put into this buffer position it decides the X-Vector position of the mouse...

    How do i get the Analogue to Digital output to Drive this buffer value so that the mouse moves in the X direction?

    Thanks

  4. #4
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by phoenix23
    which does a analogue to digital conversion and returns a value from a Potentiometer...
    No it doesn't return a value, as you can see by the return that doesn't return a value. The A/D result is read after the idle wait.
    Code:
                case RD_POT: // Comes from PC Software
                    ReadPOT();
                    dataPacket._byte[1] = ADRESL;
                    dataPacket._byte[2] = ADRESH;
    You may want to look up some of this stuff in the manual.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  5. #5
    Registered User
    Join Date
    Oct 2006
    Posts
    13

    ADRESH and ADRESL

    Regarding this section of code, There is no manual which describes this firmware... However this is what it does

    Code:
     
    case RD_POT: // Comes from PC Software
                    ReadPOT();
                    dataPacket._byte[1] = ADRESL;
                    dataPacket._byte[2] = ADRESH;
                    counter=0x03;
                    break;
    This RD_POT value comes from the PC. When the PC software wants to get the A/D result, it will send out CMD RD_POT to USB device, the USB device will do the A/D convert and send the result back to PC.

    The .GO Member and .NOT_DONE member is defined in the header file "C:\mcc18\h\p18F4550.h"

    which i have included in the code below ( I have highlighted the where ADRESL and ADRESH occur )

    Code:
    /*-------------------------------------------------------------------------
     * $Id: p18f4550.h,v 1.7.12.1 2005/10/11 01:56:23 curtiss Exp $
     * MPLAB-Cxx  PIC18F4550 processor header
     *
     * (c) Copyright 1999-2005 Microchip Technology, All rights reserved
     *-------------------------------------------------------------------------*/
    
    #ifndef __18F4550_H
    #define __18F4550_H
    
    extern volatile near unsigned char       SPPDATA;
    extern          near unsigned char       SPPCFG;
    extern          near struct {
      unsigned WS0:1;
      unsigned WS1:1;
      unsigned WS2:1;
      unsigned WS3:1;
      unsigned CLK1EN:1;
      unsigned CSEN:1;
      unsigned CLKCFG0:1;
      unsigned CLKCFG1:1;
    } SPPCFGbits;
    extern          near unsigned char       SPPEPS;
    extern          near struct {
      unsigned ADDR0:1;
      unsigned ADDR1:1;
      unsigned ADDR2:1;
      unsigned ADDR3:1;
      unsigned SPPBUSY:1;
      unsigned :1;
      unsigned WRSPP:1;
      unsigned RDSPP:1;
    } SPPEPSbits;
    extern          near unsigned char       SPPCON;
    extern          near struct {
      unsigned SPPEN:1;
      unsigned SPPOWN:1;
    } SPPCONbits;
    extern volatile near unsigned            UFRM;
    extern volatile near unsigned char       UFRML;
    extern volatile near struct {
      unsigned FRM0:1;
      unsigned FRM1:1;
      unsigned FRM2:1;
      unsigned FRM3:1;
      unsigned FRM4:1;
      unsigned FRM5:1;
      unsigned FRM6:1;
      unsigned FRM7:1;
    } UFRMLbits;
    extern volatile near unsigned char       UFRMH;
    extern volatile near struct {
      unsigned FRM8:1;
      unsigned FRM9:1;
      unsigned FRM10:1;
    } UFRMHbits;
    extern volatile near unsigned char       UIR;
    extern volatile near struct {
      unsigned URSTIF:1;
      unsigned UERRIF:1;
      unsigned ACTVIF:1;
      unsigned TRNIF:1;
      unsigned IDLEIF:1;
      unsigned STALLIF:1;
      unsigned SOFIF:1;
    } UIRbits;
    extern volatile near unsigned char       UIE;
    extern volatile near struct {
      unsigned URSTIE:1;
      unsigned UERRIE:1;
      unsigned ACTVIE:1;
      unsigned TRNIE:1;
      unsigned IDLEIE:1;
      unsigned STALLIE:1;
      unsigned SOFIE:1;
    } UIEbits;
    extern volatile near unsigned char       UEIR;
    extern volatile near struct {
      unsigned PIDEF:1;
      unsigned CRC5EF:1;
      unsigned CRC16EF:1;
      unsigned DFN8EF:1;
      unsigned BTOEF:1;
      unsigned :2;
      unsigned BTSEF:1;
    } UEIRbits;
    extern volatile near unsigned char       UEIE;
    extern volatile near struct {
      unsigned PIDEE:1;
      unsigned CRC5EE:1;
      unsigned CRC16EE:1;
      unsigned DFN8EE:1;
      unsigned BTOEE:1;
      unsigned :2;
      unsigned BTSEE:1;
    } UEIEbits;
    extern volatile near unsigned char       USTAT;
    extern volatile near struct {
      unsigned :1;
      unsigned PPBI:1;
      unsigned DIR:1;
      unsigned ENDP0:1;
      unsigned ENDP1:1;
      unsigned ENDP2:1;
      unsigned ENDP3:1;
    } USTATbits;
    extern          near unsigned char       UCON;
    extern          near struct {
      unsigned :1;
      unsigned SUSPND:1;
      unsigned RESUME:1;
      unsigned USBEN:1;
      unsigned PKTDIS:1;
      unsigned SE0:1;
      unsigned PPBRST:1;
    } UCONbits;
    extern          near unsigned char       UADDR;
    extern          near struct {
      unsigned ADDR0:1;
      unsigned ADDR1:1;
      unsigned ADDR2:1;
      unsigned ADDR3:1;
      unsigned ADDR4:1;
      unsigned ADDR5:1;
      unsigned ADDR6:1;
    } UADDRbits;
    extern          near unsigned char       UCFG;
    extern          near struct {
      unsigned PPB0:1;
      unsigned PPB1:1;
      unsigned FSEN:1;
      unsigned UTRDIS:1;
      unsigned UPUEN:1;
      unsigned :1;
      unsigned UOEMON:1;
      unsigned UTEYE:1;
    } UCFGbits;
    extern          near unsigned char       UEP0;
    extern          near struct {
      unsigned EPSTALL:1;
      unsigned EPINEN:1;
      unsigned EPOUTEN:1;
      unsigned EPCONDIS:1;
      unsigned EPHSHK:1;
    } UEP0bits;
    extern          near unsigned char       UEP1;
    extern          near struct {
      unsigned EPSTALL:1;
      unsigned EPINEN:1;
      unsigned EPOUTEN:1;
      unsigned EPCONDIS:1;
      unsigned EPHSHK:1;
    } UEP1bits;
    extern          near unsigned char       UEP2;
    extern          near struct {
      unsigned EPSTALL:1;
      unsigned EPINEN:1;
      unsigned EPOUTEN:1;
      unsigned EPCONDIS:1;
      unsigned EPHSHK:1;
    } UEP2bits;
    extern          near unsigned char       UEP3;
    extern          near struct {
      unsigned EPSTALL:1;
      unsigned EPINEN:1;
      unsigned EPOUTEN:1;
      unsigned EPCONDIS:1;
      unsigned EPHSHK:1;
    } UEP3bits;
    extern          near unsigned char       UEP4;
    extern          near struct {
      unsigned EPSTALL:1;
      unsigned EPINEN:1;
      unsigned EPOUTEN:1;
      unsigned EPCONDIS:1;
      unsigned EPHSHK:1;
    } UEP4bits;
    extern          near unsigned char       UEP5;
    extern          near struct {
      unsigned EPSTALL:1;
      unsigned EPINEN:1;
      unsigned EPOUTEN:1;
      unsigned EPCONDIS:1;
      unsigned EPHSHK:1;
    } UEP5bits;
    extern          near unsigned char       UEP6;
    extern          near struct {
      unsigned EPSTALL:1;
      unsigned EPINEN:1;
      unsigned EPOUTEN:1;
      unsigned EPCONDIS:1;
      unsigned EPHSHK:1;
    } UEP6bits;
    extern          near unsigned char       UEP7;
    extern          near struct {
      unsigned EPSTALL:1;
      unsigned EPINEN:1;
      unsigned EPOUTEN:1;
      unsigned EPCONDIS:1;
      unsigned EPHSHK:1;
    } UEP7bits;
    extern          near unsigned char       UEP8;
    extern          near struct {
      unsigned EPSTALL:1;
      unsigned EPINEN:1;
      unsigned EPOUTEN:1;
      unsigned EPCONDIS:1;
      unsigned EPHSHK:1;
    } UEP8bits;
    extern          near unsigned char       UEP9;
    extern          near struct {
      unsigned EPSTALL:1;
      unsigned EPINEN:1;
      unsigned EPOUTEN:1;
      unsigned EPCONDIS:1;
      unsigned EPHSHK:1;
    } UEP9bits;
    extern          near unsigned char       UEP10;
    extern          near struct {
      unsigned EPSTALL:1;
      unsigned EPINEN:1;
      unsigned EPOUTEN:1;
      unsigned EPCONDIS:1;
      unsigned EPHSHK:1;
    } UEP10bits;
    extern          near unsigned char       UEP11;
    extern          near struct {
      unsigned EPSTALL:1;
      unsigned EPINEN:1;
      unsigned EPOUTEN:1;
      unsigned EPCONDIS:1;
      unsigned EPHSHK:1;
    } UEP11bits;
    extern          near unsigned char       UEP12;
    extern          near struct {
      unsigned EPSTALL:1;
      unsigned EPINEN:1;
      unsigned EPOUTEN:1;
      unsigned EPCONDIS:1;
      unsigned EPHSHK:1;
    } UEP12bits;
    extern          near unsigned char       UEP13;
    extern          near struct {
      unsigned EPSTALL:1;
      unsigned EPINEN:1;
      unsigned EPOUTEN:1;
      unsigned EPCONDIS:1;
      unsigned EPHSHK:1;
    } UEP13bits;
    extern          near unsigned char       UEP14;
    extern          near struct {
      unsigned EPSTALL:1;
      unsigned EPINEN:1;
      unsigned EPOUTEN:1;
      unsigned EPCONDIS:1;
      unsigned EPHSHK:1;
    } UEP14bits;
    extern          near unsigned char       UEP15;
    extern          near struct {
      unsigned EPSTALL:1;
      unsigned EPINEN:1;
      unsigned EPOUTEN:1;
      unsigned EPCONDIS:1;
      unsigned EPHSHK:1;
    } UEP15bits;
    extern volatile near unsigned char       PORTA;
    extern volatile near union {
      struct {
        unsigned RA0:1;
        unsigned RA1:1;
        unsigned RA2:1;
        unsigned RA3:1;
        unsigned RA4:1;
        unsigned RA5:1;
        unsigned RA6:1;
      };
      struct {
        unsigned AN0:1;
        unsigned AN1:1;
        unsigned AN2:1;
        unsigned AN3:1;
        unsigned T0CKI:1;
        unsigned AN4:1;
        unsigned OSC2:1;
      };
      struct {
        unsigned :2;
        unsigned VREFM:1;
        unsigned VREFP:1;
        unsigned :1;
        unsigned LVDIN:1;
      };
      struct {
        unsigned :5;
        unsigned HLVDIN:1;
      };
    } PORTAbits;
    extern volatile near unsigned char       PORTB;
    extern volatile near union {
      struct {
        unsigned RB0:1;
        unsigned RB1:1;
        unsigned RB2:1;
        unsigned RB3:1;
        unsigned RB4:1;
        unsigned RB5:1;
        unsigned RB6:1;
        unsigned RB7:1;
      };
      struct {
        unsigned INT0:1;
        unsigned INT1:1;
        unsigned INT2:1;
      };
      struct {
        unsigned :5;
        unsigned PGM:1;
        unsigned PGC:1;
        unsigned PGD:1;
      };
    } PORTBbits;
    extern volatile near unsigned char       PORTC;
    extern volatile near union {
      struct {
        unsigned RC0:1;
        unsigned RC1:1;
        unsigned RC2:1;
        unsigned :1;
        unsigned RC4:1;
        unsigned RC5:1;
        unsigned RC6:1;
        unsigned RC7:1;
      };
      struct {
        unsigned T1OSO:1;
        unsigned T1OSI:1;
        unsigned CCP1:1;
        unsigned :3;
        unsigned TX:1;
        unsigned RX:1;
      };
      struct {
        unsigned T13CKI:1;
        unsigned :1;
        unsigned P1A:1;
        unsigned :3;
        unsigned CK:1;
        unsigned DT:1;
      };
    } PORTCbits;
    extern volatile near unsigned char       PORTD;
    extern volatile near union {
      struct {
        unsigned RD0:1;
        unsigned RD1:1;
        unsigned RD2:1;
        unsigned RD3:1;
        unsigned RD4:1;
        unsigned RD5:1;
        unsigned RD6:1;
        unsigned RD7:1;
      };
      struct {
        unsigned SPP0:1;
        unsigned SPP1:1;
        unsigned SPP2:1;
        unsigned SPP3:1;
        unsigned SPP4:1;
        unsigned SPP5:1;
        unsigned SPP6:1;
        unsigned SPP7:1;
      };
    } PORTDbits;
    extern volatile near unsigned char       PORTE;
    extern volatile near union {
      struct {
        unsigned RE0:1;
        unsigned RE1:1;
        unsigned RE2:1;
        unsigned RE3:1;
        unsigned :3;
        unsigned RDPU:1;
      };
      struct {
        unsigned CK1SPP:1;
        unsigned CK2SPP:1;
        unsigned OESPP:1;
      };
    } PORTEbits;
    extern volatile near unsigned char       LATA;
    extern volatile near struct {
      unsigned LATA0:1;
      unsigned LATA1:1;
      unsigned LATA2:1;
      unsigned LATA3:1;
      unsigned LATA4:1;
      unsigned LATA5:1;
      unsigned LATA6:1;
    } LATAbits;
    extern volatile near unsigned char       LATB;
    extern volatile near struct {
      unsigned LATB0:1;
      unsigned LATB1:1;
      unsigned LATB2:1;
      unsigned LATB3:1;
      unsigned LATB4:1;
      unsigned LATB5:1;
      unsigned LATB6:1;
      unsigned LATB7:1;
    } LATBbits;
    extern volatile near unsigned char       LATC;
    extern volatile near struct {
      unsigned LATC0:1;
      unsigned LATC1:1;
      unsigned LATC2:1;
      unsigned :3;
      unsigned LATC6:1;
      unsigned LATC7:1;
    } LATCbits;
    extern volatile near unsigned char       LATD;
    extern volatile near struct {
      unsigned LATD0:1;
      unsigned LATD1:1;
      unsigned LATD2:1;
      unsigned LATD3:1;
      unsigned LATD4:1;
      unsigned LATD5:1;
      unsigned LATD6:1;
      unsigned LATD7:1;
    } LATDbits;
    extern volatile near unsigned char       LATE;
    extern volatile near struct {
      unsigned LATE0:1;
      unsigned LATE1:1;
      unsigned LATE2:1;
    } LATEbits;
    extern volatile near unsigned char       DDRA;
    extern volatile near struct {
      unsigned RA0:1;
      unsigned RA1:1;
      unsigned RA2:1;
      unsigned RA3:1;
      unsigned RA4:1;
      unsigned RA5:1;
      unsigned RA6:1;
    } DDRAbits;
    extern volatile near unsigned char       TRISA;
    extern volatile near struct {
      unsigned TRISA0:1;
      unsigned TRISA1:1;
      unsigned TRISA2:1;
      unsigned TRISA3:1;
      unsigned TRISA4:1;
      unsigned TRISA5:1;
      unsigned TRISA6:1;
    } TRISAbits;
    extern volatile near unsigned char       DDRB;
    extern volatile near struct {
      unsigned RB0:1;
      unsigned RB1:1;
      unsigned RB2:1;
      unsigned RB3:1;
      unsigned RB4:1;
      unsigned RB5:1;
      unsigned RB6:1;
      unsigned RB7:1;
    } DDRBbits;
    extern volatile near unsigned char       TRISB;
    extern volatile near struct {
      unsigned TRISB0:1;
      unsigned TRISB1:1;
      unsigned TRISB2:1;
      unsigned TRISB3:1;
      unsigned TRISB4:1;
      unsigned TRISB5:1;
      unsigned TRISB6:1;
      unsigned TRISB7:1;
    } TRISBbits;
    extern volatile near unsigned char       DDRC;
    extern volatile near struct {
      unsigned RC0:1;
      unsigned RC1:1;
      unsigned RC2:1;
      unsigned :3;
      unsigned RC6:1;
      unsigned RC7:1;
    } DDRCbits;
    extern volatile near unsigned char       TRISC;
    extern volatile near struct {
      unsigned TRISC0:1;
      unsigned TRISC1:1;
      unsigned TRISC2:1;
      unsigned :3;
      unsigned TRISC6:1;
      unsigned TRISC7:1;
    } TRISCbits;
    extern volatile near unsigned char       DDRD;
    extern volatile near struct {
      unsigned RD0:1;
      unsigned RD1:1;
      unsigned RD2:1;
      unsigned RD3:1;
      unsigned RD4:1;
      unsigned RD5:1;
      unsigned RD6:1;
      unsigned RD7:1;
    } DDRDbits;
    extern volatile near unsigned char       TRISD;
    extern volatile near struct {
      unsigned TRISD0:1;
      unsigned TRISD1:1;
      unsigned TRISD2:1;
      unsigned TRISD3:1;
      unsigned TRISD4:1;
      unsigned TRISD5:1;
      unsigned TRISD6:1;
      unsigned TRISD7:1;
    } TRISDbits;
    extern volatile near unsigned char       DDRE;
    extern volatile near struct {
      unsigned RE0:1;
      unsigned RE1:1;
      unsigned RE2:1;
    } DDREbits;
    extern volatile near unsigned char       TRISE;
    extern volatile near struct {
      unsigned TRISE0:1;
      unsigned TRISE1:1;
      unsigned TRISE2:1;
    } TRISEbits;
    extern volatile near unsigned char       OSCTUNE;
    extern volatile near struct {
      unsigned TUN0:1;
      unsigned TUN1:1;
      unsigned TUN2:1;
      unsigned TUN3:1;
      unsigned TUN4:1;
      unsigned :2;
      unsigned INTSRC:1;
    } OSCTUNEbits;
    extern volatile near unsigned char       PIE1;
    extern volatile near struct {
      unsigned TMR1IE:1;
      unsigned TMR2IE:1;
      unsigned CCP1IE:1;
      unsigned SSPIE:1;
      unsigned TXIE:1;
      unsigned RCIE:1;
      unsigned ADIE:1;
      unsigned SPPIE:1;
    } PIE1bits;
    extern volatile near unsigned char       PIR1;
    extern volatile near struct {
      unsigned TMR1IF:1;
      unsigned TMR2IF:1;
      unsigned CCP1IF:1;
      unsigned SSPIF:1;
      unsigned TXIF:1;
      unsigned RCIF:1;
      unsigned ADIF:1;
      unsigned SPPIF:1;
    } PIR1bits;
    extern volatile near unsigned char       IPR1;
    extern volatile near struct {
      unsigned TMR1IP:1;
      unsigned TMR2IP:1;
      unsigned CCP1IP:1;
      unsigned SSPIP:1;
      unsigned TXIP:1;
      unsigned RCIP:1;
      unsigned ADIP:1;
      unsigned SPPIP:1;
    } IPR1bits;
    extern volatile near unsigned char       PIE2;
    extern volatile near union {
      struct {
        unsigned CCP2IE:1;
        unsigned TMR3IE:1;
        unsigned LVDIE:1;
        unsigned BCLIE:1;
        unsigned EEIE:1;
        unsigned USBIE:1;
        unsigned CMIE:1;
        unsigned OSCFIE:1;
      };
      struct {
        unsigned :2;
        unsigned HLVDIE:1;
      };
    } PIE2bits;
    extern volatile near unsigned char       PIR2;
    extern volatile near union {
      struct {
        unsigned CCP2IF:1;
        unsigned TMR3IF:1;
        unsigned LVDIF:1;
        unsigned BCLIF:1;
        unsigned EEIF:1;
        unsigned USBIF:1;
        unsigned CMIF:1;
        unsigned OSCFIF:1;
      };
      struct {
        unsigned :2;
        unsigned HLVDIF:1;
      };
    } PIR2bits;
    extern volatile near unsigned char       IPR2;
    extern volatile near union {
      struct {
        unsigned CCP2IP:1;
        unsigned TMR3IP:1;
        unsigned LVDIP:1;
        unsigned BCLIP:1;
        unsigned EEIP:1;
        unsigned USBIP:1;
        unsigned CMIP:1;
        unsigned OSCFIP:1;
      };
      struct {
        unsigned :2;
        unsigned HLVDIP:1;
      };
    } IPR2bits;
    extern volatile near unsigned char       EECON1;
    extern volatile near struct {
      unsigned RD:1;
      unsigned WR:1;
      unsigned WREN:1;
      unsigned WRERR:1;
      unsigned FREE:1;
      unsigned :1;
      unsigned CFGS:1;
      unsigned EEPGD:1;
    } EECON1bits;
    extern volatile near unsigned char       EECON2;
    extern volatile near unsigned char       EEDATA;
    extern volatile near unsigned char       EEADR;
    extern volatile near unsigned char       RCSTA;
    extern volatile near union {
      struct {
        unsigned RX9D:1;
        unsigned OERR:1;
        unsigned FERR:1;
        unsigned ADDEN:1;
        unsigned CREN:1;
        unsigned SREN:1;
        unsigned RX9:1;
        unsigned SPEN:1;
      };
      struct {
        unsigned :3;
        unsigned ADEN:1;
      };
    } RCSTAbits;
    extern volatile near unsigned char       TXSTA;
    extern volatile near struct {
      unsigned TX9D:1;
      unsigned TRMT:1;
      unsigned BRGH:1;
      unsigned SENDB:1;
      unsigned SYNC:1;
      unsigned TXEN:1;
      unsigned TX9:1;
      unsigned CSRC:1;
    } TXSTAbits;
    extern volatile near unsigned char       TXREG;
    extern volatile near unsigned char       RCREG;
    extern volatile near unsigned char       SPBRG;
    extern volatile near unsigned char       SPBRGH;
    extern volatile near unsigned char       T3CON;
    extern volatile near union {
      struct {
        unsigned TMR3ON:1;
        unsigned TMR3CS:1;
        unsigned T3SYNC:1;
        unsigned T3CCP1:1;
        unsigned T3CKPS0:1;
        unsigned T3CKPS1:1;
        unsigned T3CCP2:1;
        unsigned RD16:1;
      };
      struct {
        unsigned :2;
        unsigned T3NSYNC:1;
      };
      struct {
        unsigned :2;
        unsigned NOT_T3SYNC:1;
      };
    } T3CONbits;
    extern volatile near unsigned char       TMR3L;
    extern volatile near unsigned char       TMR3H;
    extern volatile near unsigned char       CMCON;
    extern volatile near struct {
      unsigned CM0:1;
      unsigned CM1:1;
      unsigned CM2:1;
      unsigned CIS:1;
      unsigned C1INV:1;
      unsigned C2INV:1;
      unsigned C1OUT:1;
      unsigned C2OUT:1;
    } CMCONbits;
    extern volatile near unsigned char       CVRCON;
    extern volatile near union {
      struct {
        unsigned CVR0:1;
        unsigned CVR1:1;
        unsigned CVR2:1;
        unsigned CVR3:1;
        unsigned CVREF:1;
        unsigned CVRR:1;
        unsigned CVROE:1;
        unsigned CVREN:1;
      };
      struct {
        unsigned :4;
        unsigned CVRSS:1;
      };
    } CVRCONbits;
    extern volatile near unsigned char       CCP1AS;
    extern volatile near struct {
      unsigned PSSBD0:1;
      unsigned PSSBD1:1;
      unsigned PSSAC0:1;
      unsigned PSSAC1:1;
      unsigned ECCPAS0:1;
      unsigned ECCPAS1:1;
      unsigned ECCPAS2:1;
      unsigned ECCPASE:1;
    } CCP1ASbits;
    extern volatile near unsigned char       ECCP1AS;
    extern volatile near struct {
      unsigned PSSBD0:1;
      unsigned PSSBD1:1;
      unsigned PSSAC0:1;
      unsigned PSSAC1:1;
      unsigned ECCPAS0:1;
      unsigned ECCPAS1:1;
      unsigned ECCPAS2:1;
      unsigned ECCPASE:1;
    } ECCP1ASbits;
    extern volatile near unsigned char       CCP1DEL;
    extern volatile near struct {
      unsigned PDC0:1;
      unsigned PDC1:1;
      unsigned PDC2:1;
      unsigned PDC3:1;
      unsigned PDC4:1;
      unsigned PDC5:1;
      unsigned PDC6:1;
      unsigned PRSEN:1;
    } CCP1DELbits;
    extern volatile near unsigned char       ECCP1DEL;
    extern volatile near struct {
      unsigned PDC0:1;
      unsigned PDC1:1;
      unsigned PDC2:1;
      unsigned PDC3:1;
      unsigned PDC4:1;
      unsigned PDC5:1;
      unsigned PDC6:1;
      unsigned PRSEN:1;
    } ECCP1DELbits;
    extern volatile near unsigned char       BAUDCON;
    extern volatile near union {
      struct {
        unsigned ABDEN:1;
        unsigned WUE:1;
        unsigned :1;
        unsigned BRG16:1;
        unsigned SCKP:1;
        unsigned :1;
        unsigned RCIDL:1;
        unsigned ABDOVF:1;
      };
      struct {
        unsigned :6;
        unsigned RCMT:1;
      };
    } BAUDCONbits;
    extern volatile near unsigned char       CCP2CON;
    extern volatile near struct {
      unsigned CCP2M0:1;
      unsigned CCP2M1:1;
      unsigned CCP2M2:1;
      unsigned CCP2M3:1;
      unsigned DC2B0:1;
      unsigned DC2B1:1;
    } CCP2CONbits;
    extern volatile near unsigned            CCPR2;
    extern volatile near unsigned char       CCPR2L;
    extern volatile near unsigned char       CCPR2H;
    extern volatile near unsigned char       CCP1CON;
    extern volatile near struct {
      unsigned CCP1M0:1;
      unsigned CCP1M1:1;
      unsigned CCP1M2:1;
      unsigned CCP1M3:1;
      unsigned DC1B0:1;
      unsigned DC1B1:1;
      unsigned P1M0:1;
      unsigned P1M1:1;
    } CCP1CONbits;
    extern volatile near unsigned char       ECCP1CON;
    extern volatile near struct {
      unsigned CCP1M0:1;
      unsigned CCP1M1:1;
      unsigned CCP1M2:1;
      unsigned CCP1M3:1;
      unsigned DC1B0:1;
      unsigned DC1B1:1;
      unsigned P1M0:1;
      unsigned P1M1:1;
    } ECCP1CONbits;
    extern volatile near unsigned            CCPR1;
    extern volatile near unsigned char       CCPR1L;
    extern volatile near unsigned char       CCPR1H;
    extern volatile near unsigned char       ADCON2;
    extern volatile near struct {
      unsigned ADCS0:1;
      unsigned ADCS1:1;
      unsigned ADCS2:1;
      unsigned ACQT0:1;
      unsigned ACQT1:1;
      unsigned ACQT2:1;
      unsigned :1;
      unsigned ADFM:1;
    } ADCON2bits;
    extern volatile near unsigned char       ADCON1;
    extern volatile near struct {
      unsigned PCFG0:1;
      unsigned PCFG1:1;
      unsigned PCFG2:1;
      unsigned PCFG3:1;
      unsigned VCFG0:1;
      unsigned VCFG1:1;
    } ADCON1bits;
    extern volatile near unsigned char       ADCON0;
    extern volatile near union {
      struct {
        unsigned ADON:1;
        unsigned GO_DONE:1;
        unsigned CHS0:1;
        unsigned CHS1:1;
        unsigned CHS2:1;
        unsigned CHS3:1;
      };
      struct {
        unsigned :1;
        unsigned DONE:1;
      };
      struct {
        unsigned :1;
        unsigned GO:1;
      };
      struct {
        unsigned :1;
        unsigned NOT_DONE:1;
      };
    } ADCON0bits;
    extern volatile near unsigned            ADRES;
    extern volatile near unsigned char       ADRESL;
    extern volatile near unsigned char       ADRESH;
    extern volatile near unsigned char       SSPCON2;
    extern volatile near struct {
      unsigned SEN:1;
      unsigned RSEN:1;
      unsigned PEN:1;
      unsigned RCEN:1;
      unsigned ACKEN:1;
      unsigned ACKDT:1;
      unsigned ACKSTAT:1;
      unsigned GCEN:1;
    } SSPCON2bits;
    extern volatile near unsigned char       SSPCON1;
    extern volatile near struct {
      unsigned SSPM0:1;
      unsigned SSPM1:1;
      unsigned SSPM2:1;
      unsigned SSPM3:1;
      unsigned CKP:1;
      unsigned SSPEN:1;
      unsigned SSPOV:1;
      unsigned WCOL:1;
    } SSPCON1bits;
    extern volatile near unsigned char       SSPSTAT;
    extern volatile near union {
      struct {
        unsigned BF:1;
        unsigned UA:1;
        unsigned R_W:1;
        unsigned S:1;
        unsigned P:1;
        unsigned D_A:1;
        unsigned CKE:1;
        unsigned SMP:1;
      };
      struct {
        unsigned :2;
        unsigned I2C_READ:1;
        unsigned I2C_START:1;
        unsigned I2C_STOP:1;
        unsigned I2C_DAT:1;
      };
      struct {
        unsigned :2;
        unsigned NOT_W:1;
        unsigned :2;
        unsigned NOT_A:1;
      };
      struct {
        unsigned :2;
        unsigned NOT_WRITE:1;
        unsigned :2;
        unsigned NOT_ADDRESS:1;
      };
      struct {
        unsigned :2;
        unsigned READ_WRITE:1;
        unsigned :2;
        unsigned DATA_ADDRESS:1;
      };
      struct {
        unsigned :2;
        unsigned R:1;
        unsigned :2;
        unsigned D:1;
      };
    } SSPSTATbits;
    extern volatile near unsigned char       SSPADD;
    extern volatile near unsigned char       SSPBUF;
    extern volatile near unsigned char       T2CON;
    extern volatile near struct {
      unsigned T2CKPS0:1;
      unsigned T2CKPS1:1;
      unsigned TMR2ON:1;
      unsigned T2OUTPS0:1;
      unsigned T2OUTPS1:1;
      unsigned T2OUTPS2:1;
      unsigned T2OUTPS3:1;
    } T2CONbits;
    extern volatile near unsigned char       PR2;
    extern volatile near unsigned char       TMR2;
    extern volatile near unsigned char       T1CON;
    extern volatile near union {
      struct {
        unsigned TMR1ON:1;
        unsigned TMR1CS:1;
        unsigned T1SYNC:1;
        unsigned T1OSCEN:1;
        unsigned T1CKPS0:1;
        unsigned T1CKPS1:1;
        unsigned T1RUN:1;
        unsigned RD16:1;
      };
      struct {
        unsigned :2;
        unsigned NOT_T1SYNC:1;
      };
    } T1CONbits;
    extern volatile near unsigned char       TMR1L;
    extern volatile near unsigned char       TMR1H;
    extern volatile near unsigned char       RCON;
    extern volatile near union {
      struct {
        unsigned NOT_BOR:1;
        unsigned NOT_POR:1;
        unsigned NOT_PD:1;
        unsigned NOT_TO:1;
        unsigned NOT_RI:1;
        unsigned :1;
        unsigned SBOREN:1;
        unsigned NOT_IPEN:1;
      };
      struct {
        unsigned BOR:1;
        unsigned POR:1;
        unsigned PD:1;
        unsigned TO:1;
        unsigned RI:1;
        unsigned :2;
        unsigned IPEN:1;
      };
    } RCONbits;
    extern volatile near unsigned char       WDTCON;
    extern volatile near union {
      struct {
        unsigned SWDTEN:1;
      };
      struct {
        unsigned SWDTE:1;
      };
    } WDTCONbits;
    extern volatile near unsigned char       HLVDCON;
    extern volatile near union {
      struct {
        unsigned LVDL0:1;
        unsigned LVDL1:1;
        unsigned LVDL2:1;
        unsigned LVDL3:1;
        unsigned LVDEN:1;
        unsigned IRVST:1;
      };
      struct {
        unsigned LVV0:1;
        unsigned LVV1:1;
        unsigned LVV2:1;
        unsigned LVV3:1;
        unsigned :1;
        unsigned BGST:1;
      };
      struct {
        unsigned HLVDL0:1;
        unsigned HLVDL1:1;
        unsigned HLVDL2:1;
        unsigned HLVDL3:1;
        unsigned HLVDEN:1;
        unsigned :2;
        unsigned VDIRMAG:1;
      };
      struct {
        unsigned :5;
        unsigned IVRST:1;
      };
    } HLVDCONbits;
    extern volatile near unsigned char       LVDCON;
    extern volatile near union {
      struct {
        unsigned LVDL0:1;
        unsigned LVDL1:1;
        unsigned LVDL2:1;
        unsigned LVDL3:1;
        unsigned LVDEN:1;
        unsigned IRVST:1;
      };
      struct {
        unsigned LVV0:1;
        unsigned LVV1:1;
        unsigned LVV2:1;
        unsigned LVV3:1;
        unsigned :1;
        unsigned BGST:1;
      };
      struct {
        unsigned HLVDL0:1;
        unsigned HLVDL1:1;
        unsigned HLVDL2:1;
        unsigned HLVDL3:1;
        unsigned HLVDEN:1;
        unsigned :2;
        unsigned VDIRMAG:1;
      };
      struct {
        unsigned :5;
        unsigned IVRST:1;
      };
    } LVDCONbits;
    extern volatile near unsigned char       OSCCON;
    extern volatile near union {
      struct {
        unsigned SCS0:1;
        unsigned SCS1:1;
        unsigned IOFS:1;
        unsigned OSTS:1;
        unsigned IRCF0:1;
        unsigned IRCF1:1;
        unsigned IRCF2:1;
        unsigned IDLEN:1;
      };
      struct {
        unsigned :2;
        unsigned FLTS:1;
      };
    } OSCCONbits;
    extern volatile near unsigned char       T0CON;
    extern volatile near struct {
      unsigned T0PS0:1;
      unsigned T0PS1:1;
      unsigned T0PS2:1;
      unsigned PSA:1;
      unsigned T0SE:1;
      unsigned T0CS:1;
      unsigned T08BIT:1;
      unsigned TMR0ON:1;
    } T0CONbits;
    extern volatile near unsigned char       TMR0L;
    extern volatile near unsigned char       TMR0H;
    extern          near unsigned char       STATUS;
    extern          near struct {
      unsigned C:1;
      unsigned DC:1;
      unsigned Z:1;
      unsigned OV:1;
      unsigned N:1;
    } STATUSbits;
    extern          near unsigned            FSR2;
    extern          near unsigned char       FSR2L;
    extern          near unsigned char       FSR2H;
    extern volatile near unsigned char       PLUSW2;
    extern volatile near unsigned char       PREINC2;
    extern volatile near unsigned char       POSTDEC2;
    extern volatile near unsigned char       POSTINC2;
    extern          near unsigned char       INDF2;
    extern          near unsigned char       BSR;
    extern          near unsigned            FSR1;
    extern          near unsigned char       FSR1L;
    extern          near unsigned char       FSR1H;
    extern volatile near unsigned char       PLUSW1;
    extern volatile near unsigned char       PREINC1;
    extern volatile near unsigned char       POSTDEC1;
    extern volatile near unsigned char       POSTINC1;
    extern          near unsigned char       INDF1;
    extern          near unsigned char       WREG;
    extern          near unsigned            FSR0;
    extern          near unsigned char       FSR0L;
    extern          near unsigned char       FSR0H;
    extern volatile near unsigned char       PLUSW0;
    extern volatile near unsigned char       PREINC0;
    extern volatile near unsigned char       POSTDEC0;
    extern volatile near unsigned char       POSTINC0;
    extern          near unsigned char       INDF0;
    extern volatile near unsigned char       INTCON3;
    extern volatile near union {
      struct {
        unsigned INT1IF:1;
        unsigned INT2IF:1;
        unsigned :1;
        unsigned INT1IE:1;
        unsigned INT2IE:1;
        unsigned :1;
        unsigned INT1IP:1;
        unsigned INT2IP:1;
      };
      struct {
        unsigned INT1F:1;
        unsigned INT2F:1;
        unsigned :1;
        unsigned INT1E:1;
        unsigned INT2E:1;
        unsigned :1;
        unsigned INT1P:1;
        unsigned INT2P:1;
      };
    } INTCON3bits;
    extern volatile near unsigned char       INTCON2;
    extern volatile near union {
      struct {
        unsigned RBIP:1;
        unsigned :1;
        unsigned TMR0IP:1;
        unsigned :1;
        unsigned INTEDG2:1;
        unsigned INTEDG1:1;
        unsigned INTEDG0:1;
        unsigned NOT_RBPU:1;
      };
      struct {
        unsigned :2;
        unsigned T0IP:1;
        unsigned :4;
        unsigned RBPU:1;
      };
    } INTCON2bits;
    extern volatile near unsigned char       INTCON;
    extern volatile near union {
      struct {
        unsigned RBIF:1;
        unsigned INT0IF:1;
        unsigned TMR0IF:1;
        unsigned RBIE:1;
        unsigned INT0IE:1;
        unsigned TMR0IE:1;
        unsigned PEIE:1;
        unsigned GIE:1;
      };
      struct {
        unsigned :1;
        unsigned INT0F:1;
        unsigned T0IF:1;
        unsigned :1;
        unsigned INT0E:1;
        unsigned T0IE:1;
        unsigned GIEL:1;
        unsigned GIEH:1;
      };
    } INTCONbits;
    extern          near unsigned            PROD;
    extern          near unsigned char       PRODL;
    extern          near unsigned char       PRODH;
    extern volatile near unsigned char       TABLAT;
    extern volatile near unsigned short long TBLPTR;
    extern volatile near unsigned char       TBLPTRL;
    extern volatile near unsigned char       TBLPTRH;
    extern volatile near unsigned char       TBLPTRU;
    extern volatile near unsigned short long PC;
    extern volatile near unsigned char       PCL;
    extern volatile near unsigned char       PCLATH;
    extern volatile near unsigned char       PCLATU;
    extern volatile near unsigned char       STKPTR;
    extern volatile near struct {
      unsigned STKPTR0:1;
      unsigned STKPTR1:1;
      unsigned STKPTR2:1;
      unsigned STKPTR3:1;
      unsigned STKPTR4:1;
      unsigned :1;
      unsigned STKUNF:1;
      unsigned STKFUL:1;
    } STKPTRbits;
    extern          near unsigned short long TOS;
    extern          near unsigned char       TOSL;
    extern          near unsigned char       TOSH;
    extern          near unsigned char       TOSU;
    
    
    /*-------------------------------------------------------------------------
     * Some useful defines for inline assembly stuff
     *-------------------------------------------------------------------------*/
    #define ACCESS 0
    #define BANKED 1
    
    /*-------------------------------------------------------------------------
     * Some useful macros for inline assembly stuff
     *-------------------------------------------------------------------------*/
    #define Nop()    {_asm nop _endasm}
    #define ClrWdt() {_asm clrwdt _endasm}
    #define Sleep()  {_asm sleep _endasm}
    #define Reset()  {_asm reset _endasm}
    
    #define Rlcf(f,dest,access)  {_asm movlb f rlcf f,dest,access _endasm}
    #define Rlncf(f,dest,access) {_asm movlb f rlncf f,dest,access _endasm}
    #define Rrcf(f,dest,access)  {_asm movlb f rrcf f,dest,access _endasm}
    #define Rrncf(f,dest,access) {_asm movlb f rrncf f,dest,access _endasm}
    #define Swapf(f,dest,access) {_asm movlb f swapf f,dest,access _endasm }
    
    /*-------------------------------------------------------------------------
     * A fairly inclusive set of registers to save for interrupts.
     * These are locations which are commonly used by the compiler.
     *-------------------------------------------------------------------------*/
    #define INTSAVELOCS TBLPTR, TABLAT, PROD
    
    
    #endif
    But i am not sure how this helps me? What do i need to look for?
    Thanks
    Last edited by phoenix23; 10-24-2006 at 06:23 AM.

  6. #6
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by phoenix23
    There is no manual which describes this firmware...
    http://www.microchip.com/stellent/id...cName=en010300
    http://ww1.microchip.com/downloads/e...Doc/39632c.pdf
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  7. #7
    Registered User
    Join Date
    Oct 2006
    Posts
    13

    Question ADRESL and ADRESH

    Thanks for the link - i've seen the site...
    The datasheet for this Microcihp does not explain how the Demo.c Firmware operates. However it does explain ADRESH and ADRESL which are high registers and low registers contained inside the PICs 10 bit A/D Module... It says that the AdresH and AdresL registers contain the result of the A/D conversion. When the A/D conversion is complete, the result is loaded into the adresh:adresl register pair, the GO/DONE bit (ADCON0 register) is cleared and A/D interrupt Flag bit, ADIF, is set.

    I have found the following line of code in the Potentiometer Firmware supplied above :-

    Code:
     mInitPOT();
    which upon checking was found to target the line in this header file:-

    Code:
    /** P O T ***********************************************************/
    #define mInitPOT()          TRISAbits.TRISA0=1;ADCON0=0x01;ADCON2=0x3C;
    after looking at the 18F4550 Datasheet it revealed that 0x01 in the ADCON0 Register is the conversion status bit. 1 = A/D conversion in Progress, 0 = A/D Idle !!!
    0x3C used in the ADCON2 register is for setting the A/D Acquisition Time Select Bits and the A/D Conversion Clock Select Bits... aparently...

    But what code would i need to write to extract the value in ADRESH or ADRESL and correctly map this into buffer[1] ?

    Thanks

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    This is what actually reads the Pot
    Code:
                case RD_POT: // Comes from PC Software
                    ReadPOT();
                    dataPacket._byte[1] = ADRESL;
                    dataPacket._byte[2] = ADRESH;
                    counter=0x03;
                    break;
    The function you mentioned just waits for a conversion.
    ReadPOT(); is mis-named, it should be more like WaitForPOTConversion();


    > signed char dir_table[]=
    If you're trying to create mouse messages, then you need to understand that the mouse is sending small +/- numbers indicating the next small amout of motion - one for X and one for Y. With only one pot, you're only going to simulate one axis.

    Also, in order to output a delta, you need to store the previous position as well.

    So the pseudocode is
    newpos = readpot();
    delta = newpos - oldpos;
    // send the delta as a mouse X or Y
    oldpos = newpos;
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Oct 2006
    Posts
    13

    Sending delta to the mouse pointer buffer

    Hi,

    I'm not sure that ReadPOT() returns a value! As you've said it basically starts the conversion and waits for completion, as shown in the code below:-

    Code:
    void ReadPOT(void)
    {
        ADCON0bits.GO = 1;              // Start AD conversion
        while(ADCON0bits.NOT_DONE);     // Wait for conversion
        return;
    }//end ReadPOT
    I think that it is ADRESL or ADRESH which contains the converted value unless i am mistaken???

    so shouldn't the code look something like this?
    Code:
    ReadPOT();
    newpos = ADRESL;
    delta = newpos - oldpos;
    buffer[1] = delta ;
    oldpos = newpos;
    why do you think there is a need for the counter = 0x03; line in the RD_POT function code displayed in the previous comment???

    also it was suggested that i do some conversions which look as follows:-

    A/D result to a value between -127~127,for 10bit A/D using this formula to convert itA/D result) * (256/1024) - 127 send this value to buffer[1] - any ideas why would i need to do that???

    Thanks again for all your help so far!

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    > so shouldn't the code look something like this?
    Yes, something like that.

    > why do you think there is a need for the counter = 0x03;
    Look at other examples in the same function, it's just a flag of some sort to manage what happens at the end. It's not necessary for what you're doing here.

    > (256/1024)
    Also known as x / 4

    extern volatile near unsigned ADRES;
    extern volatile near unsigned char ADRESL;
    extern volatile near unsigned char ADRESH;
    Use ADRES to get the full 16 bit value in one go.

    > any ideas why would i need to do that???
    Because the mouse delta is a much smaller number perhaps.
    Maybe read up on the mouse protocol specification.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  11. #11
    Registered User
    Join Date
    Oct 2006
    Posts
    13

    8 Bit device

    How can there be a register that holds a 16bit value? The Microchip is 8 bits isn't it? All the registers work in 8 bits? although it does say that the A/D converter module is 10 bits in the datasheet! So wouldn't there be a problem with using the unsigned Adres; register ?

    I found this website for the mouse specs

    http://www.mousetrak.com/rs232mousespec.htm

    Though this is for COM Port communication - i imagine that the mouse protocol is still the same regardless of whether it is USB or other??? The website shows two types of protocol - a 5 bute mouse and a Microsoft Serial 3 byte mouse protocol.
    I think the program has been written for microsoft serial communication! From the information it looks like the mouse program code that buffer[1] represents Byte 1 buffer[2] represents Byte 2 and buffer[3] represents Byte 3 !
    - Is that correct?

    If so then bits X6, X7 and Y6, Y7 would be left off wouldn't they?!
    Thanks

  12. #12
    Registered User
    Join Date
    Oct 2006
    Posts
    13

    Syntax Error on Line

    I have inserted the code as follows and received a Syntax Error on the highlighted line - why is this?

    Code:
    /** I N C L U D E S **********************************************************/
    #include <p18cxxx.h>
    #include <usart.h>
    #include "system\typedefs.h"
    
    #include "system\usb\usb.h"
    
    #include "io_cfg.h"             // I/O pin mapping
    #include "user\user_mouse.h"
    
    /** V A R I A B L E S ********************************************************/
    #pragma udata  			// not sure what udata does???
    byte old_sw2,old_sw3;
    
    BOOL emulate_mode;
    rom signed char dir_table[]={-8,-8,-8, 0, 8, 8, 8, 0};
    byte movement_length;
    byte vector = 0;
    char buffer[3]; // buffer is a char buffer and is 3 in size
    
    /** P R I V A T E  P R O T O T Y P E S ***************************************/
    void BlinkUSBStatus(void);
    BOOL Switch2IsPressed(void);
    BOOL Switch3IsPressed(void); //function returns a Boolean value (1 or 0)
    void ReadPOT(void);
    void Emulate_Mouse(void);
    
    /** D E C L A R A T I O N S **************************************************/
    #pragma code
    void UserInit(void)
    {
        mInitAllLEDs();
        mInitAllSwitches();
        old_sw2 = sw2;
        old_sw3 = sw3;
    
        buffer[0]=0;
        buffer[1]=0;
        buffer[2]=0;
        buffer[3]=0;
        
        emulate_mode = TRUE;
    }//end UserInit
    
    /******************************************************************************
     * Function:        void ProcessIO(void)
     *
     * PreCondition:    None
     *
     * Input:           None
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        This function is a place holder for other user routines.
     *                  It is a mixture of both USB and non-USB tasks.
     *
     * Note:            None
     *****************************************************************************/
    void ProcessIO(void)
    {   
        BlinkUSBStatus();
        // User Application USB tasks
        if((usb_device_state < CONFIGURED_STATE)||(UCONbits.SUSPND==1)) return;
    
        if(Switch3IsPressed())
            emulate_mode = !emulate_mode; //emulate_mode = Not emulate_mode
        
        Emulate_Mouse(); // if switch 3 is pressed on demo board it calls Emulate_Mouse Function prototyped below
        
    }//end ProcessIO
    
    /*
    void Emulate_Mouse(void) // void at beginning shows that function does not return a value
    {						 // void in brackets shows that function does not receive a value
    						 // Function Prototype
        if(emulate_mode == TRUE) // if emulate_mode has returned a value == to TRUE
        {						 // then do inside if statement
            if(movement_length > 14) // if movement_length > 14 do this statement
            {
                buffer[0] = 0; // 0 is put into buffer position 0
                //vector is a byte and is initiated to 0
    			buffer[1] = dir_table[vector & 0x07];           // X-Vector
    // takes value from a direction table, the position in the table is dictated by
    // the vector ANDED with hexadecimal 7 (This loops between positions 0 to 7)
                buffer[2] = dir_table[(vector+2) & 0x07];       // Y-Vector
    // for the Y direction 2 is added to the vector which means that when buffer pos 1 (X direction)is 
    // at dir_table value 7 buffer pos 2 is at dir_table value 1 (Y direction)     
    			vector++; // vector keeps incrementing (Isn't that dangerous ? when will it stop ?)
                movement_length = 0;
            }//end if(movement_length < 14)
        } // otherwise do this else statement
        else
            buffer[0] = buffer[1] = buffer[2] = 0; // set all buffers to zero
    
        if(!mHIDTxIsBusy()) // if transmit channel is not busy then do rest of if statement
        {
            HIDTxReport(buffer,3); // HIDTxReport takes two input arguments,
    		// The values in the buffer array and the byte length
            movement_length++; // increment movement_length (What is movement length?) is this a delay?
        }//end if(mHIDIsPutReportReady())
    }//end Emulate_Mouse
    */
    void ReadPOT(void)
    {
        ADCON0bits.GO = 1;              // Start AD conversion
        while(ADCON0bits.NOT_DONE);     // Wait for conversion
        return;
    }//end ReadPOT
    
    ReadPOT();
    newpos = ADRESL;
    delta = newpos - oldpos;
    buffer[1] = delta ;
    oldpos = newpos;
    
    /******************************************************************************
     * Function:        void BlinkUSBStatus(void)
     *
     * PreCondition:    None
     *
     * Input:           None
     *
     * Output:          None
     *
     * Side Effects:    None
     *
     * Overview:        BlinkUSBStatus turns on and off LEDs corresponding to
     *                  the USB device state.
     *
     * Note:            mLED macros can be found in io_cfg.h
     *                  usb_device_state is declared in usbmmap.c and is modified
     *                  in usbdrv.c, usbctrltrf.c, and usb9.c
     *****************************************************************************/
    void BlinkUSBStatus(void)
    {
        static word led_count=0;
        
        if(led_count == 0)led_count = 10000U;
        led_count--;
    
        #define mLED_Both_Off()         {mLED_1_Off();mLED_2_Off();}
        #define mLED_Both_On()          {mLED_1_On();mLED_2_On();}
        #define mLED_Only_1_On()        {mLED_1_On();mLED_2_Off();}
        #define mLED_Only_2_On()        {mLED_1_Off();mLED_2_On();}
    
        if(UCONbits.SUSPND == 1)
        {
            if(led_count==0)
            {
                mLED_1_Toggle();
                mLED_2 = mLED_1;        // Both blink at the same time
            }//end if
        }
        else
        {
            if(usb_device_state == DETACHED_STATE)
            {
                mLED_Both_Off();
            }
            else if(usb_device_state == ATTACHED_STATE)
            {
                mLED_Both_On();
            }
            else if(usb_device_state == POWERED_STATE)
            {
                mLED_Only_1_On();
            }
            else if(usb_device_state == DEFAULT_STATE)
            {
                mLED_Only_2_On();
            }
            else if(usb_device_state == ADDRESS_STATE)
            {
                if(led_count == 0)
                {
                    mLED_1_Toggle();
                    mLED_2_Off();
                }//end if
            }
            else if(usb_device_state == CONFIGURED_STATE)
            {
                if(led_count==0)
                {
                    mLED_1_Toggle();
                    mLED_2 = !mLED_1;       // Alternate blink                
                }//end if
            }//end if(...)
        }//end if(UCONbits.SUSPND...)
    
    }//end BlinkUSBStatus
    
    BOOL Switch2IsPressed(void) // Function Returns a Boolean
    {
        if(sw2 != old_sw2) // if sw2 is not equal to old sw then do statement, ie if pressed.
        {
            old_sw2 = sw2;                  // Save new value
            if(sw2 == 0)                    // If pressed
                return TRUE;                // Was pressed
        }//end if
        return FALSE;                       // Was not pressed
    }//end Switch2IsPressed
    
    BOOL Switch3IsPressed(void) // Function Returns a Boolean
    {
        if(sw3 != old_sw3)
        {
            old_sw3 = sw3;                  // Save new value
            if(sw3 == 0)                    // If pressed
                return TRUE;                // Was pressed
        }//end if
        return FALSE;                       // Was not pressed
    }//end Switch3IsPressed
    
    /** EOF user_mouse.c *********************************************************/

  13. #13
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    > why is this?
    Because you can't have executable statements outside of functions.

    Do you know C at all?

    Seriously, most people get familiar with C (more than you seem capable of at the moment) on the PC before attempting to write programs for embedded devices.

    Embedded programming has so many more issues associated with it to make it hard enough even when you do know C.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  14. #14
    Registered User
    Join Date
    Oct 2006
    Posts
    13
    i did put it inside a function previously - it was void PotToMouse (void) but this didn't seem to make a difference, that's why i left it out!

    This is what i had previously

    Code:
    void PotToMouse(void)
    ReadPOT();
    newpos = ADRESL;
    delta = newpos - oldpos;
    buffer[1] = delta ;
    oldpos = newpos;
    return;
    but this didn't work either - same error!

    I do know C, but it all seems a bit strange to program on integrated microchips using C... I'm trying to adjust, because i used to use assembly, and things took absolutely ages!

    Cheers

  15. #15
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by phoenix23
    i did put it inside a function previously - it was void PotToMouse (void) but this didn't seem to make a difference, that's why i left it out!
    It does not make a difference because you forget to put braces
    Code:
     
    void PotToMouse(void)
    {
       ReadPOT();
       newpos = ADRESL;
       delta = newpos - oldpos;
       buffer[1] = delta ;
       oldpos = newpos;
       return;
    }
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sorting the matrix question..
    By transgalactic2 in forum C Programming
    Replies: 47
    Last Post: 12-22-2008, 03:17 PM
  2. Making a mouse hover button, API style
    By hanhao in forum C++ Programming
    Replies: 1
    Last Post: 05-27-2004, 06:17 AM
  3. Game Design Topic #2 - Keyboard or Mouse?
    By TechWins in forum Game Programming
    Replies: 4
    Last Post: 10-08-2002, 03:34 PM
  4. How I can Show the pointer of mouse int 800*600 256 color mode in Turbo C++?
    By hadizadeh in forum A Brief History of Cprogramming.com
    Replies: 3
    Last Post: 12-12-2001, 07:17 AM
  5. Moving Mouse Pointer
    By loobian in forum Windows Programming
    Replies: 8
    Last Post: 10-16-2001, 03:45 PM