BaseUsbHost example program
Dependencies: BaseUsbHost FATFileSystem mbed mbed-rtos
Revision 1:80205a2de336, committed 2012-12-05
- Comitter:
- va009039
- Date:
- Wed Dec 05 13:25:18 2012 +0000
- Parent:
- 0:2a9734a95d55
- Child:
- 2:c10029b87439
- Commit message:
- add LifeCamVX700
Changed in this revision
--- a/BaseJpegDecode.lib Tue Dec 04 13:39:57 2012 +0000 +++ b/BaseJpegDecode.lib Wed Dec 05 13:25:18 2012 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/va009039/code/BaseJpegDecode/#a7547692071d +http://mbed.org/users/va009039/code/BaseJpegDecode/#e243fa781e5c
--- a/BaseUsbHost.lib Tue Dec 04 13:39:57 2012 +0000 +++ b/BaseUsbHost.lib Wed Dec 05 13:25:18 2012 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/va009039/code/BaseUsbHost/#b7d6879637a8 +http://mbed.org/users/va009039/code/BaseUsbHost/#3b7bc4f87a61
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LifeCamVX700.cpp Wed Dec 05 13:25:18 2012 +0000 @@ -0,0 +1,128 @@ +// LifeCamVX700.cpp 2012/12/5 +#include "mbed.h" +#include "rtos.h" +#include "BaseUsbHost.h" +#define DEBUG +#include "BaseUsbHostDebug.h" +#define TEST +#include "BaseUsbHostTest.h" +#include "LifeCamVX700.h" + +LifeCamVX700::LifeCamVX700(int frameIndex, uint32_t interval, ControlEp* ctlEp) +{ + uint8_t buf[26]; + + if (ctlEp == NULL) { // root hub + DBG_OHCI(LPC_USB->HcRhPortStatus1); + TEST_ASSERT_FALSE(LPC_USB->HcRhPortStatus1 & 0x200); + ctlEp = new ControlEp(); + TEST_ASSERT_TRUE(ctlEp); + } + bool r = check(ctlEp); + TEST_ASSERT(r); + m_ctlEp = ctlEp; + + int addr = m_ctlEp->GetAddr(); + m_isoEp = new IsochronousEp(addr, VX700_EN, VX700_MPS); + TEST_ASSERT_TRUE(m_isoEp); + + int rc = Control(GET_INFO, VS_PROBE_CONTROL, 1, buf, 1); + TEST_ASSERT(rc == USB_OK); + DBG_BYTES("GET_INFO Prob", buf, 1); + + rc = Control(GET_DEF, VS_PROBE_CONTROL, 1, buf, 26); + TEST_ASSERT(rc == USB_OK); + DBG_BYTES("GET_DEF Probe", buf, 26); + + rc = Control(GET_MIN, VS_PROBE_CONTROL, 1, buf, 26); + TEST_ASSERT(rc == USB_OK); + DBG_BYTES("GET_MIN Probe", buf, 26); + + rc = Control(GET_MAX, VS_PROBE_CONTROL, 1, buf, 26); + TEST_ASSERT(rc == USB_OK); + DBG_BYTES("GET_MAX Probe", buf, 26); + + rc = Control(GET_CUR, VS_PROBE_CONTROL, 1, buf, 26); + TEST_ASSERT(rc == USB_OK); + DBG_BYTES("GET_CUR Probe", buf, 26); + + memset(buf, 0, 26); + buf[2] = VX700_MJPEG; + buf[3] = frameIndex; + *reinterpret_cast<uint32_t*>(buf+4) = interval; + + DBG_BYTES("SET_CUR Commit", buf, 26); + rc = Control(SET_CUR, VS_COMMIT_CONTROL, 1, buf, 26); + TEST_ASSERT(rc == USB_OK); + + rc = Control(GET_CUR, VS_COMMIT_CONTROL, 1, buf, 26); + TEST_ASSERT(rc == USB_OK); + TEST_ASSERT_EQUAL(buf[2], VX700_MJPEG); + TEST_ASSERT_EQUAL(buf[3], frameIndex); + TEST_ASSERT_EQUAL(*reinterpret_cast<uint32_t*>(buf+4), interval); + DBG_BYTES("GET_CUR Commit", buf, 26); + + int cfg; + rc = m_ctlEp->GetConfiguration(&cfg); + TEST_ASSERT_EQUAL(rc, USB_OK); + DBG("config: %d\n", cfg); + + rc = m_ctlEp->SetConfiguration(1); + TEST_ASSERT_EQUAL(rc, USB_OK); + + rc = m_ctlEp->GetConfiguration(&cfg); + TEST_ASSERT_EQUAL(rc, USB_OK); + DBG("config: %d\n", cfg); + TEST_ASSERT_EQUAL(cfg, 1); + + int alt; + rc = m_ctlEp->GetInterface(1, &alt); + TEST_ASSERT_EQUAL(rc, USB_OK); + DBG("alt: %d\n", alt); + + rc = m_ctlEp->SetInterfaceAlternate(1, VX700_IF_ALT); // alt=1 packet size = 192 + TEST_ASSERT_EQUAL(rc, USB_OK); + + rc = m_ctlEp->GetInterface(1, &alt); + TEST_ASSERT_EQUAL(rc, USB_OK); + DBG("alt: %d\n", alt); + TEST_ASSERT_EQUAL(alt, 1); + + for(int i = 0; i < 16; i++) { + report_cc_count[i] = 0; + report_ps_cc_count[i] = 0; + } + + LPC_USB->HcControl |= OR_CONTROL_PLE; // PeriodicListEnable + LPC_USB->HcControl |= OR_CONTROL_IE; // IsochronousEnable +} + +bool LifeCamVX700::check(ControlEp* ctlEp) +{ + if (ctlEp == NULL) { + return false; + } + uint8_t buf[18]; + int r = ctlEp->GetDescriptor(1, 0, buf, 8); + if (r != USB_OK) { + return false; + } + DBG_HEX(buf, 8); + const uint8_t desc[] = {0x12,0x01,0x00,0x02,0xef,0x02,0x01,0x40}; + if (memcmp(buf, desc, sizeof(desc)) != 0) { + return false; + } + r = ctlEp->GetDescriptor(1, 0, buf, 18); + if (r != USB_OK) { + return false; + } + DBG_HEX(buf, 18); + uint16_t vid = *reinterpret_cast<uint16_t*>(buf+8); + uint16_t pid = *reinterpret_cast<uint16_t*>(buf+10); + DBG("VID PID: %04X %04X\n", vid, pid); + if (vid == VX700_VID && pid == VX700_PID) { + return true; + } + return false; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LifeCamVX700.h Wed Dec 05 13:25:18 2012 +0000 @@ -0,0 +1,25 @@ +// LifeCamVX700.h 2012/12/5 +#ifndef LIFECAM_VX700_H +#define LIFECAM_VX700_H + +#define VX700_VID 0x045e +#define VX700_PID 0x074a + +#define VX700_160x120 5 +#define VX700_176x144 4 +#define VX700_320x240 3 +#define VX700_352x288 2 +#define VX700_640x480 1 + +#define VX700_MJPEG 1 + +#define VX700_EN 0x81 +#define VX700_MPS 128 +#define VX700_IF_ALT 1 + +class LifeCamVX700 : public BaseUvc{ +public: + LifeCamVX700(int frameIndex = VX700_160x120, uint32_t interval = _5FPS, ControlEp* ctlEp = NULL); + static bool check(ControlEp* ctlEp); +}; +#endif //LIFECAM_VX700_H
--- a/LogitechC270/LogitechC270.cpp Tue Dec 04 13:39:57 2012 +0000 +++ b/LogitechC270/LogitechC270.cpp Wed Dec 05 13:25:18 2012 +0000 @@ -1,4 +1,4 @@ -// LogitechC270.cpp 2012/12/4 +// LogitechC270.cpp 2012/12/5 #include "mbed.h" #include "rtos.h" #include "BaseUsbHost.h" @@ -8,30 +8,22 @@ #include "BaseUsbHostTest.h" #include "LogitechC270.h" -LogitechC270::LogitechC270(int frame, uint32_t interval, ControlEp* ctlEp) +LogitechC270::LogitechC270(int frameIndex, uint32_t interval, ControlEp* ctlEp) { uint8_t buf[26]; if (ctlEp == NULL) { // root hub DBG_OHCI(LPC_USB->HcRhPortStatus1); TEST_ASSERT_FALSE(LPC_USB->HcRhPortStatus1 & 0x200); - m_ctlEp = new ControlEp(); - TEST_ASSERT_TRUE(m_ctlEp); - } else { - m_ctlEp = ctlEp; + ctlEp = new ControlEp(); + TEST_ASSERT_TRUE(ctlEp); } - - int r = m_ctlEp->GetDescriptor(1, 0, buf, 18); - TEST_ASSERT(r == USB_OK); - DBG_HEX(buf, 18); - vid = *reinterpret_cast<uint16_t*>(buf+8); - pid = *reinterpret_cast<uint16_t*>(buf+10); - DBG("VID PID: %04X %04X\n", vid, pid); - TEST_ASSERT(vid == 0x046d && pid == 0x0825); + bool r = check(ctlEp); + TEST_ASSERT(r); + m_ctlEp = ctlEp; + int addr = m_ctlEp->GetAddr(); - DBG("addr: %d\n", addr); - - m_isoEp = new IsochronousEp(addr, 0x81, 192); + m_isoEp = new IsochronousEp(addr, C270_EN, C270_MPS); TEST_ASSERT_TRUE(m_isoEp); int rc = Control(GET_INFO, VS_PROBE_CONTROL, 1, buf, 1); @@ -56,7 +48,7 @@ memset(buf, 0, 26); buf[2] = C270_MJPEG; - buf[3] = frame; + buf[3] = frameIndex; *reinterpret_cast<uint32_t*>(buf+4) = interval; DBG_BYTES("SET_CUR Commit", buf, 26); @@ -66,7 +58,7 @@ rc = Control(GET_CUR, VS_COMMIT_CONTROL, 1, buf, 26); TEST_ASSERT(rc == USB_OK); TEST_ASSERT_EQUAL(buf[2], C270_MJPEG); - TEST_ASSERT_EQUAL(buf[3], frame); + TEST_ASSERT_EQUAL(buf[3], frameIndex); TEST_ASSERT_EQUAL(*reinterpret_cast<uint32_t*>(buf+4), interval); DBG_BYTES("GET_CUR Commit", buf, 26); @@ -88,7 +80,7 @@ TEST_ASSERT_EQUAL(rc, USB_OK); DBG("alt: %d\n", alt); - rc = m_ctlEp->SetInterfaceAlternate(1, 1); // alt=1 packet size = 192 + rc = m_ctlEp->SetInterfaceAlternate(1, C270_IF_ALT); // alt=1 packet size = 192 TEST_ASSERT_EQUAL(rc, USB_OK); rc = m_ctlEp->GetInterface(1, &alt); @@ -105,53 +97,32 @@ LPC_USB->HcControl |= OR_CONTROL_IE; // IsochronousEnable } -void LogitechC270::poll() +bool LogitechC270::check(ControlEp* ctlEp) { - HCITD* itd = m_isoEp->read(); - 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; - 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++) { - uint16_t pswn = itd->OffsetPSW[i]; - cc = pswn>>12; - if (cc == 0 || cc == 9) { - int len = pswn & 0x7ff; - onResult(frame, buf, len); - } - report_ps_cc_count[cc]++; - buf += mps; - frame++; - } - } - m_isoEp->delete_HCTD(reinterpret_cast<HCTD*>(itd)); + if (ctlEp == NULL) { + return false; + } + uint8_t buf[18]; + int r = ctlEp->GetDescriptor(1, 0, buf, 8); + if (r != USB_OK) { + return false; + } + DBG_HEX(buf, 8); + const uint8_t desc[] = {0x12,0x01,0x00,0x02,0xef,0x02,0x01,0x40}; + if (memcmp(buf, desc, sizeof(desc)) != 0) { + return false; } + r = ctlEp->GetDescriptor(1, 0, buf, 18); + if (r != USB_OK) { + return false; + } + DBG_HEX(buf, 18); + uint16_t vid = *reinterpret_cast<uint16_t*>(buf+8); + uint16_t pid = *reinterpret_cast<uint16_t*>(buf+10); + DBG("VID PID: %04X %04X\n", vid, pid); + if (vid == C270_VID && pid == C270_PID) { + return true; + } + return false; } -int LogitechC270::Control(int req, int cs, int index, uint8_t* buf, int size) -{ - TEST_ASSERT(m_ctlEp); - int rc; - if (req == SET_CUR) { - rc = m_ctlEp->controlSend( - USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE, - req, cs<<8, index, buf, size); - return rc; - } - rc = m_ctlEp->controlReceive( - USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE, - req, cs<<8, index, buf, size); - return rc; -} - -void LogitechC270::onResult(uint16_t frame, uint8_t* buf, int len) -{ - if(m_pCbItem && m_pCbMeth) - (m_pCbItem->*m_pCbMeth)(frame, buf, len); - else if(m_pCb) - m_pCb(frame, buf, len); -}
--- a/LogitechC270/LogitechC270.h Tue Dec 04 13:39:57 2012 +0000 +++ b/LogitechC270/LogitechC270.h Wed Dec 05 13:25:18 2012 +0000 @@ -1,6 +1,10 @@ +// LogitechC270.h 2012/12/5 #ifndef LOGITECH_C270_H #define LOGITECH_C270_H +#define C270_VID 0x046d +#define C270_PID 0x0825 + #define C270_160x120 2 #define C270_176x144 3 #define C270_320x176 4 @@ -14,64 +18,16 @@ #define C270_800x448 11 #define C270_800x600 12 -#define _30FPS 333333 -#define _25FPS 400000 -#define _20FPS 500000 -#define _15FPS 666666 -#define _10FPS 1000000 -#define _5FPS 2000000 - #define C270_MJPEG 2 #define C270_YUV2 1 -#define SET_CUR 0x01 -#define GET_CUR 0x81 -#define GET_MIN 0x82 -#define GET_MAX 0x83 -#define GET_RES 0x84 -#define GET_LEN 0x85 -#define GET_INFO 0x86 -#define GET_DEF 0x87 +#define C270_EN 0x81 +#define C270_MPS 192 +#define C270_IF_ALT 1 -#define VS_PROBE_CONTROL 0x01 -#define VS_COMMIT_CONTROL 0x02 - -class LogitechC270 { +class LogitechC270 : public BaseUvc { public: - LogitechC270(int frame = C270_160x120, uint32_t interval = _5FPS, ControlEp* ctlEp = NULL); - void poll(); - int Control(int req, int cs, int index, uint8_t* buf, int size); - uint16_t vid; - uint16_t pid; - 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) ) - { - m_pCb = pMethod; - m_pCbItem = NULL; - m_pCbMeth = NULL; - } - - 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() - { - m_pCb = NULL; - m_pCbItem = NULL; - m_pCbMeth = NULL; - } - CDummy* m_pCbItem; - void (CDummy::*m_pCbMeth)(uint16_t, uint8_t*, int); - void (*m_pCb)(uint16_t, uint8_t*, int); + LogitechC270(int frameIndex = C270_160x120, uint32_t interval = _5FPS, ControlEp* ctlEp = NULL); + static bool check(ControlEp* ctlEp); }; #endif //LOGITECH_C270_H
--- a/UsbFlashDrive/UsbFlashDrive.cpp Tue Dec 04 13:39:57 2012 +0000 +++ b/UsbFlashDrive/UsbFlashDrive.cpp Wed Dec 05 13:25:18 2012 +0000 @@ -1,4 +1,4 @@ -// UsbFlashDrive.cpp 2012/12/4 +// UsbFlashDrive.cpp 2012/12/5 #include "mbed.h" #include "rtos.h" #include "BaseUsbHost.h" @@ -42,10 +42,8 @@ if (ctlEp == NULL) { // root hub DBG_OHCI(LPC_USB->HcRhPortStatus1); TEST_ASSERT_FALSE(LPC_USB->HcRhPortStatus1 & 0x200); - m_ctlEp = new ControlEp(); - TEST_ASSERT_TRUE(m_ctlEp); - } else { - m_ctlEp = ctlEp; + ctlEp = new ControlEp(); + TEST_ASSERT_TRUE(ctlEp); } TEST_ASSERT(sizeof(CBW) == 31); @@ -58,11 +56,30 @@ m_pEpBulkIn = NULL; m_pEpBulkOut = NULL; - ParseConfiguration(); - int rc = m_ctlEp->SetConfiguration(1); + ParseConfiguration(ctlEp); + int rc = ctlEp->SetConfiguration(1); TEST_ASSERT_EQUAL(rc, USB_OK); - GetMaxLUN(); - setup(); + GetMaxLUN(ctlEp); + setup(ctlEp); +} + +bool UsbFlashDrive::check(ControlEp* ctlEp) +{ + if (ctlEp == NULL) { + return false; + } + uint8_t buf[8]; + int rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, buf, sizeof(buf)); + if (rc != USB_OK) { + return false; + } + DBG_BYTES("ConfigDescriptor 8bytes", buf, sizeof(buf)); + TEST_ASSERT(buf[0] == 9); + TEST_ASSERT(buf[1] == 0x02); + if (buf[4] != 0x01) { + return false; + } + return true; } int UsbFlashDrive::disk_initialize() @@ -114,7 +131,7 @@ return m_numBlocks; } -int UsbFlashDrive::setup(int timeout) +int UsbFlashDrive::setup(ControlEp* ctlEp, int timeout) { int retry = 0; @@ -146,13 +163,13 @@ return 0; } -int UsbFlashDrive::ParseConfiguration() +int UsbFlashDrive::ParseConfiguration(ControlEp* ctlEp) { + TEST_ASSERT(ctlEp); int rc; uint8_t ConfigDesc[9]; int index = 0; - TEST_ASSERT(m_ctlEp); - rc = m_ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, ConfigDesc, sizeof(ConfigDesc)); + rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, ConfigDesc, sizeof(ConfigDesc)); TEST_ASSERT(rc == USB_OK); DBG_BYTES("ConfigDescriptor 9bytes", ConfigDesc, sizeof(ConfigDesc)); TEST_ASSERT(ConfigDesc[0] == 9); @@ -166,7 +183,7 @@ uint8_t* buf = new uint8_t[wTotalLength]; TEST_ASSERT(buf); - rc = m_ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, wTotalLength); + rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, wTotalLength); TEST_ASSERT(rc == USB_OK); TEST_ASSERT(ConfigDesc[1] == 0x02); for (int pos = 0; pos < wTotalLength; pos += buf[pos]) { @@ -192,7 +209,7 @@ DBG("EndpointAddress: %02X\n", ep); DBG("Attribute: %02X\n", att); DBG("MaxPacketSize: %d\n", size); - BulkEp* pEp = new BulkEp(m_ctlEp->GetAddr(), ep, size); + BulkEp* pEp = new BulkEp(ctlEp->GetAddr(), ep, size); TEST_ASSERT(pEp); if (dir) { m_pEpBulkIn = pEp; @@ -208,20 +225,20 @@ return 0; } -int UsbFlashDrive::BulkOnlyMassStorageReset() +int UsbFlashDrive::BulkOnlyMassStorageReset(ControlEp* ctlEp) { - TEST_ASSERT(m_ctlEp); - int rc = m_ctlEp->controlReceive(0x21, 0xff, 0x0000, m_interface, NULL, 0); + TEST_ASSERT(ctlEp); + int rc = ctlEp->controlReceive(0x21, 0xff, 0x0000, m_interface, NULL, 0); TEST_ASSERT(rc == USB_OK); return rc; } -int UsbFlashDrive::GetMaxLUN() +int UsbFlashDrive::GetMaxLUN(ControlEp* ctlEp) { + TEST_ASSERT(ctlEp); TEST_ASSERT(m_interface == 0); uint8_t temp[1]; - TEST_ASSERT(m_ctlEp); - int rc = m_ctlEp->controlReceive(0xa1, 0xfe, 0x0000, m_interface, temp, sizeof(temp)); + int rc = ctlEp->controlReceive(0xa1, 0xfe, 0x0000, m_interface, temp, sizeof(temp)); TEST_ASSERT(rc == USB_OK); DBG_BYTES("GetMaxLUN", temp, sizeof(temp)); m_MaxLUN = temp[0]; @@ -376,13 +393,13 @@ int UsbFlashDrive::_bulkRecv(uint8_t* buf, int size) { TEST_ASSERT(m_pEpBulkIn); - int ret = m_pEpBulkIn->read(buf, size); + int ret = m_pEpBulkIn->bulkReceive(buf, size); return ret; } int UsbFlashDrive::_bulkSend(const uint8_t* buf, int size) { TEST_ASSERT(m_pEpBulkOut); - int ret = m_pEpBulkOut->write(buf, size); + int ret = m_pEpBulkOut->bulkSend(buf, size); return ret; }
--- a/UsbFlashDrive/UsbFlashDrive.h Tue Dec 04 13:39:57 2012 +0000 +++ b/UsbFlashDrive/UsbFlashDrive.h Wed Dec 05 13:25:18 2012 +0000 @@ -1,4 +1,4 @@ -// usbFlashDrive.h 2012/12/4 +// usbFlashDrive.h 2012/12/5 #ifndef USB_FLASH_DRIVE_H #define USB_FLASH_DRIVE_H @@ -33,18 +33,18 @@ class UsbFlashDrive : public FATFileSystem { public: UsbFlashDrive(const char* name, ControlEp* ctlEp = NULL); + static bool check(ControlEp* ctlEp); virtual int disk_initialize(); virtual int disk_write(const uint8_t* buffer, uint64_t sector); virtual int disk_read(uint8_t* buffer, uint64_t sector); virtual int disk_status(); virtual int disk_sync(); virtual uint64_t disk_sectors(); - - int setup(int timeout = 9000); private: - int ParseConfiguration(); - int BulkOnlyMassStorageReset(); - int GetMaxLUN(); + int setup(ControlEp* ctlEp, int timeout = 9000); + int ParseConfiguration(ControlEp* ctlEp); + int BulkOnlyMassStorageReset(ControlEp* ctlEp); + int GetMaxLUN(ControlEp* ctlEp); int ReadCapacity(); int GetSenseInfo(); int TestUnitReady(); @@ -65,7 +65,7 @@ uint32_t m_tag; CBW m_CBW; CSW m_CSW; - ControlEp* m_ctlEp; + // endpoint BulkEp* m_pEpBulkIn; BulkEp* m_pEpBulkOut; // report
--- a/UsbMouseHost/UsbMouseHost.cpp Tue Dec 04 13:39:57 2012 +0000 +++ b/UsbMouseHost/UsbMouseHost.cpp Wed Dec 05 13:25:18 2012 +0000 @@ -1,8 +1,8 @@ -// UsbMouseHost.cpp +// UsbMouseHost.cpp 2012/12/5 #include "mbed.h" #include "rtos.h" #include "BaseUsbHost.h" -//#define DEBUG +#define DEBUG #include "BaseUsbHostDebug.h" #define TEST #include "BaseUsbHostTest.h" @@ -16,24 +16,41 @@ if (LPC_USB->HcRhPortStatus1 & 0x200) { lowSpeed = 1; } - m_ctlEp = new ControlEp(lowSpeed); - TEST_ASSERT_TRUE(m_ctlEp); - } else { - m_ctlEp = ctlEp; + ctlEp = new ControlEp(lowSpeed); + TEST_ASSERT_TRUE(ctlEp); } - - int rc = m_ctlEp->SetConfiguration(1); + bool r = check(ctlEp); + TEST_ASSERT(r); + + int rc = ctlEp->SetConfiguration(1); TEST_ASSERT_EQUAL(rc, USB_OK); - int addr = m_ctlEp->GetAddr(); - int lowSpeed = m_ctlEp->GetLowSpeed(); + int addr = ctlEp->GetAddr(); + int lowSpeed = ctlEp->GetLowSpeed(); m_intEp = new InterruptEp(addr, 0x81, 8, lowSpeed); TEST_ASSERT_TRUE(m_intEp); } +bool UsbMouseHost::check(ControlEp* ctlEp) +{ + if (ctlEp == NULL) { + return false; + } + uint8_t buf[8]; + int r = ctlEp->GetDescriptor(1, 0, buf, 8); + if (r != USB_OK) { + return false; + } + DBG_HEX(buf, 8); + if (buf[4] != 0x00) { // HID ? + return false; + } + return true; +} + int UsbMouseHost::read(uint32_t* status, int millisec) { - int rc = m_intEp->read(reinterpret_cast<uint8_t*>(status), 4, millisec); + int rc = m_intEp->interruptReceive(reinterpret_cast<uint8_t*>(status), 4, millisec); if (rc < 0) { // error? *status = 0x00000000; return rc;
--- a/UsbMouseHost/UsbMouseHost.h Tue Dec 04 13:39:57 2012 +0000 +++ b/UsbMouseHost/UsbMouseHost.h Wed Dec 05 13:25:18 2012 +0000 @@ -1,12 +1,13 @@ -// UsbMouseHost.h +// UsbMouseHost.h 2012/12/5 #ifndef USB_MOUSE_HOST_H #define USB_MOUSE_HOST_H class UsbMouseHost { public: UsbMouseHost(ControlEp* ctlEp = NULL); + static bool check(ControlEp* ctlEp); int read(uint32_t* status, int millisec=osWaitForever); - ControlEp* m_ctlEp; + //ControlEp* m_ctlEp; InterruptEp* m_intEp; };
--- a/example1_LogitechC270.cpp Tue Dec 04 13:39:57 2012 +0000 +++ b/example1_LogitechC270.cpp Wed Dec 05 13:25:18 2012 +0000 @@ -100,8 +100,8 @@ } } term.locate(0, y); - term.printf("Cr:(%d,%d)[width=%d height=%d yblock=%d %u %u]\n", - calc->x_center, calc->y_center, calc->width, calc->height, calc->yblock, calc->EOI_count, t.read_ms()/1000); + term.printf("Cr:(%d,%d)[width=%d height=%d yblock=%d %u]\n", + calc->x_center, calc->y_center, calc->width, calc->height, calc->yblock, calc->EOI_count); term.printf("[CC:"); for(int i = 0; i < 16; i++) { term.printf(" %u", cam->report_cc_count[i]); @@ -131,14 +131,15 @@ UsbHub* hub = new UsbHub(); TEST_ASSERT_TRUE(hub); - for(int i = 0; i < 4; i++) { - if (hub->PortEp[i]) { - if (hub->PortEp[i]->DeviceClass == 0x02) { - ctlEp = hub->PortEp[i]; - break; - } + for(int i = 0; i < MAX_HUB_PORT; i++) { + if (LogitechC270::check(hub->PortEp[i])) { + ctlEp = hub->PortEp[i]; + break; } } + if (ctlEp == NULL) { + error("LogitechC270 not found\n"); + } cam = new LogitechC270(C270_160x120, _15FPS, ctlEp); TEST_ASSERT_TRUE(cam);
--- a/example1_UsbFlashDrive.cpp Tue Dec 04 13:39:57 2012 +0000 +++ b/example1_UsbFlashDrive.cpp Wed Dec 05 13:25:18 2012 +0000 @@ -26,25 +26,39 @@ TEST_ASSERT_TRUE(hub); for(int i = 0; i < MAX_HUB_PORT; i++) { - if (hub->PortEp[i]) { - if (hub->PortEp[i]->DeviceClass == 0x01) { - ctlEp = hub->PortEp[i]; - break; - } + if (UsbFlashDrive::check(hub->PortEp[i])) { + ctlEp = hub->PortEp[i]; + break; } } + if (ctlEp == NULL) { + error("USB Flash Drive not found\n"); + } + TEST_ASSERT(ctlEp); drive = new UsbFlashDrive("usb", ctlEp); TEST_ASSERT(drive); - - const int file_size = 1024*256; - printf("USB FLASH DRIVE read/write file size: %d bytes\n", file_size); + const int size_table[] = { + 1024*1, + 1024*2, + 1024*4, + 1024*8, + 1024*16, + 1024*32, + 1024*64, + 1024*128, + 1204*256, + 1204*512, + }; + + printf("USB FLASH DRIVE read/write test\n"); char path[32]; int size; Timer t; for(int n = 0; n <= 9; n++) { + int file_size = size_table[n]; sprintf(path, "/usb/test%d.txt", n); FILE* fp = fopen(path, "wb"); size = 0;
--- a/example1_UsbMouseHost.cpp Tue Dec 04 13:39:57 2012 +0000 +++ b/example1_UsbMouseHost.cpp Wed Dec 05 13:25:18 2012 +0000 @@ -25,16 +25,18 @@ UsbHub* hub = new UsbHub(); TEST_ASSERT_TRUE(hub); - for(int i = 0; i < 4; i++) { - ctlEp = hub->PortEp[i]; - if (ctlEp) { + for(int i = 0; i < MAX_HUB_PORT; i++) { + if (UsbMouseHost::check(hub->PortEp[i])) { + ctlEp = hub->PortEp[i]; break; } } + if (ctlEp == NULL) { + error("USB Mouse not found\n"); + } mouse = new UsbMouseHost(ctlEp); TEST_ASSERT(mouse); - while(1) { uint32_t status;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/example2_LifeCamVX700.cpp Wed Dec 05 13:25:18 2012 +0000 @@ -0,0 +1,144 @@ +#if 0 +// example2_LifeCamVX700.cpp +#include "mbed.h" +#include "rtos.h" +#include "BaseUsbHost.h" +#define DEBUG +#include "BaseUsbHostDebug.h" +#define TEST +#include "BaseUsbHostTest.h" +#include "LifeCamVX700.h" +#include "BaseJpegDecode.h" +#include "Terminal.h" + +// LifeCamVX700 +#define WIDTH 160 +#define HEIGHT 120 + +#define THRESHOLD 200 + +DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4); +Terminal term(USBTX, USBRX); + +class JpegDecode : public BaseJpegDecode { +public: + uint32_t EOI_count; + int8_t m_buf[WIDTH/8*HEIGHT/8]; + bool mode_CbCr; + JpegDecode() { + mode_CbCr = false; + EOI_count = 0; + memset(m_buf, 0, sizeof(m_buf)); + } + virtual void outputDC(int mcu, int block, int value) { + if (mcu >= (WIDTH/16*HEIGHT/8)) { + return; + } + if (mode_CbCr) { + if (block == 2 || block == 3) { + value *= qt[1][0]; + value /= 16; + m_buf[mcu*2+block-2] = value; + } + } else { + if (block == 0 || block == 1) { + value *= qt[0][0]; + value /= 16; + m_buf[mcu*2+block] = value; + } + } + } + virtual void outputAC(int mcu, int block, int scan, int value){}; + virtual void outputMARK(uint8_t c){ + if (c == 0xd9) { // EOI + EOI_count++; + led3 = !led3; + } + }; +}; + +JpegDecode* decode = NULL; +void callback_motion_jpeg(uint16_t frame, uint8_t* buf, int len) +{ + if (decode) { + decode->input(buf+12, len-12); + } + if (buf[1]&1) { // FID + led1 = !led1; + } +} + +BaseUsbHost *UsbHost; +UsbHub* hub; +ControlEp* ctlEp = NULL; +LifeCamVX700* cam; + +void display_thread(void const *args) { + term.cls(); + int n = 0; + while(1) { + int y; + for(y = 0; y < HEIGHT/8; y++) { + term.locate(0, y); + for(int x = 0; x < WIDTH/8; x++) { + int value = decode->m_buf[y*WIDTH/8+x]; + term.printf("%+3d,", value); + } + } + term.locate(0, y); + term.printf("[%s width=%d height=%d yblock=%d %u]\n", decode->mode_CbCr ? "CbCr": "Y0Y1", + decode->width, decode->height, decode->yblock, decode->EOI_count); + term.printf("[CC:"); + for(int i = 0; i < 16; i++) { + term.printf(" %u", cam->report_cc_count[i]); + } + term.printf("]\n"); + term.printf("[PS:"); + for(int i = 0; i < 16; i++) { + term.printf(" %u", cam->report_ps_cc_count[i]); + } + term.printf("]\n"); + Thread::wait(200); + //Thread::signal_wait(1, 2000); + led2 = !led2; + if (n++ > (20000/200)) { + n = 0; + decode->mode_CbCr = !decode->mode_CbCr; + } + } +} + +int main() { + term.baud(921600); + term.printf("%s\n", __FILE__); + + decode = new JpegDecode; + TEST_ASSERT(decode); + + UsbHost = new BaseUsbHost; + TEST_ASSERT_TRUE(UsbHost); + + UsbHub* hub = new UsbHub(); + TEST_ASSERT_TRUE(hub); + + for(int i = 0; i < MAX_HUB_PORT; i++) { + if (LifeCamVX700::check(hub->PortEp[i])) { + ctlEp = hub->PortEp[i]; + break; + } + } + if (ctlEp == NULL) { + error("LifeCamVX700 not found\n"); + } + + cam = new LifeCamVX700(VX700_160x120, _5FPS, ctlEp); + TEST_ASSERT_TRUE(cam); + cam->setOnResult(callback_motion_jpeg); + + Thread thread(display_thread, NULL, osPriorityBelowNormal); + + while(1) { + cam->poll(); + } +} +#endif