forked for unsupported target
Dependents: stm32-disco-example DISCO-F469NI_BD_SD_Card_Control
Fork of USBHOST by
Diff: USBHost/USBHost.h
- Revision:
- 1:ab240722d7ef
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBHost/USBHost.h Wed Feb 15 10:49:44 2017 +0100 @@ -0,0 +1,396 @@ +/* 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. + */ + +#ifndef USBHOST_H +#define USBHOST_H +#ifdef TARGET_STM +#include "mbed.h" +#endif +#include "USBHALHost.h" +#include "USBDeviceConnected.h" +#include "IUSBEnumerator.h" +#include "USBHostConf.h" +#include "rtos.h" +#include "dbg.h" +#include "USBHostHub.h" + +/** +* USBHost class +* This class is a singleton. All drivers have a reference on the static USBHost instance +*/ +class USBHost : public USBHALHost { +public: + /** + * Static method to create or retrieve the single USBHost instance + */ + static USBHost * getHostInst(); + + /** + * Control read: setup stage, data stage and status stage + * + * @param dev the control read will be done for this device + * @param requestType request type + * @param request request + * @param value value + * @param index index + * @param buf pointer on a buffer where will be store the data received + * @param len length of the transfer + * + * @returns status of the control read + */ + USB_TYPE controlRead(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len); + + /** + * Control write: setup stage, data stage and status stage + * + * @param dev the control write will be done for this device + * @param requestType request type + * @param request request + * @param value value + * @param index index + * @param buf pointer on a buffer which will be written + * @param len length of the transfer + * + * @returns status of the control write + */ + USB_TYPE controlWrite(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len); + + /** + * Bulk read + * + * @param dev the bulk transfer will be done for this device + * @param ep USBEndpoint which will be used to read a packet + * @param buf pointer on a buffer where will be store the data received + * @param len length of the transfer + * @param blocking if true, the read is blocking (wait for completion) + * + * @returns status of the bulk read + */ + USB_TYPE bulkRead(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true); + + /** + * Bulk write + * + * @param dev the bulk transfer will be done for this device + * @param ep USBEndpoint which will be used to write a packet + * @param buf pointer on a buffer which will be written + * @param len length of the transfer + * @param blocking if true, the write is blocking (wait for completion) + * + * @returns status of the bulk write + */ + USB_TYPE bulkWrite(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true); + + /** + * Interrupt read + * + * @param dev the bulk transfer will be done for this device + * @param ep USBEndpoint which will be used to write a packet + * @param buf pointer on a buffer which will be written + * @param len length of the transfer + * @param blocking if true, the read is blocking (wait for completion) + * + * @returns status of the interrupt read + */ + USB_TYPE interruptRead(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true); + + /** + * Interrupt write + * + * @param dev the bulk transfer will be done for this device + * @param ep USBEndpoint which will be used to write a packet + * @param buf pointer on a buffer which will be written + * @param len length of the transfer + * @param blocking if true, the write is blocking (wait for completion) + * + * @returns status of the interrupt write + */ + USB_TYPE interruptWrite(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true); + + /** + * Enumerate a device. + * + * @param dev device which will be enumerated + * + * @returns status of the enumeration + */ + USB_TYPE enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerator); + + /** + * reset a specific device + * + * @param dev device which will be resetted + */ + USB_TYPE resetDevice(USBDeviceConnected * dev); + + /** + * Get a device + * + * @param index index of the device which will be returned + * + * @returns pointer on the "index" device + */ + USBDeviceConnected * getDevice(uint8_t index); + + /* + * If there is a HID device connected, the host stores the length of the report descriptor. + * This avoid to the driver to re-ask the configuration descriptor to request the report descriptor + * + * @returns length of the report descriptor + */ + inline uint16_t getLengthReportDescr() { + return lenReportDescr; + }; + + /** + * register a driver into the host associated with a callback function called when the device is disconnected + * + * @param dev device + * @param intf interface number + * @param tptr pointer to the object to call the member function on + * @param mptr pointer to the member function to be called + */ + template<typename T> + inline void registerDriver(USBDeviceConnected * dev, uint8_t intf, T* tptr, void (T::*mptr)(void)) { + int index = findDevice(dev); + if ((index != -1) && (mptr != NULL) && (tptr != NULL)) { + USB_DBG("register driver for dev: %p on intf: %d", dev, intf); + deviceAttachedDriver[index][intf] = true; + dev->onDisconnect(intf, tptr, mptr); + } + } + + /** + * register a driver into the host associated with a callback function called when the device is disconnected + * + * @param dev device + * @param intf interface number + * @param fn callback called when the specified device has been disconnected + */ + inline void registerDriver(USBDeviceConnected * dev, uint8_t intf, void (*fn)(void)) { + int index = findDevice(dev); + if ((index != -1) && (fn != NULL)) { + USB_DBG("register driver for dev: %p on intf: %d", dev, intf); + deviceAttachedDriver[index][intf] = true; + dev->onDisconnect(intf, fn); + } + } + + /** + * Instantiate to protect USB thread from accessing shared objects (USBConnectedDevices and Interfaces) + */ + class Lock + { + public: + Lock(USBHost* pHost); + ~Lock(); + private: + USBHost* m_pHost; + }; + + friend class USBHostHub; + +protected: + + /** + * Virtual method called when a transfer has been completed + * + * @param addr list of the TDs which have been completed + */ + virtual void transferCompleted(volatile uint32_t addr); + + /** + * Virtual method called when a device has been connected + * + * @param hub hub number of the device + * @param port port number of the device + * @param lowSpeed 1 if low speed, 0 otherwise + * @param hub_parent reference on the parent hub + */ + virtual void deviceConnected(int hub, int port, bool lowSpeed, USBHostHub * hub_parent = NULL); + + /** + * Virtuel method called when a device has been disconnected + * + * @param hub hub number of the device + * @param port port number of the device + * @param addr list of the TDs which have been completed to dequeue freed TDs + */ + virtual void deviceDisconnected(int hub, int port, USBHostHub * hub_parent, volatile uint32_t addr); + + +private: + // singleton class -> constructor is private + USBHost(); + static USBHost * instHost; + uint16_t lenReportDescr; + + // endpoints + void unqueueEndpoint(USBEndpoint * ep) ; + USBEndpoint endpoints[MAX_ENDPOINT]; + USBEndpoint* volatile control; + + USBEndpoint* volatile headControlEndpoint; + USBEndpoint* volatile headBulkEndpoint; + USBEndpoint* volatile headInterruptEndpoint; + + USBEndpoint* volatile tailControlEndpoint; + USBEndpoint* volatile tailBulkEndpoint; + USBEndpoint* volatile tailInterruptEndpoint; + + bool controlEndpointAllocated; + + // devices connected + USBDeviceConnected devices[MAX_DEVICE_CONNECTED]; + bool deviceInUse[MAX_DEVICE_CONNECTED]; + bool deviceAttachedDriver[MAX_DEVICE_CONNECTED][MAX_INTF]; + bool deviceReset[MAX_DEVICE_CONNECTED]; + bool deviceInited[MAX_DEVICE_CONNECTED]; + +#if MAX_HUB_NB + USBHostHub hubs[MAX_HUB_NB]; + bool hub_in_use[MAX_HUB_NB]; +#endif + + // to store a setup packet + uint8_t setupPacket[8]; + + typedef struct { + uint8_t event_id; + void * td_addr; + uint8_t hub; + uint8_t port; + uint8_t lowSpeed; + uint8_t td_state; + void * hub_parent; + } message_t; + + Thread usbThread; + void usb_process(); + Mail<message_t, 10> mail_usb_event; + Mutex usb_mutex; + Mutex td_mutex; + + // buffer for conf descriptor + uint8_t data[415]; + + /** + * Add a transfer on the TD linked list associated to an ED + * + * @param ed the transfer is associated to this ed + * @param buf pointer on a buffer where will be read/write data to send or receive + * @param len transfer length + * + * @return status of the transfer + */ + USB_TYPE addTransfer(USBEndpoint * ed, uint8_t * buf, uint32_t len) ; + + /** + * Link the USBEndpoint to the linked list and attach an USBEndpoint this USBEndpoint to a device + * + * @param dev pointer on a USBDeviceConnected object + * @param ep pointer on the USBEndpoint which will be added + * + * return true if successful + */ + bool addEndpoint(USBDeviceConnected * dev, uint8_t intf_nb, USBEndpoint * ep) ; + + /** + * Create an USBEndpoint descriptor. Warning: the USBEndpoint is not linked. + * + * @param type USBEndpoint type (CONTROL_ENDPOINT, BULK_ENDPOINT, INTERRUPT_ENDPOINT) + * @param dir USBEndpoint direction (no meaning for CONTROL_ENDPOINT) + * @param size USBEndpoint max packet size + * @param addr USBEndpoint address + * + * @returns pointer on the USBEndpoint created + */ + USBEndpoint * newEndpoint(ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint32_t size, uint8_t addr) ; + + /** + * Request the device descriptor + * + * @param dev request the device descriptor on this device + * @param buf buffer to store the device descriptor + * @param max_len_buf maximum size of buf + * @param len_dev_descr pointer to store the length of the packet transferred + */ + USB_TYPE getDeviceDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_dev_descr = NULL); + + /** + * Request the configuration descriptor + * + * @param dev request the configuration descriptor on this device + * @param buf buffer to store the configuration descriptor + * @param max_len_buf maximum size of buf + * @param len_conf_descr pointer to store the length of the packet transferred + */ + USB_TYPE getConfigurationDescriptor(USBDeviceConnected * dev, uint8_t * buf, uint16_t max_len_buf, uint16_t * len_conf_descr = NULL); + + /** + * Set the address of a specific device + * + * @param dev device to set the address + * @param address address + */ + USB_TYPE setAddress(USBDeviceConnected * dev, uint8_t address); + + /** + * Set the configuration of a device + * + * @param dev device on which the specified configuration will be activated + * @param conf configuration number to activate (usually 1) + */ + USB_TYPE setConfiguration(USBDeviceConnected * dev, uint8_t conf); + + /** + * Free a specific device + * + * @param dev device to be freed + */ + void freeDevice(USBDeviceConnected * dev); + + USB_TYPE controlTransfer( USBDeviceConnected * dev, + uint8_t requestType, + uint8_t request, + uint32_t value, + uint32_t index, + uint8_t * buf, + uint32_t len, + bool write); + + USB_TYPE generalTransfer( USBDeviceConnected * dev, + USBEndpoint * ep, + uint8_t * buf, + uint32_t len, + bool blocking, + ENDPOINT_TYPE type, + bool write) ; + + void fillControlBuf(uint8_t requestType, uint8_t request, uint16_t value, uint16_t index, int len) ; + void parseConfDescr(USBDeviceConnected * dev, uint8_t * conf_descr, uint32_t len, IUSBEnumerator* pEnumerator) ; + int findDevice(USBDeviceConnected * dev) ; + int findDevice(uint8_t hub, uint8_t port, USBHostHub * hub_parent = NULL) ; + uint8_t numberDriverAttached(USBDeviceConnected * dev); + + ///////////////////////// + /// FOR DEBUG + ///////////////////////// + void printList(ENDPOINT_TYPE type); + +}; + +#endif