main.c 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215
  1. /********************************************************************
  2. FileName: main.c
  3. Dependencies: See INCLUDES section
  4. Processor: PIC18 or PIC24 USB Microcontrollers
  5. Hardware: The code is natively intended to be used on the following
  6. hardware platforms: PICDEM™ FS USB Demo Board,
  7. PIC18F87J50 FS USB Plug-In Module, or
  8. Explorer 16 + PIC24 USB PIM. The firmware may be
  9. modified for use on other USB platforms by editing the
  10. HardwareProfile.h file.
  11. Complier: Microchip C18 (for PIC18) or C30 (for PIC24)
  12. Company: Microchip Technology, Inc.
  13. Software License Agreement:
  14. The software supplied herewith by Microchip Technology Incorporated
  15. (the “Company”) for its PIC® Microcontroller is intended and
  16. supplied to you, the Company’s customer, for use solely and
  17. exclusively on Microchip PIC Microcontroller products. The
  18. software is owned by the Company and/or its supplier, and is
  19. protected under applicable copyright laws. All rights are reserved.
  20. Any use in violation of the foregoing restrictions may subject the
  21. user to criminal sanctions under applicable laws, as well as to
  22. civil liability for the breach of the terms and conditions of this
  23. license.
  24. THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
  25. WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
  26. TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  27. PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
  28. IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
  29. CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
  30. ********************************************************************
  31. File Description:
  32. Change History:
  33. Rev Date Description
  34. 1.0 11/19/2004 Initial release
  35. 2.1 02/26/2007 Updated for simplicity and to use common
  36. coding style
  37. ********************************************************************/
  38. /** INCLUDES *******************************************************/
  39. #include "USB/usb.h"
  40. #include "USB/usb_function_generic.h"
  41. #include "HardwareProfile.h"
  42. //#include "Compiler.h"
  43. //#include "GenericTypeDefs.h"
  44. //#include "USB/usb_device.h"
  45. //#include "USB/usb.h"
  46. //#include "usb_config.h"
  47. #include "Benchmark.h"
  48. /** CONFIGURATION **************************************************/
  49. #if defined(PICDEM_FS_USB) // Configuration bits for PICDEM FS USB Demo Board (based on PIC18F4550)
  50. #pragma config PLLDIV = 5 // (20 MHz crystal on PICDEM FS USB board)
  51. #pragma config CPUDIV = OSC1_PLL2
  52. #pragma config USBDIV = 2 // Clock source from 96MHz PLL/2
  53. #pragma config FOSC = HSPLL_HS
  54. #pragma config FCMEN = OFF
  55. #pragma config IESO = OFF
  56. #pragma config PWRT = OFF
  57. #pragma config BOR = ON
  58. #pragma config BORV = 3
  59. #pragma config VREGEN = ON //USB Voltage Regulator
  60. #pragma config WDT = OFF
  61. #pragma config WDTPS = 32768
  62. #pragma config MCLRE = ON
  63. #pragma config LPT1OSC = OFF
  64. #pragma config PBADEN = OFF
  65. // #pragma config CCP2MX = ON
  66. #pragma config STVREN = ON
  67. #pragma config LVP = OFF
  68. // #pragma config ICPRT = OFF // Dedicated In-Circuit Debug/Programming
  69. #pragma config XINST = OFF // Extended Instruction Set
  70. #pragma config CP0 = OFF
  71. #pragma config CP1 = OFF
  72. // #pragma config CP2 = OFF
  73. // #pragma config CP3 = OFF
  74. #pragma config CPB = OFF
  75. // #pragma config CPD = OFF
  76. #pragma config WRT0 = OFF
  77. #pragma config WRT1 = OFF
  78. // #pragma config WRT2 = OFF
  79. // #pragma config WRT3 = OFF
  80. #pragma config WRTB = OFF // Boot Block Write Protection
  81. #pragma config WRTC = OFF
  82. // #pragma config WRTD = OFF
  83. #pragma config EBTR0 = OFF
  84. #pragma config EBTR1 = OFF
  85. // #pragma config EBTR2 = OFF
  86. // #pragma config EBTR3 = OFF
  87. #pragma config EBTRB = OFF
  88. #elif defined(PIC18F87J50_PIM) // Configuration bits for PIC18F87J50 FS USB Plug-In Module board
  89. #pragma config XINST = OFF // Extended instruction set
  90. #pragma config STVREN = ON // Stack overflow reset
  91. #pragma config PLLDIV = 3 // (12 MHz crystal used on this board)
  92. #pragma config WDTEN = OFF // Watch Dog Timer (WDT)
  93. #pragma config CP0 = OFF // Code protect
  94. #pragma config CPUDIV = OSC1 // OSC1 = divide by 1 mode
  95. #pragma config IESO = OFF // Internal External (clock) Switchover
  96. #pragma config FCMEN = OFF // Fail Safe Clock Monitor
  97. #pragma config FOSC = HSPLL // Firmware must also set OSCTUNE<PLLEN> to start PLL!
  98. #pragma config WDTPS = 32768
  99. // #pragma config WAIT = OFF // Commented choices are
  100. // #pragma config BW = 16 // only available on the
  101. // #pragma config MODE = MM // 80 pin devices in the
  102. // #pragma config EASHFT = OFF // family.
  103. #pragma config MSSPMSK = MSK5
  104. // #pragma config PMPMX = DEFAULT
  105. // #pragma config ECCPMX = DEFAULT
  106. #pragma config CCP2MX = DEFAULT
  107. #elif defined(PIC18F46J50_PIM)
  108. #pragma config WDTEN = OFF //WDT disabled (enabled by SWDTEN bit)
  109. #pragma config PLLDIV = 3 //Divide by 3 (12 MHz oscillator input)
  110. #pragma config STVREN = ON //stack overflow/underflow reset enabled
  111. #pragma config XINST = OFF //Extended instruction set disabled
  112. #pragma config CPUDIV = OSC1 //No CPU system clock divide
  113. #pragma config CP0 = OFF //Program memory is not code-protected
  114. #pragma config OSC = HSPLL //HS oscillator, PLL enabled, HSPLL used by USB
  115. #pragma config T1DIG = ON //Sec Osc clock source may be selected
  116. #pragma config LPT1OSC = OFF //high power Timer1 mode
  117. #pragma config FCMEN = OFF //Fail-Safe Clock Monitor disabled
  118. #pragma config IESO = OFF //Two-Speed Start-up disabled
  119. #pragma config WDTPS = 32768 //1:32768
  120. #pragma config DSWDTOSC = INTOSCREF //DSWDT uses INTOSC/INTRC as clock
  121. #pragma config RTCOSC = T1OSCREF //RTCC uses T1OSC/T1CKI as clock
  122. #pragma config DSBOREN = OFF //Zero-Power BOR disabled in Deep Sleep
  123. #pragma config DSWDTEN = OFF //Disabled
  124. #pragma config DSWDTPS = 8192 //1:8,192 (8.5 seconds)
  125. #pragma config IOL1WAY = OFF //IOLOCK bit can be set and cleared
  126. #pragma config MSSP7B_EN = MSK7 //7 Bit address masking
  127. #pragma config WPFP = PAGE_1 //Write Protect Program Flash Page 0
  128. #pragma config WPEND = PAGE_0 //Start protection at page 0
  129. #pragma config WPCFG = OFF //Write/Erase last page protect Disabled
  130. #pragma config WPDIS = OFF //WPFP[5:0], WPEND, and WPCFG bits ignored
  131. #elif defined(LOW_PIN_COUNT_USB_DEVELOPMENT_KIT)
  132. // PIC18F14K50
  133. #pragma config CPUDIV = NOCLKDIV
  134. #pragma config USBDIV = OFF
  135. #pragma config FOSC = HS
  136. #pragma config PLLEN = ON
  137. #pragma config FCMEN = OFF
  138. #pragma config IESO = OFF
  139. #pragma config PWRTEN = OFF
  140. #pragma config BOREN = OFF
  141. #pragma config BORV = 30
  142. #pragma config WDTEN = OFF
  143. #pragma config WDTPS = 32768
  144. #pragma config MCLRE = OFF
  145. #pragma config HFOFST = OFF
  146. #pragma config STVREN = ON
  147. #pragma config LVP = OFF
  148. #pragma config XINST = OFF
  149. #pragma config BBSIZ = OFF
  150. #pragma config CP0 = OFF
  151. #pragma config CP1 = OFF
  152. #pragma config CPB = OFF
  153. #pragma config WRT0 = OFF
  154. #pragma config WRT1 = OFF
  155. #pragma config WRTB = OFF
  156. #pragma config WRTC = OFF
  157. #pragma config EBTR0 = OFF
  158. #pragma config EBTR1 = OFF
  159. #pragma config EBTRB = OFF
  160. #elif defined(EXPLORER_16)
  161. #ifdef __PIC24FJ256GB110__ //Defined by MPLAB when using 24FJ256GB110 device
  162. _CONFIG1( JTAGEN_OFF & GCP_OFF & GWRP_OFF & COE_OFF & FWDTEN_OFF & ICS_PGx2)
  163. _CONFIG2( 0xF7FF & IESO_OFF & FCKSM_CSDCMD & OSCIOFNC_ON & POSCMOD_HS & FNOSC_PRIPLL & PLLDIV_DIV2 & IOL1WAY_ON)
  164. #elif defined(__PIC24FJ64GB004__)
  165. _CONFIG1(WDTPS_PS1 & FWPSA_PR32 & WINDIS_OFF & FWDTEN_OFF & ICS_PGx1 & GWRP_OFF & GCP_OFF & JTAGEN_OFF)
  166. _CONFIG2(POSCMOD_HS & I2C1SEL_PRI & IOL1WAY_OFF & OSCIOFNC_ON & FCKSM_CSDCMD & FNOSC_PRIPLL & PLL96MHZ_ON & PLLDIV_DIV2 & IESO_ON)
  167. _CONFIG3(WPFP_WPFP0 & SOSCSEL_SOSC & WUTSEL_LEG & WPDIS_WPDIS & WPCFG_WPCFGDIS & WPEND_WPENDMEM)
  168. _CONFIG4(DSWDTPS_DSWDTPS3 & DSWDTOSC_LPRC & RTCOSC_SOSC & DSBOREN_OFF & DSWDTEN_OFF)
  169. #elif defined(__32MX460F512L__)
  170. #pragma config UPLLEN = ON // USB PLL Enabled
  171. #pragma config FPLLMUL = MUL_15 // PLL Multiplier
  172. #pragma config UPLLIDIV = DIV_2 // USB PLL Input Divider
  173. #pragma config FPLLIDIV = DIV_2 // PLL Input Divider
  174. #pragma config FPLLODIV = DIV_1 // PLL Output Divider
  175. #pragma config FPBDIV = DIV_1 // Peripheral Clock divisor
  176. #pragma config FWDTEN = OFF // Watchdog Timer
  177. #pragma config WDTPS = PS1 // Watchdog Timer Postscale
  178. #pragma config FCKSM = CSDCMD // Clock Switching & Fail Safe Clock Monitor
  179. #pragma config OSCIOFNC = OFF // CLKO Enable
  180. #pragma config POSCMOD = HS // Primary Oscillator
  181. #pragma config IESO = OFF // Internal/External Switch-over
  182. #pragma config FSOSCEN = OFF // Secondary Oscillator Enable (KLO was off)
  183. #pragma config FNOSC = PRIPLL // Oscillator Selection
  184. #pragma config CP = OFF // Code Protect
  185. #pragma config BWP = OFF // Boot Flash Write Protect
  186. #pragma config PWP = OFF // Program Flash Write Protect
  187. #pragma config ICESEL = ICS_PGx2 // ICE/ICD Comm Channel Select
  188. #pragma config DEBUG = ON // Background Debugger Enable
  189. #else
  190. #error No hardware board defined, see "HardwareProfile.h" and __FILE__
  191. #endif
  192. #elif defined(PIC24F_STARTER_KIT)
  193. _CONFIG1( JTAGEN_OFF & GCP_OFF & GWRP_OFF & COE_OFF & FWDTEN_OFF & ICS_PGx2)
  194. _CONFIG2( 0xF7FF & IESO_OFF & FCKSM_CSDCMD & OSCIOFNC_ON & POSCMOD_HS & FNOSC_PRIPLL & PLLDIV_DIV3 & IOL1WAY_ON)
  195. #elif defined(PIC32_USB_STARTER_KIT)
  196. #pragma config UPLLEN = ON // USB PLL Enabled
  197. #pragma config FPLLMUL = MUL_15 // PLL Multiplier
  198. #pragma config UPLLIDIV = DIV_2 // USB PLL Input Divider
  199. #pragma config FPLLIDIV = DIV_2 // PLL Input Divider
  200. #pragma config FPLLODIV = DIV_1 // PLL Output Divider
  201. #pragma config FPBDIV = DIV_1 // Peripheral Clock divisor
  202. #pragma config FWDTEN = OFF // Watchdog Timer
  203. #pragma config WDTPS = PS1 // Watchdog Timer Postscale
  204. #pragma config FCKSM = CSDCMD // Clock Switching & Fail Safe Clock Monitor
  205. #pragma config OSCIOFNC = OFF // CLKO Enable
  206. #pragma config POSCMOD = HS // Primary Oscillator
  207. #pragma config IESO = OFF // Internal/External Switch-over
  208. #pragma config FSOSCEN = OFF // Secondary Oscillator Enable (KLO was off)
  209. #pragma config FNOSC = PRIPLL // Oscillator Selection
  210. #pragma config CP = OFF // Code Protect
  211. #pragma config BWP = OFF // Boot Flash Write Protect
  212. #pragma config PWP = OFF // Program Flash Write Protect
  213. #pragma config ICESEL = ICS_PGx2 // ICE/ICD Comm Channel Select
  214. #pragma config DEBUG = ON // Background Debugger Enable
  215. #elif defined(BREADBOARD)
  216. #if defined(__PIC24FJ64GB002__)
  217. _CONFIG1(WDTPS_PS1 & FWPSA_PR32 & WINDIS_OFF & FWDTEN_OFF & ICS_PGx3 & GWRP_OFF & GCP_OFF & JTAGEN_OFF)
  218. _CONFIG2(POSCMOD_HS & I2C1SEL_PRI & IOL1WAY_OFF & OSCIOFNC_OFF & FCKSM_CSDCMD & FNOSC_PRIPLL & PLL96MHZ_ON & PLLDIV_DIV3 & IESO_ON)
  219. _CONFIG3(WPFP_WPFP0 & SOSCSEL_SOSC & WUTSEL_LEG & WPDIS_WPDIS & WPCFG_WPCFGDIS & WPEND_WPENDMEM)
  220. _CONFIG4(DSWDTPS_DSWDTPS3 & DSWDTOSC_LPRC & RTCOSC_LPRC & DSBOREN_OFF & DSWDTEN_OFF)
  221. //_CONFIG1(WDTPS_PS1 & FWPSA_PR32 & WINDIS_OFF & FWDTEN_OFF & ICS_PGx3 & GWRP_OFF & GCP_OFF & JTAGEN_OFF)
  222. //_CONFIG2(POSCMOD_NONE & I2C1SEL_PRI & IOL1WAY_OFF & OSCIOFNC_OFF & FCKSM_CSDCMD & FNOSC_FRCPLL & PLL96MHZ_ON & PLLDIV_NODIV & IESO_ON)
  223. //_CONFIG3(WPFP_WPFP0 & SOSCSEL_SOSC & WUTSEL_LEG & WPDIS_WPDIS & WPCFG_WPCFGDIS & WPEND_WPENDMEM)
  224. //_CONFIG4(DSWDTPS_DSWDTPS3 & DSWDTOSC_LPRC & RTCOSC_SOSC & DSBOREN_OFF & DSWDTEN_OFF)
  225. #else
  226. #error No breadboard device defined, see "HardwareProfile.h" and __FILE__
  227. #endif
  228. #else
  229. #error No hardware board defined, see "HardwareProfile.h"
  230. #endif
  231. /** VARIABLES *****************************************************
  232. #if defined(__18F14K50) || defined(__18F13K50) || defined(__18LF14K50) || defined(__18LF13K50)
  233. #pragma udata usbram2
  234. #elif defined(__18F2455) || defined(__18F2550) || defined(__18F4455) || defined(__18F4550)\
  235. || defined(__18F2458) || defined(__18F2453) || defined(__18F4558) || defined(__18F4553)
  236. #pragma udata USB_VARIABLES=0x500
  237. #elif defined(__18F4450) || defined(__18F2450)
  238. #pragma udata USB_VARIABLES=0x480
  239. #else
  240. #pragma udata
  241. #endif
  242. unsigned char OUTPacket[64]; //User application buffer for receiving and holding OUT packets sent from the host
  243. unsigned char INPacket[64]; //User application buffer for sending IN packets to the host
  244. */
  245. #pragma udata
  246. BOOL blinkStatusValid;
  247. /*
  248. USB_HANDLE USBGenericOutHandle;
  249. USB_HANDLE USBGenericInHandle;
  250. #pragma udata
  251. */
  252. /** PRIVATE PROTOTYPES *********************************************/
  253. static void InitializeSystem(void);
  254. void USBDeviceTasks(void);
  255. void YourHighPriorityISRCode(void);
  256. void YourLowPriorityISRCode(void);
  257. void UserInit(void);
  258. void ProcessIO(void);
  259. void BlinkUSBStatus(void);
  260. /** VECTOR REMAPPING ***********************************************/
  261. #if defined(__18CXX)
  262. //On PIC18 devices, addresses 0x00, 0x08, and 0x18 are used for
  263. //the reset, high priority interrupt, and low priority interrupt
  264. //vectors. However, the current Microchip USB bootloader
  265. //examples are intended to occupy addresses 0x00-0x7FF or
  266. //0x00-0xFFF depending on which bootloader is used. Therefore,
  267. //the bootloader code remaps these vectors to new locations
  268. //as indicated below. This remapping is only necessary if you
  269. //wish to program the hex file generated from this project with
  270. //the USB bootloader. If no bootloader is used, edit the
  271. //usb_config.h file and comment out the following defines:
  272. //#define PROGRAMMABLE_WITH_USB_HID_BOOTLOADER
  273. //#define PROGRAMMABLE_WITH_USB_LEGACY_CUSTOM_CLASS_BOOTLOADER
  274. #if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)
  275. #define REMAPPED_RESET_VECTOR_ADDRESS 0x1000
  276. #define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x1008
  277. #define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS 0x1018
  278. #elif defined(PROGRAMMABLE_WITH_USB_MCHPUSB_BOOTLOADER)
  279. #define REMAPPED_RESET_VECTOR_ADDRESS 0x800
  280. #define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x808
  281. #define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS 0x818
  282. #else
  283. #define REMAPPED_RESET_VECTOR_ADDRESS 0x00
  284. #define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x08
  285. #define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS 0x18
  286. #endif
  287. #if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)||defined(PROGRAMMABLE_WITH_USB_MCHPUSB_BOOTLOADER)
  288. extern void _startup (void); // See c018i.c in your C18 compiler dir
  289. #pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS
  290. void _reset (void)
  291. {
  292. _asm goto _startup _endasm
  293. }
  294. #endif
  295. #pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS
  296. void Remapped_High_ISR (void)
  297. {
  298. _asm goto YourHighPriorityISRCode _endasm
  299. }
  300. #pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS
  301. void Remapped_Low_ISR (void)
  302. {
  303. _asm goto YourLowPriorityISRCode _endasm
  304. }
  305. #if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)||defined(PROGRAMMABLE_WITH_USB_MCHPUSB_BOOTLOADER)
  306. //Note: If this project is built while one of the bootloaders has
  307. //been defined, but then the output hex file is not programmed with
  308. //the bootloader, addresses 0x08 and 0x18 would end up programmed with 0xFFFF.
  309. //As a result, if an actual interrupt was enabled and occured, the PC would jump
  310. //to 0x08 (or 0x18) and would begin executing "0xFFFF" (unprogrammed space). This
  311. //executes as nop instructions, but the PC would eventually reach the REMAPPED_RESET_VECTOR_ADDRESS
  312. //(0x1000 or 0x800, depending upon bootloader), and would execute the "goto _startup". This
  313. //would effective reset the application.
  314. //To fix this situation, we should always deliberately place a
  315. //"goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS" at address 0x08, and a
  316. //"goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS" at address 0x18. When the output
  317. //hex file of this project is programmed with the bootloader, these sections do not
  318. //get bootloaded (as they overlap the bootloader space). If the output hex file is not
  319. //programmed using the bootloader, then the below goto instructions do get programmed,
  320. //and the hex file still works like normal. The below section is only required to fix this
  321. //scenario.
  322. #pragma code HIGH_INTERRUPT_VECTOR = 0x08
  323. void High_ISR (void)
  324. {
  325. _asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm
  326. }
  327. #pragma code LOW_INTERRUPT_VECTOR = 0x18
  328. void Low_ISR (void)
  329. {
  330. _asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm
  331. }
  332. #endif //end of "#if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)||defined(PROGRAMMABLE_WITH_USB_LEGACY_CUSTOM_CLASS_BOOTLOADER)"
  333. #pragma code
  334. //These are your actual interrupt handling routines.
  335. #pragma interrupt YourHighPriorityISRCode
  336. void YourHighPriorityISRCode()
  337. {
  338. //Check which interrupt flag caused the interrupt.
  339. //Service the interrupt
  340. //Clear the interrupt flag
  341. //Etc.
  342. #if defined(USB_INTERRUPT)
  343. USBDeviceTasks();
  344. #endif
  345. } //This return will be a "retfie fast", since this is in a #pragma interrupt section
  346. #pragma interruptlow YourLowPriorityISRCode
  347. void YourLowPriorityISRCode()
  348. {
  349. //Check which interrupt flag caused the interrupt.
  350. //Service the interrupt
  351. //Clear the interrupt flag
  352. //Etc.
  353. } //This return will be a "retfie", since this is in a #pragma interruptlow section
  354. #elif defined(__C30__)
  355. #if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)
  356. /*
  357. * ISR JUMP TABLE
  358. *
  359. * It is necessary to define jump table as a function because C30 will
  360. * not store 24-bit wide values in program memory as variables.
  361. *
  362. * This function should be stored at an address where the goto instructions
  363. * line up with the remapped vectors from the bootloader's linker script.
  364. *
  365. * For more information about how to remap the interrupt vectors,
  366. * please refer to AN1157. An example is provided below for the T2
  367. * interrupt with a bootloader ending at address 0x1400
  368. */
  369. // void __attribute__ ((address(0x1404))) ISRTable(){
  370. //
  371. // asm("reset"); //reset instruction to prevent runaway code
  372. // asm("goto %0"::"i"(&_T2Interrupt)); //T2Interrupt's address
  373. // }
  374. #endif
  375. #endif
  376. /** DECLARATIONS ***************************************************/
  377. #pragma code
  378. /******************************************************************************
  379. * Function: void main(void)
  380. *
  381. * PreCondition: None
  382. *
  383. * Input: None
  384. *
  385. * Output: None
  386. *
  387. * Side Effects: None
  388. *
  389. * Overview: Main program entry point.
  390. *
  391. * Note: None
  392. *******************************************************************/
  393. #if defined(__18CXX)
  394. void main(void)
  395. #else
  396. int main(void)
  397. #endif
  398. {
  399. InitializeSystem();
  400. #if defined(USB_INTERRUPT)
  401. USBDeviceAttach();
  402. #endif
  403. while(1)
  404. {
  405. #if defined(USB_POLLING)
  406. // Check bus status and service USB interrupts.
  407. USBDeviceTasks(); // Interrupt or polling method. If using polling, must call
  408. // this function periodically. This function will take care
  409. // of processing and responding to SETUP transactions
  410. // (such as during the enumeration process when you first
  411. // plug in). USB hosts require that USB devices should accept
  412. // and process SETUP packets in a timely fashion. Therefore,
  413. // when using polling, this function should be called
  414. // frequently (such as once about every 100 microseconds) at any
  415. // time that a SETUP packet might reasonably be expected to
  416. // be sent by the host to your device. In most cases, the
  417. // USBDeviceTasks() function does not take very long to
  418. // execute (~50 instruction cycles) before it returns.
  419. #endif
  420. // Application-specific tasks.
  421. // Application related code may be added here, or in the ProcessIO() function.
  422. Benchmark_ProcessIO();
  423. }//end while
  424. }//end main
  425. /********************************************************************
  426. * Function: static void InitializeSystem(void)
  427. *
  428. * PreCondition: None
  429. *
  430. * Input: None
  431. *
  432. * Output: None
  433. *
  434. * Side Effects: None
  435. *
  436. * Overview: InitializeSystem is a centralize initialization
  437. * routine. All required USB initialization routines
  438. * are called from here.
  439. *
  440. * User application initialization routine should
  441. * also be called from here.
  442. *
  443. * Note: None
  444. *******************************************************************/
  445. static void InitializeSystem(void)
  446. {
  447. #if (defined(__18CXX) & !defined(PIC18F87J50_PIM))
  448. ADCON1 |= 0x0F; // Default all pins to digital
  449. #elif defined(__C30__)
  450. AD1PCFGL = 0xFFFF;
  451. #elif defined(__C32__)
  452. AD1PCFG = 0xFFFF;
  453. #endif
  454. #if defined(PIC18F87J50_PIM) || defined(PIC18F46J50_PIM)
  455. //On the PIC18F87J50 Family of USB microcontrollers, the PLL will not power up and be enabled
  456. //by default, even if a PLL enabled oscillator configuration is selected (such as HS+PLL).
  457. //This allows the device to power up at a lower initial operating frequency, which can be
  458. //advantageous when powered from a source which is not gauranteed to be adequate for 48MHz
  459. //operation. On these devices, user firmware needs to manually set the OSCTUNE<PLLEN> bit to
  460. //power up the PLL.
  461. {
  462. unsigned int pll_startup_counter = 600;
  463. OSCTUNEbits.PLLEN = 1; //Enable the PLL and wait 2+ms until the PLL locks before enabling USB module
  464. while(pll_startup_counter--);
  465. }
  466. //Device switches over automatically to PLL output after PLL is locked and ready.
  467. #endif
  468. #if defined(PIC18F87J50_PIM)
  469. //Configure all I/O pins to use digital input buffers. The PIC18F87J50 Family devices
  470. //use the ANCONx registers to control this, which is different from other devices which
  471. //use the ADCON1 register for this purpose.
  472. WDTCONbits.ADSHR = 1; // Select alternate SFR location to access ANCONx registers
  473. ANCON0 = 0xFF; // Default all pins to digital
  474. ANCON1 = 0xFF; // Default all pins to digital
  475. WDTCONbits.ADSHR = 0; // Select normal SFR locations
  476. #endif
  477. #if defined(PIC18F46J50_PIM)
  478. //Configure all I/O pins to use digital input buffers. The PIC18F87J50 Family devices
  479. //use the ANCONx registers to control this, which is different from other devices which
  480. //use the ADCON1 register for this purpose.
  481. ANCON0 = 0xFF; // Default all pins to digital
  482. ANCON1 = 0xFF; // Default all pins to digital
  483. #endif
  484. #if defined(PIC24FJ64GB004_PIM)
  485. //On the PIC24FJ64GB004 Family of USB microcontrollers, the PLL will not power up and be enabled
  486. //by default, even if a PLL enabled oscillator configuration is selected (such as HS+PLL).
  487. //This allows the device to power up at a lower initial operating frequency, which can be
  488. //advantageous when powered from a source which is not gauranteed to be adequate for 32MHz
  489. //operation. On these devices, user firmware needs to manually set the CLKDIV<PLLEN> bit to
  490. //power up the PLL.
  491. {
  492. unsigned int pll_startup_counter = 600;
  493. CLKDIVbits.PLLEN = 1;
  494. while(pll_startup_counter--);
  495. }
  496. //Device switches over automatically to PLL output after PLL is locked and ready.
  497. #endif
  498. // The USB specifications require that USB peripheral devices must never source
  499. // current onto the Vbus pin. Additionally, USB peripherals should not source
  500. // current on D+ or D- when the host/hub is not actively powering the Vbus line.
  501. // When designing a self powered (as opposed to bus powered) USB peripheral
  502. // device, the firmware should make sure not to turn on the USB module and D+
  503. // or D- pull up resistor unless Vbus is actively powered. Therefore, the
  504. // firmware needs some means to detect when Vbus is being powered by the host.
  505. // A 5V tolerant I/O pin can be connected to Vbus (through a resistor), and
  506. // can be used to detect when Vbus is high (host actively powering), or low
  507. // (host is shut down or otherwise not supplying power). The USB firmware
  508. // can then periodically poll this I/O pin to know when it is okay to turn on
  509. // the USB module/D+/D- pull up resistor. When designing a purely bus powered
  510. // peripheral device, it is not possible to source current on D+ or D- when the
  511. // host is not actively providing power on Vbus. Therefore, implementing this
  512. // bus sense feature is optional. This firmware can be made to use this bus
  513. // sense feature by making sure "USE_USB_BUS_SENSE_IO" has been defined in the
  514. // HardwareProfile.h file.
  515. #if defined(USE_USB_BUS_SENSE_IO)
  516. tris_usb_bus_sense = INPUT_PIN; // See HardwareProfile.h
  517. #endif
  518. // If the host PC sends a GetStatus (device) request, the firmware must respond
  519. // and let the host know if the USB peripheral device is currently bus powered
  520. // or self powered. See chapter 9 in the official USB specifications for details
  521. // regarding this request. If the peripheral device is capable of being both
  522. // self and bus powered, it should not return a hard coded value for this request.
  523. // Instead, firmware should check if it is currently self or bus powered, and
  524. // respond accordingly. If the hardware has been configured like demonstrated
  525. // on the PICDEM FS USB Demo Board, an I/O pin can be polled to determine the
  526. // currently selected power source. On the PICDEM FS USB Demo Board, "RA2"
  527. // is used for this purpose. If using this feature, make sure "USE_SELF_POWER_SENSE_IO"
  528. // has been defined in HardwareProfile.h, and that an appropriate I/O pin has been mapped
  529. // to it in HardwareProfile.h.
  530. #if defined(USE_SELF_POWER_SENSE_IO)
  531. tris_self_power = INPUT_PIN; // See HardwareProfile.h
  532. #endif
  533. /*
  534. USBGenericOutHandle = 0;
  535. USBGenericInHandle = 0;
  536. */
  537. UserInit(); //Application related initialization. See user.c
  538. USBDeviceInit(); //usb_device.c. Initializes USB module SFRs and firmware
  539. //variables to known states.
  540. }//end InitializeSystem
  541. void UserInit(void)
  542. {
  543. mInitAllLEDs();
  544. mInitAllSwitches();
  545. blinkStatusValid = TRUE; //Blink the normal USB state on the LEDs.
  546. Benchmark_Init();
  547. }//end UserInit
  548. /******************************************************************************
  549. * Function: void ProcessIO(void)
  550. *
  551. * PreCondition: None
  552. *
  553. * Input: None
  554. *
  555. * Output: None
  556. *
  557. * Side Effects: None
  558. *
  559. * Overview: This function is a place holder for other user routines.
  560. * It is a mixture of both USB and non-USB tasks.
  561. *
  562. * Note: None
  563. *****************************************************************************/
  564. /*
  565. void ProcessIO(void)
  566. {
  567. //Blink the LEDs according to the USB device status, but only do so if the PC application isn't connected and controlling the LEDs.
  568. if(blinkStatusValid)
  569. {
  570. BlinkUSBStatus();
  571. }
  572. //User Application USB tasks below.
  573. //Note: The user application should not begin attempting to read/write over the USB
  574. //until after the device has been fully enumerated. After the device is fully
  575. //enumerated, the USBDeviceState will be set to "CONFIGURED_STATE".
  576. if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return;
  577. //As the device completes the enumeration process, the USBCBInitEP() function will
  578. //get called. In this function, we initialize the user application endpoints (in this
  579. //example code, the user application makes use of endpoint 1 IN and endpoint 1 OUT).
  580. //The USBGenRead() function call in the USBCBInitEP() function initializes endpoint 1 OUT
  581. //and "arms" it so that it can receive a packet of data from the host. Once the endpoint
  582. //has been armed, the host can then send data to it (assuming some kind of application software
  583. //is running on the host, and the application software tries to send data to the USB device).
  584. //If the host sends a packet of data to the endpoint 1 OUT buffer, the hardware of the SIE will
  585. //automatically receive it and store the data at the memory location pointed to when we called
  586. //USBGenRead(). Additionally, the endpoint handle (in this case USBGenericOutHandle) will indicate
  587. //that the endpoint is no longer busy. At this point, it is safe for this firmware to begin reading
  588. //from the endpoint buffer, and processing the data. In this example, we have implemented a few very
  589. //simple commands. For example, if the host sends a packet of data to the endpoint 1 OUT buffer, with the
  590. //first byte = 0x80, this is being used as a command to indicate that the firmware should "Toggle LED(s)".
  591. if(!USBHandleBusy(USBGenericOutHandle)) //Check if the endpoint has received any data from the host.
  592. {
  593. switch(OUTPacket[0]) //Data arrived, check what kind of command might be in the packet of data.
  594. {
  595. case 0x80: //Toggle LED(s) command from PC application.
  596. blinkStatusValid = FALSE; //Disable the regular LED blink pattern indicating USB state, PC application is controlling the LEDs.
  597. if(mGetLED_1() == mGetLED_2())
  598. {
  599. mLED_1_Toggle();
  600. mLED_2_Toggle();
  601. }
  602. else
  603. {
  604. mLED_1_On();
  605. mLED_2_On();
  606. }
  607. break;
  608. case 0x81: //Get push button state command from PC application.
  609. 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.
  610. if(sw2 == 1) //pushbutton not pressed, pull up resistor on circuit board is pulling the PORT pin high
  611. {
  612. INPacket[1] = 0x01;
  613. }
  614. else //sw2 must be == 0, pushbutton is pressed and overpowering the pull up resistor
  615. {
  616. INPacket[1] = 0x00;
  617. }
  618. //Now check to make sure no previous attempts to send data to the host are still pending. If any attemps are still
  619. //pending, we do not want to write to the endpoint 1 IN buffer again, until the previous transaction is complete.
  620. //Otherwise the unsent data waiting in the buffer will get overwritten and will result in unexpected behavior.
  621. if(!USBHandleBusy(USBGenericInHandle))
  622. {
  623. //The endpoint was not "busy", therefore it is safe to write to the buffer and arm the endpoint.
  624. //The USBGenWrite() function call "arms" the endpoint (and makes the handle indicate the endpoint is busy).
  625. //Once armed, the data will be automatically sent to the host (in hardware by the SIE) the next time the
  626. //host polls the endpoint. Once the data is successfully sent, the handle (in this case USBGenericInHandle)
  627. //will indicate the the endpoint is no longer busy.
  628. USBGenericInHandle = USBGenWrite(USBGEN_EP_NUM,(BYTE*)&INPacket,USBGEN_EP_SIZE);
  629. }
  630. break;
  631. }
  632. //Re-arm the OUT endpoint for the next packet:
  633. //The USBGenRead() function call "arms" the endpoint (and makes it "busy"). If the endpoint is armed, the SIE will
  634. //automatically accept data from the host, if the host tries to send a packet of data to the endpoint. Once a data
  635. //packet addressed to this endpoint is received from the host, the endpoint will no longer be busy, and the application
  636. //can read the data which will be sitting in the buffer.
  637. USBGenericOutHandle = USBGenRead(USBGEN_EP_NUM,(BYTE*)&OUTPacket,USBGEN_EP_SIZE);
  638. }
  639. }//end ProcessIO
  640. */
  641. /********************************************************************
  642. * Function: void BlinkUSBStatus(void)
  643. *
  644. * PreCondition: None
  645. *
  646. * Input: None
  647. *
  648. * Output: None
  649. *
  650. * Side Effects: None
  651. *
  652. * Overview: BlinkUSBStatus turns on and off LEDs
  653. * corresponding to the USB device state.
  654. *
  655. * Note: mLED macros can be found in HardwareProfile.h
  656. * USBDeviceState is declared and updated in
  657. * usb_device.c.
  658. *******************************************************************/
  659. void BlinkUSBStatus(void)
  660. {
  661. static WORD led_count=0;
  662. if(led_count == 0)led_count = 10000U;
  663. led_count--;
  664. #define mLED_Both_Off() {mLED_1_Off();mLED_2_Off();}
  665. #define mLED_Both_On() {mLED_1_On();mLED_2_On();}
  666. #define mLED_Only_1_On() {mLED_1_On();mLED_2_Off();}
  667. #define mLED_Only_2_On() {mLED_1_Off();mLED_2_On();}
  668. if(USBSuspendControl == 1)
  669. {
  670. if(led_count==0)
  671. {
  672. mLED_1_Toggle();
  673. if(mGetLED_1())
  674. {
  675. mLED_2_On();
  676. }
  677. else
  678. {
  679. mLED_2_Off();
  680. }
  681. }//end if
  682. }
  683. else
  684. {
  685. if(USBDeviceState == DETACHED_STATE)
  686. {
  687. mLED_Both_Off();
  688. }
  689. else if(USBDeviceState == ATTACHED_STATE)
  690. {
  691. mLED_Both_On();
  692. }
  693. else if(USBDeviceState == POWERED_STATE)
  694. {
  695. mLED_Only_1_On();
  696. }
  697. else if(USBDeviceState == DEFAULT_STATE)
  698. {
  699. mLED_Only_2_On();
  700. }
  701. else if(USBDeviceState == ADDRESS_STATE)
  702. {
  703. if(led_count == 0)
  704. {
  705. mLED_1_Toggle();
  706. mLED_2_Off();
  707. }//end if
  708. }
  709. else if(USBDeviceState == CONFIGURED_STATE)
  710. {
  711. if(led_count==0)
  712. {
  713. mLED_1_Toggle();
  714. if(mGetLED_1())
  715. {
  716. mLED_2_Off();
  717. }
  718. else
  719. {
  720. mLED_2_On();
  721. }
  722. }//end if
  723. }//end if(...)
  724. }//end if(UCONbits.SUSPND...)
  725. }//end BlinkUSBStatus
  726. // ******************************************************************************************************
  727. // ************** USB Callback Functions ****************************************************************
  728. // ******************************************************************************************************
  729. // The USB firmware stack will call the callback functions USBCBxxx() in response to certain USB related
  730. // events. For example, if the host PC is powering down, it will stop sending out Start of Frame (SOF)
  731. // packets to your device. In response to this, all USB devices are supposed to decrease their power
  732. // consumption from the USB Vbus to <2.5mA each. The USB module detects this condition (which according
  733. // to the USB specifications is 3+ms of no bus activity/SOF packets) and then calls the USBCBSuspend()
  734. // function. You should modify these callback functions to take appropriate actions for each of these
  735. // conditions. For example, in the USBCBSuspend(), you may wish to add code that will decrease power
  736. // consumption from Vbus to <2.5mA (such as by clock switching, turning off LEDs, putting the
  737. // microcontroller to sleep, etc.). Then, in the USBCBWakeFromSuspend() function, you may then wish to
  738. // add code that undoes the power saving things done in the USBCBSuspend() function.
  739. // The USBCBSendResume() function is special, in that the USB stack will not automatically call this
  740. // function. This function is meant to be called from the application firmware instead. See the
  741. // additional comments near the function.
  742. /******************************************************************************
  743. * Function: void USBCBSuspend(void)
  744. *
  745. * PreCondition: None
  746. *
  747. * Input: None
  748. *
  749. * Output: None
  750. *
  751. * Side Effects: None
  752. *
  753. * Overview: Call back that is invoked when a USB suspend is detected
  754. *
  755. * Note: None
  756. *****************************************************************************/
  757. void USBCBSuspend(void)
  758. {
  759. //Example power saving code. Insert appropriate code here for the desired
  760. //application behavior. If the microcontroller will be put to sleep, a
  761. //process similar to that shown below may be used:
  762. //ConfigureIOPinsForLowPower();
  763. //SaveStateOfAllInterruptEnableBits();
  764. //DisableAllInterruptEnableBits();
  765. //EnableOnlyTheInterruptsWhichWillBeUsedToWakeTheMicro(); //should enable at least USBActivityIF as a wake source
  766. //Sleep();
  767. //RestoreStateOfAllPreviouslySavedInterruptEnableBits(); //Preferrably, this should be done in the USBCBWakeFromSuspend() function instead.
  768. //RestoreIOPinsToNormal(); //Preferrably, this should be done in the USBCBWakeFromSuspend() function instead.
  769. //IMPORTANT NOTE: Do not clear the USBActivityIF (ACTVIF) bit here. This bit is
  770. //cleared inside the usb_device.c file. Clearing USBActivityIF here will cause
  771. //things to not work as intended.
  772. #if defined(__C30__)
  773. #if 0
  774. U1EIR = 0xFFFF;
  775. U1IR = 0xFFFF;
  776. U1OTGIR = 0xFFFF;
  777. IFS5bits.USB1IF = 0;
  778. IEC5bits.USB1IE = 1;
  779. U1OTGIEbits.ACTVIE = 1;
  780. U1OTGIRbits.ACTVIF = 1;
  781. Sleep();
  782. #endif
  783. #endif
  784. }
  785. /******************************************************************************
  786. * Function: void _USB1Interrupt(void)
  787. *
  788. * PreCondition: None
  789. *
  790. * Input: None
  791. *
  792. * Output: None
  793. *
  794. * Side Effects: None
  795. *
  796. * Overview: This function is called when the USB interrupt bit is set
  797. * In this example the interrupt is only used when the device
  798. * goes to sleep when it receives a USB suspend command
  799. *
  800. * Note: None
  801. *****************************************************************************/
  802. #if 0
  803. void __attribute__ ((interrupt)) _USB1Interrupt(void)
  804. {
  805. #if !defined(self_powered)
  806. if(U1OTGIRbits.ACTVIF)
  807. {
  808. IEC5bits.USB1IE = 0;
  809. U1OTGIEbits.ACTVIE = 0;
  810. IFS5bits.USB1IF = 0;
  811. //USBClearInterruptFlag(USBActivityIFReg,USBActivityIFBitNum);
  812. USBClearInterruptFlag(USBIdleIFReg,USBIdleIFBitNum);
  813. //USBSuspendControl = 0;
  814. }
  815. #endif
  816. }
  817. #endif
  818. /******************************************************************************
  819. * Function: void USBCBWakeFromSuspend(void)
  820. *
  821. * PreCondition: None
  822. *
  823. * Input: None
  824. *
  825. * Output: None
  826. *
  827. * Side Effects: None
  828. *
  829. * Overview: The host may put USB peripheral devices in low power
  830. * suspend mode (by "sending" 3+ms of idle). Once in suspend
  831. * mode, the host may wake the device back up by sending non-
  832. * idle state signalling.
  833. *
  834. * This call back is invoked when a wakeup from USB suspend
  835. * is detected.
  836. *
  837. * Note: None
  838. *****************************************************************************/
  839. void USBCBWakeFromSuspend(void)
  840. {
  841. // If clock switching or other power savings measures were taken when
  842. // executing the USBCBSuspend() function, now would be a good time to
  843. // switch back to normal full power run mode conditions. The host allows
  844. // a few milliseconds of wakeup time, after which the device must be
  845. // fully back to normal, and capable of receiving and processing USB
  846. // packets. In order to do this, the USB module must receive proper
  847. // clocking (IE: 48MHz clock must be available to SIE for full speed USB
  848. // operation).
  849. }
  850. /********************************************************************
  851. * Function: void USBCB_SOF_Handler(void)
  852. *
  853. * PreCondition: None
  854. *
  855. * Input: None
  856. *
  857. * Output: None
  858. *
  859. * Side Effects: None
  860. *
  861. * Overview: The USB host sends out a SOF packet to full-speed
  862. * devices every 1 ms. This interrupt may be useful
  863. * for isochronous pipes. End designers should
  864. * implement callback routine as necessary.
  865. *
  866. * Note: None
  867. *******************************************************************/
  868. void USBCB_SOF_Handler(void)
  869. {
  870. // No need to clear UIRbits.SOFIF to 0 here.
  871. // Callback caller is already doing that.
  872. }
  873. /*******************************************************************
  874. * Function: void USBCBErrorHandler(void)
  875. *
  876. * PreCondition: None
  877. *
  878. * Input: None
  879. *
  880. * Output: None
  881. *
  882. * Side Effects: None
  883. *
  884. * Overview: The purpose of this callback is mainly for
  885. * debugging during development. Check UEIR to see
  886. * which error causes the interrupt.
  887. *
  888. * Note: None
  889. *******************************************************************/
  890. void USBCBErrorHandler(void)
  891. {
  892. // No need to clear UEIR to 0 here.
  893. // Callback caller is already doing that.
  894. // Typically, user firmware does not need to do anything special
  895. // if a USB error occurs. For example, if the host sends an OUT
  896. // packet to your device, but the packet gets corrupted (ex:
  897. // because of a bad connection, or the user unplugs the
  898. // USB cable during the transmission) this will typically set
  899. // one or more USB error interrupt flags. Nothing specific
  900. // needs to be done however, since the SIE will automatically
  901. // send a "NAK" packet to the host. In response to this, the
  902. // host will normally retry to send the packet again, and no
  903. // data loss occurs. The system will typically recover
  904. // automatically, without the need for application firmware
  905. // intervention.
  906. // Nevertheless, this callback function is provided, such as
  907. // for debugging purposes.
  908. }
  909. /*******************************************************************
  910. * Function: void USBCBCheckOtherReq(void)
  911. *
  912. * PreCondition: None
  913. *
  914. * Input: None
  915. *
  916. * Output: None
  917. *
  918. * Side Effects: None
  919. *
  920. * Overview: When SETUP packets arrive from the host, some
  921. * firmware must process the request and respond
  922. * appropriately to fulfill the request. Some of
  923. * the SETUP packets will be for standard
  924. * USB "chapter 9" (as in, fulfilling chapter 9 of
  925. * the official USB specifications) requests, while
  926. * others may be specific to the USB device class
  927. * that is being implemented. For example, a HID
  928. * class device needs to be able to respond to
  929. * "GET REPORT" type of requests. This
  930. * is not a standard USB chapter 9 request, and
  931. * therefore not handled by usb_device.c. Instead
  932. * this request should be handled by class specific
  933. * firmware, such as that contained in usb_function_hid.c.
  934. *
  935. * Note: None
  936. *****************************************************************************
  937. void USBCBCheckOtherReq(void)
  938. {
  939. }//end
  940. */
  941. /*******************************************************************
  942. * Function: void USBCBStdSetDscHandler(void)
  943. *
  944. * PreCondition: None
  945. *
  946. * Input: None
  947. *
  948. * Output: None
  949. *
  950. * Side Effects: None
  951. *
  952. * Overview: The USBCBStdSetDscHandler() callback function is
  953. * called when a SETUP, bRequest: SET_DESCRIPTOR request
  954. * arrives. Typically SET_DESCRIPTOR requests are
  955. * not used in most applications, and it is
  956. * optional to support this type of request.
  957. *
  958. * Note: None
  959. *****************************************************************************/
  960. void USBCBStdSetDscHandler(void)
  961. {
  962. // Must claim session ownership if supporting this request
  963. }//end
  964. /******************************************************************************
  965. * Function: void USBCBInitEP(void)
  966. *
  967. * PreCondition: None
  968. *
  969. * Input: None
  970. *
  971. * Output: None
  972. *
  973. * Side Effects: None
  974. *
  975. * Overview: This function is called when the device becomes
  976. * initialized, which occurs after the host sends a
  977. * SET_CONFIGURATION (wValue not = 0) request. This
  978. * callback function should initialize the endpoints
  979. * for the device's usage according to the current
  980. * configuration.
  981. *
  982. * Note: None
  983. *****************************************************************************
  984. void USBCBInitEP(void)
  985. {
  986. USBEnableEndpoint(USBGEN_EP_NUM,USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
  987. USBGenericOutHandle = USBGenRead(USBGEN_EP_NUM,(BYTE*)&OUTPacket,USBGEN_EP_SIZE);
  988. }
  989. */
  990. /********************************************************************
  991. * Function: void USBCBSendResume(void)
  992. *
  993. * PreCondition: None
  994. *
  995. * Input: None
  996. *
  997. * Output: None
  998. *
  999. * Side Effects: None
  1000. *
  1001. * Overview: The USB specifications allow some types of USB
  1002. * peripheral devices to wake up a host PC (such
  1003. * as if it is in a low power suspend to RAM state).
  1004. * This can be a very useful feature in some
  1005. * USB applications, such as an Infrared remote
  1006. * control receiver. If a user presses the "power"
  1007. * button on a remote control, it is nice that the
  1008. * IR receiver can detect this signalling, and then
  1009. * send a USB "command" to the PC to wake up.
  1010. *
  1011. * The USBCBSendResume() "callback" function is used
  1012. * to send this special USB signalling which wakes
  1013. * up the PC. This function may be called by
  1014. * application firmware to wake up the PC. This
  1015. * function should only be called when:
  1016. *
  1017. * 1. The USB driver used on the host PC supports
  1018. * the remote wakeup capability.
  1019. * 2. The USB configuration descriptor indicates
  1020. * the device is remote wakeup capable in the
  1021. * bmAttributes field.
  1022. * 3. The USB host PC is currently sleeping,
  1023. * and has previously sent your device a SET
  1024. * FEATURE setup packet which "armed" the
  1025. * remote wakeup capability.
  1026. *
  1027. * This callback should send a RESUME signal that
  1028. * has the period of 1-15ms.
  1029. *
  1030. * Note: Interrupt vs. Polling
  1031. * -Primary clock
  1032. * -Secondary clock ***** MAKE NOTES ABOUT THIS *******
  1033. * > Can switch to primary first by calling USBCBWakeFromSuspend()
  1034. * The modifiable section in this routine should be changed
  1035. * to meet the application needs. Current implementation
  1036. * temporary blocks other functions from executing for a
  1037. * period of 1-13 ms depending on the core frequency.
  1038. *
  1039. * According to USB 2.0 specification section 7.1.7.7,
  1040. * "The remote wakeup device must hold the resume signaling
  1041. * for at lest 1 ms but for no more than 15 ms."
  1042. * The idea here is to use a delay counter loop, using a
  1043. * common value that would work over a wide range of core
  1044. * frequencies.
  1045. * That value selected is 1800. See table below:
  1046. * ==========================================================
  1047. * Core Freq(MHz) MIP RESUME Signal Period (ms)
  1048. * ==========================================================
  1049. * 48 12 1.05
  1050. * 4 1 12.6
  1051. * ==========================================================
  1052. * * These timing could be incorrect when using code
  1053. * optimization or extended instruction mode,
  1054. * or when having other interrupts enabled.
  1055. * Make sure to verify using the MPLAB SIM's Stopwatch
  1056. * and verify the actual signal on an oscilloscope.
  1057. *******************************************************************/
  1058. void USBCBSendResume(void)
  1059. {
  1060. static WORD delay_count;
  1061. USBResumeControl = 1; // Start RESUME signaling
  1062. delay_count = 1800U; // Set RESUME line for 1-13 ms
  1063. do
  1064. {
  1065. delay_count--;
  1066. }while(delay_count);
  1067. USBResumeControl = 0;
  1068. }
  1069. /*******************************************************************
  1070. * Function: BOOL USER_USB_CALLBACK_EVENT_HANDLER(
  1071. * USB_EVENT event, void *pdata, WORD size)
  1072. *
  1073. * PreCondition: None
  1074. *
  1075. * Input: USB_EVENT event - the type of event
  1076. * void *pdata - pointer to the event data
  1077. * WORD size - size of the event data
  1078. *
  1079. * Output: None
  1080. *
  1081. * Side Effects: None
  1082. *
  1083. * Overview: This function is called from the USB stack to
  1084. * notify a user application that a USB event
  1085. * occured. This callback is in interrupt context
  1086. * when the USB_INTERRUPT option is selected.
  1087. *
  1088. * Note: None
  1089. *******************************************************************/
  1090. BOOL USER_USB_CALLBACK_EVENT_HANDLER(USB_EVENT event, void *pdata, WORD size)
  1091. {
  1092. switch(event)
  1093. {
  1094. case EVENT_CONFIGURED:
  1095. USBCBInitEP();
  1096. break;
  1097. case EVENT_SET_DESCRIPTOR:
  1098. USBCBStdSetDscHandler();
  1099. break;
  1100. case EVENT_EP0_REQUEST:
  1101. USBCBCheckOtherReq();
  1102. break;
  1103. case EVENT_SOF:
  1104. USBCB_SOF_Handler();
  1105. break;
  1106. case EVENT_SUSPEND:
  1107. USBCBSuspend();
  1108. break;
  1109. case EVENT_RESUME:
  1110. USBCBWakeFromSuspend();
  1111. break;
  1112. case EVENT_BUS_ERROR:
  1113. USBCBErrorHandler();
  1114. break;
  1115. case EVENT_TRANSFER:
  1116. Nop();
  1117. break;
  1118. default:
  1119. break;
  1120. }
  1121. return TRUE;
  1122. }
  1123. /** EOF main.c ***************************************************************/