Merge remote-tracking branch 'upstream/master' into edpt_ISO_xfer
This commit is contained in:
41
examples/device/audio_test/CMakeLists.txt
Normal file
41
examples/device/audio_test/CMakeLists.txt
Normal file
@@ -0,0 +1,41 @@
|
||||
# use BOARD-Directory name for project id
|
||||
get_filename_component(PROJECT ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
set(PROJECT ${BOARD}-${PROJECT})
|
||||
|
||||
# TOP is absolute path to root directory of TinyUSB git repo
|
||||
set(TOP "../../..")
|
||||
get_filename_component(TOP "${TOP}" REALPATH)
|
||||
|
||||
# Check for -DFAMILY=
|
||||
if(FAMILY STREQUAL "rp2040")
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
set(PICO_SDK_PATH ${TOP}/hw/mcu/raspberrypi/pico-sdk)
|
||||
include(${PICO_SDK_PATH}/pico_sdk_init.cmake)
|
||||
project(${PROJECT})
|
||||
pico_sdk_init()
|
||||
add_executable(${PROJECT})
|
||||
|
||||
include(${TOP}/hw/bsp/${FAMILY}/family.cmake)
|
||||
|
||||
# Example source
|
||||
target_sources(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
|
||||
)
|
||||
|
||||
# Example include
|
||||
target_include_directories(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
# Example defines
|
||||
target_compile_definitions(${PROJECT} PUBLIC
|
||||
CFG_TUSB_OS=OPT_OS_PICO
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT} pico_stdlib pico_fix_rp2040_usb_device_enumeration)
|
||||
pico_add_extra_outputs(${PROJECT})
|
||||
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid FAMILY specified")
|
||||
endif()
|
@@ -45,7 +45,9 @@ extern "C" {
|
||||
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUSB_OS
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUSB_DEBUG
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
|
@@ -1,15 +1,45 @@
|
||||
# The following five lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
# use directory name for project id
|
||||
get_filename_component(PROJECT ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
set(PROJECT ${BOARD}-${PROJECT})
|
||||
|
||||
# TOP is absolute path to root directory of TinyUSB git repo
|
||||
set(TOP "../../..")
|
||||
get_filename_component(TOP "${TOP}" REALPATH)
|
||||
|
||||
# Add example src and bsp directories
|
||||
set(EXTRA_COMPONENT_DIRS "src" "${TOP}/hw/bsp/${BOARD}")
|
||||
# Check for -DFAMILY=
|
||||
if(FAMILY STREQUAL "esp32s2")
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
include(${TOP}/hw/bsp/${FAMILY}/family.cmake)
|
||||
project(${PROJECT})
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
set(SUPPORTED_TARGETS esp32s2)
|
||||
elseif(FAMILY STREQUAL "rp2040")
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
set(PICO_SDK_PATH ${TOP}/hw/mcu/raspberrypi/pico-sdk)
|
||||
include(${PICO_SDK_PATH}/pico_sdk_init.cmake)
|
||||
project(${PROJECT})
|
||||
pico_sdk_init()
|
||||
add_executable(${PROJECT})
|
||||
|
||||
project(board_test)
|
||||
include(${TOP}/hw/bsp/${FAMILY}/family.cmake)
|
||||
|
||||
# Example source
|
||||
target_sources(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
|
||||
)
|
||||
|
||||
# Example include
|
||||
target_include_directories(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
# Example defines
|
||||
target_compile_definitions(${PROJECT} PUBLIC
|
||||
CFG_TUSB_OS=OPT_OS_PICO
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT} pico_stdlib pico_fix_rp2040_usb_device_enumeration)
|
||||
pico_add_extra_outputs(${PROJECT})
|
||||
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid FAMILY specified")
|
||||
endif()
|
||||
|
@@ -1,3 +1,4 @@
|
||||
# FAMILY = "esp32s2"
|
||||
idf_component_register(SRCS "main.c"
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES freertos soc)
|
||||
|
@@ -55,10 +55,6 @@ int main(void)
|
||||
{
|
||||
uint32_t interval_ms = board_button_read() ? BLINK_PRESSED : BLINK_UNPRESSED;
|
||||
|
||||
// uart echo
|
||||
// uint8_t ch;
|
||||
// if ( board_uart_read(&ch, 1) ) board_uart_write(&ch, 1);
|
||||
|
||||
// Blink every interval ms
|
||||
if ( !(board_millis() - start_ms < interval_ms) )
|
||||
{
|
||||
|
41
examples/device/cdc_dual_ports/CMakeLists.txt
Normal file
41
examples/device/cdc_dual_ports/CMakeLists.txt
Normal file
@@ -0,0 +1,41 @@
|
||||
# use directory name for project id
|
||||
get_filename_component(PROJECT ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
set(PROJECT ${BOARD}-${PROJECT})
|
||||
|
||||
# TOP is absolute path to root directory of TinyUSB git repo
|
||||
set(TOP "../../..")
|
||||
get_filename_component(TOP "${TOP}" REALPATH)
|
||||
|
||||
# Check for -DFAMILY=
|
||||
if(FAMILY STREQUAL "rp2040")
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
set(PICO_SDK_PATH ${TOP}/hw/mcu/raspberrypi/pico-sdk)
|
||||
include(${PICO_SDK_PATH}/pico_sdk_init.cmake)
|
||||
project(${PROJECT})
|
||||
pico_sdk_init()
|
||||
add_executable(${PROJECT})
|
||||
|
||||
include(${TOP}/hw/bsp/${FAMILY}/family.cmake)
|
||||
|
||||
# Example source
|
||||
target_sources(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
|
||||
)
|
||||
|
||||
# Example include
|
||||
target_include_directories(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
# Example defines
|
||||
target_compile_definitions(${PROJECT} PUBLIC
|
||||
CFG_TUSB_OS=OPT_OS_PICO
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT} pico_stdlib pico_fix_rp2040_usb_device_enumeration)
|
||||
pico_add_extra_outputs(${PROJECT})
|
||||
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid FAMILY specified")
|
||||
endif()
|
47
examples/device/cdc_msc/CMakeLists.txt
Normal file
47
examples/device/cdc_msc/CMakeLists.txt
Normal file
@@ -0,0 +1,47 @@
|
||||
# use directory name for project id
|
||||
get_filename_component(PROJECT ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
set(PROJECT ${BOARD}-${PROJECT})
|
||||
|
||||
# TOP is absolute path to root directory of TinyUSB git repo
|
||||
set(TOP "../../..")
|
||||
get_filename_component(TOP "${TOP}" REALPATH)
|
||||
|
||||
# Check for -DFAMILY=
|
||||
if(FAMILY STREQUAL "esp32s2")
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
include(${TOP}/hw/bsp/${FAMILY}/family.cmake)
|
||||
project(${PROJECT})
|
||||
|
||||
elseif(FAMILY STREQUAL "rp2040")
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
set(PICO_SDK_PATH ${TOP}/hw/mcu/raspberrypi/pico-sdk)
|
||||
include(${PICO_SDK_PATH}/pico_sdk_init.cmake)
|
||||
project(${PROJECT})
|
||||
pico_sdk_init()
|
||||
add_executable(${PROJECT})
|
||||
|
||||
include(${TOP}/hw/bsp/${FAMILY}/family.cmake)
|
||||
|
||||
# Example source
|
||||
target_sources(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/msc_disk.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
|
||||
)
|
||||
|
||||
# Example include
|
||||
target_include_directories(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
# Example defines
|
||||
target_compile_definitions(${PROJECT} PUBLIC
|
||||
CFG_TUSB_OS=OPT_OS_PICO
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT} pico_stdlib pico_fix_rp2040_usb_device_enumeration)
|
||||
pico_add_extra_outputs(${PROJECT})
|
||||
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid FAMILY specified")
|
||||
endif()
|
@@ -65,7 +65,9 @@
|
||||
#endif
|
||||
|
||||
// This example doesn't use an RTOS
|
||||
#ifndef CFG_TUSB_OS
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#endif
|
||||
|
||||
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
|
||||
// #define CFG_TUSB_DEBUG 0
|
||||
|
@@ -104,6 +104,18 @@ enum
|
||||
#define EPNUM_MSC_OUT 0x04
|
||||
#define EPNUM_MSC_IN 0x85
|
||||
|
||||
#elif CFG_TUSB_MCU == OPT_MCU_CXD56
|
||||
// CXD56 doesn't support a same endpoint number with different direction IN and OUT
|
||||
// e.g EP1 OUT & EP1 IN cannot exist together
|
||||
// CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number
|
||||
// 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN)
|
||||
#define EPNUM_CDC_NOTIF 0x83
|
||||
#define EPNUM_CDC_OUT 0x02
|
||||
#define EPNUM_CDC_IN 0x81
|
||||
|
||||
#define EPNUM_MSC_OUT 0x05
|
||||
#define EPNUM_MSC_IN 0x84
|
||||
|
||||
#else
|
||||
#define EPNUM_CDC_NOTIF 0x81
|
||||
#define EPNUM_CDC_OUT 0x02
|
||||
|
0
examples/device/cdc_msc_freertos/.skip.MCU_RP2040
Normal file
0
examples/device/cdc_msc_freertos/.skip.MCU_RP2040
Normal file
@@ -1,15 +1,18 @@
|
||||
# The following five lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
# use BOARD-Directory name for project id
|
||||
get_filename_component(PROJECT ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
set(PROJECT ${BOARD}-${PROJECT})
|
||||
|
||||
# TOP is absolute path to root directory of TinyUSB git repo
|
||||
set(TOP "../../..")
|
||||
get_filename_component(TOP "${TOP}" REALPATH)
|
||||
|
||||
# Add example src and bsp directories
|
||||
set(EXTRA_COMPONENT_DIRS "src" "${TOP}/hw/bsp/${BOARD}")
|
||||
# Check for -DFAMILY=
|
||||
if(FAMILY STREQUAL "esp32s2")
|
||||
include(${TOP}/hw/bsp/${FAMILY}/family.cmake)
|
||||
project(${PROJECT})
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
set(SUPPORTED_TARGETS esp32s2)
|
||||
|
||||
project(cdc_msc_freertos)
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid FAMILY specified")
|
||||
endif()
|
||||
|
41
examples/device/dfu_runtime/CMakeLists.txt
Normal file
41
examples/device/dfu_runtime/CMakeLists.txt
Normal file
@@ -0,0 +1,41 @@
|
||||
# use directory name for project id
|
||||
get_filename_component(PROJECT ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
set(PROJECT ${BOARD}-${PROJECT})
|
||||
|
||||
# TOP is absolute path to root directory of TinyUSB git repo
|
||||
set(TOP "../../..")
|
||||
get_filename_component(TOP "${TOP}" REALPATH)
|
||||
|
||||
# Check for -DFAMILY=
|
||||
if(FAMILY STREQUAL "rp2040")
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
set(PICO_SDK_PATH ${TOP}/hw/mcu/raspberrypi/pico-sdk)
|
||||
include(${PICO_SDK_PATH}/pico_sdk_init.cmake)
|
||||
project(${PROJECT})
|
||||
pico_sdk_init()
|
||||
add_executable(${PROJECT})
|
||||
|
||||
include(${TOP}/hw/bsp/${FAMILY}/family.cmake)
|
||||
|
||||
# Example source
|
||||
target_sources(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
|
||||
)
|
||||
|
||||
# Example include
|
||||
target_include_directories(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
# Example defines
|
||||
target_compile_definitions(${PROJECT} PUBLIC
|
||||
CFG_TUSB_OS=OPT_OS_PICO
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT} pico_stdlib pico_fix_rp2040_usb_device_enumeration)
|
||||
pico_add_extra_outputs(${PROJECT})
|
||||
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid FAMILY specified")
|
||||
endif()
|
@@ -112,7 +112,7 @@ void tud_resume_cb(void)
|
||||
}
|
||||
|
||||
// Invoked on DFU_DETACH request to reboot to the bootloader
|
||||
void tud_dfu_rt_reboot_to_dfu(void)
|
||||
void tud_dfu_runtime_reboot_to_dfu_cb(void)
|
||||
{
|
||||
blink_interval_ms = BLINK_DFU_MODE;
|
||||
}
|
@@ -46,8 +46,9 @@
|
||||
#error "Incorrect RHPort configuration"
|
||||
#endif
|
||||
|
||||
// This example doesn't use an RTOS
|
||||
#ifndef CFG_TUSB_OS
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#endif
|
||||
|
||||
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
|
||||
// #define CFG_TUSB_DEBUG 0
|
||||
@@ -77,7 +78,7 @@
|
||||
|
||||
//------------- CLASS -------------//
|
||||
|
||||
#define CFG_TUD_DFU_RT 1
|
||||
#define CFG_TUD_DFU_RUNTIME 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
42
examples/device/dynamic_configuration/CMakeLists.txt
Normal file
42
examples/device/dynamic_configuration/CMakeLists.txt
Normal file
@@ -0,0 +1,42 @@
|
||||
# use directory name for project id
|
||||
get_filename_component(PROJECT ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
set(PROJECT ${BOARD}-${PROJECT})
|
||||
|
||||
# TOP is absolute path to root directory of TinyUSB git repo
|
||||
set(TOP "../../..")
|
||||
get_filename_component(TOP "${TOP}" REALPATH)
|
||||
|
||||
# Check for -DFAMILY=
|
||||
if(FAMILY STREQUAL "rp2040")
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
set(PICO_SDK_PATH ${TOP}/hw/mcu/raspberrypi/pico-sdk)
|
||||
include(${PICO_SDK_PATH}/pico_sdk_init.cmake)
|
||||
project(${PROJECT})
|
||||
pico_sdk_init()
|
||||
add_executable(${PROJECT})
|
||||
|
||||
include(${TOP}/hw/bsp/${FAMILY}/family.cmake)
|
||||
|
||||
# Example source
|
||||
target_sources(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/msc_disk.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
|
||||
)
|
||||
|
||||
# Example include
|
||||
target_include_directories(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
# Example defines
|
||||
target_compile_definitions(${PROJECT} PUBLIC
|
||||
CFG_TUSB_OS=OPT_OS_PICO
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT} pico_stdlib pico_fix_rp2040_usb_device_enumeration)
|
||||
pico_add_extra_outputs(${PROJECT})
|
||||
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid FAMILY specified")
|
||||
endif()
|
@@ -165,6 +165,12 @@ void midi_task(void)
|
||||
{
|
||||
static uint32_t start_ms = 0;
|
||||
|
||||
// The MIDI interface always creates input and output port/jack descriptors
|
||||
// regardless of these being used or not. Therefore incoming traffic should be read
|
||||
// (possibly just discarded) to avoid the sender blocking in IO
|
||||
uint8_t packet[4];
|
||||
while(tud_midi_available()) tud_midi_receive(packet);
|
||||
|
||||
// send note every 1000 ms
|
||||
if (board_millis() - start_ms < 286) return; // not enough time
|
||||
start_ms += 286;
|
||||
|
@@ -64,8 +64,9 @@
|
||||
#error "Incorrect RHPort configuration"
|
||||
#endif
|
||||
|
||||
// This example doesn't use an RTOS
|
||||
#ifndef CFG_TUSB_OS
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#endif
|
||||
|
||||
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
|
||||
// #define CFG_TUSB_DEBUG 0
|
||||
|
41
examples/device/hid_composite/CMakeLists.txt
Normal file
41
examples/device/hid_composite/CMakeLists.txt
Normal file
@@ -0,0 +1,41 @@
|
||||
# use directory name for project id
|
||||
get_filename_component(PROJECT ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
set(PROJECT ${BOARD}-${PROJECT})
|
||||
|
||||
# TOP is absolute path to root directory of TinyUSB git repo
|
||||
set(TOP "../../..")
|
||||
get_filename_component(TOP "${TOP}" REALPATH)
|
||||
|
||||
# Check for -DFAMILY=
|
||||
if(FAMILY STREQUAL "rp2040")
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
set(PICO_SDK_PATH ${TOP}/hw/mcu/raspberrypi/pico-sdk)
|
||||
include(${PICO_SDK_PATH}/pico_sdk_init.cmake)
|
||||
project(${PROJECT})
|
||||
pico_sdk_init()
|
||||
add_executable(${PROJECT})
|
||||
|
||||
include(${TOP}/hw/bsp/${FAMILY}/family.cmake)
|
||||
|
||||
# Example source
|
||||
target_sources(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
|
||||
)
|
||||
|
||||
# Example include
|
||||
target_include_directories(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
# Example defines
|
||||
target_compile_definitions(${PROJECT} PUBLIC
|
||||
CFG_TUSB_OS=OPT_OS_PICO
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT} pico_stdlib pico_fix_rp2040_usb_device_enumeration)
|
||||
pico_add_extra_outputs(${PROJECT})
|
||||
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid FAMILY specified")
|
||||
endif()
|
@@ -104,6 +104,98 @@ void tud_resume_cb(void)
|
||||
// USB HID
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
static void send_hid_report(uint8_t report_id, uint32_t btn)
|
||||
{
|
||||
// skip if hid is not ready yet
|
||||
if ( !tud_hid_ready() ) return;
|
||||
|
||||
switch(report_id)
|
||||
{
|
||||
case REPORT_ID_KEYBOARD:
|
||||
{
|
||||
// use to avoid send multiple consecutive zero report for keyboard
|
||||
static bool has_keyboard_key = false;
|
||||
|
||||
if ( btn )
|
||||
{
|
||||
uint8_t keycode[6] = { 0 };
|
||||
keycode[0] = HID_KEY_A;
|
||||
|
||||
tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, keycode);
|
||||
has_keyboard_key = true;
|
||||
}else
|
||||
{
|
||||
// send empty key report if previously has key pressed
|
||||
if (has_keyboard_key) tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, NULL);
|
||||
has_keyboard_key = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case REPORT_ID_MOUSE:
|
||||
{
|
||||
int8_t const delta = 5;
|
||||
|
||||
// no button, right + down, no scroll, no pan
|
||||
tud_hid_mouse_report(REPORT_ID_MOUSE, 0x00, delta, delta, 0, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case REPORT_ID_CONSUMER_CONTROL:
|
||||
{
|
||||
// use to avoid send multiple consecutive zero report
|
||||
static bool has_consumer_key = false;
|
||||
|
||||
if ( btn )
|
||||
{
|
||||
// volume down
|
||||
uint16_t volume_down = HID_USAGE_CONSUMER_VOLUME_DECREMENT;
|
||||
tud_hid_report(REPORT_ID_CONSUMER_CONTROL, &volume_down, 2);
|
||||
has_consumer_key = true;
|
||||
}else
|
||||
{
|
||||
// send empty key report (release key) if previously has key pressed
|
||||
uint16_t empty_key = 0;
|
||||
if (has_consumer_key) tud_hid_report(REPORT_ID_CONSUMER_CONTROL, &empty_key, 2);
|
||||
has_consumer_key = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case REPORT_ID_GAMEPAD:
|
||||
{
|
||||
// use to avoid send multiple consecutive zero report for keyboard
|
||||
static bool has_gamepad_key = false;
|
||||
|
||||
hid_gamepad_report_t report =
|
||||
{
|
||||
.x = 0, .y = 0, .z = 0, .rz = 0, .rx = 0, .ry = 0,
|
||||
.hat = 0, .buttons = 0
|
||||
};
|
||||
|
||||
if ( btn )
|
||||
{
|
||||
report.hat = GAMEPAD_HAT_UP;
|
||||
report.buttons = GAMEPAD_BUTTON_A;
|
||||
tud_hid_report(REPORT_ID_GAMEPAD, &report, sizeof(report));
|
||||
|
||||
has_gamepad_key = true;
|
||||
}else
|
||||
{
|
||||
report.hat = GAMEPAD_HAT_CENTERED;
|
||||
report.buttons = 0;
|
||||
if (has_gamepad_key) tud_hid_report(REPORT_ID_GAMEPAD, &report, sizeof(report));
|
||||
has_gamepad_key = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
// Every 10ms, we will sent 1 report for each HID profile (keyboard, mouse etc ..)
|
||||
// tud_hid_report_complete_cb() is used to send the next report after previous one is complete
|
||||
void hid_task(void)
|
||||
{
|
||||
// Poll every 10ms
|
||||
@@ -121,46 +213,28 @@ void hid_task(void)
|
||||
// Wake up host if we are in suspend mode
|
||||
// and REMOTE_WAKEUP feature is enabled by host
|
||||
tud_remote_wakeup();
|
||||
}
|
||||
|
||||
/*------------- Mouse -------------*/
|
||||
if ( tud_hid_ready() )
|
||||
}else
|
||||
{
|
||||
if ( btn )
|
||||
{
|
||||
int8_t const delta = 5;
|
||||
|
||||
// no button, right + down, no scroll pan
|
||||
tud_hid_mouse_report(REPORT_ID_MOUSE, 0x00, delta, delta, 0, 0);
|
||||
|
||||
// delay a bit before attempt to send keyboard report
|
||||
board_delay(10);
|
||||
}
|
||||
}
|
||||
|
||||
/*------------- Keyboard -------------*/
|
||||
if ( tud_hid_ready() )
|
||||
{
|
||||
// use to avoid send multiple consecutive zero report for keyboard
|
||||
static bool has_key = false;
|
||||
|
||||
if ( btn )
|
||||
{
|
||||
uint8_t keycode[6] = { 0 };
|
||||
keycode[0] = HID_KEY_A;
|
||||
|
||||
tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, keycode);
|
||||
|
||||
has_key = true;
|
||||
}else
|
||||
{
|
||||
// send empty key report if previously has key pressed
|
||||
if (has_key) tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, NULL);
|
||||
has_key = false;
|
||||
}
|
||||
// Send the 1st of report chain, the rest will be sent by tud_hid_report_complete_cb()
|
||||
send_hid_report(REPORT_ID_KEYBOARD, btn);
|
||||
}
|
||||
}
|
||||
|
||||
// Invoked when sent REPORT successfully to host
|
||||
// Application can use this to send the next report
|
||||
// Note: For composite reports, report[0] is report ID
|
||||
void tud_hid_report_complete_cb(uint8_t itf, uint8_t const* report, uint8_t len)
|
||||
{
|
||||
(void) itf;
|
||||
(void) len;
|
||||
|
||||
uint8_t next_report_id = report[0] + 1;
|
||||
|
||||
if (next_report_id < REPORT_ID_COUNT)
|
||||
{
|
||||
send_hid_report(next_report_id, board_button_read());
|
||||
}
|
||||
}
|
||||
|
||||
// Invoked when received GET_REPORT control request
|
||||
// Application must fill buffer report's content and return its length.
|
||||
|
@@ -64,8 +64,9 @@
|
||||
#error "Incorrect RHPort configuration"
|
||||
#endif
|
||||
|
||||
// This example doesn't use an RTOS
|
||||
#ifndef CFG_TUSB_OS
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#endif
|
||||
|
||||
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
|
||||
// #define CFG_TUSB_DEBUG 0
|
||||
|
@@ -73,8 +73,10 @@ uint8_t const * tud_descriptor_device_cb(void)
|
||||
|
||||
uint8_t const desc_hid_report[] =
|
||||
{
|
||||
TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(REPORT_ID_KEYBOARD) ),
|
||||
TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(REPORT_ID_MOUSE) )
|
||||
TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(REPORT_ID_KEYBOARD )),
|
||||
TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(REPORT_ID_MOUSE )),
|
||||
TUD_HID_REPORT_DESC_CONSUMER( HID_REPORT_ID(REPORT_ID_CONSUMER_CONTROL )),
|
||||
TUD_HID_REPORT_DESC_GAMEPAD ( HID_REPORT_ID(REPORT_ID_GAMEPAD ))
|
||||
};
|
||||
|
||||
// Invoked when received GET HID REPORT DESCRIPTOR
|
||||
@@ -104,8 +106,8 @@ uint8_t const desc_configuration[] =
|
||||
// Config number, interface count, string index, total length, attribute, power in mA
|
||||
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
|
||||
|
||||
// Interface number, string index, protocol, report descriptor len, EP In & Out address, size & polling interval
|
||||
TUD_HID_DESCRIPTOR(ITF_NUM_HID, 0, HID_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 10)
|
||||
// Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval
|
||||
TUD_HID_DESCRIPTOR(ITF_NUM_HID, 0, HID_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 5)
|
||||
};
|
||||
|
||||
// Invoked when received GET CONFIGURATION DESCRIPTOR
|
||||
|
@@ -28,7 +28,10 @@
|
||||
enum
|
||||
{
|
||||
REPORT_ID_KEYBOARD = 1,
|
||||
REPORT_ID_MOUSE
|
||||
REPORT_ID_MOUSE,
|
||||
REPORT_ID_CONSUMER_CONTROL,
|
||||
REPORT_ID_GAMEPAD,
|
||||
REPORT_ID_COUNT
|
||||
};
|
||||
|
||||
#endif /* USB_DESCRIPTORS_H_ */
|
||||
|
@@ -1,15 +1,18 @@
|
||||
# The following five lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
# use BOARD-Directory name for project id
|
||||
get_filename_component(PROJECT ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
set(PROJECT ${BOARD}-${PROJECT})
|
||||
|
||||
# TOP is absolute path to root directory of TinyUSB git repo
|
||||
set(TOP "../../..")
|
||||
get_filename_component(TOP "${TOP}" REALPATH)
|
||||
|
||||
# Add example src and bsp directories
|
||||
set(EXTRA_COMPONENT_DIRS "src" "${TOP}/hw/bsp/${BOARD}")
|
||||
# Check for -DFAMILY=
|
||||
if(FAMILY STREQUAL "esp32s2")
|
||||
include(${TOP}/hw/bsp/${FAMILY}/family.cmake)
|
||||
project(${PROJECT})
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
set(SUPPORTED_TARGETS esp32s2)
|
||||
|
||||
project(hid_composite_freertos)
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid FAMILY specified")
|
||||
endif()
|
||||
|
@@ -163,6 +163,96 @@ void tud_resume_cb(void)
|
||||
// USB HID
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
static void send_hid_report(uint8_t report_id, uint32_t btn)
|
||||
{
|
||||
// skip if hid is not ready yet
|
||||
if ( !tud_hid_ready() ) return;
|
||||
|
||||
switch(report_id)
|
||||
{
|
||||
case REPORT_ID_KEYBOARD:
|
||||
{
|
||||
// use to avoid send multiple consecutive zero report for keyboard
|
||||
static bool has_keyboard_key = false;
|
||||
|
||||
if ( btn )
|
||||
{
|
||||
uint8_t keycode[6] = { 0 };
|
||||
keycode[0] = HID_KEY_A;
|
||||
|
||||
tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, keycode);
|
||||
has_keyboard_key = true;
|
||||
}else
|
||||
{
|
||||
// send empty key report if previously has key pressed
|
||||
if (has_keyboard_key) tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, NULL);
|
||||
has_keyboard_key = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case REPORT_ID_MOUSE:
|
||||
{
|
||||
int8_t const delta = 5;
|
||||
|
||||
// no button, right + down, no scroll, no pan
|
||||
tud_hid_mouse_report(REPORT_ID_MOUSE, 0x00, delta, delta, 0, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case REPORT_ID_CONSUMER_CONTROL:
|
||||
{
|
||||
// use to avoid send multiple consecutive zero report
|
||||
static bool has_consumer_key = false;
|
||||
|
||||
if ( btn )
|
||||
{
|
||||
// volume down
|
||||
uint16_t volume_down = HID_USAGE_CONSUMER_VOLUME_DECREMENT;
|
||||
tud_hid_report(REPORT_ID_CONSUMER_CONTROL, &volume_down, 2);
|
||||
has_consumer_key = true;
|
||||
}else
|
||||
{
|
||||
// send empty key report (release key) if previously has key pressed
|
||||
uint16_t empty_key = 0;
|
||||
if (has_consumer_key) tud_hid_report(REPORT_ID_CONSUMER_CONTROL, &empty_key, 2);
|
||||
has_consumer_key = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case REPORT_ID_GAMEPAD:
|
||||
{
|
||||
// use to avoid send multiple consecutive zero report for keyboard
|
||||
static bool has_gamepad_key = false;
|
||||
|
||||
hid_gamepad_report_t report =
|
||||
{
|
||||
.x = 0, .y = 0, .z = 0, .rz = 0, .rx = 0, .ry = 0,
|
||||
.hat = 0, .buttons = 0
|
||||
};
|
||||
|
||||
if ( btn )
|
||||
{
|
||||
report.hat = GAMEPAD_HAT_UP;
|
||||
report.buttons = GAMEPAD_BUTTON_A;
|
||||
tud_hid_report(REPORT_ID_GAMEPAD, &report, sizeof(report));
|
||||
|
||||
has_gamepad_key = true;
|
||||
}else
|
||||
{
|
||||
report.hat = GAMEPAD_HAT_CENTERED;
|
||||
report.buttons = 0;
|
||||
if (has_gamepad_key) tud_hid_report(REPORT_ID_GAMEPAD, &report, sizeof(report));
|
||||
has_gamepad_key = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void hid_task(void* param)
|
||||
{
|
||||
(void) param;
|
||||
@@ -181,46 +271,31 @@ void hid_task(void* param)
|
||||
// and REMOTE_WAKEUP feature is enabled by host
|
||||
tud_remote_wakeup();
|
||||
}
|
||||
|
||||
/*------------- Mouse -------------*/
|
||||
if ( tud_hid_ready() )
|
||||
else
|
||||
{
|
||||
if ( btn )
|
||||
{
|
||||
int8_t const delta = 5;
|
||||
|
||||
// no button, right + down, no scroll pan
|
||||
tud_hid_mouse_report(REPORT_ID_MOUSE, 0x00, delta, delta, 0, 0);
|
||||
|
||||
// delay a bit before attempt to send keyboard report
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
}
|
||||
|
||||
/*------------- Keyboard -------------*/
|
||||
if ( tud_hid_ready() )
|
||||
{
|
||||
// use to avoid send multiple consecutive zero report for keyboard
|
||||
static bool has_key = false;
|
||||
|
||||
if ( btn )
|
||||
{
|
||||
uint8_t keycode[6] = { 0 };
|
||||
keycode[0] = HID_KEY_A;
|
||||
|
||||
tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, keycode);
|
||||
|
||||
has_key = true;
|
||||
}else
|
||||
{
|
||||
// send empty key report if previously has key pressed
|
||||
if (has_key) tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, NULL);
|
||||
has_key = false;
|
||||
}
|
||||
// Send the 1st of report chain, the rest will be sent by tud_hid_report_complete_cb()
|
||||
send_hid_report(REPORT_ID_KEYBOARD, btn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Invoked when sent REPORT successfully to host
|
||||
// Application can use this to send the next report
|
||||
// Note: For composite reports, report[0] is report ID
|
||||
void tud_hid_report_complete_cb(uint8_t itf, uint8_t const* report, uint8_t len)
|
||||
{
|
||||
(void) itf;
|
||||
(void) len;
|
||||
|
||||
uint8_t next_report_id = report[0] + 1;
|
||||
|
||||
if (next_report_id < REPORT_ID_COUNT)
|
||||
{
|
||||
send_hid_report(next_report_id, board_button_read());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Invoked when received GET_REPORT control request
|
||||
// Application must fill buffer report's content and return its length.
|
||||
// Return zero will cause the stack to STALL request
|
||||
|
@@ -73,8 +73,10 @@ uint8_t const * tud_descriptor_device_cb(void)
|
||||
|
||||
uint8_t const desc_hid_report[] =
|
||||
{
|
||||
TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(REPORT_ID_KEYBOARD) ),
|
||||
TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(REPORT_ID_MOUSE) )
|
||||
TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(REPORT_ID_KEYBOARD )),
|
||||
TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(REPORT_ID_MOUSE )),
|
||||
TUD_HID_REPORT_DESC_CONSUMER( HID_REPORT_ID(REPORT_ID_CONSUMER_CONTROL )),
|
||||
TUD_HID_REPORT_DESC_GAMEPAD ( HID_REPORT_ID(REPORT_ID_GAMEPAD ))
|
||||
};
|
||||
|
||||
// Invoked when received GET HID REPORT DESCRIPTOR
|
||||
@@ -104,8 +106,8 @@ uint8_t const desc_configuration[] =
|
||||
// Config number, interface count, string index, total length, attribute, power in mA
|
||||
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
|
||||
|
||||
// Interface number, string index, protocol, report descriptor len, EP In & Out address, size & polling interval
|
||||
TUD_HID_DESCRIPTOR(ITF_NUM_HID, 0, HID_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 10)
|
||||
// Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval
|
||||
TUD_HID_DESCRIPTOR(ITF_NUM_HID, 0, HID_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 5)
|
||||
};
|
||||
|
||||
// Invoked when received GET CONFIGURATION DESCRIPTOR
|
||||
|
@@ -28,7 +28,10 @@
|
||||
enum
|
||||
{
|
||||
REPORT_ID_KEYBOARD = 1,
|
||||
REPORT_ID_MOUSE
|
||||
REPORT_ID_MOUSE,
|
||||
REPORT_ID_CONSUMER_CONTROL,
|
||||
REPORT_ID_GAMEPAD,
|
||||
REPORT_ID_COUNT
|
||||
};
|
||||
|
||||
#endif /* USB_DESCRIPTORS_H_ */
|
||||
|
41
examples/device/hid_generic_inout/CMakeLists.txt
Normal file
41
examples/device/hid_generic_inout/CMakeLists.txt
Normal file
@@ -0,0 +1,41 @@
|
||||
# use directory name for project id
|
||||
get_filename_component(PROJECT ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
set(PROJECT ${BOARD}-${PROJECT})
|
||||
|
||||
# TOP is absolute path to root directory of TinyUSB git repo
|
||||
set(TOP "../../..")
|
||||
get_filename_component(TOP "${TOP}" REALPATH)
|
||||
|
||||
# Check for -DFAMILY=
|
||||
if(FAMILY STREQUAL "rp2040")
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
set(PICO_SDK_PATH ${TOP}/hw/mcu/raspberrypi/pico-sdk)
|
||||
include(${PICO_SDK_PATH}/pico_sdk_init.cmake)
|
||||
project(${PROJECT})
|
||||
pico_sdk_init()
|
||||
add_executable(${PROJECT})
|
||||
|
||||
include(${TOP}/hw/bsp/${FAMILY}/family.cmake)
|
||||
|
||||
# Example source
|
||||
target_sources(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
|
||||
)
|
||||
|
||||
# Example include
|
||||
target_include_directories(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
# Example defines
|
||||
target_compile_definitions(${PROJECT} PUBLIC
|
||||
CFG_TUSB_OS=OPT_OS_PICO
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT} pico_stdlib pico_fix_rp2040_usb_device_enumeration)
|
||||
pico_add_extra_outputs(${PROJECT})
|
||||
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid FAMILY specified")
|
||||
endif()
|
@@ -36,8 +36,8 @@
|
||||
*
|
||||
* There are 2 ways to test the sketch
|
||||
* 1. Using nodejs
|
||||
* - Install nodejs and nmp to your PC
|
||||
* - Install execellent node-hid (https://github.com/node-hid/node-hid) by
|
||||
* - Install nodejs and npm to your PC
|
||||
* - Install excellent node-hid (https://github.com/node-hid/node-hid) by
|
||||
* $ npm install node-hid
|
||||
* - Run provided hid test script
|
||||
* $ node hid_test.js
|
||||
|
@@ -64,8 +64,9 @@
|
||||
#error "Incorrect RHPort configuration"
|
||||
#endif
|
||||
|
||||
// This example doesn't use an RTOS
|
||||
#ifndef CFG_TUSB_OS
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#endif
|
||||
|
||||
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
|
||||
// #define CFG_TUSB_DEBUG 0
|
||||
|
41
examples/device/hid_multiple_interface/CMakeLists.txt
Normal file
41
examples/device/hid_multiple_interface/CMakeLists.txt
Normal file
@@ -0,0 +1,41 @@
|
||||
# use directory name for project id
|
||||
get_filename_component(PROJECT ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
set(PROJECT ${BOARD}-${PROJECT})
|
||||
|
||||
# TOP is absolute path to root directory of TinyUSB git repo
|
||||
set(TOP "../../..")
|
||||
get_filename_component(TOP "${TOP}" REALPATH)
|
||||
|
||||
# Check for -DFAMILY=
|
||||
if(FAMILY STREQUAL "rp2040")
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
set(PICO_SDK_PATH ${TOP}/hw/mcu/raspberrypi/pico-sdk)
|
||||
include(${PICO_SDK_PATH}/pico_sdk_init.cmake)
|
||||
project(${PROJECT})
|
||||
pico_sdk_init()
|
||||
add_executable(${PROJECT})
|
||||
|
||||
include(${TOP}/hw/bsp/${FAMILY}/family.cmake)
|
||||
|
||||
# Example source
|
||||
target_sources(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
|
||||
)
|
||||
|
||||
# Example include
|
||||
target_include_directories(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
# Example defines
|
||||
target_compile_definitions(${PROJECT} PUBLIC
|
||||
CFG_TUSB_OS=OPT_OS_PICO
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT} pico_stdlib pico_fix_rp2040_usb_device_enumeration)
|
||||
pico_add_extra_outputs(${PROJECT})
|
||||
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid FAMILY specified")
|
||||
endif()
|
@@ -64,8 +64,9 @@
|
||||
#error "Incorrect RHPort configuration"
|
||||
#endif
|
||||
|
||||
// This example doesn't use an RTOS
|
||||
#ifndef CFG_TUSB_OS
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#endif
|
||||
|
||||
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
|
||||
// #define CFG_TUSB_DEBUG 0
|
||||
|
@@ -118,7 +118,7 @@ uint8_t const desc_configuration[] =
|
||||
// Config number, interface count, string index, total length, attribute, power in mA
|
||||
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
|
||||
|
||||
// Interface number, string index, protocol, report descriptor len, EP In & Out address, size & polling interval
|
||||
// Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval
|
||||
TUD_HID_DESCRIPTOR(ITF_NUM_HID1, 4, HID_PROTOCOL_NONE, sizeof(desc_hid_report1), EPNUM_HID1, CFG_TUD_HID_EP_BUFSIZE, 10),
|
||||
TUD_HID_DESCRIPTOR(ITF_NUM_HID2, 5, HID_PROTOCOL_NONE, sizeof(desc_hid_report2), EPNUM_HID2, CFG_TUD_HID_EP_BUFSIZE, 10)
|
||||
};
|
||||
@@ -140,11 +140,11 @@ uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
|
||||
char const* string_desc_arr [] =
|
||||
{
|
||||
(const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
|
||||
"TinyUSB", // 1: Manufacturer
|
||||
"TinyUSB Device", // 2: Product
|
||||
"123456", // 3: Serials, should use chip ID
|
||||
"Keyboard Interface", // 4: Interface 1 String
|
||||
"Mouse Interface", // 5: Interface 2 String
|
||||
"TinyUSB", // 1: Manufacturer
|
||||
"TinyUSB Device", // 2: Product
|
||||
"123456", // 3: Serials, should use chip ID
|
||||
"Keyboard Interface", // 4: Interface 1 String
|
||||
"Mouse Interface", // 5: Interface 2 String
|
||||
};
|
||||
|
||||
static uint16_t _desc_str[32];
|
||||
|
41
examples/device/midi_test/CMakeLists.txt
Normal file
41
examples/device/midi_test/CMakeLists.txt
Normal file
@@ -0,0 +1,41 @@
|
||||
# use directory name for project id
|
||||
get_filename_component(PROJECT ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
set(PROJECT ${BOARD}-${PROJECT})
|
||||
|
||||
# TOP is absolute path to root directory of TinyUSB git repo
|
||||
set(TOP "../../..")
|
||||
get_filename_component(TOP "${TOP}" REALPATH)
|
||||
|
||||
# Check for -DFAMILY=
|
||||
if(FAMILY STREQUAL "rp2040")
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
set(PICO_SDK_PATH ${TOP}/hw/mcu/raspberrypi/pico-sdk)
|
||||
include(${PICO_SDK_PATH}/pico_sdk_init.cmake)
|
||||
project(${PROJECT})
|
||||
pico_sdk_init()
|
||||
add_executable(${PROJECT})
|
||||
|
||||
include(${TOP}/hw/bsp/${FAMILY}/family.cmake)
|
||||
|
||||
# Example source
|
||||
target_sources(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
|
||||
)
|
||||
|
||||
# Example include
|
||||
target_include_directories(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
# Example defines
|
||||
target_compile_definitions(${PROJECT} PUBLIC
|
||||
CFG_TUSB_OS=OPT_OS_PICO
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT} pico_stdlib pico_fix_rp2040_usb_device_enumeration)
|
||||
pico_add_extra_outputs(${PROJECT})
|
||||
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid FAMILY specified")
|
||||
endif()
|
@@ -125,6 +125,12 @@ void midi_task(void)
|
||||
{
|
||||
static uint32_t start_ms = 0;
|
||||
|
||||
// The MIDI interface always creates input and output port/jack descriptors
|
||||
// regardless of these being used or not. Therefore incoming traffic should be read
|
||||
// (possibly just discarded) to avoid the sender blocking in IO
|
||||
uint8_t packet[4];
|
||||
while(tud_midi_available()) tud_midi_receive(packet);
|
||||
|
||||
// send note every 1000 ms
|
||||
if (board_millis() - start_ms < 286) return; // not enough time
|
||||
start_ms += 286;
|
||||
|
@@ -64,8 +64,9 @@
|
||||
#error "Incorrect RHPort configuration"
|
||||
#endif
|
||||
|
||||
// This example doesn't use an RTOS
|
||||
#ifndef CFG_TUSB_OS
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#endif
|
||||
|
||||
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
|
||||
// #define CFG_TUSB_DEBUG 0
|
||||
|
42
examples/device/msc_dual_lun/CMakeLists.txt
Normal file
42
examples/device/msc_dual_lun/CMakeLists.txt
Normal file
@@ -0,0 +1,42 @@
|
||||
# use directory name for project id
|
||||
get_filename_component(PROJECT ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
set(PROJECT ${BOARD}-${PROJECT})
|
||||
|
||||
# TOP is absolute path to root directory of TinyUSB git repo
|
||||
set(TOP "../../..")
|
||||
get_filename_component(TOP "${TOP}" REALPATH)
|
||||
|
||||
# Check for -DFAMILY=
|
||||
if(FAMILY STREQUAL "rp2040")
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
set(PICO_SDK_PATH ${TOP}/hw/mcu/raspberrypi/pico-sdk)
|
||||
include(${PICO_SDK_PATH}/pico_sdk_init.cmake)
|
||||
project(${PROJECT})
|
||||
pico_sdk_init()
|
||||
add_executable(${PROJECT})
|
||||
|
||||
include(${TOP}/hw/bsp/${FAMILY}/family.cmake)
|
||||
|
||||
# Example source
|
||||
target_sources(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/msc_disk_dual.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
|
||||
)
|
||||
|
||||
# Example include
|
||||
target_include_directories(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
# Example defines
|
||||
target_compile_definitions(${PROJECT} PUBLIC
|
||||
CFG_TUSB_OS=OPT_OS_PICO
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT} pico_stdlib pico_fix_rp2040_usb_device_enumeration)
|
||||
pico_add_extra_outputs(${PROJECT})
|
||||
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid FAMILY specified")
|
||||
endif()
|
@@ -64,8 +64,9 @@
|
||||
#error "Incorrect RHPort configuration"
|
||||
#endif
|
||||
|
||||
// This example doesn't use an RTOS
|
||||
#ifndef CFG_TUSB_OS
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#endif
|
||||
|
||||
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
|
||||
// #define CFG_TUSB_DEBUG 0
|
||||
|
88
examples/device/net_lwip_webserver/CMakeLists.txt
Normal file
88
examples/device/net_lwip_webserver/CMakeLists.txt
Normal file
@@ -0,0 +1,88 @@
|
||||
# use directory name for project id
|
||||
get_filename_component(PROJECT ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
set(PROJECT ${BOARD}-${PROJECT})
|
||||
|
||||
# TOP is absolute path to root directory of TinyUSB git repo
|
||||
set(TOP "../../..")
|
||||
get_filename_component(TOP "${TOP}" REALPATH)
|
||||
|
||||
# Check for -DFAMILY=
|
||||
if(FAMILY STREQUAL "rp2040")
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
set(PICO_SDK_PATH ${TOP}/hw/mcu/raspberrypi/pico-sdk)
|
||||
include(${PICO_SDK_PATH}/pico_sdk_init.cmake)
|
||||
project(${PROJECT})
|
||||
pico_sdk_init()
|
||||
add_executable(${PROJECT})
|
||||
|
||||
include(${TOP}/hw/bsp/${FAMILY}/family.cmake)
|
||||
|
||||
# lwip Stack source
|
||||
set(SRC_LWIP
|
||||
${TOP}/lib/lwip/src/core/altcp.c
|
||||
${TOP}/lib/lwip/src/core/altcp_alloc.c
|
||||
${TOP}/lib/lwip/src/core/altcp_tcp.c
|
||||
${TOP}/lib/lwip/src/core/def.c
|
||||
${TOP}/lib/lwip/src/core/dns.c
|
||||
${TOP}/lib/lwip/src/core/inet_chksum.c
|
||||
${TOP}/lib/lwip/src/core/init.c
|
||||
${TOP}/lib/lwip/src/core/ip.c
|
||||
${TOP}/lib/lwip/src/core/mem.c
|
||||
${TOP}/lib/lwip/src/core/memp.c
|
||||
${TOP}/lib/lwip/src/core/netif.c
|
||||
${TOP}/lib/lwip/src/core/pbuf.c
|
||||
${TOP}/lib/lwip/src/core/raw.c
|
||||
${TOP}/lib/lwip/src/core/stats.c
|
||||
${TOP}/lib/lwip/src/core/sys.c
|
||||
${TOP}/lib/lwip/src/core/tcp.c
|
||||
${TOP}/lib/lwip/src/core/tcp_in.c
|
||||
${TOP}/lib/lwip/src/core/tcp_out.c
|
||||
${TOP}/lib/lwip/src/core/timeouts.c
|
||||
${TOP}/lib/lwip/src/core/udp.c
|
||||
${TOP}/lib/lwip/src/core/ipv4/autoip.c
|
||||
${TOP}/lib/lwip/src/core/ipv4/dhcp.c
|
||||
${TOP}/lib/lwip/src/core/ipv4/etharp.c
|
||||
${TOP}/lib/lwip/src/core/ipv4/icmp.c
|
||||
${TOP}/lib/lwip/src/core/ipv4/igmp.c
|
||||
${TOP}/lib/lwip/src/core/ipv4/ip4.c
|
||||
${TOP}/lib/lwip/src/core/ipv4/ip4_addr.c
|
||||
${TOP}/lib/lwip/src/core/ipv4/ip4_frag.c
|
||||
${TOP}/lib/lwip/src/netif/ethernet.c
|
||||
${TOP}/lib/lwip/src/netif/slipif.c
|
||||
${TOP}/lib/lwip/src/apps/http/httpd.c
|
||||
${TOP}/lib/lwip/src/apps/http/fs.c
|
||||
${TOP}/lib/networking/dhserver.c
|
||||
${TOP}/lib/networking/dnserver.c
|
||||
${TOP}/lib/networking/rndis_reports.c
|
||||
)
|
||||
|
||||
# Example source
|
||||
target_sources(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
|
||||
${SRC_LWIP}
|
||||
)
|
||||
|
||||
# Example include
|
||||
target_include_directories(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
${TOP}/lib/lwip/src/include
|
||||
${TOP}/lib/lwip/src/include/ipv4
|
||||
${TOP}/lib/lwip/src/include/lwip/apps
|
||||
${TOP}/lib/networking
|
||||
)
|
||||
|
||||
# Example defines
|
||||
target_compile_definitions(${PROJECT} PUBLIC
|
||||
CFG_TUSB_OS=OPT_OS_PICO
|
||||
PBUF_POOL_SIZE=2
|
||||
TCP_WND=2*TCP_MSS
|
||||
HTTPD_USE_CUSTOM_FSDATA=0
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT} pico_stdlib pico_fix_rp2040_usb_device_enumeration)
|
||||
pico_add_extra_outputs(${PROJECT})
|
||||
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid FAMILY specified")
|
||||
endif()
|
@@ -64,8 +64,9 @@
|
||||
#error "Incorrect RHPort configuration"
|
||||
#endif
|
||||
|
||||
// This example doesn't use an RTOS
|
||||
#ifndef CFG_TUSB_OS
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#endif
|
||||
|
||||
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
|
||||
// #define CFG_TUSB_DEBUG 0
|
||||
|
0
examples/device/uac2_headset/.skip.MCU_SAMD11
Normal file
0
examples/device/uac2_headset/.skip.MCU_SAMD11
Normal file
0
examples/device/uac2_headset/.skip.MCU_SAME5X
Normal file
0
examples/device/uac2_headset/.skip.MCU_SAME5X
Normal file
0
examples/device/uac2_headset/.skip.MCU_SAMG
Normal file
0
examples/device/uac2_headset/.skip.MCU_SAMG
Normal file
41
examples/device/uac2_headset/CMakeLists.txt
Normal file
41
examples/device/uac2_headset/CMakeLists.txt
Normal file
@@ -0,0 +1,41 @@
|
||||
# use directory name for project id
|
||||
get_filename_component(PROJECT ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
set(PROJECT ${BOARD}-${PROJECT})
|
||||
|
||||
# TOP is absolute path to root directory of TinyUSB git repo
|
||||
set(TOP "../../..")
|
||||
get_filename_component(TOP "${TOP}" REALPATH)
|
||||
|
||||
# Check for -DFAMILY=
|
||||
if(FAMILY STREQUAL "rp2040")
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
set(PICO_SDK_PATH ${TOP}/hw/mcu/raspberrypi/pico-sdk)
|
||||
include(${PICO_SDK_PATH}/pico_sdk_init.cmake)
|
||||
project(${PROJECT})
|
||||
pico_sdk_init()
|
||||
add_executable(${PROJECT})
|
||||
|
||||
include(${TOP}/hw/bsp/${FAMILY}/family.cmake)
|
||||
|
||||
# Example source
|
||||
target_sources(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
|
||||
)
|
||||
|
||||
# Example include
|
||||
target_include_directories(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
# Example defines
|
||||
target_compile_definitions(${PROJECT} PUBLIC
|
||||
CFG_TUSB_OS=OPT_OS_PICO
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT} pico_stdlib pico_fix_rp2040_usb_device_enumeration)
|
||||
pico_add_extra_outputs(${PROJECT})
|
||||
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid FAMILY specified")
|
||||
endif()
|
@@ -46,7 +46,9 @@ extern "C" {
|
||||
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUSB_OS
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUSB_DEBUG
|
||||
// Can be set during compilation i.e.: make LOG=<value for CFG_TUSB_DEBUG> BOARD=<bsp>
|
||||
|
42
examples/device/usbtmc/CMakeLists.txt
Normal file
42
examples/device/usbtmc/CMakeLists.txt
Normal file
@@ -0,0 +1,42 @@
|
||||
# use directory name for project id
|
||||
get_filename_component(PROJECT ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
set(PROJECT ${BOARD}-${PROJECT})
|
||||
|
||||
# TOP is absolute path to root directory of TinyUSB git repo
|
||||
set(TOP "../../..")
|
||||
get_filename_component(TOP "${TOP}" REALPATH)
|
||||
|
||||
# Check for -DFAMILY=
|
||||
if(FAMILY STREQUAL "rp2040")
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
set(PICO_SDK_PATH ${TOP}/hw/mcu/raspberrypi/pico-sdk)
|
||||
include(${PICO_SDK_PATH}/pico_sdk_init.cmake)
|
||||
project(${PROJECT})
|
||||
pico_sdk_init()
|
||||
add_executable(${PROJECT})
|
||||
|
||||
include(${TOP}/hw/bsp/${FAMILY}/family.cmake)
|
||||
|
||||
# Example source
|
||||
target_sources(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/usbtmc_app.c
|
||||
)
|
||||
|
||||
# Example include
|
||||
target_include_directories(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
# Example defines
|
||||
target_compile_definitions(${PROJECT} PUBLIC
|
||||
CFG_TUSB_OS=OPT_OS_PICO
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT} pico_stdlib pico_fix_rp2040_usb_device_enumeration)
|
||||
pico_add_extra_outputs(${PROJECT})
|
||||
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid FAMILY specified")
|
||||
endif()
|
@@ -46,8 +46,9 @@
|
||||
#error "Incorrect RHPort configuration"
|
||||
#endif
|
||||
|
||||
// This example doesn't use an RTOS
|
||||
#ifndef CFG_TUSB_OS
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#endif
|
||||
|
||||
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
|
||||
// #define CFG_TUSB_DEBUG 0
|
||||
|
@@ -80,10 +80,11 @@ uint8_t const * tud_descriptor_device_cb(void)
|
||||
TUD_USBTMC_BULK_DESCRIPTORS(/* OUT = */0x01, /* IN = */ 0x81, /* packet size = */USBTMCD_MAX_PACKET_SIZE)
|
||||
|
||||
#if CFG_TUD_USBTMC_ENABLE_INT_EP
|
||||
// Interrupt endpoint should be 2 bytes on a FS USB link
|
||||
// USBTMC Interrupt xfer always has length of 2, but we use epMaxSize=8 for
|
||||
// compatibility with mcus that only allow 8, 16, 32 or 64 for FS endpoints
|
||||
# define TUD_USBTMC_DESC(_itfnum) \
|
||||
TUD_USBTMC_DESC_MAIN(_itfnum, /* _epCount = */ 3), \
|
||||
TUD_USBTMC_INT_DESCRIPTOR(/* INT ep # */ 0x82, /* epMaxSize = */ 2, /* bInterval = */16u )
|
||||
TUD_USBTMC_INT_DESCRIPTOR(/* INT ep # */ 0x82, /* epMaxSize = */ 8, /* bInterval = */16u )
|
||||
# define TUD_USBTMC_DESC_LEN (TUD_USBTMC_IF_DESCRIPTOR_LEN + TUD_USBTMC_BULK_DESCRIPTORS_LEN + TUD_USBTMC_INT_DESCRIPTOR_LEN)
|
||||
|
||||
#else
|
||||
|
41
examples/device/webusb_serial/CMakeLists.txt
Normal file
41
examples/device/webusb_serial/CMakeLists.txt
Normal file
@@ -0,0 +1,41 @@
|
||||
# use directory name for project id
|
||||
get_filename_component(PROJECT ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
set(PROJECT ${BOARD}-${PROJECT})
|
||||
|
||||
# TOP is absolute path to root directory of TinyUSB git repo
|
||||
set(TOP "../../..")
|
||||
get_filename_component(TOP "${TOP}" REALPATH)
|
||||
|
||||
# Check for -DFAMILY=
|
||||
if(FAMILY STREQUAL "rp2040")
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
set(PICO_SDK_PATH ${TOP}/hw/mcu/raspberrypi/pico-sdk)
|
||||
include(${PICO_SDK_PATH}/pico_sdk_init.cmake)
|
||||
project(${PROJECT})
|
||||
pico_sdk_init()
|
||||
add_executable(${PROJECT})
|
||||
|
||||
include(${TOP}/hw/bsp/${FAMILY}/family.cmake)
|
||||
|
||||
# Example source
|
||||
target_sources(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
|
||||
)
|
||||
|
||||
# Example include
|
||||
target_include_directories(${PROJECT} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
# Example defines
|
||||
target_compile_definitions(${PROJECT} PUBLIC
|
||||
CFG_TUSB_OS=OPT_OS_PICO
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT} pico_stdlib pico_fix_rp2040_usb_device_enumeration)
|
||||
pico_add_extra_outputs(${PROJECT})
|
||||
|
||||
else()
|
||||
message(FATAL_ERROR "Invalid FAMILY specified")
|
||||
endif()
|
@@ -151,52 +151,54 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ
|
||||
// nothing to with DATA & ACK stage
|
||||
if (stage != CONTROL_STAGE_SETUP ) return true;
|
||||
|
||||
switch (request->bRequest)
|
||||
{
|
||||
case VENDOR_REQUEST_WEBUSB:
|
||||
// match vendor request in BOS descriptor
|
||||
// Get landing page url
|
||||
return tud_control_xfer(rhport, request, (void*) &desc_url, desc_url.bLength);
|
||||
if (request->bmRequestType_bit.type == TUSB_REQ_TYPE_VENDOR) {
|
||||
switch (request->bRequest)
|
||||
{
|
||||
case VENDOR_REQUEST_WEBUSB:
|
||||
// match vendor request in BOS descriptor
|
||||
// Get landing page url
|
||||
return tud_control_xfer(rhport, request, (void*) &desc_url, desc_url.bLength);
|
||||
|
||||
case VENDOR_REQUEST_MICROSOFT:
|
||||
if ( request->wIndex == 7 )
|
||||
{
|
||||
// Get Microsoft OS 2.0 compatible descriptor
|
||||
uint16_t total_len;
|
||||
memcpy(&total_len, desc_ms_os_20+8, 2);
|
||||
case VENDOR_REQUEST_MICROSOFT:
|
||||
if ( request->wIndex == 7 )
|
||||
{
|
||||
// Get Microsoft OS 2.0 compatible descriptor
|
||||
uint16_t total_len;
|
||||
memcpy(&total_len, desc_ms_os_20+8, 2);
|
||||
|
||||
return tud_control_xfer(rhport, request, (void*) desc_ms_os_20, total_len);
|
||||
}else
|
||||
{
|
||||
return tud_control_xfer(rhport, request, (void*) desc_ms_os_20, total_len);
|
||||
}else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (
|
||||
request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS &&
|
||||
request->bRequest == 0x22) {
|
||||
// Webserial simulate the CDC_REQUEST_SET_CONTROL_LINE_STATE (0x22) to
|
||||
// connect and disconnect.
|
||||
web_serial_connected = (request->wValue != 0);
|
||||
|
||||
case 0x22:
|
||||
// Webserial simulate the CDC_REQUEST_SET_CONTROL_LINE_STATE (0x22) to
|
||||
// connect and disconnect.
|
||||
web_serial_connected = (request->wValue != 0);
|
||||
// Always lit LED if connected
|
||||
if ( web_serial_connected ) {
|
||||
board_led_write(true);
|
||||
blink_interval_ms = BLINK_ALWAYS_ON;
|
||||
|
||||
// Always lit LED if connected
|
||||
if ( web_serial_connected )
|
||||
{
|
||||
board_led_write(true);
|
||||
blink_interval_ms = BLINK_ALWAYS_ON;
|
||||
tud_vendor_write_str("\r\nTinyUSB WebUSB device example\r\n");
|
||||
}else
|
||||
{
|
||||
blink_interval_ms = BLINK_MOUNTED;
|
||||
}
|
||||
|
||||
tud_vendor_write_str("\r\nTinyUSB WebUSB device example\r\n");
|
||||
}else
|
||||
{
|
||||
blink_interval_ms = BLINK_MOUNTED;
|
||||
}
|
||||
|
||||
// response with status OK
|
||||
return tud_control_status(rhport, request);
|
||||
|
||||
default:
|
||||
// stall unknown request
|
||||
return false;
|
||||
// response with status OK
|
||||
return tud_control_status(rhport, request);
|
||||
}
|
||||
|
||||
return true;
|
||||
// stall unknown request
|
||||
return false;
|
||||
}
|
||||
|
||||
void webserial_task(void)
|
||||
|
@@ -64,8 +64,9 @@
|
||||
#error "Incorrect RHPort configuration"
|
||||
#endif
|
||||
|
||||
// This example doesn't use an RTOS
|
||||
#ifndef CFG_TUSB_OS
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#endif
|
||||
|
||||
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
|
||||
// #define CFG_TUSB_DEBUG 0
|
||||
|
59
examples/host/cdc_msc_hid/src/keyboard_helper.h
Normal file
59
examples/host/cdc_msc_hid/src/keyboard_helper.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef KEYBOARD_HELPER_H
|
||||
#define KEYBAORD_HELPER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "tusb.h"
|
||||
|
||||
// look up new key in previous keys
|
||||
inline bool find_key_in_report(hid_keyboard_report_t const *p_report, uint8_t keycode)
|
||||
{
|
||||
for(uint8_t i = 0; i < 6; i++)
|
||||
{
|
||||
if (p_report->keycode[i] == keycode) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline uint8_t keycode_to_ascii(uint8_t modifier, uint8_t keycode)
|
||||
{
|
||||
return keycode > 128 ? 0 :
|
||||
hid_keycode_to_ascii_tbl [keycode][modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT) ? 1 : 0];
|
||||
}
|
||||
|
||||
void print_kbd_report(hid_keyboard_report_t *prev_report, hid_keyboard_report_t const *new_report)
|
||||
{
|
||||
|
||||
printf("Report: ");
|
||||
uint8_t c;
|
||||
|
||||
// I assume it's possible to have up to 6 keypress events per report?
|
||||
for (uint8_t i = 0; i < 6; i++)
|
||||
{
|
||||
// Check for key presses
|
||||
if (new_report->keycode[i])
|
||||
{
|
||||
// If not in prev report then it is newly pressed
|
||||
if ( !find_key_in_report(prev_report, new_report->keycode[i]) )
|
||||
c = keycode_to_ascii(new_report->modifier, new_report->keycode[i]);
|
||||
printf("press %c ", c);
|
||||
}
|
||||
|
||||
// Check for key depresses (i.e. was present in prev report but not here)
|
||||
if (prev_report->keycode[i])
|
||||
{
|
||||
// If not present in the current report then depressed
|
||||
if (!find_key_in_report(new_report, prev_report->keycode[i]))
|
||||
{
|
||||
c = keycode_to_ascii(prev_report->modifier, prev_report->keycode[i]);
|
||||
printf("depress %c ", c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
#endif
|
@@ -45,7 +45,9 @@
|
||||
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_HOST
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUSB_OS
|
||||
#define CFG_TUSB_OS OPT_OS_NONE
|
||||
#endif
|
||||
|
||||
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
|
||||
// #define CFG_TUSB_DEBUG 0
|
||||
|
@@ -2,14 +2,11 @@
|
||||
# Common make definition for all examples
|
||||
# ---------------------------------------
|
||||
|
||||
#-------------- Select the board to build for. ------------
|
||||
BOARD_LIST = $(sort $(subst /.,,$(subst $(TOP)/hw/bsp/,,$(wildcard $(TOP)/hw/bsp/*/.))))
|
||||
# Build directory
|
||||
BUILD := _build/$(BOARD)
|
||||
|
||||
ifeq ($(filter $(BOARD),$(BOARD_LIST)),)
|
||||
$(info You must provide a BOARD parameter with 'BOARD=', supported boards are:)
|
||||
$(foreach b,$(BOARD_LIST),$(info - $(b)))
|
||||
$(error Invalid BOARD specified)
|
||||
endif
|
||||
PROJECT := $(BOARD)-$(notdir $(CURDIR))
|
||||
BIN := $(TOP)/_bin/$(BOARD)/$(notdir $(CURDIR))
|
||||
|
||||
# Handy check parameter function
|
||||
check_defined = \
|
||||
@@ -19,11 +16,45 @@ __check_defined = \
|
||||
$(if $(value $1),, \
|
||||
$(error Undefined make flag: $1$(if $2, ($2))))
|
||||
|
||||
# Build directory
|
||||
BUILD = _build/build-$(BOARD)
|
||||
# TODO Check if submodule haven't checkout yet
|
||||
fetch_submodule_if_empty = \
|
||||
ifeq ($(wildcard $(TOP)/$1/*),) \
|
||||
$(info $(shell git -C $(TOP) submodule update --init)) \
|
||||
endif
|
||||
|
||||
# Board specific define
|
||||
include $(TOP)/hw/bsp/$(BOARD)/board.mk
|
||||
#-------------- Select the board to build for. ------------
|
||||
#BOARD_LIST = $(sort $(subst /.,,$(subst $(TOP)/hw/bsp/,,$(wildcard $(TOP)/hw/bsp/*/.))))
|
||||
#ifeq ($(filter $(BOARD),$(BOARD_LIST)),)
|
||||
# $(info You must provide a BOARD parameter with 'BOARD=', supported boards are:)
|
||||
# $(foreach b,$(BOARD_LIST),$(info - $(b)))
|
||||
# $(error Invalid BOARD specified)
|
||||
#endif
|
||||
|
||||
# Board without family
|
||||
BOARD_PATH := $(subst $(TOP)/,,$(wildcard $(TOP)/hw/bsp/$(BOARD)))
|
||||
FAMILY :=
|
||||
|
||||
# Board within family
|
||||
ifeq ($(BOARD_PATH),)
|
||||
BOARD_PATH := $(subst $(TOP)/,,$(wildcard $(TOP)/hw/bsp/*/boards/$(BOARD)))
|
||||
FAMILY := $(word 3, $(subst /, ,$(BOARD_PATH)))
|
||||
FAMILY_PATH = hw/bsp/$(FAMILY)
|
||||
endif
|
||||
|
||||
ifeq ($(BOARD_PATH),)
|
||||
$(error Invalid BOARD specified)
|
||||
endif
|
||||
|
||||
ifeq ($(FAMILY),)
|
||||
include $(TOP)/hw/bsp/$(BOARD)/board.mk
|
||||
else
|
||||
# Include Family and Board specific defs
|
||||
-include $(TOP)/$(FAMILY_PATH)/family.mk
|
||||
|
||||
SRC_C += $(subst $(TOP)/,,$(wildcard $(TOP)/$(FAMILY_PATH)/*.c))
|
||||
endif
|
||||
|
||||
#TODO $(call fetch_submodule_if_empty,lib/sct_neopixel)
|
||||
|
||||
#-------------- Cross Compiler ------------
|
||||
# Can be set by board, default to ARM GCC
|
||||
@@ -45,9 +76,9 @@ endif
|
||||
|
||||
#-------------- Source files and compiler flags --------------
|
||||
|
||||
# Include all source C in board folder
|
||||
# Include all source C in family & board folder
|
||||
SRC_C += hw/bsp/board.c
|
||||
SRC_C += $(subst $(TOP)/,,$(wildcard $(TOP)/hw/bsp/$(BOARD)/*.c))
|
||||
SRC_C += $(subst $(TOP)/,,$(wildcard $(TOP)/$(BOARD_PATH)/*.c))
|
||||
|
||||
# Compiler Flags
|
||||
CFLAGS += \
|
||||
@@ -81,13 +112,18 @@ endif
|
||||
|
||||
# Log level is mapped to TUSB DEBUG option
|
||||
ifneq ($(LOG),)
|
||||
CMAKE_DEFSYM += -DLOG=$(LOG)
|
||||
CFLAGS += -DCFG_TUSB_DEBUG=$(LOG)
|
||||
endif
|
||||
|
||||
# Logger: default is uart, can be set to rtt or swo
|
||||
ifneq ($(LOGGER),)
|
||||
CMAKE_DEFSYM += -DLOGGER=$(LOGGER)
|
||||
endif
|
||||
|
||||
ifeq ($(LOGGER),rtt)
|
||||
RTT_SRC = lib/SEGGER_RTT
|
||||
CFLAGS += -DLOGGER_RTT -DSEGGER_RTT_MODE_DEFAULT=SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL
|
||||
RTT_SRC = lib/SEGGER_RTT
|
||||
INC += $(TOP)/$(RTT_SRC)/RTT
|
||||
SRC_C += $(RTT_SRC)/RTT/SEGGER_RTT.c
|
||||
else ifeq ($(LOGGER),swo)
|
||||
|
@@ -2,20 +2,64 @@
|
||||
# Common make rules for all examples
|
||||
# ---------------------------------------
|
||||
|
||||
ifeq ($(CROSS_COMPILE),xtensa-esp32s2-elf-)
|
||||
# Set all as default goal
|
||||
.DEFAULT_GOAL := all
|
||||
|
||||
ifeq ($(FAMILY),esp32s2)
|
||||
# Espressif IDF use CMake build system, this add wrapper target to call idf.py
|
||||
|
||||
.PHONY: all clean flash
|
||||
.DEFAULT_GOAL := all
|
||||
|
||||
all:
|
||||
idf.py -B$(BUILD) -DBOARD=$(BOARD) build
|
||||
idf.py -B$(BUILD) -DFAMILY=$(FAMILY) -DBOARD=$(BOARD) $(CMAKE_DEFSYM) build
|
||||
|
||||
build: all
|
||||
|
||||
clean:
|
||||
idf.py -B$(BUILD) -DBOARD=$(BOARD) clean
|
||||
idf.py -B$(BUILD) -DFAMILY=$(FAMILY) -DBOARD=$(BOARD) $(CMAKE_DEFSYM) clean
|
||||
|
||||
fullclean:
|
||||
idf.py -B$(BUILD) -DFAMILY=$(FAMILY) -DBOARD=$(BOARD) $(CMAKE_DEFSYM) fullclean
|
||||
|
||||
flash:
|
||||
idf.py -B$(BUILD) -DBOARD=$(BOARD) flash
|
||||
idf.py -B$(BUILD) -DFAMILY=$(FAMILY) -DBOARD=$(BOARD) $(CMAKE_DEFSYM) flash
|
||||
|
||||
bootloader-flash:
|
||||
idf.py -B$(BUILD) -DFAMILY=$(FAMILY) -DBOARD=$(BOARD) $(CMAKE_DEFSYM) bootloader-flash
|
||||
|
||||
app-flash:
|
||||
idf.py -B$(BUILD) -DFAMILY=$(FAMILY) -DBOARD=$(BOARD) $(CMAKE_DEFSYM) app-flash
|
||||
|
||||
erase:
|
||||
idf.py -B$(BUILD) -DFAMILY=$(FAMILY) -DBOARD=$(BOARD) $(CMAKE_DEFSYM) erase_flash
|
||||
|
||||
monitor:
|
||||
idf.py -B$(BUILD) -DFAMILY=$(FAMILY) -DBOARD=$(BOARD) $(CMAKE_DEFSYM) monitor
|
||||
|
||||
uf2: $(BUILD)/$(PROJECT).uf2
|
||||
|
||||
UF2_FAMILY_ID = 0xbfdd4eee
|
||||
$(BUILD)/$(PROJECT).uf2: $(BUILD)/$(PROJECT).bin
|
||||
@echo CREATE $@
|
||||
$(PYTHON) $(TOP)/tools/uf2/utils/uf2conv.py -f $(UF2_FAMILY_ID) -b 0x0 -c -o $@ $^
|
||||
|
||||
else ifeq ($(FAMILY),rp2040)
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
CMAKE_DEFSYM += -DCMAKE_BUILD_TYPE=Debug
|
||||
endif
|
||||
|
||||
$(BUILD):
|
||||
cmake -S . -B $(BUILD) -DFAMILY=$(FAMILY) -DBOARD=$(BOARD) -DPICO_BUILD_DOCS=0 $(CMAKE_DEFSYM)
|
||||
|
||||
all: $(BUILD)
|
||||
$(MAKE) -C $(BUILD)
|
||||
|
||||
clean:
|
||||
$(RM) -rf $(BUILD)
|
||||
|
||||
flash:
|
||||
@$(CP) $(BUILD)/$(PROJECT).uf2 /media/$(USER)/RPI-RP2
|
||||
|
||||
else
|
||||
# GNU Make build system
|
||||
@@ -72,11 +116,9 @@ $(info LDFLAGS $(LDFLAGS)) $(info )
|
||||
$(info ASFLAGS $(ASFLAGS)) $(info )
|
||||
endif
|
||||
|
||||
# Set all as default goal
|
||||
.DEFAULT_GOAL := all
|
||||
all: $(BUILD)/$(BOARD)-firmware.bin $(BUILD)/$(BOARD)-firmware.hex size
|
||||
all: $(BUILD)/$(PROJECT).bin $(BUILD)/$(PROJECT).hex size
|
||||
|
||||
uf2: $(BUILD)/$(BOARD)-firmware.uf2
|
||||
uf2: $(BUILD)/$(PROJECT).uf2
|
||||
|
||||
OBJ_DIRS = $(sort $(dir $(OBJ)))
|
||||
$(OBJ): | $(OBJ_DIRS)
|
||||
@@ -87,22 +129,31 @@ else
|
||||
@$(MKDIR) -p $@
|
||||
endif
|
||||
|
||||
$(BUILD)/$(BOARD)-firmware.elf: $(OBJ)
|
||||
$(BUILD)/$(PROJECT).elf: $(OBJ)
|
||||
@echo LINK $@
|
||||
@$(CC) -o $@ $(LDFLAGS) $^ -Wl,--start-group $(LIBS) -Wl,--end-group
|
||||
|
||||
$(BUILD)/$(BOARD)-firmware.bin: $(BUILD)/$(BOARD)-firmware.elf
|
||||
$(BUILD)/$(PROJECT).bin: $(BUILD)/$(PROJECT).elf
|
||||
@echo CREATE $@
|
||||
@$(OBJCOPY) -O binary $^ $@
|
||||
|
||||
$(BUILD)/$(BOARD)-firmware.hex: $(BUILD)/$(BOARD)-firmware.elf
|
||||
$(BUILD)/$(PROJECT).hex: $(BUILD)/$(PROJECT).elf
|
||||
@echo CREATE $@
|
||||
@$(OBJCOPY) -O ihex $^ $@
|
||||
|
||||
UF2_FAMILY ?= 0x00
|
||||
$(BUILD)/$(BOARD)-firmware.uf2: $(BUILD)/$(BOARD)-firmware.hex
|
||||
# UF2 generation, iMXRT need to strip to text only before conversion
|
||||
ifeq ($(FAMILY),imxrt)
|
||||
$(BUILD)/$(PROJECT).uf2: $(BUILD)/$(PROJECT).elf
|
||||
@echo CREATE $@
|
||||
$(PYTHON) $(TOP)/tools/uf2/utils/uf2conv.py -f $(UF2_FAMILY) -c -o $@ $^
|
||||
@$(OBJCOPY) -O ihex -R .flash_config -R .ivt $^ $(BUILD)/$(PROJECT)-textonly.hex
|
||||
$(PYTHON) $(TOP)/tools/uf2/utils/uf2conv.py -f $(UF2_FAMILY_ID) -c -o $@ $(BUILD)/$(PROJECT)-textonly.hex
|
||||
else
|
||||
$(BUILD)/$(PROJECT).uf2: $(BUILD)/$(PROJECT).hex
|
||||
@echo CREATE $@
|
||||
$(PYTHON) $(TOP)/tools/uf2/utils/uf2conv.py -f $(UF2_FAMILY_ID) -c -o $@ $^
|
||||
endif
|
||||
|
||||
copy-artifact: $(BUILD)/$(PROJECT).bin $(BUILD)/$(PROJECT).hex $(BUILD)/$(PROJECT).uf2
|
||||
|
||||
# We set vpath to point to the top of the tree so that the source files
|
||||
# can be located. By following this scheme, it allows a single build rule
|
||||
@@ -124,7 +175,7 @@ $(BUILD)/obj/%.o: %.S
|
||||
@echo AS $(notdir $@)
|
||||
@$(CC) -x assembler-with-cpp $(ASFLAGS) -c -o $@ $<
|
||||
|
||||
size: $(BUILD)/$(BOARD)-firmware.elf
|
||||
size: $(BUILD)/$(PROJECT).elf
|
||||
-@echo ''
|
||||
@$(SIZE) $<
|
||||
-@echo ''
|
||||
@@ -152,7 +203,7 @@ endif
|
||||
JLINK_IF ?= swd
|
||||
|
||||
# Flash using jlink
|
||||
flash-jlink: $(BUILD)/$(BOARD)-firmware.hex
|
||||
flash-jlink: $(BUILD)/$(PROJECT).hex
|
||||
@echo halt > $(BUILD)/$(BOARD).jlink
|
||||
@echo r > $(BUILD)/$(BOARD).jlink
|
||||
@echo loadfile $^ >> $(BUILD)/$(BOARD).jlink
|
||||
@@ -162,12 +213,27 @@ flash-jlink: $(BUILD)/$(BOARD)-firmware.hex
|
||||
$(JLINKEXE) -device $(JLINK_DEVICE) -if $(JLINK_IF) -JTAGConf -1,-1 -speed auto -CommandFile $(BUILD)/$(BOARD).jlink
|
||||
|
||||
# flash STM32 MCU using stlink with STM32 Cube Programmer CLI
|
||||
flash-stlink: $(BUILD)/$(BOARD)-firmware.elf
|
||||
flash-stlink: $(BUILD)/$(PROJECT).elf
|
||||
STM32_Programmer_CLI --connect port=swd --write $< --go
|
||||
|
||||
# flash with pyocd
|
||||
flash-pyocd: $(BUILD)/$(BOARD)-firmware.hex
|
||||
flash-pyocd: $(BUILD)/$(PROJECT).hex
|
||||
pyocd flash -t $(PYOCD_TARGET) $<
|
||||
pyocd reset -t $(PYOCD_TARGET)
|
||||
|
||||
endif # Make target
|
||||
endif # GNU Make
|
||||
|
||||
#-------------- Artifacts --------------
|
||||
|
||||
# Create binary directory
|
||||
$(BIN):
|
||||
@$(MKDIR) -p $@
|
||||
|
||||
# Copy binaries .elf, .bin, .hex, .uf2 to BIN for upload
|
||||
# due to large size of combined artifacts, only uf2 is uploaded for now
|
||||
copy-artifact: $(BIN)
|
||||
@$(CP) $(BUILD)/$(PROJECT).uf2 $(BIN)
|
||||
#@$(CP) $(BUILD)/$(PROJECT).bin $(BIN)
|
||||
#@$(CP) $(BUILD)/$(PROJECT).hex $(BIN)
|
||||
#@$(CP) $(BUILD)/$(PROJECT).elf $(BIN)
|
||||
|
||||
|
Reference in New Issue
Block a user