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