USB host library, support isochronous,bulk,interrupt and control.

Dependents:   BaseUsbHost_example BaseJpegDecode_example SimpleJpegDecode_example

Import programBaseUsbHost_example

BaseUsbHost example program

Committer:
va009039
Date:
Tue Dec 04 13:29:41 2012 +0000
Revision:
0:b7d6879637a8
Child:
1:3b7bc4f87a61
first commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 0:b7d6879637a8 1 // BaseUsbHostIsoEp.cpp 2012/12/4
va009039 0:b7d6879637a8 2 #include "mbed.h"
va009039 0:b7d6879637a8 3 #include "rtos.h"
va009039 0:b7d6879637a8 4 #include "BaseUsbHost.h"
va009039 0:b7d6879637a8 5 #define DEBUG
va009039 0:b7d6879637a8 6 #include "BaseUsbHostDebug.h"
va009039 0:b7d6879637a8 7 #define TEST
va009039 0:b7d6879637a8 8 #include "BaseUsbHostTest.h"
va009039 0:b7d6879637a8 9
va009039 0:b7d6879637a8 10 IsochronousEp::IsochronousEp(int addr, uint8_t ep, uint16_t size):BaseEp(addr, ep, size)
va009039 0:b7d6879637a8 11 {
va009039 0:b7d6879637a8 12 DBG("%p FA:%d EP:%02X MPS:%d\n", this, addr, ep, size);
va009039 0:b7d6879637a8 13 TEST_ASSERT(m_pED);
va009039 0:b7d6879637a8 14
va009039 0:b7d6879637a8 15 m_pED->Control |= (1 << 15); // F Format ITD
va009039 0:b7d6879637a8 16
va009039 0:b7d6879637a8 17 TEST_ASSERT(size >= 128 && size <= 1023);
va009039 0:b7d6879637a8 18 m_PacketSize = size;
va009039 0:b7d6879637a8 19 m_FrameCount = 8;
va009039 0:b7d6879637a8 20 m_itd_queue_count = 0;
va009039 0:b7d6879637a8 21 reset();
va009039 0:b7d6879637a8 22 HCITD* itd = new_HCITD();
va009039 0:b7d6879637a8 23 TEST_ASSERT(itd);
va009039 0:b7d6879637a8 24 m_pED->TailTd = reinterpret_cast<HCTD*>(itd);
va009039 0:b7d6879637a8 25 m_pED->HeadTd = reinterpret_cast<HCTD*>(itd);
va009039 0:b7d6879637a8 26
va009039 0:b7d6879637a8 27 HCCA* hcca = reinterpret_cast<HCCA*>(LPC_USB->HcHCCA);
va009039 0:b7d6879637a8 28 TEST_ASSERT(hcca);
va009039 0:b7d6879637a8 29 for(int i = 0; i < 32; i++) {
va009039 0:b7d6879637a8 30 if (hcca->InterruptTable[i] == 0) {
va009039 0:b7d6879637a8 31 hcca->InterruptTable[i] = reinterpret_cast<uint32_t>(m_pED);
va009039 0:b7d6879637a8 32 } else {
va009039 0:b7d6879637a8 33 HCED* nextEd = reinterpret_cast<HCED*>(hcca->InterruptTable[i]);
va009039 0:b7d6879637a8 34 while(nextEd->Next && nextEd->Next != reinterpret_cast<uint32_t>(m_pED)) {
va009039 0:b7d6879637a8 35 nextEd = reinterpret_cast<HCED*>(nextEd->Next);
va009039 0:b7d6879637a8 36 }
va009039 0:b7d6879637a8 37 nextEd->Next = reinterpret_cast<uint32_t>(m_pED);
va009039 0:b7d6879637a8 38 }
va009039 0:b7d6879637a8 39 }
va009039 0:b7d6879637a8 40 DBG_ED(m_pED);
va009039 0:b7d6879637a8 41 }
va009039 0:b7d6879637a8 42
va009039 0:b7d6879637a8 43 void IsochronousEp::reset()
va009039 0:b7d6879637a8 44 {
va009039 0:b7d6879637a8 45 m_FrameNumber = LPC_USB->HcFmNumber + 100; // 100msec
va009039 0:b7d6879637a8 46 }
va009039 0:b7d6879637a8 47
va009039 0:b7d6879637a8 48 void IsochronousEp::irqWdhHandler(HCTD* td)
va009039 0:b7d6879637a8 49 {
va009039 0:b7d6879637a8 50 osStatus st = m_queue.put(td);
va009039 0:b7d6879637a8 51 if (st != osOK) {
va009039 0:b7d6879637a8 52 //led4_error = 1;
va009039 0:b7d6879637a8 53 }
va009039 0:b7d6879637a8 54 //led2 = !led2;
va009039 0:b7d6879637a8 55 }
va009039 0:b7d6879637a8 56
va009039 0:b7d6879637a8 57 HCITD* IsochronousEp::new_HCITD()
va009039 0:b7d6879637a8 58 {
va009039 0:b7d6879637a8 59 HCITD* itd;
va009039 0:b7d6879637a8 60 int r = posix_memalign(reinterpret_cast<void**>(&itd), 32, sizeof(HCITD)+m_PacketSize*m_FrameCount);
va009039 0:b7d6879637a8 61 if (r != 0) {
va009039 0:b7d6879637a8 62 return NULL;
va009039 0:b7d6879637a8 63 }
va009039 0:b7d6879637a8 64 int di = 0; //DelayInterrupt
va009039 0:b7d6879637a8 65 itd->Control = 0xe0000000 | // CC ConditionCode NOT ACCESSED
va009039 0:b7d6879637a8 66 ((m_FrameCount-1) << 24)| // FC FrameCount
va009039 0:b7d6879637a8 67 TD_DELAY_INT(di) | // DI DelayInterrupt
va009039 0:b7d6879637a8 68 m_FrameNumber; // SF StartingFrame
va009039 0:b7d6879637a8 69 itd->BufferPage0 = const_cast<uint8_t*>(itd->buf);
va009039 0:b7d6879637a8 70 itd->BufferEnd = const_cast<uint8_t*>(itd->buf) + m_PacketSize * m_FrameCount - 1;
va009039 0:b7d6879637a8 71 itd->Next = NULL;
va009039 0:b7d6879637a8 72 itd->ep = this;
va009039 0:b7d6879637a8 73 uint32_t addr = reinterpret_cast<uint32_t>(itd->buf);
va009039 0:b7d6879637a8 74 for(int i = 0; i < m_FrameCount; i++) {
va009039 0:b7d6879637a8 75 uint16_t offset = addr & 0x0fff;
va009039 0:b7d6879637a8 76 if ((addr&0xfffff000) == (reinterpret_cast<uint32_t>(itd->BufferEnd)&0xfffff000)) {
va009039 0:b7d6879637a8 77 offset |= 0x1000;
va009039 0:b7d6879637a8 78 }
va009039 0:b7d6879637a8 79 itd->OffsetPSW[i] = 0xe000|offset;
va009039 0:b7d6879637a8 80 addr += m_PacketSize;
va009039 0:b7d6879637a8 81 }
va009039 0:b7d6879637a8 82 m_FrameNumber += m_FrameCount;
va009039 0:b7d6879637a8 83 return itd;
va009039 0:b7d6879637a8 84 }
va009039 0:b7d6879637a8 85
va009039 0:b7d6879637a8 86
va009039 0:b7d6879637a8 87 HCITD* IsochronousEp::read()
va009039 0:b7d6879637a8 88 {
va009039 0:b7d6879637a8 89 TEST_ASSERT(m_itd_queue_count >= 0);
va009039 0:b7d6879637a8 90 while(m_itd_queue_count < HCTD_QUEUE_SIZE) {
va009039 0:b7d6879637a8 91 HCITD* itd = reinterpret_cast<HCITD*>(m_pED->TailTd);
va009039 0:b7d6879637a8 92 TEST_ASSERT(itd);
va009039 0:b7d6879637a8 93 //DBG_ITD(itd);
va009039 0:b7d6879637a8 94 HCITD* blank_itd = new_HCITD();
va009039 0:b7d6879637a8 95 TEST_ASSERT(blank_itd);
va009039 0:b7d6879637a8 96 itd->Next = reinterpret_cast<uint32_t>(blank_itd);
va009039 0:b7d6879637a8 97 m_pED->TailTd = reinterpret_cast<HCTD*>(blank_itd);
va009039 0:b7d6879637a8 98 m_itd_queue_count++;
va009039 0:b7d6879637a8 99 //DBG_IED(m_pED);
va009039 0:b7d6879637a8 100 LPC_USB->HcControl |= OR_CONTROL_PLE; // Enable Periodic
va009039 0:b7d6879637a8 101 }
va009039 0:b7d6879637a8 102
va009039 0:b7d6879637a8 103 HCITD* itd = get_queue_HCITD(1);
va009039 0:b7d6879637a8 104 if (itd) {
va009039 0:b7d6879637a8 105 m_itd_queue_count--;
va009039 0:b7d6879637a8 106 }
va009039 0:b7d6879637a8 107 return itd;
va009039 0:b7d6879637a8 108 }
va009039 0:b7d6879637a8 109
va009039 0:b7d6879637a8 110 HCITD* IsochronousEp::get_queue_HCITD(uint32_t millisec)
va009039 0:b7d6879637a8 111 {
va009039 0:b7d6879637a8 112 for(int i = 0; i < 16; i++) {
va009039 0:b7d6879637a8 113 osEvent evt = m_queue.get(millisec);
va009039 0:b7d6879637a8 114 if (evt.status == osEventMessage) {
va009039 0:b7d6879637a8 115 HCITD* itd = reinterpret_cast<HCITD*>(evt.value.p);
va009039 0:b7d6879637a8 116 TEST_ASSERT(itd);
va009039 0:b7d6879637a8 117 //led3 = !led3;
va009039 0:b7d6879637a8 118 uint8_t cc = itd->Control>>28;
va009039 0:b7d6879637a8 119 if (cc != 0) {
va009039 0:b7d6879637a8 120 m_ConditionCode = cc;
va009039 0:b7d6879637a8 121 }
va009039 0:b7d6879637a8 122 return itd;
va009039 0:b7d6879637a8 123 } else if (evt.status == osOK) {
va009039 0:b7d6879637a8 124 continue;
va009039 0:b7d6879637a8 125 } else if (evt.status == osEventTimeout) {
va009039 0:b7d6879637a8 126 return NULL;
va009039 0:b7d6879637a8 127 } else {
va009039 0:b7d6879637a8 128 DBG("evt.status: %02x\n", evt.status);
va009039 0:b7d6879637a8 129 TEST_ASSERT(evt.status == osEventMessage);
va009039 0:b7d6879637a8 130 }
va009039 0:b7d6879637a8 131 }
va009039 0:b7d6879637a8 132 return NULL;
va009039 0:b7d6879637a8 133 }
va009039 0:b7d6879637a8 134