mirror of
https://github.com/gdsports/USBHost_t36
synced 2025-02-16 06:50:14 -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 Pipe_struct Pipe_t;
|
||||||
typedef struct Transfer_struct Transfer_t;
|
typedef struct Transfer_struct Transfer_t;
|
||||||
|
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
union {
|
union {
|
||||||
@ -73,10 +74,10 @@ struct Pipe_struct {
|
|||||||
} qh;
|
} qh;
|
||||||
Device_t *device;
|
Device_t *device;
|
||||||
uint8_t type; // 0=control, 1=isochronous, 2=bulk, 3=interrupt
|
uint8_t type; // 0=control, 1=isochronous, 2=bulk, 3=interrupt
|
||||||
uint8_t direction; // 0=out, 1=in
|
uint8_t direction; // 0=out, 1=in (changes for control, others fixed)
|
||||||
//uint8_t data01; // next packet DATA0 or DATA1
|
|
||||||
uint8_t unusedbyte[2];
|
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 token;
|
||||||
volatile uint32_t buffer[5];
|
volatile uint32_t buffer[5];
|
||||||
} qtd;
|
} qtd;
|
||||||
Pipe_t *pipe;
|
// linked list of queued, not-yet-completed transfers
|
||||||
void *callback;
|
|
||||||
void *callback_arg;
|
|
||||||
Transfer_t *next_followup;
|
Transfer_t *next_followup;
|
||||||
|
// data to be used by callback function
|
||||||
|
Pipe_t *pipe;
|
||||||
|
void *buffer;
|
||||||
|
uint32_t length;
|
||||||
uint32_t unused[4];
|
uint32_t unused[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -221,13 +221,10 @@ 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;
|
||||||
Transfer_t *p, *prev=NULL, *next;
|
Transfer_t *p = async_followup_first;
|
||||||
|
|
||||||
p = async_followup_first;
|
|
||||||
while (p) {
|
while (p) {
|
||||||
|
Transfer_t *next = p->next_followup;
|
||||||
next = p->next_followup;
|
|
||||||
if (followup_Transfer(p)) {
|
if (followup_Transfer(p)) {
|
||||||
// transfer completed
|
// transfer completed
|
||||||
if (prev) {
|
if (prev) {
|
||||||
@ -242,7 +239,6 @@ void usbhs_isr(void)
|
|||||||
p = next;
|
p = next;
|
||||||
}
|
}
|
||||||
async_followup_last = prev;
|
async_followup_last = prev;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (stat & USBHS_USBSTS_UPI) { // completed qTD(s) from the periodic schedule
|
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
|
// Create a new device and begin the enumeration process
|
||||||
//
|
//
|
||||||
Device_t * new_Device(uint32_t speed, uint32_t hub_addr, uint32_t hub_port)
|
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);
|
free_Device(dev);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
dev->control_pipe->callback_function = &enumeration;
|
||||||
|
|
||||||
static uint8_t buffer[8];
|
static uint8_t buffer[8];
|
||||||
dev->control_pipe->direction = 1; // 1=IN
|
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");
|
Serial.println("new_Transfer");
|
||||||
Transfer_t *transfer = allocate_Transfer();
|
Transfer_t *transfer = allocate_Transfer();
|
||||||
if (!transfer) return false;
|
if (!transfer) return false;
|
||||||
transfer->pipe = pipe;
|
|
||||||
if (pipe->type == 0) {
|
if (pipe->type == 0) {
|
||||||
// control transfer
|
// control transfer
|
||||||
Transfer_t *data, *status;
|
Transfer_t *data, *status;
|
||||||
uint32_t status_direction;
|
uint32_t status_direction;
|
||||||
if (len > 16384) {
|
if (len > 16384) {
|
||||||
|
// hopefully we never need more
|
||||||
|
// than 16K in a control transfer
|
||||||
free_Transfer(transfer);
|
free_Transfer(transfer);
|
||||||
return false;
|
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);
|
init_qTD(data, buffer, len, pipe->direction, 1, false);
|
||||||
transfer->qtd.next = (uint32_t)data;
|
transfer->qtd.next = (uint32_t)data;
|
||||||
data->qtd.next = (uint32_t)status;
|
data->qtd.next = (uint32_t)status;
|
||||||
data->pipe = pipe;
|
|
||||||
status_direction = pipe->direction ^ 1;
|
status_direction = pipe->direction ^ 1;
|
||||||
} else {
|
} else {
|
||||||
transfer->qtd.next = (uint32_t)status;
|
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(transfer, &pipe->device->setup, 8, 2, 0, false);
|
||||||
init_qTD(status, NULL, 0, status_direction, 1, true);
|
init_qTD(status, NULL, 0, status_direction, 1, true);
|
||||||
status->pipe = pipe;
|
status->pipe = pipe;
|
||||||
|
status->buffer = buffer;
|
||||||
|
status->length = len;
|
||||||
status->qtd.next = 1;
|
status->qtd.next = 1;
|
||||||
} else {
|
} else {
|
||||||
// bulk, interrupt or isochronous transfer
|
// 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
|
// copy transfer non-token fields to halt
|
||||||
halt->qtd.next = transfer->qtd.next;
|
halt->qtd.next = transfer->qtd.next;
|
||||||
halt->qtd.alt_next = transfer->qtd.alt_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[1] = transfer->qtd.buffer[1];
|
||||||
halt->qtd.buffer[2] = transfer->qtd.buffer[2];
|
halt->qtd.buffer[2] = transfer->qtd.buffer[2];
|
||||||
halt->qtd.buffer[3] = transfer->qtd.buffer[3];
|
halt->qtd.buffer[3] = transfer->qtd.buffer[3];
|
||||||
@ -565,11 +577,17 @@ bool followup_Transfer(Transfer_t *transfer)
|
|||||||
|
|
||||||
if (!(transfer->qtd.token & 0x80)) {
|
if (!(transfer->qtd.token & 0x80)) {
|
||||||
// TODO: check error status
|
// 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...
|
// do callback function...
|
||||||
Serial.println(" completed");
|
Serial.println(" completed");
|
||||||
free_Transfer(transfer);
|
free_Transfer(transfer);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user