USB host library, support isochronous,bulk,interrupt and control.
Dependents: BaseUsbHost_example BaseJpegDecode_example SimpleJpegDecode_example
Import programBaseUsbHost_example
BaseUsbHost example program
Revision 4:d931d24c2f81, committed 2013-01-25
- Comitter:
- va009039
- Date:
- Fri Jan 25 14:51:33 2013 +0000
- Parent:
- 3:ae77d63a1eda
- Child:
- 5:8a2d056e9b38
- Commit message:
- add UsbHub::search()
Changed in this revision
--- a/BaseUsbHost.cpp Sun Jan 06 11:45:18 2013 +0000 +++ b/BaseUsbHost.cpp Fri Jan 25 14:51:33 2013 +0000 @@ -1,8 +1,8 @@ -// BaseUsbHost.cpp 2012/12/25 +// BaseUsbHost.cpp 2013/1/25 #include "mbed.h" #include "rtos.h" #include "BaseUsbHost.h" -#define DEBUG +//#define DEBUG #include "BaseUsbHostDebug.h" #define TEST #include "BaseUsbHostTest.h" @@ -35,16 +35,6 @@ } } -inline static void* malloc_align(size_t size, size_t alignment) -{ - void* p; - int r = posix_memalign(&p, alignment, size); - if (r == 0) { - return p; - } - return NULL; -} - BaseUsbHost::BaseUsbHost() { if (pHost) { @@ -53,7 +43,7 @@ } pHost = this; NVIC_DisableIRQ(USB_IRQn); - m_pHcca = reinterpret_cast<HCCA*>(malloc_align(sizeof(HCCA), 256)); + m_pHcca = new HCCA(); TEST_ASSERT(m_pHcca); init_hw_ohci(m_pHcca); ResetRootHub(); @@ -93,7 +83,7 @@ for (int i = 0; i < 32; i++) { pHcca->InterruptTable[i] = NULL; } - LPC_USB->HcHCCA = (uint32_t)pHcca; + LPC_USB->HcHCCA = reinterpret_cast<uint32_t>(pHcca); LPC_USB->HcInterruptStatus |= LPC_USB->HcInterruptStatus; /* Clear Interrrupt Status */ LPC_USB->HcInterruptEnable = OR_INTR_ENABLE_MIE|OR_INTR_ENABLE_WDH|OR_INTR_ENABLE_FNO; @@ -118,8 +108,8 @@ HCTD* result = NULL; HCTD* next; while(td) { - next = reinterpret_cast<HCTD*>(td->Next); - td->Next = reinterpret_cast<uint32_t>(result); + next = const_cast<HCTD*>(td->Next); + td->Next = result; result = td; td = next; } @@ -137,18 +127,24 @@ m_report_FNO++; } if (status & OR_INTR_STATUS_WDH) { - uint32_t done_td = m_pHcca->DoneHead; + union { + HCTD* done_td; + uint32_t lsb; + }; + done_td = const_cast<HCTD*>(m_pHcca->DoneHead); TEST_ASSERT(done_td); m_pHcca->DoneHead = NULL; // reset - if (done_td & 1) { // error ? - done_td &= ~1; + if (lsb & 1) { // error ? + lsb &= ~1; } - HCTD* td = td_reverse(reinterpret_cast<HCTD*>(done_td)); + HCTD* td = td_reverse(done_td); while(td) { - BaseEp* ep = reinterpret_cast<BaseEp*>(td->ep); + BaseEp* ep = td->ep; TEST_ASSERT(ep); - ep->irqWdhHandler(td); - td = reinterpret_cast<HCTD*>(td->Next); + if (ep) { + ep->irqWdhHandler(td); + } + td = td->Next; } m_report_WDH++; } @@ -158,36 +154,26 @@ BaseEp::BaseEp(int addr, uint8_t ep, uint16_t size, int lowSpeed):m_td_queue_count(0) { DBG("%p FA=%d EN=%02x MPS=%d S=%d\n", this, addr, ep, size, lowSpeed); - m_pED = reinterpret_cast<HCED*>(malloc_align(sizeof(HCED), 16)); - TEST_ASSERT(m_pED); TEST_ASSERT(size >= 8 && size <= 1023); TEST_ASSERT(lowSpeed == 0 || lowSpeed == 1); - m_pED->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 */ - m_pED->Next = NULL; + m_pED = new HCED(addr, ep, size, lowSpeed); + TEST_ASSERT(m_pED); } int BaseEp::GetAddr() { - HCED* ed = m_pED; - TEST_ASSERT(ed); - if (ed) { - return ed->Control & 0x7f; + TEST_ASSERT(m_pED); + if (m_pED) { + return m_pED->FunctionAddress(); } return 0; } int BaseEp::GetLowSpeed() { - HCED* ed = m_pED; - TEST_ASSERT(ed); - if (ed) { - if (ed->Control & (1<<13)) { - return 1; - } + TEST_ASSERT(m_pED); + if (m_pED) { + return m_pED->Speed(); } return 0; } @@ -195,19 +181,19 @@ void BaseEp::update_FunctionAddress(int addr) { TEST_ASSERT(addr >= 0 && addr <= 127); - HCED* ed = m_pED; - TEST_ASSERT(ed); - ed->Control &= ~0x7f; - ed->Control |= addr; + TEST_ASSERT(m_pED); + if (m_pED) { + m_pED->setFunctionAddress(addr); + } } void BaseEp::update_MaxPacketSize(uint16_t size) { TEST_ASSERT(size >= 8 && size <= 1023); - HCED* ed = m_pED; - TEST_ASSERT(ed); - ed->Control &= ~0xffff0000; - ed->Control |= size<<16; + TEST_ASSERT(m_pED); + if (m_pED) { + m_pED->setMaxPacketSize(size); + } } int BaseEp::transfer(uint8_t* buf, int len) @@ -217,16 +203,13 @@ if (data_td == NULL) { return USB_ERROR; } - data_td->CurrBufPtr = buf; - data_td->buf_top = buf; - data_td->buf_size = len; - data_td->BufEnd = const_cast<uint8_t*>(buf)+len-1; - HCTD* blank_td = new_HCTD(); + data_td->transfer(buf, len); + HCTD* blank_td = new HCTD(this); TEST_ASSERT(blank_td); if (blank_td == NULL) { return USB_ERROR_MEMORY; } - data_td->Next = reinterpret_cast<uint32_t>(blank_td); + data_td->Next = blank_td; m_pED->TailTd = blank_td; enable(); return USB_PROCESSING; @@ -238,16 +221,13 @@ if (td == NULL) { return USB_PROCESSING; } - uint8_t cc = td->Control>>28; + uint8_t cc = td->ConditionCode(); int ret; switch(cc) { case 0: case 8: case 9: - ret = td->buf_size; - if (td->CurrBufPtr) { - ret = td->CurrBufPtr - td->buf_top; - } + ret = td->status(); break; case 4: ret = USB_ERROR_STALL; @@ -260,7 +240,7 @@ ret = USB_ERROR; break; } - delete_HCTD(td); + delete td; return ret; } @@ -281,33 +261,6 @@ return ret; } -HCTD* BaseEp::new_HCTD(int buf_size) -{ - HCTD* td; - int r = posix_memalign(reinterpret_cast<void**>(&td), 16, sizeof(HCTD) + buf_size); - if (r == 0) { - td->Control = TD_CC|TD_ROUNDING; - td->Next = NULL; - td->ep = this; - td->buf_top = NULL; - td->buf_size = buf_size; - if (buf_size == 0) { - td->CurrBufPtr = NULL; - td->BufEnd = NULL; - } else { - td->CurrBufPtr = td->buf; - td->BufEnd = const_cast<uint8_t*>(td->buf)+buf_size-1; - } - return td; - } - return NULL; -} - -void BaseEp::delete_HCTD(HCTD* p) -{ - free(p); -} - HCTD* BaseEp::get_queue_HCTD(uint32_t millisec) { for(int i = 0; i < 16; i++) { @@ -315,8 +268,9 @@ if (evt.status == osEventMessage) { HCTD* td = reinterpret_cast<HCTD*>(evt.value.p); TEST_ASSERT(td); - if (td->Control & TD_CC) { - m_ConditionCode = td->Control>>28; + uint8_t cc = td->ConditionCode(); + if (cc != 0) { + m_ConditionCode = cc; DBG_TD(td); } return td; @@ -337,10 +291,10 @@ for(int i = 0; i < 16; i++) { HCTD* td = get_queue_HCTD(millisec); if (td) { - if (td->Control & TD_CC) { - uint8_t cc = td->Control>>28; + uint8_t cc = td->ConditionCode(); + if (cc != 0) { DBG_TD(td); - delete_HCTD(td); + delete td; switch(cc) { case 4: return USB_ERROR_STALL; @@ -348,7 +302,7 @@ return USB_ERROR; } } - delete_HCTD(td); + delete td; if (td == wait_td) { return USB_OK; }
--- a/BaseUsbHost.h Sun Jan 06 11:45:18 2013 +0000 +++ b/BaseUsbHost.h Fri Jan 25 14:51:33 2013 +0000 @@ -1,4 +1,4 @@ -// BaseUsbHost.h 2013/1/5 +// BaseUsbHost.h 2013/1/24 #pragma once #include <vector> @@ -33,7 +33,7 @@ #define SET_INTERFACE 11 #pragma pack(push,1) -typedef struct { // offset +struct StandardDeviceDescriptor {// offset uint8_t bLength; // +0 uint8_t bDescriptorType; // +1 uint16_t bcdUSB; // +2 @@ -48,9 +48,9 @@ uint8_t iProduct; // +15 uint8_t iSerialNumber; // +16 uint8_t bNumConfigurations; // +17 -} StandardDeviceDescriptor; // +18 +}; // +18 -typedef struct { // offset +struct StandardConfigurationDescriptor {// offset uint8_t bLength; // +0 uint8_t bDescriptorType; // +1 uint16_t wTotalLength; // +2 @@ -59,9 +59,9 @@ uint8_t iConfiguration; // +6 uint8_t bmAttributes; // +7 uint8_t bMaxPower; // +8 -} StandardConfigurationDescriptor; // +9 +}; // +9 -typedef struct { // offset +struct StandardInterfaceDescriptor {// offset uint8_t bLength; // +0 uint8_t bDescriptorType; // +1 uint8_t bInterfaceNumber; // +2 @@ -71,18 +71,18 @@ uint8_t bInterfaceSubClass;// +6 uint8_t bInterfaceProtocol;// +7 uint8_t iInterface; // +8 -} StandardInterfaceDescriptor; // +9 +}; // +9 -typedef struct { // offset +struct StandardEndpointDescriptor {// offset uint8_t bLength; // +0 uint8_t bDescriptorType; // +1 uint8_t bEndpointAddress; // +2 uint8_t bmAttributes; // +3 uint16_t wMaxPacketSize; // +4 uint8_t bInterval; // +6 -} StandardEndpointDescriptor; // +7 +}; // +7 -typedef struct { // offset +struct HubDescriptor { // offset uint8_t bDescLength; // +0 uint8_t bDescriptorType; // +1 uint8_t bNbrPorts; // +2 @@ -91,7 +91,7 @@ uint8_t bHubContrCurrent; // +6 uint8_t DeviceRemovable; // +7 uint8_t PortPweCtrlMak; // +8 -} HubDescriptor; // +9 +}; // +9 #pragma pack(pop) // ------------------ HcControl Register --------------------- @@ -135,44 +135,150 @@ #define TD_TOGGLE_1 (uint32_t)(0x03000000) /* Toggle 1 */ #define TD_CC (uint32_t)(0xF0000000) /* Completion Code */ -typedef struct { // Host Controller Communication Area - uint32_t InterruptTable[32]; // Interrupt Table - __IO uint16_t FrameNumber; // Frame Number - __IO uint16_t Pad1; - __IO uint32_t DoneHead; // Done Head - uint8_t Reserved[116]; // Reserved for future use - uint8_t Unknown[4]; // Unused -} HCCA; +class BaseEp; +struct HCTD { // HostController Transfer Descriptor + __IO uint32_t Control; // +0 Transfer descriptor control + __IO uint8_t* CurrBufPtr; // +4 Physical address of current buffer pointer + HCTD* Next; // +8 Physical pointer to next Transfer Descriptor + uint8_t* BufEnd; // +12 Physical address of end of buffer + uint8_t* buf_top; // +16 Buffer start address + uint16_t buf_size; // +20 buffer size size + uint8_t _dummy[10]; // +22 dummy + BaseEp* ep; // +32 endpoint object + // +36 + HCTD(BaseEp* obj); + inline void* operator new(size_t size) { + void* p; + if (posix_memalign(&p, 16, size) == 0) { + return p; + } + return NULL; + } -typedef struct { // HostController Transfer Descriptor - __IO uint32_t Control; // +0 Transfer descriptor control - __IO uint8_t* CurrBufPtr; // +4 Physical address of current buffer pointer - __IO uint32_t Next; // +8 Physical pointer to next Transfer Descriptor - uint8_t* BufEnd; // +12 Physical address of end of buffer - uint8_t* buf_top; // +16 Buffer start address - uint16_t buf_size; // +20 buffer size size - uint8_t setup[8]; // +22 setup cmd area - uint8_t _dummy[2]; // +30 dummy - void *ep; // +32 endpoint object - __IO uint8_t buf[0]; // +36 buffer -} HCTD; // +36 + inline void operator delete(void* p) { + free(p); + } + + inline void transfer(uint8_t* data, int len) { + CurrBufPtr = data; + buf_top = data; + buf_size = len; + BufEnd = const_cast<uint8_t*>(data)+len-1; + } -typedef struct { // HostController Isochronous Transfer Descriptor + inline int status() { + if (CurrBufPtr) { + return CurrBufPtr - buf_top; + } + return buf_size; + } + + inline uint8_t ConditionCode() { + return Control>>28; + } +}; + +struct HCITD { // HostController Isochronous Transfer Descriptor __IO uint32_t Control; // +0 Transfer descriptor control uint8_t* BufferPage0; // +4 Buffer Page 0 - __IO uint32_t Next; // +8 Physical pointer to next Transfer Descriptor + HCITD* Next; // +8 Physical pointer to next Isochronous Transfer Descriptor uint8_t* BufferEnd; // +12 buffer End __IO uint16_t OffsetPSW[8]; // +16 Offset/PSW - void *ep; // +32 endpoint object + BaseEp* ep; // +32 endpoint object __IO uint8_t buf[0]; // +36 buffer -} HCITD; // +36 + // +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); + } -typedef struct { // HostController EndPoint Descriptor + 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 - uint32_t Next; // +12 Physical address of next Endpoint descriptor -} HCED; + 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); + } +}; class BaseUsbHost { public: @@ -203,8 +309,6 @@ int status(uint32_t millisec=osWaitForever); // virtual void enable() = 0; - HCTD* new_HCTD(int buf_size=0); - void delete_HCTD(HCTD* p); virtual void irqWdhHandler(HCTD* td) {m_queue.put(td);} // WDH int wait_queue_HCTD(HCTD* wait_td, uint32_t millisec=osWaitForever); // report @@ -231,7 +335,6 @@ int controlReceive(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t* data, int length); private: int open(int addr); - void setup(HCTD* td, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex=0, uint16_t wLength=0); virtual void enable(){}; }; @@ -259,9 +362,9 @@ HCITD* isochronousReveive(int millisec=osWaitForever); int isochronousSend(uint8_t* buf, int len, int millisec=osWaitForever); HCITD* get_queue_HCITD(int millisec); - int m_PacketSize; // 128,192 + uint16_t m_PacketSize; private: - HCITD* new_HCITD(); + HCITD* new_HCITD(BaseEp* obj); int m_itd_queue_count; uint16_t m_FrameNumber; int m_FrameCount; // 1-8 @@ -276,6 +379,22 @@ int SetPortPower(int port); int ClearPortPower(int port); vector<ControlEp*> PortEp; + template<class T> ControlEp* search(int skip = 0) { + for(vector<ControlEp*>::iterator it = PortEp.begin(); it != PortEp.end(); ++it) { + if (T::check(*it)) { + if (skip-- <= 0) { + return *it; + } + } + } + return NULL; + } + template<class T> ControlEp* assign(int port) { + if (port >= 0 && port < PortEp.size()) { + return PortEp[port]; + } + return NULL; + } private: int PortReset(int port); int SetPortFeature(int feature, int index);
--- a/BaseUsbHostBlkEp.cpp Sun Jan 06 11:45:18 2013 +0000 +++ b/BaseUsbHostBlkEp.cpp Fri Jan 25 14:51:33 2013 +0000 @@ -1,22 +1,22 @@ -// BaseUsbHostBlkEp.cpp 2012/12/24 +// BaseUsbHostBlkEp.cpp 2013/1/25 #include "mbed.h" #include "rtos.h" #include "BaseUsbHost.h" -#define DEBUG +//#define DEBUG #include "BaseUsbHostDebug.h" #define TEST #include "BaseUsbHostTest.h" BulkEp::BulkEp(int addr, uint8_t ep, uint16_t size): BaseEp(addr, ep, size) { - HCTD* td = new_HCTD(); + HCTD* td = new HCTD(this); m_pED->TailTd = td; m_pED->HeadTd = td; TEST_ASSERT(td); if (td == NULL) { return; } - m_pED->Next = LPC_USB->HcBulkHeadED; + m_pED->Next = reinterpret_cast<HCED*>(LPC_USB->HcBulkHeadED); LPC_USB->HcBulkHeadED = reinterpret_cast<uint32_t>(m_pED); DBG_OHCI(LPC_USB->HcBulkHeadED);
--- a/BaseUsbHostCtlEp.cpp Sun Jan 06 11:45:18 2013 +0000 +++ b/BaseUsbHostCtlEp.cpp Fri Jan 25 14:51:33 2013 +0000 @@ -1,22 +1,43 @@ -// BaseUsbHostCtlEp.cpp 2013/1/2 +// BaseUsbHostCtlEp.cpp 2013/1/25 #include "mbed.h" #include "rtos.h" #include "BaseUsbHost.h" -#define DEBUG +//#define DEBUG #include "BaseUsbHostDebug.h" #define TEST #include "BaseUsbHostTest.h" +#pragma pack(push,1) +struct SETUP { + uint8_t bmRequestType;// +0 + uint8_t bRequest; // +1 + uint16_t wValue; // +2 + uint16_t wIndex; // +4 + uint16_t wLength; // +6 + // +8 + SETUP(uint8_t RequestType, uint8_t Request, uint16_t Value, uint16_t Index, uint16_t Length) { + CTASSERT(sizeof(SETUP) == 8); + TEST_ASSERT(sizeof(SETUP) == 8); + bmRequestType = RequestType; + bRequest = Request; + wValue = Value; + wIndex = Index; + wLength = Length; + }; +}; +#pragma pack(pop) + static uint8_t device_addr = 1; ControlEp::ControlEp(int lowSpeed):BaseEp(0, 0, 8, lowSpeed) { + CTASSERT(HCTD_QUEUE_SIZE >= 3); TEST_ASSERT(HCTD_QUEUE_SIZE >= 3); - HCTD* td = new_HCTD(); + HCTD* td = new HCTD(this); TEST_ASSERT(td); m_pED->TailTd = td; m_pED->HeadTd = td; - m_pED->Next = LPC_USB->HcControlHeadED; + m_pED->Next = reinterpret_cast<HCED*>(LPC_USB->HcControlHeadED); LPC_USB->HcControlHeadED = reinterpret_cast<uint32_t>(m_pED); DBG_OHCI(LPC_USB->HcControlHeadED); @@ -71,7 +92,6 @@ TEST_ASSERT(addr >= 1 && addr <= 127); uint8_t buf[8]; int r = GetDescriptor(1, 0, buf, 8); - TEST_ASSERT(r == USB_OK); if (r != USB_OK) { return r; } @@ -93,36 +113,36 @@ uint8_t* data, int length) { DBG("Type: %02X Request: %02X Value: %04X Index: %04X %p %d\n", bmRequestType, bRequest, wValue, wIndex, data, length); HCTD* setup_td = m_pED->TailTd; - setup(setup_td, bmRequestType, bRequest, wValue, wIndex, length); - setup_td->Control |= TD_DI; + SETUP setup(bmRequestType, bRequest, wValue, wIndex, length); + setup_td->transfer(reinterpret_cast<uint8_t*>(&setup), sizeof(SETUP)); + setup_td->Control |= TD_TOGGLE_0|TD_SETUP|TD_DI; - HCTD* data_td = new_HCTD(length); + HCTD* data_td = new HCTD(this); TEST_ASSERT(data_td); + data_td->transfer(data, length); data_td->Control |= TD_TOGGLE_1|TD_IN|TD_DI; - setup_td->Next = reinterpret_cast<uint32_t>(data_td); + setup_td->Next = data_td; - HCTD* status_td = new_HCTD(); + HCTD* status_td = new HCTD(this); TEST_ASSERT(status_td); status_td->Control |= TD_TOGGLE_1|TD_OUT; // OUT(DATA1) - data_td->Next = reinterpret_cast<uint32_t>(status_td); + data_td->Next = status_td; - HCTD* blank_td = new_HCTD(); + HCTD* blank_td = new HCTD(this); TEST_ASSERT(blank_td); - status_td->Next = reinterpret_cast<uint32_t>(blank_td); + status_td->Next = blank_td; m_pED->TailTd = blank_td; LPC_USB->HcCommandStatus |= OR_CMD_STATUS_CLF; LPC_USB->HcControl |= OR_CONTROL_CLE; int r = wait_queue_HCTD(setup_td, 100); // wait setup stage - TEST_ASSERT(r == USB_OK); if (r != USB_OK) { return r; } HCTD* td = get_queue_HCTD(100); if (td == data_td) { - memcpy(data, const_cast<uint8_t*>(td->buf), length); - delete_HCTD(td); + delete td; } else { DBG_TD(td); TEST_ASSERT(td == data_td); @@ -137,24 +157,26 @@ const uint8_t* data, int length) { DBG("Type: %02X Request: %02X Value: %04X Index: %04X %p %d\n", bmRequestType, bRequest, wValue, wIndex, data, length); HCTD* setup_td = m_pED->TailTd; - setup(setup_td, bmRequestType, bRequest, wValue, wIndex, length); - HCTD* status_td = new_HCTD(); + HCTD* status_td = new HCTD(this); TEST_ASSERT(status_td); - HCTD* blank_td = new_HCTD(); + HCTD* blank_td = new HCTD(this); TEST_ASSERT(blank_td); - setup_td->Control |= TD_DI; + + SETUP setup(bmRequestType, bRequest, wValue, wIndex, length); + setup_td->transfer(reinterpret_cast<uint8_t*>(&setup), sizeof(SETUP)); + setup_td->Control |= TD_TOGGLE_0|TD_SETUP|TD_DI; status_td->Control |= TD_TOGGLE_1|TD_IN; // IN(DATA1) - setup_td->Next = reinterpret_cast<uint32_t>(status_td); - status_td->Next = reinterpret_cast<uint32_t>(blank_td); + setup_td->Next = status_td; + status_td->Next = blank_td; if (length != 0) { - HCTD* data_td = new_HCTD(length); + HCTD* data_td = new HCTD(this); TEST_ASSERT(data_td); data_td->Control |= TD_TOGGLE_1|TD_OUT|TD_DI; - memcpy(const_cast<uint8_t*>(data_td->buf), data, length); - setup_td->Next = reinterpret_cast<uint32_t>(data_td); - data_td->Next = reinterpret_cast<uint32_t>(status_td); + data_td->transfer(const_cast<uint8_t*>(data), length); + setup_td->Next = data_td; + data_td->Next = status_td; } m_pED->TailTd = blank_td; DBG_ED(m_pED); @@ -167,18 +189,15 @@ return r; } -void ControlEp::setup(HCTD* td, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, - uint16_t wIndex, uint16_t wLength) -{ - td->setup[0] = bmRequestType; - td->setup[1] = bRequest; - td->setup[2] = wValue; - td->setup[3] = wValue>>8; - td->setup[4] = wIndex; - td->setup[5] = wIndex>>8; - td->setup[6] = wLength; - td->setup[7] = wLength>>8; - td->Control |= TD_TOGGLE_0|TD_SETUP; - td->CurrBufPtr = td->setup; - td->BufEnd = td->setup+8-1; +HCTD::HCTD(BaseEp* obj) { + CTASSERT(sizeof(HCTD) == 36); + TEST_ASSERT(sizeof(HCTD) == 36); + TEST_ASSERT(obj); + Control = TD_CC|TD_ROUNDING; + CurrBufPtr = NULL; + Next = NULL; + BufEnd = NULL; + buf_top = NULL; + buf_size = 0; + ep = obj; }
--- a/BaseUsbHostDebug.cpp Sun Jan 06 11:45:18 2013 +0000 +++ b/BaseUsbHostDebug.cpp Fri Jan 25 14:51:33 2013 +0000 @@ -1,14 +1,9 @@ -// BaseUseHostDebug.cpp 2012/12/4 +// BaseUseHostDebug.cpp 2013/1/11 #include "mbed.h" #include "rtos.h" #include "BaseUsbHost.h" #include "BaseUsbHostDebug.h" -#define OHCI_REG_READ(REG) (LPC_USB->##REG) -#define OHCI_REG_WRITE(REG,B) LPC_USB->##REG = (B) -#define OHCI_REG_OR(REG,B) LPC_USB->##REG |= (B) -#define OHCI_REG_AND(REG,B) LPC_USB->##REG &= (B) - void print_td(FILE* stream, HCTD* td) { if (td == NULL) { @@ -17,11 +12,7 @@ } uint32_t* p = reinterpret_cast<uint32_t*>(td); fprintf(stream, "TD %p: %08X %08X %08X %08X", p, p[0], p[1], p[2], p[3]); - fprintf(stream, " ep=%p", td->ep); - for(int i = 0; i < 8; i++) { - fprintf(stream, " %02X", td->buf[i]); - } - fprintf(stream, "\n"); + fprintf(stream, " ep=%p\n", td->ep); uint8_t* bp = reinterpret_cast<uint8_t*>(p[1]); uint8_t* be = reinterpret_cast<uint8_t*>(p[3]); if (bp) { @@ -43,7 +34,7 @@ HCTD* tdtail = reinterpret_cast<HCTD*>(p[1]); while(td != NULL && td != tdtail) { print_td(stream, td); - td = reinterpret_cast<HCTD*>(td->Next); + td = td->Next; } p = reinterpret_cast<uint32_t*>(p[3]); } @@ -72,7 +63,7 @@ HCITD* itdtail = reinterpret_cast<HCITD*>(p[1]); while(itd != NULL && itd != itdtail) { print_itd(stream, itd); - itd = reinterpret_cast<HCITD*>(itd->Next); + itd = itd->Next; } p = reinterpret_cast<uint32_t*>(p[3]); }
--- a/BaseUsbHostHub.cpp Sun Jan 06 11:45:18 2013 +0000 +++ b/BaseUsbHostHub.cpp Fri Jan 25 14:51:33 2013 +0000 @@ -1,8 +1,8 @@ -// BaseUsbHostHub.cpp 2013/1/6 +// BaseUsbHostHub.cpp 2013/1/25 #include "mbed.h" #include "rtos.h" #include "BaseUsbHost.h" -#define DEBUG +//#define DEBUG #include "BaseUsbHostDebug.h" #define TEST #include "BaseUsbHostTest.h" @@ -34,17 +34,17 @@ } else { m_ctlEp = ctlEp; } - uint8_t desc[9]; - int rc = m_ctlEp->GetDescriptor(1, 0, desc, sizeof(desc)); + CTASSERT(sizeof(StandardDeviceDescriptor) == 18); + StandardDeviceDescriptor devdesc; + int rc = m_ctlEp->GetDescriptor(1, 0, reinterpret_cast<uint8_t*>(&devdesc), sizeof(StandardDeviceDescriptor)); TEST_ASSERT(rc == USB_OK); if (rc != USB_OK) { return; } - DBG_HEX(desc, sizeof(desc)); - TEST_ASSERT_TRUE(desc[0] == 0x12); - TEST_ASSERT_TRUE(desc[1] == 0x01); - TEST_ASSERT_TRUE(desc[4] == 0x09); // hub - if (desc[4] != 0x09) { // hub ? + TEST_ASSERT_TRUE(devdesc.bLength == 0x12); + TEST_ASSERT_TRUE(devdesc.bDescriptorType == 0x01); + TEST_ASSERT_TRUE(devdesc.bDeviceClass == 0x09); // hub + if (devdesc.bDeviceClass != 0x09) { // hub ? return; } CTASSERT(sizeof(HubDescriptor) == 9); @@ -58,7 +58,7 @@ TEST_ASSERT(hubdesc.bDescLength == 9); // length TEST_ASSERT(hubdesc.bDescriptorType == 0x29); // hub TEST_ASSERT(hubdesc.bNbrPorts >= 1); - TEST_ASSERT(hubdesc.bNbrPorts <= 7); + TEST_ASSERT(hubdesc.bNbrPorts <= 16); m_ctlEp->SetConfiguration(1);
--- a/BaseUsbHostIntEp.cpp Sun Jan 06 11:45:18 2013 +0000 +++ b/BaseUsbHostIntEp.cpp Fri Jan 25 14:51:33 2013 +0000 @@ -10,7 +10,7 @@ InterruptEp::InterruptEp(int addr, uint8_t ep, uint16_t size, int lowSpeed) :BaseEp(addr, ep, size, lowSpeed) { - HCTD* td = new_HCTD(); + HCTD* td = new HCTD(this); m_pED->HeadTd = td; m_pED->TailTd = td; TEST_ASSERT(td); @@ -24,7 +24,7 @@ } int n = 0; m_pED->Next = pHcca->InterruptTable[n]; - pHcca->InterruptTable[n] = reinterpret_cast<uint32_t>(m_pED); + pHcca->InterruptTable[n] = m_pED; DBG_ED(m_pED); }
--- a/BaseUsbHostIsoEp.cpp Sun Jan 06 11:45:18 2013 +0000 +++ b/BaseUsbHostIsoEp.cpp Fri Jan 25 14:51:33 2013 +0000 @@ -1,12 +1,32 @@ -// BaseUsbHostIsoEp.cpp 2012/12/31 +// BaseUsbHostIsoEp.cpp 2013/1/25 #include "mbed.h" #include "rtos.h" #include "BaseUsbHost.h" -#define DEBUG +//#define DEBUG #include "BaseUsbHostDebug.h" #define TEST #include "BaseUsbHostTest.h" +HCITD::HCITD(BaseEp* obj, uint16_t FrameNumber, int FrameCount, uint16_t PacketSize) { + Control = 0xe0000000 | // CC ConditionCode NOT ACCESSED + ((FrameCount-1) << 24)| // FC FrameCount + TD_DELAY_INT(0) | // DI DelayInterrupt + FrameNumber; // SF StartingFrame + BufferPage0 = const_cast<uint8_t*>(buf); + BufferEnd = const_cast<uint8_t*>(buf) + PacketSize * FrameCount - 1; + Next = NULL; + ep = obj; + uint32_t addr = reinterpret_cast<uint32_t>(buf); + for(int i = 0; i < FrameCount; i++) { + uint16_t offset = addr & 0x0fff; + if ((addr&0xfffff000) == (reinterpret_cast<uint32_t>(BufferEnd)&0xfffff000)) { + offset |= 0x1000; + } + OffsetPSW[i] = 0xe000|offset; + addr += PacketSize; + } +} + IsochronousEp::IsochronousEp(int addr, uint8_t ep, uint16_t size):BaseEp(addr, ep, size) { DBG("%p FA:%d EP:%02X MPS:%d\n", this, addr, ep, size); @@ -20,7 +40,7 @@ TEST_ASSERT(m_FrameCount >= 1 && m_FrameCount <= 8); m_itd_queue_count = 0; reset(); - HCITD* itd = new_HCITD(); + HCITD* itd = new_HCITD(this); m_pED->TailTd = reinterpret_cast<HCTD*>(itd); m_pED->HeadTd = reinterpret_cast<HCTD*>(itd); TEST_ASSERT(itd); @@ -33,14 +53,14 @@ return; } for(int i = 0; i < 32; i++) { - if (hcca->InterruptTable[i] == 0) { - hcca->InterruptTable[i] = reinterpret_cast<uint32_t>(m_pED); + if (hcca->InterruptTable[i] == NULL) { + hcca->InterruptTable[i] = m_pED; } else { - HCED* nextEd = reinterpret_cast<HCED*>(hcca->InterruptTable[i]); - while(nextEd->Next && nextEd->Next != reinterpret_cast<uint32_t>(m_pED)) { - nextEd = reinterpret_cast<HCED*>(nextEd->Next); + HCED* nextEd = hcca->InterruptTable[i]; + while(nextEd->Next && nextEd->Next != m_pED) { + nextEd = nextEd->Next; } - nextEd->Next = reinterpret_cast<uint32_t>(m_pED); + nextEd->Next = m_pED; } } DBG_ED(m_pED); @@ -51,31 +71,12 @@ m_FrameNumber = LPC_USB->HcFmNumber + delay_ms; } -HCITD* IsochronousEp::new_HCITD() +HCITD* IsochronousEp::new_HCITD(BaseEp* obj) { - HCITD* itd; - int r = posix_memalign(reinterpret_cast<void**>(&itd), 32, sizeof(HCITD)+m_PacketSize*m_FrameCount); - if (r != 0) { + HCITD* itd = new(m_PacketSize*m_FrameCount)HCITD(obj, m_FrameNumber, m_FrameCount, m_PacketSize); + if (itd == NULL) { return NULL; } - int di = 0; //DelayInterrupt - itd->Control = 0xe0000000 | // CC ConditionCode NOT ACCESSED - ((m_FrameCount-1) << 24)| // FC FrameCount - TD_DELAY_INT(di) | // DI DelayInterrupt - m_FrameNumber; // SF StartingFrame - itd->BufferPage0 = const_cast<uint8_t*>(itd->buf); - itd->BufferEnd = const_cast<uint8_t*>(itd->buf) + m_PacketSize * m_FrameCount - 1; - itd->Next = NULL; - itd->ep = this; - uint32_t addr = reinterpret_cast<uint32_t>(itd->buf); - for(int i = 0; i < m_FrameCount; i++) { - uint16_t offset = addr & 0x0fff; - if ((addr&0xfffff000) == (reinterpret_cast<uint32_t>(itd->BufferEnd)&0xfffff000)) { - offset |= 0x1000; - } - itd->OffsetPSW[i] = 0xe000|offset; - addr += m_PacketSize; - } m_FrameNumber += m_FrameCount; return itd; } @@ -89,12 +90,12 @@ if (itd == NULL) { return NULL; } - HCITD* blank_itd = new_HCITD(); + HCITD* blank_itd = new_HCITD(this); TEST_ASSERT(blank_itd); if (blank_itd == NULL) { return NULL; } - itd->Next = reinterpret_cast<uint32_t>(blank_itd); + itd->Next = blank_itd; m_pED->TailTd = reinterpret_cast<HCTD*>(blank_itd); m_itd_queue_count++; //DBG_IED(m_pED); @@ -115,13 +116,6 @@ if (evt.status == osEventMessage) { HCITD* itd = reinterpret_cast<HCITD*>(evt.value.p); TEST_ASSERT(itd); - if (itd == NULL) { - return NULL; - } - uint8_t cc = itd->Control>>28; - if (cc != 0) { - m_ConditionCode = cc; - } return itd; } else if (evt.status == osOK) { continue;
--- a/BaseUsbHostUvc.cpp Sun Jan 06 11:45:18 2013 +0000 +++ b/BaseUsbHostUvc.cpp Fri Jan 25 14:51:33 2013 +0000 @@ -1,4 +1,4 @@ -// BaseUsbHostUvc.cpp 2012/12/11 +// BaseUsbHostUvc.cpp 2013/1/11 #include "mbed.h" #include "rtos.h" #include "BaseUsbHost.h" @@ -11,19 +11,18 @@ { HCITD* itd = m_isoEp->isochronousReveive(millisec); if (itd) { - uint8_t cc = itd->Control>>28; + uint8_t cc = itd->ConditionCode(); report_cc_count[cc]++; - if (cc == 0) { // ConditionCode - //DBG_ITD(itd); - uint16_t frame = itd->Control & 0xffff; - int fc = ((itd->Control>>24)&7)+1; + if (cc == 0) { + uint16_t frame = itd->StartingFrame(); + int fc = itd->FrameCount(); uint8_t* buf = const_cast<uint8_t*>(itd->buf); int mps = m_isoEp->m_PacketSize; for(int i = 0; i < fc; i++) { - uint16_t pswn = itd->OffsetPSW[i]; - cc = pswn>>12; + uint16_t psw = itd->OffsetPSW[i]; + cc = psw>>12; if (cc == 0 || cc == 9) { - int len = pswn & 0x7ff; + int len = psw & 0x7ff; onResult(frame, buf, len); } report_ps_cc_count[cc]++; @@ -31,13 +30,16 @@ frame++; } } - m_isoEp->delete_HCTD(reinterpret_cast<HCTD*>(itd)); + delete itd; } } int BaseUvc::Control(int req, int cs, int index, uint8_t* buf, int size) { TEST_ASSERT(m_ctlEp); + if (m_ctlEp == NULL) { + return USB_ERROR; + } int rc; if (req == SET_CUR) { rc = m_ctlEp->controlSend( @@ -72,4 +74,3 @@ m_pCbItem = NULL; m_pCbMeth = NULL; } -