Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of USBDevice by
USBHAL_LPC17.cpp
00001 /* Copyright (c) 2010-2011 mbed.org, MIT License 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00004 * and associated documentation files (the "Software"), to deal in the Software without 00005 * restriction, including without limitation the rights to use, copy, modify, merge, publish, 00006 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 00007 * Software is furnished to do so, subject to the following conditions: 00008 * 00009 * The above copyright notice and this permission notice shall be included in all copies or 00010 * substantial portions of the Software. 00011 * 00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00017 */ 00018 00019 #ifdef TARGET_LPC1768 00020 00021 #include "USBHAL.h" 00022 00023 00024 // Get endpoint direction 00025 #define IN_EP(endpoint) ((endpoint) & 1U ? true : false) 00026 #define OUT_EP(endpoint) ((endpoint) & 1U ? false : true) 00027 00028 // Convert physical endpoint number to register bit 00029 #define EP(endpoint) (1UL<<endpoint) 00030 00031 // Power Control for Peripherals register 00032 #define PCUSB (1UL<<31) 00033 00034 // USB Clock Control register 00035 #define DEV_CLK_EN (1UL<<1) 00036 #define AHB_CLK_EN (1UL<<4) 00037 00038 // USB Clock Status register 00039 #define DEV_CLK_ON (1UL<<1) 00040 #define AHB_CLK_ON (1UL<<4) 00041 00042 // USB Device Interupt registers 00043 #define FRAME (1UL<<0) 00044 #define EP_FAST (1UL<<1) 00045 #define EP_SLOW (1UL<<2) 00046 #define DEV_STAT (1UL<<3) 00047 #define CCEMPTY (1UL<<4) 00048 #define CDFULL (1UL<<5) 00049 #define RxENDPKT (1UL<<6) 00050 #define TxENDPKT (1UL<<7) 00051 #define EP_RLZED (1UL<<8) 00052 #define ERR_INT (1UL<<9) 00053 00054 // USB Control register 00055 #define RD_EN (1<<0) 00056 #define WR_EN (1<<1) 00057 #define LOG_ENDPOINT(endpoint) ((endpoint>>1)<<2) 00058 00059 // USB Receive Packet Length register 00060 #define DV (1UL<<10) 00061 #define PKT_RDY (1UL<<11) 00062 #define PKT_LNGTH_MASK (0x3ff) 00063 00064 // Serial Interface Engine (SIE) 00065 #define SIE_WRITE (0x01) 00066 #define SIE_READ (0x02) 00067 #define SIE_COMMAND (0x05) 00068 #define SIE_CMD_CODE(phase, data) ((phase<<8)|(data<<16)) 00069 00070 // SIE Command codes 00071 #define SIE_CMD_SET_ADDRESS (0xD0) 00072 #define SIE_CMD_CONFIGURE_DEVICE (0xD8) 00073 #define SIE_CMD_SET_MODE (0xF3) 00074 #define SIE_CMD_READ_FRAME_NUMBER (0xF5) 00075 #define SIE_CMD_READ_TEST_REGISTER (0xFD) 00076 #define SIE_CMD_SET_DEVICE_STATUS (0xFE) 00077 #define SIE_CMD_GET_DEVICE_STATUS (0xFE) 00078 #define SIE_CMD_GET_ERROR_CODE (0xFF) 00079 #define SIE_CMD_READ_ERROR_STATUS (0xFB) 00080 00081 #define SIE_CMD_SELECT_ENDPOINT(endpoint) (0x00+endpoint) 00082 #define SIE_CMD_SELECT_ENDPOINT_CLEAR_INTERRUPT(endpoint) (0x40+endpoint) 00083 #define SIE_CMD_SET_ENDPOINT_STATUS(endpoint) (0x40+endpoint) 00084 00085 #define SIE_CMD_CLEAR_BUFFER (0xF2) 00086 #define SIE_CMD_VALIDATE_BUFFER (0xFA) 00087 00088 // SIE Device Status register 00089 #define SIE_DS_CON (1<<0) 00090 #define SIE_DS_CON_CH (1<<1) 00091 #define SIE_DS_SUS (1<<2) 00092 #define SIE_DS_SUS_CH (1<<3) 00093 #define SIE_DS_RST (1<<4) 00094 00095 // SIE Device Set Address register 00096 #define SIE_DSA_DEV_EN (1<<7) 00097 00098 // SIE Configue Device register 00099 #define SIE_CONF_DEVICE (1<<0) 00100 00101 // Select Endpoint register 00102 #define SIE_SE_FE (1<<0) 00103 #define SIE_SE_ST (1<<1) 00104 #define SIE_SE_STP (1<<2) 00105 #define SIE_SE_PO (1<<3) 00106 #define SIE_SE_EPN (1<<4) 00107 #define SIE_SE_B_1_FULL (1<<5) 00108 #define SIE_SE_B_2_FULL (1<<6) 00109 00110 // Set Endpoint Status command 00111 #define SIE_SES_ST (1<<0) 00112 #define SIE_SES_DA (1<<5) 00113 #define SIE_SES_RF_MO (1<<6) 00114 #define SIE_SES_CND_ST (1<<7) 00115 00116 00117 USBHAL *USBHAL::instance; 00118 00119 volatile int epComplete; 00120 uint32_t endpointStallState; 00121 00122 static void SIECommand( uint32_t command ) 00123 { 00124 // The command phase of a SIE transaction 00125 LPC_USB->USBDevIntClr = CCEMPTY; 00126 LPC_USB->USBCmdCode = SIE_CMD_CODE( SIE_COMMAND, command ); 00127 00128 while ( !( LPC_USB->USBDevIntSt & CCEMPTY ) ); 00129 } 00130 00131 static void SIEWriteData( uint8_t data ) 00132 { 00133 // The data write phase of a SIE transaction 00134 LPC_USB->USBDevIntClr = CCEMPTY; 00135 LPC_USB->USBCmdCode = SIE_CMD_CODE( SIE_WRITE, data ); 00136 00137 while ( !( LPC_USB->USBDevIntSt & CCEMPTY ) ); 00138 } 00139 00140 static uint8_t SIEReadData( uint32_t command ) 00141 { 00142 // The data read phase of a SIE transaction 00143 LPC_USB->USBDevIntClr = CDFULL; 00144 LPC_USB->USBCmdCode = SIE_CMD_CODE( SIE_READ, command ); 00145 00146 while ( !( LPC_USB->USBDevIntSt & CDFULL ) ); 00147 00148 return ( uint8_t )LPC_USB->USBCmdData; 00149 } 00150 00151 static void SIEsetDeviceStatus( uint8_t status ) 00152 { 00153 // Write SIE device status register 00154 SIECommand( SIE_CMD_SET_DEVICE_STATUS ); 00155 SIEWriteData( status ); 00156 } 00157 00158 static uint8_t SIEgetDeviceStatus( void ) 00159 { 00160 // Read SIE device status register 00161 SIECommand( SIE_CMD_GET_DEVICE_STATUS ); 00162 return SIEReadData( SIE_CMD_GET_DEVICE_STATUS ); 00163 } 00164 00165 void SIEsetAddress( uint8_t address ) 00166 { 00167 // Write SIE device address register 00168 SIECommand( SIE_CMD_SET_ADDRESS ); 00169 SIEWriteData( ( address & 0x7f ) | SIE_DSA_DEV_EN ); 00170 } 00171 00172 static uint8_t SIEselectEndpoint( uint8_t endpoint ) 00173 { 00174 // SIE select endpoint command 00175 SIECommand( SIE_CMD_SELECT_ENDPOINT( endpoint ) ); 00176 return SIEReadData( SIE_CMD_SELECT_ENDPOINT( endpoint ) ); 00177 } 00178 00179 static uint8_t SIEclearBuffer( void ) 00180 { 00181 // SIE clear buffer command 00182 SIECommand( SIE_CMD_CLEAR_BUFFER ); 00183 return SIEReadData( SIE_CMD_CLEAR_BUFFER ); 00184 } 00185 00186 static void SIEvalidateBuffer( void ) 00187 { 00188 // SIE validate buffer command 00189 SIECommand( SIE_CMD_VALIDATE_BUFFER ); 00190 } 00191 00192 static void SIEsetEndpointStatus( uint8_t endpoint, uint8_t status ) 00193 { 00194 // SIE set endpoint status command 00195 SIECommand( SIE_CMD_SET_ENDPOINT_STATUS( endpoint ) ); 00196 SIEWriteData( status ); 00197 } 00198 00199 static uint16_t SIEgetFrameNumber( void ) __attribute__ ( ( unused ) ); 00200 static uint16_t SIEgetFrameNumber( void ) 00201 { 00202 // Read current frame number 00203 uint16_t lowByte; 00204 uint16_t highByte; 00205 SIECommand( SIE_CMD_READ_FRAME_NUMBER ); 00206 lowByte = SIEReadData( SIE_CMD_READ_FRAME_NUMBER ); 00207 highByte = SIEReadData( SIE_CMD_READ_FRAME_NUMBER ); 00208 return ( highByte << 8 ) | lowByte; 00209 } 00210 00211 static void SIEconfigureDevice( void ) 00212 { 00213 // SIE Configure device command 00214 SIECommand( SIE_CMD_CONFIGURE_DEVICE ); 00215 SIEWriteData( SIE_CONF_DEVICE ); 00216 } 00217 00218 static void SIEunconfigureDevice( void ) 00219 { 00220 // SIE Configure device command 00221 SIECommand( SIE_CMD_CONFIGURE_DEVICE ); 00222 SIEWriteData( 0 ); 00223 } 00224 00225 static void SIEconnect( void ) 00226 { 00227 // Connect USB device 00228 uint8_t status; 00229 status = SIEgetDeviceStatus(); 00230 SIEsetDeviceStatus( status | SIE_DS_CON ); 00231 } 00232 00233 00234 static void SIEdisconnect( void ) 00235 { 00236 // Disconnect USB device 00237 uint8_t status; 00238 status = SIEgetDeviceStatus(); 00239 SIEsetDeviceStatus( status & ~SIE_DS_CON ); 00240 } 00241 00242 00243 static uint8_t selectEndpointClearInterrupt( uint8_t endpoint ) 00244 { 00245 // Implemented using using EP_INT_CLR. 00246 LPC_USB->USBEpIntClr = EP( endpoint ); 00247 00248 while ( !( LPC_USB->USBDevIntSt & CDFULL ) ); 00249 00250 return ( uint8_t )LPC_USB->USBCmdData; 00251 } 00252 00253 00254 00255 00256 00257 static void enableEndpointEvent( uint8_t endpoint ) 00258 { 00259 // Enable an endpoint interrupt 00260 LPC_USB->USBEpIntEn |= EP( endpoint ); 00261 } 00262 00263 static void disableEndpointEvent( uint8_t endpoint ) __attribute__ ( ( unused ) ); 00264 static void disableEndpointEvent( uint8_t endpoint ) 00265 { 00266 // Disable an endpoint interrupt 00267 LPC_USB->USBEpIntEn &= ~EP( endpoint ); 00268 } 00269 00270 static volatile uint32_t __attribute__( ( used ) ) dummyRead; 00271 00272 00273 uint32_t USBHAL::endpointReadcore( uint8_t endpoint, uint8_t *buffer ) 00274 { 00275 // Read from an OUT endpoint 00276 uint32_t size; 00277 uint32_t i; 00278 uint32_t data = 0; 00279 uint8_t offset; 00280 LPC_USB->USBCtrl = LOG_ENDPOINT( endpoint ) | RD_EN; 00281 00282 while ( !( LPC_USB->USBRxPLen & PKT_RDY ) ); 00283 00284 size = LPC_USB->USBRxPLen & PKT_LNGTH_MASK; 00285 offset = 0; 00286 00287 if ( size > 0 ) 00288 { 00289 for ( i = 0; i < size; i++ ) 00290 { 00291 if ( offset == 0 ) 00292 { 00293 // Fetch up to four bytes of data as a word 00294 data = LPC_USB->USBRxData; 00295 } 00296 00297 // extract a byte 00298 *buffer = ( data >> offset ) & 0xff; 00299 buffer++; 00300 // move on to the next byte 00301 offset = ( offset + 8 ) % 32; 00302 } 00303 } 00304 else 00305 { 00306 dummyRead = LPC_USB->USBRxData; 00307 } 00308 00309 LPC_USB->USBCtrl = 0; 00310 00311 if ( ( endpoint >> 1 ) % 3 || ( endpoint >> 1 ) == 0 ) 00312 { 00313 SIEselectEndpoint( endpoint ); 00314 SIEclearBuffer(); 00315 } 00316 00317 return size; 00318 } 00319 00320 static void endpointWritecore( uint8_t endpoint, uint8_t *buffer, uint32_t size ) 00321 { 00322 // Write to an IN endpoint 00323 uint32_t temp, data; 00324 uint8_t offset; 00325 LPC_USB->USBCtrl = LOG_ENDPOINT( endpoint ) | WR_EN; 00326 LPC_USB->USBTxPLen = size; 00327 offset = 0; 00328 data = 0; 00329 00330 if ( size > 0 ) 00331 { 00332 do 00333 { 00334 // Fetch next data byte into a word-sized temporary variable 00335 temp = *buffer++; 00336 // Add to current data word 00337 temp = temp << offset; 00338 data = data | temp; 00339 // move on to the next byte 00340 offset = ( offset + 8 ) % 32; 00341 size--; 00342 00343 if ( ( offset == 0 ) || ( size == 0 ) ) 00344 { 00345 // Write the word to the endpoint 00346 LPC_USB->USBTxData = data; 00347 data = 0; 00348 } 00349 } 00350 while ( size > 0 ); 00351 } 00352 else 00353 { 00354 LPC_USB->USBTxData = 0; 00355 } 00356 00357 // Clear WR_EN to cover zero length packet case 00358 LPC_USB->USBCtrl = 0; 00359 SIEselectEndpoint( endpoint ); 00360 SIEvalidateBuffer(); 00361 } 00362 00363 00364 00365 00366 00367 00368 00369 USBHAL::USBHAL( void ) 00370 { 00371 // Disable IRQ 00372 NVIC_DisableIRQ( USB_IRQn ); 00373 // Enable power to USB device controller 00374 LPC_SC->PCONP |= PCUSB; 00375 // Enable USB clocks 00376 LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN; 00377 00378 while ( LPC_USB->USBClkSt != ( DEV_CLK_ON | AHB_CLK_ON ) ); 00379 00380 // Configure pins P0.29 and P0.30 to be USB D+ and USB D- 00381 LPC_PINCON->PINSEL1 &= 0xc3ffffff; 00382 LPC_PINCON->PINSEL1 |= 0x14000000; 00383 // Disconnect USB device 00384 SIEdisconnect(); 00385 // Configure pin P2.9 to be Connect 00386 LPC_PINCON->PINSEL4 &= 0xfffcffff; 00387 LPC_PINCON->PINSEL4 |= 0x00040000; 00388 // Connect must be low for at least 2.5uS 00389 wait( 0.3 ); 00390 // Set the maximum packet size for the control endpoints 00391 realiseEndpoint( EP0IN, MAX_PACKET_SIZE_EP0, 0 ); 00392 realiseEndpoint( EP0OUT, MAX_PACKET_SIZE_EP0, 0 ); 00393 // Attach IRQ 00394 instance = this; 00395 NVIC_SetVector( USB_IRQn, ( uint32_t )&_usbisr ); 00396 NVIC_EnableIRQ( USB_IRQn ); 00397 // Enable interrupts for device events and EP0 00398 LPC_USB->USBDevIntEn = EP_SLOW | DEV_STAT | FRAME; 00399 enableEndpointEvent( EP0IN ); 00400 enableEndpointEvent( EP0OUT ); 00401 } 00402 00403 USBHAL::~USBHAL( void ) 00404 { 00405 // Ensure device disconnected 00406 SIEdisconnect(); 00407 // Disable USB interrupts 00408 NVIC_DisableIRQ( USB_IRQn ); 00409 } 00410 00411 void USBHAL::connect( void ) 00412 { 00413 // Connect USB device 00414 SIEconnect(); 00415 } 00416 00417 void USBHAL::disconnect( void ) 00418 { 00419 // Disconnect USB device 00420 SIEdisconnect(); 00421 } 00422 00423 void USBHAL::configureDevice( void ) 00424 { 00425 SIEconfigureDevice(); 00426 } 00427 00428 void USBHAL::unconfigureDevice( void ) 00429 { 00430 SIEunconfigureDevice(); 00431 } 00432 00433 void USBHAL::setAddress( uint8_t address ) 00434 { 00435 SIEsetAddress( address ); 00436 } 00437 00438 void USBHAL::EP0setup( uint8_t *buffer ) 00439 { 00440 endpointReadcore( EP0OUT, buffer ); 00441 } 00442 00443 void USBHAL::EP0read( void ) 00444 { 00445 // Not required 00446 } 00447 00448 uint32_t USBHAL::EP0getReadResult( uint8_t *buffer ) 00449 { 00450 return endpointReadcore( EP0OUT, buffer ); 00451 } 00452 00453 void USBHAL::EP0write( uint8_t *buffer, uint32_t size ) 00454 { 00455 endpointWritecore( EP0IN, buffer, size ); 00456 } 00457 00458 void USBHAL::EP0getWriteResult( void ) 00459 { 00460 // Not required 00461 } 00462 00463 void USBHAL::EP0stall( void ) 00464 { 00465 // This will stall both control endpoints 00466 stallEndpoint( EP0OUT ); 00467 } 00468 00469 EP_STATUS USBHAL::endpointRead( uint8_t endpoint, uint32_t maximumSize ) 00470 { 00471 return EP_PENDING; 00472 } 00473 00474 EP_STATUS USBHAL::endpointReadResult( uint8_t endpoint, uint8_t *buffer, uint32_t *bytesRead ) 00475 { 00476 //for isochronous endpoint, we don't wait an interrupt 00477 if ( ( endpoint >> 1 ) % 3 || ( endpoint >> 1 ) == 0 ) 00478 { 00479 if ( !( epComplete & EP( endpoint ) ) ) 00480 { 00481 return EP_PENDING; 00482 } 00483 } 00484 00485 *bytesRead = endpointReadcore( endpoint, buffer ); 00486 epComplete &= ~EP( endpoint ); 00487 return EP_COMPLETED; 00488 } 00489 00490 EP_STATUS USBHAL::endpointWrite( uint8_t endpoint, uint8_t *data, uint32_t size ) 00491 { 00492 if ( getEndpointStallState( endpoint ) ) 00493 { 00494 return EP_STALLED; 00495 } 00496 00497 epComplete &= ~EP( endpoint ); 00498 endpointWritecore( endpoint, data, size ); 00499 return EP_PENDING; 00500 } 00501 00502 EP_STATUS USBHAL::endpointWriteResult( uint8_t endpoint ) 00503 { 00504 if ( epComplete & EP( endpoint ) ) 00505 { 00506 epComplete &= ~EP( endpoint ); 00507 return EP_COMPLETED; 00508 } 00509 00510 return EP_PENDING; 00511 } 00512 00513 bool USBHAL::realiseEndpoint( uint8_t endpoint, uint32_t maxPacket, uint32_t flags ) 00514 { 00515 // Realise an endpoint 00516 LPC_USB->USBDevIntClr = EP_RLZED; 00517 LPC_USB->USBReEp |= EP( endpoint ); 00518 LPC_USB->USBEpInd = endpoint; 00519 LPC_USB->USBMaxPSize = maxPacket; 00520 00521 while ( !( LPC_USB->USBDevIntSt & EP_RLZED ) ); 00522 00523 LPC_USB->USBDevIntClr = EP_RLZED; 00524 // Clear stall state 00525 endpointStallState &= ~EP( endpoint ); 00526 enableEndpointEvent( endpoint ); 00527 return true; 00528 } 00529 00530 void USBHAL::stallEndpoint( uint8_t endpoint ) 00531 { 00532 // Stall an endpoint 00533 if ( ( endpoint == EP0IN ) || ( endpoint == EP0OUT ) ) 00534 { 00535 // Conditionally stall both control endpoints 00536 SIEsetEndpointStatus( EP0OUT, SIE_SES_CND_ST ); 00537 } 00538 else 00539 { 00540 SIEsetEndpointStatus( endpoint, SIE_SES_ST ); 00541 // Update stall state 00542 endpointStallState |= EP( endpoint ); 00543 } 00544 } 00545 00546 void USBHAL::unstallEndpoint( uint8_t endpoint ) 00547 { 00548 // Unstall an endpoint. The endpoint will also be reinitialised 00549 SIEsetEndpointStatus( endpoint, 0 ); 00550 // Update stall state 00551 endpointStallState &= ~EP( endpoint ); 00552 } 00553 00554 bool USBHAL::getEndpointStallState( uint8_t endpoint ) 00555 { 00556 // Returns true if endpoint stalled 00557 return endpointStallState & EP( endpoint ); 00558 } 00559 00560 void USBHAL::remoteWakeup( void ) 00561 { 00562 // Remote wakeup 00563 uint8_t status; 00564 // Enable USB clocks 00565 LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN; 00566 00567 while ( LPC_USB->USBClkSt != ( DEV_CLK_ON | AHB_CLK_ON ) ); 00568 00569 status = SIEgetDeviceStatus(); 00570 SIEsetDeviceStatus( status & ~SIE_DS_SUS ); 00571 } 00572 00573 00574 00575 00576 00577 void USBHAL::_usbisr( void ) 00578 { 00579 instance->usbisr(); 00580 } 00581 00582 00583 void USBHAL::usbisr( void ) 00584 { 00585 uint8_t devStat; 00586 00587 if ( LPC_USB->USBDevIntSt & FRAME ) 00588 { 00589 // Start of frame event 00590 SOF( SIEgetFrameNumber() ); 00591 // Clear interrupt status flag 00592 LPC_USB->USBDevIntClr = FRAME; 00593 } 00594 00595 if ( LPC_USB->USBDevIntSt & DEV_STAT ) 00596 { 00597 // Device Status interrupt 00598 // Must clear the interrupt status flag before reading the device status from the SIE 00599 LPC_USB->USBDevIntClr = DEV_STAT; 00600 // Read device status from SIE 00601 devStat = SIEgetDeviceStatus(); 00602 //printf("devStat: %d\r\n", devStat); 00603 00604 if ( devStat & SIE_DS_SUS_CH ) 00605 { 00606 // Suspend status changed 00607 if( ( devStat & SIE_DS_SUS ) != 0 ) 00608 { 00609 suspendStateChanged( 0 ); 00610 } 00611 } 00612 00613 if ( devStat & SIE_DS_RST ) 00614 { 00615 // Bus reset 00616 if( ( devStat & SIE_DS_SUS ) == 0 ) 00617 { 00618 suspendStateChanged( 1 ); 00619 } 00620 00621 busReset(); 00622 } 00623 } 00624 00625 if ( LPC_USB->USBDevIntSt & EP_SLOW ) 00626 { 00627 // (Slow) Endpoint Interrupt 00628 00629 // Process each endpoint interrupt 00630 if ( LPC_USB->USBEpIntSt & EP( EP0OUT ) ) 00631 { 00632 if ( selectEndpointClearInterrupt( EP0OUT ) & SIE_SE_STP ) 00633 { 00634 // this is a setup packet 00635 EP0setupCallback(); 00636 } 00637 else 00638 { 00639 EP0out(); 00640 } 00641 00642 LPC_USB->USBDevIntClr = EP_SLOW; 00643 } 00644 00645 if ( LPC_USB->USBEpIntSt & EP( EP0IN ) ) 00646 { 00647 selectEndpointClearInterrupt( EP0IN ); 00648 LPC_USB->USBDevIntClr = EP_SLOW; 00649 EP0in(); 00650 } 00651 00652 // TODO: This should cover all endpoints, not just EP1,2,3: 00653 if ( LPC_USB->USBEpIntSt & EP( EP1IN ) ) 00654 { 00655 selectEndpointClearInterrupt( EP1IN ); 00656 epComplete |= EP( EP1IN ); 00657 LPC_USB->USBDevIntClr = EP_SLOW; 00658 00659 if ( EP1_IN_callback() ) 00660 { 00661 epComplete &= ~EP( EP1IN ); 00662 } 00663 } 00664 00665 if ( LPC_USB->USBEpIntSt & EP( EP1OUT ) ) 00666 { 00667 selectEndpointClearInterrupt( EP1OUT ); 00668 epComplete |= EP( EP1OUT ); 00669 LPC_USB->USBDevIntClr = EP_SLOW; 00670 00671 if ( EP1_OUT_callback() ) 00672 { 00673 epComplete &= ~EP( EP1OUT ); 00674 } 00675 } 00676 00677 if ( LPC_USB->USBEpIntSt & EP( EP2IN ) ) 00678 { 00679 selectEndpointClearInterrupt( EP2IN ); 00680 epComplete |= EP( EP2IN ); 00681 LPC_USB->USBDevIntClr = EP_SLOW; 00682 00683 if ( EP2_IN_callback() ) 00684 { 00685 epComplete &= ~EP( EP2IN ); 00686 } 00687 } 00688 00689 if ( LPC_USB->USBEpIntSt & EP( EP2OUT ) ) 00690 { 00691 selectEndpointClearInterrupt( EP2OUT ); 00692 epComplete |= EP( EP2OUT ); 00693 LPC_USB->USBDevIntClr = EP_SLOW; 00694 00695 if ( EP2_OUT_callback() ) 00696 { 00697 epComplete &= ~EP( EP2OUT ); 00698 } 00699 } 00700 00701 if ( LPC_USB->USBEpIntSt & EP( EP3IN ) ) 00702 { 00703 selectEndpointClearInterrupt( EP3IN ); 00704 epComplete |= EP( EP3IN ); 00705 LPC_USB->USBDevIntClr = EP_SLOW; 00706 00707 if ( EP3_IN_callback() ) 00708 { 00709 epComplete &= ~EP( EP3IN ); 00710 } 00711 } 00712 00713 if ( LPC_USB->USBEpIntSt & EP( EP3OUT ) ) 00714 { 00715 selectEndpointClearInterrupt( EP3OUT ); 00716 epComplete |= EP( EP3OUT ); 00717 LPC_USB->USBDevIntClr = EP_SLOW; 00718 00719 if ( EP3_OUT_callback() ) 00720 { 00721 epComplete &= ~EP( EP3OUT ); 00722 } 00723 } 00724 } 00725 } 00726 00727 #endif 00728
Generated on Sat Jul 16 2022 03:17:41 by
1.7.2
