BLE demo for mbed Ported RunningElectronics's SBDBT firmware for BLE. It can communicate with iOS
Dependencies: FatFileSystem mbed
Fork of BTstack 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 timeout = 5000; 00049 uint8_t* buf = new uint8_t[size]; 00050 DBG_ASSERT(buf); 00051 if (buf == NULL) { 00052 return -1; 00053 } 00054 usb_mjpeg mjpeg(buf, size); 00055 attach(&mjpeg); 00056 Timer t; 00057 t.reset(); 00058 t.start(); 00059 while(t.read_ms() < timeout) { 00060 int stat = isochronous(); 00061 if (mjpeg.status() >= 0) { 00062 break; 00063 } 00064 } 00065 detach(); 00066 int len = mjpeg.status(); 00067 if (len >= 0) { 00068 if (path != NULL) { 00069 FILE *fp = fopen(path, "wb"); 00070 if (fp != NULL) { 00071 for(int i = 0; i < len; i++) { 00072 fputc(buf[i], fp); 00073 } 00074 fclose(fp); 00075 } 00076 } 00077 } 00078 delete[] buf; 00079 return len; 00080 } 00081 00082 int uvc::get_jpeg(uint8_t* buf, int size) 00083 { 00084 //DBG("buf=%p size=%d\n", buf, size); 00085 const int timeout = 5000; 00086 usb_mjpeg mjpeg(buf, size); 00087 attach(&mjpeg); 00088 Timer t; 00089 t.reset(); 00090 t.start(); 00091 while(t.read_ms() < timeout) { 00092 int stat = isochronous(); 00093 if (mjpeg.status() >= 0) { 00094 break; 00095 } 00096 } 00097 detach(); 00098 int len = mjpeg.status(); 00099 return len; 00100 } 00101 00102 bool uvc::interrupt() 00103 { 00104 if (!m_init) { 00105 _init(); 00106 } 00107 if (m_int_seq == 0) { 00108 int rc = m_pEpIntIn->transfer(m_int_buf, sizeof(m_int_buf)); 00109 if (rc != USBERR_PROCESSING) { 00110 return false; 00111 } 00112 m_int_seq++; 00113 } 00114 int len = m_pEpIntIn->status(); 00115 if (len > 0) { 00116 m_int_seq = 0; 00117 DBG_BYTES("interrupt", m_int_buf, len); 00118 return true; 00119 } 00120 return false; 00121 } 00122 00123 #define CC_NOERROR 0x0 00124 #define CC_DATAOVERRUN 0x8 00125 #define CC_DATAUNDERRUN 0x9 00126 00127 inline void DI() 00128 { 00129 NVIC_DisableIRQ(USB_IRQn); 00130 } 00131 00132 inline void EI() 00133 { 00134 NVIC_EnableIRQ(USB_IRQn); 00135 } 00136 00137 int uvc::isochronous() 00138 { 00139 if (m_iso_seq == 0) { 00140 uint16_t frame = LPC_USB->HcFmNumber; 00141 m_iso_frame = frame + 10; // 10msec 00142 DBG_ASSERT(m_pEpIsoIn->m_itdActive == 0); 00143 m_iso_seq++; 00144 } 00145 if (m_iso_seq == 1) { 00146 DBG_ASSERT(m_itdCount > 0 && m_itdCount <= 8); 00147 while(m_pEpIsoIn->m_itdActive < m_itdCount) { 00148 int len = m_PacketSize * m_FrameCount; 00149 uint8_t* buf = (uint8_t*)usb_get_bp(len); 00150 if (buf == NULL) { 00151 DBG("len=%d\n", len); 00152 DBG("m_itdCount=%d\n", m_itdCount); 00153 } 00154 DBG_ASSERT(buf); 00155 int rc = m_pEpIsoIn->transfer(m_iso_frame, m_FrameCount, buf, len); 00156 m_iso_frame += m_FrameCount; 00157 DBG_ASSERT(rc == USBERR_PROCESSING); 00158 } 00159 m_iso_seq++; 00160 } 00161 if (m_iso_seq == 2) { 00162 //DBG("frame:%04X\n", LPC_USB->HcFmNumber); 00163 while(1) { 00164 DI(); 00165 bool empty = m_pEpIsoIn->queue_done_itd.empty(); 00166 EI(); 00167 00168 if (empty) { 00169 break; 00170 } 00171 00172 DI(); 00173 HCITD* itd = m_pEpIsoIn->queue_done_itd.front(); 00174 m_pEpIsoIn->queue_done_itd.pop(); 00175 EI(); 00176 00177 m_pEpIsoIn->m_itdActive--; 00178 usb_itd iso_td(itd); 00179 //DBG("frame:%04X\n", LPC_USB->HcFmNumber); 00180 //DBG("itd->Control=%08X\n", itd->Control); 00181 int cc = iso_td.ConditionCode(); 00182 DBG_ASSERT(cc >= 0 && cc <= 15); 00183 ReportConditionCode[cc]++; 00184 if (cc != CC_NOERROR) { 00185 DBG3("%04X ERR:%X\n", LPC_USB->HcFmNumber, cc); 00186 iso_td.free(); 00187 m_iso_seq = 3; 00188 return -1; 00189 } 00190 uint16_t frame = iso_td.StartingFrame(); 00191 int fc = iso_td.FrameCount(); 00192 for(int i = 0; i < fc; i++) { 00193 int len = iso_td.Length(i); 00194 if (len > 0) { 00195 if (m_stream) { 00196 m_stream->input(frame+i, iso_td.BufferPage(i, m_PacketSize), len); 00197 } 00198 onResult(frame+i, iso_td.BufferPage(i, m_PacketSize), len); 00199 } 00200 } 00201 iso_td.free(); 00202 } 00203 //DBG("frame:%04X\n", LPC_USB->HcFmNumber); 00204 m_iso_seq = 1; 00205 return m_pEpIsoIn->m_itdActive; 00206 } 00207 if (m_iso_seq == 3) { // cleanup 00208 DBG("m_pEpIsoIn->queue_done_itd.size() :%d\n", m_pEpIsoIn->queue_done_itd.size()); 00209 while(1) { 00210 DI(); 00211 bool empty = m_pEpIsoIn->queue_done_itd.empty(); 00212 EI(); 00213 00214 if (empty) { 00215 break; 00216 } 00217 00218 DI(); 00219 HCITD* itd = m_pEpIsoIn->queue_done_itd.front(); 00220 m_pEpIsoIn->queue_done_itd.pop(); 00221 EI(); 00222 00223 m_pEpIsoIn->m_itdActive--; 00224 usb_itd iso_td(itd); 00225 iso_td.free(); 00226 } 00227 if (m_pEpIsoIn->m_itdActive == 0) { 00228 m_iso_seq = 0; 00229 } 00230 } 00231 return m_pEpIsoIn->m_itdActive; 00232 } 00233 00234 void uvc::attach(usb_stream* stream) 00235 { 00236 m_stream = stream; 00237 } 00238 00239 void uvc::detach() 00240 { 00241 m_stream = NULL; 00242 } 00243 00244 void uvc::onResult(uint16_t frame, uint8_t* buf, int len) 00245 { 00246 if(m_pCbItem && m_pCbMeth) 00247 (m_pCbItem->*m_pCbMeth)(frame, buf, len); 00248 else if(m_pCb) 00249 m_pCb(frame, buf, len); 00250 } 00251 00252 void uvc::setOnResult( void (*pMethod)(uint16_t, uint8_t*, int) ) 00253 { 00254 m_pCb = pMethod; 00255 m_pCbItem = NULL; 00256 m_pCbMeth = NULL; 00257 } 00258 00259 void uvc::clearOnResult() 00260 { 00261 m_pCb = NULL; 00262 m_pCbItem = NULL; 00263 m_pCbMeth = NULL; 00264 }
Generated on Thu Jul 14 2022 15:03:49 by 1.7.2