123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215 |
- /********************************************************************
- FileName: main.c
- Dependencies: See INCLUDES section
- Processor: PIC18 or PIC24 USB Microcontrollers
- Hardware: The code is natively intended to be used on the following
- hardware platforms: PICDEM™ FS USB Demo Board,
- PIC18F87J50 FS USB Plug-In Module, or
- Explorer 16 + PIC24 USB PIM. The firmware may be
- modified for use on other USB platforms by editing the
- HardwareProfile.h file.
- Complier: Microchip C18 (for PIC18) or C30 (for PIC24)
- Company: Microchip Technology, Inc.
- Software License Agreement:
- The software supplied herewith by Microchip Technology Incorporated
- (the “Company”) for its PIC® Microcontroller is intended and
- supplied to you, the Company’s customer, for use solely and
- exclusively on Microchip PIC Microcontroller products. The
- software is owned by the Company and/or its supplier, and is
- protected under applicable copyright laws. All rights are reserved.
- Any use in violation of the foregoing restrictions may subject the
- user to criminal sanctions under applicable laws, as well as to
- civil liability for the breach of the terms and conditions of this
- license.
- THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
- WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
- TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
- IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
- CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
- ********************************************************************
- File Description:
- Change History:
- Rev Date Description
- 1.0 11/19/2004 Initial release
- 2.1 02/26/2007 Updated for simplicity and to use common
- coding style
- ********************************************************************/
- /** INCLUDES *******************************************************/
- #include "USB/usb.h"
- #include "USB/usb_function_generic.h"
- #include "HardwareProfile.h"
- //#include "Compiler.h"
- //#include "GenericTypeDefs.h"
- //#include "USB/usb_device.h"
- //#include "USB/usb.h"
- //#include "usb_config.h"
- #include "Benchmark.h"
- /** CONFIGURATION **************************************************/
- #if defined(PICDEM_FS_USB) // Configuration bits for PICDEM FS USB Demo Board (based on PIC18F4550)
- #pragma config PLLDIV = 5 // (20 MHz crystal on PICDEM FS USB board)
- #pragma config CPUDIV = OSC1_PLL2
- #pragma config USBDIV = 2 // Clock source from 96MHz PLL/2
- #pragma config FOSC = HSPLL_HS
- #pragma config FCMEN = OFF
- #pragma config IESO = OFF
- #pragma config PWRT = OFF
- #pragma config BOR = ON
- #pragma config BORV = 3
- #pragma config VREGEN = ON //USB Voltage Regulator
- #pragma config WDT = OFF
- #pragma config WDTPS = 32768
- #pragma config MCLRE = ON
- #pragma config LPT1OSC = OFF
- #pragma config PBADEN = OFF
- // #pragma config CCP2MX = ON
- #pragma config STVREN = ON
- #pragma config LVP = OFF
- // #pragma config ICPRT = OFF // Dedicated In-Circuit Debug/Programming
- #pragma config XINST = OFF // Extended Instruction Set
- #pragma config CP0 = OFF
- #pragma config CP1 = OFF
- // #pragma config CP2 = OFF
- // #pragma config CP3 = OFF
- #pragma config CPB = OFF
- // #pragma config CPD = OFF
- #pragma config WRT0 = OFF
- #pragma config WRT1 = OFF
- // #pragma config WRT2 = OFF
- // #pragma config WRT3 = OFF
- #pragma config WRTB = OFF // Boot Block Write Protection
- #pragma config WRTC = OFF
- // #pragma config WRTD = OFF
- #pragma config EBTR0 = OFF
- #pragma config EBTR1 = OFF
- // #pragma config EBTR2 = OFF
- // #pragma config EBTR3 = OFF
- #pragma config EBTRB = OFF
- #elif defined(PIC18F87J50_PIM) // Configuration bits for PIC18F87J50 FS USB Plug-In Module board
- #pragma config XINST = OFF // Extended instruction set
- #pragma config STVREN = ON // Stack overflow reset
- #pragma config PLLDIV = 3 // (12 MHz crystal used on this board)
- #pragma config WDTEN = OFF // Watch Dog Timer (WDT)
- #pragma config CP0 = OFF // Code protect
- #pragma config CPUDIV = OSC1 // OSC1 = divide by 1 mode
- #pragma config IESO = OFF // Internal External (clock) Switchover
- #pragma config FCMEN = OFF // Fail Safe Clock Monitor
- #pragma config FOSC = HSPLL // Firmware must also set OSCTUNE<PLLEN> to start PLL!
- #pragma config WDTPS = 32768
- // #pragma config WAIT = OFF // Commented choices are
- // #pragma config BW = 16 // only available on the
- // #pragma config MODE = MM // 80 pin devices in the
- // #pragma config EASHFT = OFF // family.
- #pragma config MSSPMSK = MSK5
- // #pragma config PMPMX = DEFAULT
- // #pragma config ECCPMX = DEFAULT
- #pragma config CCP2MX = DEFAULT
- #elif defined(PIC18F46J50_PIM)
- #pragma config WDTEN = OFF //WDT disabled (enabled by SWDTEN bit)
- #pragma config PLLDIV = 3 //Divide by 3 (12 MHz oscillator input)
- #pragma config STVREN = ON //stack overflow/underflow reset enabled
- #pragma config XINST = OFF //Extended instruction set disabled
- #pragma config CPUDIV = OSC1 //No CPU system clock divide
- #pragma config CP0 = OFF //Program memory is not code-protected
- #pragma config OSC = HSPLL //HS oscillator, PLL enabled, HSPLL used by USB
- #pragma config T1DIG = ON //Sec Osc clock source may be selected
- #pragma config LPT1OSC = OFF //high power Timer1 mode
- #pragma config FCMEN = OFF //Fail-Safe Clock Monitor disabled
- #pragma config IESO = OFF //Two-Speed Start-up disabled
- #pragma config WDTPS = 32768 //1:32768
- #pragma config DSWDTOSC = INTOSCREF //DSWDT uses INTOSC/INTRC as clock
- #pragma config RTCOSC = T1OSCREF //RTCC uses T1OSC/T1CKI as clock
- #pragma config DSBOREN = OFF //Zero-Power BOR disabled in Deep Sleep
- #pragma config DSWDTEN = OFF //Disabled
- #pragma config DSWDTPS = 8192 //1:8,192 (8.5 seconds)
- #pragma config IOL1WAY = OFF //IOLOCK bit can be set and cleared
- #pragma config MSSP7B_EN = MSK7 //7 Bit address masking
- #pragma config WPFP = PAGE_1 //Write Protect Program Flash Page 0
- #pragma config WPEND = PAGE_0 //Start protection at page 0
- #pragma config WPCFG = OFF //Write/Erase last page protect Disabled
- #pragma config WPDIS = OFF //WPFP[5:0], WPEND, and WPCFG bits ignored
- #elif defined(LOW_PIN_COUNT_USB_DEVELOPMENT_KIT)
- // PIC18F14K50
- #pragma config CPUDIV = NOCLKDIV
- #pragma config USBDIV = OFF
- #pragma config FOSC = HS
- #pragma config PLLEN = ON
- #pragma config FCMEN = OFF
- #pragma config IESO = OFF
- #pragma config PWRTEN = OFF
- #pragma config BOREN = OFF
- #pragma config BORV = 30
- #pragma config WDTEN = OFF
- #pragma config WDTPS = 32768
- #pragma config MCLRE = OFF
- #pragma config HFOFST = OFF
- #pragma config STVREN = ON
- #pragma config LVP = OFF
- #pragma config XINST = OFF
- #pragma config BBSIZ = OFF
- #pragma config CP0 = OFF
- #pragma config CP1 = OFF
- #pragma config CPB = OFF
- #pragma config WRT0 = OFF
- #pragma config WRT1 = OFF
- #pragma config WRTB = OFF
- #pragma config WRTC = OFF
- #pragma config EBTR0 = OFF
- #pragma config EBTR1 = OFF
- #pragma config EBTRB = OFF
- #elif defined(EXPLORER_16)
- #ifdef __PIC24FJ256GB110__ //Defined by MPLAB when using 24FJ256GB110 device
- _CONFIG1( JTAGEN_OFF & GCP_OFF & GWRP_OFF & COE_OFF & FWDTEN_OFF & ICS_PGx2)
- _CONFIG2( 0xF7FF & IESO_OFF & FCKSM_CSDCMD & OSCIOFNC_ON & POSCMOD_HS & FNOSC_PRIPLL & PLLDIV_DIV2 & IOL1WAY_ON)
- #elif defined(__PIC24FJ64GB004__)
- _CONFIG1(WDTPS_PS1 & FWPSA_PR32 & WINDIS_OFF & FWDTEN_OFF & ICS_PGx1 & GWRP_OFF & GCP_OFF & JTAGEN_OFF)
- _CONFIG2(POSCMOD_HS & I2C1SEL_PRI & IOL1WAY_OFF & OSCIOFNC_ON & FCKSM_CSDCMD & FNOSC_PRIPLL & PLL96MHZ_ON & PLLDIV_DIV2 & IESO_ON)
- _CONFIG3(WPFP_WPFP0 & SOSCSEL_SOSC & WUTSEL_LEG & WPDIS_WPDIS & WPCFG_WPCFGDIS & WPEND_WPENDMEM)
- _CONFIG4(DSWDTPS_DSWDTPS3 & DSWDTOSC_LPRC & RTCOSC_SOSC & DSBOREN_OFF & DSWDTEN_OFF)
- #elif defined(__32MX460F512L__)
- #pragma config UPLLEN = ON // USB PLL Enabled
- #pragma config FPLLMUL = MUL_15 // PLL Multiplier
- #pragma config UPLLIDIV = DIV_2 // USB PLL Input Divider
- #pragma config FPLLIDIV = DIV_2 // PLL Input Divider
- #pragma config FPLLODIV = DIV_1 // PLL Output Divider
- #pragma config FPBDIV = DIV_1 // Peripheral Clock divisor
- #pragma config FWDTEN = OFF // Watchdog Timer
- #pragma config WDTPS = PS1 // Watchdog Timer Postscale
- #pragma config FCKSM = CSDCMD // Clock Switching & Fail Safe Clock Monitor
- #pragma config OSCIOFNC = OFF // CLKO Enable
- #pragma config POSCMOD = HS // Primary Oscillator
- #pragma config IESO = OFF // Internal/External Switch-over
- #pragma config FSOSCEN = OFF // Secondary Oscillator Enable (KLO was off)
- #pragma config FNOSC = PRIPLL // Oscillator Selection
- #pragma config CP = OFF // Code Protect
- #pragma config BWP = OFF // Boot Flash Write Protect
- #pragma config PWP = OFF // Program Flash Write Protect
- #pragma config ICESEL = ICS_PGx2 // ICE/ICD Comm Channel Select
- #pragma config DEBUG = ON // Background Debugger Enable
- #else
- #error No hardware board defined, see "HardwareProfile.h" and __FILE__
- #endif
- #elif defined(PIC24F_STARTER_KIT)
- _CONFIG1( JTAGEN_OFF & GCP_OFF & GWRP_OFF & COE_OFF & FWDTEN_OFF & ICS_PGx2)
- _CONFIG2( 0xF7FF & IESO_OFF & FCKSM_CSDCMD & OSCIOFNC_ON & POSCMOD_HS & FNOSC_PRIPLL & PLLDIV_DIV3 & IOL1WAY_ON)
- #elif defined(PIC32_USB_STARTER_KIT)
- #pragma config UPLLEN = ON // USB PLL Enabled
- #pragma config FPLLMUL = MUL_15 // PLL Multiplier
- #pragma config UPLLIDIV = DIV_2 // USB PLL Input Divider
- #pragma config FPLLIDIV = DIV_2 // PLL Input Divider
- #pragma config FPLLODIV = DIV_1 // PLL Output Divider
- #pragma config FPBDIV = DIV_1 // Peripheral Clock divisor
- #pragma config FWDTEN = OFF // Watchdog Timer
- #pragma config WDTPS = PS1 // Watchdog Timer Postscale
- #pragma config FCKSM = CSDCMD // Clock Switching & Fail Safe Clock Monitor
- #pragma config OSCIOFNC = OFF // CLKO Enable
- #pragma config POSCMOD = HS // Primary Oscillator
- #pragma config IESO = OFF // Internal/External Switch-over
- #pragma config FSOSCEN = OFF // Secondary Oscillator Enable (KLO was off)
- #pragma config FNOSC = PRIPLL // Oscillator Selection
- #pragma config CP = OFF // Code Protect
- #pragma config BWP = OFF // Boot Flash Write Protect
- #pragma config PWP = OFF // Program Flash Write Protect
- #pragma config ICESEL = ICS_PGx2 // ICE/ICD Comm Channel Select
- #pragma config DEBUG = ON // Background Debugger Enable
- #elif defined(BREADBOARD)
- #if defined(__PIC24FJ64GB002__)
- _CONFIG1(WDTPS_PS1 & FWPSA_PR32 & WINDIS_OFF & FWDTEN_OFF & ICS_PGx3 & GWRP_OFF & GCP_OFF & JTAGEN_OFF)
- _CONFIG2(POSCMOD_HS & I2C1SEL_PRI & IOL1WAY_OFF & OSCIOFNC_OFF & FCKSM_CSDCMD & FNOSC_PRIPLL & PLL96MHZ_ON & PLLDIV_DIV3 & IESO_ON)
- _CONFIG3(WPFP_WPFP0 & SOSCSEL_SOSC & WUTSEL_LEG & WPDIS_WPDIS & WPCFG_WPCFGDIS & WPEND_WPENDMEM)
- _CONFIG4(DSWDTPS_DSWDTPS3 & DSWDTOSC_LPRC & RTCOSC_LPRC & DSBOREN_OFF & DSWDTEN_OFF)
- //_CONFIG1(WDTPS_PS1 & FWPSA_PR32 & WINDIS_OFF & FWDTEN_OFF & ICS_PGx3 & GWRP_OFF & GCP_OFF & JTAGEN_OFF)
- //_CONFIG2(POSCMOD_NONE & I2C1SEL_PRI & IOL1WAY_OFF & OSCIOFNC_OFF & FCKSM_CSDCMD & FNOSC_FRCPLL & PLL96MHZ_ON & PLLDIV_NODIV & IESO_ON)
- //_CONFIG3(WPFP_WPFP0 & SOSCSEL_SOSC & WUTSEL_LEG & WPDIS_WPDIS & WPCFG_WPCFGDIS & WPEND_WPENDMEM)
- //_CONFIG4(DSWDTPS_DSWDTPS3 & DSWDTOSC_LPRC & RTCOSC_SOSC & DSBOREN_OFF & DSWDTEN_OFF)
- #else
- #error No breadboard device defined, see "HardwareProfile.h" and __FILE__
- #endif
- #else
- #error No hardware board defined, see "HardwareProfile.h"
- #endif
- /** VARIABLES *****************************************************
- #if defined(__18F14K50) || defined(__18F13K50) || defined(__18LF14K50) || defined(__18LF13K50)
- #pragma udata usbram2
- #elif defined(__18F2455) || defined(__18F2550) || defined(__18F4455) || defined(__18F4550)\
- || defined(__18F2458) || defined(__18F2453) || defined(__18F4558) || defined(__18F4553)
- #pragma udata USB_VARIABLES=0x500
- #elif defined(__18F4450) || defined(__18F2450)
- #pragma udata USB_VARIABLES=0x480
- #else
- #pragma udata
- #endif
- unsigned char OUTPacket[64]; //User application buffer for receiving and holding OUT packets sent from the host
- unsigned char INPacket[64]; //User application buffer for sending IN packets to the host
- */
- #pragma udata
- BOOL blinkStatusValid;
- /*
- USB_HANDLE USBGenericOutHandle;
- USB_HANDLE USBGenericInHandle;
- #pragma udata
- */
- /** PRIVATE PROTOTYPES *********************************************/
- static void InitializeSystem(void);
- void USBDeviceTasks(void);
- void YourHighPriorityISRCode(void);
- void YourLowPriorityISRCode(void);
- void UserInit(void);
- void ProcessIO(void);
- void BlinkUSBStatus(void);
- /** VECTOR REMAPPING ***********************************************/
- #if defined(__18CXX)
- //On PIC18 devices, addresses 0x00, 0x08, and 0x18 are used for
- //the reset, high priority interrupt, and low priority interrupt
- //vectors. However, the current Microchip USB bootloader
- //examples are intended to occupy addresses 0x00-0x7FF or
- //0x00-0xFFF depending on which bootloader is used. Therefore,
- //the bootloader code remaps these vectors to new locations
- //as indicated below. This remapping is only necessary if you
- //wish to program the hex file generated from this project with
- //the USB bootloader. If no bootloader is used, edit the
- //usb_config.h file and comment out the following defines:
- //#define PROGRAMMABLE_WITH_USB_HID_BOOTLOADER
- //#define PROGRAMMABLE_WITH_USB_LEGACY_CUSTOM_CLASS_BOOTLOADER
-
- #if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)
- #define REMAPPED_RESET_VECTOR_ADDRESS 0x1000
- #define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x1008
- #define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS 0x1018
- #elif defined(PROGRAMMABLE_WITH_USB_MCHPUSB_BOOTLOADER)
- #define REMAPPED_RESET_VECTOR_ADDRESS 0x800
- #define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x808
- #define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS 0x818
- #else
- #define REMAPPED_RESET_VECTOR_ADDRESS 0x00
- #define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x08
- #define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS 0x18
- #endif
-
- #if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)||defined(PROGRAMMABLE_WITH_USB_MCHPUSB_BOOTLOADER)
- extern void _startup (void); // See c018i.c in your C18 compiler dir
- #pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS
- void _reset (void)
- {
- _asm goto _startup _endasm
- }
- #endif
- #pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS
- void Remapped_High_ISR (void)
- {
- _asm goto YourHighPriorityISRCode _endasm
- }
- #pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS
- void Remapped_Low_ISR (void)
- {
- _asm goto YourLowPriorityISRCode _endasm
- }
-
- #if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)||defined(PROGRAMMABLE_WITH_USB_MCHPUSB_BOOTLOADER)
- //Note: If this project is built while one of the bootloaders has
- //been defined, but then the output hex file is not programmed with
- //the bootloader, addresses 0x08 and 0x18 would end up programmed with 0xFFFF.
- //As a result, if an actual interrupt was enabled and occured, the PC would jump
- //to 0x08 (or 0x18) and would begin executing "0xFFFF" (unprogrammed space). This
- //executes as nop instructions, but the PC would eventually reach the REMAPPED_RESET_VECTOR_ADDRESS
- //(0x1000 or 0x800, depending upon bootloader), and would execute the "goto _startup". This
- //would effective reset the application.
-
- //To fix this situation, we should always deliberately place a
- //"goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS" at address 0x08, and a
- //"goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS" at address 0x18. When the output
- //hex file of this project is programmed with the bootloader, these sections do not
- //get bootloaded (as they overlap the bootloader space). If the output hex file is not
- //programmed using the bootloader, then the below goto instructions do get programmed,
- //and the hex file still works like normal. The below section is only required to fix this
- //scenario.
- #pragma code HIGH_INTERRUPT_VECTOR = 0x08
- void High_ISR (void)
- {
- _asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm
- }
- #pragma code LOW_INTERRUPT_VECTOR = 0x18
- void Low_ISR (void)
- {
- _asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm
- }
- #endif //end of "#if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)||defined(PROGRAMMABLE_WITH_USB_LEGACY_CUSTOM_CLASS_BOOTLOADER)"
- #pragma code
-
-
- //These are your actual interrupt handling routines.
- #pragma interrupt YourHighPriorityISRCode
- void YourHighPriorityISRCode()
- {
- //Check which interrupt flag caused the interrupt.
- //Service the interrupt
- //Clear the interrupt flag
- //Etc.
- #if defined(USB_INTERRUPT)
- USBDeviceTasks();
- #endif
-
- } //This return will be a "retfie fast", since this is in a #pragma interrupt section
- #pragma interruptlow YourLowPriorityISRCode
- void YourLowPriorityISRCode()
- {
- //Check which interrupt flag caused the interrupt.
- //Service the interrupt
- //Clear the interrupt flag
- //Etc.
-
- } //This return will be a "retfie", since this is in a #pragma interruptlow section
- #elif defined(__C30__)
- #if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)
- /*
- * ISR JUMP TABLE
- *
- * It is necessary to define jump table as a function because C30 will
- * not store 24-bit wide values in program memory as variables.
- *
- * This function should be stored at an address where the goto instructions
- * line up with the remapped vectors from the bootloader's linker script.
- *
- * For more information about how to remap the interrupt vectors,
- * please refer to AN1157. An example is provided below for the T2
- * interrupt with a bootloader ending at address 0x1400
- */
- // void __attribute__ ((address(0x1404))) ISRTable(){
- //
- // asm("reset"); //reset instruction to prevent runaway code
- // asm("goto %0"::"i"(&_T2Interrupt)); //T2Interrupt's address
- // }
- #endif
- #endif
- /** DECLARATIONS ***************************************************/
- #pragma code
- /******************************************************************************
- * Function: void main(void)
- *
- * PreCondition: None
- *
- * Input: None
- *
- * Output: None
- *
- * Side Effects: None
- *
- * Overview: Main program entry point.
- *
- * Note: None
- *******************************************************************/
- #if defined(__18CXX)
- void main(void)
- #else
- int main(void)
- #endif
- {
- InitializeSystem();
- #if defined(USB_INTERRUPT)
- USBDeviceAttach();
- #endif
- while(1)
- {
- #if defined(USB_POLLING)
- // Check bus status and service USB interrupts.
- USBDeviceTasks(); // Interrupt or polling method. If using polling, must call
- // this function periodically. This function will take care
- // of processing and responding to SETUP transactions
- // (such as during the enumeration process when you first
- // plug in). USB hosts require that USB devices should accept
- // and process SETUP packets in a timely fashion. Therefore,
- // when using polling, this function should be called
- // frequently (such as once about every 100 microseconds) at any
- // time that a SETUP packet might reasonably be expected to
- // be sent by the host to your device. In most cases, the
- // USBDeviceTasks() function does not take very long to
- // execute (~50 instruction cycles) before it returns.
- #endif
-
- // Application-specific tasks.
- // Application related code may be added here, or in the ProcessIO() function.
- Benchmark_ProcessIO();
- }//end while
- }//end main
- /********************************************************************
- * Function: static void InitializeSystem(void)
- *
- * PreCondition: None
- *
- * Input: None
- *
- * Output: None
- *
- * Side Effects: None
- *
- * Overview: InitializeSystem is a centralize initialization
- * routine. All required USB initialization routines
- * are called from here.
- *
- * User application initialization routine should
- * also be called from here.
- *
- * Note: None
- *******************************************************************/
- static void InitializeSystem(void)
- {
- #if (defined(__18CXX) & !defined(PIC18F87J50_PIM))
- ADCON1 |= 0x0F; // Default all pins to digital
- #elif defined(__C30__)
- AD1PCFGL = 0xFFFF;
- #elif defined(__C32__)
- AD1PCFG = 0xFFFF;
- #endif
- #if defined(PIC18F87J50_PIM) || defined(PIC18F46J50_PIM)
- //On the PIC18F87J50 Family of USB microcontrollers, the PLL will not power up and be enabled
- //by default, even if a PLL enabled oscillator configuration is selected (such as HS+PLL).
- //This allows the device to power up at a lower initial operating frequency, which can be
- //advantageous when powered from a source which is not gauranteed to be adequate for 48MHz
- //operation. On these devices, user firmware needs to manually set the OSCTUNE<PLLEN> bit to
- //power up the PLL.
- {
- unsigned int pll_startup_counter = 600;
- OSCTUNEbits.PLLEN = 1; //Enable the PLL and wait 2+ms until the PLL locks before enabling USB module
- while(pll_startup_counter--);
- }
- //Device switches over automatically to PLL output after PLL is locked and ready.
- #endif
- #if defined(PIC18F87J50_PIM)
- //Configure all I/O pins to use digital input buffers. The PIC18F87J50 Family devices
- //use the ANCONx registers to control this, which is different from other devices which
- //use the ADCON1 register for this purpose.
- WDTCONbits.ADSHR = 1; // Select alternate SFR location to access ANCONx registers
- ANCON0 = 0xFF; // Default all pins to digital
- ANCON1 = 0xFF; // Default all pins to digital
- WDTCONbits.ADSHR = 0; // Select normal SFR locations
- #endif
- #if defined(PIC18F46J50_PIM)
- //Configure all I/O pins to use digital input buffers. The PIC18F87J50 Family devices
- //use the ANCONx registers to control this, which is different from other devices which
- //use the ADCON1 register for this purpose.
- ANCON0 = 0xFF; // Default all pins to digital
- ANCON1 = 0xFF; // Default all pins to digital
- #endif
-
- #if defined(PIC24FJ64GB004_PIM)
- //On the PIC24FJ64GB004 Family of USB microcontrollers, the PLL will not power up and be enabled
- //by default, even if a PLL enabled oscillator configuration is selected (such as HS+PLL).
- //This allows the device to power up at a lower initial operating frequency, which can be
- //advantageous when powered from a source which is not gauranteed to be adequate for 32MHz
- //operation. On these devices, user firmware needs to manually set the CLKDIV<PLLEN> bit to
- //power up the PLL.
- {
- unsigned int pll_startup_counter = 600;
- CLKDIVbits.PLLEN = 1;
- while(pll_startup_counter--);
- }
- //Device switches over automatically to PLL output after PLL is locked and ready.
- #endif
- // The USB specifications require that USB peripheral devices must never source
- // current onto the Vbus pin. Additionally, USB peripherals should not source
- // current on D+ or D- when the host/hub is not actively powering the Vbus line.
- // When designing a self powered (as opposed to bus powered) USB peripheral
- // device, the firmware should make sure not to turn on the USB module and D+
- // or D- pull up resistor unless Vbus is actively powered. Therefore, the
- // firmware needs some means to detect when Vbus is being powered by the host.
- // A 5V tolerant I/O pin can be connected to Vbus (through a resistor), and
- // can be used to detect when Vbus is high (host actively powering), or low
- // (host is shut down or otherwise not supplying power). The USB firmware
- // can then periodically poll this I/O pin to know when it is okay to turn on
- // the USB module/D+/D- pull up resistor. When designing a purely bus powered
- // peripheral device, it is not possible to source current on D+ or D- when the
- // host is not actively providing power on Vbus. Therefore, implementing this
- // bus sense feature is optional. This firmware can be made to use this bus
- // sense feature by making sure "USE_USB_BUS_SENSE_IO" has been defined in the
- // HardwareProfile.h file.
- #if defined(USE_USB_BUS_SENSE_IO)
- tris_usb_bus_sense = INPUT_PIN; // See HardwareProfile.h
- #endif
-
- // If the host PC sends a GetStatus (device) request, the firmware must respond
- // and let the host know if the USB peripheral device is currently bus powered
- // or self powered. See chapter 9 in the official USB specifications for details
- // regarding this request. If the peripheral device is capable of being both
- // self and bus powered, it should not return a hard coded value for this request.
- // Instead, firmware should check if it is currently self or bus powered, and
- // respond accordingly. If the hardware has been configured like demonstrated
- // on the PICDEM FS USB Demo Board, an I/O pin can be polled to determine the
- // currently selected power source. On the PICDEM FS USB Demo Board, "RA2"
- // is used for this purpose. If using this feature, make sure "USE_SELF_POWER_SENSE_IO"
- // has been defined in HardwareProfile.h, and that an appropriate I/O pin has been mapped
- // to it in HardwareProfile.h.
- #if defined(USE_SELF_POWER_SENSE_IO)
- tris_self_power = INPUT_PIN; // See HardwareProfile.h
- #endif
- /*
- USBGenericOutHandle = 0;
- USBGenericInHandle = 0;
- */
- UserInit(); //Application related initialization. See user.c
- USBDeviceInit(); //usb_device.c. Initializes USB module SFRs and firmware
- //variables to known states.
- }//end InitializeSystem
- void UserInit(void)
- {
- mInitAllLEDs();
- mInitAllSwitches();
- blinkStatusValid = TRUE; //Blink the normal USB state on the LEDs.
- Benchmark_Init();
- }//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)
- {
- //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
- {
- 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--;
- #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(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
- // ******************************************************************************************************
- // ************** USB Callback Functions ****************************************************************
- // ******************************************************************************************************
- // The USB firmware stack will call the callback functions USBCBxxx() in response to certain USB related
- // events. For example, if the host PC is powering down, it will stop sending out Start of Frame (SOF)
- // packets to your device. In response to this, all USB devices are supposed to decrease their power
- // consumption from the USB Vbus to <2.5mA each. The USB module detects this condition (which according
- // to the USB specifications is 3+ms of no bus activity/SOF packets) and then calls the USBCBSuspend()
- // function. You should modify these callback functions to take appropriate actions for each of these
- // conditions. For example, in the USBCBSuspend(), you may wish to add code that will decrease power
- // consumption from Vbus to <2.5mA (such as by clock switching, turning off LEDs, putting the
- // microcontroller to sleep, etc.). Then, in the USBCBWakeFromSuspend() function, you may then wish to
- // add code that undoes the power saving things done in the USBCBSuspend() function.
- // The USBCBSendResume() function is special, in that the USB stack will not automatically call this
- // function. This function is meant to be called from the application firmware instead. See the
- // additional comments near the function.
- /******************************************************************************
- * Function: void USBCBSuspend(void)
- *
- * PreCondition: None
- *
- * Input: None
- *
- * Output: None
- *
- * Side Effects: None
- *
- * Overview: Call back that is invoked when a USB suspend is detected
- *
- * Note: None
- *****************************************************************************/
- void USBCBSuspend(void)
- {
- //Example power saving code. Insert appropriate code here for the desired
- //application behavior. If the microcontroller will be put to sleep, a
- //process similar to that shown below may be used:
-
- //ConfigureIOPinsForLowPower();
- //SaveStateOfAllInterruptEnableBits();
- //DisableAllInterruptEnableBits();
- //EnableOnlyTheInterruptsWhichWillBeUsedToWakeTheMicro(); //should enable at least USBActivityIF as a wake source
- //Sleep();
- //RestoreStateOfAllPreviouslySavedInterruptEnableBits(); //Preferrably, this should be done in the USBCBWakeFromSuspend() function instead.
- //RestoreIOPinsToNormal(); //Preferrably, this should be done in the USBCBWakeFromSuspend() function instead.
- //IMPORTANT NOTE: Do not clear the USBActivityIF (ACTVIF) bit here. This bit is
- //cleared inside the usb_device.c file. Clearing USBActivityIF here will cause
- //things to not work as intended.
-
- #if defined(__C30__)
- #if 0
- U1EIR = 0xFFFF;
- U1IR = 0xFFFF;
- U1OTGIR = 0xFFFF;
- IFS5bits.USB1IF = 0;
- IEC5bits.USB1IE = 1;
- U1OTGIEbits.ACTVIE = 1;
- U1OTGIRbits.ACTVIF = 1;
- Sleep();
- #endif
- #endif
- }
- /******************************************************************************
- * Function: void _USB1Interrupt(void)
- *
- * PreCondition: None
- *
- * Input: None
- *
- * Output: None
- *
- * Side Effects: None
- *
- * Overview: This function is called when the USB interrupt bit is set
- * In this example the interrupt is only used when the device
- * goes to sleep when it receives a USB suspend command
- *
- * Note: None
- *****************************************************************************/
- #if 0
- void __attribute__ ((interrupt)) _USB1Interrupt(void)
- {
- #if !defined(self_powered)
- if(U1OTGIRbits.ACTVIF)
- {
- IEC5bits.USB1IE = 0;
- U1OTGIEbits.ACTVIE = 0;
- IFS5bits.USB1IF = 0;
-
- //USBClearInterruptFlag(USBActivityIFReg,USBActivityIFBitNum);
- USBClearInterruptFlag(USBIdleIFReg,USBIdleIFBitNum);
- //USBSuspendControl = 0;
- }
- #endif
- }
- #endif
- /******************************************************************************
- * Function: void USBCBWakeFromSuspend(void)
- *
- * PreCondition: None
- *
- * Input: None
- *
- * Output: None
- *
- * Side Effects: None
- *
- * Overview: The host may put USB peripheral devices in low power
- * suspend mode (by "sending" 3+ms of idle). Once in suspend
- * mode, the host may wake the device back up by sending non-
- * idle state signalling.
- *
- * This call back is invoked when a wakeup from USB suspend
- * is detected.
- *
- * Note: None
- *****************************************************************************/
- void USBCBWakeFromSuspend(void)
- {
- // If clock switching or other power savings measures were taken when
- // executing the USBCBSuspend() function, now would be a good time to
- // switch back to normal full power run mode conditions. The host allows
- // a few milliseconds of wakeup time, after which the device must be
- // fully back to normal, and capable of receiving and processing USB
- // packets. In order to do this, the USB module must receive proper
- // clocking (IE: 48MHz clock must be available to SIE for full speed USB
- // operation).
- }
- /********************************************************************
- * Function: void USBCB_SOF_Handler(void)
- *
- * PreCondition: None
- *
- * Input: None
- *
- * Output: None
- *
- * Side Effects: None
- *
- * Overview: The USB host sends out a SOF packet to full-speed
- * devices every 1 ms. This interrupt may be useful
- * for isochronous pipes. End designers should
- * implement callback routine as necessary.
- *
- * Note: None
- *******************************************************************/
- void USBCB_SOF_Handler(void)
- {
- // No need to clear UIRbits.SOFIF to 0 here.
- // Callback caller is already doing that.
- }
- /*******************************************************************
- * Function: void USBCBErrorHandler(void)
- *
- * PreCondition: None
- *
- * Input: None
- *
- * Output: None
- *
- * Side Effects: None
- *
- * Overview: The purpose of this callback is mainly for
- * debugging during development. Check UEIR to see
- * which error causes the interrupt.
- *
- * Note: None
- *******************************************************************/
- void USBCBErrorHandler(void)
- {
- // No need to clear UEIR to 0 here.
- // Callback caller is already doing that.
- // Typically, user firmware does not need to do anything special
- // if a USB error occurs. For example, if the host sends an OUT
- // packet to your device, but the packet gets corrupted (ex:
- // because of a bad connection, or the user unplugs the
- // USB cable during the transmission) this will typically set
- // one or more USB error interrupt flags. Nothing specific
- // needs to be done however, since the SIE will automatically
- // send a "NAK" packet to the host. In response to this, the
- // host will normally retry to send the packet again, and no
- // data loss occurs. The system will typically recover
- // automatically, without the need for application firmware
- // intervention.
-
- // Nevertheless, this callback function is provided, such as
- // for debugging purposes.
- }
- /*******************************************************************
- * Function: void USBCBCheckOtherReq(void)
- *
- * PreCondition: None
- *
- * Input: None
- *
- * Output: None
- *
- * Side Effects: None
- *
- * Overview: When SETUP packets arrive from the host, some
- * firmware must process the request and respond
- * appropriately to fulfill the request. Some of
- * the SETUP packets will be for standard
- * USB "chapter 9" (as in, fulfilling chapter 9 of
- * the official USB specifications) requests, while
- * others may be specific to the USB device class
- * that is being implemented. For example, a HID
- * class device needs to be able to respond to
- * "GET REPORT" type of requests. This
- * is not a standard USB chapter 9 request, and
- * therefore not handled by usb_device.c. Instead
- * this request should be handled by class specific
- * firmware, such as that contained in usb_function_hid.c.
- *
- * Note: None
- *****************************************************************************
- void USBCBCheckOtherReq(void)
- {
- }//end
- */
- /*******************************************************************
- * Function: void USBCBStdSetDscHandler(void)
- *
- * PreCondition: None
- *
- * Input: None
- *
- * Output: None
- *
- * Side Effects: None
- *
- * Overview: The USBCBStdSetDscHandler() callback function is
- * called when a SETUP, bRequest: SET_DESCRIPTOR request
- * arrives. Typically SET_DESCRIPTOR requests are
- * not used in most applications, and it is
- * optional to support this type of request.
- *
- * Note: None
- *****************************************************************************/
- void USBCBStdSetDscHandler(void)
- {
- // Must claim session ownership if supporting this request
- }//end
- /******************************************************************************
- * Function: void USBCBInitEP(void)
- *
- * PreCondition: None
- *
- * Input: None
- *
- * Output: None
- *
- * Side Effects: None
- *
- * Overview: This function is called when the device becomes
- * initialized, which occurs after the host sends a
- * SET_CONFIGURATION (wValue not = 0) request. This
- * callback function should initialize the endpoints
- * for the device's usage according to the current
- * configuration.
- *
- * Note: None
- *****************************************************************************
- void USBCBInitEP(void)
- {
- USBEnableEndpoint(USBGEN_EP_NUM,USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
- USBGenericOutHandle = USBGenRead(USBGEN_EP_NUM,(BYTE*)&OUTPacket,USBGEN_EP_SIZE);
- }
- */
- /********************************************************************
- * Function: void USBCBSendResume(void)
- *
- * PreCondition: None
- *
- * Input: None
- *
- * Output: None
- *
- * Side Effects: None
- *
- * Overview: The USB specifications allow some types of USB
- * peripheral devices to wake up a host PC (such
- * as if it is in a low power suspend to RAM state).
- * This can be a very useful feature in some
- * USB applications, such as an Infrared remote
- * control receiver. If a user presses the "power"
- * button on a remote control, it is nice that the
- * IR receiver can detect this signalling, and then
- * send a USB "command" to the PC to wake up.
- *
- * The USBCBSendResume() "callback" function is used
- * to send this special USB signalling which wakes
- * up the PC. This function may be called by
- * application firmware to wake up the PC. This
- * function should only be called when:
- *
- * 1. The USB driver used on the host PC supports
- * the remote wakeup capability.
- * 2. The USB configuration descriptor indicates
- * the device is remote wakeup capable in the
- * bmAttributes field.
- * 3. The USB host PC is currently sleeping,
- * and has previously sent your device a SET
- * FEATURE setup packet which "armed" the
- * remote wakeup capability.
- *
- * This callback should send a RESUME signal that
- * has the period of 1-15ms.
- *
- * Note: Interrupt vs. Polling
- * -Primary clock
- * -Secondary clock ***** MAKE NOTES ABOUT THIS *******
- * > Can switch to primary first by calling USBCBWakeFromSuspend()
-
- * The modifiable section in this routine should be changed
- * to meet the application needs. Current implementation
- * temporary blocks other functions from executing for a
- * period of 1-13 ms depending on the core frequency.
- *
- * According to USB 2.0 specification section 7.1.7.7,
- * "The remote wakeup device must hold the resume signaling
- * for at lest 1 ms but for no more than 15 ms."
- * The idea here is to use a delay counter loop, using a
- * common value that would work over a wide range of core
- * frequencies.
- * That value selected is 1800. See table below:
- * ==========================================================
- * Core Freq(MHz) MIP RESUME Signal Period (ms)
- * ==========================================================
- * 48 12 1.05
- * 4 1 12.6
- * ==========================================================
- * * These timing could be incorrect when using code
- * optimization or extended instruction mode,
- * or when having other interrupts enabled.
- * Make sure to verify using the MPLAB SIM's Stopwatch
- * and verify the actual signal on an oscilloscope.
- *******************************************************************/
- void USBCBSendResume(void)
- {
- static WORD delay_count;
-
- USBResumeControl = 1; // Start RESUME signaling
-
- delay_count = 1800U; // Set RESUME line for 1-13 ms
- do
- {
- delay_count--;
- }while(delay_count);
- USBResumeControl = 0;
- }
- /*******************************************************************
- * Function: BOOL USER_USB_CALLBACK_EVENT_HANDLER(
- * USB_EVENT event, void *pdata, WORD size)
- *
- * PreCondition: None
- *
- * Input: USB_EVENT event - the type of event
- * void *pdata - pointer to the event data
- * WORD size - size of the event data
- *
- * Output: None
- *
- * Side Effects: None
- *
- * Overview: This function is called from the USB stack to
- * notify a user application that a USB event
- * occured. This callback is in interrupt context
- * when the USB_INTERRUPT option is selected.
- *
- * Note: None
- *******************************************************************/
- BOOL USER_USB_CALLBACK_EVENT_HANDLER(USB_EVENT event, void *pdata, WORD size)
- {
- switch(event)
- {
- case EVENT_CONFIGURED:
- USBCBInitEP();
- break;
- case EVENT_SET_DESCRIPTOR:
- USBCBStdSetDscHandler();
- break;
- case EVENT_EP0_REQUEST:
- USBCBCheckOtherReq();
- break;
- case EVENT_SOF:
- USBCB_SOF_Handler();
- break;
- case EVENT_SUSPEND:
- USBCBSuspend();
- break;
- case EVENT_RESUME:
- USBCBWakeFromSuspend();
- break;
- case EVENT_BUS_ERROR:
- USBCBErrorHandler();
- break;
- case EVENT_TRANSFER:
- Nop();
- break;
- default:
- break;
- }
- return TRUE;
- }
- /** EOF main.c ***************************************************************/
|