usbh_core refactor
Signed-off-by: Amir Hammad <amir.hammad@hotmail.com>
This commit is contained in:
parent
3493c1c087
commit
e0fbb799bd
2 changed files with 122 additions and 87 deletions
|
|
@ -61,6 +61,23 @@ enum USBH_CONTROL_TYPE {
|
|||
USBH_CONTROL_TYPE_DATA
|
||||
};
|
||||
|
||||
enum USBH_ENUM_STATE {
|
||||
USBH_ENUM_STATE_SET_ADDRESS,
|
||||
USBH_ENUM_STATE_FIRST = USBH_ENUM_STATE_SET_ADDRESS,
|
||||
USBH_ENUM_STATE_SET_ADDRESS_EMPTY_READ,
|
||||
USBH_ENUM_STATE_SET_ADDRESS_EMPTY_READ_COMPLETE,
|
||||
USBH_ENUM_STATE_DEVICE_DT_READ_SETUP,
|
||||
USBH_ENUM_STATE_DEVICE_DT_READ,
|
||||
USBH_ENUM_STATE_DEVICE_DT_READ_COMPLETE,
|
||||
USBH_ENUM_STATE_CONFIGURATION_DT_HEADER_READ_SETUP,
|
||||
USBH_ENUM_STATE_CONFIGURATION_DT_HEADER_READ,
|
||||
USBH_ENUM_STATE_CONFIGURATION_DT_HEADER_READ_COMPLETE,
|
||||
USBH_ENUM_STATE_CONFIGURATION_DT_READ_SETUP,
|
||||
USBH_ENUM_STATE_CONFIGURATION_DT_READ,
|
||||
USBH_ENUM_STATE_CONFIGURATION_DT_READ_COMPLETE,
|
||||
USBH_ENUM_STATE_FIND_DRIVER,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The _usbh_device struct
|
||||
*
|
||||
|
|
@ -77,7 +94,7 @@ struct _usbh_device {
|
|||
enum USBH_SPEED speed;
|
||||
|
||||
/// state used for enumeration purposes
|
||||
uint8_t state;
|
||||
enum USBH_ENUM_STATE state;
|
||||
|
||||
/// toggle bit
|
||||
uint8_t toggle0;
|
||||
|
|
|
|||
190
src/usbh_core.c
190
src/usbh_core.c
|
|
@ -172,10 +172,9 @@ void usbh_init(const void *low_level_drivers[], const usbh_dev_driver_t * const
|
|||
usbh_data.lld_drivers = (const usbh_low_level_driver_t **)low_level_drivers;
|
||||
usbh_data.dev_drivers = device_drivers;
|
||||
|
||||
// TODO: init structures
|
||||
uint32_t k = 0;
|
||||
while (usbh_data.lld_drivers[k]) {
|
||||
LOG_PRINTF("DRIVER %d\n", k);
|
||||
LOG_PRINTF("Initialization low-level driver with index=%d\n", k);
|
||||
|
||||
usbh_device_t * usbh_device =
|
||||
((usbh_generic_data_t *)(usbh_data.lld_drivers[k])->driver_data)->usbh_device;
|
||||
|
|
@ -186,7 +185,6 @@ void usbh_init(const void *low_level_drivers[], const usbh_dev_driver_t * const
|
|||
usbh_device[i].drv = 0;
|
||||
usbh_device[i].drvdata = 0;
|
||||
}
|
||||
LOG_PRINTF("DRIVER %d", k);
|
||||
usbh_data.lld_drivers[k]->init(usbh_data.lld_drivers[k]->driver_data);
|
||||
|
||||
k++;
|
||||
|
|
@ -289,17 +287,22 @@ usbh_device_t *usbh_get_free_device(const usbh_device_t *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void device_enumeration_terminate(usbh_device_t *dev)
|
||||
static void device_enumeration_finish(usbh_device_t *dev)
|
||||
{
|
||||
reset_enumeration();
|
||||
dev->state = 0;
|
||||
dev->address = -1;
|
||||
dev->state = USBH_ENUM_STATE_FIRST;
|
||||
}
|
||||
|
||||
/* Do not call this function directly,
|
||||
* only via callback passing into low-level function
|
||||
* If you must, call it carefully ;)
|
||||
*/
|
||||
static void device_enumeration_terminate(usbh_device_t *dev)
|
||||
{
|
||||
dev->address = -1;
|
||||
device_enumeration_finish(dev);
|
||||
}
|
||||
|
||||
#define CONTINUE_WITH(en) \
|
||||
dev->state = en;\
|
||||
device_enumerate(dev, cb_data);
|
||||
|
||||
static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_data)
|
||||
{
|
||||
const usbh_low_level_driver_t *lld = dev->lld;
|
||||
|
|
@ -308,12 +311,12 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_
|
|||
uint8_t state_start = dev->state; // Detection of hang
|
||||
// LOG_PRINTF("\nSTATE: %d\n", state);
|
||||
switch (dev->state) {
|
||||
case 1:
|
||||
case USBH_ENUM_STATE_SET_ADDRESS_EMPTY_READ:
|
||||
{
|
||||
switch (cb_data.status) {
|
||||
case USBH_PACKET_CALLBACK_STATUS_OK:
|
||||
dev->state++;
|
||||
LOG_PRINTF("::%d::", dev->address);
|
||||
dev->state = USBH_ENUM_STATE_SET_ADDRESS_EMPTY_READ_COMPLETE;
|
||||
LOG_PRINTF("Assigning address: %d\n", usbh_data.address_temporary);
|
||||
device_xfer_control_read(0, 0, device_enumerate, dev);
|
||||
break;
|
||||
|
||||
|
|
@ -327,25 +330,14 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_
|
|||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case USBH_ENUM_STATE_SET_ADDRESS_EMPTY_READ_COMPLETE:
|
||||
switch (cb_data.status) {
|
||||
case USBH_PACKET_CALLBACK_STATUS_OK:
|
||||
if (dev->address == 0) {
|
||||
dev->address = usbh_data.address_temporary;
|
||||
LOG_PRINTF("ADDR: %d\n", dev->address);
|
||||
LOG_PRINTF("Assigned address: %d\n", dev->address);
|
||||
}
|
||||
|
||||
struct usb_setup_data setup_data;
|
||||
|
||||
setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE;
|
||||
setup_data.bRequest = USB_REQ_GET_DESCRIPTOR;
|
||||
setup_data.wValue = USB_DT_DEVICE << 8;
|
||||
setup_data.wIndex = 0;
|
||||
setup_data.wLength = USB_DT_DEVICE_SIZE;
|
||||
|
||||
dev->state++;
|
||||
device_xfer_control_write_setup(&setup_data, sizeof(setup_data),
|
||||
device_enumerate, dev);
|
||||
CONTINUE_WITH(USBH_ENUM_STATE_DEVICE_DT_READ_SETUP);
|
||||
break;
|
||||
|
||||
case USBH_PACKET_CALLBACK_STATUS_EFATAL:
|
||||
|
|
@ -357,22 +349,34 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_
|
|||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case USBH_ENUM_STATE_DEVICE_DT_READ_SETUP:
|
||||
{
|
||||
struct usb_setup_data setup_data;
|
||||
|
||||
setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE;
|
||||
setup_data.bRequest = USB_REQ_GET_DESCRIPTOR;
|
||||
setup_data.wValue = USB_DT_DEVICE << 8;
|
||||
setup_data.wIndex = 0;
|
||||
setup_data.wLength = USB_DT_DEVICE_SIZE;
|
||||
|
||||
dev->state = USBH_ENUM_STATE_DEVICE_DT_READ;
|
||||
device_xfer_control_write_setup(&setup_data, sizeof(setup_data),
|
||||
device_enumerate, dev);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case USBH_ENUM_STATE_DEVICE_DT_READ:
|
||||
{
|
||||
switch (cb_data.status) {
|
||||
case USBH_PACKET_CALLBACK_STATUS_OK:
|
||||
dev->state++;
|
||||
dev->state = USBH_ENUM_STATE_DEVICE_DT_READ_COMPLETE;
|
||||
device_xfer_control_read(&usbh_buffer[0], USB_DT_DEVICE_SIZE,
|
||||
device_enumerate, dev);
|
||||
break;
|
||||
|
||||
case USBH_PACKET_CALLBACK_STATUS_EAGAIN:
|
||||
dev->state = 2;
|
||||
|
||||
// WARNING: Recursion
|
||||
// .. but should work
|
||||
cb_data.status = USBH_PACKET_CALLBACK_STATUS_OK;
|
||||
device_enumerate(dev, cb_data);
|
||||
CONTINUE_WITH(USBH_ENUM_STATE_DEVICE_DT_READ_SETUP);
|
||||
break;
|
||||
|
||||
case USBH_PACKET_CALLBACK_STATUS_EFATAL:
|
||||
|
|
@ -384,7 +388,7 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_
|
|||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case USBH_ENUM_STATE_DEVICE_DT_READ_COMPLETE:
|
||||
{
|
||||
switch (cb_data.status) {
|
||||
case USBH_PACKET_CALLBACK_STATUS_OK:
|
||||
|
|
@ -392,17 +396,9 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_
|
|||
struct usb_device_descriptor *ddt =
|
||||
(struct usb_device_descriptor *)&usbh_buffer[0];
|
||||
dev->packet_size_max0 = ddt->bMaxPacketSize0;
|
||||
struct usb_setup_data setup_data;
|
||||
|
||||
setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE;
|
||||
setup_data.bRequest = USB_REQ_GET_DESCRIPTOR;
|
||||
setup_data.wValue = USB_DT_CONFIGURATION << 8;
|
||||
setup_data.wIndex = 0;
|
||||
setup_data.wLength = ddt->bMaxPacketSize0;//USB_DT_CONFIGURATION_SIZE;
|
||||
|
||||
dev->state++;
|
||||
device_xfer_control_write_setup(&setup_data, sizeof(setup_data),
|
||||
device_enumerate, dev);
|
||||
LOG_PRINTF("Found device with vid=0x%04x pid=0x%04x\n", ddt->idVendor, ddt->idProduct);
|
||||
LOG_PRINTF("class=0x%02x subclass=0x%02x protocol=0x%02x\n", ddt->bDeviceClass, ddt->bDeviceSubClass, ddt->bDeviceProtocol);
|
||||
CONTINUE_WITH(USBH_ENUM_STATE_CONFIGURATION_DT_HEADER_READ_SETUP)
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -411,12 +407,10 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_
|
|||
struct usb_device_descriptor *ddt =
|
||||
(struct usb_device_descriptor *)&usbh_buffer[0];
|
||||
dev->packet_size_max0 = ddt->bMaxPacketSize0;
|
||||
dev->state = 2;
|
||||
|
||||
// WARNING: Recursion
|
||||
// .. but should work
|
||||
cb_data.status = USBH_PACKET_CALLBACK_STATUS_OK;
|
||||
device_enumerate(dev, cb_data);
|
||||
CONTINUE_WITH(USBH_ENUM_STATE_DEVICE_DT_READ_SETUP);
|
||||
} else {
|
||||
device_enumeration_terminate(dev);
|
||||
ERROR(cb_data.status);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -429,11 +423,27 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_
|
|||
}
|
||||
break;
|
||||
|
||||
case 5:
|
||||
case USBH_ENUM_STATE_CONFIGURATION_DT_HEADER_READ_SETUP:
|
||||
{
|
||||
struct usb_setup_data setup_data;
|
||||
|
||||
setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_DEVICE;
|
||||
setup_data.bRequest = USB_REQ_GET_DESCRIPTOR;
|
||||
setup_data.wValue = USB_DT_CONFIGURATION << 8;
|
||||
setup_data.wIndex = 0;
|
||||
setup_data.wLength = dev->packet_size_max0;
|
||||
|
||||
dev->state = USBH_ENUM_STATE_CONFIGURATION_DT_HEADER_READ;
|
||||
device_xfer_control_write_setup(&setup_data, sizeof(setup_data),
|
||||
device_enumerate, dev);
|
||||
}
|
||||
break;
|
||||
|
||||
case USBH_ENUM_STATE_CONFIGURATION_DT_HEADER_READ:
|
||||
{
|
||||
switch (cb_data.status) {
|
||||
case USBH_PACKET_CALLBACK_STATUS_OK:
|
||||
dev->state++;
|
||||
dev->state = USBH_ENUM_STATE_CONFIGURATION_DT_HEADER_READ_COMPLETE;
|
||||
device_xfer_control_read(&usbh_buffer[USB_DT_DEVICE_SIZE],
|
||||
dev->packet_size_max0, device_enumerate, dev);
|
||||
break;
|
||||
|
|
@ -448,38 +458,20 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_
|
|||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
case USBH_ENUM_STATE_CONFIGURATION_DT_HEADER_READ_COMPLETE:
|
||||
{
|
||||
switch (cb_data.status) {
|
||||
case USBH_PACKET_CALLBACK_STATUS_OK:
|
||||
{
|
||||
struct usb_config_descriptor *cdt =
|
||||
(struct usb_config_descriptor *)&usbh_buffer[USB_DT_DEVICE_SIZE];
|
||||
struct usb_setup_data setup_data;
|
||||
LOG_PRINTF("WRITE: LEN: %d", cdt->wTotalLength);
|
||||
setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE;
|
||||
setup_data.bRequest = USB_REQ_GET_DESCRIPTOR;
|
||||
setup_data.wValue = USB_DT_CONFIGURATION << 8;
|
||||
setup_data.wIndex = 0;
|
||||
setup_data.wLength = cdt->wTotalLength;
|
||||
|
||||
dev->state++;
|
||||
device_xfer_control_write_setup(&setup_data, sizeof(setup_data),
|
||||
device_enumerate, dev);
|
||||
}
|
||||
CONTINUE_WITH(USBH_ENUM_STATE_CONFIGURATION_DT_READ_SETUP);
|
||||
break;
|
||||
|
||||
case USBH_PACKET_CALLBACK_STATUS_ERRSIZ:
|
||||
if (cb_data.transferred_length >= USB_DT_CONFIGURATION_SIZE) {
|
||||
struct usb_config_descriptor *cdt =
|
||||
(struct usb_config_descriptor *)&usbh_buffer[USB_DT_DEVICE_SIZE];
|
||||
if (cb_data.transferred_length <= cdt->wTotalLength) {
|
||||
dev->state = 8;
|
||||
|
||||
// WARNING: Recursion
|
||||
// .. but should work
|
||||
cb_data.status = USBH_PACKET_CALLBACK_STATUS_OK;
|
||||
device_enumerate(dev, cb_data);
|
||||
if (cb_data.transferred_length == cdt->wTotalLength) {
|
||||
LOG_PRINTF("Configuration descriptor read complete. length: %d\n", cdt->wTotalLength);
|
||||
CONTINUE_WITH(USBH_ENUM_STATE_FIND_DRIVER);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -493,14 +485,32 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_
|
|||
}
|
||||
break;
|
||||
|
||||
case 7:
|
||||
case USBH_ENUM_STATE_CONFIGURATION_DT_READ_SETUP:
|
||||
{
|
||||
struct usb_config_descriptor *cdt =
|
||||
(struct usb_config_descriptor *)&usbh_buffer[USB_DT_DEVICE_SIZE];
|
||||
struct usb_setup_data setup_data;
|
||||
LOG_PRINTF("Getting complete configuration descriptor of length: %d bytes\n", cdt->wTotalLength);
|
||||
setup_data.bmRequestType = USB_REQ_TYPE_IN | USB_REQ_TYPE_DEVICE;
|
||||
setup_data.bRequest = USB_REQ_GET_DESCRIPTOR;
|
||||
setup_data.wValue = USB_DT_CONFIGURATION << 8;
|
||||
setup_data.wIndex = 0;
|
||||
setup_data.wLength = cdt->wTotalLength;
|
||||
|
||||
dev->state = USBH_ENUM_STATE_CONFIGURATION_DT_READ;
|
||||
device_xfer_control_write_setup(&setup_data, sizeof(setup_data),
|
||||
device_enumerate, dev);
|
||||
}
|
||||
break;
|
||||
|
||||
case USBH_ENUM_STATE_CONFIGURATION_DT_READ:
|
||||
{
|
||||
switch (cb_data.status) {
|
||||
case USBH_PACKET_CALLBACK_STATUS_OK:
|
||||
{
|
||||
struct usb_config_descriptor *cdt =
|
||||
(struct usb_config_descriptor *)&usbh_buffer[USB_DT_DEVICE_SIZE];
|
||||
dev->state++;
|
||||
dev->state = USBH_ENUM_STATE_CONFIGURATION_DT_READ_COMPLETE;
|
||||
device_xfer_control_read(&usbh_buffer[USB_DT_DEVICE_SIZE],
|
||||
cdt->wTotalLength, device_enumerate, dev);
|
||||
}
|
||||
|
|
@ -516,18 +526,16 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_
|
|||
}
|
||||
break;
|
||||
|
||||
case 8:
|
||||
case USBH_ENUM_STATE_CONFIGURATION_DT_READ_COMPLETE:
|
||||
{
|
||||
switch (cb_data.status) {
|
||||
case USBH_PACKET_CALLBACK_STATUS_OK:
|
||||
{
|
||||
struct usb_config_descriptor *cdt =
|
||||
(struct usb_config_descriptor *)&usbh_buffer[USB_DT_DEVICE_SIZE];
|
||||
LOG_PRINTF("TOTAL_LENGTH: %d\n", cdt->wTotalLength);
|
||||
device_register(usbh_buffer, cdt->wTotalLength + USB_DT_DEVICE_SIZE, dev);
|
||||
dev->state++;
|
||||
LOG_PRINTF("Configuration descriptor read complete. length: %d\n", cdt->wTotalLength);
|
||||
CONTINUE_WITH(USBH_ENUM_STATE_FIND_DRIVER);
|
||||
|
||||
reset_enumeration();
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -542,6 +550,16 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_
|
|||
}
|
||||
break;
|
||||
|
||||
case USBH_ENUM_STATE_FIND_DRIVER:
|
||||
{
|
||||
struct usb_config_descriptor *cdt =
|
||||
(struct usb_config_descriptor *)&usbh_buffer[USB_DT_DEVICE_SIZE];
|
||||
device_register(usbh_buffer, cdt->wTotalLength + USB_DT_DEVICE_SIZE, dev);
|
||||
|
||||
device_enumeration_finish(dev);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_PRINTF("Error: Unknown state "__FILE__"/%d\n", __LINE__);
|
||||
break;
|
||||
|
|
@ -555,7 +573,6 @@ static void device_enumerate(usbh_device_t *dev, usbh_packet_callback_data_t cb_
|
|||
void device_enumeration_start(usbh_device_t *dev)
|
||||
{
|
||||
set_enumeration();
|
||||
dev->state = 1;
|
||||
|
||||
// save address
|
||||
uint8_t address = dev->address;
|
||||
|
|
@ -571,6 +588,7 @@ void device_enumeration_start(usbh_device_t *dev)
|
|||
|
||||
LOG_PRINTF("\n\n\n ENUMERATION OF DEVICE@%d STARTED \n\n", address);
|
||||
|
||||
dev->state = USBH_ENUM_STATE_SET_ADDRESS;
|
||||
struct usb_setup_data setup_data;
|
||||
|
||||
setup_data.bmRequestType = USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue