Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of F401RE-USBHost by
USBHostC270/USBHostCam.cpp@18:61554f238584, 2014-07-01 (annotated)
- Committer:
- va009039
- Date:
- Tue Jul 01 18:33:31 2014 +0900
- Revision:
- 18:61554f238584
- Parent:
- 13:8774c07f12a5
add lpc4088/lpc1768
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 |
13:8774c07f12a5 | 1 | // USBHostCam.cpp |
va009039 |
13:8774c07f12a5 | 2 | #include "USBHostCam.h" |
va009039 |
13:8774c07f12a5 | 3 | |
va009039 |
13:8774c07f12a5 | 4 | #if 0 |
va009039 |
13:8774c07f12a5 | 5 | #define CAM_DBG(x, ...) std::printf("[%s:%d]"x"\n", __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); |
va009039 |
13:8774c07f12a5 | 6 | #else |
va009039 |
13:8774c07f12a5 | 7 | #define CAM_DBG(...) while(0); |
va009039 |
13:8774c07f12a5 | 8 | #endif |
va009039 |
13:8774c07f12a5 | 9 | #define CAM_INFO(...) do{fprintf(stderr,__VA_ARGS__);}while(0); |
va009039 |
13:8774c07f12a5 | 10 | |
va009039 |
13:8774c07f12a5 | 11 | CamInfo* getCamInfoList(); // CamInfo.cpp |
va009039 |
13:8774c07f12a5 | 12 | |
va009039 |
13:8774c07f12a5 | 13 | USBHostCam::USBHostCam(uint8_t size, uint8_t option, CamInfo* user_caminfo) |
va009039 |
13:8774c07f12a5 | 14 | { |
va009039 |
13:8774c07f12a5 | 15 | CAM_DBG("size: %d, option: %d", size, option); |
va009039 |
13:8774c07f12a5 | 16 | _caminfo_size = size; |
va009039 |
13:8774c07f12a5 | 17 | _caminfo_option = option; |
va009039 |
13:8774c07f12a5 | 18 | if (user_caminfo) { |
va009039 |
13:8774c07f12a5 | 19 | CamInfoList = user_caminfo; |
va009039 |
13:8774c07f12a5 | 20 | } else { |
va009039 |
13:8774c07f12a5 | 21 | CamInfoList = getCamInfoList(); |
va009039 |
13:8774c07f12a5 | 22 | } |
va009039 |
13:8774c07f12a5 | 23 | clearOnResult(); |
va009039 |
13:8774c07f12a5 | 24 | host = USBHost::getHostInst(); |
va009039 |
13:8774c07f12a5 | 25 | init(); |
va009039 |
13:8774c07f12a5 | 26 | } |
va009039 |
13:8774c07f12a5 | 27 | |
va009039 |
13:8774c07f12a5 | 28 | void USBHostCam::init() |
va009039 |
13:8774c07f12a5 | 29 | { |
va009039 |
13:8774c07f12a5 | 30 | CAM_DBG(""); |
va009039 |
13:8774c07f12a5 | 31 | dev_connected = false; |
va009039 |
13:8774c07f12a5 | 32 | dev = NULL; |
va009039 |
13:8774c07f12a5 | 33 | ep_iso_in = NULL; |
va009039 |
13:8774c07f12a5 | 34 | cam_intf = -1; |
va009039 |
13:8774c07f12a5 | 35 | device_found = false; |
va009039 |
13:8774c07f12a5 | 36 | caminfo_found = false; |
va009039 |
13:8774c07f12a5 | 37 | } |
va009039 |
13:8774c07f12a5 | 38 | |
va009039 |
13:8774c07f12a5 | 39 | bool USBHostCam::connected() |
va009039 |
13:8774c07f12a5 | 40 | { |
va009039 |
13:8774c07f12a5 | 41 | return dev_connected; |
va009039 |
13:8774c07f12a5 | 42 | } |
va009039 |
13:8774c07f12a5 | 43 | |
va009039 |
13:8774c07f12a5 | 44 | bool USBHostCam::connect() |
va009039 |
13:8774c07f12a5 | 45 | { |
va009039 |
13:8774c07f12a5 | 46 | if (dev_connected) { |
va009039 |
13:8774c07f12a5 | 47 | return true; |
va009039 |
13:8774c07f12a5 | 48 | } |
va009039 |
13:8774c07f12a5 | 49 | |
va009039 |
13:8774c07f12a5 | 50 | for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) { |
va009039 |
13:8774c07f12a5 | 51 | if ((dev = host->getDevice(i)) != NULL) { |
va009039 |
13:8774c07f12a5 | 52 | |
va009039 |
13:8774c07f12a5 | 53 | CAM_DBG("Trying to connect Cam device\r\n"); |
va009039 |
13:8774c07f12a5 | 54 | |
va009039 |
13:8774c07f12a5 | 55 | if(host->enumerate(dev, this)) { |
va009039 |
13:8774c07f12a5 | 56 | break; |
va009039 |
13:8774c07f12a5 | 57 | } |
va009039 |
13:8774c07f12a5 | 58 | if (device_found) { |
va009039 |
13:8774c07f12a5 | 59 | USB_INFO("New Cam: %s device: VID:%04x PID:%04x [dev: %p - intf: %d]", caminfo->name, dev->getVid(), dev->getPid(), dev, cam_intf); |
va009039 |
13:8774c07f12a5 | 60 | ep_iso_in = new USBEndpoint(dev); |
va009039 |
13:8774c07f12a5 | 61 | ep_iso_in->init(ISOCHRONOUS_ENDPOINT, IN, caminfo->mps, caminfo->en); |
va009039 |
18:61554f238584 | 62 | ep_iso_in->ohci_init(caminfo->frameCount, caminfo->queueLimit); |
va009039 |
13:8774c07f12a5 | 63 | uint8_t buf[26]; |
va009039 |
13:8774c07f12a5 | 64 | memset(buf, 0, sizeof(buf)); |
va009039 |
13:8774c07f12a5 | 65 | buf[2] = caminfo->formatIndex; |
va009039 |
13:8774c07f12a5 | 66 | buf[3] = caminfo->frameIndex; |
va009039 |
13:8774c07f12a5 | 67 | *reinterpret_cast<uint32_t*>(buf+4) = caminfo->interval; |
va009039 |
13:8774c07f12a5 | 68 | USB_TYPE res = Control(SET_CUR, VS_COMMIT_CONTROL, 1, buf, sizeof(buf)); |
va009039 |
13:8774c07f12a5 | 69 | if (res != USB_TYPE_OK) { |
va009039 |
13:8774c07f12a5 | 70 | USB_ERR("SET_CUR VS_COMMIT_CONTROL FAILED"); |
va009039 |
13:8774c07f12a5 | 71 | } |
va009039 |
13:8774c07f12a5 | 72 | res = setInterfaceAlternate(1, caminfo->if_alt); |
va009039 |
13:8774c07f12a5 | 73 | if (res != USB_TYPE_OK) { |
va009039 |
13:8774c07f12a5 | 74 | USB_ERR("SET_INTERFACE FAILED"); |
va009039 |
13:8774c07f12a5 | 75 | } |
va009039 |
13:8774c07f12a5 | 76 | dev_connected = true; |
va009039 |
13:8774c07f12a5 | 77 | return true; |
va009039 |
13:8774c07f12a5 | 78 | } |
va009039 |
13:8774c07f12a5 | 79 | } |
va009039 |
13:8774c07f12a5 | 80 | } |
va009039 |
13:8774c07f12a5 | 81 | init(); |
va009039 |
13:8774c07f12a5 | 82 | return false; |
va009039 |
13:8774c07f12a5 | 83 | } |
va009039 |
13:8774c07f12a5 | 84 | |
va009039 |
13:8774c07f12a5 | 85 | /*virtual*/ void USBHostCam::setVidPid(uint16_t vid, uint16_t pid) |
va009039 |
13:8774c07f12a5 | 86 | { |
va009039 |
13:8774c07f12a5 | 87 | CAM_DBG("vid:%04x,pid:%04x", vid, pid); |
va009039 |
13:8774c07f12a5 | 88 | caminfo = CamInfoList; |
va009039 |
13:8774c07f12a5 | 89 | while(caminfo->vid != 0) { |
va009039 |
13:8774c07f12a5 | 90 | if (caminfo->vid == vid && caminfo->pid == pid && |
va009039 |
13:8774c07f12a5 | 91 | caminfo->size == _caminfo_size && caminfo->option == _caminfo_option) { |
va009039 |
13:8774c07f12a5 | 92 | caminfo_found = true; |
va009039 |
13:8774c07f12a5 | 93 | break; |
va009039 |
13:8774c07f12a5 | 94 | } |
va009039 |
13:8774c07f12a5 | 95 | caminfo++; |
va009039 |
13:8774c07f12a5 | 96 | } |
va009039 |
13:8774c07f12a5 | 97 | } |
va009039 |
13:8774c07f12a5 | 98 | |
va009039 |
13:8774c07f12a5 | 99 | /*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 |
13:8774c07f12a5 | 100 | { |
va009039 |
13:8774c07f12a5 | 101 | CAM_DBG("intf_nb=%d,intf_class=%02X,intf_subclass=%d,intf_protocol=%d", intf_nb, intf_class, intf_subclass, intf_protocol); |
va009039 |
13:8774c07f12a5 | 102 | if ((cam_intf == -1) && caminfo_found) { |
va009039 |
13:8774c07f12a5 | 103 | cam_intf = intf_nb; |
va009039 |
13:8774c07f12a5 | 104 | device_found = true; |
va009039 |
13:8774c07f12a5 | 105 | return true; |
va009039 |
13:8774c07f12a5 | 106 | } |
va009039 |
13:8774c07f12a5 | 107 | return false; |
va009039 |
13:8774c07f12a5 | 108 | } |
va009039 |
13:8774c07f12a5 | 109 | |
va009039 |
13:8774c07f12a5 | 110 | /*virtual*/ bool USBHostCam::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used |
va009039 |
13:8774c07f12a5 | 111 | { |
va009039 |
13:8774c07f12a5 | 112 | CAM_DBG("intf_nb:%d,type:%d,dir:%d",intf_nb, type, dir); |
va009039 |
13:8774c07f12a5 | 113 | return false; |
va009039 |
13:8774c07f12a5 | 114 | } |
va009039 |
13:8774c07f12a5 | 115 | |
va009039 |
13:8774c07f12a5 | 116 | #define SEQ_READ_IDLE 0 |
va009039 |
13:8774c07f12a5 | 117 | #define SEQ_READ_EXEC 1 |
va009039 |
13:8774c07f12a5 | 118 | #define SEQ_READ_DONE 2 |
va009039 |
13:8774c07f12a5 | 119 | |
va009039 |
13:8774c07f12a5 | 120 | int USBHostCam::readJPEG(uint8_t* buf, int size, int timeout_ms) { |
va009039 |
13:8774c07f12a5 | 121 | _buf = buf; |
va009039 |
13:8774c07f12a5 | 122 | _pos = 0; |
va009039 |
13:8774c07f12a5 | 123 | _size = size; |
va009039 |
13:8774c07f12a5 | 124 | _seq = SEQ_READ_IDLE; |
va009039 |
13:8774c07f12a5 | 125 | setOnResult(this, &USBHostCam::callback_motion_jpeg); |
va009039 |
13:8774c07f12a5 | 126 | Timer timeout_t; |
va009039 |
13:8774c07f12a5 | 127 | timeout_t.reset(); |
va009039 |
13:8774c07f12a5 | 128 | timeout_t.start(); |
va009039 |
13:8774c07f12a5 | 129 | while(timeout_t.read_ms() < timeout_ms && _seq != SEQ_READ_DONE) { |
va009039 |
13:8774c07f12a5 | 130 | poll(); |
va009039 |
13:8774c07f12a5 | 131 | } |
va009039 |
13:8774c07f12a5 | 132 | return _pos; |
va009039 |
13:8774c07f12a5 | 133 | } |
va009039 |
13:8774c07f12a5 | 134 | |
va009039 |
13:8774c07f12a5 | 135 | /* virtual */ void USBHostCam::outputJPEG(uint8_t c, int status) { // from decodeMJPEG |
va009039 |
13:8774c07f12a5 | 136 | if (_seq == SEQ_READ_IDLE) { |
va009039 |
13:8774c07f12a5 | 137 | if (status == JPEG_START) { |
va009039 |
13:8774c07f12a5 | 138 | _pos = 0; |
va009039 |
13:8774c07f12a5 | 139 | _seq = SEQ_READ_EXEC; |
va009039 |
13:8774c07f12a5 | 140 | } |
va009039 |
13:8774c07f12a5 | 141 | } |
va009039 |
13:8774c07f12a5 | 142 | if (_seq == SEQ_READ_EXEC) { |
va009039 |
13:8774c07f12a5 | 143 | if (_pos < _size) { |
va009039 |
13:8774c07f12a5 | 144 | _buf[_pos++] = c; |
va009039 |
13:8774c07f12a5 | 145 | } |
va009039 |
13:8774c07f12a5 | 146 | if (status == JPEG_END) { |
va009039 |
13:8774c07f12a5 | 147 | _seq = SEQ_READ_DONE; |
va009039 |
13:8774c07f12a5 | 148 | } |
va009039 |
13:8774c07f12a5 | 149 | } |
va009039 |
13:8774c07f12a5 | 150 | } |
va009039 |
13:8774c07f12a5 | 151 | |
va009039 |
13:8774c07f12a5 | 152 | void USBHostCam::callback_motion_jpeg(uint16_t frame, uint8_t* buf, int len) { |
va009039 |
13:8774c07f12a5 | 153 | inputPacket(buf, len); |
va009039 |
13:8774c07f12a5 | 154 | } |