Merge remote-tracking branch 'upstream/master' into edpt_ISO_xfer

This commit is contained in:
Reinhard Panhuber
2021-02-12 18:05:20 +01:00
388 changed files with 11115 additions and 10689 deletions

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

View File

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

View File

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

View File

@@ -1,3 +1,4 @@
# FAMILY = "esp32s2"
idf_component_register(SRCS "main.c"
INCLUDE_DIRS "."
REQUIRES freertos soc)

View File

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

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

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

View File

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

View File

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

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

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

View File

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

View File

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

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View 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(hid_composite_freertos)
else()
message(FATAL_ERROR "Invalid FAMILY specified")
endif()

View File

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

View File

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

View File

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

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

View File

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

View File

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

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

View File

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

View File

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

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

View File

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

View File

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

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

View File

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

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

View File

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

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

View File

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

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

View File

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

View File

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

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

View File

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

View File

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

View 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

View File

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

View File

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

View File

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