mirror of
https://github.com/gdsports/USBHost_t36
synced 2024-11-16 06:05:02 -05:00
All debug printing through USBHost class
This commit is contained in:
parent
57f958c368
commit
656765bac6
35
USBHost.h
35
USBHost.h
@ -158,14 +158,45 @@ private:
|
|||||||
static void free_Pipe(Pipe_t *q);
|
static void free_Pipe(Pipe_t *q);
|
||||||
static Transfer_t * allocate_Transfer(void);
|
static Transfer_t * allocate_Transfer(void);
|
||||||
static void free_Transfer(Transfer_t *q);
|
static void free_Transfer(Transfer_t *q);
|
||||||
|
static bool allocate_interrupt_pipe_bandwidth(uint32_t speed, uint32_t maxlen,
|
||||||
|
uint32_t interval, uint32_t direction, uint32_t *offset_out,
|
||||||
|
uint32_t *smask_out, uint32_t *cmask_out);
|
||||||
protected:
|
protected:
|
||||||
static void print(const Transfer_t *transfer);
|
static void print(const Transfer_t *transfer);
|
||||||
static void print(const Transfer_t *first, const Transfer_t *last);
|
static void print(const Transfer_t *first, const Transfer_t *last);
|
||||||
static void print_token(uint32_t token);
|
static void print_token(uint32_t token);
|
||||||
static void print(const Pipe_t *pipe);
|
static void print(const Pipe_t *pipe);
|
||||||
static void print_hexbytes(const void *ptr, uint32_t len);
|
static void print_hexbytes(const void *ptr, uint32_t len);
|
||||||
static void print(const char *s);
|
static void print(const char *s) { Serial.print(s); }
|
||||||
static void print(const char *s, int num);
|
static void print(int n) { Serial.print(n); }
|
||||||
|
static void print(unsigned int n) { Serial.print(n); }
|
||||||
|
static void print(long n) { Serial.print(n); }
|
||||||
|
static void print(unsigned long n) { Serial.print(n); }
|
||||||
|
static void println(const char *s) { Serial.println(s); }
|
||||||
|
static void println(int n) { Serial.println(n); }
|
||||||
|
static void println(unsigned int n) { Serial.println(n); }
|
||||||
|
static void println(long n) { Serial.println(n); }
|
||||||
|
static void println(unsigned long n) { Serial.println(n); }
|
||||||
|
static void println() { Serial.println(); }
|
||||||
|
static void print(uint32_t n, uint8_t b) { Serial.print(n, b); }
|
||||||
|
static void println(uint32_t n, uint8_t b) { Serial.print(n, b); }
|
||||||
|
static void println(const char *s, int n) {
|
||||||
|
Serial.print(s); Serial.println(n); }
|
||||||
|
static void println(const char *s, unsigned int n) {
|
||||||
|
Serial.print(s); Serial.println(n); }
|
||||||
|
static void println(const char *s, long n) {
|
||||||
|
Serial.print(s); Serial.println(n); }
|
||||||
|
static void println(const char *s, unsigned long n) {
|
||||||
|
Serial.print(s); Serial.println(n); }
|
||||||
|
static void println(const char *s, int n, uint8_t b) {
|
||||||
|
Serial.print(s); Serial.println(n, b); }
|
||||||
|
static void println(const char *s, unsigned int n, uint8_t b) {
|
||||||
|
Serial.print(s); Serial.println(n, b); }
|
||||||
|
static void println(const char *s, long n, uint8_t b) {
|
||||||
|
Serial.print(s); Serial.println(n, b); }
|
||||||
|
static void println(const char *s, unsigned long n, uint8_t b) {
|
||||||
|
Serial.print(s); Serial.println(n, b); }
|
||||||
|
|
||||||
static void mk_setup(setup_t &s, uint32_t bmRequestType, uint32_t bRequest,
|
static void mk_setup(setup_t &s, uint32_t bmRequestType, uint32_t bRequest,
|
||||||
uint32_t wValue, uint32_t wIndex, uint32_t wLength) {
|
uint32_t wValue, uint32_t wIndex, uint32_t wLength) {
|
||||||
s.word1 = bmRequestType | (bRequest << 8) | (wValue << 16);
|
s.word1 = bmRequestType | (bRequest << 8) | (wValue << 16);
|
||||||
|
144
ehci.cpp
144
ehci.cpp
@ -48,9 +48,6 @@ static void add_to_async_followup_list(Transfer_t *first, Transfer_t *last);
|
|||||||
static void remove_from_async_followup_list(Transfer_t *transfer);
|
static void remove_from_async_followup_list(Transfer_t *transfer);
|
||||||
static void add_to_periodic_followup_list(Transfer_t *first, Transfer_t *last);
|
static void add_to_periodic_followup_list(Transfer_t *first, Transfer_t *last);
|
||||||
static void remove_from_periodic_followup_list(Transfer_t *transfer);
|
static void remove_from_periodic_followup_list(Transfer_t *transfer);
|
||||||
static bool allocate_interrupt_pipe_bandwidth(uint32_t speed, uint32_t maxlen,
|
|
||||||
uint32_t interval, uint32_t direction, uint32_t *offset, uint32_t *smask,
|
|
||||||
uint32_t *cmask);
|
|
||||||
|
|
||||||
void USBHost::begin()
|
void USBHost::begin()
|
||||||
{
|
{
|
||||||
@ -59,24 +56,20 @@ void USBHost::begin()
|
|||||||
GPIOE_PDDR |= (1<<6);
|
GPIOE_PDDR |= (1<<6);
|
||||||
GPIOE_PSOR = (1<<6); // turn on USB host power
|
GPIOE_PSOR = (1<<6); // turn on USB host power
|
||||||
delay(10);
|
delay(10);
|
||||||
Serial.print("sizeof Device = ");
|
println("sizeof Device = ", sizeof(Device_t));
|
||||||
Serial.println(sizeof(Device_t));
|
println("sizeof Pipe = ", sizeof(Pipe_t));
|
||||||
Serial.print("sizeof Pipe = ");
|
println("sizeof Transfer = ", sizeof(Transfer_t));
|
||||||
Serial.println(sizeof(Pipe_t));
|
|
||||||
Serial.print("sizeof Transfer = ");
|
|
||||||
Serial.println(sizeof(Transfer_t));
|
|
||||||
|
|
||||||
// configure the MPU to allow USBHS DMA to access memory
|
// configure the MPU to allow USBHS DMA to access memory
|
||||||
MPU_RGDAAC0 |= 0x30000000;
|
MPU_RGDAAC0 |= 0x30000000;
|
||||||
//Serial.print("MPU_RGDAAC0 = ");
|
//println("MPU_RGDAAC0 = ", MPU_RGDAAC0, HEX);
|
||||||
//Serial.println(MPU_RGDAAC0, HEX);
|
|
||||||
|
|
||||||
// turn on clocks
|
// turn on clocks
|
||||||
MCG_C1 |= MCG_C1_IRCLKEN; // enable MCGIRCLK 32kHz
|
MCG_C1 |= MCG_C1_IRCLKEN; // enable MCGIRCLK 32kHz
|
||||||
OSC0_CR |= OSC_ERCLKEN;
|
OSC0_CR |= OSC_ERCLKEN;
|
||||||
SIM_SOPT2 |= SIM_SOPT2_USBREGEN; // turn on USB regulator
|
SIM_SOPT2 |= SIM_SOPT2_USBREGEN; // turn on USB regulator
|
||||||
SIM_SOPT2 &= ~SIM_SOPT2_USBSLSRC; // use IRC for slow clock
|
SIM_SOPT2 &= ~SIM_SOPT2_USBSLSRC; // use IRC for slow clock
|
||||||
print("power up USBHS PHY");
|
println("power up USBHS PHY");
|
||||||
SIM_USBPHYCTL |= SIM_USBPHYCTL_USBDISILIM; // disable USB current limit
|
SIM_USBPHYCTL |= SIM_USBPHYCTL_USBDISILIM; // disable USB current limit
|
||||||
//SIM_USBPHYCTL = SIM_USBPHYCTL_USBDISILIM | SIM_USBPHYCTL_USB3VOUTTRG(6); // pg 237
|
//SIM_USBPHYCTL = SIM_USBPHYCTL_USBDISILIM | SIM_USBPHYCTL_USB3VOUTTRG(6); // pg 237
|
||||||
SIM_SCGC3 |= SIM_SCGC3_USBHSDCD | SIM_SCGC3_USBHSPHY | SIM_SCGC3_USBHS;
|
SIM_SCGC3 |= SIM_SCGC3_USBHSDCD | SIM_SCGC3_USBHSPHY | SIM_SCGC3_USBHS;
|
||||||
@ -94,8 +87,7 @@ void USBHost::begin()
|
|||||||
while ((USBPHY_PLL_SIC & USBPHY_PLL_SIC_PLL_LOCK) == 0) {
|
while ((USBPHY_PLL_SIC & USBPHY_PLL_SIC_PLL_LOCK) == 0) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
//Serial.print("PLL locked, waited ");
|
//println("PLL locked, waited ", count);
|
||||||
//Serial.println(count);
|
|
||||||
|
|
||||||
// turn on power to PHY
|
// turn on power to PHY
|
||||||
USBPHY_PWD = 0;
|
USBPHY_PWD = 0;
|
||||||
@ -119,7 +111,7 @@ void USBHost::begin()
|
|||||||
while (USBHS_USBCMD & USBHS_USBCMD_RST) {
|
while (USBHS_USBCMD & USBHS_USBCMD_RST) {
|
||||||
//count++;
|
//count++;
|
||||||
}
|
}
|
||||||
//print(" reset waited ", count);
|
//println(" reset waited ", count);
|
||||||
|
|
||||||
init_Device_Pipe_Transfer_memory();
|
init_Device_Pipe_Transfer_memory();
|
||||||
for (int i=0; i < 32; i++) {
|
for (int i=0; i < 32; i++) {
|
||||||
@ -165,12 +157,9 @@ void USBHost::begin()
|
|||||||
//USBHS_PORTSC1 |= USBHS_PORTSC_PFSC; // force 12 Mbit/sec
|
//USBHS_PORTSC1 |= USBHS_PORTSC_PFSC; // force 12 Mbit/sec
|
||||||
//USBHS_PORTSC1 |= USBHS_PORTSC_PHCD; // phy off
|
//USBHS_PORTSC1 |= USBHS_PORTSC_PHCD; // phy off
|
||||||
|
|
||||||
//Serial.print("USBHS_ASYNCLISTADDR = ");
|
//println("USBHS_ASYNCLISTADDR = ", USBHS_ASYNCLISTADDR, HEX);
|
||||||
//Serial.println(USBHS_ASYNCLISTADDR, HEX);
|
//println("USBHS_PERIODICLISTBASE = ", USBHS_PERIODICLISTBASE, HEX);
|
||||||
//Serial.print("USBHS_PERIODICLISTBASE = ");
|
//println("periodictable = ", (uint32_t)periodictable, HEX);
|
||||||
//Serial.println(USBHS_PERIODICLISTBASE, HEX);
|
|
||||||
//Serial.print("periodictable = ");
|
|
||||||
//Serial.println((uint32_t)periodictable, HEX);
|
|
||||||
|
|
||||||
// enable interrupts, after this point interruts to all the work
|
// enable interrupts, after this point interruts to all the work
|
||||||
attachInterruptVector(IRQ_USBHS, isr);
|
attachInterruptVector(IRQ_USBHS, isr);
|
||||||
@ -207,31 +196,29 @@ void USBHost::isr()
|
|||||||
uint32_t stat = USBHS_USBSTS;
|
uint32_t stat = USBHS_USBSTS;
|
||||||
USBHS_USBSTS = stat; // clear pending interrupts
|
USBHS_USBSTS = stat; // clear pending interrupts
|
||||||
//stat &= USBHS_USBINTR; // mask away unwanted interrupts
|
//stat &= USBHS_USBINTR; // mask away unwanted interrupts
|
||||||
Serial.println();
|
println();
|
||||||
Serial.print("ISR: ");
|
println("ISR: ", stat, HEX);
|
||||||
Serial.print(stat, HEX);
|
//if (stat & USBHS_USBSTS_UI) println(" USB Interrupt");
|
||||||
Serial.println();
|
if (stat & USBHS_USBSTS_UEI) println(" USB Error");
|
||||||
//if (stat & USBHS_USBSTS_UI) Serial.println(" USB Interrupt");
|
if (stat & USBHS_USBSTS_PCI) println(" Port Change");
|
||||||
if (stat & USBHS_USBSTS_UEI) Serial.println(" USB Error");
|
//if (stat & USBHS_USBSTS_FRI) println(" Frame List Rollover");
|
||||||
if (stat & USBHS_USBSTS_PCI) Serial.println(" Port Change");
|
if (stat & USBHS_USBSTS_SEI) println(" System Error");
|
||||||
//if (stat & USBHS_USBSTS_FRI) Serial.println(" Frame List Rollover");
|
if (stat & USBHS_USBSTS_AAI) println(" Async Advance (doorbell)");
|
||||||
if (stat & USBHS_USBSTS_SEI) Serial.println(" System Error");
|
if (stat & USBHS_USBSTS_URI) println(" Reset Recv");
|
||||||
if (stat & USBHS_USBSTS_AAI) Serial.println(" Async Advance (doorbell)");
|
//if (stat & USBHS_USBSTS_SRI) println(" SOF");
|
||||||
if (stat & USBHS_USBSTS_URI) Serial.println(" Reset Recv");
|
if (stat & USBHS_USBSTS_SLI) println(" Suspend");
|
||||||
//if (stat & USBHS_USBSTS_SRI) Serial.println(" SOF");
|
if (stat & USBHS_USBSTS_HCH) println(" Host Halted");
|
||||||
if (stat & USBHS_USBSTS_SLI) Serial.println(" Suspend");
|
//if (stat & USBHS_USBSTS_RCL) println(" Reclamation");
|
||||||
if (stat & USBHS_USBSTS_HCH) Serial.println(" Host Halted");
|
//if (stat & USBHS_USBSTS_PS) println(" Periodic Sched En");
|
||||||
//if (stat & USBHS_USBSTS_RCL) Serial.println(" Reclamation");
|
//if (stat & USBHS_USBSTS_AS) println(" Async Sched En");
|
||||||
//if (stat & USBHS_USBSTS_PS) Serial.println(" Periodic Sched En");
|
if (stat & USBHS_USBSTS_NAKI) println(" NAK");
|
||||||
//if (stat & USBHS_USBSTS_AS) Serial.println(" Async Sched En");
|
if (stat & USBHS_USBSTS_UAI) println(" USB Async");
|
||||||
if (stat & USBHS_USBSTS_NAKI) Serial.println(" NAK");
|
if (stat & USBHS_USBSTS_UPI) println(" USB Periodic");
|
||||||
if (stat & USBHS_USBSTS_UAI) Serial.println(" USB Async");
|
if (stat & USBHS_USBSTS_TI0) println(" Timer0");
|
||||||
if (stat & USBHS_USBSTS_UPI) Serial.println(" USB Periodic");
|
if (stat & USBHS_USBSTS_TI1) println(" Timer1");
|
||||||
if (stat & USBHS_USBSTS_TI0) Serial.println(" Timer0");
|
|
||||||
if (stat & USBHS_USBSTS_TI1) Serial.println(" Timer1");
|
|
||||||
|
|
||||||
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");
|
println("Async Followup");
|
||||||
//print(async_followup_first, async_followup_last);
|
//print(async_followup_first, async_followup_last);
|
||||||
Transfer_t *p = async_followup_first;
|
Transfer_t *p = async_followup_first;
|
||||||
while (p) {
|
while (p) {
|
||||||
@ -249,7 +236,7 @@ void USBHost::isr()
|
|||||||
//print(async_followup_first, async_followup_last);
|
//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");
|
println("Periodic Followup");
|
||||||
Transfer_t *p = periodic_followup_first;
|
Transfer_t *p = periodic_followup_first;
|
||||||
while (p) {
|
while (p) {
|
||||||
if (followup_Transfer(p)) {
|
if (followup_Transfer(p)) {
|
||||||
@ -267,16 +254,14 @@ void USBHost::isr()
|
|||||||
|
|
||||||
if (stat & USBHS_USBSTS_PCI) { // port change detected
|
if (stat & USBHS_USBSTS_PCI) { // port change detected
|
||||||
const uint32_t portstat = USBHS_PORTSC1;
|
const uint32_t portstat = USBHS_PORTSC1;
|
||||||
Serial.print("port change: ");
|
println("port change: ", portstat, HEX);
|
||||||
Serial.print(portstat, HEX);
|
|
||||||
Serial.println();
|
|
||||||
USBHS_PORTSC1 = portstat | (USBHS_PORTSC_OCC|USBHS_PORTSC_PEC|USBHS_PORTSC_CSC);
|
USBHS_PORTSC1 = portstat | (USBHS_PORTSC_OCC|USBHS_PORTSC_PEC|USBHS_PORTSC_CSC);
|
||||||
if (portstat & USBHS_PORTSC_OCC) {
|
if (portstat & USBHS_PORTSC_OCC) {
|
||||||
Serial.println(" overcurrent change");
|
println(" overcurrent change");
|
||||||
}
|
}
|
||||||
if (portstat & USBHS_PORTSC_CSC) {
|
if (portstat & USBHS_PORTSC_CSC) {
|
||||||
if (portstat & USBHS_PORTSC_CCS) {
|
if (portstat & USBHS_PORTSC_CCS) {
|
||||||
Serial.println(" connect");
|
println(" connect");
|
||||||
if (port_state == PORT_STATE_DISCONNECTED
|
if (port_state == PORT_STATE_DISCONNECTED
|
||||||
|| port_state == PORT_STATE_DEBOUNCE) {
|
|| port_state == PORT_STATE_DEBOUNCE) {
|
||||||
// 100 ms debounce (USB 2.0: TATTDB, page 150 & 188)
|
// 100 ms debounce (USB 2.0: TATTDB, page 150 & 188)
|
||||||
@ -287,7 +272,7 @@ void USBHost::isr()
|
|||||||
stat &= ~USBHS_USBSTS_TI0;
|
stat &= ~USBHS_USBSTS_TI0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Serial.println(" disconnect");
|
println(" disconnect");
|
||||||
port_state = PORT_STATE_DISCONNECTED;
|
port_state = PORT_STATE_DISCONNECTED;
|
||||||
USBPHY_CTRL_CLR = USBPHY_CTRL_ENHOSTDISCONDETECT;
|
USBPHY_CTRL_CLR = USBPHY_CTRL_ENHOSTDISCONDETECT;
|
||||||
// TODO: delete & clean up device state...
|
// TODO: delete & clean up device state...
|
||||||
@ -295,9 +280,9 @@ void USBHost::isr()
|
|||||||
}
|
}
|
||||||
if (portstat & USBHS_PORTSC_PEC) {
|
if (portstat & USBHS_PORTSC_PEC) {
|
||||||
// PEC bit only detects disable
|
// PEC bit only detects disable
|
||||||
Serial.println(" disable");
|
println(" disable");
|
||||||
} else if (port_state == PORT_STATE_RESET && portstat & USBHS_PORTSC_PE) {
|
} else if (port_state == PORT_STATE_RESET && portstat & USBHS_PORTSC_PE) {
|
||||||
Serial.println(" port enabled");
|
println(" port enabled");
|
||||||
port_state = PORT_STATE_RECOVERY;
|
port_state = PORT_STATE_RECOVERY;
|
||||||
// 10 ms reset recover (USB 2.0: TRSTRCY, page 151 & 188)
|
// 10 ms reset recover (USB 2.0: TRSTRCY, page 151 & 188)
|
||||||
USBHS_GPTIMER0LD = 10000; // microseconds
|
USBHS_GPTIMER0LD = 10000; // microseconds
|
||||||
@ -308,19 +293,19 @@ void USBHost::isr()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (portstat & USBHS_PORTSC_FPR) {
|
if (portstat & USBHS_PORTSC_FPR) {
|
||||||
Serial.println(" force resume");
|
println(" force resume");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (stat & USBHS_USBSTS_TI0) { // timer 0
|
if (stat & USBHS_USBSTS_TI0) { // timer 0
|
||||||
Serial.println("timer");
|
println("timer");
|
||||||
if (port_state == PORT_STATE_DEBOUNCE) {
|
if (port_state == PORT_STATE_DEBOUNCE) {
|
||||||
port_state = PORT_STATE_RESET;
|
port_state = PORT_STATE_RESET;
|
||||||
USBHS_PORTSC1 |= USBHS_PORTSC_PR; // begin reset sequence
|
USBHS_PORTSC1 |= USBHS_PORTSC_PR; // begin reset sequence
|
||||||
Serial.println(" begin reset");
|
println(" begin reset");
|
||||||
} else if (port_state == PORT_STATE_RECOVERY) {
|
} else if (port_state == PORT_STATE_RECOVERY) {
|
||||||
port_state = PORT_STATE_ACTIVE;
|
port_state = PORT_STATE_ACTIVE;
|
||||||
Serial.println(" end recovery");
|
println(" end recovery");
|
||||||
|
|
||||||
// HCSPARAMS TTCTRL page 1671
|
// HCSPARAMS TTCTRL page 1671
|
||||||
uint32_t speed = (USBHS_PORTSC1 >> 26) & 3;
|
uint32_t speed = (USBHS_PORTSC1 >> 26) & 3;
|
||||||
@ -366,7 +351,7 @@ Pipe_t * USBHost::new_Pipe(Device_t *dev, uint32_t type, uint32_t endpoint,
|
|||||||
Transfer_t *halt;
|
Transfer_t *halt;
|
||||||
uint32_t c=0, dtc=0, smask=0, cmask=0, offset=0;
|
uint32_t c=0, dtc=0, smask=0, cmask=0, offset=0;
|
||||||
|
|
||||||
Serial.println("new_Pipe");
|
println("new_Pipe");
|
||||||
pipe = allocate_Pipe();
|
pipe = allocate_Pipe();
|
||||||
if (!pipe) return NULL;
|
if (!pipe) return NULL;
|
||||||
halt = allocate_Transfer();
|
halt = allocate_Transfer();
|
||||||
@ -416,12 +401,12 @@ Pipe_t * USBHost::new_Pipe(Device_t *dev, uint32_t type, uint32_t endpoint,
|
|||||||
pipe->qh.horizontal_link = (uint32_t)&(pipe->qh) | 2; // 2=QH
|
pipe->qh.horizontal_link = (uint32_t)&(pipe->qh) | 2; // 2=QH
|
||||||
USBHS_ASYNCLISTADDR = (uint32_t)&(pipe->qh);
|
USBHS_ASYNCLISTADDR = (uint32_t)&(pipe->qh);
|
||||||
USBHS_USBCMD |= USBHS_USBCMD_ASE; // enable async schedule
|
USBHS_USBCMD |= USBHS_USBCMD_ASE; // enable async schedule
|
||||||
//Serial.println(" first in async list");
|
//println(" first in async list");
|
||||||
} else {
|
} else {
|
||||||
// EHCI 1.0: section 4.8.1, page 72
|
// EHCI 1.0: section 4.8.1, page 72
|
||||||
pipe->qh.horizontal_link = list->qh.horizontal_link;
|
pipe->qh.horizontal_link = list->qh.horizontal_link;
|
||||||
list->qh.horizontal_link = (uint32_t)&(pipe->qh) | 2;
|
list->qh.horizontal_link = (uint32_t)&(pipe->qh) | 2;
|
||||||
//Serial.println(" added to async list");
|
//println(" added to async list");
|
||||||
}
|
}
|
||||||
} else if (type == 3) {
|
} else if (type == 3) {
|
||||||
// interrupt: add to periodic schedule
|
// interrupt: add to periodic schedule
|
||||||
@ -436,8 +421,7 @@ Pipe_t * USBHost::new_Pipe(Device_t *dev, uint32_t type, uint32_t endpoint,
|
|||||||
// quick hack for testing, just put it into the first table entry
|
// quick hack for testing, just put it into the first table entry
|
||||||
pipe->qh.horizontal_link = periodictable[0];
|
pipe->qh.horizontal_link = periodictable[0];
|
||||||
periodictable[0] = (uint32_t)&(pipe->qh) | 2; // 2=QH
|
periodictable[0] = (uint32_t)&(pipe->qh) | 2; // 2=QH
|
||||||
Serial.print("init periodictable with ");
|
println("init periodictable with ", periodictable[0], HEX);
|
||||||
Serial.println(periodictable[0], HEX);
|
|
||||||
}
|
}
|
||||||
return pipe;
|
return pipe;
|
||||||
}
|
}
|
||||||
@ -476,7 +460,7 @@ bool USBHost::queue_Control_Transfer(Device_t *dev, setup_t *setup, void *buf, U
|
|||||||
Transfer_t *transfer, *data, *status;
|
Transfer_t *transfer, *data, *status;
|
||||||
uint32_t status_direction;
|
uint32_t status_direction;
|
||||||
|
|
||||||
Serial.println("new_Control_Transfer");
|
println("new_Control_Transfer");
|
||||||
if (setup->wLength > 16384) return false; // max 16K data for control
|
if (setup->wLength > 16384) return false; // max 16K data for control
|
||||||
transfer = allocate_Transfer();
|
transfer = allocate_Transfer();
|
||||||
if (!transfer) return false;
|
if (!transfer) return false;
|
||||||
@ -501,8 +485,7 @@ bool USBHost::queue_Control_Transfer(Device_t *dev, setup_t *setup, void *buf, U
|
|||||||
transfer->qtd.next = (uint32_t)status;
|
transfer->qtd.next = (uint32_t)status;
|
||||||
status_direction = 1; // always IN, USB 2.0 page 226
|
status_direction = 1; // always IN, USB 2.0 page 226
|
||||||
}
|
}
|
||||||
//Serial.print("setup address ");
|
//println("setup address ", (uint32_t)setup, HEX);
|
||||||
//Serial.println((uint32_t)setup, HEX);
|
|
||||||
init_qTD(transfer, setup, 8, 2, 0, false);
|
init_qTD(transfer, 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 = dev->control_pipe;
|
status->pipe = dev->control_pipe;
|
||||||
@ -526,7 +509,7 @@ bool USBHost::queue_Data_Transfer(Pipe_t *pipe, void *buffer, uint32_t len, USBD
|
|||||||
|
|
||||||
// TODO: option for zero length packet? Maybe in Pipe_t fields?
|
// TODO: option for zero length packet? Maybe in Pipe_t fields?
|
||||||
|
|
||||||
Serial.println("new_Data_Transfer");
|
println("new_Data_Transfer");
|
||||||
// allocate qTDs
|
// allocate qTDs
|
||||||
transfer = allocate_Transfer();
|
transfer = allocate_Transfer();
|
||||||
if (!transfer) return false;
|
if (!transfer) return false;
|
||||||
@ -628,8 +611,7 @@ bool USBHost::queue_Transfer(Pipe_t *pipe, Transfer_t *transfer)
|
|||||||
|
|
||||||
static bool followup_Transfer(Transfer_t *transfer)
|
static bool followup_Transfer(Transfer_t *transfer)
|
||||||
{
|
{
|
||||||
//Serial.print(" Followup ");
|
//println(" Followup ", (uint32_t)transfer, HEX);
|
||||||
//Serial.println((uint32_t)transfer, HEX);
|
|
||||||
|
|
||||||
if (!(transfer->qtd.token & 0x80)) {
|
if (!(transfer->qtd.token & 0x80)) {
|
||||||
// TODO: check error status
|
// TODO: check error status
|
||||||
@ -641,7 +623,7 @@ static bool followup_Transfer(Transfer_t *transfer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// do callback function...
|
// do callback function...
|
||||||
//Serial.println(" completed");
|
//println(" completed");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -744,11 +726,11 @@ static uint32_t max4(uint32_t n1, uint32_t n2, uint32_t n3, uint32_t n4)
|
|||||||
// smask: [out] Start Mask
|
// smask: [out] Start Mask
|
||||||
// cmask: [out] Complete Mask
|
// cmask: [out] Complete Mask
|
||||||
//
|
//
|
||||||
static bool allocate_interrupt_pipe_bandwidth(uint32_t speed, uint32_t maxlen,
|
bool USBHost::allocate_interrupt_pipe_bandwidth(uint32_t speed, uint32_t maxlen,
|
||||||
uint32_t interval, uint32_t direction, uint32_t *offset_out,
|
uint32_t interval, uint32_t direction, uint32_t *offset_out,
|
||||||
uint32_t *smask_out, uint32_t *cmask_out)
|
uint32_t *smask_out, uint32_t *cmask_out)
|
||||||
{
|
{
|
||||||
Serial.println("allocate_interrupt_pipe_bandwidth");
|
println("allocate_interrupt_pipe_bandwidth");
|
||||||
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
|
||||||
@ -766,10 +748,10 @@ static bool allocate_interrupt_pipe_bandwidth(uint32_t speed, uint32_t maxlen,
|
|||||||
min_offset = offset;
|
min_offset = offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Serial.print(" min_bw = ");
|
print(" min_bw = ");
|
||||||
Serial.print(min_bw);
|
print(min_bw);
|
||||||
Serial.print(", at offset = ");
|
print(", at offset = ");
|
||||||
Serial.println(min_offset);
|
println(min_offset);
|
||||||
if (min_bw > 187) return false;
|
if (min_bw > 187) return false;
|
||||||
for (uint32_t i=min_offset; i < PERIODIC_LIST_SIZE*8; i += interval) {
|
for (uint32_t i=min_offset; i < PERIODIC_LIST_SIZE*8; i += interval) {
|
||||||
uframe_bandwidth[i] += stime;
|
uframe_bandwidth[i] += stime;
|
||||||
@ -821,12 +803,12 @@ static bool allocate_interrupt_pipe_bandwidth(uint32_t speed, uint32_t maxlen,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Serial.print(" min_bw = ");
|
print(" min_bw = ");
|
||||||
Serial.println(min_bw);
|
println(min_bw);
|
||||||
Serial.print(", at offset = ");
|
print(", at offset = ");
|
||||||
Serial.print(min_offset);
|
print(min_offset);
|
||||||
Serial.print(", shift= ");
|
print(", shift= ");
|
||||||
Serial.println(min_shift);
|
println(min_shift);
|
||||||
if (min_bw > 187) return false;
|
if (min_bw > 187) return false;
|
||||||
for (uint32_t i=min_offset; i < PERIODIC_LIST_SIZE; i += interval) {
|
for (uint32_t i=min_offset; i < PERIODIC_LIST_SIZE; i += interval) {
|
||||||
uint32_t n = (i << 3) + min_shift;
|
uint32_t n = (i << 3) + min_shift;
|
||||||
|
@ -57,14 +57,14 @@ Device_t * USBHost::new_Device(uint32_t speed, uint32_t hub_addr, uint32_t hub_p
|
|||||||
{
|
{
|
||||||
Device_t *dev;
|
Device_t *dev;
|
||||||
|
|
||||||
Serial.print("new_Device: ");
|
print("new_Device: ");
|
||||||
switch (speed) {
|
switch (speed) {
|
||||||
case 0: Serial.print("12"); break;
|
case 0: print("12"); break;
|
||||||
case 1: Serial.print("1.5"); break;
|
case 1: print("1.5"); break;
|
||||||
case 2: Serial.print("480"); break;
|
case 2: print("480"); break;
|
||||||
default: Serial.print("??");
|
default: print("??");
|
||||||
}
|
}
|
||||||
Serial.println(" Mbit/sec");
|
println(" Mbit/sec");
|
||||||
dev = allocate_Device();
|
dev = allocate_Device();
|
||||||
if (!dev) return NULL;
|
if (!dev) return NULL;
|
||||||
memset(dev, 0, sizeof(Device_t));
|
memset(dev, 0, sizeof(Device_t));
|
||||||
@ -100,7 +100,7 @@ void USBHost::enumeration(const Transfer_t *transfer)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Serial.println("enumeration:");
|
println("enumeration:");
|
||||||
//print_hexbytes(transfer->buffer, transfer->length);
|
//print_hexbytes(transfer->buffer, transfer->length);
|
||||||
//print(transfer);
|
//print(transfer);
|
||||||
dev = transfer->pipe->device;
|
dev = transfer->pipe->device;
|
||||||
@ -199,8 +199,7 @@ void USBHost::enumeration(const Transfer_t *transfer)
|
|||||||
return;
|
return;
|
||||||
case 12: // read 9 bytes, request all of config desc
|
case 12: // read 9 bytes, request all of config desc
|
||||||
enumlen = enumbuf[2] | (enumbuf[3] << 8);
|
enumlen = enumbuf[2] | (enumbuf[3] << 8);
|
||||||
Serial.print("Config data length = ");
|
println("Config data length = ", enumlen);
|
||||||
Serial.println(enumlen);
|
|
||||||
if (enumlen > sizeof(enumbuf)) {
|
if (enumlen > sizeof(enumbuf)) {
|
||||||
// TODO: how to handle device with too much config data
|
// TODO: how to handle device with too much config data
|
||||||
}
|
}
|
||||||
@ -209,10 +208,8 @@ void USBHost::enumeration(const Transfer_t *transfer)
|
|||||||
dev->enum_state = 13;
|
dev->enum_state = 13;
|
||||||
return;
|
return;
|
||||||
case 13: // read all config desc, send set config
|
case 13: // read all config desc, send set config
|
||||||
Serial.print("bNumInterfaces = ");
|
println("bNumInterfaces = ", enumbuf[4]);
|
||||||
Serial.println(enumbuf[4]);
|
println("bConfigurationValue = ", enumbuf[5]);
|
||||||
Serial.print("bConfigurationValue = ");
|
|
||||||
Serial.println(enumbuf[5]);
|
|
||||||
dev->bmAttributes = enumbuf[7];
|
dev->bmAttributes = enumbuf[7];
|
||||||
dev->bMaxPower = enumbuf[8];
|
dev->bMaxPower = enumbuf[8];
|
||||||
// TODO: actually do something with interface descriptor?
|
// TODO: actually do something with interface descriptor?
|
||||||
@ -259,16 +256,16 @@ void USBHost::claim_drivers(Device_t *dev)
|
|||||||
while (p < end) {
|
while (p < end) {
|
||||||
uint8_t desclen = *p;
|
uint8_t desclen = *p;
|
||||||
uint8_t desctype = *(p+1);
|
uint8_t desctype = *(p+1);
|
||||||
Serial.print("Descriptor ");
|
print("Descriptor ");
|
||||||
Serial.print(desctype);
|
print(desctype);
|
||||||
Serial.print(" = ");
|
print(" = ");
|
||||||
if (desctype == 4) Serial.println("INTERFACE");
|
if (desctype == 4) println("INTERFACE");
|
||||||
else if (desctype == 5) Serial.println("ENDPOINT");
|
else if (desctype == 5) println("ENDPOINT");
|
||||||
else if (desctype == 6) Serial.println("DEV_QUALIFIER");
|
else if (desctype == 6) println("DEV_QUALIFIER");
|
||||||
else if (desctype == 7) Serial.println("OTHER_SPEED");
|
else if (desctype == 7) println("OTHER_SPEED");
|
||||||
else if (desctype == 11) Serial.println("IAD");
|
else if (desctype == 11) println("IAD");
|
||||||
else if (desctype == 33) Serial.println("HID");
|
else if (desctype == 33) println("HID");
|
||||||
else Serial.println(" ???");
|
else println(" ???");
|
||||||
if (desctype == 11 && desclen == 8) {
|
if (desctype == 11 && desclen == 8) {
|
||||||
// TODO: parse IAD, ask drivers for claim
|
// TODO: parse IAD, ask drivers for claim
|
||||||
// TODO: how to skip over all interfaces IAD represented
|
// TODO: how to skip over all interfaces IAD represented
|
||||||
@ -308,15 +305,11 @@ static uint32_t assign_addr(void)
|
|||||||
|
|
||||||
static void pipe_set_maxlen(Pipe_t *pipe, uint32_t maxlen)
|
static void pipe_set_maxlen(Pipe_t *pipe, uint32_t maxlen)
|
||||||
{
|
{
|
||||||
Serial.print("pipe_set_maxlen ");
|
|
||||||
Serial.println(maxlen);
|
|
||||||
pipe->qh.capabilities[0] = (pipe->qh.capabilities[0] & 0x8000FFFF) | (maxlen << 16);
|
pipe->qh.capabilities[0] = (pipe->qh.capabilities[0] & 0x8000FFFF) | (maxlen << 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pipe_set_addr(Pipe_t *pipe, uint32_t addr)
|
static void pipe_set_addr(Pipe_t *pipe, uint32_t addr)
|
||||||
{
|
{
|
||||||
Serial.print("pipe_set_addr ");
|
|
||||||
Serial.println(addr);
|
|
||||||
pipe->qh.capabilities[0] = (pipe->qh.capabilities[0] & 0xFFFFFF80) | addr;
|
pipe->qh.capabilities[0] = (pipe->qh.capabilities[0] & 0xFFFFFF80) | addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
86
hub.cpp
86
hub.cpp
@ -35,8 +35,7 @@ bool USBHub::claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t
|
|||||||
// only claim entire device, never at interface level
|
// only claim entire device, never at interface level
|
||||||
if (type != 0) return false;
|
if (type != 0) return false;
|
||||||
|
|
||||||
Serial.print("USBHub claim_device this=");
|
println("USBHub claim_device this=", (uint32_t)this, HEX);
|
||||||
Serial.println((uint32_t)this, HEX);
|
|
||||||
|
|
||||||
// check for HUB type
|
// check for HUB type
|
||||||
if (dev->bDeviceClass != 9 || dev->bDeviceSubClass != 0) return false;
|
if (dev->bDeviceClass != 9 || dev->bDeviceSubClass != 0) return false;
|
||||||
@ -56,20 +55,17 @@ bool USBHub::claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t
|
|||||||
if (maxsize == 0) return false;
|
if (maxsize == 0) return false;
|
||||||
if (maxsize > 1) return false; // do hub chips with > 7 ports exist?
|
if (maxsize > 1) return false; // do hub chips with > 7 ports exist?
|
||||||
|
|
||||||
Serial.println(descriptors[9]);
|
println(descriptors[9]);
|
||||||
Serial.println(descriptors[10]);
|
println(descriptors[10]);
|
||||||
Serial.println(descriptors[11], HEX);
|
println(descriptors[11], HEX);
|
||||||
Serial.println(maxsize);
|
println(maxsize);
|
||||||
// bDeviceProtocol = 0 is full speed
|
// bDeviceProtocol = 0 is full speed
|
||||||
// bDeviceProtocol = 1 is high speed single TT
|
// bDeviceProtocol = 1 is high speed single TT
|
||||||
// bDeviceProtocol = 2 is high speed multiple TT
|
// bDeviceProtocol = 2 is high speed multiple TT
|
||||||
|
|
||||||
Serial.print("bDeviceClass = ");
|
println("bDeviceClass = ", dev->bDeviceClass);
|
||||||
Serial.println(dev->bDeviceClass);
|
println("bDeviceSubClass = ", dev->bDeviceSubClass);
|
||||||
Serial.print("bDeviceSubClass = ");
|
println("bDeviceProtocol = ", dev->bDeviceProtocol);
|
||||||
Serial.println(dev->bDeviceSubClass);
|
|
||||||
Serial.print("bDeviceProtocol = ");
|
|
||||||
Serial.println(dev->bDeviceProtocol);
|
|
||||||
|
|
||||||
changepipe = NULL;
|
changepipe = NULL;
|
||||||
changebits = 0;
|
changebits = 0;
|
||||||
@ -118,7 +114,7 @@ void USBHub::reset(uint32_t port)
|
|||||||
|
|
||||||
void USBHub::control(const Transfer_t *transfer)
|
void USBHub::control(const Transfer_t *transfer)
|
||||||
{
|
{
|
||||||
Serial.println("USBHub control callback");
|
println("USBHub control callback");
|
||||||
print_hexbytes(transfer->buffer, transfer->length);
|
print_hexbytes(transfer->buffer, transfer->length);
|
||||||
|
|
||||||
if (state == 0) {
|
if (state == 0) {
|
||||||
@ -130,9 +126,9 @@ void USBHub::control(const Transfer_t *transfer)
|
|||||||
powertime = hub_desc[5];
|
powertime = hub_desc[5];
|
||||||
// TODO: do we need to use the DeviceRemovable
|
// TODO: do we need to use the DeviceRemovable
|
||||||
// bits to mke synthetic device connect events?
|
// bits to mke synthetic device connect events?
|
||||||
Serial.print("Hub has ");
|
print("Hub has ");
|
||||||
Serial.print(numports);
|
print(numports);
|
||||||
Serial.println(" ports");
|
println(" ports");
|
||||||
state = 1;
|
state = 1;
|
||||||
poweron(1);
|
poweron(1);
|
||||||
}
|
}
|
||||||
@ -140,12 +136,10 @@ void USBHub::control(const Transfer_t *transfer)
|
|||||||
// turn on power to all ports
|
// turn on power to all ports
|
||||||
poweron(++state);
|
poweron(++state);
|
||||||
} else if (state == numports) {
|
} else if (state == numports) {
|
||||||
Serial.println("power turned on to all ports");
|
println("power turned on to all ports");
|
||||||
Serial.print("device addr = ");
|
println("device addr = ", device->address);
|
||||||
Serial.println(device->address);
|
|
||||||
changepipe = new_Pipe(device, 3, endpoint, 1, 1, 512);
|
changepipe = new_Pipe(device, 3, endpoint, 1, 1, 512);
|
||||||
Serial.print("pipe cap1 = ");
|
println("pipe cap1 = ", changepipe->qh.capabilities[0], HEX);
|
||||||
Serial.println(changepipe->qh.capabilities[0], HEX);
|
|
||||||
changepipe->callback_function = callback;
|
changepipe->callback_function = callback;
|
||||||
queue_Data_Transfer(changepipe, &changebits, 1, this);
|
queue_Data_Transfer(changepipe, &changebits, 1, this);
|
||||||
state = 255;
|
state = 255;
|
||||||
@ -153,7 +147,7 @@ void USBHub::control(const Transfer_t *transfer)
|
|||||||
// up and running...
|
// up and running...
|
||||||
switch (setup.word1) {
|
switch (setup.word1) {
|
||||||
case 0x000000A0: // get hub status
|
case 0x000000A0: // get hub status
|
||||||
Serial.println("New Hub Status");
|
println("New Hub Status");
|
||||||
clearstatus(0);
|
clearstatus(0);
|
||||||
return;
|
return;
|
||||||
case 0x000000A3: // get port status
|
case 0x000000A3: // get port status
|
||||||
@ -161,12 +155,11 @@ void USBHub::control(const Transfer_t *transfer)
|
|||||||
clearstatus(setup.wIndex);
|
clearstatus(setup.wIndex);
|
||||||
return;
|
return;
|
||||||
case 0x00100120: // clear hub status
|
case 0x00100120: // clear hub status
|
||||||
Serial.println("Hub Status Cleared");
|
println("Hub Status Cleared");
|
||||||
changebits &= ~1;
|
changebits &= ~1;
|
||||||
break;
|
break;
|
||||||
case 0x00100123: // clear port status
|
case 0x00100123: // clear port status
|
||||||
Serial.print("Port Status Cleared, port=");
|
println("Port Status Cleared, port=", setup.wIndex);
|
||||||
Serial.println(setup.wIndex);
|
|
||||||
changebits &= ~(1 << setup.wIndex);
|
changebits &= ~(1 << setup.wIndex);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -176,15 +169,14 @@ void USBHub::control(const Transfer_t *transfer)
|
|||||||
|
|
||||||
void USBHub::callback(const Transfer_t *transfer)
|
void USBHub::callback(const Transfer_t *transfer)
|
||||||
{
|
{
|
||||||
Serial.println("HUB Callback (static)");
|
println("HUB Callback (static)");
|
||||||
if (transfer->driver) ((USBHub *)(transfer->driver))->status_change(transfer);
|
if (transfer->driver) ((USBHub *)(transfer->driver))->status_change(transfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBHub::status_change(const Transfer_t *transfer)
|
void USBHub::status_change(const Transfer_t *transfer)
|
||||||
{
|
{
|
||||||
Serial.println("HUB Callback (member)");
|
println("HUB Callback (member)");
|
||||||
Serial.print("status = ");
|
println("status = ", changebits, HEX);
|
||||||
Serial.println(changebits, HEX);
|
|
||||||
// TODO: do something with the status change info
|
// TODO: do something with the status change info
|
||||||
update_status();
|
update_status();
|
||||||
queue_Data_Transfer(changepipe, &changebits, 1, this);
|
queue_Data_Transfer(changepipe, &changebits, 1, this);
|
||||||
@ -208,42 +200,42 @@ void USBHub::new_port_status(uint32_t port, uint32_t status)
|
|||||||
uint32_t priorstatus = portstatus[port - 1];
|
uint32_t priorstatus = portstatus[port - 1];
|
||||||
portstatus[port] = status;
|
portstatus[port] = status;
|
||||||
|
|
||||||
Serial.print("New Port Status, port=");
|
print("New Port Status, port=");
|
||||||
Serial.print(port);
|
print(port);
|
||||||
Serial.print(", status=");
|
print(", status=");
|
||||||
Serial.println(status, HEX);
|
println(status, HEX);
|
||||||
|
|
||||||
// status bits, USB 2.0: 11.24.2.7.1 page 427
|
// status bits, USB 2.0: 11.24.2.7.1 page 427
|
||||||
if (status & 0x0001) Serial.println(" Device is present: ");
|
if (status & 0x0001) println(" Device is present: ");
|
||||||
if (status & 0x0002) {
|
if (status & 0x0002) {
|
||||||
Serial.println(" Enabled, speed = ");
|
println(" Enabled, speed = ");
|
||||||
if (status & 0x0200) {
|
if (status & 0x0200) {
|
||||||
Serial.print("1.5");
|
print("1.5");
|
||||||
} else {
|
} else {
|
||||||
if (status & 0x0400) {
|
if (status & 0x0400) {
|
||||||
Serial.print("480");
|
print("480");
|
||||||
} else {
|
} else {
|
||||||
Serial.print("12");
|
print("12");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Serial.println(" Mbit/sec");
|
println(" Mbit/sec");
|
||||||
}
|
}
|
||||||
if (status & 0x0004) Serial.println(" Suspended");
|
if (status & 0x0004) println(" Suspended");
|
||||||
if (status & 0x0008) Serial.println(" Over-current");
|
if (status & 0x0008) println(" Over-current");
|
||||||
if (status & 0x0010) Serial.println(" Reset");
|
if (status & 0x0010) println(" Reset");
|
||||||
if (status & 0x0100) Serial.println(" Has Power");
|
if (status & 0x0100) println(" Has Power");
|
||||||
if (status & 0x0800) Serial.println(" Test Mode");
|
if (status & 0x0800) println(" Test Mode");
|
||||||
if (status & 0x1000) Serial.println(" Software Controls LEDs");
|
if (status & 0x1000) println(" Software Controls LEDs");
|
||||||
|
|
||||||
if ((status & 0x0001) && !(priorstatus & 0x0001)) {
|
if ((status & 0x0001) && !(priorstatus & 0x0001)) {
|
||||||
Serial.println(" connect");
|
println(" connect");
|
||||||
// 100 ms debounce (USB 2.0: TATTDB, page 150 & 188)
|
// 100 ms debounce (USB 2.0: TATTDB, page 150 & 188)
|
||||||
delay(100); // TODO: horribly bad... need timing events
|
delay(100); // TODO: horribly bad... need timing events
|
||||||
reset(port);
|
reset(port);
|
||||||
// TODO... reset timer?
|
// TODO... reset timer?
|
||||||
|
|
||||||
} else if (!(status & 0x0001) && (priorstatus & 0x0001)) {
|
} else if (!(status & 0x0001) && (priorstatus & 0x0001)) {
|
||||||
Serial.println(" disconnect");
|
println(" disconnect");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
18
keyboard.cpp
18
keyboard.cpp
@ -33,8 +33,7 @@ KeyboardController::KeyboardController()
|
|||||||
|
|
||||||
bool KeyboardController::claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t len)
|
bool KeyboardController::claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t len)
|
||||||
{
|
{
|
||||||
Serial.print("KeyboardController claim this=");
|
println("KeyboardController claim this=", (uint32_t)this, HEX);
|
||||||
Serial.println((uint32_t)this, HEX);
|
|
||||||
|
|
||||||
// only claim at interface level
|
// only claim at interface level
|
||||||
if (type != 1) return false;
|
if (type != 1) return false;
|
||||||
@ -50,19 +49,16 @@ bool KeyboardController::claim(Device_t *dev, int type, const uint8_t *descripto
|
|||||||
if (descriptors[18] != 7) return false;
|
if (descriptors[18] != 7) return false;
|
||||||
if (descriptors[19] != 5) return false; // endpoint descriptor
|
if (descriptors[19] != 5) return false; // endpoint descriptor
|
||||||
uint32_t endpoint = descriptors[20];
|
uint32_t endpoint = descriptors[20];
|
||||||
Serial.print("ep = ");
|
println("ep = ", endpoint, HEX);
|
||||||
Serial.println(endpoint, HEX);
|
|
||||||
if ((endpoint & 0xF0) != 0x80) return false; // must be IN direction
|
if ((endpoint & 0xF0) != 0x80) return false; // must be IN direction
|
||||||
endpoint &= 0x0F;
|
endpoint &= 0x0F;
|
||||||
if (endpoint == 0) return false;
|
if (endpoint == 0) return false;
|
||||||
if (descriptors[21] != 3) return false; // must be interrupt type
|
if (descriptors[21] != 3) return false; // must be interrupt type
|
||||||
uint32_t size = descriptors[22] | (descriptors[23] << 8);
|
uint32_t size = descriptors[22] | (descriptors[23] << 8);
|
||||||
Serial.print("packet size = ");
|
println("packet size = ", size);
|
||||||
Serial.println(size);
|
|
||||||
if (size != 8) return false; // must be 8 bytes for Keyboard Boot Protocol
|
if (size != 8) return false; // must be 8 bytes for Keyboard Boot Protocol
|
||||||
uint32_t interval = descriptors[24];
|
uint32_t interval = descriptors[24];
|
||||||
Serial.print("polling interval = ");
|
println("polling interval = ", interval);
|
||||||
Serial.println(interval);
|
|
||||||
datapipe = new_Pipe(dev, 3, endpoint, 1, 8, 64);
|
datapipe = new_Pipe(dev, 3, endpoint, 1, 8, 64);
|
||||||
datapipe->callback_function = callback;
|
datapipe->callback_function = callback;
|
||||||
queue_Data_Transfer(datapipe, report, 8, this);
|
queue_Data_Transfer(datapipe, report, 8, this);
|
||||||
@ -71,7 +67,7 @@ bool KeyboardController::claim(Device_t *dev, int type, const uint8_t *descripto
|
|||||||
|
|
||||||
void KeyboardController::callback(const Transfer_t *transfer)
|
void KeyboardController::callback(const Transfer_t *transfer)
|
||||||
{
|
{
|
||||||
Serial.println("KeyboardController Callback (static)");
|
println("KeyboardController Callback (static)");
|
||||||
if (transfer->driver) {
|
if (transfer->driver) {
|
||||||
((KeyboardController *)(transfer->driver))->new_data(transfer);
|
((KeyboardController *)(transfer->driver))->new_data(transfer);
|
||||||
}
|
}
|
||||||
@ -79,8 +75,8 @@ void KeyboardController::callback(const Transfer_t *transfer)
|
|||||||
|
|
||||||
void KeyboardController::new_data(const Transfer_t *transfer)
|
void KeyboardController::new_data(const Transfer_t *transfer)
|
||||||
{
|
{
|
||||||
Serial.println("KeyboardController Callback (member)");
|
println("KeyboardController Callback (member)");
|
||||||
Serial.print(" KB Data: ");
|
print(" KB Data: ");
|
||||||
print_hexbytes(transfer->buffer, 8);
|
print_hexbytes(transfer->buffer, 8);
|
||||||
// TODO: parse the new data
|
// TODO: parse the new data
|
||||||
queue_Data_Transfer(datapipe, report, 8, this);
|
queue_Data_Transfer(datapipe, report, 8, this);
|
||||||
|
Loading…
Reference in New Issue
Block a user