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_KL25Z.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_KL25Z) | defined(TARGET_KL43Z) | defined(TARGET_KL46Z) | defined(TARGET_K20D5M) | defined(TARGET_K64F) 00020 00021 #include "USBHAL.h" 00022 00023 USBHAL * USBHAL::instance; 00024 00025 static volatile int epComplete = 0; 00026 00027 // Convert physical endpoint number to register bit 00028 #define EP(endpoint) (1<<(endpoint)) 00029 00030 // Convert physical to logical 00031 #define PHY_TO_LOG(endpoint) ((endpoint)>>1) 00032 00033 // Get endpoint direction 00034 #define IN_EP(endpoint) ((endpoint) & 1U ? true : false) 00035 #define OUT_EP(endpoint) ((endpoint) & 1U ? false : true) 00036 00037 #define BD_OWN_MASK (1<<7) 00038 #define BD_DATA01_MASK (1<<6) 00039 #define BD_KEEP_MASK (1<<5) 00040 #define BD_NINC_MASK (1<<4) 00041 #define BD_DTS_MASK (1<<3) 00042 #define BD_STALL_MASK (1<<2) 00043 00044 #define TX 1 00045 #define RX 0 00046 #define ODD 0 00047 #define EVEN 1 00048 // this macro waits a physical endpoint number 00049 #define EP_BDT_IDX(ep, dir, odd) (((ep * 4) + (2 * dir) + (1 * odd))) 00050 00051 #define SETUP_TOKEN 0x0D 00052 #define IN_TOKEN 0x09 00053 #define OUT_TOKEN 0x01 00054 #define TOK_PID(idx) ((bdt[idx].info >> 2) & 0x0F) 00055 00056 // for each endpt: 8 bytes 00057 typedef struct BDT { 00058 uint8_t info; // BD[0:7] 00059 uint8_t dummy; // RSVD: BD[8:15] 00060 uint16_t byte_count; // BD[16:32] 00061 uint32_t address; // Addr 00062 } BDT; 00063 00064 00065 // there are: 00066 // * 16 bidirectionnal endpt -> 32 physical endpt 00067 // * as there are ODD and EVEN buffer -> 32*2 bdt 00068 __attribute__((__aligned__(512))) BDT bdt[NUMBER_OF_PHYSICAL_ENDPOINTS * 2]; 00069 uint8_t * endpoint_buffer[(NUMBER_OF_PHYSICAL_ENDPOINTS - 2) * 2]; 00070 uint8_t * endpoint_buffer_iso[2*2]; 00071 00072 static uint8_t set_addr = 0; 00073 static uint8_t addr = 0; 00074 00075 static uint32_t Data1 = 0x55555555; 00076 00077 static uint32_t frameNumber() { 00078 return((USB0->FRMNUML | (USB0->FRMNUMH << 8)) & 0x07FF); 00079 } 00080 00081 uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) { 00082 return 0; 00083 } 00084 00085 USBHAL::USBHAL(void) { 00086 // Disable IRQ 00087 NVIC_DisableIRQ(USB0_IRQn); 00088 00089 #if defined(TARGET_K64F) 00090 MPU->CESR=0; 00091 #endif 00092 // fill in callback array 00093 epCallback[0] = &USBHAL::EP1_OUT_callback; 00094 epCallback[1] = &USBHAL::EP1_IN_callback; 00095 epCallback[2] = &USBHAL::EP2_OUT_callback; 00096 epCallback[3] = &USBHAL::EP2_IN_callback; 00097 epCallback[4] = &USBHAL::EP3_OUT_callback; 00098 epCallback[5] = &USBHAL::EP3_IN_callback; 00099 epCallback[6] = &USBHAL::EP4_OUT_callback; 00100 epCallback[7] = &USBHAL::EP4_IN_callback; 00101 epCallback[8] = &USBHAL::EP5_OUT_callback; 00102 epCallback[9] = &USBHAL::EP5_IN_callback; 00103 epCallback[10] = &USBHAL::EP6_OUT_callback; 00104 epCallback[11] = &USBHAL::EP6_IN_callback; 00105 epCallback[12] = &USBHAL::EP7_OUT_callback; 00106 epCallback[13] = &USBHAL::EP7_IN_callback; 00107 epCallback[14] = &USBHAL::EP8_OUT_callback; 00108 epCallback[15] = &USBHAL::EP8_IN_callback; 00109 epCallback[16] = &USBHAL::EP9_OUT_callback; 00110 epCallback[17] = &USBHAL::EP9_IN_callback; 00111 epCallback[18] = &USBHAL::EP10_OUT_callback; 00112 epCallback[19] = &USBHAL::EP10_IN_callback; 00113 epCallback[20] = &USBHAL::EP11_OUT_callback; 00114 epCallback[21] = &USBHAL::EP11_IN_callback; 00115 epCallback[22] = &USBHAL::EP12_OUT_callback; 00116 epCallback[23] = &USBHAL::EP12_IN_callback; 00117 epCallback[24] = &USBHAL::EP13_OUT_callback; 00118 epCallback[25] = &USBHAL::EP13_IN_callback; 00119 epCallback[26] = &USBHAL::EP14_OUT_callback; 00120 epCallback[27] = &USBHAL::EP14_IN_callback; 00121 epCallback[28] = &USBHAL::EP15_OUT_callback; 00122 epCallback[29] = &USBHAL::EP15_IN_callback; 00123 00124 #if defined(TARGET_KL43Z) 00125 // enable USBFS clock 00126 SIM->SCGC4 |= SIM_SCGC4_USBFS_MASK; 00127 00128 // enable the IRC48M clock 00129 USB0->CLK_RECOVER_IRC_EN |= USB_CLK_RECOVER_IRC_EN_IRC_EN_MASK; 00130 00131 // enable the USB clock recovery tuning 00132 USB0->CLK_RECOVER_CTRL |= USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_MASK; 00133 00134 // choose usb src clock 00135 SIM->SOPT2 |= SIM_SOPT2_USBSRC_MASK; 00136 #else 00137 // choose usb src as PLL 00138 SIM->SOPT2 |= (SIM_SOPT2_USBSRC_MASK | SIM_SOPT2_PLLFLLSEL_MASK); 00139 00140 // enable OTG clock 00141 SIM->SCGC4 |= SIM_SCGC4_USBOTG_MASK; 00142 #endif 00143 00144 // Attach IRQ 00145 instance = this; 00146 NVIC_SetVector(USB0_IRQn, (uint32_t)&_usbisr); 00147 NVIC_EnableIRQ(USB0_IRQn); 00148 00149 // USB Module Configuration 00150 // Reset USB Module 00151 USB0->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; 00152 while(USB0->USBTRC0 & USB_USBTRC0_USBRESET_MASK); 00153 00154 // Set BDT Base Register 00155 USB0->BDTPAGE1 = (uint8_t)((uint32_t)bdt>>8); 00156 USB0->BDTPAGE2 = (uint8_t)((uint32_t)bdt>>16); 00157 USB0->BDTPAGE3 = (uint8_t)((uint32_t)bdt>>24); 00158 00159 // Clear interrupt flag 00160 USB0->ISTAT = 0xff; 00161 00162 // USB Interrupt Enablers 00163 USB0->INTEN |= USB_INTEN_TOKDNEEN_MASK | 00164 USB_INTEN_SOFTOKEN_MASK | 00165 USB_INTEN_ERROREN_MASK | 00166 USB_INTEN_USBRSTEN_MASK; 00167 00168 // Disable weak pull downs 00169 USB0->USBCTRL &= ~(USB_USBCTRL_PDE_MASK | USB_USBCTRL_SUSP_MASK); 00170 00171 USB0->USBTRC0 |= 0x40; 00172 } 00173 00174 USBHAL::~USBHAL(void) { } 00175 00176 void USBHAL::connect(void) { 00177 // enable USB 00178 USB0->CTL |= USB_CTL_USBENSOFEN_MASK; 00179 // Pull up enable 00180 USB0->CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK; 00181 } 00182 00183 void USBHAL::disconnect(void) { 00184 // disable USB 00185 USB0->CTL &= ~USB_CTL_USBENSOFEN_MASK; 00186 // Pull up disable 00187 USB0->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK; 00188 00189 //Free buffers if required: 00190 for (int i = 0; i<(NUMBER_OF_PHYSICAL_ENDPOINTS - 2) * 2; i++) { 00191 free(endpoint_buffer[i]); 00192 endpoint_buffer[i] = NULL; 00193 } 00194 free(endpoint_buffer_iso[2]); 00195 endpoint_buffer_iso[2] = NULL; 00196 free(endpoint_buffer_iso[0]); 00197 endpoint_buffer_iso[0] = NULL; 00198 } 00199 00200 void USBHAL::configureDevice(void) { 00201 // not needed 00202 } 00203 00204 void USBHAL::unconfigureDevice(void) { 00205 // not needed 00206 } 00207 00208 void USBHAL::setAddress(uint8_t address) { 00209 // we don't set the address now otherwise the usb controller does not ack 00210 // we set a flag instead 00211 // see usbisr when an IN token is received 00212 set_addr = 1; 00213 addr = address; 00214 } 00215 00216 bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags) { 00217 uint32_t handshake_flag = 0; 00218 uint8_t * buf; 00219 00220 if (endpoint > NUMBER_OF_PHYSICAL_ENDPOINTS - 1) { 00221 return false; 00222 } 00223 00224 uint32_t log_endpoint = PHY_TO_LOG(endpoint); 00225 00226 if ((flags & ISOCHRONOUS) == 0) { 00227 handshake_flag = USB_ENDPT_EPHSHK_MASK; 00228 if (IN_EP(endpoint)) { 00229 if (endpoint_buffer[EP_BDT_IDX(log_endpoint, TX, ODD)] == NULL) 00230 endpoint_buffer[EP_BDT_IDX(log_endpoint, TX, ODD)] = (uint8_t *) malloc (64*2); 00231 buf = &endpoint_buffer[EP_BDT_IDX(log_endpoint, TX, ODD)][0]; 00232 } else { 00233 if (endpoint_buffer[EP_BDT_IDX(log_endpoint, RX, ODD)] == NULL) 00234 endpoint_buffer[EP_BDT_IDX(log_endpoint, RX, ODD)] = (uint8_t *) malloc (64*2); 00235 buf = &endpoint_buffer[EP_BDT_IDX(log_endpoint, RX, ODD)][0]; 00236 } 00237 } else { 00238 if (IN_EP(endpoint)) { 00239 if (endpoint_buffer_iso[2] == NULL) 00240 endpoint_buffer_iso[2] = (uint8_t *) malloc (1023*2); 00241 buf = &endpoint_buffer_iso[2][0]; 00242 } else { 00243 if (endpoint_buffer_iso[0] == NULL) 00244 endpoint_buffer_iso[0] = (uint8_t *) malloc (1023*2); 00245 buf = &endpoint_buffer_iso[0][0]; 00246 } 00247 } 00248 00249 // IN endpt -> device to host (TX) 00250 if (IN_EP(endpoint)) { 00251 USB0->ENDPOINT[log_endpoint].ENDPT |= handshake_flag | // ep handshaking (not if iso endpoint) 00252 USB_ENDPT_EPTXEN_MASK; // en TX (IN) tran 00253 bdt[EP_BDT_IDX(log_endpoint, TX, ODD )].address = (uint32_t) buf; 00254 bdt[EP_BDT_IDX(log_endpoint, TX, EVEN)].address = 0; 00255 } 00256 // OUT endpt -> host to device (RX) 00257 else { 00258 USB0->ENDPOINT[log_endpoint].ENDPT |= handshake_flag | // ep handshaking (not if iso endpoint) 00259 USB_ENDPT_EPRXEN_MASK; // en RX (OUT) tran. 00260 bdt[EP_BDT_IDX(log_endpoint, RX, ODD )].byte_count = maxPacket; 00261 bdt[EP_BDT_IDX(log_endpoint, RX, ODD )].address = (uint32_t) buf; 00262 bdt[EP_BDT_IDX(log_endpoint, RX, ODD )].info = BD_OWN_MASK | BD_DTS_MASK; 00263 bdt[EP_BDT_IDX(log_endpoint, RX, EVEN)].info = 0; 00264 } 00265 00266 Data1 |= (1 << endpoint); 00267 00268 return true; 00269 } 00270 00271 // read setup packet 00272 void USBHAL::EP0setup(uint8_t *buffer) { 00273 uint32_t sz; 00274 endpointReadResult(EP0OUT, buffer, &sz); 00275 } 00276 00277 void USBHAL::EP0readStage(void) { 00278 Data1 &= ~1UL; // set DATA0 00279 bdt[0].info = (BD_DTS_MASK | BD_OWN_MASK); 00280 } 00281 00282 void USBHAL::EP0read(void) { 00283 uint32_t idx = EP_BDT_IDX(PHY_TO_LOG(EP0OUT), RX, 0); 00284 bdt[idx].byte_count = MAX_PACKET_SIZE_EP0; 00285 } 00286 00287 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) { 00288 uint32_t sz; 00289 endpointReadResult(EP0OUT, buffer, &sz); 00290 return sz; 00291 } 00292 00293 void USBHAL::EP0write(uint8_t *buffer, uint32_t size) { 00294 endpointWrite(EP0IN, buffer, size); 00295 } 00296 00297 void USBHAL::EP0getWriteResult(void) { 00298 } 00299 00300 void USBHAL::EP0stall(void) { 00301 stallEndpoint(EP0OUT); 00302 } 00303 00304 EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) { 00305 endpoint = PHY_TO_LOG(endpoint); 00306 uint32_t idx = EP_BDT_IDX(endpoint, RX, 0); 00307 bdt[idx].byte_count = maximumSize; 00308 return EP_PENDING; 00309 } 00310 00311 EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) { 00312 uint32_t n, sz, idx, setup = 0; 00313 uint8_t not_iso; 00314 uint8_t * ep_buf; 00315 00316 uint32_t log_endpoint = PHY_TO_LOG(endpoint); 00317 00318 if (endpoint > NUMBER_OF_PHYSICAL_ENDPOINTS - 1) { 00319 return EP_INVALID; 00320 } 00321 00322 // if read on a IN endpoint -> error 00323 if (IN_EP(endpoint)) { 00324 return EP_INVALID; 00325 } 00326 00327 idx = EP_BDT_IDX(log_endpoint, RX, 0); 00328 sz = bdt[idx].byte_count; 00329 not_iso = USB0->ENDPOINT[log_endpoint].ENDPT & USB_ENDPT_EPHSHK_MASK; 00330 00331 //for isochronous endpoint, we don't wait an interrupt 00332 if ((log_endpoint != 0) && not_iso && !(epComplete & EP(endpoint))) { 00333 return EP_PENDING; 00334 } 00335 00336 if ((log_endpoint == 0) && (TOK_PID(idx) == SETUP_TOKEN)) { 00337 setup = 1; 00338 } 00339 00340 // non iso endpoint 00341 if (not_iso) { 00342 ep_buf = endpoint_buffer[idx]; 00343 } else { 00344 ep_buf = endpoint_buffer_iso[0]; 00345 } 00346 00347 for (n = 0; n < sz; n++) { 00348 buffer[n] = ep_buf[n]; 00349 } 00350 00351 if (((Data1 >> endpoint) & 1) == ((bdt[idx].info >> 6) & 1)) { 00352 if (setup && (buffer[6] == 0)) // if no setup data stage, 00353 Data1 &= ~1UL; // set DATA0 00354 else 00355 Data1 ^= (1 << endpoint); 00356 } 00357 00358 if (((Data1 >> endpoint) & 1)) { 00359 bdt[idx].info = BD_DTS_MASK | BD_DATA01_MASK | BD_OWN_MASK; 00360 } 00361 else { 00362 bdt[idx].info = BD_DTS_MASK | BD_OWN_MASK; 00363 } 00364 00365 USB0->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; 00366 *bytesRead = sz; 00367 00368 epComplete &= ~EP(endpoint); 00369 return EP_COMPLETED; 00370 } 00371 00372 EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) { 00373 uint32_t idx, n; 00374 uint8_t * ep_buf; 00375 00376 if (endpoint > NUMBER_OF_PHYSICAL_ENDPOINTS - 1) { 00377 return EP_INVALID; 00378 } 00379 00380 // if write on a OUT endpoint -> error 00381 if (OUT_EP(endpoint)) { 00382 return EP_INVALID; 00383 } 00384 00385 idx = EP_BDT_IDX(PHY_TO_LOG(endpoint), TX, 0); 00386 bdt[idx].byte_count = size; 00387 00388 00389 // non iso endpoint 00390 if (USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT & USB_ENDPT_EPHSHK_MASK) { 00391 ep_buf = endpoint_buffer[idx]; 00392 } else { 00393 ep_buf = endpoint_buffer_iso[2]; 00394 } 00395 00396 for (n = 0; n < size; n++) { 00397 ep_buf[n] = data[n]; 00398 } 00399 00400 if ((Data1 >> endpoint) & 1) { 00401 bdt[idx].info = BD_OWN_MASK | BD_DTS_MASK; 00402 } else { 00403 bdt[idx].info = BD_OWN_MASK | BD_DTS_MASK | BD_DATA01_MASK; 00404 } 00405 00406 Data1 ^= (1 << endpoint); 00407 00408 return EP_PENDING; 00409 } 00410 00411 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) { 00412 if (epComplete & EP(endpoint)) { 00413 epComplete &= ~EP(endpoint); 00414 return EP_COMPLETED; 00415 } 00416 00417 return EP_PENDING; 00418 } 00419 00420 void USBHAL::stallEndpoint(uint8_t endpoint) { 00421 USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT |= USB_ENDPT_EPSTALL_MASK; 00422 } 00423 00424 void USBHAL::unstallEndpoint(uint8_t endpoint) { 00425 USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT &= ~USB_ENDPT_EPSTALL_MASK; 00426 } 00427 00428 bool USBHAL::getEndpointStallState(uint8_t endpoint) { 00429 uint8_t stall = (USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT & USB_ENDPT_EPSTALL_MASK); 00430 return (stall) ? true : false; 00431 } 00432 00433 void USBHAL::remoteWakeup(void) { 00434 // [TODO] 00435 } 00436 00437 00438 void USBHAL::_usbisr(void) { 00439 instance->usbisr(); 00440 } 00441 00442 00443 void USBHAL::usbisr(void) { 00444 uint8_t i; 00445 uint8_t istat = USB0->ISTAT; 00446 00447 // reset interrupt 00448 if (istat & USB_ISTAT_USBRST_MASK) { 00449 // disable all endpt 00450 for(i = 0; i < 16; i++) { 00451 USB0->ENDPOINT[i].ENDPT = 0x00; 00452 } 00453 00454 // enable control endpoint 00455 realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0); 00456 realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0); 00457 00458 Data1 = 0x55555555; 00459 USB0->CTL |= USB_CTL_ODDRST_MASK; 00460 00461 USB0->ISTAT = 0xFF; // clear all interrupt status flags 00462 USB0->ERRSTAT = 0xFF; // clear all error flags 00463 USB0->ERREN = 0xFF; // enable error interrupt sources 00464 USB0->ADDR = 0x00; // set default address 00465 00466 return; 00467 } 00468 00469 // resume interrupt 00470 if (istat & USB_ISTAT_RESUME_MASK) { 00471 USB0->ISTAT = USB_ISTAT_RESUME_MASK; 00472 } 00473 00474 // SOF interrupt 00475 if (istat & USB_ISTAT_SOFTOK_MASK) { 00476 USB0->ISTAT = USB_ISTAT_SOFTOK_MASK; 00477 // SOF event, read frame number 00478 SOF(frameNumber()); 00479 } 00480 00481 // stall interrupt 00482 if (istat & 1<<7) { 00483 if (USB0->ENDPOINT[0].ENDPT & USB_ENDPT_EPSTALL_MASK) 00484 USB0->ENDPOINT[0].ENDPT &= ~USB_ENDPT_EPSTALL_MASK; 00485 USB0->ISTAT |= USB_ISTAT_STALL_MASK; 00486 } 00487 00488 // token interrupt 00489 if (istat & 1<<3) { 00490 uint32_t num = (USB0->STAT >> 4) & 0x0F; 00491 uint32_t dir = (USB0->STAT >> 3) & 0x01; 00492 uint32_t ev_odd = (USB0->STAT >> 2) & 0x01; 00493 00494 // setup packet 00495 if ((num == 0) && (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == SETUP_TOKEN)) { 00496 Data1 &= ~0x02; 00497 bdt[EP_BDT_IDX(0, TX, EVEN)].info &= ~BD_OWN_MASK; 00498 bdt[EP_BDT_IDX(0, TX, ODD)].info &= ~BD_OWN_MASK; 00499 00500 // EP0 SETUP event (SETUP data received) 00501 EP0setupCallback(); 00502 00503 } else { 00504 // OUT packet 00505 if (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == OUT_TOKEN) { 00506 if (num == 0) 00507 EP0out(); 00508 else { 00509 int phy = (num<<1) + 0; 00510 epComplete |= EP(phy); 00511 if ((instance->*(epCallback[phy - 2]))()) { 00512 epComplete &= ~EP(phy); 00513 } 00514 } 00515 } 00516 00517 // IN packet 00518 if (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == IN_TOKEN) { 00519 if (num == 0) { 00520 EP0in(); 00521 if (set_addr == 1) { 00522 USB0->ADDR = addr & 0x7F; 00523 set_addr = 0; 00524 } 00525 } 00526 else { 00527 int phy = (num<<1) + 1; 00528 epComplete |= EP(phy); 00529 if ((instance->*(epCallback[phy - 2]))()) { 00530 epComplete &= ~EP(phy); 00531 } 00532 } 00533 } 00534 } 00535 00536 USB0->ISTAT = USB_ISTAT_TOKDNE_MASK; 00537 } 00538 00539 // sleep interrupt 00540 if (istat & 1<<4) { 00541 USB0->ISTAT |= USB_ISTAT_SLEEP_MASK; 00542 } 00543 00544 // error interrupt 00545 if (istat & USB_ISTAT_ERROR_MASK) { 00546 USB0->ERRSTAT = 0xFF; 00547 USB0->ISTAT |= USB_ISTAT_ERROR_MASK; 00548 } 00549 } 00550 00551 00552 #endif
Generated on Wed Jul 13 2022 12:59:06 by
1.7.2
