static void disconnect_Device(Device_t *dev); | static void disconnect_Device(Device_t *dev); | ||||
static void enumeration(const Transfer_t *transfer); | static void enumeration(const Transfer_t *transfer); | ||||
static void driver_ready_for_device(USBDriver *driver); | static void driver_ready_for_device(USBDriver *driver); | ||||
static void contribute_Devices(Device_t *devices, uint32_t num); | |||||
static void contribute_Pipes(Pipe_t *pipes, uint32_t num); | |||||
static void contribute_Transfers(Transfer_t *transfers, uint32_t num); | |||||
static volatile bool enumeration_busy; | static volatile bool enumeration_busy; | ||||
private: | private: | ||||
static void isr(); | static void isr(); | ||||
class USBHub : public USBDriver { | class USBHub : public USBDriver { | ||||
public: | public: | ||||
USBHub(); | USBHub(); | ||||
// Hubs with more more than 7 ports are built from two tiers of hubs | |||||
// using 4 or 7 port hub chips. While the USB spec seems to allow | |||||
// hubs to have up to 255 ports, in practice all hub chips on the | |||||
// market are only 2, 3, 4 or 7 ports. | |||||
enum { MAXPORTS = 7 }; | enum { MAXPORTS = 7 }; | ||||
typedef uint8_t portbitmask_t; | typedef uint8_t portbitmask_t; | ||||
enum { | enum { | ||||
portbitmask_t send_pending_clearstatus_reset; | portbitmask_t send_pending_clearstatus_reset; | ||||
portbitmask_t send_pending_setreset; | portbitmask_t send_pending_setreset; | ||||
portbitmask_t debounce_in_use; | portbitmask_t debounce_in_use; | ||||
Device_t mydevices[MAXPORTS]; | |||||
Pipe_t mypipes[2] __attribute__ ((aligned(32))); | |||||
Transfer_t mytransfers[4] __attribute__ ((aligned(32))); | |||||
}; | }; | ||||
class KeyboardController : public USBDriver { | class KeyboardController : public USBDriver { | ||||
Pipe_t *datapipe; | Pipe_t *datapipe; | ||||
setup_t setup; | setup_t setup; | ||||
uint8_t report[8]; | uint8_t report[8]; | ||||
Pipe_t mypipes[2] __attribute__ ((aligned(32))); | |||||
Transfer_t mytransfers[4] __attribute__ ((aligned(32))); | |||||
}; | }; | ||||
class MIDIDevice : public USBDriver { | class MIDIDevice : public USBDriver { | ||||
uint8_t tx_ep; | uint8_t tx_ep; | ||||
uint16_t rx_size; | uint16_t rx_size; | ||||
uint16_t tx_size; | uint16_t tx_size; | ||||
Pipe_t mypipes[3] __attribute__ ((aligned(32))); | |||||
Transfer_t mytransfers[7] __attribute__ ((aligned(32))); | |||||
}; | }; | ||||
#endif | #endif |
USBHub::USBHub() : debouncetimer(this), resettimer(this) | USBHub::USBHub() : debouncetimer(this), resettimer(this) | ||||
{ | { | ||||
// TODO: free Device_t, Pipe_t & Transfer_t we will need | |||||
contribute_Devices(mydevices, sizeof(mydevices)/sizeof(Device_t)); | |||||
contribute_Pipes(mypipes, sizeof(mypipes)/sizeof(Pipe_t)); | |||||
contribute_Transfers(mytransfers, sizeof(mytransfers)/sizeof(Transfer_t)); | |||||
driver_ready_for_device(this); | driver_ready_for_device(this); | ||||
} | } | ||||
KeyboardController::KeyboardController() | KeyboardController::KeyboardController() | ||||
{ | { | ||||
// TODO: free Device_t, Pipe_t & Transfer_t we will need | |||||
contribute_Pipes(mypipes, sizeof(mypipes)/sizeof(Pipe_t)); | |||||
contribute_Transfers(mytransfers, sizeof(mytransfers)/sizeof(Transfer_t)); | |||||
driver_ready_for_device(this); | driver_ready_for_device(this); | ||||
} | } | ||||
// Memory allocation | // Memory allocation | ||||
static Device_t memory_Device[4]; | |||||
static Pipe_t memory_Pipe[8] __attribute__ ((aligned(32))); | |||||
static Transfer_t memory_Transfer[34] __attribute__ ((aligned(32))); | |||||
static Device_t memory_Device[1]; | |||||
static Pipe_t memory_Pipe[1] __attribute__ ((aligned(32))); | |||||
static Transfer_t memory_Transfer[4] __attribute__ ((aligned(32))); | |||||
static Device_t * free_Device_list = NULL; | static Device_t * free_Device_list = NULL; | ||||
static Pipe_t * free_Pipe_list = NULL; | static Pipe_t * free_Pipe_list = NULL; | ||||
void USBHost::init_Device_Pipe_Transfer_memory(void) | void USBHost::init_Device_Pipe_Transfer_memory(void) | ||||
{ | { | ||||
Device_t *end_device = memory_Device + sizeof(memory_Device)/sizeof(Device_t); | |||||
for (Device_t *device = memory_Device; device < end_device; device++) { | |||||
free_Device(device); | |||||
} | |||||
Pipe_t *end_pipe = memory_Pipe + sizeof(memory_Pipe)/sizeof(Pipe_t); | |||||
for (Pipe_t *pipe = memory_Pipe; pipe < end_pipe; pipe++) { | |||||
free_Pipe(pipe); | |||||
} | |||||
Transfer_t *end_transfer = memory_Transfer + sizeof(memory_Transfer)/sizeof(Transfer_t); | |||||
for (Transfer_t *transfer = memory_Transfer; transfer < end_transfer; transfer++) { | |||||
free_Transfer(transfer); | |||||
} | |||||
contribute_Devices(memory_Device, sizeof(memory_Device)/sizeof(Device_t)); | |||||
contribute_Pipes(memory_Pipe, sizeof(memory_Pipe)/sizeof(Pipe_t)); | |||||
contribute_Transfers(memory_Transfer, sizeof(memory_Transfer)/sizeof(Transfer_t)); | |||||
} | } | ||||
Device_t * USBHost::allocate_Device(void) | Device_t * USBHost::allocate_Device(void) | ||||
free_Transfer_list = transfer; | free_Transfer_list = transfer; | ||||
} | } | ||||
void USBHost::contribute_Devices(Device_t *devices, uint32_t num) | |||||
{ | |||||
Device_t *end = devices + num; | |||||
for (Device_t *device = devices ; device < end; device++) { | |||||
free_Device(device); | |||||
} | |||||
} | |||||
void USBHost::contribute_Pipes(Pipe_t *pipes, uint32_t num) | |||||
{ | |||||
Pipe_t *end = pipes + num; | |||||
for (Pipe_t *pipe = pipes; pipe < end; pipe++) { | |||||
free_Pipe(pipe); | |||||
} | |||||
} | |||||
void USBHost::contribute_Transfers(Transfer_t *transfers, uint32_t num) | |||||
{ | |||||
Transfer_t *end = transfers + num; | |||||
for (Transfer_t *transfer = transfers ; transfer < end; transfer++) { | |||||
free_Transfer(transfer); | |||||
} | |||||
} | |||||
MIDIDevice::MIDIDevice() | MIDIDevice::MIDIDevice() | ||||
{ | { | ||||
// TODO: free Device_t, Pipe_t & Transfer_t we will need | |||||
contribute_Pipes(mypipes, sizeof(mypipes)/sizeof(Pipe_t)); | |||||
contribute_Transfers(mytransfers, sizeof(mytransfers)/sizeof(Transfer_t)); | |||||
driver_ready_for_device(this); | driver_ready_for_device(this); | ||||
} | } | ||||