USB host library, support isochronous,bulk,interrupt and control.

Dependents:   BaseUsbHost_example BaseJpegDecode_example SimpleJpegDecode_example

Import programBaseUsbHost_example

BaseUsbHost example program

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?

UserRevisionLine numberNew 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 }