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 uvchost by
uvc.cpp
00001 #include "mbed.h" 00002 #include "uvc.h" 00003 00004 //#define __DEBUG 00005 //#define __DEBUG3 00006 #include "mydbg.h" 00007 #include "usb_itd.h" 00008 00009 uvc::uvc(int cam) 00010 { 00011 DBG("cam=%d\n", cam); 00012 DBG_ASSERT(cam >= 0); 00013 m_cam = cam; 00014 m_init = false; 00015 m_connect = false; 00016 m_int_seq = 0; 00017 m_iso_seq = 0; 00018 m_width = 0; 00019 m_height = 0; 00020 m_payload = PAYLOAD_MJPEG; 00021 m_FormatIndex = 0; 00022 m_FrameIndex = 0; 00023 m_FrameInterval = 0; 00024 m_PacketSize = 0; 00025 m_stream = NULL; 00026 for(int i = 0; i <= 15; i++) { 00027 ReportConditionCode[i] = 0; 00028 } 00029 clearOnResult(); 00030 } 00031 00032 uvc::~uvc() 00033 { 00034 clearOnResult(); 00035 } 00036 00037 int uvc::setup() 00038 { 00039 if (!m_init) { 00040 return _init(); 00041 } 00042 return 0; 00043 } 00044 00045 int uvc::get_jpeg(const char* path) 00046 { 00047 //const int size = 4800; 00048 const int size = 9600; 00049 const int timeout = 5000; 00050 uint8_t* buf = new uint8_t[size]; 00051 DBG_ASSERT(buf); 00052 if (buf == NULL) { 00053 return -1; 00054 } 00055 usb_mjpeg mjpeg(buf, size); 00056 attach(&mjpeg); 00057 Timer t; 00058 t.reset(); 00059 t.start(); 00060 while(t.read_ms() < timeout) { 00061 int stat = isochronous(); 00062 if (mjpeg.status() >= 0) { 00063 break; 00064 } 00065 } 00066 detach(); 00067 int len = mjpeg.status(); 00068 if (len >= 0) { 00069 if (path != NULL) { 00070 FILE *fp = fopen(path, "wb"); 00071 if (fp != NULL) { 00072 for(int i = 0; i < len; i++) { 00073 fputc(buf[i], fp); 00074 } 00075 fclose(fp); 00076 } 00077 } 00078 } 00079 delete[] buf; 00080 return len; 00081 } 00082 00083 int uvc::get_jpeg(uint8_t* buf, int size) 00084 { 00085 //DBG("buf=%p size=%d\n", buf, size); 00086 const int timeout = 5000; 00087 usb_mjpeg mjpeg(buf, size); 00088 attach(&mjpeg); 00089 Timer t; 00090 t.reset(); 00091 t.start(); 00092 while(t.read_ms() < timeout) { 00093 int stat = isochronous(); 00094 if (mjpeg.status() >= 0) { 00095 break; 00096 } 00097 } 00098 detach(); 00099 int len = mjpeg.status(); 00100 return len; 00101 } 00102 00103 bool uvc::interrupt() 00104 { 00105 if (!m_init) { 00106 _init(); 00107 } 00108 if (m_int_seq == 0) { 00109 int rc = m_pEpIntIn->transfer(m_int_buf, sizeof(m_int_buf)); 00110 if (rc != USBERR_PROCESSING) { 00111 return false; 00112 } 00113 m_int_seq++; 00114 } 00115 int len = m_pEpIntIn->status(); 00116 if (len > 0) { 00117 m_int_seq = 0; 00118 DBG_BYTES("interrupt", m_int_buf, len); 00119 return true; 00120 } 00121 return false; 00122 } 00123 00124 #define CC_NOERROR 0x0 00125 #define CC_DATAOVERRUN 0x8 00126 #define CC_DATAUNDERRUN 0x9 00127 00128 inline void DI() 00129 { 00130 NVIC_DisableIRQ(USB_IRQn); 00131 } 00132 00133 inline void EI() 00134 { 00135 NVIC_EnableIRQ(USB_IRQn); 00136 } 00137 00138 int uvc::isochronous() 00139 { 00140 if (m_iso_seq == 0) { 00141 uint16_t frame = LPC_USB->HcFmNumber; 00142 m_iso_frame = frame + 10; // 10msec 00143 DBG_ASSERT(m_pEpIsoIn->m_itdActive == 0); 00144 m_iso_seq++; 00145 } 00146 if (m_iso_seq == 1) { 00147 DBG_ASSERT(m_itdCount > 0 && m_itdCount <= 8); 00148 while(m_pEpIsoIn->m_itdActive < m_itdCount) { 00149 int len = m_PacketSize * m_FrameCount; 00150 uint8_t* buf = (uint8_t*)usb_get_bp(len); 00151 if (buf == NULL) { 00152 DBG("len=%d\n", len); 00153 DBG("m_itdCount=%d\n", m_itdCount); 00154 } 00155 DBG_ASSERT(buf); 00156 int rc = m_pEpIsoIn->transfer(m_iso_frame, m_FrameCount, buf, len); 00157 m_iso_frame += m_FrameCount; 00158 DBG_ASSERT(rc == USBERR_PROCESSING); 00159 } 00160 m_iso_seq++; 00161 } 00162 if (m_iso_seq == 2) { 00163 //DBG("frame:%04X\n", LPC_USB->HcFmNumber); 00164 while(1) { 00165 DI(); 00166 bool empty = m_pEpIsoIn->queue_done_itd.empty(); 00167 EI(); 00168 00169 if (empty) { 00170 break; 00171 } 00172 00173 DI(); 00174 HCITD* itd = m_pEpIsoIn->queue_done_itd.front(); 00175 m_pEpIsoIn->queue_done_itd.pop(); 00176 EI(); 00177 00178 m_pEpIsoIn->m_itdActive--; 00179 usb_itd iso_td(itd); 00180 //DBG("frame:%04X\n", LPC_USB->HcFmNumber); 00181 //DBG("itd->Control=%08X\n", itd->Control); 00182 int cc = iso_td.ConditionCode(); 00183 DBG_ASSERT(cc >= 0 && cc <= 15); 00184 ReportConditionCode[cc]++; 00185 if (cc != CC_NOERROR) { 00186 DBG3("%04X ERR:%X\n", LPC_USB->HcFmNumber, cc); 00187 iso_td.free(); 00188 m_iso_seq = 3; 00189 return -1; 00190 } 00191 uint16_t frame = iso_td.StartingFrame(); 00192 int fc = iso_td.FrameCount(); 00193 for(int i = 0; i < fc; i++) { 00194 int len = iso_td.Length(i); 00195 if (len > 0) { 00196 if (m_stream) { 00197 m_stream->input(frame+i, iso_td.BufferPage(i, m_PacketSize), len); 00198 } 00199 onResult(frame+i, iso_td.BufferPage(i, m_PacketSize), len); 00200 } 00201 } 00202 iso_td.free(); 00203 } 00204 //DBG("frame:%04X\n", LPC_USB->HcFmNumber); 00205 m_iso_seq = 1; 00206 return m_pEpIsoIn->m_itdActive; 00207 } 00208 if (m_iso_seq == 3) { // cleanup 00209 DBG("m_pEpIsoIn->queue_done_itd.size() :%d\n", m_pEpIsoIn->queue_done_itd.size()); 00210 while(1) { 00211 DI(); 00212 bool empty = m_pEpIsoIn->queue_done_itd.empty(); 00213 EI(); 00214 00215 if (empty) { 00216 break; 00217 } 00218 00219 DI(); 00220 HCITD* itd = m_pEpIsoIn->queue_done_itd.front(); 00221 m_pEpIsoIn->queue_done_itd.pop(); 00222 EI(); 00223 00224 m_pEpIsoIn->m_itdActive--; 00225 usb_itd iso_td(itd); 00226 iso_td.free(); 00227 } 00228 if (m_pEpIsoIn->m_itdActive == 0) { 00229 m_iso_seq = 0; 00230 } 00231 } 00232 return m_pEpIsoIn->m_itdActive; 00233 } 00234 00235 void uvc::attach(usb_stream* stream) 00236 { 00237 m_stream = stream; 00238 } 00239 00240 void uvc::detach() 00241 { 00242 m_stream = NULL; 00243 } 00244 00245 void uvc::onResult(uint16_t frame, uint8_t* buf, int len) 00246 { 00247 if(m_pCbItem && m_pCbMeth) 00248 (m_pCbItem->*m_pCbMeth)(frame, buf, len); 00249 else if(m_pCb) 00250 m_pCb(frame, buf, len); 00251 } 00252 00253 void uvc::setOnResult( void (*pMethod)(uint16_t, uint8_t*, int) ) 00254 { 00255 m_pCb = pMethod; 00256 m_pCbItem = NULL; 00257 m_pCbMeth = NULL; 00258 } 00259 00260 void uvc::clearOnResult() 00261 { 00262 m_pCb = NULL; 00263 m_pCbItem = NULL; 00264 m_pCbMeth = NULL; 00265 }
Generated on Wed Jul 13 2022 01:34:55 by
1.7.2
