USB host library, support isochronous,bulk,interrupt and control.
Dependents: BaseUsbHost_example BaseJpegDecode_example SimpleJpegDecode_example
Import programBaseUsbHost_example
BaseUsbHost example program
BaseUsbHost.h
- Committer:
- va009039
- Date:
- 2012-12-11
- Revision:
- 2:fe1e62051d88
- Parent:
- 1:3b7bc4f87a61
- Child:
- 3:ae77d63a1eda
File content as of revision 2:fe1e62051d88:
// BaseUsbHost.h 2012/12/11 #ifndef BASE_USB_HOST_H #define BASE_USB_HOST_H #define USB_OK 0 #define USB_PROCESSING -1 #define USB_ERROR -2 #define USB_ERROR_MEMORY -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); // 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 bulkSend(const uint8_t* buf, int len, int millisec=osWaitForever); int bulkReceive(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); int interruptReceive(uint8_t* buf, int len, int millisec=osWaitForever); virtual void irqWdhHandler(HCTD* td) {m_queue.put(td);} }; class IsochronousEp : public BaseEp { public: IsochronousEp(int addr, uint8_t ep, uint16_t size); virtual void irqWdhHandler(HCTD* td); void reset(); HCITD* isochronousReveive(int millisec=osWaitForever); int isochronousSend(uint8_t* buf, int len, int millisec=osWaitForever); 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 }; // --- HUB -------------------------------------------------- #define MAX_HUB_PORT 4 class UsbHub { public: UsbHub(ControlEp* ctlEp = NULL); ControlEp* GetPortEp(int port); // port: 1-4 int SetPortPower(int port); int ClearPortPower(int port); protected: void DeviceConnected(int port, int low_speed); 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 -------------------------------------------------- #define _30FPS 333333 #define _25FPS 400000 #define _20FPS 500000 #define _15FPS 666666 #define _10FPS 1000000 #define _5FPS 2000000 #define _1FPS 10000000 #define SET_CUR 0x01 #define GET_CUR 0x81 #define GET_MIN 0x82 #define GET_MAX 0x83 #define GET_RES 0x84 #define GET_LEN 0x85 #define GET_INFO 0x86 #define GET_DEF 0x87 #define VS_PROBE_CONTROL 0x01 #define VS_COMMIT_CONTROL 0x02 class BaseUvc { public: void poll(int millisec=osWaitForever); int Control(int req, int cs, int index, uint8_t* buf, int size); ControlEp* m_ctlEp; IsochronousEp* m_isoEp; uint32_t report_cc_count[16]; // ConditionCode uint32_t report_ps_cc_count[16]; // Packt Status ConditionCode // callback void onResult(uint16_t frame, uint8_t* buf, int len); void setOnResult( void (*pMethod)(uint16_t, uint8_t*, int) ); class CDummy; template<class T> void setOnResult( T* pItem, void (T::*pMethod)(uint16_t, uint8_t*, int) ) { m_pCb = NULL; m_pCbItem = (CDummy*) pItem; m_pCbMeth = (void (CDummy::*)(uint16_t, uint8_t*, int)) pMethod; } void clearOnResult(); CDummy* m_pCbItem; void (CDummy::*m_pCbMeth)(uint16_t, uint8_t*, int); void (*m_pCb)(uint16_t, uint8_t*, int); }; #endif //BASE_USB_HOST_H