Simple USBHost library for Nucleo F446RE/F411RE/F401RE FRDM-KL46Z/KL25Z/F64F LPC4088/LPC1768

Dependencies:   FATFileSystem

Dependents:   F401RE-BTstack_example F401RE-USBHostMSD_HelloWorld

Fork of KL46Z-USBHost by Norimasa Okamoto

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

Platforms

  • Nucleo F446RE
  • Nucleo F411RE
  • Nucleo F401RE
  • FRDM-K64F
  • FRDM-KL46Z
  • FRDM-KL25Z
  • LPC4088
  • LPC1768

Nucleo F446RE/F411RE/F401REのUSB接続方法

ST morphoUSB
U5V (CN10-8)VBUS (1 RED)
PA11 (CN10-14)DM  (2 WHITE)
PA12 (CN10-12)DP  (3 GREEN)
GND (CN10-20)GND (4 BLACK)

Examples

Import programF446RE-USBHostMouse_HelloWorld

USBHostMouse Hello World for ST-Nucleo-F446RE

Import programF401RE-USBHostMSD_HelloWorld

Simple USBHost MSD(USB flash drive) for Nucleo F401RE/FRDM-KL46Z test program

Import programF401RE-USBHostC270_example

Simple USBHost WebCam test program

Import programK64F_USBHostC270_example

Simple USBHost C270 example

Import programF401RE-BTstack_example

BTstack for Nucleo F401RE/FRDM-KL46Z example program

Import programUSBHostRSSI_example

Bluetooth device discovery example program.

Import programKL46Z-USBHostGPS_HelloWorld

Simple USBHost GPS Dongle Receiver for FRDM-KL46Z test program

Committer:
va009039
Date:
Sun May 01 03:18:11 2016 +0000
Revision:
23:4ab8bc835303
Parent:
18:61554f238584
add ST-Nucleo-F446RE

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