USB host library, support isochronous,bulk,interrupt and control.
Dependents: BaseUsbHost_example BaseJpegDecode_example SimpleJpegDecode_example
Import programBaseUsbHost_example
BaseUsbHost example program
Diff: BaseUsbHost.cpp
- Revision:
- 4:d931d24c2f81
- Parent:
- 3:ae77d63a1eda
--- 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; }