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 11 15:26:54 2012 +0000
Revision:
2:fe1e62051d88
Parent:
1:3b7bc4f87a61
Child:
3:ae77d63a1eda
bug fix

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 2:fe1e62051d88 1 // BaseUsbHost.h 2012/12/11
va009039 0:b7d6879637a8 2 #ifndef BASE_USB_HOST_H
va009039 0:b7d6879637a8 3 #define BASE_USB_HOST_H
va009039 0:b7d6879637a8 4
va009039 2:fe1e62051d88 5 #define USB_OK 0
va009039 2:fe1e62051d88 6 #define USB_PROCESSING -1
va009039 2:fe1e62051d88 7 #define USB_ERROR -2
va009039 2:fe1e62051d88 8 #define USB_ERROR_MEMORY -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 int open(int addr);
va009039 0:b7d6879637a8 168 void setup(HCTD* td, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex=0, uint16_t wLength=0);
va009039 0:b7d6879637a8 169 };
va009039 0:b7d6879637a8 170
va009039 0:b7d6879637a8 171 class BulkEp : public BaseEp {
va009039 0:b7d6879637a8 172 public:
va009039 0:b7d6879637a8 173 BulkEp(int addr, uint8_t ep, uint16_t size);
va009039 0:b7d6879637a8 174 virtual void irqWdhHandler(HCTD* td) {m_queue.put(td);}
va009039 1:3b7bc4f87a61 175 int bulkSend(const uint8_t* buf, int len, int millisec=osWaitForever);
va009039 1:3b7bc4f87a61 176 int bulkReceive(uint8_t* buf, int len, int millisec=osWaitForever);
va009039 0:b7d6879637a8 177 };
va009039 0:b7d6879637a8 178
va009039 0:b7d6879637a8 179 class InterruptEp : public BaseEp {
va009039 0:b7d6879637a8 180 public:
va009039 0:b7d6879637a8 181 InterruptEp(int addr, uint8_t ep, uint16_t size, int lowSpeed=0);
va009039 1:3b7bc4f87a61 182 int interruptReceive(uint8_t* buf, int len, int millisec=osWaitForever);
va009039 0:b7d6879637a8 183 virtual void irqWdhHandler(HCTD* td) {m_queue.put(td);}
va009039 0:b7d6879637a8 184 };
va009039 0:b7d6879637a8 185
va009039 0:b7d6879637a8 186 class IsochronousEp : public BaseEp {
va009039 0:b7d6879637a8 187 public:
va009039 0:b7d6879637a8 188 IsochronousEp(int addr, uint8_t ep, uint16_t size);
va009039 0:b7d6879637a8 189 virtual void irqWdhHandler(HCTD* td);
va009039 0:b7d6879637a8 190 void reset();
va009039 2:fe1e62051d88 191 HCITD* isochronousReveive(int millisec=osWaitForever);
va009039 2:fe1e62051d88 192 int isochronousSend(uint8_t* buf, int len, int millisec=osWaitForever);
va009039 0:b7d6879637a8 193 HCITD* new_HCITD();
va009039 2:fe1e62051d88 194 HCITD* get_queue_HCITD(int millisec);
va009039 0:b7d6879637a8 195 int m_itd_queue_count;
va009039 0:b7d6879637a8 196 uint16_t m_FrameNumber;
va009039 0:b7d6879637a8 197 int m_PacketSize; // 128,192
va009039 0:b7d6879637a8 198 int m_FrameCount; // 1-8
va009039 0:b7d6879637a8 199 };
va009039 0:b7d6879637a8 200
va009039 1:3b7bc4f87a61 201 // --- HUB --------------------------------------------------
va009039 0:b7d6879637a8 202 #define MAX_HUB_PORT 4
va009039 0:b7d6879637a8 203
va009039 0:b7d6879637a8 204 class UsbHub {
va009039 0:b7d6879637a8 205 public:
va009039 0:b7d6879637a8 206 UsbHub(ControlEp* ctlEp = NULL);
va009039 2:fe1e62051d88 207 ControlEp* GetPortEp(int port); // port: 1-4
va009039 2:fe1e62051d88 208 int SetPortPower(int port);
va009039 2:fe1e62051d88 209 int ClearPortPower(int port);
va009039 2:fe1e62051d88 210 protected:
va009039 0:b7d6879637a8 211 void DeviceConnected(int port, int low_speed);
va009039 0:b7d6879637a8 212 int PortReset(int port);
va009039 0:b7d6879637a8 213 int SetPortFeature(int feature, int index);
va009039 0:b7d6879637a8 214 int ClearPortFeature(int feature, int index);
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 1:3b7bc4f87a61 221 // --- UVC --------------------------------------------------
va009039 1:3b7bc4f87a61 222 #define _30FPS 333333
va009039 1:3b7bc4f87a61 223 #define _25FPS 400000
va009039 1:3b7bc4f87a61 224 #define _20FPS 500000
va009039 1:3b7bc4f87a61 225 #define _15FPS 666666
va009039 1:3b7bc4f87a61 226 #define _10FPS 1000000
va009039 1:3b7bc4f87a61 227 #define _5FPS 2000000
va009039 1:3b7bc4f87a61 228 #define _1FPS 10000000
va009039 1:3b7bc4f87a61 229
va009039 1:3b7bc4f87a61 230 #define SET_CUR 0x01
va009039 1:3b7bc4f87a61 231 #define GET_CUR 0x81
va009039 1:3b7bc4f87a61 232 #define GET_MIN 0x82
va009039 1:3b7bc4f87a61 233 #define GET_MAX 0x83
va009039 1:3b7bc4f87a61 234 #define GET_RES 0x84
va009039 1:3b7bc4f87a61 235 #define GET_LEN 0x85
va009039 1:3b7bc4f87a61 236 #define GET_INFO 0x86
va009039 1:3b7bc4f87a61 237 #define GET_DEF 0x87
va009039 1:3b7bc4f87a61 238
va009039 1:3b7bc4f87a61 239 #define VS_PROBE_CONTROL 0x01
va009039 1:3b7bc4f87a61 240 #define VS_COMMIT_CONTROL 0x02
va009039 1:3b7bc4f87a61 241
va009039 1:3b7bc4f87a61 242 class BaseUvc {
va009039 1:3b7bc4f87a61 243 public:
va009039 2:fe1e62051d88 244 void poll(int millisec=osWaitForever);
va009039 1:3b7bc4f87a61 245 int Control(int req, int cs, int index, uint8_t* buf, int size);
va009039 1:3b7bc4f87a61 246 ControlEp* m_ctlEp;
va009039 1:3b7bc4f87a61 247 IsochronousEp* m_isoEp;
va009039 1:3b7bc4f87a61 248 uint32_t report_cc_count[16]; // ConditionCode
va009039 1:3b7bc4f87a61 249 uint32_t report_ps_cc_count[16]; // Packt Status ConditionCode
va009039 1:3b7bc4f87a61 250 // callback
va009039 1:3b7bc4f87a61 251 void onResult(uint16_t frame, uint8_t* buf, int len);
va009039 1:3b7bc4f87a61 252 void setOnResult( void (*pMethod)(uint16_t, uint8_t*, int) );
va009039 1:3b7bc4f87a61 253 class CDummy;
va009039 1:3b7bc4f87a61 254 template<class T>
va009039 1:3b7bc4f87a61 255 void setOnResult( T* pItem, void (T::*pMethod)(uint16_t, uint8_t*, int) )
va009039 1:3b7bc4f87a61 256 {
va009039 1:3b7bc4f87a61 257 m_pCb = NULL;
va009039 1:3b7bc4f87a61 258 m_pCbItem = (CDummy*) pItem;
va009039 1:3b7bc4f87a61 259 m_pCbMeth = (void (CDummy::*)(uint16_t, uint8_t*, int)) pMethod;
va009039 1:3b7bc4f87a61 260 }
va009039 1:3b7bc4f87a61 261 void clearOnResult();
va009039 1:3b7bc4f87a61 262 CDummy* m_pCbItem;
va009039 1:3b7bc4f87a61 263 void (CDummy::*m_pCbMeth)(uint16_t, uint8_t*, int);
va009039 1:3b7bc4f87a61 264 void (*m_pCb)(uint16_t, uint8_t*, int);
va009039 1:3b7bc4f87a61 265 };
va009039 0:b7d6879637a8 266
va009039 0:b7d6879637a8 267 #endif //BASE_USB_HOST_H