BaseUsbHost example program

Dependencies:   BaseUsbHost FATFileSystem mbed mbed-rtos

Revision:
5:495f7536897b
Parent:
3:6ae9a03a6145
--- a/main.cpp	Sun Jan 06 11:49:30 2013 +0000
+++ b/main.cpp	Fri Jan 25 14:55:08 2013 +0000
@@ -1,4 +1,4 @@
-// BaseUsbHost_example/main.cpp 2013/1/6
+// BaseUsbHost_example/main.cpp 2013/1/25
 #include "mbed.h"
 #include "rtos.h"
 #include "BaseUsbHost.h"
@@ -10,47 +10,47 @@
 #include "MyThread.h"
 #include <string>
 
-#define IMAGE_BUF_SIZE (1024*6)
-#define INTERVAL_S 20
+#define IMAGE_BUF_SIZE (1024*7)
+#define INTERVAL_S 30
 
 Serial pc(USBTX, USBRX);
 DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4);
 
+struct ImageBuffer {
+    int pos;
+    uint8_t buf[IMAGE_BUF_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;
+        }
+    }
+};
+
+Mail<ImageBuffer, 1> mail_box;
+
 class captureJPEG : public MyThread, public decodeMJPEG {
 public:
     captureJPEG(BaseUvc* cam) : m_cam(cam) {
+        m_buf = NULL;
         m_cam->setOnResult(this, &captureJPEG::callback_motion_jpeg);
-        interval_t.start();
-        buf_size = IMAGE_BUF_SIZE;
-        buf = new uint8_t[buf_size];
-        pos = 0;
     }
-    Timer interval_t;
 private:    
     virtual void outputJPEG(uint8_t c, int status) {
-        if (status == JPEG_START) {
-            pos = 0;
-            led2 = !led2;
-        }
-        if (pos < buf_size) {
-            buf[pos++] = c;
+        if (m_buf == NULL && status == JPEG_START) {
+            m_buf = mail_box.alloc();
+            if (m_buf) {
+                m_buf->clear();
+            }
         }
-        if (status == JPEG_END) {
-            led3 = !led3;
-            if (interval_t.read_ms() > INTERVAL_S*1000) {
-                interval_t.reset();                               
-                time_t timestamp = time(NULL);
-                struct tm* tminfo = localtime(&timestamp);
-                char tmbuf[64];
-                strftime(tmbuf, sizeof(tmbuf), "/usb/img%M%S.jpg", tminfo);
-                string path = tmbuf;
-                printf("%s %d bytes\n", path.c_str(), pos);
-                FILE* fp = fopen(path.c_str(), "wb");
-                if (fp) {
-                    fwrite(buf, pos, 1, fp);
-                    fclose(fp);
-                }
-                led4 = !led4;
+        if (m_buf) {
+            m_buf->put(c);
+            if (status == JPEG_END) {
+                mail_box.put(m_buf);
+                m_buf = NULL;
+                led3 = !led3;
             }
         }
     }
@@ -70,9 +70,7 @@
             }
         }
     }
-    uint8_t* buf;
-    int buf_size;
-    int pos;
+    ImageBuffer* m_buf;
     BaseUvc* m_cam;
 };
 
@@ -93,15 +91,25 @@
         error("USB Hub is not connected.\n");
     }
     UsbHub* hub = new UsbHub(ctlEp);
-    for(vector<ControlEp*>::iterator it = hub->PortEp.begin(); it != hub->PortEp.end(); ++it) {
-        if (drive == NULL && UsbFlashDrive::check(*it)) {
-            drive = new UsbFlashDrive("usb", *it);
-        } else if (cam == NULL && LogitechC270::check(*it)) {
-            cam = new LogitechC270(C270_MJPEG, C270_160x120, _5FPS, *it); 
-        } else if (cam == NULL && LifeCamVX700::check(*it)) {
-            cam = new LifeCamVX700(VX700_160x120, _5FPS, *it); 
-        } else if (cam == NULL && UvcCam::check(*it)) {
-            cam = new UvcCam(UVC_MJPEG, UVC_160x120, _5FPS, *it); 
+    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 (cam == NULL) {
+        ctlEp = hub->search<UvcCam>();
+        if (ctlEp) {
+            cam = new UvcCam(UVC_MJPEG, UVC_160x120, _5FPS, ctlEp); 
         }
     }
     if (cam == NULL) {
@@ -112,11 +120,42 @@
     }
     
     captureJPEG* capture = new captureJPEG(cam);
-    capture->set_stack(DEFAULT_STACK_SIZE+128*4);
+    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());
-        Thread::wait(5*1000);
+        osEvent evt = mail_box.get();
+        if (evt.status == osEventMail) {
+            ImageBuffer *buf = reinterpret_cast<ImageBuffer*>(evt.value.p);
+            time_t timestamp = time(NULL);
+            struct tm* tminfo = localtime(&timestamp);
+            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);
+            }
+            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);
     }
 }