USB Host Driver with Socket Modem support. Works with revision 323 of mbed-src but broken with any later version.
Dependencies: FATFileSystem
Fork of F401RE-USBHost by
USBHost/USBHALHost_LPC4088.h@26:53970cabf56d, 2015-06-26 (annotated)
- Committer:
- fritz291
- Date:
- Fri Jun 26 19:30:55 2015 +0000
- Revision:
- 26:53970cabf56d
- Parent:
- 18:61554f238584
Fixed small error in testAT function
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 |
18:61554f238584 | 1 | /* mbed USBHost Library |
va009039 |
18:61554f238584 | 2 | * Copyright (c) 2006-2013 ARM Limited |
va009039 |
18:61554f238584 | 3 | * |
va009039 |
18:61554f238584 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
va009039 |
18:61554f238584 | 5 | * you may not use this file except in compliance with the License. |
va009039 |
18:61554f238584 | 6 | * You may obtain a copy of the License at |
va009039 |
18:61554f238584 | 7 | * |
va009039 |
18:61554f238584 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
va009039 |
18:61554f238584 | 9 | * |
va009039 |
18:61554f238584 | 10 | * Unless required by applicable law or agreed to in writing, software |
va009039 |
18:61554f238584 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
va009039 |
18:61554f238584 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
va009039 |
18:61554f238584 | 13 | * See the License for the specific language governing permissions and |
va009039 |
18:61554f238584 | 14 | * limitations under the License. |
va009039 |
18:61554f238584 | 15 | */ |
va009039 |
18:61554f238584 | 16 | |
va009039 |
18:61554f238584 | 17 | #pragma once |
va009039 |
18:61554f238584 | 18 | #include "mbed.h" |
va009039 |
18:61554f238584 | 19 | #include "rtos.h" |
va009039 |
18:61554f238584 | 20 | #include "USBHostTypes.h" |
va009039 |
18:61554f238584 | 21 | #include "USBEndpoint.h" |
va009039 |
18:61554f238584 | 22 | |
va009039 |
18:61554f238584 | 23 | #if defined(TARGET_LPC4088) |
va009039 |
18:61554f238584 | 24 | #define HcRevision Revision |
va009039 |
18:61554f238584 | 25 | #define HcControl Control |
va009039 |
18:61554f238584 | 26 | #define HcCommandStatus CommandStatus |
va009039 |
18:61554f238584 | 27 | #define HcInterruptStatus InterruptStatus |
va009039 |
18:61554f238584 | 28 | #define HcInterruptEnable InterruptEnable |
va009039 |
18:61554f238584 | 29 | #define HcHCCA HCCA |
va009039 |
18:61554f238584 | 30 | #define HcControlHeadED ControlHeadED |
va009039 |
18:61554f238584 | 31 | #define HcBulkHeadED BulkHeadED |
va009039 |
18:61554f238584 | 32 | #define HcFmInterval FmInterval |
va009039 |
18:61554f238584 | 33 | #define HcFmNumber FmNumber |
va009039 |
18:61554f238584 | 34 | #define HcPeriodicStart PeriodicStart |
va009039 |
18:61554f238584 | 35 | #define HcRhStatus RhStatus |
va009039 |
18:61554f238584 | 36 | #define HcRhPortStatus1 RhPortStatus1 |
va009039 |
18:61554f238584 | 37 | #define OTGStCtrl StCtrl |
va009039 |
18:61554f238584 | 38 | #endif |
va009039 |
18:61554f238584 | 39 | // ------------------ HcControl Register --------------------- |
va009039 |
18:61554f238584 | 40 | #define OR_CONTROL_PLE 0x00000004 |
va009039 |
18:61554f238584 | 41 | #define OR_CONTROL_IE 0x00000008 |
va009039 |
18:61554f238584 | 42 | #define OR_CONTROL_CLE 0x00000010 |
va009039 |
18:61554f238584 | 43 | #define OR_CONTROL_BLE 0x00000020 |
va009039 |
18:61554f238584 | 44 | #define OR_CONTROL_HCFS 0x000000C0 |
va009039 |
18:61554f238584 | 45 | #define OR_CONTROL_HC_OPER 0x00000080 |
va009039 |
18:61554f238584 | 46 | // ----------------- HcCommandStatus Register ----------------- |
va009039 |
18:61554f238584 | 47 | #define OR_CMD_STATUS_HCR 0x00000001 |
va009039 |
18:61554f238584 | 48 | #define OR_CMD_STATUS_CLF 0x00000002 |
va009039 |
18:61554f238584 | 49 | #define OR_CMD_STATUS_BLF 0x00000004 |
va009039 |
18:61554f238584 | 50 | // --------------- HcInterruptStatus Register ----------------- |
va009039 |
18:61554f238584 | 51 | #define OR_INTR_STATUS_WDH 0x00000002 |
va009039 |
18:61554f238584 | 52 | #define OR_INTR_STATUS_UE 0x00000010 |
va009039 |
18:61554f238584 | 53 | #define OR_INTR_STATUS_FNO 0x00000020 |
va009039 |
18:61554f238584 | 54 | #define OR_INTR_STATUS_RHSC 0x00000040 |
va009039 |
18:61554f238584 | 55 | // --------------- HcInterruptEnable Register ----------------- |
va009039 |
18:61554f238584 | 56 | #define OR_INTR_ENABLE_WDH 0x00000002 |
va009039 |
18:61554f238584 | 57 | #define OR_INTR_ENABLE_FNO 0x00000020 |
va009039 |
18:61554f238584 | 58 | #define OR_INTR_ENABLE_RHSC 0x00000040 |
va009039 |
18:61554f238584 | 59 | #define OR_INTR_ENABLE_MIE 0x80000000 |
va009039 |
18:61554f238584 | 60 | // ---------------- HcRhDescriptorA Register ------------------ |
va009039 |
18:61554f238584 | 61 | #define OR_RH_STATUS_LPSC 0x00010000 |
va009039 |
18:61554f238584 | 62 | #define OR_RH_STATUS_DRWE 0x00008000 |
va009039 |
18:61554f238584 | 63 | // -------------- HcRhPortStatus[1:NDP] Register -------------- |
va009039 |
18:61554f238584 | 64 | #define OR_RH_PORT_CCS 0x00000001 |
va009039 |
18:61554f238584 | 65 | #define OR_RH_PORT_PRS 0x00000010 |
va009039 |
18:61554f238584 | 66 | #define OR_RH_PORT_LSDA 0x00000200 |
va009039 |
18:61554f238584 | 67 | #define OR_RH_PORT_CSC 0x00010000 |
va009039 |
18:61554f238584 | 68 | #define OR_RH_PORT_PRSC 0x00100000 |
va009039 |
18:61554f238584 | 69 | |
va009039 |
18:61554f238584 | 70 | // TRANSFER DESCRIPTOR CONTROL FIELDS |
va009039 |
18:61554f238584 | 71 | #define TD_ROUNDING (uint32_t)(0x00040000) /* Buffer Rounding */ |
va009039 |
18:61554f238584 | 72 | #define TD_SETUP (uint32_t)(0x00000000) /* Direction of Setup Packet */ |
va009039 |
18:61554f238584 | 73 | #define TD_IN (uint32_t)(0x00100000) /* Direction In */ |
va009039 |
18:61554f238584 | 74 | #define TD_OUT (uint32_t)(0x00080000) /* Direction Out */ |
va009039 |
18:61554f238584 | 75 | #define TD_DELAY_INT(x) (uint32_t)((x) << 21) /* Delay Interrupt */ |
va009039 |
18:61554f238584 | 76 | #define TD_DI (uint32_t)(7<<21) /* desable interrupt */ |
va009039 |
18:61554f238584 | 77 | #define TD_TOGGLE_0 (uint32_t)(0x02000000) /* Toggle 0 */ |
va009039 |
18:61554f238584 | 78 | #define TD_TOGGLE_1 (uint32_t)(0x03000000) /* Toggle 1 */ |
va009039 |
18:61554f238584 | 79 | #define TD_CC (uint32_t)(0xF0000000) /* Completion Code */ |
va009039 |
18:61554f238584 | 80 | |
va009039 |
18:61554f238584 | 81 | void* usb_ram_malloc(size_t size, int aligment); // USBHALHost2_LPC4088.cpp |
va009039 |
18:61554f238584 | 82 | void usb_ram_free(void* p); |
va009039 |
18:61554f238584 | 83 | |
va009039 |
18:61554f238584 | 84 | struct TBUF { |
va009039 |
18:61554f238584 | 85 | uint8_t buf[0]; |
va009039 |
18:61554f238584 | 86 | TBUF(const void* data = NULL, int size = 0); |
va009039 |
18:61554f238584 | 87 | void* operator new(size_t size, int buf_size) { return usb_ram_malloc(size+buf_size, 4); } |
va009039 |
18:61554f238584 | 88 | void operator delete(void* p) { usb_ram_free(p); } |
va009039 |
18:61554f238584 | 89 | }; |
va009039 |
18:61554f238584 | 90 | |
va009039 |
18:61554f238584 | 91 | class HCED; |
va009039 |
18:61554f238584 | 92 | |
va009039 |
18:61554f238584 | 93 | struct HCTD { // HostController Transfer Descriptor |
va009039 |
18:61554f238584 | 94 | __IO uint32_t Control; // +0 Transfer descriptor control |
va009039 |
18:61554f238584 | 95 | __IO uint8_t* CurrBufPtr; // +4 Physical address of current buffer pointer |
va009039 |
18:61554f238584 | 96 | HCTD* Next; // +8 Physical pointer to next Transfer Descriptor |
va009039 |
18:61554f238584 | 97 | uint8_t* BufEnd; // +12 Physical address of end of buffer |
va009039 |
18:61554f238584 | 98 | uint8_t* buf_top; // +16 Buffer start address |
va009039 |
18:61554f238584 | 99 | uint16_t buf_size; // +20 buffer size size |
va009039 |
18:61554f238584 | 100 | uint8_t _dummy[10]; // +22 dummy |
va009039 |
18:61554f238584 | 101 | HCED* parent; // +32 HCED object |
va009039 |
18:61554f238584 | 102 | // +36 |
va009039 |
18:61554f238584 | 103 | HCTD(HCED* ed); |
va009039 |
18:61554f238584 | 104 | void* operator new(size_t size) { return usb_ram_malloc(size, 16); } |
va009039 |
18:61554f238584 | 105 | void operator delete(void* p) { usb_ram_free(p); } |
va009039 |
18:61554f238584 | 106 | |
va009039 |
18:61554f238584 | 107 | void transfer(TBUF* tbuf, int len) { |
va009039 |
18:61554f238584 | 108 | CurrBufPtr = tbuf->buf; |
va009039 |
18:61554f238584 | 109 | buf_top = tbuf->buf; |
va009039 |
18:61554f238584 | 110 | buf_size = len; |
va009039 |
18:61554f238584 | 111 | BufEnd = const_cast<uint8_t*>(tbuf->buf)+len-1; |
va009039 |
18:61554f238584 | 112 | } |
va009039 |
18:61554f238584 | 113 | int getLengthTransferred() { |
va009039 |
18:61554f238584 | 114 | if (CurrBufPtr) { |
va009039 |
18:61554f238584 | 115 | return CurrBufPtr - buf_top; |
va009039 |
18:61554f238584 | 116 | } |
va009039 |
18:61554f238584 | 117 | return buf_size; |
va009039 |
18:61554f238584 | 118 | } |
va009039 |
18:61554f238584 | 119 | int status() { |
va009039 |
18:61554f238584 | 120 | if (CurrBufPtr) { |
va009039 |
18:61554f238584 | 121 | return CurrBufPtr - buf_top; |
va009039 |
18:61554f238584 | 122 | } |
va009039 |
18:61554f238584 | 123 | return buf_size; |
va009039 |
18:61554f238584 | 124 | } |
va009039 |
18:61554f238584 | 125 | |
va009039 |
18:61554f238584 | 126 | uint8_t ConditionCode() { |
va009039 |
18:61554f238584 | 127 | return Control>>28; |
va009039 |
18:61554f238584 | 128 | } |
va009039 |
18:61554f238584 | 129 | }; |
va009039 |
18:61554f238584 | 130 | |
va009039 |
18:61554f238584 | 131 | struct HCITD { // HostController Isochronous Transfer Descriptor |
va009039 |
18:61554f238584 | 132 | __IO uint32_t Control; // +0 Transfer descriptor control |
va009039 |
18:61554f238584 | 133 | uint8_t* BufferPage0; // +4 Buffer Page 0 |
va009039 |
18:61554f238584 | 134 | HCITD* Next; // +8 Physical pointer to next Isochronous Transfer Descriptor |
va009039 |
18:61554f238584 | 135 | uint8_t* BufferEnd; // +12 buffer End |
va009039 |
18:61554f238584 | 136 | __IO uint16_t OffsetPSW[8]; // +16 Offset/PSW |
va009039 |
18:61554f238584 | 137 | HCED* parent; // +32 HCED object |
va009039 |
18:61554f238584 | 138 | __IO uint8_t buf[0]; // +36 buffer |
va009039 |
18:61554f238584 | 139 | // +36 |
va009039 |
18:61554f238584 | 140 | HCITD(HCED* ed, uint16_t FrameNumber, int FrameCount, uint16_t PacketSize); |
va009039 |
18:61554f238584 | 141 | uint8_t* Buffer(int fc); |
va009039 |
18:61554f238584 | 142 | void* operator new(size_t size, int buf_size) { return usb_ram_malloc(size+buf_size, 32); } |
va009039 |
18:61554f238584 | 143 | void operator delete(void* p) { usb_ram_free(p); } |
va009039 |
18:61554f238584 | 144 | |
va009039 |
18:61554f238584 | 145 | uint16_t StartingFrame() { |
va009039 |
18:61554f238584 | 146 | return Control & 0xffff; |
va009039 |
18:61554f238584 | 147 | } |
va009039 |
18:61554f238584 | 148 | |
va009039 |
18:61554f238584 | 149 | uint8_t FrameCount() { |
va009039 |
18:61554f238584 | 150 | return ((Control>>24)&7)+1; |
va009039 |
18:61554f238584 | 151 | } |
va009039 |
18:61554f238584 | 152 | |
va009039 |
18:61554f238584 | 153 | uint8_t ConditionCode() { |
va009039 |
18:61554f238584 | 154 | return Control>>28; |
va009039 |
18:61554f238584 | 155 | } |
va009039 |
18:61554f238584 | 156 | |
va009039 |
18:61554f238584 | 157 | uint8_t ConditionCode(int fc) { |
va009039 |
18:61554f238584 | 158 | uint16_t psw = OffsetPSW[fc]; |
va009039 |
18:61554f238584 | 159 | return psw>>12; |
va009039 |
18:61554f238584 | 160 | } |
va009039 |
18:61554f238584 | 161 | |
va009039 |
18:61554f238584 | 162 | uint16_t Length(int fc) { |
va009039 |
18:61554f238584 | 163 | uint16_t psw = OffsetPSW[fc]; |
va009039 |
18:61554f238584 | 164 | return psw & 0x7ff; |
va009039 |
18:61554f238584 | 165 | } |
va009039 |
18:61554f238584 | 166 | }; |
va009039 |
18:61554f238584 | 167 | |
va009039 |
18:61554f238584 | 168 | #define HCTD_QUEUE_SIZE 3 |
va009039 |
18:61554f238584 | 169 | |
va009039 |
18:61554f238584 | 170 | struct HCED { // HostController EndPoint Descriptor |
va009039 |
18:61554f238584 | 171 | __IO uint32_t Control; // +0 Endpoint descriptor control |
va009039 |
18:61554f238584 | 172 | HCTD* TailTd; // +4 Physical address of tail in Transfer descriptor list |
va009039 |
18:61554f238584 | 173 | __IO HCTD* HeadTd; // +8 Physcial address of head in Transfer descriptor list |
va009039 |
18:61554f238584 | 174 | HCED* Next; // +12 Physical address of next Endpoint descriptor |
va009039 |
18:61554f238584 | 175 | // +16 |
va009039 |
18:61554f238584 | 176 | uint8_t m_ConditionCode; |
va009039 |
18:61554f238584 | 177 | Queue<HCTD, HCTD_QUEUE_SIZE> _done_queue; // TD done queue |
va009039 |
18:61554f238584 | 178 | struct { |
va009039 |
18:61554f238584 | 179 | uint8_t queue_count; |
va009039 |
18:61554f238584 | 180 | uint8_t queue_limit; |
va009039 |
18:61554f238584 | 181 | uint16_t FrameNumber; |
va009039 |
18:61554f238584 | 182 | uint8_t FrameCount; // 1-8 |
va009039 |
18:61554f238584 | 183 | HCITD* Current_itd; |
va009039 |
18:61554f238584 | 184 | uint8_t Current_FrameCount; |
va009039 |
18:61554f238584 | 185 | } iso; |
va009039 |
18:61554f238584 | 186 | inline osEvent done_queue_get(uint32_t millisec) { return _done_queue.get(millisec); } |
va009039 |
18:61554f238584 | 187 | inline void irqWdhHandler(HCTD* td) {_done_queue.put(td);} // WDH |
va009039 |
18:61554f238584 | 188 | HCTD* get_queue_HCTD(uint32_t millisec=osWaitForever); |
va009039 |
18:61554f238584 | 189 | HCITD* get_queue_HCITD(); |
va009039 |
18:61554f238584 | 190 | HCITD* new_HCITD(); |
va009039 |
18:61554f238584 | 191 | HCED(USBEndpoint* ep); |
va009039 |
18:61554f238584 | 192 | void* operator new(size_t size) { return usb_ram_malloc(size, 16); } |
va009039 |
18:61554f238584 | 193 | void operator delete(void* p) { usb_ram_free(p); } |
va009039 |
18:61554f238584 | 194 | |
va009039 |
18:61554f238584 | 195 | uint8_t FunctionAddress() { |
va009039 |
18:61554f238584 | 196 | return Control & 0x7f; |
va009039 |
18:61554f238584 | 197 | } |
va009039 |
18:61554f238584 | 198 | |
va009039 |
18:61554f238584 | 199 | uint8_t EndpointNumber() { |
va009039 |
18:61554f238584 | 200 | return (Control>>7) & 0x7f; |
va009039 |
18:61554f238584 | 201 | } |
va009039 |
18:61554f238584 | 202 | |
va009039 |
18:61554f238584 | 203 | int Speed() { |
va009039 |
18:61554f238584 | 204 | return (Control>>13)&1; |
va009039 |
18:61554f238584 | 205 | } |
va009039 |
18:61554f238584 | 206 | |
va009039 |
18:61554f238584 | 207 | void setFunctionAddress(int addr) { |
va009039 |
18:61554f238584 | 208 | Control &= ~0x7f; |
va009039 |
18:61554f238584 | 209 | Control |= addr; |
va009039 |
18:61554f238584 | 210 | } |
va009039 |
18:61554f238584 | 211 | |
va009039 |
18:61554f238584 | 212 | void setMaxPacketSize(uint16_t size) { |
va009039 |
18:61554f238584 | 213 | Control &= ~0x07ff0000; |
va009039 |
18:61554f238584 | 214 | Control |= size<<16; |
va009039 |
18:61554f238584 | 215 | } |
va009039 |
18:61554f238584 | 216 | |
va009039 |
18:61554f238584 | 217 | uint16_t getMaxPacketSize() { |
va009039 |
18:61554f238584 | 218 | return (Control>>16)&0x7ff; |
va009039 |
18:61554f238584 | 219 | } |
va009039 |
18:61554f238584 | 220 | |
va009039 |
18:61554f238584 | 221 | void setToggle(uint8_t toggle); |
va009039 |
18:61554f238584 | 222 | uint8_t getToggle(); |
va009039 |
18:61554f238584 | 223 | |
va009039 |
18:61554f238584 | 224 | int Skip() { |
va009039 |
18:61554f238584 | 225 | return (Control>>14) & 1; |
va009039 |
18:61554f238584 | 226 | } |
va009039 |
18:61554f238584 | 227 | |
va009039 |
18:61554f238584 | 228 | void setSkip() { |
va009039 |
18:61554f238584 | 229 | Control |= (1<<14); |
va009039 |
18:61554f238584 | 230 | } |
va009039 |
18:61554f238584 | 231 | |
va009039 |
18:61554f238584 | 232 | void setFormat() { |
va009039 |
18:61554f238584 | 233 | Control |= (1<<15); |
va009039 |
18:61554f238584 | 234 | } |
va009039 |
18:61554f238584 | 235 | |
va009039 |
18:61554f238584 | 236 | bool enqueue(HCTD* td); |
va009039 |
18:61554f238584 | 237 | void init_queue(HCTD* td); |
va009039 |
18:61554f238584 | 238 | }; |
va009039 |
18:61554f238584 | 239 | |
va009039 |
18:61554f238584 | 240 | struct HCCA { // Host Controller Communication Area |
va009039 |
18:61554f238584 | 241 | HCED* InterruptTable[32]; // +0 Interrupt Table |
va009039 |
18:61554f238584 | 242 | __IO uint16_t FrameNumber;// +128 Frame Number |
va009039 |
18:61554f238584 | 243 | __IO uint16_t Pad1; // +130 |
va009039 |
18:61554f238584 | 244 | __IO HCTD* DoneHead; // +132 Done Head |
va009039 |
18:61554f238584 | 245 | uint8_t Reserved[116]; // +136 Reserved for future use |
va009039 |
18:61554f238584 | 246 | uint8_t Unknown[4]; // +252 Unused |
va009039 |
18:61554f238584 | 247 | // +256 |
va009039 |
18:61554f238584 | 248 | void* operator new(size_t size) { return usb_ram_malloc(size, 256); } |
va009039 |
18:61554f238584 | 249 | void operator delete(void* p) { usb_ram_free(p); } |
va009039 |
18:61554f238584 | 250 | void enqueue(HCED* ed); |
va009039 |
18:61554f238584 | 251 | }; |
va009039 |
18:61554f238584 | 252 | |
va009039 |
18:61554f238584 | 253 | class USBHALHost { |
va009039 |
18:61554f238584 | 254 | protected: |
va009039 |
18:61554f238584 | 255 | USBHALHost(); |
va009039 |
18:61554f238584 | 256 | void init(); |
va009039 |
18:61554f238584 | 257 | virtual bool addDevice(USBDeviceConnected* parent, int port, bool lowSpeed) = 0; |
va009039 |
18:61554f238584 | 258 | int token_setup(USBEndpoint* ep, SETUP_PACKET* setup, uint16_t wLength = 0); |
va009039 |
18:61554f238584 | 259 | int token_iso_in(USBEndpoint* ep, uint8_t* data, int size); |
va009039 |
18:61554f238584 | 260 | int multi_token_in(USBEndpoint* ep, uint8_t* data = NULL, int size = 0); |
va009039 |
18:61554f238584 | 261 | int multi_token_out(USBEndpoint* ep, const uint8_t* data = NULL, int size = 0); |
va009039 |
18:61554f238584 | 262 | void multi_token_inNB(USBEndpoint* ep, uint8_t* data, int size); |
va009039 |
18:61554f238584 | 263 | USB_TYPE multi_token_inNB_result(USBEndpoint* ep); |
va009039 |
18:61554f238584 | 264 | void setToggle(USBEndpoint* ep, uint8_t toggle); |
va009039 |
18:61554f238584 | 265 | |
va009039 |
18:61554f238584 | 266 | // report |
va009039 |
18:61554f238584 | 267 | uint32_t m_report_irq; |
va009039 |
18:61554f238584 | 268 | uint32_t m_report_RHSC; |
va009039 |
18:61554f238584 | 269 | uint32_t m_report_FNO; |
va009039 |
18:61554f238584 | 270 | uint32_t m_report_WDH; |
va009039 |
18:61554f238584 | 271 | uint32_t m_report_sp; |
va009039 |
18:61554f238584 | 272 | |
va009039 |
18:61554f238584 | 273 | private: |
va009039 |
18:61554f238584 | 274 | void init_hw_ohci(HCCA* pHcca); |
va009039 |
18:61554f238584 | 275 | void ResetRootHub(); |
va009039 |
18:61554f238584 | 276 | void token_init(USBEndpoint* ep); |
va009039 |
18:61554f238584 | 277 | static void _usbisr(void); |
va009039 |
18:61554f238584 | 278 | void UsbIrqhandler(); |
va009039 |
18:61554f238584 | 279 | HCCA* m_pHcca; |
va009039 |
18:61554f238584 | 280 | bool wait_attach(); |
va009039 |
18:61554f238584 | 281 | bool root_lowSpeed; |
va009039 |
18:61554f238584 | 282 | static USBHALHost * instHost; |
va009039 |
18:61554f238584 | 283 | }; |
va009039 |
18:61554f238584 | 284 |