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