summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHa Thach <[email protected]>2022-05-21 13:54:25 +0700
committerGitHub <[email protected]>2022-05-21 13:54:25 +0700
commit2683deb0dd2e049de6c9b15f49d28a2fef4380f6 (patch)
treefb480d7a4fa7aa7797097600b6d8a5fef3f080b3
parent817227a850d4942cf48ede675325d635e2e7b3d5 (diff)
parentc2bcda86e2de35cc01628f4e909e2a7869a7322b (diff)
Merge branch 'master' into ch32v307
-rw-r--r--.github/ISSUE_TEMPLATE/config.yml4
-rw-r--r--.github/workflows/build_aarch64.yml4
-rw-r--r--.github/workflows/build_arm.yml11
-rw-r--r--.github/workflows/build_esp.yml4
-rw-r--r--.github/workflows/build_msp430.yml4
-rw-r--r--.github/workflows/build_renesas.yml4
-rw-r--r--.github/workflows/build_riscv.yml4
-rw-r--r--.github/workflows/trigger.yml2
-rw-r--r--.gitmodules3
-rw-r--r--docs/requirements.txt1
-rw-r--r--examples/device/cdc_msc_freertos/src/main.c14
-rw-r--r--examples/device/hid_boot_interface/src/tusb_config.h4
-rw-r--r--examples/device/hid_composite_freertos/src/main.c4
-rw-r--r--examples/dual/host_hid_to_device_cdc/CMakeLists.txt (renamed from examples/host/hid_to_cdc/CMakeLists.txt)4
-rw-r--r--examples/dual/host_hid_to_device_cdc/Makefile (renamed from examples/host/hid_to_cdc/Makefile)0
-rw-r--r--examples/dual/host_hid_to_device_cdc/only.txt (renamed from examples/host/hid_to_cdc/only.txt)1
-rw-r--r--examples/dual/host_hid_to_device_cdc/src/main.c (renamed from examples/host/hid_to_cdc/src/main.c)215
-rw-r--r--examples/dual/host_hid_to_device_cdc/src/tusb_config.h (renamed from examples/host/hid_to_cdc/src/tusb_config.h)12
-rw-r--r--examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c (renamed from examples/host/hid_to_cdc/src/usb_descriptors.c)1
-rw-r--r--examples/host/bare_api/CMakeLists.txt5
-rw-r--r--examples/host/cdc_msc_hid/CMakeLists.txt5
-rw-r--r--examples/host/cdc_msc_hid/src/tusb_config.h7
-rw-r--r--examples/host/hid_controller/CMakeLists.txt5
-rw-r--r--examples/rules.mk2
-rw-r--r--hw/bsp/imxrt/family.c5
-rw-r--r--hw/bsp/rp2040/family.c3
-rw-r--r--hw/bsp/rp2040/family.cmake57
m---------hw/mcu/raspberry_pi/Pico-PIO-USB0
-rw-r--r--hw/mcu/sony/cxd56/tools/__pycache__/xmodem.cpython-36.pycbin15257 -> 0 bytes
m---------lib/Pico-PIO-USB0
-rw-r--r--src/class/hid/hid_host.c2
-rw-r--r--src/common/tusb_debug.h8
-rw-r--r--src/common/tusb_mcu.h7
-rw-r--r--src/common/tusb_verify.h10
-rw-r--r--src/device/dcd.h32
-rw-r--r--src/device/usbd.c46
-rw-r--r--src/device/usbd.h13
-rw-r--r--src/host/hcd.h51
-rw-r--r--src/host/usbh.c89
-rw-r--r--src/host/usbh.h19
-rw-r--r--src/osal/osal.h22
-rw-r--r--src/osal/osal_freertos.h45
-rw-r--r--src/osal/osal_mynewt.h22
-rw-r--r--src/osal/osal_none.h28
-rw-r--r--src/osal/osal_pico.h44
-rw-r--r--src/osal/osal_rtthread.h28
-rw-r--r--src/osal/osal_rtx4.h28
-rw-r--r--src/portable/ehci/ehci.c4
-rw-r--r--src/portable/mentor/musb/hcd_musb.c5
-rw-r--r--src/portable/ohci/ohci.c5
-rw-r--r--src/portable/raspberrypi/pio_usb/dcd_pio_usb.c210
-rw-r--r--src/portable/raspberrypi/pio_usb/hcd_pio_usb.c217
-rw-r--r--src/portable/raspberrypi/rp2040/dcd_rp2040.c2
-rw-r--r--src/portable/raspberrypi/rp2040/hcd_rp2040.c14
-rw-r--r--src/portable/renesas/usba/hcd_usba.c5
-rw-r--r--src/portable/sony/cxd56/dcd_cxd56.c2
-rw-r--r--src/tusb_option.h20
-rw-r--r--tools/build_board.py11
-rw-r--r--tools/build_family.py11
59 files changed, 984 insertions, 401 deletions
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index 735a5ef22..28fd27467 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -1,4 +1,8 @@
+blank_issues_enabled: false
contact_links:
- name: TinyUSB Discussion
url: https://github.com/hathach/tinyusb/discussions
about: If you have other questions or need help, post it here.
+ - name: TinyUSB Docs
+ url: https://docs.tinyusb.org/
+ about: Online documentation
diff --git a/.github/workflows/build_aarch64.yml b/.github/workflows/build_aarch64.yml
index 8cf7852b9..1720ba592 100644
--- a/.github/workflows/build_aarch64.yml
+++ b/.github/workflows/build_aarch64.yml
@@ -24,13 +24,13 @@ jobs:
uses: actions/setup-python@v2
- name: Checkout TinyUSB
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Checkout common submodules in lib
run: git submodule update --init lib/FreeRTOS-Kernel lib/lwip lib/sct_neopixel
- name: Checkout hathach/linkermap
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
with:
repository: hathach/linkermap
path: linkermap
diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml
index 177f1076e..5a796a49b 100644
--- a/.github/workflows/build_arm.yml
+++ b/.github/workflows/build_arm.yml
@@ -15,12 +15,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Setup Ruby
- uses: actions/setup-ruby@v1
+ uses: ruby/setup-ruby@v1
with:
ruby-version: '2.7'
- name: Checkout TinyUSB
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Unit Tests
run: |
@@ -66,13 +66,13 @@ jobs:
uses: actions/setup-python@v2
- name: Checkout TinyUSB
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Checkout common submodules in lib
run: git submodule update --init lib/FreeRTOS-Kernel lib/lwip lib/sct_neopixel
- name: Checkout hathach/linkermap
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
with:
repository: hathach/linkermap
path: linkermap
@@ -82,6 +82,7 @@ jobs:
run: |
git clone --depth 1 -b develop https://github.com/raspberrypi/pico-sdk ~/pico-sdk
echo >> $GITHUB_ENV PICO_SDK_PATH=~/pico-sdk
+ git submodule update --init hw/mcu/raspberry_pi/Pico-PIO-USB
- name: Set Toolchain URL
run: echo >> $GITHUB_ENV TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v10.2.1-1.1/xpack-arm-none-eabi-gcc-10.2.1-1.1-linux-x64.tar.gz
@@ -135,7 +136,7 @@ jobs:
uses: actions/setup-python@v2
- name: Checkout TinyUSB
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Checkout common submodules in lib
run: git submodule update --init lib/FreeRTOS-Kernel lib/lwip
diff --git a/.github/workflows/build_esp.yml b/.github/workflows/build_esp.yml
index 1ed76ef4d..6a46773b2 100644
--- a/.github/workflows/build_esp.yml
+++ b/.github/workflows/build_esp.yml
@@ -29,10 +29,10 @@ jobs:
run: docker pull espressif/idf:latest
- name: Checkout TinyUSB
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Checkout hathach/linkermap
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
with:
repository: hathach/linkermap
path: linkermap
diff --git a/.github/workflows/build_msp430.yml b/.github/workflows/build_msp430.yml
index 98dc36cd9..6a468ab04 100644
--- a/.github/workflows/build_msp430.yml
+++ b/.github/workflows/build_msp430.yml
@@ -21,13 +21,13 @@ jobs:
uses: actions/setup-python@v2
- name: Checkout TinyUSB
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Checkout common submodules in lib
run: git submodule update --init lib/FreeRTOS-Kernel lib/lwip
- name: Checkout hathach/linkermap
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
with:
repository: hathach/linkermap
path: linkermap
diff --git a/.github/workflows/build_renesas.yml b/.github/workflows/build_renesas.yml
index 6eb042d72..50618ff6b 100644
--- a/.github/workflows/build_renesas.yml
+++ b/.github/workflows/build_renesas.yml
@@ -21,13 +21,13 @@ jobs:
uses: actions/setup-python@v2
- name: Checkout TinyUSB
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Checkout common submodules in lib
run: git submodule update --init lib/FreeRTOS-Kernel lib/lwip
- name: Checkout hathach/linkermap
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
with:
repository: hathach/linkermap
path: linkermap
diff --git a/.github/workflows/build_riscv.yml b/.github/workflows/build_riscv.yml
index 4ac265da3..b54605346 100644
--- a/.github/workflows/build_riscv.yml
+++ b/.github/workflows/build_riscv.yml
@@ -23,13 +23,13 @@ jobs:
uses: actions/setup-python@v2
- name: Checkout TinyUSB
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Checkout common submodules in lib
run: git submodule update --init lib/FreeRTOS-Kernel lib/lwip
- name: Checkout hathach/linkermap
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
with:
repository: hathach/linkermap
path: linkermap
diff --git a/.github/workflows/trigger.yml b/.github/workflows/trigger.yml
index 40750a2f9..780d6f4f3 100644
--- a/.github/workflows/trigger.yml
+++ b/.github/workflows/trigger.yml
@@ -22,7 +22,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Push to tinyusb_src
run: |
diff --git a/.gitmodules b/.gitmodules
index fd2b75cb8..a49e0407e 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -149,3 +149,6 @@
[submodule "hw/mcu/wch/ch32v307"]
path = hw/mcu/wch/ch32v307
url = https://github.com/openwch/ch32v307.git
+[submodule "hw/mcu/raspberry_pi/Pico-PIO-USB"]
+ path = hw/mcu/raspberry_pi/Pico-PIO-USB
+ url = https://github.com/sekigon-gonnoc/Pico-PIO-USB.git
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 8ae9ae73b..15022e147 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,3 +1,4 @@
sphinx~=3.0
furo>=2020.12.30.b24
sphinx-autodoc-typehints>=1.10
+jinja2==3.0.3
diff --git a/examples/device/cdc_msc_freertos/src/main.c b/examples/device/cdc_msc_freertos/src/main.c
index 0a1c964ae..a5e907199 100644
--- a/examples/device/cdc_msc_freertos/src/main.c
+++ b/examples/device/cdc_msc_freertos/src/main.c
@@ -130,8 +130,11 @@ void usb_device_task(void* param)
// RTOS forever loop
while (1)
{
- // tinyusb device task
+ // put this thread to waiting state until there is new events
tud_task();
+
+ // following code only run if tud_task() process at least 1 event
+ tud_cdc_write_flush();
}
}
@@ -181,7 +184,7 @@ void cdc_task(void* params)
// if ( tud_cdc_connected() )
{
// There are data available
- if ( tud_cdc_available() )
+ while ( tud_cdc_available() )
{
uint8_t buf[64];
@@ -194,12 +197,13 @@ void cdc_task(void* params)
// for throughput test e.g
// $ dd if=/dev/zero of=/dev/ttyACM0 count=10000
tud_cdc_write(buf, count);
- tud_cdc_write_flush();
}
+
+ tud_cdc_write_flush();
}
- // For ESP32-S2 this delay is essential to allow idle how to run and reset wdt
- vTaskDelay(pdMS_TO_TICKS(10));
+ // For ESP32-Sx this delay is essential to allow idle how to run and reset watchdog
+ vTaskDelay(1);
}
}
diff --git a/examples/device/hid_boot_interface/src/tusb_config.h b/examples/device/hid_boot_interface/src/tusb_config.h
index 1c8fa40b2..8bc85b722 100644
--- a/examples/device/hid_boot_interface/src/tusb_config.h
+++ b/examples/device/hid_boot_interface/src/tusb_config.h
@@ -39,6 +39,10 @@
#error CFG_TUSB_MCU must be defined
#endif
+// Use raspberry pio-usb for device
+// #define CFG_TUD_RPI_PIO_USB 1
+// #define BOARD_DEVICE_RHPORT_NUM 1
+
// RHPort number used for device can be defined by board.mk, default to port 0
#ifndef BOARD_DEVICE_RHPORT_NUM
#define BOARD_DEVICE_RHPORT_NUM 0
diff --git a/examples/device/hid_composite_freertos/src/main.c b/examples/device/hid_composite_freertos/src/main.c
index 1695f968c..317b64611 100644
--- a/examples/device/hid_composite_freertos/src/main.c
+++ b/examples/device/hid_composite_freertos/src/main.c
@@ -132,8 +132,10 @@ void usb_device_task(void* param)
// RTOS forever loop
while (1)
{
- // tinyusb device task
+ // put this thread to waiting state until there is new events
tud_task();
+
+ // following code only run if tud_task() process at least 1 event
}
}
diff --git a/examples/host/hid_to_cdc/CMakeLists.txt b/examples/dual/host_hid_to_device_cdc/CMakeLists.txt
index abc4d91da..24ebfdec3 100644
--- a/examples/host/hid_to_cdc/CMakeLists.txt
+++ b/examples/dual/host_hid_to_device_cdc/CMakeLists.txt
@@ -25,4 +25,6 @@ target_include_directories(${PROJECT} PUBLIC
# Configure compilation flags and libraries for the example... see the corresponding function
# in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT}) \ No newline at end of file
+family_configure_device_example(${PROJECT})
+family_configure_host_example(${PROJECT})
+family_configure_pico_pio_usb_example(${PROJECT})
diff --git a/examples/host/hid_to_cdc/Makefile b/examples/dual/host_hid_to_device_cdc/Makefile
index 3fe9b0888..3fe9b0888 100644
--- a/examples/host/hid_to_cdc/Makefile
+++ b/examples/dual/host_hid_to_device_cdc/Makefile
diff --git a/examples/host/hid_to_cdc/only.txt b/examples/dual/host_hid_to_device_cdc/only.txt
index 78d94e3ce..6ee8e3fde 100644
--- a/examples/host/hid_to_cdc/only.txt
+++ b/examples/dual/host_hid_to_device_cdc/only.txt
@@ -1,2 +1,3 @@
board:mimxrt1060_evk
board:mimxrt1064_evk
+mcu:RP2040
diff --git a/examples/host/hid_to_cdc/src/main.c b/examples/dual/host_hid_to_device_cdc/src/main.c
index cdf5d264e..62ecb2c3f 100644
--- a/examples/host/hid_to_cdc/src/main.c
+++ b/examples/dual/host_hid_to_device_cdc/src/main.c
@@ -23,10 +23,8 @@
*
*/
-// This example runs both host and device concurrently. The USB host looks for
-// any HID device with reports that are 8 bytes long and then assumes they are
-// keyboard reports. It translates the keypresses of the reports to ASCII and
-// transmits it over CDC to the device's host.
+// This example runs both host and device concurrently. The USB host receive
+// reports from HID device and print it out over USB Device CDC interface.
#include <stdlib.h>
#include <stdio.h>
@@ -73,12 +71,14 @@ enum {
static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
void led_blinking_task(void);
-void cdc_task(void);
/*------------- MAIN -------------*/
int main(void)
{
board_init();
+
+ printf("TinyUSB Host HID <-> Device CDC Example\r\n");
+
tusb_init();
while (1)
@@ -86,15 +86,13 @@ int main(void)
tud_task(); // tinyusb device task
tuh_task(); // tinyusb host task
led_blinking_task();
-
- cdc_task();
}
return 0;
}
//--------------------------------------------------------------------+
-// Device callbacks
+// Device CDC
//--------------------------------------------------------------------+
// Invoked when device is mounted
@@ -124,8 +122,20 @@ void tud_resume_cb(void)
blink_interval_ms = BLINK_MOUNTED;
}
+// Invoked when CDC interface received data from host
+void tud_cdc_rx_cb(uint8_t itf)
+{
+ (void) itf;
+
+ char buf[64];
+ uint32_t count = tud_cdc_read(buf, sizeof(buf));
+
+ // TODO control LED on keyboard of host stack
+ (void) count;
+}
+
//--------------------------------------------------------------------+
-// Host callbacks
+// Host HID
//--------------------------------------------------------------------+
// Invoked when device with hid interface is mounted
@@ -137,169 +147,140 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re
{
(void)desc_report;
(void)desc_len;
+
+ // Interface protocol (hid_interface_protocol_enum_t)
+ const char* protocol_str[] = { "None", "Keyboard", "Mouse" };
+ uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance);
+
uint16_t vid, pid;
tuh_vid_pid_get(dev_addr, &vid, &pid);
- printf("HID device address = %d, instance = %d is mounted\r\n", dev_addr, instance);
- printf("VID = %04x, PID = %04x\r\n", vid, pid);
+ char tempbuf[256];
+ int count = sprintf(tempbuf, "[%04x:%04x][%u] HID Interface%u, Protocol = %s\r\n", vid, pid, dev_addr, instance, protocol_str[itf_protocol]);
- // Receive any report and treat it like a keyboard.
+ tud_cdc_write(tempbuf, count);
+ tud_cdc_write_flush();
+
+ // Receive report from boot keyboard & mouse only
// tuh_hid_report_received_cb() will be invoked when report is available
- if ( !tuh_hid_receive_report(dev_addr, instance) )
+ if (itf_protocol == HID_ITF_PROTOCOL_KEYBOARD || itf_protocol == HID_ITF_PROTOCOL_MOUSE)
{
- printf("Error: cannot request to receive report\r\n");
+ if ( !tuh_hid_receive_report(dev_addr, instance) )
+ {
+ tud_cdc_write_str("Error: cannot request report\r\n");
+ }
}
}
// Invoked when device with hid interface is un-mounted
void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance)
{
- printf("HID device address = %d, instance = %d is unmounted\r\n", dev_addr, instance);
+ char tempbuf[256];
+ int count = sprintf(tempbuf, "[%u] HID Interface%u is unmounted\r\n", dev_addr, instance);
+ tud_cdc_write(tempbuf, count);
+ tud_cdc_write_flush();
}
-// keycodes from last report to check if key is holding or newly pressed
-uint8_t last_keycodes[6] = {0};
-
// look up new key in previous keys
-static inline bool key_in_last_report(const uint8_t key_arr[6], uint8_t keycode)
+static inline bool find_key_in_report(hid_keyboard_report_t const *report, uint8_t keycode)
{
for(uint8_t i=0; i<6; i++)
{
- if (key_arr[i] == keycode) return true;
+ if (report->keycode[i] == keycode) return true;
}
return false;
}
-// Invoked when received report from device via interrupt endpoint
-void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len)
-{
- if (len != 8)
- {
- char ch_num;
-
- tud_cdc_write_str("incorrect report len: ");
-
- if ( len > 10 )
- {
- ch_num = '0' + (len / 10);
- tud_cdc_write(&ch_num, 1);
- len = len % 10;
- }
-
- ch_num = '0' + len;
- tud_cdc_write(&ch_num, 1);
-
- tud_cdc_write_str("\r\n");
- tud_cdc_write_flush();
-
- // Don't request a new report for a wrong sized endpoint.
- return;
- }
- uint8_t const modifiers = report[0];
+// convert hid keycode to ascii and print via usb device CDC (ignore non-printable)
+static void process_kbd_report(uint8_t dev_addr, hid_keyboard_report_t const *report)
+{
+ (void) dev_addr;
+ static hid_keyboard_report_t prev_report = { 0, 0, {0} }; // previous report to check key released
bool flush = false;
- for (int i = 2; i < 8; i++)
+ for(uint8_t i=0; i<6; i++)
{
- uint8_t keycode = report[i];
-
- if (keycode)
+ uint8_t keycode = report->keycode[i];
+ if ( keycode )
{
- if ( key_in_last_report(last_keycodes, keycode) )
+ if ( find_key_in_report(&prev_report, keycode) )
{
// exist in previous report means the current key is holding
- // do nothing
}else
{
// not existed in previous report means the current key is pressed
- // Only print keycodes 0 - 128.
- if (keycode < 128)
- {
- // remap the key code for Colemak layout so @tannewt can type.
- #ifdef KEYBOARD_COLEMAK
- uint8_t colemak_key_code = colemak[keycode];
- if (colemak_key_code != 0) keycode = colemak_key_code;
- #endif
- bool const is_shift = modifiers & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT);
- char c = keycode2ascii[keycode][is_shift ? 1 : 0];
- if (c)
- {
- if (c == '\n') tud_cdc_write("\r", 1);
- tud_cdc_write(&c, 1);
- flush = true;
- }
+ // remap the key code for Colemak layout
+ #ifdef KEYBOARD_COLEMAK
+ uint8_t colemak_key_code = colemak[keycode];
+ if (colemak_key_code != 0) keycode = colemak_key_code;
+ #endif
+
+ bool const is_shift = report->modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT);
+ uint8_t ch = keycode2ascii[keycode][is_shift ? 1 : 0];
+
+ if (ch)
+ {
+ if (ch == '\n') tud_cdc_write("\r", 1);
+ tud_cdc_write(&ch, 1);
+ flush = true;
}
}
}
+ // TODO example skips key released
}
if (flush) tud_cdc_write_flush();
- // save current report
- memcpy(last_keycodes, report+2, 6);
-
- // continue to request to receive report
- if ( !tuh_hid_receive_report(dev_addr, instance) )
- {
- printf("Error: cannot request to receive report\r\n");
- }
+ prev_report = *report;
}
-
-
-//--------------------------------------------------------------------+
-// USB CDC
-//--------------------------------------------------------------------+
-void cdc_task(void)
+// send mouse report to usb device CDC
+static void process_mouse_report(uint8_t dev_addr, hid_mouse_report_t const * report)
{
- // connected() check for DTR bit
- // Most but not all terminal client set this when making connection
- // if ( tud_cdc_connected() )
- {
- // connected and there are data available
- if ( tud_cdc_available() )
- {
- // read datas
- char buf[64];
- uint32_t count = tud_cdc_read(buf, sizeof(buf));
- (void) count;
+ //------------- button state -------------//
+ //uint8_t button_changed_mask = report->buttons ^ prev_report.buttons;
+ char l = report->buttons & MOUSE_BUTTON_LEFT ? 'L' : '-';
+ char m = report->buttons & MOUSE_BUTTON_MIDDLE ? 'M' : '-';
+ char r = report->buttons & MOUSE_BUTTON_RIGHT ? 'R' : '-';
- // Echo back
- // Note: Skip echo by commenting out write() and write_flush()
- // for throughput test e.g
- // $ dd if=/dev/zero of=/dev/ttyACM0 count=10000
- tud_cdc_write(buf, count);
- tud_cdc_write_flush();
- }
- }
+ char tempbuf[32];
+ int count = sprintf(tempbuf, "[%u] %c%c%c %d %d %d\r\n", dev_addr, l, m, r, report->x, report->y, report->wheel);
+
+ tud_cdc_write(tempbuf, count);
+ tud_cdc_write_flush();
}
-// Invoked when cdc when line state changed e.g connected/disconnected
-void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
+// Invoked when received report from device via interrupt endpoint
+void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len)
{
- (void) itf;
- (void) rts;
+ (void) len;
+ uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance);
- // TODO set some indicator
- if ( dtr )
+ switch(itf_protocol)
{
- // Terminal connected
- }else
- {
- // Terminal disconnected
+ case HID_ITF_PROTOCOL_KEYBOARD:
+ process_kbd_report(dev_addr, (hid_keyboard_report_t const*) report );
+ break;
+
+ case HID_ITF_PROTOCOL_MOUSE:
+ process_mouse_report(dev_addr, (hid_mouse_report_t const*) report );
+ break;
+
+ default: break;
}
-}
-// Invoked when CDC interface received data from host
-void tud_cdc_rx_cb(uint8_t itf)
-{
- (void) itf;
+ // continue to request to receive report
+ if ( !tuh_hid_receive_report(dev_addr, instance) )
+ {
+ tud_cdc_write_str("Error: cannot request report\r\n");
+ }
}
//--------------------------------------------------------------------+
-// BLINKING TASK
+// Blinking Task
//--------------------------------------------------------------------+
void led_blinking_task(void)
{
diff --git a/examples/host/hid_to_cdc/src/tusb_config.h b/examples/dual/host_hid_to_device_cdc/src/tusb_config.h
index 9a35ffc30..0fa4899a9 100644
--- a/examples/host/hid_to_cdc/src/tusb_config.h
+++ b/examples/dual/host_hid_to_device_cdc/src/tusb_config.h
@@ -49,6 +49,9 @@
#define BOARD_HOST_RHPORT_NUM 1
#endif
+// Use raspberry pio-usb for host
+#define CFG_TUH_RPI_PIO_USB 1
+
// RHPort max operational speed can defined by board.mk
// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed
#ifndef BOARD_DEVICE_RHPORT_SPEED
@@ -124,10 +127,6 @@
//------------- CLASS -------------//
#define CFG_TUD_CDC 1
-#define CFG_TUD_MSC 0
-#define CFG_TUD_HID 0
-#define CFG_TUD_MIDI 0
-#define CFG_TUD_VENDOR 0
// CDC FIFO size of TX and RX
#define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
@@ -144,14 +143,9 @@
#define CFG_TUH_ENUMERATION_BUFSIZE 256
#define CFG_TUH_HUB 1
-#define CFG_TUH_CDC 0
-#define CFG_TUH_MSC 0
-#define CFG_TUH_VENDOR 0
-
// max device support (excluding hub device)
#define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1) // hub typically has 4 ports
-//------------- HID -------------//
#define CFG_TUH_HID 4
#define CFG_TUH_HID_EPIN_BUFSIZE 64
#define CFG_TUH_HID_EPOUT_BUFSIZE 64
diff --git a/examples/host/hid_to_cdc/src/usb_descriptors.c b/examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c
index 7dd73937c..e55899f65 100644
--- a/examples/host/hid_to_cdc/src/usb_descriptors.c
+++ b/examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c
@@ -81,7 +81,6 @@ enum
{
ITF_NUM_CDC = 0,
ITF_NUM_CDC_DATA,
- ITF_NUM_MSC,
ITF_NUM_TOTAL
};
diff --git a/examples/host/bare_api/CMakeLists.txt b/examples/host/bare_api/CMakeLists.txt
index bff281a8c..607ef22eb 100644
--- a/examples/host/bare_api/CMakeLists.txt
+++ b/examples/host/bare_api/CMakeLists.txt
@@ -24,4 +24,7 @@ target_include_directories(${PROJECT} PUBLIC
# Configure compilation flags and libraries for the example... see the corresponding function
# in hw/bsp/FAMILY/family.cmake for details.
-family_configure_host_example(${PROJECT}) \ No newline at end of file
+family_configure_host_example(${PROJECT})
+
+# For rp2040, un-comment to enable pico-pio-usb
+# family_configure_pico_pio_usb_example(${PROJECT})
diff --git a/examples/host/cdc_msc_hid/CMakeLists.txt b/examples/host/cdc_msc_hid/CMakeLists.txt
index 0a99bc3a9..214e9f2e7 100644
--- a/examples/host/cdc_msc_hid/CMakeLists.txt
+++ b/examples/host/cdc_msc_hid/CMakeLists.txt
@@ -26,4 +26,7 @@ target_include_directories(${PROJECT} PUBLIC
# Configure compilation flags and libraries for the example... see the corresponding function
# in hw/bsp/FAMILY/family.cmake for details.
-family_configure_host_example(${PROJECT}) \ No newline at end of file
+family_configure_host_example(${PROJECT})
+
+# For rp2040, un-comment to enable pico-pio-usb
+# family_configure_pico_pio_usb_example(${PROJECT})
diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h
index bc6c68e5b..e9e68cf5a 100644
--- a/examples/host/cdc_msc_hid/src/tusb_config.h
+++ b/examples/host/cdc_msc_hid/src/tusb_config.h
@@ -39,8 +39,15 @@
#error CFG_TUSB_MCU must be defined
#endif
+// Use raspberry pio-usb for host
+// #define CFG_TUH_RPI_PIO_USB 1
+// #define CFG_TUH_RPI_PIO_USB 1
+
#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | OPT_MODE_HIGH_SPEED)
+#elif defined(CFG_TUH_RPI_PIO_USB) && CFG_TUH_RPI_PIO_USB
+ // rp2040: port0 is native, port 1 for PIO-USB
+ #define CFG_TUSB_RHPORT1_MODE OPT_MODE_HOST
#else
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_HOST
#endif
diff --git a/examples/host/hid_controller/CMakeLists.txt b/examples/host/hid_controller/CMakeLists.txt
index aaf8bc34f..6227e0790 100644
--- a/examples/host/hid_controller/CMakeLists.txt
+++ b/examples/host/hid_controller/CMakeLists.txt
@@ -25,4 +25,7 @@ target_include_directories(${PROJECT} PUBLIC
# Configure compilation flags and libraries for the example... see the corresponding function
# in hw/bsp/FAMILY/family.cmake for details.
-family_configure_host_example(${PROJECT}) \ No newline at end of file
+family_configure_host_example(${PROJECT})
+
+# For rp2040, un-comment to enable pico-pio-usb
+# family_configure_pico_pio_usb_example(${PROJECT})
diff --git a/examples/rules.mk b/examples/rules.mk
index 97f6956fa..538dffbcf 100644
--- a/examples/rules.mk
+++ b/examples/rules.mk
@@ -199,7 +199,7 @@ flash-xfel: $(BUILD)/$(PROJECT)-sunxi.bin
PYOCD_OPTION ?=
flash-pyocd: $(BUILD)/$(PROJECT).hex
pyocd flash -t $(PYOCD_TARGET) $(PYOCD_OPTION) $<
- pyocd reset -t $(PYOCD_TARGET)
+ #pyocd reset -t $(PYOCD_TARGET)
# Flash using openocd
OPENOCD_OPTION ?=
diff --git a/hw/bsp/imxrt/family.c b/hw/bsp/imxrt/family.c
index a811a7e40..8d34d4b9f 100644
--- a/hw/bsp/imxrt/family.c
+++ b/hw/bsp/imxrt/family.c
@@ -51,7 +51,10 @@ void board_init(void)
SysTick_Config(SystemCoreClock / 1000);
#elif CFG_TUSB_OS == OPT_OS_FREERTOS
// If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
-// NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
+ NVIC_SetPriority(USB_OTG1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
+#ifdef USB_OTG2_IRQn
+ NVIC_SetPriority(USB_OTG2_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
+#endif
#endif
// LED
diff --git a/hw/bsp/rp2040/family.c b/hw/bsp/rp2040/family.c
index fa63dadf5..dcf38b6ec 100644
--- a/hw/bsp/rp2040/family.c
+++ b/hw/bsp/rp2040/family.c
@@ -127,6 +127,9 @@ void board_init(void)
#ifndef BUTTON_BOOTSEL
#endif
+ // Set the system clock to a multiple of 120mhz for bitbanging USB with pico-usb
+ set_sys_clock_khz(120000, true);
+
#if defined(UART_DEV) && defined(LIB_PICO_STDIO_UART)
bi_decl(bi_2pins_with_func(UART_TX_PIN, UART_TX_PIN, GPIO_FUNC_UART));
uart_inst = uart_get_instance(UART_DEV);
diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake
index e832c0756..17ae3de9b 100644
--- a/hw/bsp/rp2040/family.cmake
+++ b/hw/bsp/rp2040/family.cmake
@@ -23,9 +23,11 @@ if (NOT TARGET _rp2040_family_inclusion_marker)
set(PICO_TINYUSB_PATH ${TOP})
endif()
+ #------------------------------------
# Base config for both device and host; wrapped by SDK's tinyusb_common
+ #------------------------------------
add_library(tinyusb_common_base INTERFACE)
-
+
target_sources(tinyusb_common_base INTERFACE
${TOP}/src/tusb.c
${TOP}/src/common/tusb_fifo.c
@@ -56,11 +58,44 @@ if (NOT TARGET _rp2040_family_inclusion_marker)
CFG_TUSB_DEBUG=${TINYUSB_DEBUG_LEVEL}
)
+ #------------------------------------
+ # PIO USB for both host and device
+ #------------------------------------
+ add_library(pico_pio_usb INTERFACE)
+
+ if (NOT DEFINED PICO_PIO_USB_PATH)
+ set(PICO_PIO_USB_PATH "${TOP}/hw/mcu/raspberry_pi/Pico-PIO-USB")
+ endif()
+
+ target_sources(pico_pio_usb INTERFACE
+ ${PICO_PIO_USB_PATH}/src/pio_usb.c
+ ${PICO_PIO_USB_PATH}/src/pio_usb_host.c
+ ${PICO_PIO_USB_PATH}/src/pio_usb_device.c
+ ${PICO_PIO_USB_PATH}/src/usb_crc.c
+ )
+
+ target_include_directories(pico_pio_usb INTERFACE
+ ${PICO_PIO_USB_PATH}/src
+ )
+
+ target_link_libraries(pico_pio_usb INTERFACE
+ hardware_dma
+ hardware_pio
+ pico_multicore
+ )
+
+ target_compile_definitions(pico_pio_usb INTERFACE
+ PIO_USB_USE_TINYUSB
+ )
+
+ #------------------------------------
# Base config for device mode; wrapped by SDK's tinyusb_device
+ #------------------------------------
add_library(tinyusb_device_base INTERFACE)
target_sources(tinyusb_device_base INTERFACE
${TOP}/src/portable/raspberrypi/rp2040/dcd_rp2040.c
${TOP}/src/portable/raspberrypi/rp2040/rp2040_usb.c
+ ${TOP}/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c
${TOP}/src/device/usbd.c
${TOP}/src/device/usbd_control.c
${TOP}/src/class/audio/audio_device.c
@@ -77,11 +112,14 @@ if (NOT TARGET _rp2040_family_inclusion_marker)
${TOP}/src/class/video/video_device.c
)
+ #------------------------------------
# Base config for host mode; wrapped by SDK's tinyusb_host
+ #------------------------------------
add_library(tinyusb_host_base INTERFACE)
target_sources(tinyusb_host_base INTERFACE
${TOP}/src/portable/raspberrypi/rp2040/hcd_rp2040.c
${TOP}/src/portable/raspberrypi/rp2040/rp2040_usb.c
+ ${TOP}/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c
${TOP}/src/host/usbh.c
${TOP}/src/host/hub.c
${TOP}/src/class/cdc/cdc_host.c
@@ -90,12 +128,14 @@ if (NOT TARGET _rp2040_family_inclusion_marker)
${TOP}/src/class/vendor/vendor_host.c
)
- # Sometimes have to do host specific actions in mostly
- # common functions
+ # Sometimes have to do host specific actions in mostly common functions
target_compile_definitions(tinyusb_host_base INTERFACE
RP2040_USB_HOST_MODE=1
)
+ #------------------------------------
+ # BSP & Additions
+ #------------------------------------
add_library(tinyusb_bsp INTERFACE)
target_sources(tinyusb_bsp INTERFACE
${TOP}/hw/bsp/rp2040/family.c
@@ -129,6 +169,10 @@ if (NOT TARGET _rp2040_family_inclusion_marker)
)
endif()
+ #------------------------------------
+ # Functions
+ #------------------------------------
+
function(family_configure_target TARGET)
pico_add_extra_outputs(${TARGET})
pico_enable_stdio_uart(${TARGET} 1)
@@ -145,6 +189,13 @@ if (NOT TARGET _rp2040_family_inclusion_marker)
target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_host)
endfunction()
+ function(family_configure_pico_pio_usb_example TARGET)
+ family_configure_target(${TARGET})
+ target_link_libraries(${TARGET} PUBLIC pico_stdlib pico_pio_usb)
+ pico_generate_pio_header(tinyusb_common_base ${PICO_PIO_USB_PATH}/src/usb_tx.pio)
+ pico_generate_pio_header(tinyusb_common_base ${PICO_PIO_USB_PATH}/src/usb_rx.pio)
+ endfunction()
+
function(family_initialize_project PROJECT DIR)
# call the original version of this function from family_common.cmake
_family_initialize_project(${PROJECT} ${DIR})
diff --git a/hw/mcu/raspberry_pi/Pico-PIO-USB b/hw/mcu/raspberry_pi/Pico-PIO-USB
new file mode 160000
+Subproject 2a9fefd6ccf42e5d8570ae83fdc54c9c875ebdd
diff --git a/hw/mcu/sony/cxd56/tools/__pycache__/xmodem.cpython-36.pyc b/hw/mcu/sony/cxd56/tools/__pycache__/xmodem.cpython-36.pyc
deleted file mode 100644
index cfa917f71..000000000
--- a/hw/mcu/sony/cxd56/tools/__pycache__/xmodem.cpython-36.pyc
+++ /dev/null
Binary files differ
diff --git a/lib/Pico-PIO-USB b/lib/Pico-PIO-USB
new file mode 160000
+Subproject 53ec09168c5a3cd30d8dcb577fa97dc328d769d
diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c
index ce3d1598c..2573f5a6b 100644
--- a/src/class/hid/hid_host.c
+++ b/src/class/hid/hid_host.c
@@ -329,7 +329,7 @@ bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de
TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass);
- TU_LOG2("HID opening Interface %u (addr = %u)\r\n", desc_itf->bInterfaceNumber, dev_addr);
+ TU_LOG2("[%u] HID opening Interface %u\r\n", dev_addr, desc_itf->bInterfaceNumber);
// len = interface + hid + n*endpoints
uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t);
diff --git a/src/common/tusb_debug.h b/src/common/tusb_debug.h
index 647e8a8db..ac5bee6ec 100644
--- a/src/common/tusb_debug.h
+++ b/src/common/tusb_debug.h
@@ -57,7 +57,7 @@ void tu_print_mem(void const *buf, uint32_t count, uint8_t indent);
#define tu_printf printf
#endif
-static inline void tu_print_var(uint8_t const* buf, uint32_t bufsize)
+static inline void tu_print_arr(uint8_t const* buf, uint32_t bufsize)
{
for(uint32_t i=0; i<bufsize; i++) tu_printf("%02X ", buf[i]);
}
@@ -65,6 +65,7 @@ static inline void tu_print_var(uint8_t const* buf, uint32_t bufsize)
// Log with Level
#define TU_LOG(n, ...) TU_XSTRCAT(TU_LOG, n)(__VA_ARGS__)
#define TU_LOG_MEM(n, ...) TU_XSTRCAT3(TU_LOG, n, _MEM)(__VA_ARGS__)
+#define TU_LOG_ARR(n, ...) TU_XSTRCAT3(TU_LOG, n, _ARR)(__VA_ARGS__)
#define TU_LOG_VAR(n, ...) TU_XSTRCAT3(TU_LOG, n, _VAR)(__VA_ARGS__)
#define TU_LOG_INT(n, ...) TU_XSTRCAT3(TU_LOG, n, _INT)(__VA_ARGS__)
#define TU_LOG_HEX(n, ...) TU_XSTRCAT3(TU_LOG, n, _HEX)(__VA_ARGS__)
@@ -74,7 +75,8 @@ static inline void tu_print_var(uint8_t const* buf, uint32_t bufsize)
// Log Level 1: Error
#define TU_LOG1 tu_printf
#define TU_LOG1_MEM tu_print_mem
-#define TU_LOG1_VAR(_x) tu_print_var((uint8_t const*)(_x), sizeof(*(_x)))
+#define TU_LOG1_ARR(_x, _n) tu_print_arr((uint8_t const*)(_x), _n)
+#define TU_LOG1_VAR(_x) tu_print_arr((uint8_t const*)(_x), sizeof(*(_x)))
#define TU_LOG1_INT(_x) tu_printf(#_x " = %ld\r\n", (unsigned long) (_x) )
#define TU_LOG1_HEX(_x) tu_printf(#_x " = %lX\r\n", (unsigned long) (_x) )
@@ -82,6 +84,7 @@ static inline void tu_print_var(uint8_t const* buf, uint32_t bufsize)
#if CFG_TUSB_DEBUG >= 2
#define TU_LOG2 TU_LOG1
#define TU_LOG2_MEM TU_LOG1_MEM
+ #define TU_LOG2_ARR TU_LOG1_ARR
#define TU_LOG2_VAR TU_LOG1_VAR
#define TU_LOG2_INT TU_LOG1_INT
#define TU_LOG2_HEX TU_LOG1_HEX
@@ -91,6 +94,7 @@ static inline void tu_print_var(uint8_t const* buf, uint32_t bufsize)
#if CFG_TUSB_DEBUG >= 3
#define TU_LOG3 TU_LOG1
#define TU_LOG3_MEM TU_LOG1_MEM
+ #define TU_LOG3_ARR TU_LOG1_ARR
#define TU_LOG3_VAR TU_LOG1_VAR
#define TU_LOG3_INT TU_LOG1_INT
#define TU_LOG3_HEX TU_LOG1_HEX
diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h
index fb0cdd361..b11354032 100644
--- a/src/common/tusb_mcu.h
+++ b/src/common/tusb_mcu.h
@@ -228,6 +228,8 @@
#elif TU_CHECK_MCU(OPT_MCU_RP2040)
#define TUP_DCD_ENDPOINT_MAX 16
+ #define TU_ATTR_FAST_FUNC __attribute__((section(".time_critical.tinyusb")))
+
//------------- Silabs -------------//
#elif TU_CHECK_MCU(OPT_MCU_EFM32GG)
#define TUP_USBIP_DWC2
@@ -286,4 +288,9 @@
#define TUP_RHPORT_HIGHSPEED 0x00
#endif
+// fast function, normally mean placing function in SRAM
+#ifndef TU_ATTR_FAST_FUNC
+ #define TU_ATTR_FAST_FUNC
+#endif
+
#endif
diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h
index f4a08ce2f..568bac8cc 100644
--- a/src/common/tusb_verify.h
+++ b/src/common/tusb_verify.h
@@ -99,8 +99,8 @@
*------------------------------------------------------------------*/
// Helper to implement optional parameter for TU_VERIFY Macro family
-#define GET_3RD_ARG(arg1, arg2, arg3, ...) arg3
-#define GET_4TH_ARG(arg1, arg2, arg3, arg4, ...) arg4
+#define _GET_3RD_ARG(arg1, arg2, arg3, ...) arg3
+#define _GET_4TH_ARG(arg1, arg2, arg3, arg4, ...) arg4
/*------------- Generator for TU_VERIFY and TU_VERIFY_HDLR -------------*/
#define TU_VERIFY_DEFINE(_cond, _handler, _ret) do \
@@ -116,7 +116,7 @@
#define TU_VERIFY_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, , false)
#define TU_VERIFY_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, , _ret)
-#define TU_VERIFY(...) GET_3RD_ARG(__VA_ARGS__, TU_VERIFY_2ARGS, TU_VERIFY_1ARGS, UNUSED)(__VA_ARGS__)
+#define TU_VERIFY(...) _GET_3RD_ARG(__VA_ARGS__, TU_VERIFY_2ARGS, TU_VERIFY_1ARGS, UNUSED)(__VA_ARGS__)
/*------------------------------------------------------------------*/
@@ -127,7 +127,7 @@
#define TU_VERIFY_HDLR_2ARGS(_cond, _handler) TU_VERIFY_DEFINE(_cond, _handler, false)
#define TU_VERIFY_HDLR_3ARGS(_cond, _handler, _ret) TU_VERIFY_DEFINE(_cond, _handler, _ret)
-#define TU_VERIFY_HDLR(...) GET_4TH_ARG(__VA_ARGS__, TU_VERIFY_HDLR_3ARGS, TU_VERIFY_HDLR_2ARGS,UNUSED)(__VA_ARGS__)
+#define TU_VERIFY_HDLR(...) _GET_4TH_ARG(__VA_ARGS__, TU_VERIFY_HDLR_3ARGS, TU_VERIFY_HDLR_2ARGS,UNUSED)(__VA_ARGS__)
/*------------------------------------------------------------------*/
/* ASSERT
@@ -139,7 +139,7 @@
#define ASSERT_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, _MESS_FAILED(); TU_BREAKPOINT(), _ret)
#ifndef TU_ASSERT
-#define TU_ASSERT(...) GET_3RD_ARG(__VA_ARGS__, ASSERT_2ARGS, ASSERT_1ARGS,UNUSED)(__VA_ARGS__)
+#define TU_ASSERT(...) _GET_3RD_ARG(__VA_ARGS__, ASSERT_2ARGS, ASSERT_1ARGS,UNUSED)(__VA_ARGS__)
#endif
/*------------------------------------------------------------------*/
diff --git a/src/device/dcd.h b/src/device/dcd.h
index 8efbc90ef..bc68c9be6 100644
--- a/src/device/dcd.h
+++ b/src/device/dcd.h
@@ -174,16 +174,40 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr);
extern void dcd_event_handler(dcd_event_t const * event, bool in_isr);
// helper to send bus signal event
-extern void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr);
+TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr)
+{
+ dcd_event_t event = { .rhport = rhport, .event_id = eid };
+ dcd_event_handler(&event, in_isr);
+}
// helper to send bus reset event
-extern void dcd_event_bus_reset (uint8_t rhport, tusb_speed_t speed, bool in_isr);
+TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_reset (uint8_t rhport, tusb_speed_t speed, bool in_isr)
+{
+ dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_BUS_RESET };
+ event.bus_reset.speed = speed;
+ dcd_event_handler(&event, in_isr);
+}
// helper to send setup received
-extern void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr);
+TU_ATTR_ALWAYS_INLINE static inline void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr)
+{
+ dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SETUP_RECEIVED };
+ memcpy(&event.setup_received, setup, 8);
+
+ dcd_event_handler(&event, in_isr);
+}
// helper to send transfer complete event
-extern void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr);
+TU_ATTR_ALWAYS_INLINE static inline void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr)
+{
+ dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_XFER_COMPLETE };
+
+ event.xfer_complete.ep_addr = ep_addr;
+ event.xfer_complete.len = xferred_bytes;
+ event.xfer_complete.result = result;
+
+ dcd_event_handler(&event, in_isr);
+}
#ifdef __cplusplus
}
diff --git a/src/device/usbd.c b/src/device/usbd.c
index 7ab2660f4..1dd1a352e 100644
--- a/src/device/usbd.c
+++ b/src/device/usbd.c
@@ -466,8 +466,10 @@ bool tud_task_event_ready(void)
}
@endcode
*/
-void tud_task (void)
+void tud_task_ext(uint32_t timeout_ms, bool in_isr)
{
+ (void) in_isr; // not implemented yet
+
// Skip if stack is not initialized
if ( !tusb_inited() ) return;
@@ -475,8 +477,7 @@ void tud_task (void)
while (1)
{
dcd_event_t event;
-
- if ( !osal_queue_receive(_usbd_q, &event) ) return;
+ if ( !osal_queue_receive(_usbd_q, &event, timeout_ms) ) return;
#if CFG_TUSB_DEBUG >= 2
if (event.event_id == DCD_EVENT_SETUP_RECEIVED) TU_LOG2("\r\n"); // extra line for setup
@@ -593,6 +594,11 @@ void tud_task (void)
TU_BREAKPOINT();
break;
}
+
+#if CFG_TUSB_OS != OPT_OS_NONE && CFG_TUSB_OS != OPT_OS_PICO
+ // return if there is no more events, for application to run other background
+ if (osal_queue_empty(_usbd_q)) return;
+#endif
}
}
@@ -1065,7 +1071,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
//--------------------------------------------------------------------+
// DCD Event Handler
//--------------------------------------------------------------------+
-void dcd_event_handler(dcd_event_t const * event, bool in_isr)
+TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const * event, bool in_isr)
{
switch (event->event_id)
{
@@ -1115,38 +1121,6 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr)
}
}
-void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr)
-{
- dcd_event_t event = { .rhport = rhport, .event_id = eid };
- dcd_event_handler(&event, in_isr);
-}
-
-void dcd_event_bus_reset (uint8_t rhport, tusb_speed_t speed, bool in_isr)
-{
- dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_BUS_RESET };
- event.bus_reset.speed = speed;
- dcd_event_handler(&event, in_isr);
-}
-
-void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr)
-{
- dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SETUP_RECEIVED };
- memcpy(&event.setup_received, setup, 8);
-
- dcd_event_handler(&event, in_isr);
-}
-
-void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr)
-{
- dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_XFER_COMPLETE };
-
- event.xfer_complete.ep_addr = ep_addr;
- event.xfer_complete.len = xferred_bytes;
- event.xfer_complete.result = result;
-
- dcd_event_handler(&event, in_isr);
-}
-
//--------------------------------------------------------------------+
// USBD API For Class Driver
//--------------------------------------------------------------------+
diff --git a/src/device/usbd.h b/src/device/usbd.h
index b2bf8ba9d..964cfb992 100644
--- a/src/device/usbd.h
+++ b/src/device/usbd.h
@@ -43,10 +43,19 @@ bool tud_init (uint8_t rhport);
// Check if device stack is already initialized
bool tud_inited(void);
+// Task function should be called in main/rtos loop, extended version of tud_task()
+// - timeout_ms: millisecond to wait, zero = no wait, 0xFFFFFFFF = wait forever
+// - in_isr: if function is called in ISR
+void tud_task_ext(uint32_t timeout_ms, bool in_isr);
+
// Task function should be called in main/rtos loop
-void tud_task (void);
+TU_ATTR_ALWAYS_INLINE static inline
+void tud_task (void)
+{
+ tud_task_ext(UINT32_MAX, false);
+}
-// Check if there is pending events need proccessing by tud_task()
+// Check if there is pending events need processing by tud_task()
bool tud_task_event_ready(void);
// Interrupt handler, name alias to DCD
diff --git a/src/host/hcd.h b/src/host/hcd.h
index c40bea64c..036394c72 100644
--- a/src/host/hcd.h
+++ b/src/host/hcd.h
@@ -144,9 +144,16 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr);
// Endpoints API
//--------------------------------------------------------------------+
-bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]);
+// Open an endpoint
bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc);
+
+// Submit a transfer, when complete hcd_event_xfer_complete() must be invoked
bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen);
+
+// Submit a special transfer to send 8-byte Setup Packet, when complete hcd_event_xfer_complete() must be invoked
+bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]);
+
+// clear stall, data toggle is also reset to DATA0
bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr);
//--------------------------------------------------------------------+
@@ -164,13 +171,49 @@ extern void hcd_devtree_get_info(uint8_t dev_addr, hcd_devtree_info_t* devtree_i
extern void hcd_event_handler(hcd_event_t const* event, bool in_isr);
// Helper to send device attach event
-extern void hcd_event_device_attach(uint8_t rhport, bool in_isr);
+TU_ATTR_ALWAYS_INLINE static inline
+void hcd_event_device_attach(uint8_t rhport, bool in_isr)
+{
+ hcd_event_t event;
+ event.rhport = rhport;
+ event.event_id = HCD_EVENT_DEVICE_ATTACH;
+ event.connection.hub_addr = 0;
+ event.connection.hub_port = 0;
+ hcd_event_handler(&event, in_isr);
+}
// Helper to send device removal event
-extern void hcd_event_device_remove(uint8_t rhport, bool in_isr);
+TU_ATTR_ALWAYS_INLINE static inline
+void hcd_event_device_remove(uint8_t rhport, bool in_isr)
+{
+ hcd_event_t event;
+ event.rhport = rhport;
+ event.event_id = HCD_EVENT_DEVICE_REMOVE;
+ event.connection.hub_addr = 0;
+ event.connection.hub_port = 0;
+
+ hcd_event_handler(&event, in_isr);
+}
// Helper to send USB transfer event
-extern void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred_bytes, xfer_result_t result, bool in_isr);
+TU_ATTR_ALWAYS_INLINE static inline
+void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred_bytes, xfer_result_t result, bool in_isr)
+{
+ hcd_event_t event =
+ {
+ .rhport = 0, // TODO correct rhport
+ .event_id = HCD_EVENT_XFER_COMPLETE,
+ .dev_addr = dev_addr,
+ .xfer_complete =
+ {
+ .ep_addr = ep_addr,
+ .result = result,
+ .len = xferred_bytes
+ }
+ };
+
+ hcd_event_handler(&event, in_isr);
+}
#ifdef __cplusplus
}
diff --git a/src/host/usbh.c b/src/host/usbh.c
index f534070de..e0e41a8d1 100644
--- a/src/host/usbh.c
+++ b/src/host/usbh.c
@@ -392,8 +392,10 @@ bool tuh_init(uint8_t rhport)
}
@endcode
*/
-void tuh_task(void)
+void tuh_task_ext(uint32_t timeout_ms, bool in_isr)
{
+ (void) in_isr; // not implemented yet
+
// Skip if stack is not initialized
if ( !tusb_inited() ) return;
@@ -401,14 +403,14 @@ void tuh_task(void)
while (1)
{
hcd_event_t event;
- if ( !osal_queue_receive(_usbh_q, &event) ) return;
+ if ( !osal_queue_receive(_usbh_q, &event, timeout_ms) ) return;
switch (event.event_id)
{
case HCD_EVENT_DEVICE_ATTACH:
// TODO due to the shared _usbh_ctrl_buf, we must complete enumerating
// one device before enumerating another one.
- TU_LOG2("USBH DEVICE ATTACH\r\n");
+ TU_LOG2("[%u:] USBH DEVICE ATTACH\r\n", event.rhport);
enum_new_device(&event);
break;
@@ -497,6 +499,11 @@ void tuh_task(void)
default: break;
}
+
+#if CFG_TUSB_OS != OPT_OS_NONE && CFG_TUSB_OS != OPT_OS_PICO
+ // return if there is no more events, for application to run other background
+ if (osal_queue_empty(_usbh_q)) return;
+#endif
}
}
@@ -543,12 +550,12 @@ bool tuh_control_xfer (tuh_xfer_t* xfer)
const uint8_t rhport = usbh_get_rhport(daddr);
TU_LOG2("[%u:%u] %s: ", rhport, daddr, xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME ? tu_str_std_request[xfer->setup->bRequest] : "Unknown Request");
- TU_LOG2_VAR(&xfer->setup);
+ TU_LOG2_VAR(xfer->setup);
TU_LOG2("\r\n");
if (xfer->complete_cb)
{
- TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t*) &_ctrl_xfer.request) );
+ TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t const*) &_ctrl_xfer.request) );
}else
{
// blocking if complete callback is not provided
@@ -623,7 +630,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result
if (XFER_RESULT_SUCCESS != result)
{
- TU_LOG2("[%u:%u] Control %s\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED");
+ TU_LOG1("[%u:%u] Control %s\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED");
// terminate transfer if any stage failed
_xfer_complete(dev_addr, result);
@@ -636,12 +643,13 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result
{
// DATA stage: initial data toggle is always 1
_set_control_xfer_stage(CONTROL_STAGE_DATA);
- return hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength);
+ TU_ASSERT( hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength) );
+ return true;
}
__attribute__((fallthrough));
case CONTROL_STAGE_DATA:
- if (xferred_bytes)
+ if (request->wLength)
{
TU_LOG2("[%u:%u] Control data:\r\n", rhport, dev_addr);
TU_LOG2_MEM(_ctrl_xfer.buffer, xferred_bytes, 2);
@@ -651,7 +659,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result
// ACK stage: toggle is always 1
_set_control_xfer_stage(CONTROL_STAGE_ACK);
- hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, 1-request->bmRequestType_bit.direction), NULL, 0);
+ TU_ASSERT( hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, 1-request->bmRequestType_bit.direction), NULL, 0) );
break;
case CONTROL_STAGE_ACK:
@@ -791,7 +799,7 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b
static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size)
{
- TU_LOG2("Open EP0 with Size = %u (addr = %u)\r\n", max_packet_size, dev_addr);
+ TU_LOG2("[%u:%u] Open EP0 with Size = %u\r\n", usbh_get_rhport(dev_addr), dev_addr, max_packet_size);
tusb_desc_endpoint_t ep0_desc =
{
@@ -847,7 +855,7 @@ void hcd_devtree_get_info(uint8_t dev_addr, hcd_devtree_info_t* devtree_info)
}
}
-void hcd_event_handler(hcd_event_t const* event, bool in_isr)
+TU_ATTR_FAST_FUNC void hcd_event_handler(hcd_event_t const* event, bool in_isr)
{
switch (event->event_id)
{
@@ -857,52 +865,6 @@ void hcd_event_handler(hcd_event_t const* event, bool in_isr)
}
}
-void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred_bytes, xfer_result_t result, bool in_isr)
-{
- hcd_event_t event =
- {
- .rhport = 0, // TODO correct rhport
- .event_id = HCD_EVENT_XFER_COMPLETE,
- .dev_addr = dev_addr,
- .xfer_complete =
- {
- .ep_addr = ep_addr,
- .result = result,
- .len = xferred_bytes
- }
- };
-
- hcd_event_handler(&event, in_isr);
-}
-
-void hcd_event_device_attach(uint8_t rhport, bool in_isr)
-{
- hcd_event_t event =
- {
- .rhport = rhport,
- .event_id = HCD_EVENT_DEVICE_ATTACH
- };
-
- event.connection.hub_addr = 0;
- event.connection.hub_port = 0;
-
- hcd_event_handler(&event, in_isr);
-}
-
-void hcd_event_device_remove(uint8_t hostid, bool in_isr)
-{
- hcd_event_t event =
- {
- .rhport = hostid,
- .event_id = HCD_EVENT_DEVICE_REMOVE
- };
-
- event.connection.hub_addr = 0;
- event.connection.hub_port = 0;
-
- hcd_event_handler(&event, in_isr);
-}
-
//--------------------------------------------------------------------+
// Descriptors Async
//--------------------------------------------------------------------+
@@ -1177,7 +1139,7 @@ enum {
//ENUM_HUB_GET_STATUS_1,
ENUM_HUB_CLEAR_RESET_1,
ENUM_ADDR0_DEVICE_DESC,
- ENUM_RESET_2, // 2nd reset before set address
+ ENUM_RESET_2, // 2nd reset before set address (not used)
ENUM_HUB_GET_STATUS_2,
ENUM_HUB_CLEAR_RESET_2,
ENUM_SET_ADDR,
@@ -1265,15 +1227,17 @@ static void process_enumeration(tuh_xfer_t* xfer)
}
break;
+#if 0
case ENUM_RESET_2:
+ // XXX note used by now, but may be needed for some devices !?
// Reset device again before Set Address
- TU_LOG2("Port reset \r\n");
+ TU_LOG2("Port reset2 \r\n");
if (_dev0.hub_addr == 0)
{
// connected directly to roothub
hcd_port_reset( _dev0.rhport );
osal_task_delay(RESET_DELAY);
-
+ hcd_port_reset_end(_dev0.rhport);
// TODO: fall through to SET ADDRESS, refactor later
}
#if CFG_TUH_HUB
@@ -1285,6 +1249,7 @@ static void process_enumeration(tuh_xfer_t* xfer)
}
#endif
__attribute__((fallthrough));
+#endif
case ENUM_SET_ADDR:
enum_request_set_addr();
@@ -1298,7 +1263,7 @@ static void process_enumeration(tuh_xfer_t* xfer)
TU_ASSERT(new_dev, );
new_dev->addressed = 1;
- // TODO close device 0, may not be needed
+ // Close device 0
hcd_device_close(_dev0.rhport, 0);
// open control pipe for new address
@@ -1389,7 +1354,9 @@ static bool enum_new_device(hcd_event_t* event)
{
// connected/disconnected directly with roothub
// wait until device is stable TODO non blocking
+ hcd_port_reset(_dev0.rhport);
osal_task_delay(RESET_DELAY);
+ hcd_port_reset_end( _dev0.rhport);
// device unplugged while delaying
if ( !hcd_port_connect_status(_dev0.rhport) ) return true;
diff --git a/src/host/usbh.h b/src/host/usbh.h
index e883ac90b..c6d36fb7f 100644
--- a/src/host/usbh.h
+++ b/src/host/usbh.h
@@ -91,8 +91,17 @@ bool tuh_init(uint8_t rhport);
// Check if host stack is already initialized
bool tuh_inited(void);
+// Task function should be called in main/rtos loop, extended version of tuh_task()
+// - timeout_ms: millisecond to wait, zero = no wait, 0xFFFFFFFF = wait forever
+// - in_isr: if function is called in ISR
+void tuh_task_ext(uint32_t timeout_ms, bool in_isr);
+
// Task function should be called in main/rtos loop
-void tuh_task(void);
+TU_ATTR_ALWAYS_INLINE static inline
+void tuh_task(void)
+{
+ tuh_task_ext(UINT32_MAX, false);
+}
// Interrupt handler, name alias to HCD
extern void hcd_int_handler(uint8_t rhport);
@@ -106,8 +115,8 @@ tusb_speed_t tuh_speed_get(uint8_t daddr);
bool tuh_mounted(uint8_t daddr);
// Check if device is suspended
-TU_ATTR_ALWAYS_INLINE
-static inline bool tuh_suspended(uint8_t daddr)
+TU_ATTR_ALWAYS_INLINE static inline
+bool tuh_suspended(uint8_t daddr)
{
// TODO implement suspend & resume on host
(void) daddr;
@@ -115,8 +124,8 @@ static inline bool tuh_suspended(uint8_t daddr)
}
// Check if device is ready to communicate with
-TU_ATTR_ALWAYS_INLINE
-static inline bool tuh_ready(uint8_t daddr)
+TU_ATTR_ALWAYS_INLINE static inline
+bool tuh_ready(uint8_t daddr)
{
return tuh_mounted(daddr) && !tuh_suspended(daddr);
}
diff --git a/src/osal/osal.h b/src/osal/osal.h
index 7111bbdb2..9d11866df 100644
--- a/src/osal/osal.h
+++ b/src/osal/osal.h
@@ -66,19 +66,19 @@ typedef void (*osal_task_func_t)( void * );
// OSAL Porting API
// Should be implemented as static inline function in osal_port.h header
/*
- static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef);
- static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr);
- static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec);
- static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl); // TODO removed
+ osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef);
+ bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr);
+ bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec);
+ void osal_semaphore_reset(osal_semaphore_t sem_hdl); // TODO removed
- static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef);
- static inline bool osal_mutex_lock (osal_mutex_t sem_hdl, uint32_t msec);
- static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl);
+ osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef);
+ bool osal_mutex_lock (osal_mutex_t sem_hdl, uint32_t msec);
+ bool osal_mutex_unlock(osal_mutex_t mutex_hdl);
- static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef);
- static inline bool osal_queue_receive(osal_queue_t qhdl, void* data);
- static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr);
- static inline bool osal_queue_empty(osal_queue_t qhdl);
+ osal_queue_t osal_queue_create(osal_queue_def_t* qdef);
+ bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec);
+ bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr);
+ bool osal_queue_empty(osal_queue_t qhdl);
*/
//--------------------------------------------------------------------+
diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h
index 69a026df5..52db336f5 100644
--- a/src/osal/osal_freertos.h
+++ b/src/osal/osal_freertos.h
@@ -37,10 +37,24 @@
extern "C" {
#endif
+TU_ATTR_ALWAYS_INLINE static inline uint32_t _osal_ms2tick(uint32_t msec)
+{
+ if (msec == OSAL_TIMEOUT_WAIT_FOREVER) return portMAX_DELAY;
+ if (msec == 0) return 0;
+
+ uint32_t ticks = pdMS_TO_TICKS(msec);
+
+ // configTICK_RATE_HZ is less than 1000 and 1 tick > 1 ms
+ // we still need to delay at least 1 tick
+ if (ticks == 0) ticks =1 ;
+
+ return ticks;
+}
+
//--------------------------------------------------------------------+
// TASK API
//--------------------------------------------------------------------+
-static inline void osal_task_delay(uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec)
{
vTaskDelay( pdMS_TO_TICKS(msec) );
}
@@ -51,12 +65,12 @@ static inline void osal_task_delay(uint32_t msec)
typedef StaticSemaphore_t osal_semaphore_def_t;
typedef SemaphoreHandle_t osal_semaphore_t;
-static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef)
{
return xSemaphoreCreateBinaryStatic(semdef);
}
-static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
{
if ( !in_isr )
{
@@ -78,13 +92,12 @@ static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
}
}
-static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec)
{
- uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec);
- return xSemaphoreTake(sem_hdl, ticks);
+ return xSemaphoreTake(sem_hdl, _osal_ms2tick(msec));
}
-static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl)
+TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl)
{
xQueueReset(sem_hdl);
}
@@ -95,17 +108,17 @@ static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl)
typedef StaticSemaphore_t osal_mutex_def_t;
typedef SemaphoreHandle_t osal_mutex_t;
-static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
{
return xSemaphoreCreateMutexStatic(mdef);
}
-static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec)
{
return osal_semaphore_wait(mutex_hdl, msec);
}
-static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
{
return xSemaphoreGive(mutex_hdl);
}
@@ -114,7 +127,7 @@ static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
// QUEUE API
//--------------------------------------------------------------------+
-// role device/host is used by OS NONE for mutex (disable usb isr) only
+// _int_set is not used with an RTOS
#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \
static _type _name##_##buf[_depth];\
osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf };
@@ -130,17 +143,17 @@ typedef struct
typedef QueueHandle_t osal_queue_t;
-static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
{
return xQueueCreateStatic(qdef->depth, qdef->item_sz, (uint8_t*) qdef->buf, &qdef->sq);
}
-static inline bool osal_queue_receive(osal_queue_t qhdl, void* data)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec)
{
- return xQueueReceive(qhdl, data, portMAX_DELAY);
+ return xQueueReceive(qhdl, data, _osal_ms2tick(msec));
}
-static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr)
{
if ( !in_isr )
{
@@ -162,7 +175,7 @@ static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in
}
}
-static inline bool osal_queue_empty(osal_queue_t qhdl)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl)
{
return uxQueueMessagesWaiting(qhdl) == 0;
}
diff --git a/src/osal/osal_mynewt.h b/src/osal/osal_mynewt.h
index 78a257cd6..b8ea2087c 100644
--- a/src/osal/osal_mynewt.h
+++ b/src/osal/osal_mynewt.h
@@ -36,7 +36,7 @@
//--------------------------------------------------------------------+
// TASK API
//--------------------------------------------------------------------+
-static inline void osal_task_delay(uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec)
{
os_time_delay( os_time_ms_to_ticks32(msec) );
}
@@ -47,18 +47,18 @@ static inline void osal_task_delay(uint32_t msec)
typedef struct os_sem osal_semaphore_def_t;
typedef struct os_sem* osal_semaphore_t;
-static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef)
{
return (os_sem_init(semdef, 0) == OS_OK) ? (osal_semaphore_t) semdef : NULL;
}
-static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
{
(void) in_isr;
return os_sem_release(sem_hdl) == OS_OK;
}
-static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec)
{
uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? OS_TIMEOUT_NEVER : os_time_ms_to_ticks32(msec);
return os_sem_pend(sem_hdl, ticks) == OS_OK;
@@ -75,18 +75,18 @@ static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl)
typedef struct os_mutex osal_mutex_def_t;
typedef struct os_mutex* osal_mutex_t;
-static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
{
return (os_mutex_init(mdef) == OS_OK) ? (osal_mutex_t) mdef : NULL;
}
-static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec)
{
uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? OS_TIMEOUT_NEVER : os_time_ms_to_ticks32(msec);
return os_mutex_pend(mutex_hdl, ticks) == OS_OK;
}
-static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
{
return os_mutex_release(mutex_hdl) == OS_OK;
}
@@ -116,7 +116,7 @@ typedef struct
typedef osal_queue_def_t* osal_queue_t;
-static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
{
if ( OS_OK != os_mempool_init(&qdef->mpool, qdef->depth, qdef->item_sz, qdef->buf, "usbd queue") ) return NULL;
if ( OS_OK != os_mempool_init(&qdef->epool, qdef->depth, sizeof(struct os_event), qdef->evbuf, "usbd evqueue") ) return NULL;
@@ -125,8 +125,10 @@ static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
return (osal_queue_t) qdef;
}
-static inline bool osal_queue_receive(osal_queue_t qhdl, void* data)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec)
{
+ (void) msec; // os_eventq_get() does not take timeout, always behave as msec = WAIT_FOREVER
+
struct os_event* ev;
ev = os_eventq_get(&qhdl->evq);
@@ -161,7 +163,7 @@ static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in
return true;
}
-static inline bool osal_queue_empty(osal_queue_t qhdl)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl)
{
return STAILQ_EMPTY(&qhdl->evq.evq_list);
}
diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h
index 4217f0422..9c80e4548 100644
--- a/src/osal/osal_none.h
+++ b/src/osal/osal_none.h
@@ -46,13 +46,13 @@ typedef struct
typedef osal_semaphore_def_t* osal_semaphore_t;
-static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef)
{
semdef->count = 0;
return semdef;
}
-static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
{
(void) in_isr;
sem_hdl->count++;
@@ -60,7 +60,7 @@ static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
}
// TODO blocking for now
-static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec)
{
(void) msec;
@@ -70,7 +70,7 @@ static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec)
return true;
}
-static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl)
+TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl)
{
sem_hdl->count = 0;
}
@@ -82,18 +82,18 @@ static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl)
typedef osal_semaphore_def_t osal_mutex_def_t;
typedef osal_semaphore_t osal_mutex_t;
-static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
{
mdef->count = 1;
return mdef;
}
-static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec)
{
return osal_semaphore_wait(mutex_hdl, msec);
}
-static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
{
return osal_semaphore_post(mutex_hdl, false);
}
@@ -120,27 +120,29 @@ typedef osal_queue_def_t* osal_queue_t;
}
// lock queue by disable USB interrupt
-static inline void _osal_q_lock(osal_queue_t qhdl)
+TU_ATTR_ALWAYS_INLINE static inline void _osal_q_lock(osal_queue_t qhdl)
{
// disable dcd/hcd interrupt
qhdl->interrupt_set(false);
}
// unlock queue
-static inline void _osal_q_unlock(osal_queue_t qhdl)
+TU_ATTR_ALWAYS_INLINE static inline void _osal_q_unlock(osal_queue_t qhdl)
{
// enable dcd/hcd interrupt
qhdl->interrupt_set(true);
}
-static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
{
tu_fifo_clear(&qdef->ff);
return (osal_queue_t) qdef;
}
-static inline bool osal_queue_receive(osal_queue_t qhdl, void* data)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec)
{
+ (void) msec; // not used, always behave as msec = 0
+
_osal_q_lock(qhdl);
bool success = tu_fifo_read(&qhdl->ff, data);
_osal_q_unlock(qhdl);
@@ -148,7 +150,7 @@ static inline bool osal_queue_receive(osal_queue_t qhdl, void* data)
return success;
}
-static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr)
{
if (!in_isr) {
_osal_q_lock(qhdl);
@@ -165,7 +167,7 @@ static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in
return success;
}
-static inline bool osal_queue_empty(osal_queue_t qhdl)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl)
{
// Skip queue lock/unlock since this function is primarily called
// with interrupt disabled before going into low power mode
diff --git a/src/osal/osal_pico.h b/src/osal/osal_pico.h
index 70432d22b..abef286b4 100644
--- a/src/osal/osal_pico.h
+++ b/src/osal/osal_pico.h
@@ -39,7 +39,7 @@
//--------------------------------------------------------------------+
// TASK API
//--------------------------------------------------------------------+
-static inline void osal_task_delay(uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec)
{
sleep_ms(msec);
}
@@ -49,25 +49,25 @@ static inline void osal_task_delay(uint32_t msec)
//--------------------------------------------------------------------+
typedef struct semaphore osal_semaphore_def_t, *osal_semaphore_t;
-static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef)
{
sem_init(semdef, 0, 255);
return semdef;
}
-static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
{
(void) in_isr;
sem_release(sem_hdl);
return true;
}
-static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec)
{
return sem_acquire_timeout_ms(sem_hdl, msec);
}
-static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl)
+TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl)
{
sem_reset(sem_hdl, 0);
}
@@ -78,21 +78,21 @@ static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl)
//--------------------------------------------------------------------+
typedef struct mutex osal_mutex_def_t, *osal_mutex_t;
-static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
{
- mutex_init(mdef);
- return mdef;
+ mutex_init(mdef);
+ return mdef;
}
-static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec)
{
- return mutex_enter_timeout_ms(mutex_hdl, msec);
+ return mutex_enter_timeout_ms(mutex_hdl, msec);
}
-static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
{
- mutex_exit(mutex_hdl);
- return true;
+ mutex_exit(mutex_hdl);
+ return true;
}
//--------------------------------------------------------------------+
@@ -121,26 +121,28 @@ typedef osal_queue_def_t* osal_queue_t;
}
// lock queue by disable USB interrupt
-static inline void _osal_q_lock(osal_queue_t qhdl)
+TU_ATTR_ALWAYS_INLINE static inline void _osal_q_lock(osal_queue_t qhdl)
{
- critical_section_enter_blocking(&qhdl->critsec);
+ critical_section_enter_blocking(&qhdl->critsec);
}
// unlock queue
-static inline void _osal_q_unlock(osal_queue_t qhdl)
+TU_ATTR_ALWAYS_INLINE static inline void _osal_q_unlock(osal_queue_t qhdl)
{
- critical_section_exit(&qhdl->critsec);
+ critical_section_exit(&qhdl->critsec);
}
-static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
{
critical_section_init(&qdef->critsec);
tu_fifo_clear(&qdef->ff);
return (osal_queue_t) qdef;
}
-static inline bool osal_queue_receive(osal_queue_t qhdl, void* data)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec)
{
+ (void) msec; // not used, always behave as msec = 0
+
// TODO: revisit... docs say that mutexes are never used from IRQ context,
// however osal_queue_recieve may be. therefore my assumption is that
// the fifo mutex is not populated for queues used from an IRQ context
@@ -153,7 +155,7 @@ static inline bool osal_queue_receive(osal_queue_t qhdl, void* data)
return success;
}
-static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr)
{
// TODO: revisit... docs say that mutexes are never used from IRQ context,
// however osal_queue_recieve may be. therefore my assumption is that
@@ -170,7 +172,7 @@ static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in
return success;
}
-static inline bool osal_queue_empty(osal_queue_t qhdl)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl)
{
// TODO: revisit; whether this is true or not currently, tu_fifo_empty is a single
// volatile read.
diff --git a/src/osal/osal_rtthread.h b/src/osal/osal_rtthread.h
index 0845175b8..a790a5e27 100644
--- a/src/osal/osal_rtthread.h
+++ b/src/osal/osal_rtthread.h
@@ -37,7 +37,7 @@ extern "C" {
//--------------------------------------------------------------------+
// TASK API
//--------------------------------------------------------------------+
-static inline void osal_task_delay(uint32_t msec) {
+TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) {
rt_thread_mdelay(msec);
}
@@ -47,22 +47,22 @@ static inline void osal_task_delay(uint32_t msec) {
typedef struct rt_semaphore osal_semaphore_def_t;
typedef rt_sem_t osal_semaphore_t;
-static inline osal_semaphore_t
+TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t
osal_semaphore_create(osal_semaphore_def_t *semdef) {
rt_sem_init(semdef, "tusb", 0, RT_IPC_FLAG_FIFO);
return semdef;
}
-static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) {
+TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) {
(void) in_isr;
return rt_sem_release(sem_hdl) == RT_EOK;
}
-static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) {
+TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) {
return rt_sem_take(sem_hdl, rt_tick_from_millisecond(msec)) == RT_EOK;
}
-static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) {
+TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) {
// TODO: implement
}
@@ -72,16 +72,16 @@ static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) {
typedef struct rt_mutex osal_mutex_def_t;
typedef rt_mutex_t osal_mutex_t;
-static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t *mdef) {
+TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t *mdef) {
rt_mutex_init(mdef, "tusb", RT_IPC_FLAG_FIFO);
return mdef;
}
-static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) {
+TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) {
return rt_mutex_take(mutex_hdl, rt_tick_from_millisecond(msec)) == RT_EOK;
}
-static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) {
+TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) {
return rt_mutex_release(mutex_hdl) == RT_EOK;
}
@@ -104,22 +104,24 @@ typedef struct {
typedef rt_mq_t osal_queue_t;
-static inline osal_queue_t osal_queue_create(osal_queue_def_t *qdef) {
+TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t *qdef) {
rt_mq_init(&(qdef->sq), "tusb", qdef->buf, qdef->item_sz,
qdef->item_sz * qdef->depth, RT_IPC_FLAG_FIFO);
return &(qdef->sq);
}
-static inline bool osal_queue_receive(osal_queue_t qhdl, void *data) {
- return rt_mq_recv(qhdl, data, qhdl->msg_size, RT_WAITING_FOREVER) == RT_EOK;
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void *data, uint32_t msec) {
+
+ rt_tick_t tick = rt_tick_from_millisecond((rt_int32_t) msec));
+ return rt_mq_recv(qhdl, data, qhdl->msg_size, tick) == RT_EOK;
}
-static inline bool osal_queue_send(osal_queue_t qhdl, void const *data, bool in_isr) {
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const *data, bool in_isr) {
(void) in_isr;
return rt_mq_send(qhdl, (void *)data, qhdl->msg_size) == RT_EOK;
}
-static inline bool osal_queue_empty(osal_queue_t qhdl) {
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) {
return (qhdl->entry) == 0;
}
diff --git a/src/osal/osal_rtx4.h b/src/osal/osal_rtx4.h
index 1856a5d9a..dea1c12c8 100644
--- a/src/osal/osal_rtx4.h
+++ b/src/osal/osal_rtx4.h
@@ -37,7 +37,7 @@ extern "C" {
//--------------------------------------------------------------------+
// TASK API
//--------------------------------------------------------------------+
-static inline void osal_task_delay(uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec)
{
uint16_t hi = msec >> 16;
uint16_t lo = msec;
@@ -47,7 +47,7 @@ static inline void osal_task_delay(uint32_t msec)
os_dly_wait(lo);
}
-static inline uint16_t msec2wait(uint32_t msec) {
+TU_ATTR_ALWAYS_INLINE static inline uint16_t msec2wait(uint32_t msec) {
if (msec == OSAL_TIMEOUT_WAIT_FOREVER)
return 0xFFFF;
else if (msec >= 0xFFFE)
@@ -62,12 +62,12 @@ static inline uint16_t msec2wait(uint32_t msec) {
typedef OS_SEM osal_semaphore_def_t;
typedef OS_ID osal_semaphore_t;
-static inline OS_ID osal_semaphore_create(osal_semaphore_def_t* semdef) {
+TU_ATTR_ALWAYS_INLINE static inline OS_ID osal_semaphore_create(osal_semaphore_def_t* semdef) {
os_sem_init(semdef, 0);
return semdef;
}
-static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) {
+TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) {
if ( !in_isr ) {
os_sem_send(sem_hdl);
} else {
@@ -76,11 +76,11 @@ static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) {
return true;
}
-static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) {
+TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) {
return os_sem_wait(sem_hdl, msec2wait(msec)) != OS_R_TMO;
}
-static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) {
+TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) {
// TODO: implement
}
@@ -90,18 +90,18 @@ static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) {
typedef OS_MUT osal_mutex_def_t;
typedef OS_ID osal_mutex_t;
-static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
{
os_mut_init(mdef);
return mdef;
}
-static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec)
{
return os_mut_wait(mutex_hdl, msec2wait(msec)) != OS_R_TMO;
}
-static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
{
return os_mut_release(mutex_hdl) == OS_R_OK;
}
@@ -127,23 +127,23 @@ typedef struct
typedef osal_queue_def_t* osal_queue_t;
-static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
{
os_mbx_init(qdef->mbox, (qdef->depth + 4) * 4);
_init_box(qdef->pool, ((qdef->item_sz+3)/4)*(qdef->depth) + 3, qdef->item_sz);
return qdef;
}
-static inline bool osal_queue_receive(osal_queue_t qhdl, void* data)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec)
{
void* buf;
- os_mbx_wait(qhdl->mbox, &buf, 0xFFFF);
+ os_mbx_wait(qhdl->mbox, &buf, msec2wait(msec));
memcpy(data, buf, qhdl->item_sz);
_free_box(qhdl->pool, buf);
return true;
}
-static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr)
{
void* buf = _alloc_box(qhdl->pool);
memcpy(buf, data, qhdl->item_sz);
@@ -158,7 +158,7 @@ static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in
return true;
}
-static inline bool osal_queue_empty(osal_queue_t qhdl)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl)
{
return os_mbx_check(qhdl->mbox) == qhdl->depth;
}
diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c
index 665f2380b..76ba2a921 100644
--- a/src/portable/ehci/ehci.c
+++ b/src/portable/ehci/ehci.c
@@ -163,15 +163,15 @@ void hcd_port_reset(uint8_t rhport)
regs->portsc = portsc;
}
-#if 0
void hcd_port_reset_end(uint8_t rhport)
{
(void) rhport;
+#if 0
ehci_registers_t* regs = ehci_data.regs;
regs->portsc_bm.port_reset = 0;
-}
#endif
+}
bool hcd_port_connect_status(uint8_t rhport)
{
diff --git a/src/portable/mentor/musb/hcd_musb.c b/src/portable/mentor/musb/hcd_musb.c
index 3bfd65b45..85e18e3aa 100644
--- a/src/portable/mentor/musb/hcd_musb.c
+++ b/src/portable/mentor/musb/hcd_musb.c
@@ -617,6 +617,11 @@ void hcd_port_reset(uint8_t rhport)
_hcd.need_reset = false;
}
+void hcd_port_reset_end(uint8_t rhport)
+{
+ (void) rhport;
+}
+
tusb_speed_t hcd_port_speed_get(uint8_t rhport)
{
(void)rhport;
diff --git a/src/portable/ohci/ohci.c b/src/portable/ohci/ohci.c
index e09382241..3e523ebc2 100644
--- a/src/portable/ohci/ohci.c
+++ b/src/portable/ohci/ohci.c
@@ -216,6 +216,11 @@ void hcd_port_reset(uint8_t hostid)
OHCI_REG->rhport_status[0] = RHPORT_PORT_RESET_STATUS_MASK;
}
+void hcd_port_reset_end(uint8_t rhport)
+{
+ (void) rhport;
+}
+
bool hcd_port_connect_status(uint8_t hostid)
{
(void) hostid;
diff --git a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c
new file mode 100644
index 000000000..1bc5594d8
--- /dev/null
+++ b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c
@@ -0,0 +1,210 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018, hathach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#include "tusb_option.h"
+
+#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && CFG_TUD_RPI_PIO_USB
+
+#include "pico.h"
+#include "pio_usb.h"
+#include "pio_usb_ll.h"
+
+#include "device/dcd.h"
+
+//--------------------------------------------------------------------+
+// MACRO TYPEDEF CONSTANT ENUM DECLARATION
+//--------------------------------------------------------------------+
+
+#define RHPORT_OFFSET 1
+#define RHPORT_PIO(_x) ((_x)-RHPORT_OFFSET)
+
+//------------- -------------//
+static usb_device_t *usb_device = NULL;
+static usb_descriptor_buffers_t desc;
+
+/*------------------------------------------------------------------*/
+/* Device API
+ *------------------------------------------------------------------*/
+
+// Initialize controller to device mode
+void dcd_init (uint8_t rhport)
+{
+ (void) rhport;
+
+ static pio_usb_configuration_t config = PIO_USB_DEFAULT_CONFIG;
+ usb_device = pio_usb_device_init(&config, &desc);
+}
+
+// Enable device interrupt
+void dcd_int_enable (uint8_t rhport)
+{
+ (void) rhport;
+}
+
+// Disable device interrupt
+void dcd_int_disable (uint8_t rhport)
+{
+ (void) rhport;
+}
+
+// Receive Set Address request, mcu port must also include status IN response
+void dcd_set_address (uint8_t rhport, uint8_t dev_addr)
+{
+ // must be called before queuing status
+ pio_usb_device_set_address(dev_addr);
+ dcd_edpt_xfer(rhport, 0x80, NULL, 0);
+}
+
+// Wake up host
+void dcd_remote_wakeup (uint8_t rhport)
+{
+ (void) rhport;
+}
+
+// Connect by enabling internal pull-up resistor on D+/D-
+void dcd_connect(uint8_t rhport)
+{
+ (void) rhport;
+}
+
+// Disconnect by disabling internal pull-up resistor on D+/D-
+void dcd_disconnect(uint8_t rhport)
+{
+ (void) rhport;
+}
+
+//--------------------------------------------------------------------+
+// Endpoint API
+//--------------------------------------------------------------------+
+
+// Configure endpoint's registers according to descriptor
+bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_ep)
+{
+ (void) rhport;
+ return pio_usb_device_endpoint_open((uint8_t const*) desc_ep);
+}
+
+void dcd_edpt_close_all (uint8_t rhport)
+{
+ (void) rhport;
+}
+
+// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack
+bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)
+{
+ (void) rhport;
+ endpoint_t *ep = pio_usb_device_get_endpoint_by_address(ep_addr);
+ return pio_usb_ll_transfer_start(ep, buffer, total_bytes);
+}
+
+// Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c
+//bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes)
+//{
+// (void) rhport;
+// (void) ep_addr;
+// (void) ff;
+// (void) total_bytes;
+// return false;
+//}
+
+// Stall endpoint
+void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
+{
+ (void) rhport;
+ endpoint_t *ep = pio_usb_device_get_endpoint_by_address(ep_addr);
+ ep->has_transfer = false;
+ ep->stalled = true;
+}
+
+// clear stall, data toggle is also reset to DATA0
+void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr)
+{
+ (void) rhport;
+ endpoint_t *ep = pio_usb_device_get_endpoint_by_address(ep_addr);
+ ep->data_id = 0;
+ ep->stalled = false;
+}
+
+//--------------------------------------------------------------------+
+//
+//--------------------------------------------------------------------+
+
+static void __no_inline_not_in_flash_func(handle_endpoint_irq)(uint8_t tu_rhport, xfer_result_t result, volatile uint32_t* ep_reg)
+{
+ const uint32_t ep_all = *ep_reg;
+
+ for(uint8_t ep_idx = 0; ep_idx < PIO_USB_EP_POOL_CNT; ep_idx++)
+ {
+ uint32_t const mask = (1u << ep_idx);
+
+ if (ep_all & mask)
+ {
+ endpoint_t* ep = PIO_USB_ENDPOINT(ep_idx);
+ dcd_event_xfer_complete(tu_rhport, ep->ep_num, ep->actual_len, result, true);
+ }
+ }
+
+ // clear all
+ (*ep_reg) &= ~ep_all;
+}
+
+// IRQ Handler
+void __no_inline_not_in_flash_func(pio_usb_device_irq_handler)(uint8_t root_id)
+{
+ uint8_t const tu_rhport = root_id + 1;
+ root_port_t* rport = PIO_USB_ROOT_PORT(root_id);
+ uint32_t const ints = rport->ints;
+
+ if (ints & PIO_USB_INTS_RESET_END_BITS)
+ {
+ dcd_event_bus_reset(tu_rhport, TUSB_SPEED_FULL, true);
+ }
+
+ if (ints & PIO_USB_INTS_SETUP_REQ_BITS)
+ {
+ dcd_event_setup_received(tu_rhport, rport->setup_packet, true);
+ }
+
+ if ( ints & PIO_USB_INTS_ENDPOINT_COMPLETE_BITS )
+ {
+ handle_endpoint_irq(tu_rhport, XFER_RESULT_SUCCESS, &rport->ep_complete);
+ }
+
+ if ( ints & PIO_USB_INTS_ENDPOINT_STALLED_BITS )
+ {
+ handle_endpoint_irq(tu_rhport, XFER_RESULT_STALLED, &rport->ep_stalled);
+ }
+
+ if ( ints & PIO_USB_INTS_ENDPOINT_ERROR_BITS )
+ {
+ handle_endpoint_irq(tu_rhport, XFER_RESULT_FAILED, &rport->ep_error);
+ }
+
+ // clear all
+ rport->ints &= ~ints;
+}
+
+#endif
diff --git a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c
new file mode 100644
index 000000000..1b2d29331
--- /dev/null
+++ b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c
@@ -0,0 +1,217 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2021 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#include "tusb_option.h"
+
+#if CFG_TUH_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && CFG_TUH_RPI_PIO_USB
+
+#include "pico.h"
+#include "pio_usb.h"
+#include "pio_usb_ll.h"
+
+//--------------------------------------------------------------------+
+// INCLUDE
+//--------------------------------------------------------------------+
+#include "osal/osal.h"
+
+#include "host/hcd.h"
+#include "host/usbh.h"
+
+#define RHPORT_OFFSET 1
+#define RHPORT_PIO(_x) ((_x)-RHPORT_OFFSET)
+
+static pio_usb_configuration_t pio_host_config = PIO_USB_DEFAULT_CONFIG;
+
+//--------------------------------------------------------------------+
+// HCD API
+//--------------------------------------------------------------------+
+bool hcd_init(uint8_t rhport)
+{
+ (void) rhport;
+
+ // To run USB SOF interrupt in core1, call this init in core1
+ pio_usb_host_init(&pio_host_config);
+
+ return true;
+}
+
+void hcd_port_reset(uint8_t rhport)
+{
+ uint8_t const pio_rhport = RHPORT_PIO(rhport);
+ pio_usb_host_port_reset_start(pio_rhport);
+}
+
+void hcd_port_reset_end(uint8_t rhport)
+{
+ uint8_t const pio_rhport = RHPORT_PIO(rhport);
+ pio_usb_host_port_reset_end(pio_rhport);
+}
+
+bool hcd_port_connect_status(uint8_t rhport)
+{
+ uint8_t const pio_rhport = RHPORT_PIO(rhport);
+
+ root_port_t *root = PIO_USB_ROOT_PORT(pio_rhport);
+ port_pin_status_t line_state = pio_usb_bus_get_line_state(root);
+
+ return line_state != PORT_PIN_SE0;
+}
+
+tusb_speed_t hcd_port_speed_get(uint8_t rhport)
+{
+ // TODO determine link speed
+ uint8_t const pio_rhport = RHPORT_PIO(rhport);
+ return PIO_USB_ROOT_PORT(pio_rhport)->is_fullspeed ? TUSB_SPEED_FULL : TUSB_SPEED_LOW;
+}
+
+// Close all opened endpoint belong to this device
+void hcd_device_close(uint8_t rhport, uint8_t dev_addr)
+{
+ uint8_t const pio_rhport = RHPORT_PIO(rhport);
+ pio_usb_host_close_device(pio_rhport, dev_addr);
+}
+
+uint32_t hcd_frame_number(uint8_t rhport)
+{
+ (void) rhport;
+ return 0;
+}
+
+void hcd_int_enable(uint8_t rhport)
+{
+ (void) rhport;
+}
+
+void hcd_int_disable(uint8_t rhport)
+{
+ (void) rhport;
+}
+
+//--------------------------------------------------------------------+
+// Endpoint API
+//--------------------------------------------------------------------+
+
+bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep)
+{
+ hcd_devtree_info_t dev_tree;
+ hcd_devtree_get_info(dev_addr, &dev_tree);
+ bool const need_pre = (dev_tree.hub_addr && dev_tree.speed == TUSB_SPEED_LOW);
+
+ uint8_t const pio_rhport = RHPORT_PIO(rhport);
+ return pio_usb_host_endpoint_open(pio_rhport, dev_addr, (uint8_t const*) desc_ep, need_pre);
+}
+
+bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen)
+{
+ uint8_t const pio_rhport = RHPORT_PIO(rhport);
+ return pio_usb_host_endpoint_transfer(pio_rhport, dev_addr, ep_addr, buffer, buflen);
+}
+
+bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8])
+{
+ uint8_t const pio_rhport = RHPORT_PIO(rhport);
+ return pio_usb_host_send_setup(pio_rhport, dev_addr, setup_packet);
+}
+
+//bool hcd_edpt_busy(uint8_t dev_addr, uint8_t ep_addr)
+//{
+// // EPX is shared, so multiple device addresses and endpoint addresses share that
+// // so if any transfer is active on epx, we are busy. Interrupt endpoints have their own
+// // EPX so ep->active will only be busy if there is a pending transfer on that interrupt endpoint
+// // on that device
+// pico_trace("hcd_edpt_busy dev addr %d ep_addr 0x%x\n", dev_addr, ep_addr);
+// struct hw_endpoint *ep = get_dev_ep(dev_addr, ep_addr);
+// assert(ep);
+// bool busy = ep->active;
+// pico_trace("busy == %d\n", busy);
+// return busy;
+//}
+
+bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr)
+{
+ (void) dev_addr;
+ (void) ep_addr;
+
+ return true;
+}
+
+static void __no_inline_not_in_flash_func(handle_endpoint_irq)(root_port_t* rport, xfer_result_t result, volatile uint32_t* ep_reg)
+{
+ (void) rport;
+ const uint32_t ep_all = *ep_reg;
+
+ for(uint8_t ep_idx = 0; ep_idx < PIO_USB_EP_POOL_CNT; ep_idx++)
+ {
+ uint32_t const mask = (1u << ep_idx);
+
+ if (ep_all & mask)
+ {
+ endpoint_t* ep = PIO_USB_ENDPOINT(ep_idx);
+ hcd_event_xfer_complete(ep->dev_addr, ep->ep_num, ep->actual_len, result, true);
+ }
+ }
+
+ // clear all
+ (*ep_reg) &= ~ep_all;
+}
+
+// IRQ Handler
+void __no_inline_not_in_flash_func(pio_usb_host_irq_handler)(uint8_t root_id)
+{
+ uint8_t const tu_rhport = root_id + 1;
+ root_port_t* rport = PIO_USB_ROOT_PORT(root_id);
+ uint32_t const ints = rport->ints;
+
+ if ( ints & PIO_USB_INTS_CONNECT_BITS )
+ {
+ hcd_event_device_attach(tu_rhport, true);
+ }
+
+ if ( ints & PIO_USB_INTS_DISCONNECT_BITS )
+ {
+ hcd_event_device_remove(tu_rhport, true);
+ }
+
+ if ( ints & PIO_USB_INTS_ENDPOINT_COMPLETE_BITS )
+ {
+ handle_endpoint_irq(rport, XFER_RESULT_SUCCESS, &rport->ep_complete);
+ }
+
+ if ( ints & PIO_USB_INTS_ENDPOINT_STALLED_BITS )
+ {
+ handle_endpoint_irq(rport, XFER_RESULT_STALLED, &rport->ep_stalled);
+ }
+
+ if ( ints & PIO_USB_INTS_ENDPOINT_ERROR_BITS )
+ {
+ handle_endpoint_irq(rport, XFER_RESULT_FAILED, &rport->ep_error);
+ }
+
+ // clear all
+ rport->ints &= ~ints;
+}
+
+#endif
diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c
index 915822798..2d77ad4f9 100644
--- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c
+++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c
@@ -26,7 +26,7 @@
#include "tusb_option.h"
-#if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_RP2040
+#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && !CFG_TUD_RPI_PIO_USB
#include "pico.h"
#include "rp2040_usb.h"
diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c
index 234bea203..5164035aa 100644
--- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c
+++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c
@@ -27,7 +27,7 @@
#include "tusb_option.h"
-#if CFG_TUH_ENABLED && CFG_TUSB_MCU == OPT_MCU_RP2040
+#if CFG_TUH_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && !CFG_TUH_RPI_PIO_USB
#include "pico.h"
#include "rp2040_usb.h"
@@ -40,7 +40,8 @@
#include "host/hcd.h"
#include "host/usbh.h"
-#define ROOT_PORT 0
+// port 0 is native USB port, other is counted as software PIO
+#define RHPORT_NATIVE 0
//--------------------------------------------------------------------+
// Low level rp2040 controller functions
@@ -185,11 +186,11 @@ static void hcd_rp2040_irq(void)
if (dev_speed())
{
- hcd_event_device_attach(ROOT_PORT, true);
+ hcd_event_device_attach(RHPORT_NATIVE, true);
}
else
{
- hcd_event_device_remove(ROOT_PORT, true);
+ hcd_event_device_remove(RHPORT_NATIVE, true);
}
// Clear speed change interrupt
@@ -388,6 +389,11 @@ void hcd_port_reset(uint8_t rhport)
// TODO: Nothing to do here yet. Perhaps need to reset some state?
}
+void hcd_port_reset_end(uint8_t rhport)
+{
+ (void) rhport;
+}
+
bool hcd_port_connect_status(uint8_t rhport)
{
pico_trace("hcd_port_connect_status\n");
diff --git a/src/portable/renesas/usba/hcd_usba.c b/src/portable/renesas/usba/hcd_usba.c
index ebb682342..5246ecb94 100644
--- a/src/portable/renesas/usba/hcd_usba.c
+++ b/src/portable/renesas/usba/hcd_usba.c
@@ -620,6 +620,11 @@ void hcd_port_reset(uint8_t rhport)
_hcd.need_reset = false;
}
+void hcd_port_reset_end(uint8_t rhport)
+{
+ (void) rhport;
+}
+
tusb_speed_t hcd_port_speed_get(uint8_t rhport)
{
(void)rhport;
diff --git a/src/portable/sony/cxd56/dcd_cxd56.c b/src/portable/sony/cxd56/dcd_cxd56.c
index fbea03b1d..d3154e58f 100644
--- a/src/portable/sony/cxd56/dcd_cxd56.c
+++ b/src/portable/sony/cxd56/dcd_cxd56.c
@@ -363,7 +363,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to
if (usbdcd_driver.setup_processed)
{
- if (osal_queue_receive(usbdcd_driver.setup_queue, &ctrl))
+ if (osal_queue_receive(usbdcd_driver.setup_queue, &ctrl, 100))
{
usbdcd_driver.setup_processed = false;
dcd_event_setup_received(0, (uint8_t *)&ctrl, false);
diff --git a/src/tusb_option.h b/src/tusb_option.h
index 28bf8a60d..65d886e59 100644
--- a/src/tusb_option.h
+++ b/src/tusb_option.h
@@ -242,7 +242,7 @@
#define TUH_OPT_RHPORT -1
#endif
-#define CFG_TUH_ENABLED ( TUH_RHPORT_MODE & OPT_MODE_HOST )
+#define CFG_TUH_ENABLED (TUH_RHPORT_MODE & OPT_MODE_HOST)
// For backward compatible
#define TUSB_OPT_DEVICE_ENABLED CFG_TUD_ENABLED
@@ -261,7 +261,7 @@
//--------------------------------------------------------------------+
-// COMMON OPTIONS
+// Common Options (Default)
//--------------------------------------------------------------------+
// Debug enable to print out error message
@@ -289,10 +289,10 @@
#endif
// mutex is only needed for RTOS TODO also required with multiple core MCUs
-#define TUSB_OPT_MUTEX (CFG_TUSB_OS != OPT_OS_NONE)
+#define TUSB_OPT_MUTEX (CFG_TUSB_OS != OPT_OS_NONE)
//--------------------------------------------------------------------
-// DEVICE OPTIONS
+// Device Options (Default)
//--------------------------------------------------------------------
#ifndef CFG_TUD_ENDPOINT0_SIZE
@@ -357,7 +357,7 @@
#endif
//--------------------------------------------------------------------
-// HOST OPTIONS
+// Host Options (Default)
//--------------------------------------------------------------------
#if CFG_TUH_ENABLED
#ifndef CFG_TUH_DEVICE_MAX
@@ -399,6 +399,16 @@
#define CFG_TUH_API_EDPT_XFER 0
#endif
+// Enable PIO-USB software host controller
+#ifndef CFG_TUH_RPI_PIO_USB
+#define CFG_TUH_RPI_PIO_USB 0
+#endif
+
+#ifndef CFG_TUD_RPI_PIO_USB
+#define CFG_TUD_RPI_PIO_USB 0
+#endif
+
+
//------------------------------------------------------------------
// Configuration Validation
//------------------------------------------------------------------
diff --git a/tools/build_board.py b/tools/build_board.py
index b2a80c680..4d895329a 100644
--- a/tools/build_board.py
+++ b/tools/build_board.py
@@ -28,12 +28,11 @@ def filter_with_input(mylist):
# If examples are not specified in arguments, build all
all_examples = []
-for entry in os.scandir("examples/device"):
- if entry.is_dir():
- all_examples.append("device/" + entry.name)
-for entry in os.scandir("examples/host"):
- if entry.is_dir():
- all_examples.append("host/" + entry.name)
+for dir1 in os.scandir("examples"):
+ if dir1.is_dir():
+ for entry in os.scandir(dir1.path):
+ if entry.is_dir():
+ all_examples.append(dir1.name + '/' + entry.name)
filter_with_input(all_examples)
all_examples.sort()
diff --git a/tools/build_family.py b/tools/build_family.py
index 4094d07db..095ca4ff7 100644
--- a/tools/build_family.py
+++ b/tools/build_family.py
@@ -28,12 +28,11 @@ def filter_with_input(mylist):
# If examples are not specified in arguments, build all
all_examples = []
-for entry in os.scandir("examples/device"):
- if entry.is_dir():
- all_examples.append("device/" + entry.name)
-for entry in os.scandir("examples/host"):
- if entry.is_dir():
- all_examples.append("host/" + entry.name)
+for dir1 in os.scandir("examples"):
+ if dir1.is_dir():
+ for entry in os.scandir(dir1.path):
+ if entry.is_dir():
+ all_examples.append(dir1.name + '/' + entry.name)
filter_with_input(all_examples)
all_examples.sort()