adding host/cdc_msc_hid_freertos example

This commit is contained in:
hathach 2023-09-25 16:53:11 +07:00
parent 81cd995108
commit a7c136c03f
No known key found for this signature in database
GPG Key ID: F5D50C6D51D17CBA
20 changed files with 623 additions and 112 deletions

19
.idea/cmake.xml generated
View File

@ -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="true" 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>
@ -53,7 +54,7 @@
<configuration PROFILE_NAME="ra6m5 PORT0" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ra6m5_ek -DLOG=3 -DLOGGER=RTT -DTRACE_ETM=1 -DPORT=0" />
<configuration PROFILE_NAME="uno_r4" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=uno_r4 -DLOG=4 -DLOGGER=RTT" />
<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_m4_express" ENABLED="true" 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" />
</configurations>
</component>

View File

@ -10,7 +10,7 @@ INC += \
src/FreeRTOSConfig \
$(TOP)/hw \
$(TOP)/$(FREERTOS_SRC)/include \
$(TOP)/$(FREERTOS_PORTABLE_SRC)
$(TOP)/$(FREERTOS_PORTABLE_SRC) \
# Example source
EXAMPLE_SOURCE = \

View File

@ -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;

View File

@ -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

View File

@ -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

View 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)

View File

@ -0,0 +1,4 @@
# This file is for ESP-IDF only
idf_component_register(SRCS "hid_app.c" "main.c"
INCLUDE_DIRS "."
REQUIRES boards tinyusb_src)

View File

@ -0,0 +1,170 @@
/*
* 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;
//StackType_t cdc_stack[CDC_STACK_SZIE];
//StaticTask_t cdc_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_task(void);
extern void hid_app_task(void);
/*------------- MAIN -------------*/
int main(void) {
board_init();
printf("TinyUSB Host CDC MSC HID with FreeRTOS Example\r\n");
#if configSUPPORT_STATIC_ALLOCATION
// soft timer for blinky
blinky_tm = xTimerCreateStatic(NULL, pdMS_TO_TICKS(BLINK_MOUNTED), true, NULL, led_blinky_cb, &blinky_tmdef);
// Create a task for tinyusb device stack
xTaskCreateStatic(usb_host_task, "usbh", USBH_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_host_stack, &usb_host_taskdef);
// Create CDC task
//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", USBH_STACK_SIZE, NULL, configMAX_PRIORITIES-1, NULL);
//xTaskCreate( cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, 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();
}
// 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
}

View 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_ */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,2 @@
# Apply board specific content here
set(IDF_TARGET "esp32s2")

View File

@ -0,0 +1,45 @@
/*
* The MIT License (MIT)
*
* 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
* 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.
*/
#ifndef BOARD_H_
#define BOARD_H_
#ifdef __cplusplus
extern "C" {
#endif
// 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
#define BUTTON_PIN 0
#define BUTTON_STATE_ACTIVE 0
#ifdef __cplusplus
}
#endif
#endif /* BOARD_H_ */

View File

@ -45,16 +45,19 @@
static led_strip_t *strip;
#endif
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
//--------------------------------------------------------------------+
#if CFG_TUH_ENABLED && CFG_TUH_MAX3421
#include "driver/spi_master.h"
static void max3421_init(void);
#endif
static void configure_pins(usb_hal_context_t *usb);
// Initialize on-board peripherals : led, button, uart and USB
void board_init(void)
{
//--------------------------------------------------------------------+
// Implementation
//--------------------------------------------------------------------+
// Initialize on-board peripherals : led, button, uart and USB
void board_init(void) {
#ifdef NEOPIXEL_PIN
#ifdef NEOPIXEL_POWER_PIN
gpio_reset_pin(NEOPIXEL_POWER_PIN);
@ -79,23 +82,27 @@ void board_init(void)
gpio_set_direction(BUTTON_PIN, GPIO_MODE_INPUT);
gpio_set_pull_mode(BUTTON_PIN, BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN_ONLY : GPIO_PULLUP_ONLY);
#if CFG_TUD_ENABLED
// USB Controller Hal init
periph_module_reset(PERIPH_USB_MODULE);
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);
#endif
#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 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);
@ -115,6 +122,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 +130,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 +139,102 @@ 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;
int board_uart_read(uint8_t *buf, int len) {
(void) buf;
(void) len;
return 0;
}
// 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;
}
//--------------------------------------------------------------------+
// 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;
static void IRAM_ATTR max3421_isr_handler(void* arg)
{
(void) arg;
//uint32_t gpio_num = (uint32_t) arg;
//xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
tuh_int_handler(1);
}
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 = 128
};
ESP_ERROR_CHECK( spi_bus_initialize(MAX3421_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO) );
spi_device_interface_config_t max3421_cfg = {
.command_bits = 8,
.mode = 0,
.clock_speed_hz = 4000000, // 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) );
// Interrupt pin
// gpio_set_direction(MAX3421_INTR_PIN, GPIO_MODE_INPUT);
// gpio_set_intr_type(MAX3421_INTR_PIN, GPIO_INTR_NEGEDGE);
//
// gpio_install_isr_service(ESP_INTR_FLAG_EDGE);
// 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, size_t tx_len, uint8_t *rx_buf, size_t rx_len) {
(void) rhport;
spi_transaction_t xact = {
.length = tx_len,
.rxlength = rx_len,
.tx_buffer = tx_buf,
.rx_buffer = rx_buf
};
ESP_ERROR_CHECK(spi_device_transmit(max3421_spi, &xact));
return true;
}
#endif

View File

@ -16,40 +16,57 @@ 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})

View File

@ -659,7 +659,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result
tusb_control_request_t const * request = &_ctrl_xfer.request;
if (XFER_RESULT_SUCCESS != result) {
TU_LOG1("[%u:%u] Control %s, xferred_bytes = %lu\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes);
TU_LOG1("[%u:%u] Control %s, xferred_bytes = %u\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes);
TU_LOG1_BUF(request, 8);
TU_LOG1("\r\n");

View File

@ -882,7 +882,7 @@ 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 ) {