USB device stack
Dependents: blinky_max32630fthr FTHR_USB_serial FTHR_OLED HSP_RPC_GUI_3_0_1 ... more
Fork of USBDevice by
USBHAL_LPC40.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 #if defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM) 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 PORT_CLK_EN (1UL<<3) 00037 #define AHB_CLK_EN (1UL<<4) 00038 00039 // USB Clock Status register 00040 #define DEV_CLK_ON (1UL<<1) 00041 #define AHB_CLK_ON (1UL<<4) 00042 00043 // USB Device Interupt registers 00044 #define FRAME (1UL<<0) 00045 #define EP_FAST (1UL<<1) 00046 #define EP_SLOW (1UL<<2) 00047 #define DEV_STAT (1UL<<3) 00048 #define CCEMPTY (1UL<<4) 00049 #define CDFULL (1UL<<5) 00050 #define RxENDPKT (1UL<<6) 00051 #define TxENDPKT (1UL<<7) 00052 #define EP_RLZED (1UL<<8) 00053 #define ERR_INT (1UL<<9) 00054 00055 // USB Control register 00056 #define RD_EN (1<<0) 00057 #define WR_EN (1<<1) 00058 #define LOG_ENDPOINT(endpoint) ((endpoint>>1)<<2) 00059 00060 // USB Receive Packet Length register 00061 #define DV (1UL<<10) 00062 #define PKT_RDY (1UL<<11) 00063 #define PKT_LNGTH_MASK (0x3ff) 00064 00065 // Serial Interface Engine (SIE) 00066 #define SIE_WRITE (0x01) 00067 #define SIE_READ (0x02) 00068 #define SIE_COMMAND (0x05) 00069 #define SIE_CMD_CODE(phase, data) ((phase<<8)|(data<<16)) 00070 00071 // SIE Command codes 00072 #define SIE_CMD_SET_ADDRESS (0xD0) 00073 #define SIE_CMD_CONFIGURE_DEVICE (0xD8) 00074 #define SIE_CMD_SET_MODE (0xF3) 00075 #define SIE_CMD_READ_FRAME_NUMBER (0xF5) 00076 #define SIE_CMD_READ_TEST_REGISTER (0xFD) 00077 #define SIE_CMD_SET_DEVICE_STATUS (0xFE) 00078 #define SIE_CMD_GET_DEVICE_STATUS (0xFE) 00079 #define SIE_CMD_GET_ERROR_CODE (0xFF) 00080 #define SIE_CMD_READ_ERROR_STATUS (0xFB) 00081 00082 #define SIE_CMD_SELECT_ENDPOINT(endpoint) (0x00+endpoint) 00083 #define SIE_CMD_SELECT_ENDPOINT_CLEAR_INTERRUPT(endpoint) (0x40+endpoint) 00084 #define SIE_CMD_SET_ENDPOINT_STATUS(endpoint) (0x40+endpoint) 00085 00086 #define SIE_CMD_CLEAR_BUFFER (0xF2) 00087 #define SIE_CMD_VALIDATE_BUFFER (0xFA) 00088 00089 // SIE Device Status register 00090 #define SIE_DS_CON (1<<0) 00091 #define SIE_DS_CON_CH (1<<1) 00092 #define SIE_DS_SUS (1<<2) 00093 #define SIE_DS_SUS_CH (1<<3) 00094 #define SIE_DS_RST (1<<4) 00095 00096 // SIE Device Set Address register 00097 #define SIE_DSA_DEV_EN (1<<7) 00098 00099 // SIE Configue Device register 00100 #define SIE_CONF_DEVICE (1<<0) 00101 00102 // Select Endpoint register 00103 #define SIE_SE_FE (1<<0) 00104 #define SIE_SE_ST (1<<1) 00105 #define SIE_SE_STP (1<<2) 00106 #define SIE_SE_PO (1<<3) 00107 #define SIE_SE_EPN (1<<4) 00108 #define SIE_SE_B_1_FULL (1<<5) 00109 #define SIE_SE_B_2_FULL (1<<6) 00110 00111 // Set Endpoint Status command 00112 #define SIE_SES_ST (1<<0) 00113 #define SIE_SES_DA (1<<5) 00114 #define SIE_SES_RF_MO (1<<6) 00115 #define SIE_SES_CND_ST (1<<7) 00116 00117 00118 USBHAL * USBHAL::instance; 00119 00120 static volatile int epComplete; 00121 static uint32_t endpointStallState; 00122 00123 static void SIECommand(uint32_t command) { 00124 // The command phase of a SIE transaction 00125 LPC_USB->DevIntClr = CCEMPTY; 00126 LPC_USB->CmdCode = SIE_CMD_CODE(SIE_COMMAND, command); 00127 while (!(LPC_USB->DevIntSt & CCEMPTY)); 00128 } 00129 00130 static void SIEWriteData(uint8_t data) { 00131 // The data write phase of a SIE transaction 00132 LPC_USB->DevIntClr = CCEMPTY; 00133 LPC_USB->CmdCode = SIE_CMD_CODE(SIE_WRITE, data); 00134 while (!(LPC_USB->DevIntSt & CCEMPTY)); 00135 } 00136 00137 static uint8_t SIEReadData(uint32_t command) { 00138 // The data read phase of a SIE transaction 00139 LPC_USB->DevIntClr = CDFULL; 00140 LPC_USB->CmdCode = SIE_CMD_CODE(SIE_READ, command); 00141 while (!(LPC_USB->DevIntSt & CDFULL)); 00142 return (uint8_t)LPC_USB->CmdData; 00143 } 00144 00145 static void SIEsetDeviceStatus(uint8_t status) { 00146 // Write SIE device status register 00147 SIECommand(SIE_CMD_SET_DEVICE_STATUS); 00148 SIEWriteData(status); 00149 } 00150 00151 static uint8_t SIEgetDeviceStatus(void) { 00152 // Read SIE device status register 00153 SIECommand(SIE_CMD_GET_DEVICE_STATUS); 00154 return SIEReadData(SIE_CMD_GET_DEVICE_STATUS); 00155 } 00156 00157 void SIEsetAddress(uint8_t address) { 00158 // Write SIE device address register 00159 SIECommand(SIE_CMD_SET_ADDRESS); 00160 SIEWriteData((address & 0x7f) | SIE_DSA_DEV_EN); 00161 } 00162 00163 static uint8_t SIEselectEndpoint(uint8_t endpoint) { 00164 // SIE select endpoint command 00165 SIECommand(SIE_CMD_SELECT_ENDPOINT(endpoint)); 00166 return SIEReadData(SIE_CMD_SELECT_ENDPOINT(endpoint)); 00167 } 00168 00169 static uint8_t SIEclearBuffer(void) { 00170 // SIE clear buffer command 00171 SIECommand(SIE_CMD_CLEAR_BUFFER); 00172 return SIEReadData(SIE_CMD_CLEAR_BUFFER); 00173 } 00174 00175 static void SIEvalidateBuffer(void) { 00176 // SIE validate buffer command 00177 SIECommand(SIE_CMD_VALIDATE_BUFFER); 00178 } 00179 00180 static void SIEsetEndpointStatus(uint8_t endpoint, uint8_t status) { 00181 // SIE set endpoint status command 00182 SIECommand(SIE_CMD_SET_ENDPOINT_STATUS(endpoint)); 00183 SIEWriteData(status); 00184 } 00185 00186 static uint16_t SIEgetFrameNumber(void) __attribute__ ((unused)); 00187 static uint16_t SIEgetFrameNumber(void) { 00188 // Read current frame number 00189 uint16_t lowByte; 00190 uint16_t highByte; 00191 00192 SIECommand(SIE_CMD_READ_FRAME_NUMBER); 00193 lowByte = SIEReadData(SIE_CMD_READ_FRAME_NUMBER); 00194 highByte = SIEReadData(SIE_CMD_READ_FRAME_NUMBER); 00195 00196 return (highByte << 8) | lowByte; 00197 } 00198 00199 static void SIEconfigureDevice(void) { 00200 // SIE Configure device command 00201 SIECommand(SIE_CMD_CONFIGURE_DEVICE); 00202 SIEWriteData(SIE_CONF_DEVICE); 00203 } 00204 00205 static void SIEunconfigureDevice(void) { 00206 // SIE Configure device command 00207 SIECommand(SIE_CMD_CONFIGURE_DEVICE); 00208 SIEWriteData(0); 00209 } 00210 00211 static void SIEconnect(void) { 00212 // Connect USB device 00213 uint8_t status = SIEgetDeviceStatus(); 00214 SIEsetDeviceStatus(status | SIE_DS_CON); 00215 } 00216 00217 00218 static void SIEdisconnect(void) { 00219 // Disconnect USB device 00220 uint8_t status = SIEgetDeviceStatus(); 00221 SIEsetDeviceStatus(status & ~SIE_DS_CON); 00222 } 00223 00224 00225 static uint8_t selectEndpointClearInterrupt(uint8_t endpoint) { 00226 // Implemented using using EP_INT_CLR. 00227 LPC_USB->EpIntClr = EP(endpoint); 00228 while (!(LPC_USB->DevIntSt & CDFULL)); 00229 return (uint8_t)LPC_USB->CmdData; 00230 } 00231 00232 00233 static void enableEndpointEvent(uint8_t endpoint) { 00234 // Enable an endpoint interrupt 00235 LPC_USB->EpIntEn |= EP(endpoint); 00236 } 00237 00238 static void disableEndpointEvent(uint8_t endpoint) __attribute__ ((unused)); 00239 static void disableEndpointEvent(uint8_t endpoint) { 00240 // Disable an endpoint interrupt 00241 LPC_USB->EpIntEn &= ~EP(endpoint); 00242 } 00243 00244 static volatile uint32_t __attribute__((used)) dummyRead; 00245 uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) { 00246 // Read from an OUT endpoint 00247 uint32_t size; 00248 uint32_t i; 00249 uint32_t data = 0; 00250 uint8_t offset; 00251 00252 LPC_USB->Ctrl = LOG_ENDPOINT(endpoint) | RD_EN; 00253 while (!(LPC_USB->RxPLen & PKT_RDY)); 00254 00255 size = LPC_USB->RxPLen & PKT_LNGTH_MASK; 00256 00257 offset = 0; 00258 00259 if (size > 0) { 00260 for (i=0; i<size; i++) { 00261 if (offset==0) { 00262 // Fetch up to four bytes of data as a word 00263 data = LPC_USB->RxData; 00264 } 00265 00266 // extract a byte 00267 *buffer = (data>>offset) & 0xff; 00268 buffer++; 00269 00270 // move on to the next byte 00271 offset = (offset + 8) % 32; 00272 } 00273 } else { 00274 dummyRead = LPC_USB->RxData; 00275 } 00276 00277 LPC_USB->Ctrl = 0; 00278 00279 if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) { 00280 SIEselectEndpoint(endpoint); 00281 SIEclearBuffer(); 00282 } 00283 00284 return size; 00285 } 00286 00287 static void endpointWritecore(uint8_t endpoint, uint8_t *buffer, uint32_t size) { 00288 // Write to an IN endpoint 00289 uint32_t temp, data; 00290 uint8_t offset; 00291 00292 LPC_USB->Ctrl = LOG_ENDPOINT(endpoint) | WR_EN; 00293 00294 LPC_USB->TxPLen = size; 00295 offset = 0; 00296 data = 0; 00297 00298 if (size>0) { 00299 do { 00300 // Fetch next data byte into a word-sized temporary variable 00301 temp = *buffer++; 00302 00303 // Add to current data word 00304 temp = temp << offset; 00305 data = data | temp; 00306 00307 // move on to the next byte 00308 offset = (offset + 8) % 32; 00309 size--; 00310 00311 if ((offset==0) || (size==0)) { 00312 // Write the word to the endpoint 00313 LPC_USB->TxData = data; 00314 data = 0; 00315 } 00316 } while (size>0); 00317 } else { 00318 LPC_USB->TxData = 0; 00319 } 00320 00321 // Clear WR_EN to cover zero length packet case 00322 LPC_USB->Ctrl=0; 00323 00324 SIEselectEndpoint(endpoint); 00325 SIEvalidateBuffer(); 00326 } 00327 00328 USBHAL::USBHAL(void) { 00329 // Disable IRQ 00330 NVIC_DisableIRQ(USB_IRQn); 00331 00332 // fill in callback array 00333 epCallback[0] = &USBHAL::EP1_OUT_callback; 00334 epCallback[1] = &USBHAL::EP1_IN_callback; 00335 epCallback[2] = &USBHAL::EP2_OUT_callback; 00336 epCallback[3] = &USBHAL::EP2_IN_callback; 00337 epCallback[4] = &USBHAL::EP3_OUT_callback; 00338 epCallback[5] = &USBHAL::EP3_IN_callback; 00339 epCallback[6] = &USBHAL::EP4_OUT_callback; 00340 epCallback[7] = &USBHAL::EP4_IN_callback; 00341 epCallback[8] = &USBHAL::EP5_OUT_callback; 00342 epCallback[9] = &USBHAL::EP5_IN_callback; 00343 epCallback[10] = &USBHAL::EP6_OUT_callback; 00344 epCallback[11] = &USBHAL::EP6_IN_callback; 00345 epCallback[12] = &USBHAL::EP7_OUT_callback; 00346 epCallback[13] = &USBHAL::EP7_IN_callback; 00347 epCallback[14] = &USBHAL::EP8_OUT_callback; 00348 epCallback[15] = &USBHAL::EP8_IN_callback; 00349 epCallback[16] = &USBHAL::EP9_OUT_callback; 00350 epCallback[17] = &USBHAL::EP9_IN_callback; 00351 epCallback[18] = &USBHAL::EP10_OUT_callback; 00352 epCallback[19] = &USBHAL::EP10_IN_callback; 00353 epCallback[20] = &USBHAL::EP11_OUT_callback; 00354 epCallback[21] = &USBHAL::EP11_IN_callback; 00355 epCallback[22] = &USBHAL::EP12_OUT_callback; 00356 epCallback[23] = &USBHAL::EP12_IN_callback; 00357 epCallback[24] = &USBHAL::EP13_OUT_callback; 00358 epCallback[25] = &USBHAL::EP13_IN_callback; 00359 epCallback[26] = &USBHAL::EP14_OUT_callback; 00360 epCallback[27] = &USBHAL::EP14_IN_callback; 00361 epCallback[28] = &USBHAL::EP15_OUT_callback; 00362 epCallback[29] = &USBHAL::EP15_IN_callback; 00363 00364 // Enable power to USB device controller 00365 LPC_SC->PCONP |= PCUSB; 00366 00367 // Enable USB clocks 00368 LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN | PORT_CLK_EN; 00369 while ((LPC_USB->USBClkSt & (DEV_CLK_EN | AHB_CLK_EN | PORT_CLK_EN)) != (DEV_CLK_ON | AHB_CLK_ON | PORT_CLK_EN)); 00370 00371 // Select port USB2 00372 LPC_USB->StCtrl |= 3; 00373 00374 00375 // Configure pin P0.31 to be USB2 00376 LPC_IOCON->P0_31 &= ~0x07; 00377 LPC_IOCON->P0_31 |= 0x01; 00378 00379 // Disconnect USB device 00380 SIEdisconnect(); 00381 00382 // Configure pin P0.14 to be Connect 00383 LPC_IOCON->P0_14 &= ~0x07; 00384 LPC_IOCON->P0_14 |= 0x03; 00385 00386 // Connect must be low for at least 2.5uS 00387 wait(0.3); 00388 00389 // Set the maximum packet size for the control endpoints 00390 realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0); 00391 realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0); 00392 00393 // Attach IRQ 00394 instance = this; 00395 NVIC_SetVector(USB_IRQn, (uint32_t)&_usbisr); 00396 00397 // Enable interrupts for device events and EP0 00398 LPC_USB->DevIntEn = EP_SLOW | DEV_STAT | FRAME; 00399 enableEndpointEvent(EP0IN); 00400 enableEndpointEvent(EP0OUT); 00401 } 00402 00403 USBHAL::~USBHAL(void) { 00404 // Ensure device disconnected 00405 SIEdisconnect(); 00406 // Disable USB interrupts 00407 NVIC_DisableIRQ(USB_IRQn); 00408 } 00409 00410 void USBHAL::connect(void) { 00411 NVIC_EnableIRQ(USB_IRQn); 00412 // Connect USB device 00413 SIEconnect(); 00414 } 00415 00416 void USBHAL::disconnect(void) { 00417 NVIC_DisableIRQ(USB_IRQn); 00418 // Disconnect USB device 00419 SIEdisconnect(); 00420 } 00421 00422 void USBHAL::configureDevice(void) { 00423 SIEconfigureDevice(); 00424 } 00425 00426 void USBHAL::unconfigureDevice(void) { 00427 SIEunconfigureDevice(); 00428 } 00429 00430 void USBHAL::setAddress(uint8_t address) { 00431 SIEsetAddress(address); 00432 } 00433 00434 void USBHAL::EP0setup(uint8_t *buffer) { 00435 endpointReadcore(EP0OUT, buffer); 00436 } 00437 00438 void USBHAL::EP0read(void) { 00439 // Not required 00440 } 00441 00442 void USBHAL::EP0readStage(void) { 00443 // Not required 00444 } 00445 00446 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) { 00447 return endpointReadcore(EP0OUT, buffer); 00448 } 00449 00450 void USBHAL::EP0write(uint8_t *buffer, uint32_t size) { 00451 endpointWritecore(EP0IN, buffer, size); 00452 } 00453 00454 void USBHAL::EP0getWriteResult(void) { 00455 // Not required 00456 } 00457 00458 void USBHAL::EP0stall(void) { 00459 // This will stall both control endpoints 00460 stallEndpoint(EP0OUT); 00461 } 00462 00463 EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) { 00464 return EP_PENDING; 00465 } 00466 00467 EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) { 00468 00469 //for isochronous endpoint, we don't wait an interrupt 00470 if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) { 00471 if (!(epComplete & EP(endpoint))) 00472 return EP_PENDING; 00473 } 00474 00475 *bytesRead = endpointReadcore(endpoint, buffer); 00476 epComplete &= ~EP(endpoint); 00477 return EP_COMPLETED; 00478 } 00479 00480 EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) { 00481 if (getEndpointStallState(endpoint)) { 00482 return EP_STALLED; 00483 } 00484 00485 epComplete &= ~EP(endpoint); 00486 00487 endpointWritecore(endpoint, data, size); 00488 return EP_PENDING; 00489 } 00490 00491 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) { 00492 if (epComplete & EP(endpoint)) { 00493 epComplete &= ~EP(endpoint); 00494 return EP_COMPLETED; 00495 } 00496 00497 return EP_PENDING; 00498 } 00499 00500 bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags) { 00501 // Realise an endpoint 00502 LPC_USB->DevIntClr = EP_RLZED; 00503 LPC_USB->ReEp |= EP(endpoint); 00504 LPC_USB->EpInd = endpoint; 00505 LPC_USB->MaxPSize = maxPacket; 00506 00507 while (!(LPC_USB->DevIntSt & EP_RLZED)); 00508 LPC_USB->DevIntClr = EP_RLZED; 00509 00510 // Clear stall state 00511 endpointStallState &= ~EP(endpoint); 00512 00513 enableEndpointEvent(endpoint); 00514 return true; 00515 } 00516 00517 void USBHAL::stallEndpoint(uint8_t endpoint) { 00518 // Stall an endpoint 00519 if ( (endpoint==EP0IN) || (endpoint==EP0OUT) ) { 00520 // Conditionally stall both control endpoints 00521 SIEsetEndpointStatus(EP0OUT, SIE_SES_CND_ST); 00522 } else { 00523 SIEsetEndpointStatus(endpoint, SIE_SES_ST); 00524 00525 // Update stall state 00526 endpointStallState |= EP(endpoint); 00527 } 00528 } 00529 00530 void USBHAL::unstallEndpoint(uint8_t endpoint) { 00531 // Unstall an endpoint. The endpoint will also be reinitialised 00532 SIEsetEndpointStatus(endpoint, 0); 00533 00534 // Update stall state 00535 endpointStallState &= ~EP(endpoint); 00536 } 00537 00538 bool USBHAL::getEndpointStallState(uint8_t endpoint) { 00539 // Returns true if endpoint stalled 00540 return endpointStallState & EP(endpoint); 00541 } 00542 00543 void USBHAL::remoteWakeup(void) { 00544 // Remote wakeup 00545 uint8_t status; 00546 00547 // Enable USB clocks 00548 LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN; 00549 while (LPC_USB->USBClkSt != (DEV_CLK_ON | AHB_CLK_ON)); 00550 00551 status = SIEgetDeviceStatus(); 00552 SIEsetDeviceStatus(status & ~SIE_DS_SUS); 00553 } 00554 00555 void USBHAL::_usbisr(void) { 00556 instance->usbisr(); 00557 } 00558 00559 00560 void USBHAL::usbisr(void) { 00561 uint8_t devStat; 00562 00563 if (LPC_USB->DevIntSt & FRAME) { 00564 // Start of frame event 00565 SOF(SIEgetFrameNumber()); 00566 // Clear interrupt status flag 00567 LPC_USB->DevIntClr = FRAME; 00568 } 00569 00570 if (LPC_USB->DevIntSt & DEV_STAT) { 00571 // Device Status interrupt 00572 // Must clear the interrupt status flag before reading the device status from the SIE 00573 LPC_USB->DevIntClr = DEV_STAT; 00574 00575 // Read device status from SIE 00576 devStat = SIEgetDeviceStatus(); 00577 //printf("devStat: %d\r\n", devStat); 00578 00579 if (devStat & SIE_DS_SUS_CH) { 00580 // Suspend status changed 00581 if((devStat & SIE_DS_SUS) != 0) { 00582 suspendStateChanged(0); 00583 } 00584 } 00585 00586 if (devStat & SIE_DS_RST) { 00587 // Bus reset 00588 if((devStat & SIE_DS_SUS) == 0) { 00589 suspendStateChanged(1); 00590 } 00591 busReset(); 00592 } 00593 } 00594 00595 if (LPC_USB->DevIntSt & EP_SLOW) { 00596 // (Slow) Endpoint Interrupt 00597 00598 // Process each endpoint interrupt 00599 if (LPC_USB->EpIntSt & EP(EP0OUT)) { 00600 if (selectEndpointClearInterrupt(EP0OUT) & SIE_SE_STP) { 00601 // this is a setup packet 00602 EP0setupCallback(); 00603 } else { 00604 EP0out(); 00605 } 00606 LPC_USB->DevIntClr = EP_SLOW; 00607 } 00608 00609 if (LPC_USB->EpIntSt & EP(EP0IN)) { 00610 selectEndpointClearInterrupt(EP0IN); 00611 LPC_USB->DevIntClr = EP_SLOW; 00612 EP0in(); 00613 } 00614 00615 for (uint8_t num = 2; num < 16*2; num++) { 00616 if (LPC_USB->EpIntSt & EP(num)) { 00617 selectEndpointClearInterrupt(num); 00618 epComplete |= EP(num); 00619 LPC_USB->DevIntClr = EP_SLOW; 00620 if ((instance->*(epCallback[num - 2]))()) { 00621 epComplete &= ~EP(num); 00622 } 00623 } 00624 } 00625 } 00626 } 00627 00628 #endif
Generated on Wed Jul 13 2022 12:44:03 by 1.7.2