BaseUsbHost example program
Dependencies: BaseUsbHost FATFileSystem mbed mbed-rtos
main.cpp@5:495f7536897b, 2013-01-25 (annotated)
- Committer:
- va009039
- Date:
- Fri Jan 25 14:55:08 2013 +0000
- Revision:
- 5:495f7536897b
- Parent:
- 3:6ae9a03a6145
update library
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 | 5:495f7536897b | 1 | // BaseUsbHost_example/main.cpp 2013/1/25 |
va009039 | 3:6ae9a03a6145 | 2 | #include "mbed.h" |
va009039 | 3:6ae9a03a6145 | 3 | #include "rtos.h" |
va009039 | 3:6ae9a03a6145 | 4 | #include "BaseUsbHost.h" |
va009039 | 3:6ae9a03a6145 | 5 | #include "LogitechC270.h" |
va009039 | 3:6ae9a03a6145 | 6 | #include "LifeCamVX700.h" |
va009039 | 3:6ae9a03a6145 | 7 | #include "UvcCam.h" |
va009039 | 3:6ae9a03a6145 | 8 | #include "UsbFlashDrive.h" |
va009039 | 3:6ae9a03a6145 | 9 | #include "decodeMJPEG.h" |
va009039 | 3:6ae9a03a6145 | 10 | #include "MyThread.h" |
va009039 | 3:6ae9a03a6145 | 11 | #include <string> |
va009039 | 3:6ae9a03a6145 | 12 | |
va009039 | 5:495f7536897b | 13 | #define IMAGE_BUF_SIZE (1024*7) |
va009039 | 5:495f7536897b | 14 | #define INTERVAL_S 30 |
va009039 | 3:6ae9a03a6145 | 15 | |
va009039 | 3:6ae9a03a6145 | 16 | Serial pc(USBTX, USBRX); |
va009039 | 3:6ae9a03a6145 | 17 | DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4); |
va009039 | 3:6ae9a03a6145 | 18 | |
va009039 | 5:495f7536897b | 19 | struct ImageBuffer { |
va009039 | 5:495f7536897b | 20 | int pos; |
va009039 | 5:495f7536897b | 21 | uint8_t buf[IMAGE_BUF_SIZE]; |
va009039 | 5:495f7536897b | 22 | void clear() { pos = 0; } |
va009039 | 5:495f7536897b | 23 | int size() { return pos; } |
va009039 | 5:495f7536897b | 24 | uint8_t get(int pos) { return buf[pos]; } |
va009039 | 5:495f7536897b | 25 | void put(uint8_t c) { |
va009039 | 5:495f7536897b | 26 | if (pos < sizeof(buf)) { |
va009039 | 5:495f7536897b | 27 | buf[pos++] = c; |
va009039 | 5:495f7536897b | 28 | } |
va009039 | 5:495f7536897b | 29 | } |
va009039 | 5:495f7536897b | 30 | }; |
va009039 | 5:495f7536897b | 31 | |
va009039 | 5:495f7536897b | 32 | Mail<ImageBuffer, 1> mail_box; |
va009039 | 5:495f7536897b | 33 | |
va009039 | 3:6ae9a03a6145 | 34 | class captureJPEG : public MyThread, public decodeMJPEG { |
va009039 | 3:6ae9a03a6145 | 35 | public: |
va009039 | 3:6ae9a03a6145 | 36 | captureJPEG(BaseUvc* cam) : m_cam(cam) { |
va009039 | 5:495f7536897b | 37 | m_buf = NULL; |
va009039 | 3:6ae9a03a6145 | 38 | m_cam->setOnResult(this, &captureJPEG::callback_motion_jpeg); |
va009039 | 3:6ae9a03a6145 | 39 | } |
va009039 | 3:6ae9a03a6145 | 40 | private: |
va009039 | 3:6ae9a03a6145 | 41 | virtual void outputJPEG(uint8_t c, int status) { |
va009039 | 5:495f7536897b | 42 | if (m_buf == NULL && status == JPEG_START) { |
va009039 | 5:495f7536897b | 43 | m_buf = mail_box.alloc(); |
va009039 | 5:495f7536897b | 44 | if (m_buf) { |
va009039 | 5:495f7536897b | 45 | m_buf->clear(); |
va009039 | 5:495f7536897b | 46 | } |
va009039 | 3:6ae9a03a6145 | 47 | } |
va009039 | 5:495f7536897b | 48 | if (m_buf) { |
va009039 | 5:495f7536897b | 49 | m_buf->put(c); |
va009039 | 5:495f7536897b | 50 | if (status == JPEG_END) { |
va009039 | 5:495f7536897b | 51 | mail_box.put(m_buf); |
va009039 | 5:495f7536897b | 52 | m_buf = NULL; |
va009039 | 5:495f7536897b | 53 | led3 = !led3; |
va009039 | 3:6ae9a03a6145 | 54 | } |
va009039 | 3:6ae9a03a6145 | 55 | } |
va009039 | 3:6ae9a03a6145 | 56 | } |
va009039 | 3:6ae9a03a6145 | 57 | |
va009039 | 3:6ae9a03a6145 | 58 | void callback_motion_jpeg(uint16_t frame, uint8_t* buf, int len) { |
va009039 | 3:6ae9a03a6145 | 59 | inputPacket(buf, len); |
va009039 | 3:6ae9a03a6145 | 60 | led1 = buf[1]&1; // FID |
va009039 | 3:6ae9a03a6145 | 61 | if (buf[1]&2) { // EOF |
va009039 | 3:6ae9a03a6145 | 62 | led2 = !led2; |
va009039 | 3:6ae9a03a6145 | 63 | } |
va009039 | 3:6ae9a03a6145 | 64 | } |
va009039 | 3:6ae9a03a6145 | 65 | |
va009039 | 3:6ae9a03a6145 | 66 | virtual void run() { |
va009039 | 3:6ae9a03a6145 | 67 | while(true) { |
va009039 | 3:6ae9a03a6145 | 68 | if (m_cam) { |
va009039 | 3:6ae9a03a6145 | 69 | m_cam->poll(); |
va009039 | 3:6ae9a03a6145 | 70 | } |
va009039 | 3:6ae9a03a6145 | 71 | } |
va009039 | 3:6ae9a03a6145 | 72 | } |
va009039 | 5:495f7536897b | 73 | ImageBuffer* m_buf; |
va009039 | 3:6ae9a03a6145 | 74 | BaseUvc* m_cam; |
va009039 | 3:6ae9a03a6145 | 75 | }; |
va009039 | 3:6ae9a03a6145 | 76 | |
va009039 | 3:6ae9a03a6145 | 77 | void no_memory () { |
va009039 | 3:6ae9a03a6145 | 78 | error("Failed to allocate memory!\n"); |
va009039 | 3:6ae9a03a6145 | 79 | } |
va009039 | 3:6ae9a03a6145 | 80 | |
va009039 | 3:6ae9a03a6145 | 81 | int main() { |
va009039 | 3:6ae9a03a6145 | 82 | pc.baud(921600); |
va009039 | 3:6ae9a03a6145 | 83 | printf("%s\n", __FILE__); |
va009039 | 3:6ae9a03a6145 | 84 | set_new_handler(no_memory); |
va009039 | 3:6ae9a03a6145 | 85 | |
va009039 | 3:6ae9a03a6145 | 86 | BaseUvc* cam = NULL; |
va009039 | 3:6ae9a03a6145 | 87 | UsbFlashDrive* drive = NULL; |
va009039 | 3:6ae9a03a6145 | 88 | BaseUsbHost* usbHost = new BaseUsbHost(); |
va009039 | 3:6ae9a03a6145 | 89 | ControlEp* ctlEp = new ControlEp; // root hub |
va009039 | 3:6ae9a03a6145 | 90 | if (!UsbHub::check(ctlEp)) { |
va009039 | 3:6ae9a03a6145 | 91 | error("USB Hub is not connected.\n"); |
va009039 | 3:6ae9a03a6145 | 92 | } |
va009039 | 3:6ae9a03a6145 | 93 | UsbHub* hub = new UsbHub(ctlEp); |
va009039 | 5:495f7536897b | 94 | ctlEp = hub->search<UsbFlashDrive>(); |
va009039 | 5:495f7536897b | 95 | if (ctlEp) { |
va009039 | 5:495f7536897b | 96 | drive = new UsbFlashDrive("usb", ctlEp); |
va009039 | 5:495f7536897b | 97 | } |
va009039 | 5:495f7536897b | 98 | ctlEp = hub->search<LogitechC270>(); |
va009039 | 5:495f7536897b | 99 | if (ctlEp) { |
va009039 | 5:495f7536897b | 100 | //cam = new LogitechC270(C270_MJPEG, C270_160x120, _5FPS, ctlEp); |
va009039 | 5:495f7536897b | 101 | cam = new LogitechC270(C270_MJPEG, C270_320x176, _5FPS, ctlEp); |
va009039 | 5:495f7536897b | 102 | } |
va009039 | 5:495f7536897b | 103 | if (cam == NULL) { |
va009039 | 5:495f7536897b | 104 | ctlEp = hub->search<LifeCamVX700>(); |
va009039 | 5:495f7536897b | 105 | if (ctlEp) { |
va009039 | 5:495f7536897b | 106 | cam = new LifeCamVX700(VX700_160x120, _5FPS, ctlEp); |
va009039 | 5:495f7536897b | 107 | } |
va009039 | 5:495f7536897b | 108 | } |
va009039 | 5:495f7536897b | 109 | if (cam == NULL) { |
va009039 | 5:495f7536897b | 110 | ctlEp = hub->search<UvcCam>(); |
va009039 | 5:495f7536897b | 111 | if (ctlEp) { |
va009039 | 5:495f7536897b | 112 | cam = new UvcCam(UVC_MJPEG, UVC_160x120, _5FPS, ctlEp); |
va009039 | 3:6ae9a03a6145 | 113 | } |
va009039 | 3:6ae9a03a6145 | 114 | } |
va009039 | 3:6ae9a03a6145 | 115 | if (cam == NULL) { |
va009039 | 3:6ae9a03a6145 | 116 | error("UVC Camera is not connected.\n"); |
va009039 | 3:6ae9a03a6145 | 117 | } |
va009039 | 3:6ae9a03a6145 | 118 | if (drive == NULL) { |
va009039 | 3:6ae9a03a6145 | 119 | error("USB flash drive is not connected.\n"); |
va009039 | 3:6ae9a03a6145 | 120 | } |
va009039 | 3:6ae9a03a6145 | 121 | |
va009039 | 3:6ae9a03a6145 | 122 | captureJPEG* capture = new captureJPEG(cam); |
va009039 | 5:495f7536897b | 123 | capture->set_stack(DEFAULT_STACK_SIZE-128*8); |
va009039 | 3:6ae9a03a6145 | 124 | capture->start(); |
va009039 | 3:6ae9a03a6145 | 125 | |
va009039 | 3:6ae9a03a6145 | 126 | for(int n = 0; ; n++) { |
va009039 | 3:6ae9a03a6145 | 127 | printf("%d captureJPEG stack used: %d/%d bytes\n", n, capture->stack_used(), capture->stack_size()); |
va009039 | 5:495f7536897b | 128 | osEvent evt = mail_box.get(); |
va009039 | 5:495f7536897b | 129 | if (evt.status == osEventMail) { |
va009039 | 5:495f7536897b | 130 | ImageBuffer *buf = reinterpret_cast<ImageBuffer*>(evt.value.p); |
va009039 | 5:495f7536897b | 131 | time_t timestamp = time(NULL); |
va009039 | 5:495f7536897b | 132 | struct tm* tminfo = localtime(×tamp); |
va009039 | 5:495f7536897b | 133 | char tmbuf[32]; |
va009039 | 5:495f7536897b | 134 | strftime(tmbuf, sizeof(tmbuf), "/usb/img%M%S.jpg", tminfo); |
va009039 | 5:495f7536897b | 135 | string path = tmbuf; |
va009039 | 5:495f7536897b | 136 | printf("%s %d bytes\n", path.c_str(), buf->size()); |
va009039 | 5:495f7536897b | 137 | FILE* fp = fopen(path.c_str(), "wb"); |
va009039 | 5:495f7536897b | 138 | if (fp) { |
va009039 | 5:495f7536897b | 139 | for(int i = 0; i < buf->size(); i++) { |
va009039 | 5:495f7536897b | 140 | fputc(buf->get(i), fp); |
va009039 | 5:495f7536897b | 141 | //Thread::yield(); |
va009039 | 5:495f7536897b | 142 | } |
va009039 | 5:495f7536897b | 143 | fclose(fp); |
va009039 | 5:495f7536897b | 144 | } |
va009039 | 5:495f7536897b | 145 | mail_box.free(buf); |
va009039 | 5:495f7536897b | 146 | led4 = !led4; |
va009039 | 5:495f7536897b | 147 | } |
va009039 | 5:495f7536897b | 148 | |
va009039 | 5:495f7536897b | 149 | printf("CC:"); |
va009039 | 5:495f7536897b | 150 | for(int i = 0; i < 16; i++) { |
va009039 | 5:495f7536897b | 151 | printf(" %u", cam->report_cc_count[i]); |
va009039 | 5:495f7536897b | 152 | } |
va009039 | 5:495f7536897b | 153 | printf("\nPS:"); |
va009039 | 5:495f7536897b | 154 | for(int i = 0; i < 16; i++) { |
va009039 | 5:495f7536897b | 155 | printf(" %u", cam->report_ps_cc_count[i]); |
va009039 | 5:495f7536897b | 156 | } |
va009039 | 5:495f7536897b | 157 | printf("\n"); |
va009039 | 5:495f7536897b | 158 | |
va009039 | 5:495f7536897b | 159 | Thread::wait(INTERVAL_S*1000); |
va009039 | 3:6ae9a03a6145 | 160 | } |
va009039 | 3:6ae9a03a6145 | 161 | } |