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 getstatus(uint32_t port);
void clearstatus(uint32_t port);
void reset(uint32_t port);
static void callback(const Transfer_t *transfer);
void status_change(const Transfer_t *transfer);
void new_port_status(uint32_t port, uint32_t status);
void update_status();
setup_t setup;
uint8_t hub_desc[16];
@ -251,7 +253,9 @@ protected:
uint8_t state;
Pipe_t *changepipe;
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
if (speed == 2) {
// 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_bw = 0xFFFFFFFF;
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
uint32_t stime, ctime;
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;
ctime = (55 + 32) >> 5;
} else {
@ -795,6 +797,8 @@ static bool allocate_interrupt_pipe_bandwidth(uint32_t speed, uint32_t maxlen,
ctime = (70 + 32 + maxlen) >> 5;
}
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_offset = 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;
changebits = 0;
state = 0;
memset(portstatus, 0, sizeof(portstatus));
memset(portstate, 0, sizeof(portstate));
mk_setup(setup, 0xA0, 6, 0x2900, 0, sizeof(hub_desc));
queue_Control_Transfer(dev, &setup, hub_desc, this);
@ -94,7 +96,7 @@ void USBHub::getstatus(uint32_t port)
} else {
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)
@ -107,6 +109,13 @@ void USBHub::clearstatus(uint32_t port)
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)
{
Serial.println("USBHub control callback");
@ -148,8 +157,7 @@ void USBHub::control(const Transfer_t *transfer)
clearstatus(0);
return;
case 0x000000A3: // get port status
Serial.print("New Port Status, port=");
Serial.println(setup.wIndex);
new_port_status(setup.wIndex, statusbits);
clearstatus(setup.wIndex);
return;
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()
{
// TODO: free resources