Simple USBHost WebCam test program

Dependencies:   F401RE-USBHost mbed

Fork of KL46Z-USBHostC270_example by Norimasa Okamoto

WebカメラからJPEG画像を読み取るテストプログラムです。
使い方はKL46Z-USBHostC270_exampleと同じです。
動作確認カメラ: Logitech C270, Logitech C210, Logitech Q200R(Qcam Orbit AF), LifeCam VX-500
/media/uploads/va009039/f401re-c270-1.jpg /media/uploads/va009039/k64f-c270.jpg

Committer:
va009039
Date:
Fri Jan 31 13:50:15 2014 +0000
Revision:
2:2a40888db9fc
Parent:
1:22304b8f8395
USB hub support.

Who changed what in which revision?

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