main.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. // Open source PIC USB stack echo demo
  2. // USB stack by JTR and Honken
  3. // CC-BY
  4. //
  5. // USB driver files should be in '..\dp_usb\'
  6. // Enter a USB VID and PID in prj_usb_config.h
  7. //USB stack
  8. #include "../dp_usb/usb_stack_globals.h" // USB stack only defines Not function related.
  9. #include "descriptors.h" // JTR Only included in main.c
  10. //#include "configwords.h" // JTR only included in main.c
  11. #include "fraisemaster.h"
  12. #include "stdio.h"
  13. // PIC18F Move reset vectors for bootloader compatibility
  14. #ifdef __18CXX
  15. #define REMAPPED_RESET_VECTOR_ADDRESS 0x800
  16. #define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS 0x808
  17. #define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS 0x818
  18. #endif
  19. void SetupBoard(void);
  20. void InterruptHandlerHigh();
  21. void InterruptHandlerLow();
  22. void USBSuspend(void);
  23. int _user_putc(char c)
  24. {
  25. putc_cdc(c);
  26. }
  27. #pragma udata
  28. extern BYTE usb_device_state;
  29. //BYTE LineFromUsb[96];
  30. //BYTE LineFromUsbLen=0;
  31. //#pragma udata accessram
  32. volatile BYTE SofFlag;
  33. #pragma code
  34. void SOFHandler(void)
  35. {
  36. //static BYTE il;
  37. //if(il++==200) { il=0; mLED_2_Toggle(); }
  38. SofFlag=1;
  39. CDCFlushOnTimeout();
  40. }
  41. #ifdef PIC_18F
  42. void main(void)
  43. #else
  44. int main(void)
  45. #endif
  46. {
  47. BYTE RecvdByte;
  48. long int jj;
  49. stdout = _H_USER; // Use our own special output function for STDOUT
  50. initCDC(); // setup the CDC state machine
  51. SetupBoard(); //setup the hardware, customize for your hardware
  52. usb_init(cdc_device_descriptor, cdc_config_descriptor, cdc_str_descs, USB_NUM_STRINGS); // initialize USB. TODO: Remove magic with macro
  53. usb_start(); //start the USB peripheral
  54. // PIC18 INTERRUPTS
  55. // It is the users resposibility to set up high, low or legacy mode
  56. // interrupt operation. The following macros for high and low interrupt
  57. // setup have been removed:
  58. #define EnableUsbHighPriInterrupt() do { RCONbits.IPEN = 1; IPR2bits.USBIP = 1; INTCONbits.GIEH = 1;} while(0) // JTR new
  59. #define EnableUsbLowPriInterrupt() do { RCONbits.IPEN = 1; IPR2bits.USBIP = 0; INTCONbits.GIEL = 1;} while(0) // JTR new
  60. // By default, the interrupt mode will be LEGACY (ISR Vector 0x08)
  61. // (Same as high priority vector wise but the operation (latency) is
  62. // not the same. Consult the data sheet for details.)
  63. // If a priority mode is enabled then this affects ALL other interrupt
  64. // sources therefore it does not belong to the usb stack to be
  65. // doing this. It is a global, user application choice.
  66. #if defined USB_INTERRUPTS // See the prj_usb_config.h file.
  67. EnableUsbPerifInterrupts(USB_TRN + USB_SOF + USB_UERR + USB_URST);
  68. #if defined __18CXX //turn on interrupts for PIC18
  69. //EnableUsbHighPriInterrupt();
  70. EnableUsbLowPriInterrupt();
  71. INTCONbits.PEIE = 1;
  72. INTCONbits.GIE = 1;
  73. #endif
  74. EnableUsbGlobalInterrupt(); // Only enables global USB interrupt. Chip interrupts must be enabled by the user (PIC18)
  75. #endif
  76. // Wait for USB to connect
  77. do {
  78. #ifndef USB_INTERRUPTS
  79. usb_handler();
  80. #endif
  81. } while (usb_device_state < CONFIGURED_STATE);
  82. usb_register_sof_handler(SOFHandler); // Register our CDC timeout handler after device configured
  83. //usb_register_sof_handler(CDCFlushOnTimeout); // Register our CDC timeout handler after device configured
  84. FraiseInit();
  85. // Main echo loop
  86. do {
  87. // If USB_INTERRUPT is not defined each loop should have at least one additional call to the usb handler to allow for control transfers.
  88. #ifndef USB_INTERRUPTS
  89. usb_handler();
  90. #endif
  91. // Receive and send method 1
  92. // The CDC module will call usb_handler each time a BULK CDC packet is sent or received.
  93. // If there is a byte ready will return with the number of bytes available and received byte in RecvdByte
  94. /*if (poll_getc_cdc(&RecvdByte))
  95. putc_cdc(RecvdByte); */
  96. if(!FrGotLineFromUsb) {
  97. while(poll_getc_cdc(&RecvdByte)) {
  98. if(RecvdByte=='\n') {
  99. FrGotLineFromUsb=1;
  100. //printf((const far rom char*)"rcvd line !\n");
  101. break;
  102. }
  103. else if(LineFromUsbLen<(sizeof(LineFromUsb)-1))
  104. LineFromUsb[LineFromUsbLen++]=RecvdByte;
  105. }
  106. }
  107. if(SofFlag==1) { FraiseSOF(); SofFlag=0; }
  108. FraiseService();
  109. /*if(!UserSW) { //goto booloader... doesn't work well... bouhou !
  110. INTCONbits.GIEH=0;
  111. INTCONbits.GIEL=0;
  112. //SuspendUsb();
  113. //UCONbits.USBEN = 0;
  114. UCFGbits.UPUEN=0;
  115. UCFGbits.UTRDIS=1;
  116. mLED_2_On();
  117. while(jj++<600000) ;
  118. mLED_2_Off();
  119. while(jj++<600000) ;
  120. Reset();
  121. }*/
  122. //while(!UserSW);
  123. // Receive and send method 2
  124. // Same as poll_getc_cdc except that byte is NOT removed from queue.
  125. // This function will wait for a byte and return and remove it from the queue when it arrives.
  126. /*if (peek_getc_cdc(&RecvdByte)) {
  127. RecvdByte = getc_cdc();
  128. putc_cdc(RecvdByte+1);
  129. }*/
  130. // Receive and send method 3
  131. // If there is a byte ready will return with the number of bytes available and received byte in RecvdByte
  132. // use CDC_Flush_In_Now(); when it has to be sent immediately and not wait for a timeout condition.
  133. /* if (poll_getc_cdc(&RecvdByte)) {
  134. putc_cdc(RecvdByte+1); //
  135. CDC_Flush_In_Now();
  136. }*/
  137. } while (1);
  138. } //end main
  139. //board hardware setup
  140. //add your hardware here
  141. void SetupBoard(void) {
  142. #if defined (PIEDUSB)
  143. //disable some defaults
  144. ADCON1 |= 0b1111; //all pins digital
  145. CVRCON = 0b00000000;
  146. LATC = 0x00;
  147. TRISC = 0xFF;
  148. #endif
  149. }
  150. // USB suspend not yet enabled
  151. void USBSuspend(void) {}
  152. //interrupt routines for PIC 18 and PIC24
  153. #if defined(USB_INTERRUPTS)
  154. //PIC 24F type USB interrupts
  155. #if defined(__PIC24FJ64GB106__) || defined(__PIC24FJ128GB106__) || defined(__PIC24FJ192GB106__) || defined(__PIC24FJ256GB106__) || defined(__PIC24FJ64GB108__) || defined(__PIC24FJ128GB108__) || defined(__PIC24FJ192GB108__) || defined(__PIC24FJ256GB108__) || defined(__PIC24FJ64GB110__) || defined(__PIC24FJ128GB110__) || defined(__PIC24FJ192GB110__) || defined(__PIC24FJ256GB110__)
  156. #pragma interrupt _USB1Interrupt
  157. void __attribute__((interrupt, auto_psv)) _USB1Interrupt() {
  158. //USB interrupt
  159. //IRQ enable IEC5bits.USB1IE
  160. //IRQ flag IFS5bits.USB1IF
  161. //IRQ priority IPC21<10:8>
  162. usb_handler();
  163. ClearGlobalUsbInterruptFlag();
  164. }
  165. #elif defined (__18CXX) //PIC18F style interrupts with remapping for bootloader
  166. // Interrupt remap chain
  167. //
  168. //This function directs the interrupt to
  169. // the proper function depending on the mode
  170. // set in the mode variable.
  171. //USB stack on low priority interrupts,
  172. #pragma interruptlow InterruptHandlerLow nosave= PROD, PCLATH, PCLATU, TBLPTR, TBLPTRU, TABLAT, section (".tmpdata"), section("MATH_DATA")
  173. void InterruptHandlerLow(void) {
  174. usb_handler();
  175. ClearGlobalUsbInterruptFlag();
  176. //FraiseISR();
  177. }
  178. #pragma interrupt InterruptHandlerHigh nosave= PROD, PCLATH, PCLATU, TBLPTR, TBLPTRU, TABLAT, section (".tmpdata"), section("MATH_DATA")
  179. void InterruptHandlerHigh(void) { //Also legacy mode interrupt.
  180. //usb_handler();
  181. //ClearGlobalUsbInterruptFlag();
  182. FraiseISR();
  183. }
  184. //these statements remap the vector to our function
  185. //When the interrupt fires the PIC checks here for directions
  186. #pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS
  187. void Remapped_High_ISR(void) {
  188. _asm goto InterruptHandlerHigh _endasm
  189. }
  190. #pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS
  191. void Remapped_Low_ISR(void) {
  192. _asm goto InterruptHandlerLow _endasm
  193. }
  194. //relocate the reset vector
  195. extern void _startup(void);
  196. #pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS
  197. void _reset(void) {
  198. _asm goto _startup _endasm
  199. }
  200. //set the initial vectors so this works without the bootloader too.
  201. #if 0
  202. #pragma code HIGH_INTERRUPT_VECTOR = 0x08
  203. void High_ISR(void) {
  204. _asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm
  205. }
  206. #pragma code LOW_INTERRUPT_VECTOR = 0x18
  207. void Low_ISR(void) {
  208. _asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm
  209. }
  210. #endif
  211. #endif //defined (__18CXX)
  212. #endif //defined(USB_INTERRUPTS)
  213. #pragma code