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

Dependents:   BaseUsbHost_example BaseJpegDecode_example SimpleJpegDecode_example

Import programBaseUsbHost_example

BaseUsbHost example program

Committer:
va009039
Date:
Tue Dec 04 13:29:41 2012 +0000
Revision:
0:b7d6879637a8
Child:
1:3b7bc4f87a61
first commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 0:b7d6879637a8 1 // BaseUsbHost.h 2012/12/4
va009039 0:b7d6879637a8 2 #ifndef BASE_USB_HOST_H
va009039 0:b7d6879637a8 3 #define BASE_USB_HOST_H
va009039 0:b7d6879637a8 4
va009039 0:b7d6879637a8 5 #define USB_OK 0
va009039 0:b7d6879637a8 6 #define USB_ERROR -1
va009039 0:b7d6879637a8 7 #define USB_TIMEOUT -2
va009039 0:b7d6879637a8 8 #define USB_ERROR2 -3
va009039 0:b7d6879637a8 9
va009039 0:b7d6879637a8 10 // USB STANDARD REQUEST DEFINITIONS
va009039 0:b7d6879637a8 11 #define USB_DESCRIPTOR_TYPE_DEVICE 1
va009039 0:b7d6879637a8 12 #define USB_DESCRIPTOR_TYPE_CONFIGURATION 2
va009039 0:b7d6879637a8 13 #define USB_DESCRIPTOR_TYPE_STRING 3
va009039 0:b7d6879637a8 14 #define USB_DESCRIPTOR_TYPE_INTERFACE 4
va009039 0:b7d6879637a8 15 #define USB_DESCRIPTOR_TYPE_ENDPOINT 5
va009039 0:b7d6879637a8 16 #define USB_DESCRIPTOR_TYPE_HUB 0x29
va009039 0:b7d6879637a8 17 // ----------- Control RequestType Fields -----------
va009039 0:b7d6879637a8 18 #define USB_DEVICE_TO_HOST 0x80
va009039 0:b7d6879637a8 19 #define USB_HOST_TO_DEVICE 0x00
va009039 0:b7d6879637a8 20 #define USB_REQUEST_TYPE_CLASS 0x20
va009039 0:b7d6879637a8 21 #define USB_RECIPIENT_DEVICE 0x00
va009039 0:b7d6879637a8 22 #define USB_RECIPIENT_INTERFACE 0x01
va009039 0:b7d6879637a8 23 #define USB_RECIPIENT_OTHER 0x03
va009039 0:b7d6879637a8 24 // -------------- USB Standard Requests --------------
va009039 0:b7d6879637a8 25 #define GET_STATUS 0
va009039 0:b7d6879637a8 26 #define CLEAR_FEATURE 1
va009039 0:b7d6879637a8 27 #define SET_FEATURE 3
va009039 0:b7d6879637a8 28 #define SET_ADDRESS 5
va009039 0:b7d6879637a8 29 #define GET_DESCRIPTOR 6
va009039 0:b7d6879637a8 30 #define SET_CONFIGURATION 9
va009039 0:b7d6879637a8 31 #define SET_INTERFACE 11
va009039 0:b7d6879637a8 32 // ------------------ HcControl Register ---------------------
va009039 0:b7d6879637a8 33 #define OR_CONTROL_PLE 0x00000004
va009039 0:b7d6879637a8 34 #define OR_CONTROL_IE 0x00000008
va009039 0:b7d6879637a8 35 #define OR_CONTROL_CLE 0x00000010
va009039 0:b7d6879637a8 36 #define OR_CONTROL_BLE 0x00000020
va009039 0:b7d6879637a8 37 #define OR_CONTROL_HCFS 0x000000C0
va009039 0:b7d6879637a8 38 #define OR_CONTROL_HC_OPER 0x00000080
va009039 0:b7d6879637a8 39 // ----------------- HcCommandStatus Register -----------------
va009039 0:b7d6879637a8 40 #define OR_CMD_STATUS_HCR 0x00000001
va009039 0:b7d6879637a8 41 #define OR_CMD_STATUS_CLF 0x00000002
va009039 0:b7d6879637a8 42 #define OR_CMD_STATUS_BLF 0x00000004
va009039 0:b7d6879637a8 43 // --------------- HcInterruptStatus Register -----------------
va009039 0:b7d6879637a8 44 #define OR_INTR_STATUS_WDH 0x00000002
va009039 0:b7d6879637a8 45 #define OR_INTR_STATUS_UE 0x00000010
va009039 0:b7d6879637a8 46 #define OR_INTR_STATUS_FNO 0x00000020
va009039 0:b7d6879637a8 47 #define OR_INTR_STATUS_RHSC 0x00000040
va009039 0:b7d6879637a8 48 // --------------- HcInterruptEnable Register -----------------
va009039 0:b7d6879637a8 49 #define OR_INTR_ENABLE_WDH 0x00000002
va009039 0:b7d6879637a8 50 #define OR_INTR_ENABLE_FNO 0x00000020
va009039 0:b7d6879637a8 51 #define OR_INTR_ENABLE_RHSC 0x00000040
va009039 0:b7d6879637a8 52 #define OR_INTR_ENABLE_MIE 0x80000000
va009039 0:b7d6879637a8 53 // ---------------- HcRhDescriptorA Register ------------------
va009039 0:b7d6879637a8 54 #define OR_RH_STATUS_LPSC 0x00010000
va009039 0:b7d6879637a8 55 #define OR_RH_STATUS_DRWE 0x00008000
va009039 0:b7d6879637a8 56 // -------------- HcRhPortStatus[1:NDP] Register --------------
va009039 0:b7d6879637a8 57 #define OR_RH_PORT_CCS 0x00000001
va009039 0:b7d6879637a8 58 #define OR_RH_PORT_PRS 0x00000010
va009039 0:b7d6879637a8 59 #define OR_RH_PORT_CSC 0x00010000
va009039 0:b7d6879637a8 60 #define OR_RH_PORT_PRSC 0x00100000
va009039 0:b7d6879637a8 61
va009039 0:b7d6879637a8 62 // TRANSFER DESCRIPTOR CONTROL FIELDS
va009039 0:b7d6879637a8 63 #define TD_ROUNDING (uint32_t)(0x00040000) /* Buffer Rounding */
va009039 0:b7d6879637a8 64 #define TD_SETUP (uint32_t)(0x00000000) /* Direction of Setup Packet */
va009039 0:b7d6879637a8 65 #define TD_IN (uint32_t)(0x00100000) /* Direction In */
va009039 0:b7d6879637a8 66 #define TD_OUT (uint32_t)(0x00080000) /* Direction Out */
va009039 0:b7d6879637a8 67 #define TD_DELAY_INT(x) (uint32_t)((x) << 21) /* Delay Interrupt */
va009039 0:b7d6879637a8 68 #define TD_DI (uint32_t)(7<<21) /* desable interrupt */
va009039 0:b7d6879637a8 69 #define TD_TOGGLE_0 (uint32_t)(0x02000000) /* Toggle 0 */
va009039 0:b7d6879637a8 70 #define TD_TOGGLE_1 (uint32_t)(0x03000000) /* Toggle 1 */
va009039 0:b7d6879637a8 71 #define TD_CC (uint32_t)(0xF0000000) /* Completion Code */
va009039 0:b7d6879637a8 72
va009039 0:b7d6879637a8 73 typedef struct { // Host Controller Communication Area
va009039 0:b7d6879637a8 74 uint32_t InterruptTable[32]; // Interrupt Table
va009039 0:b7d6879637a8 75 __IO uint16_t FrameNumber; // Frame Number
va009039 0:b7d6879637a8 76 __IO uint16_t Pad1;
va009039 0:b7d6879637a8 77 __IO uint32_t DoneHead; // Done Head
va009039 0:b7d6879637a8 78 uint8_t Reserved[116]; // Reserved for future use
va009039 0:b7d6879637a8 79 uint8_t Unknown[4]; // Unused
va009039 0:b7d6879637a8 80 } HCCA;
va009039 0:b7d6879637a8 81
va009039 0:b7d6879637a8 82 typedef struct { // HostController Transfer Descriptor
va009039 0:b7d6879637a8 83 __IO uint32_t Control; // +0 Transfer descriptor control
va009039 0:b7d6879637a8 84 __IO uint8_t* CurrBufPtr; // +4 Physical address of current buffer pointer
va009039 0:b7d6879637a8 85 __IO uint32_t Next; // +8 Physical pointer to next Transfer Descriptor
va009039 0:b7d6879637a8 86 uint8_t* BufEnd; // +12 Physical address of end of buffer
va009039 0:b7d6879637a8 87 uint8_t* buf_top; // +16 Buffer start address
va009039 0:b7d6879637a8 88 uint16_t buf_size; // +20 buffer size size
va009039 0:b7d6879637a8 89 uint8_t setup[8]; // +22 setup cmd area
va009039 0:b7d6879637a8 90 uint8_t _dummy[2]; // +30 dummy
va009039 0:b7d6879637a8 91 void *ep; // +32 endpoint object
va009039 0:b7d6879637a8 92 __IO uint8_t buf[0]; // +36 buffer
va009039 0:b7d6879637a8 93 } HCTD; // +36
va009039 0:b7d6879637a8 94
va009039 0:b7d6879637a8 95 typedef struct { // HostController Isochronous Transfer Descriptor
va009039 0:b7d6879637a8 96 __IO uint32_t Control; // +0 Transfer descriptor control
va009039 0:b7d6879637a8 97 uint8_t* BufferPage0; // +4 Buffer Page 0
va009039 0:b7d6879637a8 98 __IO uint32_t Next; // +8 Physical pointer to next Transfer Descriptor
va009039 0:b7d6879637a8 99 uint8_t* BufferEnd; // +12 buffer End
va009039 0:b7d6879637a8 100 __IO uint16_t OffsetPSW[8]; // +16 Offset/PSW
va009039 0:b7d6879637a8 101 void *ep; // +32 endpoint object
va009039 0:b7d6879637a8 102 __IO uint8_t buf[0]; // +36 buffer
va009039 0:b7d6879637a8 103 } HCITD; // +36
va009039 0:b7d6879637a8 104
va009039 0:b7d6879637a8 105 typedef struct { // HostController EndPoint Descriptor
va009039 0:b7d6879637a8 106 __IO uint32_t Control; // +0 Endpoint descriptor control
va009039 0:b7d6879637a8 107 HCTD* TailTd; // +4 Physical address of tail in Transfer descriptor list
va009039 0:b7d6879637a8 108 __IO HCTD* HeadTd; // +8 Physcial address of head in Transfer descriptor list
va009039 0:b7d6879637a8 109 uint32_t Next; // +12 Physical address of next Endpoint descriptor
va009039 0:b7d6879637a8 110 } HCED;
va009039 0:b7d6879637a8 111
va009039 0:b7d6879637a8 112 #define DELETE_TD(A) free(A)
va009039 0:b7d6879637a8 113 #define DELETE_ITD(A) free(A)
va009039 0:b7d6879637a8 114
va009039 0:b7d6879637a8 115 class BaseUsbHost {
va009039 0:b7d6879637a8 116 public:
va009039 0:b7d6879637a8 117 BaseUsbHost();
va009039 0:b7d6879637a8 118 void init_hw_ohci(HCCA* pHcca);
va009039 0:b7d6879637a8 119 void ResetRootHub();
va009039 0:b7d6879637a8 120 void irqHandler();
va009039 0:b7d6879637a8 121 HCCA* m_pHcca;
va009039 0:b7d6879637a8 122 // report
va009039 0:b7d6879637a8 123 uint32_t m_report_irq;
va009039 0:b7d6879637a8 124 uint32_t m_report_RHSC;
va009039 0:b7d6879637a8 125 uint32_t m_report_FNO;
va009039 0:b7d6879637a8 126 uint32_t m_report_WDH;
va009039 0:b7d6879637a8 127 uint32_t m_report_sp;
va009039 0:b7d6879637a8 128 };
va009039 0:b7d6879637a8 129
va009039 0:b7d6879637a8 130 #define HCTD_QUEUE_SIZE 3
va009039 0:b7d6879637a8 131
va009039 0:b7d6879637a8 132 class BaseEp { // endpoint
va009039 0:b7d6879637a8 133 public:
va009039 0:b7d6879637a8 134 BaseEp(int addr, uint8_t ep = 0, uint16_t size = 8, int lowSpeed = 0);
va009039 0:b7d6879637a8 135 int GetAddr();
va009039 0:b7d6879637a8 136 int GetLowSpeed();
va009039 0:b7d6879637a8 137 void update_FunctionAddress(int addr);
va009039 0:b7d6879637a8 138 void update_MaxPacketSize(uint16_t size);
va009039 0:b7d6879637a8 139 //
va009039 0:b7d6879637a8 140 HCTD* new_HCTD(int buf_size=0);
va009039 0:b7d6879637a8 141 void delete_HCTD(HCTD* p);
va009039 0:b7d6879637a8 142 HCED* m_pED;
va009039 0:b7d6879637a8 143 // TD done queue
va009039 0:b7d6879637a8 144 virtual void irqWdhHandler(HCTD* td) = 0; // WDH
va009039 0:b7d6879637a8 145 HCTD* get_queue_HCTD(uint32_t millisec=osWaitForever);
va009039 0:b7d6879637a8 146 int wait_queue_HCTD(HCTD* wait_td, uint32_t millisec=osWaitForever);
va009039 0:b7d6879637a8 147 Queue<HCTD, HCTD_QUEUE_SIZE> m_queue;
va009039 0:b7d6879637a8 148 int m_td_queue_count;
va009039 0:b7d6879637a8 149 // report
va009039 0:b7d6879637a8 150 uint8_t m_ConditionCode;
va009039 0:b7d6879637a8 151 int m_report_queue_error;
va009039 0:b7d6879637a8 152 };
va009039 0:b7d6879637a8 153
va009039 0:b7d6879637a8 154 class ControlEp : public BaseEp {
va009039 0:b7d6879637a8 155 public:
va009039 0:b7d6879637a8 156 ControlEp(int lowSpeed = 0);
va009039 0:b7d6879637a8 157 virtual void irqWdhHandler(HCTD* td) {m_queue.put(td);}
va009039 0:b7d6879637a8 158 int GetDescriptor(int descType, int descIndex, uint8_t* data, int length);
va009039 0:b7d6879637a8 159 int SetAddress(int addr); // device address
va009039 0:b7d6879637a8 160 int SetConfiguration(int config);
va009039 0:b7d6879637a8 161 int GetConfiguration(int *config);
va009039 0:b7d6879637a8 162 int SetInterfaceAlternate(int interface, int alternate);
va009039 0:b7d6879637a8 163 int GetInterface(int interface, int *alternate);
va009039 0:b7d6879637a8 164 int controlSend(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex=0, const uint8_t* data=NULL, int length=0);
va009039 0:b7d6879637a8 165 int controlReceive(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t* data, int length);
va009039 0:b7d6879637a8 166 //
va009039 0:b7d6879637a8 167 uint8_t DeviceClass;
va009039 0:b7d6879637a8 168 uint8_t DeviceSubClass;
va009039 0:b7d6879637a8 169 uint8_t DeviceProtocol;
va009039 0:b7d6879637a8 170 //
va009039 0:b7d6879637a8 171 int open(int addr);
va009039 0:b7d6879637a8 172 void setup(HCTD* td, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex=0, uint16_t wLength=0);
va009039 0:b7d6879637a8 173 };
va009039 0:b7d6879637a8 174
va009039 0:b7d6879637a8 175 class BulkEp : public BaseEp {
va009039 0:b7d6879637a8 176 public:
va009039 0:b7d6879637a8 177 BulkEp(int addr, uint8_t ep, uint16_t size);
va009039 0:b7d6879637a8 178 virtual void irqWdhHandler(HCTD* td) {m_queue.put(td);}
va009039 0:b7d6879637a8 179 int read(uint8_t* buf, int len, int millisec=osWaitForever);
va009039 0:b7d6879637a8 180 int write(const uint8_t* buf, int len, int millisec=osWaitForever);
va009039 0:b7d6879637a8 181 };
va009039 0:b7d6879637a8 182
va009039 0:b7d6879637a8 183 class InterruptEp : public BaseEp {
va009039 0:b7d6879637a8 184 public:
va009039 0:b7d6879637a8 185 InterruptEp(int addr, uint8_t ep, uint16_t size, int lowSpeed=0);
va009039 0:b7d6879637a8 186 virtual void irqWdhHandler(HCTD* td) {m_queue.put(td);}
va009039 0:b7d6879637a8 187 int read(uint8_t* buf, int len, int millisec=osWaitForever);
va009039 0:b7d6879637a8 188 };
va009039 0:b7d6879637a8 189
va009039 0:b7d6879637a8 190 class IsochronousEp : public BaseEp {
va009039 0:b7d6879637a8 191 public:
va009039 0:b7d6879637a8 192 IsochronousEp(int addr, uint8_t ep, uint16_t size);
va009039 0:b7d6879637a8 193 virtual void irqWdhHandler(HCTD* td);
va009039 0:b7d6879637a8 194 void reset();
va009039 0:b7d6879637a8 195 HCITD* read();
va009039 0:b7d6879637a8 196 HCITD* new_HCITD();
va009039 0:b7d6879637a8 197 HCITD* get_queue_HCITD(uint32_t millisec);
va009039 0:b7d6879637a8 198 int m_itd_queue_count;
va009039 0:b7d6879637a8 199 uint16_t m_FrameNumber;
va009039 0:b7d6879637a8 200 int m_PacketSize; // 128,192
va009039 0:b7d6879637a8 201 int m_FrameCount; // 1-8
va009039 0:b7d6879637a8 202 };
va009039 0:b7d6879637a8 203
va009039 0:b7d6879637a8 204 #define MAX_HUB_PORT 4
va009039 0:b7d6879637a8 205
va009039 0:b7d6879637a8 206 class UsbHub {
va009039 0:b7d6879637a8 207 public:
va009039 0:b7d6879637a8 208 UsbHub(ControlEp* ctlEp = NULL);
va009039 0:b7d6879637a8 209 void DeviceConnected(int port, int low_speed);
va009039 0:b7d6879637a8 210 int PortReset(int port);
va009039 0:b7d6879637a8 211 //
va009039 0:b7d6879637a8 212 int SetPortFeature(int feature, int index);
va009039 0:b7d6879637a8 213 int ClearPortFeature(int feature, int index);
va009039 0:b7d6879637a8 214 int SetPortPower(int port);
va009039 0:b7d6879637a8 215 int SetPortReset(int port);
va009039 0:b7d6879637a8 216 int GetPortStatus(int port, uint32_t* status);
va009039 0:b7d6879637a8 217 ControlEp* m_ctlEp;
va009039 0:b7d6879637a8 218 ControlEp* PortEp[MAX_HUB_PORT]; // port endpoint(control)
va009039 0:b7d6879637a8 219 };
va009039 0:b7d6879637a8 220
va009039 0:b7d6879637a8 221
va009039 0:b7d6879637a8 222 #endif //BASE_USB_HOST_H