Simple USBHost library for Nucleo F446RE/F411RE/F401RE FRDM-KL46Z/KL25Z/F64F LPC4088/LPC1768
Dependents: F401RE-BTstack_example F401RE-USBHostMSD_HelloWorld
Fork of KL46Z-USBHost by
簡易USBホストライブラリです。
official-USBHostの下位互換で対応プログラムを僅かな修正で動かすことが出来ます。
Platforms
- Nucleo F446RE
- Nucleo F411RE
- Nucleo F401RE
- FRDM-K64F
- FRDM-KL46Z
- FRDM-KL25Z
- LPC4088
- LPC1768
Nucleo F446RE/F411RE/F401REのUSB接続方法
ST morpho | USB |
---|---|
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
Revision 10:40c7f6788902, committed 2014-02-05
- Comitter:
- va009039
- Date:
- Wed Feb 05 13:34:37 2014 +0000
- Parent:
- 9:7f9f64cf5ded
- Child:
- 11:61843badd06e
- Commit message:
- fix endpoint callback.
Changed in this revision
--- a/USBHost/USBDeviceConnected.cpp Mon Feb 03 13:00:16 2014 +0000 +++ b/USBHost/USBDeviceConnected.cpp Wed Feb 05 13:34:37 2014 +0000 @@ -22,51 +22,39 @@ } void USBDeviceConnected::init() { - hub_nb = 0; port = 0; vid = 0; pid = 0; nb_interf = 0; enumerated = false; - //activeAddr = false; - //sizeControlEndpoint = 8; device_class = 0; device_subclass = 0; proto = 0; lowSpeed = false; - intf.clear(); - //hub_parent = NULL; - //hub = NULL; + hub_parent = NULL; } bool USBDeviceConnected::addInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) { USB_DBG("intf_nb=%d", intf_nb); - INTERFACE* inter = intf.get(intf_nb); - if (inter) { - return false; + if (intf.count(intf_nb) > 0) { + return false; } - inter = new INTERFACE; - inter->in_use = true; - inter->intf_class = intf_class; - inter->intf_subclass = intf_subclass; - inter->intf_protocol = intf_protocol; - intf.put(intf_nb, inter); + intf[intf_nb] = new INTERFACE(intf_class, intf_subclass, intf_protocol); return true; } bool USBDeviceConnected::addEndpoint(uint8_t intf_nb, USBEndpoint * ept) { - INTERFACE* inter = intf.get(intf_nb); - if (inter == NULL) { - return false; - } - inter->ep.push(ept); - return true; + if (intf.count(intf_nb) > 0) { + intf[intf_nb]->ep.push_back(ept); + return true; + } + return false; } -void USBDeviceConnected::init(uint8_t hub_, uint8_t port_, bool lowSpeed_) { +void USBDeviceConnected::init(USBDeviceConnected* parent, uint8_t port_, bool lowSpeed_) { USB_DBG("init dev: %p", this); init(); - hub_nb = hub_; + hub_parent = parent; port = port_; lowSpeed = lowSpeed_; } @@ -81,14 +69,14 @@ USBEndpoint * USBDeviceConnected::getEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint8_t index) { USB_DBG("intf_nb=%d", intf_nb); - INTERFACE* inter = intf.get(intf_nb); - USB_TEST_ASSERT(inter); + USB_TEST_ASSERT(intf.count(intf_nb) > 0); + INTERFACE* inter = intf[intf_nb]; for (int i = 0; i < inter->ep.size(); i++) { - if ((inter->ep.at(i)->getType() == type) && (inter->ep.at(i)->getDir() == dir)) { + if ((inter->ep[i]->getType() == type) && (inter->ep[i]->getDir() == dir)) { if(index) { index--; } else { - return inter->ep.at(i); + return inter->ep[i]; } } } @@ -96,7 +84,6 @@ } USBEndpoint * USBDeviceConnected::getEndpoint(uint8_t intf_nb, uint8_t index) { - INTERFACE* inter = intf.get(intf_nb); - USB_TEST_ASSERT(inter); - return inter->ep.at(index); + USB_TEST_ASSERT(intf.count(intf_nb) > 0); + return intf[intf_nb]->ep[index]; }
--- a/USBHost/USBDeviceConnected.h Mon Feb 03 13:00:16 2014 +0000 +++ b/USBHost/USBDeviceConnected.h Wed Feb 05 13:34:37 2014 +0000 @@ -17,24 +17,21 @@ #include "USBEndpoint.h" #include "USBHostConf.h" -#include "myqueue.h" +#include "myvector.h" #include "mymap.h" class USBEndpoint; struct INTERFACE { - INTERFACE() { - in_use = false; - intf_class = 0; - intf_subclass = 0; - intf_protocol = 0; - ep.clear(); + INTERFACE(uint8_t _class, uint8_t _subclass, uint8_t _protocol) { + intf_class = _class; + intf_subclass = _subclass; + intf_protocol = _protocol; } - bool in_use; uint8_t intf_class; uint8_t intf_subclass; uint8_t intf_protocol; - myqueue<USBEndpoint*>ep; + myvector<USBEndpoint*>ep; }; /** @@ -93,7 +90,7 @@ */ void disconnect(); - void init(uint8_t hub, uint8_t _port, bool _lowSpeed); + void init(USBDeviceConnected* parent, uint8_t _port, bool _lowSpeed); void setAddress(uint8_t addr_) { addr = addr_; }; void setVid(uint16_t vid_) { vid = vid_; }; void setPid(uint16_t pid_) { pid = pid_; }; @@ -110,7 +107,6 @@ static int addr = 1; return addr++; } - uint8_t getHub() { return hub_nb; }; uint8_t getAddress() { return addr; }; uint16_t getVid() { return vid; }; uint16_t getPid() { return pid; }; @@ -120,8 +116,8 @@ USBEndpoint* getEpCtl() { return ep_ctl; } private: + USBDeviceConnected* hub_parent; mymap<int,INTERFACE*>intf; - uint8_t hub_nb; uint8_t port; uint16_t vid; uint16_t pid;
--- a/USBHost/USBEndpoint.h Mon Feb 03 13:00:16 2014 +0000 +++ b/USBHost/USBEndpoint.h Wed Feb 05 13:34:37 2014 +0000 @@ -29,8 +29,25 @@ /** * Constructor */ - USBEndpoint() : data01_toggle(DATA0),address(0),MaxPacketSize(8) { - dev = NULL; + USBEndpoint(USBDeviceConnected* _dev) { + init(CONTROL_ENDPOINT, IN, 8, 0); + dev = _dev; + } + + /** + * Initialize an endpoint + * + * @param type endpoint type + * @param dir endpoint direction + * @param size endpoint size + * @param ep_number endpoint number + */ + void init(ENDPOINT_TYPE _type, ENDPOINT_DIRECTION _dir, uint32_t size, uint8_t ep_number) { + type = _type; + dir = _dir; + MaxPacketSize = size; + address = ep_number; + data01_toggle = DATA0; } /** @@ -69,9 +86,8 @@ void setBuffer(uint8_t* buf, int size) { buf_start = buf, buf_size = size; } void setLengthTransferred(int len) { transferred = len; }; void setSize(int size) { MaxPacketSize = size; } - void setType(ENDPOINT_TYPE _type) { type = _type; }; - void setAddress(uint8_t addr) { address = addr; } void setData01(uint8_t data01) { data01_toggle = data01; } + void setNextEndpoint(USBEndpoint* ep) { nextEp = ep; }; USBDeviceConnected* getDevice() { return dev; } ENDPOINT_TYPE getType() { return type; }; @@ -80,11 +96,12 @@ int getBufSize() { return buf_size; } uint8_t getAddress(){ return address; }; int getSize() { return MaxPacketSize; } - ENDPOINT_DIRECTION getDir() { return (address & 0x80) ? IN : OUT; } + ENDPOINT_DIRECTION getDir() { return dir; } uint8_t getData01() { return data01_toggle; } void toggleData01() { data01_toggle = (data01_toggle == DATA0) ? DATA1 : DATA0; } + USBEndpoint* nextEndpoint() { return nextEp; }; private: ENDPOINT_TYPE type; @@ -92,12 +109,36 @@ USBDeviceConnected* dev; uint8_t data01_toggle; // DATA0,DATA1 uint8_t address; - int transferred; uint8_t * buf_start; int buf_size; - FunctionPointer rx; + int MaxPacketSize; + USBEndpoint* nextEp; +}; - int MaxPacketSize; +class EndpointQueue { +public: + EndpointQueue():head(NULL),tail(NULL) {} + void push(USBEndpoint* ep) { + if (head) { + tail->setNextEndpoint(ep); + } else { + head = ep; + } + tail = ep; + ep->setNextEndpoint(NULL); + } + USBEndpoint* pop() { + USBEndpoint* ep = head; + if (ep) { + head = ep->nextEndpoint(); + } + return ep; + } + bool empty() { return head == NULL; } + +private: + USBEndpoint* head; + USBEndpoint* tail; };
--- a/USBHost/USBHALHost.cpp Mon Feb 03 13:00:16 2014 +0000 +++ b/USBHost/USBHALHost.cpp Wed Feb 05 13:34:37 2014 +0000 @@ -129,7 +129,7 @@ USB_ERREN_DMAERREN_MASK| USB_ERREN_BTSERREN_MASK; - if (addDevice(0, 0, lowSpeed)) { + if (addDevice(NULL, 0, lowSpeed)) { break; } USB_DBG("retry=%d", retry);
--- a/USBHost/USBHALHost.h Mon Feb 03 13:00:16 2014 +0000 +++ b/USBHost/USBHALHost.h Wed Feb 05 13:34:37 2014 +0000 @@ -49,7 +49,7 @@ protected: USBHALHost(); void init(); - virtual bool addDevice(int port, int hub, bool lowSpeed) = 0; + virtual bool addDevice(USBDeviceConnected* parent, int port, bool lowSpeed) = 0; void setAddr(int addr, bool lowSpeed = false); void setEndpoint(); void token_transfer_init();
--- a/USBHost/USBHost.cpp Mon Feb 03 13:00:16 2014 +0000 +++ b/USBHost/USBHost.cpp Wed Feb 05 13:34:37 2014 +0000 @@ -23,11 +23,10 @@ USBHost::USBHost() { } -/* virtual */ bool USBHost::addDevice(int hub, int port, bool lowSpeed) { +/* virtual */ bool USBHost::addDevice(USBDeviceConnected* parent, int port, bool lowSpeed) { USBDeviceConnected* dev = new USBDeviceConnected; - USBEndpoint* ep = new USBEndpoint; - ep->setDevice(dev); - dev->init(hub, port, lowSpeed); + USBEndpoint* ep = new USBEndpoint(dev); + dev->init(0, port, lowSpeed); dev->setAddress(0); dev->setEpCtl(ep); uint8_t desc[18]; @@ -35,6 +34,9 @@ int rc = controlRead(dev, 0x80, GET_DESCRIPTOR, 1<<8, 0, desc, 8); USB_TEST_ASSERT(rc == USB_TYPE_OK); + if (rc != USB_TYPE_OK) { + USB_ERR("ADD DEVICE FAILD"); + } USB_DBG_HEX(desc, 8); DeviceDescriptor* dev_desc = reinterpret_cast<DeviceDescriptor*>(desc); ep->setSize(dev_desc->bMaxPacketSize); @@ -52,11 +54,11 @@ dev->setVid(dev_desc->idVendor); dev->setPid(dev_desc->idProduct); dev->setClass(dev_desc->bDeviceClass); - USB_INFO("hub: %d port: %d speed: %s vid: %04x pid: %04x class: %02x addr: %d", - hub, port, (lowSpeed ? "low " : "full"), dev->getVid(), dev->getPid(), dev->getClass(), + USB_INFO("parent:%p port:%d speed:%s VID:%04x PID:%04x class:%02x addr:%d", + parent, port, (lowSpeed ? "low " : "full"), dev->getVid(), dev->getPid(), dev->getClass(), dev->getAddress()); - DeviceLists.push(dev); + DeviceLists.push_back(dev); if (dev->getClass() == HUB_CLASS) { const int config = 1; @@ -105,7 +107,7 @@ int config = 1; USB_TYPE res = controlWrite(dev, 0x00, SET_CONFIGURATION, config, 0, NULL, 0); if (res != USB_TYPE_OK) { - USB_DBG("SET CONF FAILED"); + USB_ERR("SET CONF FAILED"); return res; } // Some devices may require this delay @@ -155,11 +157,8 @@ ENDPOINT_TYPE type = (ENDPOINT_TYPE)(ep_desc->bmAttributes & 0x03); ENDPOINT_DIRECTION dir = (ep_desc->bEndpointAddress & 0x80) ? IN : OUT; if(pEnumerator->useEndpoint(current_intf, type, dir)) { - ep = new USBEndpoint; - ep->setDevice(dev); - ep->setType(type); - ep->setAddress(ep_desc->bEndpointAddress); - ep->setSize(ep_desc->wMaxPacketSize); + ep = new USBEndpoint(dev); + ep->init(type, dir, ep_desc->wMaxPacketSize, ep_desc->bEndpointAddress); USB_DBG("ADD USBEndpoint %p, on interf %d on device %p", ep, current_intf, dev); dev->addEndpoint(current_intf, ep); } @@ -195,7 +194,6 @@ USB_TYPE USBHost::bulkRead(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) { if (blocking == false) { - ep->setType(BULK_ENDPOINT); ep->setBuffer(buf, len); ep_queue.push(ep); return USB_TYPE_PROCESSING; @@ -220,7 +218,6 @@ USB_TYPE USBHost::interruptRead(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) { if (blocking == false) { - ep->setType(INTERRUPT_ENDPOINT); ep->setBuffer(buf, len); ep_queue.push(ep); return USB_TYPE_PROCESSING; @@ -237,7 +234,6 @@ USB_TYPE USBHost::isochronousRead(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) { if (blocking == false) { - ep->setType(ISOCHRONOUS_ENDPOINT); ep->setBuffer(buf, len); ep_queue.push(ep); return USB_TYPE_PROCESSING;
--- a/USBHost/USBHost.h Mon Feb 03 13:00:16 2014 +0000 +++ b/USBHost/USBHost.h Wed Feb 05 13:34:37 2014 +0000 @@ -1,4 +1,19 @@ -// Simple USBHost for FRDM-KL46Z +/* mbed USBHost Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #pragma once #include "mbed.h" #include "USBHALHost.h" @@ -6,8 +21,12 @@ #include "IUSBEnumerator.h" #include "USBHostConf.h" #include "dbg.h" -#include "myqueue.h" +#include "myvector.h" +/** +* USBHost class +* This class is a singleton. All drivers have a reference on the static USBHost instance +*/ class USBHost : public USBHALHost { public: /** @@ -127,7 +146,7 @@ * @returns pointer on the "index" device */ USBDeviceConnected * getDevice(uint8_t index) { - return DeviceLists.empty() ? NULL : DeviceLists.at(index); + return index < DeviceLists.size() ? DeviceLists[index] : NULL; } /** @@ -153,16 +172,16 @@ private: USBHost(); static USBHost* inst; - virtual bool addDevice(int hub, int port, bool lowSpeed); + virtual bool addDevice(USBDeviceConnected* parent, int port, bool lowSpeed); void root_enumeration(USBDeviceConnected* dev); void parseConfDescr(USBDeviceConnected* dev, uint8_t* conf_descr, uint32_t len, IUSBEnumerator* pEnumerator); - myqueue<USBDeviceConnected*>DeviceLists; + myvector<USBDeviceConnected*>DeviceLists; int ControlRead(USBDeviceConnected* dev, SETUP_PACKET* setup, uint8_t* data, int size); int ControlWrite(USBDeviceConnected* dev, SETUP_PACKET* setup, uint8_t* data = NULL, int size = 0); int bulkReadBLOCK(USBEndpoint*ep, uint8_t* data, int size, int timeout_ms); void task(); - myqueue<USBEndpoint*>ep_queue; + EndpointQueue ep_queue; // USB HUB bool Hub(USBDeviceConnected* dev);
--- a/USBHost/USBHostHub.cpp Mon Feb 03 13:00:16 2014 +0000 +++ b/USBHost/USBHostHub.cpp Wed Feb 05 13:34:37 2014 +0000 @@ -15,6 +15,7 @@ #define C_PORT_RESET 20 bool USBHost::Hub(USBDeviceConnected* dev) { + USB_INFO("New HUB: VID:%04x PID:%04x [dev: %p]", dev->getVid(), dev->getPid(), dev); HubDescriptor hubdesc; // get HUB descriptor int rc = controlRead(dev, @@ -51,7 +52,7 @@ lowSpeed = 1; } PortReset(dev, i); - if (!addDevice(1, i, lowSpeed)) { + if (!addDevice(dev, i, lowSpeed)) { ClearPortPower(dev, i); // power off } } else {
--- a/USBHost/mymap.h Mon Feb 03 13:00:16 2014 +0000 +++ b/USBHost/mymap.h Wed Feb 05 13:34:37 2014 +0000 @@ -3,51 +3,63 @@ template<class K,class T> class mymap { struct mypair { - K key; - T value; + K first; + T second; }; public: mymap() { m_size = 0; - m_limit = 4; - m_buf = new mypair[m_limit]; } - void put(K key, T value) { - int i = find(key); - if (i == (-1)) { - if (m_size >= m_limit) { - int new_limit = m_limit + 4; - mypair* new_buf = new mypair[new_limit]; - for(int i = 0; i < m_size; i++) { - new_buf[i] = m_buf[i]; - } - delete[] m_buf; - m_buf = new_buf; - m_limit = new_limit; - } - i = m_size++; - m_buf[i].key = key; + T& operator[](const K& key) { + int it; + if (count(key) == 0) { + it = insert(key, 0); + } else { + it = find(key); } - m_buf[i].value = value; - } - T get(K key) { - int i = find(key); - return (i == -1) ? NULL : m_buf[i].value; + return m_buf[it].second; } bool empty() { return m_size == 0 ? true : false; } int size() { return m_size; } void clear() { m_size = 0; } + int count(K key) { + for(int i = 0; i < m_size; i++) { + if (m_buf[i].first == key) { + return 1; + } + } + return 0; + } private: int find(K key) { for(int i = 0; i < m_size; i++) { - if (m_buf[i].key == key) { + if (m_buf[i].first == key) { return i; } } return -1; } - int m_limit; + int insert(K key, T value) { + int it = find(key); + if (it != -1) { + m_buf[it].second = value; + return it; + } + mypair* new_buf = new mypair[m_size+1]; + if (m_size > 0) { + for(int i = 0; i < m_size; i++) { + new_buf[i] = m_buf[i]; + } + delete[] m_buf; + } + m_buf = new_buf; + it = m_size++; + m_buf[it].first = key; + m_buf[it].second = value; + return it; + } + int m_size; mypair *m_buf; };
--- a/USBHost/myqueue.h Mon Feb 03 13:00:16 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -#pragma once - -template<class T> -class myqueue { -public: - myqueue() { - m_w = m_r = 0; - m_size = 0; - m_limit = 4; - m_buf = new T[m_limit]; - } - void push(T v) { - if (m_size >= m_limit) { - int new_limit = m_limit + 4; - T* new_buf = new T[new_limit]; - for(int i = 0; i < m_size; i++) { - new_buf[i] = m_buf[i]; - } - delete[] m_buf; - m_buf = new_buf; - m_limit = new_limit; - } - m_buf[m_w++] = v; - if (m_w >= m_limit) { - m_w = 0; - } - m_size++; - } - T pop() { - T v = m_buf[m_r++]; - if (m_r >= m_limit) { - m_r = 0; - } - m_size--; - return v; - } - bool empty() { return (m_w == m_r) ? true : false; } - int size() { return m_size; } - void clear() { m_size = 0; } - T at(int i) { return m_buf[i]; } - -private: - int m_limit; - int m_size; - int m_w; - int m_r; - T *m_buf; -};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBHost/myvector.h Wed Feb 05 13:34:37 2014 +0000 @@ -0,0 +1,29 @@ +#pragma once + +template<class T> +class myvector { +public: + myvector() { + m_size = 0; + m_buf = NULL; + } + void push_back(T v) { + T* new_buf = new T[m_size+1]; + if (m_size > 0) { + for(int i = 0; i < m_size; i++) { + new_buf[i] = m_buf[i]; + } + delete[] m_buf; + } + m_buf = new_buf; + m_buf[m_size++] = v; + } + T& operator[](const int index) { + return m_buf[index]; + } + int size() { return m_size; } + +private: + int m_size; + T *m_buf; +};