USB host library, support isochronous,bulk,interrupt and control.
Dependents: BaseUsbHost_example BaseJpegDecode_example SimpleJpegDecode_example
Import programBaseUsbHost_example
BaseUsbHost example program
Revision 2:fe1e62051d88, committed 2012-12-11
- Comitter:
- va009039
- Date:
- Tue Dec 11 15:26:54 2012 +0000
- Parent:
- 1:3b7bc4f87a61
- Child:
- 3:ae77d63a1eda
- Commit message:
- bug fix
Changed in this revision
--- a/BaseUsbHost.h Wed Dec 05 13:23:06 2012 +0000 +++ b/BaseUsbHost.h Tue Dec 11 15:26:54 2012 +0000 @@ -1,11 +1,11 @@ -// BaseUsbHost.h 2012/12/5 +// BaseUsbHost.h 2012/12/11 #ifndef BASE_USB_HOST_H #define BASE_USB_HOST_H -#define USB_OK 0 -#define USB_ERROR -1 -#define USB_TIMEOUT -2 -#define USB_ERROR2 -3 +#define USB_OK 0 +#define USB_PROCESSING -1 +#define USB_ERROR -2 +#define USB_ERROR_MEMORY -3 // USB STANDARD REQUEST DEFINITIONS #define USB_DESCRIPTOR_TYPE_DEVICE 1 @@ -188,10 +188,10 @@ IsochronousEp(int addr, uint8_t ep, uint16_t size); virtual void irqWdhHandler(HCTD* td); void reset(); - HCITD* isochronousReveive(); - int isochronousSend(uint8_t* buf, int len); + HCITD* isochronousReveive(int millisec=osWaitForever); + int isochronousSend(uint8_t* buf, int len, int millisec=osWaitForever); HCITD* new_HCITD(); - HCITD* get_queue_HCITD(uint32_t millisec); + HCITD* get_queue_HCITD(int millisec); int m_itd_queue_count; uint16_t m_FrameNumber; int m_PacketSize; // 128,192 @@ -204,12 +204,14 @@ class UsbHub { public: UsbHub(ControlEp* ctlEp = NULL); + ControlEp* GetPortEp(int port); // port: 1-4 + int SetPortPower(int port); + int ClearPortPower(int port); +protected: void DeviceConnected(int port, int low_speed); int PortReset(int port); - // int SetPortFeature(int feature, int index); int ClearPortFeature(int feature, int index); - int SetPortPower(int port); int SetPortReset(int port); int GetPortStatus(int port, uint32_t* status); ControlEp* m_ctlEp; @@ -239,7 +241,7 @@ class BaseUvc { public: - void poll(); + void poll(int millisec=osWaitForever); int Control(int req, int cs, int index, uint8_t* buf, int size); ControlEp* m_ctlEp; IsochronousEp* m_isoEp;
--- a/BaseUsbHostBlkEp.cpp Wed Dec 05 13:23:06 2012 +0000 +++ b/BaseUsbHostBlkEp.cpp Tue Dec 11 15:26:54 2012 +0000 @@ -1,4 +1,4 @@ -// BaseUsbHostBlkEp.cpp 2012/12/5 +// BaseUsbHostBlkEp.cpp 2012/12/11 #include "mbed.h" #include "rtos.h" #include "BaseUsbHost.h" @@ -10,10 +10,12 @@ BulkEp::BulkEp(int addr, uint8_t ep, uint16_t size): BaseEp(addr, ep, size) { HCTD* td = new_HCTD(); - TEST_ASSERT(td); m_pED->TailTd = td; m_pED->HeadTd = td; - + TEST_ASSERT(td); + if (td == NULL) { + return; + } m_pED->Next = LPC_USB->HcBulkHeadED; LPC_USB->HcBulkHeadED = reinterpret_cast<uint32_t>(m_pED); @@ -26,44 +28,57 @@ int BulkEp::bulkReceive(uint8_t* buf, int len, int millisec) { - HCTD* data_td = m_pED->TailTd; - TEST_ASSERT(data_td); - data_td->Control |= TD_IN; - data_td->CurrBufPtr = buf; - data_td->BufEnd = const_cast<uint8_t*>(buf)+len-1; - HCTD* blank_td = new_HCTD(); - TEST_ASSERT(blank_td); - data_td->Next = reinterpret_cast<uint32_t>(blank_td); - m_pED->TailTd = blank_td; - m_td_queue_count++; - DBG_ED(m_pED); - - LPC_USB->HcCommandStatus |= OR_CMD_STATUS_BLF; - LPC_USB->HcControl |= OR_CONTROL_BLE; - + if (m_td_queue_count == 0) { + HCTD* data_td = m_pED->TailTd; + TEST_ASSERT(data_td); + if (data_td == NULL) { + return USB_ERROR; + } + data_td->Control |= TD_IN; + data_td->CurrBufPtr = buf; + data_td->BufEnd = const_cast<uint8_t*>(buf)+len-1; + HCTD* blank_td = new_HCTD(); + TEST_ASSERT(blank_td); + if (blank_td == NULL) { + return USB_ERROR_MEMORY; + } + data_td->Next = reinterpret_cast<uint32_t>(blank_td); + m_pED->TailTd = blank_td; + m_td_queue_count++; + DBG_ED(m_pED); + LPC_USB->HcCommandStatus |= OR_CMD_STATUS_BLF; + LPC_USB->HcControl |= OR_CONTROL_BLE; + } + HCTD* td = get_queue_HCTD(millisec); - if (td) { - DBG_TD(td); - int ret = len; - if (td->CurrBufPtr) { - ret = td->CurrBufPtr - buf; - } - delete_HCTD(td); - m_td_queue_count--; - return ret; + if (td == NULL) { + return USB_PROCESSING; } - return USB_ERROR; + DBG_TD(td); + int ret = len; + if (td->CurrBufPtr) { + ret = td->CurrBufPtr - buf; + } + delete_HCTD(td); + m_td_queue_count--; + return ret; } int BulkEp::bulkSend(const uint8_t* buf, int len, int millisec) { HCTD* data_td = m_pED->TailTd; TEST_ASSERT(data_td); + if (data_td == NULL) { + return USB_ERROR; + } data_td->Control |= TD_OUT; data_td->CurrBufPtr = const_cast<uint8_t*>(buf); data_td->BufEnd = const_cast<uint8_t*>(buf)+len-1; HCTD* blank_td = new_HCTD(); TEST_ASSERT(blank_td); + if (blank_td == NULL) { + return USB_ERROR_MEMORY; + } data_td->Next = reinterpret_cast<uint32_t>(blank_td); m_pED->TailTd = blank_td; m_td_queue_count++; @@ -85,4 +100,3 @@ } return USB_ERROR; } -
--- a/BaseUsbHostHub.cpp Wed Dec 05 13:23:06 2012 +0000 +++ b/BaseUsbHostHub.cpp Tue Dec 11 15:26:54 2012 +0000 @@ -1,4 +1,4 @@ -// BaseUsbHostHub.cpp 2012/12/4 +// BaseUsbHostHub.cpp 2012/12/11 #include "mbed.h" #include "rtos.h" #include "BaseUsbHost.h" @@ -21,31 +21,6 @@ #define C_PORT_OVER_CURRENT 19 #define C_PORT_RESET 20 -int UsbHub::SetPortFeature(int feature, int index) -{ - return m_ctlEp->controlSend(0x23, SET_FEATURE,feature,index,0,0); -} - -int UsbHub::ClearPortFeature(int feature, int index) -{ - return m_ctlEp->controlSend(0x23, CLEAR_FEATURE,feature,index,0,0); -} - -int UsbHub::SetPortPower(int port) -{ - return SetPortFeature(PORT_POWER, port); -} - -int UsbHub::SetPortReset(int port) -{ - return SetPortFeature(PORT_RESET, port); -} - -int UsbHub::GetPortStatus(int port, uint32_t* status) -{ - return m_ctlEp->controlReceive(0xa3, GET_STATUS, 0, port, (uint8_t*)status, 4); -} - UsbHub::UsbHub(ControlEp* ctlEp) { for(int i = 0; i < MAX_HUB_PORT; i++) { @@ -86,10 +61,7 @@ DBG("HUB STATUS: %08X\n", status); for(int i = 1; i <= bNbrPorts; i++) { - SetPortFeature(PORT_POWER, i); // power on - } - - for(int i = 1; i <= bNbrPorts; i++) { + SetPortPower(i); // power on uint32_t status; GetPortStatus(i, &status); DBG("port: %d status: %08X\n", i, status); @@ -101,10 +73,50 @@ low_speed = true; } DeviceConnected(i, low_speed); + } else { + ClearPortPower(i); // power on } } } +ControlEp* UsbHub::GetPortEp(int port) +{ + if (port >= 1 && port <= MAX_HUB_PORT) { + return PortEp[port-1]; + } + return NULL; +} + +int UsbHub::SetPortPower(int port) +{ + return SetPortFeature(PORT_POWER, port); +} + +int UsbHub::ClearPortPower(int port) +{ + return ClearPortFeature(PORT_POWER, port); +} + +int UsbHub::SetPortFeature(int feature, int index) +{ + return m_ctlEp->controlSend(0x23, SET_FEATURE,feature,index,0,0); +} + +int UsbHub::ClearPortFeature(int feature, int index) +{ + return m_ctlEp->controlSend(0x23, CLEAR_FEATURE,feature,index,0,0); +} + +int UsbHub::SetPortReset(int port) +{ + return SetPortFeature(PORT_RESET, port); +} + +int UsbHub::GetPortStatus(int port, uint32_t* status) +{ + return m_ctlEp->controlReceive(0xa3, GET_STATUS, 0, port, (uint8_t*)status, 4); +} + void UsbHub::DeviceConnected(int port, int low_speed) { DBG("port=%d low_speed=%d\n", port, low_speed);
--- a/BaseUsbHostIntEp.cpp Wed Dec 05 13:23:06 2012 +0000 +++ b/BaseUsbHostIntEp.cpp Tue Dec 11 15:26:54 2012 +0000 @@ -1,4 +1,4 @@ -// BaseUsbHostIntEp.cpp 2012/12/5 +// BaseUsbHostIntEp.cpp 2012/12/11 #include "mbed.h" #include "rtos.h" #include "BaseUsbHost.h" @@ -11,12 +11,17 @@ :BaseEp(addr, ep, size, lowSpeed) { HCTD* td = new_HCTD(); - TEST_ASSERT(td); m_pED->TailTd = td; m_pED->HeadTd = td; - + TEST_ASSERT(td); + if (td == NULL) { + return; + } HCCA* pHcca = reinterpret_cast<HCCA*>(LPC_USB->HcHCCA); TEST_ASSERT(pHcca); + if (pHcca == NULL) { + return; + } int n = 0; m_pED->Next = pHcca->InterruptTable[n]; pHcca->InterruptTable[n] = reinterpret_cast<uint32_t>(m_pED); @@ -28,11 +33,17 @@ if (m_td_queue_count == 0) { HCTD* data_td = m_pED->TailTd; TEST_ASSERT(data_td); + if (data_td == NULL) { + return USB_ERROR; + } data_td->Control |= TD_IN; data_td->CurrBufPtr = buf; data_td->BufEnd = const_cast<uint8_t*>(buf)+len-1; HCTD* blank_td = new_HCTD(); TEST_ASSERT(blank_td); + if (blank_td == NULL) { + return USB_ERROR_MEMORY; + } data_td->Next = reinterpret_cast<uint32_t>(blank_td); m_pED->TailTd = blank_td; m_td_queue_count++; @@ -41,15 +52,15 @@ } HCTD* td = get_queue_HCTD(millisec); - if (td) { - DBG_TD(td); - int ret = len; - if (td->CurrBufPtr) { - ret = td->CurrBufPtr - buf; - } - delete_HCTD(td); - m_td_queue_count--; - return ret; + if (td == NULL) { + return USB_PROCESSING; } - return USB_TIMEOUT; + DBG_TD(td); + int ret = len; + if (td->CurrBufPtr) { + ret = td->CurrBufPtr - buf; + } + delete_HCTD(td); + m_td_queue_count--; + return ret; }
--- a/BaseUsbHostIsoEp.cpp Wed Dec 05 13:23:06 2012 +0000 +++ b/BaseUsbHostIsoEp.cpp Tue Dec 11 15:26:54 2012 +0000 @@ -1,4 +1,4 @@ -// BaseUsbHostIsoEp.cpp 2012/12/5 +// BaseUsbHostIsoEp.cpp 2012/12/11 #include "mbed.h" #include "rtos.h" #include "BaseUsbHost.h" @@ -16,16 +16,22 @@ TEST_ASSERT(size >= 128 && size <= 1023); m_PacketSize = size; - m_FrameCount = 8; + m_FrameCount = 4; // 1-8 + TEST_ASSERT(m_FrameCount >= 1 && m_FrameCount <= 8); m_itd_queue_count = 0; reset(); HCITD* itd = new_HCITD(); - TEST_ASSERT(itd); m_pED->TailTd = reinterpret_cast<HCTD*>(itd); m_pED->HeadTd = reinterpret_cast<HCTD*>(itd); - + TEST_ASSERT(itd); + if (itd == NULL) { + return; + } HCCA* hcca = reinterpret_cast<HCCA*>(LPC_USB->HcHCCA); TEST_ASSERT(hcca); + if (hcca == NULL) { + return; + } for(int i = 0; i < 32; i++) { if (hcca->InterruptTable[i] == 0) { hcca->InterruptTable[i] = reinterpret_cast<uint32_t>(m_pED); @@ -84,15 +90,20 @@ } -HCITD* IsochronousEp::isochronousReveive() +HCITD* IsochronousEp::isochronousReveive(int millisec) { TEST_ASSERT(m_itd_queue_count >= 0); - while(m_itd_queue_count < HCTD_QUEUE_SIZE) { + while(m_itd_queue_count < 3 && m_itd_queue_count < HCTD_QUEUE_SIZE) { HCITD* itd = reinterpret_cast<HCITD*>(m_pED->TailTd); TEST_ASSERT(itd); - //DBG_ITD(itd); + if (itd == NULL) { + return NULL; + } HCITD* blank_itd = new_HCITD(); TEST_ASSERT(blank_itd); + if (blank_itd == NULL) { + return NULL; + } itd->Next = reinterpret_cast<uint32_t>(blank_itd); m_pED->TailTd = reinterpret_cast<HCTD*>(blank_itd); m_itd_queue_count++; @@ -100,21 +111,23 @@ LPC_USB->HcControl |= OR_CONTROL_PLE; // Enable Periodic } - HCITD* itd = get_queue_HCITD(1); + HCITD* itd = get_queue_HCITD(millisec); if (itd) { m_itd_queue_count--; } return itd; } -HCITD* IsochronousEp::get_queue_HCITD(uint32_t millisec) +HCITD* IsochronousEp::get_queue_HCITD(int millisec) { for(int i = 0; i < 16; i++) { osEvent evt = m_queue.get(millisec); if (evt.status == osEventMessage) { HCITD* itd = reinterpret_cast<HCITD*>(evt.value.p); TEST_ASSERT(itd); - //led3 = !led3; + if (itd == NULL) { + return NULL; + } uint8_t cc = itd->Control>>28; if (cc != 0) { m_ConditionCode = cc; @@ -127,8 +140,8 @@ } else { DBG("evt.status: %02x\n", evt.status); TEST_ASSERT(evt.status == osEventMessage); + return NULL; } } return NULL; } -
--- a/BaseUsbHostUvc.cpp Wed Dec 05 13:23:06 2012 +0000 +++ b/BaseUsbHostUvc.cpp Tue Dec 11 15:26:54 2012 +0000 @@ -1,4 +1,4 @@ -// BaseUsbHostUvc.cpp 2012/12/5 +// BaseUsbHostUvc.cpp 2012/12/11 #include "mbed.h" #include "rtos.h" #include "BaseUsbHost.h" @@ -7,18 +7,20 @@ #define TEST #include "BaseUsbHostTest.h" -void BaseUvc::poll() +void BaseUvc::poll(int millisec) { - HCITD* itd = m_isoEp->isochronousReveive(); + HCITD* itd = m_isoEp->isochronousReveive(millisec); if (itd) { uint8_t cc = itd->Control>>28; report_cc_count[cc]++; if (cc == 0) { // ConditionCode //DBG_ITD(itd); uint16_t frame = itd->Control & 0xffff; + int fc = ((itd->Control>>24)&7)+1; + TEST_ASSERT(fc == m_isoEp->m_FrameCount); uint8_t* buf = const_cast<uint8_t*>(itd->buf); int mps = m_isoEp->m_PacketSize; - for(int i = 0; i < m_isoEp->m_FrameCount; i++) { + for(int i = 0; i < fc; i++) { uint16_t pswn = itd->OffsetPSW[i]; cc = pswn>>12; if (cc == 0 || cc == 9) {