mirror of
https://github.com/gdsports/USBHost_t36
synced 2024-11-27 19:42:15 -05:00
Fix adding to follup lists while also processing them
This commit is contained in:
parent
38dea38146
commit
46324071f0
3
host.h
3
host.h
@ -92,11 +92,12 @@ struct Transfer_struct {
|
|||||||
} qtd;
|
} qtd;
|
||||||
// linked list of queued, not-yet-completed transfers
|
// linked list of queued, not-yet-completed transfers
|
||||||
Transfer_t *next_followup;
|
Transfer_t *next_followup;
|
||||||
|
Transfer_t *prev_followup;
|
||||||
// data to be used by callback function
|
// data to be used by callback function
|
||||||
Pipe_t *pipe;
|
Pipe_t *pipe;
|
||||||
void *buffer;
|
void *buffer;
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
uint32_t unused[4];
|
uint32_t unused[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
void init_Device_Pipe_Transfer_memory(void);
|
void init_Device_Pipe_Transfer_memory(void);
|
||||||
|
154
k66_usbhost.ino
154
k66_usbhost.ino
@ -192,6 +192,7 @@ void pulse(int usec)
|
|||||||
// PORT_STATE_RECOVERY 3
|
// PORT_STATE_RECOVERY 3
|
||||||
// PORT_STATE_ACTIVE 4
|
// PORT_STATE_ACTIVE 4
|
||||||
|
|
||||||
|
|
||||||
void usbhs_isr(void)
|
void usbhs_isr(void)
|
||||||
{
|
{
|
||||||
uint32_t stat = USBHS_USBSTS;
|
uint32_t stat = USBHS_USBSTS;
|
||||||
@ -222,27 +223,37 @@ void usbhs_isr(void)
|
|||||||
|
|
||||||
if (stat & USBHS_USBSTS_UAI) { // completed qTD(s) from the async schedule
|
if (stat & USBHS_USBSTS_UAI) { // completed qTD(s) from the async schedule
|
||||||
Serial.println("Async Followup");
|
Serial.println("Async Followup");
|
||||||
Transfer_t *prev=NULL;
|
print(async_followup_first, async_followup_last);
|
||||||
Transfer_t *p = async_followup_first;
|
Transfer_t *p = async_followup_first;
|
||||||
while (p) {
|
while (p) {
|
||||||
Transfer_t *next = p->next_followup;
|
|
||||||
if (followup_Transfer(p)) {
|
if (followup_Transfer(p)) {
|
||||||
// transfer completed
|
// transfer completed
|
||||||
if (prev) {
|
Transfer_t *next = p->next_followup;
|
||||||
prev->next_followup = next;
|
remove_from_async_followup_list(p);
|
||||||
} else {
|
free_Transfer(p);
|
||||||
async_followup_first = next;
|
p = next;
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// transfer still pending
|
// transfer still pending
|
||||||
prev = p;
|
p = p->next_followup;
|
||||||
}
|
}
|
||||||
p = next;
|
|
||||||
}
|
}
|
||||||
async_followup_last = prev;
|
print(async_followup_first, async_followup_last);
|
||||||
}
|
}
|
||||||
if (stat & USBHS_USBSTS_UPI) { // completed qTD(s) from the periodic schedule
|
if (stat & USBHS_USBSTS_UPI) { // completed qTD(s) from the periodic schedule
|
||||||
|
Serial.println("Periodic Followup");
|
||||||
|
Transfer_t *p = periodic_followup_first;
|
||||||
|
while (p) {
|
||||||
|
if (followup_Transfer(p)) {
|
||||||
|
// transfer completed
|
||||||
|
Transfer_t *next = p->next_followup;
|
||||||
|
remove_from_periodic_followup_list(p);
|
||||||
|
free_Transfer(p);
|
||||||
|
p = next;
|
||||||
|
} else {
|
||||||
|
// transfer still pending
|
||||||
|
p = p->next_followup;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stat & USBHS_USBSTS_PCI) { // port change detected
|
if (stat & USBHS_USBSTS_PCI) { // port change detected
|
||||||
@ -338,6 +349,7 @@ void enumeration(const Transfer_t *transfer)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: // request all 18 bytes of device descriptor
|
case 1: // request all 18 bytes of device descriptor
|
||||||
|
Serial.println("TODO: request 18 byte device descriptor");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
@ -593,31 +605,25 @@ bool new_Transfer(Pipe_t *pipe, void *buffer, uint32_t len)
|
|||||||
// last points to transfer (which becomes new halt)
|
// last points to transfer (which becomes new halt)
|
||||||
last->qtd.next = (uint32_t)transfer;
|
last->qtd.next = (uint32_t)transfer;
|
||||||
transfer->qtd.next = 1;
|
transfer->qtd.next = 1;
|
||||||
// link all the new qTD by next_followup
|
// link all the new qTD by next_followup & prev_followup
|
||||||
|
Transfer_t *prev = NULL;
|
||||||
Transfer_t *p = halt;
|
Transfer_t *p = halt;
|
||||||
while (p->qtd.next != (uint32_t)transfer) {
|
while (p->qtd.next != (uint32_t)transfer) {
|
||||||
Transfer_t *n = (Transfer_t *)p->qtd.next;
|
Transfer_t *n = (Transfer_t *)p->qtd.next;
|
||||||
|
p->prev_followup = prev;
|
||||||
p->next_followup = n;
|
p->next_followup = n;
|
||||||
|
prev = p;
|
||||||
p = n;
|
p = n;
|
||||||
}
|
}
|
||||||
p->next_followup = NULL;
|
p->next_followup = NULL;
|
||||||
|
print(halt, p);
|
||||||
// add them to a followup list
|
// add them to a followup list
|
||||||
if (pipe->type == 0 || pipe->type == 2) {
|
if (pipe->type == 0 || pipe->type == 2) {
|
||||||
// control or bulk
|
// control or bulk
|
||||||
if (async_followup_first == NULL) {
|
add_to_async_followup_list(halt, p);
|
||||||
async_followup_first = halt;
|
|
||||||
} else {
|
|
||||||
async_followup_last->next_followup = halt;
|
|
||||||
}
|
|
||||||
async_followup_last = p;
|
|
||||||
} else {
|
} else {
|
||||||
// interrupt
|
// interrupt
|
||||||
if (periodic_followup_first == NULL) {
|
add_to_periodic_followup_list(halt, p);
|
||||||
periodic_followup_first = halt;
|
|
||||||
} else {
|
|
||||||
periodic_followup_last->next_followup = halt;
|
|
||||||
}
|
|
||||||
periodic_followup_last = p;
|
|
||||||
}
|
}
|
||||||
// old halt becomes new transfer, this commits all new qTDs to QH
|
// old halt becomes new transfer, this commits all new qTDs to QH
|
||||||
halt->qtd.token = token;
|
halt->qtd.token = token;
|
||||||
@ -640,12 +646,69 @@ bool followup_Transfer(Transfer_t *transfer)
|
|||||||
}
|
}
|
||||||
// do callback function...
|
// do callback function...
|
||||||
Serial.println(" completed");
|
Serial.println(" completed");
|
||||||
free_Transfer(transfer);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void add_to_async_followup_list(Transfer_t *first, Transfer_t *last)
|
||||||
|
{
|
||||||
|
last->next_followup = NULL; // always add to end of list
|
||||||
|
if (async_followup_last == NULL) {
|
||||||
|
first->prev_followup = NULL;
|
||||||
|
async_followup_first = first;
|
||||||
|
} else {
|
||||||
|
first->prev_followup = async_followup_last;
|
||||||
|
async_followup_last->next_followup = first;
|
||||||
|
}
|
||||||
|
async_followup_last = last;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void remove_from_async_followup_list(Transfer_t *transfer)
|
||||||
|
{
|
||||||
|
Transfer_t *next = transfer->next_followup;
|
||||||
|
Transfer_t *prev = transfer->prev_followup;
|
||||||
|
if (prev) {
|
||||||
|
prev->next_followup = next;
|
||||||
|
} else {
|
||||||
|
async_followup_first = next;
|
||||||
|
}
|
||||||
|
if (next) {
|
||||||
|
next->prev_followup = prev;
|
||||||
|
} else {
|
||||||
|
async_followup_last = prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_to_periodic_followup_list(Transfer_t *first, Transfer_t *last)
|
||||||
|
{
|
||||||
|
last->next_followup = NULL; // always add to end of list
|
||||||
|
if (periodic_followup_last == NULL) {
|
||||||
|
first->prev_followup = NULL;
|
||||||
|
periodic_followup_first = first;
|
||||||
|
} else {
|
||||||
|
first->prev_followup = periodic_followup_last;
|
||||||
|
periodic_followup_last->next_followup = first;
|
||||||
|
}
|
||||||
|
periodic_followup_last = last;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void remove_from_periodic_followup_list(Transfer_t *transfer)
|
||||||
|
{
|
||||||
|
Transfer_t *next = transfer->next_followup;
|
||||||
|
Transfer_t *prev = transfer->prev_followup;
|
||||||
|
if (prev) {
|
||||||
|
prev->next_followup = next;
|
||||||
|
} else {
|
||||||
|
periodic_followup_first = next;
|
||||||
|
}
|
||||||
|
if (next) {
|
||||||
|
next->prev_followup = prev;
|
||||||
|
} else {
|
||||||
|
periodic_followup_last = prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void print(const Transfer_t *transfer)
|
void print(const Transfer_t *transfer)
|
||||||
{
|
{
|
||||||
if (!((uint32_t)transfer & 0xFFFFFFE0)) return;
|
if (!((uint32_t)transfer & 0xFFFFFFE0)) return;
|
||||||
@ -665,6 +728,47 @@ void print(const Transfer_t *transfer)
|
|||||||
Serial.println();
|
Serial.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print(const Transfer_t *first, const Transfer_t *last)
|
||||||
|
{
|
||||||
|
Serial.print("Transfer Followup List ");
|
||||||
|
Serial.print((uint32_t)first, HEX);
|
||||||
|
Serial.print(" to ");
|
||||||
|
Serial.println((uint32_t)last, HEX);
|
||||||
|
Serial.println(" forward:");
|
||||||
|
while (first) {
|
||||||
|
Serial.print(" ");
|
||||||
|
Serial.print((uint32_t)first, HEX);
|
||||||
|
print_token(first->qtd.token);
|
||||||
|
first = first->next_followup;
|
||||||
|
}
|
||||||
|
Serial.println(" backward:");
|
||||||
|
while (last) {
|
||||||
|
Serial.print(" ");
|
||||||
|
Serial.print((uint32_t)last, HEX);
|
||||||
|
print_token(last->qtd.token);
|
||||||
|
last = last->prev_followup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_token(uint32_t token)
|
||||||
|
{
|
||||||
|
switch ((token >> 8) & 3) {
|
||||||
|
case 0:
|
||||||
|
Serial.print(" OUT ");
|
||||||
|
Serial.println((token >> 16) & 0x7FFF);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
Serial.print(" IN ");
|
||||||
|
Serial.println((token >> 16) & 0x7FFF);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
Serial.println(" SETUP");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Serial.println(" unknown");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void print(const Pipe_t *pipe)
|
void print(const Pipe_t *pipe)
|
||||||
{
|
{
|
||||||
if (!((uint32_t)pipe & 0xFFFFFFE0)) return;
|
if (!((uint32_t)pipe & 0xFFFFFFE0)) return;
|
||||||
|
Loading…
Reference in New Issue
Block a user