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
Revision 4:97438d526ad3, committed 2013-02-10
- Comitter:
- Dromar
- Date:
- Sun Feb 10 15:20:36 2013 +0000
- Parent:
- 0:b0f04c137829
- Commit message:
- ????????4800????????????????; /uvchost/uvc/uvc.cpp??; int uvc::get_jpeg(const char* path); const int size = 9600;; ????
Changed in this revision
uvc/uvc.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/uvc/uvc.cpp Tue Jul 31 13:58:03 2012 +0000 +++ b/uvc/uvc.cpp Sun Feb 10 15:20:36 2013 +0000 @@ -1,264 +1,265 @@ -#include "mbed.h" -#include "uvc.h" - -//#define __DEBUG -//#define __DEBUG3 -#include "mydbg.h" -#include "usb_itd.h" - -uvc::uvc(int cam) -{ - DBG("cam=%d\n", cam); - DBG_ASSERT(cam >= 0); - m_cam = cam; - m_init = false; - m_connect = false; - m_int_seq = 0; - m_iso_seq = 0; - m_width = 0; - m_height = 0; - m_payload = PAYLOAD_MJPEG; - m_FormatIndex = 0; - m_FrameIndex = 0; - m_FrameInterval = 0; - m_PacketSize = 0; - m_stream = NULL; - for(int i = 0; i <= 15; i++) { - ReportConditionCode[i] = 0; - } - clearOnResult(); -} - -uvc::~uvc() -{ - clearOnResult(); -} - -int uvc::setup() -{ - if (!m_init) { - return _init(); - } - return 0; -} - -int uvc::get_jpeg(const char* path) -{ - const int size = 4800; - const int timeout = 5000; - uint8_t* buf = new uint8_t[size]; - DBG_ASSERT(buf); - if (buf == NULL) { - return -1; - } - usb_mjpeg mjpeg(buf, size); - attach(&mjpeg); - Timer t; - t.reset(); - t.start(); - while(t.read_ms() < timeout) { - int stat = isochronous(); - if (mjpeg.status() >= 0) { - break; - } - } - detach(); - int len = mjpeg.status(); - if (len >= 0) { - if (path != NULL) { - FILE *fp = fopen(path, "wb"); - if (fp != NULL) { - for(int i = 0; i < len; i++) { - fputc(buf[i], fp); - } - fclose(fp); - } - } - } - delete[] buf; - return len; -} - -int uvc::get_jpeg(uint8_t* buf, int size) -{ - //DBG("buf=%p size=%d\n", buf, size); - const int timeout = 5000; - usb_mjpeg mjpeg(buf, size); - attach(&mjpeg); - Timer t; - t.reset(); - t.start(); - while(t.read_ms() < timeout) { - int stat = isochronous(); - if (mjpeg.status() >= 0) { - break; - } - } - detach(); - int len = mjpeg.status(); - return len; -} - -bool uvc::interrupt() -{ - if (!m_init) { - _init(); - } - if (m_int_seq == 0) { - int rc = m_pEpIntIn->transfer(m_int_buf, sizeof(m_int_buf)); - if (rc != USBERR_PROCESSING) { - return false; - } - m_int_seq++; - } - int len = m_pEpIntIn->status(); - if (len > 0) { - m_int_seq = 0; - DBG_BYTES("interrupt", m_int_buf, len); - return true; - } - return false; -} - -#define CC_NOERROR 0x0 -#define CC_DATAOVERRUN 0x8 -#define CC_DATAUNDERRUN 0x9 - -inline void DI() -{ - NVIC_DisableIRQ(USB_IRQn); -} - -inline void EI() -{ - NVIC_EnableIRQ(USB_IRQn); -} - -int uvc::isochronous() -{ - if (m_iso_seq == 0) { - uint16_t frame = LPC_USB->HcFmNumber; - m_iso_frame = frame + 10; // 10msec - DBG_ASSERT(m_pEpIsoIn->m_itdActive == 0); - m_iso_seq++; - } - if (m_iso_seq == 1) { - DBG_ASSERT(m_itdCount > 0 && m_itdCount <= 8); - while(m_pEpIsoIn->m_itdActive < m_itdCount) { - int len = m_PacketSize * m_FrameCount; - uint8_t* buf = (uint8_t*)usb_get_bp(len); - if (buf == NULL) { - DBG("len=%d\n", len); - DBG("m_itdCount=%d\n", m_itdCount); - } - DBG_ASSERT(buf); - int rc = m_pEpIsoIn->transfer(m_iso_frame, m_FrameCount, buf, len); - m_iso_frame += m_FrameCount; - DBG_ASSERT(rc == USBERR_PROCESSING); - } - m_iso_seq++; - } - if (m_iso_seq == 2) { - //DBG("frame:%04X\n", LPC_USB->HcFmNumber); - while(1) { - DI(); - bool empty = m_pEpIsoIn->queue_done_itd.empty(); - EI(); - - if (empty) { - break; - } - - DI(); - HCITD* itd = m_pEpIsoIn->queue_done_itd.front(); - m_pEpIsoIn->queue_done_itd.pop(); - EI(); - - m_pEpIsoIn->m_itdActive--; - usb_itd iso_td(itd); - //DBG("frame:%04X\n", LPC_USB->HcFmNumber); - //DBG("itd->Control=%08X\n", itd->Control); - int cc = iso_td.ConditionCode(); - DBG_ASSERT(cc >= 0 && cc <= 15); - ReportConditionCode[cc]++; - if (cc != CC_NOERROR) { - DBG3("%04X ERR:%X\n", LPC_USB->HcFmNumber, cc); - iso_td.free(); - m_iso_seq = 3; - return -1; - } - uint16_t frame = iso_td.StartingFrame(); - int fc = iso_td.FrameCount(); - for(int i = 0; i < fc; i++) { - int len = iso_td.Length(i); - if (len > 0) { - if (m_stream) { - m_stream->input(frame+i, iso_td.BufferPage(i, m_PacketSize), len); - } - onResult(frame+i, iso_td.BufferPage(i, m_PacketSize), len); - } - } - iso_td.free(); - } - //DBG("frame:%04X\n", LPC_USB->HcFmNumber); - m_iso_seq = 1; - return m_pEpIsoIn->m_itdActive; - } - if (m_iso_seq == 3) { // cleanup - DBG("m_pEpIsoIn->queue_done_itd.size() :%d\n", m_pEpIsoIn->queue_done_itd.size()); - while(1) { - DI(); - bool empty = m_pEpIsoIn->queue_done_itd.empty(); - EI(); - - if (empty) { - break; - } - - DI(); - HCITD* itd = m_pEpIsoIn->queue_done_itd.front(); - m_pEpIsoIn->queue_done_itd.pop(); - EI(); - - m_pEpIsoIn->m_itdActive--; - usb_itd iso_td(itd); - iso_td.free(); - } - if (m_pEpIsoIn->m_itdActive == 0) { - m_iso_seq = 0; - } - } - return m_pEpIsoIn->m_itdActive; -} - -void uvc::attach(usb_stream* stream) -{ - m_stream = stream; -} - -void uvc::detach() -{ - m_stream = NULL; -} - -void uvc::onResult(uint16_t frame, uint8_t* buf, int len) -{ - if(m_pCbItem && m_pCbMeth) - (m_pCbItem->*m_pCbMeth)(frame, buf, len); - else if(m_pCb) - m_pCb(frame, buf, len); -} - -void uvc::setOnResult( void (*pMethod)(uint16_t, uint8_t*, int) ) -{ - m_pCb = pMethod; - m_pCbItem = NULL; - m_pCbMeth = NULL; -} - -void uvc::clearOnResult() -{ - m_pCb = NULL; - m_pCbItem = NULL; - m_pCbMeth = NULL; -} +#include "mbed.h" +#include "uvc.h" + +//#define __DEBUG +//#define __DEBUG3 +#include "mydbg.h" +#include "usb_itd.h" + +uvc::uvc(int cam) +{ + DBG("cam=%d\n", cam); + DBG_ASSERT(cam >= 0); + m_cam = cam; + m_init = false; + m_connect = false; + m_int_seq = 0; + m_iso_seq = 0; + m_width = 0; + m_height = 0; + m_payload = PAYLOAD_MJPEG; + m_FormatIndex = 0; + m_FrameIndex = 0; + m_FrameInterval = 0; + m_PacketSize = 0; + m_stream = NULL; + for(int i = 0; i <= 15; i++) { + ReportConditionCode[i] = 0; + } + clearOnResult(); +} + +uvc::~uvc() +{ + clearOnResult(); +} + +int uvc::setup() +{ + if (!m_init) { + return _init(); + } + return 0; +} + +int uvc::get_jpeg(const char* path) +{ + //const int size = 4800; + const int size = 9600; + const int timeout = 5000; + uint8_t* buf = new uint8_t[size]; + DBG_ASSERT(buf); + if (buf == NULL) { + return -1; + } + usb_mjpeg mjpeg(buf, size); + attach(&mjpeg); + Timer t; + t.reset(); + t.start(); + while(t.read_ms() < timeout) { + int stat = isochronous(); + if (mjpeg.status() >= 0) { + break; + } + } + detach(); + int len = mjpeg.status(); + if (len >= 0) { + if (path != NULL) { + FILE *fp = fopen(path, "wb"); + if (fp != NULL) { + for(int i = 0; i < len; i++) { + fputc(buf[i], fp); + } + fclose(fp); + } + } + } + delete[] buf; + return len; +} + +int uvc::get_jpeg(uint8_t* buf, int size) +{ + //DBG("buf=%p size=%d\n", buf, size); + const int timeout = 5000; + usb_mjpeg mjpeg(buf, size); + attach(&mjpeg); + Timer t; + t.reset(); + t.start(); + while(t.read_ms() < timeout) { + int stat = isochronous(); + if (mjpeg.status() >= 0) { + break; + } + } + detach(); + int len = mjpeg.status(); + return len; +} + +bool uvc::interrupt() +{ + if (!m_init) { + _init(); + } + if (m_int_seq == 0) { + int rc = m_pEpIntIn->transfer(m_int_buf, sizeof(m_int_buf)); + if (rc != USBERR_PROCESSING) { + return false; + } + m_int_seq++; + } + int len = m_pEpIntIn->status(); + if (len > 0) { + m_int_seq = 0; + DBG_BYTES("interrupt", m_int_buf, len); + return true; + } + return false; +} + +#define CC_NOERROR 0x0 +#define CC_DATAOVERRUN 0x8 +#define CC_DATAUNDERRUN 0x9 + +inline void DI() +{ + NVIC_DisableIRQ(USB_IRQn); +} + +inline void EI() +{ + NVIC_EnableIRQ(USB_IRQn); +} + +int uvc::isochronous() +{ + if (m_iso_seq == 0) { + uint16_t frame = LPC_USB->HcFmNumber; + m_iso_frame = frame + 10; // 10msec + DBG_ASSERT(m_pEpIsoIn->m_itdActive == 0); + m_iso_seq++; + } + if (m_iso_seq == 1) { + DBG_ASSERT(m_itdCount > 0 && m_itdCount <= 8); + while(m_pEpIsoIn->m_itdActive < m_itdCount) { + int len = m_PacketSize * m_FrameCount; + uint8_t* buf = (uint8_t*)usb_get_bp(len); + if (buf == NULL) { + DBG("len=%d\n", len); + DBG("m_itdCount=%d\n", m_itdCount); + } + DBG_ASSERT(buf); + int rc = m_pEpIsoIn->transfer(m_iso_frame, m_FrameCount, buf, len); + m_iso_frame += m_FrameCount; + DBG_ASSERT(rc == USBERR_PROCESSING); + } + m_iso_seq++; + } + if (m_iso_seq == 2) { + //DBG("frame:%04X\n", LPC_USB->HcFmNumber); + while(1) { + DI(); + bool empty = m_pEpIsoIn->queue_done_itd.empty(); + EI(); + + if (empty) { + break; + } + + DI(); + HCITD* itd = m_pEpIsoIn->queue_done_itd.front(); + m_pEpIsoIn->queue_done_itd.pop(); + EI(); + + m_pEpIsoIn->m_itdActive--; + usb_itd iso_td(itd); + //DBG("frame:%04X\n", LPC_USB->HcFmNumber); + //DBG("itd->Control=%08X\n", itd->Control); + int cc = iso_td.ConditionCode(); + DBG_ASSERT(cc >= 0 && cc <= 15); + ReportConditionCode[cc]++; + if (cc != CC_NOERROR) { + DBG3("%04X ERR:%X\n", LPC_USB->HcFmNumber, cc); + iso_td.free(); + m_iso_seq = 3; + return -1; + } + uint16_t frame = iso_td.StartingFrame(); + int fc = iso_td.FrameCount(); + for(int i = 0; i < fc; i++) { + int len = iso_td.Length(i); + if (len > 0) { + if (m_stream) { + m_stream->input(frame+i, iso_td.BufferPage(i, m_PacketSize), len); + } + onResult(frame+i, iso_td.BufferPage(i, m_PacketSize), len); + } + } + iso_td.free(); + } + //DBG("frame:%04X\n", LPC_USB->HcFmNumber); + m_iso_seq = 1; + return m_pEpIsoIn->m_itdActive; + } + if (m_iso_seq == 3) { // cleanup + DBG("m_pEpIsoIn->queue_done_itd.size() :%d\n", m_pEpIsoIn->queue_done_itd.size()); + while(1) { + DI(); + bool empty = m_pEpIsoIn->queue_done_itd.empty(); + EI(); + + if (empty) { + break; + } + + DI(); + HCITD* itd = m_pEpIsoIn->queue_done_itd.front(); + m_pEpIsoIn->queue_done_itd.pop(); + EI(); + + m_pEpIsoIn->m_itdActive--; + usb_itd iso_td(itd); + iso_td.free(); + } + if (m_pEpIsoIn->m_itdActive == 0) { + m_iso_seq = 0; + } + } + return m_pEpIsoIn->m_itdActive; +} + +void uvc::attach(usb_stream* stream) +{ + m_stream = stream; +} + +void uvc::detach() +{ + m_stream = NULL; +} + +void uvc::onResult(uint16_t frame, uint8_t* buf, int len) +{ + if(m_pCbItem && m_pCbMeth) + (m_pCbItem->*m_pCbMeth)(frame, buf, len); + else if(m_pCb) + m_pCb(frame, buf, len); +} + +void uvc::setOnResult( void (*pMethod)(uint16_t, uint8_t*, int) ) +{ + m_pCb = pMethod; + m_pCbItem = NULL; + m_pCbMeth = NULL; +} + +void uvc::clearOnResult() +{ + m_pCb = NULL; + m_pCbItem = NULL; + m_pCbMeth = NULL; +}