BaseUsbHost example program

Dependencies:   BaseUsbHost FATFileSystem mbed mbed-rtos

main.cpp

Committer:
va009039
Date:
2013-01-25
Revision:
5:495f7536897b
Parent:
3:6ae9a03a6145

File content as of revision 5:495f7536897b:

// BaseUsbHost_example/main.cpp 2013/1/25
#include "mbed.h"
#include "rtos.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

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);
    }
private:    
    virtual void outputJPEG(uint8_t c, int status) {
        if (m_buf == NULL && status == JPEG_START) {
            m_buf = mail_box.alloc();
            if (m_buf) {
                m_buf->clear();
            }
        }
        if (m_buf) {
            m_buf->put(c);
            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;
        }
    }

    virtual void run() {
        while(true) {
            if (m_cam) {
                m_cam->poll();
            }
        }
    }
    ImageBuffer* m_buf;
    BaseUvc* m_cam;
};

void no_memory () {
  error("Failed to allocate memory!\n");
}

int main() {
    pc.baud(921600);
    printf("%s\n", __FILE__);
    set_new_handler(no_memory);

    BaseUvc* cam = NULL;
    UsbFlashDrive* drive = NULL;
    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 (cam == NULL) {
        ctlEp = hub->search<UvcCam>();
        if (ctlEp) {
            cam = new UvcCam(UVC_MJPEG, UVC_160x120, _5FPS, ctlEp); 
        }
    }
    if (cam == NULL) {
        error("UVC Camera is not connected.\n");
    }
    if (drive == NULL) {
        error("USB flash drive is not connected.\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();
        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);
    }
}