USB host library, support isochronous,bulk,interrupt and control.
Dependents: BaseUsbHost_example BaseJpegDecode_example SimpleJpegDecode_example
Import programBaseUsbHost_example
BaseUsbHost example program
Diff: BaseUsbHost.h
- Revision:
- 3:ae77d63a1eda
- Parent:
- 2:fe1e62051d88
- Child:
- 4:d931d24c2f81
--- a/BaseUsbHost.h Tue Dec 11 15:26:54 2012 +0000 +++ b/BaseUsbHost.h Sun Jan 06 11:45:18 2013 +0000 @@ -1,11 +1,13 @@ -// BaseUsbHost.h 2012/12/11 -#ifndef BASE_USB_HOST_H -#define BASE_USB_HOST_H +// BaseUsbHost.h 2013/1/5 +#pragma once +#include <vector> #define USB_OK 0 #define USB_PROCESSING -1 #define USB_ERROR -2 #define USB_ERROR_MEMORY -3 +#define USB_ERROR_STALL -4 +#define USB_ERROR_DEVICE_NOT_RESPONDING -5 // USB STANDARD REQUEST DEFINITIONS #define USB_DESCRIPTOR_TYPE_DEVICE 1 @@ -29,6 +31,69 @@ #define GET_DESCRIPTOR 6 #define SET_CONFIGURATION 9 #define SET_INTERFACE 11 + +#pragma pack(push,1) +typedef struct { // offset + uint8_t bLength; // +0 + uint8_t bDescriptorType; // +1 + uint16_t bcdUSB; // +2 + uint8_t bDeviceClass; // +4 + uint8_t bDeviceSubClass; // +5 + uint8_t bDeviceProtocol; // +6 + uint8_t bMaxPacketSize; // +7 + uint16_t idVendor; // +8 + uint16_t idProduct; // +10 + uint16_t bcdDevice; // +12 + uint8_t iManufacturer; // +14 + uint8_t iProduct; // +15 + uint8_t iSerialNumber; // +16 + uint8_t bNumConfigurations; // +17 +} StandardDeviceDescriptor; // +18 + +typedef struct { // offset + uint8_t bLength; // +0 + uint8_t bDescriptorType; // +1 + uint16_t wTotalLength; // +2 + uint8_t bNumInterfaces; // +4 + uint8_t bConfigurationValue; // +5 + uint8_t iConfiguration; // +6 + uint8_t bmAttributes; // +7 + uint8_t bMaxPower; // +8 +} StandardConfigurationDescriptor; // +9 + +typedef struct { // offset + uint8_t bLength; // +0 + uint8_t bDescriptorType; // +1 + uint8_t bInterfaceNumber; // +2 + uint8_t bAlternateSetting; // +3 + uint8_t bNumEndpoints; // +4 + uint8_t bInterfaceClass; // +5 + uint8_t bInterfaceSubClass;// +6 + uint8_t bInterfaceProtocol;// +7 + uint8_t iInterface; // +8 +} StandardInterfaceDescriptor; // +9 + +typedef struct { // offset + uint8_t bLength; // +0 + uint8_t bDescriptorType; // +1 + uint8_t bEndpointAddress; // +2 + uint8_t bmAttributes; // +3 + uint16_t wMaxPacketSize; // +4 + uint8_t bInterval; // +6 +} StandardEndpointDescriptor; // +7 + +typedef struct { // offset + uint8_t bDescLength; // +0 + uint8_t bDescriptorType; // +1 + uint8_t bNbrPorts; // +2 + uint16_t wHubCharacteristics;// +3 + uint8_t bPwrOn2PwrGood; // +5 + uint8_t bHubContrCurrent; // +6 + uint8_t DeviceRemovable; // +7 + uint8_t PortPweCtrlMak; // +8 +} HubDescriptor; // +9 +#pragma pack(pop) + // ------------------ HcControl Register --------------------- #define OR_CONTROL_PLE 0x00000004 #define OR_CONTROL_IE 0x00000008 @@ -109,22 +174,20 @@ uint32_t Next; // +12 Physical address of next Endpoint descriptor } HCED; -#define DELETE_TD(A) free(A) -#define DELETE_ITD(A) free(A) - class BaseUsbHost { public: BaseUsbHost(); - void init_hw_ohci(HCCA* pHcca); - void ResetRootHub(); void irqHandler(); - HCCA* m_pHcca; // report uint32_t m_report_irq; uint32_t m_report_RHSC; uint32_t m_report_FNO; uint32_t m_report_WDH; uint32_t m_report_sp; +private: + void init_hw_ohci(HCCA* pHcca); + void ResetRootHub(); + HCCA* m_pHcca; }; #define HCTD_QUEUE_SIZE 3 @@ -136,25 +199,28 @@ int GetLowSpeed(); void update_FunctionAddress(int addr); void update_MaxPacketSize(uint16_t size); + int transfer(uint8_t* buf, int len); + int status(uint32_t millisec=osWaitForever); // + virtual void enable() = 0; HCTD* new_HCTD(int buf_size=0); void delete_HCTD(HCTD* p); - HCED* m_pED; - // TD done queue - virtual void irqWdhHandler(HCTD* td) = 0; // WDH - HCTD* get_queue_HCTD(uint32_t millisec=osWaitForever); + virtual void irqWdhHandler(HCTD* td) {m_queue.put(td);} // WDH int wait_queue_HCTD(HCTD* wait_td, uint32_t millisec=osWaitForever); - Queue<HCTD, HCTD_QUEUE_SIZE> m_queue; - int m_td_queue_count; // report uint8_t m_ConditionCode; int m_report_queue_error; +protected: + int send_receive(uint8_t* buf, int len, int millisec); + HCTD* get_queue_HCTD(uint32_t millisec=osWaitForever); + HCED* m_pED; + Queue<HCTD, HCTD_QUEUE_SIZE> m_queue; // TD done queue + int m_td_queue_count; }; class ControlEp : public BaseEp { public: ControlEp(int lowSpeed = 0); - virtual void irqWdhHandler(HCTD* td) {m_queue.put(td);} int GetDescriptor(int descType, int descIndex, uint8_t* data, int length); int SetAddress(int addr); // device address int SetConfiguration(int config); @@ -163,59 +229,60 @@ int GetInterface(int interface, int *alternate); int controlSend(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex=0, const uint8_t* data=NULL, int length=0); int controlReceive(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t* data, int length); - // +private: int open(int addr); void setup(HCTD* td, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex=0, uint16_t wLength=0); + virtual void enable(){}; }; class BulkEp : public BaseEp { public: BulkEp(int addr, uint8_t ep, uint16_t size); - virtual void irqWdhHandler(HCTD* td) {m_queue.put(td);} int bulkSend(const uint8_t* buf, int len, int millisec=osWaitForever); int bulkReceive(uint8_t* buf, int len, int millisec=osWaitForever); +private: + virtual void enable(); }; class InterruptEp : public BaseEp { public: InterruptEp(int addr, uint8_t ep, uint16_t size, int lowSpeed=0); int interruptReceive(uint8_t* buf, int len, int millisec=osWaitForever); - virtual void irqWdhHandler(HCTD* td) {m_queue.put(td);} +private: + virtual void enable(); }; class IsochronousEp : public BaseEp { public: IsochronousEp(int addr, uint8_t ep, uint16_t size); - virtual void irqWdhHandler(HCTD* td); - void reset(); + void reset(int delay_ms = 100); HCITD* isochronousReveive(int millisec=osWaitForever); int isochronousSend(uint8_t* buf, int len, int millisec=osWaitForever); + HCITD* get_queue_HCITD(int millisec); + int m_PacketSize; // 128,192 +private: HCITD* new_HCITD(); - HCITD* get_queue_HCITD(int millisec); int m_itd_queue_count; uint16_t m_FrameNumber; - int m_PacketSize; // 128,192 int m_FrameCount; // 1-8 + virtual void enable(); }; // --- HUB -------------------------------------------------- -#define MAX_HUB_PORT 4 - class UsbHub { public: UsbHub(ControlEp* ctlEp = NULL); - ControlEp* GetPortEp(int port); // port: 1-4 + static bool check(ControlEp* ctlEp); int SetPortPower(int port); int ClearPortPower(int port); -protected: - void DeviceConnected(int port, int low_speed); + vector<ControlEp*> PortEp; +private: int PortReset(int port); int SetPortFeature(int feature, int index); int ClearPortFeature(int feature, int index); int SetPortReset(int port); int GetPortStatus(int port, uint32_t* status); ControlEp* m_ctlEp; - ControlEp* PortEp[MAX_HUB_PORT]; // port endpoint(control) }; // --- UVC -------------------------------------------------- @@ -263,5 +330,3 @@ void (CDummy::*m_pCbMeth)(uint16_t, uint8_t*, int); void (*m_pCb)(uint16_t, uint8_t*, int); }; - -#endif //BASE_USB_HOST_H