Simple USBHost MSD(USB flash drive) for EA LPC4088 QSB test program
Dependencies: LPC4088-USBHost mbed
EA LPC4088をUSBホストにしてUSBフラッシュメモリ(USB flash drive)を読み書きするテストプログラムです。
https://bitbucket.org/va009039/lpc4088_usbhost
Revision 1:26a4baad1736, committed 2014-04-25
- Comitter:
- va009039
- Date:
- Fri Apr 25 05:48:06 2014 +0000
- Parent:
- 0:11152e69fc05
- Commit message:
- update LPC4088-USBHost library
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LPC4088-USBHost.lib Fri Apr 25 05:48:06 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/va009039/code/LPC4088-USBHost/#148fca6fd246
--- a/LPC4088-USBHost/FATFileSystem.lib Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/mbed_official/code/FATFileSystem/#b6669c987c8e
--- a/LPC4088-USBHost/USBHost/BaseUsbHost.cpp Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,301 +0,0 @@ -/* mbed USBHost Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "USBHost.h" -#define USB_DEBUG -#include "BaseUsbHostDebug.h" -#define TEST -#include "BaseUsbHostTest.h" - -USBHost* USBHost::inst = NULL; - -USBHost* USBHost::getHostInst() { - if (inst == NULL) { - inst = new USBHost(); - inst->init(); - } - return inst; -} - -void USBHost::poll() -{ - if (inst) { - inst->task(); - } -} - -USBHost::USBHost() { -} - -/* virtual */ bool USBHost::addDevice(USBDeviceConnected* parent, int port, bool lowSpeed) { - USBDeviceConnected* dev = new USBDeviceConnected; - USBEndpoint* ep = new USBEndpoint(dev); - dev->init(0, port, lowSpeed); - dev->setAddress(0); - dev->setEpCtl(ep); - uint8_t desc[18]; - wait_ms(100); - - int rc = controlRead(dev, 0x80, GET_DESCRIPTOR, 1<<8, 0, desc, 8); - USB_TEST_ASSERT(rc == USB_TYPE_OK); - if (rc != USB_TYPE_OK) { - USB_ERR("ADD DEVICE FAILD"); - } - USB_DBG_HEX(desc, 8); - DeviceDescriptor* dev_desc = reinterpret_cast<DeviceDescriptor*>(desc); - ep->setSize(dev_desc->bMaxPacketSize); - - int new_addr = USBDeviceConnected::getNewAddress(); - rc = controlWrite(dev, 0x00, SET_ADDRESS, new_addr, 0, NULL, 0); - USB_TEST_ASSERT(rc == USB_TYPE_OK); - dev->setAddress(new_addr); - wait_ms(100); - - rc = controlRead(dev, 0x80, GET_DESCRIPTOR, 1<<8, 0, desc, sizeof(desc)); - USB_TEST_ASSERT(rc == USB_TYPE_OK); - USB_DBG_HEX(desc, sizeof(desc)); - - dev->setVid(dev_desc->idVendor); - dev->setPid(dev_desc->idProduct); - dev->setClass(dev_desc->bDeviceClass); - USB_INFO("parent:%p port:%d speed:%s VID:%04x PID:%04x class:%02x addr:%d", - parent, port, (lowSpeed ? "low " : "full"), dev->getVid(), dev->getPid(), dev->getClass(), - dev->getAddress()); - - DeviceLists.push_back(dev); - - if (dev->getClass() == HUB_CLASS) { - const int config = 1; - int rc = controlWrite(dev, 0x00, SET_CONFIGURATION, config, 0, NULL, 0); - USB_TEST_ASSERT(rc == USB_TYPE_OK); - wait_ms(100); - Hub(dev); - } - return true; -} - -// enumerate a device with the control USBEndpoint -USB_TYPE USBHost::enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerator) -{ - if (dev->getClass() == HUB_CLASS) { // skip hub class - return USB_TYPE_OK; - } - uint8_t desc[18]; - USB_TYPE rc = controlRead(dev, 0x80, GET_DESCRIPTOR, 1<<8, 0, desc, sizeof(desc)); - USB_TEST_ASSERT(rc == USB_TYPE_OK); - USB_DBG_HEX(desc, sizeof(desc)); - if (rc != USB_TYPE_OK) { - return rc; - } - DeviceDescriptor* dev_desc = reinterpret_cast<DeviceDescriptor*>(desc); - dev->setClass(dev_desc->bDeviceClass); - pEnumerator->setVidPid(dev->getVid(), dev->getPid()); - - rc = controlRead(dev, 0x80, GET_DESCRIPTOR, 2<<8, 0, desc, 4); - USB_TEST_ASSERT(rc == USB_TYPE_OK); - USB_DBG_HEX(desc, 4); - - int TotalLength = desc[2]|desc[3]<<8; - uint8_t* buf = new uint8_t[TotalLength]; - rc = controlRead(dev, 0x80, GET_DESCRIPTOR, 2<<8, 0, buf, TotalLength); - USB_TEST_ASSERT(rc == USB_TYPE_OK); - //USB_DBG_HEX(buf, TotalLength); - - // Parse the configuration descriptor - parseConfDescr(dev, buf, TotalLength, pEnumerator); - delete[] buf; - // only set configuration if not enumerated before - if (!dev->isEnumerated()) { - USB_DBG("Set configuration 1 on dev: %p", dev); - // sixth step: set configuration (only 1 supported) - int config = 1; - USB_TYPE res = controlWrite(dev, 0x00, SET_CONFIGURATION, config, 0, NULL, 0); - if (res != USB_TYPE_OK) { - USB_ERR("SET CONF FAILED"); - return res; - } - // Some devices may require this delay - wait_ms(100); - dev->setEnumerated(); - // Now the device is enumerated! - USB_DBG("dev %p is enumerated", dev); - } - return USB_TYPE_OK; -} - -// this method fills the USBDeviceConnected object: class,.... . It also add endpoints found in the descriptor. -void USBHost::parseConfDescr(USBDeviceConnected * dev, uint8_t * conf_descr, uint32_t len, IUSBEnumerator* pEnumerator) -{ - uint32_t index = 0; - uint32_t len_desc = 0; - uint8_t id = 0; - USBEndpoint * ep = NULL; - uint8_t intf_nb = 0; - bool parsing_intf = false; - uint8_t current_intf = 0; - EndpointDescriptor* ep_desc; - - while (index < len) { - len_desc = conf_descr[index]; - id = conf_descr[index+1]; - USB_DBG_HEX(conf_descr+index, len_desc); - switch (id) { - case CONFIGURATION_DESCRIPTOR: - USB_DBG("dev: %p has %d intf", dev, conf_descr[4]); - dev->setNbIntf(conf_descr[4]); - break; - case INTERFACE_DESCRIPTOR: - if(pEnumerator->parseInterface(conf_descr[index + 2], conf_descr[index + 5], conf_descr[index + 6], conf_descr[index + 7])) { - intf_nb++; - current_intf = conf_descr[index + 2]; - dev->addInterface(current_intf, conf_descr[index + 5], conf_descr[index + 6], conf_descr[index + 7]); - USB_DBG("ADD INTF %d on device %p: class: %d, subclass: %d, proto: %d", current_intf, dev, conf_descr[index + 5],conf_descr[index + 6],conf_descr[index + 7]); - parsing_intf = true; - } else { - parsing_intf = false; - } - break; - case ENDPOINT_DESCRIPTOR: - ep_desc = reinterpret_cast<EndpointDescriptor*>(conf_descr+index); - if (parsing_intf && (intf_nb <= MAX_INTF) ) { - ENDPOINT_TYPE type = (ENDPOINT_TYPE)(ep_desc->bmAttributes & 0x03); - ENDPOINT_DIRECTION dir = (ep_desc->bEndpointAddress & 0x80) ? IN : OUT; - if(pEnumerator->useEndpoint(current_intf, type, dir)) { - ep = new USBEndpoint(dev); - ep->init(type, dir, ep_desc->wMaxPacketSize, ep_desc->bEndpointAddress); - USB_DBG("ADD USBEndpoint %p, on interf %d on device %p", ep, current_intf, dev); - dev->addEndpoint(current_intf, ep); - } - } - break; - case HID_DESCRIPTOR: - //lenReportDescr = conf_descr[index + 7] | (conf_descr[index + 8] << 8); - break; - default: - break; - } - index += len_desc; - } -} - -USB_TYPE USBHost::controlRead(USBDeviceConnected* dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len) { - USBEndpoint* ep = dev->getEpCtl(); - return controlRead(ep, requestType, request, value, index, buf, len); -} - -USB_TYPE USBHost::controlWrite(USBDeviceConnected* dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len) { - USBEndpoint* ep = dev->getEpCtl(); - return controlWrite(ep, requestType, request, value, index, buf, len); -} - -USB_TYPE USBHost::controlRead(USBEndpoint* ep, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t* buf, uint32_t len) -{ - SETUP_PACKET setup(requestType, request, value, index, len); - int result = token_setup(ep, &setup, len); // setup stage - if (result < 0) { - return USB_TYPE_ERROR; - } - - result = token_in(ep, buf, len); // data stage - if (result < 0) { - return USB_TYPE_ERROR; - } - int read_len = result; - - ep->m_pED->setToggleDATA1(); - result = token_out(ep); // status stage - if (result < 0) { - return USB_TYPE_ERROR; - } - ep->setLengthTransferred(read_len); - return USB_TYPE_OK; -} - -USB_TYPE USBHost::controlWrite(USBEndpoint* ep, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len) -{ - SETUP_PACKET setup(requestType, request, value, index, len); - int result = token_setup(ep, &setup, len); // setup stage - if (result < 0) { - return USB_TYPE_ERROR; - } - int write_len = 0; - if (buf != NULL) { - result = token_out(ep, buf, len); // data stage - if (result < 0) { - return USB_TYPE_ERROR; - } - write_len = result; - } - ep->m_pED->setToggleDATA1(); - result = token_in(ep); // status stage - if (result < 0) { - return USB_TYPE_ERROR; - } - ep->setLengthTransferred(write_len); - return USB_TYPE_OK; -} - -USB_TYPE USBHost::bulkRead(USBDeviceConnected* dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) { - if (!blocking) { - ep->setBuffer(buf, len); - ep_queue.push(ep); - token_inNB(ep, buf, len); - return USB_TYPE_PROCESSING; - } - int result = token_in(ep, buf, len); - if (result >= 0) { - ep->setLengthTransferred(result); - return USB_TYPE_OK; - } - return USB_TYPE_ERROR; -} - -USB_TYPE USBHost::bulkWrite(USBDeviceConnected * dev, USBEndpoint* ep, uint8_t * buf, uint32_t len, bool blocking) -{ - int result = token_out(ep, buf, len); - if (result >= 0) { - ep->setLengthTransferred(result); - return USB_TYPE_OK; - } - return USB_TYPE_ERROR; -} - -USB_TYPE USBHost::interruptRead(USBDeviceConnected * dev, USBEndpoint* ep, uint8_t* buf, uint32_t len, bool blocking) { - if (!blocking) { - ep->setBuffer(buf, len); - ep_queue.push(ep); - token_inNB(ep, buf, len); - return USB_TYPE_PROCESSING; - } - int result = token_in(ep, buf, len); - if (result >= 0) { - ep->setLengthTransferred(result); - return USB_TYPE_OK; - } - return USB_TYPE_ERROR; -} - -void USBHost::task() { - USBEndpoint* ep = ep_queue.pop(); - if (ep) { - if (token_inNB_result(ep) == USB_TYPE_OK) { - ep->call(); - } else { - ep_queue.push(ep); - } - } -} -
--- a/LPC4088-USBHost/USBHost/BaseUsbHostCtlEp.cpp Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,107 +0,0 @@ -// BaseUsbHostCtlEp.cpp 2014/4/21 -#include "USBHost.h" -#define USB_DEBUG -#include "BaseUsbHostDebug.h" -#define TEST -#include "BaseUsbHostTest.h" - -static uint8_t device_addr = 1; -ControlEp::ControlEp(int lowSpeed):USBEndpoint(0, 0, 8, lowSpeed) { - setType(CONTROL_ENDPOINT); - USB_TYPE r = open(device_addr); - if (r == USB_TYPE_OK) { - device_addr++; - } -} - -USB_TYPE ControlEp::SetAddress(int addr) -{ - return controlSend(0x00, 5, addr); -} - -USB_TYPE ControlEp::GetDescriptor(int descType, int descIndex, uint8_t* data, int length) -{ - return controlReceive(0x80, 6, (descType<<8)|descIndex, 0, data, length); -} - -USB_TYPE ControlEp::SetConfiguration(int config) -{ - return controlSend(0x00, 9, config); -} - -USB_TYPE ControlEp::GetConfiguration(int *config) -{ - uint8_t buf[1]; - USB_TYPE rc = controlReceive(0x80, 8, 0, 0, buf, 1); - *config = buf[0]; - return rc; -} - -USB_TYPE ControlEp::SetInterfaceAlternate(int interface, int alternate) -{ - return controlSend(USB_HOST_TO_DEVICE | USB_RECIPIENT_INTERFACE, - SET_INTERFACE, alternate, interface, NULL, 0); -} - -USB_TYPE ControlEp::GetInterface(int interface, int *alternate) -{ - uint8_t buf[1]; - USB_TYPE rc = controlReceive(0x81, 10, 0, interface, buf, 1); - *alternate = buf[0]; - return rc; -} - -USB_TYPE ControlEp::GetStringDescriptor(char* s, int index) -{ - uint8_t buf[128]; - USB_TYPE r = GetDescriptor(USB_DESCRIPTOR_TYPE_STRING, index, buf, sizeof(buf)); - if (r != USB_TYPE_OK) { - return r; - } - DBG_HEX(buf, sizeof(buf)); - StringDescriptor* desc = reinterpret_cast<StringDescriptor*>(buf); - if (desc->bLength <= 2 || desc->bDescriptorType != 3) { - return USB_TYPE_ERROR; - } - for(int i = 0; i < desc->bLength-2; i += 2) { - *s++ = desc->bString[i]; - } - *s = '\0'; - return USB_TYPE_OK; -} - -USB_TYPE ControlEp::open(int addr) -{ - TEST_ASSERT(addr >= 1 && addr <= 127); - uint8_t buf[8]; - USB_TYPE r = GetDescriptor(1, 0, buf, 8); - if (r != USB_TYPE_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_TYPE_OK); - if (r != USB_TYPE_OK) { - return r; - } - wait_ms(2); - update_FunctionAddress(addr); - return USB_TYPE_OK; -} - -USB_TYPE ControlEp::controlReceive(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, - uint8_t* data, int length) -{ - return host->controlRead(this, bmRequestType, bRequest, wValue, wIndex, data, length); -} - -USB_TYPE ControlEp::controlSend(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, - const uint8_t* data, int length) -{ - return host->controlWrite(this, bmRequestType, bRequest, wValue, wIndex, (uint8_t*)data, length); -} - -
--- a/LPC4088-USBHost/USBHost/BaseUsbHostDebug.cpp Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -// BaseUseHostDebug.cpp 2014/4/21 -#include "USBHost.h" -#include "BaseUsbHostDebug.h" - -void print_td(FILE* stream, HCTD* td) -{ - if (td == NULL) { - fprintf(stream, "TD %p:\n", td); - return; - } - uint32_t* p = reinterpret_cast<uint32_t*>(td); - fprintf(stream, "TD %p: %08X %08X %08X %08X", p, p[0], p[1], p[2], p[3]); - fprintf(stream, " ep=%p\n", td->ep); - uint8_t* bp = reinterpret_cast<uint8_t*>(p[1]); - uint8_t* be = reinterpret_cast<uint8_t*>(p[3]); - if (bp) { - fprintf(stream, "BF %p:", bp); - while(bp <= be) { - fprintf(stream, " %02X", *bp); - bp++; - } - fprintf(stream, "\n"); - } -} - -void print_ed(FILE* stream, HCED* ed) -{ - uint32_t* p = reinterpret_cast<uint32_t*>(ed); - while(p) { - fprintf(stream, "ED %p: %08X %08X %08X %08X\n", p, p[0], p[1], p[2], p[3]); - HCTD* td = reinterpret_cast<HCTD*>(p[2] & ~3); - HCTD* tdtail = reinterpret_cast<HCTD*>(p[1]); - while(td != NULL && td != tdtail) { - print_td(stream, td); - td = td->Next; - } - p = reinterpret_cast<uint32_t*>(p[3]); - } -} - -void print_itd(FILE* stream, HCITD* itd) -{ - if (itd == NULL) { - fprintf(stream, "ITD %p:\n", itd); - return; - } - uint32_t* p = reinterpret_cast<uint32_t*>(itd); - fprintf(stream, "ITD %p: %08X %08X %08X %08X", p, p[0], p[1], p[2], p[3]); - fprintf(stream, " ep=%p\n", itd->ep); - uint16_t* offset = reinterpret_cast<uint16_t*>(p+4); - fprintf(stream, "ITD %p: %04X %04X %04X %04X %04X %04X %04X %04X\n", offset, - offset[0], offset[1], offset[2], offset[3], offset[4], offset[5], offset[6], offset[7]); -} - -void print_ied(FILE* stream, HCED* ed) -{ - uint32_t* p = reinterpret_cast<uint32_t*>(ed); - while(p) { - fprintf(stream, "ED %p: %08X %08X %08X %08X\n", p, p[0], p[1], p[2], p[3]); - HCITD* itd = reinterpret_cast<HCITD*>(p[2] & ~3); - HCITD* itdtail = reinterpret_cast<HCITD*>(p[1]); - while(itd != NULL && itd != itdtail) { - print_itd(stream, itd); - itd = itd->Next; - } - p = reinterpret_cast<uint32_t*>(p[3]); - } -} - -void print_bytes(FILE* stream, char* s, uint8_t* buf, int len) -{ - fprintf(stream, "%s %d:", s, len); - for(int i = 0; i < len; i++) { - fprintf(stream, " %02X", buf[i]); - } - fprintf(stream, "\n"); -} - -void print_hex(FILE* stream, uint8_t* p, int len) -{ - for(int i = 0; i < len; i++) { - if (i%16 == 0) { - fprintf(stream, "%p:", p); - } - fprintf(stream, " %02X", *p); - p++; - if (i%16 == 15) { - fprintf(stream, "\n"); - } - } - fprintf(stream, "\n"); -} - -void assert_print(const char* pf, int line, const char* msg) { - fprintf(stderr, "\n\n%s@%d %s ASSERT!\n\n", pf, line, msg); - exit(1); -} -
--- a/LPC4088-USBHost/USBHost/BaseUsbHostDebug.h Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -// BaseUsbHostDebug.h 2014/4/22 -#pragma once - -#ifdef USB_DEBUG -//#define USB_DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);} while(0); -#define USB_DBG_IF(C, ...) if(C){fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);}else{} -#define USB_DBG_ED_IF(C,A) if(C){fprintf(stderr,"[%s@%d]\n",__PRETTY_FUNCTION__,__LINE__);print_ed(stderr,A);}else{} -#define USB_DBG_ED(A) fprintf(stderr,"[%s@%d]\n",__PRETTY_FUNCTION__,__LINE__);print_ed(stderr,A); -#else -//#define USB_DBG(...) while(0); -#define USB_DBG_IF(...) while(0); -#define USB_DBG_ED_IF(C,A) while(0) -#define USB_DBG_ED(A) while(0) -#endif - -#ifdef DEBUG -#define DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);} while(0); -#define DBG_PRINTF(...) do{fprintf(stderr,__VA_ARGS__);}while(0); -#define DBG_TD(A) do{fprintf(stderr,"[%s@%d]\n",__PRETTY_FUNCTION__,__LINE__);print_td(stderr,A);}while(0); -#define DBG_ED(A) do{fprintf(stderr,"[%s@%d]\n",__PRETTY_FUNCTION__,__LINE__);print_ed(stderr,A);}while(0); -#define DBG_ITD(A) do{fprintf(stderr,"[%s@%d]\n",__PRETTY_FUNCTION__,__LINE__);print_itd(stderr,A);}while(0); -#define DBG_IED(A) do{fprintf(stderr,"[%s@%d]\n",__PRETTY_FUNCTION__,__LINE__);print_ied(stderr,A);}while(0); -#define DBG_BYTES(A,B,C) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);print_bytes(stderr,A,B,C);}while(0); -#define DBG_HEX(A,B) do{fprintf(stderr,"[%s@%d]\n",__PRETTY_FUNCTION__,__LINE__);print_hex(stderr,A,B);}while(0); -#define DBG_OHCI(A) do{fprintf(stderr,"[%s@%d] %s: %08X\n",__PRETTY_FUNCTION__,__LINE__,#A,A);}while(0); -#else //DEBUG -#define DBG(...) while(0); -#define DBG_PRINTF(...) while(0); -#define DBG_TD(A) while(0); -#define DBG_ED(A) while(0); -#define DBG_ITD(A) while(0); -#define DBG_IED(A) while(0); -#define DBG_BYTES(A,B,C) while(0); -#define DBG_HEX(A,B) while(0); -#define DBG_OHCI(A) while(0); -#endif //DEBUG - -void print_td(FILE* stream, HCTD* td); -void print_ed(FILE* stream, HCED* ed); -void print_itd(FILE* stream, HCITD* itd); -void print_ied(FILE* stream, HCED* ed); -void print_bytes(FILE* stream, char* s, uint8_t* buf, int len); -void print_hex(FILE* stream, uint8_t* p, int len); - -
--- a/LPC4088-USBHost/USBHost/BaseUsbHostHub.cpp Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,157 +0,0 @@ -// BaseUsbHostHub.cpp 2014/4/21 -#include "USBHost.h" -//#define DEBUG -#include "BaseUsbHostDebug.h" -#define TEST -#include "BaseUsbHostTest.h" - -#define PORT_CONNECTION 0 -#define PORT_ENABLE 1 -#define PORT_SUSPEND 2 -#define PORT_OVER_CURRENT 3 -#define PORT_RESET 4 -#define PORT_POWER 8 -#define PORT_LOW_SPEED 9 - -#define C_PORT_CONNECTION 16 -#define C_PORT_ENABLE 17 -#define C_PORT_SUSPEND 18 -#define C_PORT_OVER_CURRENT 19 -#define C_PORT_RESET 20 - -UsbHub::UsbHub(ControlEp* ctlEp) -{ - if (ctlEp == NULL) { - DBG_OHCI(LPC_USB->HcRhPortStatus1); - int lowSpeed = 0; - if (LPC_USB->HcRhPortStatus1 & 0x200) { - lowSpeed = 1; - } - m_ctlEp = new ControlEp(lowSpeed); - TEST_ASSERT_TRUE(m_ctlEp); - } else { - m_ctlEp = ctlEp; - } - CTASSERT(sizeof(DeviceDescriptor) == 18); - DeviceDescriptor devdesc; - USB_TYPE rc = m_ctlEp->GetDescriptor(1, 0, reinterpret_cast<uint8_t*>(&devdesc), sizeof(DeviceDescriptor)); - TEST_ASSERT(rc == USB_TYPE_OK); - if (rc != USB_TYPE_OK) { - return; - } - TEST_ASSERT_TRUE(devdesc.bLength == 0x12); - TEST_ASSERT_TRUE(devdesc.bDescriptorType == 0x01); - TEST_ASSERT_TRUE(devdesc.bDeviceClass == 0x09); // hub - if (devdesc.bDeviceClass != 0x09) { // hub ? - return; - } - CTASSERT(sizeof(HubDescriptor) == 9); - TEST_ASSERT(sizeof(HubDescriptor) == 9); - HubDescriptor hubdesc; - rc = m_ctlEp->controlReceive(0xa0, 6, 0x29<<8, 0, reinterpret_cast<uint8_t*>(&hubdesc), sizeof(HubDescriptor)); - TEST_ASSERT(rc == USB_TYPE_OK); - if (rc != USB_TYPE_OK) { - return; - } - TEST_ASSERT(hubdesc.bDescLength == 9); // length - TEST_ASSERT(hubdesc.bDescriptorType == 0x29); // hub - TEST_ASSERT(hubdesc.bNbrPorts >= 1); - TEST_ASSERT(hubdesc.bNbrPorts <= 16); - - rc = m_ctlEp->SetConfiguration(1); - TEST_ASSERT(rc == USB_TYPE_OK); - - uint32_t status; - rc = m_ctlEp->controlReceive(0xa0, 0, 0, 0, reinterpret_cast<uint8_t*>(&status), 4); - TEST_ASSERT(rc == USB_TYPE_OK); - if (rc != USB_TYPE_OK) { - return; - } - DBG("HUB STATUS: %08X\n", status); - - for(int i = 1; i <= hubdesc.bNbrPorts; i++) { - SetPortPower(i); // power on - wait_ms(hubdesc.bPwrOn2PwrGood*2); - uint32_t status; - GetPortStatus(i, &status); - DBG("port: %d status: %08X\n", i, status); - if (status & 0x010000) { // Connect Status Change, has changed - TEST_ASSERT(status & 0x000001); - ClearPortFeature(C_PORT_CONNECTION, i); - int lowSpeed = 0; - if (status & 0x0200) { - lowSpeed = 1; - } - PortReset(i); - ControlEp* ctlEp = new ControlEp(lowSpeed); - PortEp.push_back(ctlEp); - } else { - ClearPortPower(i); // power off - } - } -} - -bool UsbHub::check(ControlEp* ctlEp) -{ - if (ctlEp == NULL) { - return false; - } - DeviceDescriptor desc; - USB_TYPE rc = ctlEp->GetDescriptor(DEVICE_DESCRIPTOR, 0, reinterpret_cast<uint8_t*>(&desc), sizeof(DeviceDescriptor)); - if (rc != USB_TYPE_OK) { - return false; - } - if (desc.bDeviceClass == 9) { // hub? - return true; - } - return false; -} - -USB_TYPE UsbHub::SetPortPower(int port) -{ - return SetPortFeature(PORT_POWER, port); -} - -USB_TYPE UsbHub::ClearPortPower(int port) -{ - return ClearPortFeature(PORT_POWER, port); -} - -USB_TYPE UsbHub::SetPortFeature(int feature, int index) -{ - return m_ctlEp->controlSend(0x23, SET_FEATURE,feature,index,0,0); -} - -USB_TYPE UsbHub::ClearPortFeature(int feature, int index) -{ - return m_ctlEp->controlSend(0x23, CLEAR_FEATURE,feature,index,0,0); -} - -USB_TYPE UsbHub::SetPortReset(int port) -{ - return SetPortFeature(PORT_RESET, port); -} - -USB_TYPE UsbHub::GetPortStatus(int port, uint32_t* status) -{ - return m_ctlEp->controlReceive(0xa3, GET_STATUS, 0, port, (uint8_t*)status, 4); -} - -USB_TYPE UsbHub::PortReset(int port) -{ - DBG("%p port=%d\n", this, port); - TEST_ASSERT(port >= 1); - SetPortReset(port); - // wait reset - for(int i = 0; i < 100; i++) { - uint32_t status; - GetPortStatus(port, &status); - DBG("RESET port: %d status: %08X\n", port, status); - if (status & 0x100000) { // Reset change , Reset complete - return USB_TYPE_OK; - } - wait_ms(5); - } - return USB_TYPE_ERROR; -} -
--- a/LPC4088-USBHost/USBHost/BaseUsbHostIsoEp.cpp Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,131 +0,0 @@ -// BaseUsbHostIsoEp.cpp 2014/4/21 -#include "USBHost.h" -//#define DEBUG -#include "BaseUsbHostDebug.h" -//#define TEST -#include "BaseUsbHostTest.h" - -HCITD::HCITD(USBEndpoint* obj, uint16_t FrameNumber, int FrameCount, uint16_t PacketSize) { - Control = 0xe0000000 | // CC ConditionCode NOT ACCESSED - ((FrameCount-1) << 24)| // FC FrameCount - TD_DELAY_INT(0) | // DI DelayInterrupt - FrameNumber; // SF StartingFrame - BufferPage0 = const_cast<uint8_t*>(buf); - BufferEnd = const_cast<uint8_t*>(buf) + PacketSize * FrameCount - 1; - Next = NULL; - ep = obj; - uint32_t addr = reinterpret_cast<uint32_t>(buf); - for(int i = 0; i < FrameCount; i++) { - uint16_t offset = addr & 0x0fff; - if ((addr&0xfffff000) == (reinterpret_cast<uint32_t>(BufferEnd)&0xfffff000)) { - offset |= 0x1000; - } - OffsetPSW[i] = 0xe000|offset; - addr += PacketSize; - } -} - -IsochronousEp::IsochronousEp(int addr, uint8_t ep, uint16_t size):USBEndpoint(addr, ep, size) -{ - setType(ISOCHRONOUS_ENDPOINT); - DBG("%p FA:%d EP:%02X MPS:%d\n", this, addr, ep, size); - TEST_ASSERT(m_pED); - - m_pED->Control |= (1 << 15); // F Format ITD - - TEST_ASSERT(size >= 128 && size <= 1023); - m_PacketSize = size; - m_FrameCount = 4; // 1-8 - TEST_ASSERT(m_FrameCount >= 1 && m_FrameCount <= 8); - m_itd_queue_count = 0; - reset(); - HCITD* itd = new_HCITD(this); - m_pED->TailTd = reinterpret_cast<HCTD*>(itd); - m_pED->HeadTd = reinterpret_cast<HCTD*>(itd); - TEST_ASSERT(itd); - if (itd == NULL) { - return; - } - HCCA* hcca = reinterpret_cast<HCCA*>(LPC_USB->HcHCCA); - TEST_ASSERT(hcca); - if (hcca == NULL) { - return; - } - for(int i = 0; i < 32; i++) { - if (hcca->InterruptTable[i] == NULL) { - hcca->InterruptTable[i] = m_pED; - } else { - HCED* nextEd = hcca->InterruptTable[i]; - while(nextEd->Next && nextEd->Next != m_pED) { - nextEd = nextEd->Next; - } - nextEd->Next = m_pED; - } - } - DBG_ED(m_pED); -} - -void IsochronousEp::reset(int delay_ms) -{ - m_FrameNumber = LPC_USB->HcFmNumber + delay_ms; -} - -HCITD* IsochronousEp::new_HCITD(USBEndpoint* obj) -{ - HCITD* itd = new(m_PacketSize*m_FrameCount)HCITD(obj, m_FrameNumber, m_FrameCount, m_PacketSize); - if (itd == NULL) { - return NULL; - } - m_FrameNumber += m_FrameCount; - return itd; -} - -HCITD* IsochronousEp::isochronousReveive(int millisec) -{ - TEST_ASSERT(m_itd_queue_count >= 0); - while(m_itd_queue_count < 3 && m_itd_queue_count < HCTD_QUEUE_SIZE) { - HCITD* itd = reinterpret_cast<HCITD*>(m_pED->TailTd); - TEST_ASSERT(itd); - if (itd == NULL) { - return NULL; - } - HCITD* blank_itd = new_HCITD(this); - TEST_ASSERT(blank_itd); - if (blank_itd == NULL) { - return NULL; - } - itd->Next = blank_itd; - m_pED->TailTd = reinterpret_cast<HCTD*>(blank_itd); - m_itd_queue_count++; - //DBG_IED(m_pED); - USBHALHost::enable(ISOCHRONOUS_ENDPOINT); // Enable Periodic - } - - HCITD* itd = get_queue_HCITD(millisec); - if (itd) { - m_itd_queue_count--; - } - return itd; -} - -HCITD* IsochronousEp::get_queue_HCITD(int millisec) -{ - for(int i = 0; i < 16; i++) { - osEvent evt = m_queue.get(millisec); - if (evt.status == osEventMessage) { - HCITD* itd = reinterpret_cast<HCITD*>(evt.value.p); - TEST_ASSERT(itd); - return itd; - } else if (evt.status == osOK) { - continue; - } else if (evt.status == osEventTimeout) { - return NULL; - } else { - DBG("evt.status: %02x\n", evt.status); - TEST_ASSERT(evt.status == osEventMessage); - return NULL; - } - } - return NULL; -} -
--- a/LPC4088-USBHost/USBHost/BaseUsbHostLib.cpp Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,107 +0,0 @@ -// BaseUsbHostLib.cpp 2014/4/22 -#include "USBHost.h" -//#define DEBUG -#include "BaseUsbHostDebug.h" -#define TEST -#include "BaseUsbHostTest.h" - -//#define DBG_USE_POSIX_MEMALIGN - -#ifdef DBG_USE_POSIX_MEMALIGN -void* usb_ram_malloc(size_t size, int aligment) -{ - TEST_ASSERT(aligment >= 4); - TEST_ASSERT(!(aligment & 3)); - void* p; - if (posix_memalign(&p, aligment, size) == 0) { - return p; - } - return NULL; -} - -void usb_ram_free(void* p) -{ - free(p); -} -#else - -#define CHUNK_SIZE 64 - -#if defined(TARGET_LPC1768) -#define USB_RAM_BASE 0x2007C000 -#define USB_RAM_SIZE 0x4000 -#define BLOCK_COUNT (USB_RAM_SIZE/CHUNK_SIZE) -#elif defined(TARGET_LPC4088) -#define USB_RAM_BASE 0x20000000 -#define USB_RAM_SIZE 0x4000 -#define BLOCK_COUNT (USB_RAM_SIZE/CHUNK_SIZE) -#else -#error "target error" -#endif - -static uint8_t* ram = NULL; -static uint8_t* map; - -static void usb_ram_init() -{ - USB_INFO("USB_RAM: 0x%p(%d)", USB_RAM_BASE, USB_RAM_SIZE); - ram = (uint8_t*)USB_RAM_BASE; - TEST_ASSERT((int)ram%256 == 0); - map = (uint8_t*)malloc(BLOCK_COUNT); - TEST_ASSERT(map); - memset(map, 0, BLOCK_COUNT); -} - -// first fit malloc -void* usb_ram_malloc(size_t size, int aligment) -{ - TEST_ASSERT(aligment >= 4); - TEST_ASSERT(!(aligment & 3)); - if (ram == NULL) { - usb_ram_init(); - } - int needs = (size+CHUNK_SIZE-1)/CHUNK_SIZE; - void* p = NULL; - for(int idx = 0; idx < BLOCK_COUNT;) { - bool found = true; - for(int i = 0; i < needs; i++) { - int block = map[idx + i]; - if (block != 0) { - idx += block; - found = false; - break; - } - } - if (!found) { - continue; - } - p = ram+idx*CHUNK_SIZE; - if ((int)p % aligment) { - idx++; - continue; - } - TEST_ASSERT((idx + needs) <= BLOCK_COUNT); - for(int i = 0; i < needs; i++) { - map[idx + i] = needs - i; - } - break; - } - TEST_ASSERT(p); - return p; -} - -void usb_ram_free(void* p) -{ - TEST_ASSERT(p >= ram); - TEST_ASSERT(p < (ram+CHUNK_SIZE*BLOCK_COUNT)); - int idx = ((int)p-(int)ram)/CHUNK_SIZE; - int block = map[idx]; - TEST_ASSERT(block >= 1); - for(int i =0; i < block; i++) { - map[idx + i] = 0; - } -} - -#endif // DBG_USE_POSIX_MEMALIGN - -
--- a/LPC4088-USBHost/USBHost/BaseUsbHostTest.h Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -// BaseUsbHostTest.h 2014/4/22 -#pragma once - -#ifndef CTASSERT -template <bool>struct CtAssert; -template <>struct CtAssert<true> {}; -#define CTASSERT(A) CtAssert<A>(); -#endif //CTASSERT - -#ifdef TEST -//#define USB_TEST_ASSERT(A) if(A){}else{assert_print(__PRETTY_FUNCTION__, __LINE__, #A);} -#define TEST_ASSERT(A) if(A){}else{assert_print(__PRETTY_FUNCTION__, __LINE__,#A);} -#define TEST_ASSERT_TRUE(A) if(A){}else{assert_print(__PRETTY_FUNCTION__, __LINE__, #A);} -#define TEST_ASSERT_FALSE(A) if(A){assert_print(__PRETTY_FUNCTION__, __LINE__, #A);}else{} -#define TEST_ASSERT_EQUAL(A,B) if (A == B){}else{assert_print(__PRETTY_FUNCTION__, __LINE__, #A);} -void assert_print(const char* pf, int line, const char* msg); -#else -#define TEST_ASSERT(A) -#define TEST_ASSERT_TRUE(A) while(0); -#define TEST_ASSERT_FALSE(A) while(0); -#define TEST_ASSERT_EQUAL(A,B) while(0); -#endif
--- a/LPC4088-USBHost/USBHost/BaseUsbHostUvc.cpp Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -// BaseUsbHostUvc.cpp 2014/4/21 -#include "USBHost.h" -//#define DEBUG -#include "BaseUsbHostDebug.h" -//#define TEST -#include "BaseUsbHostTest.h" - -void BaseUvc::poll(int millisec) -{ - HCITD* itd = m_isoEp->isochronousReveive(millisec); - if (itd) { - uint8_t cc = itd->ConditionCode(); - report_cc_count[cc]++; - if (cc == 0) { - uint16_t frame = itd->StartingFrame(); - int fc = itd->FrameCount(); - uint8_t* buf = const_cast<uint8_t*>(itd->buf); - int mps = m_isoEp->m_PacketSize; - for(int i = 0; i < fc; i++) { - uint16_t psw = itd->OffsetPSW[i]; - cc = psw>>12; - if (cc == 0 || cc == 9) { - int len = psw & 0x7ff; - onResult(frame, buf, len); - } - report_ps_cc_count[cc]++; - buf += mps; - frame++; - } - } - delete itd; - } -} - -USB_TYPE BaseUvc::Control(int req, int cs, int index, uint8_t* buf, int size) -{ - TEST_ASSERT(m_ctlEp); - if (m_ctlEp == NULL) { - return USB_TYPE_ERROR; - } - USB_TYPE rc; - if (req == SET_CUR) { - rc = m_ctlEp->controlSend( - USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE, - req, cs<<8, index, buf, size); - return rc; - } - rc = m_ctlEp->controlReceive( - USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE, - req, cs<<8, index, buf, size); - return rc; -} - -void BaseUvc::onResult(uint16_t frame, uint8_t* buf, int len) -{ - if(m_pCbItem && m_pCbMeth) - (m_pCbItem->*m_pCbMeth)(frame, buf, len); - else if(m_pCb) - m_pCb(frame, buf, len); -} - -void BaseUvc::setOnResult( void (*pMethod)(uint16_t, uint8_t*, int) ) -{ - m_pCb = pMethod; - m_pCbItem = NULL; - m_pCbMeth = NULL; -} - -void BaseUvc::clearOnResult() -{ - m_pCb = NULL; - m_pCbItem = NULL; - m_pCbMeth = NULL; -} -
--- a/LPC4088-USBHost/USBHost/IUSBEnumerator.h Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* mbed USBHost Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef IUSBENUMERATOR_H_ -#define IUSBENUMERATOR_H_ - -#include "stdint.h" -#include "USBEndpoint.h" - -/* -Generic interface to implement for "smart" USB enumeration -*/ - -class IUSBEnumerator -{ -public: - virtual void setVidPid(uint16_t vid, uint16_t pid) = 0; - virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) = 0; //Must return true if the interface should be parsed - virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) = 0; //Must return true if the endpoint will be used -}; - -#endif /*IUSBENUMERATOR_H_*/ -
--- a/LPC4088-USBHost/USBHost/USBDeviceConnected.cpp Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -/* mbed USBHost Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "USBDeviceConnected.h" -#include "dbg.h" - -USBDeviceConnected::USBDeviceConnected() { - init(); -} - -void USBDeviceConnected::init() { - port = 0; - vid = 0; - pid = 0; - nb_interf = 0; - enumerated = false; - device_class = 0; - device_subclass = 0; - proto = 0; - lowSpeed = false; - hub_parent = NULL; -} - -bool USBDeviceConnected::addInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) { - USB_DBG("intf_nb=%d", intf_nb); - if (intf.count(intf_nb) > 0) { - return false; - } - intf[intf_nb] = new INTERFACE(intf_class, intf_subclass, intf_protocol); - return true; -} - -bool USBDeviceConnected::addEndpoint(uint8_t intf_nb, USBEndpoint * ept) { - if (intf.count(intf_nb) > 0) { - intf[intf_nb]->ep.push_back(ept); - return true; - } - return false; -} - -void USBDeviceConnected::init(USBDeviceConnected* parent, uint8_t port_, bool lowSpeed_) { - USB_DBG("init dev: %p", this); - init(); - hub_parent = parent; - port = port_; - lowSpeed = lowSpeed_; -} - -void USBDeviceConnected::disconnect() { - //for(int i = 0; i < MAX_INTF; i++) { - // intf[i].detach.call(); - //} - //init(); -} - - -USBEndpoint * USBDeviceConnected::getEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint8_t index) { - USB_DBG("intf_nb=%d", intf_nb); - USB_TEST_ASSERT(intf.count(intf_nb) > 0); - INTERFACE* inter = intf[intf_nb]; - for (int i = 0; i < inter->ep.size(); i++) { - if ((inter->ep[i]->getType() == type) && (inter->ep[i]->getDir() == dir)) { - if(index) { - index--; - } else { - return inter->ep[i]; - } - } - } - return NULL; -} - -USBEndpoint * USBDeviceConnected::getEndpoint(uint8_t intf_nb, uint8_t index) { - USB_TEST_ASSERT(intf.count(intf_nb) > 0); - return intf[intf_nb]->ep[index]; -}
--- a/LPC4088-USBHost/USBHost/USBDeviceConnected.h Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,133 +0,0 @@ -/* mbed USBHost Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include "USBEndpoint.h" -#include "USBHostConf.h" -#include "myvector.h" -#include "mymap.h" - -class USBEndpoint; - -struct INTERFACE { - INTERFACE(uint8_t _class, uint8_t _subclass, uint8_t _protocol) { - intf_class = _class; - intf_subclass = _subclass; - intf_protocol = _protocol; - } - uint8_t intf_class; - uint8_t intf_subclass; - uint8_t intf_protocol; - myvector<USBEndpoint*>ep; -}; - -/** -* USBDeviceConnected class -*/ -class USBDeviceConnected { -public: - - /** - * Constructor - */ - USBDeviceConnected(); - - /** - * Attach an USBEndpoint to this device - * - * @param intf_nb interface number - * @param ep pointeur on the USBEndpoint which will be attached - * @returns true if successful, false otherwise - */ - bool addEndpoint(uint8_t intf_nb, USBEndpoint * ep); - - /** - * Retrieve an USBEndpoint by its TYPE and DIRECTION - * - * @param intf_nb the interface on which to lookup the USBEndpoint - * @param type type of the USBEndpoint looked for - * @param dir direction of the USBEndpoint looked for - * @param index the index of the USBEndpoint whitin the interface - * @returns pointer on the USBEndpoint if found, NULL otherwise - */ - USBEndpoint * getEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint8_t index = 0); - - /** - * Retrieve an USBEndpoint by its index - * - * @param intf_nb interface number - * @param index index of the USBEndpoint - * @returns pointer on the USBEndpoint if found, NULL otherwise - */ - USBEndpoint * getEndpoint(uint8_t intf_nb, uint8_t index); - - /** - * Add a new interface to this device - * - * @param intf_nb interface number - * @param intf_class interface class - * @param intf_subclass interface subclass - * @param intf_protocol interface protocol - * @returns true if successful, false otherwise - */ - bool addInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); - - /** - * Disconnect the device by calling a callback function registered by a driver - */ - void disconnect(); - - void init(USBDeviceConnected* parent, uint8_t _port, bool _lowSpeed); - void setAddress(uint8_t addr_) { addr = addr_; }; - void setVid(uint16_t vid_) { vid = vid_; }; - void setPid(uint16_t pid_) { pid = pid_; }; - void setClass(uint8_t device_class_) { device_class = device_class_; } - void setSubClass(uint8_t device_subclass_) { device_subclass = device_subclass_; }; - void setProtocol(uint8_t pr) { proto = pr; }; - void setEnumerated() { enumerated = true; }; - void setNbIntf(uint8_t nb_intf) {nb_interf = nb_intf; }; - void setSpeed(bool _lowSpeed) { lowSpeed = _lowSpeed; } - void setName(const char * name_, uint8_t intf_nb) { return; }; - void setEpCtl(USBEndpoint* ep) { ep_ctl = ep; } - - static int getNewAddress() { - static int addr = 1; - return addr++; - } - uint8_t getAddress() { return addr; }; - uint16_t getVid() { return vid; }; - uint16_t getPid() { return pid; }; - uint8_t getClass() { return device_class; }; - bool getSpeed() { return lowSpeed; } - bool isEnumerated() { return enumerated; }; - USBEndpoint* getEpCtl() { return ep_ctl; } - -private: - USBDeviceConnected* hub_parent; - mymap<int,INTERFACE*>intf; - uint8_t port; - uint16_t vid; - uint16_t pid; - uint8_t addr; - uint8_t device_class; - uint8_t device_subclass; - uint8_t proto; - bool lowSpeed; - bool enumerated; - uint8_t nb_interf; - USBEndpoint* ep_ctl; - void init(); -};
--- a/LPC4088-USBHost/USBHost/USBEndpoint.cpp Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,103 +0,0 @@ -/* mbed USBHost Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "USBHost.h" -#include "BaseUsbHostDebug.h" -#include "USBEndpoint.h" -#include "BaseUsbHostTest.h" - -USBEndpoint::USBEndpoint(int addr, uint8_t ep, uint16_t size, int lowSpeed) - :m_td_queue_count(0) { - dev = NULL; - host = USBHost::getHostInst(); - setNextEndpoint(NULL); - DBG("%p FA=%d EN=%02x MPS=%d S=%d\n", this, addr, ep, size, lowSpeed); - TEST_ASSERT(size >= 8 && size <= 1023); - TEST_ASSERT(lowSpeed == 0 || lowSpeed == 1); - m_pED = new HCED(addr, ep, size, lowSpeed); - TEST_ASSERT(m_pED); -} - -int USBEndpoint::GetAddr() { - USB_TEST_ASSERT(m_pED); - if (m_pED) { - return m_pED->FunctionAddress(); - } - return 0; -} - -int USBEndpoint::GetLowSpeed() -{ - TEST_ASSERT(m_pED); - if (m_pED) { - return m_pED->Speed(); - } - return 0; -} - -void USBEndpoint::update_FunctionAddress(int addr) -{ - TEST_ASSERT(addr >= 0 && addr <= 127); - TEST_ASSERT(m_pED); - if (m_pED) { - m_pED->setFunctionAddress(addr); - } -} - -void USBEndpoint::update_MaxPacketSize(uint16_t size) -{ - TEST_ASSERT(size >= 8 && size <= 1023); - TEST_ASSERT(m_pED); - if (m_pED) { - m_pED->setMaxPacketSize(size); - } -} - -HCTD* USBEndpoint::get_queue_HCTD(uint32_t millisec) -{ - for(int i = 0; i < 16; i++) { - osEvent evt = m_queue.get(millisec); - if (evt.status == osEventMessage) { - HCTD* td = reinterpret_cast<HCTD*>(evt.value.p); - TEST_ASSERT(td); - uint8_t cc = td->ConditionCode(); - if (cc != 0) { - m_ConditionCode = cc; - DBG_TD(td); - } - return td; - } else if (evt.status == osOK) { - continue; - } else if (evt.status == osEventTimeout) { - return NULL; - } else { - DBG("evt.status: %02x\n", evt.status); - TEST_ASSERT(evt.status == osEventMessage); - } - } - return NULL; -} - -InterruptEp::InterruptEp(int addr, uint8_t ep, uint16_t size, int lowSpeed) - :USBEndpoint(addr, ep, size, lowSpeed) { - setType(INTERRUPT_ENDPOINT); -} - -BulkEp::BulkEp(int addr, uint8_t ep, uint16_t size): USBEndpoint(addr, ep, size) { - setType(BULK_ENDPOINT); -} - -
--- a/LPC4088-USBHost/USBHost/USBEndpoint.h Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,211 +0,0 @@ -/* mbed USBHost Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once -#include "rtos.h" -#include "FunctionPointer.h" -#include "USBHostTypes.h" -#include "USBDeviceConnected.h" - -class USBDeviceConnected; - -#define HCTD_QUEUE_SIZE 3 - -struct HCTD; -struct HCED; -struct HCITD; -class USBHost; - -/** -* USBEndpoint class -*/ -class USBEndpoint { -public: - /** - * Constructor - */ - USBEndpoint(USBDeviceConnected* _dev) { - init(CONTROL_ENDPOINT, IN, 8, 0); - dev = _dev; - } - - /** - * Initialize an endpoint - * - * @param type endpoint type - * @param dir endpoint direction - * @param size endpoint size - * @param ep_number endpoint number - */ - void init(ENDPOINT_TYPE _type, ENDPOINT_DIRECTION _dir, uint32_t size, uint8_t ep_number) { - setType(_type); - dir = _dir; - MaxPacketSize = size; - address = ep_number; - m_pED = NULL; - //data01_toggle = DATA0; - } - - USBEndpoint(int addr, uint8_t ep = 0, uint16_t size = 8, int lowSpeed = 0); - - /** - * Attach a member function to call when a transfer is finished - * - * @param tptr pointer to the object to call the member function on - * @param mptr pointer to the member function to be called - */ - template<typename T> - void attach(T* tptr, void (T::*mptr)(void)) { - if((mptr != NULL) && (tptr != NULL)) { - rx.attach(tptr, mptr); - } - } - - /** - * Attach a callback called when a transfer is finished - * - * @param fptr function pointer - */ - void attach(void (*fptr)(void)) { - if(fptr != NULL) { - rx.attach(fptr); - } - } - - /** - * Call the handler associted to the end of a transfer - */ - void call() { - rx.call(); - }; - - int GetAddr(); - int GetLowSpeed(); - void update_FunctionAddress(int addr); - void update_MaxPacketSize(uint16_t size); - // - virtual void irqWdhHandler(HCTD* td) {m_queue.put(td);} // WDH - HCTD* get_queue_HCTD(uint32_t millisec=osWaitForever); - HCED* m_pED; - // report - uint8_t m_ConditionCode; - int m_report_queue_error; - - void setType(ENDPOINT_TYPE _type) { type = _type; }; - void setState(uint8_t st){}; // dummy - void setLengthTransferred(int len) { transferred = len; }; - void setBuffer(uint8_t* buf, int size) { buf_start = buf, buf_size = size; } - void setSize(int size) { MaxPacketSize = size; } - void setNextEndpoint(USBEndpoint* ep) { nextEp = ep; }; - - USBDeviceConnected* getDevice() { return dev; } - ENDPOINT_TYPE getType() { return type; }; - int getLengthTransferred() { return transferred; } - uint8_t *getBufStart() { return buf_start; } - int getBufSize() { return buf_size; } - uint8_t getAddress(){ return address; }; - int getSize() { return MaxPacketSize; } - ENDPOINT_DIRECTION getDir() { return dir; } - USBEndpoint* nextEndpoint() { return nextEp; }; - -private: - ENDPOINT_TYPE type; - ENDPOINT_DIRECTION dir; - USBDeviceConnected* dev; - uint8_t address; - int transferred; - uint8_t * buf_start; - int buf_size; - FunctionPointer rx; - int MaxPacketSize; - USBEndpoint* nextEp; - -protected: - Queue<HCTD, HCTD_QUEUE_SIZE> m_queue; // TD done queue - int m_td_queue_count; - USBHost* host; -}; - -class ControlEp : public USBEndpoint { -public: - ControlEp(int lowSpeed = 0); - USB_TYPE GetDescriptor(int descType, int descIndex, uint8_t* data, int length); - USB_TYPE SetAddress(int addr); // device address - USB_TYPE SetConfiguration(int config); - USB_TYPE GetConfiguration(int *config); - USB_TYPE SetInterfaceAlternate(int interface, int alternate); - USB_TYPE GetInterface(int interface, int *alternate); - USB_TYPE controlSend(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex=0, const uint8_t* data=NULL, int length=0); - USB_TYPE controlReceive(uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t* data, int length); - USB_TYPE GetStringDescriptor(char* s, int index); - -private: - USB_TYPE open(int addr); - -}; - -class BulkEp : public USBEndpoint { -public: - BulkEp(int addr, uint8_t ep, uint16_t size); -}; - -class InterruptEp : public USBEndpoint { -public: - InterruptEp(int addr, uint8_t ep, uint16_t size, int lowSpeed=0); -}; - -class IsochronousEp : public USBEndpoint { -public: - IsochronousEp(int addr, uint8_t ep, uint16_t size); - void reset(int delay_ms = 100); - HCITD* isochronousReveive(int millisec=osWaitForever); - int isochronousSend(uint8_t* buf, int len, int millisec=osWaitForever); - HCITD* get_queue_HCITD(int millisec); - uint16_t m_PacketSize; -private: - HCITD* new_HCITD(USBEndpoint* obj); - int m_itd_queue_count; - uint16_t m_FrameNumber; - int m_FrameCount; // 1-8 -}; - -class EndpointQueue { -public: - EndpointQueue():head(NULL),tail(NULL) {} - void push(USBEndpoint* ep) { - if (head) { - tail->setNextEndpoint(ep); - } else { - head = ep; - } - tail = ep; - ep->setNextEndpoint(NULL); - } - USBEndpoint* pop() { - USBEndpoint* ep = head; - if (ep) { - head = ep->nextEndpoint(); - } - return ep; - } - bool empty() { return head == NULL; } - -private: - USBEndpoint* head; - USBEndpoint* tail; -}; - -
--- a/LPC4088-USBHost/USBHost/USBHALHost.cpp Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,388 +0,0 @@ -/* mbed USBHost Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "USBHALHost.h" -//#define _USB_DBG -#include "BaseUsbHostDebug.h" -#include "BaseUsbHostTest.h" - -#ifndef CTASSERT -template <bool>struct CtAssert; -template <>struct CtAssert<true> {}; -#define CTASSERT(A) CtAssert<A>(); -#endif - -#ifdef _USB_DBG -#define USB_DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n");} while(0); -#define USB_DBG_HEX(A,B) debug_hex(A,B) -void debug_hex(uint8_t* buf, int size); -#else -#define USB_DBG(...) while(0) -#define USB_DBG_HEX(A,B) while(0) -#endif - -#ifdef _USB_TEST -#define USB_TEST_ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);}; -#define USB_TEST_ASSERT_FALSE(A) USB_TEST_ASSERT(!(A)) -#else -#define USB_TEST_ASSERT(A) while(0) -#define USB_TEST_ASSERT_FALSE(A) while(0) -#endif - -#define USB_INFO(...) do{fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n");}while(0); - -// bits of the USB/OTG clock control register -#define HOST_CLK_EN (1<<0) -#define DEV_CLK_EN (1<<1) -#define PORTSEL_CLK_EN (1<<3) -#define AHB_CLK_EN (1<<4) - -// bits of the USB/OTG clock status register -#define HOST_CLK_ON (1<<0) -#define DEV_CLK_ON (1<<1) -#define PORTSEL_CLK_ON (1<<3) -#define AHB_CLK_ON (1<<4) - -// we need host clock, OTG/portsel clock and AHB clock -#define CLOCK_MASK (HOST_CLK_EN | PORTSEL_CLK_EN | AHB_CLK_EN) -#define FI 0x2EDF /* 12000 bits per frame (-1) */ -#define DEFAULT_FMINTERVAL ((((6 * (FI - 210)) / 7) << 16) | FI) - -USBHALHost* USBHALHost::instHost; - -USBHALHost::USBHALHost() { - instHost = this; -} - -void USBHALHost::init() { - NVIC_DisableIRQ(USB_IRQn); - m_pHcca = new HCCA(); - init_hw_ohci(m_pHcca); - ResetRootHub(); - NVIC_SetVector(USB_IRQn, (uint32_t)_usbisr); - NVIC_SetPriority(USB_IRQn, 0); - NVIC_EnableIRQ(USB_IRQn); - -#ifndef BASE_USBHOST - USB_INFO("Simple USBHost Library for EA LPC4088 QSB"); - bool lowSpeed = false; - addDevice(NULL, 0, lowSpeed); -#endif // BASE_USBHOST -} - -void USBHALHost::init_hw_ohci(HCCA* pHcca) { - LPC_SC->PCONP &= ~(1UL<<31); //Cut power - wait(1); - LPC_SC->PCONP |= (1UL<<31); // turn on power for USB - LPC_USB->USBClkCtrl |= CLOCK_MASK; // Enable USB host clock, port selection and AHB clock - // Wait for clocks to become available - while ((LPC_USB->USBClkSt & CLOCK_MASK) != CLOCK_MASK) - ; - LPC_USB->OTGStCtrl |= 1; - LPC_USB->USBClkCtrl &= ~PORTSEL_CLK_EN; - -#if defined(TARGET_LPC1768) - LPC_PINCON->PINSEL1 &= ~((3<<26) | (3<<28)); - LPC_PINCON->PINSEL1 |= ((1<<26)|(1<<28)); // 0x14000000 -#elif defined(TARGET_LPC4088) - LPC_IOCON->P0_29 = 0x01; // USB_D+1 - LPC_IOCON->P0_30 = 0x01; // USB_D-1 - // DO NOT CHANGE P1_19. -#else -#error "target error" -#endif - DBG("initialize OHCI\n"); - wait_ms(100); /* Wait 50 ms before apply reset */ - TEST_ASSERT((LPC_USB->HcRevision&0xff) == 0x10); // check revision - LPC_USB->HcControl = 0; /* HARDWARE RESET */ - LPC_USB->HcControlHeadED = 0; /* Initialize Control list head to Zero */ - LPC_USB->HcBulkHeadED = 0; /* Initialize Bulk list head to Zero */ - /* SOFTWARE RESET */ - LPC_USB->HcCommandStatus = OR_CMD_STATUS_HCR; - LPC_USB->HcFmInterval = DEFAULT_FMINTERVAL; /* Write Fm Interval and Largest Data Packet Counter */ - LPC_USB->HcPeriodicStart = FI*90/100; - /* Put HC in operational state */ - LPC_USB->HcControl = (LPC_USB->HcControl & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER; - LPC_USB->HcRhStatus = OR_RH_STATUS_LPSC; /* Set Global Power */ - TEST_ASSERT(pHcca); - for (int i = 0; i < 32; i++) { - pHcca->InterruptTable[i] = NULL; - } - LPC_USB->HcHCCA = reinterpret_cast<uint32_t>(pHcca); - LPC_USB->HcInterruptStatus |= LPC_USB->HcInterruptStatus; /* Clear Interrrupt Status */ - LPC_USB->HcInterruptEnable = OR_INTR_ENABLE_MIE|OR_INTR_ENABLE_WDH|OR_INTR_ENABLE_FNO; - - LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC; - LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC; -} - -void USBHALHost::ResetRootHub() { - wait_ms(100); /* USB 2.0 spec says at least 50ms delay before port reset */ - LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRS; // Initiate port reset - DBG("Before loop\n"); - while (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRS) - ; - LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC; // ...and clear port reset signal - DBG("After loop\n"); - wait_ms(200); /* Wait for 100 MS after port reset */ -} - -void USBHALHost::enable(ENDPOINT_TYPE type) { - switch(type) { - case CONTROL_ENDPOINT: - LPC_USB->HcCommandStatus |= OR_CMD_STATUS_CLF; - LPC_USB->HcControl |= OR_CONTROL_CLE; - break; - case ISOCHRONOUS_ENDPOINT: - LPC_USB->HcControl |= OR_CONTROL_PLE; - break; - case BULK_ENDPOINT: - LPC_USB->HcCommandStatus |= OR_CMD_STATUS_BLF; - LPC_USB->HcControl |= OR_CONTROL_BLE; - break; - case INTERRUPT_ENDPOINT: - LPC_USB->HcControl |= OR_CONTROL_PLE; - break; - } -} - -void USBHALHost::token_init(USBEndpoint* ep) { - if (ep->m_pED == NULL) { - ep->m_pED = new HCED(ep); - USB_DBG_ED(ep->m_pED); - } - HCED* ed = ep->m_pED; - USBDeviceConnected* dev = ep->getDevice(); - USB_TEST_ASSERT(dev); - if (dev) { - uint8_t devAddr = dev->getAddress(); - USB_DBG("devAddr=%02x", devAddr); - ed->setFunctionAddress(devAddr); - } - uint16_t size = ep->getSize(); - USB_DBG("MaxPacketSize=%d", size); - ed->setMaxPacketSize(size); - if (ed->HeadTd == NULL) { - HCTD* td = new HCTD(ep); - ed->TailTd = td; - ed->HeadTd = td; - switch(ep->getType()) { - case CONTROL_ENDPOINT: - ed->Next = reinterpret_cast<HCED*>(LPC_USB->HcControlHeadED); - LPC_USB->HcControlHeadED = reinterpret_cast<uint32_t>(ed); - break; - case BULK_ENDPOINT: - ed->Next = reinterpret_cast<HCED*>(LPC_USB->HcBulkHeadED); - LPC_USB->HcBulkHeadED = reinterpret_cast<uint32_t>(ed); - break; - case INTERRUPT_ENDPOINT: - HCCA* pHcca = reinterpret_cast<HCCA*>(LPC_USB->HcHCCA); - ed->Next = pHcca->InterruptTable[0]; - pHcca->InterruptTable[0] = ed; - break; - } - USB_DBG_ED(ed); - } -} - -int USBHALHost::token_setup(USBEndpoint* ep, SETUP_PACKET* setup, uint16_t wLength) { - token_init(ep); - HCED* ed = ep->m_pED; - HCTD* td = ed->TailTd; - setup->wLength = wLength; - TBUF* tbuf = new(sizeof(SETUP_PACKET))TBUF(setup, sizeof(SETUP_PACKET)); - td->transfer(tbuf, sizeof(SETUP_PACKET)); - td->Control |= TD_TOGGLE_0|TD_SETUP; - HCTD* blank = new HCTD(ep); - td->Next = blank; - ed->TailTd = blank; - //DBG_ED(ed); - enable(ep->getType()); - - td = ep->get_queue_HCTD(); - TEST_ASSERT(td); - int result = td->getLengthTransferred(); - DBG_TD(td); - delete tbuf; - delete td; - return result; -} - -int USBHALHost::token_in(USBEndpoint* ep, uint8_t* data, int size, int retryLimit) { - token_init(ep); - HCED* ed = ep->m_pED; - HCTD* td = ed->TailTd; - TBUF* tbuf = NULL; - if (data != NULL) { - tbuf = new(size)TBUF(); - td->transfer(tbuf, size); - } - td->Control |= TD_IN; - HCTD* blank = new HCTD(ep); - td->Next = blank; - ed->TailTd = blank; - USB_DBG_ED_IF(ed->EndpointNumber()==0, ed); // control transfer - enable(ep->getType()); - - td = ep->get_queue_HCTD(); - TEST_ASSERT(td); - if (data != NULL) { - memcpy(data, tbuf->buf, size); - delete tbuf; - } - int result = td->getLengthTransferred(); - delete td; - return result; -} - -int USBHALHost::token_out(USBEndpoint* ep, const uint8_t* data, int size, int retryLimit) { - token_init(ep); - HCED* ed = ep->m_pED; - HCTD* td = ed->TailTd; - TBUF* tbuf = NULL; - if (data != NULL) { - tbuf = new(size)TBUF(data, size); - td->transfer(tbuf, size); - } - td->Control |= TD_OUT; - HCTD* blank = new HCTD(ep); - td->Next = blank; - ed->TailTd = blank; - DBG_ED(ed); - enable(ep->getType()); - - td = ep->get_queue_HCTD(); - TEST_ASSERT(td); - if (data != NULL) { - delete tbuf; - } - int result = td->getLengthTransferred(); - delete td; - return result; -} - -void USBHALHost::token_inNB(USBEndpoint* ep, uint8_t* data, int size) { - token_init(ep); - HCED* ed = ep->m_pED; - HCTD* td = ed->TailTd; - TBUF* tbuf = new(size)TBUF(); - td->transfer(tbuf, size); - td->Control |= TD_IN; - HCTD* blank = new HCTD(ep); - td->Next = blank; - ed->TailTd = blank; - enable(ep->getType()); -} - -USB_TYPE USBHALHost::token_inNB_result(USBEndpoint* ep) { - HCTD* td = ep->get_queue_HCTD(0); - if (td) { - int len = td->getLengthTransferred(); - TBUF* tbuf = (TBUF*)td->buf_top; - memcpy(ep->getBufStart(), tbuf->buf, len); - ep->setLengthTransferred(len); - delete td; - delete tbuf; - return USB_TYPE_OK; - } - return USB_TYPE_PROCESSING; -} - -void USBHALHost::_usbisr(void) { - if (instHost) { - instHost->UsbIrqhandler(); - } -} - -HCTD* td_reverse(HCTD* td) -{ - HCTD* result = NULL; - HCTD* next; - while(td) { - next = const_cast<HCTD*>(td->Next); - td->Next = result; - result = td; - td = next; - } - return result; -} - -void USBHALHost::UsbIrqhandler() { - if (!(LPC_USB->HcInterruptStatus & LPC_USB->HcInterruptEnable)) { - return; - } - m_report_irq++; - uint32_t status = LPC_USB->HcInterruptStatus; - if (status & OR_INTR_STATUS_FNO) { - m_report_FNO++; - } - if (status & OR_INTR_STATUS_WDH) { - union { - HCTD* done_td; - uint32_t lsb; - }; - done_td = const_cast<HCTD*>(m_pHcca->DoneHead); - TEST_ASSERT(done_td); - m_pHcca->DoneHead = NULL; // reset - if (lsb & 1) { // error ? - lsb &= ~1; - } - HCTD* td = td_reverse(done_td); - while(td) { - USBEndpoint* ep = td->ep; - TEST_ASSERT(ep); - if (ep) { - ep->irqWdhHandler(td); - } - td = td->Next; - } - m_report_WDH++; - } - LPC_USB->HcInterruptStatus = status; // Clear Interrrupt Status -} - -HCTD::HCTD(USBEndpoint* obj) { - CTASSERT(sizeof(HCTD) == 36); - TEST_ASSERT(obj); - Control = TD_CC|TD_ROUNDING; - CurrBufPtr = NULL; - Next = NULL; - BufEnd = NULL; - buf_top = NULL; - buf_size = 0; - ep = obj; -} - -HCED::HCED(USBEndpoint* ep) { - USBDeviceConnected* dev = ep->getDevice(); - int devAddr = 0; - bool lowSpeed = false; - if (dev) { - devAddr = dev->getAddress(); - lowSpeed = dev->getSpeed(); - } - int ep_number = ep->getAddress(); - int MaxPacketSize = ep->getSize(); - Control = devAddr | /* USB address */ - ((ep_number & 0x7F) << 7) | /* Endpoint address */ - (ep_number!=0?(((ep_number&0x80)?2:1) << 11):0)| /* direction : Out = 1, 2 = In */ - ((lowSpeed?1:0) << 13) | /* speed full=0 low=1 */ - (MaxPacketSize << 16); /* MaxPkt Size */ - TailTd = NULL; - HeadTd = NULL; - Next = NULL; -} -
--- a/LPC4088-USBHost/USBHost/USBHALHost.h Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,272 +0,0 @@ -/* mbed USBHost Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once -#include "mbed.h" -#include "USBHostTypes.h" -#include "USBEndpoint.h" - -#if defined(TARGET_LPC4088) -#define HcRevision Revision -#define HcControl Control -#define HcCommandStatus CommandStatus -#define HcInterruptStatus InterruptStatus -#define HcInterruptEnable InterruptEnable -#define HcHCCA HCCA -#define HcControlHeadED ControlHeadED -#define HcBulkHeadED BulkHeadED -#define HcFmInterval FmInterval -#define HcFmNumber FmNumber -#define HcPeriodicStart PeriodicStart -#define HcRhStatus RhStatus -#define HcRhPortStatus1 RhPortStatus1 -#define OTGStCtrl StCtrl -#endif -// ------------------ HcControl Register --------------------- -#define OR_CONTROL_PLE 0x00000004 -#define OR_CONTROL_IE 0x00000008 -#define OR_CONTROL_CLE 0x00000010 -#define OR_CONTROL_BLE 0x00000020 -#define OR_CONTROL_HCFS 0x000000C0 -#define OR_CONTROL_HC_OPER 0x00000080 -// ----------------- HcCommandStatus Register ----------------- -#define OR_CMD_STATUS_HCR 0x00000001 -#define OR_CMD_STATUS_CLF 0x00000002 -#define OR_CMD_STATUS_BLF 0x00000004 -// --------------- HcInterruptStatus Register ----------------- -#define OR_INTR_STATUS_WDH 0x00000002 -#define OR_INTR_STATUS_UE 0x00000010 -#define OR_INTR_STATUS_FNO 0x00000020 -#define OR_INTR_STATUS_RHSC 0x00000040 -// --------------- HcInterruptEnable Register ----------------- -#define OR_INTR_ENABLE_WDH 0x00000002 -#define OR_INTR_ENABLE_FNO 0x00000020 -#define OR_INTR_ENABLE_RHSC 0x00000040 -#define OR_INTR_ENABLE_MIE 0x80000000 -// ---------------- HcRhDescriptorA Register ------------------ -#define OR_RH_STATUS_LPSC 0x00010000 -#define OR_RH_STATUS_DRWE 0x00008000 -// -------------- HcRhPortStatus[1:NDP] Register -------------- -#define OR_RH_PORT_CCS 0x00000001 -#define OR_RH_PORT_PRS 0x00000010 -#define OR_RH_PORT_CSC 0x00010000 -#define OR_RH_PORT_PRSC 0x00100000 - -// TRANSFER DESCRIPTOR CONTROL FIELDS -#define TD_ROUNDING (uint32_t)(0x00040000) /* Buffer Rounding */ -#define TD_SETUP (uint32_t)(0x00000000) /* Direction of Setup Packet */ -#define TD_IN (uint32_t)(0x00100000) /* Direction In */ -#define TD_OUT (uint32_t)(0x00080000) /* Direction Out */ -#define TD_DELAY_INT(x) (uint32_t)((x) << 21) /* Delay Interrupt */ -#define TD_DI (uint32_t)(7<<21) /* desable interrupt */ -#define TD_TOGGLE_0 (uint32_t)(0x02000000) /* Toggle 0 */ -#define TD_TOGGLE_1 (uint32_t)(0x03000000) /* Toggle 1 */ -#define TD_CC (uint32_t)(0xF0000000) /* Completion Code */ - -struct SETUP_PACKET { - uint8_t bmRequestType; - uint8_t bRequest; - uint16_t wValue; - uint16_t wIndex; - uint16_t wLength; - SETUP_PACKET(uint8_t RequestType, uint8_t Request, uint16_t Value, uint16_t Index, uint16_t Length) { - bmRequestType = RequestType; - bRequest = Request; - wValue = Value; - wIndex = Index; - wLength = Length; - } -}; - -void* usb_ram_malloc(size_t size, int aligment); // BaseUsbHostLib.cpp -void usb_ram_free(void* p); - -struct TBUF { - uint8_t buf[0]; - TBUF(const void* data = NULL, int size = 0) { - if (size > 0) { - memcpy(buf, data, size); - } - } - void* operator new(size_t size, int buf_size) { return usb_ram_malloc(size+buf_size, 4); } - void operator delete(void* p) { usb_ram_free(p); } -}; - -struct HCTD { // HostController Transfer Descriptor - __IO uint32_t Control; // +0 Transfer descriptor control - __IO uint8_t* CurrBufPtr; // +4 Physical address of current buffer pointer - HCTD* Next; // +8 Physical pointer to next Transfer Descriptor - uint8_t* BufEnd; // +12 Physical address of end of buffer - uint8_t* buf_top; // +16 Buffer start address - uint16_t buf_size; // +20 buffer size size - uint8_t _dummy[10]; // +22 dummy - USBEndpoint* ep; // +32 endpoint object - // +36 - HCTD(USBEndpoint* obj); - void* operator new(size_t size) { return usb_ram_malloc(size, 16); } - void operator delete(void* p) { usb_ram_free(p); } - - void transfer(TBUF* tbuf, int len) { - CurrBufPtr = tbuf->buf; - buf_top = tbuf->buf; - buf_size = len; - BufEnd = const_cast<uint8_t*>(tbuf->buf)+len-1; - } - int getLengthTransferred() { - if (CurrBufPtr) { - return CurrBufPtr - buf_top; - } - return buf_size; - } - int status() { - if (CurrBufPtr) { - return CurrBufPtr - buf_top; - } - return buf_size; - } - - uint8_t ConditionCode() { - return Control>>28; - } -}; - -struct HCITD { // HostController Isochronous Transfer Descriptor - __IO uint32_t Control; // +0 Transfer descriptor control - uint8_t* BufferPage0; // +4 Buffer Page 0 - HCITD* Next; // +8 Physical pointer to next Isochronous Transfer Descriptor - uint8_t* BufferEnd; // +12 buffer End - __IO uint16_t OffsetPSW[8]; // +16 Offset/PSW - USBEndpoint* ep; // +32 endpoint object - __IO uint8_t buf[0]; // +36 buffer - // +36 - HCITD(USBEndpoint* obj, uint16_t FrameNumber, int FrameCount, uint16_t PacketSize); - void* operator new(size_t size, int buf_size) { return usb_ram_malloc(size+buf_size, 32); } - void operator delete(void* p) { usb_ram_free(p); } - - uint16_t StartingFrame() { - return Control & 0xffff; - } - - uint8_t FrameCount() { - return ((Control>>24)&7)+1; - } - - uint8_t ConditionCode() { - return Control>>28; - } -}; - -struct HCED { // HostController EndPoint Descriptor - __IO uint32_t Control; // +0 Endpoint descriptor control - HCTD* TailTd; // +4 Physical address of tail in Transfer descriptor list - __IO HCTD* HeadTd; // +8 Physcial address of head in Transfer descriptor list - HCED* Next; // +12 Physical address of next Endpoint descriptor - // +16 - HCED(USBEndpoint* ep); - HCED(int addr, uint8_t ep, uint16_t size, int lowSpeed) { - Control = addr | /* USB address */ - ((ep & 0x7F) << 7) | /* Endpoint address */ - (ep!=0?(((ep&0x80)?2:1) << 11):0)| /* direction : Out = 1, 2 = In */ - ((lowSpeed?1:0) << 13) | /* speed full=0 low=1 */ - (size << 16); /* MaxPkt Size */ - TailTd = NULL; - HeadTd = NULL; - Next = NULL; - } - - void* operator new(size_t size) { return usb_ram_malloc(size, 16); } - void operator delete(void* p) { usb_ram_free(p); } - - uint8_t FunctionAddress() { - return Control & 0x7f; - } - - uint8_t EndpointNumber() { - return (Control>>7) & 0x7f; - } - - int Speed() { - return (Control>>13)&1; - } - - void setFunctionAddress(int addr) { - Control &= ~0x7f; - Control |= addr; - } - - void setMaxPacketSize(uint16_t size) { - Control &= ~0xffff0000; - Control |= size<<16; - } - void setToggleDATA1() { - uint32_t c = reinterpret_cast<uint32_t>(HeadTd); - c |= 0x02; - HeadTd = reinterpret_cast<HCTD*>(c); - } -}; - -struct HCCA { // Host Controller Communication Area - HCED* InterruptTable[32]; // +0 Interrupt Table - __IO uint16_t FrameNumber;// +128 Frame Number - __IO uint16_t Pad1; // +130 - __IO HCTD* DoneHead; // +132 Done Head - uint8_t Reserved[116]; // +136 Reserved for future use - uint8_t Unknown[4]; // +252 Unused - // +256 - void* operator new(size_t size) { return usb_ram_malloc(size, 256); } - void operator delete(void* p) { usb_ram_free(p); } -}; - -class USBHALHost { -public: - uint8_t LastStatus; - uint8_t prev_LastStatus; - static void enable(ENDPOINT_TYPE type); - -protected: - USBHALHost(); - void init(); - void init_hw_ohci(HCCA* pHcca); - void ResetRootHub(); - virtual bool addDevice(USBDeviceConnected* parent, int port, bool lowSpeed) = 0; - //void setAddr(int addr, bool lowSpeed = false); - //void setEndpoint(); - //void token_transfer_init(); - void token_init(USBEndpoint* ep); - int token_setup(USBEndpoint* ep, SETUP_PACKET* setup, uint16_t wLength = 0); - int token_in(USBEndpoint* ep, uint8_t* data = NULL, int size = 0, int retryLimit = 0); - int token_out(USBEndpoint* ep, const uint8_t* data = NULL, int size = 0, int retryLimit = 0); - void token_inNB(USBEndpoint* ep, uint8_t* data, int size); - USB_TYPE token_inNB_result(USBEndpoint* ep); - //void token_ready(); - // report - uint32_t m_report_irq; - uint32_t m_report_RHSC; - uint32_t m_report_FNO; - uint32_t m_report_WDH; - uint32_t m_report_sp; - -private: - static void _usbisr(void); - void UsbIrqhandler(); - HCCA* m_pHcca; - //__IO bool attach_done; - //__IO bool token_done; - bool wait_attach(); - bool root_lowSpeed; - static USBHALHost * instHost; -}; -
--- a/LPC4088-USBHost/USBHost/USBHost.h Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,269 +0,0 @@ -/* mbed USBHost Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once -#include "mbed.h" -#include "USBHALHost.h" -#include "USBDeviceConnected.h" -#include "IUSBEnumerator.h" -#include "USBHostConf.h" -#include "dbg.h" -#include "myvector.h" - -// USB STANDARD REQUEST DEFINITIONS -#define USB_DESCRIPTOR_TYPE_STRING 3 -#define USB_DESCRIPTOR_TYPE_HUB 0x29 - -#pragma pack(push,1) -struct StringDescriptor {// offset - uint8_t bLength; // +0 - uint8_t bDescriptorType; // +1 - char bString[0]; // +2 -}; -#pragma pack(pop) - -/** -* USBHost class -* This class is a singleton. All drivers have a reference on the static USBHost instance -*/ -class USBHost : public USBHALHost { -public: - /** - * Static method to create or retrieve the single USBHost instance - */ - static USBHost* getHostInst(); - - /** - * Control read: setup stage, data stage and status stage - * - * @param dev the control read will be done for this device - * @param requestType request type - * @param request request - * @param value value - * @param index index - * @param buf pointer on a buffer where will be store the data received - * @param len length of the transfer - * - * @returns status of the control read - */ - USB_TYPE controlRead(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len); - - /** - * Control write: setup stage, data stage and status stage - * - * @param dev the control write will be done for this device - * @param requestType request type - * @param request request - * @param value value - * @param index index - * @param buf pointer on a buffer which will be written - * @param len length of the transfer - * - * @returns status of the control write - */ - USB_TYPE controlWrite(USBDeviceConnected * dev, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t * buf, uint32_t len); - - /** - * Bulk read - * - * @param dev the bulk transfer will be done for this device - * @param ep USBEndpoint which will be used to read a packet - * @param buf pointer on a buffer where will be store the data received - * @param len length of the transfer - * @param blocking if true, the read is blocking (wait for completion) - * - * @returns status of the bulk read - */ - USB_TYPE bulkRead(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true); - - /** - * Bulk write - * - * @param dev the bulk transfer will be done for this device - * @param ep USBEndpoint which will be used to write a packet - * @param buf pointer on a buffer which will be written - * @param len length of the transfer - * @param blocking if true, the write is blocking (wait for completion) - * - * @returns status of the bulk write - */ - USB_TYPE bulkWrite(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true); - - /** - * Interrupt read - * - * @param dev the interrupt transfer will be done for this device - * @param ep USBEndpoint which will be used to write a packet - * @param buf pointer on a buffer which will be written - * @param len length of the transfer - * @param blocking if true, the read is blocking (wait for completion) - * - * @returns status of the interrupt read - */ - USB_TYPE interruptRead(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true); - - /** - * Interrupt write - * - * @param dev the interrupt transfer will be done for this device - * @param ep USBEndpoint which will be used to write a packet - * @param buf pointer on a buffer which will be written - * @param len length of the transfer - * @param blocking if true, the write is blocking (wait for completion) - * - * @returns status of the interrupt write - */ - USB_TYPE interruptWrite(USBDeviceConnected * dev, USBEndpoint * ep, uint8_t * buf, uint32_t len, bool blocking = true); - - /** - * Enumerate a device. - * - * @param dev device which will be enumerated - * - * @returns status of the enumeration - */ - USB_TYPE enumerate(USBDeviceConnected * dev, IUSBEnumerator* pEnumerator); - - /** - * Get a device - * - * @param index index of the device which will be returned - * - * @returns pointer on the "index" device - */ - USBDeviceConnected * getDevice(uint8_t index) { - return index < DeviceLists.size() ? DeviceLists[index] : NULL; - } - - /** - * register a driver into the host associated with a callback function called when the device is disconnected - * - * @param dev device - * @param intf interface number - * @param tptr pointer to the object to call the member function on - * @param mptr pointer to the member function to be called - */ - template<typename T> - void registerDriver(USBDeviceConnected * dev, uint8_t intf, T* tptr, void (T::*mptr)(void)) { - } - - // LPC4088-USBHost extensions - USB_TYPE controlRead(USBEndpoint* ep, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t* buf, uint32_t len); - USB_TYPE controlWrite(USBEndpoint* ep, uint8_t requestType, uint8_t request, uint32_t value, uint32_t index, uint8_t* buf, uint32_t len); - static void poll(); - -private: - USBHost(); - static USBHost* inst; - virtual bool addDevice(USBDeviceConnected* parent, int port, bool lowSpeed); - void root_enumeration(USBDeviceConnected* dev); - void parseConfDescr(USBDeviceConnected* dev, uint8_t* conf_descr, uint32_t len, IUSBEnumerator* pEnumerator); - myvector<USBDeviceConnected*>DeviceLists; - - void task(); - EndpointQueue ep_queue; - - // USB HUB - bool Hub(USBDeviceConnected* dev); - int SetPortPower(USBDeviceConnected* dev, int port); - int ClearPortPower(USBDeviceConnected* dev, int port); - int PortReset(USBDeviceConnected* dev, int port); - int SetPortFeature(USBDeviceConnected* dev, int feature, int index); - int ClearPortFeature(USBDeviceConnected* dev, int feature, int index); - int SetPortReset(USBDeviceConnected* dev, int port); - int GetPortStatus(USBDeviceConnected* dev, int port, uint32_t* status); -}; - -// --- HUB -------------------------------------------------- -class UsbHub { -public: - UsbHub(ControlEp* ctlEp = NULL); - static bool check(ControlEp* ctlEp); - USB_TYPE SetPortPower(int port); - USB_TYPE ClearPortPower(int port); - myvector<ControlEp*> PortEp; - template<class T> ControlEp* search(int skip = 0) { - for(int i = 0; i < PortEp.size(); i++) { - if (T::check(PortEp[i])) { - if (skip-- <= 0) { - return PortEp[i]; - } - } - } - return NULL; - } - template<class T> ControlEp* assign(int port) { - if (port >= 0 && port < PortEp.size()) { - return PortEp[port]; - } - return NULL; - } -private: - USB_TYPE PortReset(int port); - USB_TYPE SetPortFeature(int feature, int index); - USB_TYPE ClearPortFeature(int feature, int index); - USB_TYPE SetPortReset(int port); - USB_TYPE GetPortStatus(int port, uint32_t* status); - ControlEp* m_ctlEp; -}; - -// --- UVC -------------------------------------------------- -#define _30FPS 333333 -#define _25FPS 400000 -#define _20FPS 500000 -#define _15FPS 666666 -#define _10FPS 1000000 -#define _5FPS 2000000 -#define _1FPS 10000000 - -#define SET_CUR 0x01 -#define GET_CUR 0x81 -#define GET_MIN 0x82 -#define GET_MAX 0x83 -#define GET_RES 0x84 -#define GET_LEN 0x85 -#define GET_INFO 0x86 -#define GET_DEF 0x87 - -#define VS_PROBE_CONTROL 0x01 -#define VS_COMMIT_CONTROL 0x02 - -class BaseUvc { -public: - BaseUvc(){clearOnResult();} - void poll(int millisec=osWaitForever); - USB_TYPE Control(int req, int cs, int index, uint8_t* buf, int size); - ControlEp* m_ctlEp; - IsochronousEp* m_isoEp; - uint32_t report_cc_count[16]; // ConditionCode - uint32_t report_ps_cc_count[16]; // Packt Status ConditionCode - // callback - void onResult(uint16_t frame, uint8_t* buf, int len); - void setOnResult( void (*pMethod)(uint16_t, uint8_t*, int) ); - class CDummy; - template<class T> - void setOnResult( T* pItem, void (T::*pMethod)(uint16_t, uint8_t*, int) ) - { - m_pCb = NULL; - m_pCbItem = (CDummy*) pItem; - m_pCbMeth = (void (CDummy::*)(uint16_t, uint8_t*, int)) pMethod; - } - void clearOnResult(); - CDummy* m_pCbItem; - void (CDummy::*m_pCbMeth)(uint16_t, uint8_t*, int); - void (*m_pCb)(uint16_t, uint8_t*, int); -}; -
--- a/LPC4088-USBHost/USBHost/USBHostConf.h Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -/* mbed USBHost Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef USBHOST_CONF_H -#define USBHOST_CONF_H - -/* -* Maximum number of devices that can be connected -* to the usb host -*/ -#define MAX_DEVICE_CONNECTED 5 - -/* -* Maximum of Hub connected to the usb host -*/ -#define MAX_HUB_NB 2 - -/* -* Maximum number of ports on a USB hub -*/ -#define MAX_HUB_PORT 4 - -/* -* Enable USBHostMSD -*/ -#define USBHOST_MSD 1 - -/* -* Enable USBHostKeyboard -*/ -#define USBHOST_KEYBOARD 1 - -/* -* Enable USBHostMouse -*/ -#define USBHOST_MOUSE 1 - -/* -* Enable USBHostSerial or USBHostMultiSerial (if set > 1) -*/ -#define USBHOST_SERIAL 1 - -/* -* Enable USB3Gmodule -*/ -#define USBHOST_3GMODULE 1 - -/* -* Maximum number of interfaces of a usb device -*/ -#define MAX_INTF 4 - -/* -* usb_thread stack size -*/ -#define USB_THREAD_STACK (256*4 + MAX_HUB_NB*256*4) - -#endif
--- a/LPC4088-USBHost/USBHost/USBHostHub.cpp Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,112 +0,0 @@ -#include "USBHost.h" - -#define PORT_CONNECTION 0 -#define PORT_ENABLE 1 -#define PORT_SUSPEND 2 -#define PORT_OVER_CURRENT 3 -#define PORT_RESET 4 -#define PORT_POWER 8 -#define PORT_LOW_SPEED 9 - -#define C_PORT_CONNECTION 16 -#define C_PORT_ENABLE 17 -#define C_PORT_SUSPEND 18 -#define C_PORT_OVER_CURRENT 19 -#define C_PORT_RESET 20 - -bool USBHost::Hub(USBDeviceConnected* dev) { - USB_INFO("New HUB: VID:%04x PID:%04x [dev: %p]", dev->getVid(), dev->getPid(), dev); - HubDescriptor hubdesc; - // get HUB descriptor - int rc = controlRead(dev, - USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS, - GET_DESCRIPTOR, - 0x29 << 8, 0, reinterpret_cast<uint8_t*>(&hubdesc), - sizeof(HubDescriptor)); - USB_TEST_ASSERT(rc == USB_TYPE_OK); - if (rc != USB_TYPE_OK) { - return false; - } - USB_DBG_HEX((uint8_t*)&hubdesc, sizeof(hubdesc)); - - uint32_t status; - rc = controlRead( dev, - 0xa0, 0, 0, 0, reinterpret_cast<uint8_t*>(&status), 4); - USB_TEST_ASSERT(rc == USB_TYPE_OK); - if (rc != USB_TYPE_OK) { - return false; - } - USB_DBG("HUB STATUS: %08X\n", status); - - for(int i = 1; i <= hubdesc.bNbrPorts; i++) { - SetPortPower(dev, i); // power on - wait_ms(hubdesc.bPwrOn2PwrGood*2); - uint32_t status; - GetPortStatus(dev, i, &status); - USB_DBG("port: %d status: %08X\n", i, status); - if (status & 0x010000) { // Connect Status Change, has changed - USB_TEST_ASSERT(status & 0x000001); - ClearPortFeature(dev, C_PORT_CONNECTION, i); - int lowSpeed = 0; - if (status & 0x0200) { - lowSpeed = 1; - } - PortReset(dev, i); - if (!addDevice(dev, i, lowSpeed)) { - ClearPortPower(dev, i); // power off - } - } else { - ClearPortPower(dev, i); // power off - } - } - return false; -} - - -int USBHost::SetPortPower(USBDeviceConnected* dev, int port) -{ - return SetPortFeature(dev, PORT_POWER, port); -} - -int USBHost::ClearPortPower(USBDeviceConnected* dev, int port) -{ - return ClearPortFeature(dev, PORT_POWER, port); -} - -int USBHost::SetPortFeature(USBDeviceConnected* dev, int feature, int index) -{ - return controlWrite(dev, 0x23, SET_FEATURE,feature,index,0,0); -} - -int USBHost::ClearPortFeature(USBDeviceConnected* dev, int feature, int index) -{ - return controlWrite(dev, 0x23, CLEAR_FEATURE,feature,index,0,0); -} - -int USBHost::SetPortReset(USBDeviceConnected* dev, int port) -{ - return SetPortFeature(dev, PORT_RESET, port); -} - -int USBHost::GetPortStatus(USBDeviceConnected* dev, int port, uint32_t* status) -{ - return controlRead(dev, 0xa3, GET_STATUS, 0, port, (uint8_t*)status, 4); -} - -int USBHost::PortReset(USBDeviceConnected* dev, int port) -{ - USB_DBG("%p port=%d\n", this, port); - USB_TEST_ASSERT(port >= 1); - SetPortReset(dev, port); - // wait reset - for(int i = 0; i < 100; i++) { - uint32_t status; - GetPortStatus(dev, port, &status); - USB_DBG("RESET port: %d status: %08X\n", port, status); - if (status & 0x100000) { // Reset change , Reset complete - return USB_TYPE_OK; - } - wait_ms(5); - } - return USB_TYPE_ERROR; -}
--- a/LPC4088-USBHost/USBHost/USBHostTypes.h Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,167 +0,0 @@ -/* mbed USBHost Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef USB_INC_H -#define USB_INC_H - -#include "mbed.h" -#include "toolchain.h" - -enum USB_TYPE { - USB_TYPE_OK = 0, - - // completion code - USB_TYPE_CRC_ERROR = 1, - USB_TYPE_BIT_STUFFING_ERROR = 2, - USB_TYPE_DATA_TOGGLE_MISMATCH_ERROR = 3, - USB_TYPE_STALL_ERROR = 4, - USB_TYPE_DEVICE_NOT_RESPONDING_ERROR = 5, - USB_TYPE_PID_CHECK_FAILURE_ERROR = 6, - USB_TYPE_UNEXPECTED_PID_ERROR = 7, - USB_TYPE_DATA_OVERRUN_ERROR = 8, - USB_TYPE_DATA_UNDERRUN_ERROR = 9, - USB_TYPE_RESERVED = 9, - USB_TYPE_RESERVED_ = 10, - USB_TYPE_BUFFER_OVERRUN_ERROR = 12, - USB_TYPE_BUFFER_UNDERRUN_ERROR = 13, - - // general usb state - USB_TYPE_DISCONNECTED = 14, - USB_TYPE_FREE = 15, - USB_TYPE_IDLE = 16, - USB_TYPE_PROCESSING = 17, - - USB_TYPE_ERROR = 18, -}; - - -enum ENDPOINT_DIRECTION { - OUT = 1, - IN -}; - -enum ENDPOINT_TYPE { - CONTROL_ENDPOINT = 0, - ISOCHRONOUS_ENDPOINT, - BULK_ENDPOINT, - INTERRUPT_ENDPOINT -}; - -#define AUDIO_CLASS 0x01 -#define CDC_CLASS 0x02 -#define HID_CLASS 0x03 -#define MSD_CLASS 0x08 -#define HUB_CLASS 0x09 -#define SERIAL_CLASS 0x0A - -#define DEVICE_DESCRIPTOR (1) -#define CONFIGURATION_DESCRIPTOR (2) -#define INTERFACE_DESCRIPTOR (4) -#define ENDPOINT_DESCRIPTOR (5) -#define HID_DESCRIPTOR (33) - -// ----------- Control RequestType Fields ----------- -#define USB_DEVICE_TO_HOST 0x80 -#define USB_HOST_TO_DEVICE 0x00 -#define USB_REQUEST_TYPE_CLASS 0x20 -#define USB_REQUEST_TYPE_STANDARD 0x00 -#define USB_RECIPIENT_DEVICE 0x00 -#define USB_RECIPIENT_INTERFACE 0x01 -#define USB_RECIPIENT_ENDPOINT 0x02 - -// -------------- USB Standard Requests -------------- -#define GET_STATUS 0x00 -#define SET_FEATURE 0x03 -#define SET_ADDRESS 0x05 -#define GET_DESCRIPTOR 0x06 -#define SET_CONFIGURATION 0x09 -#define SET_INTERFACE 0x0b -#define CLEAR_FEATURE 0x01 - -// -------------- USB Descriptor Length -------------- -#define DEVICE_DESCRIPTOR_LENGTH 0x12 -#define CONFIGURATION_DESCRIPTOR_LENGTH 0x09 - -// PID -#define DATA0 0x03 -#define DATA1 0x0b -#define ACK 0x02 -#define STALL 0x0e -#define NAK 0x0a - -#pragma pack(push,1) -typedef struct { - uint8_t bLength; - uint8_t bDescriptorType; - uint16_t bcdUSB; - uint8_t bDeviceClass; - uint8_t bDeviceSubClass; - uint8_t bDeviceProtocol; - uint8_t bMaxPacketSize; - uint16_t idVendor; - uint16_t idProduct; - uint16_t bcdDevice; - uint8_t iManufacturer; - uint8_t iProduct; - uint8_t iSerialNumber; - uint8_t bNumConfigurations; -} PACKED DeviceDescriptor; - -typedef struct { - uint8_t bLength; - uint8_t bDescriptorType; - uint16_t wTotalLength; - uint8_t bNumInterfaces; - uint8_t bConfigurationValue; - uint8_t iConfiguration; - uint8_t bmAttributes; - uint8_t bMaxPower; -} PACKED ConfigurationDescriptor; - -typedef struct { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bInterfaceNumber; - uint8_t bAlternateSetting; - uint8_t bNumEndpoints; - uint8_t bInterfaceClass; - uint8_t bInterfaceSubClass; - uint8_t bInterfaceProtocol; - uint8_t iInterface; -} InterfaceDescriptor; - -typedef struct { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bEndpointAddress; - uint8_t bmAttributes; - uint16_t wMaxPacketSize; - uint8_t bInterval; -} EndpointDescriptor; - -typedef struct { - uint8_t bDescLength; - uint8_t bDescriptorType; - uint8_t bNbrPorts; - uint16_t wHubCharacteristics; - uint8_t bPwrOn2PwrGood; - uint8_t bHubContrCurrent; - uint8_t DeviceRemovable; - uint8_t PortPweCtrlMak; -} HubDescriptor; -#pragma pack(pop) - -#endif
--- a/LPC4088-USBHost/USBHost/dbg.h Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -/* mbed USBHost Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef USB_DEBUG_H -#define USB_DEBUG_H - -//Debug is disabled by default -#ifndef DEBUG -#define DEBUG 3 /*INFO,ERR,WARN*/ -#endif -#ifndef DEBUG2 -#define DEBUG2 0 -#endif -#define DEBUG_TRANSFER 0 -#define DEBUG_EP_STATE 0 -#define DEBUG_EVENT 0 - -#if (DEBUG > 3) -#define USB_DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\r\n");} while(0); -//#define USB_DBG(x, ...) std::printf("[USB_DBG: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__); -#define USB_DBG_HEX(A,B) debug_hex(A,B) -extern void debug_hex(uint8_t* buf, int size); -#define USB_DBG_ERRSTAT() report.print_errstat(); -#else -#define USB_DBG(x, ...) -#define USB_DBG_HEX(A,B) while(0) -#define USB_DBG_ERRSTAT() while(0) -#endif - -#if (DEBUG2 > 3) -#define USB_DBG2(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\r\n");} while(0); -#else -#define USB_DBG2(...) while(0); -#endif - -#if (DEBUG > 2) -#define USB_INFO(...) do{fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\r\n");}while(0); -//#define USB_INFO(x, ...) std::printf("[USB_INFO: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__); -#else -#define USB_INFO(x, ...) -#endif - -#if (DEBUG > 1) -#define USB_WARN(x, ...) std::printf("[USB_WARNING: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__); -#else -#define USB_WARN(x, ...) -#endif - -#if (DEBUG > 0) -#define USB_ERR(x, ...) std::printf("[USB_ERR: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__); -#else -#define USB_ERR(x, ...) -#endif - -#if (DEBUG_TRANSFER) -#define USB_DBG_TRANSFER(x, ...) std::printf("[USB_TRANSFER: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__); -#else -#define USB_DBG_TRANSFER(x, ...) -#endif - -#if (DEBUG_EVENT) -#define USB_DBG_EVENT(x, ...) std::printf("[USB_EVENT: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__); -#else -#define USB_DBG_EVENT(x, ...) -#endif - -template <bool>struct CtAssert; -template <>struct CtAssert<true> {}; -#define CTASSERT(A) CtAssert<A>(); - -#ifdef _USB_TEST -#define USB_TEST_ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);}; -#define USB_TEST_ASSERT_FALSE(A) USB_TEST_ASSERT(!(A)) -#else -#define USB_TEST_ASSERT(A) while(0) -#define USB_TEST_ASSERT_FALSE(A) while(0) -#endif - -#endif -
--- a/LPC4088-USBHost/USBHost/mymap.h Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -#pragma once - -template<class K,class T> -class mymap { - struct mypair { - K first; - T second; - }; -public: - mymap() { - m_size = 0; - } - T& operator[](const K& key) { - int it; - if (count(key) == 0) { - it = insert(key, 0); - } else { - it = find(key); - } - return m_buf[it].second; - } - bool empty() { return m_size == 0 ? true : false; } - int size() { return m_size; } - void clear() { m_size = 0; } - int count(K key) { - for(int i = 0; i < m_size; i++) { - if (m_buf[i].first == key) { - return 1; - } - } - return 0; - } - -private: - int find(K key) { - for(int i = 0; i < m_size; i++) { - if (m_buf[i].first == key) { - return i; - } - } - return -1; - } - int insert(K key, T value) { - int it = find(key); - if (it != -1) { - m_buf[it].second = value; - return it; - } - mypair* new_buf = new mypair[m_size+1]; - if (m_size > 0) { - for(int i = 0; i < m_size; i++) { - new_buf[i] = m_buf[i]; - } - delete[] m_buf; - } - m_buf = new_buf; - it = m_size++; - m_buf[it].first = key; - m_buf[it].second = value; - return it; - } - - int m_size; - mypair *m_buf; -};
--- a/LPC4088-USBHost/USBHost/myvector.h Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -#pragma once - -template<class T> -class myvector { -public: - myvector() { - m_size = 0; - m_buf = NULL; - } - ~myvector() { - if (m_buf) { - delete[] m_buf; - } - } - void push_back(T v) { - T* new_buf = new T[m_size+1]; - if (m_size > 0) { - for(int i = 0; i < m_size; i++) { - new_buf[i] = m_buf[i]; - } - delete[] m_buf; - } - m_buf = new_buf; - m_buf[m_size++] = v; - } - T& operator[](const int index) { - return m_buf[index]; - } - int size() { return m_size; } - -private: - int m_size; - T *m_buf; -};
--- a/LPC4088-USBHost/USBHostMSD/USBHostMSD.cpp Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,356 +0,0 @@ -/* mbed USBHost Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "USBHostMSD.h" - -#if USBHOST_MSD - -#include "dbg.h" - -#define CBW_SIGNATURE 0x43425355 -#define CSW_SIGNATURE 0x53425355 - -#define DEVICE_TO_HOST 0x80 -#define HOST_TO_DEVICE 0x00 - -#define GET_MAX_LUN (0xFE) -#define BO_MASS_STORAGE_RESET (0xFF) - -USBHostMSD::USBHostMSD(const char * rootdir) : FATFileSystem(rootdir) -{ - host = USBHost::getHostInst(); - init(); -} - -void USBHostMSD::init() { - dev_connected = false; - dev = NULL; - bulk_in = NULL; - bulk_out = NULL; - dev_connected = false; - blockSize = 0; - blockCount = 0; - msd_intf = -1; - msd_device_found = false; - disk_init = false; - dev_connected = false; - nb_ep = 0; -} - - -bool USBHostMSD::connected() -{ - return dev_connected; -} - -bool USBHostMSD::connect() -{ - - if (dev_connected) { - return true; - } - - for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) { - if ((dev = host->getDevice(i)) != NULL) { - - USB_DBG("Trying to connect MSD device\r\n"); - - if(host->enumerate(dev, this)) - break; - - if (msd_device_found) { - bulk_in = dev->getEndpoint(msd_intf, BULK_ENDPOINT, IN); - bulk_out = dev->getEndpoint(msd_intf, BULK_ENDPOINT, OUT); - - if (!bulk_in || !bulk_out) - continue; - - USB_INFO("New MSD device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, msd_intf); - dev->setName("MSD", msd_intf); - host->registerDriver(dev, msd_intf, this, &USBHostMSD::init); - - dev_connected = true; - return true; - } - } //if() - } //for() - init(); - return false; -} - -/*virtual*/ void USBHostMSD::setVidPid(uint16_t vid, uint16_t pid) -{ - // we don't check VID/PID for MSD driver -} - -/*virtual*/ bool USBHostMSD::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed -{ - if ((msd_intf == -1) && - (intf_class == MSD_CLASS) && - (intf_subclass == 0x06) && - (intf_protocol == 0x50)) { - msd_intf = intf_nb; - return true; - } - return false; -} - -/*virtual*/ bool USBHostMSD::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used -{ - if (intf_nb == msd_intf) { - if (type == BULK_ENDPOINT) { - nb_ep++; - if (nb_ep == 2) - msd_device_found = true; - return true; - } - } - return false; -} - - -int USBHostMSD::testUnitReady() { - USB_DBG("Test unit ready"); - return SCSITransfer(NULL, 6, DEVICE_TO_HOST, 0, 0); -} - - -int USBHostMSD::readCapacity() { - USB_DBG("Read capacity"); - uint8_t cmd[10] = {0x25,0,0,0,0,0,0,0,0,0}; - uint8_t result[8]; - int status = SCSITransfer(cmd, 10, DEVICE_TO_HOST, result, 8); - if (status == 0) { - blockCount = (result[0] << 24) | (result[1] << 16) | (result[2] << 8) | result[3]; - blockSize = (result[4] << 24) | (result[5] << 16) | (result[6] << 8) | result[7]; - USB_INFO("MSD [dev: %p] - blockCount: %lld, blockSize: %d, Capacity: %lld\r\n", dev, blockCount, blockSize, blockCount*blockSize); - } - return status; -} - - -int USBHostMSD::SCSIRequestSense() { - USB_DBG("Request sense"); - uint8_t cmd[6] = {0x03,0,0,0,18,0}; - uint8_t result[18]; - int status = SCSITransfer(cmd, 6, DEVICE_TO_HOST, result, 18); - return status; -} - - -int USBHostMSD::inquiry(uint8_t lun, uint8_t page_code) { - USB_DBG("Inquiry"); - uint8_t evpd = (page_code == 0) ? 0 : 1; - uint8_t cmd[6] = {0x12, uint8_t((lun << 5) | evpd), page_code, 0, 36, 0}; - uint8_t result[36]; - int status = SCSITransfer(cmd, 6, DEVICE_TO_HOST, result, 36); - if (status == 0) { - char vid_pid[17]; - memcpy(vid_pid, &result[8], 8); - vid_pid[8] = 0; - USB_INFO("MSD [dev: %p] - Vendor ID: %s", dev, vid_pid); - - memcpy(vid_pid, &result[16], 16); - vid_pid[16] = 0; - USB_INFO("MSD [dev: %p] - Product ID: %s", dev, vid_pid); - - memcpy(vid_pid, &result[32], 4); - vid_pid[4] = 0; - USB_INFO("MSD [dev: %p] - Product rev: %s", dev, vid_pid); - } - return status; -} - -int USBHostMSD::checkResult(uint8_t res, USBEndpoint * ep) { - // if ep stalled: send clear feature - if (res == USB_TYPE_STALL_ERROR) { - res = host->controlWrite( dev, - USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD, - CLEAR_FEATURE, - 0, ep->getAddress(), NULL, 0); - // set state to IDLE if clear feature successful - if (res == USB_TYPE_OK) { - ep->setState(USB_TYPE_IDLE); - } - } - - if (res != USB_TYPE_OK) - return -1; - - return 0; -} - - -int USBHostMSD::SCSITransfer(uint8_t * cmd, uint8_t cmd_len, int flags, uint8_t * data, uint32_t transfer_len) { - - int res = 0; - - cbw.Signature = CBW_SIGNATURE; - cbw.Tag = 0; - cbw.DataLength = transfer_len; - cbw.Flags = flags; - cbw.LUN = 0; - cbw.CBLength = cmd_len; - memset(cbw.CB,0,sizeof(cbw.CB)); - if (cmd) { - memcpy(cbw.CB,cmd,cmd_len); - } - - // send the cbw - USB_DBG("Send CBW"); - res = host->bulkWrite(dev, bulk_out,(uint8_t *)&cbw, 31); - if (checkResult(res, bulk_out)) - return -1; - - // data stage if needed - if (data) { - USB_DBG("data stage"); - if (flags == HOST_TO_DEVICE) { - - res = host->bulkWrite(dev, bulk_out, data, transfer_len); - if (checkResult(res, bulk_out)) - return -1; - - } else if (flags == DEVICE_TO_HOST) { - - res = host->bulkRead(dev, bulk_in, data, transfer_len); - if (checkResult(res, bulk_in)) - return -1; - } - } - - // status stage - csw.Signature = 0; - USB_DBG("Read CSW"); - res = host->bulkRead(dev, bulk_in,(uint8_t *)&csw, 13); - if (checkResult(res, bulk_in)) - return -1; - - if (csw.Signature != CSW_SIGNATURE) { - return -1; - } - - USB_DBG("recv csw: status: %d", csw.Status); - - // ModeSense? - if ((csw.Status == 1) && (cmd[0] != 0x03)) { - USB_DBG("request mode sense"); - return SCSIRequestSense(); - } - - // perform reset recovery - if ((csw.Status == 2) && (cmd[0] != 0x03)) { - - // send Bulk-Only Mass Storage Reset request - res = host->controlWrite( dev, - USB_RECIPIENT_INTERFACE | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS, - BO_MASS_STORAGE_RESET, - 0, msd_intf, NULL, 0); - - // unstall both endpoints - res = host->controlWrite( dev, - USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD, - CLEAR_FEATURE, - 0, bulk_in->getAddress(), NULL, 0); - - res = host->controlWrite( dev, - USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD, - CLEAR_FEATURE, - 0, bulk_out->getAddress(), NULL, 0); - - } - - return csw.Status; -} - - -int USBHostMSD::dataTransfer(uint8_t * buf, uint32_t block, uint8_t nbBlock, int direction) { - uint8_t cmd[10]; - memset(cmd,0,10); - cmd[0] = (direction == DEVICE_TO_HOST) ? 0x28 : 0x2A; - - cmd[2] = (block >> 24) & 0xff; - cmd[3] = (block >> 16) & 0xff; - cmd[4] = (block >> 8) & 0xff; - cmd[5] = block & 0xff; - - cmd[7] = (nbBlock >> 8) & 0xff; - cmd[8] = nbBlock & 0xff; - - return SCSITransfer(cmd, 10, direction, buf, blockSize*nbBlock); -} - -int USBHostMSD::getMaxLun() { - uint8_t buf[1], res; - res = host->controlRead( dev, USB_RECIPIENT_INTERFACE | USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS, - 0xfe, 0, msd_intf, buf, 1); - USB_DBG("max lun: %d", buf[0]); - return res; -} - -int USBHostMSD::disk_initialize() { - USB_DBG("FILESYSTEM: init"); - /* U16 */int i, timeout = 10; - - getMaxLun(); - - for (i = 0; i < timeout; i++) { - wait_ms(100); //Thread::wait(100); - if (!testUnitReady()) - break; - } - - if (i == timeout) { - disk_init = false; - return -1; - } - - inquiry(0, 0); - disk_init = 1; - return readCapacity(); -} - -int USBHostMSD::disk_write(const uint8_t *buffer, uint64_t block_number) { - USB_DBG("FILESYSTEM: write block: %lld", block_number); - if (!disk_init) { - disk_initialize(); - } - if (!disk_init) - return -1; - return dataTransfer((uint8_t *)buffer, block_number, 1, HOST_TO_DEVICE); -} - -int USBHostMSD::disk_read(uint8_t * buffer, uint64_t block_number) { - USB_DBG("FILESYSTEM: read block %lld", block_number); - if (!disk_init) { - disk_initialize(); - } - if (!disk_init) - return -1; - return dataTransfer((uint8_t *)buffer, block_number, 1, DEVICE_TO_HOST); -} - -uint64_t USBHostMSD::disk_sectors() { - USB_DBG("FILESYSTEM: sectors"); - if (!disk_init) { - disk_initialize(); - } - if (!disk_init) - return 0; - return blockCount; -} - -#endif
--- a/LPC4088-USBHost/USBHostMSD/USBHostMSD.h Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,119 +0,0 @@ -/* mbed USBHost Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef USBHOSTMSD_H -#define USBHOSTMSD_H - -#include "USBHostConf.h" - -#if USBHOST_MSD - -#include "USBHost.h" -#include "FATFileSystem.h" - -/** - * A class to communicate a USB flash disk - */ -class USBHostMSD : public IUSBEnumerator, public FATFileSystem { -public: - /** - * Constructor - * - * @param rootdir mount name - */ - USBHostMSD(const char * rootdir); - - /** - * Check if a MSD device is connected - * - * @return true if a MSD device is connected - */ - bool connected(); - - /** - * Try to connect to a MSD device - * - * @return true if connection was successful - */ - bool connect(); - -protected: - //From IUSBEnumerator - virtual void setVidPid(uint16_t vid, uint16_t pid); - virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed - virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used - - // From FATFileSystem - virtual int disk_initialize(); - virtual int disk_status() {return 0;}; - virtual int disk_read(uint8_t * buffer, uint64_t sector); - virtual int disk_write(const uint8_t * buffer, uint64_t sector); - virtual int disk_sync() {return 0;}; - virtual uint64_t disk_sectors(); - -private: - USBHost * host; - USBDeviceConnected * dev; - bool dev_connected; - USBEndpoint * bulk_in; - USBEndpoint * bulk_out; - uint8_t nb_ep; - - // Bulk-only CBW - typedef struct { - uint32_t Signature; - uint32_t Tag; - uint32_t DataLength; - uint8_t Flags; - uint8_t LUN; - uint8_t CBLength; - uint8_t CB[16]; - } PACKED CBW; - - // Bulk-only CSW - typedef struct { - uint32_t Signature; - uint32_t Tag; - uint32_t DataResidue; - uint8_t Status; - } PACKED CSW; - - CBW cbw; - CSW csw; - - int SCSITransfer(uint8_t * cmd, uint8_t cmd_len, int flags, uint8_t * data, uint32_t transfer_len); - int testUnitReady(); - int readCapacity(); - int inquiry(uint8_t lun, uint8_t page_code); - int SCSIRequestSense(); - int dataTransfer(uint8_t * buf, uint32_t block, uint8_t nbBlock, int direction); - int checkResult(uint8_t res, USBEndpoint * ep); - int getMaxLun(); - - int blockSize; - uint64_t blockCount; - - int msd_intf; - bool msd_device_found; - bool disk_init; - - void init(); - -}; - -#endif - -#endif
--- a/LPC4088-USBHost/mbed-rtos.lib Tue Apr 22 10:54:52 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/mbed_official/code/mbed-rtos/#4ef72665e2c8