/****************************************************************************** * 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) { //Blink the LEDs according to the USB device status, but only do so if the PC application isn't connected and controlling the LEDs. if(blinkStatusValid) { BlinkUSBStatus(); } //User Application USB tasks below. //Note: The user application should not begin attempting to read/write over the USB //until after the device has been fully enumerated. After the device is fully //enumerated, the USBDeviceState will be set to "CONFIGURED_STATE". if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; //As the device completes the enumeration process, the USBCBInitEP() function will //get called. In this function, we initialize the user application endpoints (in this //example code, the user application makes use of endpoint 1 IN and endpoint 1 OUT). //The USBGenRead() function call in the USBCBInitEP() function initializes endpoint 1 OUT //and "arms" it so that it can receive a packet of data from the host. Once the endpoint //has been armed, the host can then send data to it (assuming some kind of application software //is running on the host, and the application software tries to send data to the USB device). //If the host sends a packet of data to the endpoint 1 OUT buffer, the hardware of the SIE will //automatically receive it and store the data at the memory location pointed to when we called //USBGenRead(). Additionally, the endpoint handle (in this case USBGenericOutHandle) will indicate //that the endpoint is no longer busy. At this point, it is safe for this firmware to begin reading //from the endpoint buffer, and processing the data. In this example, we have implemented a few very //simple commands. For example, if the host sends a packet of data to the endpoint 1 OUT buffer, with the //first byte = 0x80, this is being used as a command to indicate that the firmware should "Toggle LED(s)". if(!USBHandleBusy(USBGenericOutHandle)) //Check if the endpoint has received any data from the host. { switch(OUTPacket[0]) //Data arrived, check what kind of command might be in the packet of data. { case 0x80: //Toggle LED(s) command from PC application. blinkStatusValid = FALSE; //Disable the regular LED blink pattern indicating USB state, PC application is controlling the LEDs. if(mGetLED_1() == mGetLED_2()) { mLED_1_Toggle(); mLED_2_Toggle(); } else { mLED_1_On(); mLED_2_On(); } break; case 0x81: //Get push button state command from PC application. INPacket[0] = 0x81; //Echo back to the host PC the command we are fulfilling in the first byte. In this case, the Get Pushbutton State command. // if(sw2 == 1) //pushbutton not pressed, pull up resistor on circuit board is pulling the PORT pin high if (UserSW == 1) { INPacket[1] = 0x01; } else //sw2 must be == 0, pushbutton is pressed and overpowering the pull up resistor { INPacket[1] = 0x00; } //Now check to make sure no previous attempts to send data to the host are still pending. If any attemps are still //pending, we do not want to write to the endpoint 1 IN buffer again, until the previous transaction is complete. //Otherwise the unsent data waiting in the buffer will get overwritten and will result in unexpected behavior. if(!USBHandleBusy(USBGenericInHandle)) { //The endpoint was not "busy", therefore it is safe to write to the buffer and arm the endpoint. //The USBGenWrite() function call "arms" the endpoint (and makes the handle indicate the endpoint is busy). //Once armed, the data will be automatically sent to the host (in hardware by the SIE) the next time the //host polls the endpoint. Once the data is successfully sent, the handle (in this case USBGenericInHandle) //will indicate the the endpoint is no longer busy. USBGenericInHandle = USBGenWrite(USBGEN_EP_NUM,(BYTE*)&INPacket,USBGEN_EP_SIZE); } break; } //Re-arm the OUT endpoint for the next packet: //The USBGenRead() function call "arms" the endpoint (and makes it "busy"). If the endpoint is armed, the SIE will //automatically accept data from the host, if the host tries to send a packet of data to the endpoint. Once a data //packet addressed to this endpoint is received from the host, the endpoint will no longer be busy, and the application //can read the data which will be sitting in the buffer. USBGenericOutHandle = USBGenRead(USBGEN_EP_NUM,(BYTE*)&OUTPacket,USBGEN_EP_SIZE); } }//end ProcessIO
/******************************************************************** * 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 HardwareProfile.h * USBDeviceState is declared and updated in * usb_device.c. *******************************************************************/ void BlinkUSBStatus(void) { static WORD led_count=0; if(led_count == 0)led_count = 10000U; led_count--; if(USBSuspendControl == 1) { if(led_count==0) { mLED_1_Toggle(); if(mGetLED_1()) { mLED_2_On(); } else { mLED_2_Off(); } }//end if } else { if(USBDeviceState == DETACHED_STATE) { mLED_Both_Off(); } else if(USBDeviceState == ATTACHED_STATE) { mLED_Both_On(); } else if(USBDeviceState == POWERED_STATE) { mLED_Only_1_On(); } else if(USBDeviceState == DEFAULT_STATE) { mLED_Only_2_On(); } else if(USBDeviceState == ADDRESS_STATE) { if(led_count == 0) { mLED_1_Toggle(); mLED_2_Off(); }//end if } else if(USBDeviceState == CONFIGURED_STATE) { if(led_count==0) { mLED_1_Toggle(); if(mGetLED_1()) { mLED_2_Off(); } else { mLED_2_On(); } }//end if }//end if(...) }//end if(UCONbits.SUSPND...) }//end BlinkUSBStatus
/****************************************************************************** * 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) { //Blink the LEDs according to the USB device status, but only do so if the PC application isn't connected and controlling the LEDs. if(blinkStatusValid) { BlinkUSBStatus(); } // Check if the device is enumerated and is ready to accept commands. if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; if(!USBHandleBusy(USBGenericOutHandle)) //Check if the endpoint has received any data from the host. { switch(OUTPacket[0]) //Data arrived, check what kind of command might be in the packet of data. { case 'A': if(!USBHandleBusy(USBGenericInHandle)) { if(OUTPacket[1] == '0') { ADCON0bits.ADON = 0; // Switch off ADC. ADCON0 &= 0xF0; // Select channel 0 ADCON0bits.ADON = 1; ADCON0bits.GO = 1; // Wait if conversion is happening while(ADCON0bits.DONE); INPacket[0] = ADRESL; INPacket[1] = ADRESH; } else if(OUTPacket[1] == '1') { ADCON0bits.ADON = 0; // Switch off ADC. ADCON0 &= 0xF0; // Select channel ADCON0bits.CHS0 = 1; ADCON0bits.ADON = 1; ADCON0bits.GO = 1; // Wait if conversion is happening while(ADCON0bits.DONE); INPacket[0] = ADRESL; INPacket[1] = ADRESH; } USBGenericInHandle = USBGenWrite(USBGEN_EP_NUM,(BYTE*)&INPacket,USBGEN_EP_SIZE); } break; case 0x80: //Toggle LED(s) command from PC application. blinkStatusValid = FALSE; //Disable the regular LED blink pattern indicating USB state, PC application is controlling the LEDs. if(mGetLED_1() == mGetLED_2()) { mLED_1_Toggle(); mLED_2_Toggle(); } else { mLED_1_On(); mLED_2_On(); } break; case 0x81: //Get push button state command from PC application. if(!USBHandleBusy(USBGenericInHandle)) { //The endpoint was not "busy", therefore it is safe to write to the buffer and arm the endpoint. INPacket[0] = 0x81; //Echo back to the host PC the command we are fulfilling in the first byte. In this case, the Get Pushbutton State command. if(sw2 == 1) //pushbutton not pressed, pull up resistor on circuit board is pulling the PORT pin high { INPacket[1] = 0x01; } else //sw2 must be == 0, pushbutton is pressed and overpowering the pull up resistor { INPacket[1] = 0x00; } // Arm back the handle. USBGenericInHandle = USBGenWrite(USBGEN_EP_NUM,(BYTE*)&INPacket,USBGEN_EP_SIZE); } break; } USBGenericOutHandle = USBGenRead(USBGEN_EP_NUM,(BYTE*)&OUTPacket,USBGEN_EP_SIZE); } }//end ProcessIO