Simple USBHost WebCam for EA LPC4088 QSB/LPC1768 test program

Dependencies:   LPC4088-USBHost mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBIsochronous.cpp Source File

USBIsochronous.cpp

00001 // USBIsochronous.cpp
00002 #include "USBHostConf.h"
00003 #include "USBHost.h"
00004 #include "USBIsochronous.h"
00005 
00006 //#define ISO_DEBUG 1
00007 #ifdef ISO_DEBUG
00008 #define ISO_DBG(x, ...) std::printf("[%s:%d]"x"\r\n", __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
00009 #else
00010 #define ISO_DBG(...)  while(0);
00011 #endif
00012 
00013 #if 0
00014 #define TEST_ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);};
00015 #else
00016 #define TEST_ASSERT(A) while(0)
00017 #endif
00018 
00019 IsochronousEp::IsochronousEp(USBDeviceConnected* dev):USBEndpoint(dev) {
00020 }
00021 
00022 void IsochronousEp::init2(uint8_t frameCount, uint8_t queueLimit) {
00023     m_pED  = new HCED(this);
00024     m_pED->setFormat(); // F Format ITD
00025     TEST_ASSERT(frameCount >= 1 && frameCount <= 8);
00026     m_FrameCount = frameCount;
00027     TEST_ASSERT(queueLimit >= 1 && queueLimit <= HCTD_QUEUE_SIZE);
00028     m_itd_queue_limit = queueLimit;
00029     
00030     m_itd_queue_count = 0;
00031     reset();
00032     HCITD* itd = new_HCITD(this);
00033     m_pED->init_queue(reinterpret_cast<HCTD*>(itd)); 
00034     HCCA* hcca = reinterpret_cast<HCCA*>(LPC_USB->HcHCCA);
00035     hcca->enqueue(m_pED);
00036 }
00037 
00038 void IsochronousEp::reset(int delay_ms) {
00039     m_FrameNumber = LPC_USB->HcFmNumber + delay_ms;
00040 }
00041 
00042 HCITD* IsochronousEp::new_HCITD(IsochronousEp* obj) {
00043     HCITD* itd = new(getSize() * m_FrameCount)HCITD(obj, m_FrameNumber, m_FrameCount, getSize());
00044     m_FrameNumber += m_FrameCount;
00045     return itd;
00046 }
00047 
00048 HCITD* IsochronousEp::isochronousReceive(int timeout_ms) {
00049     while(m_itd_queue_count < m_itd_queue_limit) {
00050         HCITD* blank_itd = new_HCITD(this);
00051         if (m_pED->enqueue(reinterpret_cast<HCTD*>(blank_itd))) {
00052             m_itd_queue_count++;
00053         }
00054         enable(); // Enable Periodic
00055     }
00056     
00057     HCITD* itd = get_queue_HCITD(timeout_ms);
00058     if (itd) {
00059         m_itd_queue_count--;
00060     }
00061     return itd;
00062 }
00063 
00064 #if 0
00065 int IsochronousEp::isochronousSend(uint8_t* buf, int len, int timeout_ms)
00066 {
00067     //ISO_DBG("buf: %p, len: %d", buf, len);
00068     HCITD* itd = get_queue_HCITD(timeout_ms);
00069     if (itd) {
00070         delete itd;
00071         m_itd_queue_count--;
00072         TEST_ASSERT(m_itd_queue_count >= 0);
00073     }
00074     TEST_ASSERT(m_itd_queue_count >= 0);
00075     if(m_itd_queue_count < m_itd_queue_limit) {
00076         if (m_pED == NULL) {
00077             ISO_DBG("m_pED is NULL");
00078             return 0;
00079         }
00080         if (m_pED->Skip()) {
00081             return 0;
00082         }
00083         itd = new_HCITD(this);
00084         TEST_ASSERT(itd);
00085         //ISO_DBG("m_pED: %p itd: %p", m_pED, itd);
00086         memcpy(const_cast<uint8_t*>(itd->buf), buf, len);
00087         if (m_pED->enqueue<HCITD>(itd)) {
00088             m_itd_queue_count++;
00089         }
00090         enable(); // Enable Periodic
00091         //ISO_DBG("m_itd_queue_count: %d", m_itd_queue_count);
00092         return len;
00093     }
00094     return 0;
00095 }
00096 #endif
00097 
00098 HCITD* IsochronousEp::get_queue_HCITD(int timeout_ms)
00099 {
00100     Timer t;
00101     t.reset();
00102     t.start();
00103     do {
00104         osEvent evt = m_queue.get(0);
00105         if (evt.status == osEventMessage) {
00106             HCITD* itd = reinterpret_cast<HCITD*>(evt.value.p);
00107             TEST_ASSERT(itd);
00108             return itd;
00109         } else if (evt.status == osOK) {
00110             ;
00111         } else if (evt.status == osEventTimeout) {
00112             break;
00113         } else {
00114             ISO_DBG("evt.status: %02x\n", evt.status);
00115             TEST_ASSERT(evt.status == osEventMessage);
00116             break;
00117         }
00118     } while(t.read_ms() < timeout_ms);
00119     return NULL;
00120 }
00121 
00122 void IsochronousEp::enable()
00123 {
00124     LPC_USB->HcControl |= OR_CONTROL_PLE;
00125 }
00126 
00127