video streaming using websocket. but,streaming is very slower than 0.1fps.
Dependencies: BaseUsbHost EthernetInterface WebSocketClient mbed-rtos mbed
Fork of BaseUsbHost_example by
Revision 6:420a86583681, committed 2013-02-19
- Comitter:
- va009039
- Date:
- Tue Feb 19 15:49:33 2013 +0000
- Parent:
- 5:495f7536897b
- Child:
- 7:5dc595bbff58
- Commit message:
- video streaming using websocket
Changed in this revision
--- a/BaseUsbHost.lib Fri Jan 25 14:55:08 2013 +0000 +++ b/BaseUsbHost.lib Tue Feb 19 15:49:33 2013 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/va009039/code/BaseUsbHost/#d931d24c2f81 +http://mbed.org/users/va009039/code/BaseUsbHost/#8a2d056e9b38
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EthernetInterface.lib Tue Feb 19 15:49:33 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/EthernetInterface/#dd9794ce1d64
--- a/FATFileSystem.lib Fri Jan 25 14:55:08 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/va009039/code/FATFileSystem/#86638c0f65b0
--- a/LifeCamVX700/LifeCamVX700.cpp Fri Jan 25 14:55:08 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,99 +0,0 @@ -// LifeCamVX700.cpp 2013/1/25 -#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); - - 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); - int 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); - - rc = m_ctlEp->SetConfiguration(1); - TEST_ASSERT_EQUAL(rc, USB_OK); - - int value; - rc = m_ctlEp->GetConfiguration(&value); - TEST_ASSERT_EQUAL(rc, USB_OK); - DBG("config: %d\n", value); - TEST_ASSERT_EQUAL(value, 1); - - rc = m_ctlEp->SetInterfaceAlternate(1, VX700_IF_ALT); // alt=1 packet size = 192 - TEST_ASSERT_EQUAL(rc, USB_OK); - - rc = m_ctlEp->GetInterface(1, &value); - TEST_ASSERT_EQUAL(rc, USB_OK); - DBG("alt: %d\n", value); - TEST_ASSERT_EQUAL(value, 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; -} -
--- a/LifeCamVX700/LifeCamVX700.h Fri Jan 25 14:55:08 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ -// LifeCamVX700.h 2013/1/6 -#pragma once - -#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); -};
--- a/LogitechC270/LogitechC270.cpp Fri Jan 25 14:55:08 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,126 +0,0 @@ -// LogitechC270.cpp 2013/1/25 -#include "mbed.h" -#include "rtos.h" -#include "BaseUsbHost.h" -//#define DEBUG -#include "BaseUsbHostDebug.h" -#define TEST -#include "BaseUsbHostTest.h" -#include "LogitechC270.h" - -LogitechC270::LogitechC270(int formatIndex, 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, C270_EN, C270_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] = formatIndex; - 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], formatIndex); - TEST_ASSERT_EQUAL(buf[3], frameIndex); - TEST_ASSERT_EQUAL(*reinterpret_cast<uint32_t*>(buf+4), interval); - DBG_BYTES("GET_CUR Commit", buf, 26); - - int value; - rc = m_ctlEp->GetConfiguration(&value); - TEST_ASSERT_EQUAL(rc, USB_OK); - DBG("config: %d\n", value); - - rc = m_ctlEp->SetConfiguration(1); - TEST_ASSERT_EQUAL(rc, USB_OK); - - rc = m_ctlEp->GetConfiguration(&value); - TEST_ASSERT_EQUAL(rc, USB_OK); - DBG("config: %d\n", value); - TEST_ASSERT_EQUAL(value, 1); - - rc = m_ctlEp->GetInterface(1, &value); - TEST_ASSERT_EQUAL(rc, USB_OK); - DBG("alt: %d\n", value); - - rc = m_ctlEp->SetInterfaceAlternate(1, C270_IF_ALT); // alt=1 packet size = 192 - TEST_ASSERT_EQUAL(rc, USB_OK); - - rc = m_ctlEp->GetInterface(1, &value); - TEST_ASSERT_EQUAL(rc, USB_OK); - DBG("alt: %d\n", value); - TEST_ASSERT_EQUAL(value, C270_IF_ALT); - - 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 LogitechC270::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 == C270_VID && pid == C270_PID) { - return true; - } - return false; -}
--- a/LogitechC270/LogitechC270.h Fri Jan 25 14:55:08 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -// LogitechC270.h 2013/1/6 -#pragma once - -#define C270_VID 0x046d -#define C270_PID 0x0825 - -#define C270_160x120 2 -#define C270_176x144 3 -#define C270_320x176 4 -#define C270_320x240 5 -#define C270_352x288 6 -#define C270_432x240 7 -#define C270_640x480 1 -#define C270_544x288 8 -#define C270_640x360 9 -#define C270_752x416 10 -#define C270_800x448 11 -#define C270_800x600 12 - -#define C270_MJPEG 2 -#define C270_YUV2 1 - -#define C270_EN 0x81 -#define C270_MPS 192 -#define C270_IF_ALT 1 - -class LogitechC270 : public BaseUvc { -public: - LogitechC270(int formatIndex = C270_MJPEG, int frameIndex = C270_160x120, uint32_t interval = _5FPS, ControlEp* ctlEp = NULL); - static bool check(ControlEp* ctlEp); -};
--- a/UsbFlashDrive/UsbFlashDrive.cpp Fri Jan 25 14:55:08 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,406 +0,0 @@ -// UsbFlashDrive.cpp 2013/1/25 -#include "mbed.h" -#include "rtos.h" -#include "BaseUsbHost.h" -//#define DEBUG -#include "BaseUsbHostDebug.h" -#define TEST -#include "BaseUsbHostTest.h" -#include "UsbFlashDrive.h" - -//#define WRITE_PROTECT - - -uint32_t BE32(uint8_t* d) -{ - return (d[0] << 24) | (d[1] << 16) | (d[2] << 8) | d[3]; -} - -void BE16(uint32_t n, uint8_t* d) -{ - d[0] = (uint8_t)(n >> 8); - d[1] = (uint8_t)n; -} - -void BE32(uint32_t n, uint8_t* d) -{ - d[0] = (uint8_t)(n >> 24); - d[1] = (uint8_t)(n >> 16); - d[2] = (uint8_t)(n >> 8); - d[3] = (uint8_t)n; -} - -UsbFlashDrive::UsbFlashDrive(const char* name, ControlEp* ctlEp): FATFileSystem(name) -{ - m_name = name; - - if (ctlEp == NULL) { // root hub - DBG_OHCI(LPC_USB->HcRhPortStatus1); - TEST_ASSERT_FALSE(LPC_USB->HcRhPortStatus1 & 0x200); - ctlEp = new ControlEp(); - TEST_ASSERT_TRUE(ctlEp); - } - - CTASSERT(sizeof(CBW) == 31); - CTASSERT(sizeof(CSW) == 13); - TEST_ASSERT(sizeof(CBW) == 31); - TEST_ASSERT(sizeof(CSW) == 13); - - m_numBlocks = 0; - m_BlockSize = 0; - m_lun = 0; - m_interface = 0; - m_pEpBulkIn = NULL; - m_pEpBulkOut = NULL; - - ParseConfiguration(ctlEp); - int rc = ctlEp->SetConfiguration(1); - TEST_ASSERT_EQUAL(rc, USB_OK); - GetMaxLUN(ctlEp); - setup(ctlEp); -} - -bool UsbFlashDrive::check(ControlEp* ctlEp) -{ - if (ctlEp == NULL) { - return false; - } - CTASSERT(sizeof(StandardDeviceDescriptor) == 18); - CTASSERT(sizeof(StandardConfigurationDescriptor) == 9); - CTASSERT(sizeof(StandardInterfaceDescriptor) == 9); - TEST_ASSERT(sizeof(StandardDeviceDescriptor) == 18); - TEST_ASSERT(sizeof(StandardConfigurationDescriptor) == 9); - TEST_ASSERT(sizeof(StandardInterfaceDescriptor) == 9); - - StandardDeviceDescriptor desc; - int rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_DEVICE, 0, reinterpret_cast<uint8_t*>(&desc), sizeof(StandardDeviceDescriptor)); - if (rc != USB_OK) { - return false; - } - if (desc.bDeviceClass == 8) { - return true; - } else if (desc.bDeviceClass != 0x00) { - return false; - } - uint8_t temp[4]; - rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, temp, sizeof(temp)); - if (rc != USB_OK) { - return false; - } - StandardConfigurationDescriptor* cfg = reinterpret_cast<StandardConfigurationDescriptor*>(temp); - uint8_t* buf = new uint8_t[cfg->wTotalLength]; - - rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, buf, cfg->wTotalLength); - if (rc != USB_OK) { - return false; - } - DBG_HEX(buf, cfg->wTotalLength); - bool ret = false; - for(int pos = 0; pos < cfg->wTotalLength; pos += buf[pos]) { - StandardInterfaceDescriptor* desc = reinterpret_cast<StandardInterfaceDescriptor*>(buf+pos); - if (desc->bDescriptorType == 4) { // interface ? - if (desc->bInterfaceClass == 8 && desc->bInterfaceSubClass == 6 && desc->bInterfaceProtocol == 0x50) { - ret = true; - } - break; - } - } - delete[] buf; - return ret; -} - -int UsbFlashDrive::disk_initialize() -{ - //DBG("m_BlockSize=%d\n", m_BlockSize); - if (m_BlockSize != 512) { - return 1; - } - return 0; -} - -int UsbFlashDrive::disk_write(const uint8_t* buffer, uint64_t sector) -{ - m_report_disk_write++; - //DBG("buffer=%p block_number=%d\n", buffer, sector); - int ret = MS_BulkSend(sector, 1, buffer); - if (ret >= 0) { - return 0; - } - return 1; -} - -int UsbFlashDrive::disk_read(uint8_t* buffer, uint64_t sector) -{ - m_report_disk_read++; - //DBG("buffer=%p block_number=%d\n", buffer, sector); - int ret = MS_BulkRecv(sector, 1, buffer); - if (ret >= 0) { - return 0; - } - return 1; -} - -int UsbFlashDrive::disk_status() -{ - m_report_disk_status++; - return 0; -} - -int UsbFlashDrive::disk_sync() -{ - m_report_disk_sync++; - return 0; -} - -uint64_t UsbFlashDrive::disk_sectors() -{ - DBG("m_numBlocks=%d\n", m_numBlocks); - return m_numBlocks; -} - -int UsbFlashDrive::setup(ControlEp* ctlEp, int timeout) -{ - - int retry = 0; - Timer t; - t.start(); - t.reset(); - while(t.read_ms() < timeout) { - DBG("retry=%d t=%d\n", retry, t.read_ms()); - if (retry > 80) { - return -1; - } - int rc = TestUnitReady(); - DBG("TestUnitReady(): %d\n", rc); - if (rc == USB_OK) { - DBG("m_CSW.bCSWStatus: %02X\n", m_CSW.bCSWStatus); - if (m_CSW.bCSWStatus == 0x00) { - break; - } - } - GetSenseInfo(); - retry++; - wait_ms(50); - } - if (t.read_ms() >= timeout) { - return -1; - } - ReadCapacity(); - Inquire(); - return 0; -} - -int UsbFlashDrive::ParseConfiguration(ControlEp* ctlEp) -{ - TEST_ASSERT(ctlEp); - TEST_ASSERT(sizeof(StandardEndpointDescriptor) == 7); - uint8_t temp[4]; - int rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, temp, sizeof(temp)); - if (rc != USB_OK) { - return rc; - } - StandardConfigurationDescriptor* cfg = reinterpret_cast<StandardConfigurationDescriptor*>(temp); - uint8_t* buf = new uint8_t[cfg->wTotalLength]; - rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, buf, cfg->wTotalLength); - if (rc != USB_OK) { - return rc; - } - DBG_HEX(buf, cfg->wTotalLength); - for(int pos = 0; pos < cfg->wTotalLength; pos += buf[pos]) { - StandardEndpointDescriptor* desc = reinterpret_cast<StandardEndpointDescriptor*>(buf+pos); - if (desc->bDescriptorType == USB_DESCRIPTOR_TYPE_ENDPOINT) { - if (desc->bmAttributes == 2) { // bulk - BulkEp* pEp = new BulkEp(ctlEp->GetAddr(), desc->bEndpointAddress, desc->wMaxPacketSize); - if (desc->bEndpointAddress & 0x80) { - m_pEpBulkIn = pEp; - } else { - m_pEpBulkOut = pEp; - } - } - } - } - delete[] buf; - if (m_pEpBulkIn && m_pEpBulkOut) { - return USB_OK; - } - return USB_ERROR; -} - -int UsbFlashDrive::BulkOnlyMassStorageReset(ControlEp* ctlEp) -{ - TEST_ASSERT(ctlEp); - int rc = ctlEp->controlReceive(0x21, 0xff, 0x0000, m_interface, NULL, 0); - TEST_ASSERT(rc == USB_OK); - return rc; -} - -int UsbFlashDrive::GetMaxLUN(ControlEp* ctlEp) -{ - TEST_ASSERT(ctlEp); - TEST_ASSERT(m_interface == 0); - uint8_t temp[1]; - 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]; - TEST_ASSERT(m_MaxLUN <= 15); - return rc; -} - - -int UsbFlashDrive::TestUnitReady() -{ - const uint8_t cdb[6] = {SCSI_CMD_TEST_UNIT_READY, 0x00, 0x00, 0x00, 0x00, 0x00}; - m_CBW.dCBWDataTraansferLength = 0; - m_CBW.bmCBWFlags = 0x00; - CommandTransport(cdb, sizeof(cdb)); - StatusTransport(); - return 0; -} - -int UsbFlashDrive::GetSenseInfo() -{ - const uint8_t cdb[6] = {SCSI_CMD_REQUEST_SENSE, 0x00, 0x00, 0x00, 18, 0x00}; - m_CBW.dCBWDataTraansferLength = 18; - m_CBW.bmCBWFlags = 0x80; // data In - CommandTransport(cdb, sizeof(cdb)); - - uint8_t buf[18]; - _bulkRecv(buf, sizeof(buf)); - DBG_HEX(buf, sizeof(buf)); - - StatusTransport(); - TEST_ASSERT(m_CSW.bCSWStatus == 0x00); - return 0; -} - -int UsbFlashDrive::ReadCapacity() -{ - const uint8_t cdb[10] = {SCSI_CMD_READ_CAPACITY, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00}; - m_CBW.dCBWDataTraansferLength = 8; - m_CBW.bmCBWFlags = 0x80; // data In - CommandTransport(cdb, sizeof(cdb)); - - uint8_t buf[8]; - int rc = _bulkRecv(buf, sizeof(buf)); - TEST_ASSERT(rc >= 0); - DBG_HEX(buf, sizeof(buf)); - - StatusTransport(); - TEST_ASSERT(m_CSW.bCSWStatus == 0x00); - - m_numBlocks = BE32(buf); - m_BlockSize = BE32(buf+4); - DBG("m_numBlocks=%d m_BlockSize=%d\n", m_numBlocks, m_BlockSize); - TEST_ASSERT(m_BlockSize == 512); - TEST_ASSERT(m_numBlocks > 0); - return 0; -} - -int UsbFlashDrive::Inquire() -{ - const uint8_t cdb[6] = {SCSI_CMD_INQUIRY, 0x00, 0x00, 0x00, 36, 0x00}; - m_CBW.dCBWDataTraansferLength = 36; - m_CBW.bmCBWFlags = 0x80; // data In - CommandTransport(cdb, sizeof(cdb)); - - uint8_t buf[36]; - int rc = _bulkRecv(buf, sizeof(buf)); - TEST_ASSERT(rc >= 0); - DBG_HEX(buf, sizeof(buf)); - - StatusTransport(); - return 0; -} - -int UsbFlashDrive::MS_BulkRecv(uint32_t block_number, int num_blocks, uint8_t* user_buffer) -{ - TEST_ASSERT(m_BlockSize == 512); - TEST_ASSERT(num_blocks == 1); - TEST_ASSERT(user_buffer); - uint8_t cdb[10] = {SCSI_CMD_READ_10, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00}; - BE32(block_number, cdb+2); - BE16(num_blocks, cdb+7); - uint32_t len = m_BlockSize * num_blocks; - TEST_ASSERT(len <= 512); - m_CBW.dCBWDataTraansferLength = len; - m_CBW.bmCBWFlags = 0x80; // data In - CommandTransport(cdb, sizeof(cdb)); - - int ret = _bulkRecv(user_buffer, len); - //DBG_HEX(user_buffer, len); - - StatusTransport(); - TEST_ASSERT(m_CSW.bCSWStatus == 0x00); - return ret; -} - -int UsbFlashDrive::MS_BulkSend(uint32_t block_number, int num_blocks, const uint8_t* user_buffer) -{ -#ifdef WRITE_PROTECT - return 0; -#else - TEST_ASSERT(num_blocks == 1); - TEST_ASSERT(user_buffer); - uint8_t cdb[10] = {SCSI_CMD_WRITE_10, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00}; - BE32(block_number, cdb+2); - BE16(num_blocks, cdb+7); - uint32_t len = m_BlockSize * num_blocks; - TEST_ASSERT(len <= 512); - m_CBW.dCBWDataTraansferLength = len; - m_CBW.bmCBWFlags = 0x00; // data Out - CommandTransport(cdb, sizeof(cdb)); - - int ret = _bulkSend(user_buffer, len); - //DBG_HEX(user_buffer, len); - - StatusTransport(); - TEST_ASSERT(m_CSW.bCSWStatus == 0x00); - return ret; -#endif //WRITE_PROTECT -} - -int UsbFlashDrive::CommandTransport(const uint8_t* cdb, int size) -{ - TEST_ASSERT(cdb); - TEST_ASSERT(size >= 6); - TEST_ASSERT(size <= 16); - m_CBW.bCBWLUN = m_lun; - m_CBW.bCBWCBLength = size; - memcpy(m_CBW.CBWCB, cdb, size); - - m_CBW.dCBWSignature = 0x43425355; - m_CBW.dCBWTag = m_tag++; - m_CBW.bCBWLUN = 0; - //DBG_HEX((uint8_t*)&m_CBW, sizeof(CBW)); - int rc = _bulkSend((uint8_t*)&m_CBW, sizeof(CBW)); - return rc; -} - -int UsbFlashDrive::StatusTransport() -{ - TEST_ASSERT(sizeof(CSW) == 13); - int rc = _bulkRecv((uint8_t*)&m_CSW, sizeof(CSW)); - //DBG_HEX((uint8_t*)&m_CSW, sizeof(CSW)); - TEST_ASSERT(m_CSW.dCSWSignature == 0x53425355); - TEST_ASSERT(m_CSW.dCSWTag == m_CBW.dCBWTag); - TEST_ASSERT(m_CSW.dCSWDataResidue == 0); - return rc; -} - -int UsbFlashDrive::_bulkRecv(uint8_t* buf, int size) -{ - TEST_ASSERT(m_pEpBulkIn); - 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->bulkSend(buf, size); - return ret; -}
--- a/UsbFlashDrive/UsbFlashDrive.h Fri Jan 25 14:55:08 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -// usbFlashDrive.h 2013/1/8 -#pragma once - -#include "FATFileSystem.h" - -#define SCSI_CMD_REQUEST_SENSE 0x03 -#define SCSI_CMD_TEST_UNIT_READY 0x00 -#define SCSI_CMD_INQUIRY 0x12 -#define SCSI_CMD_READ_10 0x28 -#define SCSI_CMD_READ_CAPACITY 0x25 -#define SCSI_CMD_WRITE_10 0x2A - -#pragma pack(push,1) -struct CBW { - uint32_t dCBWSignature; - uint32_t dCBWTag; - uint32_t dCBWDataTraansferLength; - uint8_t bmCBWFlags; - uint8_t bCBWLUN; - uint8_t bCBWCBLength; - uint8_t CBWCB[16]; -}; - -struct CSW { - uint32_t dCSWSignature; - uint32_t dCSWTag; - uint32_t dCSWDataResidue; - uint8_t bCSWStatus; -}; -#pragma pack(pop) - -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(); -private: - 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(); - int Inquire(); - int MS_BulkRecv(uint32_t block_number, int num_blocks, uint8_t* user_buffer); - int MS_BulkSend(uint32_t block_number, int num_blocks, const uint8_t* user_buffer); - int CommandTransport(const uint8_t* cdb, int size); - int StatusTransport(); - int _bulkRecv(uint8_t* buf, int size); - int _bulkSend(const uint8_t* buf, int size); - const char* m_name; - int m_drive; - uint32_t m_numBlocks; - int m_BlockSize; - int m_lun; - int m_MaxLUN; - int m_interface; - uint32_t m_tag; - CBW m_CBW; - CSW m_CSW; - // endpoint - BulkEp* m_pEpBulkIn; - BulkEp* m_pEpBulkOut; - // report - uint32_t m_report_disk_write; - uint32_t m_report_disk_read; - uint32_t m_report_disk_status; - uint32_t m_report_disk_sync; -};
--- a/UvcCam/UvcCam.cpp Fri Jan 25 14:55:08 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,566 +0,0 @@ -// UvcCam.cpp 2013/1/25 -#include "mbed.h" -#include "rtos.h" -#include "BaseUsbHost.h" -//#define DEBUG -#include "BaseUsbHostDebug.h" -#define TEST -#include "BaseUsbHostTest.h" -#include "UvcCam.h" - -UvcCam::UvcCam(int formatIndex, int frameIndex, uint32_t interval, ControlEp* ctlEp) -{ - uint8_t buf[34]; - int rc; - int alt; - int cfg2; - - 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; - - UvcCfg* cfg = new UvcCfg(formatIndex, frameIndex, ctlEp); - TEST_ASSERT(cfg); - - int param_len = 34; - TEST_ASSERT(cfg->bcdUVC >= 0x0100); - if (cfg->bcdUVC == 0x0100) { // UVC ver. 1.0 - param_len = 26; - } - - int addr = m_ctlEp->GetAddr(); - m_isoEp = new IsochronousEp(addr, cfg->bEndpointAddress, cfg->wMaxPacketSize); - TEST_ASSERT_TRUE(m_isoEp); - -//#define USE_PROBE - -#ifdef USE_PROBE - 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, param_len); - TEST_ASSERT(rc == USB_OK); - DBG_BYTES("GET_DEF Probe", buf, param_len); - - rc = Control(GET_MIN, VS_PROBE_CONTROL, 1, buf, param_len); - TEST_ASSERT(rc == USB_OK); - DBG_BYTES("GET_MIN Probe", buf, param_len); - - rc = Control(GET_MAX, VS_PROBE_CONTROL, 1, buf, param_len); - TEST_ASSERT(rc == USB_OK); - DBG_BYTES("GET_MAX Probe", buf, param_len); - - rc = Control(GET_CUR, VS_PROBE_CONTROL, 1, buf, param_len); - TEST_ASSERT(rc == USB_OK); - DBG_BYTES("GET_CUR Probe", buf, param_len); -#endif // USE_PROBE - - rc = Control(GET_INFO, VS_COMMIT_CONTROL, 1, buf, 1); - TEST_ASSERT(rc == USB_OK); - DBG_BYTES("GET_INFO Commit", buf, 1); - - memset(buf, 0, param_len); - buf[2] = cfg->FormatIndex; - buf[3] = cfg->FrameIndex; - *reinterpret_cast<uint32_t*>(buf+4) = interval; - - DBG_BYTES("SET_CUR Commit", buf, param_len); - rc = Control(SET_CUR, VS_COMMIT_CONTROL, 1, buf, param_len); - TEST_ASSERT(rc == USB_OK); - - rc = Control(GET_CUR, VS_COMMIT_CONTROL, 1, buf, param_len); - TEST_ASSERT(rc == USB_OK); - TEST_ASSERT_EQUAL(buf[2], cfg->FormatIndex); - TEST_ASSERT_EQUAL(buf[3], cfg->FrameIndex); - TEST_ASSERT_EQUAL(*reinterpret_cast<uint32_t*>(buf+4), interval); - DBG_BYTES("GET_CUR Commit", buf, param_len); - - rc = m_ctlEp->GetConfiguration(&cfg2); - TEST_ASSERT_EQUAL(rc, USB_OK); - DBG("config: %d\n", cfg2); - - rc = m_ctlEp->SetConfiguration(1); - TEST_ASSERT_EQUAL(rc, USB_OK); - - rc = m_ctlEp->GetConfiguration(&cfg2); - TEST_ASSERT_EQUAL(rc, USB_OK); - DBG("config: %d\n", cfg2); - TEST_ASSERT_EQUAL(cfg2, 1); - - rc = m_ctlEp->GetInterface(cfg->bInterface, &alt); - TEST_ASSERT_EQUAL(rc, USB_OK); - DBG("alt: %d\n", alt); - - rc = m_ctlEp->SetInterfaceAlternate(cfg->bInterface, cfg->bAlternate); - TEST_ASSERT_EQUAL(rc, USB_OK); - - rc = m_ctlEp->GetInterface(cfg->bInterface, &alt); - TEST_ASSERT_EQUAL(rc, USB_OK); - DBG("alt: %d\n", alt); - TEST_ASSERT_EQUAL(alt, cfg->bAlternate); - delete cfg; - - 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 UvcCam::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}; - 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); - return true; -} - -#define DESCRIPTOR_TYPE_DEVICE 1 -#define DESCRIPTOR_TYPE_CONFIGURATION 2 -#define DESCRIPTOR_TYPE_STRING 3 -#define DESCRIPTOR_TYPE_INTERFACE 4 -#define DESCRIPTOR_TYPE_ENDPOINT 5 - -#define DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION 0x0b - -#define DESCRIPTOR_TYPE_HID 0x21 -#define DESCRIPTOR_TYPE_REPORT 0x22 -#define DESCRIPTOR_TYPE_PHYSICAL 0x23 -#define DESCRIPTOR_TYPE_CS_INTERFACE 0x24 -#define DESCRIPTOR_TYPE_CS_ENDPOINT 0x25 -#define DESCRIPTOR_TYPE_HUB 0x29 - -#define CLASS_AUDIO 0x02 -#define CLASS_HUB 0x09 - -#define IF_EQ_THEN_PRINTF(A,B) if (A == B) {VERBOSE("%s\n", #A); -#define ENDIF } - -#define CC_AUDIO 0x01 -#define SC_AUDIOCONTROL 0x01 -#define SC_AUDIOSTREAMING 0x02 - -#define AC_HEADER 0x01 -#define AC_INPUT_TERMINAL 0x02 -#define AC_OUTPUT_TERMINAL 0x03 -#define AC_FEATURE_UNIT 0x06 - -// Input Terminal Types -#define ITT_CAMERA 0x0201 - -static int LE16(const uint8_t* d) -{ - return d[0] | (d[1] << 8); -} - -static int LE24(const uint8_t* d) { - return d[0] | (d[1]<<8) | (d[2] << 16); -} - -static int LE32(const uint8_t* d) { - return d[0] |(d[1]<<8) | (d[2] << 16) |(d[3] << 24) ; -} - -UvcCfg::UvcCfg(int formatIndex, int frameIndex, ControlEp* ctlEp):wMaxPacketSize(0) -{ - TEST_ASSERT(ctlEp); - switch(formatIndex) { - case UVC_MJPEG: _payload = UVC_MJPEG; break; - case UVC_YUY2: _payload = UVC_YUY2; break; - default: _payload = UVC_MJPEG; break; - } - - switch(frameIndex) { - case UVC_160x120: _width = 160; _height = 120; break; - case UVC_176x144: _width = 176; _height = 144; break; - case UVC_320x176: _width = 320; _height = 176; break; - case UVC_320x240: _width = 320; _height = 240; break; - case UVC_352x288: _width = 352; _height = 288; break; - case UVC_432x240: _width = 432; _height = 240; break; - case UVC_640x480: _width = 640; _height = 480; break; - case UVC_544x288: _width = 544; _height = 288; break; - case UVC_640x360: _width = 640; _height = 360; break; - case UVC_752x416: _width = 752; _height = 416; break; - case UVC_800x448: _width = 800; _height = 448; break; - case UVC_800x600: _width = 800; _height = 600; break; - default: _width = 160; _height = 120; break; - } - int index = 0; - uint8_t temp[4]; - int rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, temp, sizeof(temp)); - TEST_ASSERT(rc == USB_OK); - DBG_BYTES("Config Descriptor 4bytes", temp, sizeof(temp)); - TEST_ASSERT(temp[0] == 9); - TEST_ASSERT(temp[1] == 0x02); - int TotalLength = LE16(temp+2); - DBG("TotalLength: %d\n", TotalLength); - - uint8_t* buf = new uint8_t[TotalLength]; - TEST_ASSERT(buf); - rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, TotalLength); - TEST_ASSERT(rc == USB_OK); - if (rc != USB_OK) { - delete[] buf; - return; - } - _parserConfigurationDescriptor(buf, TotalLength); - delete[] buf; -} - -void UvcCfg::_parserAudioControl(uint8_t* buf, int len) { - int subtype = buf[2]; - IF_EQ_THEN_PRINTF(AC_HEADER, subtype) - VERBOSE("ADC: %04x\n", LE16(buf+3)); - VERBOSE("TotalLength: %d\n", LE16(buf+5)); - VERBOSE("InCollection: %d\n", buf[7]); - for (int n = 1; n <= buf[7]; n++) { - VERBOSE("aInterfaceNr(%d): %d\n", n, buf[8+n-1]); - } - ENDIF - IF_EQ_THEN_PRINTF(AC_INPUT_TERMINAL, subtype) - VERBOSE("TerminalID: %d\n", buf[3]); - VERBOSE("TerminalType: %04X\n", LE16(buf+4)); - VERBOSE("AssocTermianl: %d\n", buf[6]); - VERBOSE("NrChannels: %d\n", buf[7]); - ENDIF - IF_EQ_THEN_PRINTF(AC_OUTPUT_TERMINAL, subtype) - VERBOSE("TerminalID: %d\n", buf[3]); - VERBOSE("TerminalType: %04X\n", LE16(buf+4)); - VERBOSE("AssocTermianl: %d\n", buf[6]); - ENDIF - IF_EQ_THEN_PRINTF(AC_FEATURE_UNIT, subtype) - VERBOSE("UnitID: %d\n", buf[3]); - VERBOSE("SourceID: %d\n", buf[4]); - VERBOSE("ControlSize: %d\n", buf[5]); - ENDIF -} - -#define AS_GENERAL 0x01 -#define AS_FORMAT_TYPE 0x02 - -void UvcCfg::_parserAudioStream(uint8_t* buf, int len) { - int subtype = buf[2]; - IF_EQ_THEN_PRINTF(AS_GENERAL, subtype) - VERBOSE("TerminalLink: %d\n", buf[3]); - VERBOSE("Delay: %d\n", buf[4]); - VERBOSE("FormatTag: %04x\n", LE16(buf+5)); - ENDIF - IF_EQ_THEN_PRINTF(AS_FORMAT_TYPE, subtype) - VERBOSE("FormatType: %d\n", buf[3]); - VERBOSE("NrChannels: %d\n", buf[4]); - VERBOSE("SubFrameSize: %d\n", buf[5]); - VERBOSE("BitResolution: %d\n", buf[6]); - VERBOSE("SamFreqType: %d\n", buf[7]); - VERBOSE("SamFreq(1): %d\n", LE24(buf+8)); - ENDIF -} - -#define CC_VIDEO 0x0e - -#define SC_VIDEOCONTROL 0x01 -#define SC_VIDEOSTREAMING 0x02 - -#define VC_HEADER 0x01 -#define VC_INPUT_TERMINAL 0x02 -#define VC_OUTPUT_TERMINAL 0x03 -#define VC_SELECTOR_UNIT 0x04 -#define VC_PROCESSING_UNIT 0x05 -#define VC_EXTENSION_UNIT 0x06 - -void UvcCfg::_parserVideoControl(uint8_t* buf, int len) { - int subtype = buf[2]; - IF_EQ_THEN_PRINTF(VC_HEADER, subtype) - bcdUVC = LE16(buf+3); - VERBOSE("UVC: %04x\n", bcdUVC); - VERBOSE("TotalLength: %d\n", LE16(buf+5)); - VERBOSE("ClockFrequency: %d\n", LE32(buf+7)); - VERBOSE("InCollection: %d\n", buf[11]); - VERBOSE("aInterfaceNr(1): %d\n", buf[12]); - ENDIF - IF_EQ_THEN_PRINTF(VC_INPUT_TERMINAL, subtype) - VERBOSE("TerminalID: %d\n", buf[3]); - uint16_t tt = LE16(buf+4); - VERBOSE("TerminalType: %04X\n", tt); - VERBOSE("AssocTerminal: %d\n", buf[6]); - VERBOSE("Terminal: %d\n", buf[7]); - if (tt == ITT_CAMERA) { // camera - int bControlSize = buf[14]; - VERBOSE("ControlSize: %d\n", bControlSize); - for(int i = 0; i < bControlSize; i++) { - uint8_t bControls = buf[15+i]; - VERBOSE("Controls(%d): %02X\n", i, bControls); - } - } - ENDIF - IF_EQ_THEN_PRINTF(VC_OUTPUT_TERMINAL, subtype) - VERBOSE("TerminalID: %d\n", buf[3]); - VERBOSE("TerminalType: %04X\n", LE16(buf+4)); - VERBOSE("AssocTerminal: %d\n", buf[6]); - VERBOSE("SourceID: %d\n", buf[7]); - VERBOSE("Terminal: %d\n", buf[8]); - ENDIF - IF_EQ_THEN_PRINTF(VC_SELECTOR_UNIT, subtype) - VERBOSE("UnitID: %d\n", buf[3]); - ENDIF - IF_EQ_THEN_PRINTF(VC_PROCESSING_UNIT, subtype) - VERBOSE("UnitID: %d\n", buf[3]); - VERBOSE("SourceID: %d\n", buf[4]); - VERBOSE("MaxMultiplier: %d\n", LE16(buf+5)); - VERBOSE("ControlSize: %d\n", buf[7]); - int pos = 8; - for (int n = 1; n <= buf[7]; n++) { - VERBOSE("Controls(%d): %02X\n", n , buf[pos]); - pos++; - } - VERBOSE("Processing: %d\n", buf[pos]); - pos++; - VERBOSE("VideoStanders: %02X\n", buf[pos]); - ENDIF - IF_EQ_THEN_PRINTF(VC_EXTENSION_UNIT, subtype) - VERBOSE("UnitID: %d\n", buf[3]); - ENDIF -} - -#define VS_INPUT_HEADER 0x01 -#define VS_STILL_FRAME 0x03 -#define VS_FORMAT_UNCOMPRESSED 0x04 -#define VS_FRAME_UNCOMPRESSED 0x05 -#define VS_FORMAT_MJPEG 0x06 -#define VS_FRAME_MJPEG 0x07 -#define VS_COLOR_FORMAT 0x0d - -void UvcCfg::_parserVideoStream(uint8_t* buf, int len) { - int subtype = buf[2]; - IF_EQ_THEN_PRINTF(VS_INPUT_HEADER, subtype) - VERBOSE("NumFormats: %d\n", buf[3]); - VERBOSE("TotalLength: %d\n", LE16(buf+4)); - VERBOSE("EndpointAddress: %02X\n", buf[6]); - VERBOSE("Info: %02X\n", buf[7]); - VERBOSE("TerminalLink: %d\n", buf[8]); - VERBOSE("StillCaptureMethod: %d\n", buf[9]); - VERBOSE("TriggerSupport: %d\n", buf[10]); - VERBOSE("TriggerUsage: %d\n", buf[11]); - VERBOSE("ControlSize: %d\n", buf[12]); - int pos = 13; - for (int n = 1; n <= buf[12]; n++) { - VERBOSE("Controls(%d): %02X\n", n, buf[pos]); - pos++; - } - bEndpointAddress = buf[6]; - ENDIF - IF_EQ_THEN_PRINTF(VS_STILL_FRAME, subtype) - VERBOSE("EndpointAdress: %02X\n", buf[3]); - VERBOSE("NumImageSizePatterns: %d\n", buf[4]); - int ptn = buf[4]; - int pos = 5; - for (int n = 1; n <= ptn; n++) { - VERBOSE("Width(%d): %d\n", n, LE16(buf+pos)); - VERBOSE("Height(%d): %d\n", n, LE16(buf+pos+2)); - pos += 4; - } - VERBOSE("NumCompressPtn: %d\n", buf[pos]); - ptn = buf[pos++]; - for (int n = 1; n <= ptn; n++) { - VERBOSE("Compress(%d): %d\n", n, buf[pos]); - pos++; - } - ENDIF - IF_EQ_THEN_PRINTF(VS_FORMAT_UNCOMPRESSED, subtype) - VERBOSE("FormatIndex: %d\n", buf[3]); - VERBOSE("NumFrameDescriptors: %d\n", buf[4]); - uint32_t guid = LE32(buf+5); - if (guid == 0x32595559) { - VERBOSE("GUID: YUY2\n"); - } else if (guid == 0x3231564e) { - VERBOSE("GUID: NV12\n"); - } else { - VERBOSE("GUID: %08x\n", guid); - } - VERBOSE("DefaultFrameIndex: %d\n", buf[22]); - if (_payload == UVC_YUY2) { - FormatIndex = buf[3]; - } - ENDIF - IF_EQ_THEN_PRINTF(VS_FRAME_UNCOMPRESSED, subtype) - VERBOSE("FrameIndex: %d\n", buf[3]); - VERBOSE("Capabilites: %d\n", buf[4]); - VERBOSE("Width: %d\n", LE16(buf+5)); - VERBOSE("Height: %d\n", LE16(buf+7)); - VERBOSE("MinBitRate: %d\n", LE32(buf+9)); - VERBOSE("MaxBitRate: %d\n", LE32(buf+13)); - VERBOSE("MaxVideoFrameBufferSize: %d\n", LE32(buf+17)); - VERBOSE("DefaultFrameInterval: %d\n", LE32(buf+21)); - VERBOSE("FrameIntervalType: %d\n", buf[25]); - int it = buf[25]; - uint32_t max_fi = 333333; // 30.0fps - if (it == 0) { - VERBOSE("FrameMinInterval: %d\n", buf[26]); - VERBOSE("FrameMaxInterval: %d\n", buf[30]); - VERBOSE("FrameIntervalStep: %d\n", buf[34]); - } else { - int pos = 26; - for (int n = 1; n <= it; n++) { - uint32_t fi = LE32(buf+pos); - if (fi >= max_fi) { - max_fi = fi; - } - float fps = 1e+7 / fi; - VERBOSE("FrameInterval(%u): %d (%.1f fps)\n", n, fi, fps); - pos += 4; - } - } - if (_payload == UVC_YUY2) { - if (_width == LE16(buf+5) && _height == LE16(buf+7)) { - FrameIndex = buf[3]; - } - if (dwFrameInterval == 0) { - dwFrameInterval = max_fi; - } - } - ENDIF - IF_EQ_THEN_PRINTF(VS_FORMAT_MJPEG, subtype) - VERBOSE("FormatIndex: %d\n", buf[3]); - VERBOSE("NumFrameDescriptors: %d\n", buf[4]); - VERBOSE("Flags: %d\n", buf[5]); - VERBOSE("DefaultFrameIndex: %d\n", buf[6]); - if (_payload == UVC_MJPEG) { - FormatIndex = buf[3]; - } - ENDIF - IF_EQ_THEN_PRINTF(VS_FRAME_MJPEG, subtype) - VERBOSE("FrameIndex: %d\n", buf[3]); - VERBOSE("Capabilites: %d\n", buf[4]); - VERBOSE("Width: %d\n", LE16(buf+5)); - VERBOSE("Height: %d\n", LE16(buf+7)); - VERBOSE("MinBitRate: %d\n", LE32(buf+9)); - VERBOSE("MaxBitRate: %d\n", LE32(buf+13)); - VERBOSE("MaxVideoFrameBufferSize: %d\n", LE32(buf+17)); - VERBOSE("DefaultFrameInterval: %d\n", LE32(buf+21)); - VERBOSE("FrameIntervalType: %d\n", buf[25]); - int it = buf[25]; - uint32_t max_fi = 333333; // 30.0fps - if (it == 0) { - VERBOSE("FrameMinInterval: %d\n", buf[26]); - VERBOSE("FrameMaxInterval: %d\n", buf[30]); - VERBOSE("FrameIntervalStep: %d\n", buf[34]); - } else { - int pos = 26; - for (int n = 1; n <= it; n++) { - uint32_t fi = LE32(buf+pos); - if (fi >= max_fi) { - max_fi = fi; - } - float fps = 1e+7 / fi; - VERBOSE("FrameInterval(%u): %d (%.1f fps)\n", n, fi, fps); - pos += 4; - } - } - if (_payload == UVC_MJPEG) { - if (_width == LE16(buf+5) && _height == LE16(buf+7)) { - FrameIndex = buf[3]; - } - if (dwFrameInterval == 0) { - dwFrameInterval = max_fi; - } - } - ENDIF - IF_EQ_THEN_PRINTF(VS_COLOR_FORMAT, subtype) - ENDIF -} - -void UvcCfg::_parserConfigurationDescriptor(uint8_t* buf, int len) { - int pos = 0; - _IfClass = 0; - _IfSubClass = 0; - while (pos < len) { - int type = buf[pos+1]; - //DBG_BYTES(TYPE_Str(type), buf+pos, buf[pos]); - IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_CONFIGURATION, type) - VERBOSE("NumInterfaces: %d\n", buf[pos+4]); - ENDIF - IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, type) - VERBOSE("FirstInterface: %d\n", buf[pos+2]); - VERBOSE("InterfaceCount: %d\n", buf[pos+3]); - VERBOSE("FunctionClass: %02X\n", buf[pos+4]); - VERBOSE("FunctionSubClass: %02X\n", buf[pos+5]); - VERBOSE("FunctionProtocol: %02X\n", buf[pos+6]); - VERBOSE("Function: %d\n", buf[pos+7]); - ENDIF - IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_INTERFACE,type) - VERBOSE("InterfaceNumber: %d\n", buf[pos+2]); - VERBOSE("AlternateSetting: %d\n", buf[pos+3]); - VERBOSE("NumEndpoint: %d\n", buf[pos+4]); - VERBOSE("InterfaceClass: %02X\n", buf[pos+5]); - VERBOSE("InterfaceSubClass: %02X\n", buf[pos+6]); - VERBOSE("InterfaceProtocol: %02X\n", buf[pos+7]); - VERBOSE("Interface: %d\n", buf[pos+8]); - _If = buf[pos+2]; - _Ifalt = buf[pos+3]; - _IfClass = buf[pos+5]; - _IfSubClass = buf[pos+6]; - ENDIF - IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_ENDPOINT, type) - VERBOSE("EndpointAddress: %02X\n", buf[pos+2]); - VERBOSE("Attributes: %02X\n", buf[pos+3]); - VERBOSE("MaxPacketSize: %d\n", LE16(buf+pos+4)); - VERBOSE("Interval: %d\n", buf[pos+6]); - if (_IfClass == CC_VIDEO && _IfSubClass == SC_VIDEOSTREAMING) { - if (bEndpointAddress == buf[pos+2]) { - if (wMaxPacketSize == 0) { - wMaxPacketSize = LE16(buf+pos+4); - } - if (wMaxPacketSize == LE16(buf+pos+4)) { - bInterface = _If; - bAlternate = _Ifalt; - } - } - } - ENDIF - IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_CS_INTERFACE, type) - IF_EQ_THEN_PRINTF(CC_VIDEO, _IfClass) - IF_EQ_THEN_PRINTF(SC_VIDEOCONTROL, _IfSubClass) - _parserVideoControl(buf+pos, buf[pos]); - ENDIF - IF_EQ_THEN_PRINTF(SC_VIDEOSTREAMING, _IfSubClass) - _parserVideoStream(buf+pos, buf[pos]); - ENDIF - ENDIF - IF_EQ_THEN_PRINTF(CC_AUDIO, _IfClass) - IF_EQ_THEN_PRINTF(SC_AUDIOCONTROL, _IfSubClass) - _parserAudioControl(buf+pos, buf[pos]); - ENDIF - IF_EQ_THEN_PRINTF(SC_AUDIOSTREAMING, _IfSubClass) - _parserAudioStream(buf+pos, buf[pos]); - ENDIF - ENDIF - ENDIF - IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_HUB, type) - ENDIF - pos += buf[pos]; - } -} -
--- a/UvcCam/UvcCam.h Fri Jan 25 14:55:08 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -// UvcCam.h 2012/12/9 -#ifndef UVC_CAM_H -#define UVC_CAM_H - -#define UVC_160x120 2 -#define UVC_176x144 3 -#define UVC_320x176 4 -#define UVC_320x240 5 -#define UVC_352x288 6 -#define UVC_432x240 7 -#define UVC_640x480 1 -#define UVC_544x288 8 -#define UVC_640x360 9 -#define UVC_752x416 10 -#define UVC_800x448 11 -#define UVC_800x600 12 - -#define UVC_MJPEG 2 -#define UVC_YUY2 1 - -#define VERBOSE(...) do{printf(__VA_ARGS__);} while(0); - -class UvcCam : public BaseUvc { -public: - UvcCam(int formatIndex = UVC_MJPEG, int frameIndex = UVC_160x120, uint32_t interval = _5FPS, ControlEp* ctlEp = NULL); - static bool check(ControlEp* ctlEp); -}; - -class UvcCfg { -public: - UvcCfg(int formatIndex, int frameIndex, ControlEp* ctlEp); - uint8_t bEndpointAddress; - uint16_t wMaxPacketSize; - uint8_t FormatIndex; - uint8_t FrameIndex; - uint32_t dwFrameInterval; - uint8_t bInterface; - uint8_t bAlternate; - uint16_t bcdUVC; -protected: - void _parserAudioControl(uint8_t* buf, int len); - void _parserAudioStream(uint8_t* buf, int len); - void _parserVideoControl(uint8_t* buf, int len); - void _parserVideoStream(uint8_t* buf, int len); - void _parserConfigurationDescriptor(uint8_t* buf, int len); - uint16_t _width; - uint16_t _height; - uint8_t _payload; - int _If; - int _Ifalt; - int _IfClass; - int _IfSubClass; -}; - -#endif //UVC_CAM_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WebSocketClient.lib Tue Feb 19 15:49:33 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/samux/code/WebSocketClient/#4567996414a5
--- a/main.cpp Fri Jan 25 14:55:08 2013 +0000 +++ b/main.cpp Tue Feb 19 15:49:33 2013 +0000 @@ -1,27 +1,25 @@ -// BaseUsbHost_example/main.cpp 2013/1/25 -#include "mbed.h" -#include "rtos.h" +// VideoStreaming/main.cpp 2013/2/20 +#include "EthernetInterface.h" +#include "Websocket.h" #include "BaseUsbHost.h" -#include "LogitechC270.h" -#include "LifeCamVX700.h" #include "UvcCam.h" -#include "UsbFlashDrive.h" #include "decodeMJPEG.h" #include "MyThread.h" -#include <string> -#define IMAGE_BUF_SIZE (1024*7) -#define INTERVAL_S 30 +#define CHANNEL "public-ch" +#define URL "ws://sockets.mbed.org/ws/"CHANNEL"/rw" +#define VIEWER "http://va009039-mbed.appspot.com/VideoStreaming/"CHANNEL"/viewer" +#define FRAME_LIMIT 4 +#define IMAGE_BUFFER_SIZE (1024*3) -Serial pc(USBTX, USBRX); +Serial term(USBTX, USBRX); DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4); struct ImageBuffer { - int pos; - uint8_t buf[IMAGE_BUF_SIZE]; + uint16_t pos; + uint8_t buf[IMAGE_BUFFER_SIZE]; void clear() { pos = 0; } int size() { return pos; } - uint8_t get(int pos) { return buf[pos]; } void put(uint8_t c) { if (pos < sizeof(buf)) { buf[pos++] = c; @@ -31,13 +29,17 @@ Mail<ImageBuffer, 1> mail_box; -class captureJPEG : public MyThread, public decodeMJPEG { +class Capture : public MyThread, public decodeMJPEG { public: - captureJPEG(BaseUvc* cam) : m_cam(cam) { + Capture(BaseUvc* cam) : m_cam(cam) { + m_cam->setOnResult(this, &Capture::callback_motion_jpeg); m_buf = NULL; - m_cam->setOnResult(this, &captureJPEG::callback_motion_jpeg); } -private: +private: + ImageBuffer* m_buf; + BaseUvc* m_cam; + + // from decodeMJPEG virtual void outputJPEG(uint8_t c, int status) { if (m_buf == NULL && status == JPEG_START) { m_buf = mail_box.alloc(); @@ -50,112 +52,126 @@ if (status == JPEG_END) { mail_box.put(m_buf); m_buf = NULL; - led3 = !led3; } } } void callback_motion_jpeg(uint16_t frame, uint8_t* buf, int len) { - inputPacket(buf, len); - led1 = buf[1]&1; // FID - if (buf[1]&2) { // EOF - led2 = !led2; - } + inputPacket(buf, len); // to decodeMJPEG } virtual void run() { - while(true) { - if (m_cam) { - m_cam->poll(); - } + while(1) { + m_cam->poll(); } } - ImageBuffer* m_buf; - BaseUvc* m_cam; }; +// Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) +int base64enc(const char *input, unsigned int length, char *output, int outputlen) { + static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + unsigned int c, c1, c2, c3; + + if (outputlen < (((length-1)/3)+1)<<2) return -1; + + for(unsigned int i = 0, j = 0; i<length; i+=3,j+=4) { + c1 = ((((unsigned char)*((unsigned char *)&input[i])))); + c2 = (length>i+1)?((((unsigned char)*((unsigned char *)&input[i+1])))):0; + c3 = (length>i+2)?((((unsigned char)*((unsigned char *)&input[i+2])))):0; + + c = ((c1 & 0xFC) >> 2); + output[j+0] = base64[c]; + c = ((c1 & 0x03) << 4) | ((c2 & 0xF0) >> 4); + output[j+1] = base64[c]; + c = ((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6); + output[j+2] = (length>i+1)?base64[c]:'='; + c = (c3 & 0x3F); + output[j+3] = (length>i+2)?base64[c]:'='; + } + output[(((length-1)/3)+1)<<2] = '\0'; + return 0; +} + +#define CHUNK (3*20) + +void buf_to_websocket(Websocket*ws, ImageBuffer* buf) { + Timer t; + int send_bytes = 0; + t.reset(); + t.start(); + char output[CHUNK/3*4+1]; + for(int i = 0; i < buf->size(); i += CHUNK) { + int len = buf->size() - i; + if (len > CHUNK) { + len = CHUNK; + } + base64enc(reinterpret_cast<const char*>(buf->buf+i), len, output, sizeof(output)); + term.printf("%s\n", output); + send_bytes += ws->send(output); + } + strcpy(output, "."); + term.printf("%s\n", output); + send_bytes += ws->send(output); + term.printf("websocket: send %d bytes %d ms\n", send_bytes, t.read_ms()); +} + void no_memory () { error("Failed to allocate memory!\n"); } int main() { - pc.baud(921600); - printf("%s\n", __FILE__); + term.baud(921600); + term.printf("%s\n", __FILE__); set_new_handler(no_memory); - BaseUvc* cam = NULL; - UsbFlashDrive* drive = NULL; + EthernetInterface eth; + eth.init(); //Use DHCP + int r = eth.connect(); + if (r != 0) { + error("mbed is not connected to the Internet. %d\n", r); + } + term.printf("IP Address is %s\n\r", eth.getIPAddress()); + Websocket* ws = new Websocket(URL); + if (!ws->connect()) { + error("mbed is not connected to websocket "URL); + } + BaseUsbHost* usbHost = new BaseUsbHost(); ControlEp* ctlEp = new ControlEp; // root hub - if (!UsbHub::check(ctlEp)) { - error("USB Hub is not connected.\n"); - } - UsbHub* hub = new UsbHub(ctlEp); - ctlEp = hub->search<UsbFlashDrive>(); - if (ctlEp) { - drive = new UsbFlashDrive("usb", ctlEp); - } - ctlEp = hub->search<LogitechC270>(); - if (ctlEp) { - //cam = new LogitechC270(C270_MJPEG, C270_160x120, _5FPS, ctlEp); - cam = new LogitechC270(C270_MJPEG, C270_320x176, _5FPS, ctlEp); - } - if (cam == NULL) { - ctlEp = hub->search<LifeCamVX700>(); - if (ctlEp) { - cam = new LifeCamVX700(VX700_160x120, _5FPS, ctlEp); + if (UsbHub::check(ctlEp)) { + UsbHub* hub = new UsbHub(ctlEp); + ctlEp = hub->search<UvcCam>(0); + if (ctlEp == NULL) { + error("UVC Camera is not connected in USB hub.\n"); } - } - if (cam == NULL) { - ctlEp = hub->search<UvcCam>(); - if (ctlEp) { - cam = new UvcCam(UVC_MJPEG, UVC_160x120, _5FPS, ctlEp); - } - } - if (cam == NULL) { + } else if (!UvcCam::check(ctlEp)) { error("UVC Camera is not connected.\n"); } - if (drive == NULL) { - error("USB flash drive is not connected.\n"); - } + UvcCam* cam = new UvcCam(UVC_MJPEG, UVC_160x120, _5FPS, ctlEp); + + Capture* capture_th = new Capture(cam); + capture_th->set_stack(512); + capture_th->start(); + + term.printf("\n\n"VIEWER"\n\n"); - captureJPEG* capture = new captureJPEG(cam); - capture->set_stack(DEFAULT_STACK_SIZE-128*8); - capture->start(); - - for(int n = 0; ; n++) { - printf("%d captureJPEG stack used: %d/%d bytes\n", n, capture->stack_used(), capture->stack_size()); - osEvent evt = mail_box.get(); + int frame = 0; + for(int n = 0;; n++) { + osEvent evt = mail_box.get(200); if (evt.status == osEventMail) { ImageBuffer *buf = reinterpret_cast<ImageBuffer*>(evt.value.p); - time_t timestamp = time(NULL); - struct tm* tminfo = localtime(×tamp); - char tmbuf[32]; - strftime(tmbuf, sizeof(tmbuf), "/usb/img%M%S.jpg", tminfo); - string path = tmbuf; - printf("%s %d bytes\n", path.c_str(), buf->size()); - FILE* fp = fopen(path.c_str(), "wb"); - if (fp) { - for(int i = 0; i < buf->size(); i++) { - fputc(buf->get(i), fp); - //Thread::yield(); - } - fclose(fp); + if (frame < 10) { + term.printf("Capture stack used: %d/%d bytes\n", capture_th->stack_used(), capture_th->stack_size()); + term.printf("image size: %d bytes\n", buf->size()); + } + if (frame++ < FRAME_LIMIT || FRAME_LIMIT==(-1)) { + led2 = 1; + buf_to_websocket(ws, buf); + led2 = 0; } mail_box.free(buf); led4 = !led4; } - - printf("CC:"); - for(int i = 0; i < 16; i++) { - printf(" %u", cam->report_cc_count[i]); - } - printf("\nPS:"); - for(int i = 0; i < 16; i++) { - printf(" %u", cam->report_ps_cc_count[i]); - } - printf("\n"); - - Thread::wait(INTERVAL_S*1000); + led1 = ws->is_connected(); } }
--- a/mbed.bld Fri Jan 25 14:55:08 2013 +0000 +++ b/mbed.bld Tue Feb 19 15:49:33 2013 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/0954ebd79f59 \ No newline at end of file +http://mbed.org/users/mbed_official/code/mbed/builds/3d0ef94e36ec \ No newline at end of file