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 Norimasa Okamoto

Committer:
va009039
Date:
Tue Jul 01 18:33:31 2014 +0900
Revision:
18:61554f238584
add lpc4088/lpc1768

Who changed what in which revision?

UserRevisionLine numberNew 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