diff options
| author | hathach <[email protected]> | 2019-05-02 20:30:44 +0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2019-05-02 20:30:44 +0700 |
| commit | 867e69ed9d1ef44a7574ccf6543c8a46ef8d8e6c (patch) | |
| tree | 59b0e0aad89d7735585737be52fd2daffdbab5c0 /examples/device | |
| parent | 2341ecb4188b1998e1e682a09e9b04570929a5a4 (diff) | |
| parent | 7e2088765daf15f59f43c9e7cffb46b9ae997e19 (diff) | |
Merge pull request #61 from hathach/develop
enhance HID, add HID out endpoint support
Diffstat (limited to 'examples/device')
19 files changed, 587 insertions, 571 deletions
diff --git a/examples/device/cdc_msc_hid/Makefile b/examples/device/cdc_msc_hid/Makefile index 69bffaace..4ff3371dc 100644 --- a/examples/device/cdc_msc_hid/Makefile +++ b/examples/device/cdc_msc_hid/Makefile @@ -1,185 +1,15 @@ include ../../../tools/top.mk +include ../../make.mk -# Select the board to build for. -ifeq ($(BOARD),) - $(info You must provide a BOARD parameter with 'BOARD=') - $(info Possible values are:) - $(info $(sort $(subst /.,,$(subst $(TOP)/hw/bsp/,,$(wildcard $(TOP)/hw/bsp/*/.))))) - $(error BOARD not defined) -else - ifeq ($(wildcard $(TOP)/hw/bsp/$(BOARD)/.),) - $(error Invalid BOARD specified) - endif -endif - -# Verbose mode (V=). 0: default, 1: print out CFLAG, LDFLAG 2: print all compile command -ifeq ("$(V)","2") - QUIET = -else - QUIET = @ -endif - -# If the build directory is not given, make it reflect the board name. -BUILD ?= build-$(BOARD) - -CROSS_COMPILE = arm-none-eabi- - -include $(TOP)/hw/bsp/$(BOARD)/board.mk - -CC = $(CROSS_COMPILE)gcc -CXX = $(CROSS_COMPILE)g++ -OBJCOPY = $(CROSS_COMPILE)objcopy -SIZE = $(CROSS_COMPILE)size -MKDIR = mkdir -SED = sed -CP = cp -RM = rm - -INC += -Isrc \ - -I$(TOP)/hw \ - -I$(TOP)/src - -CFLAGS += \ - -fsingle-precision-constant \ - -fno-strict-aliasing \ - -Wdouble-promotion \ - -Wno-endif-labels \ - -Wstrict-prototypes \ - -Werror-implicit-function-declaration \ - -Wfloat-equal \ - -Wundef \ - -Wshadow \ - -Wwrite-strings \ - -Wsign-compare \ - -Wmissing-format-attribute \ - -Wno-deprecated-declarations \ - -Wnested-externs \ - -Wunreachable-code \ - -Wno-error=lto-type-mismatch \ - -ffunction-sections \ - -fdata-sections - -# This causes lots of warning with nrf5x build due to nrfx code -# CFLAGS += -Wcast-align - -#Debugging/Optimization -ifeq ($(DEBUG), 1) - CFLAGS += -O0 -ggdb -else - CFLAGS += -flto -Os -endif - -CFLAGS += $(INC) -Wall -Werror -std=gnu11 -DBOARD_$(shell echo $(BOARD) | tr '[:lower:]' '[:upper:]') -LDFLAGS += $(CFLAGS) -fshort-enums -Wl,-T,$(TOP)/$(LD_FILE) -Wl,[email protected] -Wl,-cref -Wl,-gc-sections -specs=nosys.specs -specs=nano.specs - -ifeq ("$(V)","1") -$(info CFLAGS $(CFLAGS)) -$(info ) -$(info LDFLAGS $(LDFLAGS)) -$(info ) -$(info ASFLAGS $(ASFLAGS)) -$(info ) -endif - -LIBS = -lgcc -lc -lm -lnosys +INC += \ + src \ + $(TOP)/hw \ +# Example source EXAMPLE_SOURCE += $(wildcard src/*.c) SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -LIB_SOURCE += \ - hw/bsp/$(BOARD)/board_$(BOARD).c \ - src/common/tusb_fifo.c \ - src/device/usbd.c \ - src/device/usbd_control.c \ - src/class/msc/msc_device.c \ - src/class/cdc/cdc_device.c \ - src/class/hid/hid_device.c \ - src/tusb.c \ - src/portable/$(VENDOR)/$(CHIP_FAMILY)/dcd_$(CHIP_FAMILY).c - -SRC_C += $(LIB_SOURCE) - -# Assembly files can be name with upper case .S, convert it to .s -SRC_S := $(SRC_S:.S=.s) - -# Due to GCC LTO bug https://bugs.launchpad.net/gcc-arm-embedded/+bug/1747966 -# assembly file should be placed first in linking order -OBJ += $(addprefix $(BUILD)/obj/, $(SRC_S:.s=.o)) -OBJ += $(addprefix $(BUILD)/obj/, $(SRC_C:.c=.o)) - -# Set all as default goal -.DEFAULT_GOAL := all -all: $(BUILD)/$(BOARD)-firmware.bin size - -OBJ_DIRS = $(sort $(dir $(OBJ))) -$(OBJ): | $(OBJ_DIRS) -$(OBJ_DIRS): - @$(MKDIR) -p $@ - -$(BUILD)/$(BOARD)-firmware.elf: $(OBJ) - @echo LINK $@ - $(QUIET)$(CC) -o $@ $(LDFLAGS) $^ -Wl,--start-group $(LIBS) -Wl,--end-group - -$(BUILD)/$(BOARD)-firmware.bin: $(BUILD)/$(BOARD)-firmware.elf - @echo CREATE $@ - @$(OBJCOPY) -O binary -j .vectors -j .text -j .data $^ $@ - -$(BUILD)/$(BOARD)-firmware.hex: $(BUILD)/$(BOARD)-firmware.elf - @echo CREATE $@ - @$(OBJCOPY) -O ihex $^ $@ - -# 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 -# to be used to compile all .c files. -vpath %.c . $(TOP) -$(BUILD)/obj/%.o: %.c - @echo CC $(notdir $@) - $(QUIET)$(CC) $(CFLAGS) -c -MD -o $@ $< - @# The following fixes the dependency file. - @# See http://make.paulandlesley.org/autodep.html for details. - @# Regex adjusted from the above to play better with Windows paths, etc. - @$(CP) $(@:.o=.d) $(@:.o=.P); \ - $(SED) -e 's/#.*//' -e 's/^.*: *//' -e 's/ *\\$$//' \ - -e '/^$$/ d' -e 's/$$/ :/' < $(@:.o=.d) >> $(@:.o=.P); \ - $(RM) $(@:.o=.d) - -# ASM sources lower case .s -vpath %.s . $(TOP) -$(BUILD)/obj/%.o: %.s - @echo AS $(notdir $@) - $(QUIET)$(CC) -x assembler-with-cpp $(ASFLAGS) -c -o $@ $< - -# ASM sources upper case .S -vpath %.S . $(TOP) -$(BUILD)/obj/%.o: %.S - @echo AS $(notdir $@) - $(QUIET)$(CC) -x assembler-with-cpp $(ASFLAGS) -c -o $@ $< - -# Flash binary using Jlink, should be added into system path -ifeq ($(OS),Windows_NT) - JLINKEXE = JLink.exe -else - JLINKEXE = JLinkExe -endif - -# default jlink interface is swd -ifeq ($(JLINK_IF),) - JLINK_IF = swd -endif - -# Flash using jlink -flash-jlink: $(BUILD)/$(BOARD)-firmware.hex - @echo halt > $(BUILD)/$(BOARD).jlink - @echo loadfile $^ >> $(BUILD)/$(BOARD).jlink - @echo r >> $(BUILD)/$(BOARD).jlink - @echo go >> $(BUILD)/$(BOARD).jlink - @echo exit >> $(BUILD)/$(BOARD).jlink - $(JLINKEXE) -device $(JLINK_DEVICE) -if $(JLINK_IF) -speed auto -CommandFile $(BUILD)/$(BOARD).jlink - -size: $(BUILD)/$(BOARD)-firmware.elf - -@echo '' - @$(SIZE) $< - -@echo '' +# Board source +SRC_C += hw/bsp/$(BOARD)/board_$(BOARD).c -clean: - rm -rf build-$(BOARD) +include ../../rules.mk diff --git a/examples/device/cdc_msc_hid/src/main.c b/examples/device/cdc_msc_hid/src/main.c index fc2f2aad0..f743026c2 100644 --- a/examples/device/cdc_msc_hid/src/main.c +++ b/examples/device/cdc_msc_hid/src/main.c @@ -49,8 +49,8 @@ static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; void led_blinking_task(void); -extern void cdc_task(void); -extern void hid_task(void); +void cdc_task(void); +void hid_task(void); /*------------- MAIN -------------*/ int main(void) @@ -196,7 +196,9 @@ void hid_task(void) if ( btn ) { int8_t const delta = 5; - tud_hid_mouse_move(REPORT_ID_MOUSE, delta, delta); // right + down + + // 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(2); @@ -220,12 +222,15 @@ void hid_task(void) }else { // send empty key report if previously has key pressed - if (has_key) tud_hid_keyboard_key_release(REPORT_ID_KEYBOARD); + if (has_key) tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, NULL); has_key = false; } } } +// 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 uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) { // TODO not Implemented @@ -237,6 +242,8 @@ uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, return 0; } +// Invoked when received SET_REPORT control request or +// received data on OUT endpoint ( Report ID = 0, Type = 0 ) void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) { // TODO not Implemented diff --git a/examples/device/cdc_msc_hid/src/tusb_config.h b/examples/device/cdc_msc_hid/src/tusb_config.h index 400afb620..c1210152e 100644 --- a/examples/device/cdc_msc_hid/src/tusb_config.h +++ b/examples/device/cdc_msc_hid/src/tusb_config.h @@ -77,17 +77,13 @@ #define CFG_TUD_MIDI 0 #define CFG_TUD_CUSTOM_CLASS 0 -//-------------------------------------------------------------------- -// CDC -//-------------------------------------------------------------------- +//------------- CDC -------------// // FIFO size of CDC TX and RX #define CFG_TUD_CDC_RX_BUFSIZE 64 #define CFG_TUD_CDC_TX_BUFSIZE 64 -//-------------------------------------------------------------------- -// MSC -//-------------------------------------------------------------------- +//------------- MSC -------------// // Buffer size of Device Mass storage #define CFG_TUD_MSC_BUFSIZE 512 @@ -101,9 +97,10 @@ // Product revision string included in Inquiry response, max 4 bytes #define CFG_TUD_MSC_PRODUCT_REV "1.0" -//-------------------------------------------------------------------- -// HID -//-------------------------------------------------------------------- +//------------- HID -------------// + +// Should be sufficient to hold ID (if any) + Data +#define CFG_TUD_HID_BUFSIZE 16 #ifdef __cplusplus } diff --git a/examples/device/cdc_msc_hid/src/usb_descriptors.c b/examples/device/cdc_msc_hid/src/usb_descriptors.c index c3bcc6f2b..72d280c2f 100644 --- a/examples/device/cdc_msc_hid/src/usb_descriptors.c +++ b/examples/device/cdc_msc_hid/src/usb_descriptors.c @@ -76,8 +76,8 @@ enum uint8_t const desc_hid_report[] = { - HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(REPORT_ID_KEYBOARD), ), - 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), ) }; #endif @@ -117,19 +117,22 @@ enum uint8_t const desc_configuration[] = { - // Config: self-powered with remote wakeup support, max power up to 100 mA + // Inteface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), #if CFG_TUD_CDC + // Interface number, string index, EP notification address and size, EP data address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, 0x81, 8, 0x02, 0x82, 64), #endif #if CFG_TUD_MSC + // Interface number, string index, EP Out & EP In address, EP size TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC, 0x80 | EPNUM_MSC, 64), // highspeed 512 #endif #if CFG_TUD_HID - TUD_HID_DESCRIPTOR(ITF_NUM_HID, 6, HID_PROTOCOL_KEYBOARD, sizeof(desc_hid_report), 0x84, 16, 10) + // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval + TUD_HID_DESCRIPTOR(ITF_NUM_HID, 6, HID_PROTOCOL_NONE, sizeof(desc_hid_report), 0x84, 16, 10) #endif }; @@ -162,13 +165,13 @@ uint16_t const * const string_desc_arr [] = // tud_desc_set is required by tinyusb stack tud_desc_set_t tud_desc_set = { - .device = &desc_device, - .config = desc_configuration, + .device = &desc_device, + .config = desc_configuration, - .string_arr = (uint8_t const **) string_desc_arr, - .string_count = sizeof(string_desc_arr)/sizeof(string_desc_arr[0]), + .string_arr = (uint8_t const **) string_desc_arr, + .string_count = sizeof(string_desc_arr)/sizeof(string_desc_arr[0]), #if CFG_TUD_HID - .hid_report = desc_hid_report, + .hid_report = desc_hid_report, #endif }; diff --git a/examples/device/cdc_msc_hid_freertos/Makefile b/examples/device/cdc_msc_hid_freertos/Makefile new file mode 100644 index 000000000..3a39f4601 --- /dev/null +++ b/examples/device/cdc_msc_hid_freertos/Makefile @@ -0,0 +1,29 @@ +include ../../../tools/top.mk +include ../../make.mk + +INC += \ + src \ + $(TOP)/hw \ + $(TOP)/lib/FreeRTOS/Source/include \ + $(TOP)/lib/FreeRTOS/Source/portable/GCC/$(FREERTOS_PORT) + +# Example source +EXAMPLE_SOURCE += $(wildcard src/*.c) +SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) + +# Board source +SRC_C += hw/bsp/$(BOARD)/board_$(BOARD).c + +# FreeRTOS source +SRC_C += \ + lib/FreeRTOS/Source/list.c \ + lib/FreeRTOS/Source/queue.c \ + lib/FreeRTOS/Source/tasks.c \ + lib/FreeRTOS/Source/timers.c \ + lib/FreeRTOS/Source/portable/MemMang/heap_4.c \ + lib/FreeRTOS/Source/portable/GCC/$(FREERTOS_PORT)/port.c \ + +# FreeRTOS (lto + Os) linker issue +LDFLAGS += -Wl,--undefined=vTaskSwitchContext + +include ../../rules.mk diff --git a/examples/device/cdc_msc_hid_freertos/ses/nrf5x/FreeRTOSConfig.h b/examples/device/cdc_msc_hid_freertos/ses/nrf5x/FreeRTOSConfig.h deleted file mode 100644 index 754158622..000000000 --- a/examples/device/cdc_msc_hid_freertos/ses/nrf5x/FreeRTOSConfig.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * 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. - *----------------------------------------------------------*/ -#include "nrf.h" - - -#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 ( 16*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 2 -#define configUSE_QUEUE_SETS 0 -#define configUSE_TIME_SLICING 0 -#define configUSE_NEWLIB_REENTRANT 0 -#define configENABLE_BACKWARD_COMPATIBILITY 1 - -#define configSUPPORT_STATIC_ALLOCATION 1 -#define configSUPPORT_DYNAMIC_ALLOCATION 1 - -/* Hook function related definitions. */ -#define configUSE_IDLE_HOOK 0 -#define configUSE_TICK_HOOK 0 -#define configUSE_MALLOC_FAILED_HOOK 1 -#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 - -/* FreeRTOS hooks to NVIC vectors */ -#define xPortPendSVHandler PendSV_Handler -#define xPortSysTickHandler SysTick_Handler -#define vPortSVCHandler SVC_Handler - -//--------------------------------------------------------------------+ -// Interrupt nesting behavior configuration. -//--------------------------------------------------------------------+ -/* Cortex-M specific definitions. __NVIC_PRIO_BITS is defined in core_cmx.h */ -#ifdef __NVIC_PRIO_BITS - #define configPRIO_BITS __NVIC_PRIO_BITS -#else - #error "This port requires __NVIC_PRIO_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. */ - -/* SD priority - * 0: SD timing critical - * 1: SD memory protection - * 2: App Highest - * 3: App High - * 4: SD non-time-critical - * 5+ Remaining Application - */ -#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 /* __FREERTOS_CONFIG__H */ diff --git a/examples/device/cdc_msc_hid_freertos/ses/nrf5x/nrf5x.emProject b/examples/device/cdc_msc_hid_freertos/ses/nrf5x/nrf5x.emProject index ee387958e..f01b26d23 100644 --- a/examples/device/cdc_msc_hid_freertos/ses/nrf5x/nrf5x.emProject +++ b/examples/device/cdc_msc_hid_freertos/ses/nrf5x/nrf5x.emProject @@ -141,7 +141,6 @@ <file file_name="../../../../../lib/FreeRTOS/Source/tasks.c" /> <file file_name="../../../../../lib/FreeRTOS/Source/timers.c" /> </folder> - <file file_name="../../../../../lib/FreeRTOS/freertos_hook.c" /> </folder> </folder> <configuration diff --git a/examples/device/cdc_msc_hid_freertos/src/freertos_hook.c b/examples/device/cdc_msc_hid_freertos/src/freertos_hook.c new file mode 100644 index 000000000..71bad3ddf --- /dev/null +++ b/examples/device/cdc_msc_hid_freertos/src/freertos_hook.c @@ -0,0 +1,96 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018, hathach (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 +//--------------------------------------------------------------------+ +#include "FreeRTOS.h" +#include "task.h" +#include "common/tusb_common.h" + + +void vApplicationMallocFailedHook(void) +{ + taskDISABLE_INTERRUPTS(); + TU_ASSERT(false, ); +} + +void vApplicationStackOverflowHook(xTaskHandle pxTask, signed 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; +} diff --git a/examples/device/cdc_msc_hid_freertos/src/main.c b/examples/device/cdc_msc_hid_freertos/src/main.c index f10c81d7c..b912c23e8 100644 --- a/examples/device/cdc_msc_hid_freertos/src/main.c +++ b/examples/device/cdc_msc_hid_freertos/src/main.c @@ -55,6 +55,8 @@ TimerHandle_t blink_tm; void led_blinky_cb(TimerHandle_t xTimer); void usb_device_task(void* param); +void cdc_task(void* params); +void hid_task(void* params); /*------------- MAIN -------------*/ int main(void) @@ -72,12 +74,10 @@ int main(void) // Create task #if CFG_TUD_CDC - extern void cdc_task(void* params); xTaskCreate( cdc_task, "cdc", 128, NULL, configMAX_PRIORITIES-2, NULL); #endif #if CFG_TUD_HID - extern void hid_task(void* params); xTaskCreate( hid_task, "hid", 128, NULL, configMAX_PRIORITIES-2, NULL); #endif @@ -226,7 +226,9 @@ void hid_task(void* params) if ( btn ) { int8_t const delta = 5; - tud_hid_mouse_move(REPORT_ID_MOUSE, delta, delta); // right + down + + // 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(2)); @@ -250,13 +252,16 @@ void hid_task(void* params) }else { // send empty key report if previously has key pressed - if (has_key) tud_hid_keyboard_key_release(REPORT_ID_KEYBOARD); + if (has_key) tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, NULL); has_key = false; } } } } +// 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 uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) { // TODO not Implemented @@ -268,6 +273,8 @@ uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, return 0; } +// Invoked when received SET_REPORT control request or +// received data on OUT endpoint ( Report ID = 0, Type = 0 ) void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) { // TODO not Implemented diff --git a/examples/device/cdc_msc_hid_freertos/src/tusb_config.h b/examples/device/cdc_msc_hid_freertos/src/tusb_config.h index 834d01216..04ffaafca 100644 --- a/examples/device/cdc_msc_hid_freertos/src/tusb_config.h +++ b/examples/device/cdc_msc_hid_freertos/src/tusb_config.h @@ -77,17 +77,13 @@ #define CFG_TUD_MIDI 0 #define CFG_TUD_CUSTOM_CLASS 0 -//-------------------------------------------------------------------- -// CDC -//-------------------------------------------------------------------- +//------------- CDC -------------// // FIFO size of CDC TX and RX #define CFG_TUD_CDC_RX_BUFSIZE 64 #define CFG_TUD_CDC_TX_BUFSIZE 64 -//-------------------------------------------------------------------- -// MSC -//-------------------------------------------------------------------- +//------------- MSC -------------// // Buffer size of Device Mass storage #define CFG_TUD_MSC_BUFSIZE 512 @@ -101,9 +97,10 @@ // Product revision string included in Inquiry response, max 4 bytes #define CFG_TUD_MSC_PRODUCT_REV "1.0" -//-------------------------------------------------------------------- -// HID -//-------------------------------------------------------------------- +//------------- HID -------------// + +// Should be sufficient to hold ID (if any) + Data +#define CFG_TUD_HID_BUFSIZE 16 #ifdef __cplusplus } diff --git a/examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c b/examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c index c3bcc6f2b..1faaaed66 100644 --- a/examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c +++ b/examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c @@ -76,8 +76,8 @@ enum uint8_t const desc_hid_report[] = { - HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(REPORT_ID_KEYBOARD), ), - 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), ) }; #endif @@ -117,19 +117,22 @@ enum uint8_t const desc_configuration[] = { - // Config: self-powered with remote wakeup support, max power up to 100 mA + // Inteface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), #if CFG_TUD_CDC + // Interface number, string index, EP notification address and size, EP data address (out, in) and size. TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, 0x81, 8, 0x02, 0x82, 64), #endif #if CFG_TUD_MSC + // Interface number, string index, EP Out & EP In address, EP size TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC, 0x80 | EPNUM_MSC, 64), // highspeed 512 #endif #if CFG_TUD_HID - TUD_HID_DESCRIPTOR(ITF_NUM_HID, 6, HID_PROTOCOL_KEYBOARD, sizeof(desc_hid_report), 0x84, 16, 10) + // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval + TUD_HID_DESCRIPTOR(ITF_NUM_HID, 6, HID_PROTOCOL_NONE, sizeof(desc_hid_report), 0x84, 16, 10) #endif }; diff --git a/examples/device/hid_generic_inout/Makefile b/examples/device/hid_generic_inout/Makefile new file mode 100644 index 000000000..4ff3371dc --- /dev/null +++ b/examples/device/hid_generic_inout/Makefile @@ -0,0 +1,15 @@ +include ../../../tools/top.mk +include ../../make.mk + +INC += \ + src \ + $(TOP)/hw \ + +# Example source +EXAMPLE_SOURCE += $(wildcard src/*.c) +SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) + +# Board source +SRC_C += hw/bsp/$(BOARD)/board_$(BOARD).c + +include ../../rules.mk diff --git a/examples/device/hid_generic_inout/hid_test.py b/examples/device/hid_generic_inout/hid_test.py new file mode 100644 index 000000000..b6799687d --- /dev/null +++ b/examples/device/hid_generic_inout/hid_test.py @@ -0,0 +1,15 @@ +# Install python3 HID package https://pypi.org/project/hid/ +import hid + +USB_VID = 0xcafe + +for dict in hid.enumerate(0xcafe): + print(dict) + dev = hid.Device(dict['vendor_id'], dict['product_id']) + if dev: + while True: + # Get input from console and encode to UTF8 for array of chars. + str_out = input("Send text to HID Device : ").encode('utf-8') + dev.write(str_out) + str_in = dev.read(64) + print("Received from HID Device:", str_in, '\n') diff --git a/examples/device/hid_generic_inout/src/main.c b/examples/device/hid_generic_inout/src/main.c new file mode 100644 index 000000000..650df1ce2 --- /dev/null +++ b/examples/device/hid_generic_inout/src/main.c @@ -0,0 +1,154 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018, hathach (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.h" +#include "tusb.h" + +/* This example demonstrate HID Generic raw Input & Output. + * It will receive data from Host (In endpoint) and echo back (Out endpoint). + * HID Report descriptor use vendor for usage page (using template TUD_HID_REPORT_DESC_GENERIC_INOUT) + * + * Run 'python3 hid_test.py' on your PC to send and receive data to this device. + * Python and `hid` package is required, for installation please follow + * https://pypi.org/project/hid/ + */ + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF PROTYPES +//--------------------------------------------------------------------+ + +/* 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 uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; + +void led_blinking_task(void); + +/*------------- MAIN -------------*/ +int main(void) +{ + board_init(); + + tusb_init(); + + while (1) + { + // tinyusb device task + tud_task(); + + led_blinking_task(); + } + + return 0; +} + +//--------------------------------------------------------------------+ +// Device callbacks +//--------------------------------------------------------------------+ + +// Invoked when device is mounted +void tud_mount_cb(void) +{ + blink_interval_ms = BLINK_MOUNTED; +} + +// Invoked when device is unmounted +void tud_umount_cb(void) +{ + blink_interval_ms = BLINK_NOT_MOUNTED; +} + +// 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) remote_wakeup_en; + blink_interval_ms = BLINK_SUSPENDED; +} + +// Invoked when usb bus is resumed +void tud_resume_cb(void) +{ + blink_interval_ms = BLINK_MOUNTED; +} + +//--------------------------------------------------------------------+ +// USB HID +//--------------------------------------------------------------------+ + +// 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 +uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) +{ + // TODO not Implemented + (void) report_id; + (void) report_type; + (void) buffer; + (void) reqlen; + + return 0; +} + +// Invoked when received SET_REPORT control request or +// received data on OUT endpoint ( Report ID = 0, Type = 0 ) +void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) +{ + // This example doesn't use multiple report and report ID + (void) report_id; + (void) report_type; + + // echo back anything we received from host + tud_hid_report(0, buffer, bufsize); +} + +//--------------------------------------------------------------------+ +// BLINKING TASK +//--------------------------------------------------------------------+ +void led_blinking_task(void) +{ + static uint32_t start_ms = 0; + static bool led_state = false; + + // Blink every 1000 ms + if ( board_millis() < start_ms + blink_interval_ms) return; // not enough time + start_ms += blink_interval_ms; + + board_led_write(led_state); + led_state = 1 - led_state; // toggle +} diff --git a/examples/device/hid_generic_inout/src/tusb_config.h b/examples/device/hid_generic_inout/src/tusb_config.h new file mode 100644 index 000000000..baf418d94 --- /dev/null +++ b/examples/device/hid_generic_inout/src/tusb_config.h @@ -0,0 +1,88 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018, hathach (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 + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +// defined by compiler flags for flexibility +#ifndef CFG_TUSB_MCU + #error CFG_TUSB_MCU must be defined +#endif + +#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX +#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) +#else +#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE +#endif + +#define CFG_TUSB_OS OPT_OS_NONE +#define CFG_TUSB_DEBUG 2 + +/* 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_TUSB_MEM_SECTION +#define CFG_TUSB_MEM_SECTION +#endif + +#ifndef CFG_TUSB_MEM_ALIGN +#define CFG_TUSB_MEM_ALIGN ATTR_ALIGNED(4) +#endif + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +#define CFG_TUD_ENDOINT0_SIZE 64 + +//------------- CLASS -------------// +#define CFG_TUD_CDC 0 +#define CFG_TUD_MSC 0 +#define CFG_TUD_HID 1 +#define CFG_TUD_MIDI 0 +#define CFG_TUD_CUSTOM_CLASS 0 + +//------------- HID -------------// + +// Should be sufficient to hold ID (if any) + Data +#define CFG_TUD_HID_BUFSIZE 64 + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/examples/device/hid_generic_inout/src/usb_descriptors.c b/examples/device/hid_generic_inout/src/usb_descriptors.c new file mode 100644 index 000000000..231eb4fa6 --- /dev/null +++ b/examples/device/hid_generic_inout/src/usb_descriptors.c @@ -0,0 +1,117 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018, hathach (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" + +/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. + * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. + * + * Auto ProductID layout's Bitmap: + * [MSB] HID | MSC | CDC [LSB] + */ +#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) ) +#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) ) + +//------------- Device Descriptors -------------// +tusb_desc_device_t const desc_device = +{ + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = 0x0200, + .bDeviceClass = 0x00, + .bDeviceSubClass = 0x00, + .bDeviceProtocol = 0x00, + .bMaxPacketSize0 = CFG_TUD_ENDOINT0_SIZE, + + .idVendor = 0xCafe, + .idProduct = USB_PID, + .bcdDevice = 0x0100, + + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, + + .bNumConfigurations = 0x01 +}; + +//------------- HID Report Descriptor -------------// +uint8_t const desc_hid_report[] = +{ + TUD_HID_REPORT_DESC_GENERIC_INOUT(CFG_TUD_HID_BUFSIZE) +}; + +//------------- Configuration Descriptor -------------// +enum +{ + ITF_NUM_HID, + ITF_NUM_TOTAL +}; + +enum +{ + CONFIG_TOTAL_LEN = TUD_CONFIG_DESC_LEN + TUD_HID_INOUT_DESC_LEN +}; + +// Use Endpoint 2 instead of 1 due to NXP MCU +// LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number +// 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... +#define EPNUM_HID 0x01 + +uint8_t const desc_configuration[] = +{ + // Inteface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(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_INOUT_DESCRIPTOR(ITF_NUM_HID, 0, HID_PROTOCOL_NONE, sizeof(desc_hid_report), 0x80 | EPNUM_HID, EPNUM_HID, 16, 10) +}; + +//------------- String Descriptors -------------// +// array of pointer to string descriptors +uint16_t const * const string_desc_arr [] = +{ + // 0: is supported language = English + TUD_DESC_STRCONV(0x0409), + + // 1: Manufacturer + TUD_DESC_STRCONV('t', 'i', 'n', 'y', 'u', 's', 'b', '.', 'o', 'r', 'g'), + + // 2: Product + TUD_DESC_STRCONV('t', 'i', 'n', 'y', 'u', 's', 'b', ' ', 'd', 'e', 'v', 'i', 'c', 'e'), + + // 3: Serials, should use chip ID + TUD_DESC_STRCONV('1', '2', '3', '4', '5', '6'), +}; + +// tud_desc_set is required by tinyusb stack +tud_desc_set_t tud_desc_set = +{ + .device = &desc_device, + .config = desc_configuration, + + .string_arr = (uint8_t const **) string_desc_arr, + .string_count = sizeof(string_desc_arr)/sizeof(string_desc_arr[0]), + .hid_report = desc_hid_report, +}; diff --git a/examples/device/msc_dual_lun/Makefile b/examples/device/msc_dual_lun/Makefile index 1a9f9d135..59eeacf4d 100644 --- a/examples/device/msc_dual_lun/Makefile +++ b/examples/device/msc_dual_lun/Makefile @@ -1,186 +1,15 @@ include ../../../tools/top.mk +include ../../make.mk -# Select the board to build for. -ifeq ($(BOARD),) - $(info You must provide a BOARD parameter with 'BOARD=') - $(info Possible values are:) - $(info $(sort $(subst /.,,$(subst $(TOP)/hw/bsp/,,$(wildcard $(TOP)/hw/bsp/*/.))))) - $(error BOARD not defined) -else - ifeq ($(wildcard $(TOP)/hw/bsp/$(BOARD)/.),) - $(error Invalid BOARD specified) - endif -endif - -# Verbose mode (V=). 0: default, 1: print out CFLAG, LDFLAG 2: print all compile command -ifeq ("$(V)","2") - QUIET = -else - QUIET = @ -endif - -# If the build directory is not given, make it reflect the board name. -BUILD ?= build-$(BOARD) - -CROSS_COMPILE = arm-none-eabi- - -include $(TOP)/hw/bsp/$(BOARD)/board.mk - -CC = $(CROSS_COMPILE)gcc -CXX = $(CROSS_COMPILE)g++ -OBJCOPY = $(CROSS_COMPILE)objcopy -SIZE = $(CROSS_COMPILE)size -MKDIR = mkdir -SED = sed -CP = cp -RM = rm - -INC += -Isrc \ - -I$(TOP)/hw \ - -I$(TOP)/src - -CFLAGS += \ - -fsingle-precision-constant \ - -fno-strict-aliasing \ - -Wdouble-promotion \ - -Wno-endif-labels \ - -Wstrict-prototypes \ - -Werror-implicit-function-declaration \ - -Wfloat-equal \ - -Wundef \ - -Wshadow \ - -Wwrite-strings \ - -Wsign-compare \ - -Wmissing-format-attribute \ - -Wno-deprecated-declarations \ - -Wnested-externs \ - -Wunreachable-code \ - -Wno-error=lto-type-mismatch \ - -ffunction-sections \ - -fdata-sections - -# This causes lots of warning with nrf5x build due to nrfx code -# CFLAGS += -Wcast-align - -#Debugging/Optimization -ifeq ($(DEBUG), 1) - CFLAGS += -O0 -ggdb -else - CFLAGS += -flto -Os -endif - -CFLAGS += $(INC) -Wall -Werror -std=gnu11 -DBOARD_$(shell echo $(BOARD) | tr '[:lower:]' '[:upper:]') -LDFLAGS += $(CFLAGS) -fshort-enums -Wl,-T,$(TOP)/$(LD_FILE) -Wl,[email protected] -Wl,-cref -Wl,-gc-sections -specs=nosys.specs -specs=nano.specs - -ifeq ("$(V)","1") -$(info CFLAGS $(CFLAGS)) -$(info ) -$(info LDFLAGS $(LDFLAGS)) -$(info ) -$(info ASFLAGS $(ASFLAGS)) -$(info ) -endif - -LIBS = -lgcc -lc -lm -lnosys +INC += \ + src \ + $(TOP)/hw \ +# Example source EXAMPLE_SOURCE += $(wildcard src/*.c) - SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) -LIB_SOURCE += \ - hw/bsp/$(BOARD)/board_$(BOARD).c \ - src/common/tusb_fifo.c \ - src/device/usbd.c \ - src/device/usbd_control.c \ - src/class/msc/msc_device.c \ - src/class/cdc/cdc_device.c \ - src/class/hid/hid_device.c \ - src/tusb.c \ - src/portable/$(VENDOR)/$(CHIP_FAMILY)/dcd_$(CHIP_FAMILY).c - -SRC_C += $(LIB_SOURCE) - -# Assembly files can be name with upper case .S, convert it to .s -SRC_S := $(SRC_S:.S=.s) - -# Due to GCC LTO bug https://bugs.launchpad.net/gcc-arm-embedded/+bug/1747966 -# assembly file should be placed first in linking order -OBJ += $(addprefix $(BUILD)/obj/, $(SRC_S:.s=.o)) -OBJ += $(addprefix $(BUILD)/obj/, $(SRC_C:.c=.o)) - -# Set all as default goal -.DEFAULT_GOAL := all -all: $(BUILD)/$(BOARD)-firmware.bin size - -OBJ_DIRS = $(sort $(dir $(OBJ))) -$(OBJ): | $(OBJ_DIRS) -$(OBJ_DIRS): - @$(MKDIR) -p $@ - -$(BUILD)/$(BOARD)-firmware.elf: $(OBJ) - @echo LINK $@ - $(QUIET)$(CC) -o $@ $(LDFLAGS) $^ -Wl,--start-group $(LIBS) -Wl,--end-group - -$(BUILD)/$(BOARD)-firmware.bin: $(BUILD)/$(BOARD)-firmware.elf - @echo CREATE $@ - @$(OBJCOPY) -O binary -j .vectors -j .text -j .data $^ $@ - -$(BUILD)/$(BOARD)-firmware.hex: $(BUILD)/$(BOARD)-firmware.elf - @echo CREATE $@ - @$(OBJCOPY) -O ihex $^ $@ - -# 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 -# to be used to compile all .c files. -vpath %.c . $(TOP) -$(BUILD)/obj/%.o: %.c - @echo CC $(notdir $@) - $(QUIET)$(CC) $(CFLAGS) -c -MD -o $@ $< - @# The following fixes the dependency file. - @# See http://make.paulandlesley.org/autodep.html for details. - @# Regex adjusted from the above to play better with Windows paths, etc. - @$(CP) $(@:.o=.d) $(@:.o=.P); \ - $(SED) -e 's/#.*//' -e 's/^.*: *//' -e 's/ *\\$$//' \ - -e '/^$$/ d' -e 's/$$/ :/' < $(@:.o=.d) >> $(@:.o=.P); \ - $(RM) $(@:.o=.d) - -# ASM sources lower case .s -vpath %.s . $(TOP) -$(BUILD)/obj/%.o: %.s - @echo AS $(notdir $@) - $(QUIET)$(CC) -x assembler-with-cpp $(ASFLAGS) -c -o $@ $< - -# ASM sources upper case .S -vpath %.S . $(TOP) -$(BUILD)/obj/%.o: %.S - @echo AS $(notdir $@) - $(QUIET)$(CC) -x assembler-with-cpp $(ASFLAGS) -c -o $@ $< - -# Flash binary using Jlink, should be added into system path -ifeq ($(OS),Windows_NT) - JLINKEXE = JLink.exe -else - JLINKEXE = JLinkExe -endif - -# default jlink interface is swd -ifeq ($(JLINK_IF),) - JLINK_IF = swd -endif - -# Flash using jlink -flash-jlink: $(BUILD)/$(BOARD)-firmware.hex - @echo halt > $(BUILD)/$(BOARD).jlink - @echo loadfile $^ >> $(BUILD)/$(BOARD).jlink - @echo r >> $(BUILD)/$(BOARD).jlink - @echo go >> $(BUILD)/$(BOARD).jlink - @echo exit >> $(BUILD)/$(BOARD).jlink - $(JLINKEXE) -device $(JLINK_DEVICE) -if $(JLINK_IF) -speed auto -CommandFile $(BUILD)/$(BOARD).jlink - -size: $(BUILD)/$(BOARD)-firmware.elf - -@echo '' - @$(SIZE) $< - -@echo '' +# Board source +SRC_C += hw/bsp/$(BOARD)/board_$(BOARD).c -clean: - rm -rf build-$(BOARD) +include ../../rules.mk diff --git a/examples/device/msc_dual_lun/src/tusb_config.h b/examples/device/msc_dual_lun/src/tusb_config.h index b25510f25..492eba5f1 100644 --- a/examples/device/msc_dual_lun/src/tusb_config.h +++ b/examples/device/msc_dual_lun/src/tusb_config.h @@ -76,9 +76,7 @@ #define CFG_TUD_MIDI 0 #define CFG_TUD_CUSTOM_CLASS 0 -//-------------------------------------------------------------------- -// MSC -//-------------------------------------------------------------------- +//------------- MSC -------------// // Buffer size of Device Mass storage #define CFG_TUD_MSC_BUFSIZE 512 diff --git a/examples/device/msc_dual_lun/src/usb_descriptors.c b/examples/device/msc_dual_lun/src/usb_descriptors.c index ede516eb1..af2b1a091 100644 --- a/examples/device/msc_dual_lun/src/usb_descriptors.c +++ b/examples/device/msc_dual_lun/src/usb_descriptors.c @@ -43,7 +43,6 @@ tusb_desc_device_t const desc_device = .bDeviceClass = 0x00, .bDeviceSubClass = 0x00, .bDeviceProtocol = 0x00, - .bMaxPacketSize0 = CFG_TUD_ENDOINT0_SIZE, .idVendor = 0xCafe, @@ -76,12 +75,11 @@ enum uint8_t const desc_configuration[] = { - // Config: self-powered with remote wakeup support, max power up to 100 mA + // Inteface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), -#if CFG_TUD_MSC - TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC, 0x80 | EPNUM_MSC, 64), // highspeed 512 -#endif + // Interface number, string index, EP Out & EP In address, EP size + TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 0, EPNUM_MSC, 0x80 | EPNUM_MSC, 64), // highspeed 512 }; //------------- String Descriptors -------------// |
