Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: GR-PEACH_HVC-P2_sample_client mbed-os-storage-access GR-PEACH_Digital_Signage GR-PEACH_Audio_Playback_Sample ... more
Fork of USBHost by
USBHost/USBHost.h
- Committer:
- mbed_official
- Date:
- 2013-03-06
- Revision:
- 0:a554658735bf
- Child:
- 4:b320d68e98e7
File content as of revision 0:a554658735bf:
/* Copyright (c) 2010-2012 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef USBHOST_H
#define USBHOST_H
#include "USBHALHost.h"
#include "USBDeviceConnected.h"
#include "IUSBEnumerator.h"
#include "USBHostConf.h"
#include "rtos.h"
#include "dbg.h"
#include "USBHostHub.h"
// singleton class
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);
/**
* Get a device
*
* @param index index of the device which will be returned
*
* @returns pointer on the "index" device
*/
USBDeviceConnected * getDevice(uint8_t index);
/*
* reset a specific device
*
* @param dev device which will be resetted
*/
USB_TYPE resetDevice(USBDeviceConnected * dev);
/**
* 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 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", dev);
deviceAttachedDriver[index] = 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 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", dev);
deviceAttachedDriver[index] = true;
dev->onDisconnect(intf, fn);
}
}
/**
* 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);
/**
* Free a specific device
*
* @param dev device to be freed
*/
void freeDevice(USBDeviceConnected * dev);
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) ;
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];
volatile bool deviceInUse[MAX_DEVICE_CONNECTED];
volatile bool deviceAttachedDriver[MAX_DEVICE_CONNECTED];
volatile bool deviceReset[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();
static void usb_process_static(void const * arg);
MemoryPool<message_t, 10> mpool_usb_event;
Queue<message_t, 10> queue_usb_event;
Mutex usb_mutex;
// buffer for conf descriptor
uint8_t data[400];
/**
* 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);
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) ;
/////////////////////////
/// FOR DEBUG
/////////////////////////
void printList(ENDPOINT_TYPE type);
};
#endif
