
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
Revision 2:2a40888db9fc, committed 2014-01-31
- Comitter:
- va009039
- Date:
- Fri Jan 31 13:50:15 2014 +0000
- Parent:
- 1:22304b8f8395
- Child:
- 3:b2f688e2ddd7
- Commit message:
- USB hub support.
Changed in this revision
--- a/KL46Z-USBHost.lib Tue Jan 28 06:54:16 2014 +0000 +++ b/KL46Z-USBHost.lib Fri Jan 31 13:50:15 2014 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/va009039/code/KL46Z-USBHost/#9a20482c9a7a +http://mbed.org/users/va009039/code/KL46Z-USBHost/#6463cd1964c0
--- a/KL46Z_USBHostC270/BaseUvc.cpp Tue Jan 28 06:54:16 2014 +0000 +++ b/KL46Z_USBHostC270/BaseUvc.cpp Fri Jan 31 13:50:15 2014 +0000 @@ -1,16 +1,15 @@ // BaseUvc.cpp #include "USBHostConf.h" #include "USBHost.h" -//#include "USBIsochronous.h" #include "BaseUvc.h" void BaseUvc::poll() { - uint8_t buf[ep_iso_in.getSize()]; - int result = host->IsochronousRead(&ep_iso_in, buf, sizeof(buf)); + uint8_t buf[ep_iso_in->getSize()]; + int result = host->IsochronousRead(ep_iso_in, buf, sizeof(buf)); if (result >= 0) { uint16_t frame = 0; - onResult(frame, buf, result); + onResult(frame, buf, ep_iso_in->getLengthTransferred()); } }
--- a/KL46Z_USBHostC270/BaseUvc.h Tue Jan 28 06:54:16 2014 +0000 +++ b/KL46Z_USBHostC270/BaseUvc.h Fri Jan 31 13:50:15 2014 +0000 @@ -46,6 +46,6 @@ void (*m_pCb)(uint16_t, uint8_t*, int); protected: USBHost * host; - USBDeviceConnected * dev; // dummy - USBEndpoint ep_iso_in; + USBDeviceConnected * dev; + USBEndpoint* ep_iso_in; };
--- a/KL46Z_USBHostC270/USBHostC270.cpp Tue Jan 28 06:54:16 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -#include "USBHostC270.h" -//#include "dbg.h" - -#define C270_DEBUG 1 -#ifdef C270_DEBUG -#define C270_DBG(x, ...) std::printf("[%s:%d]"x"\r\n", __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); -#else -#define C270_DBG(...) while(0); -#endif - -USBHostC270::USBHostC270(int formatIndex, int frameIndex, uint32_t interval) { - _formatIndex = formatIndex; - _frameIndex = frameIndex; - _interval = interval; - clearOnResult(); - host = USBHost::getHostInst(); - report = &host->report; - setup(); -} - -void USBHostC270::setup() { - ep_iso_in.setAddress(C270_EN); - ep_iso_in.setSize(C270_MPS); - uint8_t buf[26]; - memset(buf, 0, sizeof(buf)); - buf[2] = _formatIndex; - buf[3] = _frameIndex; - *reinterpret_cast<uint32_t*>(buf+4) = _interval; - USB_TYPE res = Control(SET_CUR, VS_COMMIT_CONTROL, 1, buf, sizeof(buf)); - if (res != USB_TYPE_OK) { - C270_DBG("SET_CUR VS_COMMIT_CONTROL FAILED"); - } - res = setInterfaceAlternate(1, C270_IF_ALT); // alt=1 packet size = 192 - if (res != USB_TYPE_OK) { - C270_DBG("SET_INTERFACE FAILED"); - } -} - -#define SEQ_READ_IDOL 0 -#define SEQ_READ_EXEC 1 -#define SEQ_READ_DONE 2 - -int USBHostC270::readJPEG(uint8_t* buf, int size, int timeout_ms) { - _buf = buf; - _pos = 0; - _size = size; - _seq = SEQ_READ_IDOL; - setOnResult(this, &USBHostC270::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 USBHostC270::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 USBHostC270::callback_motion_jpeg(uint16_t frame, uint8_t* buf, int len) { - inputPacket(buf, len); -}
--- a/KL46Z_USBHostC270/USBHostC270.h Tue Jan 28 06:54:16 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -// Simple USBHost Logtigech C270 for FRDM-KL46Z -#include "USBHost.h" -#include "BaseUvc.h" -#include "decodeMJPEG.h" - -// Logitech C270 -#define C270_VID 0x046d -#define C270_PID 0x0825 -#define C270_160x120 2 -#define C270_176x144 3 -#define C270_320x176 4 -#define C270_320x240 5 -#define C270_352x288 6 -#define C270_432x240 7 -#define C270_640x480 1 -#define C270_544x288 8 -#define C270_640x360 9 -#define C270_752x416 10 -#define C270_800x448 11 -#define C270_800x600 12 - -#define C270_MJPEG 2 -#define C270_YUV2 1 - -#define C270_EN 0x81 -#define C270_MPS 192 -#define C270_IF_ALT 1 - -class USBHostC270 : public BaseUvc, public decodeMJPEG { -public: - USBHostC270(int formatIndex = C270_MJPEG, int frameIndex = C270_160x120, uint32_t interval = _5FPS); - /** - * read jpeg image - * - * @param buf read buffer - * @param size buffer size - * @param timeout_ms timeout default 15sec - * @return jpeg size if read success else -1 - */ - int readJPEG(uint8_t* buf, int size, int timeout_ms = 15*1000); - - Report* report; - -private: - int _formatIndex; - int _frameIndex; - uint32_t _interval; - uint8_t _seq; - uint8_t* _buf; - int _pos; - int _size; - - void setup(); - virtual void outputJPEG(uint8_t c, int status); // from decodeMJPEG - void callback_motion_jpeg(uint16_t frame, uint8_t* buf, int len); -}; -
--- a/KL46Z_USBHostC270/USBHostCam.cpp Tue Jan 28 06:54:16 2014 +0000 +++ b/KL46Z_USBHostC270/USBHostCam.cpp Fri Jan 31 13:50:15 2014 +0000 @@ -1,13 +1,13 @@ // 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__); +#if 0 +#define CAM_DBG(x, ...) std::printf("[%s:%d]"x"\n", __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); #else #define CAM_DBG(...) while(0); #endif #define CAM_INFO(...) do{fprintf(stderr,__VA_ARGS__);}while(0); +#define USB_INFO(...) do{fprintf(stderr,__VA_ARGS__);}while(0); CamInfo* getCamInfoList(); // CamInfo.cpp @@ -23,14 +23,78 @@ } clearOnResult(); host = USBHost::getHostInst(); - setup(); + dev = host->getDevice(0); + ep_iso_in = new USBEndpoint; + init(); } +void USBHostCam::init() +{ + CAM_DBG(""); + dev_connected = false; + dev = NULL; + cam_intf = -1; + device_found = false; + caminfo_found = false; +} + +bool USBHostCam::connected() +{ + return dev_connected; +} + +bool USBHostCam::connect() +{ + if (dev_connected) { + return true; + } + + for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) { + if ((dev = host->getDevice(i)) != NULL) { + + CAM_DBG("Trying to connect Cam device\r\n"); + + if(host->enumerate(dev, this)) { + break; + } + if (device_found) { + USB_INFO("New Cam: %s device: VID:%04x PID:%04x [dev: %p - intf: %d]\n", caminfo->name, dev->getVid(), dev->getPid(), dev, cam_intf); + dev->setName(caminfo->name, cam_intf); + //host->registerDriver(dev, cam_intf, this, &USBHostCam::onDisconnect); + int addr = dev->getAddress(); + ep_iso_in->setDevice(dev); + ep_iso_in->setAddress(caminfo->en); + ep_iso_in->setSize(caminfo->mps); + //ep_iso_in->init(addr, caminfo->en, caminfo->mps, caminfo->frameCount, caminfo->queueLimit); + 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"); + } + dev_connected = true; + return true; + } + } + } + init(); + return false; +} + +#if 0 void USBHostCam::setup() { caminfo = CamInfoList; bool found = false; while(caminfo->vid != 0) { - if (caminfo->vid == host->dev.vid && caminfo->pid == host->dev.pid && + if (caminfo->vid == host->getDevice(0)->getVid() && + caminfo->pid == host->getDevice(0)->getPid() && caminfo->size == _caminfo_size && caminfo->option == _caminfo_option) { found = true; break; @@ -59,6 +123,39 @@ CAM_DBG("SET_INTERFACE FAILED"); } } +#endif + + +/*virtual*/ void USBHostCam::setVidPid(uint16_t vid, uint16_t pid) +{ + CAM_DBG("vid:%04x,pid:%04x", vid, pid); + caminfo = CamInfoList; + while(caminfo->vid != 0) { + if (caminfo->vid == vid && caminfo->pid == pid && + caminfo->size == _caminfo_size && caminfo->option == _caminfo_option) { + caminfo_found = true; + break; + } + caminfo++; + } +} + +/*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 +{ + CAM_DBG("intf_nb=%d,intf_class=%02X,intf_subclass=%d,intf_protocol=%d", intf_nb, intf_class, intf_subclass, intf_protocol); + if ((cam_intf == -1) && caminfo_found) { + cam_intf = intf_nb; + device_found = true; + return true; + } + return false; +} + +/*virtual*/ bool USBHostCam::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used +{ + CAM_DBG("intf_nb:%d,type:%d,dir:%d",intf_nb, type, dir); + return false; +} #define SEQ_READ_IDOL 0 #define SEQ_READ_EXEC 1
--- a/KL46Z_USBHostC270/USBHostCam.h Tue Jan 28 06:54:16 2014 +0000 +++ b/KL46Z_USBHostC270/USBHostCam.h Fri Jan 31 13:50:15 2014 +0000 @@ -38,7 +38,7 @@ /** * A class to communicate a Cam */ -class USBHostCam : public BaseUvc, public decodeMJPEG { +class USBHostCam : public IUSBEnumerator, public BaseUvc, public decodeMJPEG { public: /** * Constructor @@ -47,6 +47,20 @@ USBHostCam(uint8_t size = _160x120, uint8_t option = 0, CamInfo* user_caminfo = NULL); /** + * Check if a Cam device is connected + * + * @return true if a Cam device is connected + */ + bool connected(); + + /** + * Try to connect to a Cam device + * + * @return true if connection was successful + */ + bool connect(); + + /** * read jpeg image * * @param buf read buffer @@ -56,7 +70,19 @@ */ int readJPEG(uint8_t* buf, int size, int timeout_ms = 15*1000); +protected: + //From IUSBEnumerator + virtual void setVidPid(uint16_t vid, uint16_t pid); + virtual bool 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 + virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used + private: + bool dev_connected; + + int cam_intf; + bool device_found; + bool caminfo_found; + uint8_t _seq; uint8_t* _buf; int _pos; @@ -66,7 +92,7 @@ uint8_t _caminfo_size; uint8_t _caminfo_option; - void setup(); virtual void outputJPEG(uint8_t c, int status); // from decodeMJPEG void callback_motion_jpeg(uint16_t frame, uint8_t* buf, int len); + void init(); };
--- a/main.cpp Tue Jan 28 06:54:16 2014 +0000 +++ b/main.cpp Fri Jan 31 13:50:15 2014 +0000 @@ -17,6 +17,9 @@ // Logitech C270 USBHostCam* cam = new USBHostCam(_320x240); + if (!cam->connect()) { + error("WebCam not found.\n"); + } int pos = 0; int size = 0;