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) || 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 Tue Jul 12 2022 14:14:02 by
