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:
Wed Dec 05 13:23:06 2012 +0000
Revision:
1:3b7bc4f87a61
Parent:
0:b7d6879637a8
Child:
3:ae77d63a1eda
add uvc class

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 1:3b7bc4f87a61 1 // BaseUsbHostCtlEp.cpp 2012/12/5
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 static uint8_t device_addr = 1;
va009039 0:b7d6879637a8 11 ControlEp::ControlEp(int lowSpeed):BaseEp(0, 0, 8, lowSpeed)
va009039 0:b7d6879637a8 12 {
va009039 0:b7d6879637a8 13 TEST_ASSERT(HCTD_QUEUE_SIZE >= 3);
va009039 0:b7d6879637a8 14 HCTD* td = new_HCTD();
va009039 0:b7d6879637a8 15 TEST_ASSERT(td);
va009039 0:b7d6879637a8 16 m_pED->TailTd = td;
va009039 0:b7d6879637a8 17 m_pED->HeadTd = td;
va009039 0:b7d6879637a8 18
va009039 0:b7d6879637a8 19 m_pED->Next = LPC_USB->HcControlHeadED;
va009039 0:b7d6879637a8 20 LPC_USB->HcControlHeadED = reinterpret_cast<uint32_t>(m_pED);
va009039 0:b7d6879637a8 21
va009039 0:b7d6879637a8 22 DBG_OHCI(LPC_USB->HcControlHeadED);
va009039 0:b7d6879637a8 23 DBG_ED(m_pED);
va009039 0:b7d6879637a8 24
va009039 0:b7d6879637a8 25 int r = open(device_addr);
va009039 0:b7d6879637a8 26 if (r == USB_OK) {
va009039 0:b7d6879637a8 27 device_addr++;
va009039 0:b7d6879637a8 28 }
va009039 0:b7d6879637a8 29 }
va009039 0:b7d6879637a8 30
va009039 0:b7d6879637a8 31 int ControlEp::SetAddress(int addr)
va009039 0:b7d6879637a8 32 {
va009039 0:b7d6879637a8 33 return controlSend(0x00, 5, addr);
va009039 0:b7d6879637a8 34 }
va009039 0:b7d6879637a8 35
va009039 0:b7d6879637a8 36 int ControlEp::GetDescriptor(int descType, int descIndex, uint8_t* data, int length)
va009039 0:b7d6879637a8 37 {
va009039 0:b7d6879637a8 38 return controlReceive(0x80, 6, (descType<<8)|descIndex, 0, data, length);
va009039 0:b7d6879637a8 39 }
va009039 0:b7d6879637a8 40
va009039 0:b7d6879637a8 41 int ControlEp::SetConfiguration(int config)
va009039 0:b7d6879637a8 42 {
va009039 0:b7d6879637a8 43 return controlSend(0x00, 9, config);
va009039 0:b7d6879637a8 44 }
va009039 0:b7d6879637a8 45
va009039 0:b7d6879637a8 46 int ControlEp::GetConfiguration(int *config)
va009039 0:b7d6879637a8 47 {
va009039 0:b7d6879637a8 48 uint8_t buf[1];
va009039 0:b7d6879637a8 49 int rc = controlReceive(0x80, 8, 0, 0, buf, 1);
va009039 0:b7d6879637a8 50 *config = buf[0];
va009039 0:b7d6879637a8 51 return rc;
va009039 0:b7d6879637a8 52 }
va009039 0:b7d6879637a8 53
va009039 0:b7d6879637a8 54 int ControlEp::SetInterfaceAlternate(int interface, int alternate)
va009039 0:b7d6879637a8 55 {
va009039 0:b7d6879637a8 56 int rc = controlSend(USB_HOST_TO_DEVICE | USB_RECIPIENT_INTERFACE,
va009039 0:b7d6879637a8 57 SET_INTERFACE, alternate, interface, NULL, 0);
va009039 0:b7d6879637a8 58 return rc;
va009039 0:b7d6879637a8 59 }
va009039 0:b7d6879637a8 60
va009039 0:b7d6879637a8 61 int ControlEp::GetInterface(int interface, int *alternate)
va009039 0:b7d6879637a8 62 {
va009039 0:b7d6879637a8 63 uint8_t buf[1];
va009039 0:b7d6879637a8 64 int rc = controlReceive(0x81, 10, 0, interface, buf, 1);
va009039 0:b7d6879637a8 65 *alternate = buf[0];
va009039 0:b7d6879637a8 66 return rc;
va009039 0:b7d6879637a8 67 }
va009039 0:b7d6879637a8 68
va009039 0:b7d6879637a8 69 int ControlEp::open(int addr)
va009039 0:b7d6879637a8 70 {
va009039 0:b7d6879637a8 71 TEST_ASSERT(addr >= 1 && addr <= 127);
va009039 0:b7d6879637a8 72 uint8_t buf[8];
va009039 0:b7d6879637a8 73 int r = GetDescriptor(1, 0, buf, 8);
va009039 0:b7d6879637a8 74 TEST_ASSERT(r == USB_OK);
va009039 0:b7d6879637a8 75 if (r != USB_OK) {
va009039 0:b7d6879637a8 76 return r;
va009039 0:b7d6879637a8 77 }
va009039 0:b7d6879637a8 78 TEST_ASSERT(buf[0] == 0x12);
va009039 0:b7d6879637a8 79 TEST_ASSERT(buf[1] == 0x01);
va009039 0:b7d6879637a8 80 TEST_ASSERT(buf[7] >= 8);
va009039 0:b7d6879637a8 81 update_MaxPacketSize(buf[7]);
va009039 0:b7d6879637a8 82 r = SetAddress(addr);
va009039 0:b7d6879637a8 83 TEST_ASSERT(r == USB_OK);
va009039 0:b7d6879637a8 84 if (r != USB_OK) {
va009039 0:b7d6879637a8 85 return r;
va009039 0:b7d6879637a8 86 }
va009039 0:b7d6879637a8 87 wait_ms(2);
va009039 0:b7d6879637a8 88 update_FunctionAddress(addr);
va009039 0:b7d6879637a8 89 return USB_OK;
va009039 0:b7d6879637a8 90 }
va009039 0:b7d6879637a8 91
va009039 0:b7d6879637a8 92 int ControlEp::controlReceive(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
va009039 0:b7d6879637a8 93 uint8_t* data, int length) {
va009039 0:b7d6879637a8 94 DBG("Type: %02X Request: %02X Value: %04X Index: %04X %p %d\n", bmRequestType, bRequest, wValue, wIndex, data, length);
va009039 0:b7d6879637a8 95 HCTD* setup_td = m_pED->TailTd;
va009039 0:b7d6879637a8 96 setup(setup_td, bmRequestType, bRequest, wValue, wIndex, length);
va009039 0:b7d6879637a8 97 setup_td->Control |= TD_DI;
va009039 0:b7d6879637a8 98
va009039 0:b7d6879637a8 99 HCTD* data_td = new_HCTD(length);
va009039 0:b7d6879637a8 100 TEST_ASSERT(data_td);
va009039 0:b7d6879637a8 101 data_td->Control |= TD_TOGGLE_1|TD_IN|TD_DI;
va009039 0:b7d6879637a8 102 //data_td->Control |= TD_IN|TD_DI;
va009039 0:b7d6879637a8 103 setup_td->Next = reinterpret_cast<uint32_t>(data_td);
va009039 0:b7d6879637a8 104
va009039 0:b7d6879637a8 105 HCTD* status_td = new_HCTD();
va009039 0:b7d6879637a8 106 TEST_ASSERT(status_td);
va009039 0:b7d6879637a8 107 status_td->Control |= TD_TOGGLE_1|TD_OUT; // OUT(DATA1)
va009039 0:b7d6879637a8 108 data_td->Next = reinterpret_cast<uint32_t>(status_td);
va009039 0:b7d6879637a8 109
va009039 0:b7d6879637a8 110 HCTD* blank_td = new_HCTD();
va009039 0:b7d6879637a8 111 TEST_ASSERT(blank_td);
va009039 0:b7d6879637a8 112 status_td->Next = reinterpret_cast<uint32_t>(blank_td);
va009039 0:b7d6879637a8 113 m_pED->TailTd = blank_td;
va009039 0:b7d6879637a8 114
va009039 0:b7d6879637a8 115 LPC_USB->HcCommandStatus |= OR_CMD_STATUS_CLF;
va009039 0:b7d6879637a8 116 LPC_USB->HcControl |= OR_CONTROL_CLE;
va009039 0:b7d6879637a8 117
va009039 0:b7d6879637a8 118 int r = wait_queue_HCTD(setup_td, 100); // wait setup stage
va009039 0:b7d6879637a8 119 TEST_ASSERT(r == USB_OK);
va009039 0:b7d6879637a8 120 HCTD* td = get_queue_HCTD(100);
va009039 0:b7d6879637a8 121 if (td == data_td) {
va009039 0:b7d6879637a8 122 memcpy(data, const_cast<uint8_t*>(td->buf), length);
va009039 0:b7d6879637a8 123 delete_HCTD(td);
va009039 0:b7d6879637a8 124 } else {
va009039 0:b7d6879637a8 125 DBG_TD(td);
va009039 0:b7d6879637a8 126 TEST_ASSERT(td == data_td);
va009039 0:b7d6879637a8 127 return USB_ERROR;
va009039 0:b7d6879637a8 128 }
va009039 0:b7d6879637a8 129 r = wait_queue_HCTD(status_td, 100); // wait status stage
va009039 0:b7d6879637a8 130 TEST_ASSERT(r == USB_OK);
va009039 0:b7d6879637a8 131 return r;
va009039 0:b7d6879637a8 132 }
va009039 0:b7d6879637a8 133
va009039 0:b7d6879637a8 134 int ControlEp::controlSend(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
va009039 0:b7d6879637a8 135 const uint8_t* data, int length) {
va009039 0:b7d6879637a8 136 DBG("Type: %02X Request: %02X Value: %04X Index: %04X %p %d\n", bmRequestType, bRequest, wValue, wIndex, data, length);
va009039 0:b7d6879637a8 137 HCTD* setup_td = m_pED->TailTd;
va009039 0:b7d6879637a8 138 setup(setup_td, bmRequestType, bRequest, wValue, wIndex, length);
va009039 0:b7d6879637a8 139
va009039 0:b7d6879637a8 140 HCTD* status_td = new_HCTD();
va009039 0:b7d6879637a8 141 TEST_ASSERT(status_td);
va009039 0:b7d6879637a8 142 HCTD* blank_td = new_HCTD();
va009039 0:b7d6879637a8 143 TEST_ASSERT(blank_td);
va009039 0:b7d6879637a8 144 setup_td->Control |= TD_DI;
va009039 0:b7d6879637a8 145 status_td->Control |= TD_TOGGLE_1|TD_IN; // IN(DATA1)
va009039 0:b7d6879637a8 146 setup_td->Next = reinterpret_cast<uint32_t>(status_td);
va009039 0:b7d6879637a8 147 status_td->Next = reinterpret_cast<uint32_t>(blank_td);
va009039 0:b7d6879637a8 148
va009039 0:b7d6879637a8 149 if (length != 0) {
va009039 0:b7d6879637a8 150 HCTD* data_td = new_HCTD(length);
va009039 0:b7d6879637a8 151 TEST_ASSERT(data_td);
va009039 0:b7d6879637a8 152 data_td->Control |= TD_TOGGLE_1|TD_OUT|TD_DI;
va009039 0:b7d6879637a8 153 memcpy(const_cast<uint8_t*>(data_td->buf), data, length);
va009039 0:b7d6879637a8 154 setup_td->Next = reinterpret_cast<uint32_t>(data_td);
va009039 0:b7d6879637a8 155 data_td->Next = reinterpret_cast<uint32_t>(status_td);
va009039 0:b7d6879637a8 156 }
va009039 0:b7d6879637a8 157 m_pED->TailTd = blank_td;
va009039 0:b7d6879637a8 158 DBG_ED(m_pED);
va009039 0:b7d6879637a8 159
va009039 0:b7d6879637a8 160 LPC_USB->HcCommandStatus |= OR_CMD_STATUS_CLF;
va009039 0:b7d6879637a8 161 LPC_USB->HcControl |= OR_CONTROL_CLE;
va009039 0:b7d6879637a8 162
va009039 0:b7d6879637a8 163 int r = wait_queue_HCTD(status_td, 200); // wait status stage
va009039 0:b7d6879637a8 164 TEST_ASSERT(r == USB_OK);
va009039 0:b7d6879637a8 165 return r;
va009039 0:b7d6879637a8 166 }
va009039 0:b7d6879637a8 167
va009039 0:b7d6879637a8 168 void ControlEp::setup(HCTD* td, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue,
va009039 0:b7d6879637a8 169 uint16_t wIndex, uint16_t wLength)
va009039 0:b7d6879637a8 170 {
va009039 0:b7d6879637a8 171 td->setup[0] = bmRequestType;
va009039 0:b7d6879637a8 172 td->setup[1] = bRequest;
va009039 0:b7d6879637a8 173 td->setup[2] = wValue;
va009039 0:b7d6879637a8 174 td->setup[3] = wValue>>8;
va009039 0:b7d6879637a8 175 td->setup[4] = wIndex;
va009039 0:b7d6879637a8 176 td->setup[5] = wIndex>>8;
va009039 0:b7d6879637a8 177 td->setup[6] = wLength;
va009039 0:b7d6879637a8 178 td->setup[7] = wLength>>8;
va009039 0:b7d6879637a8 179 td->Control |= TD_TOGGLE_0|TD_SETUP;
va009039 0:b7d6879637a8 180 td->CurrBufPtr = td->setup;
va009039 0:b7d6879637a8 181 td->BufEnd = td->setup+8-1;
va009039 0:b7d6879637a8 182 }
va009039 0:b7d6879637a8 183