Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: BaseUsbHost_example BaseJpegDecode_example SimpleJpegDecode_example
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;
}
-