00001 //----------------------------------------------------------------------------- 00002 // USB_Main.c 00003 //----------------------------------------------------------------------------- 00004 00005 //----------------------------------------------------------------------------- 00006 // Includes 00007 //----------------------------------------------------------------------------- 00008 00009 #include "USB_Type.h" 00010 #include "USB_Configuration.h" 00011 #include "USB_Register.h" 00012 #include "USB_Descriptor.h" 00013 #include "USB_Standard_Requests.h" 00014 #include "USB_ISR.h" 00015 #include "USB_CDC_UART.h" 00016 #include "FIFO_RW.h" 00017 #include "USB_Main.h" 00018 00019 #include "CD_Link.h" 00020 #include "CD_Main.h" 00021 00022 00023 00024 #if defined KEIL 00025 #include <intrins.h> // for _testbit_(), _nop_() 00026 #endif // KEIL 00027 00028 //----------------------------------------------------------------------------- 00029 // Definitions 00030 //----------------------------------------------------------------------------- 00031 00032 #if defined C8051F320_H 00033 #define SYSCLK 24000000L // SYSCLK frequency in Hz 00034 #endif 00035 #if defined C8051F340_H 00036 #define SYSCLK 48000000L // SYSCLK frequency in Hz 00037 #endif 00038 00039 //----------------------------------------------------------------------------- 00040 // 16-bit SFR Definitions 00041 //----------------------------------------------------------------------------- 00042 00043 #if defined KEIL 00044 00045 sfr16 TMR2RL = 0xca; // Timer2 reload value 00046 sfr16 TMR2 = 0xcc; // Timer2 counter 00047 00048 #endif // KEIL 00049 00050 //----------------------------------------------------------------------------- 00051 // Global Variables 00052 //----------------------------------------------------------------------------- 00053 00054 // port assignment 00055 00056 #if defined KEIL 00057 00058 sbit Sw1 = P2^0; 00059 sbit Sw2 = P2^1; 00060 sbit Led1 = P2^2; // LED='1' means ON 00061 sbit Led2 = P2^3; 00062 00063 #endif // KEIL 00064 00065 #if defined SDCC 00066 00067 #define Sw1 P2_0 00068 #define Sw2 P2_1 00069 #define Led1 P2_2 // LED='1' means ON 00070 #define Led2 P2_3 00071 00072 #endif // SDCC 00073 00074 static bit Switch1State = FALSE; // Indicate status of switch 00075 static bit Switch2State = FALSE; // starting at 0 == off 00076 00077 static bit Toggle1 = FALSE; // Variable to make sure each button 00078 static bit Toggle2 = FALSE; // press and release toggles switch 00079 00080 volatile bit switch_changed = FALSE; 00081 00082 00083 //----------------------------------------------------------------------------- 00084 // Static variables in this file 00085 //----------------------------------------------------------------------------- 00086 00087 //----------------------------------------------------------------------------- 00088 // Local Prototypes 00089 //----------------------------------------------------------------------------- 00090 00091 // Initialization Routines 00092 void Sysclk_Init(void); // Initialize the system clock 00093 void Port_Init(void); // Configure ports 00094 void Timer_Init(void); // Timer 2 for use by ADC and swtiches 00095 00096 //----------------------------------------------------------------------------- 00097 // ISR prototype 00098 //----------------------------------------------------------------------------- 00099 #if defined SDCC 00100 00101 extern void Usb_ISR(void) interrupt 8; 00102 extern void Timer2_ISR(void) interrupt 5; 00103 00104 #endif // SDCC 00105 00106 //------------------------------------------------------------------------ 00107 // startup routine 00108 //------------------------------------------------------------------------ 00109 00110 #if defined SDCC 00111 00112 unsigned char _sdcc_external_startup ( void ) 00113 { 00114 PCA0MD &= ~0x40; // Disable Watchdog timer 00115 return 0; 00116 } 00117 00118 #endif // SDCC 00119 00120 00121 //----------------------------------------------------------------------------- 00122 // Main Routine 00123 //----------------------------------------------------------------------------- 00124 void main(void) 00125 { 00126 #if defined KEIL 00127 PCA0MD &= ~0x40; // Disable Watchdog timer temporarily 00128 #endif // KEIL 00129 Sysclk_Init(); // Initialize oscillator 00130 Port_Init(); // Initialize crossbar and GPIO 00131 Timer_Init(); // Initialize timer2 00132 Flush_COMbuffers(); // Initialize COM ring buffer 00133 //Led1 = FALSE; 00134 //Led2 = FALSE; 00135 Usb0_Init(); // Initialize USB0 - at the end of initizaliation 00136 00137 EIE1 |= 0x02; // Enable USB0 interrupt 00138 IE |= 0xA0; // Enable Timer2 and Global Interrupt enable 00139 00140 00141 //main_kk(); 00142 CD_Main_Init(); 00143 00144 while ( 1 ) { // main loop 00145 00146 { // task1 - CDC support 00147 //BYTE dt; 00148 BYTE line_state; 00149 00150 CDC_Handle_Bulk_IN(); // Poll IN/OUT EP2 and handle transaction 00151 CDC_Handle_Bulk_OUT(); 00152 00153 if ( switch_changed ) // Reflect the switch status to DSR and CTS signaling 00154 { 00155 switch_changed = FALSE; 00156 00157 line_state = 0; 00158 if ( Switch1State ) line_state |= CDC_DSR; 00159 // if ( Switch2State ) line_state |= CDC_CTS; // CTS is not supported in generic CDC 00160 Update_Line_State( line_state ); 00161 } 00162 00163 //while (TXReady && RXReady) // loop back TX to RX 00164 while (TXReady) 00165 { 00166 CD_LinkRXChar(COMGetByte()); // transfer byte to CheapDAQ 00167 } 00168 //COMPutByte('1'); 00169 00170 //Led1 = uart_DTR; // output line status 00171 //Led2 = uart_RTS; 00172 } 00173 00174 } 00175 } 00176 00177 //----------------------------------------------------------------------------- 00178 // Initialization Subroutines 00179 //----------------------------------------------------------------------------- 00180 00181 //----------------------------------------------------------------------------- 00182 // Sysclk_Init 00183 //----------------------------------------------------------------------------- 00184 // 00185 // Initialize the system clock and USB clock 00186 // 00187 //----------------------------------------------------------------------------- 00188 00189 #if defined KEIL 00190 #include <intrins.h> 00191 #endif 00192 00193 static void Sysclk_Init(void) 00194 { 00195 CLKSEL = 0x00; // Set SYSCLK to 12 / 8 MHz 00196 OSCICN &= ~0x03; 00197 CLKMUL = 0x00; // Select internal oscillator as 00198 // input to clock multiplier 00199 CLKMUL |= 0x80; // Enable clock multiplier 00200 // delay about 5 us (8 clock) 00201 #if defined KEIL 00202 _nop_(); _nop_(); _nop_(); _nop_(); 00203 _nop_(); _nop_(); _nop_(); _nop_(); 00204 #endif 00205 00206 #if defined SDCC 00207 _asm 00208 DIV AB 00209 _endasm; 00210 #endif 00211 00212 CLKMUL |= 0xC0; // Initialize the clock multiplier 00213 while(!(CLKMUL & 0x20)); // Wait for multiplier to lock 00214 00215 #if defined C8051F320_H 00216 CLKSEL = USB_4X_CLOCK | SYS_4X_DIV_2; // Select system clock and USB clock 00217 #endif // C8051F320_H 00218 00219 #if defined C8051F340_H 00220 FLSCL |= 0x10; // set FLRT for 48MHz SYSCLK 00221 CLKSEL = USB_4X_CLOCK | SYS_4X; // Select system clock and USB clock 00222 #endif // C8051F340_H 00223 00224 } 00225 00226 //----------------------------------------------------------------------------- 00227 // PORT_Init 00228 //----------------------------------------------------------------------------- 00229 // 00230 // This function configures the crossbar and GPIO ports. 00231 // 00232 // F320DB 00233 // P1.7 analog Potentiometer 00234 // P2.2 digital push-pull LED 00235 // P2.3 digital push-pull LED 00236 // 00237 // F340DB 00238 // P2.2 digital push-pull LED 00239 // P2.3 digital push-pull LED 00240 // P2.5 analog Potentiometer 00241 //----------------------------------------------------------------------------- 00242 static void Port_Init(void) 00243 { 00244 00245 #if defined C8051F320_H 00246 P1MDIN = 0x7F; // Port 1 pin 7 set as analog input 00247 P0MDOUT |= 0x0F; // Port 0 pins 0-3 set push-pull 00248 P1MDOUT |= 0x0F; // Port 1 pins 0-3 set push-pull 00249 P2MDOUT |= 0x0C; // P2.2 and P2.3 set to push-pull 00250 P1SKIP = 0x80; // Port 1 pin 7 skipped by crossbar 00251 XBR0 = 0x00; 00252 XBR1 = 0x40; // Enable Crossbar 00253 #endif // C8051F320_H 00254 00255 #if defined C8051F340_H 00256 P2MDIN = ~(0x20); // Port 2 pin 5 set as analog input 00257 00258 //P0MDOUT |= 0x0F; // Port 0 pins 0-3 set high impedence 00259 00260 P0MDOUT |= 0x01; /* push-pull P0.0 (Pin_PWM0) */ 00261 00262 P0MDOUT &= ~0x08; /* Open-drain for P0.3., It will be INT0 */ 00263 P0SKIP |= 0x08; /* Skip P0.3 for peripheral assigment, it will be INT0 */ 00264 00265 P1MDOUT |= 0x0F; // Port 1 pins 0-3 set high impedence 00266 00267 P2MDOUT |= 0x0C; // Port 2 pins 0,1 set high empedence 00268 P2SKIP = 0x20; // Port 2 pin 5 skipped by crossbar 00269 00270 P2MDOUT |= 0x04; /* push-pull for P2.2 (led) */ 00271 00272 XBR0 = 0x00; 00273 XBR1 = 0x40; // Enable Crossbar, weak-pullups enabled 00274 #endif // C8051F340_H 00275 00276 } 00277 00278 //----------------------------------------------------------------------------- 00279 // Usb_Suspend 00280 //----------------------------------------------------------------------------- 00281 // 00282 // Enter suspend mode after suspend signalling is present on the bus 00283 // - called from USB ISR 00284 // 00285 //----------------------------------------------------------------------------- 00286 00287 //--------------------------- 00288 // SDCC suport 00289 //--------------------------- 00290 #if defined SDCC 00291 #pragma save 00292 #pragma nooverlay 00293 #endif // SDCC 00294 00295 #ifdef ENABLE_SUSPEND_RESUME 00296 00297 void Usb_Suspend(void) 00298 { 00299 // Put the device in a low power configuration 00300 P0MDIN = 0x00; // Port 0 configured as analog input 00301 P1MDIN = 0x00; // Port 1 configured as analog input 00302 P2MDIN = 0x00; // Port 2 configured as analog input 00303 P3MDIN = 0x00; // Port 3 configured as analog input 00304 00305 // ADC0CN &= ~0x80; // Disable ADC0 00306 // REF0CN = 0x00; // Disable voltage reference 00307 00308 OSCICN |= 0x20; // Put oscillator to suspend 00309 00310 // When the device receives a non-idle USB event, it will resume execution 00311 // on the instruction that follows OSCICN |= 0x20. 00312 00313 // Re-enable everything that was disabled when going into Suspend 00314 #if defined C8051F320_H 00315 P0MDIN = 0xFF; // Port 0 configured as diital input 00316 P1MDIN = 0x7F; // Port 1 pin 7 set as analog input 00317 P2MDIN = 0xFF; // Port 2 configured as diital input 00318 P3MDIN = 0xFF; // Port 3 configured as diital input 00319 #endif // C8051F320_H 00320 00321 #if defined C8051F340_H 00322 P0MDIN = 0xFF; // Port 0 configured as diital input 00323 P1MDIN = 0xFF; // Port 1 configured as diital input 00324 P2MDIN = ~(0x20); // Port 2 pin 5 set as analog input 00325 P3MDIN = 0xFF; // Port 3 configured as diital input 00326 #endif // C8051F340_H 00327 00328 00329 // REF0CN = 0x0E; // Enable voltage reference VREF 00330 // ADC0CN |= 0x80; // Re-enable ADC 00331 00332 } 00333 00334 #endif // ENABLE_SUSPEND_RESUME 00335 00336 //--------------------------- 00337 // SDCC suport 00338 //--------------------------- 00339 #if defined SDCC 00340 #pragma restore 00341 #endif // SDCC 00342 00343 //----------------------------------------------------------------------------- 00344 // Usb_Resume 00345 //----------------------------------------------------------------------------- 00346 // 00347 // Resume normal USB operation 00348 // - called from USB ISR 00349 // 00350 //----------------------------------------------------------------------------- 00351 00352 //--------------------------- 00353 // SDCC suport 00354 //--------------------------- 00355 #if defined SDCC 00356 #pragma save 00357 #pragma nooverlay 00358 #endif // SDCC 00359 00360 #ifdef ENABLE_SUSPEND_RESUME 00361 00362 // In this implementation, suspend/resume is supported by the oscillator suspend (OSCICN.5) 00363 // Then, the resume process is also coded in Usb_Suspend(), just after "OSCICN |= 0x20" 00364 /* 00365 void Usb_Resume(void) 00366 { 00367 } 00368 */ 00369 #endif // ENABLE_SUSPEND_RESUME 00370 00371 //--------------------------- 00372 // SDCC suport 00373 //--------------------------- 00374 #if defined SDCC 00375 #pragma restore 00376 #endif // SDCC 00377 00378 //----------------------------------------------------------------------------- 00379 // Timer_Init 00380 //----------------------------------------------------------------------------- 00381 // 00382 // Return Value : None 00383 // Parameters : None 00384 // 00385 // Timer 2 reload, used to check if switch pressed on overflow and 00386 // used for ADC continuous conversion 00387 //----------------------------------------------------------------------------- 00388 00389 void Timer_Init(void) 00390 { 00391 TMR2CN = 0x00; // Stop Timer2; Clear TF2; 00392 00393 CKCON &= ~0xF0; // Timer2 clocked based on T2XCLK; 00394 TMR2RL = 0; // Initialize reload value 00395 TMR2 = 0xffff; // Set to reload immediately 00396 00397 TR2 = 1; // Start Timer2 00398 } 00399 00400 //----------------------------------------------------------------------------- 00401 // Timer2_ISR 00402 //----------------------------------------------------------------------------- 00403 // 00404 // Called when timer 2 overflows, check to see if switch is pressed, 00405 // then watch for release. 00406 // 00407 //----------------------------------------------------------------------------- 00408 00409 void Timer2_ISR(void) interrupt 5 00410 { 00411 TF2H = 0; // Clear Timer2 interrupt flag 00412 00413 if ( !Sw1 ) // Check for switch #1 pressed 00414 { 00415 if ( !Toggle1 ) // Toggle is used to debounce switch 00416 { // so that one press and release will 00417 Switch1State = !Switch1State; // toggle the state of the switch sent 00418 Toggle1 = TRUE; // to the host 00419 switch_changed = TRUE; 00420 } 00421 } 00422 else Toggle1 = FALSE; // Reset toggle variable 00423 00424 if ( !Sw2 ) // Same as above, but Switch2 00425 { 00426 if ( !Toggle2 ) 00427 { 00428 Switch2State = !Switch2State; 00429 Toggle2 = TRUE; 00430 switch_changed = TRUE; 00431 } 00432 } 00433 else Toggle2 = FALSE; 00434 } 00435 00436 00437 //----------------------------------------------------------------------------- 00438 // End Of File 00439 //-----------------------------------------------------------------------------