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