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.
Dependencies: BaseJpegDecode Terminal BaseUsbHost mbed mbed-rtos
Fork of BaseJpegDecode by
Revision 7:3ad9c948bc06, committed 2013-01-27
- Comitter:
- va009039
- Date:
- Sun Jan 27 11:15:26 2013 +0000
- Parent:
- 6:95be1cd2bc14
- Commit message:
- change library uvchost to BaseUsbHost, delete SimpleJpegDecode
Changed in this revision
--- a/BaseJpegDecode.lib Wed Dec 05 12:41:25 2012 +0000 +++ b/BaseJpegDecode.lib Sun Jan 27 11:15:26 2013 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/va009039/code/BaseJpegDecode/#e243fa781e5c +http://mbed.org/users/va009039/code/BaseJpegDecode/#85e99ec2e7b5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BaseUsbHost.lib Sun Jan 27 11:15:26 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/va009039/code/BaseUsbHost/#d931d24c2f81
--- a/FATFileSystem.lib Wed Dec 05 12:41:25 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/mbed_official/code/FATFileSystem/#b6669c987c8e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MyThread/MyThread.h Sun Jan 27 11:15:26 2013 +0000
@@ -0,0 +1,52 @@
+// MyThread.h 2012/12/9
+#ifndef MY_THREAD_H
+#define MY_THREAD_H
+
+#define MAGIC_WORD 0xE25A2EA5
+static void thread_handler(void const *argument);
+
+class MyThread {
+public:
+ MyThread() {
+ m_stack_size = DEFAULT_STACK_SIZE;
+ m_stack_pointer = NULL;
+ }
+ void set_stack(uint32_t stack_size=DEFAULT_STACK_SIZE, uint8_t* stack_pointer = NULL) {
+ m_stack_size = stack_size;
+ m_stack_pointer = stack_pointer;
+ }
+ virtual void run() = 0;
+ Thread* start(osPriority priority=osPriorityNormal) {
+ if (m_stack_pointer == NULL) {
+ m_stack_pointer = reinterpret_cast<uint8_t*>(malloc(m_stack_size));
+ }
+ for(int i = 0; i < m_stack_size-64; i += 4) {
+ *reinterpret_cast<uint32_t*>(m_stack_pointer+i) = MAGIC_WORD;
+ }
+ return th = new Thread(thread_handler, this, priority, m_stack_size, m_stack_pointer);
+ }
+
+ int stack_used() {
+ int i;
+ for(i = 0; i < m_stack_size; i += 4) {
+ if(*reinterpret_cast<uint32_t*>(m_stack_pointer+i) != MAGIC_WORD) {
+ break;
+ }
+ }
+ return m_stack_size - i;
+ }
+
+ int stack_size() { return m_stack_size; }
+protected:
+ Thread* th;
+ uint32_t m_stack_size;
+ uint8_t* m_stack_pointer;
+};
+static void thread_handler(void const *argument) {
+ MyThread* th = (MyThread*)argument;
+ if (th) {
+ th->run();
+ }
+}
+
+#endif //MY_THREAD_H
--- a/SimpleJpegDecode.cpp Wed Dec 05 12:41:25 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,161 +0,0 @@
-#include "SimpleJpegDecode.h"
-
-#define DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);} while(0);
-#define ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);};
-
-
-#define _1_4020 45
-#define _0_3441 11
-#define _0_7139 23
-#define _1_7718 57
-#define _0_0012 0
-
-int adjust(int r) {
- if (r >= 0) {
- if (r <= 255) {
- return r;
- } else {
- return 255;
- }
- } else {
- return 0;
- }
-}
-
-void convYUVtoRGB(uint8_t rgb[], int y, int u, int v)
-{
- rgb[0] = adjust((y*32 + v*_1_4020)/32 + 128);
- rgb[1] = adjust((y*32 - u*_0_3441 - v*_0_7139)/32 + 128);
- rgb[2] = adjust((y*32 + u*_1_7718 - v*_0_0012)/32 + 128);
-}
-
-SimpleJpegDecode::SimpleJpegDecode(uint8_t output_mode)
-{
- m_output_mode = output_mode;
- clearOnResult();
-}
-
-
-void SimpleJpegDecode::output(int mcu, int block, int scan, int value)
-{
- int sc = (block < yblock) ? 0 : 1;
- inputBLOCK(mcu, block, scan, value * qt[sc][scan]);
-}
-
-void SimpleJpegDecode::outputDC(int mcu, int block, int value)
-{
- output(mcu, block, 0, value);
- DC_count++;
-}
-
-void SimpleJpegDecode::outputAC(int mcu, int block, int scan, int value)
-{
- output(mcu, block, scan, value);
- AC_count++;
-}
-
-void SimpleJpegDecode::outputMARK(uint8_t c)
-{
-}
-
-void SimpleJpegDecode::format_YUV(int mcu, int block, int8_t* values)
-{
- if (block < yblock+1) {
- memcpy(m_block_data[block], values, 64);
- return;
- }
- int mcu_x_count = (width+15)/16;
- int mcu_x = mcu % mcu_x_count;
- int mcu_y = mcu / mcu_x_count;
- uint8_t yuv[3];
- if (yblock == 2) {
- for(int y = 0; y < 8; y++) {
- for(int x = 0; x < 16; x++) {
- yuv[0] = m_block_data[x/8][y*8+x%8] + 128;
- yuv[1] = m_block_data[2][y*8+x/2] + 128;
- yuv[2] = values[y*8+x/2] + 128;
- onResult(mcu_x * 16 + x, mcu_y * 8 + y, yuv);
- }
- }
- } else if (yblock == 4) {
- for(int y = 0; y < 16; y++) {
- for(int x = 0; x < 16; x++) {
- yuv[0] = m_block_data[(y/8)*2+x/8][(y%8)*8+x%8] + 128;
- yuv[1] = m_block_data[4][(y/2)*8+x/2] + 128;
- yuv[2] = values[(y/2)*8+x/2] + 128;
- onResult(mcu_x * 16 + x, mcu_y * 16 + y, yuv);
- }
- }
- } else {
- ASSERT(yblock == 2 || yblock == 4);
- }
-}
-
-void SimpleJpegDecode::format_RGB24(int mcu, int block, int8_t* values)
-{
- if (block < yblock+1) {
- memcpy(m_block_data[block], values, 64);
- return;
- }
- int mcu_x_count = (width+15)/16;
- int mcu_x = mcu % mcu_x_count;
- int mcu_y = mcu / mcu_x_count;
- uint8_t rgb[3];
- if (yblock == 2) {
- for(int y = 0; y < 8; y++) {
- for(int x = 0; x < 16; x++) {
- int8_t yuv_y = m_block_data[x/8][y*8+x%8];
- int8_t yuv_u = m_block_data[2][y*8+x/2];
- int8_t yuv_v = values[y*8+x/2];
- convYUVtoRGB(rgb, yuv_y, yuv_u, yuv_v);
- onResult(mcu_x * 16 + x, mcu_y * 8 + y, rgb);
- }
- }
- } else if (yblock == 4) {
- for(int y = 0; y < 16; y++) {
- for(int x = 0; x < 16; x++) {
- int8_t yuv_y = m_block_data[(y/8)*2+x/8][(y%8)*8+x%8];
- int8_t yuv_u = m_block_data[4][(y/2)*8+x/2];
- int8_t yuv_v = values[(y/2)*8+x/2];
- convYUVtoRGB(rgb, yuv_y, yuv_u, yuv_v);
- onResult(mcu_x * 16 + x, mcu_y * 16 + y, rgb);
- }
- }
- } else {
- ASSERT(yblock == 2 || yblock == 4);
- }
-}
-
-void SimpleJpegDecode::outputBLOCK(int mcu, int block, int8_t* values)
-{
- BLOCK_count++;
- if (m_output_mode == YUV) {
- format_YUV(mcu, block, values);
- } else if (m_output_mode == RGB24) {
- format_RGB24(mcu, block, values);
- } else {
- ASSERT(m_output_mode == YUV || m_output_mode == RGB24);
- }
-}
-
-void SimpleJpegDecode::onResult(int x, int y, uint8_t* yuv)
-{
- if(m_pCbItem && m_pCbMeth)
- (m_pCbItem->*m_pCbMeth)(x, y, yuv);
- else if(m_pCb)
- m_pCb(x, y, yuv);
-}
-
-void SimpleJpegDecode::setOnResult( void (*pMethod)(int, int, uint8_t*) )
-{
- m_pCb = pMethod;
- m_pCbItem = NULL;
- m_pCbMeth = NULL;
-}
-
-void SimpleJpegDecode::clearOnResult()
-{
- m_pCb = NULL;
- m_pCbItem = NULL;
- m_pCbMeth = NULL;
-}
--- a/SimpleJpegDecode.h Wed Dec 05 12:41:25 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-#ifndef SIMPLE_JPEG_DECODE_H
-#define SIMPLE_JPEG_DECODE_H
-
-#include "BaseJpegDecode.h"
-#include "inverseDCT.h"
-
-#define YUV 0
-#define RGB24 1
-
-class SimpleJpegDecode : public BaseJpegDecode, public inverseDCT {
-public:
- SimpleJpegDecode(uint8_t output_mode=RGB24);
-
- void format_YUV(int mcu, int block, int8_t* values);
- void format_RGB24(int mcu, int block, int8_t* values);
-
- void output(int mcu, int block, int scan, int value);
- virtual void outputDC(int mcu, int block, int value);
- virtual void outputAC(int mcu, int block, int scan, int value);
- virtual void outputMARK(uint8_t c);
- virtual void outputBLOCK(int muc, int block, int8_t* values); // iDCT
-
- int8_t m_block_data[5][64];
- int DC_count;
- int AC_count;
- int BLOCK_count;
-
- ///Setups the result callback
- /**
- @param pMethod : callback function
- */
- void setOnResult( void (*pMethod)(int, int, uint8_t*) );
-
- ///Setups the result callback
- /**
- @param pItem : instance of class on which to execute the callback method
- @param pMethod : callback method
- */
- class CDummy;
- template<class T>
- void setOnResult( T* pItem, void (T::*pMethod)(int, int, uint8_t*) )
- {
- m_pCb = NULL;
- m_pCbItem = (CDummy*) pItem;
- m_pCbMeth = (void (CDummy::*)(int, int, uint8_t*)) pMethod;
- }
- void clearOnResult();
-protected:
- void onResult(int x, int y, uint8_t* yuv);
- CDummy* m_pCbItem;
- void (CDummy::*m_pCbMeth)(int, int, uint8_t*);
- void (*m_pCb)(int, int, uint8_t*);
- uint8_t m_output_mode;
-};
-
-#endif // SIMPLE_JPEG_DECODE_H
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/UvcCam/UvcCam.cpp Sun Jan 27 11:15:26 2013 +0000
@@ -0,0 +1,566 @@
+// 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];
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/UvcCam/UvcCam.h Sun Jan 27 11:15:26 2013 +0000
@@ -0,0 +1,55 @@
+// 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
--- a/bmp24.h Wed Dec 05 12:41:25 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-#ifndef BMP24_H
-#define BMP24_H
-
-#define BMP24_WIDTH (16*4)
-#define BMP24_HEIGHT (16*3)
-
-class bmp24 {
-public:
- int width;
- int height;
-
- bmp24() {
- width = BMP24_WIDTH;
- height = BMP24_HEIGHT;
- }
-
- void clear() {
- memset(m_bitmap, 0, sizeof(m_bitmap));
- }
-
- void point(int x, int y, uint8_t* rgb) {
- if (x >= 0 && x < width && y >= 0 && y < height) {
- int pos = y*width*3+x*3;
- m_bitmap[pos++] = rgb[0];
- m_bitmap[pos++] = rgb[1];
- m_bitmap[pos] = rgb[2];
- }
- }
-
- void LE32write(uint8_t* buf, int value) {
- *buf++ = value & 0xff;
- *buf++ = (value>>8) & 0xff;
- *buf++ = (value>>16) & 0xff;
- *buf = (value>>24) & 0xff;
- }
-
- void writeFile(const char *path) {
- FILE *fp = fopen(path, "wb");
- if (fp == NULL) {
- return;
- }
- uint8_t header[] = {
-0x42,0x4d,0x36,0xe1,0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x28,0x00,
-0x00,0x00,0xa0,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x01,0x00,0x18,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-0x00,0x00,0x00,0x00,0x00,0x00};
- int file_size = sizeof(header) + sizeof(m_bitmap);
- LE32write(header+2, file_size);
- LE32write(header+18, width);
- LE32write(header+22, height);
-
- fwrite(header, 1, sizeof(header), fp);
- for(int y = height-1; y >=0; y--) {
- for(int x = 0; x < width; x++) {
- fputc(m_bitmap[y*width*3+x*3+2], fp);
- fputc(m_bitmap[y*width*3+x*3+1], fp);
- fputc(m_bitmap[y*width*3+x*3+0], fp);
- }
- }
- fclose(fp);
- }
-
- uint8_t m_bitmap[BMP24_WIDTH*BMP24_HEIGHT*3];
-};
-
-#endif // BMP24_H
--- a/example1_c270.cpp Wed Dec 05 12:41:25 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-#if 1
-//
-// simple color tracking
-//
-#include "mbed.h"
-#include "BaseJpegDecode.h"
-#include "uvc.h"
-#include "Terminal.h"
-
-// Logitech C270
-#define WIDTH 320
-//#define HEIGHT 176
-
-// LifeCam
-#define HEIGHT 240
-
-#define THRESHOLD 100
-
-#define ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);};
-
-DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4);
-Terminal term(USBTX, USBRX);
-
-class CalcCenter : public BaseJpegDecode {
-public:
- int y_center, x_center;
- int m_x_sum, m_y_sum, m_sum;
- int16_t m_buf[WIDTH/16*HEIGHT/8];
- virtual void outputDC(int mcu, int block, int value) {
- if (mcu >= (WIDTH/16*HEIGHT/8)) {
- return;
- }
- if (block == 3) { // 0-1:Y 2:Cb 3:Cr
- value *= qt[1][0];
- ASSERT(value < 32367 && value > -32368);
- m_buf[mcu] = value; // debug
- if (value >= THRESHOLD) { // red
- m_x_sum += value*(mcu%(WIDTH/16));
- m_y_sum += value*(mcu/(WIDTH/16));
- m_sum += value;
- }
- }
- }
- virtual void outputAC(int mcu, int block, int scan, int value){};
- virtual void outputMARK(uint8_t c){
- if (c == 0xd9) { // EOI
- if(m_sum == 0) {
- x_center = y_center = -1; // not found
- } else {
- x_center = m_x_sum / m_sum;
- y_center = m_y_sum / m_sum;
- }
- m_x_sum = m_y_sum = m_sum = 0; // reset
- led2 = !led2;
- }
- };
-};
-
-CalcCenter* calc = NULL;
-
-void callback_motion_jpeg(uint16_t frame, uint8_t* buf, int len)
-{
- if (calc) {
- calc->input(buf+12, len-12);
- }
- led1 = buf[1]&1; // FID
-}
-
-int main() {
- term.baud(921600);
- term.printf("%s\n", __FILE__);
-
- calc = new CalcCenter;
- ASSERT(calc);
- uvc* cam = new uvc;
- ASSERT(cam);
- cam->SetImageSize(WIDTH, HEIGHT);
- cam->SetFrameInterval(2000000); // 5.0fps
- cam->setOnResult(callback_motion_jpeg);
- ASSERT(cam->setup() >= 0);
- term.cls();
- int fg, old_fg = 0xffffff;
- while(1) {
- int y;
- for(y = 0; y < HEIGHT/8; y++) {
- term.locate(0, y);
- for(int x = 0; x < WIDTH/16; x++) {
- int value = calc->m_buf[y*WIDTH/16+x];
- if (value >= THRESHOLD) {
- fg = 0xff0000; // red
- } else {
- fg = 0xffffff; // white
- }
- if (fg != old_fg) {
- term.foreground(fg);
- old_fg = fg;
- }
- term.printf("%+4d,", value);
- cam->poll();
- }
- }
- term.locate(0, y);
- term.printf("Cr:(%d,%d)", calc->x_center, calc->y_center);
- cam->wait_ms(500);
- led3 = !led3;
- }
-}
-#endif
--- a/example_SimpleJpegDecode.cpp Wed Dec 05 12:41:25 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-#if 0
-//
-// split jpeg to bmp files
-//
-#include "mbed.h"
-#include "SimpleJpegDecode.h"
-#include "bmp24.h"
-#include "uvc.h"
-#include "msc.h"
-
-#define ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);};
-
-DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4);
-Serial pc(USBTX, USBRX);
-
-SimpleJpegDecode* decode = NULL;
-bmp24* bmp = NULL;
-
-int offset_x = 0;
-int offset_y = 0;
-
-void callbackRGB(int x, int y, uint8_t* rgb)
-{
- led1 = !led1;
- if (bmp) {
- bmp->point(x - offset_x, y - offset_y, rgb);
- }
-}
-
-int main() {
- pc.baud(921600);
- printf("%s\n", __FILE__);
-
- msc* usb = new msc("usb");
- int r = usb->setup();
- ASSERT(r == 0);
-
- bmp = new bmp24;
- ASSERT(bmp);
-
- decode = new SimpleJpegDecode();
- ASSERT(decode);
-
- const char* input_file = "/usb/input.jpg";
-
- FILE *fp = fopen(input_file, "rb");
- ASSERT(fp != NULL);
- Timer benchmark_t;
- benchmark_t.reset();
- benchmark_t.start();
- while(!feof(fp)) {
- int c = fgetc(fp);
- led2 = !led2;
- }
- benchmark_t.stop();
- fclose(fp);
- printf("input: %s, %d ms\n", input_file, benchmark_t.read_ms());
-
- decode->clear();
- fp = fopen(input_file, "rb");
- ASSERT(fp != NULL);
- benchmark_t.reset();
- benchmark_t.start();
- while(!feof(fp)) {
- int c = fgetc(fp);
- decode->input(c);
- led2 = !led2;
- }
- benchmark_t.stop();
- fclose(fp);
- printf("width: %d, height: %d, yblock: %d, %d ms\n", decode->width, decode->height,
- decode->yblock, benchmark_t.read_ms());
-
- decode->setOnResult(callbackRGB);
- int n = 0;
- for(offset_y = 0; offset_y < decode->height; offset_y += bmp->height) {
- for(offset_x = 0; offset_x < decode->width; offset_x += bmp->width) {
- bmp->clear();
- decode->clear();
- fp = fopen(input_file, "rb");
- ASSERT(fp != NULL);
- benchmark_t.reset();
- benchmark_t.start();
- while(!feof(fp)) {
- int c = fgetc(fp);
- decode->input(c);
- led2 = !led2;
- }
- benchmark_t.stop();
- fclose(fp);
- char path[32];
- sprintf(path, "/usb/output%02d.bmp", n++);
- printf("offset: (%3d,%3d), size:(%3d,%3d), %s %d ms\n",
- offset_x, offset_y, bmp->width, bmp->height,
- path, benchmark_t.read_ms());
- bmp->writeFile(path);
- led3 = !led3;
- }
- led4 = !led4;
- }
- printf("done\n");
- exit(1);
-}
-#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Sun Jan 27 11:15:26 2013 +0000
@@ -0,0 +1,153 @@
+// BaseJpegDecode_example/main.cpp 2013/1/27
+// simple color tracking
+//
+#include "mbed.h"
+#include "rtos.h"
+#include "BaseUsbHost.h"
+#include "UvcCam.h"
+#include "BaseJpegDecode.h"
+#include "Terminal.h"
+#include "MyThread.h"
+
+#define WIDTH 160
+#define HEIGHT 120
+
+#define THRESHOLD 200
+
+DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4);
+Terminal term(USBTX, USBRX);
+
+class CalcCenter : public MyThread, public BaseJpegDecode {
+public:
+ int y_center, x_center;
+ int m_x_sum, m_y_sum, m_sum;
+ uint32_t EOI_count;
+ int16_t buf_Cb[WIDTH/16*HEIGHT/8]; // debug
+ int16_t buf_Cr[WIDTH/16*HEIGHT/8]; // debug
+ CalcCenter(BaseUvc* cam) {
+ m_cam = cam;
+ m_cam->setOnResult(this, &CalcCenter::callback_motion_jpeg);
+ EOI_count = 0;
+ }
+protected:
+ void callback_motion_jpeg(uint16_t frame, uint8_t* buf, int len) {
+ input(buf+12, len-12);
+ if (buf[1]&1) { // FID
+ led1 = !led1;
+ }
+ }
+
+ virtual void outputDC(int mcu, int block, int value) {
+ if (mcu >= (WIDTH/16*HEIGHT/8)) {
+ return;
+ }
+ if (block == 2) {
+ buf_Cb[mcu] = value * qt[1][0];
+ } else if (block == 3) { // 0-1:Y 2:Cb 3:Cr
+ buf_Cr[mcu] = value * qt[1][0];
+ value *= qt[1][0];
+ if (value >= THRESHOLD) { // red
+ m_x_sum += value*(mcu%(WIDTH/16));
+ m_y_sum += value*(mcu/(WIDTH/16));
+ m_sum += value;
+ }
+ }
+ }
+ virtual void outputAC(int mcu, int block, int scan, int value){};
+ virtual void outputMARK(uint8_t c){
+ if (c == 0xd9) { // EOI
+ if(m_sum == 0) {
+ x_center = y_center = -1; // not found
+ } else {
+ x_center = m_x_sum / m_sum;
+ y_center = m_y_sum / m_sum;
+ }
+ m_x_sum = m_y_sum = m_sum = 0; // reset
+ EOI_count++;
+ led3 = !led3;
+ }
+ }
+
+ virtual void run() {
+ while(true) {
+ if (m_cam) {
+ m_cam->poll();
+ }
+ }
+ }
+ BaseUvc* m_cam;
+};
+
+BaseUvc* cam = NULL;
+CalcCenter* calc = NULL;
+
+class display_Thread : public MyThread {
+ virtual void run() {
+ term.cls();
+ int fg, old_fg = 0xffffff;
+ while(1) {
+ int column = 0;
+ for(int y = 0; y < HEIGHT/8; y++) {
+ term.locate(0, column++);
+ for(int x = 0; x < WIDTH/16; x++) {
+ int value = calc->buf_Cr[y*WIDTH/16+x];
+ if (value >= THRESHOLD) {
+ fg = 0xff0000; // red
+ } else {
+ fg = 0xffffff; // white
+ }
+ if (fg != old_fg) {
+ term.foreground(fg);
+ old_fg = fg;
+ }
+ term.printf("%+4d,", value);
+ Thread::yield();
+ }
+ }
+ term.locate(0, column++);
+ term.printf("Cr:(%d,%d)", calc->x_center, calc->y_center);
+
+ term.locate(0, column++);
+ term.printf("width=%d height=%d yblock=%d EOI: %u]\nCC:",
+ calc->width, calc->height, calc->yblock, calc->EOI_count);
+ for(int i = 0; i < 16; i++) {
+ term.printf(" %u", cam->report_cc_count[i]);
+ }
+ term.printf("]\nPS:");
+ for(int i = 0; i < 16; i++) {
+ term.printf(" %u", cam->report_ps_cc_count[i]);
+ }
+ term.printf("]\n");
+ Thread::wait(150);
+ led2 = !led2;
+ }
+ }
+};
+
+void no_memory () {
+ error("Failed to allocate memory!\n");
+}
+
+int main() {
+ term.baud(921600);
+ term.printf("%s\n", __FILE__);
+ set_new_handler(no_memory);
+
+ BaseUsbHost* UsbHost = new BaseUsbHost;
+ ControlEp* ctlEp = new ControlEp; // root hub
+ if (UsbHub::check(ctlEp)) { // hub?
+ UsbHub* hub = new UsbHub(ctlEp);
+ ctlEp = hub->search<UvcCam>();
+ }
+ if (!UvcCam::check(ctlEp)) {
+ error("UVC camera is not connected\n");
+ }
+ cam = new UvcCam(UVC_MJPEG, UVC_160x120, _15FPS, ctlEp);
+ calc = new CalcCenter(cam);
+ calc->start();
+
+ display_Thread* display_th = new display_Thread;
+ display_th->start(osPriorityBelowNormal);
+
+ Thread::wait(osWaitForever);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Sun Jan 27 11:15:26 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-rtos/#88a1a9c26ae3
--- a/mbed.bld Wed Dec 05 12:41:25 2012 +0000 +++ b/mbed.bld Sun Jan 27 11:15:26 2013 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/b60934f96c0c \ No newline at end of file +http://mbed.org/users/mbed_official/code/mbed/builds/0954ebd79f59 \ No newline at end of file
--- a/msc/msc.cpp Wed Dec 05 12:41:25 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,390 +0,0 @@
-#include "msc.h"
-//#define __DEBUG
-#include "mydbg.h"
-#include "Utils.h"
-
-//#define WRITE_PROTECT
-
-msc::msc(const char* name, int drive): FATFileSystem(name)
-{
- DBG("drive=%d\n", drive);
- m_name = name;
- m_drive = drive;
- DBG_ASSERT(sizeof(CBW) == 31);
- DBG_ASSERT(sizeof(CSW) == 13);
- m_numBlocks = 0;
- m_BlockSize = 0;
- m_lun = 0;
- m_interface = 0;
- m_pDev = NULL;
- m_pEpBulkIn = NULL;
- m_pEpBulkOut = NULL;
-}
-
-int msc::disk_initialize()
-{
- DBG("m_BlockSize=%d\n", m_BlockSize);
- if (m_BlockSize != 512) {
- return 1;
- }
- return 0;
-}
-
-int msc::disk_write(const uint8_t *buffer, uint64_t block_number)
-{
- DBG("buffer=%p block_number=%d\n", buffer, block_number);
- int ret = MS_BulkSend(block_number, 1, (uint8_t*)buffer);
- if (ret >= 0) {
- return 0;
- }
- return 1;
-}
-
-int msc::disk_read(uint8_t *buffer, uint64_t block_number)
-{
- DBG("buffer=%p block_number=%d\n", buffer, block_number);
- int ret = MS_BulkRecv(block_number, 1, (uint8_t*)buffer);
- if (ret >= 0) {
- return 0;
- }
- return 1;
-}
-
-int msc::disk_status()
-{
- DBG("\n");
- return 0;
-}
-
-int msc::disk_sync()
-{
- DBG("\n");
- return 0;
-}
-
-uint64_t msc::disk_sectors()
-{
- DBG("m_numBlocks=%d\n", m_numBlocks);
- return m_numBlocks;
-}
-
-int msc::setup(int timeout)
-{
- for(int i = 0; i < 2; i++) {
- m_pDev = m_pHost->getDeviceByClass(0x08, m_drive); // USB Mass Storage Class
- if (m_pDev || i > 0) {
- break;
- }
- UsbErr rc = Usb_poll();
- if (rc == USBERR_PROCESSING) {
- VERBOSE("%p USBERR_PROCESSING\n", this);
- return -1;
- }
- }
- DBG("m_pDev=%p\n", m_pDev);
- if (m_pDev == NULL) {
- VERBOSE("%p MSC DISK(%d) NOT FOUND\n", this, m_drive);
- return -1;
- }
- DBG_ASSERT(m_pDev);
-
- ParseConfiguration();
-
- GetMaxLUN();
-
- 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 == USBERR_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;
-}
-void msc::_test()
-{
- ReadCapacity();
-
- uint8_t buf[512];
- for(int block = 0; block < m_numBlocks; block++) {
- DBG("block=%d\n", block);
- disk_read(buf, block);
- }
- exit(1);
-}
-
-int msc::ParseConfiguration()
-{
- UsbErr rc;
- uint8_t ConfigDesc[9];
- int index = 0;
- DBG_ASSERT(m_pDev);
- rc = m_pDev->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, ConfigDesc, sizeof(ConfigDesc));
- DBG_ASSERT(rc == USBERR_OK);
- DBG_BYTES("ConfigDescriptor 9bytes", ConfigDesc, sizeof(ConfigDesc));
- DBG_ASSERT(ConfigDesc[0] == 9);
- DBG_ASSERT(ConfigDesc[1] == 0x02);
- int wTotalLength = *((uint16_t*)&ConfigDesc[2]);
- DBG("TotalLength: %d\n", wTotalLength);
- int bConfigValue = ConfigDesc[5];
- DBG_ASSERT(bConfigValue == 1);
- DBG("ConfigValue: %d\n", bConfigValue);
- DBG("MaxPower: %d mA\n", ConfigDesc[8]*2);
-
- uint8_t* buf = new uint8_t[wTotalLength];
- DBG_ASSERT(buf);
- rc = m_pDev->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, wTotalLength);
- DBG_ASSERT(rc == USBERR_OK);
- DBG_ASSERT(ConfigDesc[1] == 0x02);
- for (int pos = 0; pos < wTotalLength; pos += buf[pos]) {
- DBG_BYTES("CFG", buf+pos, buf[pos]);
- int type = buf[pos+1];
- if (USB_DESCRIPTOR_TYPE_INTERFACE == type) { // 0x04
- DBG("InterfaceNumber: %d\n", buf[pos+2]);
- DBG("AlternateSetting: %d\n", buf[pos+3]);
- DBG("NumEndpoint: %d\n", buf[pos+4]);
- DBG("InterfaceClass: %02X\n", buf[pos+5]);
- DBG("InterfaceSubClass: %02X\n", buf[pos+6]);
- DBG("InterfaceProtocol: %02X\n", buf[pos+7]);
- DBG_ASSERT(buf[pos+6] == 0x06); // SCSI
- DBG_ASSERT(buf[pos+7] == 0x50); // bulk only
- }
- if (USB_DESCRIPTOR_TYPE_ENDPOINT == type) {
- DBG_ASSERT(buf[pos] == 7);
- uint8_t att = buf[pos+3];
- if (att == 2) { // bulk
- uint8_t ep = buf[pos+2];
- bool dir = ep & 0x80; // true=IN
- uint16_t size = LE16(buf+pos+4);
- DBG("EndpointAddress: %02X\n", ep);
- DBG("Attribute: %02X\n", att);
- DBG("MaxPacketSize: %d\n", size);
- UsbEndpoint* pEp = new UsbEndpoint(m_pDev, ep, dir, USB_BULK, size);
- DBG_ASSERT(pEp);
- if (dir) {
- m_pEpBulkIn = pEp;
- } else {
- m_pEpBulkOut = pEp;
- }
- }
- }
- }
- delete[] buf;
- DBG_ASSERT(m_pEpBulkIn);
- DBG_ASSERT(m_pEpBulkOut);
- return 0;
-}
-
-int msc::BulkOnlyMassStorageReset()
-{
- DBG_ASSERT(m_pDev);
- UsbErr rc = m_pDev->controlReceive(0x21, 0xff, 0x0000, m_interface, NULL, 0);
- DBG_ASSERT(rc == USBERR_OK);
- return rc;
-}
-
-int msc::GetMaxLUN()
-{
- DBG_ASSERT(m_interface == 0);
- uint8_t temp[1];
- DBG_ASSERT(m_pDev);
- UsbErr rc = m_pDev->controlReceive(0xa1, 0xfe, 0x0000, m_interface, temp, sizeof(temp));
- DBG_ASSERT(rc == USBERR_OK);
- DBG_BYTES("GetMaxLUN", temp, sizeof(temp));
- m_MaxLUN = temp[0];
- DBG_ASSERT(m_MaxLUN <= 15);
- return rc;
-}
-
-
-int msc::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 msc::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();
- DBG_ASSERT(m_CSW.bCSWStatus == 0x00);
- return 0;
-}
-
-int msc::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));
- DBG_ASSERT(rc >= 0);
- DBG_HEX(buf, sizeof(buf));
-
- StatusTransport();
- DBG_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);
- DBG_ASSERT(m_BlockSize == 512);
- DBG_ASSERT(m_numBlocks > 0);
- return 0;
-}
-
-int msc::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];
- _bulkRecv(buf, sizeof(buf));
- DBG_HEX(buf, sizeof(buf));
-
- StatusTransport();
- return 0;
-}
-
-int msc::MS_BulkRecv(uint32_t block_number, int num_blocks, uint8_t* user_buffer)
-{
- DBG_ASSERT(m_BlockSize == 512);
- DBG_ASSERT(num_blocks == 1);
- DBG_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;
- DBG_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();
- DBG_ASSERT(m_CSW.bCSWStatus == 0x00);
- return ret;
-}
-
-int msc::MS_BulkSend(uint32_t block_number, int num_blocks, uint8_t* user_buffer)
-{
-#ifdef WRITE_PROTECT
- return 0;
-#else
- DBG_ASSERT(num_blocks == 1);
- DBG_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;
- DBG_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();
- DBG_ASSERT(m_CSW.bCSWStatus == 0x00);
- return ret;
-#endif //WRITE_PROTECT
-}
-
-int msc::CommandTransport(const uint8_t* cdb, int size)
-{
- DBG_ASSERT(cdb);
- DBG_ASSERT(size >= 6);
- DBG_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 msc::StatusTransport()
-{
- DBG_ASSERT(sizeof(CSW) == 13);
- int rc = _bulkRecv((uint8_t*)&m_CSW, sizeof(CSW));
- //DBG_HEX((uint8_t*)&m_CSW, sizeof(CSW));
- DBG_ASSERT(m_CSW.dCSWSignature == 0x53425355);
- DBG_ASSERT(m_CSW.dCSWTag == m_CBW.dCBWTag);
- DBG_ASSERT(m_CSW.dCSWDataResidue == 0);
- return rc;
-}
-
-int msc::_bulkRecv(uint8_t* buf, int size)
-{
- UsbErr rc = m_pEpBulkIn->transfer(buf, size);
- DBG_ASSERT(rc == USBERR_PROCESSING);
- while(m_pEpBulkIn->status() == USBERR_PROCESSING){
- wait_us(1);
- }
- int ret = m_pEpBulkIn->status();
- if (ret >= 0) {
- return ret;
- }
- DBG("buf=%p size=%d ret=%d\n", buf, size, ret);
- return ret;
-}
-
-int msc::_bulkSend(uint8_t* buf, int size)
-{
- DBG_ASSERT(m_pEpBulkOut);
- UsbErr rc = m_pEpBulkOut->transfer(buf, size);
- DBG_ASSERT(rc == USBERR_PROCESSING);
- while(m_pEpBulkOut->status() == USBERR_PROCESSING){
- wait_us(1);
- }
- int ret = m_pEpBulkOut->status();
- if (ret >= 0) {
- return ret;
- }
- DBG("buf=%p size=%d ret=%d\n", buf, size, ret);
- return ret;
-}
--- a/msc/msc.h Wed Dec 05 12:41:25 2012 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-#ifndef MSC_H
-#define MSC_H
-#include "UsbHostMgr.h"
-#include "UsbEndpoint.h"
-#include "UsbBaseClass.h"
-#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)
-typedef struct stcbw {
- uint32_t dCBWSignature;
- uint32_t dCBWTag;
- uint32_t dCBWDataTraansferLength;
- uint8_t bmCBWFlags;
- uint8_t bCBWLUN;
- uint8_t bCBWCBLength;
- uint8_t CBWCB[16];
-} CBW;
-
-typedef struct stcsw {
- uint32_t dCSWSignature;
- uint32_t dCSWTag;
- uint32_t dCSWDataResidue;
- uint8_t bCSWStatus;
-} CSW;
-#pragma pack(pop)
-
-class msc : public FATFileSystem, public UsbBaseClass {
-public:
- msc(const char* name = NULL, int drive = 0);
- virtual int disk_initialize();
- virtual int disk_write(const uint8_t *buffer, uint64_t block_number);
- virtual int disk_read(uint8_t *buffer, uint64_t block_number);
- virtual int disk_status();
- virtual int disk_sync();
- virtual uint64_t disk_sectors();
-
- int setup(int timeout = 9000);
- void _test();
-private:
- int ParseConfiguration();
- int BulkOnlyMassStorageReset();
- int GetMaxLUN();
- 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, uint8_t* user_buffer);
- int CommandTransport(const uint8_t* cdb, int size);
- int StatusTransport();
- int _bulkRecv(uint8_t* buf, int size);
- int _bulkSend(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;
- UsbDevice* m_pDev;
- UsbEndpoint* m_pEpBulkIn;
- UsbEndpoint* m_pEpBulkOut;
-};
-
-#endif // MSC_H
--- a/uvchost.lib Wed Dec 05 12:41:25 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/va009039/code/uvchost/#3eb41d749f9a
