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
LPC4088-USBHost/USBHost/BaseUsbHostHub.cpp@0:11152e69fc05, 2014-04-22 (annotated)
- Committer:
- va009039
- Date:
- Tue Apr 22 10:54:52 2014 +0000
- Revision:
- 0:11152e69fc05
first commit,sync rev.25.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 | 0:11152e69fc05 | 1 | // BaseUsbHostHub.cpp 2014/4/21 |
va009039 | 0:11152e69fc05 | 2 | #include "USBHost.h" |
va009039 | 0:11152e69fc05 | 3 | //#define DEBUG |
va009039 | 0:11152e69fc05 | 4 | #include "BaseUsbHostDebug.h" |
va009039 | 0:11152e69fc05 | 5 | #define TEST |
va009039 | 0:11152e69fc05 | 6 | #include "BaseUsbHostTest.h" |
va009039 | 0:11152e69fc05 | 7 | |
va009039 | 0:11152e69fc05 | 8 | #define PORT_CONNECTION 0 |
va009039 | 0:11152e69fc05 | 9 | #define PORT_ENABLE 1 |
va009039 | 0:11152e69fc05 | 10 | #define PORT_SUSPEND 2 |
va009039 | 0:11152e69fc05 | 11 | #define PORT_OVER_CURRENT 3 |
va009039 | 0:11152e69fc05 | 12 | #define PORT_RESET 4 |
va009039 | 0:11152e69fc05 | 13 | #define PORT_POWER 8 |
va009039 | 0:11152e69fc05 | 14 | #define PORT_LOW_SPEED 9 |
va009039 | 0:11152e69fc05 | 15 | |
va009039 | 0:11152e69fc05 | 16 | #define C_PORT_CONNECTION 16 |
va009039 | 0:11152e69fc05 | 17 | #define C_PORT_ENABLE 17 |
va009039 | 0:11152e69fc05 | 18 | #define C_PORT_SUSPEND 18 |
va009039 | 0:11152e69fc05 | 19 | #define C_PORT_OVER_CURRENT 19 |
va009039 | 0:11152e69fc05 | 20 | #define C_PORT_RESET 20 |
va009039 | 0:11152e69fc05 | 21 | |
va009039 | 0:11152e69fc05 | 22 | UsbHub::UsbHub(ControlEp* ctlEp) |
va009039 | 0:11152e69fc05 | 23 | { |
va009039 | 0:11152e69fc05 | 24 | if (ctlEp == NULL) { |
va009039 | 0:11152e69fc05 | 25 | DBG_OHCI(LPC_USB->HcRhPortStatus1); |
va009039 | 0:11152e69fc05 | 26 | int lowSpeed = 0; |
va009039 | 0:11152e69fc05 | 27 | if (LPC_USB->HcRhPortStatus1 & 0x200) { |
va009039 | 0:11152e69fc05 | 28 | lowSpeed = 1; |
va009039 | 0:11152e69fc05 | 29 | } |
va009039 | 0:11152e69fc05 | 30 | m_ctlEp = new ControlEp(lowSpeed); |
va009039 | 0:11152e69fc05 | 31 | TEST_ASSERT_TRUE(m_ctlEp); |
va009039 | 0:11152e69fc05 | 32 | } else { |
va009039 | 0:11152e69fc05 | 33 | m_ctlEp = ctlEp; |
va009039 | 0:11152e69fc05 | 34 | } |
va009039 | 0:11152e69fc05 | 35 | CTASSERT(sizeof(DeviceDescriptor) == 18); |
va009039 | 0:11152e69fc05 | 36 | DeviceDescriptor devdesc; |
va009039 | 0:11152e69fc05 | 37 | USB_TYPE rc = m_ctlEp->GetDescriptor(1, 0, reinterpret_cast<uint8_t*>(&devdesc), sizeof(DeviceDescriptor)); |
va009039 | 0:11152e69fc05 | 38 | TEST_ASSERT(rc == USB_TYPE_OK); |
va009039 | 0:11152e69fc05 | 39 | if (rc != USB_TYPE_OK) { |
va009039 | 0:11152e69fc05 | 40 | return; |
va009039 | 0:11152e69fc05 | 41 | } |
va009039 | 0:11152e69fc05 | 42 | TEST_ASSERT_TRUE(devdesc.bLength == 0x12); |
va009039 | 0:11152e69fc05 | 43 | TEST_ASSERT_TRUE(devdesc.bDescriptorType == 0x01); |
va009039 | 0:11152e69fc05 | 44 | TEST_ASSERT_TRUE(devdesc.bDeviceClass == 0x09); // hub |
va009039 | 0:11152e69fc05 | 45 | if (devdesc.bDeviceClass != 0x09) { // hub ? |
va009039 | 0:11152e69fc05 | 46 | return; |
va009039 | 0:11152e69fc05 | 47 | } |
va009039 | 0:11152e69fc05 | 48 | CTASSERT(sizeof(HubDescriptor) == 9); |
va009039 | 0:11152e69fc05 | 49 | TEST_ASSERT(sizeof(HubDescriptor) == 9); |
va009039 | 0:11152e69fc05 | 50 | HubDescriptor hubdesc; |
va009039 | 0:11152e69fc05 | 51 | rc = m_ctlEp->controlReceive(0xa0, 6, 0x29<<8, 0, reinterpret_cast<uint8_t*>(&hubdesc), sizeof(HubDescriptor)); |
va009039 | 0:11152e69fc05 | 52 | TEST_ASSERT(rc == USB_TYPE_OK); |
va009039 | 0:11152e69fc05 | 53 | if (rc != USB_TYPE_OK) { |
va009039 | 0:11152e69fc05 | 54 | return; |
va009039 | 0:11152e69fc05 | 55 | } |
va009039 | 0:11152e69fc05 | 56 | TEST_ASSERT(hubdesc.bDescLength == 9); // length |
va009039 | 0:11152e69fc05 | 57 | TEST_ASSERT(hubdesc.bDescriptorType == 0x29); // hub |
va009039 | 0:11152e69fc05 | 58 | TEST_ASSERT(hubdesc.bNbrPorts >= 1); |
va009039 | 0:11152e69fc05 | 59 | TEST_ASSERT(hubdesc.bNbrPorts <= 16); |
va009039 | 0:11152e69fc05 | 60 | |
va009039 | 0:11152e69fc05 | 61 | rc = m_ctlEp->SetConfiguration(1); |
va009039 | 0:11152e69fc05 | 62 | TEST_ASSERT(rc == USB_TYPE_OK); |
va009039 | 0:11152e69fc05 | 63 | |
va009039 | 0:11152e69fc05 | 64 | uint32_t status; |
va009039 | 0:11152e69fc05 | 65 | rc = m_ctlEp->controlReceive(0xa0, 0, 0, 0, reinterpret_cast<uint8_t*>(&status), 4); |
va009039 | 0:11152e69fc05 | 66 | TEST_ASSERT(rc == USB_TYPE_OK); |
va009039 | 0:11152e69fc05 | 67 | if (rc != USB_TYPE_OK) { |
va009039 | 0:11152e69fc05 | 68 | return; |
va009039 | 0:11152e69fc05 | 69 | } |
va009039 | 0:11152e69fc05 | 70 | DBG("HUB STATUS: %08X\n", status); |
va009039 | 0:11152e69fc05 | 71 | |
va009039 | 0:11152e69fc05 | 72 | for(int i = 1; i <= hubdesc.bNbrPorts; i++) { |
va009039 | 0:11152e69fc05 | 73 | SetPortPower(i); // power on |
va009039 | 0:11152e69fc05 | 74 | wait_ms(hubdesc.bPwrOn2PwrGood*2); |
va009039 | 0:11152e69fc05 | 75 | uint32_t status; |
va009039 | 0:11152e69fc05 | 76 | GetPortStatus(i, &status); |
va009039 | 0:11152e69fc05 | 77 | DBG("port: %d status: %08X\n", i, status); |
va009039 | 0:11152e69fc05 | 78 | if (status & 0x010000) { // Connect Status Change, has changed |
va009039 | 0:11152e69fc05 | 79 | TEST_ASSERT(status & 0x000001); |
va009039 | 0:11152e69fc05 | 80 | ClearPortFeature(C_PORT_CONNECTION, i); |
va009039 | 0:11152e69fc05 | 81 | int lowSpeed = 0; |
va009039 | 0:11152e69fc05 | 82 | if (status & 0x0200) { |
va009039 | 0:11152e69fc05 | 83 | lowSpeed = 1; |
va009039 | 0:11152e69fc05 | 84 | } |
va009039 | 0:11152e69fc05 | 85 | PortReset(i); |
va009039 | 0:11152e69fc05 | 86 | ControlEp* ctlEp = new ControlEp(lowSpeed); |
va009039 | 0:11152e69fc05 | 87 | PortEp.push_back(ctlEp); |
va009039 | 0:11152e69fc05 | 88 | } else { |
va009039 | 0:11152e69fc05 | 89 | ClearPortPower(i); // power off |
va009039 | 0:11152e69fc05 | 90 | } |
va009039 | 0:11152e69fc05 | 91 | } |
va009039 | 0:11152e69fc05 | 92 | } |
va009039 | 0:11152e69fc05 | 93 | |
va009039 | 0:11152e69fc05 | 94 | bool UsbHub::check(ControlEp* ctlEp) |
va009039 | 0:11152e69fc05 | 95 | { |
va009039 | 0:11152e69fc05 | 96 | if (ctlEp == NULL) { |
va009039 | 0:11152e69fc05 | 97 | return false; |
va009039 | 0:11152e69fc05 | 98 | } |
va009039 | 0:11152e69fc05 | 99 | DeviceDescriptor desc; |
va009039 | 0:11152e69fc05 | 100 | USB_TYPE rc = ctlEp->GetDescriptor(DEVICE_DESCRIPTOR, 0, reinterpret_cast<uint8_t*>(&desc), sizeof(DeviceDescriptor)); |
va009039 | 0:11152e69fc05 | 101 | if (rc != USB_TYPE_OK) { |
va009039 | 0:11152e69fc05 | 102 | return false; |
va009039 | 0:11152e69fc05 | 103 | } |
va009039 | 0:11152e69fc05 | 104 | if (desc.bDeviceClass == 9) { // hub? |
va009039 | 0:11152e69fc05 | 105 | return true; |
va009039 | 0:11152e69fc05 | 106 | } |
va009039 | 0:11152e69fc05 | 107 | return false; |
va009039 | 0:11152e69fc05 | 108 | } |
va009039 | 0:11152e69fc05 | 109 | |
va009039 | 0:11152e69fc05 | 110 | USB_TYPE UsbHub::SetPortPower(int port) |
va009039 | 0:11152e69fc05 | 111 | { |
va009039 | 0:11152e69fc05 | 112 | return SetPortFeature(PORT_POWER, port); |
va009039 | 0:11152e69fc05 | 113 | } |
va009039 | 0:11152e69fc05 | 114 | |
va009039 | 0:11152e69fc05 | 115 | USB_TYPE UsbHub::ClearPortPower(int port) |
va009039 | 0:11152e69fc05 | 116 | { |
va009039 | 0:11152e69fc05 | 117 | return ClearPortFeature(PORT_POWER, port); |
va009039 | 0:11152e69fc05 | 118 | } |
va009039 | 0:11152e69fc05 | 119 | |
va009039 | 0:11152e69fc05 | 120 | USB_TYPE UsbHub::SetPortFeature(int feature, int index) |
va009039 | 0:11152e69fc05 | 121 | { |
va009039 | 0:11152e69fc05 | 122 | return m_ctlEp->controlSend(0x23, SET_FEATURE,feature,index,0,0); |
va009039 | 0:11152e69fc05 | 123 | } |
va009039 | 0:11152e69fc05 | 124 | |
va009039 | 0:11152e69fc05 | 125 | USB_TYPE UsbHub::ClearPortFeature(int feature, int index) |
va009039 | 0:11152e69fc05 | 126 | { |
va009039 | 0:11152e69fc05 | 127 | return m_ctlEp->controlSend(0x23, CLEAR_FEATURE,feature,index,0,0); |
va009039 | 0:11152e69fc05 | 128 | } |
va009039 | 0:11152e69fc05 | 129 | |
va009039 | 0:11152e69fc05 | 130 | USB_TYPE UsbHub::SetPortReset(int port) |
va009039 | 0:11152e69fc05 | 131 | { |
va009039 | 0:11152e69fc05 | 132 | return SetPortFeature(PORT_RESET, port); |
va009039 | 0:11152e69fc05 | 133 | } |
va009039 | 0:11152e69fc05 | 134 | |
va009039 | 0:11152e69fc05 | 135 | USB_TYPE UsbHub::GetPortStatus(int port, uint32_t* status) |
va009039 | 0:11152e69fc05 | 136 | { |
va009039 | 0:11152e69fc05 | 137 | return m_ctlEp->controlReceive(0xa3, GET_STATUS, 0, port, (uint8_t*)status, 4); |
va009039 | 0:11152e69fc05 | 138 | } |
va009039 | 0:11152e69fc05 | 139 | |
va009039 | 0:11152e69fc05 | 140 | USB_TYPE UsbHub::PortReset(int port) |
va009039 | 0:11152e69fc05 | 141 | { |
va009039 | 0:11152e69fc05 | 142 | DBG("%p port=%d\n", this, port); |
va009039 | 0:11152e69fc05 | 143 | TEST_ASSERT(port >= 1); |
va009039 | 0:11152e69fc05 | 144 | SetPortReset(port); |
va009039 | 0:11152e69fc05 | 145 | // wait reset |
va009039 | 0:11152e69fc05 | 146 | for(int i = 0; i < 100; i++) { |
va009039 | 0:11152e69fc05 | 147 | uint32_t status; |
va009039 | 0:11152e69fc05 | 148 | GetPortStatus(port, &status); |
va009039 | 0:11152e69fc05 | 149 | DBG("RESET port: %d status: %08X\n", port, status); |
va009039 | 0:11152e69fc05 | 150 | if (status & 0x100000) { // Reset change , Reset complete |
va009039 | 0:11152e69fc05 | 151 | return USB_TYPE_OK; |
va009039 | 0:11152e69fc05 | 152 | } |
va009039 | 0:11152e69fc05 | 153 | wait_ms(5); |
va009039 | 0:11152e69fc05 | 154 | } |
va009039 | 0:11152e69fc05 | 155 | return USB_TYPE_ERROR; |
va009039 | 0:11152e69fc05 | 156 | } |
va009039 | 0:11152e69fc05 | 157 |