User | Revision | Line number | New contents of line |
beaglescout007 |
0:3dac1f1bc9e0
|
1
|
#include "USBHost.h"
|
beaglescout007 |
0:3dac1f1bc9e0
|
2
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
3
|
#define PORT_CONNECTION 0
|
beaglescout007 |
0:3dac1f1bc9e0
|
4
|
#define PORT_ENABLE 1
|
beaglescout007 |
0:3dac1f1bc9e0
|
5
|
#define PORT_SUSPEND 2
|
beaglescout007 |
0:3dac1f1bc9e0
|
6
|
#define PORT_OVER_CURRENT 3
|
beaglescout007 |
0:3dac1f1bc9e0
|
7
|
#define PORT_RESET 4
|
beaglescout007 |
0:3dac1f1bc9e0
|
8
|
#define PORT_POWER 8
|
beaglescout007 |
0:3dac1f1bc9e0
|
9
|
#define PORT_LOW_SPEED 9
|
beaglescout007 |
0:3dac1f1bc9e0
|
10
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
11
|
#define C_PORT_CONNECTION 16
|
beaglescout007 |
0:3dac1f1bc9e0
|
12
|
#define C_PORT_ENABLE 17
|
beaglescout007 |
0:3dac1f1bc9e0
|
13
|
#define C_PORT_SUSPEND 18
|
beaglescout007 |
0:3dac1f1bc9e0
|
14
|
#define C_PORT_OVER_CURRENT 19
|
beaglescout007 |
0:3dac1f1bc9e0
|
15
|
#define C_PORT_RESET 20
|
beaglescout007 |
0:3dac1f1bc9e0
|
16
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
17
|
bool USBHost::Hub(USBDeviceConnected* dev) {
|
beaglescout007 |
0:3dac1f1bc9e0
|
18
|
USB_INFO("New HUB: VID:%04x PID:%04x [dev: %p]", dev->getVid(), dev->getPid(), dev);
|
beaglescout007 |
0:3dac1f1bc9e0
|
19
|
HubDescriptor hubdesc;
|
beaglescout007 |
0:3dac1f1bc9e0
|
20
|
// get HUB descriptor
|
beaglescout007 |
0:3dac1f1bc9e0
|
21
|
int rc = controlRead(dev,
|
beaglescout007 |
0:3dac1f1bc9e0
|
22
|
USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS,
|
beaglescout007 |
0:3dac1f1bc9e0
|
23
|
GET_DESCRIPTOR,
|
beaglescout007 |
0:3dac1f1bc9e0
|
24
|
0x29 << 8, 0, reinterpret_cast<uint8_t*>(&hubdesc),
|
beaglescout007 |
0:3dac1f1bc9e0
|
25
|
sizeof(HubDescriptor));
|
beaglescout007 |
0:3dac1f1bc9e0
|
26
|
USB_TEST_ASSERT(rc == USB_TYPE_OK);
|
beaglescout007 |
0:3dac1f1bc9e0
|
27
|
if (rc != USB_TYPE_OK) {
|
beaglescout007 |
0:3dac1f1bc9e0
|
28
|
return false;
|
beaglescout007 |
0:3dac1f1bc9e0
|
29
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
30
|
USB_DBG_HEX((uint8_t*)&hubdesc, sizeof(hubdesc));
|
beaglescout007 |
0:3dac1f1bc9e0
|
31
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
32
|
uint32_t status;
|
beaglescout007 |
0:3dac1f1bc9e0
|
33
|
rc = controlRead( dev,
|
beaglescout007 |
0:3dac1f1bc9e0
|
34
|
0xa0, 0, 0, 0, reinterpret_cast<uint8_t*>(&status), 4);
|
beaglescout007 |
0:3dac1f1bc9e0
|
35
|
USB_TEST_ASSERT(rc == USB_TYPE_OK);
|
beaglescout007 |
0:3dac1f1bc9e0
|
36
|
if (rc != USB_TYPE_OK) {
|
beaglescout007 |
0:3dac1f1bc9e0
|
37
|
return false;
|
beaglescout007 |
0:3dac1f1bc9e0
|
38
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
39
|
USB_DBG("HUB STATUS: %08X\n", status);
|
beaglescout007 |
0:3dac1f1bc9e0
|
40
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
41
|
for(int i = 1; i <= hubdesc.bNbrPorts; i++) {
|
beaglescout007 |
0:3dac1f1bc9e0
|
42
|
SetPortPower(dev, i); // power on
|
beaglescout007 |
0:3dac1f1bc9e0
|
43
|
wait_ms(hubdesc.bPwrOn2PwrGood*2);
|
beaglescout007 |
0:3dac1f1bc9e0
|
44
|
uint32_t status;
|
beaglescout007 |
0:3dac1f1bc9e0
|
45
|
GetPortStatus(dev, i, &status);
|
beaglescout007 |
0:3dac1f1bc9e0
|
46
|
USB_DBG("port: %d status: %08X\n", i, status);
|
beaglescout007 |
0:3dac1f1bc9e0
|
47
|
if (status & 0x010000) { // Connect Status Change, has changed
|
beaglescout007 |
0:3dac1f1bc9e0
|
48
|
USB_TEST_ASSERT(status & 0x000001);
|
beaglescout007 |
0:3dac1f1bc9e0
|
49
|
ClearPortFeature(dev, C_PORT_CONNECTION, i);
|
beaglescout007 |
0:3dac1f1bc9e0
|
50
|
int lowSpeed = 0;
|
beaglescout007 |
0:3dac1f1bc9e0
|
51
|
if (status & 0x0200) {
|
beaglescout007 |
0:3dac1f1bc9e0
|
52
|
lowSpeed = 1;
|
beaglescout007 |
0:3dac1f1bc9e0
|
53
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
54
|
PortReset(dev, i);
|
beaglescout007 |
0:3dac1f1bc9e0
|
55
|
if (!addDevice(dev, i, lowSpeed)) {
|
beaglescout007 |
0:3dac1f1bc9e0
|
56
|
ClearPortPower(dev, i); // power off
|
beaglescout007 |
0:3dac1f1bc9e0
|
57
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
58
|
} else {
|
beaglescout007 |
0:3dac1f1bc9e0
|
59
|
ClearPortPower(dev, i); // power off
|
beaglescout007 |
0:3dac1f1bc9e0
|
60
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
61
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
62
|
return false;
|
beaglescout007 |
0:3dac1f1bc9e0
|
63
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
64
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
65
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
66
|
int USBHost::SetPortPower(USBDeviceConnected* dev, int port)
|
beaglescout007 |
0:3dac1f1bc9e0
|
67
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
68
|
return SetPortFeature(dev, PORT_POWER, port);
|
beaglescout007 |
0:3dac1f1bc9e0
|
69
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
70
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
71
|
int USBHost::ClearPortPower(USBDeviceConnected* dev, int port)
|
beaglescout007 |
0:3dac1f1bc9e0
|
72
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
73
|
return ClearPortFeature(dev, PORT_POWER, port);
|
beaglescout007 |
0:3dac1f1bc9e0
|
74
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
75
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
76
|
int USBHost::SetPortFeature(USBDeviceConnected* dev, int feature, int index)
|
beaglescout007 |
0:3dac1f1bc9e0
|
77
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
78
|
return controlWrite(dev, 0x23, SET_FEATURE,feature,index,0,0);
|
beaglescout007 |
0:3dac1f1bc9e0
|
79
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
80
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
81
|
int USBHost::ClearPortFeature(USBDeviceConnected* dev, int feature, int index)
|
beaglescout007 |
0:3dac1f1bc9e0
|
82
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
83
|
return controlWrite(dev, 0x23, CLEAR_FEATURE,feature,index,0,0);
|
beaglescout007 |
0:3dac1f1bc9e0
|
84
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
85
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
86
|
int USBHost::SetPortReset(USBDeviceConnected* dev, int port)
|
beaglescout007 |
0:3dac1f1bc9e0
|
87
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
88
|
return SetPortFeature(dev, PORT_RESET, port);
|
beaglescout007 |
0:3dac1f1bc9e0
|
89
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
90
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
91
|
int USBHost::GetPortStatus(USBDeviceConnected* dev, int port, uint32_t* status)
|
beaglescout007 |
0:3dac1f1bc9e0
|
92
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
93
|
return controlRead(dev, 0xa3, GET_STATUS, 0, port, (uint8_t*)status, 4);
|
beaglescout007 |
0:3dac1f1bc9e0
|
94
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
95
|
|
beaglescout007 |
0:3dac1f1bc9e0
|
96
|
int USBHost::PortReset(USBDeviceConnected* dev, int port)
|
beaglescout007 |
0:3dac1f1bc9e0
|
97
|
{
|
beaglescout007 |
0:3dac1f1bc9e0
|
98
|
USB_DBG("%p port=%d\n", this, port);
|
beaglescout007 |
0:3dac1f1bc9e0
|
99
|
USB_TEST_ASSERT(port >= 1);
|
beaglescout007 |
0:3dac1f1bc9e0
|
100
|
SetPortReset(dev, port);
|
beaglescout007 |
0:3dac1f1bc9e0
|
101
|
// wait reset
|
beaglescout007 |
0:3dac1f1bc9e0
|
102
|
for(int i = 0; i < 100; i++) {
|
beaglescout007 |
0:3dac1f1bc9e0
|
103
|
uint32_t status;
|
beaglescout007 |
0:3dac1f1bc9e0
|
104
|
GetPortStatus(dev, port, &status);
|
beaglescout007 |
0:3dac1f1bc9e0
|
105
|
USB_DBG("RESET port: %d status: %08X\n", port, status);
|
beaglescout007 |
0:3dac1f1bc9e0
|
106
|
if (status & 0x100000) { // Reset change , Reset complete
|
beaglescout007 |
0:3dac1f1bc9e0
|
107
|
return USB_TYPE_OK;
|
beaglescout007 |
0:3dac1f1bc9e0
|
108
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
109
|
wait_ms(5);
|
beaglescout007 |
0:3dac1f1bc9e0
|
110
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
111
|
return USB_TYPE_ERROR;
|
beaglescout007 |
0:3dac1f1bc9e0
|
112
|
}
|
beaglescout007 |
0:3dac1f1bc9e0
|
113
|
|