testing n-Bed with a Logitech C270 camera

Dependencies:   USBHost mbed

Fork of USBHostC270_example by Norimasa Okamoto

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);
+};