USB host library, support isochronous,bulk,interrupt and control.

Dependents:   BaseUsbHost_example BaseJpegDecode_example SimpleJpegDecode_example

Import programBaseUsbHost_example

BaseUsbHost example program

Revision:
0:b7d6879637a8
Child:
1:3b7bc4f87a61
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BaseUsbHost.h	Tue Dec 04 13:29:41 2012 +0000
@@ -0,0 +1,222 @@
+// BaseUsbHost.h 2012/12/4
+#ifndef BASE_USB_HOST_H
+#define BASE_USB_HOST_H
+
+#define USB_OK       0
+#define USB_ERROR   -1
+#define USB_TIMEOUT -2
+#define USB_ERROR2  -3
+
+// USB STANDARD REQUEST DEFINITIONS
+#define  USB_DESCRIPTOR_TYPE_DEVICE         1
+#define  USB_DESCRIPTOR_TYPE_CONFIGURATION  2
+#define  USB_DESCRIPTOR_TYPE_STRING         3
+#define  USB_DESCRIPTOR_TYPE_INTERFACE      4
+#define  USB_DESCRIPTOR_TYPE_ENDPOINT       5
+#define  USB_DESCRIPTOR_TYPE_HUB         0x29
+// ----------- Control RequestType Fields  -----------
+#define  USB_DEVICE_TO_HOST      0x80
+#define  USB_HOST_TO_DEVICE      0x00
+#define  USB_REQUEST_TYPE_CLASS  0x20
+#define  USB_RECIPIENT_DEVICE    0x00
+#define  USB_RECIPIENT_INTERFACE 0x01
+#define  USB_RECIPIENT_OTHER     0x03
+// -------------- USB Standard Requests  --------------
+#define  GET_STATUS              0
+#define  CLEAR_FEATURE           1
+#define  SET_FEATURE             3
+#define  SET_ADDRESS             5
+#define  GET_DESCRIPTOR          6
+#define  SET_CONFIGURATION       9
+#define  SET_INTERFACE           11
+// ------------------ HcControl Register ---------------------
+#define  OR_CONTROL_PLE                 0x00000004
+#define  OR_CONTROL_IE                  0x00000008
+#define  OR_CONTROL_CLE                 0x00000010
+#define  OR_CONTROL_BLE                 0x00000020
+#define  OR_CONTROL_HCFS                0x000000C0
+#define  OR_CONTROL_HC_OPER             0x00000080
+// ----------------- HcCommandStatus Register -----------------
+#define  OR_CMD_STATUS_HCR              0x00000001
+#define  OR_CMD_STATUS_CLF              0x00000002
+#define  OR_CMD_STATUS_BLF              0x00000004
+// --------------- HcInterruptStatus Register -----------------
+#define  OR_INTR_STATUS_WDH             0x00000002
+#define  OR_INTR_STATUS_UE              0x00000010
+#define  OR_INTR_STATUS_FNO             0x00000020
+#define  OR_INTR_STATUS_RHSC            0x00000040
+// --------------- HcInterruptEnable Register -----------------
+#define  OR_INTR_ENABLE_WDH             0x00000002
+#define  OR_INTR_ENABLE_FNO             0x00000020
+#define  OR_INTR_ENABLE_RHSC            0x00000040
+#define  OR_INTR_ENABLE_MIE             0x80000000
+// ---------------- HcRhDescriptorA Register ------------------
+#define  OR_RH_STATUS_LPSC              0x00010000
+#define  OR_RH_STATUS_DRWE              0x00008000
+// -------------- HcRhPortStatus[1:NDP] Register --------------
+#define  OR_RH_PORT_CCS                 0x00000001
+#define  OR_RH_PORT_PRS                 0x00000010
+#define  OR_RH_PORT_CSC                 0x00010000
+#define  OR_RH_PORT_PRSC                0x00100000
+
+// TRANSFER DESCRIPTOR CONTROL FIELDS
+#define  TD_ROUNDING     (uint32_t)(0x00040000) /* Buffer Rounding */
+#define  TD_SETUP        (uint32_t)(0x00000000) /* Direction of Setup Packet */
+#define  TD_IN           (uint32_t)(0x00100000) /* Direction In */
+#define  TD_OUT          (uint32_t)(0x00080000) /* Direction Out */
+#define  TD_DELAY_INT(x) (uint32_t)((x) << 21)  /* Delay Interrupt */
+#define  TD_DI           (uint32_t)(7<<21)      /* desable interrupt */
+#define  TD_TOGGLE_0     (uint32_t)(0x02000000) /* Toggle 0 */
+#define  TD_TOGGLE_1     (uint32_t)(0x03000000) /* Toggle 1 */
+#define  TD_CC           (uint32_t)(0xF0000000) /* Completion Code */
+
+typedef struct {    // Host Controller Communication Area
+    uint32_t InterruptTable[32]; // Interrupt Table
+    __IO uint16_t FrameNumber;   // Frame Number
+    __IO uint16_t Pad1;
+    __IO uint32_t DoneHead;      // Done Head
+    uint8_t Reserved[116];       // Reserved for future use
+    uint8_t Unknown[4];          // Unused
+} HCCA;
+
+typedef struct {    // HostController Transfer Descriptor
+    __IO uint32_t  Control;    // +0 Transfer descriptor control
+    __IO uint8_t*  CurrBufPtr; // +4 Physical address of current buffer pointer
+    __IO uint32_t  Next;       // +8 Physical pointer to next Transfer Descriptor
+    uint8_t*  BufEnd;          // +12 Physical address of end of buffer
+    uint8_t* buf_top;          // +16 Buffer start address
+    uint16_t buf_size;         // +20 buffer size size
+    uint8_t setup[8];          // +22 setup cmd area
+    uint8_t _dummy[2];         // +30 dummy
+    void *ep;                  // +32 endpoint object
+    __IO uint8_t buf[0];       // +36 buffer
+} HCTD;                        // +36 
+
+typedef struct {    // HostController Isochronous Transfer Descriptor
+    __IO uint32_t Control;      // +0 Transfer descriptor control
+    uint8_t*  BufferPage0;      // +4 Buffer Page 0
+    __IO uint32_t  Next;        // +8 Physical pointer to next Transfer Descriptor
+    uint8_t*  BufferEnd;        // +12 buffer End
+    __IO uint16_t OffsetPSW[8]; // +16 Offset/PSW
+    void *ep;                   // +32 endpoint object
+    __IO uint8_t buf[0];        // +36 buffer
+} HCITD;                        // +36
+
+typedef struct {    // HostController EndPoint Descriptor
+    __IO uint32_t Control; // +0 Endpoint descriptor control
+    HCTD* TailTd;          // +4 Physical address of tail in Transfer descriptor list
+    __IO HCTD* HeadTd;     // +8 Physcial address of head in Transfer descriptor list
+    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;
+};
+
+#define HCTD_QUEUE_SIZE 3
+
+class BaseEp { // endpoint
+public:
+    BaseEp(int addr, uint8_t ep = 0, uint16_t size = 8, int lowSpeed = 0);
+    int GetAddr();
+    int GetLowSpeed();
+    void update_FunctionAddress(int addr);
+    void update_MaxPacketSize(uint16_t size);
+    //
+    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);
+    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;
+};
+
+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);
+    int GetConfiguration(int *config);
+    int SetInterfaceAlternate(int interface, int alternate);
+    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);
+    //
+    uint8_t DeviceClass;
+    uint8_t DeviceSubClass;
+    uint8_t DeviceProtocol;
+    //
+    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);
+};
+
+class BulkEp : public BaseEp {
+public:
+    BulkEp(int addr, uint8_t ep, uint16_t size);
+    virtual void irqWdhHandler(HCTD* td) {m_queue.put(td);}
+    int read(uint8_t* buf, int len, int millisec=osWaitForever);
+    int write(const uint8_t* buf, int len, int millisec=osWaitForever);
+};
+
+class InterruptEp : public BaseEp {
+public:
+    InterruptEp(int addr, uint8_t ep, uint16_t size, int lowSpeed=0);
+    virtual void irqWdhHandler(HCTD* td) {m_queue.put(td);}
+    int read(uint8_t* buf, int len, int millisec=osWaitForever);
+};
+
+class IsochronousEp : public BaseEp {
+public:
+    IsochronousEp(int addr, uint8_t ep, uint16_t size);
+    virtual void irqWdhHandler(HCTD* td);
+    void reset();
+    HCITD* read();
+    HCITD* new_HCITD();
+    HCITD* get_queue_HCITD(uint32_t millisec);
+    int m_itd_queue_count;
+    uint16_t m_FrameNumber;
+    int m_PacketSize; // 128,192
+    int m_FrameCount; // 1-8
+};
+
+#define MAX_HUB_PORT 4
+
+class UsbHub {
+public:
+    UsbHub(ControlEp* ctlEp = NULL);
+    void DeviceConnected(int port, int low_speed);
+    int PortReset(int port);
+    //
+    int SetPortFeature(int feature, int index);
+    int ClearPortFeature(int feature, int index);
+    int SetPortPower(int port);
+    int SetPortReset(int port);
+    int GetPortStatus(int port, uint32_t* status);
+    ControlEp* m_ctlEp;
+    ControlEp* PortEp[MAX_HUB_PORT]; // port endpoint(control) 
+};
+
+
+#endif //BASE_USB_HOST_H