summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorHiFiPhile <[email protected]>2023-10-10 15:02:25 +0200
committerHiFiPhile <[email protected]>2023-10-10 15:02:25 +0200
commitb5c839f739280a59dec8e2fe082005518dfc19c8 (patch)
tree8140b74bfddb16a6ed5a0dcff13a22727da3a727 /examples
parent6be7f354c26e09a87d1b856b0e237ff82be5963f (diff)
parent513ab37ec6f394d5332d159a62afa468a1a0a7cb (diff)
Merge branch 'master' of https://github.com/hathach/tinyusb into uac_interl
Diffstat (limited to 'examples')
-rw-r--r--examples/device/cdc_msc_freertos/Makefile4
-rw-r--r--examples/device/cdc_msc_freertos/src/main.c70
-rw-r--r--examples/host/bare_api/CMakeLists.txt5
-rw-r--r--examples/host/bare_api/Makefile10
-rw-r--r--examples/host/bare_api/only.txt1
-rw-r--r--examples/host/cdc_msc_hid/CMakeLists.txt5
-rw-r--r--examples/host/cdc_msc_hid/Makefile10
-rw-r--r--examples/host/cdc_msc_hid/only.txt1
-rw-r--r--examples/host/cdc_msc_hid_freertos/CMakeLists.txt36
-rw-r--r--examples/host/cdc_msc_hid_freertos/Makefile34
-rw-r--r--examples/host/cdc_msc_hid_freertos/only.txt13
-rw-r--r--examples/host/cdc_msc_hid_freertos/src/CMakeLists.txt6
-rw-r--r--examples/host/cdc_msc_hid_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h215
-rw-r--r--examples/host/cdc_msc_hid_freertos/src/cdc_app.c145
-rw-r--r--examples/host/cdc_msc_hid_freertos/src/freertos_hook.c111
-rw-r--r--examples/host/cdc_msc_hid_freertos/src/hid_app.c267
-rw-r--r--examples/host/cdc_msc_hid_freertos/src/main.c165
-rw-r--r--examples/host/cdc_msc_hid_freertos/src/msc_app.c67
-rw-r--r--examples/host/cdc_msc_hid_freertos/src/tusb_config.h133
-rw-r--r--examples/host/hid_controller/CMakeLists.txt5
-rw-r--r--examples/host/hid_controller/Makefile10
-rw-r--r--examples/host/hid_controller/only.txt1
-rw-r--r--examples/host/msc_file_explorer/CMakeLists.txt5
-rw-r--r--examples/host/msc_file_explorer/Makefile10
-rw-r--r--examples/host/msc_file_explorer/only.txt1
-rw-r--r--examples/make.mk3
26 files changed, 1243 insertions, 90 deletions
diff --git a/examples/device/cdc_msc_freertos/Makefile b/examples/device/cdc_msc_freertos/Makefile
index 0bee668b7..84c833fb5 100644
--- a/examples/device/cdc_msc_freertos/Makefile
+++ b/examples/device/cdc_msc_freertos/Makefile
@@ -1,5 +1,3 @@
-DEPS_SUBMODULES += lib/FreeRTOS-Kernel
-
include ../../make.mk
FREERTOS_SRC = lib/FreeRTOS-Kernel
@@ -10,7 +8,7 @@ INC += \
src/FreeRTOSConfig \
$(TOP)/hw \
$(TOP)/$(FREERTOS_SRC)/include \
- $(TOP)/$(FREERTOS_PORTABLE_SRC)
+ $(TOP)/$(FREERTOS_PORTABLE_SRC) \
# Example source
EXAMPLE_SOURCE = \
diff --git a/examples/device/cdc_msc_freertos/src/main.c b/examples/device/cdc_msc_freertos/src/main.c
index 0b115a595..1dadc4513 100644
--- a/examples/device/cdc_msc_freertos/src/main.c
+++ b/examples/device/cdc_msc_freertos/src/main.c
@@ -41,6 +41,7 @@
#define USBD_STACK_SIZE 4096
#else
+
#include "FreeRTOS.h"
#include "semphr.h"
#include "queue.h"
@@ -54,7 +55,7 @@
#define CDC_STACK_SZIE configMINIMAL_STACK_SIZE
//--------------------------------------------------------------------+
-// MACRO CONSTANT TYPEDEF PROTYPES
+// MACRO CONSTANT TYPEDEF PROTOTYPES
//--------------------------------------------------------------------+
/* Blink pattern
@@ -62,7 +63,7 @@
* - 1000 ms : device mounted
* - 2500 ms : device is suspended
*/
-enum {
+enum {
BLINK_NOT_MOUNTED = 250,
BLINK_MOUNTED = 1000,
BLINK_SUSPENDED = 2500,
@@ -81,16 +82,15 @@ StaticTask_t cdc_taskdef;
TimerHandle_t blinky_tm;
-void led_blinky_cb(TimerHandle_t xTimer);
-void usb_device_task(void* param);
-void cdc_task(void* params);
+static void led_blinky_cb(TimerHandle_t xTimer);
+static void usb_device_task(void *param);
+void cdc_task(void *params);
//--------------------------------------------------------------------+
// Main
//--------------------------------------------------------------------+
-int main(void)
-{
+int main(void) {
board_init();
#if configSUPPORT_STATIC_ALLOCATION
@@ -104,8 +104,8 @@ int main(void)
xTaskCreateStatic(cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, cdc_stack, &cdc_taskdef);
#else
blinky_tm = xTimerCreate(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb);
- xTaskCreate( usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES-1, NULL);
- xTaskCreate( cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, NULL);
+ xTaskCreate(usb_device_task, "usbd", USBD_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL);
+ xTaskCreate(cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES - 2, NULL);
#endif
xTimerStart(blinky_tm, 0);
@@ -119,16 +119,14 @@ int main(void)
}
#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
-void app_main(void)
-{
+void app_main(void) {
main();
}
#endif
// USB Device Driver task
// This top level thread process all usb events and invoke callbacks
-void usb_device_task(void* param)
-{
+static void usb_device_task(void *param) {
(void) param;
// init device stack on configured roothub port
@@ -141,8 +139,7 @@ void usb_device_task(void* param)
}
// RTOS forever loop
- while (1)
- {
+ while (1) {
// put this thread to waiting state until there is new events
tud_task();
@@ -156,35 +153,28 @@ void usb_device_task(void* param)
//--------------------------------------------------------------------+
// Invoked when device is mounted
-void tud_mount_cb(void)
-{
+void tud_mount_cb(void) {
xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0);
}
// Invoked when device is unmounted
-void tud_umount_cb(void)
-{
+void tud_umount_cb(void) {
xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), 0);
}
// Invoked when usb bus is suspended
// remote_wakeup_en : if host allow us to perform remote wakeup
// Within 7ms, device must draw an average of current less than 2.5 mA from bus
-void tud_suspend_cb(bool remote_wakeup_en)
-{
+void tud_suspend_cb(bool remote_wakeup_en) {
(void) remote_wakeup_en;
xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_SUSPENDED), 0);
}
// Invoked when usb bus is resumed
-void tud_resume_cb(void)
-{
- if (tud_mounted())
- {
+void tud_resume_cb(void) {
+ if (tud_mounted()) {
xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_MOUNTED), 0);
- }
- else
- {
+ } else {
xTimerChangePeriod(blinky_tm, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), 0);
}
}
@@ -192,20 +182,17 @@ void tud_resume_cb(void)
//--------------------------------------------------------------------+
// USB CDC
//--------------------------------------------------------------------+
-void cdc_task(void* params)
-{
+void cdc_task(void *params) {
(void) params;
// RTOS forever loop
- while ( 1 )
- {
+ while (1) {
// connected() check for DTR bit
// Most but not all terminal client set this when making connection
// if ( tud_cdc_connected() )
{
// There are data available
- while ( tud_cdc_available() )
- {
+ while (tud_cdc_available()) {
uint8_t buf[64];
// read and echo back
@@ -228,32 +215,27 @@ void cdc_task(void* params)
}
// Invoked when cdc when line state changed e.g connected/disconnected
-void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
-{
+void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) {
(void) itf;
(void) rts;
// TODO set some indicator
- if ( dtr )
- {
+ if (dtr) {
// Terminal connected
- }else
- {
+ } else {
// Terminal disconnected
}
}
// Invoked when CDC interface received data from host
-void tud_cdc_rx_cb(uint8_t itf)
-{
+void tud_cdc_rx_cb(uint8_t itf) {
(void) itf;
}
//--------------------------------------------------------------------+
// BLINKING TASK
//--------------------------------------------------------------------+
-void led_blinky_cb(TimerHandle_t xTimer)
-{
+static void led_blinky_cb(TimerHandle_t xTimer) {
(void) xTimer;
static bool led_state = false;
diff --git a/examples/host/bare_api/CMakeLists.txt b/examples/host/bare_api/CMakeLists.txt
index 05398b079..76182d6fa 100644
--- a/examples/host/bare_api/CMakeLists.txt
+++ b/examples/host/bare_api/CMakeLists.txt
@@ -10,6 +10,11 @@ project(${PROJECT} C CXX ASM)
# Checks this example is valid for the family and initializes the project
family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+# Espressif has its own cmake build system
+if(FAMILY STREQUAL "espressif")
+ return()
+endif()
+
add_executable(${PROJECT})
# Example source
diff --git a/examples/host/bare_api/Makefile b/examples/host/bare_api/Makefile
index 058307c40..161f8c774 100644
--- a/examples/host/bare_api/Makefile
+++ b/examples/host/bare_api/Makefile
@@ -10,14 +10,4 @@ EXAMPLE_SOURCE += \
SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
-# TinyUSB Host Stack source
-SRC_C += \
- src/class/cdc/cdc_host.c \
- src/class/hid/hid_host.c \
- src/class/msc/msc_host.c \
- src/host/hub.c \
- src/host/usbh.c \
- src/portable/ohci/ohci.c \
- src/portable/nxp/lpc17_40/hcd_lpc17_40.c
-
include ../../rules.mk
diff --git a/examples/host/bare_api/only.txt b/examples/host/bare_api/only.txt
index 3837ac8a2..fee10f9e2 100644
--- a/examples/host/bare_api/only.txt
+++ b/examples/host/bare_api/only.txt
@@ -1,3 +1,4 @@
+mcu:KINETIS_KL
mcu:LPC175X_6X
mcu:LPC177X_8X
mcu:LPC18XX
diff --git a/examples/host/cdc_msc_hid/CMakeLists.txt b/examples/host/cdc_msc_hid/CMakeLists.txt
index ad5751705..a7c372a34 100644
--- a/examples/host/cdc_msc_hid/CMakeLists.txt
+++ b/examples/host/cdc_msc_hid/CMakeLists.txt
@@ -10,6 +10,11 @@ project(${PROJECT} C CXX ASM)
# Checks this example is valid for the family and initializes the project
family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+# Espressif has its own cmake build system
+if(FAMILY STREQUAL "espressif")
+ return()
+endif()
+
add_executable(${PROJECT})
# Example source
diff --git a/examples/host/cdc_msc_hid/Makefile b/examples/host/cdc_msc_hid/Makefile
index 7c16b39d3..15b8a5b31 100644
--- a/examples/host/cdc_msc_hid/Makefile
+++ b/examples/host/cdc_msc_hid/Makefile
@@ -13,14 +13,4 @@ EXAMPLE_SOURCE = \
SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
-# TinyUSB Host Stack source
-SRC_C += \
- src/class/cdc/cdc_host.c \
- src/class/hid/hid_host.c \
- src/class/msc/msc_host.c \
- src/host/hub.c \
- src/host/usbh.c \
- src/portable/ohci/ohci.c \
- src/portable/nxp/lpc17_40/hcd_lpc17_40.c
-
include ../../rules.mk
diff --git a/examples/host/cdc_msc_hid/only.txt b/examples/host/cdc_msc_hid/only.txt
index 3837ac8a2..fee10f9e2 100644
--- a/examples/host/cdc_msc_hid/only.txt
+++ b/examples/host/cdc_msc_hid/only.txt
@@ -1,3 +1,4 @@
+mcu:KINETIS_KL
mcu:LPC175X_6X
mcu:LPC177X_8X
mcu:LPC18XX
diff --git a/examples/host/cdc_msc_hid_freertos/CMakeLists.txt b/examples/host/cdc_msc_hid_freertos/CMakeLists.txt
new file mode 100644
index 000000000..2e95a18e0
--- /dev/null
+++ b/examples/host/cdc_msc_hid_freertos/CMakeLists.txt
@@ -0,0 +1,36 @@
+cmake_minimum_required(VERSION 3.17)
+
+include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
+
+# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
+family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
+
+project(${PROJECT} C CXX ASM)
+
+# Checks this example is valid for the family and initializes the project
+family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+
+# Espressif has its own cmake build system
+if(FAMILY STREQUAL "espressif")
+ return()
+endif()
+
+add_executable(${PROJECT})
+
+# Example source
+target_sources(${PROJECT} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/cdc_app.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/freertos_hook.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/hid_app.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/msc_app.c
+ )
+
+# Example include
+target_include_directories(${PROJECT} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}/src
+ )
+
+# Configure compilation flags and libraries for the example without RTOS.
+# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
+family_configure_host_example(${PROJECT} freertos)
diff --git a/examples/host/cdc_msc_hid_freertos/Makefile b/examples/host/cdc_msc_hid_freertos/Makefile
new file mode 100644
index 000000000..a9670b4f2
--- /dev/null
+++ b/examples/host/cdc_msc_hid_freertos/Makefile
@@ -0,0 +1,34 @@
+include ../../make.mk
+
+FREERTOS_SRC = lib/FreeRTOS-Kernel
+FREERTOS_PORTABLE_PATH= $(FREERTOS_SRC)/portable/$(if $(USE_IAR),IAR,GCC)
+
+INC += \
+ src \
+ src/FreeRTOSConfig \
+ $(TOP)/hw \
+ $(TOP)/$(FREERTOS_SRC)/include \
+ $(TOP)/$(FREERTOS_PORTABLE_SRC) \
+
+# Example source
+EXAMPLE_SOURCE = \
+ src/cdc_app.c \
+ src/freertos_hook.c \
+ src/hid_app.c \
+ src/main.c \
+ src/msc_app.c \
+
+SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
+
+# FreeRTOS source, all files in port folder
+SRC_C += \
+ $(FREERTOS_SRC)/list.c \
+ $(FREERTOS_SRC)/queue.c \
+ $(FREERTOS_SRC)/tasks.c \
+ $(FREERTOS_SRC)/timers.c \
+ $(subst $(TOP)/,,$(wildcard $(TOP)/$(FREERTOS_PORTABLE_SRC)/*.c))
+
+SRC_S += \
+ $(subst $(TOP)/,,$(wildcard $(TOP)/$(FREERTOS_PORTABLE_SRC)/*.s))
+
+include ../../rules.mk
diff --git a/examples/host/cdc_msc_hid_freertos/only.txt b/examples/host/cdc_msc_hid_freertos/only.txt
new file mode 100644
index 000000000..3837ac8a2
--- /dev/null
+++ b/examples/host/cdc_msc_hid_freertos/only.txt
@@ -0,0 +1,13 @@
+mcu:LPC175X_6X
+mcu:LPC177X_8X
+mcu:LPC18XX
+mcu:LPC40XX
+mcu:LPC43XX
+mcu:MIMXRT1XXX
+mcu:MIMXRT10XX
+mcu:MIMXRT11XX
+mcu:RP2040
+mcu:MSP432E4
+mcu:RX65X
+mcu:RAXXX
+mcu:MAX3421
diff --git a/examples/host/cdc_msc_hid_freertos/src/CMakeLists.txt b/examples/host/cdc_msc_hid_freertos/src/CMakeLists.txt
new file mode 100644
index 000000000..6f057c106
--- /dev/null
+++ b/examples/host/cdc_msc_hid_freertos/src/CMakeLists.txt
@@ -0,0 +1,6 @@
+# This file is for ESP-IDF only
+idf_component_register(SRCS "cdc_app.c" "hid_app.c" "main.c" "msc_app.c"
+ INCLUDE_DIRS "."
+ REQUIRES boards tinyusb_src)
+
+target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-error=format)
diff --git a/examples/host/cdc_msc_hid_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h b/examples/host/cdc_msc_hid_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h
new file mode 100644
index 000000000..a1fc8bb09
--- /dev/null
+++ b/examples/host/cdc_msc_hid_freertos/src/FreeRTOSConfig/FreeRTOSConfig.h
@@ -0,0 +1,215 @@
+/*
+ * FreeRTOS Kernel V10.0.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software. If you wish to use our Amazon
+ * FreeRTOS name, please do so in a fair use way that does not cause confusion.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ * 1 tab == 4 spaces!
+ */
+
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+/*-----------------------------------------------------------
+ * Application specific definitions.
+ *
+ * These definitions should be adjusted for your particular hardware and
+ * application requirements.
+ *
+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
+ *
+ * See http://www.freertos.org/a00110.html.
+ *----------------------------------------------------------*/
+
+// skip if included from IAR assembler
+#ifndef __IASMARM__
+
+// Include MCU header
+#include "bsp/board_mcu.h"
+
+#if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3
+ #error "ESP32-Sx should use IDF's FreeRTOSConfig.h"
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+#endif
+
+// TODO fix later
+// FIXME cause redundant-decls warnings
+#if CFG_TUSB_MCU == OPT_MCU_MM32F327X
+ extern u32 SystemCoreClock;
+#else
+ extern uint32_t SystemCoreClock;
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
+
+#endif
+
+/* Cortex M23/M33 port configuration. */
+#define configENABLE_MPU 0
+#define configENABLE_FPU 1
+#define configENABLE_TRUSTZONE 0
+#define configMINIMAL_SECURE_STACK_SIZE ( 1024 )
+
+#define configUSE_PREEMPTION 1
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
+#define configCPU_CLOCK_HZ SystemCoreClock
+#define configTICK_RATE_HZ ( 1000 )
+#define configMAX_PRIORITIES ( 5 )
+#define configMINIMAL_STACK_SIZE ( 128 )
+#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 )
+#define configMAX_TASK_NAME_LEN 16
+#define configUSE_16_BIT_TICKS 0
+#define configIDLE_SHOULD_YIELD 1
+#define configUSE_MUTEXES 1
+#define configUSE_RECURSIVE_MUTEXES 1
+#define configUSE_COUNTING_SEMAPHORES 1
+#define configQUEUE_REGISTRY_SIZE 4
+#define configUSE_QUEUE_SETS 0
+#define configUSE_TIME_SLICING 0
+#define configUSE_NEWLIB_REENTRANT 0
+#define configENABLE_BACKWARD_COMPATIBILITY 1
+#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
+
+#define configSUPPORT_STATIC_ALLOCATION 1
+#define configSUPPORT_DYNAMIC_ALLOCATION 0
+
+/* Hook function related definitions. */
+#define configUSE_IDLE_HOOK 0
+#define configUSE_TICK_HOOK 0
+#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning
+#define configCHECK_FOR_STACK_OVERFLOW 2
+
+/* Run time and task stats gathering related definitions. */
+#define configGENERATE_RUN_TIME_STATS 0
+#define configUSE_TRACE_FACILITY 1 // legacy trace
+#define configUSE_STATS_FORMATTING_FUNCTIONS 0
+
+/* Co-routine definitions. */
+#define configUSE_CO_ROUTINES 0
+#define configMAX_CO_ROUTINE_PRIORITIES 2
+
+/* Software timer related definitions. */
+#define configUSE_TIMERS 1
+#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2)
+#define configTIMER_QUEUE_LENGTH 32
+#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
+
+/* Optional functions - most linkers will remove unused functions anyway. */
+#define INCLUDE_vTaskPrioritySet 0
+#define INCLUDE_uxTaskPriorityGet 0
+#define INCLUDE_vTaskDelete 0
+#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY
+#define INCLUDE_xResumeFromISR 0
+#define INCLUDE_vTaskDelayUntil 1
+#define INCLUDE_vTaskDelay 1
+#define INCLUDE_xTaskGetSchedulerState 0
+#define INCLUDE_xTaskGetCurrentTaskHandle 0
+#define INCLUDE_uxTaskGetStackHighWaterMark 0
+#define INCLUDE_xTaskGetIdleTaskHandle 0
+#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
+#define INCLUDE_pcTaskGetTaskName 0
+#define INCLUDE_eTaskGetState 0
+#define INCLUDE_xEventGroupSetBitFromISR 0
+#define INCLUDE_xTimerPendFunctionCall 0
+
+/* Define to trap errors during development. */
+// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7
+#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__)
+ #define configASSERT(_exp) \
+ do {\
+ if ( !(_exp) ) { \
+ volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \
+ if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \
+ taskDISABLE_INTERRUPTS(); \
+ __asm("BKPT #0\n"); \
+ }\
+ }\
+ } while(0)
+#else
+ #define configASSERT( x )
+#endif
+
+#ifdef __RX__
+/* Renesas RX series */
+#define vSoftwareInterruptISR INT_Excep_ICU_SWINT
+#define vTickISR INT_Excep_CMT0_CMI0
+#define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2)
+#define configKERNEL_INTERRUPT_PRIORITY 1
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY 4
+
+#else
+
+/* FreeRTOS hooks to NVIC vectors */
+#define xPortPendSVHandler PendSV_Handler
+#define xPortSysTickHandler SysTick_Handler
+#define vPortSVCHandler SVC_Handler
+
+//--------------------------------------------------------------------+
+// Interrupt nesting behavior configuration.
+//--------------------------------------------------------------------+
+#if defined(__NVIC_PRIO_BITS)
+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h
+ #define configPRIO_BITS __NVIC_PRIO_BITS
+
+#elif defined(__ECLIC_INTCTLBITS)
+ // RISC-V Bumblebee core from nuclei
+ #define configPRIO_BITS __ECLIC_INTCTLBITS
+
+#elif defined(__IASMARM__)
+ // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS.
+ // Therefore we will hard coded it to minimum value of 2 to get pass ci build.
+ // IAR user must update this to correct value of the target MCU
+ #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU"
+ #define configPRIO_BITS 2
+
+#else
+ #error "FreeRTOS configPRIO_BITS to be defined"
+#endif
+
+/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
+#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<configPRIO_BITS) - 1)
+
+/* The highest interrupt priority that can be used by any interrupt service
+routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
+INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
+PRIORITY THAN THIS! (higher priorities are lower numeric values. */
+#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2
+
+/* Interrupt priorities used by the kernel port layer itself. These are generic
+to all Cortex-M ports, and do not rely on any particular library functions. */
+#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+
+/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
+See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
+
+#endif
+
+#endif /* __FREERTOS_CONFIG__H */
diff --git a/examples/host/cdc_msc_hid_freertos/src/cdc_app.c b/examples/host/cdc_msc_hid_freertos/src/cdc_app.c
new file mode 100644
index 000000000..6ff513be1
--- /dev/null
+++ b/examples/host/cdc_msc_hid_freertos/src/cdc_app.c
@@ -0,0 +1,145 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2022, Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#include "tusb.h"
+#include "bsp/board_api.h"
+
+#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
+// ESP-IDF need "freertos/" prefix in include path.
+// CFG_TUSB_OS_INC_PATH should be defined accordingly.
+ #include "freertos/FreeRTOS.h"
+ #include "freertos/semphr.h"
+ #include "freertos/queue.h"
+ #include "freertos/task.h"
+ #include "freertos/timers.h"
+
+ #define CDC_STACK_SZIE 2048
+#else
+ #include "FreeRTOS.h"
+ #include "semphr.h"
+ #include "queue.h"
+ #include "task.h"
+ #include "timers.h"
+
+ #define CDC_STACK_SZIE (3*configMINIMAL_STACK_SIZE/2)
+#endif
+
+//--------------------------------------------------------------------+
+// MACRO TYPEDEF CONSTANT ENUM DECLARATION
+//--------------------------------------------------------------------+
+#if configSUPPORT_STATIC_ALLOCATION
+StackType_t cdc_stack[CDC_STACK_SZIE];
+StaticTask_t cdc_taskdef;
+#endif
+
+static void cdc_app_task(void* param);
+
+void cdc_app_init(void) {
+ #if configSUPPORT_STATIC_ALLOCATION
+ xTaskCreateStatic(cdc_app_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, cdc_stack, &cdc_taskdef);
+ #else
+ xTaskCreate(cdc_app_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, NULL);
+ #endif
+}
+
+// helper
+size_t get_console_inputs(uint8_t *buf, size_t bufsize) {
+ size_t count = 0;
+ while (count < bufsize) {
+ int ch = board_getchar();
+ if (ch <= 0) break;
+
+ buf[count] = (uint8_t) ch;
+ count++;
+ }
+
+ return count;
+}
+
+static void cdc_app_task(void* param) {
+ (void) param;
+
+ uint8_t buf[64 + 1]; // +1 for extra null character
+ uint32_t const bufsize = sizeof(buf) - 1;
+
+ while (1) {
+ uint32_t count = get_console_inputs(buf, bufsize);
+ buf[count] = 0;
+
+ if (count) {
+ // loop over all mounted interfaces
+ for (uint8_t idx = 0; idx < CFG_TUH_CDC; idx++) {
+ if (tuh_cdc_mounted(idx)) {
+ // console --> cdc interfaces
+ tuh_cdc_write(idx, buf, count);
+ tuh_cdc_write_flush(idx);
+ }
+ }
+ }
+
+ vTaskDelay(1);
+ }
+}
+
+//--------------------------------------------------------------------+
+// TinyUSB Callbacks
+//--------------------------------------------------------------------+
+
+// Invoked when received new data
+void tuh_cdc_rx_cb(uint8_t idx) {
+ uint8_t buf[64 + 1]; // +1 for extra null character
+ uint32_t const bufsize = sizeof(buf) - 1;
+
+ // forward cdc interfaces -> console
+ uint32_t count = tuh_cdc_read(idx, buf, bufsize);
+ buf[count] = 0;
+
+ printf((char *) buf);
+}
+
+void tuh_cdc_mount_cb(uint8_t idx) {
+ tuh_itf_info_t itf_info = { 0 };
+ tuh_cdc_itf_get_info(idx, &itf_info);
+
+ printf("CDC Interface is mounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.desc.bInterfaceNumber);
+
+#ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM
+ // CFG_TUH_CDC_LINE_CODING_ON_ENUM must be defined for line coding is set by tinyusb in enumeration
+ // otherwise you need to call tuh_cdc_set_line_coding() first
+ cdc_line_coding_t line_coding = { 0 };
+ if (tuh_cdc_get_local_line_coding(idx, &line_coding)) {
+ printf(" Baudrate: %lu, Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits);
+ printf(" Parity : %u, Data Width: %u\r\n", line_coding.parity, line_coding.data_bits);
+ }
+#endif
+}
+
+void tuh_cdc_umount_cb(uint8_t idx) {
+ tuh_itf_info_t itf_info = { 0 };
+ tuh_cdc_itf_get_info(idx, &itf_info);
+
+ printf("CDC Interface is unmounted: address = %u, itf_num = %u\r\n", itf_info.daddr, itf_info.desc.bInterfaceNumber);
+}
diff --git a/examples/host/cdc_msc_hid_freertos/src/freertos_hook.c b/examples/host/cdc_msc_hid_freertos/src/freertos_hook.c
new file mode 100644
index 000000000..07d159fd5
--- /dev/null
+++ b/examples/host/cdc_msc_hid_freertos/src/freertos_hook.c
@@ -0,0 +1,111 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+//--------------------------------------------------------------------+
+// INCLUDE
+//--------------------------------------------------------------------+
+#include "FreeRTOS.h"
+#include "task.h"
+#include "common/tusb_common.h"
+
+void vApplicationMallocFailedHook(void) {
+ taskDISABLE_INTERRUPTS();
+ TU_ASSERT(false,);
+}
+
+void vApplicationStackOverflowHook(xTaskHandle pxTask, char *pcTaskName) {
+ (void) pxTask;
+ (void) pcTaskName;
+
+ taskDISABLE_INTERRUPTS();
+ TU_ASSERT(false,);
+}
+
+/* configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must provide an
+ * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
+ * used by the Idle task. */
+void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer,
+ uint32_t *pulIdleTaskStackSize) {
+ /* If the buffers to be provided to the Idle task are declared inside this
+ * function then they must be declared static - otherwise they will be allocated on
+ * the stack and so not exists after this function exits. */
+ static StaticTask_t xIdleTaskTCB;
+ static StackType_t uxIdleTaskStack[configMINIMAL_STACK_SIZE];
+
+ /* Pass out a pointer to the StaticTask_t structure in which the Idle task's
+ state will be stored. */
+ *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
+
+ /* Pass out the array that will be used as the Idle task's stack. */
+ *ppxIdleTaskStackBuffer = uxIdleTaskStack;
+
+ /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
+ Note that, as the array is necessarily of type StackType_t,
+ configMINIMAL_STACK_SIZE is specified in words, not bytes. */
+ *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
+}
+
+/* configSUPPORT_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
+ * application must provide an implementation of vApplicationGetTimerTaskMemory()
+ * to provide the memory that is used by the Timer service task. */
+void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer,
+ uint32_t *pulTimerTaskStackSize) {
+ /* If the buffers to be provided to the Timer task are declared inside this
+ * function then they must be declared static - otherwise they will be allocated on
+ * the stack and so not exists after this function exits. */
+ static StaticTask_t xTimerTaskTCB;
+ static StackType_t uxTimerTaskStack[configTIMER_TASK_STACK_DEPTH];
+
+ /* Pass out a pointer to the StaticTask_t structure in which the Timer
+ task's state will be stored. */
+ *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
+
+ /* Pass out the array that will be used as the Timer task's stack. */
+ *ppxTimerTaskStackBuffer = uxTimerTaskStack;
+
+ /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
+ Note that, as the array is necessarily of type StackType_t,
+ configTIMER_TASK_STACK_DEPTH is specified in words, not bytes. */
+ *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
+}
+
+#if CFG_TUSB_MCU == OPT_MCU_RX63X | CFG_TUSB_MCU == OPT_MCU_RX65X
+#include "iodefine.h"
+void vApplicationSetupTimerInterrupt(void)
+{
+ /* Enable CMT0 */
+ SYSTEM.PRCR.WORD = (0xA5u<<8) | TU_BIT(1);
+ MSTP(CMT0) = 0;
+ SYSTEM.PRCR.WORD = (0xA5u<<8);
+
+ CMT0.CMCNT = 0;
+ CMT0.CMCOR = (unsigned short)(((configPERIPHERAL_CLOCK_HZ/configTICK_RATE_HZ)-1)/128);
+ CMT0.CMCR.WORD = TU_BIT(6) | 2;
+ IR(CMT0, CMI0) = 0;
+ IPR(CMT0, CMI0) = configKERNEL_INTERRUPT_PRIORITY;
+ IEN(CMT0, CMI0) = 1;
+ CMT.CMSTR0.BIT.STR0 = 1;
+}
+#endif
diff --git a/examples/host/cdc_msc_hid_freertos/src/hid_app.c b/examples/host/cdc_msc_hid_freertos/src/hid_app.c
new file mode 100644
index 000000000..9ea5c1be0
--- /dev/null
+++ b/examples/host/cdc_msc_hid_freertos/src/hid_app.c
@@ -0,0 +1,267 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2021, Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "bsp/board_api.h"
+#include "tusb.h"
+
+//--------------------------------------------------------------------+
+// MACRO TYPEDEF CONSTANT ENUM DECLARATION
+//--------------------------------------------------------------------+
+
+// If your host terminal support ansi escape code such as TeraTerm
+// it can be use to simulate mouse cursor movement within terminal
+#define USE_ANSI_ESCAPE 0
+
+#define MAX_REPORT 4
+
+static uint8_t const keycode2ascii[128][2] = { HID_KEYCODE_TO_ASCII };
+
+// Each HID instance can has multiple reports
+static struct {
+ uint8_t report_count;
+ tuh_hid_report_info_t report_info[MAX_REPORT];
+} hid_info[CFG_TUH_HID];
+
+static void process_kbd_report(hid_keyboard_report_t const *report);
+static void process_mouse_report(hid_mouse_report_t const *report);
+static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len);
+
+void hid_app_init(void) {
+ // nothing to do
+}
+
+//--------------------------------------------------------------------+
+// TinyUSB Callbacks
+//--------------------------------------------------------------------+
+
+// Invoked when device with hid interface is mounted
+// Report descriptor is also available for use. tuh_hid_parse_report_descriptor()
+// can be used to parse common/simple enough descriptor.
+// Note: if report descriptor length > CFG_TUH_ENUMERATION_BUFSIZE, it will be skipped
+// therefore report_desc = NULL, desc_len = 0
+void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *desc_report, uint16_t desc_len) {
+ printf("HID device address = %d, instance = %d is mounted\r\n", dev_addr, instance);
+
+ // Interface protocol (hid_interface_protocol_enum_t)
+ const char *protocol_str[] = { "None", "Keyboard", "Mouse" };
+ uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance);
+
+ printf("HID Interface Protocol = %s\r\n", protocol_str[itf_protocol]);
+
+ // By default host stack will use activate boot protocol on supported interface.
+ // Therefore for this simple example, we only need to parse generic report descriptor (with built-in parser)
+ if (itf_protocol == HID_ITF_PROTOCOL_NONE) {
+ hid_info[instance].report_count = tuh_hid_parse_report_descriptor(hid_info[instance].report_info, MAX_REPORT,
+ desc_report, desc_len);
+ printf("HID has %u reports \r\n", hid_info[instance].report_count);
+ }
+
+ // request to receive report
+ // tuh_hid_report_received_cb() will be invoked when report is available
+ if (!tuh_hid_receive_report(dev_addr, instance)) {
+ printf("Error: cannot request to receive report\r\n");
+ }
+}
+
+// Invoked when device with hid interface is un-mounted
+void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) {
+ printf("HID device address = %d, instance = %d is unmounted\r\n", dev_addr, instance);
+}
+
+// Invoked when received report from device via interrupt endpoint
+void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len) {
+ uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance);
+
+ switch (itf_protocol) {
+ case HID_ITF_PROTOCOL_KEYBOARD:
+ TU_LOG2("HID receive boot keyboard report\r\n");
+ process_kbd_report((hid_keyboard_report_t const *) report);
+ break;
+
+ case HID_ITF_PROTOCOL_MOUSE:
+ TU_LOG2("HID receive boot mouse report\r\n");
+ process_mouse_report((hid_mouse_report_t const *) report);
+ break;
+
+ default:
+ // Generic report requires matching ReportID and contents with previous parsed report info
+ process_generic_report(dev_addr, instance, report, len);
+ break;
+ }
+
+ // continue to request to receive report
+ if (!tuh_hid_receive_report(dev_addr, instance)) {
+ printf("Error: cannot request to receive report\r\n");
+ }
+}
+
+//--------------------------------------------------------------------+
+// Keyboard
+//--------------------------------------------------------------------+
+
+// look up new key in previous keys
+static inline bool find_key_in_report(hid_keyboard_report_t const *report, uint8_t keycode) {
+ for (uint8_t i = 0; i < 6; i++) {
+ if (report->keycode[i] == keycode) return true;
+ }
+
+ return false;
+}
+
+static void process_kbd_report(hid_keyboard_report_t const *report) {
+ static hid_keyboard_report_t prev_report = { 0, 0, { 0 } }; // previous report to check key released
+
+ //------------- example code ignore control (non-printable) key affects -------------//
+ for (uint8_t i = 0; i < 6; i++) {
+ if (report->keycode[i]) {
+ if (find_key_in_report(&prev_report, report->keycode[i])) {
+ // exist in previous report means the current key is holding
+ } else {
+ // not existed in previous report means the current key is pressed
+ bool const is_shift = report->modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT);
+ uint8_t ch = keycode2ascii[report->keycode[i]][is_shift ? 1 : 0];
+ putchar(ch);
+ if (ch == '\r') putchar('\n'); // added new line for enter key
+
+ #ifndef __ICCARM__ // TODO IAR doesn't support stream control ?
+ fflush(stdout); // flush right away, else nanolib will wait for newline
+ #endif
+ }
+ }
+ // TODO example skips key released
+ }
+
+ prev_report = *report;
+}
+
+//--------------------------------------------------------------------+
+// Mouse
+//--------------------------------------------------------------------+
+
+void cursor_movement(int8_t x, int8_t y, int8_t wheel) {
+#if USE_ANSI_ESCAPE
+ // Move X using ansi escape
+ if ( x < 0) {
+ printf(ANSI_CURSOR_BACKWARD(%d), (-x)); // move left
+ }else if ( x > 0) {
+ printf(ANSI_CURSOR_FORWARD(%d), x); // move right
+ }
+
+ // Move Y using ansi escape
+ if ( y < 0) {
+ printf(ANSI_CURSOR_UP(%d), (-y)); // move up
+ }else if ( y > 0) {
+ printf(ANSI_CURSOR_DOWN(%d), y); // move down
+ }
+
+ // Scroll using ansi escape
+ if (wheel < 0) {
+ printf(ANSI_SCROLL_UP(%d), (-wheel)); // scroll up
+ }else if (wheel > 0) {
+ printf(ANSI_SCROLL_DOWN(%d), wheel); // scroll down
+ }
+
+ printf("\r\n");
+#else
+ printf("(%d %d %d)\r\n", x, y, wheel);
+#endif
+}
+
+static void process_mouse_report(hid_mouse_report_t const *report) {
+ static hid_mouse_report_t prev_report = { 0 };
+
+ //------------- button state -------------//
+ uint8_t button_changed_mask = report->buttons ^ prev_report.buttons;
+ if (button_changed_mask & report->buttons) {
+ printf(" %c%c%c ",
+ report->buttons & MOUSE_BUTTON_LEFT ? 'L' : '-',
+ report->buttons & MOUSE_BUTTON_MIDDLE ? 'M' : '-',
+ report->buttons & MOUSE_BUTTON_RIGHT ? 'R' : '-');
+ }
+
+ //------------- cursor movement -------------//
+ cursor_movement(report->x, report->y, report->wheel);
+}
+
+//--------------------------------------------------------------------+
+// Generic Report
+//--------------------------------------------------------------------+
+static void process_generic_report(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len) {
+ (void) dev_addr;
+
+ uint8_t const rpt_count = hid_info[instance].report_count;
+ tuh_hid_report_info_t *rpt_info_arr = hid_info[instance].report_info;
+ tuh_hid_report_info_t *rpt_info = NULL;
+
+ if (rpt_count == 1 && rpt_info_arr[0].report_id == 0) {
+ // Simple report without report ID as 1st byte
+ rpt_info = &rpt_info_arr[0];
+ } else {
+ // Composite report, 1st byte is report ID, data starts from 2nd byte
+ uint8_t const rpt_id = report[0];
+
+ // Find report id in the array
+ for (uint8_t i = 0; i < rpt_count; i++) {
+ if (rpt_id == rpt_info_arr[i].report_id) {
+ rpt_info = &rpt_info_arr[i];
+ break;
+ }
+ }
+
+ report++;
+ len--;
+ }
+
+ if (!rpt_info) {
+ printf("Couldn't find report info !\r\n");
+ return;
+ }
+
+ // For complete list of Usage Page & Usage checkout src/class/hid/hid.h. For examples:
+ // - Keyboard : Desktop, Keyboard
+ // - Mouse : Desktop, Mouse
+ // - Gamepad : Desktop, Gamepad
+ // - Consumer Control (Media Key) : Consumer, Consumer Control
+ // - System Control (Power key) : Desktop, System Control
+ // - Generic (vendor) : 0xFFxx, xx
+ if (rpt_info->usage_page == HID_USAGE_PAGE_DESKTOP) {
+ switch (rpt_info->usage) {
+ case HID_USAGE_DESKTOP_KEYBOARD:
+ TU_LOG1("HID receive keyboard report\r\n");
+ // Assume keyboard follow boot report layout
+ process_kbd_report((hid_keyboard_report_t const *) report);
+ break;
+
+ case HID_USAGE_DESKTOP_MOUSE:
+ TU_LOG1("HID receive mouse report\r\n");
+ // Assume mouse follow boot report layout
+ process_mouse_report((hid_mouse_report_t const *) report);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
diff --git a/examples/host/cdc_msc_hid_freertos/src/main.c b/examples/host/cdc_msc_hid_freertos/src/main.c
new file mode 100644
index 000000000..691ff3e29
--- /dev/null
+++ b/examples/host/cdc_msc_hid_freertos/src/main.c
@@ -0,0 +1,165 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "bsp/board_api.h"
+#include "tusb.h"
+
+#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
+ // ESP-IDF need "freertos/" prefix in include path.
+ // CFG_TUSB_OS_INC_PATH should be defined accordingly.
+ #include "freertos/FreeRTOS.h"
+ #include "freertos/semphr.h"
+ #include "freertos/queue.h"
+ #include "freertos/task.h"
+ #include "freertos/timers.h"
+
+ #define USBH_STACK_SIZE 4096
+#else
+ #include "FreeRTOS.h"
+ #include "semphr.h"
+ #include "queue.h"
+ #include "task.h"
+ #include "timers.h"
+
+ // Increase stack size when debug log is enabled
+ #define USBH_STACK_SIZE (3*configMINIMAL_STACK_SIZE/2) * (CFG_TUSB_DEBUG ? 2 : 1)
+#endif
+
+
+//--------------------------------------------------------------------+
+// MACRO CONSTANT TYPEDEF PROTOTYPES
+//--------------------------------------------------------------------+
+/* Blink pattern
+ * - 250 ms : device not mounted
+ * - 1000 ms : device mounted
+ * - 2500 ms : device is suspended
+ */
+enum {
+ BLINK_NOT_MOUNTED = 250,
+ BLINK_MOUNTED = 1000,
+ BLINK_SUSPENDED = 2500,
+};
+
+// static timer & task
+#if configSUPPORT_STATIC_ALLOCATION
+StaticTimer_t blinky_tmdef;
+
+StackType_t usb_host_stack[USBH_STACK_SIZE];
+StaticTask_t usb_host_taskdef;
+#endif
+
+TimerHandle_t blinky_tm;
+
+static void led_blinky_cb(TimerHandle_t xTimer);
+static void usb_host_task(void* param);
+
+extern void cdc_app_init(void);
+extern void hid_app_init(void);
+extern void msc_app_init(void);
+
+/*------------- MAIN -------------*/
+int main(void) {
+ board_init();
+
+ printf("TinyUSB Host CDC MSC HID with FreeRTOS Example\r\n");
+
+ // Create soft timer for blinky, task for tinyusb stack
+#if configSUPPORT_STATIC_ALLOCATION
+ blinky_tm = xTimerCreateStatic(NULL, pdMS_TO_TICKS(BLINK_MOUNTED), true, NULL, led_blinky_cb, &blinky_tmdef);
+ xTaskCreateStatic(usb_host_task, "usbh", USBH_STACK_SIZE, NULL, configMAX_PRIORITIES-1, usb_host_stack, &usb_host_taskdef);
+#else
+ blinky_tm = xTimerCreate(NULL, pdMS_TO_TICKS(BLINK_NOT_MOUNTED), true, NULL, led_blinky_cb);
+ xTaskCreate(usb_host_task, "usbd", USBH_STACK_SIZE, NULL, configMAX_PRIORITIES-1, NULL);
+#endif
+
+ xTimerStart(blinky_tm, 0);
+
+ // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3
+#if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
+ vTaskStartScheduler();
+#endif
+
+ return 0;
+}
+
+#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
+void app_main(void) {
+ main();
+}
+#endif
+
+// USB Host task
+// This top level thread process all usb events and invoke callbacks
+static void usb_host_task(void *param) {
+ (void) param;
+
+ // init host stack on configured roothub port
+ tuh_init(BOARD_TUH_RHPORT);
+
+ if (board_init_after_tusb) {
+ board_init_after_tusb();
+ }
+
+ cdc_app_init();
+ hid_app_init();
+ msc_app_init();
+
+ // RTOS forever loop
+ while (1) {
+ // put this thread to waiting state until there is new events
+ tuh_task();
+
+ // following code only run if tuh_task() process at least 1 event
+ }
+}
+
+//--------------------------------------------------------------------+
+// TinyUSB Callbacks
+//--------------------------------------------------------------------+
+
+void tuh_mount_cb(uint8_t dev_addr) {
+ // application set-up
+ printf("A device with address %d is mounted\r\n", dev_addr);
+}
+
+void tuh_umount_cb(uint8_t dev_addr) {
+ // application tear-down
+ printf("A device with address %d is unmounted \r\n", dev_addr);
+}
+
+//--------------------------------------------------------------------+
+// BLINKING TASK
+//--------------------------------------------------------------------+
+static void led_blinky_cb(TimerHandle_t xTimer) {
+ (void) xTimer;
+ static bool led_state = false;
+
+ board_led_write(led_state);
+ led_state = 1 - led_state; // toggle
+}
diff --git a/examples/host/cdc_msc_hid_freertos/src/msc_app.c b/examples/host/cdc_msc_hid_freertos/src/msc_app.c
new file mode 100644
index 000000000..ee02ba917
--- /dev/null
+++ b/examples/host/cdc_msc_hid_freertos/src/msc_app.c
@@ -0,0 +1,67 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "tusb.h"
+
+static scsi_inquiry_resp_t inquiry_resp;
+
+void msc_app_init(void) {
+ // nothing to do
+}
+
+bool inquiry_complete_cb(uint8_t dev_addr, tuh_msc_complete_data_t const *cb_data) {
+ msc_cbw_t const *cbw = cb_data->cbw;
+ msc_csw_t const *csw = cb_data->csw;
+
+ if (csw->status != 0) {
+ printf("Inquiry failed\r\n");
+ return false;
+ }
+
+ // Print out Vendor ID, Product ID and Rev
+ printf("%.8s %.16s rev %.4s\r\n", inquiry_resp.vendor_id, inquiry_resp.product_id, inquiry_resp.product_rev);
+
+ // Get capacity of device
+ uint32_t const block_count = tuh_msc_get_block_count(dev_addr, cbw->lun);
+ uint32_t const block_size = tuh_msc_get_block_size(dev_addr, cbw->lun);
+
+ printf("Disk Size: %lu MB\r\n", block_count / ((1024 * 1024) / block_size));
+ printf("Block Count = %lu, Block Size: %lu\r\n", block_count, block_size);
+
+ return true;
+}
+
+//------------- IMPLEMENTATION -------------//
+void tuh_msc_mount_cb(uint8_t dev_addr) {
+ printf("A MassStorage device is mounted\r\n");
+
+ uint8_t const lun = 0;
+ tuh_msc_inquiry(dev_addr, lun, &inquiry_resp, inquiry_complete_cb, 0);
+}
+
+void tuh_msc_umount_cb(uint8_t dev_addr) {
+ (void) dev_addr;
+ printf("A MassStorage device is unmounted\r\n");
+}
diff --git a/examples/host/cdc_msc_hid_freertos/src/tusb_config.h b/examples/host/cdc_msc_hid_freertos/src/tusb_config.h
new file mode 100644
index 000000000..1bed9a9b3
--- /dev/null
+++ b/examples/host/cdc_msc_hid_freertos/src/tusb_config.h
@@ -0,0 +1,133 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef _TUSB_CONFIG_H_
+#define _TUSB_CONFIG_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+//--------------------------------------------------------------------+
+// Board Specific Configuration
+//--------------------------------------------------------------------+
+
+#if CFG_TUSB_MCU == OPT_MCU_RP2040
+ // change to 1 if using pico-pio-usb as host controller for raspberry rp2040
+ #define CFG_TUH_RPI_PIO_USB 0
+ #define BOARD_TUH_RHPORT CFG_TUH_RPI_PIO_USB
+#endif
+
+// RHPort number used for host can be defined by board.mk, default to port 0
+#ifndef BOARD_TUH_RHPORT
+#define BOARD_TUH_RHPORT 0
+#endif
+
+// RHPort max operational speed can defined by board.mk
+#ifndef BOARD_TUH_MAX_SPEED
+#define BOARD_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED
+#endif
+
+//--------------------------------------------------------------------
+// COMMON CONFIGURATION
+//--------------------------------------------------------------------
+
+// defined by compiler flags for flexibility
+#ifndef CFG_TUSB_MCU
+#error CFG_TUSB_MCU must be defined
+#endif
+
+#ifndef CFG_TUSB_OS
+#define CFG_TUSB_OS OPT_OS_FREERTOS
+#endif
+
+// Espressif IDF requires "freertos/" prefix in include path
+#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
+#define CFG_TUSB_OS_INC_PATH freertos/
+#endif
+
+#ifndef CFG_TUSB_DEBUG
+#define CFG_TUSB_DEBUG 0
+#endif
+
+// Enable Host stack
+#define CFG_TUH_ENABLED 1
+
+// Default is max speed that hardware controller could support with on-chip PHY
+#define CFG_TUH_MAX_SPEED BOARD_TUH_MAX_SPEED
+
+/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
+ * Tinyusb use follows macros to declare transferring memory so that they can be put
+ * into those specific section.
+ * e.g
+ * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
+ * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
+ */
+#ifndef CFG_TUH_MEM_SECTION
+#define CFG_TUH_MEM_SECTION
+#endif
+
+#ifndef CFG_TUH_MEM_ALIGN
+#define CFG_TUH_MEM_ALIGN __attribute__ ((aligned(4)))
+#endif
+
+//--------------------------------------------------------------------
+// CONFIGURATION
+//--------------------------------------------------------------------
+
+// Size of buffer to hold descriptors and other data used for enumeration
+#define CFG_TUH_ENUMERATION_BUFSIZE 256
+
+#define CFG_TUH_HUB 1 // number of supported hubs
+#define CFG_TUH_CDC 1 // CDC ACM
+#define CFG_TUH_CDC_FTDI 1 // FTDI Serial. FTDI is not part of CDC class, only to re-use CDC driver API
+#define CFG_TUH_CDC_CP210X 1 // CP210x Serial. CP210X is not part of CDC class, only to re-use CDC driver API
+#define CFG_TUH_HID (3*CFG_TUH_DEVICE_MAX) // typical keyboard + mouse device can have 3-4 HID interfaces
+#define CFG_TUH_MSC 1
+#define CFG_TUH_VENDOR 0
+
+// max device support (excluding hub device): 1 hub typically has 4 ports
+#define CFG_TUH_DEVICE_MAX (3*CFG_TUH_HUB + 1)
+
+//------------- HID -------------//
+#define CFG_TUH_HID_EPIN_BUFSIZE 64
+#define CFG_TUH_HID_EPOUT_BUFSIZE 64
+
+//------------- CDC -------------//
+
+// Set Line Control state on enumeration/mounted:
+// DTR ( bit 0), RTS (bit 1)
+#define CFG_TUH_CDC_LINE_CONTROL_ON_ENUM 0x03
+
+// Set Line Coding on enumeration/mounted, value for cdc_line_coding_t
+// bit rate = 115200, 1 stop bit, no parity, 8 bit data width
+#define CFG_TUH_CDC_LINE_CODING_ON_ENUM { 115200, CDC_LINE_CONDING_STOP_BITS_1, CDC_LINE_CODING_PARITY_NONE, 8 }
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_CONFIG_H_ */
diff --git a/examples/host/hid_controller/CMakeLists.txt b/examples/host/hid_controller/CMakeLists.txt
index 3fb630aaa..c1b500dd8 100644
--- a/examples/host/hid_controller/CMakeLists.txt
+++ b/examples/host/hid_controller/CMakeLists.txt
@@ -10,6 +10,11 @@ project(${PROJECT} C CXX ASM)
# Checks this example is valid for the family and initializes the project
family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+# Espressif has its own cmake build system
+if(FAMILY STREQUAL "espressif")
+ return()
+endif()
+
add_executable(${PROJECT})
# Example source
diff --git a/examples/host/hid_controller/Makefile b/examples/host/hid_controller/Makefile
index cda2977bc..e7f603f25 100644
--- a/examples/host/hid_controller/Makefile
+++ b/examples/host/hid_controller/Makefile
@@ -11,14 +11,4 @@ EXAMPLE_SOURCE += \
SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
-# TinyUSB Host Stack source
-SRC_C += \
- src/class/cdc/cdc_host.c \
- src/class/hid/hid_host.c \
- src/class/msc/msc_host.c \
- src/host/hub.c \
- src/host/usbh.c \
- src/portable/ohci/ohci.c \
- src/portable/nxp/lpc17_40/hcd_lpc17_40.c
-
include ../../rules.mk
diff --git a/examples/host/hid_controller/only.txt b/examples/host/hid_controller/only.txt
index 3837ac8a2..fee10f9e2 100644
--- a/examples/host/hid_controller/only.txt
+++ b/examples/host/hid_controller/only.txt
@@ -1,3 +1,4 @@
+mcu:KINETIS_KL
mcu:LPC175X_6X
mcu:LPC177X_8X
mcu:LPC18XX
diff --git a/examples/host/msc_file_explorer/CMakeLists.txt b/examples/host/msc_file_explorer/CMakeLists.txt
index 1868b632e..1a57c7466 100644
--- a/examples/host/msc_file_explorer/CMakeLists.txt
+++ b/examples/host/msc_file_explorer/CMakeLists.txt
@@ -10,6 +10,11 @@ project(${PROJECT} C CXX ASM)
# Checks this example is valid for the family and initializes the project
family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+# Espressif has its own cmake build system
+if(FAMILY STREQUAL "espressif")
+ return()
+endif()
+
add_executable(${PROJECT})
# Example source
diff --git a/examples/host/msc_file_explorer/Makefile b/examples/host/msc_file_explorer/Makefile
index 1fda72b18..8319d3c2b 100644
--- a/examples/host/msc_file_explorer/Makefile
+++ b/examples/host/msc_file_explorer/Makefile
@@ -24,14 +24,4 @@ SRC_C += \
# suppress warning caused by fatfs
CFLAGS += -Wno-error=cast-qual
-# TinyUSB Host Stack source
-SRC_C += \
- src/class/cdc/cdc_host.c \
- src/class/hid/hid_host.c \
- src/class/msc/msc_host.c \
- src/host/hub.c \
- src/host/usbh.c \
- src/portable/ohci/ohci.c \
- src/portable/nxp/lpc17_40/hcd_lpc17_40.c
-
include ../../rules.mk
diff --git a/examples/host/msc_file_explorer/only.txt b/examples/host/msc_file_explorer/only.txt
index 3837ac8a2..fee10f9e2 100644
--- a/examples/host/msc_file_explorer/only.txt
+++ b/examples/host/msc_file_explorer/only.txt
@@ -1,3 +1,4 @@
+mcu:KINETIS_KL
mcu:LPC175X_6X
mcu:LPC177X_8X
mcu:LPC18XX
diff --git a/examples/make.mk b/examples/make.mk
index 8fe4a3486..448d7883d 100644
--- a/examples/make.mk
+++ b/examples/make.mk
@@ -26,9 +26,6 @@ ifeq '$(findstring ;,$(PATH))' ';'
CMDEXE := 1
# makefile shell commands should use syntax for DOS CMD, not unix sh
-# Unfortunately, SHELL may point to sh or bash, which can't accept DOS syntax.
-# We can't just use sh, because while sh and/or bash shell may be available,
-# many Windows environments won't have utilities like realpath used below, so...
# Force DOS command shell on Windows.
SHELL := cmd.exe
endif