Simple USBHost WebCam for EA LPC4088 QSB/LPC1768 test program

Dependencies:   LPC4088-USBHost mbed

EA LPC4088 QSB/LPC1768をUSBホストにしてWebカメラからJPEG画像を読み取るテストプログラムです。

The usage is the same as KL46Z-USBHostC270_example.
使い方はKL46Z-USBHostC270_exampleと同じです。
動作確認: Logitech C270,Logitech Q200R(Qcam Orbit AF)
/media/uploads/va009039/lpc4088-c270-480x360.jpg

Committer:
va009039
Date:
Fri Apr 25 05:55:06 2014 +0000
Revision:
1:1bb68ef9aa77
Parent:
0:c972ee42b455
update LPC4088-USBHost library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 0:c972ee42b455 1 // USBHostCam.cpp
va009039 0:c972ee42b455 2 #include "USBHostCam.h"
va009039 0:c972ee42b455 3 #include "dbg.h"
va009039 0:c972ee42b455 4
va009039 0:c972ee42b455 5 //#define CAM_DEBUG 1
va009039 0:c972ee42b455 6 #ifdef CAM_DEBUG
va009039 0:c972ee42b455 7 #define CAM_DBG(x, ...) std::printf("[%s:%d]"x"\r\n", __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
va009039 0:c972ee42b455 8 #else
va009039 0:c972ee42b455 9 #define CAM_DBG(...) while(0);
va009039 0:c972ee42b455 10 #endif
va009039 0:c972ee42b455 11
va009039 0:c972ee42b455 12 // ------------------ HcControl Register ---------------------
va009039 0:c972ee42b455 13 #define OR_CONTROL_IE 0x00000008
va009039 0:c972ee42b455 14
va009039 0:c972ee42b455 15 CamInfo* getCamInfoList(); // CamInfo.cpp
va009039 0:c972ee42b455 16
va009039 0:c972ee42b455 17 USBHostCam::USBHostCam(uint8_t size, uint8_t option, CamInfo* user_caminfo)
va009039 0:c972ee42b455 18 {
va009039 0:c972ee42b455 19 CAM_DBG("size: %d, option: %d", size, option);
va009039 0:c972ee42b455 20 _caminfo_size = size;
va009039 0:c972ee42b455 21 _caminfo_option = option;
va009039 0:c972ee42b455 22 if (user_caminfo) {
va009039 0:c972ee42b455 23 CamInfoList = user_caminfo;
va009039 0:c972ee42b455 24 } else {
va009039 0:c972ee42b455 25 CamInfoList = getCamInfoList();
va009039 0:c972ee42b455 26 }
va009039 0:c972ee42b455 27 clearOnResult();
va009039 0:c972ee42b455 28 host = USBHost::getHostInst();
va009039 0:c972ee42b455 29 init();
va009039 0:c972ee42b455 30 }
va009039 0:c972ee42b455 31
va009039 0:c972ee42b455 32 void USBHostCam::init()
va009039 0:c972ee42b455 33 {
va009039 0:c972ee42b455 34 CAM_DBG("");
va009039 0:c972ee42b455 35 dev_connected = false;
va009039 0:c972ee42b455 36 dev = NULL;
va009039 0:c972ee42b455 37 cam_intf = -1;
va009039 0:c972ee42b455 38 device_found = false;
va009039 0:c972ee42b455 39 caminfo_found = false;
va009039 0:c972ee42b455 40 }
va009039 0:c972ee42b455 41
va009039 0:c972ee42b455 42 bool USBHostCam::connected()
va009039 0:c972ee42b455 43 {
va009039 0:c972ee42b455 44 return dev_connected;
va009039 0:c972ee42b455 45 }
va009039 0:c972ee42b455 46
va009039 0:c972ee42b455 47 bool USBHostCam::connect()
va009039 0:c972ee42b455 48 {
va009039 0:c972ee42b455 49 if (dev_connected) {
va009039 0:c972ee42b455 50 return true;
va009039 0:c972ee42b455 51 }
va009039 0:c972ee42b455 52
va009039 0:c972ee42b455 53 for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
va009039 0:c972ee42b455 54 if ((dev = host->getDevice(i)) != NULL) {
va009039 0:c972ee42b455 55
va009039 0:c972ee42b455 56 CAM_DBG("Trying to connect Cam device\r\n");
va009039 0:c972ee42b455 57
va009039 0:c972ee42b455 58 if(host->enumerate(dev, this)) {
va009039 0:c972ee42b455 59 break;
va009039 0:c972ee42b455 60 }
va009039 0:c972ee42b455 61 if (device_found) {
va009039 0:c972ee42b455 62 USB_INFO("New Cam: %s device: VID:%04x PID:%04x [dev: %p - intf: %d]", caminfo->name, dev->getVid(), dev->getPid(), dev, cam_intf);
va009039 0:c972ee42b455 63 dev->setName(caminfo->name, cam_intf);
va009039 0:c972ee42b455 64 //host->registerDriver(dev, cam_intf, this, &USBHostCam::onDisconnect);
va009039 0:c972ee42b455 65 m_isoEp = new IsochronousEp(dev);
va009039 0:c972ee42b455 66 m_isoEp->init(ISOCHRONOUS_ENDPOINT, IN, caminfo->mps, caminfo->en);
va009039 0:c972ee42b455 67 m_isoEp->init2(caminfo->frameCount, caminfo->queueLimit);
va009039 0:c972ee42b455 68 uint8_t buf[26];
va009039 0:c972ee42b455 69 memset(buf, 0, sizeof(buf));
va009039 0:c972ee42b455 70 buf[2] = caminfo->formatIndex;
va009039 0:c972ee42b455 71 buf[3] = caminfo->frameIndex;
va009039 0:c972ee42b455 72 *reinterpret_cast<uint32_t*>(buf+4) = caminfo->interval;
va009039 0:c972ee42b455 73 USB_TYPE res = Control(SET_CUR, VS_COMMIT_CONTROL, 1, buf, sizeof(buf));
va009039 0:c972ee42b455 74 if (res != USB_TYPE_OK) {
va009039 0:c972ee42b455 75 CAM_DBG("SET_CUR VS_COMMIT_CONTROL FAILED");
va009039 0:c972ee42b455 76 }
va009039 0:c972ee42b455 77 res = setInterfaceAlternate(1, caminfo->if_alt);
va009039 0:c972ee42b455 78 if (res != USB_TYPE_OK) {
va009039 0:c972ee42b455 79 CAM_DBG("SET_INTERFACE FAILED");
va009039 0:c972ee42b455 80 }
va009039 0:c972ee42b455 81 for(int i = 0; i < 16; i++) {
va009039 0:c972ee42b455 82 report_cc_count[i] = 0;
va009039 0:c972ee42b455 83 report_ps_cc_count[i] = 0;
va009039 0:c972ee42b455 84 }
va009039 0:c972ee42b455 85 LPC_USB->HcControl |= OR_CONTROL_PLE; // PeriodicListEnable
va009039 0:c972ee42b455 86 LPC_USB->HcControl |= OR_CONTROL_IE; // IsochronousEnable
va009039 0:c972ee42b455 87
va009039 0:c972ee42b455 88 dev_connected = true;
va009039 0:c972ee42b455 89 return true;
va009039 0:c972ee42b455 90 }
va009039 0:c972ee42b455 91 }
va009039 0:c972ee42b455 92 }
va009039 0:c972ee42b455 93 init();
va009039 0:c972ee42b455 94 return false;
va009039 0:c972ee42b455 95 }
va009039 0:c972ee42b455 96
va009039 0:c972ee42b455 97 void USBHostCam::onDisconnect()
va009039 0:c972ee42b455 98 {
va009039 0:c972ee42b455 99 }
va009039 0:c972ee42b455 100
va009039 0:c972ee42b455 101 /*virtual*/ void USBHostCam::setVidPid(uint16_t vid, uint16_t pid)
va009039 0:c972ee42b455 102 {
va009039 0:c972ee42b455 103 CAM_DBG("vid:%04x,pid:%04x", vid, pid);
va009039 0:c972ee42b455 104 caminfo = CamInfoList;
va009039 0:c972ee42b455 105 while(caminfo->vid != 0) {
va009039 0:c972ee42b455 106 if (caminfo->vid == vid && caminfo->pid == pid &&
va009039 0:c972ee42b455 107 caminfo->size == _caminfo_size && caminfo->option == _caminfo_option) {
va009039 0:c972ee42b455 108 caminfo_found = true;
va009039 0:c972ee42b455 109 break;
va009039 0:c972ee42b455 110 }
va009039 0:c972ee42b455 111 caminfo++;
va009039 0:c972ee42b455 112 }
va009039 0:c972ee42b455 113 }
va009039 0:c972ee42b455 114
va009039 0:c972ee42b455 115 /*virtual*/ bool USBHostCam::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
va009039 0:c972ee42b455 116 {
va009039 0:c972ee42b455 117 CAM_DBG("intf_nb=%d,intf_class=%02X,intf_subclass=%d,intf_protocol=%d", intf_nb, intf_class, intf_subclass, intf_protocol);
va009039 0:c972ee42b455 118 if ((cam_intf == -1) && caminfo_found) {
va009039 0:c972ee42b455 119 cam_intf = intf_nb;
va009039 0:c972ee42b455 120 device_found = true;
va009039 0:c972ee42b455 121 return true;
va009039 0:c972ee42b455 122 }
va009039 0:c972ee42b455 123 return false;
va009039 0:c972ee42b455 124 }
va009039 0:c972ee42b455 125
va009039 0:c972ee42b455 126 /*virtual*/ bool USBHostCam::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
va009039 0:c972ee42b455 127 {
va009039 0:c972ee42b455 128 CAM_DBG("intf_nb:%d,type:%d,dir:%d",intf_nb, type, dir);
va009039 0:c972ee42b455 129 return false;
va009039 0:c972ee42b455 130 }
va009039 0:c972ee42b455 131
va009039 0:c972ee42b455 132 #define SEQ_READ_IDLE 0
va009039 0:c972ee42b455 133 #define SEQ_READ_EXEC 1
va009039 0:c972ee42b455 134 #define SEQ_READ_DONE 2
va009039 0:c972ee42b455 135
va009039 0:c972ee42b455 136 int USBHostCam::readJPEG(uint8_t* buf, int size, int timeout_ms) {
va009039 0:c972ee42b455 137 _buf = buf;
va009039 0:c972ee42b455 138 _pos = 0;
va009039 0:c972ee42b455 139 _size = size;
va009039 0:c972ee42b455 140 _seq = SEQ_READ_IDLE;
va009039 0:c972ee42b455 141 setOnResult(this, &USBHostCam::callback_motion_jpeg);
va009039 0:c972ee42b455 142 Timer timeout_t;
va009039 0:c972ee42b455 143 timeout_t.reset();
va009039 0:c972ee42b455 144 timeout_t.start();
va009039 0:c972ee42b455 145 while(timeout_t.read_ms() < timeout_ms && _seq != SEQ_READ_DONE && connected()) {
va009039 0:c972ee42b455 146 poll();
va009039 0:c972ee42b455 147 Thread::wait(1);
va009039 0:c972ee42b455 148 }
va009039 0:c972ee42b455 149 return _pos;
va009039 0:c972ee42b455 150 }
va009039 0:c972ee42b455 151
va009039 0:c972ee42b455 152 /* virtual */ void USBHostCam::outputJPEG(uint8_t c, int status) { // from decodeMJPEG
va009039 0:c972ee42b455 153 if (_seq == SEQ_READ_IDLE) {
va009039 0:c972ee42b455 154 if (status == JPEG_START) {
va009039 0:c972ee42b455 155 _pos = 0;
va009039 0:c972ee42b455 156 _seq = SEQ_READ_EXEC;
va009039 0:c972ee42b455 157 }
va009039 0:c972ee42b455 158 }
va009039 0:c972ee42b455 159 if (_seq == SEQ_READ_EXEC) {
va009039 0:c972ee42b455 160 if (_pos < _size) {
va009039 0:c972ee42b455 161 _buf[_pos++] = c;
va009039 0:c972ee42b455 162 }
va009039 0:c972ee42b455 163 if (status == JPEG_END) {
va009039 0:c972ee42b455 164 _seq = SEQ_READ_DONE;
va009039 0:c972ee42b455 165 }
va009039 0:c972ee42b455 166 }
va009039 0:c972ee42b455 167 }
va009039 0:c972ee42b455 168
va009039 0:c972ee42b455 169 void USBHostCam::callback_motion_jpeg(uint16_t frame, uint8_t* buf, int len) {
va009039 0:c972ee42b455 170 inputPacket(buf, len);
va009039 0:c972ee42b455 171 }
va009039 0:c972ee42b455 172