Преглед на файлове

All debug printing through USBHost class

main
PaulStoffregen преди 8 години
родител
ревизия
656765bac6
променени са 6 файла, в които са добавени 162 реда и са изтрити 180 реда
  1. +33
    -2
      USBHost.h
  2. +63
    -81
      ehci.cpp
  3. +20
    -27
      enumeration.cpp
  4. +39
    -47
      hub.cpp
  5. +7
    -11
      keyboard.cpp
  6. +0
    -12
      print.cpp

+ 33
- 2
USBHost.h Целия файл

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, int num);
static void print(const char *s) { Serial.print(s); }
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);

+ 63
- 81
ehci.cpp Целия файл

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()
{ {
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 = ");
Serial.println(sizeof(Device_t));
Serial.print("sizeof Pipe = ");
Serial.println(sizeof(Pipe_t));
Serial.print("sizeof Transfer = ");
Serial.println(sizeof(Transfer_t));
println("sizeof Device = ", sizeof(Device_t));
println("sizeof Pipe = ", sizeof(Pipe_t));
println("sizeof Transfer = ", 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 = ");
//Serial.println(MPU_RGDAAC0, HEX);
//println("MPU_RGDAAC0 = ", 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;
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 ");
//Serial.println(count);
//println("PLL locked, waited ", count);


// turn on power to PHY // turn on power to PHY
USBPHY_PWD = 0; USBPHY_PWD = 0;
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++) {
//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 = ");
//Serial.println(USBHS_ASYNCLISTADDR, HEX);
//Serial.print("USBHS_PERIODICLISTBASE = ");
//Serial.println(USBHS_PERIODICLISTBASE, HEX);
//Serial.print("periodictable = ");
//Serial.println((uint32_t)periodictable, HEX);
//println("USBHS_ASYNCLISTADDR = ", USBHS_ASYNCLISTADDR, HEX);
//println("USBHS_PERIODICLISTBASE = ", USBHS_PERIODICLISTBASE, HEX);
//println("periodictable = ", (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);
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();
Serial.print("ISR: ");
Serial.print(stat, HEX);
Serial.println();
//if (stat & USBHS_USBSTS_UI) Serial.println(" USB Interrupt");
if (stat & USBHS_USBSTS_UEI) Serial.println(" USB Error");
if (stat & USBHS_USBSTS_PCI) Serial.println(" Port Change");
//if (stat & USBHS_USBSTS_FRI) Serial.println(" Frame List Rollover");
if (stat & USBHS_USBSTS_SEI) Serial.println(" System Error");
if (stat & USBHS_USBSTS_AAI) Serial.println(" Async Advance (doorbell)");
if (stat & USBHS_USBSTS_URI) Serial.println(" Reset Recv");
//if (stat & USBHS_USBSTS_SRI) Serial.println(" SOF");
if (stat & USBHS_USBSTS_SLI) Serial.println(" Suspend");
if (stat & USBHS_USBSTS_HCH) Serial.println(" Host Halted");
//if (stat & USBHS_USBSTS_RCL) Serial.println(" Reclamation");
//if (stat & USBHS_USBSTS_PS) Serial.println(" Periodic Sched En");
//if (stat & USBHS_USBSTS_AS) Serial.println(" Async Sched En");
if (stat & USBHS_USBSTS_NAKI) Serial.println(" NAK");
if (stat & USBHS_USBSTS_UAI) Serial.println(" USB Async");
if (stat & USBHS_USBSTS_UPI) Serial.println(" USB Periodic");
if (stat & USBHS_USBSTS_TI0) Serial.println(" Timer0");
if (stat & USBHS_USBSTS_TI1) Serial.println(" Timer1");
println();
println("ISR: ", stat, HEX);
//if (stat & USBHS_USBSTS_UI) println(" USB Interrupt");
if (stat & USBHS_USBSTS_UEI) println(" USB Error");
if (stat & USBHS_USBSTS_PCI) println(" Port Change");
//if (stat & USBHS_USBSTS_FRI) println(" Frame List Rollover");
if (stat & USBHS_USBSTS_SEI) println(" System Error");
if (stat & USBHS_USBSTS_AAI) println(" Async Advance (doorbell)");
if (stat & USBHS_USBSTS_URI) println(" Reset Recv");
//if (stat & USBHS_USBSTS_SRI) println(" SOF");
if (stat & USBHS_USBSTS_SLI) println(" Suspend");
if (stat & USBHS_USBSTS_HCH) println(" Host Halted");
//if (stat & USBHS_USBSTS_RCL) println(" Reclamation");
//if (stat & USBHS_USBSTS_PS) println(" Periodic Sched En");
//if (stat & USBHS_USBSTS_AS) println(" Async Sched En");
if (stat & USBHS_USBSTS_NAKI) println(" NAK");
if (stat & USBHS_USBSTS_UAI) println(" USB Async");
if (stat & USBHS_USBSTS_UPI) println(" USB Periodic");
if (stat & USBHS_USBSTS_TI0) println(" Timer0");
if (stat & USBHS_USBSTS_TI1) 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) {
//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)) {


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: ");
Serial.print(portstat, HEX);
Serial.println();
println("port change: ", portstat, HEX);
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)
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...
} }
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
} }
} }
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;
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();
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
// 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 ");
Serial.println(periodictable[0], HEX);
println("init periodictable with ", periodictable[0], HEX);
} }
return pipe; return pipe;
} }
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;
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 ");
//Serial.println((uint32_t)setup, HEX);
//println("setup address ", (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;


// 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;


static bool followup_Transfer(Transfer_t *transfer) static bool followup_Transfer(Transfer_t *transfer)
{ {
//Serial.print(" Followup ");
//Serial.println((uint32_t)transfer, HEX);
//println(" Followup ", (uint32_t)transfer, HEX);


if (!(transfer->qtd.token & 0x80)) { if (!(transfer->qtd.token & 0x80)) {
// TODO: check error status // TODO: check error status
} }
} }
// do callback function... // do callback function...
//Serial.println(" completed");
//println(" completed");
return true; return true;
} }
return false; return false;
// 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
min_offset = offset; min_offset = offset;
} }
} }
Serial.print(" min_bw = ");
Serial.print(min_bw);
Serial.print(", at offset = ");
Serial.println(min_offset);
print(" min_bw = ");
print(min_bw);
print(", at 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;
} }
} }
} }
Serial.print(" min_bw = ");
Serial.println(min_bw);
Serial.print(", at offset = ");
Serial.print(min_offset);
Serial.print(", shift= ");
Serial.println(min_shift);
print(" min_bw = ");
println(min_bw);
print(", at offset = ");
print(min_offset);
print(", 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;

+ 20
- 27
enumeration.cpp Целия файл

{ {
Device_t *dev; Device_t *dev;


Serial.print("new_Device: ");
print("new_Device: ");
switch (speed) { switch (speed) {
case 0: Serial.print("12"); break;
case 1: Serial.print("1.5"); break;
case 2: Serial.print("480"); break;
default: Serial.print("??");
case 0: print("12"); break;
case 1: print("1.5"); break;
case 2: print("480"); break;
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));
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;
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 = ");
Serial.println(enumlen);
println("Config data length = ", 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
} }
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 = ");
Serial.println(enumbuf[4]);
Serial.print("bConfigurationValue = ");
Serial.println(enumbuf[5]);
println("bNumInterfaces = ", enumbuf[4]);
println("bConfigurationValue = ", 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?
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 ");
Serial.print(desctype);
Serial.print(" = ");
if (desctype == 4) Serial.println("INTERFACE");
else if (desctype == 5) Serial.println("ENDPOINT");
else if (desctype == 6) Serial.println("DEV_QUALIFIER");
else if (desctype == 7) Serial.println("OTHER_SPEED");
else if (desctype == 11) Serial.println("IAD");
else if (desctype == 33) Serial.println("HID");
else Serial.println(" ???");
print("Descriptor ");
print(desctype);
print(" = ");
if (desctype == 4) println("INTERFACE");
else if (desctype == 5) println("ENDPOINT");
else if (desctype == 6) println("DEV_QUALIFIER");
else if (desctype == 7) println("OTHER_SPEED");
else if (desctype == 11) println("IAD");
else if (desctype == 33) println("HID");
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


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;
} }



+ 39
- 47
hub.cpp Целия файл

// 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=");
Serial.println((uint32_t)this, HEX);
println("USBHub claim_device this=", (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;
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]);
Serial.println(descriptors[10]);
Serial.println(descriptors[11], HEX);
Serial.println(maxsize);
println(descriptors[9]);
println(descriptors[10]);
println(descriptors[11], HEX);
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 = ");
Serial.println(dev->bDeviceClass);
Serial.print("bDeviceSubClass = ");
Serial.println(dev->bDeviceSubClass);
Serial.print("bDeviceProtocol = ");
Serial.println(dev->bDeviceProtocol);
println("bDeviceClass = ", dev->bDeviceClass);
println("bDeviceSubClass = ", dev->bDeviceSubClass);
println("bDeviceProtocol = ", dev->bDeviceProtocol);


changepipe = NULL; changepipe = NULL;
changebits = 0; changebits = 0;


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) {
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 ");
Serial.print(numports);
Serial.println(" ports");
print("Hub has ");
print(numports);
println(" ports");
state = 1; state = 1;
poweron(1); poweron(1);
} }
// 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");
Serial.print("device addr = ");
Serial.println(device->address);
println("power turned on to all ports");
println("device addr = ", device->address);
changepipe = new_Pipe(device, 3, endpoint, 1, 1, 512); changepipe = new_Pipe(device, 3, endpoint, 1, 1, 512);
Serial.print("pipe cap1 = ");
Serial.println(changepipe->qh.capabilities[0], HEX);
println("pipe cap1 = ", 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;
// 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
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=");
Serial.println(setup.wIndex);
println("Port Status Cleared, port=", setup.wIndex);
changebits &= ~(1 << setup.wIndex); changebits &= ~(1 << setup.wIndex);
break; break;
} }


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)");
Serial.print("status = ");
Serial.println(changebits, HEX);
println("HUB Callback (member)");
println("status = ", 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);
uint32_t priorstatus = portstatus[port - 1]; uint32_t priorstatus = portstatus[port - 1];
portstatus[port] = status; portstatus[port] = status;


Serial.print("New Port Status, port=");
Serial.print(port);
Serial.print(", status=");
Serial.println(status, HEX);
print("New Port Status, port=");
print(port);
print(", status=");
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 & 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 & 0x0004) println(" Suspended");
if (status & 0x0008) println(" Over-current");
if (status & 0x0010) println(" Reset");
if (status & 0x0100) println(" Has Power");
if (status & 0x0800) println(" Test Mode");
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");




} }

+ 7
- 11
keyboard.cpp Целия файл



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=");
Serial.println((uint32_t)this, HEX);
println("KeyboardController claim this=", (uint32_t)this, HEX);


// only claim at interface level // only claim at interface level
if (type != 1) return false; if (type != 1) return false;
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 = ");
Serial.println(endpoint, HEX);
println("ep = ", 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 = ");
Serial.println(size);
println("packet size = ", 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 = ");
Serial.println(interval);
println("polling interval = ", 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);


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);
} }


void KeyboardController::new_data(const Transfer_t *transfer) void KeyboardController::new_data(const Transfer_t *transfer)
{ {
Serial.println("KeyboardController Callback (member)");
Serial.print(" KB Data: ");
println("KeyboardController Callback (member)");
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);

+ 0
- 12
print.cpp Целия файл

Serial.println(); Serial.println();
} }


void USBHost::print(const char *s)
{
Serial.println(s);
}

void USBHost::print(const char *s, int num)
{
Serial.print(s);
Serial.println(num);
}



Loading…
Отказ
Запис