diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9afe32d..951163b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,6 +16,7 @@ jobs: fail-fast: false matrix: sdk_version: + - '2.1.0' - '2.0.0' - '1.5.1' runs-on: ubuntu-latest @@ -56,7 +57,5 @@ jobs: path: | examples/build/usb_device/usb_device.uf2 examples/build/usb_device/usb_device.hex - examples/build/capture_hid_report/capture_hid_report.uf2 - examples/build/capture_hid_report/capture_hid_report.hex examples/build/host_hid_to_device_cdc/host_hid_to_device_cdc.uf2 examples/build/host_hid_to_device_cdc/host_hid_to_device_cdc.hex diff --git a/README.md b/README.md index f207e71..d3db403 100644 --- a/README.md +++ b/README.md @@ -20,9 +20,8 @@ https://user-images.githubusercontent.com/43873124/146642806-bdf34af6-4342-4a95- ## Examples -- [capture_hid_report.c](examples/capture_hid_report/capture_hid_report.c) is a USB host sample program which print HID reports received from device. Open serial port and connect devices to pico. Default D+/D- is gp0/gp1. Call `pio_usb_add_port()` to use additional ports. +- [host_hid_to_device_cdc.c](examples/host_hid_to_device_cdc/host_hid_to_device_cdc.c) which print mouse/keyboard report from host port to device port's cdc. TinyUSB is used to manage both device (native usb) and host (pio usb) stack. - [usb_device.c](examples/usb_device/usb_device.c) is a HID USB FS device sample which moves mouse cursor every 0.5s. External 1.5kohm pull-up register is necessary to D+ pin (Default is gp0). -- [host_hid_to_device_cdc.c](examples/host_hid_to_device_cdc/host_hid_to_device_cdc.c) is similar to **capture_hid_report.c** which print mouse/keyboard report from host port to device port's cdc. TinyUSB is used to manage both device (native usb) and host (pio usb) stack. ```bash cd examples diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index aa9c23a..060ae10 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -11,7 +11,6 @@ set(PICO_PIO_USB_DIR "${CMAKE_CURRENT_LIST_DIR}/../") # a subdirectory, it's out of tree. add_subdirectory(${PICO_PIO_USB_DIR} pico_pio_usb) -add_subdirectory(capture_hid_report) add_subdirectory(usb_device) add_subdirectory(host_hid_to_device_cdc) add_subdirectory(test_ll) diff --git a/examples/capture_hid_report/CMakeLists.txt b/examples/capture_hid_report/CMakeLists.txt deleted file mode 100755 index d86f617..0000000 --- a/examples/capture_hid_report/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -set(target_name capture_hid_report) -add_executable(${target_name}) - -pico_enable_stdio_usb(${target_name} 1) - -target_sources(${target_name} PRIVATE - capture_hid_report.c - ) - -# print memory usage, enable all warnings -target_link_options(${target_name} PRIVATE -Xlinker --print-memory-usage) -target_compile_options(${target_name} PRIVATE -Wall -Wextra) - -target_link_libraries(${target_name} PRIVATE pico_stdlib pico_multicore pico_pio_usb) -pico_add_extra_outputs(${target_name}) diff --git a/examples/capture_hid_report/capture_hid_report.c b/examples/capture_hid_report/capture_hid_report.c deleted file mode 100644 index e0927b6..0000000 --- a/examples/capture_hid_report/capture_hid_report.c +++ /dev/null @@ -1,77 +0,0 @@ - -#include -#include - -#include "hardware/clocks.h" -#include "pico/stdlib.h" -#include "pico/multicore.h" -#include "pico/bootrom.h" - -#include "pio_usb.h" - -static usb_device_t *usb_device = NULL; - -void core1_main() { - sleep_ms(10); - - // To run USB SOF interrupt in core1, create alarm pool in core1. - static pio_usb_configuration_t config = PIO_USB_DEFAULT_CONFIG; - config.alarm_pool = (void*)alarm_pool_create(2, 1); - usb_device = pio_usb_host_init(&config); - - //// Call pio_usb_host_add_port to use multi port - // const uint8_t pin_dp2 = 8; - // pio_usb_host_add_port(pin_dp2); - - while (true) { - pio_usb_host_task(); - } -} - -int main() { - // default 125MHz is not appropreate. Sysclock should be multiple of 12MHz. - set_sys_clock_khz(120000, true); - - stdio_init_all(); - printf("hello!"); - - sleep_ms(10); - - multicore_reset_core1(); - // all USB task run in core1 - multicore_launch_core1(core1_main); - - while (true) { - if (usb_device != NULL) { - for (int dev_idx = 0; dev_idx < PIO_USB_DEVICE_CNT; dev_idx++) { - usb_device_t *device = &usb_device[dev_idx]; - if (!device->connected) { - continue; - } - - // Print received packet to EPs - for (int ep_idx = 0; ep_idx < PIO_USB_DEV_EP_CNT; ep_idx++) { - endpoint_t *ep = pio_usb_get_endpoint(device, ep_idx); - - if (ep == NULL) { - break; - } - - uint8_t temp[64]; - int len = pio_usb_get_in_data(ep, temp, sizeof(temp)); - - if (len > 0) { - printf("%04x:%04x EP 0x%02x:\t", device->vid, device->pid, - ep->ep_num); - for (int i = 0; i < len; i++) { - printf("%02x ", temp[i]); - } - printf("\n"); - } - } - } - } - stdio_flush(); - sleep_us(10); - } -} \ No newline at end of file diff --git a/library.properties b/library.properties index c52d4aa..3b1eeb0 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Pico PIO USB -version=0.6.0 +version=0.6.1 author=sekigon-gonnoc maintainer=sekigon-gonnoc sentence=Pico PIO USB library for Arduino diff --git a/src/pio_usb.c b/src/pio_usb.c index 27407da..f1bdcbe 100644 --- a/src/pio_usb.c +++ b/src/pio_usb.c @@ -178,6 +178,8 @@ int __no_inline_not_in_flash_func(pio_usb_bus_receive_packet_and_handshake)( bool crc_match = false; int16_t t = 240; uint16_t idx = 0; + uint16_t nak_timeout = 10000; + const uint16_t rx_buf_len = sizeof(pp->usb_rx_buffer) / sizeof(pp->usb_rx_buffer[0]); while (t--) { if (pio_sm_get_rx_fifo_level(pp->pio_usb_rx, pp->sm_rx)) { @@ -192,7 +194,7 @@ int __no_inline_not_in_flash_func(pio_usb_bus_receive_packet_and_handshake)( // timing critical start if (t > 0) { if (handshake == USB_PID_ACK) { - while ((pp->pio_usb_rx->irq & IRQ_RX_COMP_MASK) == 0) { + while ((pp->pio_usb_rx->irq & IRQ_RX_COMP_MASK) == 0 && idx < rx_buf_len - 1) { if (pio_sm_get_rx_fifo_level(pp->pio_usb_rx, pp->sm_rx)) { uint8_t data = pio_sm_get(pp->pio_usb_rx, pp->sm_rx) >> 24; crc_prev2 = crc_prev; @@ -212,7 +214,7 @@ int __no_inline_not_in_flash_func(pio_usb_bus_receive_packet_and_handshake)( } } else { // just discard received data since we NAK/STALL anyway - while ((pp->pio_usb_rx->irq & IRQ_RX_COMP_MASK) == 0) { + while ((pp->pio_usb_rx->irq & IRQ_RX_COMP_MASK) == 0 && nak_timeout--) { continue; } pio_sm_clear_fifos(pp->pio_usb_rx, pp->sm_rx); @@ -289,17 +291,30 @@ static void apply_config(pio_port_t *pp, const pio_usb_configuration_t *c, pp->sm_eop = c->sm_eop; port->pin_dp = c->pin_dp; + uint highest_pin; if (c->pinout == PIO_USB_PINOUT_DPDM) { port->pin_dm = c->pin_dp + 1; + highest_pin = port->pin_dm; pp->fs_tx_program = &usb_tx_dpdm_program; pp->fs_tx_pre_program = &usb_tx_pre_dpdm_program; pp->ls_tx_program = &usb_tx_dmdp_program; } else { port->pin_dm = c->pin_dp - 1; + highest_pin = port->pin_dp; pp->fs_tx_program = &usb_tx_dmdp_program; pp->fs_tx_pre_program = &usb_tx_pre_dmdp_program; pp->ls_tx_program = &usb_tx_dpdm_program; } + +#if defined(PICO_PIO_USE_GPIO_BASE) && PICO_PIO_USE_GPIO_BASE+0 + if (highest_pin > 32) { + pio_set_gpio_base(pp->pio_usb_tx, 16); + pio_set_gpio_base(pp->pio_usb_rx, 16); + } +#else + (void)highest_pin; +#endif + port->pinout = c->pinout; pp->debug_pin_rx = c->debug_pin_rx; @@ -458,12 +473,13 @@ uint8_t __no_inline_not_in_flash_func(pio_usb_ll_encode_tx_data)( encoded_data[byte_idx] |= PIO_USB_TX_ENCODED_DATA_COMP; bit_idx++; + // terminate buffers with K do { byte_idx = bit_idx >> 2; encoded_data[byte_idx] <<= 2; encoded_data[byte_idx] |= PIO_USB_TX_ENCODED_DATA_K; bit_idx++; - } while (bit_idx & 0x07); + } while (bit_idx & 0x03); byte_idx = bit_idx >> 2; return byte_idx; @@ -570,8 +586,8 @@ int pio_usb_host_add_port(uint8_t pin_dp, PIO_USB_PINOUT pinout) { pio_gpio_init(pio_port[0].pio_usb_tx, root->pin_dm); gpio_set_inover(pin_dp, GPIO_OVERRIDE_INVERT); gpio_set_inover(root->pin_dm, GPIO_OVERRIDE_INVERT); - pio_sm_set_pindirs_with_mask(pio_port[0].pio_usb_tx, pio_port[0].sm_tx, 0, - (1 << pin_dp) | (1 << root->pin_dm)); + pio_sm_set_pindirs_with_mask64(pio_port[0].pio_usb_tx, pio_port[0].sm_tx, 0, + (1ull << pin_dp) | (1ull << root->pin_dm)); port_pin_drive_setting(root); root->initialized = true; diff --git a/src/pio_usb_host.c b/src/pio_usb_host.c index 831bce9..0059ad0 100644 --- a/src/pio_usb_host.c +++ b/src/pio_usb_host.c @@ -612,646 +612,6 @@ static int __no_inline_not_in_flash_func(usb_setup_transaction)( return res; } -//--------------------------------------------------------------------+ -// USB Host Stack -//--------------------------------------------------------------------+ -static void on_device_connect(pio_port_t *pp, root_port_t *root, - int device_idx) { - bool fullspeed_flag = false; - - if (pio_usb_bus_get_line_state(root) == PORT_PIN_FS_IDLE) { - fullspeed_flag = true; - } else if (pio_usb_bus_get_line_state(root) == PORT_PIN_LS_IDLE) { - fullspeed_flag = false; - } - - pio_sm_set_pins_with_mask(pp->pio_usb_tx, pp->sm_tx, 0, - (1 << root->pin_dp) | (1 << root->pin_dm)); - pio_sm_set_pindirs_with_mask(pp->pio_usb_tx, pp->sm_tx, - (1 << root->pin_dp) | (1 << root->pin_dm), - (1 << root->pin_dp) | (1 << root->pin_dm)); - - busy_wait_ms(100); - - pio_sm_set_pindirs_with_mask(pp->pio_usb_tx, pp->sm_tx, 0, - (1 << root->pin_dp) | (1 << root->pin_dm)); - - busy_wait_us(100); - - root->suspended = false; - - if (fullspeed_flag && pio_usb_bus_get_line_state(root) == PORT_PIN_FS_IDLE) { - root->root_device = &pio_usb_device[device_idx]; - if (!root->root_device->connected) { - configure_fullspeed_host(pp, root); - root->root_device->is_fullspeed = true; - root->root_device->is_root = true; - root->root_device->connected = true; - root->root_device->root = root; - root->root_device->event = EVENT_CONNECT; - } - } else if (!fullspeed_flag && pio_usb_bus_get_line_state(root) == PORT_PIN_LS_IDLE) { - root->root_device = &pio_usb_device[device_idx]; - if (!root->root_device->connected) { - configure_lowspeed_host(pp, root); - root->root_device->is_fullspeed = false; - root->root_device->is_root = true; - root->root_device->connected = true; - root->root_device->root = root; - root->root_device->event = EVENT_CONNECT; - } - } - - endpoint_descriptor_t ep0_desc = { - sizeof(endpoint_descriptor_t), DESC_TYPE_ENDPOINT, 0x00, 0x00, { 0x08, 0x00 }, 0x00 - }; - pio_usb_host_endpoint_open(root - pio_usb_root_port, 0x00, - (uint8_t const *)&ep0_desc, false); -} - -static int __no_inline_not_in_flash_func(control_out_protocol)( - usb_device_t *device, uint8_t *setup_data, uint16_t setup_length, - uint8_t *out_data, uint16_t out_length) { - int res = 0; - - control_pipe_t *pipe = &device->control_pipe; - - if (pipe->operation == CONTROL_NONE) { - pipe->setup_packet.tx_address = setup_data; - pipe->setup_packet.tx_length = setup_length; - pipe->out_data_packet.tx_address = out_data; - pipe->out_data_packet.tx_length = out_length; - pipe->operation = CONTROL_OUT; - - pio_usb_host_send_setup(device->root - pio_usb_root_port, device->address, setup_data); - } else { - return -1; - } - - const uint64_t timeout = 5000 * 1000; // 5s - uint64_t start_time = time_us_64(); - while (pipe->operation == CONTROL_OUT && - time_us_64() - start_time < timeout) { - if (!device->connected) { - pipe->operation = CONTROL_NONE; - return -1; - } - } - - if (time_us_64() - start_time >= timeout) { - printf("control out[timeout]\n"); - res = -2; - } else if (pipe->operation == CONTROL_ERROR) { - printf("control out[error]\n"); - res = -1; - } else if (pipe->operation == CONTROL_COMPLETE) { - printf("control out[complete]\n"); - res = 0; - } - pipe->operation = CONTROL_NONE; - - return res; -} - -static int __no_inline_not_in_flash_func(control_in_protocol)( - usb_device_t *device, uint8_t *tx_data, uint16_t tx_length, - uint8_t *rx_buffer, uint16_t request_length) { - int res = 0; - - control_pipe_t *pipe = &device->control_pipe; - - if (pipe->operation == CONTROL_NONE) { - pipe->setup_packet.tx_address = tx_data; - pipe->setup_packet.tx_length = tx_length; - pipe->rx_buffer = rx_buffer; - pipe->request_length = request_length; - pipe->operation = CONTROL_IN; - - pio_usb_host_send_setup(device->root - pio_usb_root_port, device->address, tx_data); - } else { - return -1; - } - - const uint64_t timeout = 5000 * 1000; // 5s - uint64_t start_time = time_us_64(); - while (pipe->operation == CONTROL_IN && - time_us_64() - start_time < timeout) { - if (!device->connected) { - pipe->operation = CONTROL_NONE; - return -1; - } - } - - if (time_us_64() - start_time >= timeout) { - printf("control in[timeout]\n"); - res = -2; - } else if (pipe->operation == CONTROL_ERROR) { - printf("control in[error]\n"); - res = -1; - } else if (pipe->operation == CONTROL_COMPLETE) { - printf("control in[complete]\n"); - res = 0; - } - pipe->operation = CONTROL_NONE; - - return res; -} - -static int set_hub_feature(usb_device_t *device, uint8_t port, uint8_t value) { - usb_setup_packet_t req = SET_HUB_FEATURE_REQUEST; - req.index_lsb = port + 1; - req.value_lsb = value; - return control_out_protocol(device, (uint8_t *)&req, sizeof(req), NULL, 0); -} - -static int clear_hub_feature(usb_device_t *device, uint8_t port, - uint8_t value) { - usb_setup_packet_t req = CLEAR_HUB_FEATURE_REQUEST; - req.index_lsb = port + 1; - req.value_lsb = value; - return control_out_protocol(device, (uint8_t *)&req, sizeof(req), NULL, 0); -} - -static int get_hub_port_status(usb_device_t *device, uint8_t port, - hub_port_status_t *status) { - usb_setup_packet_t req = GET_HUB_PORT_STATUS_REQUEST; - req.index_lsb = port + 1; - return control_in_protocol(device, (uint8_t *)&req, sizeof(req), (uint8_t*)status, - sizeof(*status)); -} - -static int initialize_hub(usb_device_t *device) { - uint8_t rx_buffer[16]; - int res = 0; - printf("USB Hub detected\n"); - usb_setup_packet_t get_hub_desc_request = GET_HUB_DESCRPTOR_REQUEST; - control_in_protocol(device, (uint8_t *)&get_hub_desc_request, - sizeof(get_hub_desc_request), rx_buffer, 8); - const hub_descriptor_t *desc = (hub_descriptor_t *)rx_buffer; - uint8_t port_num = desc->port_num; - - printf("\tTurn on port powers\n"); - for (int idx = 0; idx < port_num; idx++) { - res = set_hub_feature(device, idx, HUB_SET_PORT_POWER); - if (res != 0) { - printf("\tFailed to turn on ports\n"); - break; - } - } - - busy_wait_ms(500); - - return res; -} - -static int get_string_descriptor(usb_device_t *device, uint8_t idx, - uint8_t *rx_buffer, uint8_t *str_buffer) { - int res = -1; - usb_setup_packet_t req = GET_DEVICE_DESCRIPTOR_REQ_DEFAULT; - req.value_msb = DESC_TYPE_STRING; - req.value_lsb = idx; - req.length_lsb = 1; - req.length_msb = 0; - res = control_in_protocol(device, (uint8_t *)&req, sizeof(req), rx_buffer, 1); - if (res != 0) { - return res; - } - - uint8_t len = rx_buffer[0]; - req.length_lsb = len; - req.length_msb = 0; - res = - control_in_protocol(device, (uint8_t *)&req, sizeof(req), rx_buffer, len); - if (res != 0) { - return res; - } - - uint16_t *wchar_buffer = (uint16_t *)(uintptr_t) rx_buffer; - for (int i = 0; i < (len - 2) / 2; i++) { - str_buffer[i] = wchar_buffer[i + 1]; - } - str_buffer[(len - 2) / 2] = '\0'; - - return res; -} - -static int enumerate_device(usb_device_t *device, uint8_t address) { - int res = 0; - uint8_t rx_buffer[512]; - - usb_setup_packet_t get_device_descriptor_request = - GET_DEVICE_DESCRIPTOR_REQ_DEFAULT; - res = control_in_protocol(device, (uint8_t *)&get_device_descriptor_request, - sizeof(get_device_descriptor_request), rx_buffer, 18); - if (res != 0) { - pio_usb_host_close_device(device->root - pio_usb_root_port, 0); - return res; - } - - const device_descriptor_t *desc = - (device_descriptor_t *)device->control_pipe.rx_buffer; - device->vid = desc->vid[0] | (desc->vid[1] << 8); - device->pid = desc->pid[0] | (desc->pid[1] << 8); - device->device_class = desc->device_class; - uint8_t idx_manufacture = desc->manufacture; - uint8_t idx_product = desc->product; - uint8_t idx_serial = desc->serial; - - printf("Enumerating %04x:%04x, class:%d, address:%d\n", device->vid, - device->pid, device->device_class, address); - - usb_setup_packet_t set_address_request = SET_ADDRESS_REQ_DEFAULT; - set_address_request.value_lsb = address; - set_address_request.value_msb = 0; - res = control_out_protocol(device, (uint8_t *)&set_address_request, - sizeof(set_address_request), NULL, 0); - pio_usb_host_close_device(device->root - pio_usb_root_port, 0); - if (res != 0) { - return res; - } - device->address = address; - - endpoint_descriptor_t ep0_desc = { - sizeof(endpoint_descriptor_t), DESC_TYPE_ENDPOINT, 0x00, 0x00, { desc->max_packet_size, 0x00 }, 0x00 - }; - pio_usb_host_endpoint_open(device->root - pio_usb_root_port, address, - (uint8_t const *)&ep0_desc, - !device->is_root && !device->is_fullspeed); - - uint8_t str[64]; - if (idx_manufacture != 0) { - res = get_string_descriptor(device, idx_manufacture, rx_buffer, str); - if (res == 0) { - printf("Manufacture:%s\n", str); - } else { - printf("Failed to get string descriptor (Manufacture)\n"); - } - stdio_flush(); - } - - if (idx_product != 0) { - res = get_string_descriptor(device, idx_product, rx_buffer, str); - if (res == 0) { - printf("Product:%s\n", str); - } else { - printf("Failed to get string descriptor (Product)\n"); - } - stdio_flush(); - } - - if (idx_serial != 0) { - res = get_string_descriptor(device, idx_serial, rx_buffer, str); - if (res == 0) { - printf("Serial:%s\n", str); - } else { - printf("Failed to get string descriptor (Serial)\n"); - } - stdio_flush(); - } - - usb_setup_packet_t get_configuration_descriptor_request = - GET_CONFIGURATION_DESCRIPTOR_REQ_DEFAULT; - get_configuration_descriptor_request.length_lsb = 9; - get_configuration_descriptor_request.length_msb = 0; - res = control_in_protocol( - device, (uint8_t *)&get_configuration_descriptor_request, - sizeof(get_configuration_descriptor_request), rx_buffer, 9); - if (res != 0) { - return res; - } - - get_configuration_descriptor_request.length_lsb = - ((configuration_descriptor_t *)(device->control_pipe.rx_buffer)) - ->total_length_lsb; - get_configuration_descriptor_request.length_msb = - ((configuration_descriptor_t *)(device->control_pipe.rx_buffer)) - ->total_length_msb; - uint16_t request_length = - get_configuration_descriptor_request.length_lsb | - (get_configuration_descriptor_request.length_msb << 8); - res = control_in_protocol( - device, (uint8_t *)&get_configuration_descriptor_request, - sizeof(get_configuration_descriptor_request), rx_buffer, request_length); - - if (res != 0) { - return res; - } - uint8_t configuration_descrptor_data[512]; - int16_t configuration_descrptor_length = - request_length > 512 ? 512 : request_length; - memcpy(configuration_descrptor_data, - (const void *)device->control_pipe.rx_buffer, - configuration_descrptor_length); - - usb_setup_packet_t set_usb_configuration_request = - SET_CONFIGURATION_REQ_DEFAULT; - set_usb_configuration_request.value_lsb = - ((configuration_descriptor_t *)(device->control_pipe.rx_buffer)) - ->configuration_value; - res = control_out_protocol(device, (uint8_t *)&set_usb_configuration_request, - sizeof(set_usb_configuration_request), NULL, 0); - - if (res != 0) { - return res; - } - volatile uint8_t ep_id_idx = 0; - volatile uint8_t interface = 0; - volatile uint8_t class = 0; - uint8_t *descriptor = configuration_descrptor_data; - while (configuration_descrptor_length > 0) { - switch (descriptor[1]) { - case DESC_TYPE_INTERFACE: { - const interface_descriptor_t *d = - (const interface_descriptor_t *)descriptor; - printf( - "inum:%d, altsetting:%d, numep:%d, iclass:%d, isubclass:%d, " - "iprotcol:%d, iface:%d\n", - d->inum, d->altsetting, d->numep, d->iclass, d->isubclass, - d->iprotocol, d->iface); - interface = d->inum; - class = d->iclass; - } break; - case DESC_TYPE_ENDPOINT: { - const endpoint_descriptor_t *d = - (const endpoint_descriptor_t *)descriptor; - printf("\t\t\tepaddr:0x%02x, attr:%d, size:%d, interval:%d\n", - d->epaddr, d->attr, d->max_size[0] | (d->max_size[1] << 8), - d->interval); - - if ((class == CLASS_HID || class == CLASS_HUB) && - d->attr == EP_ATTR_INTERRUPT) { - volatile endpoint_t *ep = NULL; - for (int ep_pool_idx = 0; ep_pool_idx < PIO_USB_EP_POOL_CNT; - ep_pool_idx++) { - if (pio_usb_ep_pool[ep_pool_idx].size == 0) { - ep = &pio_usb_ep_pool[ep_pool_idx]; - device->endpoint_id[ep_id_idx] = ep_pool_idx + 1; - ep_id_idx++; - break; - } - } - - if (ep != NULL) { - ep->interval = d->interval; - ep->interval_counter = 0; - ep->size = d->max_size[0] | (d->max_size[1] << 8); - ep->attr = d->attr | EP_ATTR_ENUMERATING; - ep->ep_num = d->epaddr; - - ep->root_idx = device->root - pio_usb_root_port; - ep->dev_addr = device->address; - ep->need_pre = !device->is_root && !device->is_fullspeed; - ep->is_tx = (d->epaddr & 0x80) ? false : true; - } else { - printf("No empty EP\n"); - } - } - } break; - case DESC_TYPE_HID: { - const hid_descriptor_t *d = (const hid_descriptor_t *)descriptor; - printf( - "\tbcdHID:%x.%x, country:%d, desc num:%d, desc_type:%d, " - "desc_size:%d\n", - d->bcd_hid[1], d->bcd_hid[0], d->contry_code, d->num_desc, - d->desc_type, d->desc_len[0] | (d->desc_len[1] << 8)); - - usb_setup_packet_t set_hid_idle_request = SET_HID_IDLE_REQ_DEFAULT; - set_hid_idle_request.value_lsb = interface; - set_hid_idle_request.value_msb = 0; - control_out_protocol(device, (uint8_t *)&set_hid_idle_request, - sizeof(set_hid_idle_request), NULL, 0); - - usb_setup_packet_t get_hid_report_descrpitor_request = - GET_HID_REPORT_DESCRIPTOR_DEFAULT; - get_hid_report_descrpitor_request.index_lsb = interface; - get_hid_report_descrpitor_request.index_msb = 0; - get_hid_report_descrpitor_request.length_lsb = d->desc_len[0]; - get_hid_report_descrpitor_request.length_msb = d->desc_len[1]; - uint16_t desc_len = d->desc_len[0] | (d->desc_len[1] << 8); - control_in_protocol( - device, (uint8_t *)&get_hid_report_descrpitor_request, - sizeof(get_hid_report_descrpitor_request), rx_buffer, desc_len); - printf("\t\tReport descriptor:"); - for (int i = 0; i < desc_len; i++) { - printf("%02x ", device->control_pipe.rx_buffer[i]); - } - printf("\n"); - stdio_flush(); - - } break; - default: - break; - } - - configuration_descrptor_length -= descriptor[0]; - descriptor += descriptor[0]; - } - - for (int epidx = 0; epidx < PIO_USB_DEV_EP_CNT; epidx++) { - endpoint_t *ep = pio_usb_get_endpoint(device, epidx); - if (ep == NULL) { - break; - } - ep->attr &= ~EP_ATTR_ENUMERATING; - - // prepare transfer - if (ep->ep_num & EP_IN) { - pio_usb_ll_transfer_start(ep, ep->buffer, ep->size); - } - } - - return res; -} - -static void device_disconnect(usb_device_t *device) { - printf("Disconnect device %d\n", device->address); - for (int port = 0; port < PIO_USB_HUB_PORT_CNT; port++) { - if (device->child_devices[port] != 0) { - device_disconnect(&pio_usb_device[device->child_devices[port]]); - } - } - - for (int ep_idx = 0; ep_idx < PIO_USB_DEV_EP_CNT; ep_idx++) { - endpoint_t *ep = pio_usb_get_endpoint(device, ep_idx); - if (ep == NULL) { - break; - } - memset(ep, 0, sizeof(*ep)); - } - - if (device->address == 0 && device->root != NULL) { - device->root->addr0_exists = false; - } - - memset(device, 0, sizeof(*device)); -} - -static int device_pool_vacant(void) { - for (int idx = 0; idx < PIO_USB_DEVICE_CNT; idx++) { - if (!pio_usb_device[idx].connected) { - return idx; - } - } - - return -1; -} - -static int assign_new_device_to_port(usb_device_t *hub_device, uint8_t port, bool is_ls) { - int idx = device_pool_vacant(); - if (idx >= 0) { - hub_device->child_devices[port] = idx; - pio_usb_device[idx].parent_device = hub_device; - pio_usb_device[idx].parent_port = port; - pio_usb_device[idx].root = hub_device->root; - pio_usb_device[idx].connected = true; - pio_usb_device[idx].is_fullspeed = !is_ls; - pio_usb_device[idx].event = EVENT_CONNECT; - printf("Assign device %d to %d-%d\n", idx, hub_device->address, port); - - endpoint_descriptor_t ep0_desc = { - sizeof(endpoint_descriptor_t), DESC_TYPE_ENDPOINT, 0x00, 0x00, { 0x08, 0x00 }, 0x00 - }; - pio_usb_host_endpoint_open(hub_device->root - pio_usb_root_port, 0x00, - (uint8_t const *)&ep0_desc, is_ls); - - return 0; - } - - printf("Failed to assign device\n"); - - return -1; -} - -static void __no_inline_not_in_flash_func(process_hub_event)( - usb_device_t *device) { - volatile endpoint_t *ep = pio_usb_get_endpoint(device, 0); - uint8_t bitmap = ep->buffer[0]; - for (int bit = 1; bit < 8; bit++) { - if (!(bitmap & (1 << bit))) { - continue; - } - uint8_t port = bit - 1; - hub_port_status_t status; - int res = get_hub_port_status(device, port, &status); - if (res != 0) { - printf("Failed to get port%d-%d status\n", device->address, port); - continue; - } - printf("port%d-%d status:%d %d\n", device->address, port, - status.port_change, status.port_status); - - if (status.port_change & HUB_CHANGE_PORT_CONNECTION) { - if (status.port_status & HUB_STAT_PORT_CONNECTION) { - printf("new device on port %d, reset port\n", port); - if (device->child_devices[port] != 0) { - printf("device is already assigned. disconnect previous\n"); - device_disconnect(&pio_usb_device[device->child_devices[port]]); - } - - if (device->root->addr0_exists) { - printf("Address 0 already exists\n"); - continue; - } - - if (device_pool_vacant() >= 0) { - set_hub_feature(device, port, HUB_SET_PORT_RESET); - device->root->addr0_exists = true; - } else { - printf("No vacant in device pool\n"); - } - } else { - printf("device removed from port %d\n", port); - if (device->child_devices[port] != 0) { - device_disconnect(&pio_usb_device[device->child_devices[port]]); - } - } - clear_hub_feature(device, port, HUB_CLR_PORT_CONNECTION); - } else if (status.port_change & HUB_CHANGE_PORT_RESET) { - printf("reset port %d complete\n", port); - res = clear_hub_feature(device, port, HUB_CLR_PORT_RESET); - if (res == 0) { - assign_new_device_to_port(device, port, - status.port_status & HUB_STAT_PORT_LOWSPEED); - } - } else if (status.port_change & HUB_CHANGE_PORT_ENABLE) { - clear_hub_feature(device, port, HUB_CLR_PORT_ENABLE); - } - } - - device->event = EVENT_NONE; -} - -void __no_inline_not_in_flash_func(pio_usb_host_task)(void) { - for (int root_idx = 0; root_idx < PIO_USB_ROOT_PORT_CNT; root_idx++) { - if (pio_usb_root_port[root_idx].event == EVENT_CONNECT) { - printf("Root %d connected\n", root_idx); - int dev_idx = device_pool_vacant(); - if (dev_idx >= 0) { - on_device_connect(&pio_port[0], &pio_usb_root_port[root_idx], dev_idx); - pio_usb_root_port[root_idx].addr0_exists = true; - } - pio_usb_root_port[root_idx].event = EVENT_NONE; - } else if (pio_usb_root_port[root_idx].event == EVENT_DISCONNECT) { - printf("Root %d disconnected\n", root_idx); - pio_usb_host_close_device( - root_idx, pio_usb_root_port[root_idx].root_device->address); - pio_usb_root_port[root_idx].root_device->connected = false; - pio_usb_root_port[root_idx].root_device->event = EVENT_DISCONNECT; - pio_usb_root_port[root_idx].root_device = NULL; - pio_usb_root_port[root_idx].event = EVENT_NONE; - } - } - - for (int idx = 0; idx < PIO_USB_DEVICE_CNT; idx++) { - usb_device_t *device = &pio_usb_device[idx]; - - if (device->event == EVENT_CONNECT) { - device->event = EVENT_NONE; - printf("Device %d Connected\n", idx); - int res = enumerate_device(device, idx + 1); - if (res == 0) { - device->enumerated = true; - device->root->addr0_exists = false; - if (device->device_class == CLASS_HUB) { - res = initialize_hub(device); - } - } - - if (res != 0) { - printf("Enumeration failed(%d)\n", res); - // retry - if (device->is_root) { - device->root->event = EVENT_DISCONNECT; - } else { - set_hub_feature(device->parent_device, device->parent_port, - HUB_SET_PORT_RESET); - device_disconnect(device); - } - } - } else if (device->event == EVENT_DISCONNECT) { - device->event = EVENT_NONE; - printf("Disconnect\n"); - device_disconnect(device); - } else if (device->event == EVENT_HUB_PORT_CHANGE) { - process_hub_event(device); - } - } - - if (cancel_timer_flag) { - int_stat = save_and_disable_interrupts(); - stop_timer(); - if (pio_usb_root_port->root_device != NULL) { - device_disconnect(pio_usb_root_port->root_device); - } - cancel_timer_flag = false; - } - - if (start_timer_flag) { - start_timer(_alarm_pool); - restore_interrupts(int_stat); - start_timer_flag = false; - } -} static void __no_inline_not_in_flash_func(handle_endpoint_irq)( root_port_t *root, uint32_t flag, volatile uint32_t *ep_reg) { diff --git a/src/sdk_compat.h b/src/sdk_compat.h new file mode 100644 index 0000000..935dce2 --- /dev/null +++ b/src/sdk_compat.h @@ -0,0 +1,20 @@ +#pragma once + +#if PICO_SDK_VERSION_MAJOR < 2 +static __always_inline void pio_sm_set_jmp_pin(PIO pio, uint sm, uint jmp_pin) { + pio->sm[sm].execctrl = + (pio->sm[sm].execctrl & ~PIO_SM0_EXECCTRL_JMP_PIN_BITS) | + (jmp_pin << PIO_SM0_EXECCTRL_JMP_PIN_LSB); +} +#endif + +#if PICO_SDK_VERSION_MAJOR < 2 || (PICO_SDK_VERSION_MAJOR == 2 && PICO_SDK_VERSION_MINOR < 1) +static void pio_sm_set_pins_with_mask64(PIO pio, uint sm, uint64_t pin_values, uint64_t pin_mask) { + pio_sm_set_pins_with_mask(pio, sm, (uint32_t) pin_values, (uint32_t) pin_mask); +} + +static void pio_sm_set_pindirs_with_mask64(PIO pio, uint sm, uint64_t pin_values, uint64_t pin_mask) { + pio_sm_set_pindirs_with_mask(pio, sm, (uint32_t) pin_values, (uint32_t) pin_mask); +} +#endif + diff --git a/src/usb_rx.pio b/src/usb_rx.pio index 76e6fbe..aa0807e 100644 --- a/src/usb_rx.pio +++ b/src/usb_rx.pio @@ -155,14 +155,7 @@ J2: % c-sdk { #include "hardware/clocks.h" - -#if PICO_SDK_VERSION_MAJOR < 2 -static __always_inline void pio_sm_set_jmp_pin(PIO pio, uint sm, uint jmp_pin) { - pio->sm[sm].execctrl = - (pio->sm[sm].execctrl & ~PIO_SM0_EXECCTRL_JMP_PIN_BITS) | - (jmp_pin << PIO_SM0_EXECCTRL_JMP_PIN_LSB); -} -#endif +#include "sdk_compat.h" static inline void usb_rx_fs_program_init(PIO pio, uint sm, uint offset, uint pin_dp, uint pin_dm, int pin_debug) { if (pin_dp < pin_dm) { @@ -182,8 +175,8 @@ static inline void usb_rx_fs_program_init(PIO pio, uint sm, uint offset, uint pi } else { c = usb_nrzi_decoder_debug_program_get_default_config(offset); - pio_sm_set_pins_with_mask(pio, sm, 0, 1 << pin_debug); - pio_sm_set_pindirs_with_mask(pio, sm, 1 << pin_debug, 1 << pin_debug); + pio_sm_set_pins_with_mask64(pio, sm, 0, 1ull << pin_debug); + pio_sm_set_pindirs_with_mask64(pio, sm, 1ull << pin_debug, 1ull << pin_debug); pio_gpio_init(pio, pin_debug); sm_config_set_sideset_pins(&c, pin_debug); } @@ -208,8 +201,8 @@ static inline void eop_detect_fs_program_init(PIO pio, uint sm, uint offset, c = usb_edge_detector_program_get_default_config(offset); } else { c = usb_edge_detector_debug_program_get_default_config(offset); - pio_sm_set_pins_with_mask(pio, sm, 0, 1 << pin_debug); - pio_sm_set_pindirs_with_mask(pio, sm, 1 << pin_debug, 1 << pin_debug); + pio_sm_set_pins_with_mask64(pio, sm, 0, 1ull << pin_debug); + pio_sm_set_pindirs_with_mask64(pio, sm, 1ull << pin_debug, 1ull << pin_debug); pio_gpio_init(pio, pin_debug); sm_config_set_sideset_pins(&c, pin_debug); } @@ -232,4 +225,4 @@ static inline void eop_detect_fs_program_init(PIO pio, uint sm, uint offset, pio_sm_set_enabled(pio, sm, true); } -%} \ No newline at end of file +%} diff --git a/src/usb_rx.pio.h b/src/usb_rx.pio.h index 4beaa35..29341e1 100644 --- a/src/usb_rx.pio.h +++ b/src/usb_rx.pio.h @@ -173,13 +173,7 @@ static inline pio_sm_config usb_nrzi_decoder_debug_program_get_default_config(ui } #include "hardware/clocks.h" -#if PICO_SDK_VERSION_MAJOR < 2 -static __always_inline void pio_sm_set_jmp_pin(PIO pio, uint sm, uint jmp_pin) { - pio->sm[sm].execctrl = - (pio->sm[sm].execctrl & ~PIO_SM0_EXECCTRL_JMP_PIN_BITS) | - (jmp_pin << PIO_SM0_EXECCTRL_JMP_PIN_LSB); -} -#endif +#include "sdk_compat.h" static inline void usb_rx_fs_program_init(PIO pio, uint sm, uint offset, uint pin_dp, uint pin_dm, int pin_debug) { if (pin_dp < pin_dm) { pio_sm_set_consecutive_pindirs(pio, sm, pin_dp, 2, false); @@ -195,8 +189,8 @@ static inline void usb_rx_fs_program_init(PIO pio, uint sm, uint offset, uint pi c = usb_nrzi_decoder_program_get_default_config(offset); } else { c = usb_nrzi_decoder_debug_program_get_default_config(offset); - pio_sm_set_pins_with_mask(pio, sm, 0, 1 << pin_debug); - pio_sm_set_pindirs_with_mask(pio, sm, 1 << pin_debug, 1 << pin_debug); + pio_sm_set_pins_with_mask64(pio, sm, 0, 1ull << pin_debug); + pio_sm_set_pindirs_with_mask64(pio, sm, 1ull << pin_debug, 1ull << pin_debug); pio_gpio_init(pio, pin_debug); sm_config_set_sideset_pins(&c, pin_debug); } @@ -216,8 +210,8 @@ static inline void eop_detect_fs_program_init(PIO pio, uint sm, uint offset, c = usb_edge_detector_program_get_default_config(offset); } else { c = usb_edge_detector_debug_program_get_default_config(offset); - pio_sm_set_pins_with_mask(pio, sm, 0, 1 << pin_debug); - pio_sm_set_pindirs_with_mask(pio, sm, 1 << pin_debug, 1 << pin_debug); + pio_sm_set_pins_with_mask64(pio, sm, 0, 1ull << pin_debug); + pio_sm_set_pindirs_with_mask64(pio, sm, 1ull << pin_debug, 1ull << pin_debug); pio_gpio_init(pio, pin_debug); sm_config_set_sideset_pins(&c, pin_debug); } diff --git a/src/usb_tx.pio b/src/usb_tx.pio index dffb7b9..b64fe64 100644 --- a/src/usb_tx.pio +++ b/src/usb_tx.pio @@ -91,6 +91,7 @@ set pindirs, 0b11 side FJ_LK % c-sdk { #include "hardware/clocks.h" +#include "sdk_compat.h" static void __no_inline_not_in_flash_func(usb_tx_configure_pins)(PIO pio, uint sm, uint pin_dp, uint pin_dm) { if (pin_dp < pin_dm) { @@ -106,7 +107,7 @@ set pindirs, 0b11 side FJ_LK static inline void usb_tx_fs_program_init(PIO pio, uint sm, uint offset, uint pin_dp, uint pin_dm) { - pio_sm_set_pins_with_mask(pio, sm, (1 << pin_dp), ((1 << pin_dp) | (1 << pin_dm))); + pio_sm_set_pins_with_mask64(pio, sm, (1ull << pin_dp), ((1ull << pin_dp) | (1ull << pin_dm))); gpio_pull_down(pin_dp); gpio_pull_down(pin_dm); @@ -132,7 +133,7 @@ set pindirs, 0b11 side FJ_LK static inline void usb_tx_ls_program_init(PIO pio, uint sm, uint offset, uint pin_dp, uint pin_dm) { - pio_sm_set_pins_with_mask(pio, sm, (1 << pin_dm), ((1 << pin_dp) | (1 << pin_dm))); + pio_sm_set_pins_with_mask64(pio, sm, (1ull << pin_dm), ((1ull << pin_dp) | (1ull << pin_dm))); gpio_pull_down(pin_dp); gpio_pull_down(pin_dm); @@ -156,4 +157,4 @@ set pindirs, 0b11 side FJ_LK pio_sm_set_enabled(pio, sm, true); } -%} \ No newline at end of file +%} diff --git a/src/usb_tx.pio.h b/src/usb_tx.pio.h index 0e938c8..991565b 100644 --- a/src/usb_tx.pio.h +++ b/src/usb_tx.pio.h @@ -138,6 +138,7 @@ static inline pio_sm_config usb_tx_pre_dmdp_program_get_default_config(uint offs } #include "hardware/clocks.h" +#include "sdk_compat.h" static void __no_inline_not_in_flash_func(usb_tx_configure_pins)(PIO pio, uint sm, uint pin_dp, uint pin_dm) { if (pin_dp < pin_dm) { pio_sm_set_out_pins(pio, sm, pin_dp, 2); @@ -151,7 +152,7 @@ static inline pio_sm_config usb_tx_pre_dmdp_program_get_default_config(uint offs } static inline void usb_tx_fs_program_init(PIO pio, uint sm, uint offset, uint pin_dp, uint pin_dm) { - pio_sm_set_pins_with_mask(pio, sm, (1 << pin_dp), ((1 << pin_dp) | (1 << pin_dm))); + pio_sm_set_pins_with_mask64(pio, sm, (1ull << pin_dp), ((1ull << pin_dp) | (1ull << pin_dm))); gpio_pull_down(pin_dp); gpio_pull_down(pin_dm); pio_gpio_init(pio, pin_dp); @@ -170,7 +171,7 @@ static inline pio_sm_config usb_tx_pre_dmdp_program_get_default_config(uint offs } static inline void usb_tx_ls_program_init(PIO pio, uint sm, uint offset, uint pin_dp, uint pin_dm) { - pio_sm_set_pins_with_mask(pio, sm, (1 << pin_dm), ((1 << pin_dp) | (1 << pin_dm))); + pio_sm_set_pins_with_mask64(pio, sm, (1ull << pin_dm), ((1ull << pin_dp) | (1ull << pin_dm))); gpio_pull_down(pin_dp); gpio_pull_down(pin_dm); pio_gpio_init(pio, pin_dp);