Simple USBHost library for Nucleo F446RE/F411RE/F401RE FRDM-KL46Z/KL25Z/F64F LPC4088/LPC1768
Dependents: F401RE-BTstack_example F401RE-USBHostMSD_HelloWorld
Fork of KL46Z-USBHost by
USBHALHost_LPC4088.cpp
00001 /* mbed USBHost Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #if defined(TARGET_LPC4088)||defined(TARGET_LPC1768) 00018 #include "USBHALHost.h" 00019 00020 #ifndef CTASSERT 00021 template <bool>struct CtAssert; 00022 template <>struct CtAssert<true> {}; 00023 #define CTASSERT(A) CtAssert<A>(); 00024 #endif 00025 00026 #ifdef _USB_DBG 00027 #define USB_DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n");} while(0); 00028 #define USB_DBG_HEX(A,B) debug_hex(A,B) 00029 #define USB_DBG_ED(A) while(0) 00030 #define USB_DBG_TD(A) while(0) 00031 #define USB_DBG_ED_IF(A,B) while(0) 00032 void debug_hex(uint8_t* buf, int size); 00033 #else 00034 #define USB_DBG(...) while(0) 00035 #define USB_DBG_ED(A) while(0) 00036 #define USB_DBG_TD(A) while(0) 00037 #define USB_DBG_ED_IF(A,B) while(0) 00038 #define USB_DBG_HEX(A,B) while(0) 00039 #endif 00040 00041 #define USB_TRACE1(A) while(0) 00042 00043 #ifdef _USB_TEST 00044 #undef USB_TEST_ASSERT 00045 void usb_test_assert_internal(const char *expr, const char *file, int line); 00046 #define USB_TEST_ASSERT(EXPR) while(!(EXPR)){usb_test_assert_internal(#EXPR,__FILE__,__LINE__);} 00047 #else 00048 #define USB_TEST_ASSERT(EXPR) while(0) 00049 #endif 00050 00051 #define USB_INFO(...) do{fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n");}while(0); 00052 00053 // bits of the USB/OTG clock control register 00054 #define HOST_CLK_EN (1<<0) 00055 #define DEV_CLK_EN (1<<1) 00056 #define PORTSEL_CLK_EN (1<<3) 00057 #define AHB_CLK_EN (1<<4) 00058 00059 // bits of the USB/OTG clock status register 00060 #define HOST_CLK_ON (1<<0) 00061 #define DEV_CLK_ON (1<<1) 00062 #define PORTSEL_CLK_ON (1<<3) 00063 #define AHB_CLK_ON (1<<4) 00064 00065 // we need host clock, OTG/portsel clock and AHB clock 00066 #define CLOCK_MASK (HOST_CLK_EN | PORTSEL_CLK_EN | AHB_CLK_EN) 00067 #define FI 0x2EDF /* 12000 bits per frame (-1) */ 00068 #define DEFAULT_FMINTERVAL ((((6 * (FI - 210)) / 7) << 16) | FI) 00069 00070 USBHALHost* USBHALHost::instHost; 00071 00072 USBHALHost::USBHALHost() { 00073 instHost = this; 00074 } 00075 00076 void USBHALHost::init() { 00077 NVIC_DisableIRQ(USB_IRQn); 00078 m_pHcca = new HCCA(); 00079 init_hw_ohci(m_pHcca); 00080 ResetRootHub(); 00081 NVIC_SetVector(USB_IRQn, (uint32_t)_usbisr); 00082 NVIC_SetPriority(USB_IRQn, 0); 00083 NVIC_EnableIRQ(USB_IRQn); 00084 00085 USB_INFO("Simple USBHost Library for LPC4088/LPC1768"); 00086 bool lowSpeed = wait_attach(); 00087 addDevice(NULL, 0, lowSpeed); 00088 } 00089 00090 void USBHALHost::init_hw_ohci(HCCA* pHcca) { 00091 LPC_SC->PCONP &= ~(1UL<<31); //Cut power 00092 wait_ms(1000); 00093 LPC_SC->PCONP |= (1UL<<31); // turn on power for USB 00094 LPC_USB->USBClkCtrl |= CLOCK_MASK; // Enable USB host clock, port selection and AHB clock 00095 // Wait for clocks to become available 00096 while ((LPC_USB->USBClkSt & CLOCK_MASK) != CLOCK_MASK) 00097 ; 00098 LPC_USB->OTGStCtrl |= 1; 00099 LPC_USB->USBClkCtrl &= ~PORTSEL_CLK_EN; 00100 00101 #if defined(TARGET_LPC1768) 00102 LPC_PINCON->PINSEL1 &= ~((3<<26) | (3<<28)); 00103 LPC_PINCON->PINSEL1 |= ((1<<26)|(1<<28)); // 0x14000000 00104 #elif defined(TARGET_LPC4088) 00105 LPC_IOCON->P0_29 = 0x01; // USB_D+1 00106 LPC_IOCON->P0_30 = 0x01; // USB_D-1 00107 // DO NOT CHANGE P1_19. 00108 #else 00109 #error "target error" 00110 #endif 00111 USB_DBG("initialize OHCI\n"); 00112 wait_ms(100); /* Wait 50 ms before apply reset */ 00113 USB_TEST_ASSERT((LPC_USB->HcRevision&0xff) == 0x10); // check revision 00114 LPC_USB->HcControl = 0; /* HARDWARE RESET */ 00115 LPC_USB->HcControlHeadED = 0; /* Initialize Control list head to Zero */ 00116 LPC_USB->HcBulkHeadED = 0; /* Initialize Bulk list head to Zero */ 00117 /* SOFTWARE RESET */ 00118 LPC_USB->HcCommandStatus = OR_CMD_STATUS_HCR; 00119 LPC_USB->HcFmInterval = DEFAULT_FMINTERVAL; /* Write Fm Interval and Largest Data Packet Counter */ 00120 LPC_USB->HcPeriodicStart = FI*90/100; 00121 /* Put HC in operational state */ 00122 LPC_USB->HcControl = (LPC_USB->HcControl & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER; 00123 LPC_USB->HcRhStatus = OR_RH_STATUS_LPSC; /* Set Global Power */ 00124 USB_TEST_ASSERT(pHcca); 00125 for (int i = 0; i < 32; i++) { 00126 pHcca->InterruptTable[i] = NULL; 00127 } 00128 LPC_USB->HcHCCA = reinterpret_cast<uint32_t>(pHcca); 00129 LPC_USB->HcInterruptStatus |= LPC_USB->HcInterruptStatus; /* Clear Interrrupt Status */ 00130 LPC_USB->HcInterruptEnable = OR_INTR_ENABLE_MIE|OR_INTR_ENABLE_WDH|OR_INTR_ENABLE_FNO; 00131 00132 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC; 00133 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC; 00134 } 00135 00136 void USBHALHost::ResetRootHub() { 00137 wait_ms(100); /* USB 2.0 spec says at least 50ms delay before port reset */ 00138 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRS; // Initiate port reset 00139 USB_DBG("Before loop\n"); 00140 while (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRS) 00141 ; 00142 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC; // ...and clear port reset signal 00143 USB_DBG("After loop\n"); 00144 wait_ms(200); /* Wait for 100 MS after port reset */ 00145 } 00146 00147 bool USBHALHost::wait_attach() { 00148 bool lowSpeed = false; 00149 uint32_t status = LPC_USB->HcRhPortStatus1; 00150 if (status & OR_RH_PORT_LSDA) { // lowSpeedDeviceAttached 00151 lowSpeed = true; 00152 } 00153 return lowSpeed; 00154 } 00155 00156 void enable(ENDPOINT_TYPE type) { 00157 switch(type) { 00158 case CONTROL_ENDPOINT: 00159 LPC_USB->HcCommandStatus |= OR_CMD_STATUS_CLF; 00160 LPC_USB->HcControl |= OR_CONTROL_CLE; 00161 break; 00162 case ISOCHRONOUS_ENDPOINT: 00163 LPC_USB->HcControl |= OR_CONTROL_PLE; 00164 break; 00165 case BULK_ENDPOINT: 00166 LPC_USB->HcCommandStatus |= OR_CMD_STATUS_BLF; 00167 LPC_USB->HcControl |= OR_CONTROL_BLE; 00168 break; 00169 case INTERRUPT_ENDPOINT: 00170 LPC_USB->HcControl |= OR_CONTROL_PLE; 00171 break; 00172 } 00173 } 00174 00175 void USBHALHost::token_init(USBEndpoint* ep) { 00176 HCED* ed = ep->getHALData<HCED*>(); 00177 if (ed == NULL) { 00178 ed = new HCED(ep); 00179 ep->setHALData<HCED*>(ed); 00180 } 00181 USBDeviceConnected* dev = ep->getDevice(); 00182 USB_TEST_ASSERT(dev); 00183 if (dev) { 00184 uint8_t devAddr = dev->getAddress(); 00185 USB_DBG("devAddr=%02x", devAddr); 00186 ed->setFunctionAddress(devAddr); 00187 } 00188 uint16_t size = ep->getSize(); 00189 USB_DBG("MaxPacketSize=%d", size); 00190 ed->setMaxPacketSize(size); 00191 if (ed->HeadTd == NULL) { 00192 HCTD* td = new HCTD(ed); 00193 ed->TailTd = td; 00194 ed->HeadTd = td; 00195 switch(ep->getType()) { 00196 case CONTROL_ENDPOINT: 00197 ed->Next = reinterpret_cast<HCED*>(LPC_USB->HcControlHeadED); 00198 LPC_USB->HcControlHeadED = reinterpret_cast<uint32_t>(ed); 00199 break; 00200 case BULK_ENDPOINT: 00201 ed->Next = reinterpret_cast<HCED*>(LPC_USB->HcBulkHeadED); 00202 LPC_USB->HcBulkHeadED = reinterpret_cast<uint32_t>(ed); 00203 break; 00204 case INTERRUPT_ENDPOINT: 00205 HCCA* pHcca = reinterpret_cast<HCCA*>(LPC_USB->HcHCCA); 00206 ed->Next = pHcca->InterruptTable[0]; 00207 pHcca->InterruptTable[0] = ed; 00208 break; 00209 } 00210 } 00211 } 00212 00213 int USBHALHost::token_setup(USBEndpoint* ep, SETUP_PACKET* setup, uint16_t wLength) { 00214 token_init(ep); 00215 HCED* ed = ep->getHALData<HCED*>(); 00216 HCTD* td = ed->TailTd; 00217 setup->wLength = wLength; 00218 TBUF* tbuf = new(sizeof(SETUP_PACKET))TBUF(setup, sizeof(SETUP_PACKET)); 00219 td->transfer(tbuf, sizeof(SETUP_PACKET)); 00220 td->Control |= TD_TOGGLE_0|TD_SETUP; // DATA0 00221 HCTD* blank = new HCTD(ed); 00222 ed->enqueue(blank); 00223 //DBG_ED(ed); 00224 enable(ep->getType()); 00225 00226 td = ed->get_queue_HCTD(); 00227 USB_TEST_ASSERT(td); 00228 int result = td->getLengthTransferred(); 00229 USB_DBG_TD(td); 00230 delete tbuf; 00231 delete td; 00232 return result; 00233 } 00234 00235 static HCED* getHCED_iso(USBEndpoint* ep) { 00236 HCED* ed = ep->getHALData<HCED*>(); 00237 if (ed != NULL) { 00238 return ed; 00239 } 00240 ed = new HCED(ep); 00241 ep->setHALData<HCED*>(ed); 00242 ed->setFormat(); // F Format ITD 00243 ed->iso.FrameCount = ep->ohci.frameCount; 00244 ed->iso.queue_limit = ep->ohci.queueLimit; 00245 ed->iso.queue_count = 0; 00246 ed->iso.Current_FrameCount = 0; 00247 ed->iso.Current_itd = NULL; 00248 ed->iso.FrameNumber = LPC_USB->HcFmNumber + 10; // after 10msec 00249 HCITD* itd = ed->new_HCITD(); 00250 ed->init_queue(reinterpret_cast<HCTD*>(itd)); 00251 HCCA* hcca = reinterpret_cast<HCCA*>(LPC_USB->HcHCCA); 00252 hcca->enqueue(ed); 00253 LPC_USB->HcControl |= OR_CONTROL_PLE; // PeriodicListEnable 00254 LPC_USB->HcControl |= OR_CONTROL_IE; // IsochronousEnable 00255 return ed; 00256 } 00257 00258 static void enablePeriodic() { 00259 LPC_USB->HcControl |= OR_CONTROL_PLE; 00260 } 00261 00262 HCITD* isochronousReceive(USBEndpoint* ep) { 00263 HCED* ed = getHCED_iso(ep); 00264 USB_TEST_ASSERT(ed); 00265 while(ed->iso.queue_count < ed->iso.queue_limit) { 00266 HCITD* blank_itd = ed->new_HCITD(); 00267 if (ed->enqueue(reinterpret_cast<HCTD*>(blank_itd))) { 00268 ed->iso.queue_count++; 00269 } 00270 enablePeriodic(); 00271 } 00272 00273 HCITD* itd = ed->get_queue_HCITD(); 00274 if (itd) { 00275 ed->iso.queue_count--; 00276 } 00277 return itd; 00278 } 00279 00280 int USBHALHost::token_iso_in(USBEndpoint* ep, uint8_t* data, int size) { 00281 HCED* ed = getHCED_iso(ep); 00282 if (ed->iso.Current_FrameCount == 0) { 00283 HCITD* itd = isochronousReceive(ep); 00284 if (itd == NULL) { 00285 return -1; 00286 } 00287 if (itd->ConditionCode() != 0) { 00288 delete itd; 00289 return -1; 00290 } 00291 ed->iso.Current_itd = itd; 00292 } 00293 00294 HCITD* itd = ed->iso.Current_itd; 00295 int fc = ed->iso.Current_FrameCount; 00296 int result = -1; 00297 uint8_t cc = itd->ConditionCode(fc); 00298 if (cc == 0 || cc == 9) { 00299 result = itd->Length(fc); 00300 memcpy(data, itd->Buffer(fc), result); 00301 } 00302 00303 if (++ed->iso.Current_FrameCount >= itd->FrameCount()) { 00304 ed->iso.Current_FrameCount = 0; 00305 delete ed->iso.Current_itd; 00306 } 00307 return result; 00308 } 00309 00310 int USBHALHost::multi_token_in(USBEndpoint* ep, uint8_t* data, int size) { 00311 token_init(ep); 00312 HCED* ed = ep->getHALData<HCED*>(); 00313 HCTD* td = ed->TailTd; 00314 TBUF* tbuf = NULL; 00315 if (data != NULL) { 00316 tbuf = new(size)TBUF(); 00317 td->transfer(tbuf, size); 00318 } 00319 td->Control |= TD_IN; 00320 HCTD* blank = new HCTD(ed); 00321 ed->enqueue(blank); 00322 USB_DBG_ED_IF(ed->EndpointNumber()==0, ed); // control transfer 00323 enable(ep->getType()); 00324 00325 td = ed->get_queue_HCTD(); 00326 USB_TEST_ASSERT(td); 00327 if (data != NULL) { 00328 memcpy(data, tbuf->buf, size); 00329 delete tbuf; 00330 } 00331 int result = td->getLengthTransferred(); 00332 delete td; 00333 return result; 00334 } 00335 00336 int USBHALHost::multi_token_out(USBEndpoint* ep, const uint8_t* data, int size) { 00337 token_init(ep); 00338 HCED* ed = ep->getHALData<HCED*>(); 00339 HCTD* td = ed->TailTd; 00340 TBUF* tbuf = NULL; 00341 if (data != NULL) { 00342 tbuf = new(size)TBUF(data, size); 00343 td->transfer(tbuf, size); 00344 } 00345 td->Control |= TD_OUT; 00346 HCTD* blank = new HCTD(ed); 00347 ed->enqueue(blank); 00348 USB_DBG_ED(ed); 00349 enable(ep->getType()); 00350 00351 td = ed->get_queue_HCTD(); 00352 USB_TEST_ASSERT(td); 00353 if (data != NULL) { 00354 delete tbuf; 00355 } 00356 int result = td->getLengthTransferred(); 00357 delete td; 00358 return result; 00359 } 00360 00361 void USBHALHost::multi_token_inNB(USBEndpoint* ep, uint8_t* data, int size) { 00362 token_init(ep); 00363 HCED* ed = ep->getHALData<HCED*>(); 00364 HCTD* td = ed->TailTd; 00365 TBUF* tbuf = new(size)TBUF(); 00366 td->transfer(tbuf, size); 00367 td->Control |= TD_IN; 00368 HCTD* blank = new HCTD(ed); 00369 ed->enqueue(blank); 00370 enable(ep->getType()); 00371 } 00372 00373 USB_TYPE USBHALHost::multi_token_inNB_result(USBEndpoint* ep) { 00374 HCED* ed = ep->getHALData<HCED*>(); 00375 if (ed == NULL) { 00376 return USB_TYPE_ERROR; 00377 } 00378 HCTD* td = ed->get_queue_HCTD(0); 00379 if (td) { 00380 int len = td->getLengthTransferred(); 00381 TBUF* tbuf = (TBUF*)td->buf_top; 00382 memcpy(ep->getBufStart(), tbuf->buf, len); 00383 ep->setLengthTransferred(len); 00384 ep->setState((USB_TYPE)td->ConditionCode()); 00385 delete td; 00386 delete tbuf; 00387 return USB_TYPE_OK; 00388 } 00389 return USB_TYPE_PROCESSING; 00390 } 00391 00392 void USBHALHost::setToggle(USBEndpoint* ep, uint8_t toggle) { 00393 USB_TEST_ASSERT(toggle == 1); 00394 HCED* ed = ep->getHALData<HCED*>(); 00395 ed->setToggle(toggle); 00396 } 00397 00398 void USBHALHost::_usbisr(void) { 00399 if (instHost) { 00400 instHost->UsbIrqhandler(); 00401 } 00402 } 00403 00404 HCTD* td_reverse(HCTD* td) 00405 { 00406 HCTD* result = NULL; 00407 HCTD* next; 00408 while(td) { 00409 next = const_cast<HCTD*>(td->Next); 00410 td->Next = result; 00411 result = td; 00412 td = next; 00413 } 00414 return result; 00415 } 00416 00417 void USBHALHost::UsbIrqhandler() { 00418 if (!(LPC_USB->HcInterruptStatus & LPC_USB->HcInterruptEnable)) { 00419 return; 00420 } 00421 m_report_irq++; 00422 uint32_t status = LPC_USB->HcInterruptStatus; 00423 if (status & OR_INTR_STATUS_FNO) { 00424 m_report_FNO++; 00425 } 00426 if (status & OR_INTR_STATUS_WDH) { 00427 union { 00428 HCTD* done_td; 00429 uint32_t lsb; 00430 }; 00431 done_td = const_cast<HCTD*>(m_pHcca->DoneHead); 00432 USB_TEST_ASSERT(done_td); 00433 m_pHcca->DoneHead = NULL; // reset 00434 if (lsb & 1) { // error ? 00435 lsb &= ~1; 00436 } 00437 HCTD* td = td_reverse(done_td); 00438 while(td) { 00439 HCED* ed = td->parent; 00440 USB_TEST_ASSERT(ed); 00441 if (ed) { 00442 ed->irqWdhHandler(td); 00443 } 00444 td = td->Next; 00445 } 00446 m_report_WDH++; 00447 } 00448 LPC_USB->HcInterruptStatus = status; // Clear Interrrupt Status 00449 } 00450 00451 TBUF::TBUF(const void* data, int size) { 00452 if (size > 0) { 00453 memcpy(buf, data, size); 00454 } 00455 } 00456 00457 HCTD::HCTD(HCED* obj) { 00458 CTASSERT(sizeof(HCTD) == 36); 00459 USB_TEST_ASSERT(obj); 00460 Control = TD_CC|TD_ROUNDING; 00461 CurrBufPtr = NULL; 00462 Next = NULL; 00463 BufEnd = NULL; 00464 buf_top = NULL; 00465 buf_size = 0; 00466 parent = obj; 00467 } 00468 00469 HCITD::HCITD(HCED* obj, uint16_t FrameNumber, int FrameCount, uint16_t PacketSize) { 00470 Control = 0xe0000000 | // CC ConditionCode NOT ACCESSED 00471 ((FrameCount-1) << 24)| // FC FrameCount 00472 TD_DELAY_INT(0) | // DI DelayInterrupt 00473 FrameNumber; // SF StartingFrame 00474 BufferPage0 = const_cast<uint8_t*>(buf); 00475 BufferEnd = const_cast<uint8_t*>(buf) + PacketSize * FrameCount - 1; 00476 Next = NULL; 00477 parent = obj; 00478 uint32_t addr = reinterpret_cast<uint32_t>(buf); 00479 for(int i = 0; i < FrameCount; i++) { 00480 uint16_t offset = addr & 0x0fff; 00481 if ((addr&0xfffff000) == (reinterpret_cast<uint32_t>(BufferEnd)&0xfffff000)) { 00482 offset |= 0x1000; 00483 } 00484 OffsetPSW[i] = 0xe000|offset; 00485 addr += PacketSize; 00486 } 00487 } 00488 00489 uint8_t* HCITD::Buffer(int fc) { 00490 int offset = fc * parent->getMaxPacketSize(); 00491 return const_cast<uint8_t*>(buf) + offset; 00492 } 00493 00494 HCED::HCED(USBEndpoint* ep) { 00495 CTASSERT(sizeof(HCED) <= (64*2)); 00496 USBDeviceConnected* dev = ep->getDevice(); 00497 int devAddr = 0; 00498 bool lowSpeed = false; 00499 if (dev) { 00500 devAddr = dev->getAddress(); 00501 lowSpeed = dev->getSpeed(); 00502 } 00503 int ep_number = ep->getAddress(); 00504 int MaxPacketSize = ep->getSize(); 00505 Control = devAddr | /* USB address */ 00506 ((ep_number & 0x7F) << 7) | /* Endpoint address */ 00507 (ep_number!=0?(((ep_number&0x80)?2:1) << 11):0)| /* direction : Out = 1, 2 = In */ 00508 ((lowSpeed?1:0) << 13) | /* speed full=0 low=1 */ 00509 (MaxPacketSize << 16); /* MaxPkt Size */ 00510 TailTd = NULL; 00511 HeadTd = NULL; 00512 Next = NULL; 00513 } 00514 00515 bool HCED::enqueue(HCTD* td) { 00516 if (td) { 00517 HCTD* tail = reinterpret_cast<HCTD*>(TailTd); 00518 if (tail) { 00519 tail->Next = td; 00520 TailTd = reinterpret_cast<HCTD*>(td); 00521 return true; 00522 } 00523 } 00524 return false; 00525 } 00526 00527 void HCED::init_queue(HCTD* td) { 00528 TailTd = reinterpret_cast<HCTD*>(td); 00529 HeadTd = reinterpret_cast<HCTD*>(td); 00530 } 00531 00532 void HCED::setToggle(uint8_t toggle) { 00533 uint32_t c = reinterpret_cast<uint32_t>(HeadTd); 00534 if (toggle == 0) { // DATA0 00535 c &= ~0x02; 00536 } else { // DATA1 00537 c |= 0x02; 00538 } 00539 HeadTd = reinterpret_cast<HCTD*>(c); 00540 } 00541 00542 uint8_t HCED::getToggle() { 00543 uint32_t c = reinterpret_cast<uint32_t>(HeadTd); 00544 return (c&0x02) ? 1 : 0; 00545 } 00546 00547 HCTD* HCED::get_queue_HCTD(uint32_t millisec) 00548 { 00549 for(int i = 0; i < 16; i++) { 00550 osEvent evt = done_queue_get(millisec); 00551 if (evt.status == osEventMessage) { 00552 HCTD* td = reinterpret_cast<HCTD*>(evt.value.p); 00553 USB_TEST_ASSERT(td); 00554 uint8_t cc = td->ConditionCode(); 00555 if (cc != 0) { 00556 m_ConditionCode = cc; 00557 USB_DBG_TD(td); 00558 } 00559 return td; 00560 } else if (evt.status == osOK) { 00561 continue; 00562 } else if (evt.status == osEventTimeout) { 00563 return NULL; 00564 } else { 00565 USB_DBG("evt.status: %02x\n", evt.status); 00566 USB_TEST_ASSERT(evt.status == osEventMessage); 00567 } 00568 } 00569 return NULL; 00570 } 00571 00572 HCITD* HCED::get_queue_HCITD() { 00573 osEvent evt = done_queue_get(0); 00574 if (evt.status == osEventMessage) { 00575 HCITD* itd = reinterpret_cast<HCITD*>(evt.value.p); 00576 USB_TEST_ASSERT(itd); 00577 return itd; 00578 } 00579 return NULL; 00580 } 00581 HCITD* HCED::new_HCITD() { 00582 uint16_t mps = getMaxPacketSize(); 00583 int total_size = mps * iso.FrameCount; 00584 HCITD* itd = new(total_size)HCITD(this, iso.FrameNumber, iso.FrameCount, mps); 00585 iso.FrameNumber += iso.FrameCount; 00586 return itd; 00587 } 00588 00589 void HCCA::enqueue(HCED* ed) { 00590 for(int i = 0; i < 32; i++) { 00591 if (InterruptTable[i] == NULL) { 00592 InterruptTable[i] = ed; 00593 } else { 00594 HCED* nextEd = InterruptTable[i]; 00595 while(nextEd->Next && nextEd->Next != ed) { 00596 nextEd = nextEd->Next; 00597 } 00598 nextEd->Next = ed; 00599 } 00600 } 00601 } 00602 00603 #endif // defined(TARGET_LPC4088)||defined(TARGET_LPC1768) 00604
Generated on Wed Jul 13 2022 05:41:27 by 1.7.2