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