Simple USBHost MSD(USB flash drive) for EA LPC4088 QSB test program

Dependencies:   LPC4088-USBHost mbed

EA LPC4088をUSBホストにしてUSBフラッシュメモリ(USB flash drive)を読み書きするテストプログラムです。
/media/uploads/va009039/lpc4088-msd-1.jpg
/media/uploads/va009039/lpc4088-msd-2.png

https://bitbucket.org/va009039/lpc4088_usbhost

Committer:
va009039
Date:
Tue Apr 22 10:54:52 2014 +0000
Revision:
0:11152e69fc05
first commit,sync rev.25.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 0:11152e69fc05 1 /* mbed USBHost Library
va009039 0:11152e69fc05 2 * Copyright (c) 2006-2013 ARM Limited
va009039 0:11152e69fc05 3 *
va009039 0:11152e69fc05 4 * Licensed under the Apache License, Version 2.0 (the "License");
va009039 0:11152e69fc05 5 * you may not use this file except in compliance with the License.
va009039 0:11152e69fc05 6 * You may obtain a copy of the License at
va009039 0:11152e69fc05 7 *
va009039 0:11152e69fc05 8 * http://www.apache.org/licenses/LICENSE-2.0
va009039 0:11152e69fc05 9 *
va009039 0:11152e69fc05 10 * Unless required by applicable law or agreed to in writing, software
va009039 0:11152e69fc05 11 * distributed under the License is distributed on an "AS IS" BASIS,
va009039 0:11152e69fc05 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
va009039 0:11152e69fc05 13 * See the License for the specific language governing permissions and
va009039 0:11152e69fc05 14 * limitations under the License.
va009039 0:11152e69fc05 15 */
va009039 0:11152e69fc05 16
va009039 0:11152e69fc05 17 #include "USBHALHost.h"
va009039 0:11152e69fc05 18 //#define _USB_DBG
va009039 0:11152e69fc05 19 #include "BaseUsbHostDebug.h"
va009039 0:11152e69fc05 20 #include "BaseUsbHostTest.h"
va009039 0:11152e69fc05 21
va009039 0:11152e69fc05 22 #ifndef CTASSERT
va009039 0:11152e69fc05 23 template <bool>struct CtAssert;
va009039 0:11152e69fc05 24 template <>struct CtAssert<true> {};
va009039 0:11152e69fc05 25 #define CTASSERT(A) CtAssert<A>();
va009039 0:11152e69fc05 26 #endif
va009039 0:11152e69fc05 27
va009039 0:11152e69fc05 28 #ifdef _USB_DBG
va009039 0:11152e69fc05 29 #define USB_DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n");} while(0);
va009039 0:11152e69fc05 30 #define USB_DBG_HEX(A,B) debug_hex(A,B)
va009039 0:11152e69fc05 31 void debug_hex(uint8_t* buf, int size);
va009039 0:11152e69fc05 32 #else
va009039 0:11152e69fc05 33 #define USB_DBG(...) while(0)
va009039 0:11152e69fc05 34 #define USB_DBG_HEX(A,B) while(0)
va009039 0:11152e69fc05 35 #endif
va009039 0:11152e69fc05 36
va009039 0:11152e69fc05 37 #ifdef _USB_TEST
va009039 0:11152e69fc05 38 #define USB_TEST_ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);};
va009039 0:11152e69fc05 39 #define USB_TEST_ASSERT_FALSE(A) USB_TEST_ASSERT(!(A))
va009039 0:11152e69fc05 40 #else
va009039 0:11152e69fc05 41 #define USB_TEST_ASSERT(A) while(0)
va009039 0:11152e69fc05 42 #define USB_TEST_ASSERT_FALSE(A) while(0)
va009039 0:11152e69fc05 43 #endif
va009039 0:11152e69fc05 44
va009039 0:11152e69fc05 45 #define USB_INFO(...) do{fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n");}while(0);
va009039 0:11152e69fc05 46
va009039 0:11152e69fc05 47 // bits of the USB/OTG clock control register
va009039 0:11152e69fc05 48 #define HOST_CLK_EN (1<<0)
va009039 0:11152e69fc05 49 #define DEV_CLK_EN (1<<1)
va009039 0:11152e69fc05 50 #define PORTSEL_CLK_EN (1<<3)
va009039 0:11152e69fc05 51 #define AHB_CLK_EN (1<<4)
va009039 0:11152e69fc05 52
va009039 0:11152e69fc05 53 // bits of the USB/OTG clock status register
va009039 0:11152e69fc05 54 #define HOST_CLK_ON (1<<0)
va009039 0:11152e69fc05 55 #define DEV_CLK_ON (1<<1)
va009039 0:11152e69fc05 56 #define PORTSEL_CLK_ON (1<<3)
va009039 0:11152e69fc05 57 #define AHB_CLK_ON (1<<4)
va009039 0:11152e69fc05 58
va009039 0:11152e69fc05 59 // we need host clock, OTG/portsel clock and AHB clock
va009039 0:11152e69fc05 60 #define CLOCK_MASK (HOST_CLK_EN | PORTSEL_CLK_EN | AHB_CLK_EN)
va009039 0:11152e69fc05 61 #define FI 0x2EDF /* 12000 bits per frame (-1) */
va009039 0:11152e69fc05 62 #define DEFAULT_FMINTERVAL ((((6 * (FI - 210)) / 7) << 16) | FI)
va009039 0:11152e69fc05 63
va009039 0:11152e69fc05 64 USBHALHost* USBHALHost::instHost;
va009039 0:11152e69fc05 65
va009039 0:11152e69fc05 66 USBHALHost::USBHALHost() {
va009039 0:11152e69fc05 67 instHost = this;
va009039 0:11152e69fc05 68 }
va009039 0:11152e69fc05 69
va009039 0:11152e69fc05 70 void USBHALHost::init() {
va009039 0:11152e69fc05 71 NVIC_DisableIRQ(USB_IRQn);
va009039 0:11152e69fc05 72 m_pHcca = new HCCA();
va009039 0:11152e69fc05 73 init_hw_ohci(m_pHcca);
va009039 0:11152e69fc05 74 ResetRootHub();
va009039 0:11152e69fc05 75 NVIC_SetVector(USB_IRQn, (uint32_t)_usbisr);
va009039 0:11152e69fc05 76 NVIC_SetPriority(USB_IRQn, 0);
va009039 0:11152e69fc05 77 NVIC_EnableIRQ(USB_IRQn);
va009039 0:11152e69fc05 78
va009039 0:11152e69fc05 79 #ifndef BASE_USBHOST
va009039 0:11152e69fc05 80 USB_INFO("Simple USBHost Library for EA LPC4088 QSB");
va009039 0:11152e69fc05 81 bool lowSpeed = false;
va009039 0:11152e69fc05 82 addDevice(NULL, 0, lowSpeed);
va009039 0:11152e69fc05 83 #endif // BASE_USBHOST
va009039 0:11152e69fc05 84 }
va009039 0:11152e69fc05 85
va009039 0:11152e69fc05 86 void USBHALHost::init_hw_ohci(HCCA* pHcca) {
va009039 0:11152e69fc05 87 LPC_SC->PCONP &= ~(1UL<<31); //Cut power
va009039 0:11152e69fc05 88 wait(1);
va009039 0:11152e69fc05 89 LPC_SC->PCONP |= (1UL<<31); // turn on power for USB
va009039 0:11152e69fc05 90 LPC_USB->USBClkCtrl |= CLOCK_MASK; // Enable USB host clock, port selection and AHB clock
va009039 0:11152e69fc05 91 // Wait for clocks to become available
va009039 0:11152e69fc05 92 while ((LPC_USB->USBClkSt & CLOCK_MASK) != CLOCK_MASK)
va009039 0:11152e69fc05 93 ;
va009039 0:11152e69fc05 94 LPC_USB->OTGStCtrl |= 1;
va009039 0:11152e69fc05 95 LPC_USB->USBClkCtrl &= ~PORTSEL_CLK_EN;
va009039 0:11152e69fc05 96
va009039 0:11152e69fc05 97 #if defined(TARGET_LPC1768)
va009039 0:11152e69fc05 98 LPC_PINCON->PINSEL1 &= ~((3<<26) | (3<<28));
va009039 0:11152e69fc05 99 LPC_PINCON->PINSEL1 |= ((1<<26)|(1<<28)); // 0x14000000
va009039 0:11152e69fc05 100 #elif defined(TARGET_LPC4088)
va009039 0:11152e69fc05 101 LPC_IOCON->P0_29 = 0x01; // USB_D+1
va009039 0:11152e69fc05 102 LPC_IOCON->P0_30 = 0x01; // USB_D-1
va009039 0:11152e69fc05 103 // DO NOT CHANGE P1_19.
va009039 0:11152e69fc05 104 #else
va009039 0:11152e69fc05 105 #error "target error"
va009039 0:11152e69fc05 106 #endif
va009039 0:11152e69fc05 107 DBG("initialize OHCI\n");
va009039 0:11152e69fc05 108 wait_ms(100); /* Wait 50 ms before apply reset */
va009039 0:11152e69fc05 109 TEST_ASSERT((LPC_USB->HcRevision&0xff) == 0x10); // check revision
va009039 0:11152e69fc05 110 LPC_USB->HcControl = 0; /* HARDWARE RESET */
va009039 0:11152e69fc05 111 LPC_USB->HcControlHeadED = 0; /* Initialize Control list head to Zero */
va009039 0:11152e69fc05 112 LPC_USB->HcBulkHeadED = 0; /* Initialize Bulk list head to Zero */
va009039 0:11152e69fc05 113 /* SOFTWARE RESET */
va009039 0:11152e69fc05 114 LPC_USB->HcCommandStatus = OR_CMD_STATUS_HCR;
va009039 0:11152e69fc05 115 LPC_USB->HcFmInterval = DEFAULT_FMINTERVAL; /* Write Fm Interval and Largest Data Packet Counter */
va009039 0:11152e69fc05 116 LPC_USB->HcPeriodicStart = FI*90/100;
va009039 0:11152e69fc05 117 /* Put HC in operational state */
va009039 0:11152e69fc05 118 LPC_USB->HcControl = (LPC_USB->HcControl & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER;
va009039 0:11152e69fc05 119 LPC_USB->HcRhStatus = OR_RH_STATUS_LPSC; /* Set Global Power */
va009039 0:11152e69fc05 120 TEST_ASSERT(pHcca);
va009039 0:11152e69fc05 121 for (int i = 0; i < 32; i++) {
va009039 0:11152e69fc05 122 pHcca->InterruptTable[i] = NULL;
va009039 0:11152e69fc05 123 }
va009039 0:11152e69fc05 124 LPC_USB->HcHCCA = reinterpret_cast<uint32_t>(pHcca);
va009039 0:11152e69fc05 125 LPC_USB->HcInterruptStatus |= LPC_USB->HcInterruptStatus; /* Clear Interrrupt Status */
va009039 0:11152e69fc05 126 LPC_USB->HcInterruptEnable = OR_INTR_ENABLE_MIE|OR_INTR_ENABLE_WDH|OR_INTR_ENABLE_FNO;
va009039 0:11152e69fc05 127
va009039 0:11152e69fc05 128 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC;
va009039 0:11152e69fc05 129 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC;
va009039 0:11152e69fc05 130 }
va009039 0:11152e69fc05 131
va009039 0:11152e69fc05 132 void USBHALHost::ResetRootHub() {
va009039 0:11152e69fc05 133 wait_ms(100); /* USB 2.0 spec says at least 50ms delay before port reset */
va009039 0:11152e69fc05 134 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRS; // Initiate port reset
va009039 0:11152e69fc05 135 DBG("Before loop\n");
va009039 0:11152e69fc05 136 while (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRS)
va009039 0:11152e69fc05 137 ;
va009039 0:11152e69fc05 138 LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC; // ...and clear port reset signal
va009039 0:11152e69fc05 139 DBG("After loop\n");
va009039 0:11152e69fc05 140 wait_ms(200); /* Wait for 100 MS after port reset */
va009039 0:11152e69fc05 141 }
va009039 0:11152e69fc05 142
va009039 0:11152e69fc05 143 void USBHALHost::enable(ENDPOINT_TYPE type) {
va009039 0:11152e69fc05 144 switch(type) {
va009039 0:11152e69fc05 145 case CONTROL_ENDPOINT:
va009039 0:11152e69fc05 146 LPC_USB->HcCommandStatus |= OR_CMD_STATUS_CLF;
va009039 0:11152e69fc05 147 LPC_USB->HcControl |= OR_CONTROL_CLE;
va009039 0:11152e69fc05 148 break;
va009039 0:11152e69fc05 149 case ISOCHRONOUS_ENDPOINT:
va009039 0:11152e69fc05 150 LPC_USB->HcControl |= OR_CONTROL_PLE;
va009039 0:11152e69fc05 151 break;
va009039 0:11152e69fc05 152 case BULK_ENDPOINT:
va009039 0:11152e69fc05 153 LPC_USB->HcCommandStatus |= OR_CMD_STATUS_BLF;
va009039 0:11152e69fc05 154 LPC_USB->HcControl |= OR_CONTROL_BLE;
va009039 0:11152e69fc05 155 break;
va009039 0:11152e69fc05 156 case INTERRUPT_ENDPOINT:
va009039 0:11152e69fc05 157 LPC_USB->HcControl |= OR_CONTROL_PLE;
va009039 0:11152e69fc05 158 break;
va009039 0:11152e69fc05 159 }
va009039 0:11152e69fc05 160 }
va009039 0:11152e69fc05 161
va009039 0:11152e69fc05 162 void USBHALHost::token_init(USBEndpoint* ep) {
va009039 0:11152e69fc05 163 if (ep->m_pED == NULL) {
va009039 0:11152e69fc05 164 ep->m_pED = new HCED(ep);
va009039 0:11152e69fc05 165 USB_DBG_ED(ep->m_pED);
va009039 0:11152e69fc05 166 }
va009039 0:11152e69fc05 167 HCED* ed = ep->m_pED;
va009039 0:11152e69fc05 168 USBDeviceConnected* dev = ep->getDevice();
va009039 0:11152e69fc05 169 USB_TEST_ASSERT(dev);
va009039 0:11152e69fc05 170 if (dev) {
va009039 0:11152e69fc05 171 uint8_t devAddr = dev->getAddress();
va009039 0:11152e69fc05 172 USB_DBG("devAddr=%02x", devAddr);
va009039 0:11152e69fc05 173 ed->setFunctionAddress(devAddr);
va009039 0:11152e69fc05 174 }
va009039 0:11152e69fc05 175 uint16_t size = ep->getSize();
va009039 0:11152e69fc05 176 USB_DBG("MaxPacketSize=%d", size);
va009039 0:11152e69fc05 177 ed->setMaxPacketSize(size);
va009039 0:11152e69fc05 178 if (ed->HeadTd == NULL) {
va009039 0:11152e69fc05 179 HCTD* td = new HCTD(ep);
va009039 0:11152e69fc05 180 ed->TailTd = td;
va009039 0:11152e69fc05 181 ed->HeadTd = td;
va009039 0:11152e69fc05 182 switch(ep->getType()) {
va009039 0:11152e69fc05 183 case CONTROL_ENDPOINT:
va009039 0:11152e69fc05 184 ed->Next = reinterpret_cast<HCED*>(LPC_USB->HcControlHeadED);
va009039 0:11152e69fc05 185 LPC_USB->HcControlHeadED = reinterpret_cast<uint32_t>(ed);
va009039 0:11152e69fc05 186 break;
va009039 0:11152e69fc05 187 case BULK_ENDPOINT:
va009039 0:11152e69fc05 188 ed->Next = reinterpret_cast<HCED*>(LPC_USB->HcBulkHeadED);
va009039 0:11152e69fc05 189 LPC_USB->HcBulkHeadED = reinterpret_cast<uint32_t>(ed);
va009039 0:11152e69fc05 190 break;
va009039 0:11152e69fc05 191 case INTERRUPT_ENDPOINT:
va009039 0:11152e69fc05 192 HCCA* pHcca = reinterpret_cast<HCCA*>(LPC_USB->HcHCCA);
va009039 0:11152e69fc05 193 ed->Next = pHcca->InterruptTable[0];
va009039 0:11152e69fc05 194 pHcca->InterruptTable[0] = ed;
va009039 0:11152e69fc05 195 break;
va009039 0:11152e69fc05 196 }
va009039 0:11152e69fc05 197 USB_DBG_ED(ed);
va009039 0:11152e69fc05 198 }
va009039 0:11152e69fc05 199 }
va009039 0:11152e69fc05 200
va009039 0:11152e69fc05 201 int USBHALHost::token_setup(USBEndpoint* ep, SETUP_PACKET* setup, uint16_t wLength) {
va009039 0:11152e69fc05 202 token_init(ep);
va009039 0:11152e69fc05 203 HCED* ed = ep->m_pED;
va009039 0:11152e69fc05 204 HCTD* td = ed->TailTd;
va009039 0:11152e69fc05 205 setup->wLength = wLength;
va009039 0:11152e69fc05 206 TBUF* tbuf = new(sizeof(SETUP_PACKET))TBUF(setup, sizeof(SETUP_PACKET));
va009039 0:11152e69fc05 207 td->transfer(tbuf, sizeof(SETUP_PACKET));
va009039 0:11152e69fc05 208 td->Control |= TD_TOGGLE_0|TD_SETUP;
va009039 0:11152e69fc05 209 HCTD* blank = new HCTD(ep);
va009039 0:11152e69fc05 210 td->Next = blank;
va009039 0:11152e69fc05 211 ed->TailTd = blank;
va009039 0:11152e69fc05 212 //DBG_ED(ed);
va009039 0:11152e69fc05 213 enable(ep->getType());
va009039 0:11152e69fc05 214
va009039 0:11152e69fc05 215 td = ep->get_queue_HCTD();
va009039 0:11152e69fc05 216 TEST_ASSERT(td);
va009039 0:11152e69fc05 217 int result = td->getLengthTransferred();
va009039 0:11152e69fc05 218 DBG_TD(td);
va009039 0:11152e69fc05 219 delete tbuf;
va009039 0:11152e69fc05 220 delete td;
va009039 0:11152e69fc05 221 return result;
va009039 0:11152e69fc05 222 }
va009039 0:11152e69fc05 223
va009039 0:11152e69fc05 224 int USBHALHost::token_in(USBEndpoint* ep, uint8_t* data, int size, int retryLimit) {
va009039 0:11152e69fc05 225 token_init(ep);
va009039 0:11152e69fc05 226 HCED* ed = ep->m_pED;
va009039 0:11152e69fc05 227 HCTD* td = ed->TailTd;
va009039 0:11152e69fc05 228 TBUF* tbuf = NULL;
va009039 0:11152e69fc05 229 if (data != NULL) {
va009039 0:11152e69fc05 230 tbuf = new(size)TBUF();
va009039 0:11152e69fc05 231 td->transfer(tbuf, size);
va009039 0:11152e69fc05 232 }
va009039 0:11152e69fc05 233 td->Control |= TD_IN;
va009039 0:11152e69fc05 234 HCTD* blank = new HCTD(ep);
va009039 0:11152e69fc05 235 td->Next = blank;
va009039 0:11152e69fc05 236 ed->TailTd = blank;
va009039 0:11152e69fc05 237 USB_DBG_ED_IF(ed->EndpointNumber()==0, ed); // control transfer
va009039 0:11152e69fc05 238 enable(ep->getType());
va009039 0:11152e69fc05 239
va009039 0:11152e69fc05 240 td = ep->get_queue_HCTD();
va009039 0:11152e69fc05 241 TEST_ASSERT(td);
va009039 0:11152e69fc05 242 if (data != NULL) {
va009039 0:11152e69fc05 243 memcpy(data, tbuf->buf, size);
va009039 0:11152e69fc05 244 delete tbuf;
va009039 0:11152e69fc05 245 }
va009039 0:11152e69fc05 246 int result = td->getLengthTransferred();
va009039 0:11152e69fc05 247 delete td;
va009039 0:11152e69fc05 248 return result;
va009039 0:11152e69fc05 249 }
va009039 0:11152e69fc05 250
va009039 0:11152e69fc05 251 int USBHALHost::token_out(USBEndpoint* ep, const uint8_t* data, int size, int retryLimit) {
va009039 0:11152e69fc05 252 token_init(ep);
va009039 0:11152e69fc05 253 HCED* ed = ep->m_pED;
va009039 0:11152e69fc05 254 HCTD* td = ed->TailTd;
va009039 0:11152e69fc05 255 TBUF* tbuf = NULL;
va009039 0:11152e69fc05 256 if (data != NULL) {
va009039 0:11152e69fc05 257 tbuf = new(size)TBUF(data, size);
va009039 0:11152e69fc05 258 td->transfer(tbuf, size);
va009039 0:11152e69fc05 259 }
va009039 0:11152e69fc05 260 td->Control |= TD_OUT;
va009039 0:11152e69fc05 261 HCTD* blank = new HCTD(ep);
va009039 0:11152e69fc05 262 td->Next = blank;
va009039 0:11152e69fc05 263 ed->TailTd = blank;
va009039 0:11152e69fc05 264 DBG_ED(ed);
va009039 0:11152e69fc05 265 enable(ep->getType());
va009039 0:11152e69fc05 266
va009039 0:11152e69fc05 267 td = ep->get_queue_HCTD();
va009039 0:11152e69fc05 268 TEST_ASSERT(td);
va009039 0:11152e69fc05 269 if (data != NULL) {
va009039 0:11152e69fc05 270 delete tbuf;
va009039 0:11152e69fc05 271 }
va009039 0:11152e69fc05 272 int result = td->getLengthTransferred();
va009039 0:11152e69fc05 273 delete td;
va009039 0:11152e69fc05 274 return result;
va009039 0:11152e69fc05 275 }
va009039 0:11152e69fc05 276
va009039 0:11152e69fc05 277 void USBHALHost::token_inNB(USBEndpoint* ep, uint8_t* data, int size) {
va009039 0:11152e69fc05 278 token_init(ep);
va009039 0:11152e69fc05 279 HCED* ed = ep->m_pED;
va009039 0:11152e69fc05 280 HCTD* td = ed->TailTd;
va009039 0:11152e69fc05 281 TBUF* tbuf = new(size)TBUF();
va009039 0:11152e69fc05 282 td->transfer(tbuf, size);
va009039 0:11152e69fc05 283 td->Control |= TD_IN;
va009039 0:11152e69fc05 284 HCTD* blank = new HCTD(ep);
va009039 0:11152e69fc05 285 td->Next = blank;
va009039 0:11152e69fc05 286 ed->TailTd = blank;
va009039 0:11152e69fc05 287 enable(ep->getType());
va009039 0:11152e69fc05 288 }
va009039 0:11152e69fc05 289
va009039 0:11152e69fc05 290 USB_TYPE USBHALHost::token_inNB_result(USBEndpoint* ep) {
va009039 0:11152e69fc05 291 HCTD* td = ep->get_queue_HCTD(0);
va009039 0:11152e69fc05 292 if (td) {
va009039 0:11152e69fc05 293 int len = td->getLengthTransferred();
va009039 0:11152e69fc05 294 TBUF* tbuf = (TBUF*)td->buf_top;
va009039 0:11152e69fc05 295 memcpy(ep->getBufStart(), tbuf->buf, len);
va009039 0:11152e69fc05 296 ep->setLengthTransferred(len);
va009039 0:11152e69fc05 297 delete td;
va009039 0:11152e69fc05 298 delete tbuf;
va009039 0:11152e69fc05 299 return USB_TYPE_OK;
va009039 0:11152e69fc05 300 }
va009039 0:11152e69fc05 301 return USB_TYPE_PROCESSING;
va009039 0:11152e69fc05 302 }
va009039 0:11152e69fc05 303
va009039 0:11152e69fc05 304 void USBHALHost::_usbisr(void) {
va009039 0:11152e69fc05 305 if (instHost) {
va009039 0:11152e69fc05 306 instHost->UsbIrqhandler();
va009039 0:11152e69fc05 307 }
va009039 0:11152e69fc05 308 }
va009039 0:11152e69fc05 309
va009039 0:11152e69fc05 310 HCTD* td_reverse(HCTD* td)
va009039 0:11152e69fc05 311 {
va009039 0:11152e69fc05 312 HCTD* result = NULL;
va009039 0:11152e69fc05 313 HCTD* next;
va009039 0:11152e69fc05 314 while(td) {
va009039 0:11152e69fc05 315 next = const_cast<HCTD*>(td->Next);
va009039 0:11152e69fc05 316 td->Next = result;
va009039 0:11152e69fc05 317 result = td;
va009039 0:11152e69fc05 318 td = next;
va009039 0:11152e69fc05 319 }
va009039 0:11152e69fc05 320 return result;
va009039 0:11152e69fc05 321 }
va009039 0:11152e69fc05 322
va009039 0:11152e69fc05 323 void USBHALHost::UsbIrqhandler() {
va009039 0:11152e69fc05 324 if (!(LPC_USB->HcInterruptStatus & LPC_USB->HcInterruptEnable)) {
va009039 0:11152e69fc05 325 return;
va009039 0:11152e69fc05 326 }
va009039 0:11152e69fc05 327 m_report_irq++;
va009039 0:11152e69fc05 328 uint32_t status = LPC_USB->HcInterruptStatus;
va009039 0:11152e69fc05 329 if (status & OR_INTR_STATUS_FNO) {
va009039 0:11152e69fc05 330 m_report_FNO++;
va009039 0:11152e69fc05 331 }
va009039 0:11152e69fc05 332 if (status & OR_INTR_STATUS_WDH) {
va009039 0:11152e69fc05 333 union {
va009039 0:11152e69fc05 334 HCTD* done_td;
va009039 0:11152e69fc05 335 uint32_t lsb;
va009039 0:11152e69fc05 336 };
va009039 0:11152e69fc05 337 done_td = const_cast<HCTD*>(m_pHcca->DoneHead);
va009039 0:11152e69fc05 338 TEST_ASSERT(done_td);
va009039 0:11152e69fc05 339 m_pHcca->DoneHead = NULL; // reset
va009039 0:11152e69fc05 340 if (lsb & 1) { // error ?
va009039 0:11152e69fc05 341 lsb &= ~1;
va009039 0:11152e69fc05 342 }
va009039 0:11152e69fc05 343 HCTD* td = td_reverse(done_td);
va009039 0:11152e69fc05 344 while(td) {
va009039 0:11152e69fc05 345 USBEndpoint* ep = td->ep;
va009039 0:11152e69fc05 346 TEST_ASSERT(ep);
va009039 0:11152e69fc05 347 if (ep) {
va009039 0:11152e69fc05 348 ep->irqWdhHandler(td);
va009039 0:11152e69fc05 349 }
va009039 0:11152e69fc05 350 td = td->Next;
va009039 0:11152e69fc05 351 }
va009039 0:11152e69fc05 352 m_report_WDH++;
va009039 0:11152e69fc05 353 }
va009039 0:11152e69fc05 354 LPC_USB->HcInterruptStatus = status; // Clear Interrrupt Status
va009039 0:11152e69fc05 355 }
va009039 0:11152e69fc05 356
va009039 0:11152e69fc05 357 HCTD::HCTD(USBEndpoint* obj) {
va009039 0:11152e69fc05 358 CTASSERT(sizeof(HCTD) == 36);
va009039 0:11152e69fc05 359 TEST_ASSERT(obj);
va009039 0:11152e69fc05 360 Control = TD_CC|TD_ROUNDING;
va009039 0:11152e69fc05 361 CurrBufPtr = NULL;
va009039 0:11152e69fc05 362 Next = NULL;
va009039 0:11152e69fc05 363 BufEnd = NULL;
va009039 0:11152e69fc05 364 buf_top = NULL;
va009039 0:11152e69fc05 365 buf_size = 0;
va009039 0:11152e69fc05 366 ep = obj;
va009039 0:11152e69fc05 367 }
va009039 0:11152e69fc05 368
va009039 0:11152e69fc05 369 HCED::HCED(USBEndpoint* ep) {
va009039 0:11152e69fc05 370 USBDeviceConnected* dev = ep->getDevice();
va009039 0:11152e69fc05 371 int devAddr = 0;
va009039 0:11152e69fc05 372 bool lowSpeed = false;
va009039 0:11152e69fc05 373 if (dev) {
va009039 0:11152e69fc05 374 devAddr = dev->getAddress();
va009039 0:11152e69fc05 375 lowSpeed = dev->getSpeed();
va009039 0:11152e69fc05 376 }
va009039 0:11152e69fc05 377 int ep_number = ep->getAddress();
va009039 0:11152e69fc05 378 int MaxPacketSize = ep->getSize();
va009039 0:11152e69fc05 379 Control = devAddr | /* USB address */
va009039 0:11152e69fc05 380 ((ep_number & 0x7F) << 7) | /* Endpoint address */
va009039 0:11152e69fc05 381 (ep_number!=0?(((ep_number&0x80)?2:1) << 11):0)| /* direction : Out = 1, 2 = In */
va009039 0:11152e69fc05 382 ((lowSpeed?1:0) << 13) | /* speed full=0 low=1 */
va009039 0:11152e69fc05 383 (MaxPacketSize << 16); /* MaxPkt Size */
va009039 0:11152e69fc05 384 TailTd = NULL;
va009039 0:11152e69fc05 385 HeadTd = NULL;
va009039 0:11152e69fc05 386 Next = NULL;
va009039 0:11152e69fc05 387 }
va009039 0:11152e69fc05 388