Simple USBHost library for LPC4088. Backward compatibility of official-USBHost.

Dependencies:   FATFileSystem mbed-rtos

EA LPC4088 QSB専用の簡易USBホストライブラリです。
official-USBHostの下位互換で対応プログラムを僅かな修正で動かすことが出来ます。
examples:

Import programLPC4088-USBHostMSD_HelloWorld

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

Import programLPC4088-BTstack_example

BTstack for EA LPC4088 QSB example program

Import programLPC4088-USBHostC270_example

Simple USBHost WebCam for EA LPC4088 QSB/LPC1768 test program

Committer:
va009039
Date:
Fri Apr 25 05:18:55 2014 +0000
Revision:
0:148fca6fd246
first commit

Who changed what in which revision?

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