1
0
mirror of https://github.com/gdsports/USBHost_t36 synced 2024-11-27 19:42:15 -05:00

Parse hub port status, work-in-progress...

This commit is contained in:
PaulStoffregen 2017-02-17 17:44:24 -08:00
parent 97f728e83c
commit 4eaeb84a82
3 changed files with 70 additions and 5 deletions

View File

@ -239,8 +239,10 @@ protected:
void poweron(uint32_t port); void poweron(uint32_t port);
void getstatus(uint32_t port); void getstatus(uint32_t port);
void clearstatus(uint32_t port); void clearstatus(uint32_t port);
void reset(uint32_t port);
static void callback(const Transfer_t *transfer); static void callback(const Transfer_t *transfer);
void status_change(const Transfer_t *transfer); void status_change(const Transfer_t *transfer);
void new_port_status(uint32_t port, uint32_t status);
void update_status(); void update_status();
setup_t setup; setup_t setup;
uint8_t hub_desc[16]; uint8_t hub_desc[16];
@ -251,7 +253,9 @@ protected:
uint8_t state; uint8_t state;
Pipe_t *changepipe; Pipe_t *changepipe;
uint32_t changebits; uint32_t changebits;
uint32_t status; uint32_t statusbits;
uint16_t portstatus[7];
uint8_t portstate[7];
}; };

View File

@ -751,7 +751,7 @@ static bool allocate_interrupt_pipe_bandwidth(uint32_t speed, uint32_t maxlen,
maxlen = (maxlen * 76459) >> 16; // worst case bit stuffing maxlen = (maxlen * 76459) >> 16; // worst case bit stuffing
if (speed == 2) { if (speed == 2) {
// high speed 480 Mbit/sec // high speed 480 Mbit/sec
uint32_t stime = (55 + 32 + maxlen) >> 5; uint32_t stime = (55 + 32 + maxlen) >> 5; // time units: 32 bytes or 533 ns
uint32_t min_offset = 0xFFFFFFFF; uint32_t min_offset = 0xFFFFFFFF;
uint32_t min_bw = 0xFFFFFFFF; uint32_t min_bw = 0xFFFFFFFF;
for (uint32_t offset=0; offset < interval; offset++) { for (uint32_t offset=0; offset < interval; offset++) {
@ -788,6 +788,8 @@ static bool allocate_interrupt_pipe_bandwidth(uint32_t speed, uint32_t maxlen,
// full speed 12 Mbit/sec or low speed 1.5 Mbit/sec // full speed 12 Mbit/sec or low speed 1.5 Mbit/sec
uint32_t stime, ctime; uint32_t stime, ctime;
if (direction == 0) { if (direction == 0) {
// TODO: how much time to SSPLIT & CSPLIT actually take?
// they're not documented in 5.7 or 5.11.3.
stime = (100 + 32 + maxlen) >> 5; stime = (100 + 32 + maxlen) >> 5;
ctime = (55 + 32) >> 5; ctime = (55 + 32) >> 5;
} else { } else {
@ -795,6 +797,8 @@ static bool allocate_interrupt_pipe_bandwidth(uint32_t speed, uint32_t maxlen,
ctime = (70 + 32 + maxlen) >> 5; ctime = (70 + 32 + maxlen) >> 5;
} }
interval = interval >> 3; // can't be zero, earlier check for interval >= 8 interval = interval >> 3; // can't be zero, earlier check for interval >= 8
// TODO: should we take Single-TT hubs into account, avoid
// scheduling overlapping SSPLIT & CSPLIT to the same hub?
uint32_t min_shift = 0; uint32_t min_shift = 0;
uint32_t min_offset = 0xFFFFFFFF; uint32_t min_offset = 0xFFFFFFFF;
uint32_t min_bw = 0xFFFFFFFF; uint32_t min_bw = 0xFFFFFFFF;

63
hub.cpp
View File

@ -74,6 +74,8 @@ bool USBHub::claim(Device_t *dev, int type, const uint8_t *descriptors)
changepipe = NULL; changepipe = NULL;
changebits = 0; changebits = 0;
state = 0; state = 0;
memset(portstatus, 0, sizeof(portstatus));
memset(portstate, 0, sizeof(portstate));
mk_setup(setup, 0xA0, 6, 0x2900, 0, sizeof(hub_desc)); mk_setup(setup, 0xA0, 6, 0x2900, 0, sizeof(hub_desc));
queue_Control_Transfer(dev, &setup, hub_desc, this); queue_Control_Transfer(dev, &setup, hub_desc, this);
@ -94,7 +96,7 @@ void USBHub::getstatus(uint32_t port)
} else { } else {
mk_setup(setup, 0xA3, 0, 0, port, 4); // get port status mk_setup(setup, 0xA3, 0, 0, port, 4); // get port status
} }
queue_Control_Transfer(device, &setup, &status, this); queue_Control_Transfer(device, &setup, &statusbits, this);
} }
void USBHub::clearstatus(uint32_t port) void USBHub::clearstatus(uint32_t port)
@ -107,6 +109,13 @@ void USBHub::clearstatus(uint32_t port)
queue_Control_Transfer(device, &setup, NULL, this); queue_Control_Transfer(device, &setup, NULL, this);
} }
void USBHub::reset(uint32_t port)
{
mk_setup(setup, 0x23, 3, 4, port, 0); // set feature PORT_RESET
queue_Control_Transfer(device, &setup, NULL, this);
}
void USBHub::control(const Transfer_t *transfer) void USBHub::control(const Transfer_t *transfer)
{ {
Serial.println("USBHub control callback"); Serial.println("USBHub control callback");
@ -148,8 +157,7 @@ void USBHub::control(const Transfer_t *transfer)
clearstatus(0); clearstatus(0);
return; return;
case 0x000000A3: // get port status case 0x000000A3: // get port status
Serial.print("New Port Status, port="); new_port_status(setup.wIndex, statusbits);
Serial.println(setup.wIndex);
clearstatus(setup.wIndex); clearstatus(setup.wIndex);
return; return;
case 0x00100120: // clear hub status case 0x00100120: // clear hub status
@ -194,6 +202,55 @@ void USBHub::update_status()
} }
} }
void USBHub::new_port_status(uint32_t port, uint32_t status)
{
if (port < 1 || port > 7) return;
uint32_t priorstatus = portstatus[port - 1];
portstatus[port] = status;
Serial.print("New Port Status, port=");
Serial.print(port);
Serial.print(", status=");
Serial.println(status, HEX);
// status bits, USB 2.0: 11.24.2.7.1 page 427
if (status & 0x0001) Serial.println(" Device is present: ");
if (status & 0x0002) {
Serial.println(" Enabled, speed = ");
if (status & 0x0200) {
Serial.print("1.5");
} else {
if (status & 0x0400) {
Serial.print("480");
} else {
Serial.print("12");
}
}
Serial.println(" Mbit/sec");
}
if (status & 0x0004) Serial.println(" Suspended");
if (status & 0x0008) Serial.println(" Over-current");
if (status & 0x0010) Serial.println(" Reset");
if (status & 0x0100) Serial.println(" Has Power");
if (status & 0x0800) Serial.println(" Test Mode");
if (status & 0x1000) Serial.println(" Software Controls LEDs");
if ((status & 0x0001) && !(priorstatus & 0x0001)) {
Serial.println(" connect");
// 100 ms debounce (USB 2.0: TATTDB, page 150 & 188)
delay(100); // TODO: horribly bad... need timing events
reset(port);
// TODO... reset timer?
} else if (!(status & 0x0001) && (priorstatus & 0x0001)) {
Serial.println(" disconnect");
}
}
void USBHub::disconnect() void USBHub::disconnect()
{ {
// TODO: free resources // TODO: free resources