Zoltan Hudak / USBHost-STM32F4

Dependents:   STM32F407VET6_USBHostMSD STM32F407VET6_USBHostMouse STM32F407VET6_USBHostKeyboard STM32F407VET6_USBHostMSD_1

Committer:
hudakz
Date:
Tue Feb 19 21:32:56 2019 +0000
Revision:
0:458bf947f46f
Fork of [[https://os.mbed.com/users/va009039/code/F401RE-USBHost/]]. Added support for Seeed Arch Max and STM32F407.

Who changed what in which revision?

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