USB host library, support isochronous,bulk,interrupt and control.
Dependents: BaseUsbHost_example BaseJpegDecode_example SimpleJpegDecode_example
Import programBaseUsbHost_example
BaseUsbHost example program
BaseUsbHostCtlEp.cpp
- Committer:
- va009039
- Date:
- 2012-12-05
- Revision:
- 1:3b7bc4f87a61
- Parent:
- 0:b7d6879637a8
- Child:
- 3:ae77d63a1eda
File content as of revision 1:3b7bc4f87a61:
// BaseUsbHostCtlEp.cpp 2012/12/5 #include "mbed.h" #include "rtos.h" #include "BaseUsbHost.h" #define DEBUG #include "BaseUsbHostDebug.h" #define TEST #include "BaseUsbHostTest.h" static uint8_t device_addr = 1; ControlEp::ControlEp(int lowSpeed):BaseEp(0, 0, 8, lowSpeed) { TEST_ASSERT(HCTD_QUEUE_SIZE >= 3); HCTD* td = new_HCTD(); TEST_ASSERT(td); m_pED->TailTd = td; m_pED->HeadTd = td; m_pED->Next = LPC_USB->HcControlHeadED; LPC_USB->HcControlHeadED = reinterpret_cast<uint32_t>(m_pED); DBG_OHCI(LPC_USB->HcControlHeadED); DBG_ED(m_pED); int r = open(device_addr); if (r == USB_OK) { device_addr++; } } int ControlEp::SetAddress(int addr) { return controlSend(0x00, 5, addr); } int ControlEp::GetDescriptor(int descType, int descIndex, uint8_t* data, int length) { return controlReceive(0x80, 6, (descType<<8)|descIndex, 0, data, length); } int ControlEp::SetConfiguration(int config) { return controlSend(0x00, 9, config); } int ControlEp::GetConfiguration(int *config) { uint8_t buf[1]; int rc = controlReceive(0x80, 8, 0, 0, buf, 1); *config = buf[0]; return rc; } int ControlEp::SetInterfaceAlternate(int interface, int alternate) { int rc = controlSend(USB_HOST_TO_DEVICE | USB_RECIPIENT_INTERFACE, SET_INTERFACE, alternate, interface, NULL, 0); return rc; } int ControlEp::GetInterface(int interface, int *alternate) { uint8_t buf[1]; int rc = controlReceive(0x81, 10, 0, interface, buf, 1); *alternate = buf[0]; return rc; } int ControlEp::open(int addr) { TEST_ASSERT(addr >= 1 && addr <= 127); uint8_t buf[8]; int r = GetDescriptor(1, 0, buf, 8); TEST_ASSERT(r == USB_OK); if (r != USB_OK) { return r; } TEST_ASSERT(buf[0] == 0x12); TEST_ASSERT(buf[1] == 0x01); TEST_ASSERT(buf[7] >= 8); update_MaxPacketSize(buf[7]); r = SetAddress(addr); TEST_ASSERT(r == USB_OK); if (r != USB_OK) { return r; } wait_ms(2); update_FunctionAddress(addr); return USB_OK; } int ControlEp::controlReceive(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t* data, int length) { DBG("Type: %02X Request: %02X Value: %04X Index: %04X %p %d\n", bmRequestType, bRequest, wValue, wIndex, data, length); HCTD* setup_td = m_pED->TailTd; setup(setup_td, bmRequestType, bRequest, wValue, wIndex, length); setup_td->Control |= TD_DI; HCTD* data_td = new_HCTD(length); TEST_ASSERT(data_td); data_td->Control |= TD_TOGGLE_1|TD_IN|TD_DI; //data_td->Control |= TD_IN|TD_DI; setup_td->Next = reinterpret_cast<uint32_t>(data_td); HCTD* status_td = new_HCTD(); TEST_ASSERT(status_td); status_td->Control |= TD_TOGGLE_1|TD_OUT; // OUT(DATA1) data_td->Next = reinterpret_cast<uint32_t>(status_td); HCTD* blank_td = new_HCTD(); TEST_ASSERT(blank_td); status_td->Next = reinterpret_cast<uint32_t>(blank_td); m_pED->TailTd = blank_td; LPC_USB->HcCommandStatus |= OR_CMD_STATUS_CLF; LPC_USB->HcControl |= OR_CONTROL_CLE; int r = wait_queue_HCTD(setup_td, 100); // wait setup stage TEST_ASSERT(r == USB_OK); HCTD* td = get_queue_HCTD(100); if (td == data_td) { memcpy(data, const_cast<uint8_t*>(td->buf), length); delete_HCTD(td); } else { DBG_TD(td); TEST_ASSERT(td == data_td); return USB_ERROR; } r = wait_queue_HCTD(status_td, 100); // wait status stage TEST_ASSERT(r == USB_OK); return r; } int ControlEp::controlSend(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, const uint8_t* data, int length) { DBG("Type: %02X Request: %02X Value: %04X Index: %04X %p %d\n", bmRequestType, bRequest, wValue, wIndex, data, length); HCTD* setup_td = m_pED->TailTd; setup(setup_td, bmRequestType, bRequest, wValue, wIndex, length); HCTD* status_td = new_HCTD(); TEST_ASSERT(status_td); HCTD* blank_td = new_HCTD(); TEST_ASSERT(blank_td); setup_td->Control |= TD_DI; status_td->Control |= TD_TOGGLE_1|TD_IN; // IN(DATA1) setup_td->Next = reinterpret_cast<uint32_t>(status_td); status_td->Next = reinterpret_cast<uint32_t>(blank_td); if (length != 0) { HCTD* data_td = new_HCTD(length); TEST_ASSERT(data_td); data_td->Control |= TD_TOGGLE_1|TD_OUT|TD_DI; memcpy(const_cast<uint8_t*>(data_td->buf), data, length); setup_td->Next = reinterpret_cast<uint32_t>(data_td); data_td->Next = reinterpret_cast<uint32_t>(status_td); } m_pED->TailTd = blank_td; DBG_ED(m_pED); LPC_USB->HcCommandStatus |= OR_CMD_STATUS_CLF; LPC_USB->HcControl |= OR_CONTROL_CLE; int r = wait_queue_HCTD(status_td, 200); // wait status stage TEST_ASSERT(r == USB_OK); return r; } void ControlEp::setup(HCTD* td, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength) { td->setup[0] = bmRequestType; td->setup[1] = bRequest; td->setup[2] = wValue; td->setup[3] = wValue>>8; td->setup[4] = wIndex; td->setup[5] = wIndex>>8; td->setup[6] = wLength; td->setup[7] = wLength>>8; td->Control |= TD_TOGGLE_0|TD_SETUP; td->CurrBufPtr = td->setup; td->BufEnd = td->setup+8-1; }