testing n-Bed with a Logitech C270 camera
Fork of USBHostC270_example by
Diff: USBHostC270/BaseUvc.h
- Revision:
- 9:fecabade834a
- Child:
- 10:387c49b2fc7e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBHostC270/BaseUvc.h Sat Mar 16 13:07:55 2013 +0000 @@ -0,0 +1,171 @@ +#pragma once + +class BaseEp; +struct HCITD { // HostController Isochronous Transfer Descriptor + __IO uint32_t Control; // +0 Transfer descriptor control + uint8_t* BufferPage0; // +4 Buffer Page 0 + HCITD* Next; // +8 Physical pointer to next Isochronous Transfer Descriptor + uint8_t* BufferEnd; // +12 buffer End + __IO uint16_t OffsetPSW[8]; // +16 Offset/PSW + BaseEp* ep; // +32 endpoint object + __IO uint8_t buf[0]; // +36 buffer + // +36 + HCITD(BaseEp* obj, uint16_t FrameNumber, int FrameCount, uint16_t PacketSize); + inline void* operator new(size_t size, int buf_size) { + void* p; + if (posix_memalign(&p, 32, size+buf_size) == 0) { + return p; + } + return NULL; + } + + inline void operator delete(void* p) { + free(p); + } + + inline uint16_t StartingFrame() { + return Control & 0xffff; + } + + inline uint8_t FrameCount() { + return ((Control>>24)&7)+1; + } + + inline uint8_t ConditionCode() { + return Control>>28; + } +}; + +struct _HCED { // 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 + _HCED* Next; // +12 Physical address of next Endpoint descriptor + // +16 + _HCED(int addr, uint8_t ep, uint16_t size, int lowSpeed) { + Control = addr | /* USB address */ + ((ep & 0x7F) << 7) | /* Endpoint address */ + (ep!=0?(((ep&0x80)?2:1) << 11):0)| /* direction : Out = 1, 2 = In */ + ((lowSpeed?1:0) << 13) | /* speed full=0 low=1 */ + (size << 16); /* MaxPkt Size */ + Next = NULL; + } + + inline void* operator new(size_t size) { + void* p; + if (posix_memalign(&p, 16, size) == 0) { + return p; + } + return NULL; + } + + inline void operator delete(void* p) { + free(p); + } + + inline uint8_t FunctionAddress() { + return Control & 0x7f; + } + + inline int Speed() { + return (Control>>13)&1; + } + + inline void setFunctionAddress(int addr) { + Control &= ~0x7f; + Control |= addr; + } + + inline void setMaxPacketSize(uint16_t size) { + Control &= ~0xffff0000; + Control |= size<<16; + } +}; + +struct _HCCA { // Host Controller Communication Area + _HCED* InterruptTable[32]; // +0 Interrupt Table + __IO uint16_t FrameNumber;// +128 Frame Number + __IO uint16_t Pad1; // +130 + __IO HCTD* DoneHead; // +132 Done Head + uint8_t Reserved[116]; // +136 Reserved for future use + uint8_t Unknown[4]; // +252 Unused + // +256 + inline void* operator new(size_t size) { + void* p; + if (posix_memalign(&p, 256, size) == 0) { + return p; + } + return NULL; + } + + inline void operator delete(void* p) { + free(p); + } +}; + +#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); + int transfer(uint8_t* buf, int len); + int status(uint32_t millisec=osWaitForever); + // + virtual void enable() = 0; + virtual void irqWdhHandler(HCTD* td) {m_queue.put(td);} // WDH + int wait_queue_HCTD(HCTD* wait_td, uint32_t millisec=osWaitForever); + // report + uint8_t m_ConditionCode; + int m_report_queue_error; +protected: + int send_receive(uint8_t* buf, int len, int millisec); + HCTD* get_queue_HCTD(uint32_t millisec=osWaitForever); + _HCED* m_pED; + Queue<HCTD, HCTD_QUEUE_SIZE> m_queue; // TD done queue + int m_td_queue_count; +}; + +class IsochronousEp : public BaseEp { +public: + IsochronousEp(int addr, uint8_t ep, uint16_t size); + void reset(int delay_ms = 100); + HCITD* isochronousReveive(int millisec=osWaitForever); + int isochronousSend(uint8_t* buf, int len, int millisec=osWaitForever); + HCITD* get_queue_HCITD(int millisec); + uint16_t m_PacketSize; +private: + HCITD* new_HCITD(BaseEp* obj); + int m_itd_queue_count; + uint16_t m_FrameNumber; + int m_FrameCount; // 1-8 + virtual void enable(); +}; + +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); +};