mirror of
https://github.com/hathach/tinyusb.git
synced 2025-01-31 05:52:55 +08:00
Merge pull request #61 from hathach/develop
enhance HID, add HID out endpoint support
This commit is contained in:
commit
867e69ed9d
@ -24,7 +24,7 @@ TinyUSB is an open-source cross-platform USB Host/Device stack for embedded syst
|
||||
Support multiple device configurations by dynamically changing usb descriptors. Low power functions such as suspend, resume and remote wakeup. Following device classes are supported:
|
||||
|
||||
- Communication Class (CDC)
|
||||
- Human Interface Device (HID): Keyboard, Mouse, Gamepad etc ...
|
||||
- Human Interface Device (HID): Generic (In & Out), Keyboard, Mouse, Gamepad etc ...
|
||||
- Mass Storage Class (MSC): with multiple LUNs
|
||||
- Musical Instrument Digital Interface (MIDI)
|
||||
|
||||
@ -78,5 +78,6 @@ TinyUSB is currently used by these other projects:
|
||||
* [Adafruit nRF52 Arduino](https://github.com/adafruit/Adafruit_nRF52_Arduino)
|
||||
* [Adafruit nRF52 Bootloader](https://github.com/adafruit/Adafruit_nRF52_Bootloader)
|
||||
* [CircuitPython](https://github.com/adafruit/circuitpython)
|
||||
* [TinyUSB Arduino Library](https://github.com/adafruit/Adafruit_TinyUSB_Arduino)
|
||||
|
||||
If your project also uses TinyUSB and want to share, feel free to create a pull request.
|
||||
|
@ -11,6 +11,7 @@ This code base already had supported for a handful of following boards
|
||||
|
||||
### Nordic nRF5x
|
||||
|
||||
- [Adafruit Feather nRF52840 Express](https://www.adafruit.com/product/4062)
|
||||
- [nRF52840-DK (aka pca10056)](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK)
|
||||
|
||||
### NXP LPC
|
||||
|
@ -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,-Map=$@.map -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
|
||||
# Board source
|
||||
SRC_C += hw/bsp/$(BOARD)/board_$(BOARD).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 ''
|
||||
|
||||
clean:
|
||||
rm -rf build-$(BOARD)
|
||||
include ../../rules.mk
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
};
|
||||
|
29
examples/device/cdc_msc_hid_freertos/Makefile
Normal file
29
examples/device/cdc_msc_hid_freertos/Makefile
Normal file
@ -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
|
@ -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
|
||||
|
@ -94,10 +94,3 @@ void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, Stack
|
||||
configTIMER_TASK_STACK_DEPTH is specified in words, not bytes. */
|
||||
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
|
||||
}
|
||||
|
||||
|
||||
// executes from within an ISR
|
||||
void vApplicationTickHook(void)
|
||||
{
|
||||
|
||||
}
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
15
examples/device/hid_generic_inout/Makefile
Normal file
15
examples/device/hid_generic_inout/Makefile
Normal file
@ -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
|
15
examples/device/hid_generic_inout/hid_test.py
Normal file
15
examples/device/hid_generic_inout/hid_test.py
Normal file
@ -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')
|
154
examples/device/hid_generic_inout/src/main.c
Normal file
154
examples/device/hid_generic_inout/src/main.c
Normal file
@ -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
|
||||
}
|
88
examples/device/hid_generic_inout/src/tusb_config.h
Normal file
88
examples/device/hid_generic_inout/src/tusb_config.h
Normal file
@ -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_ */
|
117
examples/device/hid_generic_inout/src/usb_descriptors.c
Normal file
117
examples/device/hid_generic_inout/src/usb_descriptors.c
Normal file
@ -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,
|
||||
};
|
@ -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,-Map=$@.map -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
|
||||
# Board source
|
||||
SRC_C += hw/bsp/$(BOARD)/board_$(BOARD).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 ''
|
||||
|
||||
clean:
|
||||
rm -rf build-$(BOARD)
|
||||
include ../../rules.mk
|
||||
|
@ -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
|
||||
|
@ -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 -------------//
|
||||
|
65
examples/make.mk
Normal file
65
examples/make.mk
Normal file
@ -0,0 +1,65 @@
|
||||
#
|
||||
# Common make definition for all examples
|
||||
#
|
||||
|
||||
# Compiler
|
||||
CROSS_COMPILE = arm-none-eabi-
|
||||
CC = $(CROSS_COMPILE)gcc
|
||||
CXX = $(CROSS_COMPILE)g++
|
||||
OBJCOPY = $(CROSS_COMPILE)objcopy
|
||||
SIZE = $(CROSS_COMPILE)size
|
||||
MKDIR = mkdir
|
||||
SED = sed
|
||||
CP = cp
|
||||
RM = rm
|
||||
|
||||
# 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
|
||||
|
||||
# Build directory
|
||||
BUILD = build-$(BOARD)
|
||||
|
||||
# Board specific
|
||||
include $(TOP)/hw/bsp/$(BOARD)/board.mk
|
||||
|
||||
# Compiler Flags
|
||||
CFLAGS += \
|
||||
-fsingle-precision-constant \
|
||||
-fno-strict-aliasing \
|
||||
-Wdouble-promotion \
|
||||
-Wno-endif-labels \
|
||||
-Wstrict-prototypes \
|
||||
-Wall \
|
||||
-Werror \
|
||||
-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
|
111
examples/rules.mk
Normal file
111
examples/rules.mk
Normal file
@ -0,0 +1,111 @@
|
||||
#
|
||||
# Common make definition for all examples
|
||||
#
|
||||
|
||||
# libc
|
||||
LIBS = -lgcc -lc -lm -lnosys
|
||||
|
||||
# TinyUSB Stack source
|
||||
SRC_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
|
||||
|
||||
# TinyUSB stack include
|
||||
INC += $(TOP)/src
|
||||
|
||||
#
|
||||
CFLAGS += $(addprefix -I,$(INC))
|
||||
LDFLAGS += $(CFLAGS) -fshort-enums -Wl,-T,$(TOP)/$(LD_FILE) -Wl,-Map=$@.map -Wl,-cref -Wl,-gc-sections -specs=nosys.specs -specs=nano.specs
|
||||
|
||||
# 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))
|
||||
|
||||
# Verbose mode
|
||||
ifeq ("$(V)","1")
|
||||
$(info CFLAGS $(CFLAGS) ) $(info )
|
||||
$(info LDFLAGS $(LDFLAGS)) $(info )
|
||||
$(info ASFLAGS $(ASFLAGS)) $(info )
|
||||
endif
|
||||
|
||||
# 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 $@
|
||||
@$(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 $@)
|
||||
@$(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 $@)
|
||||
@$(CC) -x assembler-with-cpp $(ASFLAGS) -c -o $@ $<
|
||||
|
||||
# ASM sources upper case .S
|
||||
vpath %.S . $(TOP)
|
||||
$(BUILD)/obj/%.o: %.S
|
||||
@echo AS $(notdir $@)
|
||||
@$(CC) -x assembler-with-cpp $(ASFLAGS) -c -o $@ $<
|
||||
|
||||
size: $(BUILD)/$(BOARD)-firmware.elf
|
||||
-@echo ''
|
||||
@$(SIZE) $<
|
||||
-@echo ''
|
||||
|
||||
clean:
|
||||
rm -rf build-$(BOARD)
|
||||
|
||||
# Flash binary using Jlink
|
||||
ifeq ($(OS),Windows_NT)
|
||||
JLINKEXE = JLink.exe
|
||||
else
|
||||
JLINKEXE = JLinkExe
|
||||
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
|
54
hw/bsp/feather_nrf52840_express/board.mk
Normal file
54
hw/bsp/feather_nrf52840_express/board.mk
Normal file
@ -0,0 +1,54 @@
|
||||
CFLAGS += \
|
||||
-mthumb \
|
||||
-mabi=aapcs \
|
||||
-mcpu=cortex-m4 \
|
||||
-mfloat-abi=hard \
|
||||
-mfpu=fpv4-sp-d16 \
|
||||
-DCFG_TUSB_MCU=OPT_MCU_NRF5X \
|
||||
-DNRF52840_XXAA \
|
||||
-DCONFIG_GPIO_AS_PINRESET
|
||||
|
||||
# nrfx issue undef _ARMCC_VERSION usage https://github.com/NordicSemiconductor/nrfx/issues/49
|
||||
CFLAGS += -Wno-error=undef
|
||||
|
||||
# All source paths should be relative to the top level.
|
||||
LD_FILE = hw/mcu/nordic/nrfx/mdk/nrf52840_xxaa.ld
|
||||
|
||||
LDFLAGS += -L$(TOP)/hw/mcu/nordic/nrfx/mdk
|
||||
|
||||
SRC_C += \
|
||||
hw/mcu/nordic/nrfx/drivers/src/nrfx_power.c \
|
||||
hw/mcu/nordic/nrfx/mdk/system_nrf52840.c \
|
||||
|
||||
# TODO remove later
|
||||
SRC_C += src/portable/$(VENDOR)/$(CHIP_FAMILY)/hal_$(CHIP_FAMILY).c
|
||||
|
||||
INC += \
|
||||
$(TOP)/hw/cmsis/Include \
|
||||
$(TOP)/hw/mcu/nordic \
|
||||
$(TOP)/hw/mcu/nordic/nrfx \
|
||||
$(TOP)/hw/mcu/nordic/nrfx/mdk \
|
||||
$(TOP)/hw/mcu/nordic/nrfx/hal \
|
||||
$(TOP)/hw/mcu/nordic/nrfx/drivers/include \
|
||||
$(TOP)/hw/mcu/nordic/nrfx/drivers/src \
|
||||
|
||||
SRC_S += hw/mcu/nordic/nrfx/mdk/gcc_startup_nrf52840.S
|
||||
|
||||
ASFLAGS += -D__HEAP_SIZE=0
|
||||
ASFLAGS += -DSWI_DISABLE0
|
||||
ASFLAGS += -DFLOAT_ABI_HARD
|
||||
ASFLAGS += -DNRF52840_XXAA
|
||||
|
||||
# For TinyUSB port source
|
||||
VENDOR = nordic
|
||||
CHIP_FAMILY = nrf5x
|
||||
|
||||
# For freeRTOS port source
|
||||
FREERTOS_PORT = ARM_CM4F
|
||||
|
||||
# For flash-jlink target
|
||||
JLINK_DEVICE = nRF52840_xxAA
|
||||
JLINK_IF = swd
|
||||
|
||||
# flash using jlink
|
||||
flash: flash-jlink
|
197
hw/bsp/feather_nrf52840_express/board_feather_nrf52840_express.c
Normal file
197
hw/bsp/feather_nrf52840_express/board_feather_nrf52840_express.c
Normal file
@ -0,0 +1,197 @@
|
||||
/*
|
||||
* 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 "bsp/board.h"
|
||||
|
||||
#include "nrfx.h"
|
||||
#include "nrfx/hal/nrf_gpio.h"
|
||||
#include "nrfx/drivers/include/nrfx_power.h"
|
||||
#include "nrfx/drivers/include/nrfx_qspi.h"
|
||||
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
#include "nrf_sdm.h"
|
||||
#include "nrf_soc.h"
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* MACRO TYPEDEF CONSTANT ENUM
|
||||
*------------------------------------------------------------------*/
|
||||
#define _PINNUM(port, pin) ((port)*32 + (pin))
|
||||
|
||||
#define LED_PIN _PINNUM(1, 15)
|
||||
#define LED_STATE_ON 1
|
||||
|
||||
#define BUTTON_PIN _PINNUM(1, 02)
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* TUSB HAL MILLISECOND
|
||||
*------------------------------------------------------------------*/
|
||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||
volatile uint32_t system_ticks = 0;
|
||||
|
||||
void SysTick_Handler (void)
|
||||
{
|
||||
system_ticks++;
|
||||
}
|
||||
|
||||
uint32_t board_millis(void)
|
||||
{
|
||||
return system_ticks;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* BOARD API
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
// tinyusb function that handles power event (detected, ready, removed)
|
||||
// We must call it within SD's SOC event handler, or set it as power event handler if SD is not enabled.
|
||||
extern void tusb_hal_nrf_power_event(uint32_t event);
|
||||
|
||||
void board_init(void)
|
||||
{
|
||||
// Config clock source: XTAL or RC in sdk_config.h
|
||||
NRF_CLOCK->LFCLKSRC = (uint32_t)((CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk);
|
||||
NRF_CLOCK->TASKS_LFCLKSTART = 1UL;
|
||||
|
||||
// LED
|
||||
nrf_gpio_cfg_output(LED_PIN);
|
||||
board_led_write(false);
|
||||
|
||||
// Button
|
||||
nrf_gpio_cfg_input(BUTTON_PIN, NRF_GPIO_PIN_PULLUP);
|
||||
|
||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||
// 1ms tick timer
|
||||
SysTick_Config(SystemCoreClock/1000);
|
||||
#endif
|
||||
|
||||
// Priorities 0, 1, 4 (nRF52) are reserved for SoftDevice
|
||||
// 2 is highest for application
|
||||
NVIC_SetPriority(USBD_IRQn, 2);
|
||||
|
||||
// USB power may already be ready at this time -> no event generated
|
||||
// We need to invoke the handler based on the status initially
|
||||
uint32_t usb_reg;
|
||||
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
uint8_t sd_en = false;
|
||||
sd_softdevice_is_enabled(&sd_en);
|
||||
|
||||
if ( sd_en ) {
|
||||
sd_power_usbdetected_enable(true);
|
||||
sd_power_usbpwrrdy_enable(true);
|
||||
sd_power_usbremoved_enable(true);
|
||||
|
||||
sd_power_usbregstatus_get(&usb_reg);
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
// Power module init
|
||||
const nrfx_power_config_t pwr_cfg = { 0 };
|
||||
nrfx_power_init(&pwr_cfg);
|
||||
|
||||
// Register tusb function as USB power handler
|
||||
const nrfx_power_usbevt_config_t config = { .handler = (nrfx_power_usb_event_handler_t) tusb_hal_nrf_power_event };
|
||||
nrfx_power_usbevt_init(&config);
|
||||
|
||||
nrfx_power_usbevt_enable();
|
||||
|
||||
usb_reg = NRF_POWER->USBREGSTATUS;
|
||||
}
|
||||
|
||||
if ( usb_reg & POWER_USBREGSTATUS_VBUSDETECT_Msk ) tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_DETECTED);
|
||||
if ( usb_reg & POWER_USBREGSTATUS_OUTPUTRDY_Msk ) tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_READY);
|
||||
}
|
||||
|
||||
void board_led_write(bool state)
|
||||
{
|
||||
nrf_gpio_pin_write(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON));
|
||||
}
|
||||
|
||||
uint32_t board_button_read(void)
|
||||
{
|
||||
// button is active LOW
|
||||
return (nrf_gpio_pin_read(BUTTON_PIN) ? 0 : 1);
|
||||
}
|
||||
|
||||
int board_uart_read(uint8_t* buf, int len)
|
||||
{
|
||||
(void) buf;
|
||||
(void) len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_uart_write(void const * buf, int len)
|
||||
{
|
||||
(void) buf;
|
||||
(void) len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
// process SOC event from SD
|
||||
uint32_t proc_soc(void)
|
||||
{
|
||||
uint32_t soc_evt;
|
||||
uint32_t err = sd_evt_get(&soc_evt);
|
||||
|
||||
if (NRF_SUCCESS == err)
|
||||
{
|
||||
/*------------- usb power event handler -------------*/
|
||||
int32_t usbevt = (soc_evt == NRF_EVT_POWER_USB_DETECTED ) ? NRFX_POWER_USB_EVT_DETECTED:
|
||||
(soc_evt == NRF_EVT_POWER_USB_POWER_READY) ? NRFX_POWER_USB_EVT_READY :
|
||||
(soc_evt == NRF_EVT_POWER_USB_REMOVED ) ? NRFX_POWER_USB_EVT_REMOVED : -1;
|
||||
|
||||
if ( usbevt >= 0) tusb_hal_nrf_power_event(usbevt);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
uint32_t proc_ble(void)
|
||||
{
|
||||
// do nothing with ble
|
||||
return NRF_ERROR_NOT_FOUND;
|
||||
}
|
||||
|
||||
void SD_EVT_IRQHandler(void)
|
||||
{
|
||||
// process BLE and SOC until there is no more events
|
||||
while( (NRF_ERROR_NOT_FOUND != proc_ble()) || (NRF_ERROR_NOT_FOUND != proc_soc()) )
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void nrf_error_cb(uint32_t id, uint32_t pc, uint32_t info)
|
||||
{
|
||||
(void) id;
|
||||
(void) pc;
|
||||
(void) info;
|
||||
}
|
||||
#endif
|
@ -23,20 +23,26 @@ SRC_C += \
|
||||
hw/mcu/microchip/samd/asf4/samd21/hal/src/hal_atomic.c
|
||||
|
||||
INC += \
|
||||
-I$(TOP)/hw/mcu/microchip/samd/asf4/samd21/ \
|
||||
-I$(TOP)/hw/mcu/microchip/samd/asf4/samd21/config \
|
||||
-I$(TOP)/hw/mcu/microchip/samd/asf4/samd21/include \
|
||||
-I$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hal/include \
|
||||
-I$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hal/utils/include \
|
||||
-I$(TOP)/hw/mcu/microchip/samd/asf4/samd51/hpl/pm/ \
|
||||
-I$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hpl/port \
|
||||
-I$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hri \
|
||||
-I$(TOP)/hw/mcu/microchip/samd/asf4/samd21/CMSIS/Include
|
||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/ \
|
||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/config \
|
||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/include \
|
||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hal/include \
|
||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hal/utils/include \
|
||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd51/hpl/pm/ \
|
||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hpl/port \
|
||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/hri \
|
||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd21/CMSIS/Include
|
||||
|
||||
# For TinyUSB port source
|
||||
VENDOR = microchip
|
||||
CHIP_FAMILY = samd21
|
||||
|
||||
# For freeRTOS port source
|
||||
FREERTOS_PORT = ARM_CM0
|
||||
|
||||
# For flash-jlink target
|
||||
JLINK_DEVICE = ATSAMD21G18
|
||||
JLINK_IF = swd
|
||||
|
||||
# flash using jlink
|
||||
flash: flash-jlink
|
||||
|
@ -25,19 +25,25 @@ SRC_C += \
|
||||
hw/mcu/microchip/samd/asf4/samd51/hal/src/hal_atomic.c
|
||||
|
||||
INC += \
|
||||
-I$(TOP)/hw/mcu/microchip/samd/asf4/samd51/ \
|
||||
-I$(TOP)/hw/mcu/microchip/samd/asf4/samd51/config \
|
||||
-I$(TOP)/hw/mcu/microchip/samd/asf4/samd51/include \
|
||||
-I$(TOP)/hw/mcu/microchip/samd/asf4/samd51/hal/include \
|
||||
-I$(TOP)/hw/mcu/microchip/samd/asf4/samd51/hal/utils/include \
|
||||
-I$(TOP)/hw/mcu/microchip/samd/asf4/samd51/hpl/port \
|
||||
-I$(TOP)/hw/mcu/microchip/samd/asf4/samd51/hri \
|
||||
-I$(TOP)/hw/mcu/microchip/samd/asf4/samd51/CMSIS/Include
|
||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd51/ \
|
||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd51/config \
|
||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd51/include \
|
||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd51/hal/include \
|
||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd51/hal/utils/include \
|
||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd51/hpl/port \
|
||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd51/hri \
|
||||
$(TOP)/hw/mcu/microchip/samd/asf4/samd51/CMSIS/Include
|
||||
|
||||
# For TinyUSB port source
|
||||
VENDOR = microchip
|
||||
CHIP_FAMILY = samd51
|
||||
|
||||
# For freeRTOS port source
|
||||
FREERTOS_PORT = ARM_CM4F
|
||||
|
||||
# For flash-jlink target
|
||||
JLINK_DEVICE = ATSAMD51J19
|
||||
JLINK_IF = swd
|
||||
|
||||
# flash using jlink
|
||||
flash: flash-jlink
|
||||
|
@ -1,11 +1,12 @@
|
||||
CFLAGS += \
|
||||
-DCFG_TUSB_MCU=OPT_MCU_NRF5X \
|
||||
-DNRF52840_XXAA \
|
||||
-mthumb \
|
||||
-mabi=aapcs \
|
||||
-mcpu=cortex-m4 \
|
||||
-mfloat-abi=hard \
|
||||
-mfpu=fpv4-sp-d16
|
||||
-mfpu=fpv4-sp-d16 \
|
||||
-DCFG_TUSB_MCU=OPT_MCU_NRF5X \
|
||||
-DNRF52840_XXAA \
|
||||
-DCONFIG_GPIO_AS_PINRESET
|
||||
|
||||
# nrfx issue undef _ARMCC_VERSION usage https://github.com/NordicSemiconductor/nrfx/issues/49
|
||||
CFLAGS += -Wno-error=undef
|
||||
@ -23,27 +24,31 @@ SRC_C += \
|
||||
SRC_C += src/portable/$(VENDOR)/$(CHIP_FAMILY)/hal_$(CHIP_FAMILY).c
|
||||
|
||||
INC += \
|
||||
-I$(TOP)/hw/cmsis/Include \
|
||||
-I$(TOP)/hw/mcu/nordic \
|
||||
-I$(TOP)/hw/mcu/nordic/nrfx \
|
||||
-I$(TOP)/hw/mcu/nordic/nrfx/mdk \
|
||||
-I$(TOP)/hw/mcu/nordic/nrfx/hal \
|
||||
-I$(TOP)/hw/mcu/nordic/nrfx/drivers/include \
|
||||
-I$(TOP)/hw/mcu/nordic/nrfx/drivers/src \
|
||||
$(TOP)/hw/cmsis/Include \
|
||||
$(TOP)/hw/mcu/nordic \
|
||||
$(TOP)/hw/mcu/nordic/nrfx \
|
||||
$(TOP)/hw/mcu/nordic/nrfx/mdk \
|
||||
$(TOP)/hw/mcu/nordic/nrfx/hal \
|
||||
$(TOP)/hw/mcu/nordic/nrfx/drivers/include \
|
||||
$(TOP)/hw/mcu/nordic/nrfx/drivers/src \
|
||||
|
||||
SRC_S += hw/mcu/nordic/nrfx/mdk/gcc_startup_nrf52840.S
|
||||
|
||||
ASFLAGS += -D__HEAP_SIZE=0
|
||||
ASFLAGS += -DCONFIG_GPIO_AS_PINRESET
|
||||
ASFLAGS += -DBLE_STACK_SUPPORT_REQD
|
||||
ASFLAGS += -DSWI_DISABLE0
|
||||
ASFLAGS += -DFLOAT_ABI_HARD
|
||||
ASFLAGS += -DNRF52840_XXAA
|
||||
|
||||
# For TinyUSB port source
|
||||
VENDOR = nordic
|
||||
CHIP_FAMILY = nrf5x
|
||||
|
||||
# For freeRTOS port source
|
||||
FREERTOS_PORT = ARM_CM4F
|
||||
|
||||
# For flash-jlink target
|
||||
JLINK_DEVICE = nRF52840_xxAA
|
||||
JLINK_IF = swd
|
||||
|
||||
# flash using jlink
|
||||
flash: flash-jlink
|
||||
|
@ -25,15 +25,21 @@ SRC_S += \
|
||||
hw/mcu/st/startup/stm32f3/startup_stm32f303xc.s
|
||||
|
||||
INC += \
|
||||
-I$(TOP)/hw/bsp/stm32f303disc \
|
||||
-I$(TOP)/hw/mcu/st/cmsis \
|
||||
-I$(TOP)/hw/mcu/st/stm32lib/CMSIS/STM32F3xx/Include \
|
||||
-I$(TOP)/hw/mcu/st/stm32lib/STM32F3xx_HAL_Driver/Inc
|
||||
$(TOP)/hw/bsp/stm32f303disc \
|
||||
$(TOP)/hw/mcu/st/cmsis \
|
||||
$(TOP)/hw/mcu/st/stm32lib/CMSIS/STM32F3xx/Include \
|
||||
$(TOP)/hw/mcu/st/stm32lib/STM32F3xx_HAL_Driver/Inc
|
||||
|
||||
# For TinyUSB port source
|
||||
VENDOR = st
|
||||
CHIP_FAMILY = stm32f3
|
||||
|
||||
# For freeRTOS port source
|
||||
FREERTOS_PORT = ARM_CM4F
|
||||
|
||||
# For flash-jlink target
|
||||
JLINK_DEVICE = stm32f303vc
|
||||
JLINK_IF = swd
|
||||
|
||||
# Path to STM32 Cube Programmer CLI, should be added into system path
|
||||
STM32Prog = STM32_Programmer_CLI
|
||||
|
@ -21,13 +21,19 @@ SRC_S += \
|
||||
hw/mcu/st/startup/stm32f4/startup_stm32f407xx.s
|
||||
|
||||
INC += \
|
||||
-I$(TOP)/hw/mcu/st/stm32lib/CMSIS/STM32F4xx/Include \
|
||||
-I$(TOP)/hw/mcu/st/cmsis
|
||||
$(TOP)/hw/mcu/st/stm32lib/CMSIS/STM32F4xx/Include \
|
||||
$(TOP)/hw/mcu/st/cmsis
|
||||
|
||||
# For TinyUSB port source
|
||||
VENDOR = st
|
||||
CHIP_FAMILY = stm32f4
|
||||
|
||||
# For freeRTOS port source
|
||||
FREERTOS_PORT = ARM_CM4F
|
||||
|
||||
# For flash-jlink target
|
||||
JLINK_DEVICE = stm32f407vg
|
||||
JLINK_IF = swd
|
||||
|
||||
# Path to STM32 Cube Programmer CLI, should be added into system path
|
||||
STM32Prog = STM32_Programmer_CLI
|
||||
|
@ -69,7 +69,7 @@
|
||||
/* Hook function related definitions. */
|
||||
#define configUSE_IDLE_HOOK 0
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#define configUSE_MALLOC_FAILED_HOOK 1
|
||||
#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||
|
||||
/* Run time and task stats gathering related definitions. */
|
@ -1 +1 @@
|
||||
Subproject commit 6f54f689e9555ea18f9aca87caf44a3419e5dd7a
|
||||
Subproject commit 9d68726e41c321f1772c187bd12d82f5b13104f1
|
@ -71,7 +71,7 @@ typedef struct
|
||||
//--------------------------------------------------------------------+
|
||||
// INTERNAL OBJECT & FUNCTION DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
CFG_TUSB_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC] = { { 0 } };
|
||||
CFG_TUSB_MEM_SECTION static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC];
|
||||
|
||||
// TODO will be replaced by dcd_edpt_busy()
|
||||
bool pending_read_from_host;
|
||||
@ -289,14 +289,12 @@ bool cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t
|
||||
(TUSB_CLASS_CDC_DATA == ((tusb_desc_interface_t const *) p_desc)->bInterfaceClass) )
|
||||
{
|
||||
// next to endpoint descriptor
|
||||
(*p_length) += tu_desc_len(p_desc);
|
||||
p_desc = tu_desc_next(p_desc);
|
||||
|
||||
// Open endpoint pair with usbd helper
|
||||
tusb_desc_endpoint_t const *p_desc_ep = (tusb_desc_endpoint_t const *) p_desc;
|
||||
TU_ASSERT( usbd_open_edpt_pair(rhport, p_desc_ep, TUSB_XFER_BULK, &p_cdc->ep_out, &p_cdc->ep_in) );
|
||||
// Open endpoint pair
|
||||
TU_ASSERT( usbd_open_edpt_pair(rhport, p_desc, 2, TUSB_XFER_BULK, &p_cdc->ep_out, &p_cdc->ep_in) );
|
||||
|
||||
(*p_length) += 2*sizeof(tusb_desc_endpoint_t);
|
||||
(*p_length) += sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t);
|
||||
}
|
||||
|
||||
// Prepare for incoming data
|
||||
|
@ -89,9 +89,17 @@ static inline bool tud_cdc_write_flush (void)
|
||||
//--------------------------------------------------------------------+
|
||||
// APPLICATION CALLBACK API (WEAK is optional)
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Invoked when received new data
|
||||
ATTR_WEAK void tud_cdc_rx_cb(uint8_t itf);
|
||||
|
||||
// Invoked when received `wanted_char`
|
||||
ATTR_WEAK void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char);
|
||||
|
||||
// Invoked when line state DTR & RTS are changed via SET_CONTROL_LINE_STATE
|
||||
ATTR_WEAK void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts);
|
||||
|
||||
// Invoked when line coding is change via SET_LINE_CODING
|
||||
ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding);
|
||||
|
||||
/** @} */
|
||||
|
@ -43,6 +43,20 @@
|
||||
/** \defgroup ClassDriver_HID_Common Common Definitions
|
||||
* @{ */
|
||||
|
||||
/// USB HID Descriptor
|
||||
typedef struct ATTR_PACKED
|
||||
{
|
||||
uint8_t bLength; /**< Numeric expression that is the total size of the HID descriptor */
|
||||
uint8_t bDescriptorType; /**< Constant name specifying type of HID descriptor. */
|
||||
|
||||
uint16_t bcdHID; /**< Numeric expression identifying the HID Class Specification release */
|
||||
uint8_t bCountryCode; /**< Numeric expression identifying country code of the localized hardware. */
|
||||
uint8_t bNumDescriptors; /**< Numeric expression specifying the number of class descriptors */
|
||||
|
||||
uint8_t bReportType; /**< Type of HID class report. */
|
||||
uint16_t wReportLength; /**< the total size of the Report descriptor. */
|
||||
} tusb_hid_descriptor_hid_t;
|
||||
|
||||
/// HID Subclass
|
||||
typedef enum
|
||||
{
|
||||
@ -69,9 +83,10 @@ typedef enum
|
||||
/// HID Request Report Type
|
||||
typedef enum
|
||||
{
|
||||
HID_REPORT_TYPE_INPUT = 1, ///< Input
|
||||
HID_REPORT_TYPE_OUTPUT, ///< Output
|
||||
HID_REPORT_TYPE_FEATURE ///< Feature
|
||||
HID_REPORT_TYPE_INVALID = 0,
|
||||
HID_REPORT_TYPE_INPUT, ///< Input
|
||||
HID_REPORT_TYPE_OUTPUT, ///< Output
|
||||
HID_REPORT_TYPE_FEATURE ///< Feature
|
||||
}hid_report_type_t;
|
||||
|
||||
/// HID Class Specific Control Request
|
||||
@ -85,59 +100,45 @@ typedef enum
|
||||
HID_REQ_CONTROL_SET_PROTOCOL = 0x0b ///< Set Protocol
|
||||
}hid_request_type_t;
|
||||
|
||||
/// USB HID Descriptor
|
||||
typedef struct ATTR_PACKED
|
||||
{
|
||||
uint8_t bLength; /**< Numeric expression that is the total size of the HID descriptor */
|
||||
uint8_t bDescriptorType; /**< Constant name specifying type of HID descriptor. */
|
||||
|
||||
uint16_t bcdHID; /**< Numeric expression identifying the HID Class Specification release */
|
||||
uint8_t bCountryCode; /**< Numeric expression identifying country code of the localized hardware. */
|
||||
uint8_t bNumDescriptors; /**< Numeric expression specifying the number of class descriptors */
|
||||
|
||||
uint8_t bReportType; /**< Type of HID class report. */
|
||||
uint16_t wReportLength; /**< the total size of the Report descriptor. */
|
||||
} tusb_hid_descriptor_hid_t;
|
||||
|
||||
/// HID Country Code
|
||||
typedef enum
|
||||
{
|
||||
HID_Local_NotSupported = 0 , ///< NotSupported
|
||||
HID_Local_Arabic , ///< Arabic
|
||||
HID_Local_Belgian , ///< Belgian
|
||||
HID_Local_Canadian_Bilingual , ///< Canadian_Bilingual
|
||||
HID_Local_Canadian_French , ///< Canadian_French
|
||||
HID_Local_Czech_Republic , ///< Czech_Republic
|
||||
HID_Local_Danish , ///< Danish
|
||||
HID_Local_Finnish , ///< Finnish
|
||||
HID_Local_French , ///< French
|
||||
HID_Local_German , ///< German
|
||||
HID_Local_Greek , ///< Greek
|
||||
HID_Local_Hebrew , ///< Hebrew
|
||||
HID_Local_Hungary , ///< Hungary
|
||||
HID_Local_International , ///< International
|
||||
HID_Local_Italian , ///< Italian
|
||||
HID_Local_Japan_Katakana , ///< Japan_Katakana
|
||||
HID_Local_Korean , ///< Korean
|
||||
HID_Local_Latin_American , ///< Latin_American
|
||||
HID_Local_Netherlands_Dutch , ///< Netherlands/Dutch
|
||||
HID_Local_Norwegian , ///< Norwegian
|
||||
HID_Local_Persian_Farsi , ///< Persian (Farsi)
|
||||
HID_Local_Poland , ///< Poland
|
||||
HID_Local_Portuguese , ///< Portuguese
|
||||
HID_Local_Russia , ///< Russia
|
||||
HID_Local_Slovakia , ///< Slovakia
|
||||
HID_Local_Spanish , ///< Spanish
|
||||
HID_Local_Swedish , ///< Swedish
|
||||
HID_Local_Swiss_French , ///< Swiss/French
|
||||
HID_Local_Swiss_German , ///< Swiss/German
|
||||
HID_Local_Switzerland , ///< Switzerland
|
||||
HID_Local_Taiwan , ///< Taiwan
|
||||
HID_Local_Turkish_Q , ///< Turkish-Q
|
||||
HID_Local_UK , ///< UK
|
||||
HID_Local_US , ///< US
|
||||
HID_Local_Yugoslavia , ///< Yugoslavia
|
||||
HID_Local_Turkish_F ///< Turkish-F
|
||||
HID_LOCAL_NotSupported = 0 , ///< NotSupported
|
||||
HID_LOCAL_Arabic , ///< Arabic
|
||||
HID_LOCAL_Belgian , ///< Belgian
|
||||
HID_LOCAL_Canadian_Bilingual , ///< Canadian_Bilingual
|
||||
HID_LOCAL_Canadian_French , ///< Canadian_French
|
||||
HID_LOCAL_Czech_Republic , ///< Czech_Republic
|
||||
HID_LOCAL_Danish , ///< Danish
|
||||
HID_LOCAL_Finnish , ///< Finnish
|
||||
HID_LOCAL_French , ///< French
|
||||
HID_LOCAL_German , ///< German
|
||||
HID_LOCAL_Greek , ///< Greek
|
||||
HID_LOCAL_Hebrew , ///< Hebrew
|
||||
HID_LOCAL_Hungary , ///< Hungary
|
||||
HID_LOCAL_International , ///< International
|
||||
HID_LOCAL_Italian , ///< Italian
|
||||
HID_LOCAL_Japan_Katakana , ///< Japan_Katakana
|
||||
HID_LOCAL_Korean , ///< Korean
|
||||
HID_LOCAL_Latin_American , ///< Latin_American
|
||||
HID_LOCAL_Netherlands_Dutch , ///< Netherlands/Dutch
|
||||
HID_LOCAL_Norwegian , ///< Norwegian
|
||||
HID_LOCAL_Persian_Farsi , ///< Persian (Farsi)
|
||||
HID_LOCAL_Poland , ///< Poland
|
||||
HID_LOCAL_Portuguese , ///< Portuguese
|
||||
HID_LOCAL_Russia , ///< Russia
|
||||
HID_LOCAL_Slovakia , ///< Slovakia
|
||||
HID_LOCAL_Spanish , ///< Spanish
|
||||
HID_LOCAL_Swedish , ///< Swedish
|
||||
HID_LOCAL_Swiss_French , ///< Swiss/French
|
||||
HID_LOCAL_Swiss_German , ///< Swiss/German
|
||||
HID_LOCAL_Switzerland , ///< Switzerland
|
||||
HID_LOCAL_Taiwan , ///< Taiwan
|
||||
HID_LOCAL_Turkish_Q , ///< Turkish-Q
|
||||
HID_LOCAL_UK , ///< UK
|
||||
HID_LOCAL_US , ///< US
|
||||
HID_LOCAL_Yugoslavia , ///< Yugoslavia
|
||||
HID_LOCAL_Turkish_F ///< Turkish-F
|
||||
} hid_country_code_t;
|
||||
|
||||
/** @} */
|
||||
@ -155,7 +156,7 @@ typedef struct ATTR_PACKED
|
||||
int8_t x; /**< Current delta x movement of the mouse. */
|
||||
int8_t y; /**< Current delta y movement on the mouse. */
|
||||
int8_t wheel; /**< Current delta wheel movement on the mouse. */
|
||||
// int8_t pan;
|
||||
int8_t pan; // using AC Pan
|
||||
} hid_mouse_report_t;
|
||||
|
||||
/// Standard Mouse Buttons Bitmap
|
||||
@ -461,7 +462,7 @@ enum {
|
||||
HID_USAGE_PAGE_MSR = 0x8e,
|
||||
HID_USAGE_PAGE_CAMERA = 0x90,
|
||||
HID_USAGE_PAGE_ARCADE = 0x91,
|
||||
HID_USAGE_PAGE_VENDOR = 0xFFFF // 0xFF00 - 0xFFFF
|
||||
HID_USAGE_PAGE_VENDOR = 0xFF00 // 0xFF00 - 0xFFFF
|
||||
};
|
||||
|
||||
/// HID Usage Table - Table 6: Generic Desktop Page
|
||||
|
@ -38,24 +38,19 @@
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO CONSTANT TYPEDEF
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
#ifndef CFG_TUD_HID_BUFSIZE
|
||||
#define CFG_TUD_HID_BUFSIZE 16
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t itf_num;
|
||||
uint8_t ep_in;
|
||||
uint8_t ep_out; // optional Out endpoint
|
||||
uint8_t boot_protocol; // Boot mouse or keyboard
|
||||
bool boot_mode;
|
||||
|
||||
bool boot_mode; // default = false (Report)
|
||||
uint8_t idle_rate; // up to application to handle idle rate
|
||||
uint16_t reprot_desc_len;
|
||||
uint8_t idle_rate; // Idle Rate = 0 : only send report if there is changes, i.e skip duplication
|
||||
// Idle Rate > 0 : skip duplication, but send at least 1 report every idle rate (in unit of 4 ms).
|
||||
uint8_t mouse_button; // caching button for using with tud_hid_mouse_ API
|
||||
|
||||
CFG_TUSB_MEM_ALIGN uint8_t report_buf[CFG_TUD_HID_BUFSIZE];
|
||||
CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_HID_BUFSIZE];
|
||||
CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_HID_BUFSIZE];
|
||||
|
||||
}hidd_interface_t;
|
||||
|
||||
CFG_TUSB_MEM_SECTION static hidd_interface_t _hidd_itf[CFG_TUD_HID];
|
||||
@ -91,15 +86,15 @@ bool tud_hid_report(uint8_t report_id, void const* report, uint8_t len)
|
||||
// If report id = 0, skip ID field
|
||||
if (report_id)
|
||||
{
|
||||
p_hid->report_buf[0] = report_id;
|
||||
memcpy(p_hid->report_buf+1, report, len);
|
||||
p_hid->epin_buf[0] = report_id;
|
||||
memcpy(p_hid->epin_buf+1, report, len);
|
||||
len++;
|
||||
}else
|
||||
{
|
||||
memcpy(p_hid->report_buf, report, len);
|
||||
memcpy(p_hid->epin_buf, report, len);
|
||||
}
|
||||
|
||||
// TODO skip duplication ? and or idle rate
|
||||
return dcd_edpt_xfer(TUD_OPT_RHPORT, p_hid->ep_in, p_hid->report_buf, len + (report_id ? 1 : 0) );
|
||||
return dcd_edpt_xfer(TUD_OPT_RHPORT, p_hid->ep_in, p_hid->epin_buf, len);
|
||||
}
|
||||
|
||||
bool tud_hid_boot_mode(void)
|
||||
@ -125,47 +120,26 @@ bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycod
|
||||
tu_memclr(report.keycode, 6);
|
||||
}
|
||||
|
||||
// TODO skip duplication ? and or idle rate
|
||||
return tud_hid_report(report_id, &report, sizeof(report));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MOUSE APPLICATION API
|
||||
//--------------------------------------------------------------------+
|
||||
bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t scroll, int8_t pan)
|
||||
bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal)
|
||||
{
|
||||
(void) pan;
|
||||
hid_mouse_report_t report =
|
||||
{
|
||||
.buttons = buttons,
|
||||
.x = x,
|
||||
.y = y,
|
||||
.wheel = scroll,
|
||||
//.pan = pan
|
||||
.wheel = vertical,
|
||||
.pan = horizontal
|
||||
};
|
||||
|
||||
uint8_t itf = 0;
|
||||
_hidd_itf[itf].mouse_button = buttons;
|
||||
|
||||
return tud_hid_report(report_id, &report, sizeof(report));
|
||||
}
|
||||
|
||||
bool tud_hid_mouse_move(uint8_t report_id, int8_t x, int8_t y)
|
||||
{
|
||||
uint8_t itf = 0;
|
||||
uint8_t const button = _hidd_itf[itf].mouse_button;
|
||||
|
||||
return tud_hid_mouse_report(report_id, button, x, y, 0, 0);
|
||||
}
|
||||
|
||||
bool tud_hid_mouse_scroll(uint8_t report_id, int8_t scroll, int8_t pan)
|
||||
{
|
||||
uint8_t itf = 0;
|
||||
uint8_t const button = _hidd_itf[itf].mouse_button;
|
||||
|
||||
return tud_hid_mouse_report(report_id, button, 0, 0, scroll, pan);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// USBD-CLASS API
|
||||
//--------------------------------------------------------------------+
|
||||
@ -184,6 +158,10 @@ bool hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t
|
||||
{
|
||||
uint8_t const *p_desc = (uint8_t const *) desc_itf;
|
||||
|
||||
// TODO support multiple HID interface
|
||||
uint8_t const itf = 0;
|
||||
hidd_interface_t * p_hid = &_hidd_itf[itf];
|
||||
|
||||
//------------- HID descriptor -------------//
|
||||
p_desc = tu_desc_next(p_desc);
|
||||
tusb_hid_descriptor_hid_t const *desc_hid = (tusb_hid_descriptor_hid_t const *) p_desc;
|
||||
@ -191,24 +169,19 @@ bool hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t
|
||||
|
||||
//------------- Endpoint Descriptor -------------//
|
||||
p_desc = tu_desc_next(p_desc);
|
||||
tusb_desc_endpoint_t const *desc_edpt = (tusb_desc_endpoint_t const *) p_desc;
|
||||
TU_ASSERT(TUSB_DESC_ENDPOINT == desc_edpt->bDescriptorType);
|
||||
|
||||
TU_ASSERT(dcd_edpt_open(rhport, desc_edpt));
|
||||
|
||||
// TODO support multiple HID interface
|
||||
uint8_t itf = 0;
|
||||
hidd_interface_t * p_hid = &_hidd_itf[itf];
|
||||
TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, desc_itf->bNumEndpoints, TUSB_XFER_INTERRUPT, &p_hid->ep_out, &p_hid->ep_in));
|
||||
|
||||
if ( desc_itf->bInterfaceSubClass == HID_SUBCLASS_BOOT ) p_hid->boot_protocol = desc_itf->bInterfaceProtocol;
|
||||
|
||||
p_hid->boot_mode = false; // default mode is REPORT
|
||||
p_hid->itf_num = desc_itf->bInterfaceNumber;
|
||||
p_hid->ep_in = desc_edpt->bEndpointAddress;
|
||||
p_hid->reprot_desc_len = desc_hid->wReportLength;
|
||||
|
||||
*p_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t);
|
||||
|
||||
// Prepare for output endpoint
|
||||
if (p_hid->ep_out) TU_ASSERT(dcd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -245,20 +218,25 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque
|
||||
uint8_t const report_type = tu_u16_high(p_request->wValue);
|
||||
uint8_t const report_id = tu_u16_low(p_request->wValue);
|
||||
|
||||
uint16_t xferlen = tud_hid_get_report_cb(report_id, (hid_report_type_t) report_type, p_hid->report_buf, p_request->wLength);
|
||||
uint16_t xferlen = tud_hid_get_report_cb(report_id, (hid_report_type_t) report_type, p_hid->epin_buf, p_request->wLength);
|
||||
TU_ASSERT( xferlen > 0 );
|
||||
|
||||
usbd_control_xfer(rhport, p_request, p_hid->report_buf, xferlen);
|
||||
usbd_control_xfer(rhport, p_request, p_hid->epin_buf, xferlen);
|
||||
}
|
||||
break;
|
||||
|
||||
case HID_REQ_CONTROL_SET_REPORT:
|
||||
usbd_control_xfer(rhport, p_request, p_hid->report_buf, p_request->wLength);
|
||||
usbd_control_xfer(rhport, p_request, p_hid->epout_buf, p_request->wLength);
|
||||
break;
|
||||
|
||||
case HID_REQ_CONTROL_SET_IDLE:
|
||||
// TODO idle rate of report
|
||||
p_hid->idle_rate = tu_u16_high(p_request->wValue);
|
||||
if ( tud_hid_set_idle_cb )
|
||||
{
|
||||
// stall request if callback return false
|
||||
if ( !tud_hid_set_idle_cb(p_hid->idle_rate) ) return false;
|
||||
}
|
||||
|
||||
usbd_control_status(rhport, p_request);
|
||||
break;
|
||||
|
||||
@ -277,7 +255,7 @@ bool hidd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque
|
||||
case HID_REQ_CONTROL_SET_PROTOCOL:
|
||||
p_hid->boot_mode = 1 - p_request->wValue; // 0 is Boot, 1 is Report protocol
|
||||
|
||||
if (tud_hid_mode_changed_cb) tud_hid_mode_changed_cb(p_hid->boot_mode);
|
||||
if (tud_hid_boot_mode_cb) tud_hid_boot_mode_cb(p_hid->boot_mode);
|
||||
|
||||
usbd_control_status(rhport, p_request);
|
||||
break;
|
||||
@ -307,19 +285,25 @@ bool hidd_control_request_complete(uint8_t rhport, tusb_control_request_t const
|
||||
uint8_t const report_type = tu_u16_high(p_request->wValue);
|
||||
uint8_t const report_id = tu_u16_low(p_request->wValue);
|
||||
|
||||
tud_hid_set_report_cb(report_id, (hid_report_type_t) report_type, p_hid->report_buf, p_request->wLength);
|
||||
tud_hid_set_report_cb(report_id, (hid_report_type_t) report_type, p_hid->epout_buf, p_request->wLength);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes)
|
||||
bool hidd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
|
||||
{
|
||||
// nothing to do
|
||||
(void) rhport;
|
||||
(void) ep_addr;
|
||||
(void) event;
|
||||
(void) xferred_bytes;
|
||||
(void) result;
|
||||
|
||||
// TODO support multiple HID interface
|
||||
uint8_t const itf = 0;
|
||||
hidd_interface_t * p_hid = &_hidd_itf[itf];
|
||||
|
||||
if (ep_addr == p_hid->ep_out)
|
||||
{
|
||||
tud_hid_set_report_cb(0, HID_REPORT_TYPE_INVALID, p_hid->epout_buf, xferred_bytes);
|
||||
TU_ASSERT(dcd_edpt_xfer(rhport, p_hid->ep_out, p_hid->epout_buf, sizeof(p_hid->epout_buf)));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -39,6 +39,9 @@
|
||||
// Class Driver Default Configure & Validation
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
#ifndef CFG_TUD_HID_BUFSIZE
|
||||
#define CFG_TUD_HID_BUFSIZE 16
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Application API
|
||||
@ -53,51 +56,34 @@ bool tud_hid_boot_mode(void);
|
||||
// Send report to host
|
||||
bool tud_hid_report(uint8_t report_id, void const* report, uint8_t len);
|
||||
|
||||
/*------------- Callbacks (Weak is optional) -------------*/
|
||||
// KEYBOARD: convenient helper to send keyboard report if application
|
||||
// use template layout report as defined by hid_keyboard_report_t
|
||||
bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]);
|
||||
|
||||
// Invoked when receiving GET_REPORT control request
|
||||
// MOUSE: convenient helper to send mouse report if application
|
||||
// use template layout report as defined by hid_mouse_report_t
|
||||
bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal);
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Callbacks (Weak is optional)
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// 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);
|
||||
|
||||
// Invoked when receiving SET_REPORT control request
|
||||
// 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);
|
||||
|
||||
// Invoked when host switch mode Boot <-> Report via SET_PROTOCOL request
|
||||
void tud_hid_mode_changed_cb(uint8_t boot_mode) ATTR_WEAK;
|
||||
// Invoked when received SET_PROTOCOL request ( mode switch Boot <-> Report )
|
||||
ATTR_WEAK void tud_hid_boot_mode_cb(uint8_t boot_mode);
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// KEYBOARD API
|
||||
// Convenient helper to send keyboard report if application use standard/boot
|
||||
// layout report as defined by hid_keyboard_report_t
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]);
|
||||
|
||||
static inline bool tud_hid_keyboard_key_release(uint8_t report_id)
|
||||
{
|
||||
return tud_hid_keyboard_report(report_id, 0, NULL);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MOUSE API
|
||||
// Convenient helper to send mouse report if application use standard/boot
|
||||
// layout report as defined by hid_mouse_report_t
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t scroll, int8_t pan);
|
||||
bool tud_hid_mouse_move(uint8_t report_id, int8_t x, int8_t y);
|
||||
bool tud_hid_mouse_scroll(uint8_t report_id, int8_t scroll, int8_t pan);
|
||||
|
||||
static inline bool tud_hid_mouse_button_press(uint8_t report_id, uint8_t buttons)
|
||||
{
|
||||
return tud_hid_mouse_report(report_id, buttons, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
static inline bool tud_hid_mouse_button_release(uint8_t report_id)
|
||||
{
|
||||
return tud_hid_mouse_report(report_id, 0, 0, 0, 0, 0);
|
||||
}
|
||||
// Invoked when received SET_IDLE request. return false will stall the request
|
||||
// - Idle Rate = 0 : only send report if there is changes, i.e skip duplication
|
||||
// - Idle Rate > 0 : skip duplication, but send at least 1 report every idle rate (in unit of 4 ms).
|
||||
ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t idle_rate);
|
||||
|
||||
/* --------------------------------------------------------------------+
|
||||
* HID Report Descriptor Template
|
||||
@ -107,23 +93,24 @@ static inline bool tud_hid_mouse_button_release(uint8_t report_id)
|
||||
* empty if multiple reports is not used
|
||||
*
|
||||
* - Only 1 report: no parameter
|
||||
* uint8_t const report_desc[] = { HID_REPORT_DESC_KEYBOARD() };
|
||||
* uint8_t const report_desc[] = { TUD_HID_REPORT_DESC_KEYBOARD() };
|
||||
*
|
||||
* - Multiple Reports: "HID_REPORT_ID(ID)," must be passed to template
|
||||
* uint8_t const report_desc[] =
|
||||
* {
|
||||
* HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(1), ) ,
|
||||
* HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(2), )
|
||||
* TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(1), ) ,
|
||||
* TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(2), )
|
||||
* };
|
||||
*--------------------------------------------------------------------*/
|
||||
|
||||
// Keyboard Report Descriptor Template
|
||||
#define HID_REPORT_DESC_KEYBOARD(...) \
|
||||
#define TUD_HID_REPORT_DESC_KEYBOARD(...) \
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_KEYBOARD ) ,\
|
||||
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
|
||||
/* 8 bits Modifier Keys (Shfit, Control, Alt) */ \
|
||||
/* Report ID if any */\
|
||||
__VA_ARGS__ \
|
||||
/* 8 bits Modifier Keys (Shfit, Control, Alt) */ \
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_KEYBOARD ) ,\
|
||||
HID_USAGE_MIN ( 224 ) ,\
|
||||
HID_USAGE_MAX ( 231 ) ,\
|
||||
@ -159,50 +146,60 @@ static inline bool tud_hid_mouse_button_release(uint8_t report_id)
|
||||
HID_COLLECTION_END \
|
||||
|
||||
// Mouse Report Descriptor Template
|
||||
#define HID_REPORT_DESC_MOUSE(...) \
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_MOUSE ) ,\
|
||||
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
|
||||
#define TUD_HID_REPORT_DESC_MOUSE(...) \
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_MOUSE ) ,\
|
||||
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
|
||||
/* Report ID if any */\
|
||||
__VA_ARGS__ \
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_POINTER ) ,\
|
||||
HID_COLLECTION ( HID_COLLECTION_PHYSICAL ) ,\
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\
|
||||
HID_USAGE_MIN ( 1 ) ,\
|
||||
HID_USAGE_MAX ( 3 ) ,\
|
||||
HID_LOGICAL_MIN ( 0 ) ,\
|
||||
HID_LOGICAL_MAX ( 1 ) ,\
|
||||
/* Left, Right, Middle, Backward, Forward mouse buttons */ \
|
||||
HID_REPORT_COUNT ( 3 ) ,\
|
||||
HID_REPORT_SIZE ( 1 ) ,\
|
||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_POINTER ) ,\
|
||||
HID_COLLECTION ( HID_COLLECTION_PHYSICAL ) ,\
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\
|
||||
HID_USAGE_MIN ( 1 ) ,\
|
||||
HID_USAGE_MAX ( 5 ) ,\
|
||||
HID_LOGICAL_MIN ( 0 ) ,\
|
||||
HID_LOGICAL_MAX ( 1 ) ,\
|
||||
/* Left, Right, Middle, Backward, Forward buttons */ \
|
||||
HID_REPORT_COUNT( 5 ) ,\
|
||||
HID_REPORT_SIZE ( 1 ) ,\
|
||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
|
||||
/* 3 bit padding */ \
|
||||
HID_REPORT_COUNT ( 1 ) ,\
|
||||
HID_REPORT_SIZE ( 5 ) ,\
|
||||
HID_INPUT ( HID_CONSTANT ) ,\
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
||||
HID_REPORT_COUNT( 1 ) ,\
|
||||
HID_REPORT_SIZE ( 3 ) ,\
|
||||
HID_INPUT ( HID_CONSTANT ) ,\
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
||||
/* X, Y position [-127, 127] */ \
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\
|
||||
HID_LOGICAL_MIN ( 0x81 ) ,\
|
||||
HID_LOGICAL_MAX ( 0x7f ) ,\
|
||||
HID_REPORT_COUNT ( 2 ) ,\
|
||||
HID_REPORT_SIZE ( 8 ) ,\
|
||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ) ,\
|
||||
/* Mouse scroll [-127, 127] */ \
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\
|
||||
HID_LOGICAL_MIN ( 0x81 ) ,\
|
||||
HID_LOGICAL_MAX ( 0x7f ) ,\
|
||||
HID_REPORT_COUNT( 2 ) ,\
|
||||
HID_REPORT_SIZE ( 8 ) ,\
|
||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ) ,\
|
||||
/* Verital wheel scroll [-127, 127] */ \
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_WHEEL ) ,\
|
||||
HID_LOGICAL_MIN ( 0x81 ) ,\
|
||||
HID_LOGICAL_MAX ( 0x7f ) ,\
|
||||
HID_REPORT_COUNT( 1 ) ,\
|
||||
HID_REPORT_SIZE ( 8 ) ,\
|
||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ) ,\
|
||||
HID_COLLECTION_END ,\
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ), \
|
||||
/* Horizontal wheel scroll [-127, 127] */ \
|
||||
HID_USAGE_N ( HID_USAGE_CONSUMER_AC_PAN, 2 ), \
|
||||
HID_LOGICAL_MIN ( 0x81 ), \
|
||||
HID_LOGICAL_MAX ( 0x7f ), \
|
||||
HID_REPORT_COUNT( 1 ), \
|
||||
HID_REPORT_SIZE ( 8 ), \
|
||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ), \
|
||||
HID_COLLECTION_END , \
|
||||
HID_COLLECTION_END \
|
||||
|
||||
// Consumer Control Report Descriptor Template
|
||||
#define HID_REPORT_DESC_CONSUMER(...) \
|
||||
#define TUD_HID_REPORT_DESC_CONSUMER(...) \
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ) ,\
|
||||
HID_USAGE ( HID_USAGE_CONSUMER_CONTROL ) ,\
|
||||
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
|
||||
/* Report ID if any */\
|
||||
__VA_ARGS__ \
|
||||
HID_LOGICAL_MIN ( 0x00 ) ,\
|
||||
HID_LOGICAL_MAX_N( 0x03FF, 2 ) ,\
|
||||
@ -219,10 +216,11 @@ static inline bool tud_hid_mouse_button_release(uint8_t report_id)
|
||||
* 0x02 - Standby
|
||||
* 0x04 - Wake Host
|
||||
*/
|
||||
#define HID_REPORT_DESC_SYSTEM_CONTROL(...) \
|
||||
#define TUD_HID_REPORT_DESC_SYSTEM_CONTROL(...) \
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_CONTROL ) ,\
|
||||
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
|
||||
/* Report ID if any */\
|
||||
__VA_ARGS__ \
|
||||
/* 2 bit system power control */ \
|
||||
HID_LOGICAL_MIN ( 1 ) ,\
|
||||
@ -242,10 +240,11 @@ static inline bool tud_hid_mouse_button_release(uint8_t report_id)
|
||||
// Gamepad Report Descriptor Template
|
||||
// with 16 buttons and 2 joysticks with following layout
|
||||
// | Button Map (2 bytes) | X | Y | Z | Rz
|
||||
#define HID_REPORT_DESC_GAMEPAD(...) \
|
||||
#define TUD_HID_REPORT_DESC_GAMEPAD(...) \
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
|
||||
HID_USAGE ( HID_USAGE_DESKTOP_GAMEPAD ) ,\
|
||||
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
|
||||
/* Report ID if any */\
|
||||
__VA_ARGS__ \
|
||||
/* 16 bit Button Map */ \
|
||||
HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\
|
||||
@ -269,6 +268,31 @@ static inline bool tud_hid_mouse_button_release(uint8_t report_id)
|
||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
|
||||
HID_COLLECTION_END \
|
||||
|
||||
// HID Generic Input & Output
|
||||
// - 1st parameter is report size (mandatory)
|
||||
// - 2nd parameter is report id HID_REPORT_ID(n) (optional)
|
||||
#define TUD_HID_REPORT_DESC_GENERIC_INOUT(report_size, ...) \
|
||||
HID_USAGE_PAGE_N ( HID_USAGE_PAGE_VENDOR, 2 ),\
|
||||
HID_USAGE ( 0x01 ),\
|
||||
HID_COLLECTION ( HID_COLLECTION_APPLICATION ),\
|
||||
/* Report ID if any */\
|
||||
__VA_ARGS__ \
|
||||
/* Input */ \
|
||||
HID_USAGE ( 0x02 ),\
|
||||
HID_LOGICAL_MIN ( 0x00 ),\
|
||||
HID_LOGICAL_MAX ( 0xff ),\
|
||||
HID_REPORT_SIZE ( 8 ),\
|
||||
HID_REPORT_COUNT( report_size ),\
|
||||
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\
|
||||
/* Output */ \
|
||||
HID_USAGE ( 0x03 ),\
|
||||
HID_LOGICAL_MIN ( 0x00 ),\
|
||||
HID_LOGICAL_MAX ( 0xff ),\
|
||||
HID_REPORT_SIZE ( 8 ),\
|
||||
HID_REPORT_COUNT( report_size ),\
|
||||
HID_OUTPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\
|
||||
HID_COLLECTION_END \
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
* ASCII to KEYCODE Conversion
|
||||
* Expand to array of [128][2] (shift, keycode)
|
||||
|
@ -42,13 +42,9 @@ enum
|
||||
MSC_STAGE_STATUS
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
CFG_TUSB_MEM_ALIGN msc_cbw_t cbw;
|
||||
|
||||
//#if defined (__ICCARM__) && (CFG_TUSB_MCU == OPT_MCU_LPC11UXX || CFG_TUSB_MCU == OPT_MCU_LPC13XX)
|
||||
// uint8_t padding1[64-sizeof(msc_cbw_t)]; // IAR cannot align struct's member
|
||||
//#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CFG_TUSB_MEM_ALIGN msc_cbw_t cbw;
|
||||
CFG_TUSB_MEM_ALIGN msc_csw_t csw;
|
||||
|
||||
uint8_t itf_num;
|
||||
@ -66,7 +62,7 @@ typedef struct {
|
||||
uint8_t add_sense_qualifier;
|
||||
}mscd_interface_t;
|
||||
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static mscd_interface_t _mscd_itf = { 0 };
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static mscd_interface_t _mscd_itf;
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN static uint8_t _mscd_buf[CFG_TUD_MSC_BUFSIZE];
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
@ -135,9 +131,8 @@ bool mscd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t
|
||||
|
||||
mscd_interface_t * p_msc = &_mscd_itf;
|
||||
|
||||
// Open endpoint pair with usbd helper
|
||||
tusb_desc_endpoint_t const *p_desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next( itf_desc );
|
||||
TU_ASSERT( usbd_open_edpt_pair(rhport, p_desc_ep, TUSB_XFER_BULK, &p_msc->ep_out, &p_msc->ep_in) );
|
||||
// Open endpoint pair
|
||||
TU_ASSERT( usbd_open_edpt_pair(rhport, tu_desc_next(itf_desc), 2, TUSB_XFER_BULK, &p_msc->ep_out, &p_msc->ep_in) );
|
||||
|
||||
p_msc->itf_num = itf_desc->bInterfaceNumber;
|
||||
(*p_len) = sizeof(tusb_desc_interface_t) + 2*sizeof(tusb_desc_endpoint_t);
|
||||
@ -163,9 +158,12 @@ bool mscd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque
|
||||
|
||||
case MSC_REQ_GET_MAX_LUN:
|
||||
{
|
||||
uint8_t maxlun = 1;
|
||||
if (tud_msc_maxlun_cb) maxlun = tud_msc_maxlun_cb();
|
||||
TU_VERIFY(maxlun);
|
||||
|
||||
// MAX LUN is minus 1 by specs
|
||||
uint8_t maxlun = 0;
|
||||
if (tud_msc_maxlun_cb) maxlun = tud_msc_maxlun_cb() -1;
|
||||
maxlun--;
|
||||
|
||||
usbd_control_xfer(rhport, p_request, &maxlun, 1);
|
||||
}
|
||||
|
@ -64,10 +64,11 @@ TU_VERIFY_STATIC(CFG_TUD_MSC_BUFSIZE < UINT16_MAX, "Size is not correct");
|
||||
bool tud_msc_set_sense(uint8_t lun, uint8_t sense_key, uint8_t add_sense_code, uint8_t add_sense_qualifier);
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// APPLICATION CALLBACK (WEAK is optional)
|
||||
// Application Callbacks (WEAK is optional)
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
* Callback invoked when received \ref SCSI_CMD_READ_10 command
|
||||
* Invoked when received \ref SCSI_CMD_READ_10 command
|
||||
* \param[in] lun Logical unit number
|
||||
* \param[in] lba Logical Block Address to be read
|
||||
* \param[in] offset Byte offset from LBA
|
||||
@ -86,7 +87,7 @@ bool tud_msc_set_sense(uint8_t lun, uint8_t sense_key, uint8_t add_sense_code, u
|
||||
int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize);
|
||||
|
||||
/**
|
||||
* Callback invoked when received \ref SCSI_CMD_WRITE_10 command
|
||||
* Invoked when received \ref SCSI_CMD_WRITE_10 command
|
||||
* \param[in] lun Logical unit number
|
||||
* \param[in] lba Logical Block Address to be write
|
||||
* \param[in] offset Byte offset from LBA
|
||||
@ -104,7 +105,8 @@ int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buf
|
||||
*/
|
||||
int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize);
|
||||
|
||||
// Invoked to determine the disk size
|
||||
// Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size
|
||||
// Application update block count and block size
|
||||
void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size);
|
||||
|
||||
/**
|
||||
@ -128,13 +130,13 @@ int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer,
|
||||
|
||||
/*------------- Optional callbacks -------------*/
|
||||
|
||||
// Invoked to determine max LUN
|
||||
// Invoked when received GET_MAX_LUN request
|
||||
ATTR_WEAK uint8_t tud_msc_maxlun_cb(void);
|
||||
|
||||
// Invoked when Read10 command is complete
|
||||
ATTR_WEAK void tud_msc_read10_complete_cb(uint8_t lun);
|
||||
|
||||
// Invoke when Write10 command is complete
|
||||
// Invoke when Write10 command is complete, can be used to flush flash caching
|
||||
ATTR_WEAK void tud_msc_write10_complete_cb(uint8_t lun);
|
||||
|
||||
// Invoked when command in tud_msc_scsi_cb is complete
|
||||
|
@ -169,7 +169,7 @@ enum {
|
||||
|
||||
#define TUSB_DESC_CONFIG_POWER_MA(x) ((x)/2)
|
||||
|
||||
/// Device State
|
||||
/// Device State TODO remove
|
||||
typedef enum
|
||||
{
|
||||
TUSB_DEVICE_STATE_UNPLUG = 0 ,
|
||||
@ -184,7 +184,7 @@ typedef enum
|
||||
XFER_RESULT_STALLED,
|
||||
}xfer_result_t;
|
||||
|
||||
enum
|
||||
enum // TODO remove
|
||||
{
|
||||
DESC_OFFSET_LEN = 0,
|
||||
DESC_OFFSET_TYPE = 1
|
||||
|
@ -702,25 +702,25 @@ void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_
|
||||
// Helper
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Helper to parse an pair of endpoint descriptors (IN & OUT)
|
||||
bool usbd_open_edpt_pair(uint8_t rhport, tusb_desc_endpoint_t const* ep_desc, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in)
|
||||
// Parse consecutive endpoint descriptors (IN & OUT)
|
||||
bool usbd_open_edpt_pair(uint8_t rhport, uint8_t const* p_desc, uint8_t ep_count, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in)
|
||||
{
|
||||
for(int i=0; i<2; i++)
|
||||
for(int i=0; i<ep_count; i++)
|
||||
{
|
||||
TU_ASSERT(TUSB_DESC_ENDPOINT == ep_desc->bDescriptorType &&
|
||||
xfer_type == ep_desc->bmAttributes.xfer );
|
||||
tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc;
|
||||
|
||||
TU_ASSERT(dcd_edpt_open(rhport, ep_desc));
|
||||
TU_VERIFY(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType && xfer_type == desc_ep->bmAttributes.xfer);
|
||||
TU_ASSERT(dcd_edpt_open(rhport, desc_ep));
|
||||
|
||||
if ( tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN )
|
||||
if ( tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN )
|
||||
{
|
||||
(*ep_in) = ep_desc->bEndpointAddress;
|
||||
(*ep_in) = desc_ep->bEndpointAddress;
|
||||
}else
|
||||
{
|
||||
(*ep_out) = ep_desc->bEndpointAddress;
|
||||
(*ep_out) = desc_ep->bEndpointAddress;
|
||||
}
|
||||
|
||||
ep_desc = (tusb_desc_endpoint_t const *) tu_desc_next(ep_desc);
|
||||
p_desc = tu_desc_next(p_desc);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -107,7 +107,7 @@ ATTR_WEAK void tud_resume_cb(void);
|
||||
#define TUD_CDC_DESC_LEN (8+9+5+5+4+5+7+9+7+7)
|
||||
|
||||
// CDC Descriptor Template
|
||||
// interface number, string index, EP notification address and size, EP data address (out,in) and size.
|
||||
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
||||
#define TUD_CDC_DESCRIPTOR(_itfnum, _stridx, _ep_notif, _ep_notif_size, _epout, _epin, _epsize) \
|
||||
/* Interface Associate */\
|
||||
8, TUSB_DESC_INTERFACE_ASSOCIATION, _itfnum, 2, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, CDC_COMM_PROTOCOL_ATCOMMAND, 0,\
|
||||
@ -149,15 +149,31 @@ ATTR_WEAK void tud_resume_cb(void);
|
||||
// Length of template descriptor: 25 bytes
|
||||
#define TUD_HID_DESC_LEN (9 + 9 + 7)
|
||||
|
||||
// HID Input only descriptor
|
||||
// Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval
|
||||
#define TUD_HID_DESCRIPTOR(_itfnum, _stridx, _boot_protocol, _report_desc_len, _epin, _epsize, _ep_interval) \
|
||||
/* Interface */\
|
||||
9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUSB_CLASS_HID, (_boot_protocol) ? HID_SUBCLASS_BOOT : 0, _boot_protocol, _stridx,\
|
||||
/* HID descriptor */\
|
||||
9, HID_DESC_TYPE_HID, U16_TO_U8S_LE(0x0111), 0, 1, HID_DESC_TYPE_REPORT, U16_TO_U8S_LE(_report_desc_len),\
|
||||
/* Endpoint descriptor */\
|
||||
/* Endpoint In */\
|
||||
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), _ep_interval
|
||||
|
||||
// Length of template descriptor: 32 bytes
|
||||
#define TUD_HID_INOUT_DESC_LEN (9 + 9 + 7 + 7)
|
||||
|
||||
// HID Input & Output descriptor
|
||||
// Interface number, string index, protocol, report descriptor len, EP In & Out address, size & polling interval
|
||||
#define TUD_HID_INOUT_DESCRIPTOR(_itfnum, _stridx, _boot_protocol, _report_desc_len, _epin, _epout, _epsize, _ep_interval) \
|
||||
/* Interface */\
|
||||
9, TUSB_DESC_INTERFACE, _itfnum, 0, 2, TUSB_CLASS_HID, (_boot_protocol) ? HID_SUBCLASS_BOOT : 0, _boot_protocol, _stridx,\
|
||||
/* HID descriptor */\
|
||||
9, HID_DESC_TYPE_HID, U16_TO_U8S_LE(0x0111), 0, 1, HID_DESC_TYPE_REPORT, U16_TO_U8S_LE(_report_desc_len),\
|
||||
/* Endpoint In */\
|
||||
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), _ep_interval,\
|
||||
/* Endpoint Out */\
|
||||
7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), _ep_interval
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -53,9 +53,8 @@ bool usbd_edpt_stalled(uint8_t rhport, uint8_t ep_addr);
|
||||
/*------------------------------------------------------------------*/
|
||||
/* Helper
|
||||
*------------------------------------------------------------------*/
|
||||
// helper to parse an pair of In and Out endpoint descriptors. They must be consecutive
|
||||
bool usbd_open_edpt_pair(uint8_t rhport, tusb_desc_endpoint_t const* p_desc_ep, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in);
|
||||
|
||||
bool usbd_open_edpt_pair(uint8_t rhport, uint8_t const* p_desc, uint8_t ep_count, uint8_t xfer_type, uint8_t* ep_out, uint8_t* ep_in);
|
||||
void usbd_defer_func( osal_task_func_t func, void* param, bool in_isr );
|
||||
|
||||
|
||||
|
@ -47,56 +47,49 @@ enum
|
||||
|
||||
typedef void (*osal_task_func_t)( void * );
|
||||
|
||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||
#include "osal_none.h"
|
||||
#elif CFG_TUSB_OS == OPT_OS_FREERTOS
|
||||
#include "osal_freertos.h"
|
||||
#elif CFG_TUSB_OS == OPT_OS_MYNEWT
|
||||
#include "osal_mynewt.h"
|
||||
#else
|
||||
#error OS is not supported yet
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// OSAL Porting API
|
||||
//--------------------------------------------------------------------+
|
||||
#if 0
|
||||
void osal_task_delay(uint32_t msec);
|
||||
static inline void osal_task_delay(uint32_t msec);
|
||||
|
||||
//------------- Semaphore -------------//
|
||||
osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef);
|
||||
bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr);
|
||||
bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec);
|
||||
static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef);
|
||||
static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr);
|
||||
static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec);
|
||||
|
||||
void osal_semaphore_reset(osal_semaphore_t sem_hdl); // TODO removed
|
||||
static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl); // TODO removed
|
||||
|
||||
//------------- Mutex -------------//
|
||||
osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef);
|
||||
bool osal_mutex_lock (osal_mutex_t sem_hdl, uint32_t msec);
|
||||
bool osal_mutex_unlock(osal_mutex_t mutex_hdl);
|
||||
static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef);
|
||||
static inline bool osal_mutex_lock (osal_mutex_t sem_hdl, uint32_t msec);
|
||||
static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl);
|
||||
|
||||
//------------- Queue -------------//
|
||||
osal_queue_t osal_queue_create(osal_queue_def_t* qdef);
|
||||
bool osal_queue_receive(osal_queue_t const qhdl, void* data);
|
||||
bool osal_queue_send(osal_queue_t const qhdl, void const * data, bool in_isr);
|
||||
#endif
|
||||
static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef);
|
||||
static inline bool osal_queue_receive(osal_queue_t const qhdl, void* data);
|
||||
static inline bool osal_queue_send(osal_queue_t const qhdl, void const * data, bool in_isr);
|
||||
|
||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||
#include "osal_none.h"
|
||||
#else
|
||||
#if CFG_TUSB_OS == OPT_OS_FREERTOS
|
||||
#include "osal_freertos.h"
|
||||
#elif CFG_TUSB_OS == OPT_OS_MYNEWT
|
||||
#include "osal_mynewt.h"
|
||||
#else
|
||||
#error CFG_TUSB_OS is not defined or OS is not supported yet
|
||||
#endif
|
||||
#if 0 // TODO remove subtask related macros later
|
||||
// Sub Task
|
||||
#define OSAL_SUBTASK_BEGIN
|
||||
#define OSAL_SUBTASK_END return TUSB_ERROR_NONE;
|
||||
|
||||
// TODO remove subtask related macros later
|
||||
#define STASK_RETURN(_error) return _error;
|
||||
#define STASK_INVOKE(_subtask, _status) (_status) = _subtask
|
||||
|
||||
//------------- Sub Task -------------//
|
||||
#define OSAL_SUBTASK_BEGIN
|
||||
#define OSAL_SUBTASK_END return TUSB_ERROR_NONE;
|
||||
|
||||
#define STASK_RETURN(_error) return _error;
|
||||
#define STASK_INVOKE(_subtask, _status) (_status) = _subtask
|
||||
|
||||
//------------- Sub Task Assert -------------//
|
||||
#define STASK_ASSERT_ERR(_err) TU_VERIFY_ERR(_err)
|
||||
#define STASK_ASSERT_ERR_HDLR(_err, _func) TU_VERIFY_ERR_HDLR(_err, _func)
|
||||
|
||||
#define STASK_ASSERT(_cond) TU_VERIFY(_cond, TUSB_ERROR_OSAL_TASK_FAILED)
|
||||
#define STASK_ASSERT_HDLR(_cond, _func) TU_VERIFY_HDLR(_cond, _func)
|
||||
// Sub Task Assert
|
||||
#define STASK_ASSERT_ERR(_err) TU_VERIFY_ERR(_err)
|
||||
#define STASK_ASSERT(_cond) TU_VERIFY(_cond, TUSB_ERROR_OSAL_TASK_FAILED)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -489,7 +489,7 @@ void USBD_IRQHandler(void)
|
||||
{
|
||||
xfer->total_len = xfer->actual_len;
|
||||
|
||||
// BULK/INT OUT complete
|
||||
// CBI OUT complete
|
||||
dcd_event_xfer_complete(0, epnum, xfer->actual_len, XFER_RESULT_SUCCESS, true);
|
||||
}
|
||||
}
|
||||
@ -524,7 +524,7 @@ void USBD_IRQHandler(void)
|
||||
xact_in_prepare(epnum);
|
||||
} else
|
||||
{
|
||||
// Bulk/Int IN complete
|
||||
// CBI IN complete
|
||||
dcd_event_xfer_complete(0, epnum | TUSB_DIR_IN_MASK, xfer->actual_len, XFER_RESULT_SUCCESS, true);
|
||||
}
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ const app_configuration_desc_t desc_configuration =
|
||||
.bLength = sizeof(tusb_hid_descriptor_hid_t),
|
||||
.bDescriptorType = HID_DESC_TYPE_HID,
|
||||
.bcdHID = 0x0111,
|
||||
.bCountryCode = HID_Local_NotSupported,
|
||||
.bCountryCode = HID_LOCAL_NotSupported,
|
||||
.bNumDescriptors = 1,
|
||||
.bReportType = HID_DESC_TYPE_REPORT,
|
||||
.wReportLength = sizeof(keyboard_report_descriptor)
|
||||
@ -201,7 +201,7 @@ const app_configuration_desc_t desc_configuration =
|
||||
.bLength = sizeof(tusb_hid_descriptor_hid_t),
|
||||
.bDescriptorType = HID_DESC_TYPE_HID,
|
||||
.bcdHID = 0x0111,
|
||||
.bCountryCode = HID_Local_NotSupported,
|
||||
.bCountryCode = HID_LOCAL_NotSupported,
|
||||
.bNumDescriptors = 1,
|
||||
.bReportType = HID_DESC_TYPE_REPORT,
|
||||
.wReportLength = sizeof(mouse_report_descriptor)
|
||||
|
@ -4,10 +4,53 @@ import sys
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
all_device_example = ["cdc_msc_hid", "msc_dual_lun"]
|
||||
all_boards = ["metro_m0_express", "metro_m4_express", "pca10056", "stm32f407g_disc1"]
|
||||
travis = False
|
||||
if "TRAVIS" in os.environ and os.environ["TRAVIS"] == "true":
|
||||
PARALLEL="-j 2"
|
||||
travis = True
|
||||
|
||||
success_count = 0
|
||||
fail_count = 0
|
||||
exit_status = 0
|
||||
|
||||
all_device_example = ["cdc_msc_hid", "msc_dual_lun", "hid_generic_inout"]
|
||||
all_boards = ["metro_m0_express", "metro_m4_express", "pca10056", "feather_nrf52840_express", "stm32f407g_disc1"]
|
||||
|
||||
def build_example(example, board):
|
||||
subprocess.run("make -C examples/device/{} BOARD={} clean".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
return subprocess.run("make -j 4 -C examples/device/{} BOARD={} all".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
|
||||
total_time = time.monotonic()
|
||||
|
||||
for example in all_device_example:
|
||||
for board in all_boards:
|
||||
subprocess.run("make -j2 -C examples/device/{} BOARD={} clean".format(example, board), shell=True)
|
||||
subprocess.run("make -j2 -C examples/device/{} BOARD={} all".format(example, board), shell=True)
|
||||
start_time = time.monotonic()
|
||||
build_result = build_example(example, board)
|
||||
build_duration = time.monotonic() - start_time
|
||||
|
||||
if build_result.returncode != 0:
|
||||
exit_status = build_result.returncode
|
||||
success = "\033[31mfailed\033[0m"
|
||||
fail_count += 1
|
||||
else:
|
||||
success = "\033[32msucceeded\033[0m"
|
||||
success_count += 1
|
||||
|
||||
if travis:
|
||||
print('travis_fold:start:build-{}-{}\\r'.format(example, board))
|
||||
print("Build {} on {} took {:.2f}s and {}".format(example, board, build_duration, success))
|
||||
if build_result.returncode != 0:
|
||||
print(build_result.stdout.decode("utf-8"))
|
||||
if travis:
|
||||
print('travis_fold:end:build-{}-{}\\r'.format(example, board))
|
||||
|
||||
# FreeRTOS example
|
||||
#example = 'cdc_msc_hid_freertos'
|
||||
#board = 'pca10056'
|
||||
#subprocess.run("make -j2 -C examples/device/{} BOARD={} clean all".format(example, board), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
|
||||
|
||||
total_time = time.monotonic() - total_time
|
||||
|
||||
print("Total build time took {:.2f}s".format(total_time))
|
||||
sys.exit(exit_status)
|
||||
|
Loading…
x
Reference in New Issue
Block a user