![](/media/cache/profiles/f095cedd23b99f1696fc8caecbcf257e.jpg.50x50_q85.jpg)
see: http://mbed.org/users/okini3939/notebook/wifi_webcam/
Dependencies: GSwifiInterface_ap_webcam USBHost mbed
Diff: USBHostC270/USBHostC270.cpp
- Revision:
- 0:8558bdecb0fa
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBHostC270/USBHostC270.cpp Fri Jun 06 00:44:06 2014 +0000 @@ -0,0 +1,165 @@ +#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 + +// ------------------ HcControl Register --------------------- +#define OR_CONTROL_IE 0x00000008 + +USBHostC270::USBHostC270(int formatIndex, int frameIndex, uint32_t interval) +{ + C270_DBG("formatIndex: %d, frameIndex: %d, interval: %d", formatIndex, frameIndex, interval); + _formatIndex = formatIndex; + _frameIndex = frameIndex; + _interval = interval; + clearOnResult(); + host = USBHost::getHostInst(); + m_isoEp = new IsochronousEp; + init(); +} + +void USBHostC270::init() +{ + C270_DBG(""); + dev_connected = false; + dev = NULL; + c270_intf = -1; + c270_device_found = false; + c270_vid_pid_found = false; +} + +bool USBHostC270::connected() +{ + return dev_connected; +} + +bool USBHostC270::connect() +{ + if (dev_connected) { + return true; + } + + for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) { + if ((dev = host->getDevice(i)) != NULL) { + + C270_DBG("Trying to connect C270 device\r\n"); + + if(host->enumerate(dev, this)) { + break; + } + if (c270_device_found) { + USB_INFO("New C270 device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, c270_intf); + dev->setName("C270", c270_intf); + host->registerDriver(dev, c270_intf, this, &USBHostC270::onDisconnect); + int addr = dev->getAddress(); + m_isoEp->init(addr, C270_EN, 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"); + } + for(int i = 0; i < 16; i++) { + report_cc_count[i] = 0; + report_ps_cc_count[i] = 0; + } + LPC_USB->HcControl |= OR_CONTROL_PLE; // PeriodicListEnable + LPC_USB->HcControl |= OR_CONTROL_IE; // IsochronousEnable + + dev_connected = true; + return true; + } + } + } + init(); + return false; +} + +void USBHostC270::onDisconnect() +{ + C270_DBG("dev_connected: %d", dev_connected); + if (dev_connected) { + m_isoEp->disconnect(); + init(); + } +} + +/*virtual*/ void USBHostC270::setVidPid(uint16_t vid, uint16_t pid) +{ + C270_DBG("vid:%04x,pid:%04x", vid, pid); + if (vid == C270_VID && pid == C270_PID) { + c270_vid_pid_found = true; + } else { + c270_vid_pid_found = false; + } +} + +/*virtual*/ bool USBHostC270::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 +{ + C270_DBG("intf_nb=%d,intf_class=%02X,intf_subclass=%d,intf_protocol=%d", intf_nb, intf_class, intf_subclass, intf_protocol); + if ((c270_intf == -1) && c270_vid_pid_found) { + c270_intf = intf_nb; + c270_vid_pid_found = false; + c270_device_found = true; + return true; + } + return false; +} + +/*virtual*/ bool USBHostC270::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used +{ + C270_DBG("intf_nb:%d,type:%d,dir:%d",intf_nb, type, dir); + return false; +} + +#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(timeout_ms); + } + 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); +}