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_K20D50M) | defined(TARGET_K64F) | defined(TARGET_K22F) | defined(TARGET_TEENSY3_1) 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_PLLFLLSEL_MASK; 00139 SIM->SOPT2 |= (SIM_SOPT2_USBSRC_MASK | (1 << SIM_SOPT2_PLLFLLSEL_SHIFT)); 00140 00141 // enable OTG clock 00142 SIM->SCGC4 |= SIM_SCGC4_USBOTG_MASK; 00143 #endif 00144 00145 // Attach IRQ 00146 instance = this; 00147 NVIC_SetVector(USB0_IRQn, (uint32_t)&_usbisr); 00148 NVIC_EnableIRQ(USB0_IRQn); 00149 00150 // USB Module Configuration 00151 // Reset USB Module 00152 USB0->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; 00153 while(USB0->USBTRC0 & USB_USBTRC0_USBRESET_MASK); 00154 00155 // Set BDT Base Register 00156 USB0->BDTPAGE1 = (uint8_t)((uint32_t)bdt>>8); 00157 USB0->BDTPAGE2 = (uint8_t)((uint32_t)bdt>>16); 00158 USB0->BDTPAGE3 = (uint8_t)((uint32_t)bdt>>24); 00159 00160 // Clear interrupt flag 00161 USB0->ISTAT = 0xff; 00162 00163 // USB Interrupt Enablers 00164 USB0->INTEN |= USB_INTEN_TOKDNEEN_MASK | 00165 USB_INTEN_SOFTOKEN_MASK | 00166 USB_INTEN_ERROREN_MASK | 00167 USB_INTEN_USBRSTEN_MASK; 00168 00169 // Disable weak pull downs 00170 USB0->USBCTRL &= ~(USB_USBCTRL_PDE_MASK | USB_USBCTRL_SUSP_MASK); 00171 00172 USB0->USBTRC0 |= 0x40; 00173 } 00174 00175 USBHAL::~USBHAL(void) { } 00176 00177 void USBHAL::connect(void) { 00178 // enable USB 00179 USB0->CTL |= USB_CTL_USBENSOFEN_MASK; 00180 // Pull up enable 00181 USB0->CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK; 00182 } 00183 00184 void USBHAL::disconnect(void) { 00185 // disable USB 00186 USB0->CTL &= ~USB_CTL_USBENSOFEN_MASK; 00187 // Pull up disable 00188 USB0->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK; 00189 00190 //Free buffers if required: 00191 for (int i = 0; i<(NUMBER_OF_PHYSICAL_ENDPOINTS - 2) * 2; i++) { 00192 free(endpoint_buffer[i]); 00193 endpoint_buffer[i] = NULL; 00194 } 00195 free(endpoint_buffer_iso[2]); 00196 endpoint_buffer_iso[2] = NULL; 00197 free(endpoint_buffer_iso[0]); 00198 endpoint_buffer_iso[0] = NULL; 00199 } 00200 00201 void USBHAL::configureDevice(void) { 00202 // not needed 00203 } 00204 00205 void USBHAL::unconfigureDevice(void) { 00206 // not needed 00207 } 00208 00209 void USBHAL::setAddress(uint8_t address) { 00210 // we don't set the address now otherwise the usb controller does not ack 00211 // we set a flag instead 00212 // see usbisr when an IN token is received 00213 set_addr = 1; 00214 addr = address; 00215 } 00216 00217 bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags) { 00218 uint32_t handshake_flag = 0; 00219 uint8_t * buf; 00220 00221 if (endpoint > NUMBER_OF_PHYSICAL_ENDPOINTS - 1) { 00222 return false; 00223 } 00224 00225 uint32_t log_endpoint = PHY_TO_LOG(endpoint); 00226 00227 if ((flags & ISOCHRONOUS) == 0) { 00228 handshake_flag = USB_ENDPT_EPHSHK_MASK; 00229 if (IN_EP(endpoint)) { 00230 if (endpoint_buffer[EP_BDT_IDX(log_endpoint, TX, ODD)] == NULL) 00231 endpoint_buffer[EP_BDT_IDX(log_endpoint, TX, ODD)] = (uint8_t *) malloc (64*2); 00232 buf = &endpoint_buffer[EP_BDT_IDX(log_endpoint, TX, ODD)][0]; 00233 } else { 00234 if (endpoint_buffer[EP_BDT_IDX(log_endpoint, RX, ODD)] == NULL) 00235 endpoint_buffer[EP_BDT_IDX(log_endpoint, RX, ODD)] = (uint8_t *) malloc (64*2); 00236 buf = &endpoint_buffer[EP_BDT_IDX(log_endpoint, RX, ODD)][0]; 00237 } 00238 } else { 00239 if (IN_EP(endpoint)) { 00240 if (endpoint_buffer_iso[2] == NULL) 00241 endpoint_buffer_iso[2] = (uint8_t *) malloc (1023*2); 00242 buf = &endpoint_buffer_iso[2][0]; 00243 } else { 00244 if (endpoint_buffer_iso[0] == NULL) 00245 endpoint_buffer_iso[0] = (uint8_t *) malloc (1023*2); 00246 buf = &endpoint_buffer_iso[0][0]; 00247 } 00248 } 00249 00250 // IN endpt -> device to host (TX) 00251 if (IN_EP(endpoint)) { 00252 USB0->ENDPOINT[log_endpoint].ENDPT |= handshake_flag | // ep handshaking (not if iso endpoint) 00253 USB_ENDPT_EPTXEN_MASK; // en TX (IN) tran 00254 bdt[EP_BDT_IDX(log_endpoint, TX, ODD )].address = (uint32_t) buf; 00255 bdt[EP_BDT_IDX(log_endpoint, TX, EVEN)].address = 0; 00256 } 00257 // OUT endpt -> host to device (RX) 00258 else { 00259 USB0->ENDPOINT[log_endpoint].ENDPT |= handshake_flag | // ep handshaking (not if iso endpoint) 00260 USB_ENDPT_EPRXEN_MASK; // en RX (OUT) tran. 00261 bdt[EP_BDT_IDX(log_endpoint, RX, ODD )].byte_count = maxPacket; 00262 bdt[EP_BDT_IDX(log_endpoint, RX, ODD )].address = (uint32_t) buf; 00263 bdt[EP_BDT_IDX(log_endpoint, RX, ODD )].info = BD_OWN_MASK | BD_DTS_MASK; 00264 bdt[EP_BDT_IDX(log_endpoint, RX, EVEN)].info = 0; 00265 } 00266 00267 Data1 |= (1 << endpoint); 00268 00269 return true; 00270 } 00271 00272 // read setup packet 00273 void USBHAL::EP0setup(uint8_t *buffer) { 00274 uint32_t sz; 00275 endpointReadResult(EP0OUT, buffer, &sz); 00276 } 00277 00278 void USBHAL::EP0readStage(void) { 00279 Data1 &= ~1UL; // set DATA0 00280 bdt[0].info = (BD_DTS_MASK | BD_OWN_MASK); 00281 } 00282 00283 void USBHAL::EP0read(void) { 00284 uint32_t idx = EP_BDT_IDX(PHY_TO_LOG(EP0OUT), RX, 0); 00285 bdt[idx].byte_count = MAX_PACKET_SIZE_EP0; 00286 } 00287 00288 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) { 00289 uint32_t sz; 00290 endpointReadResult(EP0OUT, buffer, &sz); 00291 return sz; 00292 } 00293 00294 void USBHAL::EP0write(uint8_t *buffer, uint32_t size) { 00295 endpointWrite(EP0IN, buffer, size); 00296 } 00297 00298 void USBHAL::EP0getWriteResult(void) { 00299 } 00300 00301 void USBHAL::EP0stall(void) { 00302 stallEndpoint(EP0OUT); 00303 } 00304 00305 EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) { 00306 endpoint = PHY_TO_LOG(endpoint); 00307 uint32_t idx = EP_BDT_IDX(endpoint, RX, 0); 00308 bdt[idx].byte_count = maximumSize; 00309 return EP_PENDING; 00310 } 00311 00312 EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) { 00313 uint32_t n, sz, idx, setup = 0; 00314 uint8_t not_iso; 00315 uint8_t * ep_buf; 00316 00317 uint32_t log_endpoint = PHY_TO_LOG(endpoint); 00318 00319 if (endpoint > NUMBER_OF_PHYSICAL_ENDPOINTS - 1) { 00320 return EP_INVALID; 00321 } 00322 00323 // if read on a IN endpoint -> error 00324 if (IN_EP(endpoint)) { 00325 return EP_INVALID; 00326 } 00327 00328 idx = EP_BDT_IDX(log_endpoint, RX, 0); 00329 sz = bdt[idx].byte_count; 00330 not_iso = USB0->ENDPOINT[log_endpoint].ENDPT & USB_ENDPT_EPHSHK_MASK; 00331 00332 //for isochronous endpoint, we don't wait an interrupt 00333 if ((log_endpoint != 0) && not_iso && !(epComplete & EP(endpoint))) { 00334 return EP_PENDING; 00335 } 00336 00337 if ((log_endpoint == 0) && (TOK_PID(idx) == SETUP_TOKEN)) { 00338 setup = 1; 00339 } 00340 00341 // non iso endpoint 00342 if (not_iso) { 00343 ep_buf = endpoint_buffer[idx]; 00344 } else { 00345 ep_buf = endpoint_buffer_iso[0]; 00346 } 00347 00348 for (n = 0; n < sz; n++) { 00349 buffer[n] = ep_buf[n]; 00350 } 00351 00352 if (((Data1 >> endpoint) & 1) == ((bdt[idx].info >> 6) & 1)) { 00353 if (setup && (buffer[6] == 0)) // if no setup data stage, 00354 Data1 &= ~1UL; // set DATA0 00355 else 00356 Data1 ^= (1 << endpoint); 00357 } 00358 00359 if (((Data1 >> endpoint) & 1)) { 00360 bdt[idx].info = BD_DTS_MASK | BD_DATA01_MASK | BD_OWN_MASK; 00361 } 00362 else { 00363 bdt[idx].info = BD_DTS_MASK | BD_OWN_MASK; 00364 } 00365 00366 USB0->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; 00367 *bytesRead = sz; 00368 00369 epComplete &= ~EP(endpoint); 00370 return EP_COMPLETED; 00371 } 00372 00373 EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) { 00374 uint32_t idx, n; 00375 uint8_t * ep_buf; 00376 00377 if (endpoint > NUMBER_OF_PHYSICAL_ENDPOINTS - 1) { 00378 return EP_INVALID; 00379 } 00380 00381 // if write on a OUT endpoint -> error 00382 if (OUT_EP(endpoint)) { 00383 return EP_INVALID; 00384 } 00385 00386 idx = EP_BDT_IDX(PHY_TO_LOG(endpoint), TX, 0); 00387 bdt[idx].byte_count = size; 00388 00389 00390 // non iso endpoint 00391 if (USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT & USB_ENDPT_EPHSHK_MASK) { 00392 ep_buf = endpoint_buffer[idx]; 00393 } else { 00394 ep_buf = endpoint_buffer_iso[2]; 00395 } 00396 00397 for (n = 0; n < size; n++) { 00398 ep_buf[n] = data[n]; 00399 } 00400 00401 if ((Data1 >> endpoint) & 1) { 00402 bdt[idx].info = BD_OWN_MASK | BD_DTS_MASK; 00403 } else { 00404 bdt[idx].info = BD_OWN_MASK | BD_DTS_MASK | BD_DATA01_MASK; 00405 } 00406 00407 Data1 ^= (1 << endpoint); 00408 00409 return EP_PENDING; 00410 } 00411 00412 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) { 00413 if (epComplete & EP(endpoint)) { 00414 epComplete &= ~EP(endpoint); 00415 return EP_COMPLETED; 00416 } 00417 00418 return EP_PENDING; 00419 } 00420 00421 void USBHAL::stallEndpoint(uint8_t endpoint) { 00422 USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT |= USB_ENDPT_EPSTALL_MASK; 00423 } 00424 00425 void USBHAL::unstallEndpoint(uint8_t endpoint) { 00426 USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT &= ~USB_ENDPT_EPSTALL_MASK; 00427 } 00428 00429 bool USBHAL::getEndpointStallState(uint8_t endpoint) { 00430 uint8_t stall = (USB0->ENDPOINT[PHY_TO_LOG(endpoint)].ENDPT & USB_ENDPT_EPSTALL_MASK); 00431 return (stall) ? true : false; 00432 } 00433 00434 void USBHAL::remoteWakeup(void) { 00435 // [TODO] 00436 } 00437 00438 00439 void USBHAL::_usbisr(void) { 00440 instance->usbisr(); 00441 } 00442 00443 00444 void USBHAL::usbisr(void) { 00445 uint8_t i; 00446 uint8_t istat = USB0->ISTAT; 00447 00448 // reset interrupt 00449 if (istat & USB_ISTAT_USBRST_MASK) { 00450 // disable all endpt 00451 for(i = 0; i < 16; i++) { 00452 USB0->ENDPOINT[i].ENDPT = 0x00; 00453 } 00454 00455 // enable control endpoint 00456 realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0); 00457 realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0); 00458 00459 Data1 = 0x55555555; 00460 USB0->CTL |= USB_CTL_ODDRST_MASK; 00461 00462 USB0->ISTAT = 0xFF; // clear all interrupt status flags 00463 USB0->ERRSTAT = 0xFF; // clear all error flags 00464 USB0->ERREN = 0xFF; // enable error interrupt sources 00465 USB0->ADDR = 0x00; // set default address 00466 00467 return; 00468 } 00469 00470 // resume interrupt 00471 if (istat & USB_ISTAT_RESUME_MASK) { 00472 USB0->ISTAT = USB_ISTAT_RESUME_MASK; 00473 } 00474 00475 // SOF interrupt 00476 if (istat & USB_ISTAT_SOFTOK_MASK) { 00477 USB0->ISTAT = USB_ISTAT_SOFTOK_MASK; 00478 // SOF event, read frame number 00479 SOF(frameNumber()); 00480 } 00481 00482 // stall interrupt 00483 if (istat & 1<<7) { 00484 if (USB0->ENDPOINT[0].ENDPT & USB_ENDPT_EPSTALL_MASK) 00485 USB0->ENDPOINT[0].ENDPT &= ~USB_ENDPT_EPSTALL_MASK; 00486 USB0->ISTAT |= USB_ISTAT_STALL_MASK; 00487 } 00488 00489 // token interrupt 00490 if (istat & 1<<3) { 00491 uint32_t num = (USB0->STAT >> 4) & 0x0F; 00492 uint32_t dir = (USB0->STAT >> 3) & 0x01; 00493 uint32_t ev_odd = (USB0->STAT >> 2) & 0x01; 00494 00495 // setup packet 00496 if ((num == 0) && (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == SETUP_TOKEN)) { 00497 Data1 &= ~0x02; 00498 bdt[EP_BDT_IDX(0, TX, EVEN)].info &= ~BD_OWN_MASK; 00499 bdt[EP_BDT_IDX(0, TX, ODD)].info &= ~BD_OWN_MASK; 00500 00501 // EP0 SETUP event (SETUP data received) 00502 EP0setupCallback(); 00503 00504 } else { 00505 // OUT packet 00506 if (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == OUT_TOKEN) { 00507 if (num == 0) 00508 EP0out(); 00509 else { 00510 epComplete |= (1 << EP(num)); 00511 if ((instance->*(epCallback[EP(num) - 2]))()) { 00512 epComplete &= ~(1 << EP(num)); 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 epComplete |= (1 << (EP(num) + 1)); 00528 if ((instance->*(epCallback[EP(num) + 1 - 2]))()) { 00529 epComplete &= ~(1 << (EP(num) + 1)); 00530 } 00531 } 00532 } 00533 } 00534 00535 USB0->ISTAT = USB_ISTAT_TOKDNE_MASK; 00536 } 00537 00538 // sleep interrupt 00539 if (istat & 1<<4) { 00540 USB0->ISTAT |= USB_ISTAT_SLEEP_MASK; 00541 } 00542 00543 // error interrupt 00544 if (istat & USB_ISTAT_ERROR_MASK) { 00545 USB0->ERRSTAT = 0xFF; 00546 USB0->ISTAT |= USB_ISTAT_ERROR_MASK; 00547 } 00548 } 00549 00550 00551 #endif
Generated on Tue Jul 12 2022 14:14:02 by
