![](/media/cache/profiles/45ab12afa05e563bb484781693dffc87.50x50_q85.jpg)
modify for C210 webcam and Startboard Orange.
Dependencies: TextLCD USBHost mbed
Fork of USBHostC270_example by
Norimasa Okamoto さんの http://mbed.org/users/va009039/code/USBHostC270_example/ を C210 webcam と StarBoard Orange での SD カード保存用に変更。
USBHostC270/BaseUvc.h@12:c827ed52021d, 2013-03-19 (annotated)
- Committer:
- masato
- Date:
- Tue Mar 19 14:16:25 2013 +0000
- Revision:
- 12:c827ed52021d
- Parent:
- 10:387c49b2fc7e
for C210 and StartBoard Orange
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 | 10:387c49b2fc7e | 1 | // BaseUvc.h |
va009039 | 10:387c49b2fc7e | 2 | |
va009039 | 9:fecabade834a | 3 | #pragma once |
va009039 | 9:fecabade834a | 4 | |
va009039 | 10:387c49b2fc7e | 5 | // --- UVC -------------------------------------------------- |
va009039 | 10:387c49b2fc7e | 6 | #define _30FPS 333333 |
va009039 | 10:387c49b2fc7e | 7 | #define _25FPS 400000 |
va009039 | 10:387c49b2fc7e | 8 | #define _20FPS 500000 |
va009039 | 10:387c49b2fc7e | 9 | #define _15FPS 666666 |
va009039 | 10:387c49b2fc7e | 10 | #define _10FPS 1000000 |
va009039 | 10:387c49b2fc7e | 11 | #define _5FPS 2000000 |
va009039 | 10:387c49b2fc7e | 12 | #define _1FPS 10000000 |
va009039 | 10:387c49b2fc7e | 13 | |
va009039 | 10:387c49b2fc7e | 14 | #define SET_CUR 0x01 |
va009039 | 10:387c49b2fc7e | 15 | #define GET_CUR 0x81 |
va009039 | 10:387c49b2fc7e | 16 | #define GET_MIN 0x82 |
va009039 | 10:387c49b2fc7e | 17 | #define GET_MAX 0x83 |
va009039 | 10:387c49b2fc7e | 18 | #define GET_RES 0x84 |
va009039 | 10:387c49b2fc7e | 19 | #define GET_LEN 0x85 |
va009039 | 10:387c49b2fc7e | 20 | #define GET_INFO 0x86 |
va009039 | 10:387c49b2fc7e | 21 | #define GET_DEF 0x87 |
va009039 | 10:387c49b2fc7e | 22 | |
va009039 | 10:387c49b2fc7e | 23 | #define VS_PROBE_CONTROL 0x01 |
va009039 | 10:387c49b2fc7e | 24 | #define VS_COMMIT_CONTROL 0x02 |
va009039 | 10:387c49b2fc7e | 25 | |
va009039 | 9:fecabade834a | 26 | class BaseEp; |
va009039 | 9:fecabade834a | 27 | struct HCITD { // HostController Isochronous Transfer Descriptor |
va009039 | 9:fecabade834a | 28 | __IO uint32_t Control; // +0 Transfer descriptor control |
va009039 | 9:fecabade834a | 29 | uint8_t* BufferPage0; // +4 Buffer Page 0 |
va009039 | 9:fecabade834a | 30 | HCITD* Next; // +8 Physical pointer to next Isochronous Transfer Descriptor |
va009039 | 9:fecabade834a | 31 | uint8_t* BufferEnd; // +12 buffer End |
va009039 | 9:fecabade834a | 32 | __IO uint16_t OffsetPSW[8]; // +16 Offset/PSW |
va009039 | 9:fecabade834a | 33 | BaseEp* ep; // +32 endpoint object |
va009039 | 9:fecabade834a | 34 | __IO uint8_t buf[0]; // +36 buffer |
va009039 | 9:fecabade834a | 35 | // +36 |
va009039 | 9:fecabade834a | 36 | HCITD(BaseEp* obj, uint16_t FrameNumber, int FrameCount, uint16_t PacketSize); |
va009039 | 9:fecabade834a | 37 | inline void* operator new(size_t size, int buf_size) { |
va009039 | 9:fecabade834a | 38 | void* p; |
va009039 | 9:fecabade834a | 39 | if (posix_memalign(&p, 32, size+buf_size) == 0) { |
va009039 | 9:fecabade834a | 40 | return p; |
va009039 | 9:fecabade834a | 41 | } |
va009039 | 9:fecabade834a | 42 | return NULL; |
va009039 | 9:fecabade834a | 43 | } |
va009039 | 9:fecabade834a | 44 | |
va009039 | 9:fecabade834a | 45 | inline void operator delete(void* p) { |
va009039 | 9:fecabade834a | 46 | free(p); |
va009039 | 9:fecabade834a | 47 | } |
va009039 | 9:fecabade834a | 48 | |
va009039 | 9:fecabade834a | 49 | inline uint16_t StartingFrame() { |
va009039 | 9:fecabade834a | 50 | return Control & 0xffff; |
va009039 | 9:fecabade834a | 51 | } |
va009039 | 9:fecabade834a | 52 | |
va009039 | 9:fecabade834a | 53 | inline uint8_t FrameCount() { |
va009039 | 9:fecabade834a | 54 | return ((Control>>24)&7)+1; |
va009039 | 9:fecabade834a | 55 | } |
va009039 | 9:fecabade834a | 56 | |
va009039 | 9:fecabade834a | 57 | inline uint8_t ConditionCode() { |
va009039 | 9:fecabade834a | 58 | return Control>>28; |
va009039 | 9:fecabade834a | 59 | } |
va009039 | 9:fecabade834a | 60 | }; |
va009039 | 9:fecabade834a | 61 | |
va009039 | 9:fecabade834a | 62 | struct _HCED { // HostController EndPoint Descriptor |
va009039 | 9:fecabade834a | 63 | __IO uint32_t Control; // +0 Endpoint descriptor control |
va009039 | 9:fecabade834a | 64 | HCTD* TailTd; // +4 Physical address of tail in Transfer descriptor list |
va009039 | 9:fecabade834a | 65 | __IO HCTD* HeadTd; // +8 Physcial address of head in Transfer descriptor list |
va009039 | 9:fecabade834a | 66 | _HCED* Next; // +12 Physical address of next Endpoint descriptor |
va009039 | 9:fecabade834a | 67 | // +16 |
va009039 | 9:fecabade834a | 68 | _HCED(int addr, uint8_t ep, uint16_t size, int lowSpeed) { |
va009039 | 9:fecabade834a | 69 | Control = addr | /* USB address */ |
va009039 | 9:fecabade834a | 70 | ((ep & 0x7F) << 7) | /* Endpoint address */ |
va009039 | 9:fecabade834a | 71 | (ep!=0?(((ep&0x80)?2:1) << 11):0)| /* direction : Out = 1, 2 = In */ |
va009039 | 9:fecabade834a | 72 | ((lowSpeed?1:0) << 13) | /* speed full=0 low=1 */ |
va009039 | 9:fecabade834a | 73 | (size << 16); /* MaxPkt Size */ |
va009039 | 9:fecabade834a | 74 | Next = NULL; |
va009039 | 9:fecabade834a | 75 | } |
va009039 | 9:fecabade834a | 76 | |
va009039 | 9:fecabade834a | 77 | inline void* operator new(size_t size) { |
va009039 | 9:fecabade834a | 78 | void* p; |
va009039 | 9:fecabade834a | 79 | if (posix_memalign(&p, 16, size) == 0) { |
va009039 | 9:fecabade834a | 80 | return p; |
va009039 | 9:fecabade834a | 81 | } |
va009039 | 9:fecabade834a | 82 | return NULL; |
va009039 | 9:fecabade834a | 83 | } |
va009039 | 9:fecabade834a | 84 | |
va009039 | 9:fecabade834a | 85 | inline void operator delete(void* p) { |
va009039 | 9:fecabade834a | 86 | free(p); |
va009039 | 9:fecabade834a | 87 | } |
va009039 | 9:fecabade834a | 88 | |
va009039 | 9:fecabade834a | 89 | inline uint8_t FunctionAddress() { |
va009039 | 9:fecabade834a | 90 | return Control & 0x7f; |
va009039 | 9:fecabade834a | 91 | } |
va009039 | 9:fecabade834a | 92 | |
va009039 | 9:fecabade834a | 93 | inline int Speed() { |
va009039 | 9:fecabade834a | 94 | return (Control>>13)&1; |
va009039 | 9:fecabade834a | 95 | } |
va009039 | 9:fecabade834a | 96 | |
va009039 | 9:fecabade834a | 97 | inline void setFunctionAddress(int addr) { |
va009039 | 9:fecabade834a | 98 | Control &= ~0x7f; |
va009039 | 9:fecabade834a | 99 | Control |= addr; |
va009039 | 9:fecabade834a | 100 | } |
va009039 | 9:fecabade834a | 101 | |
va009039 | 9:fecabade834a | 102 | inline void setMaxPacketSize(uint16_t size) { |
va009039 | 9:fecabade834a | 103 | Control &= ~0xffff0000; |
va009039 | 9:fecabade834a | 104 | Control |= size<<16; |
va009039 | 9:fecabade834a | 105 | } |
va009039 | 10:387c49b2fc7e | 106 | |
va009039 | 10:387c49b2fc7e | 107 | inline void setSkip() { |
va009039 | 10:387c49b2fc7e | 108 | Control |= 1<<14; |
va009039 | 10:387c49b2fc7e | 109 | } |
va009039 | 9:fecabade834a | 110 | }; |
va009039 | 9:fecabade834a | 111 | |
va009039 | 9:fecabade834a | 112 | struct _HCCA { // Host Controller Communication Area |
va009039 | 9:fecabade834a | 113 | _HCED* InterruptTable[32]; // +0 Interrupt Table |
va009039 | 9:fecabade834a | 114 | __IO uint16_t FrameNumber;// +128 Frame Number |
va009039 | 9:fecabade834a | 115 | __IO uint16_t Pad1; // +130 |
va009039 | 9:fecabade834a | 116 | __IO HCTD* DoneHead; // +132 Done Head |
va009039 | 9:fecabade834a | 117 | uint8_t Reserved[116]; // +136 Reserved for future use |
va009039 | 9:fecabade834a | 118 | uint8_t Unknown[4]; // +252 Unused |
va009039 | 9:fecabade834a | 119 | // +256 |
va009039 | 9:fecabade834a | 120 | inline void* operator new(size_t size) { |
va009039 | 9:fecabade834a | 121 | void* p; |
va009039 | 9:fecabade834a | 122 | if (posix_memalign(&p, 256, size) == 0) { |
va009039 | 9:fecabade834a | 123 | return p; |
va009039 | 9:fecabade834a | 124 | } |
va009039 | 9:fecabade834a | 125 | return NULL; |
va009039 | 9:fecabade834a | 126 | } |
va009039 | 9:fecabade834a | 127 | |
va009039 | 9:fecabade834a | 128 | inline void operator delete(void* p) { |
va009039 | 9:fecabade834a | 129 | free(p); |
va009039 | 9:fecabade834a | 130 | } |
va009039 | 10:387c49b2fc7e | 131 | |
va009039 | 10:387c49b2fc7e | 132 | inline void enqueue(_HCED* ed) { |
va009039 | 10:387c49b2fc7e | 133 | for(int i = 0; i < 32; i++) { |
va009039 | 10:387c49b2fc7e | 134 | if (InterruptTable[i] == NULL) { |
va009039 | 10:387c49b2fc7e | 135 | InterruptTable[i] = ed; |
va009039 | 10:387c49b2fc7e | 136 | } else { |
va009039 | 10:387c49b2fc7e | 137 | _HCED* nextEd = InterruptTable[i]; |
va009039 | 10:387c49b2fc7e | 138 | while(nextEd->Next && nextEd->Next != ed) { |
va009039 | 10:387c49b2fc7e | 139 | nextEd = nextEd->Next; |
va009039 | 10:387c49b2fc7e | 140 | } |
va009039 | 10:387c49b2fc7e | 141 | nextEd->Next = ed; |
va009039 | 10:387c49b2fc7e | 142 | } |
va009039 | 10:387c49b2fc7e | 143 | } |
va009039 | 10:387c49b2fc7e | 144 | } |
va009039 | 10:387c49b2fc7e | 145 | |
va009039 | 10:387c49b2fc7e | 146 | inline void dequeue(_HCED* ed) { |
va009039 | 10:387c49b2fc7e | 147 | for(int i = 0; i < 32; i++) { |
va009039 | 10:387c49b2fc7e | 148 | if (InterruptTable[i] == ed) { |
va009039 | 10:387c49b2fc7e | 149 | InterruptTable[i] = ed->Next; |
va009039 | 10:387c49b2fc7e | 150 | } else if (InterruptTable[i]) { |
va009039 | 10:387c49b2fc7e | 151 | _HCED* nextEd = InterruptTable[i]; |
va009039 | 10:387c49b2fc7e | 152 | while(nextEd) { |
va009039 | 10:387c49b2fc7e | 153 | if (nextEd->Next == ed) { |
va009039 | 10:387c49b2fc7e | 154 | nextEd->Next = ed->Next; |
va009039 | 10:387c49b2fc7e | 155 | break; |
va009039 | 10:387c49b2fc7e | 156 | } |
va009039 | 10:387c49b2fc7e | 157 | nextEd = nextEd->Next; |
va009039 | 10:387c49b2fc7e | 158 | } |
va009039 | 10:387c49b2fc7e | 159 | } |
va009039 | 10:387c49b2fc7e | 160 | } |
va009039 | 10:387c49b2fc7e | 161 | } |
va009039 | 9:fecabade834a | 162 | }; |
va009039 | 9:fecabade834a | 163 | |
va009039 | 9:fecabade834a | 164 | #define HCTD_QUEUE_SIZE 3 |
va009039 | 9:fecabade834a | 165 | |
va009039 | 9:fecabade834a | 166 | class BaseEp { // endpoint |
va009039 | 9:fecabade834a | 167 | public: |
va009039 | 9:fecabade834a | 168 | BaseEp(int addr, uint8_t ep = 0, uint16_t size = 8, int lowSpeed = 0); |
va009039 | 9:fecabade834a | 169 | int GetAddr(); |
va009039 | 9:fecabade834a | 170 | int GetLowSpeed(); |
va009039 | 9:fecabade834a | 171 | void update_FunctionAddress(int addr); |
va009039 | 9:fecabade834a | 172 | void update_MaxPacketSize(uint16_t size); |
va009039 | 9:fecabade834a | 173 | int transfer(uint8_t* buf, int len); |
va009039 | 9:fecabade834a | 174 | int status(uint32_t millisec=osWaitForever); |
va009039 | 9:fecabade834a | 175 | // |
va009039 | 9:fecabade834a | 176 | virtual void enable() = 0; |
va009039 | 9:fecabade834a | 177 | virtual void irqWdhHandler(HCTD* td) {m_queue.put(td);} // WDH |
va009039 | 9:fecabade834a | 178 | int wait_queue_HCTD(HCTD* wait_td, uint32_t millisec=osWaitForever); |
va009039 | 9:fecabade834a | 179 | // report |
va009039 | 9:fecabade834a | 180 | uint8_t m_ConditionCode; |
va009039 | 9:fecabade834a | 181 | int m_report_queue_error; |
va009039 | 9:fecabade834a | 182 | protected: |
va009039 | 9:fecabade834a | 183 | int send_receive(uint8_t* buf, int len, int millisec); |
va009039 | 9:fecabade834a | 184 | HCTD* get_queue_HCTD(uint32_t millisec=osWaitForever); |
va009039 | 9:fecabade834a | 185 | _HCED* m_pED; |
va009039 | 9:fecabade834a | 186 | Queue<HCTD, HCTD_QUEUE_SIZE> m_queue; // TD done queue |
va009039 | 9:fecabade834a | 187 | int m_td_queue_count; |
va009039 | 9:fecabade834a | 188 | }; |
va009039 | 9:fecabade834a | 189 | |
va009039 | 9:fecabade834a | 190 | class IsochronousEp : public BaseEp { |
va009039 | 9:fecabade834a | 191 | public: |
va009039 | 9:fecabade834a | 192 | IsochronousEp(int addr, uint8_t ep, uint16_t size); |
va009039 | 9:fecabade834a | 193 | void reset(int delay_ms = 100); |
va009039 | 10:387c49b2fc7e | 194 | HCITD* isochronousReceive(int millisec=osWaitForever); |
va009039 | 9:fecabade834a | 195 | int isochronousSend(uint8_t* buf, int len, int millisec=osWaitForever); |
va009039 | 9:fecabade834a | 196 | HCITD* get_queue_HCITD(int millisec); |
va009039 | 9:fecabade834a | 197 | uint16_t m_PacketSize; |
va009039 | 10:387c49b2fc7e | 198 | void disconnect(); |
va009039 | 9:fecabade834a | 199 | private: |
va009039 | 9:fecabade834a | 200 | HCITD* new_HCITD(BaseEp* obj); |
va009039 | 9:fecabade834a | 201 | int m_itd_queue_count; |
va009039 | 9:fecabade834a | 202 | uint16_t m_FrameNumber; |
va009039 | 9:fecabade834a | 203 | int m_FrameCount; // 1-8 |
va009039 | 9:fecabade834a | 204 | virtual void enable(); |
va009039 | 9:fecabade834a | 205 | }; |
va009039 | 9:fecabade834a | 206 | |
va009039 | 9:fecabade834a | 207 | class BaseUvc { |
va009039 | 9:fecabade834a | 208 | public: |
va009039 | 9:fecabade834a | 209 | void poll(int millisec=osWaitForever); |
va009039 | 10:387c49b2fc7e | 210 | USB_TYPE Control(int req, int cs, int index, uint8_t* buf, int size); |
va009039 | 10:387c49b2fc7e | 211 | USB_TYPE setInterfaceAlternate(uint8_t intf, uint8_t alt); |
va009039 | 9:fecabade834a | 212 | //ControlEp* m_ctlEp; |
va009039 | 9:fecabade834a | 213 | IsochronousEp* m_isoEp; |
va009039 | 9:fecabade834a | 214 | uint32_t report_cc_count[16]; // ConditionCode |
va009039 | 9:fecabade834a | 215 | uint32_t report_ps_cc_count[16]; // Packt Status ConditionCode |
va009039 | 9:fecabade834a | 216 | // callback |
va009039 | 9:fecabade834a | 217 | void onResult(uint16_t frame, uint8_t* buf, int len); |
va009039 | 9:fecabade834a | 218 | void setOnResult( void (*pMethod)(uint16_t, uint8_t*, int) ); |
va009039 | 9:fecabade834a | 219 | class CDummy; |
va009039 | 9:fecabade834a | 220 | template<class T> |
va009039 | 9:fecabade834a | 221 | void setOnResult( T* pItem, void (T::*pMethod)(uint16_t, uint8_t*, int) ) |
va009039 | 9:fecabade834a | 222 | { |
va009039 | 9:fecabade834a | 223 | m_pCb = NULL; |
va009039 | 9:fecabade834a | 224 | m_pCbItem = (CDummy*) pItem; |
va009039 | 9:fecabade834a | 225 | m_pCbMeth = (void (CDummy::*)(uint16_t, uint8_t*, int)) pMethod; |
va009039 | 9:fecabade834a | 226 | } |
va009039 | 9:fecabade834a | 227 | void clearOnResult(); |
va009039 | 9:fecabade834a | 228 | CDummy* m_pCbItem; |
va009039 | 9:fecabade834a | 229 | void (CDummy::*m_pCbMeth)(uint16_t, uint8_t*, int); |
va009039 | 9:fecabade834a | 230 | void (*m_pCb)(uint16_t, uint8_t*, int); |
va009039 | 10:387c49b2fc7e | 231 | protected: |
va009039 | 10:387c49b2fc7e | 232 | USBHost * host; |
va009039 | 10:387c49b2fc7e | 233 | USBDeviceConnected * dev; |
va009039 | 9:fecabade834a | 234 | }; |