mirror of
https://github.com/gdsports/USBHost_t36
synced 2024-11-24 18:12:16 -05:00
Add transfer callbacks
This commit is contained in:
parent
7997b07157
commit
600166af4c
15
host.h
15
host.h
@ -30,6 +30,7 @@ typedef struct Device_struct Device_t;
|
||||
typedef struct Pipe_struct Pipe_t;
|
||||
typedef struct Transfer_struct Transfer_t;
|
||||
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
union {
|
||||
@ -73,10 +74,10 @@ struct Pipe_struct {
|
||||
} qh;
|
||||
Device_t *device;
|
||||
uint8_t type; // 0=control, 1=isochronous, 2=bulk, 3=interrupt
|
||||
uint8_t direction; // 0=out, 1=in
|
||||
//uint8_t data01; // next packet DATA0 or DATA1
|
||||
uint8_t direction; // 0=out, 1=in (changes for control, others fixed)
|
||||
uint8_t unusedbyte[2];
|
||||
uint32_t unused[2];
|
||||
void *callback_object; // TODO: C++ callbacks??
|
||||
void (*callback_function)(const Transfer_t *);
|
||||
};
|
||||
|
||||
|
||||
@ -88,10 +89,12 @@ struct Transfer_struct {
|
||||
volatile uint32_t token;
|
||||
volatile uint32_t buffer[5];
|
||||
} qtd;
|
||||
Pipe_t *pipe;
|
||||
void *callback;
|
||||
void *callback_arg;
|
||||
// linked list of queued, not-yet-completed transfers
|
||||
Transfer_t *next_followup;
|
||||
// data to be used by callback function
|
||||
Pipe_t *pipe;
|
||||
void *buffer;
|
||||
uint32_t length;
|
||||
uint32_t unused[4];
|
||||
};
|
||||
|
||||
|
@ -221,13 +221,10 @@ void usbhs_isr(void)
|
||||
|
||||
if (stat & USBHS_USBSTS_UAI) { // completed qTD(s) from the async schedule
|
||||
Serial.println("Async Followup");
|
||||
|
||||
Transfer_t *p, *prev=NULL, *next;
|
||||
|
||||
p = async_followup_first;
|
||||
Transfer_t *prev=NULL;
|
||||
Transfer_t *p = async_followup_first;
|
||||
while (p) {
|
||||
|
||||
next = p->next_followup;
|
||||
Transfer_t *next = p->next_followup;
|
||||
if (followup_Transfer(p)) {
|
||||
// transfer completed
|
||||
if (prev) {
|
||||
@ -242,7 +239,6 @@ void usbhs_isr(void)
|
||||
p = next;
|
||||
}
|
||||
async_followup_last = prev;
|
||||
|
||||
}
|
||||
if (stat & USBHS_USBSTS_UPI) { // completed qTD(s) from the periodic schedule
|
||||
|
||||
@ -311,6 +307,19 @@ void usbhs_isr(void)
|
||||
|
||||
}
|
||||
|
||||
void enumeration(const Transfer_t *transfer)
|
||||
{
|
||||
Serial.print(" CALLBACK: ");
|
||||
uint8_t *p = (uint8_t *)transfer->buffer;
|
||||
for (uint32_t i=0; i < transfer->length; i++) {
|
||||
Serial.print(*p++, HEX);
|
||||
Serial.print(' ');
|
||||
}
|
||||
Serial.println();
|
||||
print(transfer);
|
||||
|
||||
}
|
||||
|
||||
// Create a new device and begin the enumeration process
|
||||
//
|
||||
Device_t * new_Device(uint32_t speed, uint32_t hub_addr, uint32_t hub_port)
|
||||
@ -336,6 +345,7 @@ Device_t * new_Device(uint32_t speed, uint32_t hub_addr, uint32_t hub_port)
|
||||
free_Device(dev);
|
||||
return NULL;
|
||||
}
|
||||
dev->control_pipe->callback_function = &enumeration;
|
||||
|
||||
static uint8_t buffer[8];
|
||||
dev->control_pipe->direction = 1; // 1=IN
|
||||
@ -464,12 +474,13 @@ bool new_Transfer(Pipe_t *pipe, void *buffer, uint32_t len)
|
||||
Serial.println("new_Transfer");
|
||||
Transfer_t *transfer = allocate_Transfer();
|
||||
if (!transfer) return false;
|
||||
transfer->pipe = pipe;
|
||||
if (pipe->type == 0) {
|
||||
// control transfer
|
||||
Transfer_t *data, *status;
|
||||
uint32_t status_direction;
|
||||
if (len > 16384) {
|
||||
// hopefully we never need more
|
||||
// than 16K in a control transfer
|
||||
free_Transfer(transfer);
|
||||
return false;
|
||||
}
|
||||
@ -488,7 +499,6 @@ bool new_Transfer(Pipe_t *pipe, void *buffer, uint32_t len)
|
||||
init_qTD(data, buffer, len, pipe->direction, 1, false);
|
||||
transfer->qtd.next = (uint32_t)data;
|
||||
data->qtd.next = (uint32_t)status;
|
||||
data->pipe = pipe;
|
||||
status_direction = pipe->direction ^ 1;
|
||||
} else {
|
||||
transfer->qtd.next = (uint32_t)status;
|
||||
@ -499,6 +509,8 @@ bool new_Transfer(Pipe_t *pipe, void *buffer, uint32_t len)
|
||||
init_qTD(transfer, &pipe->device->setup, 8, 2, 0, false);
|
||||
init_qTD(status, NULL, 0, status_direction, 1, true);
|
||||
status->pipe = pipe;
|
||||
status->buffer = buffer;
|
||||
status->length = len;
|
||||
status->qtd.next = 1;
|
||||
} else {
|
||||
// bulk, interrupt or isochronous transfer
|
||||
@ -515,7 +527,7 @@ bool new_Transfer(Pipe_t *pipe, void *buffer, uint32_t len)
|
||||
// copy transfer non-token fields to halt
|
||||
halt->qtd.next = transfer->qtd.next;
|
||||
halt->qtd.alt_next = transfer->qtd.alt_next;
|
||||
halt->qtd.buffer[0] = transfer->qtd.buffer[0];
|
||||
halt->qtd.buffer[0] = transfer->qtd.buffer[0]; // TODO: optimize...
|
||||
halt->qtd.buffer[1] = transfer->qtd.buffer[1];
|
||||
halt->qtd.buffer[2] = transfer->qtd.buffer[2];
|
||||
halt->qtd.buffer[3] = transfer->qtd.buffer[3];
|
||||
@ -565,11 +577,17 @@ bool followup_Transfer(Transfer_t *transfer)
|
||||
|
||||
if (!(transfer->qtd.token & 0x80)) {
|
||||
// TODO: check error status
|
||||
if (transfer->qtd.token & 0x8000) {
|
||||
// this transfer caused an interrupt
|
||||
if (transfer->pipe->callback_function) {
|
||||
// do the callback
|
||||
(*(transfer->pipe->callback_function))(transfer);
|
||||
}
|
||||
}
|
||||
// do callback function...
|
||||
Serial.println(" completed");
|
||||
free_Transfer(transfer);
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user