![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
LogitechC270 webcam class driver alpha version
Fork of USBHostMSD_HelloWorld by
USBHostC270/BaseUvc.cpp@9:fecabade834a, 2013-03-16 (annotated)
- Committer:
- va009039
- Date:
- Sat Mar 16 13:07:55 2013 +0000
- Revision:
- 9:fecabade834a
- Child:
- 10:387c49b2fc7e
LogitechC270 class driver alpha version
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 | 9:fecabade834a | 1 | #include "USBHostConf.h" |
va009039 | 9:fecabade834a | 2 | #include "USBHost.h" |
va009039 | 9:fecabade834a | 3 | |
va009039 | 9:fecabade834a | 4 | #include "USBHostC270.h" |
va009039 | 9:fecabade834a | 5 | #include "BaseUvc.h" |
va009039 | 9:fecabade834a | 6 | |
va009039 | 9:fecabade834a | 7 | #define TEST_ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);}; |
va009039 | 9:fecabade834a | 8 | |
va009039 | 9:fecabade834a | 9 | void BaseUvc::poll(int millisec) |
va009039 | 9:fecabade834a | 10 | { |
va009039 | 9:fecabade834a | 11 | HCITD* itd = m_isoEp->isochronousReveive(millisec); |
va009039 | 9:fecabade834a | 12 | if (itd) { |
va009039 | 9:fecabade834a | 13 | uint8_t cc = itd->ConditionCode(); |
va009039 | 9:fecabade834a | 14 | report_cc_count[cc]++; |
va009039 | 9:fecabade834a | 15 | if (cc == 0) { |
va009039 | 9:fecabade834a | 16 | uint16_t frame = itd->StartingFrame(); |
va009039 | 9:fecabade834a | 17 | int fc = itd->FrameCount(); |
va009039 | 9:fecabade834a | 18 | uint8_t* buf = const_cast<uint8_t*>(itd->buf); |
va009039 | 9:fecabade834a | 19 | int mps = m_isoEp->m_PacketSize; |
va009039 | 9:fecabade834a | 20 | for(int i = 0; i < fc; i++) { |
va009039 | 9:fecabade834a | 21 | uint16_t psw = itd->OffsetPSW[i]; |
va009039 | 9:fecabade834a | 22 | cc = psw>>12; |
va009039 | 9:fecabade834a | 23 | if (cc == 0 || cc == 9) { |
va009039 | 9:fecabade834a | 24 | int len = psw & 0x7ff; |
va009039 | 9:fecabade834a | 25 | onResult(frame, buf, len); |
va009039 | 9:fecabade834a | 26 | } |
va009039 | 9:fecabade834a | 27 | report_ps_cc_count[cc]++; |
va009039 | 9:fecabade834a | 28 | buf += mps; |
va009039 | 9:fecabade834a | 29 | frame++; |
va009039 | 9:fecabade834a | 30 | } |
va009039 | 9:fecabade834a | 31 | } |
va009039 | 9:fecabade834a | 32 | delete itd; |
va009039 | 9:fecabade834a | 33 | } |
va009039 | 9:fecabade834a | 34 | } |
va009039 | 9:fecabade834a | 35 | |
va009039 | 9:fecabade834a | 36 | void BaseUvc::onResult(uint16_t frame, uint8_t* buf, int len) |
va009039 | 9:fecabade834a | 37 | { |
va009039 | 9:fecabade834a | 38 | if(m_pCbItem && m_pCbMeth) |
va009039 | 9:fecabade834a | 39 | (m_pCbItem->*m_pCbMeth)(frame, buf, len); |
va009039 | 9:fecabade834a | 40 | else if(m_pCb) |
va009039 | 9:fecabade834a | 41 | m_pCb(frame, buf, len); |
va009039 | 9:fecabade834a | 42 | } |
va009039 | 9:fecabade834a | 43 | |
va009039 | 9:fecabade834a | 44 | void BaseUvc::setOnResult( void (*pMethod)(uint16_t, uint8_t*, int) ) |
va009039 | 9:fecabade834a | 45 | { |
va009039 | 9:fecabade834a | 46 | m_pCb = pMethod; |
va009039 | 9:fecabade834a | 47 | m_pCbItem = NULL; |
va009039 | 9:fecabade834a | 48 | m_pCbMeth = NULL; |
va009039 | 9:fecabade834a | 49 | } |
va009039 | 9:fecabade834a | 50 | |
va009039 | 9:fecabade834a | 51 | void BaseUvc::clearOnResult() |
va009039 | 9:fecabade834a | 52 | { |
va009039 | 9:fecabade834a | 53 | m_pCb = NULL; |
va009039 | 9:fecabade834a | 54 | m_pCbItem = NULL; |
va009039 | 9:fecabade834a | 55 | m_pCbMeth = NULL; |
va009039 | 9:fecabade834a | 56 | } |
va009039 | 9:fecabade834a | 57 | |
va009039 | 9:fecabade834a | 58 | |
va009039 | 9:fecabade834a | 59 | HCITD::HCITD(BaseEp* obj, uint16_t FrameNumber, int FrameCount, uint16_t PacketSize) { |
va009039 | 9:fecabade834a | 60 | Control = 0xe0000000 | // CC ConditionCode NOT ACCESSED |
va009039 | 9:fecabade834a | 61 | ((FrameCount-1) << 24)| // FC FrameCount |
va009039 | 9:fecabade834a | 62 | TD_DELAY_INT(0) | // DI DelayInterrupt |
va009039 | 9:fecabade834a | 63 | FrameNumber; // SF StartingFrame |
va009039 | 9:fecabade834a | 64 | BufferPage0 = const_cast<uint8_t*>(buf); |
va009039 | 9:fecabade834a | 65 | BufferEnd = const_cast<uint8_t*>(buf) + PacketSize * FrameCount - 1; |
va009039 | 9:fecabade834a | 66 | Next = NULL; |
va009039 | 9:fecabade834a | 67 | ep = obj; |
va009039 | 9:fecabade834a | 68 | uint32_t addr = reinterpret_cast<uint32_t>(buf); |
va009039 | 9:fecabade834a | 69 | for(int i = 0; i < FrameCount; i++) { |
va009039 | 9:fecabade834a | 70 | uint16_t offset = addr & 0x0fff; |
va009039 | 9:fecabade834a | 71 | if ((addr&0xfffff000) == (reinterpret_cast<uint32_t>(BufferEnd)&0xfffff000)) { |
va009039 | 9:fecabade834a | 72 | offset |= 0x1000; |
va009039 | 9:fecabade834a | 73 | } |
va009039 | 9:fecabade834a | 74 | OffsetPSW[i] = 0xe000|offset; |
va009039 | 9:fecabade834a | 75 | addr += PacketSize; |
va009039 | 9:fecabade834a | 76 | } |
va009039 | 9:fecabade834a | 77 | } |
va009039 | 9:fecabade834a | 78 | |
va009039 | 9:fecabade834a | 79 | IsochronousEp::IsochronousEp(int addr, uint8_t ep, uint16_t size):BaseEp(addr, ep, size) |
va009039 | 9:fecabade834a | 80 | { |
va009039 | 9:fecabade834a | 81 | C270_DBG("%p FA:%d EP:%02X MPS:%d\n", this, addr, ep, size); |
va009039 | 9:fecabade834a | 82 | TEST_ASSERT(m_pED); |
va009039 | 9:fecabade834a | 83 | |
va009039 | 9:fecabade834a | 84 | m_pED->Control |= (1 << 15); // F Format ITD |
va009039 | 9:fecabade834a | 85 | |
va009039 | 9:fecabade834a | 86 | TEST_ASSERT(size >= 128 && size <= 1023); |
va009039 | 9:fecabade834a | 87 | m_PacketSize = size; |
va009039 | 9:fecabade834a | 88 | m_FrameCount = 4; // 1-8 |
va009039 | 9:fecabade834a | 89 | TEST_ASSERT(m_FrameCount >= 1 && m_FrameCount <= 8); |
va009039 | 9:fecabade834a | 90 | m_itd_queue_count = 0; |
va009039 | 9:fecabade834a | 91 | reset(); |
va009039 | 9:fecabade834a | 92 | HCITD* itd = new_HCITD(this); |
va009039 | 9:fecabade834a | 93 | m_pED->TailTd = reinterpret_cast<HCTD*>(itd); |
va009039 | 9:fecabade834a | 94 | m_pED->HeadTd = reinterpret_cast<HCTD*>(itd); |
va009039 | 9:fecabade834a | 95 | TEST_ASSERT(itd); |
va009039 | 9:fecabade834a | 96 | if (itd == NULL) { |
va009039 | 9:fecabade834a | 97 | return; |
va009039 | 9:fecabade834a | 98 | } |
va009039 | 9:fecabade834a | 99 | _HCCA* hcca = reinterpret_cast<_HCCA*>(LPC_USB->HcHCCA); |
va009039 | 9:fecabade834a | 100 | TEST_ASSERT(hcca); |
va009039 | 9:fecabade834a | 101 | if (hcca == NULL) { |
va009039 | 9:fecabade834a | 102 | return; |
va009039 | 9:fecabade834a | 103 | } |
va009039 | 9:fecabade834a | 104 | for(int i = 0; i < 32; i++) { |
va009039 | 9:fecabade834a | 105 | if (hcca->InterruptTable[i] == NULL) { |
va009039 | 9:fecabade834a | 106 | hcca->InterruptTable[i] = m_pED; |
va009039 | 9:fecabade834a | 107 | } else { |
va009039 | 9:fecabade834a | 108 | _HCED* nextEd = hcca->InterruptTable[i]; |
va009039 | 9:fecabade834a | 109 | while(nextEd->Next && nextEd->Next != m_pED) { |
va009039 | 9:fecabade834a | 110 | nextEd = nextEd->Next; |
va009039 | 9:fecabade834a | 111 | } |
va009039 | 9:fecabade834a | 112 | nextEd->Next = m_pED; |
va009039 | 9:fecabade834a | 113 | } |
va009039 | 9:fecabade834a | 114 | } |
va009039 | 9:fecabade834a | 115 | //DBG_ED(m_pED); |
va009039 | 9:fecabade834a | 116 | } |
va009039 | 9:fecabade834a | 117 | |
va009039 | 9:fecabade834a | 118 | void IsochronousEp::reset(int delay_ms) |
va009039 | 9:fecabade834a | 119 | { |
va009039 | 9:fecabade834a | 120 | m_FrameNumber = LPC_USB->HcFmNumber + delay_ms; |
va009039 | 9:fecabade834a | 121 | } |
va009039 | 9:fecabade834a | 122 | |
va009039 | 9:fecabade834a | 123 | HCITD* IsochronousEp::new_HCITD(BaseEp* obj) |
va009039 | 9:fecabade834a | 124 | { |
va009039 | 9:fecabade834a | 125 | HCITD* itd = new(m_PacketSize*m_FrameCount)HCITD(obj, m_FrameNumber, m_FrameCount, m_PacketSize); |
va009039 | 9:fecabade834a | 126 | if (itd == NULL) { |
va009039 | 9:fecabade834a | 127 | return NULL; |
va009039 | 9:fecabade834a | 128 | } |
va009039 | 9:fecabade834a | 129 | m_FrameNumber += m_FrameCount; |
va009039 | 9:fecabade834a | 130 | return itd; |
va009039 | 9:fecabade834a | 131 | } |
va009039 | 9:fecabade834a | 132 | |
va009039 | 9:fecabade834a | 133 | HCITD* IsochronousEp::isochronousReveive(int millisec) |
va009039 | 9:fecabade834a | 134 | { |
va009039 | 9:fecabade834a | 135 | TEST_ASSERT(m_itd_queue_count >= 0); |
va009039 | 9:fecabade834a | 136 | while(m_itd_queue_count < 3 && m_itd_queue_count < HCTD_QUEUE_SIZE) { |
va009039 | 9:fecabade834a | 137 | HCITD* itd = reinterpret_cast<HCITD*>(m_pED->TailTd); |
va009039 | 9:fecabade834a | 138 | TEST_ASSERT(itd); |
va009039 | 9:fecabade834a | 139 | if (itd == NULL) { |
va009039 | 9:fecabade834a | 140 | return NULL; |
va009039 | 9:fecabade834a | 141 | } |
va009039 | 9:fecabade834a | 142 | HCITD* blank_itd = new_HCITD(this); |
va009039 | 9:fecabade834a | 143 | TEST_ASSERT(blank_itd); |
va009039 | 9:fecabade834a | 144 | if (blank_itd == NULL) { |
va009039 | 9:fecabade834a | 145 | return NULL; |
va009039 | 9:fecabade834a | 146 | } |
va009039 | 9:fecabade834a | 147 | itd->Next = blank_itd; |
va009039 | 9:fecabade834a | 148 | m_pED->TailTd = reinterpret_cast<HCTD*>(blank_itd); |
va009039 | 9:fecabade834a | 149 | m_itd_queue_count++; |
va009039 | 9:fecabade834a | 150 | //DBG_IED(m_pED); |
va009039 | 9:fecabade834a | 151 | enable(); // Enable Periodic |
va009039 | 9:fecabade834a | 152 | } |
va009039 | 9:fecabade834a | 153 | |
va009039 | 9:fecabade834a | 154 | HCITD* itd = get_queue_HCITD(millisec); |
va009039 | 9:fecabade834a | 155 | if (itd) { |
va009039 | 9:fecabade834a | 156 | m_itd_queue_count--; |
va009039 | 9:fecabade834a | 157 | } |
va009039 | 9:fecabade834a | 158 | return itd; |
va009039 | 9:fecabade834a | 159 | } |
va009039 | 9:fecabade834a | 160 | |
va009039 | 9:fecabade834a | 161 | HCITD* IsochronousEp::get_queue_HCITD(int millisec) |
va009039 | 9:fecabade834a | 162 | { |
va009039 | 9:fecabade834a | 163 | for(int i = 0; i < 16; i++) { |
va009039 | 9:fecabade834a | 164 | osEvent evt = m_queue.get(millisec); |
va009039 | 9:fecabade834a | 165 | if (evt.status == osEventMessage) { |
va009039 | 9:fecabade834a | 166 | HCITD* itd = reinterpret_cast<HCITD*>(evt.value.p); |
va009039 | 9:fecabade834a | 167 | TEST_ASSERT(itd); |
va009039 | 9:fecabade834a | 168 | return itd; |
va009039 | 9:fecabade834a | 169 | } else if (evt.status == osOK) { |
va009039 | 9:fecabade834a | 170 | continue; |
va009039 | 9:fecabade834a | 171 | } else if (evt.status == osEventTimeout) { |
va009039 | 9:fecabade834a | 172 | return NULL; |
va009039 | 9:fecabade834a | 173 | } else { |
va009039 | 9:fecabade834a | 174 | //DBG("evt.status: %02x\n", evt.status); |
va009039 | 9:fecabade834a | 175 | TEST_ASSERT(evt.status == osEventMessage); |
va009039 | 9:fecabade834a | 176 | return NULL; |
va009039 | 9:fecabade834a | 177 | } |
va009039 | 9:fecabade834a | 178 | } |
va009039 | 9:fecabade834a | 179 | return NULL; |
va009039 | 9:fecabade834a | 180 | } |
va009039 | 9:fecabade834a | 181 | |
va009039 | 9:fecabade834a | 182 | void IsochronousEp::enable() |
va009039 | 9:fecabade834a | 183 | { |
va009039 | 9:fecabade834a | 184 | LPC_USB->HcControl |= OR_CONTROL_PLE; |
va009039 | 9:fecabade834a | 185 | } |
va009039 | 9:fecabade834a | 186 | |
va009039 | 9:fecabade834a | 187 | BaseEp::BaseEp(int addr, uint8_t ep, uint16_t size, int lowSpeed):m_td_queue_count(0) |
va009039 | 9:fecabade834a | 188 | { |
va009039 | 9:fecabade834a | 189 | C270_DBG("%p FA=%d EN=%02x MPS=%d S=%d\n", this, addr, ep, size, lowSpeed); |
va009039 | 9:fecabade834a | 190 | TEST_ASSERT(size >= 8 && size <= 1023); |
va009039 | 9:fecabade834a | 191 | TEST_ASSERT(lowSpeed == 0 || lowSpeed == 1); |
va009039 | 9:fecabade834a | 192 | m_pED = new _HCED(addr, ep, size, lowSpeed); |
va009039 | 9:fecabade834a | 193 | TEST_ASSERT(m_pED); |
va009039 | 9:fecabade834a | 194 | } |
va009039 | 9:fecabade834a | 195 |