Simple USBHost WebCam test program
Dependencies: F401RE-USBHost mbed
Fork of KL46Z-USBHostC270_example by
WebカメラからJPEG画像を読み取るテストプログラムです。
使い方はKL46Z-USBHostC270_exampleと同じです。
動作確認カメラ: Logitech C270, Logitech C210, Logitech Q200R(Qcam Orbit AF), LifeCam VX-500
Diff: KL46Z_USBHostC270/USBHostCam.cpp
- Revision:
- 1:22304b8f8395
- Child:
- 2:2a40888db9fc
diff -r a72d9b047d8d -r 22304b8f8395 KL46Z_USBHostC270/USBHostCam.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/KL46Z_USBHostC270/USBHostCam.cpp Tue Jan 28 06:54:16 2014 +0000 @@ -0,0 +1,101 @@ +// USBHostCam.cpp +#include "USBHostCam.h" + +//#define CAM_DEBUG 1 +#ifdef CAM_DEBUG +#define CAM_DBG(x, ...) std::printf("[%s:%d]"x"\r\n", __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); +#else +#define CAM_DBG(...) while(0); +#endif +#define CAM_INFO(...) do{fprintf(stderr,__VA_ARGS__);}while(0); + +CamInfo* getCamInfoList(); // CamInfo.cpp + +USBHostCam::USBHostCam(uint8_t size, uint8_t option, CamInfo* user_caminfo) +{ + CAM_DBG("size: %d, option: %d", size, option); + _caminfo_size = size; + _caminfo_option = option; + if (user_caminfo) { + CamInfoList = user_caminfo; + } else { + CamInfoList = getCamInfoList(); + } + clearOnResult(); + host = USBHost::getHostInst(); + setup(); +} + +void USBHostCam::setup() { + caminfo = CamInfoList; + bool found = false; + while(caminfo->vid != 0) { + if (caminfo->vid == host->dev.vid && caminfo->pid == host->dev.pid && + caminfo->size == _caminfo_size && caminfo->option == _caminfo_option) { + found = true; + break; + } + caminfo++; + } + if (!found) { + CAM_INFO("caminfo not found.\n"); + exit(1); + } + CAM_INFO("Found: %s\n", caminfo->name); + + ep_iso_in.setAddress(caminfo->en); + ep_iso_in.setSize(caminfo->mps); + uint8_t buf[26]; + memset(buf, 0, sizeof(buf)); + buf[2] = caminfo->formatIndex; + buf[3] = caminfo->frameIndex; + *reinterpret_cast<uint32_t*>(buf+4) = caminfo->interval; + USB_TYPE res = Control(SET_CUR, VS_COMMIT_CONTROL, 1, buf, sizeof(buf)); + if (res != USB_TYPE_OK) { + CAM_DBG("SET_CUR VS_COMMIT_CONTROL FAILED"); + } + res = setInterfaceAlternate(1, caminfo->if_alt); + if (res != USB_TYPE_OK) { + CAM_DBG("SET_INTERFACE FAILED"); + } +} + +#define SEQ_READ_IDOL 0 +#define SEQ_READ_EXEC 1 +#define SEQ_READ_DONE 2 + +int USBHostCam::readJPEG(uint8_t* buf, int size, int timeout_ms) { + _buf = buf; + _pos = 0; + _size = size; + _seq = SEQ_READ_IDOL; + setOnResult(this, &USBHostCam::callback_motion_jpeg); + Timer timeout_t; + timeout_t.reset(); + timeout_t.start(); + while(timeout_t.read_ms() < timeout_ms && _seq != SEQ_READ_DONE) { + poll(); + } + return _pos; +} + +/* virtual */ void USBHostCam::outputJPEG(uint8_t c, int status) { // from decodeMJPEG + if (_seq == SEQ_READ_IDOL) { + if (status == JPEG_START) { + _pos = 0; + _seq = SEQ_READ_EXEC; + } + } + if (_seq == SEQ_READ_EXEC) { + if (_pos < _size) { + _buf[_pos++] = c; + } + if (status == JPEG_END) { + _seq = SEQ_READ_DONE; + } + } +} + +void USBHostCam::callback_motion_jpeg(uint16_t frame, uint8_t* buf, int len) { + inputPacket(buf, len); +}