mirror of
https://github.com/hathach/tinyusb.git
synced 2025-03-26 08:37:16 +00:00
Merge branch 'master' of https://github.com/hathach/tinyusb into uac_interl
This commit is contained in:
commit
b5c839f739
4
.github/workflows/build_arm.yml
vendored
4
.github/workflows/build_arm.yml
vendored
@ -36,11 +36,11 @@ jobs:
|
||||
- 'broadcom_32bit'
|
||||
- 'kinetis_k32l2'
|
||||
- 'lpc11 lpc13 lpc15 lpc17'
|
||||
- 'lpc51 lpc54'
|
||||
- 'lpc51'
|
||||
- 'mm32 msp432e4'
|
||||
- 'samd11 same5x saml2x'
|
||||
- 'stm32f2 stm32f3'
|
||||
- 'stm32l0 stm32u5 stm32wb'
|
||||
- 'stm32l0 stm32wb'
|
||||
- 'tm4c123 xmc4000'
|
||||
steps:
|
||||
- name: Setup Python
|
||||
|
21
.github/workflows/build_esp.yml
vendored
21
.github/workflows/build_esp.yml
vendored
@ -29,12 +29,10 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
board:
|
||||
# Alphabetical order
|
||||
# ESP32-S2
|
||||
- 'espressif_saola_1'
|
||||
- 'espressif_kaluga_1'
|
||||
# ESP32-S3
|
||||
#- 'espressif_s3_devkitm'
|
||||
# S3 compile error with "dangerous relocation: call8: call target out of range: memcpy"
|
||||
- 'espressif_s3_devkitm'
|
||||
|
||||
steps:
|
||||
- name: Setup Python
|
||||
@ -48,20 +46,5 @@ jobs:
|
||||
- name: Checkout TinyUSB
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Checkout hathach/linkermap
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: hathach/linkermap
|
||||
path: linkermap
|
||||
|
||||
- name: Build
|
||||
run: docker run --rm -v $PWD:/project -w /project espressif/idf:latest python3 tools/build_esp32.py ${{ matrix.board }}
|
||||
|
||||
- name: Linker Map
|
||||
run: |
|
||||
pip install linkermap/
|
||||
# find -quit to only print linkermap of 1 board per example
|
||||
for ex in `ls -d examples/device/*/`
|
||||
do
|
||||
find ${ex} -maxdepth 3 -name *.map -print -quit | xargs -I % sh -c 'echo "::group::%"; linkermap -v %; echo "::endgroup::"'
|
||||
done
|
||||
|
3
.github/workflows/cmake_arm.yml
vendored
3
.github/workflows/cmake_arm.yml
vendored
@ -36,7 +36,7 @@ jobs:
|
||||
- 'imxrt'
|
||||
- 'kinetis_kl'
|
||||
- 'lpc18 lpc40 lpc43'
|
||||
- 'lpc55'
|
||||
- 'lpc54 lpc55'
|
||||
- 'mcx'
|
||||
- 'nrf'
|
||||
- 'ra'
|
||||
@ -51,6 +51,7 @@ jobs:
|
||||
- 'stm32g4'
|
||||
- 'stm32h7'
|
||||
- 'stm32l4'
|
||||
- 'stm32u5'
|
||||
steps:
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v4
|
||||
|
25
.idea/cmake.xml
generated
25
.idea/cmake.xml
generated
@ -2,23 +2,24 @@
|
||||
<project version="4">
|
||||
<component name="CMakeSharedSettings">
|
||||
<configurations>
|
||||
<configuration PROFILE_NAME="esp32s2" ENABLED="false" GENERATION_OPTIONS="-DBOARD=espressif_saola_1 -DIDF_TARGET=esp32s2">
|
||||
<configuration PROFILE_NAME="esp32s2" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=espressif_saola_1">
|
||||
<ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||
<envs>
|
||||
<env name="ESPBAUD" value="1500000" />
|
||||
<env name="ESPPORT" value="/dev/ttyUSB0" />
|
||||
<env name="IDF_PATH" value="$PROJECT_DIR$/../esp-idf" />
|
||||
<env name="PATH" value="$PROJECT_DIR$/../esp-idf/components/esptool_py/esptool:/home/hathach/code/esp-idf/components/espcoredump:/home/hathach/code/esp-idf/components/partition_table:/home/hathach/code/esp-idf/components/app_update:/home/hathach/.espressif/tools/xtensa-esp-elf-gdb/11.2_20220823/xtensa-esp-elf-gdb/bin:/home/hathach/.espressif/tools/riscv32-esp-elf-gdb/11.2_20220823/riscv32-esp-elf-gdb/bin:/home/hathach/.espressif/tools/xtensa-esp32-elf/esp-2021r2-patch5-8.4.0/xtensa-esp32-elf/bin:/home/hathach/.espressif/tools/xtensa-esp32s2-elf/esp-2021r2-patch5-8.4.0/xtensa-esp32s2-elf/bin:/home/hathach/.espressif/tools/xtensa-esp32s3-elf/esp-2021r2-patch5-8.4.0/xtensa-esp32s3-elf/bin:/home/hathach/.espressif/tools/riscv32-esp-elf/esp-2021r2-patch5-8.4.0/riscv32-esp-elf/bin:/home/hathach/.espressif/tools/esp32ulp-elf/2.35_20220830/esp32ulp-elf/bin:/home/hathach/.espressif/tools/openocd-esp32/v0.11.0-esp32-20221026/openocd-esp32/bin:/home/hathach/.espressif/python_env/idf4.4_py3.10_env/bin:/home/hathach/code/esp-idf/tools:/home/hathach/app/riscv-openocd-wch/src:/home/hathach/app/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi/bin:/home/hathach/.local/bin:/home/hathach/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:/opt/SEGGER/JLink:/home/hathach/app/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin:/home/hathach/.local/xPacks/@xpack-dev-tools/riscv-none-embed-gcc/10.2.0-1.2.1/.content/bin:/home/hathach/.local/xPacks/@xpack-dev-tools/openocd/*/.content/bin:/home/hathach/ti/msp430-gcc/bin:/home/hathach/ti/MSPFlasher_1.3.20:/home/hathach/ti/uniflash_7.0.0:/home/hathach/app/gcc_8.3.0.202102_gnurx-elf/bin:/home/hathach/app/RFP_CLI_Linux_V31101_x64/linux-x64:/home/hathach/app/fomu-toolchain-linux_x86_64-v1.5.5/bin:/home/hathach/app/nuclei_riscv_newlibc_prebuilt_linux64_2020.08/gcc/bin:/home/hathach/app/riscv32-embecosm-ubuntu2004-gcc11.1.0/bin:/home/hathach/app/cov-analysis-linux64-2019.03/bin:/opt/iarsystems/bxarm/arm/bin:/home/hathach/.local/bin" />
|
||||
</envs>
|
||||
</ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||
</configuration>
|
||||
<configuration PROFILE_NAME="esp32s3" ENABLED="false" GENERATION_OPTIONS="-DBOARD=espressif_s3_devkitm -DIDF_TARGET=esp32s3">
|
||||
<configuration PROFILE_NAME="kaluga" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=espressif_kaluga_1 -DMAX3421_HOST=1 -DLOG=2">
|
||||
<ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||
<envs>
|
||||
<env name="ESPBAUD" value="1500000" />
|
||||
</envs>
|
||||
</ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||
</configuration>
|
||||
<configuration PROFILE_NAME="esp32s3" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=espressif_s3_devkitm">
|
||||
<ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||
<envs>
|
||||
<env name="ESPBAUD" value="1500000" />
|
||||
<env name="ESPPORT" value="/dev/ttyUSB0" />
|
||||
<env name="IDF_PATH" value="$PROJECT_DIR$/../esp-idf" />
|
||||
<env name="PATH" value="$PROJECT_DIR$/../esp-idf/components/esptool_py/esptool:/home/hathach/code/esp-idf/components/espcoredump:/home/hathach/code/esp-idf/components/partition_table:/home/hathach/code/esp-idf/components/app_update:/home/hathach/.espressif/tools/xtensa-esp-elf-gdb/11.2_20220823/xtensa-esp-elf-gdb/bin:/home/hathach/.espressif/tools/riscv32-esp-elf-gdb/11.2_20220823/riscv32-esp-elf-gdb/bin:/home/hathach/.espressif/tools/xtensa-esp32-elf/esp-2021r2-patch5-8.4.0/xtensa-esp32-elf/bin:/home/hathach/.espressif/tools/xtensa-esp32s2-elf/esp-2021r2-patch5-8.4.0/xtensa-esp32s2-elf/bin:/home/hathach/.espressif/tools/xtensa-esp32s3-elf/esp-2021r2-patch5-8.4.0/xtensa-esp32s3-elf/bin:/home/hathach/.espressif/tools/riscv32-esp-elf/esp-2021r2-patch5-8.4.0/riscv32-esp-elf/bin:/home/hathach/.espressif/tools/esp32ulp-elf/2.35_20220830/esp32ulp-elf/bin:/home/hathach/.espressif/tools/openocd-esp32/v0.11.0-esp32-20221026/openocd-esp32/bin:/home/hathach/.espressif/python_env/idf4.4_py3.10_env/bin:/home/hathach/code/esp-idf/tools:/home/hathach/app/riscv-openocd-wch/src:/home/hathach/app/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi/bin:/home/hathach/.local/bin:/home/hathach/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:/opt/SEGGER/JLink:/home/hathach/app/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin:/home/hathach/.local/xPacks/@xpack-dev-tools/riscv-none-embed-gcc/10.2.0-1.2.1/.content/bin:/home/hathach/.local/xPacks/@xpack-dev-tools/openocd/*/.content/bin:/home/hathach/ti/msp430-gcc/bin:/home/hathach/ti/MSPFlasher_1.3.20:/home/hathach/ti/uniflash_7.0.0:/home/hathach/app/gcc_8.3.0.202102_gnurx-elf/bin:/home/hathach/app/RFP_CLI_Linux_V31101_x64/linux-x64:/home/hathach/app/fomu-toolchain-linux_x86_64-v1.5.5/bin:/home/hathach/app/nuclei_riscv_newlibc_prebuilt_linux64_2020.08/gcc/bin:/home/hathach/app/riscv32-embecosm-ubuntu2004-gcc11.1.0/bin:/home/hathach/app/cov-analysis-linux64-2019.03/bin:/opt/iarsystems/bxarm/arm/bin:/home/hathach/.local/bin" />
|
||||
</envs>
|
||||
</ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||
</configuration>
|
||||
@ -55,6 +56,14 @@
|
||||
<configuration PROFILE_NAME="portenta_c33" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=portenta_c33 -DLOG=3" />
|
||||
<configuration PROFILE_NAME="metro_m4_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=metro_m4_express -DLOG=3 -DLOGGER=RTT -DMAX3421_HOST=1" />
|
||||
<configuration PROFILE_NAME="metro_m0_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=metro_m0_express -DLOG=3 -DLOGGER=RTT -DMAX3421_HOST=1" />
|
||||
<configuration PROFILE_NAME="stm32u5" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32u575eval" />
|
||||
<configuration PROFILE_NAME="metro esp32s2" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=adafruit_metro_esp32s2 -DMAX3421_HOST=1 -DLOG=2">
|
||||
<ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||
<envs>
|
||||
<env name="ESPBAUD" value="1500000" />
|
||||
</envs>
|
||||
</ADDITIONAL_GENERATION_ENVIRONMENT>
|
||||
</configuration>
|
||||
</configurations>
|
||||
</component>
|
||||
</project>
|
@ -1,5 +1,3 @@
|
||||
DEPS_SUBMODULES += lib/FreeRTOS-Kernel
|
||||
|
||||
include ../../make.mk
|
||||
|
||||
FREERTOS_SRC = lib/FreeRTOS-Kernel
|
||||
@ -10,7 +8,7 @@ INC += \
|
||||
src/FreeRTOSConfig \
|
||||
$(TOP)/hw \
|
||||
$(TOP)/$(FREERTOS_SRC)/include \
|
||||
$(TOP)/$(FREERTOS_PORTABLE_SRC)
|
||||
$(TOP)/$(FREERTOS_PORTABLE_SRC) \
|
||||
|
||||
# Example source
|
||||
EXAMPLE_SOURCE = \
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
#define USBD_STACK_SIZE 4096
|
||||
#else
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
#include "queue.h"
|
||||
@ -54,7 +55,7 @@
|
||||
#define CDC_STACK_SZIE configMINIMAL_STACK_SIZE
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO CONSTANT TYPEDEF PROTYPES
|
||||
// MACRO CONSTANT TYPEDEF PROTOTYPES
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
/* Blink pattern
|
||||
@ -62,7 +63,7 @@
|
||||
* - 1000 ms : device mounted
|
||||
* - 2500 ms : device is suspended
|
||||
*/
|
||||
enum {
|
||||
enum {
|
||||
BLINK_NOT_MOUNTED = 250,
|
||||
BLINK_MOUNTED = 1000,
|
||||
BLINK_SUSPENDED = 2500,
|
||||
@ -81,16 +82,15 @@ StaticTask_t cdc_taskdef;
|
||||
|
||||
TimerHandle_t blinky_tm;
|
||||
|
||||
void led_blinky_cb(TimerHandle_t xTimer);
|
||||
void usb_device_task(void* param);
|
||||
void cdc_task(void* params);
|
||||
static void led_blinky_cb(TimerHandle_t xTimer);
|
||||
static void usb_device_task(void *param);
|
||||
void cdc_task(void *params);
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Main
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int main(void) {
|
||||
board_init();
|
||||
|
||||
#if configSUPPORT_STATIC_ALLOCATION
|
||||
@ -104,8 +104,8 @@ int main(void)
|
||||
xTaskCreateStatic(cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, cdc_stack, &cdc_taskdef);
|
||||
#else
|
||||
blinky_tm = xTimerCreate(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb);
|
||||
xTaskCreate( usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, NULL);
|
||||
xTaskCreate( cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, NULL);
|
||||
xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL);
|
||||
xTaskCreate(cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES - 2, NULL);
|
||||
#endif
|
||||
|
||||
xTimerStart(blinky_tm, 0);
|
||||
@ -119,16 +119,14 @@ int main(void)
|
||||
}
|
||||
|
||||
#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
|
||||
void app_main(void)
|
||||
{
|
||||
void app_main(void) {
|
||||
main();
|
||||
}
|
||||
#endif
|
||||
|
||||
// USB Device Driver task
|
||||
// This top level thread process all usb events and invoke callbacks
|
||||
void usb_device_task(void* param)
|
||||
{
|
||||
static void usb_device_task(void *param) {
|
||||
(void) param;
|
||||
|
||||
// init device stack on configured roothub port
|
||||
@ -141,8 +139,7 @@ void usb_device_task(void* param)
|
||||
}
|
||||
|
||||
// RTOS forever loop
|
||||
while (1)
|
||||
{
|
||||
while (1) {
|
||||
// put this thread to waiting state until there is new events
|
||||
tud_task();
|
||||
|
||||
@ -156,35 +153,28 @@ void usb_device_task(void* param)
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Invoked when device is mounted
|
||||
void tud_mount_cb(void)
|
||||
{
|
||||
void tud_mount_cb(void) {
|
||||
xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0);
|
||||
}
|
||||
|
||||
// Invoked when device is unmounted
|
||||
void tud_umount_cb(void)
|
||||
{
|
||||
void tud_umount_cb(void) {
|
||||
xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), 0);
|
||||
}
|
||||
|
||||
// Invoked when usb bus is suspended
|
||||
// remote_wakeup_en : if host allow us to perform remote wakeup
|
||||
// Within 7ms, device must draw an average of current less than 2.5 mA from bus
|
||||
void tud_suspend_cb(bool remote_wakeup_en)
|
||||
{
|
||||
void tud_suspend_cb(bool remote_wakeup_en) {
|
||||
(void) remote_wakeup_en;
|
||||
xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_SUSPENDED), 0);
|
||||
}
|
||||
|
||||
// Invoked when usb bus is resumed
|
||||
void tud_resume_cb(void)
|
||||
{
|
||||
if (tud_mounted())
|
||||
{
|
||||
void tud_resume_cb(void) {
|
||||
if (tud_mounted()) {
|
||||
xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), 0);
|
||||
}
|
||||
}
|
||||
@ -192,20 +182,17 @@ void tud_resume_cb(void)
|
||||
//--------------------------------------------------------------------+
|
||||
// USB CDC
|
||||
//--------------------------------------------------------------------+
|
||||
void cdc_task(void* params)
|
||||
{
|
||||
void cdc_task(void *params) {
|
||||
(void) params;
|
||||
|
||||
// RTOS forever loop
|
||||
while ( 1 )
|
||||
{
|
||||
while (1) {
|
||||
// connected() check for DTR bit
|
||||
// Most but not all terminal client set this when making connection
|
||||
// if ( tud_cdc_connected() )
|
||||
{
|
||||
// There are data available
|
||||
while ( tud_cdc_available() )
|
||||
{
|
||||
while (tud_cdc_available()) {
|
||||
uint8_t buf[64];
|
||||
|
||||
// read and echo back
|
||||
@ -228,32 +215,27 @@ void cdc_task(void* params)
|
||||
}
|
||||
|
||||
// Invoked when cdc when line state changed e.g connected/disconnected
|
||||
void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
|
||||
{
|
||||
void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) {
|
||||
(void) itf;
|
||||
(void) rts;
|
||||
|
||||
// TODO set some indicator
|
||||
if ( dtr )
|
||||
{
|
||||
if (dtr) {
|
||||
// Terminal connected
|
||||
}else
|
||||
{
|
||||
} else {
|
||||
// Terminal disconnected
|
||||
}
|
||||
}
|
||||
|
||||
// Invoked when CDC interface received data from host
|
||||
void tud_cdc_rx_cb(uint8_t itf)
|
||||
{
|
||||
void tud_cdc_rx_cb(uint8_t itf) {
|
||||
(void) itf;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// BLINKING TASK
|
||||
//--------------------------------------------------------------------+
|
||||
void led_blinky_cb(TimerHandle_t xTimer)
|
||||
{
|
||||
static void led_blinky_cb(TimerHandle_t xTimer) {
|
||||
(void) xTimer;
|
||||
static bool led_state = false;
|
||||
|
||||
|
@ -10,6 +10,11 @@ project(${PROJECT} C CXX ASM)
|
||||
# Checks this example is valid for the family and initializes the project
|
||||
family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
# Espressif has its own cmake build system
|
||||
if(FAMILY STREQUAL "espressif")
|
||||
return()
|
||||
endif()
|
||||
|
||||
add_executable(${PROJECT})
|
||||
|
||||
# Example source
|
||||
|
@ -10,14 +10,4 @@ EXAMPLE_SOURCE += \
|
||||
|
||||
SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
|
||||
|
||||
# TinyUSB Host Stack source
|
||||
SRC_C += \
|
||||
src/class/cdc/cdc_host.c \
|
||||
src/class/hid/hid_host.c \
|
||||
src/class/msc/msc_host.c \
|
||||
src/host/hub.c \
|
||||
src/host/usbh.c \
|
||||
src/portable/ohci/ohci.c \
|
||||
src/portable/nxp/lpc17_40/hcd_lpc17_40.c
|
||||
|
||||
include ../../rules.mk
|
||||
|
@ -1,3 +1,4 @@
|
||||
mcu:KINETIS_KL
|
||||
mcu:LPC175X_6X
|
||||
mcu:LPC177X_8X
|
||||
mcu:LPC18XX
|
||||
|
@ -10,6 +10,11 @@ project(${PROJECT} C CXX ASM)
|
||||
# Checks this example is valid for the family and initializes the project
|
||||
family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
# Espressif has its own cmake build system
|
||||
if(FAMILY STREQUAL "espressif")
|
||||
return()
|
||||
endif()
|
||||
|
||||
add_executable(${PROJECT})
|
||||
|
||||
# Example source
|
||||
|
@ -13,14 +13,4 @@ EXAMPLE_SOURCE = \
|
||||
|
||||
SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
|
||||
|
||||
# TinyUSB Host Stack source
|
||||
SRC_C += \
|
||||
src/class/cdc/cdc_host.c \
|
||||
src/class/hid/hid_host.c \
|
||||
src/class/msc/msc_host.c \
|
||||
src/host/hub.c \
|
||||
src/host/usbh.c \
|
||||
src/portable/ohci/ohci.c \
|
||||
src/portable/nxp/lpc17_40/hcd_lpc17_40.c
|
||||
|
||||
include ../../rules.mk
|
||||
|
@ -1,3 +1,4 @@
|
||||
mcu:KINETIS_KL
|
||||
mcu:LPC175X_6X
|
||||
mcu:LPC177X_8X
|
||||
mcu:LPC18XX
|
||||
|
36
examples/host/cdc_msc_hid_freertos/CMakeLists.txt
Normal file
36
examples/host/cdc_msc_hid_freertos/CMakeLists.txt
Normal file
@ -0,0 +1,36 @@
|
||||
cmake_minimum_required(VERSION 3.17)
|
||||
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
|
||||
|
||||
# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
|
||||
family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
project(${PROJECT} C CXX ASM)
|
||||
|
||||
# Checks this example is valid for the family and initializes the project
|
||||
family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
# Espressif has its own cmake build system
|
||||
if(FAMILY STREQUAL "espressif")
|
||||
return()
|
||||
endif()
|
||||
|
||||
add_executable(${PROJECT})
|
||||
|
||||
# Example source
|
||||
target_sources(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/cdc_app.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/freertos_hook.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/hid_app.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/msc_app.c
|
||||
)
|
||||
|
||||
# Example include
|
||||
target_include_directories(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
# Configure compilation flags and libraries for the example without RTOS.
|
||||
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
|
||||
family_configure_host_example(${PROJECT} freertos)
|
34
examples/host/cdc_msc_hid_freertos/Makefile
Normal file
34
examples/host/cdc_msc_hid_freertos/Makefile
Normal file
@ -0,0 +1,34 @@
|
||||
include ../../make.mk
|
||||
|
||||
FREERTOS_SRC = lib/FreeRTOS-Kernel
|
||||
FREERTOS_PORTABLE_PATH= $(FREERTOS_SRC)/portable/$(if $(USE_IAR),IAR,GCC)
|
||||
|
||||
INC += \
|
||||
src \
|
||||
src/FreeRTOSConfig \
|
||||
$(TOP)/hw \
|
||||
$(TOP)/$(FREERTOS_SRC)/include \
|
||||
$(TOP)/$(FREERTOS_PORTABLE_SRC) \
|
||||
|
||||
# Example source
|
||||
EXAMPLE_SOURCE = \
|
||||
src/cdc_app.c \
|
||||
src/freertos_hook.c \
|
||||
src/hid_app.c \
|
||||
src/main.c \
|
||||
src/msc_app.c \
|
||||
|
||||
SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
|
||||
|
||||
# FreeRTOS source, all files in port folder
|
||||
SRC_C += \
|
||||
$(FREERTOS_SRC)/list.c \
|
||||
$(FREERTOS_SRC)/queue.c \
|
||||
$(FREERTOS_SRC)/tasks.c \
|
||||
$(FREERTOS_SRC)/timers.c \
|
||||
$(subst $(TOP)/,,$(wildcard $(TOP)/$(FREERTOS_PORTABLE_SRC)/*.c))
|
||||
|
||||
SRC_S += \
|
||||
$(subst $(TOP)/,,$(wildcard $(TOP)/$(FREERTOS_PORTABLE_SRC)/*.s))
|
||||
|
||||
include ../../rules.mk
|
13
examples/host/cdc_msc_hid_freertos/only.txt
Normal file
13
examples/host/cdc_msc_hid_freertos/only.txt
Normal file
@ -0,0 +1,13 @@
|
||||
mcu:LPC175X_6X
|
||||
mcu:LPC177X_8X
|
||||
mcu:LPC18XX
|
||||
mcu:LPC40XX
|
||||
mcu:LPC43XX
|
||||
mcu:MIMXRT1XXX
|
||||
mcu:MIMXRT10XX
|
||||
mcu:MIMXRT11XX
|
||||
mcu:RP2040
|
||||
mcu:MSP432E4
|
||||
mcu:RX65X
|
||||
mcu:RAXXX
|
||||
mcu:MAX3421
|
6
examples/host/cdc_msc_hid_freertos/src/CMakeLists.txt
Normal file
6
examples/host/cdc_msc_hid_freertos/src/CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
||||
# This file is for ESP-IDF only
|
||||
idf_component_register(SRCS "cdc_app.c" "hid_app.c" "main.c" "msc_app.c"
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES boards tinyusb_src)
|
||||
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-error=format)
|
@ -0,0 +1,215 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.0.0
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* 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. If you wish to use our Amazon
|
||||
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FREERTOS_CONFIG_H
|
||||
#define FREERTOS_CONFIG_H
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Application specific definitions.
|
||||
*
|
||||
* These definitions should be adjusted for your particular hardware and
|
||||
* application requirements.
|
||||
*
|
||||
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||
*
|
||||
* See http://www.freertos.org/a00110.html.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
// skip if included from IAR assembler
|
||||
#ifndef __IASMARM__
|
||||
|
||||
// Include MCU header
|
||||
#include "bsp/board_mcu.h"
|
||||
|
||||
#if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3
|
||||
#error "ESP32-Sx should use IDF's FreeRTOSConfig.h"
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wredundant-decls"
|
||||
#endif
|
||||
|
||||
// TODO fix later
|
||||
// FIXME cause redundant-decls warnings
|
||||
#if CFG_TUSB_MCU == OPT_MCU_MM32F327X
|
||||
extern u32 SystemCoreClock;
|
||||
#else
|
||||
extern uint32_t SystemCoreClock;
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* Cortex M23/M33 port configuration. */
|
||||
#define configENABLE_MPU 0
|
||||
#define configENABLE_FPU 1
|
||||
#define configENABLE_TRUSTZONE 0
|
||||
#define configMINIMAL_SECURE_STACK_SIZE ( 1024 )
|
||||
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#define configCPU_CLOCK_HZ SystemCoreClock
|
||||
#define configTICK_RATE_HZ ( 1000 )
|
||||
#define configMAX_PRIORITIES ( 5 )
|
||||
#define configMINIMAL_STACK_SIZE ( 128 )
|
||||
#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 )
|
||||
#define configMAX_TASK_NAME_LEN 16
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configIDLE_SHOULD_YIELD 1
|
||||
#define configUSE_MUTEXES 1
|
||||
#define configUSE_RECURSIVE_MUTEXES 1
|
||||
#define configUSE_COUNTING_SEMAPHORES 1
|
||||
#define configQUEUE_REGISTRY_SIZE 4
|
||||
#define configUSE_QUEUE_SETS 0
|
||||
#define configUSE_TIME_SLICING 0
|
||||
#define configUSE_NEWLIB_REENTRANT 0
|
||||
#define configENABLE_BACKWARD_COMPATIBILITY 1
|
||||
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
|
||||
|
||||
#define configSUPPORT_STATIC_ALLOCATION 1
|
||||
#define configSUPPORT_DYNAMIC_ALLOCATION 0
|
||||
|
||||
/* Hook function related definitions. */
|
||||
#define configUSE_IDLE_HOOK 0
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||
|
||||
/* Run time and task stats gathering related definitions. */
|
||||
#define configGENERATE_RUN_TIME_STATS 0
|
||||
#define configUSE_TRACE_FACILITY 1 // legacy trace
|
||||
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
|
||||
|
||||
/* Co-routine definitions. */
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES 2
|
||||
|
||||
/* Software timer related definitions. */
|
||||
#define configUSE_TIMERS 1
|
||||
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2)
|
||||
#define configTIMER_QUEUE_LENGTH 32
|
||||
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
|
||||
|
||||
/* Optional functions - most linkers will remove unused functions anyway. */
|
||||
#define INCLUDE_vTaskPrioritySet 0
|
||||
#define INCLUDE_uxTaskPriorityGet 0
|
||||
#define INCLUDE_vTaskDelete 0
|
||||
#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY
|
||||
#define INCLUDE_xResumeFromISR 0
|
||||
#define INCLUDE_vTaskDelayUntil 1
|
||||
#define INCLUDE_vTaskDelay 1
|
||||
#define INCLUDE_xTaskGetSchedulerState 0
|
||||
#define INCLUDE_xTaskGetCurrentTaskHandle 0
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark 0
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 0
|
||||
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
|
||||
#define INCLUDE_pcTaskGetTaskName 0
|
||||
#define INCLUDE_eTaskGetState 0
|
||||
#define INCLUDE_xEventGroupSetBitFromISR 0
|
||||
#define INCLUDE_xTimerPendFunctionCall 0
|
||||
|
||||
/* Define to trap errors during development. */
|
||||
// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7
|
||||
#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__)
|
||||
#define configASSERT(_exp) \
|
||||
do {\
|
||||
if ( !(_exp) ) { \
|
||||
volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \
|
||||
if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \
|
||||
taskDISABLE_INTERRUPTS(); \
|
||||
__asm("BKPT #0\n"); \
|
||||
}\
|
||||
}\
|
||||
} while(0)
|
||||
#else
|
||||
#define configASSERT( x )
|
||||
#endif
|
||||
|
||||
#ifdef __RX__
|
||||
/* Renesas RX series */
|
||||
#define vSoftwareInterruptISR INT_Excep_ICU_SWINT
|
||||
#define vTickISR INT_Excep_CMT0_CMI0
|
||||
#define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2)
|
||||
#define configKERNEL_INTERRUPT_PRIORITY 1
|
||||
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 4
|
||||
|
||||
#else
|
||||
|
||||
/* FreeRTOS hooks to NVIC vectors */
|
||||
#define xPortPendSVHandler PendSV_Handler
|
||||
#define xPortSysTickHandler SysTick_Handler
|
||||
#define vPortSVCHandler SVC_Handler
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Interrupt nesting behavior configuration.
|
||||
//--------------------------------------------------------------------+
|
||||
#if defined(__NVIC_PRIO_BITS)
|
||||
// For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h
|
||||
#define configPRIO_BITS __NVIC_PRIO_BITS
|
||||
|
||||
#elif defined(__ECLIC_INTCTLBITS)
|
||||
// RISC-V Bumblebee core from nuclei
|
||||
#define configPRIO_BITS __ECLIC_INTCTLBITS
|
||||
|
||||
#elif defined(__IASMARM__)
|
||||
// FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS.
|
||||
// Therefore we will hard coded it to minimum value of 2 to get pass ci build.
|
||||
// IAR user must update this to correct value of the target MCU
|
||||
#message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU"
|
||||
#define configPRIO_BITS 2
|
||||
|
||||
#else
|
||||
#error "FreeRTOS configPRIO_BITS to be defined"
|
||||
#endif
|
||||
|
||||
/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
|
||||
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<configPRIO_BITS) - 1)
|
||||
|
||||
/* The highest interrupt priority that can be used by any interrupt service
|
||||
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
|
||||
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
|
||||
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
|
||||
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2
|
||||
|
||||
/* Interrupt priorities used by the kernel port layer itself. These are generic
|
||||
to all Cortex-M ports, and do not rely on any particular library functions. */
|
||||
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||
|
||||
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
|
||||
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
|
||||
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __FREERTOS_CONFIG__H */
|
145
examples/host/cdc_msc_hid_freertos/src/cdc_app.c
Normal file
145
examples/host/cdc_msc_hid_freertos/src/cdc_app.c
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2022, 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.h"
|
||||
#include "bsp/board_api.h"
|
||||
|
||||
#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
|
||||
// ESP-IDF need "freertos/" prefix in include path.
|
||||
// CFG_TUSB_OS_INC_PATH should be defined accordingly.
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/timers.h"
|
||||
|
||||
#define CDC_STACK_SZIE 2048
|
||||
#else
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
#include "queue.h"
|
||||
#include "task.h"
|
||||
#include "timers.h"
|
||||
|
||||
#define CDC_STACK_SZIE (3*configMINIMAL_STACK_SIZE/2)
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
#if configSUPPORT_STATIC_ALLOCATION
|
||||
StackType_t cdc_stack[CDC_STACK_SZIE];
|
||||
StaticTask_t cdc_taskdef;
|
||||
#endif
|
||||
|
||||
static void cdc_app_task(void* param);
|
||||
|
||||
void cdc_app_init(void) {
|
||||
#if configSUPPORT_STATIC_ALLOCATION
|
||||
xTaskCreateStatic(cdc_app_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, cdc_stack, &cdc_taskdef);
|
||||
#else
|
||||
xTaskCreate(cdc_app_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
// helper
|
||||
size_t get_console_inputs(uint8_t *buf, size_t bufsize) {
|
||||
size_t count = 0;
|
||||
while (count < bufsize) {
|
||||
int ch = board_getchar();
|
||||
if (ch <= 0) break;
|
||||
|
||||
buf[count] = (uint8_t) ch;
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static void cdc_app_task(void* param) {
|
||||
(void) param;
|
||||
|
||||
uint8_t buf[64 + 1]; // +1 for extra null character
|
||||
uint32_t const bufsize = sizeof(buf) - 1;
|
||||
|
||||
while (1) {
|
||||
uint32_t count = get_console_inputs(buf, bufsize);
|
||||
buf[count] = 0;
|
||||
|
||||
if (count) {
|
||||
// loop over all mounted interfaces
|
||||
for (uint8_t idx = 0; idx < CFG_TUH_CDC; idx++) {
|
||||
if (tuh_cdc_mounted(idx)) {
|
||||
// console --> cdc interfaces
|
||||
tuh_cdc_write(idx, buf, count);
|
||||
tuh_cdc_write_flush(idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vTaskDelay(1);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// TinyUSB Callbacks
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Invoked when received new data
|
||||
void tuh_cdc_rx_cb(uint8_t idx) {
|
||||
uint8_t buf[64 + 1]; // +1 for extra null character
|
||||
uint32_t const bufsize = sizeof(buf) - 1;
|
||||
|
||||
// forward cdc interfaces -> console
|
||||
uint32_t count = tuh_cdc_read(idx, buf, bufsize);
|
||||
buf[count] = 0;
|
||||
|
||||
printf((char *) buf);
|
||||
}
|
||||
|
||||
void tuh_cdc_mount_cb(uint8_t idx) {
|
||||
tuh_itf_info_t itf_info = { 0 };
|
||||
tuh_cdc_itf_get_info(idx, &itf_info);
|
||||
|
||||
printf("CDC Interface is mounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.desc.bInterfaceNumber);
|
||||
|
||||
#ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM
|
||||
// CFG_TUH_CDC_LINE_CODING_ON_ENUM must be defined for line coding is set by tinyusb in enumeration
|
||||
// otherwise you need to call tuh_cdc_set_line_coding() first
|
||||
cdc_line_coding_t line_coding = { 0 };
|
||||
if (tuh_cdc_get_local_line_coding(idx, &line_coding)) {
|
||||
printf(" Baudrate: %lu, Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits);
|
||||
printf(" Parity : %u, Data Width: %u\r\n", line_coding.parity, line_coding.data_bits);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void tuh_cdc_umount_cb(uint8_t idx) {
|
||||
tuh_itf_info_t itf_info = { 0 };
|
||||
tuh_cdc_itf_get_info(idx, &itf_info);
|
||||
|
||||
printf("CDC Interface is unmounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.desc.bInterfaceNumber);
|
||||
}
|
111
examples/host/cdc_msc_hid_freertos/src/freertos_hook.c
Normal file
111
examples/host/cdc_msc_hid_freertos/src/freertos_hook.c
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 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.
|
||||
*
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// INCLUDE
|
||||
//--------------------------------------------------------------------+
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "common/tusb_common.h"
|
||||
|
||||
void vApplicationMallocFailedHook(void) {
|
||||
taskDISABLE_INTERRUPTS();
|
||||
TU_ASSERT(false,);
|
||||
}
|
||||
|
||||
void vApplicationStackOverflowHook(xTaskHandle pxTask, char *pcTaskName) {
|
||||
(void) pxTask;
|
||||
(void) pcTaskName;
|
||||
|
||||
taskDISABLE_INTERRUPTS();
|
||||
TU_ASSERT(false,);
|
||||
}
|
||||
|
||||
/* configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must provide an
|
||||
* implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
|
||||
* used by the Idle task. */
|
||||
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer,
|
||||
uint32_t *pulIdleTaskStackSize) {
|
||||
/* If the buffers to be provided to the Idle task are declared inside this
|
||||
* function then they must be declared static - otherwise they will be allocated on
|
||||
* the stack and so not exists after this function exits. */
|
||||
static StaticTask_t xIdleTaskTCB;
|
||||
static StackType_t uxIdleTaskStack[configMINIMAL_STACK_SIZE];
|
||||
|
||||
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's
|
||||
state will be stored. */
|
||||
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
|
||||
|
||||
/* Pass out the array that will be used as the Idle task's stack. */
|
||||
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
|
||||
|
||||
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
|
||||
Note that, as the array is necessarily of type StackType_t,
|
||||
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
|
||||
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
|
||||
}
|
||||
|
||||
/* configSUPPORT_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
|
||||
* application must provide an implementation of vApplicationGetTimerTaskMemory()
|
||||
* to provide the memory that is used by the Timer service task. */
|
||||
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer,
|
||||
uint32_t *pulTimerTaskStackSize) {
|
||||
/* If the buffers to be provided to the Timer task are declared inside this
|
||||
* function then they must be declared static - otherwise they will be allocated on
|
||||
* the stack and so not exists after this function exits. */
|
||||
static StaticTask_t xTimerTaskTCB;
|
||||
static StackType_t uxTimerTaskStack[configTIMER_TASK_STACK_DEPTH];
|
||||
|
||||
/* Pass out a pointer to the StaticTask_t structure in which the Timer
|
||||
task's state will be stored. */
|
||||
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
|
||||
|
||||
/* Pass out the array that will be used as the Timer task's stack. */
|
||||
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
|
||||
|
||||
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
|
||||
Note that, as the array is necessarily of type StackType_t,
|
||||
configTIMER_TASK_STACK_DEPTH is specified in words, not bytes. */
|
||||
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
|
||||
}
|
||||
|
||||
#if CFG_TUSB_MCU == OPT_MCU_RX63X | CFG_TUSB_MCU == OPT_MCU_RX65X
|
||||
#include "iodefine.h"
|
||||
void vApplicationSetupTimerInterrupt(void)
|
||||
{
|
||||
/* Enable CMT0 */
|
||||
SYSTEM.PRCR.WORD = (0xA5u<<8) | TU_BIT(1);
|
||||
MSTP(CMT0) = 0;
|
||||
SYSTEM.PRCR.WORD = (0xA5u<<8);
|
||||
|
||||
CMT0.CMCNT = 0;
|
||||
CMT0.CMCOR = (unsigned short)(((configPERIPHERAL_CLOCK_HZ/configTICK_RATE_HZ)-1)/128);
|
||||
CMT0.CMCR.WORD = TU_BIT(6) | 2;
|
||||
IR(CMT0, CMI0) = 0;
|
||||
IPR(CMT0, CMI0) = configKERNEL_INTERRUPT_PRIORITY;
|
||||
IEN(CMT0, CMI0) = 1;
|
||||
CMT.CMSTR0.BIT.STR0 = 1;
|
||||
}
|
||||
#endif
|
267
examples/host/cdc_msc_hid_freertos/src/hid_app.c
Normal file
267
examples/host/cdc_msc_hid_freertos/src/hid_app.c
Normal file
@ -0,0 +1,267 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "bsp/board_api.h"
|
||||
#include "tusb.h"
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// If your host terminal support ansi escape code such as TeraTerm
|
||||
// it can be use to simulate mouse cursor movement within terminal
|
||||
#define USE_ANSI_ESCAPE 0
|
||||
|
||||
#define MAX_REPORT 4
|
||||
|
||||
static uint8_t const keycode2ascii[128][2] = { HID_KEYCODE_TO_ASCII };
|
||||
|
||||
// Each HID instance can has multiple reports
|
||||
static struct {
|
||||
uint8_t report_count;
|
||||
tuh_hid_report_info_t report_info[MAX_REPORT];
|
||||
} hid_info[CFG_TUH_HID];
|
||||
|
||||
static void process_kbd_report(hid_keyboard_report_t const *report);
|
||||
static void process_mouse_report(hid_mouse_report_t const *report);
|
||||
static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len);
|
||||
|
||||
void hid_app_init(void) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// TinyUSB Callbacks
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Invoked when device with hid interface is mounted
|
||||
// Report descriptor is also available for use. tuh_hid_parse_report_descriptor()
|
||||
// can be used to parse common/simple enough descriptor.
|
||||
// Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped
|
||||
// therefore report_desc = NULL, desc_len = 0
|
||||
void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *desc_report, uint16_t desc_len) {
|
||||
printf("HID device address = %d, instance = %d is mounted\r\n", dev_addr, instance);
|
||||
|
||||
// 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);
|
||||
|
||||
printf("HID Interface Protocol = %s\r\n", protocol_str[itf_protocol]);
|
||||
|
||||
// By default host stack will use activate boot protocol on supported interface.
|
||||
// Therefore for this simple example, we only need to parse generic report descriptor (with built-in parser)
|
||||
if (itf_protocol == HID_ITF_PROTOCOL_NONE) {
|
||||
hid_info[instance].report_count = tuh_hid_parse_report_descriptor(hid_info[instance].report_info, MAX_REPORT,
|
||||
desc_report, desc_len);
|
||||
printf("HID has %u reports \r\n", hid_info[instance].report_count);
|
||||
}
|
||||
|
||||
// request to receive report
|
||||
// tuh_hid_report_received_cb() will be invoked when report is available
|
||||
if (!tuh_hid_receive_report(dev_addr, instance)) {
|
||||
printf("Error: cannot request to receive 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);
|
||||
}
|
||||
|
||||
// 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) {
|
||||
uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance);
|
||||
|
||||
switch (itf_protocol) {
|
||||
case HID_ITF_PROTOCOL_KEYBOARD:
|
||||
TU_LOG2("HID receive boot keyboard report\r\n");
|
||||
process_kbd_report((hid_keyboard_report_t const *) report);
|
||||
break;
|
||||
|
||||
case HID_ITF_PROTOCOL_MOUSE:
|
||||
TU_LOG2("HID receive boot mouse report\r\n");
|
||||
process_mouse_report((hid_mouse_report_t const *) report);
|
||||
break;
|
||||
|
||||
default:
|
||||
// Generic report requires matching ReportID and contents with previous parsed report info
|
||||
process_generic_report(dev_addr, instance, report, len);
|
||||
break;
|
||||
}
|
||||
|
||||
// continue to request to receive report
|
||||
if (!tuh_hid_receive_report(dev_addr, instance)) {
|
||||
printf("Error: cannot request to receive report\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Keyboard
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// look up new key in previous keys
|
||||
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 (report->keycode[i] == keycode) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void process_kbd_report(hid_keyboard_report_t const *report) {
|
||||
static hid_keyboard_report_t prev_report = { 0, 0, { 0 } }; // previous report to check key released
|
||||
|
||||
//------------- example code ignore control (non-printable) key affects -------------//
|
||||
for (uint8_t i = 0; i < 6; i++) {
|
||||
if (report->keycode[i]) {
|
||||
if (find_key_in_report(&prev_report, report->keycode[i])) {
|
||||
// exist in previous report means the current key is holding
|
||||
} else {
|
||||
// not existed in previous report means the current key is pressed
|
||||
bool const is_shift = report->modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT);
|
||||
uint8_t ch = keycode2ascii[report->keycode[i]][is_shift ? 1 : 0];
|
||||
putchar(ch);
|
||||
if (ch == '\r') putchar('\n'); // added new line for enter key
|
||||
|
||||
#ifndef __ICCARM__ // TODO IAR doesn't support stream control ?
|
||||
fflush(stdout); // flush right away, else nanolib will wait for newline
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// TODO example skips key released
|
||||
}
|
||||
|
||||
prev_report = *report;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Mouse
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
void cursor_movement(int8_t x, int8_t y, int8_t wheel) {
|
||||
#if USE_ANSI_ESCAPE
|
||||
// Move X using ansi escape
|
||||
if ( x < 0) {
|
||||
printf(ANSI_CURSOR_BACKWARD(%d), (-x)); // move left
|
||||
}else if ( x > 0) {
|
||||
printf(ANSI_CURSOR_FORWARD(%d), x); // move right
|
||||
}
|
||||
|
||||
// Move Y using ansi escape
|
||||
if ( y < 0) {
|
||||
printf(ANSI_CURSOR_UP(%d), (-y)); // move up
|
||||
}else if ( y > 0) {
|
||||
printf(ANSI_CURSOR_DOWN(%d), y); // move down
|
||||
}
|
||||
|
||||
// Scroll using ansi escape
|
||||
if (wheel < 0) {
|
||||
printf(ANSI_SCROLL_UP(%d), (-wheel)); // scroll up
|
||||
}else if (wheel > 0) {
|
||||
printf(ANSI_SCROLL_DOWN(%d), wheel); // scroll down
|
||||
}
|
||||
|
||||
printf("\r\n");
|
||||
#else
|
||||
printf("(%d %d %d)\r\n", x, y, wheel);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void process_mouse_report(hid_mouse_report_t const *report) {
|
||||
static hid_mouse_report_t prev_report = { 0 };
|
||||
|
||||
//------------- button state -------------//
|
||||
uint8_t button_changed_mask = report->buttons ^ prev_report.buttons;
|
||||
if (button_changed_mask & report->buttons) {
|
||||
printf(" %c%c%c ",
|
||||
report->buttons & MOUSE_BUTTON_LEFT ? 'L' : '-',
|
||||
report->buttons & MOUSE_BUTTON_MIDDLE ? 'M' : '-',
|
||||
report->buttons & MOUSE_BUTTON_RIGHT ? 'R' : '-');
|
||||
}
|
||||
|
||||
//------------- cursor movement -------------//
|
||||
cursor_movement(report->x, report->y, report->wheel);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Generic Report
|
||||
//--------------------------------------------------------------------+
|
||||
static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len) {
|
||||
(void) dev_addr;
|
||||
|
||||
uint8_t const rpt_count = hid_info[instance].report_count;
|
||||
tuh_hid_report_info_t *rpt_info_arr = hid_info[instance].report_info;
|
||||
tuh_hid_report_info_t *rpt_info = NULL;
|
||||
|
||||
if (rpt_count == 1 && rpt_info_arr[0].report_id == 0) {
|
||||
// Simple report without report ID as 1st byte
|
||||
rpt_info = &rpt_info_arr[0];
|
||||
} else {
|
||||
// Composite report, 1st byte is report ID, data starts from 2nd byte
|
||||
uint8_t const rpt_id = report[0];
|
||||
|
||||
// Find report id in the array
|
||||
for (uint8_t i = 0; i < rpt_count; i++) {
|
||||
if (rpt_id == rpt_info_arr[i].report_id) {
|
||||
rpt_info = &rpt_info_arr[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
report++;
|
||||
len--;
|
||||
}
|
||||
|
||||
if (!rpt_info) {
|
||||
printf("Couldn't find report info !\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// For complete list of Usage Page & Usage checkout src/class/hid/hid.h. For examples:
|
||||
// - Keyboard : Desktop, Keyboard
|
||||
// - Mouse : Desktop, Mouse
|
||||
// - Gamepad : Desktop, Gamepad
|
||||
// - Consumer Control (Media Key) : Consumer, Consumer Control
|
||||
// - System Control (Power key) : Desktop, System Control
|
||||
// - Generic (vendor) : 0xFFxx, xx
|
||||
if (rpt_info->usage_page == HID_USAGE_PAGE_DESKTOP) {
|
||||
switch (rpt_info->usage) {
|
||||
case HID_USAGE_DESKTOP_KEYBOARD:
|
||||
TU_LOG1("HID receive keyboard report\r\n");
|
||||
// Assume keyboard follow boot report layout
|
||||
process_kbd_report((hid_keyboard_report_t const *) report);
|
||||
break;
|
||||
|
||||
case HID_USAGE_DESKTOP_MOUSE:
|
||||
TU_LOG1("HID receive mouse report\r\n");
|
||||
// Assume mouse follow boot report layout
|
||||
process_mouse_report((hid_mouse_report_t const *) report);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
165
examples/host/cdc_msc_hid_freertos/src/main.c
Normal file
165
examples/host/cdc_msc_hid_freertos/src/main.c
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "bsp/board_api.h"
|
||||
#include "tusb.h"
|
||||
|
||||
#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
|
||||
// ESP-IDF need "freertos/" prefix in include path.
|
||||
// CFG_TUSB_OS_INC_PATH should be defined accordingly.
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/timers.h"
|
||||
|
||||
#define USBH_STACK_SIZE 4096
|
||||
#else
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
#include "queue.h"
|
||||
#include "task.h"
|
||||
#include "timers.h"
|
||||
|
||||
// Increase stack size when debug log is enabled
|
||||
#define USBH_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1)
|
||||
#endif
|
||||
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO CONSTANT TYPEDEF PROTOTYPES
|
||||
//--------------------------------------------------------------------+
|
||||
/* Blink pattern
|
||||
* - 250 ms : device not mounted
|
||||
* - 1000 ms : device mounted
|
||||
* - 2500 ms : device is suspended
|
||||
*/
|
||||
enum {
|
||||
BLINK_NOT_MOUNTED = 250,
|
||||
BLINK_MOUNTED = 1000,
|
||||
BLINK_SUSPENDED = 2500,
|
||||
};
|
||||
|
||||
// static timer & task
|
||||
#if configSUPPORT_STATIC_ALLOCATION
|
||||
StaticTimer_t blinky_tmdef;
|
||||
|
||||
StackType_t usb_host_stack[USBH_STACK_SIZE];
|
||||
StaticTask_t usb_host_taskdef;
|
||||
#endif
|
||||
|
||||
TimerHandle_t blinky_tm;
|
||||
|
||||
static void led_blinky_cb(TimerHandle_t xTimer);
|
||||
static void usb_host_task(void* param);
|
||||
|
||||
extern void cdc_app_init(void);
|
||||
extern void hid_app_init(void);
|
||||
extern void msc_app_init(void);
|
||||
|
||||
/*------------- MAIN -------------*/
|
||||
int main(void) {
|
||||
board_init();
|
||||
|
||||
printf("TinyUSB Host CDC MSC HID with FreeRTOS Example\r\n");
|
||||
|
||||
// Create soft timer for blinky, task for tinyusb stack
|
||||
#if configSUPPORT_STATIC_ALLOCATION
|
||||
blinky_tm = xTimerCreateStatic(NULL, pdMS_TO_TICKS(BLINK_MOUNTED), true, NULL, led_blinky_cb, &blinky_tmdef);
|
||||
xTaskCreateStatic(usb_host_task, "usbh", USBH_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_host_stack, &usb_host_taskdef);
|
||||
#else
|
||||
blinky_tm = xTimerCreate(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb);
|
||||
xTaskCreate(usb_host_task, "usbd", USBH_STACK_SIZE, NULL, configMAX_PRIORITIES-1, NULL);
|
||||
#endif
|
||||
|
||||
xTimerStart(blinky_tm, 0);
|
||||
|
||||
// skip starting scheduler (and return) for ESP32-S2 or ESP32-S3
|
||||
#if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
|
||||
vTaskStartScheduler();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
|
||||
void app_main(void) {
|
||||
main();
|
||||
}
|
||||
#endif
|
||||
|
||||
// USB Host task
|
||||
// This top level thread process all usb events and invoke callbacks
|
||||
static void usb_host_task(void *param) {
|
||||
(void) param;
|
||||
|
||||
// init host stack on configured roothub port
|
||||
tuh_init(BOARD_TUH_RHPORT);
|
||||
|
||||
if (board_init_after_tusb) {
|
||||
board_init_after_tusb();
|
||||
}
|
||||
|
||||
cdc_app_init();
|
||||
hid_app_init();
|
||||
msc_app_init();
|
||||
|
||||
// RTOS forever loop
|
||||
while (1) {
|
||||
// put this thread to waiting state until there is new events
|
||||
tuh_task();
|
||||
|
||||
// following code only run if tuh_task() process at least 1 event
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// TinyUSB Callbacks
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
void tuh_mount_cb(uint8_t dev_addr) {
|
||||
// application set-up
|
||||
printf("A device with address %d is mounted\r\n", dev_addr);
|
||||
}
|
||||
|
||||
void tuh_umount_cb(uint8_t dev_addr) {
|
||||
// application tear-down
|
||||
printf("A device with address %d is unmounted \r\n", dev_addr);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// BLINKING TASK
|
||||
//--------------------------------------------------------------------+
|
||||
static void led_blinky_cb(TimerHandle_t xTimer) {
|
||||
(void) xTimer;
|
||||
static bool led_state = false;
|
||||
|
||||
board_led_write(led_state);
|
||||
led_state = 1 - led_state; // toggle
|
||||
}
|
67
examples/host/cdc_msc_hid_freertos/src/msc_app.c
Normal file
67
examples/host/cdc_msc_hid_freertos/src/msc_app.c
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "tusb.h"
|
||||
|
||||
static scsi_inquiry_resp_t inquiry_resp;
|
||||
|
||||
void msc_app_init(void) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const *cb_data) {
|
||||
msc_cbw_t const *cbw = cb_data->cbw;
|
||||
msc_csw_t const *csw = cb_data->csw;
|
||||
|
||||
if (csw->status != 0) {
|
||||
printf("Inquiry failed\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Print out Vendor ID, Product ID and Rev
|
||||
printf("%.8s %.16s rev %.4s\r\n", inquiry_resp.vendor_id, inquiry_resp.product_id, inquiry_resp.product_rev);
|
||||
|
||||
// Get capacity of device
|
||||
uint32_t const block_count = tuh_msc_get_block_count(dev_addr, cbw->lun);
|
||||
uint32_t const block_size = tuh_msc_get_block_size(dev_addr, cbw->lun);
|
||||
|
||||
printf("Disk Size: %lu MB\r\n", block_count / ((1024 * 1024) / block_size));
|
||||
printf("Block Count = %lu, Block Size: %lu\r\n", block_count, block_size);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------- IMPLEMENTATION -------------//
|
||||
void tuh_msc_mount_cb(uint8_t dev_addr) {
|
||||
printf("A MassStorage device is mounted\r\n");
|
||||
|
||||
uint8_t const lun = 0;
|
||||
tuh_msc_inquiry(dev_addr, lun, &inquiry_resp, inquiry_complete_cb, 0);
|
||||
}
|
||||
|
||||
void tuh_msc_umount_cb(uint8_t dev_addr) {
|
||||
(void) dev_addr;
|
||||
printf("A MassStorage device is unmounted\r\n");
|
||||
}
|
133
examples/host/cdc_msc_hid_freertos/src/tusb_config.h
Normal file
133
examples/host/cdc_msc_hid_freertos/src/tusb_config.h
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_CONFIG_H_
|
||||
#define _TUSB_CONFIG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Board Specific Configuration
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
#if CFG_TUSB_MCU == OPT_MCU_RP2040
|
||||
// change to 1 if using pico-pio-usb as host controller for raspberry rp2040
|
||||
#define CFG_TUH_RPI_PIO_USB 0
|
||||
#define BOARD_TUH_RHPORT CFG_TUH_RPI_PIO_USB
|
||||
#endif
|
||||
|
||||
// RHPort number used for host can be defined by board.mk, default to port 0
|
||||
#ifndef BOARD_TUH_RHPORT
|
||||
#define BOARD_TUH_RHPORT 0
|
||||
#endif
|
||||
|
||||
// RHPort max operational speed can defined by board.mk
|
||||
#ifndef BOARD_TUH_MAX_SPEED
|
||||
#define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// COMMON CONFIGURATION
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// defined by compiler flags for flexibility
|
||||
#ifndef CFG_TUSB_MCU
|
||||
#error CFG_TUSB_MCU must be defined
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUSB_OS
|
||||
#define CFG_TUSB_OS OPT_OS_FREERTOS
|
||||
#endif
|
||||
|
||||
// Espressif IDF requires "freertos/" prefix in include path
|
||||
#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
|
||||
#define CFG_TUSB_OS_INC_PATH freertos/
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUSB_DEBUG
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#endif
|
||||
|
||||
// Enable Host stack
|
||||
#define CFG_TUH_ENABLED 1
|
||||
|
||||
// Default is max speed that hardware controller could support with on-chip PHY
|
||||
#define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED
|
||||
|
||||
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
|
||||
* Tinyusb use follows macros to declare transferring memory so that they can be put
|
||||
* into those specific section.
|
||||
* e.g
|
||||
* - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
|
||||
* - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
|
||||
*/
|
||||
#ifndef CFG_TUH_MEM_SECTION
|
||||
#define CFG_TUH_MEM_SECTION
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUH_MEM_ALIGN
|
||||
#define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4)))
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// CONFIGURATION
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// Size of buffer to hold descriptors and other data used for enumeration
|
||||
#define CFG_TUH_ENUMERATION_BUFSIZE 256
|
||||
|
||||
#define CFG_TUH_HUB 1 // number of supported hubs
|
||||
#define CFG_TUH_CDC 1 // CDC ACM
|
||||
#define CFG_TUH_CDC_FTDI 1 // FTDI Serial. FTDI is not part of CDC class, only to re-use CDC driver API
|
||||
#define CFG_TUH_CDC_CP210X 1 // CP210x Serial. CP210X is not part of CDC class, only to re-use CDC driver API
|
||||
#define CFG_TUH_HID (3*CFG_TUH_DEVICE_MAX) // typical keyboard + mouse device can have 3-4 HID interfaces
|
||||
#define CFG_TUH_MSC 1
|
||||
#define CFG_TUH_VENDOR 0
|
||||
|
||||
// max device support (excluding hub device): 1 hub typically has 4 ports
|
||||
#define CFG_TUH_DEVICE_MAX (3*CFG_TUH_HUB + 1)
|
||||
|
||||
//------------- HID -------------//
|
||||
#define CFG_TUH_HID_EPIN_BUFSIZE 64
|
||||
#define CFG_TUH_HID_EPOUT_BUFSIZE 64
|
||||
|
||||
//------------- CDC -------------//
|
||||
|
||||
// Set Line Control state on enumeration/mounted:
|
||||
// DTR ( bit 0), RTS (bit 1)
|
||||
#define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM 0x03
|
||||
|
||||
// Set Line Coding on enumeration/mounted, value for cdc_line_coding_t
|
||||
// bit rate = 115200, 1 stop bit, no parity, 8 bit data width
|
||||
#define CFG_TUH_CDC_LINE_CODING_ON_ENUM { 115200, CDC_LINE_CONDING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 }
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_CONFIG_H_ */
|
@ -10,6 +10,11 @@ project(${PROJECT} C CXX ASM)
|
||||
# Checks this example is valid for the family and initializes the project
|
||||
family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
# Espressif has its own cmake build system
|
||||
if(FAMILY STREQUAL "espressif")
|
||||
return()
|
||||
endif()
|
||||
|
||||
add_executable(${PROJECT})
|
||||
|
||||
# Example source
|
||||
|
@ -11,14 +11,4 @@ EXAMPLE_SOURCE += \
|
||||
|
||||
SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
|
||||
|
||||
# TinyUSB Host Stack source
|
||||
SRC_C += \
|
||||
src/class/cdc/cdc_host.c \
|
||||
src/class/hid/hid_host.c \
|
||||
src/class/msc/msc_host.c \
|
||||
src/host/hub.c \
|
||||
src/host/usbh.c \
|
||||
src/portable/ohci/ohci.c \
|
||||
src/portable/nxp/lpc17_40/hcd_lpc17_40.c
|
||||
|
||||
include ../../rules.mk
|
||||
|
@ -1,3 +1,4 @@
|
||||
mcu:KINETIS_KL
|
||||
mcu:LPC175X_6X
|
||||
mcu:LPC177X_8X
|
||||
mcu:LPC18XX
|
||||
|
@ -10,6 +10,11 @@ project(${PROJECT} C CXX ASM)
|
||||
# Checks this example is valid for the family and initializes the project
|
||||
family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
# Espressif has its own cmake build system
|
||||
if(FAMILY STREQUAL "espressif")
|
||||
return()
|
||||
endif()
|
||||
|
||||
add_executable(${PROJECT})
|
||||
|
||||
# Example source
|
||||
|
@ -24,14 +24,4 @@ SRC_C += \
|
||||
# suppress warning caused by fatfs
|
||||
CFLAGS += -Wno-error=cast-qual
|
||||
|
||||
# TinyUSB Host Stack source
|
||||
SRC_C += \
|
||||
src/class/cdc/cdc_host.c \
|
||||
src/class/hid/hid_host.c \
|
||||
src/class/msc/msc_host.c \
|
||||
src/host/hub.c \
|
||||
src/host/usbh.c \
|
||||
src/portable/ohci/ohci.c \
|
||||
src/portable/nxp/lpc17_40/hcd_lpc17_40.c
|
||||
|
||||
include ../../rules.mk
|
||||
|
@ -1,3 +1,4 @@
|
||||
mcu:KINETIS_KL
|
||||
mcu:LPC175X_6X
|
||||
mcu:LPC177X_8X
|
||||
mcu:LPC18XX
|
||||
|
@ -26,9 +26,6 @@ ifeq '$(findstring ;,$(PATH))' ';'
|
||||
CMDEXE := 1
|
||||
|
||||
# makefile shell commands should use syntax for DOS CMD, not unix sh
|
||||
# Unfortunately, SHELL may point to sh or bash, which can't accept DOS syntax.
|
||||
# We can't just use sh, because while sh and/or bash shell may be available,
|
||||
# many Windows environments won't have utilities like realpath used below, so...
|
||||
# Force DOS command shell on Windows.
|
||||
SHELL := cmd.exe
|
||||
endif
|
||||
|
@ -4,3 +4,5 @@ idf_component_register(SRCS family.c
|
||||
INCLUDE_DIRS "." ${BOARD} ${hw_dir}
|
||||
PRIV_REQUIRES "driver"
|
||||
REQUIRES led_strip src tinyusb_src)
|
||||
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-error=format)
|
||||
|
@ -36,6 +36,14 @@
|
||||
#define BUTTON_PIN 0
|
||||
#define BUTTON_STATE_ACTIVE 0
|
||||
|
||||
// SPI for USB host shield
|
||||
#define MAX3421_SPI_HOST SPI2_HOST
|
||||
#define MAX3421_SCK_PIN 36
|
||||
#define MAX3421_MOSI_PIN 35
|
||||
#define MAX3421_MISO_PIN 37
|
||||
#define MAX3421_CS_PIN 15
|
||||
#define MAX3421_INTR_PIN 14
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -37,6 +37,14 @@
|
||||
#define BUTTON_PIN 0
|
||||
#define BUTTON_STATE_ACTIVE 0
|
||||
|
||||
// SPI for USB host shield
|
||||
#define MAX3421_SPI_HOST SPI2_HOST
|
||||
#define MAX3421_SCK_PIN 36
|
||||
#define MAX3421_MOSI_PIN 35
|
||||
#define MAX3421_MISO_PIN 37
|
||||
#define MAX3421_CS_PIN 15
|
||||
#define MAX3421_INTR_PIN 14
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
2
hw/bsp/espressif/boards/espressif_s2_devkitc/board.cmake
Normal file
2
hw/bsp/espressif/boards/espressif_s2_devkitc/board.cmake
Normal file
@ -0,0 +1,2 @@
|
||||
# Apply board specific content here
|
||||
set(IDF_TARGET "esp32s2")
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
* Copyright (c) 2020, 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
|
||||
@ -24,57 +24,22 @@
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_Common Common Files
|
||||
* \defgroup Group_TimeoutTimer timeout timer
|
||||
* @{ */
|
||||
|
||||
#ifndef _TUSB_TIMEOUT_H_
|
||||
#define _TUSB_TIMEOUT_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#ifndef BOARD_H_
|
||||
#define BOARD_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint32_t start;
|
||||
uint32_t interval;
|
||||
}tu_timeout_t;
|
||||
// Note: On the production version (v1.2) WS2812 is connected to GPIO 18,
|
||||
// however earlier revision v1.1 WS2812 is connected to GPIO 17
|
||||
#define NEOPIXEL_PIN 18
|
||||
|
||||
#if 0
|
||||
|
||||
extern uint32_t tusb_hal_millis(void);
|
||||
|
||||
static inline void tu_timeout_set(tu_timeout_t* tt, uint32_t msec)
|
||||
{
|
||||
tt->interval = msec;
|
||||
tt->start = tusb_hal_millis();
|
||||
}
|
||||
|
||||
static inline bool tu_timeout_expired(tu_timeout_t* tt)
|
||||
{
|
||||
return ( tusb_hal_millis() - tt->start ) >= tt->interval;
|
||||
}
|
||||
|
||||
// For used with periodic event to prevent drift
|
||||
static inline void tu_timeout_reset(tu_timeout_t* tt)
|
||||
{
|
||||
tt->start += tt->interval;
|
||||
}
|
||||
|
||||
static inline void tu_timeout_restart(tu_timeout_t* tt)
|
||||
{
|
||||
tt->start = tusb_hal_millis();
|
||||
}
|
||||
|
||||
#endif
|
||||
#define BUTTON_PIN 0
|
||||
#define BUTTON_STATE_ACTIVE 0
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_TIMEOUT_H_ */
|
||||
|
||||
/** @} */
|
||||
#endif /* BOARD_H_ */
|
@ -36,6 +36,14 @@
|
||||
#define BUTTON_PIN 0
|
||||
#define BUTTON_STATE_ACTIVE 0
|
||||
|
||||
// SPI for USB host shield
|
||||
#define MAX3421_SPI_HOST SPI2_HOST
|
||||
#define MAX3421_SCK_PIN 36
|
||||
#define MAX3421_MOSI_PIN 35
|
||||
#define MAX3421_MISO_PIN 37
|
||||
#define MAX3421_CS_PIN 15
|
||||
#define MAX3421_INTR_PIN 14
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -33,27 +33,55 @@
|
||||
#include "soc/usb_periph.h"
|
||||
|
||||
#include "driver/rmt.h"
|
||||
#include "driver/uart.h"
|
||||
|
||||
#if ESP_IDF_VERSION_MAJOR > 4
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#else
|
||||
|
||||
#include "driver/periph_ctrl.h"
|
||||
|
||||
#endif
|
||||
|
||||
// Note; current code use UART0 can cause device to reset while monitoring
|
||||
#define USE_UART 0
|
||||
#define UART_ID UART_NUM_0
|
||||
|
||||
#ifdef NEOPIXEL_PIN
|
||||
|
||||
#include "led_strip.h"
|
||||
static led_strip_t *strip;
|
||||
|
||||
static led_strip_t* strip;
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
#if CFG_TUH_ENABLED && CFG_TUH_MAX3421
|
||||
|
||||
static void configure_pins(usb_hal_context_t *usb);
|
||||
#include "driver/spi_master.h"
|
||||
|
||||
static void max3421_init(void);
|
||||
|
||||
#endif
|
||||
|
||||
static void configure_pins(usb_hal_context_t* usb);
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Implementation
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Initialize on-board peripherals : led, button, uart and USB
|
||||
void board_init(void)
|
||||
{
|
||||
void board_init(void) {
|
||||
#if USE_UART
|
||||
// uart init
|
||||
uart_config_t uart_config = {
|
||||
.baud_rate = 115200,
|
||||
.data_bits = UART_DATA_8_BITS,
|
||||
.parity = UART_PARITY_DISABLE,
|
||||
.stop_bits = UART_STOP_BITS_1,
|
||||
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE
|
||||
};
|
||||
uart_driver_install(UART_ID, 1024, 0, 0, NULL, 0);
|
||||
uart_param_config(UART_ID, &uart_config);
|
||||
#endif
|
||||
|
||||
#ifdef NEOPIXEL_PIN
|
||||
#ifdef NEOPIXEL_POWER_PIN
|
||||
@ -84,19 +112,21 @@ void board_init(void)
|
||||
periph_module_enable(PERIPH_USB_MODULE);
|
||||
|
||||
usb_hal_context_t hal = {
|
||||
.use_external_phy = false // use built-in PHY
|
||||
.use_external_phy = false // use built-in PHY
|
||||
};
|
||||
usb_hal_init(&hal);
|
||||
configure_pins(&hal);
|
||||
|
||||
#if CFG_TUH_ENABLED && CFG_TUH_MAX3421
|
||||
max3421_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void configure_pins(usb_hal_context_t *usb)
|
||||
{
|
||||
static void configure_pins(usb_hal_context_t* usb) {
|
||||
/* usb_periph_iopins currently configures USB_OTG as USB Device.
|
||||
* Introduce additional parameters in usb_hal_context_t when adding support
|
||||
* for USB Host.
|
||||
*/
|
||||
for (const usb_iopin_dsc_t *iopin = usb_periph_iopins; iopin->pin != -1; ++iopin) {
|
||||
* for USB Host. */
|
||||
for (const usb_iopin_dsc_t* iopin = usb_periph_iopins; iopin->pin != -1; ++iopin) {
|
||||
if ((usb->use_external_phy) || (iopin->ext_phy_only == 0)) {
|
||||
esp_rom_gpio_pad_select_gpio(iopin->pin);
|
||||
if (iopin->is_output) {
|
||||
@ -115,6 +145,7 @@ static void configure_pins(usb_hal_context_t *usb)
|
||||
esp_rom_gpio_pad_unhold(iopin->pin);
|
||||
}
|
||||
}
|
||||
|
||||
if (!usb->use_external_phy) {
|
||||
gpio_set_drive_capability(USBPHY_DM_NUM, GPIO_DRIVE_CAP_3);
|
||||
gpio_set_drive_capability(USBPHY_DP_NUM, GPIO_DRIVE_CAP_3);
|
||||
@ -122,8 +153,7 @@ static void configure_pins(usb_hal_context_t *usb)
|
||||
}
|
||||
|
||||
// Turn LED on or off
|
||||
void board_led_write(bool state)
|
||||
{
|
||||
void board_led_write(bool state) {
|
||||
#ifdef NEOPIXEL_PIN
|
||||
strip->set_pixel(strip, 0, (state ? 0x88 : 0x00), 0x00, 0x00);
|
||||
strip->refresh(strip, 100);
|
||||
@ -132,21 +162,138 @@ void board_led_write(bool state)
|
||||
|
||||
// Get the current state of button
|
||||
// a '1' means active (pressed), a '0' means inactive.
|
||||
uint32_t board_button_read(void)
|
||||
{
|
||||
uint32_t board_button_read(void) {
|
||||
return gpio_get_level(BUTTON_PIN) == BUTTON_STATE_ACTIVE;
|
||||
}
|
||||
|
||||
// Get characters from UART
|
||||
int board_uart_read(uint8_t* buf, int len)
|
||||
{
|
||||
(void) buf; (void) len;
|
||||
return 0;
|
||||
int board_uart_read(uint8_t* buf, int len) {
|
||||
#if USE_UART
|
||||
return uart_read_bytes(UART_ID, buf, len, 0);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Send characters to UART
|
||||
int board_uart_write(void const * buf, int len)
|
||||
{
|
||||
(void) buf; (void) len;
|
||||
int board_uart_write(void const* buf, int len) {
|
||||
(void) buf;
|
||||
(void) len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_getchar(void) {
|
||||
uint8_t c = 0;
|
||||
return board_uart_read(&c, 1) > 0 ? (int) c : (-1);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// API: SPI transfer with MAX3421E, must be implemented by application
|
||||
//--------------------------------------------------------------------+
|
||||
#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
|
||||
|
||||
static spi_device_handle_t max3421_spi;
|
||||
SemaphoreHandle_t max3421_intr_sem;
|
||||
|
||||
static void IRAM_ATTR max3421_isr_handler(void* arg) {
|
||||
(void) arg; // arg is gpio num
|
||||
gpio_set_level(13, 1);
|
||||
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
xSemaphoreGiveFromISR(max3421_intr_sem, &xHigherPriorityTaskWoken);
|
||||
if (xHigherPriorityTaskWoken) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
|
||||
gpio_set_level(13, 0);
|
||||
}
|
||||
|
||||
static void max3421_intr_task(void* param) {
|
||||
(void) param;
|
||||
|
||||
while (1) {
|
||||
xSemaphoreTake(max3421_intr_sem, portMAX_DELAY);
|
||||
tuh_int_handler(BOARD_TUH_RHPORT, false);
|
||||
}
|
||||
}
|
||||
|
||||
static void max3421_init(void) {
|
||||
// CS pin
|
||||
gpio_set_direction(MAX3421_CS_PIN, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(MAX3421_CS_PIN, 1);
|
||||
|
||||
// SPI
|
||||
spi_bus_config_t buscfg = {
|
||||
.miso_io_num = MAX3421_MISO_PIN,
|
||||
.mosi_io_num = MAX3421_MOSI_PIN,
|
||||
.sclk_io_num = MAX3421_SCK_PIN,
|
||||
.quadwp_io_num = -1,
|
||||
.quadhd_io_num = -1,
|
||||
.data4_io_num = -1,
|
||||
.data5_io_num = -1,
|
||||
.data6_io_num = -1,
|
||||
.data7_io_num = -1,
|
||||
.max_transfer_sz = 1024
|
||||
};
|
||||
ESP_ERROR_CHECK(spi_bus_initialize(MAX3421_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO));
|
||||
|
||||
spi_device_interface_config_t max3421_cfg = {
|
||||
.mode = 0,
|
||||
.clock_speed_hz = 26000000,
|
||||
.spics_io_num = -1, // manual control CS
|
||||
.queue_size = 1
|
||||
};
|
||||
ESP_ERROR_CHECK(spi_bus_add_device(MAX3421_SPI_HOST, &max3421_cfg, &max3421_spi));
|
||||
|
||||
// debug
|
||||
gpio_set_direction(13, GPIO_MODE_OUTPUT);
|
||||
gpio_set_level(13, 0);
|
||||
|
||||
// Interrupt pin
|
||||
max3421_intr_sem = xSemaphoreCreateBinary();
|
||||
xTaskCreate(max3421_intr_task, "max3421 intr", 2048, NULL, configMAX_PRIORITIES - 2, NULL);
|
||||
|
||||
gpio_set_direction(MAX3421_INTR_PIN, GPIO_MODE_INPUT);
|
||||
gpio_set_intr_type(MAX3421_INTR_PIN, GPIO_INTR_NEGEDGE);
|
||||
|
||||
gpio_install_isr_service(0);
|
||||
gpio_isr_handler_add(MAX3421_INTR_PIN, max3421_isr_handler, NULL);
|
||||
}
|
||||
|
||||
void tuh_max3421_int_api(uint8_t rhport, bool enabled) {
|
||||
(void) rhport;
|
||||
if (enabled) {
|
||||
gpio_intr_enable(MAX3421_INTR_PIN);
|
||||
} else {
|
||||
gpio_intr_disable(MAX3421_INTR_PIN);
|
||||
}
|
||||
}
|
||||
|
||||
void tuh_max3421_spi_cs_api(uint8_t rhport, bool active) {
|
||||
(void) rhport;
|
||||
gpio_set_level(MAX3421_CS_PIN, active ? 0 : 1);
|
||||
}
|
||||
|
||||
bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint8_t* rx_buf, size_t xfer_bytes) {
|
||||
(void) rhport;
|
||||
|
||||
if (tx_buf == NULL) {
|
||||
// fifo read, transmit rx_buf as dummy
|
||||
tx_buf = rx_buf;
|
||||
}
|
||||
|
||||
// length in bits
|
||||
size_t const len_bits = xfer_bytes << 3;
|
||||
|
||||
spi_transaction_t xact = {
|
||||
.length = len_bits,
|
||||
.rxlength = rx_buf ? len_bits : 0,
|
||||
.tx_buffer = tx_buf,
|
||||
.rx_buffer = rx_buf
|
||||
};
|
||||
|
||||
ESP_ERROR_CHECK(spi_device_transmit(max3421_spi, &xact));
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -16,40 +16,58 @@ else()
|
||||
return()
|
||||
endif()
|
||||
|
||||
list(APPEND compile_options
|
||||
"-DCFG_TUSB_MCU=${tusb_mcu}"
|
||||
"-DCFG_TUSB_OS=OPT_OS_FREERTOS"
|
||||
#"-DCFG_TUSB_DEBUG=1"
|
||||
)
|
||||
|
||||
idf_component_get_property(freertos_component_dir freertos COMPONENT_DIR)
|
||||
|
||||
list(APPEND includes_public
|
||||
"${tusb_src}"
|
||||
# The FreeRTOS API include convention in tinyusb is different from esp-idf
|
||||
#"${freertos_component_dir}/include/freertos"
|
||||
)
|
||||
list(APPEND compile_definitions
|
||||
CFG_TUSB_MCU=${tusb_mcu}
|
||||
CFG_TUSB_OS=OPT_OS_FREERTOS
|
||||
)
|
||||
|
||||
list(APPEND srcs
|
||||
"${tusb_src}/tusb.c"
|
||||
"${tusb_src}/common/tusb_fifo.c"
|
||||
"${tusb_src}/device/usbd.c"
|
||||
"${tusb_src}/device/usbd_control.c"
|
||||
"${tusb_src}/class/cdc/cdc_device.c"
|
||||
"${tusb_src}/class/dfu/dfu_rt_device.c"
|
||||
"${tusb_src}/class/hid/hid_device.c"
|
||||
"${tusb_src}/class/midi/midi_device.c"
|
||||
"${tusb_src}/class/msc/msc_device.c"
|
||||
"${tusb_src}/class/net/ecm_rndis_device.c"
|
||||
"${tusb_src}/class/net/ncm_device.c"
|
||||
"${tusb_src}/class/usbtmc/usbtmc_device.c"
|
||||
"${tusb_src}/class/vendor/vendor_device.c"
|
||||
"${tusb_src}/portable/synopsys/dwc2/dcd_dwc2.c"
|
||||
)
|
||||
# common
|
||||
${tusb_src}/tusb.c
|
||||
${tusb_src}/common/tusb_fifo.c
|
||||
# device
|
||||
${tusb_src}/device/usbd.c
|
||||
${tusb_src}/device/usbd_control.c
|
||||
${tusb_src}/class/audio/audio_device.c
|
||||
${tusb_src}/class/cdc/cdc_device.c
|
||||
${tusb_src}/class/dfu/dfu_device.c
|
||||
${tusb_src}/class/dfu/dfu_rt_device.c
|
||||
${tusb_src}/class/hid/hid_device.c
|
||||
${tusb_src}/class/midi/midi_device.c
|
||||
${tusb_src}/class/msc/msc_device.c
|
||||
${tusb_src}/class/net/ecm_rndis_device.c
|
||||
${tusb_src}/class/net/ncm_device.c
|
||||
${tusb_src}/class/usbtmc/usbtmc_device.c
|
||||
${tusb_src}/class/vendor/vendor_device.c
|
||||
${tusb_src}/class/video/video_device.c
|
||||
${tusb_src}/portable/synopsys/dwc2/dcd_dwc2.c
|
||||
# host
|
||||
${tusb_src}/host/usbh.c
|
||||
${tusb_src}/host/hub.c
|
||||
${tusb_src}/class/cdc/cdc_host.c
|
||||
${tusb_src}/class/hid/hid_host.c
|
||||
${tusb_src}/class/msc/msc_host.c
|
||||
${tusb_src}/class/vendor/vendor_host.c
|
||||
)
|
||||
|
||||
# use max3421 as host controller
|
||||
if (MAX3421_HOST STREQUAL "1")
|
||||
list(APPEND srcs ${tusb_src}/portable/analog/max3421/hcd_max3421.c)
|
||||
list(APPEND compile_definitions CFG_TUH_MAX3421=1)
|
||||
endif ()
|
||||
|
||||
if (DEFINED LOG)
|
||||
list(APPEND compile_definitions CFG_TUSB_DEBUG=${LOG})
|
||||
if (LOG STREQUAL "4")
|
||||
# no inline for debug level 4
|
||||
list(APPEND compile_definitions TU_ATTR_ALWAYS_INLINE=)
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS ${srcs}
|
||||
INCLUDE_DIRS ${includes_public}
|
||||
REQUIRES src
|
||||
)
|
||||
INCLUDE_DIRS ${tusb_src}
|
||||
REQUIRES src
|
||||
)
|
||||
|
||||
target_compile_options(${COMPONENT_LIB} PUBLIC ${compile_options})
|
||||
target_compile_definitions(${COMPONENT_LIB} PUBLIC ${compile_definitions})
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-error=format)
|
||||
|
@ -40,6 +40,7 @@ if (NOT FAMILY STREQUAL rp2040)
|
||||
# enable LTO if supported skip rp2040
|
||||
include(CheckIPOSupported)
|
||||
check_ipo_supported(RESULT IPO_SUPPORTED)
|
||||
cmake_print_variables(IPO_SUPPORTED)
|
||||
if (IPO_SUPPORTED)
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
endif()
|
||||
|
@ -188,7 +188,7 @@ void USB_OTG1_IRQHandler(void)
|
||||
#endif
|
||||
|
||||
#if PORT_SUPPORT_HOST(0)
|
||||
tuh_int_handler(0);
|
||||
tuh_int_handler(0, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -199,7 +199,7 @@ void USB_OTG2_IRQHandler(void)
|
||||
#endif
|
||||
|
||||
#if PORT_SUPPORT_HOST(1)
|
||||
tuh_int_handler(1);
|
||||
tuh_int_handler(1, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
void USB0_IRQHandler(void)
|
||||
{
|
||||
#if CFG_TUH_ENABLED
|
||||
tuh_int_handler(0);
|
||||
tuh_int_handler(0, true);
|
||||
#endif
|
||||
#if CFG_TUD_ENABLED
|
||||
tud_int_handler(0);
|
||||
|
@ -22,48 +22,47 @@ set(FAMILY_MCUS KINETIS_KL CACHE INTERNAL "")
|
||||
#------------------------------------
|
||||
# only need to be built ONCE for all examples
|
||||
function(add_board_target BOARD_TARGET)
|
||||
if (NOT TARGET ${BOARD_TARGET})
|
||||
add_library(${BOARD_TARGET} STATIC
|
||||
${SDK_DIR}/drivers/gpio/fsl_gpio.c
|
||||
${SDK_DIR}/drivers/lpsci/fsl_lpsci.c
|
||||
${SDK_DIR}/drivers/uart/fsl_uart.c
|
||||
${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c
|
||||
${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_VARIANT}.c
|
||||
)
|
||||
target_compile_definitions(${BOARD_TARGET} PUBLIC
|
||||
)
|
||||
target_include_directories(${BOARD_TARGET} PUBLIC
|
||||
${CMSIS_DIR}/CMSIS/Core/Include
|
||||
${SDK_DIR}/devices/${MCU_VARIANT}
|
||||
${SDK_DIR}/devices/${MCU_VARIANT}/drivers
|
||||
${SDK_DIR}/drivers/common
|
||||
${SDK_DIR}/drivers/gpio
|
||||
${SDK_DIR}/drivers/lpsci
|
||||
${SDK_DIR}/drivers/port
|
||||
${SDK_DIR}/drivers/smc
|
||||
${SDK_DIR}/drivers/uart
|
||||
)
|
||||
if (TARGET ${BOARD_TARGET})
|
||||
return()
|
||||
endif ()
|
||||
|
||||
update_board(${BOARD_TARGET})
|
||||
add_library(${BOARD_TARGET} STATIC
|
||||
${SDK_DIR}/drivers/gpio/fsl_gpio.c
|
||||
${SDK_DIR}/drivers/lpsci/fsl_lpsci.c
|
||||
${SDK_DIR}/drivers/uart/fsl_uart.c
|
||||
${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c
|
||||
${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_VARIANT}.c
|
||||
)
|
||||
target_compile_definitions(${BOARD_TARGET} PUBLIC
|
||||
)
|
||||
target_include_directories(${BOARD_TARGET} PUBLIC
|
||||
${CMSIS_DIR}/CMSIS/Core/Include
|
||||
${SDK_DIR}/devices/${MCU_VARIANT}
|
||||
${SDK_DIR}/devices/${MCU_VARIANT}/drivers
|
||||
${SDK_DIR}/drivers/common
|
||||
${SDK_DIR}/drivers/gpio
|
||||
${SDK_DIR}/drivers/lpsci
|
||||
${SDK_DIR}/drivers/port
|
||||
${SDK_DIR}/drivers/smc
|
||||
${SDK_DIR}/drivers/uart
|
||||
)
|
||||
update_board(${BOARD_TARGET})
|
||||
|
||||
# LD_FILE and STARTUP_FILE can be defined in board.cmake
|
||||
# LD_FILE and STARTUP_FILE can be defined in board.cmake
|
||||
target_sources(${BOARD_TARGET} PUBLIC
|
||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||
)
|
||||
|
||||
target_sources(${BOARD_TARGET} PUBLIC
|
||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
target_link_options(${BOARD_TARGET} PUBLIC
|
||||
"LINKER:--script=${LD_FILE_GNU}"
|
||||
# nanolib
|
||||
--specs=nosys.specs --specs=nano.specs
|
||||
)
|
||||
elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
|
||||
target_link_options(${BOARD_TARGET} PUBLIC
|
||||
"LINKER:--config=${LD_FILE_IAR}"
|
||||
)
|
||||
|
||||
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
target_link_options(${BOARD_TARGET} PUBLIC
|
||||
"LINKER:--script=${LD_FILE_GNU}"
|
||||
# nanolib
|
||||
--specs=nosys.specs
|
||||
--specs=nano.specs
|
||||
)
|
||||
elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
|
||||
target_link_options(${BOARD_TARGET} PUBLIC
|
||||
"LINKER:--config=${LD_FILE_IAR}"
|
||||
)
|
||||
endif ()
|
||||
endif ()
|
||||
endfunction()
|
||||
|
||||
|
@ -37,7 +37,7 @@ void USB_IRQHandler(void)
|
||||
#endif
|
||||
|
||||
#if CFG_TUH_ENABLED
|
||||
tuh_int_handler(0);
|
||||
tuh_int_handler(0, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -151,7 +151,7 @@ void USB_IRQHandler(void)
|
||||
#endif
|
||||
|
||||
#if CFG_TUH_ENABLED
|
||||
tuh_int_handler(0);
|
||||
tuh_int_handler(0, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,8 @@ MCU_DIR = hw/mcu/nxp/lpcopen/lpc175x_6x/lpc_chip_175x_6x
|
||||
|
||||
SRC_C += \
|
||||
src/portable/nxp/lpc17_40/dcd_lpc17_40.c \
|
||||
src/portable/ohci/ohci.c \
|
||||
src/portable/nxp/lpc17_40/hcd_lpc17_40.c \
|
||||
$(MCU_DIR)/../gcc/cr_startup_lpc175x_6x.c \
|
||||
$(MCU_DIR)/src/chip_17xx_40xx.c \
|
||||
$(MCU_DIR)/src/clock_17xx_40xx.c \
|
||||
@ -29,7 +31,7 @@ SRC_C += \
|
||||
$(MCU_DIR)/src/iocon_17xx_40xx.c \
|
||||
$(MCU_DIR)/src/sysctl_17xx_40xx.c \
|
||||
$(MCU_DIR)/src/sysinit_17xx_40xx.c \
|
||||
$(MCU_DIR)/src/uart_17xx_40xx.c
|
||||
$(MCU_DIR)/src/uart_17xx_40xx.c \
|
||||
|
||||
INC += \
|
||||
$(TOP)/$(MCU_DIR)/inc
|
||||
|
@ -43,25 +43,23 @@
|
||||
//--------------------------------------------------------------------+
|
||||
// USB Interrupt Handler
|
||||
//--------------------------------------------------------------------+
|
||||
void USB0_IRQHandler(void)
|
||||
{
|
||||
void USB0_IRQHandler(void) {
|
||||
#if PORT_SUPPORT_DEVICE(0)
|
||||
tud_int_handler(0);
|
||||
tud_int_handler(0);
|
||||
#endif
|
||||
|
||||
#if PORT_SUPPORT_HOST(0)
|
||||
tuh_int_handler(0);
|
||||
tuh_int_handler(0, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void USB1_IRQHandler(void)
|
||||
{
|
||||
void USB1_IRQHandler(void) {
|
||||
#if PORT_SUPPORT_DEVICE(1)
|
||||
tud_int_handler(1);
|
||||
tud_int_handler(1);
|
||||
#endif
|
||||
|
||||
#if PORT_SUPPORT_HOST(1)
|
||||
tuh_int_handler(1);
|
||||
tuh_int_handler(1, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -74,28 +72,26 @@ const uint32_t OscRateIn = 12000000;
|
||||
const uint32_t ExtRateIn = 0;
|
||||
|
||||
// Invoked by startup code
|
||||
void SystemInit(void)
|
||||
{
|
||||
void SystemInit(void) {
|
||||
#ifdef __USE_LPCOPEN
|
||||
extern void (* const g_pfnVectors[])(void);
|
||||
extern void (*const g_pfnVectors[])(void);
|
||||
unsigned int *pSCB_VTOR = (unsigned int *) 0xE000ED08;
|
||||
*pSCB_VTOR = (unsigned int) g_pfnVectors;
|
||||
*pSCB_VTOR = (unsigned int) g_pfnVectors;
|
||||
#endif
|
||||
|
||||
board_lpc18_pinmux();
|
||||
|
||||
#ifdef TRACE_ETM
|
||||
#ifdef TRACE_ETM
|
||||
// Trace clock is limited to 60MHz, limit CPU clock to 120MHz
|
||||
Chip_SetupCoreClock(CLKIN_CRYSTAL, 120000000UL, true);
|
||||
#else
|
||||
#else
|
||||
// CPU clock max to 180 Mhz
|
||||
Chip_SetupCoreClock(CLKIN_CRYSTAL, MAX_CLOCK_FREQ, true);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void board_init(void)
|
||||
{
|
||||
void board_init(void) {
|
||||
SystemCoreClockUpdate();
|
||||
|
||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||
@ -135,27 +131,22 @@ void board_init(void)
|
||||
// Board porting API
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
void board_led_write(bool state)
|
||||
{
|
||||
void board_led_write(bool state) {
|
||||
Chip_GPIO_SetPinState(LPC_GPIO_PORT, LED_PORT, LED_PIN, state);
|
||||
}
|
||||
|
||||
uint32_t board_button_read(void)
|
||||
{
|
||||
uint32_t board_button_read(void) {
|
||||
// active low
|
||||
return Chip_GPIO_GetPinState(LPC_GPIO_PORT, BUTTON_PORT, BUTTON_PIN) ? 0 : 1;
|
||||
}
|
||||
|
||||
int board_uart_read(uint8_t* buf, int len)
|
||||
{
|
||||
int board_uart_read(uint8_t *buf, int len) {
|
||||
return Chip_UART_Read(UART_DEV, buf, len);
|
||||
}
|
||||
|
||||
int board_uart_write(void const * buf, int len)
|
||||
{
|
||||
uint8_t const* buf8 = (uint8_t const*) buf;
|
||||
for(int i=0; i<len; i++)
|
||||
{
|
||||
int board_uart_write(void const *buf, int len) {
|
||||
uint8_t const *buf8 = (uint8_t const *) buf;
|
||||
for (int i = 0; i < len; i++) {
|
||||
while ((Chip_UART_ReadLineStatus(UART_DEV) & UART_LSR_THRE) == 0) {}
|
||||
Chip_UART_SendByte(UART_DEV, buf8[i]);
|
||||
}
|
||||
@ -165,13 +156,13 @@ int board_uart_write(void const * buf, int len)
|
||||
|
||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||
volatile uint32_t system_ticks = 0;
|
||||
void SysTick_Handler (void)
|
||||
{
|
||||
|
||||
void SysTick_Handler(void) {
|
||||
system_ticks++;
|
||||
}
|
||||
|
||||
uint32_t board_millis(void)
|
||||
{
|
||||
uint32_t board_millis(void) {
|
||||
return system_ticks;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -37,7 +37,7 @@ void USB_IRQHandler(void) {
|
||||
#endif
|
||||
|
||||
#if CFG_TUH_ENABLED
|
||||
tuh_int_handler(0);
|
||||
tuh_int_handler(0, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -213,7 +213,7 @@ void USB0_IRQHandler(void)
|
||||
#endif
|
||||
|
||||
#if PORT_SUPPORT_HOST(0)
|
||||
tuh_int_handler(0);
|
||||
tuh_int_handler(0, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -224,7 +224,7 @@ void USB1_IRQHandler(void)
|
||||
#endif
|
||||
|
||||
#if PORT_SUPPORT_HOST(1)
|
||||
tuh_int_handler(1);
|
||||
tuh_int_handler(1, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
165
hw/bsp/lpc54/FreeRTOSConfig/FreeRTOSConfig.h
Normal file
165
hw/bsp/lpc54/FreeRTOSConfig/FreeRTOSConfig.h
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.0.0
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* 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. If you wish to use our Amazon
|
||||
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FREERTOS_CONFIG_H
|
||||
#define FREERTOS_CONFIG_H
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Application specific definitions.
|
||||
*
|
||||
* These definitions should be adjusted for your particular hardware and
|
||||
* application requirements.
|
||||
*
|
||||
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||
*
|
||||
* See http://www.freertos.org/a00110.html.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
// skip if included from IAR assembler
|
||||
#ifndef __IASMARM__
|
||||
#include "fsl_device_registers.h"
|
||||
#endif
|
||||
|
||||
/* Cortex M23/M33 port configuration. */
|
||||
#define configENABLE_MPU 0
|
||||
#define configENABLE_FPU 1
|
||||
#define configENABLE_TRUSTZONE 0
|
||||
#define configMINIMAL_SECURE_STACK_SIZE (1024)
|
||||
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#define configCPU_CLOCK_HZ SystemCoreClock
|
||||
#define configTICK_RATE_HZ ( 1000 )
|
||||
#define configMAX_PRIORITIES ( 5 )
|
||||
#define configMINIMAL_STACK_SIZE ( 128 )
|
||||
#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 )
|
||||
#define configMAX_TASK_NAME_LEN 16
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configIDLE_SHOULD_YIELD 1
|
||||
#define configUSE_MUTEXES 1
|
||||
#define configUSE_RECURSIVE_MUTEXES 1
|
||||
#define configUSE_COUNTING_SEMAPHORES 1
|
||||
#define configQUEUE_REGISTRY_SIZE 4
|
||||
#define configUSE_QUEUE_SETS 0
|
||||
#define configUSE_TIME_SLICING 0
|
||||
#define configUSE_NEWLIB_REENTRANT 0
|
||||
#define configENABLE_BACKWARD_COMPATIBILITY 1
|
||||
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
|
||||
|
||||
#define configSUPPORT_STATIC_ALLOCATION 0
|
||||
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||
|
||||
/* Hook function related definitions. */
|
||||
#define configUSE_IDLE_HOOK 0
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||
|
||||
/* Run time and task stats gathering related definitions. */
|
||||
#define configGENERATE_RUN_TIME_STATS 0
|
||||
#define configRECORD_STACK_HIGH_ADDRESS 1
|
||||
#define configUSE_TRACE_FACILITY 1 // legacy trace
|
||||
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
|
||||
|
||||
/* Co-routine definitions. */
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES 2
|
||||
|
||||
/* Software timer related definitions. */
|
||||
#define configUSE_TIMERS 1
|
||||
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2)
|
||||
#define configTIMER_QUEUE_LENGTH 32
|
||||
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
|
||||
|
||||
/* Optional functions - most linkers will remove unused functions anyway. */
|
||||
#define INCLUDE_vTaskPrioritySet 0
|
||||
#define INCLUDE_uxTaskPriorityGet 0
|
||||
#define INCLUDE_vTaskDelete 0
|
||||
#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY
|
||||
#define INCLUDE_xResumeFromISR 0
|
||||
#define INCLUDE_vTaskDelayUntil 1
|
||||
#define INCLUDE_vTaskDelay 1
|
||||
#define INCLUDE_xTaskGetSchedulerState 0
|
||||
#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark 0
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 0
|
||||
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
|
||||
#define INCLUDE_pcTaskGetTaskName 0
|
||||
#define INCLUDE_eTaskGetState 0
|
||||
#define INCLUDE_xEventGroupSetBitFromISR 0
|
||||
#define INCLUDE_xTimerPendFunctionCall 0
|
||||
|
||||
/* Define to trap errors during development. */
|
||||
// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7
|
||||
#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__)
|
||||
#define configASSERT(_exp) \
|
||||
do {\
|
||||
if ( !(_exp) ) { \
|
||||
volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \
|
||||
if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \
|
||||
taskDISABLE_INTERRUPTS(); \
|
||||
__asm("BKPT #0\n"); \
|
||||
}\
|
||||
}\
|
||||
} while(0)
|
||||
#else
|
||||
#define configASSERT( x )
|
||||
#endif
|
||||
|
||||
/* FreeRTOS hooks to NVIC vectors */
|
||||
#define xPortPendSVHandler PendSV_Handler
|
||||
#define xPortSysTickHandler SysTick_Handler
|
||||
#define vPortSVCHandler SVC_Handler
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Interrupt nesting behavior configuration.
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header
|
||||
#define configPRIO_BITS 3
|
||||
|
||||
/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
|
||||
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<configPRIO_BITS) - 1)
|
||||
|
||||
/* The highest interrupt priority that can be used by any interrupt service
|
||||
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
|
||||
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
|
||||
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
|
||||
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2
|
||||
|
||||
/* Interrupt priorities used by the kernel port layer itself. These are generic
|
||||
to all Cortex-M ports, and do not rely on any particular library functions. */
|
||||
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||
|
||||
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
|
||||
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
|
||||
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||
|
||||
#endif
|
21
hw/bsp/lpc54/boards/lpcxpresso54114/board.cmake
Normal file
21
hw/bsp/lpc54/boards/lpcxpresso54114/board.cmake
Normal file
@ -0,0 +1,21 @@
|
||||
set(MCU_VARIANT LPC54114)
|
||||
set(MCU_CORE LPC54114_cm4)
|
||||
|
||||
set(JLINK_DEVICE LPC54114J256_M4)
|
||||
set(PYOCD_TARGET LPC54114)
|
||||
|
||||
set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/LPC54114J256_cm4_flash.ld)
|
||||
|
||||
# Device port default to PORT1 Highspeed
|
||||
if (NOT DEFINED PORT)
|
||||
set(PORT 1)
|
||||
endif()
|
||||
|
||||
function(update_board TARGET)
|
||||
target_compile_definitions(${TARGET} PUBLIC
|
||||
CPU_LPC54114J256BD64_cm4
|
||||
)
|
||||
target_link_libraries(${TARGET} PUBLIC
|
||||
${SDK_DIR}/devices/${MCU_VARIANT}/gcc/libpower_cm4_hardabi.a
|
||||
)
|
||||
endfunction()
|
22
hw/bsp/lpc54/boards/lpcxpresso54608/board.cmake
Normal file
22
hw/bsp/lpc54/boards/lpcxpresso54608/board.cmake
Normal file
@ -0,0 +1,22 @@
|
||||
set(MCU_VARIANT LPC54608)
|
||||
set(MCU_CORE LPC54608)
|
||||
|
||||
set(JLINK_DEVICE LPC54608J512)
|
||||
set(PYOCD_TARGET LPC54608)
|
||||
set(NXPLINK_DEVICE LPC54608:LPCXpresso54608)
|
||||
|
||||
set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/LPC54608J512_flash.ld)
|
||||
|
||||
# Device port default to PORT1 Highspeed
|
||||
if (NOT DEFINED PORT)
|
||||
set(PORT 1)
|
||||
endif()
|
||||
|
||||
function(update_board TARGET)
|
||||
target_compile_definitions(${TARGET} PUBLIC
|
||||
CPU_LPC54608J512ET180
|
||||
)
|
||||
target_link_libraries(${TARGET} PUBLIC
|
||||
${SDK_DIR}/devices/${MCU_VARIANT}/gcc/libpower_hardabi.a
|
||||
)
|
||||
endfunction()
|
@ -28,83 +28,85 @@ set(HOST_PORT $<NOT:${PORT}>)
|
||||
#------------------------------------
|
||||
# only need to be built ONCE for all examples
|
||||
function(add_board_target BOARD_TARGET)
|
||||
if (NOT TARGET ${BOARD_TARGET})
|
||||
add_library(${BOARD_TARGET} STATIC
|
||||
# driver
|
||||
${SDK_DIR}/drivers/lpc_gpio/fsl_gpio.c
|
||||
${SDK_DIR}/drivers/common/fsl_common_arm.c
|
||||
${SDK_DIR}/drivers/flexcomm/fsl_flexcomm.c
|
||||
${SDK_DIR}/drivers/flexcomm/fsl_usart.c
|
||||
# mcu
|
||||
${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_CORE}.c
|
||||
${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c
|
||||
${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_power.c
|
||||
${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_reset.c
|
||||
)
|
||||
if (TARGET ${BOARD_TARGET})
|
||||
return()
|
||||
endif()
|
||||
|
||||
add_library(${BOARD_TARGET} STATIC
|
||||
# driver
|
||||
${SDK_DIR}/drivers/lpc_gpio/fsl_gpio.c
|
||||
${SDK_DIR}/drivers/common/fsl_common_arm.c
|
||||
${SDK_DIR}/drivers/flexcomm/fsl_flexcomm.c
|
||||
${SDK_DIR}/drivers/flexcomm/fsl_usart.c
|
||||
# mcu
|
||||
${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_CORE}.c
|
||||
${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c
|
||||
${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_power.c
|
||||
${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_reset.c
|
||||
)
|
||||
|
||||
target_compile_definitions(${BOARD_TARGET} PUBLIC
|
||||
CFG_TUSB_MEM_ALIGN=TU_ATTR_ALIGNED\(64\)
|
||||
BOARD_TUD_RHPORT=${PORT}
|
||||
BOARD_TUH_RHPORT=${HOST_PORT}
|
||||
)
|
||||
# Port 0 is Fullspeed, Port 1 is Highspeed. Port1 controller can only access USB_SRAM
|
||||
if (PORT EQUAL 1)
|
||||
target_compile_definitions(${BOARD_TARGET} PUBLIC
|
||||
CFG_TUSB_MEM_ALIGN=TU_ATTR_ALIGNED\(64\)
|
||||
BOARD_TUD_RHPORT=${PORT}
|
||||
BOARD_TUH_RHPORT=${HOST_PORT}
|
||||
BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED
|
||||
BOARD_TUH_MAX_SPEED=OPT_MODE_FULL_SPEED
|
||||
CFG_TUD_MEM_SECTION=__attribute__\(\(section\(\"m_usb_global\"\)\)\)
|
||||
)
|
||||
# Port 0 is Fullspeed, Port 1 is Highspeed. Port1 controller can only access USB_SRAM
|
||||
if (PORT EQUAL 1)
|
||||
target_compile_definitions(${BOARD_TARGET} PUBLIC
|
||||
BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED
|
||||
BOARD_TUH_MAX_SPEED=OPT_MODE_FULL_SPEED
|
||||
CFG_TUD_MEM_SECTION=__attribute__\(\(section\(\"m_usb_global\"\)\)\)
|
||||
)
|
||||
else ()
|
||||
target_compile_definitions(${BOARD_TARGET} PUBLIC
|
||||
BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED
|
||||
BOARD_TUH_MAX_SPEED=OPT_MODE_HIGH_SPEED
|
||||
CFG_TUH_MEM_SECTION=__attribute__\(\(section\(\"m_usb_global\"\)\)\)
|
||||
#CFG_TUD_MEM_SECTION=__attribute__\(\(section\(\"m_usb_global\"\)\)\)
|
||||
)
|
||||
endif ()
|
||||
|
||||
target_include_directories(${BOARD_TARGET} PUBLIC
|
||||
${TOP}/lib/sct_neopixel
|
||||
# driver
|
||||
${SDK_DIR}/drivers/common
|
||||
${SDK_DIR}/drivers/flexcomm
|
||||
${SDK_DIR}/drivers/lpc_iocon
|
||||
${SDK_DIR}/drivers/lpc_gpio
|
||||
${SDK_DIR}/drivers/lpuart
|
||||
${SDK_DIR}/drivers/sctimer
|
||||
# mcu
|
||||
${CMSIS_DIR}/CMSIS/Core/Include
|
||||
${SDK_DIR}/devices/${MCU_VARIANT}
|
||||
${SDK_DIR}/devices/${MCU_VARIANT}/drivers
|
||||
else ()
|
||||
target_compile_definitions(${BOARD_TARGET} PUBLIC
|
||||
BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED
|
||||
BOARD_TUH_MAX_SPEED=OPT_MODE_HIGH_SPEED
|
||||
CFG_TUH_MEM_SECTION=__attribute__\(\(section\(\"m_usb_global\"\)\)\)
|
||||
#CFG_TUD_MEM_SECTION=__attribute__\(\(section\(\"m_usb_global\"\)\)\)
|
||||
)
|
||||
endif ()
|
||||
|
||||
update_board(${BOARD_TARGET})
|
||||
target_include_directories(${BOARD_TARGET} PUBLIC
|
||||
${TOP}/lib/sct_neopixel
|
||||
# driver
|
||||
${SDK_DIR}/drivers/common
|
||||
${SDK_DIR}/drivers/flexcomm
|
||||
${SDK_DIR}/drivers/lpc_iocon
|
||||
${SDK_DIR}/drivers/lpc_gpio
|
||||
${SDK_DIR}/drivers/lpuart
|
||||
${SDK_DIR}/drivers/sctimer
|
||||
# mcu
|
||||
${CMSIS_DIR}/CMSIS/Core/Include
|
||||
${SDK_DIR}/devices/${MCU_VARIANT}
|
||||
${SDK_DIR}/devices/${MCU_VARIANT}/drivers
|
||||
)
|
||||
|
||||
if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID})
|
||||
set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld)
|
||||
endif ()
|
||||
update_board(${BOARD_TARGET})
|
||||
|
||||
if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID})
|
||||
set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_CORE}.S)
|
||||
endif ()
|
||||
if (NOT DEFINED LD_FILE_${CMAKE_C_COMPILER_ID})
|
||||
set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld)
|
||||
endif ()
|
||||
|
||||
target_sources(${BOARD_TARGET} PUBLIC
|
||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||
if (NOT DEFINED STARTUP_FILE_${CMAKE_C_COMPILER_ID})
|
||||
set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_CORE}.S)
|
||||
endif ()
|
||||
|
||||
target_sources(${BOARD_TARGET} PUBLIC
|
||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||
)
|
||||
|
||||
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
target_link_options(${BOARD_TARGET} PUBLIC
|
||||
# linker file
|
||||
"LINKER:--script=${LD_FILE_GNU}"
|
||||
# nanolib
|
||||
--specs=nosys.specs
|
||||
--specs=nano.specs
|
||||
)
|
||||
elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
|
||||
target_link_options(${BOARD_TARGET} PUBLIC
|
||||
"LINKER:--config=${LD_FILE_IAR}"
|
||||
)
|
||||
|
||||
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
target_link_options(${BOARD_TARGET} PUBLIC
|
||||
# linker file
|
||||
"LINKER:--script=${LD_FILE_GNU}"
|
||||
# nanolib
|
||||
--specs=nosys.specs
|
||||
--specs=nano.specs
|
||||
)
|
||||
elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
|
||||
target_link_options(${BOARD_TARGET} PUBLIC
|
||||
"LINKER:--config=${LD_FILE_IAR}"
|
||||
)
|
||||
endif ()
|
||||
endif ()
|
||||
endfunction()
|
||||
|
||||
@ -124,8 +126,6 @@ function(family_configure_example TARGET RTOS)
|
||||
# BSP
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
||||
# external driver
|
||||
${TOP}/lib/sct_neopixel/sct_neopixel.c
|
||||
)
|
||||
|
||||
# https://github.com/gsteiert/sct_neopixel/pull/1
|
||||
|
@ -34,7 +34,7 @@
|
||||
void USB0_IRQHandler(void)
|
||||
{
|
||||
#if CFG_TUH_ENABLED
|
||||
tuh_int_handler(0);
|
||||
tuh_int_handler(0, true);
|
||||
#endif
|
||||
#if CFG_TUD_ENABLED
|
||||
tud_int_handler(0);
|
||||
|
@ -214,7 +214,7 @@ void USB0_IRQHandler(void)
|
||||
#endif
|
||||
|
||||
#if PORT_SUPPORT_HOST(0)
|
||||
tuh_int_handler(0);
|
||||
tuh_int_handler(0, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -225,7 +225,7 @@ void USB1_IRQHandler(void)
|
||||
#endif
|
||||
|
||||
#if PORT_SUPPORT_HOST(1)
|
||||
tuh_int_handler(1);
|
||||
tuh_int_handler(1, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
set(MCU_VARIANT nrf52840)
|
||||
#set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/nrf52840_s140_v6.ld)
|
||||
set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf52840_xxaa.ld)
|
||||
set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/nrf52840_s140_v6.ld)
|
||||
#set(LD_FILE_GNU ${NRFX_DIR}/mdk/nrf52840_xxaa.ld)
|
||||
|
||||
# enable max3421 host driver for this board
|
||||
set(MAX3421_HOST 1)
|
||||
|
@ -49,8 +49,8 @@
|
||||
#define MAX3421_SCK_PIN 14
|
||||
#define MAX3421_MOSI_PIN 13
|
||||
#define MAX3421_MISO_PIN 15
|
||||
#define MAX3421_CS_PIN 27
|
||||
#define MAX3421_INTR_PIN 26
|
||||
#define MAX3421_CS_PIN 27 // D10
|
||||
#define MAX3421_INTR_PIN 26 // D9
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -95,13 +95,10 @@ TU_ATTR_UNUSED static void power_event_handler(nrfx_power_usb_evt_t event) {
|
||||
|
||||
//------------- Host using MAX2341E -------------//
|
||||
#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
|
||||
|
||||
static void max3421_init(void);
|
||||
|
||||
static nrfx_spim_t _spi = NRFX_SPIM_INSTANCE(1);
|
||||
|
||||
void max3421_int_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
|
||||
if (!(pin == MAX3421_INTR_PIN && action == NRF_GPIOTE_POLARITY_HITOLO)) return;
|
||||
|
||||
tuh_int_handler(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -191,50 +188,7 @@ void board_init(void) {
|
||||
#endif
|
||||
|
||||
#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
|
||||
// MAX3421 need 3.3v signal (may not be needed)
|
||||
#if defined(UICR_REGOUT0_VOUT_Msk) && 0
|
||||
if ((NRF_UICR->REGOUT0 & UICR_REGOUT0_VOUT_Msk) != UICR_REGOUT0_VOUT_3V3) {
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||
|
||||
NRF_UICR->REGOUT0 = (NRF_UICR->REGOUT0 & ~UICR_REGOUT0_VOUT_Msk) | UICR_REGOUT0_VOUT_3V3;
|
||||
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
#endif
|
||||
|
||||
// manually manage CS
|
||||
nrf_gpio_cfg_output(MAX3421_CS_PIN);
|
||||
nrf_gpio_pin_write(MAX3421_CS_PIN, 1);
|
||||
|
||||
// USB host using max3421e usb controller via SPI
|
||||
nrfx_spim_config_t cfg = {
|
||||
.sck_pin = MAX3421_SCK_PIN,
|
||||
.mosi_pin = MAX3421_MOSI_PIN,
|
||||
.miso_pin = MAX3421_MISO_PIN,
|
||||
.ss_pin = NRFX_SPIM_PIN_NOT_USED,
|
||||
.ss_active_high = false,
|
||||
.irq_priority = 3,
|
||||
.orc = 0xFF,
|
||||
// default setting 4 Mhz, Mode 0, MSB first
|
||||
.frequency = NRF_SPIM_FREQ_4M,
|
||||
.mode = NRF_SPIM_MODE_0,
|
||||
.bit_order = NRF_SPIM_BIT_ORDER_MSB_FIRST,
|
||||
};
|
||||
|
||||
// no handler --> blocking
|
||||
nrfx_spim_init(&_spi, &cfg, NULL, NULL);
|
||||
|
||||
// max3421e interrupt pin
|
||||
nrfx_gpiote_init(1);
|
||||
nrfx_gpiote_in_config_t in_config = NRFX_GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
|
||||
in_config.pull = NRF_GPIO_PIN_PULLUP;
|
||||
|
||||
nrfx_gpiote_in_init(MAX3421_INTR_PIN, &in_config, max3421_int_handler);
|
||||
nrfx_gpiote_trigger_enable(MAX3421_INTR_PIN, true);
|
||||
max3421_init();
|
||||
#endif
|
||||
|
||||
}
|
||||
@ -251,15 +205,15 @@ uint32_t board_button_read(void) {
|
||||
return BUTTON_STATE_ACTIVE == nrf_gpio_pin_read(BUTTON_PIN);
|
||||
}
|
||||
|
||||
int board_uart_read(uint8_t *buf, int len) {
|
||||
int board_uart_read(uint8_t* buf, int len) {
|
||||
(void) buf;
|
||||
(void) len;
|
||||
return 0;
|
||||
// return NRFX_SUCCESS == nrfx_uart_rx(&_uart_id, buf, (size_t) len) ? len : 0;
|
||||
}
|
||||
|
||||
int board_uart_write(void const *buf, int len) {
|
||||
return (NRFX_SUCCESS == nrfx_uarte_tx(&_uart_id, (uint8_t const *) buf, (size_t) len)) ? len : 0;
|
||||
int board_uart_write(void const* buf, int len) {
|
||||
return (NRFX_SUCCESS == nrfx_uarte_tx(&_uart_id, (uint8_t const*) buf, (size_t) len)) ? len : 0;
|
||||
}
|
||||
|
||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||
@ -317,6 +271,61 @@ void nrf_error_cb(uint32_t id, uint32_t pc, uint32_t info) {
|
||||
//--------------------------------------------------------------------+
|
||||
#if CFG_TUH_ENABLED && defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
|
||||
|
||||
void max3421_int_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
|
||||
if (!(pin == MAX3421_INTR_PIN && action == NRF_GPIOTE_POLARITY_HITOLO)) return;
|
||||
tuh_int_handler(1, true);
|
||||
}
|
||||
|
||||
static void max3421_init(void) {
|
||||
// MAX3421 need 3.3v signal (may not be needed)
|
||||
// #if defined(UICR_REGOUT0_VOUT_Msk)
|
||||
// if ((NRF_UICR->REGOUT0 & UICR_REGOUT0_VOUT_Msk) != UICR_REGOUT0_VOUT_3V3) {
|
||||
// NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
|
||||
// while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||
//
|
||||
// NRF_UICR->REGOUT0 = (NRF_UICR->REGOUT0 & ~UICR_REGOUT0_VOUT_Msk) | UICR_REGOUT0_VOUT_3V3;
|
||||
//
|
||||
// NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
|
||||
// while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
|
||||
//
|
||||
// NVIC_SystemReset();
|
||||
// }
|
||||
// #endif
|
||||
|
||||
// manually manage CS
|
||||
nrf_gpio_cfg_output(MAX3421_CS_PIN);
|
||||
nrf_gpio_pin_write(MAX3421_CS_PIN, 1);
|
||||
|
||||
// USB host using max3421e usb controller via SPI
|
||||
nrfx_spim_config_t cfg = {
|
||||
.sck_pin = MAX3421_SCK_PIN,
|
||||
.mosi_pin = MAX3421_MOSI_PIN,
|
||||
.miso_pin = MAX3421_MISO_PIN,
|
||||
.ss_pin = NRFX_SPIM_PIN_NOT_USED,
|
||||
.ss_active_high = false,
|
||||
.irq_priority = 3,
|
||||
.orc = 0xFF,
|
||||
// default setting 4 Mhz, Mode 0, MSB first
|
||||
.frequency = NRF_SPIM_FREQ_4M,
|
||||
.mode = NRF_SPIM_MODE_0,
|
||||
.bit_order = NRF_SPIM_BIT_ORDER_MSB_FIRST,
|
||||
};
|
||||
|
||||
// no handler --> blocking
|
||||
nrfx_spim_init(&_spi, &cfg, NULL, NULL);
|
||||
|
||||
// max3421e interrupt pin
|
||||
nrfx_gpiote_init(1);
|
||||
nrfx_gpiote_in_config_t in_config = NRFX_GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
|
||||
in_config.pull = NRF_GPIO_PIN_PULLUP;
|
||||
|
||||
NVIC_SetPriority(GPIOTE_IRQn, 2);
|
||||
|
||||
nrfx_gpiote_in_init(MAX3421_INTR_PIN, &in_config, max3421_int_handler);
|
||||
nrfx_gpiote_trigger_enable(MAX3421_INTR_PIN, true);
|
||||
}
|
||||
|
||||
// API to enable/disable MAX3421 INTR pin interrupt
|
||||
void tuh_max3421_int_api(uint8_t rhport, bool enabled) {
|
||||
(void) rhport;
|
||||
|
||||
@ -329,22 +338,25 @@ void tuh_max3421_int_api(uint8_t rhport, bool enabled) {
|
||||
}
|
||||
}
|
||||
|
||||
// API to control MAX3421 SPI CS
|
||||
void tuh_max3421_spi_cs_api(uint8_t rhport, bool active) {
|
||||
(void) rhport;
|
||||
nrf_gpio_pin_write(MAX3421_CS_PIN, active ? 0 : 1);
|
||||
}
|
||||
|
||||
bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const *tx_buf, size_t tx_len, uint8_t *rx_buf, size_t rx_len) {
|
||||
// API to transfer data with MAX3421 SPI
|
||||
// Either tx_buf or rx_buf can be NULL, which means transfer is write or read only
|
||||
bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint8_t* rx_buf, size_t xfer_bytes) {
|
||||
(void) rhport;
|
||||
|
||||
nrfx_spim_xfer_desc_t xfer = {
|
||||
.p_tx_buffer = tx_buf,
|
||||
.tx_length = tx_len,
|
||||
.tx_length = tx_buf ? xfer_bytes : 0,
|
||||
.p_rx_buffer = rx_buf,
|
||||
.rx_length = rx_len,
|
||||
.rx_length = rx_buf ? xfer_bytes : 0,
|
||||
};
|
||||
|
||||
return (nrfx_spim_xfer(&_spi, &xfer, 0) == NRFX_SUCCESS);
|
||||
return nrfx_spim_xfer(&_spi, &xfer, 0) == NRFX_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -188,7 +188,7 @@ void usbfs_interrupt_handler(void) {
|
||||
R_BSP_IrqStatusClear(irq);
|
||||
|
||||
#if PORT_SUPPORT_HOST(0)
|
||||
tuh_int_handler(0);
|
||||
tuh_int_handler(0, true);
|
||||
#endif
|
||||
|
||||
#if PORT_SUPPORT_DEVICE(0)
|
||||
@ -201,7 +201,7 @@ void usbfs_resume_handler(void) {
|
||||
R_BSP_IrqStatusClear(irq);
|
||||
|
||||
#if PORT_SUPPORT_HOST(0)
|
||||
tuh_int_handler(0);
|
||||
tuh_int_handler(0, true);
|
||||
#endif
|
||||
|
||||
#if PORT_SUPPORT_DEVICE(0)
|
||||
@ -229,7 +229,7 @@ void usbhs_interrupt_handler(void) {
|
||||
R_BSP_IrqStatusClear(irq);
|
||||
|
||||
#if PORT_SUPPORT_HOST(1)
|
||||
tuh_int_handler(1);
|
||||
tuh_int_handler(1, true);
|
||||
#endif
|
||||
|
||||
#if PORT_SUPPORT_DEVICE(1)
|
||||
|
@ -177,7 +177,7 @@ void INT_Excep_SCI5_RXI5(void)
|
||||
void INT_Excep_USB0_USBI0(void)
|
||||
{
|
||||
#if CFG_TUH_ENABLED
|
||||
tuh_int_handler(0);
|
||||
tuh_int_handler(0, true);
|
||||
#endif
|
||||
#if CFG_TUD_ENABLED
|
||||
tud_int_handler(0);
|
||||
|
@ -72,6 +72,7 @@ static void uart_init(void);
|
||||
#define MAX3421_SERCOM TU_XSTRCAT(SERCOM, MAX3421_SERCOM_ID)
|
||||
|
||||
static void max3421_init(void);
|
||||
|
||||
#endif
|
||||
|
||||
void board_init(void) {
|
||||
@ -237,13 +238,13 @@ int board_uart_write(void const * buf, int len)
|
||||
static void uart_init(void) {
|
||||
}
|
||||
|
||||
int board_uart_read(uint8_t *buf, int len) {
|
||||
int board_uart_read(uint8_t* buf, int len) {
|
||||
(void) buf;
|
||||
(void) len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_uart_write(void const *buf, int len) {
|
||||
int board_uart_write(void const* buf, int len) {
|
||||
(void) buf;
|
||||
(void) len;
|
||||
return 0;
|
||||
@ -262,6 +263,8 @@ uint32_t board_millis(void) {
|
||||
return system_ticks;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
//
|
||||
//--------------------------------------------------------------------+
|
||||
@ -269,15 +272,16 @@ uint32_t board_millis(void) {
|
||||
|
||||
static void max3421_init(void) {
|
||||
//------------- SPI Init -------------//
|
||||
uint32_t const baudrate = 4000000u;
|
||||
// MAX3421E max SPI clock is 26MHz however SAMD can only work reliably at 12 Mhz
|
||||
uint32_t const baudrate = 12000000u;
|
||||
|
||||
// Enable the APB clock for SERCOM
|
||||
PM->APBCMASK.reg |= 1u << (PM_APBCMASK_SERCOM0_Pos + MAX3421_SERCOM_ID);
|
||||
|
||||
// Configure GCLK for SERCOM
|
||||
// GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_SERCOM4_CORE | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_CLKEN;
|
||||
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(GCLK_CLKCTRL_ID_SERCOM0_CORE_Val+MAX3421_SERCOM_ID) |
|
||||
GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_CLKEN;
|
||||
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(GCLK_CLKCTRL_ID_SERCOM0_CORE_Val + MAX3421_SERCOM_ID) |
|
||||
GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_CLKEN;
|
||||
while (GCLK->STATUS.bit.SYNCBUSY);
|
||||
|
||||
Sercom* sercom = MAX3421_SERCOM;
|
||||
@ -291,7 +295,7 @@ static void max3421_init(void) {
|
||||
|
||||
// Set up SPI in master mode, MSB first, SPI mode 0
|
||||
sercom->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_DOPO(MAX3421_TX_PAD) | SERCOM_SPI_CTRLA_DIPO(MAX3421_RX_PAD) |
|
||||
SERCOM_SPI_CTRLA_MODE(3);
|
||||
SERCOM_SPI_CTRLA_MODE(3);
|
||||
|
||||
sercom->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_CHSIZE(0) | SERCOM_SPI_CTRLB_RXEN;
|
||||
while (sercom->SPI.SYNCBUSY.bit.CTRLB == 1);
|
||||
@ -343,6 +347,11 @@ static void max3421_init(void) {
|
||||
EIC->CONFIG[0].reg &= ~(7 << sense_shift);
|
||||
EIC->CONFIG[0].reg |= 2 << sense_shift;
|
||||
|
||||
#if CFG_TUSB_OS == OPT_OS_FREERTOS
|
||||
// If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
|
||||
NVIC_SetPriority(EIC_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
|
||||
#endif
|
||||
|
||||
// Enable External Interrupt
|
||||
EIC->INTENSET.reg = EIC_INTENSET_EXTINT(1 << MAX3421_INTR_EIC_ID);
|
||||
|
||||
@ -356,9 +365,10 @@ void EIC_Handler(void) {
|
||||
EIC->INTFLAG.reg = EIC_INTFLAG_EXTINT(1 << MAX3421_INTR_EIC_ID);
|
||||
|
||||
// Call the TinyUSB interrupt handler
|
||||
tuh_int_handler(1);
|
||||
tuh_int_handler(1, true);
|
||||
}
|
||||
|
||||
// API to enable/disable MAX3421 INTR pin interrupt
|
||||
void tuh_max3421_int_api(uint8_t rhport, bool enabled) {
|
||||
(void) rhport;
|
||||
|
||||
@ -369,24 +379,26 @@ void tuh_max3421_int_api(uint8_t rhport, bool enabled) {
|
||||
}
|
||||
}
|
||||
|
||||
// API to control MAX3421 SPI CS
|
||||
void tuh_max3421_spi_cs_api(uint8_t rhport, bool active) {
|
||||
(void) rhport;
|
||||
gpio_set_pin_level(MAX3421_CS_PIN, active ? 0 : 1);
|
||||
}
|
||||
|
||||
bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const *tx_buf, size_t tx_len, uint8_t *rx_buf, size_t rx_len) {
|
||||
// API to transfer data with MAX3421 SPI
|
||||
// Either tx_buf or rx_buf can be NULL, which means transfer is write or read only
|
||||
bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint8_t* rx_buf, size_t xfer_bytes) {
|
||||
(void) rhport;
|
||||
|
||||
Sercom* sercom = MAX3421_SERCOM;
|
||||
|
||||
size_t count = 0;
|
||||
while (count < tx_len || count < rx_len) {
|
||||
for (size_t count = 0; count < xfer_bytes; count++) {
|
||||
// Wait for the transmit buffer to be empty
|
||||
while (!sercom->SPI.INTFLAG.bit.DRE);
|
||||
|
||||
// Write data to be transmitted
|
||||
uint8_t data = 0x00;
|
||||
if (count < tx_len) {
|
||||
if (tx_buf) {
|
||||
data = tx_buf[count];
|
||||
}
|
||||
|
||||
@ -397,11 +409,9 @@ bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const *tx_buf, size_t tx_l
|
||||
|
||||
// Read received data
|
||||
data = (uint8_t) sercom->SPI.DATA.reg;
|
||||
if (count < rx_len) {
|
||||
if (rx_buf) {
|
||||
rx_buf[count] = data;
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
// wait for bus idle and clear flags
|
||||
@ -412,6 +422,3 @@ bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const *tx_buf, size_t tx_l
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -59,7 +59,7 @@
|
||||
#define configTICK_RATE_HZ ( 1000 )
|
||||
#define configMAX_PRIORITIES ( 5 )
|
||||
#define configMINIMAL_STACK_SIZE ( 128 )
|
||||
#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 )
|
||||
#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*6*1024 )
|
||||
#define configMAX_TASK_NAME_LEN 16
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configIDLE_SHOULD_YIELD 1
|
||||
|
@ -81,6 +81,7 @@ void USB_3_Handler(void) {
|
||||
#define MAX3421_EIC_Handler TU_XSTRCAT3(EIC_, MAX3421_INTR_EIC_ID, _Handler)
|
||||
|
||||
static void max3421_init(void);
|
||||
|
||||
#endif
|
||||
|
||||
void board_init(void) {
|
||||
@ -153,13 +154,13 @@ uint32_t board_button_read(void) {
|
||||
return gpio_get_pin_level(BUTTON_PIN) ? 0 : 1;
|
||||
}
|
||||
|
||||
int board_uart_read(uint8_t *buf, int len) {
|
||||
int board_uart_read(uint8_t* buf, int len) {
|
||||
(void) buf;
|
||||
(void) len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_uart_write(void const *buf, int len) {
|
||||
int board_uart_write(void const* buf, int len) {
|
||||
(void) buf;
|
||||
(void) len;
|
||||
return 0;
|
||||
@ -176,6 +177,8 @@ uint32_t board_millis(void) {
|
||||
return system_ticks;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// API: SPI transfer with MAX3421E, must be implemented by application
|
||||
//--------------------------------------------------------------------+
|
||||
@ -183,10 +186,12 @@ uint32_t board_millis(void) {
|
||||
|
||||
static void max3421_init(void) {
|
||||
//------------- SPI Init -------------//
|
||||
uint32_t const baudrate = 4000000u;
|
||||
|
||||
// MAX3421E max SPI clock is 26MHz however SAMD can only work reliably at 12 Mhz
|
||||
uint32_t const baudrate = 12000000u;
|
||||
|
||||
struct {
|
||||
volatile uint32_t *mck_apb;
|
||||
volatile uint32_t* mck_apb;
|
||||
uint32_t mask;
|
||||
uint8_t gclk_id_core;
|
||||
uint8_t gclk_id_slow;
|
||||
@ -211,8 +216,10 @@ static void max3421_init(void) {
|
||||
*sercom_clock[MAX3421_SERCOM_ID].mck_apb |= sercom_clock[MAX3421_SERCOM_ID].mask;
|
||||
|
||||
// Configure GCLK for SERCOM
|
||||
GCLK->PCHCTRL[sercom_clock[MAX3421_SERCOM_ID].gclk_id_core].reg = GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
|
||||
GCLK->PCHCTRL[sercom_clock[MAX3421_SERCOM_ID].gclk_id_slow].reg = GCLK_PCHCTRL_GEN_GCLK3_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
|
||||
GCLK->PCHCTRL[sercom_clock[MAX3421_SERCOM_ID].gclk_id_core].reg =
|
||||
GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
|
||||
GCLK->PCHCTRL[sercom_clock[MAX3421_SERCOM_ID].gclk_id_slow].reg =
|
||||
GCLK_PCHCTRL_GEN_GCLK3_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
|
||||
|
||||
// Disable the SPI module
|
||||
sercom->SPI.CTRLA.bit.ENABLE = 0;
|
||||
@ -223,13 +230,18 @@ static void max3421_init(void) {
|
||||
|
||||
// Set up SPI in master mode, MSB first, SPI mode 0
|
||||
sercom->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_DOPO(MAX3421_TX_PAD) | SERCOM_SPI_CTRLA_DIPO(MAX3421_RX_PAD) |
|
||||
SERCOM_SPI_CTRLA_MODE(3);
|
||||
SERCOM_SPI_CTRLA_MODE(3);
|
||||
|
||||
sercom->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_CHSIZE(0) | SERCOM_SPI_CTRLB_RXEN;
|
||||
while (sercom->SPI.SYNCBUSY.bit.CTRLB == 1);
|
||||
|
||||
// Set the baud rate
|
||||
sercom->SPI.BAUD.reg = (uint8_t) (SystemCoreClock / (2 * baudrate) - 1);
|
||||
uint8_t baud_reg = (uint8_t) (SystemCoreClock / (2 * baudrate));
|
||||
if (baud_reg) {
|
||||
baud_reg--;
|
||||
}
|
||||
|
||||
sercom->SPI.BAUD.reg = baud_reg;
|
||||
|
||||
// Configure PA12 as MOSI (PAD0), PA13 as SCK (PAD1), PA14 as MISO (PAD2), function C (sercom)
|
||||
gpio_set_pin_direction(MAX3421_SCK_PIN, GPIO_DIRECTION_OUT);
|
||||
@ -270,9 +282,9 @@ static void max3421_init(void) {
|
||||
while (EIC->SYNCBUSY.bit.ENABLE);
|
||||
|
||||
// Configure EIC to trigger on falling edge
|
||||
volatile uint32_t * eic_config;
|
||||
volatile uint32_t* eic_config;
|
||||
uint8_t sense_shift;
|
||||
if ( MAX3421_INTR_EIC_ID < 8 ) {
|
||||
if (MAX3421_INTR_EIC_ID < 8) {
|
||||
eic_config = &EIC->CONFIG[0].reg;
|
||||
sense_shift = MAX3421_INTR_EIC_ID * 4;
|
||||
} else {
|
||||
@ -283,6 +295,11 @@ static void max3421_init(void) {
|
||||
*eic_config &= ~(7 << sense_shift);
|
||||
*eic_config |= 2 << sense_shift;
|
||||
|
||||
#if CFG_TUSB_OS == OPT_OS_FREERTOS
|
||||
// If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
|
||||
NVIC_SetPriority(EIC_0_IRQn + MAX3421_INTR_EIC_ID, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
|
||||
#endif
|
||||
|
||||
// Enable External Interrupt
|
||||
EIC->INTENSET.reg = EIC_INTENSET_EXTINT(1 << MAX3421_INTR_EIC_ID);
|
||||
|
||||
@ -296,9 +313,10 @@ void MAX3421_EIC_Handler(void) {
|
||||
EIC->INTFLAG.reg = EIC_INTFLAG_EXTINT(1 << MAX3421_INTR_EIC_ID);
|
||||
|
||||
// Call the TinyUSB interrupt handler
|
||||
tuh_int_handler(1);
|
||||
tuh_int_handler(1, true);
|
||||
}
|
||||
|
||||
// API to enable/disable MAX3421 INTR pin interrupt
|
||||
void tuh_max3421_int_api(uint8_t rhport, bool enabled) {
|
||||
(void) rhport;
|
||||
|
||||
@ -310,24 +328,26 @@ void tuh_max3421_int_api(uint8_t rhport, bool enabled) {
|
||||
}
|
||||
}
|
||||
|
||||
// API to control MAX3421 SPI CS
|
||||
void tuh_max3421_spi_cs_api(uint8_t rhport, bool active) {
|
||||
(void) rhport;
|
||||
gpio_set_pin_level(MAX3421_CS_PIN, active ? 0 : 1);
|
||||
}
|
||||
|
||||
bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const *tx_buf, size_t tx_len, uint8_t *rx_buf, size_t rx_len) {
|
||||
// API to transfer data with MAX3421 SPI
|
||||
// Either tx_buf or rx_buf can be NULL, which means transfer is write or read only
|
||||
bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint8_t* rx_buf, size_t xfer_bytes) {
|
||||
(void) rhport;
|
||||
|
||||
Sercom* sercom = MAX3421_SERCOM;
|
||||
|
||||
size_t count = 0;
|
||||
while (count < tx_len || count < rx_len) {
|
||||
for (size_t count = 0; count < xfer_bytes; count++) {
|
||||
// Wait for the transmit buffer to be empty
|
||||
while (!sercom->SPI.INTFLAG.bit.DRE);
|
||||
|
||||
// Write data to be transmitted
|
||||
uint8_t data = 0x00;
|
||||
if (count < tx_len) {
|
||||
if (tx_buf) {
|
||||
data = tx_buf[count];
|
||||
}
|
||||
|
||||
@ -338,11 +358,9 @@ bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const *tx_buf, size_t tx_l
|
||||
|
||||
// Read received data
|
||||
data = (uint8_t) sercom->SPI.DATA.reg;
|
||||
if (count < rx_len) {
|
||||
if (rx_buf) {
|
||||
rx_buf[count] = data;
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
// wait for bus idle and clear flags
|
||||
@ -353,5 +371,3 @@ bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const *tx_buf, size_t tx_l
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -26,50 +26,46 @@ set(FAMILY_MCUS STM32G4 CACHE INTERNAL "")
|
||||
#------------------------------------
|
||||
# only need to be built ONCE for all examples
|
||||
function(add_board_target BOARD_TARGET)
|
||||
if (NOT TARGET ${BOARD_TARGET})
|
||||
# Startup & Linker script
|
||||
set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s)
|
||||
set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s)
|
||||
set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf)
|
||||
if (TARGET ${BOARD_TARGET})
|
||||
return()
|
||||
endif ()
|
||||
|
||||
add_library(${BOARD_TARGET} STATIC
|
||||
${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c
|
||||
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c
|
||||
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c
|
||||
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c
|
||||
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c
|
||||
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c
|
||||
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c
|
||||
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c
|
||||
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c
|
||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||
)
|
||||
target_include_directories(${BOARD_TARGET} PUBLIC
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
|
||||
${CMSIS_5}/CMSIS/Core/Include
|
||||
${ST_CMSIS}/Include
|
||||
${ST_HAL_DRIVER}/Inc
|
||||
)
|
||||
target_compile_options(${BOARD_TARGET} PUBLIC
|
||||
)
|
||||
target_compile_definitions(${BOARD_TARGET} PUBLIC
|
||||
)
|
||||
# Startup & Linker script
|
||||
set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s)
|
||||
set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s)
|
||||
set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf)
|
||||
|
||||
update_board(${BOARD_TARGET})
|
||||
add_library(${BOARD_TARGET} STATIC
|
||||
${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c
|
||||
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c
|
||||
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c
|
||||
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c
|
||||
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c
|
||||
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c
|
||||
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c
|
||||
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c
|
||||
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c
|
||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||
)
|
||||
target_include_directories(${BOARD_TARGET} PUBLIC
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
|
||||
${CMSIS_5}/CMSIS/Core/Include
|
||||
${ST_CMSIS}/Include
|
||||
${ST_HAL_DRIVER}/Inc
|
||||
)
|
||||
update_board(${BOARD_TARGET})
|
||||
|
||||
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
target_link_options(${BOARD_TARGET} PUBLIC
|
||||
"LINKER:--script=${LD_FILE_GNU}"
|
||||
-nostartfiles
|
||||
# nanolib
|
||||
--specs=nosys.specs
|
||||
--specs=nano.specs
|
||||
)
|
||||
elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
|
||||
target_link_options(${BOARD_TARGET} PUBLIC
|
||||
"LINKER:--config=${LD_FILE_IAR}"
|
||||
)
|
||||
endif ()
|
||||
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
target_link_options(${BOARD_TARGET} PUBLIC
|
||||
"LINKER:--script=${LD_FILE_GNU}"
|
||||
-nostartfiles
|
||||
# nanolib
|
||||
--specs=nosys.specs --specs=nano.specs
|
||||
)
|
||||
elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
|
||||
target_link_options(${BOARD_TARGET} PUBLIC
|
||||
"LINKER:--config=${LD_FILE_IAR}"
|
||||
)
|
||||
endif ()
|
||||
endfunction()
|
||||
|
||||
|
165
hw/bsp/stm32u5/FreeRTOSConfig/FreeRTOSConfig.h
Normal file
165
hw/bsp/stm32u5/FreeRTOSConfig/FreeRTOSConfig.h
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* FreeRTOS Kernel V10.0.0
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* 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. If you wish to use our Amazon
|
||||
* FreeRTOS name, please do so in a fair use way that does not cause confusion.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FREERTOS_CONFIG_H
|
||||
#define FREERTOS_CONFIG_H
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Application specific definitions.
|
||||
*
|
||||
* These definitions should be adjusted for your particular hardware and
|
||||
* application requirements.
|
||||
*
|
||||
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||
*
|
||||
* See http://www.freertos.org/a00110.html.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
// skip if included from IAR assembler
|
||||
#ifndef __IASMARM__
|
||||
#include "stm32u5xx.h"
|
||||
#endif
|
||||
|
||||
/* Cortex M23/M33 port configuration. */
|
||||
#define configENABLE_MPU 0
|
||||
#define configENABLE_FPU 1
|
||||
#define configENABLE_TRUSTZONE 0
|
||||
#define configMINIMAL_SECURE_STACK_SIZE (1024)
|
||||
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#define configCPU_CLOCK_HZ SystemCoreClock
|
||||
#define configTICK_RATE_HZ ( 1000 )
|
||||
#define configMAX_PRIORITIES ( 5 )
|
||||
#define configMINIMAL_STACK_SIZE ( 128 )
|
||||
#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 )
|
||||
#define configMAX_TASK_NAME_LEN 16
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configIDLE_SHOULD_YIELD 1
|
||||
#define configUSE_MUTEXES 1
|
||||
#define configUSE_RECURSIVE_MUTEXES 1
|
||||
#define configUSE_COUNTING_SEMAPHORES 1
|
||||
#define configQUEUE_REGISTRY_SIZE 4
|
||||
#define configUSE_QUEUE_SETS 0
|
||||
#define configUSE_TIME_SLICING 0
|
||||
#define configUSE_NEWLIB_REENTRANT 0
|
||||
#define configENABLE_BACKWARD_COMPATIBILITY 1
|
||||
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
|
||||
|
||||
#define configSUPPORT_STATIC_ALLOCATION 0
|
||||
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||
|
||||
/* Hook function related definitions. */
|
||||
#define configUSE_IDLE_HOOK 0
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||
|
||||
/* Run time and task stats gathering related definitions. */
|
||||
#define configGENERATE_RUN_TIME_STATS 0
|
||||
#define configRECORD_STACK_HIGH_ADDRESS 1
|
||||
#define configUSE_TRACE_FACILITY 1 // legacy trace
|
||||
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
|
||||
|
||||
/* Co-routine definitions. */
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES 2
|
||||
|
||||
/* Software timer related definitions. */
|
||||
#define configUSE_TIMERS 1
|
||||
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2)
|
||||
#define configTIMER_QUEUE_LENGTH 32
|
||||
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
|
||||
|
||||
/* Optional functions - most linkers will remove unused functions anyway. */
|
||||
#define INCLUDE_vTaskPrioritySet 0
|
||||
#define INCLUDE_uxTaskPriorityGet 0
|
||||
#define INCLUDE_vTaskDelete 0
|
||||
#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY
|
||||
#define INCLUDE_xResumeFromISR 0
|
||||
#define INCLUDE_vTaskDelayUntil 1
|
||||
#define INCLUDE_vTaskDelay 1
|
||||
#define INCLUDE_xTaskGetSchedulerState 0
|
||||
#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark 0
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 0
|
||||
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
|
||||
#define INCLUDE_pcTaskGetTaskName 0
|
||||
#define INCLUDE_eTaskGetState 0
|
||||
#define INCLUDE_xEventGroupSetBitFromISR 0
|
||||
#define INCLUDE_xTimerPendFunctionCall 0
|
||||
|
||||
/* Define to trap errors during development. */
|
||||
// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7
|
||||
#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__)
|
||||
#define configASSERT(_exp) \
|
||||
do {\
|
||||
if ( !(_exp) ) { \
|
||||
volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \
|
||||
if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \
|
||||
taskDISABLE_INTERRUPTS(); \
|
||||
__asm("BKPT #0\n"); \
|
||||
}\
|
||||
}\
|
||||
} while(0)
|
||||
#else
|
||||
#define configASSERT( x )
|
||||
#endif
|
||||
|
||||
/* FreeRTOS hooks to NVIC vectors */
|
||||
#define xPortPendSVHandler PendSV_Handler
|
||||
#define xPortSysTickHandler SysTick_Handler
|
||||
#define vPortSVCHandler SVC_Handler
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Interrupt nesting behavior configuration.
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header
|
||||
#define configPRIO_BITS 4
|
||||
|
||||
/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
|
||||
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<configPRIO_BITS) - 1)
|
||||
|
||||
/* The highest interrupt priority that can be used by any interrupt service
|
||||
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
|
||||
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
|
||||
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
|
||||
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2
|
||||
|
||||
/* Interrupt priorities used by the kernel port layer itself. These are generic
|
||||
to all Cortex-M ports, and do not rely on any particular library functions. */
|
||||
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||
|
||||
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
|
||||
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
|
||||
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||
|
||||
#endif
|
10
hw/bsp/stm32u5/boards/stm32u575eval/board.cmake
Normal file
10
hw/bsp/stm32u5/boards/stm32u575eval/board.cmake
Normal file
@ -0,0 +1,10 @@
|
||||
set(MCU_VARIANT stm32u575xx)
|
||||
set(JLINK_DEVICE stm32u575ai)
|
||||
|
||||
set(LD_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/linker/STM32U575xx_FLASH.ld)
|
||||
|
||||
function(update_board TARGET)
|
||||
target_compile_definitions(${TARGET} PUBLIC
|
||||
STM32U575xx
|
||||
)
|
||||
endfunction()
|
@ -7,4 +7,4 @@ LD_FILE = $(BOARD_PATH)/STM32U575AIIXQ_FLASH.ld
|
||||
SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32u575xx.s
|
||||
|
||||
# For flash-jlink target
|
||||
JLINK_DEVICE = stm32u575
|
||||
JLINK_DEVICE = stm32u575ai
|
||||
|
@ -25,15 +25,25 @@
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
// Suppress warning caused by mcu driver
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wundef"
|
||||
#endif
|
||||
|
||||
#include "stm32u5xx_hal.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#include "bsp/board_api.h"
|
||||
#include "board.h"
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Forward USB interrupt events to TinyUSB IRQ Handler
|
||||
//--------------------------------------------------------------------+
|
||||
void OTG_FS_IRQHandler(void)
|
||||
{
|
||||
void OTG_FS_IRQHandler(void) {
|
||||
tud_int_handler(0);
|
||||
}
|
||||
|
||||
@ -43,8 +53,7 @@ void OTG_FS_IRQHandler(void)
|
||||
|
||||
UART_HandleTypeDef UartHandle;
|
||||
|
||||
void board_init(void)
|
||||
{
|
||||
void board_init(void) {
|
||||
|
||||
board_clock_init();
|
||||
|
||||
@ -123,8 +132,8 @@ void board_init(void)
|
||||
GPIO_InitStruct.Alternate = GPIO_AF10_USB;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
#if OTG_FS_VBUS_SENSE
|
||||
// Configure VBUS Pin
|
||||
#if defined(OTG_FS_VBUS_SENSE) && OTG_FS_VBUS_SENSE
|
||||
// Configure VBUS Pin OTG_FS_VBUS_SENSE
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_9;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
@ -152,50 +161,44 @@ void board_init(void)
|
||||
// Board porting API
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
void board_led_write(bool state)
|
||||
{
|
||||
void board_led_write(bool state) {
|
||||
HAL_GPIO_WritePin(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON));
|
||||
}
|
||||
|
||||
uint32_t board_button_read(void)
|
||||
{
|
||||
uint32_t board_button_read(void) {
|
||||
return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN);
|
||||
}
|
||||
|
||||
int board_uart_read(uint8_t *buf, int len)
|
||||
{
|
||||
(void)buf;
|
||||
(void)len;
|
||||
int board_uart_read(uint8_t *buf, int len) {
|
||||
(void) buf;
|
||||
(void) len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_uart_write(void const *buf, int len)
|
||||
{
|
||||
HAL_UART_Transmit(&UartHandle, (uint8_t *)(uintptr_t)buf, len, 0xffff);
|
||||
int board_uart_write(void const *buf, int len) {
|
||||
HAL_UART_Transmit(&UartHandle, (uint8_t *) (uintptr_t) buf, len, 0xffff);
|
||||
return len;
|
||||
}
|
||||
|
||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||
volatile uint32_t system_ticks = 0;
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
|
||||
void SysTick_Handler(void) {
|
||||
HAL_IncTick();
|
||||
system_ticks++;
|
||||
}
|
||||
|
||||
uint32_t board_millis(void)
|
||||
{
|
||||
uint32_t board_millis(void) {
|
||||
return system_ticks;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void HardFault_Handler(void)
|
||||
{
|
||||
void HardFault_Handler(void) {
|
||||
asm("bkpt");
|
||||
}
|
||||
|
||||
// Required by __libc_init_array in startup code if we are compiling using
|
||||
// -nostdlib/-nostartfiles.
|
||||
void _init(void)
|
||||
{
|
||||
void _init(void) {
|
||||
}
|
||||
|
108
hw/bsp/stm32u5/family.cmake
Normal file
108
hw/bsp/stm32u5/family.cmake
Normal file
@ -0,0 +1,108 @@
|
||||
include_guard()
|
||||
|
||||
if (NOT BOARD)
|
||||
message(FATAL_ERROR "BOARD not specified")
|
||||
endif ()
|
||||
|
||||
set(ST_FAMILY u5)
|
||||
set(ST_PREFIX stm32${ST_FAMILY}xx)
|
||||
|
||||
set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver)
|
||||
set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis_device_${ST_FAMILY})
|
||||
set(CMSIS_5 ${TOP}/lib/CMSIS_5)
|
||||
|
||||
# include board specific
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
|
||||
|
||||
# toolchain set up
|
||||
set(CMAKE_SYSTEM_PROCESSOR cortex-m33 CACHE INTERNAL "System Processor")
|
||||
set(CMAKE_TOOLCHAIN_FILE ${TOP}/tools/cmake/toolchain/arm_${TOOLCHAIN}.cmake)
|
||||
|
||||
set(FAMILY_MCUS STM32U5 CACHE INTERNAL "")
|
||||
|
||||
|
||||
#------------------------------------
|
||||
# BOARD_TARGET
|
||||
#------------------------------------
|
||||
# only need to be built ONCE for all examples
|
||||
function(add_board_target BOARD_TARGET)
|
||||
if (NOT TARGET ${BOARD_TARGET})
|
||||
# Startup & Linker script
|
||||
set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s)
|
||||
set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s)
|
||||
set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf)
|
||||
|
||||
add_library(${BOARD_TARGET} STATIC
|
||||
${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c
|
||||
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal.c
|
||||
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_cortex.c
|
||||
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_gpio.c
|
||||
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_pwr_ex.c
|
||||
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc.c
|
||||
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_rcc_ex.c
|
||||
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c
|
||||
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c
|
||||
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
|
||||
)
|
||||
target_include_directories(${BOARD_TARGET} PUBLIC
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
|
||||
${CMSIS_5}/CMSIS/Core/Include
|
||||
${ST_CMSIS}/Include
|
||||
${ST_HAL_DRIVER}/Inc
|
||||
)
|
||||
update_board(${BOARD_TARGET})
|
||||
|
||||
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
target_link_options(${BOARD_TARGET} PUBLIC
|
||||
"LINKER:--script=${LD_FILE_GNU}"
|
||||
-nostartfiles
|
||||
# nanolib
|
||||
--specs=nosys.specs --specs=nano.specs
|
||||
)
|
||||
elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
|
||||
target_link_options(${BOARD_TARGET} PUBLIC
|
||||
"LINKER:--config=${LD_FILE_IAR}"
|
||||
)
|
||||
endif ()
|
||||
endif ()
|
||||
endfunction()
|
||||
|
||||
|
||||
#------------------------------------
|
||||
# Functions
|
||||
#------------------------------------
|
||||
function(family_configure_example TARGET RTOS)
|
||||
family_configure_common(${TARGET} ${RTOS})
|
||||
|
||||
# Board target
|
||||
add_board_target(board_${BOARD})
|
||||
|
||||
#---------- Port Specific ----------
|
||||
# These files are built for each example since it depends on example's tusb_config.h
|
||||
target_sources(${TARGET} PUBLIC
|
||||
# BSP
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
|
||||
)
|
||||
target_include_directories(${TARGET} PUBLIC
|
||||
# family, hw, board
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
|
||||
)
|
||||
|
||||
# Add TinyUSB target and port source
|
||||
family_add_tinyusb(${TARGET} OPT_MCU_STM32U5 ${RTOS})
|
||||
target_sources(${TARGET}-tinyusb PUBLIC
|
||||
${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c
|
||||
#${TOP}/src/portable/st/typec/typec_stm32.c
|
||||
)
|
||||
target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD})
|
||||
|
||||
# Link dependencies
|
||||
target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb)
|
||||
|
||||
# Flashing
|
||||
family_flash_stlink(${TARGET})
|
||||
family_flash_jlink(${TARGET})
|
||||
endfunction()
|
@ -20,11 +20,11 @@ SRC_C += \
|
||||
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \
|
||||
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \
|
||||
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
|
||||
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \
|
||||
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \
|
||||
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \
|
||||
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr.c \
|
||||
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c \
|
||||
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \
|
||||
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \
|
||||
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \
|
||||
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c
|
||||
|
||||
INC += \
|
||||
|
@ -8,7 +8,7 @@
|
||||
void USB0_Handler(void)
|
||||
{
|
||||
#if CFG_TUH_ENABLED
|
||||
tuh_int_handler(0);
|
||||
tuh_int_handler(0, true);
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_ENABLED
|
||||
|
@ -43,16 +43,14 @@
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO CONSTANT TYPEDEF
|
||||
//--------------------------------------------------------------------+
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
MSC_STAGE_IDLE = 0,
|
||||
MSC_STAGE_CMD,
|
||||
MSC_STAGE_DATA,
|
||||
MSC_STAGE_STATUS,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
uint8_t itf_num;
|
||||
uint8_t ep_in;
|
||||
uint8_t ep_out;
|
||||
@ -69,13 +67,13 @@ typedef struct
|
||||
|
||||
//------------- SCSI -------------//
|
||||
uint8_t stage;
|
||||
void* buffer;
|
||||
void* buffer;
|
||||
tuh_msc_complete_cb_t complete_cb;
|
||||
uintptr_t complete_arg;
|
||||
|
||||
CFG_TUH_MEM_ALIGN msc_cbw_t cbw;
|
||||
CFG_TUH_MEM_ALIGN msc_csw_t csw;
|
||||
}msch_interface_t;
|
||||
} msch_interface_t;
|
||||
|
||||
CFG_TUH_MEM_SECTION static msch_interface_t _msch_itf[CFG_TUH_DEVICE_MAX];
|
||||
|
||||
@ -86,40 +84,34 @@ static uint8_t _msch_buffer[sizeof(scsi_inquiry_resp_t)];
|
||||
|
||||
// FIXME potential nul reference
|
||||
TU_ATTR_ALWAYS_INLINE
|
||||
static inline msch_interface_t* get_itf(uint8_t dev_addr)
|
||||
{
|
||||
return &_msch_itf[dev_addr-1];
|
||||
static inline msch_interface_t* get_itf(uint8_t dev_addr) {
|
||||
return &_msch_itf[dev_addr - 1];
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// PUBLIC API
|
||||
//--------------------------------------------------------------------+
|
||||
uint8_t tuh_msc_get_maxlun(uint8_t dev_addr)
|
||||
{
|
||||
uint8_t tuh_msc_get_maxlun(uint8_t dev_addr) {
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
return p_msc->max_lun;
|
||||
}
|
||||
|
||||
uint32_t tuh_msc_get_block_count(uint8_t dev_addr, uint8_t lun)
|
||||
{
|
||||
uint32_t tuh_msc_get_block_count(uint8_t dev_addr, uint8_t lun) {
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
return p_msc->capacity[lun].block_count;
|
||||
}
|
||||
|
||||
uint32_t tuh_msc_get_block_size(uint8_t dev_addr, uint8_t lun)
|
||||
{
|
||||
uint32_t tuh_msc_get_block_size(uint8_t dev_addr, uint8_t lun) {
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
return p_msc->capacity[lun].block_size;
|
||||
}
|
||||
|
||||
bool tuh_msc_mounted(uint8_t dev_addr)
|
||||
{
|
||||
bool tuh_msc_mounted(uint8_t dev_addr) {
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
return p_msc->mounted;
|
||||
}
|
||||
|
||||
bool tuh_msc_ready(uint8_t dev_addr)
|
||||
{
|
||||
bool tuh_msc_ready(uint8_t dev_addr) {
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
return p_msc->mounted && !usbh_edpt_busy(dev_addr, p_msc->ep_in) && !usbh_edpt_busy(dev_addr, p_msc->ep_out);
|
||||
}
|
||||
@ -127,20 +119,20 @@ bool tuh_msc_ready(uint8_t dev_addr)
|
||||
//--------------------------------------------------------------------+
|
||||
// PUBLIC API: SCSI COMMAND
|
||||
//--------------------------------------------------------------------+
|
||||
static inline void cbw_init(msc_cbw_t *cbw, uint8_t lun)
|
||||
{
|
||||
static inline void cbw_init(msc_cbw_t* cbw, uint8_t lun) {
|
||||
tu_memclr(cbw, sizeof(msc_cbw_t));
|
||||
cbw->signature = MSC_CBW_SIGNATURE;
|
||||
cbw->tag = 0x54555342; // TUSB
|
||||
cbw->lun = lun;
|
||||
}
|
||||
|
||||
bool tuh_msc_scsi_command(uint8_t dev_addr, msc_cbw_t const* cbw, void* data, tuh_msc_complete_cb_t complete_cb, uintptr_t arg)
|
||||
{
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
bool tuh_msc_scsi_command(uint8_t daddr, msc_cbw_t const* cbw, void* data,
|
||||
tuh_msc_complete_cb_t complete_cb, uintptr_t arg) {
|
||||
msch_interface_t* p_msc = get_itf(daddr);
|
||||
TU_VERIFY(p_msc->configured);
|
||||
|
||||
// TODO claim endpoint
|
||||
// claim endpoint
|
||||
TU_VERIFY(usbh_edpt_claim(daddr, p_msc->ep_out));
|
||||
|
||||
p_msc->cbw = *cbw;
|
||||
p_msc->stage = MSC_STAGE_CMD;
|
||||
@ -148,15 +140,18 @@ bool tuh_msc_scsi_command(uint8_t dev_addr, msc_cbw_t const* cbw, void* data, tu
|
||||
p_msc->complete_cb = complete_cb;
|
||||
p_msc->complete_arg = arg;
|
||||
|
||||
TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t)));
|
||||
if (!usbh_edpt_xfer(daddr, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t))) {
|
||||
usbh_edpt_release(daddr, p_msc->ep_out);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_resp_t* response, tuh_msc_complete_cb_t complete_cb, uintptr_t arg)
|
||||
{
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
TU_VERIFY(p_msc->configured);
|
||||
bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_resp_t* response,
|
||||
tuh_msc_complete_cb_t complete_cb, uintptr_t arg) {
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
TU_VERIFY(p_msc->configured);
|
||||
|
||||
msc_cbw_t cbw;
|
||||
cbw_init(&cbw, lun);
|
||||
@ -169,8 +164,8 @@ bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_r
|
||||
return tuh_msc_scsi_command(dev_addr, &cbw, response, complete_cb, arg);
|
||||
}
|
||||
|
||||
bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* response, tuh_msc_complete_cb_t complete_cb, uintptr_t arg)
|
||||
{
|
||||
bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* response,
|
||||
tuh_msc_complete_cb_t complete_cb, uintptr_t arg) {
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
TU_VERIFY(p_msc->mounted);
|
||||
|
||||
@ -181,18 +176,16 @@ bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* respons
|
||||
cbw.dir = TUSB_DIR_IN_MASK;
|
||||
cbw.cmd_len = sizeof(scsi_inquiry_t);
|
||||
|
||||
scsi_inquiry_t const cmd_inquiry =
|
||||
{
|
||||
.cmd_code = SCSI_CMD_INQUIRY,
|
||||
.alloc_length = sizeof(scsi_inquiry_resp_t)
|
||||
scsi_inquiry_t const cmd_inquiry = {
|
||||
.cmd_code = SCSI_CMD_INQUIRY,
|
||||
.alloc_length = sizeof(scsi_inquiry_resp_t)
|
||||
};
|
||||
memcpy(cbw.command, &cmd_inquiry, cbw.cmd_len);
|
||||
|
||||
return tuh_msc_scsi_command(dev_addr, &cbw, response, complete_cb, arg);
|
||||
}
|
||||
|
||||
bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_t complete_cb, uintptr_t arg)
|
||||
{
|
||||
bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_t complete_cb, uintptr_t arg) {
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
TU_VERIFY(p_msc->configured);
|
||||
|
||||
@ -200,16 +193,16 @@ bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_
|
||||
cbw_init(&cbw, lun);
|
||||
|
||||
cbw.total_bytes = 0;
|
||||
cbw.dir = TUSB_DIR_OUT;
|
||||
cbw.cmd_len = sizeof(scsi_test_unit_ready_t);
|
||||
cbw.command[0] = SCSI_CMD_TEST_UNIT_READY;
|
||||
cbw.command[1] = lun; // according to wiki TODO need verification
|
||||
cbw.dir = TUSB_DIR_OUT;
|
||||
cbw.cmd_len = sizeof(scsi_test_unit_ready_t);
|
||||
cbw.command[0] = SCSI_CMD_TEST_UNIT_READY;
|
||||
cbw.command[1] = lun; // according to wiki TODO need verification
|
||||
|
||||
return tuh_msc_scsi_command(dev_addr, &cbw, NULL, complete_cb, arg);
|
||||
}
|
||||
|
||||
bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void *response, tuh_msc_complete_cb_t complete_cb, uintptr_t arg)
|
||||
{
|
||||
bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void* response,
|
||||
tuh_msc_complete_cb_t complete_cb, uintptr_t arg) {
|
||||
msc_cbw_t cbw;
|
||||
cbw_init(&cbw, lun);
|
||||
|
||||
@ -217,73 +210,64 @@ bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void *response, tuh_ms
|
||||
cbw.dir = TUSB_DIR_IN_MASK;
|
||||
cbw.cmd_len = sizeof(scsi_request_sense_t);
|
||||
|
||||
scsi_request_sense_t const cmd_request_sense =
|
||||
{
|
||||
.cmd_code = SCSI_CMD_REQUEST_SENSE,
|
||||
.alloc_length = 18
|
||||
scsi_request_sense_t const cmd_request_sense = {
|
||||
.cmd_code = SCSI_CMD_REQUEST_SENSE,
|
||||
.alloc_length = 18
|
||||
};
|
||||
|
||||
memcpy(cbw.command, &cmd_request_sense, cbw.cmd_len);
|
||||
|
||||
return tuh_msc_scsi_command(dev_addr, &cbw, response, complete_cb, arg);
|
||||
}
|
||||
|
||||
bool tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb, uintptr_t arg)
|
||||
{
|
||||
bool tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void* buffer, uint32_t lba, uint16_t block_count,
|
||||
tuh_msc_complete_cb_t complete_cb, uintptr_t arg) {
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
TU_VERIFY(p_msc->mounted);
|
||||
|
||||
msc_cbw_t cbw;
|
||||
cbw_init(&cbw, lun);
|
||||
|
||||
cbw.total_bytes = block_count*p_msc->capacity[lun].block_size;
|
||||
cbw.dir = TUSB_DIR_IN_MASK;
|
||||
cbw.cmd_len = sizeof(scsi_read10_t);
|
||||
cbw.total_bytes = block_count * p_msc->capacity[lun].block_size;
|
||||
cbw.dir = TUSB_DIR_IN_MASK;
|
||||
cbw.cmd_len = sizeof(scsi_read10_t);
|
||||
|
||||
scsi_read10_t const cmd_read10 =
|
||||
{
|
||||
.cmd_code = SCSI_CMD_READ_10,
|
||||
.lba = tu_htonl(lba),
|
||||
.block_count = tu_htons(block_count)
|
||||
scsi_read10_t const cmd_read10 = {
|
||||
.cmd_code = SCSI_CMD_READ_10,
|
||||
.lba = tu_htonl(lba),
|
||||
.block_count = tu_htons(block_count)
|
||||
};
|
||||
|
||||
memcpy(cbw.command, &cmd_read10, cbw.cmd_len);
|
||||
|
||||
return tuh_msc_scsi_command(dev_addr, &cbw, buffer, complete_cb, arg);
|
||||
}
|
||||
|
||||
bool tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb, uintptr_t arg)
|
||||
{
|
||||
bool tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const* buffer, uint32_t lba, uint16_t block_count,
|
||||
tuh_msc_complete_cb_t complete_cb, uintptr_t arg) {
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
TU_VERIFY(p_msc->mounted);
|
||||
|
||||
msc_cbw_t cbw;
|
||||
cbw_init(&cbw, lun);
|
||||
|
||||
cbw.total_bytes = block_count*p_msc->capacity[lun].block_size;
|
||||
cbw.total_bytes = block_count * p_msc->capacity[lun].block_size;
|
||||
cbw.dir = TUSB_DIR_OUT;
|
||||
cbw.cmd_len = sizeof(scsi_write10_t);
|
||||
|
||||
scsi_write10_t const cmd_write10 =
|
||||
{
|
||||
.cmd_code = SCSI_CMD_WRITE_10,
|
||||
.lba = tu_htonl(lba),
|
||||
.block_count = tu_htons(block_count)
|
||||
scsi_write10_t const cmd_write10 = {
|
||||
.cmd_code = SCSI_CMD_WRITE_10,
|
||||
.lba = tu_htonl(lba),
|
||||
.block_count = tu_htons(block_count)
|
||||
};
|
||||
|
||||
memcpy(cbw.command, &cmd_write10, cbw.cmd_len);
|
||||
|
||||
return tuh_msc_scsi_command(dev_addr, &cbw, (void*)(uintptr_t) buffer, complete_cb, arg);
|
||||
return tuh_msc_scsi_command(dev_addr, &cbw, (void*) (uintptr_t) buffer, complete_cb, arg);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// MSC interface Reset (not used now)
|
||||
bool tuh_msc_reset(uint8_t dev_addr)
|
||||
{
|
||||
tusb_control_request_t const new_request =
|
||||
{
|
||||
.bmRequestType_bit =
|
||||
{
|
||||
bool tuh_msc_reset(uint8_t dev_addr) {
|
||||
tusb_control_request_t const new_request = {
|
||||
.bmRequestType_bit = {
|
||||
.recipient = TUSB_REQ_RCPT_INTERFACE,
|
||||
.type = TUSB_REQ_TYPE_CLASS,
|
||||
.direction = TUSB_DIR_OUT
|
||||
@ -300,79 +284,71 @@ bool tuh_msc_reset(uint8_t dev_addr)
|
||||
//--------------------------------------------------------------------+
|
||||
// CLASS-USBH API
|
||||
//--------------------------------------------------------------------+
|
||||
void msch_init(void)
|
||||
{
|
||||
void msch_init(void) {
|
||||
tu_memclr(_msch_itf, sizeof(_msch_itf));
|
||||
}
|
||||
|
||||
void msch_close(uint8_t dev_addr)
|
||||
{
|
||||
TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX, );
|
||||
void msch_close(uint8_t dev_addr) {
|
||||
TU_VERIFY(dev_addr <= CFG_TUH_DEVICE_MAX,);
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
TU_VERIFY(p_msc->configured, );
|
||||
TU_VERIFY(p_msc->configured,);
|
||||
|
||||
TU_LOG_DRV(" MSCh close addr = %d\r\n", dev_addr);
|
||||
|
||||
// invoke Application Callback
|
||||
if (p_msc->mounted) {
|
||||
if(tuh_msc_umount_cb) tuh_msc_umount_cb(dev_addr);
|
||||
if (tuh_msc_umount_cb) tuh_msc_umount_cb(dev_addr);
|
||||
}
|
||||
|
||||
tu_memclr(p_msc, sizeof(msch_interface_t));
|
||||
}
|
||||
|
||||
bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes)
|
||||
{
|
||||
bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes) {
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
msc_cbw_t const * cbw = &p_msc->cbw;
|
||||
msc_csw_t * csw = &p_msc->csw;
|
||||
|
||||
switch (p_msc->stage)
|
||||
{
|
||||
switch (p_msc->stage) {
|
||||
case MSC_STAGE_CMD:
|
||||
// Must be Command Block
|
||||
TU_ASSERT(ep_addr == p_msc->ep_out && event == XFER_RESULT_SUCCESS && xferred_bytes == sizeof(msc_cbw_t));
|
||||
TU_ASSERT(ep_addr == p_msc->ep_out && event == XFER_RESULT_SUCCESS && xferred_bytes == sizeof(msc_cbw_t));
|
||||
|
||||
if ( cbw->total_bytes && p_msc->buffer )
|
||||
{
|
||||
if (cbw->total_bytes && p_msc->buffer) {
|
||||
// Data stage if any
|
||||
p_msc->stage = MSC_STAGE_DATA;
|
||||
|
||||
uint8_t const ep_data = (cbw->dir & TUSB_DIR_IN_MASK) ? p_msc->ep_in : p_msc->ep_out;
|
||||
TU_ASSERT(usbh_edpt_xfer(dev_addr, ep_data, p_msc->buffer, (uint16_t) cbw->total_bytes));
|
||||
}else
|
||||
{
|
||||
} else {
|
||||
// Status stage
|
||||
p_msc->stage = MSC_STAGE_STATUS;
|
||||
TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_in, (uint8_t*) &p_msc->csw, (uint16_t) sizeof(msc_csw_t)));
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case MSC_STAGE_DATA:
|
||||
// Status stage
|
||||
p_msc->stage = MSC_STAGE_STATUS;
|
||||
TU_ASSERT(usbh_edpt_xfer(dev_addr, p_msc->ep_in, (uint8_t*) &p_msc->csw, (uint16_t) sizeof(msc_csw_t)));
|
||||
break;
|
||||
break;
|
||||
|
||||
case MSC_STAGE_STATUS:
|
||||
// SCSI op is complete
|
||||
p_msc->stage = MSC_STAGE_IDLE;
|
||||
|
||||
if (p_msc->complete_cb)
|
||||
{
|
||||
tuh_msc_complete_data_t const cb_data =
|
||||
{
|
||||
.cbw = cbw,
|
||||
.csw = csw,
|
||||
.scsi_data = p_msc->buffer,
|
||||
.user_arg = p_msc->complete_arg
|
||||
if (p_msc->complete_cb) {
|
||||
tuh_msc_complete_data_t const cb_data = {
|
||||
.cbw = cbw,
|
||||
.csw = csw,
|
||||
.scsi_data = p_msc->buffer,
|
||||
.user_arg = p_msc->complete_arg
|
||||
};
|
||||
p_msc->complete_cb(dev_addr, &cb_data);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
// unknown state
|
||||
default: break;
|
||||
// unknown state
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -381,39 +357,35 @@ bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32
|
||||
//--------------------------------------------------------------------+
|
||||
// MSC Enumeration
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
static void config_get_maxlun_complete (tuh_xfer_t* xfer);
|
||||
static bool config_test_unit_ready_complete(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_data);
|
||||
static void config_get_maxlun_complete(tuh_xfer_t* xfer);
|
||||
static bool config_test_unit_ready_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data);
|
||||
static bool config_request_sense_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data);
|
||||
static bool config_read_capacity_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data);
|
||||
|
||||
bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t max_len)
|
||||
{
|
||||
bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const* desc_itf, uint16_t max_len) {
|
||||
(void) rhport;
|
||||
TU_VERIFY (MSC_SUBCLASS_SCSI == desc_itf->bInterfaceSubClass &&
|
||||
MSC_PROTOCOL_BOT == desc_itf->bInterfaceProtocol);
|
||||
MSC_PROTOCOL_BOT == desc_itf->bInterfaceProtocol);
|
||||
|
||||
// msc driver length is fixed
|
||||
uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) + desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t));
|
||||
uint16_t const drv_len = (uint16_t) (sizeof(tusb_desc_interface_t) +
|
||||
desc_itf->bNumEndpoints * sizeof(tusb_desc_endpoint_t));
|
||||
TU_ASSERT(drv_len <= max_len);
|
||||
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
tusb_desc_endpoint_t const * ep_desc = (tusb_desc_endpoint_t const *) tu_desc_next(desc_itf);
|
||||
tusb_desc_endpoint_t const* ep_desc = (tusb_desc_endpoint_t const*) tu_desc_next(desc_itf);
|
||||
|
||||
for(uint32_t i=0; i<2; i++)
|
||||
{
|
||||
for (uint32_t i = 0; i < 2; i++) {
|
||||
TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType && TUSB_XFER_BULK == ep_desc->bmAttributes.xfer);
|
||||
TU_ASSERT(tuh_edpt_open(dev_addr, ep_desc));
|
||||
|
||||
if ( tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN )
|
||||
{
|
||||
if (TUSB_DIR_IN == tu_edpt_dir(ep_desc->bEndpointAddress)) {
|
||||
p_msc->ep_in = ep_desc->bEndpointAddress;
|
||||
}else
|
||||
{
|
||||
} else {
|
||||
p_msc->ep_out = ep_desc->bEndpointAddress;
|
||||
}
|
||||
|
||||
ep_desc = (tusb_desc_endpoint_t const *) tu_desc_next(ep_desc);
|
||||
ep_desc = (tusb_desc_endpoint_t const*) tu_desc_next(ep_desc);
|
||||
}
|
||||
|
||||
p_msc->itf_num = desc_itf->bInterfaceNumber;
|
||||
@ -430,32 +402,31 @@ bool msch_set_config(uint8_t dev_addr, uint8_t itf_num) {
|
||||
//------------- Get Max Lun -------------//
|
||||
TU_LOG_DRV("MSC Get Max Lun\r\n");
|
||||
tusb_control_request_t const request = {
|
||||
.bmRequestType_bit = {
|
||||
.recipient = TUSB_REQ_RCPT_INTERFACE,
|
||||
.type = TUSB_REQ_TYPE_CLASS,
|
||||
.direction = TUSB_DIR_IN
|
||||
},
|
||||
.bRequest = MSC_REQ_GET_MAX_LUN,
|
||||
.wValue = 0,
|
||||
.wIndex = itf_num,
|
||||
.wLength = 1
|
||||
.bmRequestType_bit = {
|
||||
.recipient = TUSB_REQ_RCPT_INTERFACE,
|
||||
.type = TUSB_REQ_TYPE_CLASS,
|
||||
.direction = TUSB_DIR_IN
|
||||
},
|
||||
.bRequest = MSC_REQ_GET_MAX_LUN,
|
||||
.wValue = 0,
|
||||
.wIndex = itf_num,
|
||||
.wLength = 1
|
||||
};
|
||||
|
||||
tuh_xfer_t xfer = {
|
||||
.daddr = dev_addr,
|
||||
.ep_addr = 0,
|
||||
.setup = &request,
|
||||
.buffer = _msch_buffer,
|
||||
.complete_cb = config_get_maxlun_complete,
|
||||
.user_data = 0
|
||||
.daddr = dev_addr,
|
||||
.ep_addr = 0,
|
||||
.setup = &request,
|
||||
.buffer = _msch_buffer,
|
||||
.complete_cb = config_get_maxlun_complete,
|
||||
.user_data = 0
|
||||
};
|
||||
TU_ASSERT(tuh_control_xfer(&xfer));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void config_get_maxlun_complete (tuh_xfer_t* xfer)
|
||||
{
|
||||
static void config_get_maxlun_complete(tuh_xfer_t* xfer) {
|
||||
uint8_t const daddr = xfer->daddr;
|
||||
msch_interface_t* p_msc = get_itf(daddr);
|
||||
|
||||
@ -471,18 +442,16 @@ static void config_get_maxlun_complete (tuh_xfer_t* xfer)
|
||||
tuh_msc_test_unit_ready(daddr, lun, config_test_unit_ready_complete, 0);
|
||||
}
|
||||
|
||||
static bool config_test_unit_ready_complete(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_data)
|
||||
{
|
||||
static bool config_test_unit_ready_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data) {
|
||||
msc_cbw_t const* cbw = cb_data->cbw;
|
||||
msc_csw_t const* csw = cb_data->csw;
|
||||
|
||||
if (csw->status == 0)
|
||||
{
|
||||
if (csw->status == 0) {
|
||||
// Unit is ready, read its capacity
|
||||
TU_LOG_DRV("SCSI Read Capacity\r\n");
|
||||
tuh_msc_read_capacity(dev_addr, cbw->lun, (scsi_read_capacity10_resp_t*) ((void*) _msch_buffer), config_read_capacity_complete, 0);
|
||||
}else
|
||||
{
|
||||
tuh_msc_read_capacity(dev_addr, cbw->lun, (scsi_read_capacity10_resp_t*) ((void*) _msch_buffer),
|
||||
config_read_capacity_complete, 0);
|
||||
} else {
|
||||
// Note: During enumeration, some device fails Test Unit Ready and require a few retries
|
||||
// with Request Sense to start working !!
|
||||
// TODO limit number of retries
|
||||
@ -493,8 +462,7 @@ static bool config_test_unit_ready_complete(uint8_t dev_addr, tuh_msc_complete_d
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool config_request_sense_complete(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_data)
|
||||
{
|
||||
static bool config_request_sense_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data) {
|
||||
msc_cbw_t const* cbw = cb_data->cbw;
|
||||
msc_csw_t const* csw = cb_data->csw;
|
||||
|
||||
@ -503,8 +471,7 @@ static bool config_request_sense_complete(uint8_t dev_addr, tuh_msc_complete_dat
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool config_read_capacity_complete(uint8_t dev_addr, tuh_msc_complete_data_t const * cb_data)
|
||||
{
|
||||
static bool config_read_capacity_complete(uint8_t dev_addr, tuh_msc_complete_data_t const* cb_data) {
|
||||
msc_cbw_t const* cbw = cb_data->cbw;
|
||||
msc_csw_t const* csw = cb_data->csw;
|
||||
|
||||
|
@ -24,8 +24,8 @@
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_MSC_HOST_H_
|
||||
#define _TUSB_MSC_HOST_H_
|
||||
#ifndef TUSB_MSC_HOST_H_
|
||||
#define TUSB_MSC_HOST_H_
|
||||
|
||||
#include "msc.h"
|
||||
|
||||
@ -73,7 +73,7 @@ uint32_t tuh_msc_get_block_size(uint8_t dev_addr, uint8_t lun);
|
||||
// Perform a full SCSI command (cbw, data, csw) in non-blocking manner.
|
||||
// Complete callback is invoked when SCSI op is complete.
|
||||
// return true if success, false if there is already pending operation.
|
||||
bool tuh_msc_scsi_command(uint8_t dev_addr, msc_cbw_t const* cbw, void* data, tuh_msc_complete_cb_t complete_cb, uintptr_t arg);
|
||||
bool tuh_msc_scsi_command(uint8_t daddr, msc_cbw_t const* cbw, void* data, tuh_msc_complete_cb_t complete_cb, uintptr_t arg);
|
||||
|
||||
// Perform SCSI Inquiry command
|
||||
// Complete callback is invoked when SCSI op is complete.
|
||||
@ -123,4 +123,4 @@ bool msch_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, ui
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TUSB_MSC_HOST_H_ */
|
||||
#endif
|
||||
|
@ -75,8 +75,6 @@
|
||||
#include "tusb_types.h"
|
||||
#include "tusb_debug.h"
|
||||
|
||||
#include "tusb_timeout.h" // TODO remove
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Optional API implemented by application if needed
|
||||
// TODO move to a more ovious place/file
|
||||
|
@ -56,12 +56,8 @@
|
||||
* #define TU_VERIFY(cond) if(cond) return false;
|
||||
* #define TU_VERIFY(cond,ret) if(cond) return ret;
|
||||
*
|
||||
* #define TU_VERIFY_HDLR(cond,handler) if(cond) {handler; return false;}
|
||||
* #define TU_VERIFY_HDLR(cond,ret,handler) if(cond) {handler; return ret;}
|
||||
*
|
||||
* #define TU_ASSERT(cond) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return false;}
|
||||
* #define TU_ASSERT(cond,ret) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return ret;}
|
||||
*
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -97,40 +93,23 @@
|
||||
#define TU_BREAKPOINT() do {} while (0)
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* Macro Generator
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
// 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
|
||||
|
||||
/*------------- Generator for TU_VERIFY and TU_VERIFY_HDLR -------------*/
|
||||
#define TU_VERIFY_DEFINE(_cond, _handler, _ret) do \
|
||||
{ \
|
||||
if ( !(_cond) ) { _handler; return _ret; } \
|
||||
} while(0)
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* TU_VERIFY
|
||||
* - TU_VERIFY_1ARGS : return false if failed
|
||||
* - TU_VERIFY_2ARGS : return provided value if failed
|
||||
*------------------------------------------------------------------*/
|
||||
#define TU_VERIFY_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, , false)
|
||||
#define TU_VERIFY_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, , _ret)
|
||||
#define TU_VERIFY_DEFINE(_cond, _ret) \
|
||||
do { \
|
||||
if ( !(_cond) ) { return _ret; } \
|
||||
} while(0)
|
||||
|
||||
#define TU_VERIFY(...) _GET_3RD_ARG(__VA_ARGS__, TU_VERIFY_2ARGS, TU_VERIFY_1ARGS, UNUSED)(__VA_ARGS__)
|
||||
#define TU_VERIFY_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, false)
|
||||
#define TU_VERIFY_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, _ret)
|
||||
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* TU_VERIFY WITH HANDLER
|
||||
* - TU_VERIFY_HDLR_2ARGS : execute handler, return false if failed
|
||||
* - TU_VERIFY_HDLR_3ARGS : execute handler, return provided error if failed
|
||||
*------------------------------------------------------------------*/
|
||||
#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(...) _GET_3RD_ARG(__VA_ARGS__, TU_VERIFY_2ARGS, TU_VERIFY_1ARGS, _dummy)(__VA_ARGS__)
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* ASSERT
|
||||
@ -138,19 +117,20 @@
|
||||
* - 1 arg : return false if failed
|
||||
* - 2 arg : return error if failed
|
||||
*------------------------------------------------------------------*/
|
||||
#define ASSERT_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, _MESS_FAILED(); TU_BREAKPOINT(), false)
|
||||
#define ASSERT_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, _MESS_FAILED(); TU_BREAKPOINT(), _ret)
|
||||
#define TU_ASSERT_DEFINE(_cond, _ret) \
|
||||
do { \
|
||||
if ( !(_cond) ) { _MESS_FAILED(); TU_BREAKPOINT(); return _ret; } \
|
||||
} while(0)
|
||||
|
||||
#define TU_ASSERT_1ARGS(_cond) TU_ASSERT_DEFINE(_cond, false)
|
||||
#define TU_ASSERT_2ARGS(_cond, _ret) TU_ASSERT_DEFINE(_cond, _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__, TU_ASSERT_2ARGS, TU_ASSERT_1ARGS, _dummy)(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* ASSERT HDLR
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* TUSB_VERIFY_H_ */
|
||||
#endif
|
||||
|
@ -131,7 +131,7 @@ bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) TU_AT
|
||||
bool hcd_init(uint8_t rhport);
|
||||
|
||||
// Interrupt Handler
|
||||
void hcd_int_handler(uint8_t rhport);
|
||||
void hcd_int_handler(uint8_t rhport, bool in_isr);
|
||||
|
||||
// Enable USB interrupt
|
||||
void hcd_int_enable (uint8_t rhport);
|
||||
|
@ -817,6 +817,7 @@ bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr)
|
||||
}
|
||||
|
||||
// Submit an transfer
|
||||
// TODO call usbh_edpt_release if failed
|
||||
bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes,
|
||||
tuh_xfer_cb_t complete_cb, uintptr_t user_data)
|
||||
{
|
||||
@ -1713,19 +1714,16 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur
|
||||
return true;
|
||||
}
|
||||
|
||||
void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num)
|
||||
{
|
||||
void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) {
|
||||
usbh_device_t* dev = get_device(dev_addr);
|
||||
|
||||
for(itf_num++; itf_num < CFG_TUH_INTERFACE_MAX; itf_num++)
|
||||
{
|
||||
for(itf_num++; itf_num < CFG_TUH_INTERFACE_MAX; itf_num++) {
|
||||
// continue with next valid interface
|
||||
// IAD binding interface such as CDCs should return itf_num + 1 when complete
|
||||
// with usbh_driver_set_config_complete()
|
||||
uint8_t const drv_id = dev->itf2drv[itf_num];
|
||||
usbh_class_driver_t const * driver = get_driver(drv_id);
|
||||
if (driver)
|
||||
{
|
||||
if (driver) {
|
||||
TU_LOG_USBH("%s set config: itf = %u\r\n", driver->name, itf_num);
|
||||
driver->set_config(dev_addr, itf_num);
|
||||
break;
|
||||
@ -1733,23 +1731,19 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num)
|
||||
}
|
||||
|
||||
// all interface are configured
|
||||
if (itf_num == CFG_TUH_INTERFACE_MAX)
|
||||
{
|
||||
if (itf_num == CFG_TUH_INTERFACE_MAX) {
|
||||
enum_full_complete();
|
||||
|
||||
if (is_hub_addr(dev_addr))
|
||||
{
|
||||
if (is_hub_addr(dev_addr)) {
|
||||
TU_LOG(CFG_TUH_LOG_LEVEL, "HUB address = %u is mounted\r\n", dev_addr);
|
||||
}else
|
||||
{
|
||||
}else {
|
||||
// Invoke callback if available
|
||||
if (tuh_mount_cb) tuh_mount_cb(dev_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void enum_full_complete(void)
|
||||
{
|
||||
static void enum_full_complete(void) {
|
||||
// mark enumeration as complete
|
||||
_dev0.enumerating = 0;
|
||||
|
||||
|
@ -124,11 +124,16 @@ void tuh_task(void) {
|
||||
bool tuh_task_event_ready(void);
|
||||
|
||||
#ifndef _TUSB_HCD_H_
|
||||
extern void hcd_int_handler(uint8_t rhport);
|
||||
extern void hcd_int_handler(uint8_t rhport, bool in_isr);
|
||||
#endif
|
||||
|
||||
// Interrupt handler, name alias to HCD
|
||||
#define tuh_int_handler hcd_int_handler
|
||||
// Interrupt handler alias to HCD with in_isr as optional parameter
|
||||
// - tuh_int_handler(rhport) --> hcd_int_handler(rhport, true)
|
||||
// - tuh_int_handler(rhport, in_isr) --> hcd_int_handler(rhport, in_isr)
|
||||
// Note: this is similar to TU_VERIFY(), _GET_3RD_ARG() is defined in tusb_verify.h
|
||||
#define _tuh_int_handler_1arg(_rhport) hcd_int_handler(_rhport, true)
|
||||
#define _tuh_int_hanlder_2arg(_rhport, _in_isr) hcd_int_handler(_rhport, _in_isr)
|
||||
#define tuh_int_handler(...) _GET_3RD_ARG(__VA_ARGS__, _tuh_int_hanlder_2arg, _tuh_int_handler_1arg, _dummy)(__VA_ARGS__)
|
||||
|
||||
// Check if roothub port is initialized and active as a host
|
||||
bool tuh_rhport_is_active(uint8_t rhport);
|
||||
|
@ -210,16 +210,21 @@ static max3421_data_t _hcd_data;
|
||||
// API: SPI transfer with MAX3421E, must be implemented by application
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
void tuh_max3421_spi_cs_api(uint8_t rhport, bool active);
|
||||
bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const * tx_buf, size_t tx_len, uint8_t * rx_buf, size_t rx_len);
|
||||
void tuh_max3421_int_api(uint8_t rhport, bool enabled);
|
||||
// API to control MAX3421 SPI CS
|
||||
extern void tuh_max3421_spi_cs_api(uint8_t rhport, bool active);
|
||||
|
||||
static void handle_connect_irq(uint8_t rhport, bool in_isr);
|
||||
static inline void hirq_write(uint8_t rhport, uint8_t data, bool in_isr);
|
||||
// API to transfer data with MAX3421 SPI
|
||||
// Either tx_buf or rx_buf can be NULL, which means transfer is write or read only
|
||||
extern bool tuh_max3421_spi_xfer_api(uint8_t rhport, uint8_t const* tx_buf, uint8_t* rx_buf, size_t xfer_bytes);
|
||||
|
||||
// API to enable/disable MAX3421 INTR pin interrupt
|
||||
extern void tuh_max3421_int_api(uint8_t rhport, bool enabled);
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// SPI Helper
|
||||
//--------------------------------------------------------------------+
|
||||
static void handle_connect_irq(uint8_t rhport, bool in_isr);
|
||||
static inline void hirq_write(uint8_t rhport, uint8_t data, bool in_isr);
|
||||
|
||||
static void max3421_spi_lock(uint8_t rhport, bool in_isr) {
|
||||
// disable interrupt and mutex lock (for pre-emptive RTOS) if not in_isr
|
||||
@ -249,9 +254,9 @@ static void fifo_write(uint8_t rhport, uint8_t reg, uint8_t const * buffer, uint
|
||||
|
||||
max3421_spi_lock(rhport, in_isr);
|
||||
|
||||
tuh_max3421_spi_xfer_api(rhport, ®, 1, &hirq, 1);
|
||||
tuh_max3421_spi_xfer_api(rhport, ®, &hirq, 1);
|
||||
_hcd_data.hirq = hirq;
|
||||
tuh_max3421_spi_xfer_api(rhport, buffer, len, NULL, 0);
|
||||
tuh_max3421_spi_xfer_api(rhport, buffer, NULL, len);
|
||||
|
||||
max3421_spi_unlock(rhport, in_isr);
|
||||
|
||||
@ -263,9 +268,9 @@ static void fifo_read(uint8_t rhport, uint8_t * buffer, uint16_t len, bool in_is
|
||||
|
||||
max3421_spi_lock(rhport, in_isr);
|
||||
|
||||
tuh_max3421_spi_xfer_api(rhport, ®, 1, &hirq, 0);
|
||||
tuh_max3421_spi_xfer_api(rhport, ®, &hirq, 1);
|
||||
_hcd_data.hirq = hirq;
|
||||
tuh_max3421_spi_xfer_api(rhport, NULL, 0, buffer, len);
|
||||
tuh_max3421_spi_xfer_api(rhport, NULL, buffer, len);
|
||||
|
||||
max3421_spi_unlock(rhport, in_isr);
|
||||
}
|
||||
@ -276,7 +281,7 @@ static void reg_write(uint8_t rhport, uint8_t reg, uint8_t data, bool in_isr) {
|
||||
|
||||
max3421_spi_lock(rhport, in_isr);
|
||||
|
||||
tuh_max3421_spi_xfer_api(rhport, tx_buf, 2, rx_buf, 2);
|
||||
tuh_max3421_spi_xfer_api(rhport, tx_buf, rx_buf, 2);
|
||||
|
||||
max3421_spi_unlock(rhport, in_isr);
|
||||
|
||||
@ -290,7 +295,7 @@ static uint8_t reg_read(uint8_t rhport, uint8_t reg, bool in_isr) {
|
||||
|
||||
max3421_spi_lock(rhport, in_isr);
|
||||
|
||||
bool ret = tuh_max3421_spi_xfer_api(rhport, tx_buf, 2, rx_buf, 2);
|
||||
bool ret = tuh_max3421_spi_xfer_api(rhport, tx_buf, rx_buf, 2);
|
||||
|
||||
max3421_spi_unlock(rhport, in_isr);
|
||||
|
||||
@ -428,8 +433,8 @@ bool hcd_init(uint8_t rhport) {
|
||||
reg_write(rhport, PINCTL_ADDR, PINCTL_FDUPSPI, false);
|
||||
|
||||
// V1 is 0x01, V2 is 0x12, V3 is 0x13
|
||||
// uint8_t const revision = reg_read(rhport, REVISION_ADDR, false);
|
||||
// TU_LOG2_HEX(revision);
|
||||
// uint8_t const revision = reg_read(rhport, REVISION_ADDR, false);
|
||||
// TU_LOG2_HEX(revision);
|
||||
|
||||
// reset
|
||||
reg_write(rhport, USBCTL_ADDR, USBCTL_CHIPRES, false);
|
||||
@ -693,9 +698,7 @@ static void handle_connect_irq(uint8_t rhport, bool in_isr) {
|
||||
|
||||
// port reset anyway, this will help to stable bus signal for next connection
|
||||
reg_write(rhport, HCTL_ADDR, HCTL_BUSRST, in_isr);
|
||||
|
||||
hcd_event_device_remove(rhport, in_isr);
|
||||
|
||||
reg_write(rhport, HCTL_ADDR, 0, in_isr);
|
||||
break;
|
||||
|
||||
@ -721,13 +724,12 @@ static void handle_connect_irq(uint8_t rhport, bool in_isr) {
|
||||
free_ep(daddr);
|
||||
|
||||
hcd_event_device_attach(rhport, in_isr);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t result, uint8_t hrsl) {
|
||||
static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t result, uint8_t hrsl, bool in_isr) {
|
||||
uint8_t const ep_addr = tu_edpt_addr(ep->ep_num, ep->ep_dir);
|
||||
|
||||
// save data toggle
|
||||
@ -738,20 +740,20 @@ static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t re
|
||||
}
|
||||
|
||||
ep->xfer_pending = 0;
|
||||
hcd_event_xfer_complete(ep->daddr, ep_addr, ep->xferred_len, result, true);
|
||||
hcd_event_xfer_complete(ep->daddr, ep_addr, ep->xferred_len, result, in_isr);
|
||||
|
||||
// Find next pending endpoint
|
||||
max3421_ep_t *next_ep = find_next_pending_ep(ep);
|
||||
if (next_ep) {
|
||||
xact_inout(rhport, next_ep, true, true);
|
||||
xact_inout(rhport, next_ep, true, in_isr);
|
||||
}else {
|
||||
// no more pending
|
||||
atomic_flag_clear(&_hcd_data.busy);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_xfer_done(uint8_t rhport) {
|
||||
uint8_t const hrsl = reg_read(rhport, HRSL_ADDR, true);
|
||||
static void handle_xfer_done(uint8_t rhport, bool in_isr) {
|
||||
uint8_t const hrsl = reg_read(rhport, HRSL_ADDR, in_isr);
|
||||
uint8_t const hresult = hrsl & HRSL_RESULT_MASK;
|
||||
|
||||
uint8_t const ep_num = _hcd_data.hxfr & HXFR_EPNUM_MASK;
|
||||
@ -774,17 +776,17 @@ static void handle_xfer_done(uint8_t rhport) {
|
||||
case HRSL_NAK:
|
||||
if (ep_num == 0) {
|
||||
// NAK on control, retry immediately
|
||||
hxfr_write(rhport, _hcd_data.hxfr, true);
|
||||
hxfr_write(rhport, _hcd_data.hxfr, in_isr);
|
||||
}else {
|
||||
// NAK on non-control, find next pending to switch
|
||||
max3421_ep_t *next_ep = find_next_pending_ep(ep);
|
||||
|
||||
if (ep == next_ep) {
|
||||
// this endpoint is only one pending, retry immediately
|
||||
hxfr_write(rhport, _hcd_data.hxfr, true);
|
||||
hxfr_write(rhport, _hcd_data.hxfr, in_isr);
|
||||
}else if (next_ep) {
|
||||
// switch to next pending TODO could have issue with double buffered if not clear previously out data
|
||||
xact_inout(rhport, next_ep, true, true);
|
||||
xact_inout(rhport, next_ep, true, in_isr);
|
||||
}else {
|
||||
TU_ASSERT(false,);
|
||||
}
|
||||
@ -802,7 +804,7 @@ static void handle_xfer_done(uint8_t rhport) {
|
||||
}
|
||||
|
||||
if (xfer_result != XFER_RESULT_SUCCESS) {
|
||||
xfer_complete_isr(rhport, ep, xfer_result, hrsl);
|
||||
xfer_complete_isr(rhport, ep, xfer_result, hrsl, in_isr);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -814,10 +816,10 @@ static void handle_xfer_done(uint8_t rhport) {
|
||||
|
||||
// short packet or all bytes transferred
|
||||
if ( ep->xfer_complete ) {
|
||||
xfer_complete_isr(rhport, ep, xfer_result, hrsl);
|
||||
xfer_complete_isr(rhport, ep, xfer_result, hrsl, in_isr);
|
||||
}else {
|
||||
// more to transfer
|
||||
hxfr_write(rhport, _hcd_data.hxfr, true);
|
||||
hxfr_write(rhport, _hcd_data.hxfr, in_isr);
|
||||
}
|
||||
} else {
|
||||
// SETUP or OUT transfer
|
||||
@ -835,10 +837,10 @@ static void handle_xfer_done(uint8_t rhport) {
|
||||
ep->buf += xact_len;
|
||||
|
||||
if (xact_len < ep->packet_size || ep->xferred_len >= ep->total_len) {
|
||||
xfer_complete_isr(rhport, ep, xfer_result, hrsl);
|
||||
xfer_complete_isr(rhport, ep, xfer_result, hrsl, in_isr);
|
||||
} else {
|
||||
// more to transfer
|
||||
xact_out(rhport, ep, false, true);
|
||||
xact_out(rhport, ep, false, in_isr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -862,9 +864,9 @@ void print_hirq(uint8_t hirq) {
|
||||
#define print_hirq(hirq)
|
||||
#endif
|
||||
|
||||
// Interrupt Handler
|
||||
void hcd_int_handler(uint8_t rhport) {
|
||||
uint8_t hirq = reg_read(rhport, HIRQ_ADDR, true) & _hcd_data.hien;
|
||||
// Interrupt handler
|
||||
void hcd_int_handler(uint8_t rhport, bool in_isr) {
|
||||
uint8_t hirq = reg_read(rhport, HIRQ_ADDR, in_isr) & _hcd_data.hien;
|
||||
if (!hirq) return;
|
||||
// print_hirq(hirq);
|
||||
|
||||
@ -873,7 +875,7 @@ void hcd_int_handler(uint8_t rhport) {
|
||||
}
|
||||
|
||||
if (hirq & HIRQ_CONDET_IRQ) {
|
||||
handle_connect_irq(rhport, true);
|
||||
handle_connect_irq(rhport, in_isr);
|
||||
}
|
||||
|
||||
// queue more transfer in handle_xfer_done() can cause hirq to be set again while external IRQ may not catch and/or
|
||||
@ -882,21 +884,21 @@ void hcd_int_handler(uint8_t rhport) {
|
||||
if ( hirq & HIRQ_RCVDAV_IRQ ) {
|
||||
uint8_t const ep_num = _hcd_data.hxfr & HXFR_EPNUM_MASK;
|
||||
max3421_ep_t *ep = find_opened_ep(_hcd_data.peraddr, ep_num, 1);
|
||||
uint8_t xact_len;
|
||||
uint8_t xact_len = 0;
|
||||
|
||||
// RCVDAV_IRQ can trigger 2 times (dual buffered)
|
||||
while ( hirq & HIRQ_RCVDAV_IRQ ) {
|
||||
uint8_t rcvbc = reg_read(rhport, RCVBC_ADDR, true);
|
||||
uint8_t rcvbc = reg_read(rhport, RCVBC_ADDR, in_isr);
|
||||
xact_len = (uint8_t) tu_min16(rcvbc, ep->total_len - ep->xferred_len);
|
||||
if ( xact_len ) {
|
||||
fifo_read(rhport, ep->buf, xact_len, true);
|
||||
fifo_read(rhport, ep->buf, xact_len, in_isr);
|
||||
ep->buf += xact_len;
|
||||
ep->xferred_len += xact_len;
|
||||
}
|
||||
|
||||
// ack RCVDVAV IRQ
|
||||
hirq_write(rhport, HIRQ_RCVDAV_IRQ, true);
|
||||
hirq = reg_read(rhport, HIRQ_ADDR, true);
|
||||
hirq_write(rhport, HIRQ_RCVDAV_IRQ, in_isr);
|
||||
hirq = reg_read(rhport, HIRQ_ADDR, in_isr);
|
||||
}
|
||||
|
||||
if ( xact_len < ep->packet_size || ep->xferred_len >= ep->total_len ) {
|
||||
@ -905,17 +907,17 @@ void hcd_int_handler(uint8_t rhport) {
|
||||
}
|
||||
|
||||
if ( hirq & HIRQ_HXFRDN_IRQ ) {
|
||||
hirq_write(rhport, HIRQ_HXFRDN_IRQ, true);
|
||||
handle_xfer_done(rhport);
|
||||
hirq_write(rhport, HIRQ_HXFRDN_IRQ, in_isr);
|
||||
handle_xfer_done(rhport, in_isr);
|
||||
}
|
||||
|
||||
hirq = reg_read(rhport, HIRQ_ADDR, true);
|
||||
hirq = reg_read(rhport, HIRQ_ADDR, in_isr);
|
||||
}
|
||||
|
||||
// clear all interrupt except SNDBAV_IRQ (never clear by us). Note RCVDAV_IRQ, HXFRDN_IRQ already clear while processing
|
||||
hirq &= ~HIRQ_SNDBAV_IRQ;
|
||||
if ( hirq ) {
|
||||
hirq_write(rhport, hirq, true);
|
||||
hirq_write(rhport, hirq, in_isr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -656,8 +656,8 @@ void process_period_xfer_isr(uint8_t rhport, uint32_t interval_ms)
|
||||
}
|
||||
|
||||
//------------- Host Controller Driver's Interrupt Handler -------------//
|
||||
void hcd_int_handler(uint8_t rhport)
|
||||
{
|
||||
void hcd_int_handler(uint8_t rhport, bool in_isr) {
|
||||
(void) in_isr;
|
||||
ehci_registers_t* regs = ehci_data.regs;
|
||||
uint32_t const int_status = regs->status;
|
||||
|
||||
|
@ -847,8 +847,10 @@ bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
|
||||
/*-------------------------------------------------------------------
|
||||
* ISR
|
||||
*-------------------------------------------------------------------*/
|
||||
void hcd_int_handler(uint8_t rhport)
|
||||
void hcd_int_handler(uint8_t rhport, bool in_isr)
|
||||
{
|
||||
(void) in_isr;
|
||||
|
||||
uint_fast8_t is, txis, rxis;
|
||||
|
||||
is = USB0->IS; /* read and clear interrupt status */
|
||||
|
@ -447,6 +447,10 @@ 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;
|
||||
@ -583,8 +587,9 @@ bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
|
||||
/*--------------------------------------------------------------------+
|
||||
* ISR
|
||||
*--------------------------------------------------------------------+*/
|
||||
void hcd_int_handler(uint8_t rhport)
|
||||
void hcd_int_handler(uint8_t rhport, bool in_isr)
|
||||
{
|
||||
(void) in_isr;
|
||||
uint32_t is = KHCI->ISTAT;
|
||||
uint32_t msk = KHCI->INTEN;
|
||||
|
||||
|
@ -667,8 +667,9 @@ static void done_queue_isr(uint8_t hostid)
|
||||
}
|
||||
}
|
||||
|
||||
void hcd_int_handler(uint8_t hostid)
|
||||
{
|
||||
void hcd_int_handler(uint8_t hostid, bool in_isr) {
|
||||
(void) in_isr;
|
||||
|
||||
uint32_t const int_en = OHCI_REG->interrupt_enable;
|
||||
uint32_t const int_status = OHCI_REG->interrupt_status & int_en;
|
||||
|
||||
|
@ -252,9 +252,9 @@ static void __tusb_irq_path_func(hcd_rp2040_irq)(void)
|
||||
}
|
||||
}
|
||||
|
||||
void __tusb_irq_path_func(hcd_int_handler)(uint8_t rhport)
|
||||
{
|
||||
void __tusb_irq_path_func(hcd_int_handler)(uint8_t rhport, bool in_isr) {
|
||||
(void) rhport;
|
||||
(void) in_isr;
|
||||
hcd_rp2040_irq();
|
||||
}
|
||||
|
||||
|
@ -771,8 +771,9 @@ bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
|
||||
//--------------------------------------------------------------------+
|
||||
// ISR
|
||||
//--------------------------------------------------------------------+
|
||||
void hcd_int_handler(uint8_t rhport)
|
||||
{
|
||||
void hcd_int_handler(uint8_t rhport, bool in_isr) {
|
||||
(void) in_isr;
|
||||
|
||||
rusb2_reg_t* rusb = RUSB2_REG(rhport);
|
||||
unsigned is0 = rusb->INTSTS0;
|
||||
unsigned is1 = rusb->INTSTS1;
|
||||
|
@ -51,8 +51,9 @@ bool hcd_init(uint8_t rhport) {
|
||||
}
|
||||
|
||||
// Interrupt Handler
|
||||
void hcd_int_handler(uint8_t rhport) {
|
||||
void hcd_int_handler(uint8_t rhport, bool in_isr) {
|
||||
(void) rhport;
|
||||
(void) in_isr;
|
||||
}
|
||||
|
||||
// Enable USB interrupt
|
||||
|
@ -17,3 +17,10 @@ TINYUSB_SRC_C += \
|
||||
src/class/usbtmc/usbtmc_device.c \
|
||||
src/class/video/video_device.c \
|
||||
src/class/vendor/vendor_device.c \
|
||||
src/host/usbh.c \
|
||||
src/host/hub.c \
|
||||
src/class/cdc/cdc_host.c \
|
||||
src/class/hid/hid_host.c \
|
||||
src/class/msc/msc_host.c \
|
||||
src/class/vendor/vendor_host.c \
|
||||
src/typec/usbc.c \
|
||||
|
@ -66,7 +66,7 @@
|
||||
#endif
|
||||
#else
|
||||
#ifndef tuh_int_handler
|
||||
#define tuh_int_handler(_x)
|
||||
#define tuh_int_handler(...)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -123,7 +123,7 @@
|
||||
#endif
|
||||
#else
|
||||
#ifndef tud_int_handler
|
||||
#define tud_int_handler(_x)
|
||||
#define tud_int_handler(...)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -424,11 +424,11 @@
|
||||
//------------- CLASS -------------//
|
||||
|
||||
#ifndef CFG_TUH_HUB
|
||||
#define CFG_TUH_HUB 0
|
||||
#define CFG_TUH_HUB 0
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUH_CDC
|
||||
#define CFG_TUH_CDC 0
|
||||
#define CFG_TUH_CDC 0
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUH_CDC_FTDI
|
||||
@ -442,34 +442,38 @@
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUH_HID
|
||||
#define CFG_TUH_HID 0
|
||||
#define CFG_TUH_HID 0
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUH_MIDI
|
||||
#define CFG_TUH_MIDI 0
|
||||
#define CFG_TUH_MIDI 0
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUH_MSC
|
||||
#define CFG_TUH_MSC 0
|
||||
#define CFG_TUH_MSC 0
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUH_VENDOR
|
||||
#define CFG_TUH_VENDOR 0
|
||||
#define CFG_TUH_VENDOR 0
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUH_API_EDPT_XFER
|
||||
#define CFG_TUH_API_EDPT_XFER 0
|
||||
#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
|
||||
#define CFG_TUH_RPI_PIO_USB 0
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUD_RPI_PIO_USB
|
||||
#define CFG_TUD_RPI_PIO_USB 0
|
||||
#define CFG_TUD_RPI_PIO_USB 0
|
||||
#endif
|
||||
|
||||
// MAX3421 Host controller option
|
||||
#ifndef CFG_TUH_MAX3421
|
||||
#define CFG_TUH_MAX3421 0
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// TypeC Options (Default)
|
||||
|
@ -17,8 +17,8 @@ exit_status = 0
|
||||
|
||||
total_time = time.monotonic()
|
||||
|
||||
build_format = '| {:23} | {:30} | {:18} | {:7} | {:6} | {:6} |'
|
||||
build_separator = '-' * 100
|
||||
build_format = '| {:30} | {:30} | {:18} | {:7} | {:6} | {:6} |'
|
||||
build_separator = '-' * 107
|
||||
|
||||
def filter_with_input(mylist):
|
||||
if len(sys.argv) > 1:
|
||||
@ -26,12 +26,9 @@ def filter_with_input(mylist):
|
||||
if len(input_args) > 0:
|
||||
mylist[:] = input_args
|
||||
|
||||
|
||||
# Build all examples if not specified
|
||||
all_examples = []
|
||||
for entry in os.scandir("examples/device"):
|
||||
# Only includes example with CMakeLists.txt for esp32s, and skip board_test to speed up ci
|
||||
if entry.is_dir() and os.path.exists(entry.path + "/sdkconfig.defaults") and entry.name != 'board_test':
|
||||
all_examples.append(entry.name)
|
||||
all_examples = [entry.replace('examples/', '') for entry in glob.glob("examples/*/*_freertos")]
|
||||
filter_with_input(all_examples)
|
||||
all_examples.sort()
|
||||
|
||||
@ -46,32 +43,41 @@ all_boards.sort()
|
||||
def build_board(example, board):
|
||||
global success_count, fail_count, skip_count, exit_status
|
||||
start_time = time.monotonic()
|
||||
|
||||
# Check if board is skipped
|
||||
build_dir = f"cmake-build/cmake-build-{board}/{example}"
|
||||
|
||||
# Generate and build
|
||||
r = subprocess.run(f"cmake examples/{example} -B {build_dir} -G \"Ninja\" -DBOARD={board} -DMAX3421_HOST=1",
|
||||
shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
if r.returncode == 0:
|
||||
r = subprocess.run(f"cmake --build {build_dir}", shell=True, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT)
|
||||
build_duration = time.monotonic() - start_time
|
||||
flash_size = "-"
|
||||
sram_size = "-"
|
||||
|
||||
# Check if board is skipped
|
||||
if build_utils.skip_example(example, board):
|
||||
success = SKIPPED
|
||||
skip_count += 1
|
||||
print(build_format.format(example, board, success, '-', flash_size, sram_size))
|
||||
if r.returncode == 0:
|
||||
success = SUCCEEDED
|
||||
success_count += 1
|
||||
#(flash_size, sram_size) = build_size(example, board)
|
||||
else:
|
||||
subprocess.run("make -C examples/device/{} BOARD={} clean".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
build_result = subprocess.run("make -j -C examples/device/{} BOARD={} all".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
exit_status = r.returncode
|
||||
success = FAILED
|
||||
fail_count += 1
|
||||
|
||||
if build_result.returncode == 0:
|
||||
success = SUCCEEDED
|
||||
success_count += 1
|
||||
(flash_size, sram_size) = build_size(example, board)
|
||||
else:
|
||||
exit_status = build_result.returncode
|
||||
success = FAILED
|
||||
fail_count += 1
|
||||
title = build_format.format(example, board, success, "{:.2f}s".format(build_duration), flash_size, sram_size)
|
||||
if os.getenv('CI'):
|
||||
# always print build output if in CI
|
||||
print(f"::group::{title}")
|
||||
print(r.stdout.decode("utf-8"))
|
||||
print(f"::endgroup::")
|
||||
else:
|
||||
# print build output if failed
|
||||
print(title)
|
||||
if r.returncode != 0:
|
||||
print(r.stdout.decode("utf-8"))
|
||||
|
||||
build_duration = time.monotonic() - start_time
|
||||
print(build_format.format(example, board, success, "{:.2f}s".format(build_duration), flash_size, sram_size))
|
||||
|
||||
if build_result.returncode != 0:
|
||||
print(build_result.stdout.decode("utf-8"))
|
||||
|
||||
def build_size(example, board):
|
||||
#elf_file = 'examples/device/{}/_build/{}/{}-firmware.elf'.format(example, board, board)
|
||||
@ -82,6 +88,7 @@ def build_size(example, board):
|
||||
sram_size = int(size_list[1]) + int(size_list[2])
|
||||
return (flash_size, sram_size)
|
||||
|
||||
|
||||
print(build_separator)
|
||||
print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM'))
|
||||
print(build_separator)
|
||||
|
123
tools/iar_gen.py
123
tools/iar_gen.py
@ -1,51 +1,84 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
import xml.dom.minidom as XML
|
||||
import glob
|
||||
|
||||
# Read base configuration
|
||||
base = ""
|
||||
with open("iar_template.ipcf") as f:
|
||||
base = f.read()
|
||||
def Main():
|
||||
# Read base configuration
|
||||
base = ""
|
||||
with open("iar_template.ipcf") as f:
|
||||
base = f.read()
|
||||
|
||||
# Enumerate all device/host examples
|
||||
dir_1 = os.listdir("../examples")
|
||||
for dir_2 in dir_1:
|
||||
if os.path.isdir("../examples/{}".format(dir_2)):
|
||||
print(dir_2)
|
||||
examples = os.listdir("../examples/{}".format(dir_2))
|
||||
for example in examples:
|
||||
if os.path.isdir("../examples/{}/{}".format(dir_2, example)):
|
||||
print("../examples/{}/{}".format(dir_2, example))
|
||||
conf = XML.parseString(base)
|
||||
files = conf.getElementsByTagName("files")[0]
|
||||
inc = conf.getElementsByTagName("includePath")[0]
|
||||
# Add bsp inc
|
||||
path = conf.createElement('path')
|
||||
path_txt = conf.createTextNode("$TUSB_DIR$/hw")
|
||||
path.appendChild(path_txt)
|
||||
inc.appendChild(path)
|
||||
# Add board.c/.h
|
||||
grp = conf.createElement('group')
|
||||
grp.setAttribute("name", "bsp")
|
||||
path = conf.createElement('path')
|
||||
path_txt = conf.createTextNode("$TUSB_DIR$/hw/bsp/board.c")
|
||||
path.appendChild(path_txt)
|
||||
grp.appendChild(path)
|
||||
files.appendChild(grp)
|
||||
# Add example's .c/.h
|
||||
grp = conf.createElement('group')
|
||||
grp.setAttribute("name", "example")
|
||||
for file in os.listdir("../examples/{}/{}/src".format(dir_2, example)):
|
||||
if file.endswith(".c") or file.endswith(".h"):
|
||||
path = conf.createElement('path')
|
||||
path.setAttribute("copyTo", "$PROJ_DIR$/{}".format(file))
|
||||
path_txt = conf.createTextNode("$TUSB_DIR$/examples/{0}/{1}/src/{2}".format(dir_2, example, file))
|
||||
path.appendChild(path_txt)
|
||||
grp.appendChild(path)
|
||||
files.appendChild(grp)
|
||||
cfg_str = conf.toprettyxml()
|
||||
cfg_str = '\n'.join([s for s in cfg_str.splitlines() if s.strip()])
|
||||
#print(cfg_str)
|
||||
with open("../examples/{0}/{1}/iar_{1}.ipcf".format(dir_2, example), 'w') as f:
|
||||
f.write(cfg_str)
|
||||
# Enumerate all device/host examples
|
||||
dir_1 = os.listdir("../examples")
|
||||
for dir_2 in dir_1:
|
||||
if os.path.isdir("../examples/{}".format(dir_2)):
|
||||
print(dir_2)
|
||||
examples = os.listdir("../examples/{}".format(dir_2))
|
||||
for example in examples:
|
||||
if os.path.isdir("../examples/{}/{}".format(dir_2, example)):
|
||||
print("../examples/{}/{}".format(dir_2, example))
|
||||
conf = XML.parseString(base)
|
||||
files = conf.getElementsByTagName("files")[0]
|
||||
inc = conf.getElementsByTagName("includePath")[0]
|
||||
# Add bsp inc
|
||||
path = conf.createElement('path')
|
||||
path_txt = conf.createTextNode("$TUSB_DIR$/hw")
|
||||
path.appendChild(path_txt)
|
||||
inc.appendChild(path)
|
||||
# Add board.c/.h
|
||||
grp = conf.createElement('group')
|
||||
grp.setAttribute("name", "bsp")
|
||||
path = conf.createElement('path')
|
||||
path_txt = conf.createTextNode("$TUSB_DIR$/hw/bsp/board.c")
|
||||
path.appendChild(path_txt)
|
||||
grp.appendChild(path)
|
||||
files.appendChild(grp)
|
||||
# Add example's .c/.h
|
||||
grp = conf.createElement('group')
|
||||
grp.setAttribute("name", "example")
|
||||
for file in os.listdir("../examples/{}/{}/src".format(dir_2, example)):
|
||||
if file.endswith(".c") or file.endswith(".h"):
|
||||
path = conf.createElement('path')
|
||||
path.setAttribute("copyTo", "$PROJ_DIR$/{}".format(file))
|
||||
path_txt = conf.createTextNode("$TUSB_DIR$/examples/{0}/{1}/src/{2}".format(dir_2, example, file))
|
||||
path.appendChild(path_txt)
|
||||
grp.appendChild(path)
|
||||
files.appendChild(grp)
|
||||
cfg_str = conf.toprettyxml()
|
||||
cfg_str = '\n'.join([s for s in cfg_str.splitlines() if s.strip()])
|
||||
#print(cfg_str)
|
||||
with open("../examples/{0}/{1}/iar_{1}.ipcf".format(dir_2, example), 'w') as f:
|
||||
f.write(cfg_str)
|
||||
|
||||
def ListPath(path, blacklist=[]):
|
||||
# Get all .c files
|
||||
files = glob.glob(f'../{path}/**/*.c', recursive=True)
|
||||
# Filter
|
||||
files = [x for x in files if all(y not in x for y in blacklist)]
|
||||
# Get common dir list
|
||||
dirs = []
|
||||
for file in files:
|
||||
dir = os.path.dirname(file)
|
||||
if dir not in dirs:
|
||||
dirs.append(dir)
|
||||
# Print .c grouped by dir
|
||||
for dir in dirs:
|
||||
print('<group name="' + dir.replace('../', '').replace('\\','/') + '">')
|
||||
for file in files:
|
||||
if os.path.dirname(file) == dir:
|
||||
print(' <path>$TUSB_DIR$/' + file.replace('../','').replace('\\','/')+'</path>')
|
||||
print('</group>')
|
||||
|
||||
def List():
|
||||
ListPath('src', [ 'template.c', 'dcd_synopsys.c', 'dcd_esp32sx.c' ])
|
||||
ListPath('lib/SEGGER_RTT')
|
||||
|
||||
if __name__ == "__main__":
|
||||
if (len(sys.argv) > 1):
|
||||
if (sys.argv[1] == 'l'):
|
||||
List()
|
||||
else:
|
||||
Main()
|
||||
|
@ -4,166 +4,176 @@
|
||||
<includePath>
|
||||
<path>$TUSB_DIR$/src</path>
|
||||
<path>$TUSB_DIR$/lib/SEGGER_RTT/RTT</path>
|
||||
<path>$TUSB_DIR$/lib/SEGGER_RTT/Config</path>
|
||||
<path>$PROJ_DIR$</path>
|
||||
</includePath>
|
||||
<files>
|
||||
<group name="src/device">
|
||||
<path>$TUSB_DIR$/src/device/usbd.c</path>
|
||||
<path>$TUSB_DIR$/src/device/usbd_control.c</path>
|
||||
</group>
|
||||
<group name="src/common">
|
||||
<path>$TUSB_DIR$/src/common/tusb_fifo.c</path>
|
||||
</group>
|
||||
<group name="src/class/audio">
|
||||
<path>$TUSB_DIR$/src/class/audio/audio_device.c</path>
|
||||
</group>
|
||||
<group name="src/class/bth">
|
||||
<path>$TUSB_DIR$/src/class/bth/bth_device.c</path>
|
||||
</group>
|
||||
<group name="src/class/cdc">
|
||||
<path>$TUSB_DIR$/src/class/cdc/cdc_device.c</path>
|
||||
<path>$TUSB_DIR$/src/class/cdc/cdc_host.c</path>
|
||||
<path>$TUSB_DIR$/src/class/cdc/cdc_rndis_host.c</path>
|
||||
</group>
|
||||
<group name="src/class/dfu">
|
||||
<path>$TUSB_DIR$/src/class/dfu/dfu_device.c</path>
|
||||
<path>$TUSB_DIR$/src/class/dfu/dfu_rt_device.c</path>
|
||||
</group>
|
||||
<group name="src/class/hid">
|
||||
<path>$TUSB_DIR$/src/class/hid/hid_device.c</path>
|
||||
<path>$TUSB_DIR$/src/class/hid/hid_host.c</path>
|
||||
</group>
|
||||
<group name="src/class/midi">
|
||||
<path>$TUSB_DIR$/src/class/midi/midi_device.c</path>
|
||||
</group>
|
||||
<group name="src/class/msc">
|
||||
<path>$TUSB_DIR$/src/class/msc/msc_device.c</path>
|
||||
<path>$TUSB_DIR$/src/class/msc/msc_host.c</path>
|
||||
</group>
|
||||
<group name="src/class/net">
|
||||
<path>$TUSB_DIR$/src/class/net/ecm_rndis_device.c</path>
|
||||
<path>$TUSB_DIR$/src/class/net/ncm_device.c</path>
|
||||
</group>
|
||||
<group name="src/class/usbtmc">
|
||||
<path>$TUSB_DIR$/src/class/usbtmc/usbtmc_device.c</path>
|
||||
</group>
|
||||
<group name="src/class/vendor">
|
||||
<path>$TUSB_DIR$/src/class/vendor/vendor_device.c</path>
|
||||
<path>$TUSB_DIR$/src/class/vendor/vendor_host.c</path>
|
||||
</group>
|
||||
<group name="src">
|
||||
<path>$TUSB_DIR$/src/tusb.c</path>
|
||||
</group>
|
||||
<group name="src/host">
|
||||
<path>$TUSB_DIR$/src/host/hub.c</path>
|
||||
<path>$TUSB_DIR$/src/host/usbh.c</path>
|
||||
</group>
|
||||
<group name="src/portable/bridgetek/ft9xx">
|
||||
<path>$TUSB_DIR$/src/portable/bridgetek/ft9xx/dcd_ft9xx.c</path>
|
||||
</group>
|
||||
<group name="src/portable/chipidea/ci_hs">
|
||||
<path>$TUSB_DIR$/src/portable/chipidea/ci_hs/dcd_ci_hs.c</path>
|
||||
<path>$TUSB_DIR$/src/portable/chipidea/ci_hs/hcd_ci_hs.c</path>
|
||||
</group>
|
||||
<group name="src/portable/synopsys/dwc2">
|
||||
<path>$TUSB_DIR$/src/portable/synopsys/dwc2/dcd_dwc2.c</path>
|
||||
</group>
|
||||
<group name="src/portable/dialog/da146xx">
|
||||
<path>$TUSB_DIR$/src/portable/dialog/da146xx/dcd_da146xx.c</path>
|
||||
</group>
|
||||
<group name="src/portable/ehci">
|
||||
<path>$TUSB_DIR$/src/portable/ehci/ehci.c</path>
|
||||
</group>
|
||||
<group name="src/portable/espressif/esp32sx">
|
||||
<path>$TUSB_DIR$/src/portable/espressif/esp32sx/dcd_esp32sx.c</path>
|
||||
</group>
|
||||
<group name="src/portable/mentor/musb">
|
||||
<path>$TUSB_DIR$/src/portable/mentor/musb/dcd_musb.c</path>
|
||||
<path>$TUSB_DIR$/src/portable/mentor/musb/hcd_musb.c</path>
|
||||
</group>
|
||||
<group name="src/portable/microchip/samd">
|
||||
<path>$TUSB_DIR$/src/portable/microchip/samd/dcd_samd.c</path>
|
||||
</group>
|
||||
<group name="src/portable/microchip/samg">
|
||||
<path>$TUSB_DIR$/src/portable/microchip/samg/dcd_samg.c</path>
|
||||
</group>
|
||||
<group name="src/portable/microchip/samx7x">
|
||||
<path>$TUSB_DIR$/src/portable/microchip/samx7x/dcd_samx7x.c</path>
|
||||
</group>
|
||||
<group name="src/portable/microchip/pic">
|
||||
<path>$TUSB_DIR$/src/portable/microchip/pic/dcd_pic.c</path>
|
||||
</group>
|
||||
<group name="src/portable/microchip/pic32mz">
|
||||
<path>$TUSB_DIR$/src/portable/microchip/pic32mz/dcd_pic32mz.c</path>
|
||||
</group>
|
||||
<group name="src/portable/mindmotion/mm32">
|
||||
<path>$TUSB_DIR$/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c</path>
|
||||
</group>
|
||||
<group name="src/portable/nordic/nrf5x">
|
||||
<path>$TUSB_DIR$/src/portable/nordic/nrf5x/dcd_nrf5x.c</path>
|
||||
</group>
|
||||
<group name="src/portable/nuvoton/nuc120">
|
||||
<path>$TUSB_DIR$/src/portable/nuvoton/nuc120/dcd_nuc120.c</path>
|
||||
</group>
|
||||
<group name="src/portable/nuvoton/nuc121">
|
||||
<path>$TUSB_DIR$/src/portable/nuvoton/nuc121/dcd_nuc121.c</path>
|
||||
</group>
|
||||
<group name="src/portable/nuvoton/nuc505">
|
||||
<path>$TUSB_DIR$/src/portable/nuvoton/nuc505/dcd_nuc505.c</path>
|
||||
</group>
|
||||
<group name="src/portable/nxp/khci">
|
||||
<path>$TUSB_DIR$/src/portable/nxp/khci/dcd_khci.c</path>
|
||||
<path>$TUSB_DIR$/src/portable/nxp/khci/hcd_khci.c</path>
|
||||
</group>
|
||||
<group name="src/portable/nxp/lpc17_40">
|
||||
<path>$TUSB_DIR$/src/portable/nxp/lpc17_40/dcd_lpc17_40.c</path>
|
||||
<path>$TUSB_DIR$/src/portable/nxp/lpc17_40/hcd_lpc17_40.c</path>
|
||||
</group>
|
||||
<group name="src/portable/nxp/lpc_ip3511">
|
||||
<path>$TUSB_DIR$/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c</path>
|
||||
</group>
|
||||
<group name="src/portable/nxp/transdimension">
|
||||
<path>$TUSB_DIR$/src/portable/nxp/transdimension/dcd_transdimension.c</path>
|
||||
<path>$TUSB_DIR$/src/portable/nxp/transdimension/hcd_transdimension.c</path>
|
||||
</group>
|
||||
<group name="src/portable/ohci">
|
||||
<path>$TUSB_DIR$/src/portable/ohci/ohci.c</path>
|
||||
</group>
|
||||
<group name="src/portable/raspberrypi/pio_usb">
|
||||
<path>$TUSB_DIR$/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c</path>
|
||||
<path>$TUSB_DIR$/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c</path>
|
||||
</group>
|
||||
<group name="src/portable/raspberrypi/rp2040">
|
||||
<path>$TUSB_DIR$/src/portable/raspberrypi/rp2040/dcd_rp2040.c</path>
|
||||
<path>$TUSB_DIR$/src/portable/raspberrypi/rp2040/hcd_rp2040.c</path>
|
||||
</group>
|
||||
<group name="src/portable/renesas/rusb2">
|
||||
<path>$TUSB_DIR$/src/portable/renesas/rusb2/dcd_rusb2.c</path>
|
||||
<path>$TUSB_DIR$/src/portable/renesas/rusb2/hcd_rusb2.c</path>
|
||||
</group>
|
||||
<group name="src/portable/sony/cxd56">
|
||||
<path>$TUSB_DIR$/src/portable/sony/cxd56/dcd_cxd56.c</path>
|
||||
</group>
|
||||
<group name="src/portable/st/stm32_fsdev">
|
||||
<path>$TUSB_DIR$/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c</path>
|
||||
</group>
|
||||
<group name="src/portable/sunxi">
|
||||
<path>$TUSB_DIR$/src/portable/sunxi/dcd_sunxi_musb.c</path>
|
||||
</group>
|
||||
<group name="src/portable/ti/msp430x5xx">
|
||||
<path>$TUSB_DIR$/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c</path>
|
||||
</group>
|
||||
<group name="src/portable/valentyusb/eptri">
|
||||
<path>$TUSB_DIR$/src/portable/valentyusb/eptri/dcd_eptri.c</path>
|
||||
</group>
|
||||
<group name="src/portable/wch/ch32v307">
|
||||
<path>$TUSB_DIR$/src/portable/wch/ch32v307/dcd_usbhs.c</path>
|
||||
</group>
|
||||
<group name="lib/SEGGER_RTT">
|
||||
<path>$TUSB_DIR$/lib/SEGGER_RTT/RTT/SEGGER_RTT.c</path>
|
||||
<group name="src/class/audio">
|
||||
<path>$TUSB_DIR$/src/class/audio/audio_device.c</path>
|
||||
</group>
|
||||
<group name="src/class/bth">
|
||||
<path>$TUSB_DIR$/src/class/bth/bth_device.c</path>
|
||||
</group>
|
||||
<group name="src/class/cdc">
|
||||
<path>$TUSB_DIR$/src/class/cdc/cdc_device.c</path>
|
||||
<path>$TUSB_DIR$/src/class/cdc/cdc_host.c</path>
|
||||
<path>$TUSB_DIR$/src/class/cdc/cdc_rndis_host.c</path>
|
||||
</group>
|
||||
<group name="src/class/dfu">
|
||||
<path>$TUSB_DIR$/src/class/dfu/dfu_device.c</path>
|
||||
<path>$TUSB_DIR$/src/class/dfu/dfu_rt_device.c</path>
|
||||
</group>
|
||||
<group name="src/class/hid">
|
||||
<path>$TUSB_DIR$/src/class/hid/hid_device.c</path>
|
||||
<path>$TUSB_DIR$/src/class/hid/hid_host.c</path>
|
||||
</group>
|
||||
<group name="src/class/midi">
|
||||
<path>$TUSB_DIR$/src/class/midi/midi_device.c</path>
|
||||
</group>
|
||||
<group name="src/class/msc">
|
||||
<path>$TUSB_DIR$/src/class/msc/msc_device.c</path>
|
||||
<path>$TUSB_DIR$/src/class/msc/msc_host.c</path>
|
||||
</group>
|
||||
<group name="src/class/net">
|
||||
<path>$TUSB_DIR$/src/class/net/ecm_rndis_device.c</path>
|
||||
<path>$TUSB_DIR$/src/class/net/ncm_device.c</path>
|
||||
</group>
|
||||
<group name="src/class/usbtmc">
|
||||
<path>$TUSB_DIR$/src/class/usbtmc/usbtmc_device.c</path>
|
||||
</group>
|
||||
<group name="src/class/vendor">
|
||||
<path>$TUSB_DIR$/src/class/vendor/vendor_device.c</path>
|
||||
<path>$TUSB_DIR$/src/class/vendor/vendor_host.c</path>
|
||||
</group>
|
||||
<group name="src/class/video">
|
||||
<path>$TUSB_DIR$/src/class/video/video_device.c</path>
|
||||
</group>
|
||||
<group name="src/common">
|
||||
<path>$TUSB_DIR$/src/common/tusb_fifo.c</path>
|
||||
</group>
|
||||
<group name="src/device">
|
||||
<path>$TUSB_DIR$/src/device/usbd.c</path>
|
||||
<path>$TUSB_DIR$/src/device/usbd_control.c</path>
|
||||
</group>
|
||||
<group name="src/host">
|
||||
<path>$TUSB_DIR$/src/host/hub.c</path>
|
||||
<path>$TUSB_DIR$/src/host/usbh.c</path>
|
||||
</group>
|
||||
<group name="src/portable/analog/max3421">
|
||||
<path>$TUSB_DIR$/src/portable/analog/max3421/hcd_max3421.c</path>
|
||||
</group>
|
||||
<group name="src/portable/bridgetek/ft9xx">
|
||||
<path>$TUSB_DIR$/src/portable/bridgetek/ft9xx/dcd_ft9xx.c</path>
|
||||
</group>
|
||||
<group name="src/portable/chipidea/ci_fs">
|
||||
<path>$TUSB_DIR$/src/portable/chipidea/ci_fs/dcd_ci_fs.c</path>
|
||||
</group>
|
||||
<group name="src/portable/chipidea/ci_hs">
|
||||
<path>$TUSB_DIR$/src/portable/chipidea/ci_hs/dcd_ci_hs.c</path>
|
||||
<path>$TUSB_DIR$/src/portable/chipidea/ci_hs/hcd_ci_hs.c</path>
|
||||
</group>
|
||||
<group name="src/portable/dialog/da146xx">
|
||||
<path>$TUSB_DIR$/src/portable/dialog/da146xx/dcd_da146xx.c</path>
|
||||
</group>
|
||||
<group name="src/portable/ehci">
|
||||
<path>$TUSB_DIR$/src/portable/ehci/ehci.c</path>
|
||||
</group>
|
||||
<group name="src/portable/mentor/musb">
|
||||
<path>$TUSB_DIR$/src/portable/mentor/musb/dcd_musb.c</path>
|
||||
<path>$TUSB_DIR$/src/portable/mentor/musb/hcd_musb.c</path>
|
||||
</group>
|
||||
<group name="src/portable/microchip/pic">
|
||||
<path>$TUSB_DIR$/src/portable/microchip/pic/dcd_pic.c</path>
|
||||
</group>
|
||||
<group name="src/portable/microchip/pic32mz">
|
||||
<path>$TUSB_DIR$/src/portable/microchip/pic32mz/dcd_pic32mz.c</path>
|
||||
</group>
|
||||
<group name="src/portable/microchip/samd">
|
||||
<path>$TUSB_DIR$/src/portable/microchip/samd/dcd_samd.c</path>
|
||||
</group>
|
||||
<group name="src/portable/microchip/samg">
|
||||
<path>$TUSB_DIR$/src/portable/microchip/samg/dcd_samg.c</path>
|
||||
</group>
|
||||
<group name="src/portable/microchip/samx7x">
|
||||
<path>$TUSB_DIR$/src/portable/microchip/samx7x/dcd_samx7x.c</path>
|
||||
</group>
|
||||
<group name="src/portable/mindmotion/mm32">
|
||||
<path>$TUSB_DIR$/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c</path>
|
||||
</group>
|
||||
<group name="src/portable/nordic/nrf5x">
|
||||
<path>$TUSB_DIR$/src/portable/nordic/nrf5x/dcd_nrf5x.c</path>
|
||||
</group>
|
||||
<group name="src/portable/nuvoton/nuc120">
|
||||
<path>$TUSB_DIR$/src/portable/nuvoton/nuc120/dcd_nuc120.c</path>
|
||||
</group>
|
||||
<group name="src/portable/nuvoton/nuc121">
|
||||
<path>$TUSB_DIR$/src/portable/nuvoton/nuc121/dcd_nuc121.c</path>
|
||||
</group>
|
||||
<group name="src/portable/nuvoton/nuc505">
|
||||
<path>$TUSB_DIR$/src/portable/nuvoton/nuc505/dcd_nuc505.c</path>
|
||||
</group>
|
||||
<group name="src/portable/nxp/khci">
|
||||
<path>$TUSB_DIR$/src/portable/nxp/khci/dcd_khci.c</path>
|
||||
<path>$TUSB_DIR$/src/portable/nxp/khci/hcd_khci.c</path>
|
||||
</group>
|
||||
<group name="src/portable/nxp/lpc17_40">
|
||||
<path>$TUSB_DIR$/src/portable/nxp/lpc17_40/dcd_lpc17_40.c</path>
|
||||
<path>$TUSB_DIR$/src/portable/nxp/lpc17_40/hcd_lpc17_40.c</path>
|
||||
</group>
|
||||
<group name="src/portable/nxp/lpc_ip3511">
|
||||
<path>$TUSB_DIR$/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c</path>
|
||||
</group>
|
||||
<group name="src/portable/ohci">
|
||||
<path>$TUSB_DIR$/src/portable/ohci/ohci.c</path>
|
||||
</group>
|
||||
<group name="src/portable/raspberrypi/pio_usb">
|
||||
<path>$TUSB_DIR$/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c</path>
|
||||
<path>$TUSB_DIR$/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c</path>
|
||||
</group>
|
||||
<group name="src/portable/raspberrypi/rp2040">
|
||||
<path>$TUSB_DIR$/src/portable/raspberrypi/rp2040/dcd_rp2040.c</path>
|
||||
<path>$TUSB_DIR$/src/portable/raspberrypi/rp2040/hcd_rp2040.c</path>
|
||||
<path>$TUSB_DIR$/src/portable/raspberrypi/rp2040/rp2040_usb.c</path>
|
||||
</group>
|
||||
<group name="src/portable/renesas/rusb2">
|
||||
<path>$TUSB_DIR$/src/portable/renesas/rusb2/dcd_rusb2.c</path>
|
||||
<path>$TUSB_DIR$/src/portable/renesas/rusb2/hcd_rusb2.c</path>
|
||||
<path>$TUSB_DIR$/src/portable/renesas/rusb2/rusb2_common.c</path>
|
||||
</group>
|
||||
<group name="src/portable/sony/cxd56">
|
||||
<path>$TUSB_DIR$/src/portable/sony/cxd56/dcd_cxd56.c</path>
|
||||
</group>
|
||||
<group name="src/portable/st/stm32_fsdev">
|
||||
<path>$TUSB_DIR$/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c</path>
|
||||
</group>
|
||||
<group name="src/portable/st/typec">
|
||||
<path>$TUSB_DIR$/src/portable/st/typec/typec_stm32.c</path>
|
||||
</group>
|
||||
<group name="src/portable/sunxi">
|
||||
<path>$TUSB_DIR$/src/portable/sunxi/dcd_sunxi_musb.c</path>
|
||||
</group>
|
||||
<group name="src/portable/synopsys/dwc2">
|
||||
<path>$TUSB_DIR$/src/portable/synopsys/dwc2/dcd_dwc2.c</path>
|
||||
</group>
|
||||
<group name="src/portable/ti/msp430x5xx">
|
||||
<path>$TUSB_DIR$/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c</path>
|
||||
</group>
|
||||
<group name="src/portable/valentyusb/eptri">
|
||||
<path>$TUSB_DIR$/src/portable/valentyusb/eptri/dcd_eptri.c</path>
|
||||
</group>
|
||||
<group name="src/portable/wch/ch32v307">
|
||||
<path>$TUSB_DIR$/src/portable/wch/ch32v307/dcd_usbhs.c</path>
|
||||
</group>
|
||||
<group name="src/typec">
|
||||
<path>$TUSB_DIR$/src/typec/usbc.c</path>
|
||||
</group>
|
||||
<group name="lib/SEGGER_RTT/RTT">
|
||||
<path>$TUSB_DIR$/lib/SEGGER_RTT/RTT/SEGGER_RTT.c</path>
|
||||
<path>$TUSB_DIR$/lib/SEGGER_RTT/RTT/SEGGER_RTT_printf.c</path>
|
||||
<path>$TUSB_DIR$/lib/SEGGER_RTT/Syscalls/SEGGER_RTT_Syscalls_IAR.c</path>
|
||||
</group>
|
||||
</group>
|
||||
</files>
|
||||
|
||||
</iarProjectConnection>
|
||||
|
Loading…
x
Reference in New Issue
Block a user