1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

pkg: add tinyUSB device/host stack as package

This commit is contained in:
Gunar Schorcht 2022-09-14 09:03:56 +02:00
parent 3b7c1254d3
commit 136827e6da
18 changed files with 1131 additions and 0 deletions

View File

@ -27,3 +27,6 @@ FEATURES_CONFLICT_MSG += "Only one standard C library can be used"
FEATURES_CONFLICT += periph_gpio_irq:periph_gpio_ll_irq
FEATURES_CONFLICT_MSG += "Only one GPIO IRQ implementation can be used"
FEATURES_CONFLICT += periph_usbdev:tinyusb
FEATURES_CONFLICT_MSG += "Package tinyUSB is not yet compatible with periph/usdev"

View File

@ -137,6 +137,10 @@ ifneq (,$(filter periph_ptp_timer periph_ptp_speed_adjustment,$(FEATURES_USED)))
FEATURES_REQUIRED += periph_ptp
endif
ifneq (,$(filter periph_usbdev,$(USEMODULE)))
USEMODULE += periph_usbdev_clk
endif
ifneq (,$(filter pn532_i2c,$(USEMODULE)))
FEATURES_REQUIRED += periph_i2c
USEMODULE += pn532

View File

@ -161,12 +161,24 @@ config MODULE_PERIPH_USBDEV
bool "USBDEV peripheral driver"
depends on HAS_PERIPH_USBDEV
select MODULE_PERIPH_COMMON
select MODULE_PERIPH_USBDEV_CLK
config MODULE_PERIPH_INIT_USBDEV
bool "Auto initialize USBDEV peripheral"
default y if MODULE_PERIPH_INIT
depends on MODULE_PERIPH_USBDEV
config MODULE_PERIPH_USBDEV_CLK
bool
depends on HAS_PERIPH_USBDEV
help
Enable the USB device specific clock settings, if there are any
config MODULE_PERIPH_INIT_USBDEV_CLK
bool
default y if MODULE_PERIPH_INIT && MODULE_PERIPH_USBDEV_CLK
depends on HAS_PERIPH_USBDEV
endif # TEST_KCONFIG
config HAVE_SHARED_PERIPH_RTT_PERIPH_RTC

View File

@ -67,6 +67,7 @@ rsource "tiny-asn1/Kconfig"
rsource "tinycbor/Kconfig"
rsource "tinycrypt/Kconfig"
rsource "tinydtls/Kconfig"
rsource "tinyusb/Kconfig"
rsource "tinyvcdiff/Kconfig"
rsource "tlsf/Kconfig"
rsource "tweetnacl/Kconfig"

138
pkg/tinyusb/Kconfig Normal file
View File

@ -0,0 +1,138 @@
# Copyright (c) 2021 HAW Hamburg
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
#
config HAS_TINYUSB_DEVICE
bool
help
Indicates that the hardware supports tinyUSB device stack
config HAS_TINYUSB_HOST
bool
help
Indicates that the hardware supports tinyUSB host stack
menuconfig PACKAGE_TINYUSB
bool "TinyUSB stack package"
depends on HAS_ARCH_32BIT
depends on HAS_TINYUSB_DEVICE || HAS_TINYUSB_HOST
select MODULE_PERIPH_USBDEV_CLK
select MODULE_SEMA
select MODULE_TINYUSB_COMMON
select MODULE_TINYUSB_CONTRIB
select MODULE_TINYUSB_HW
select MODULE_TINYUSB_PORTABLE_ESPRESSIF if CPU_FAM_ESP32S2 || CPU_FAM_ESP32S3
select MODULE_TINYUSB_PORTABLE_SYNOPSYS_DWC2 if CPU_STM32 && CPU_FAM_F2
select MODULE_TINYUSB_PORTABLE_SYNOPSYS_DWC2 if CPU_STM32 && CPU_FAM_F4
select MODULE_TINYUSB_PORTABLE_SYNOPSYS_DWC2 if CPU_STM32 && CPU_FAM_F7
select MODULE_TINYUSB_PORTABLE_SYNOPSYS_DWC2 if CPU_STM32 && CPU_FAM_H7
select MODULE_TINYUSB_PORTABLE_SYNOPSYS_DWC2 if CPU_STM32 && CPU_FAM_L4
select MODULE_TINYUSB_PORTABLE_STM32_FSEDV if CPU_STM32 && CPU_FAM_F0
select MODULE_TINYUSB_PORTABLE_STM32_FSEDV if CPU_STM32 && CPU_FAM_F1
select MODULE_TINYUSB_PORTABLE_STM32_FSEDV if CPU_STM32 && CPU_FAM_G4
select MODULE_TINYUSB_PORTABLE_STM32_FSEDV if CPU_STM32 && CPU_FAM_L0
select MODULE_TINYUSB_PORTABLE_STM32_FSEDV if CPU_STM32 && CPU_FAM_WB
select MODULE_ZTIMER_MSEC
help
tinyUSB is an open-source cross-platform USB Host/Device stack for
embedded systems.
if PACKAGE_TINYUSB
config MODULE_TINYUSB_COMMON
bool
help
Common tinyUSB files
config MODULE_TINYUSB_CONTRIB
bool
help
RIOT support for tinyUSB
config MODULE_TINYUSB_HW
bool
help
tinyUSB hardware driver implementation
config MODULE_TINYUSB_DEVICE
bool "Device Stack"
depends on HAS_TINYUSB_DEVICE
help
Select to enable tinyUSB device stack
config MODULE_TINYUSB_HOST
bool "Host Stack"
depends on HAS_TINYUSB_HOST
help
Select to enable tinyUSB host stack
config MODULE_TINYUSB_PORTABLE_ESPRESSIF
bool
help
tinyUSB driver for ESP32Sx is used
config MODULE_TINYUSB_PORTABLE_SYNOPSYS_DWC2
bool
help
tinyUSB Sysnopsys DCW2 driver is used
config MODULE_TINYUSB_PORTABLE_STM32_FSDEV
bool
help
tinyUSB STM32 FS device driver is used
menu "Device Classes"
config MODULE_TINYUSB_CLASS_AUDIO
bool "Audio Class 2.0 (UAC2)"
depends on MODULE_TINYUSB_DEVICE
config MODULE_TINYUSB_CLASS_BTH
bool "Bluetooth Host Controller Interface (BTH HCI)"
depends on MODULE_TINYUSB_DEVICE
config MODULE_TINYUSB_CLASS_CDC
bool "Communication Device Class (CDC)"
config MODULE_TINYUSB_CLASS_DFU
bool "Device Firmware Update (DFU) Runtime"
depends on MODULE_TINYUSB_DEVICE
config MODULE_TINYUSB_CLASS_DFU_RUNTIME
bool "Device Firmware Update (DFU)"
depends on MODULE_TINYUSB_DEVICE
config MODULE_TINYUSB_CLASS_HID
bool "Human Interface Device (HID)"
config MODULE_TINYUSB_CLASS_MSC
bool "Mass Storage Class (MSC)"
config MODULE_TINYUSB_CLASS_MIDI
bool "Musical Instrument Digital Interface (MIDI)"
depends on MODULE_TINYUSB_DEVICE
config MODULE_TINYUSB_CLASS_NET_ECM_RNDIS
bool "Network with RNDIS, Ethernet Control Model (ECM)"
depends on MODULE_TINYUSB_DEVICE
config MODULE_TINYUSB_CLASS_NET_NCM
bool "Network with Network Control Model (NCM)"
depends on MODULE_TINYUSB_DEVICE
config MODULE_TINYUSB_CLASS_USBTMC
bool "Test and Measurement Class (USBTMC)"
depends on MODULE_TINYUSB_DEVICE
config MODULE_TINYUSB_CLASS_VENDOR
bool "Vendor-specific class support with generic IN & OUT endpoints"
config MODULE_TINYUSB_CLASS_VIDEO
bool "Video class 1.5 (UVC)"
depends on MODULE_TINYUSB_DEVICE
endmenu
endif # PACKAGE_TINYUSB

69
pkg/tinyusb/Makefile Normal file
View File

@ -0,0 +1,69 @@
PKG_NAME=tinyusb
PKG_URL=https://github.com/hathach/tinyusb
# TinyUSB 0.14.0
PKG_VERSION=9e91b02ec7fb3502747b5c413a4824654fa7fc7e
PKG_LICENSE=MIT
include $(RIOTBASE)/pkg/pkg.mk
PSRC = $(PKG_SOURCE_DIR)/src
.PHONY: all
all: $(filter tinyusb_%,$(USEMODULE))
$(QQ)"$(MAKE)" -C $(PSRC) -f $(RIOTBASE)/Makefile.base MODULE=tinyusb
tinyusb_contrib:
$(QQ)"$(MAKE)" -C $(RIOTPKG)/$(PKG_NAME)/contrib
tinyusb_hw:
$(QQ)"$(MAKE)" -C $(RIOTPKG)/$(PKG_NAME)/hw
tinyusb_class_audio:
$(QQ)"$(MAKE)" -C $(PSRC)/class/audio -f $(RIOTBASE)/Makefile.base MODULE=$@
tinyusb_class_bth:
$(QQ)"$(MAKE)" -C $(PSRC)/class/bth -f $(RIOTBASE)/Makefile.base MODULE=$@
tinyusb_class_cdc:
$(QQ)"$(MAKE)" -C $(PSRC)/class/cdc -f $(RIOTBASE)/Makefile.base MODULE=$@
tinyusb_class_dfu:
$(QQ)"$(MAKE)" -C $(PSRC)/class/dfu -f $(RIOTBASE)/Makefile.base MODULE=$@
tinyusb_class_dfu_runtime:
$(QQ)"$(MAKE)" -C $(PSRC)/class/dfu -f $(RIOTBASE)/Makefile.base MODULE=$@
tinyusb_class_hid:
$(QQ)"$(MAKE)" -C $(PSRC)/class/hid -f $(RIOTBASE)/Makefile.base MODULE=$@
tinyusb_class_midi:
$(QQ)"$(MAKE)" -C $(PSRC)/class/midi -f $(RIOTBASE)/Makefile.base MODULE=$@
tinyusb_class_msc:
$(QQ)"$(MAKE)" -C $(PSRC)/class/msc -f $(RIOTBASE)/Makefile.base MODULE=$@
tinyusb_class_net_ecm_rndis:
$(QQ)"$(MAKE)" -C $(PSRC)/class/net -f $(RIOTBASE)/Makefile.base MODULE=$@
tinyusb_class_net_ncm:
$(QQ)"$(MAKE)" -C $(PSRC)/class/net -f $(RIOTBASE)/Makefile.base MODULE=$@
tinyusb_class_usbtmc:
$(QQ)"$(MAKE)" -C $(PSRC)/class/usbtmc -f $(RIOTBASE)/Makefile.base MODULE=$@
tinyusb_class_vendor:
$(QQ)"$(MAKE)" -C $(PSRC)/class/vendor -f $(RIOTBASE)/Makefile.base MODULE=$@
tinyusb_class_video:
$(QQ)"$(MAKE)" -C $(PSRC)/class/video -f $(RIOTBASE)/Makefile.base MODULE=$@
tinyusb_common:
$(QQ)"$(MAKE)" -C $(PSRC)/common -f $(RIOTBASE)/Makefile.base MODULE=$@
tinyusb_device:
$(QQ)"$(MAKE)" -C $(PSRC)/device -f $(RIOTBASE)/Makefile.base MODULE=$@
tinyusb_host:
$(QQ)"$(MAKE)" -C $(PSRC)/host -f $(RIOTBASE)/Makefile.base MODULE=$@

61
pkg/tinyusb/Makefile.dep Normal file
View File

@ -0,0 +1,61 @@
# Package tinyUSB has its own USB device driver. Therefore, it cannot be used
# together with periph/usbdev for now.
ifneq (,$(filter periph_usbdev,$(USEMODULE)))
$(error "Package tinyUSB is not yet compatible with periph/usdev")
endif
# tinyUSB muteces use priority inheritance
# USEMODULE += core_mutex_priority_inheritance
# tinyUSB modules always needed
USEMODULE += tinyusb_common
USEMODULE += tinyusb_contrib
USEMODULE += tinyusb_hw
ifeq (,$(filter tinyusb_class_%,$(USEMODULE)))
$(error At least one tinyusb_class_* module has to be enabled)
endif
# tinyUSB device stack has to be supported if tinyusb_device is used
ifneq (,$(filter tinyusb_device,$(USEMODULE)))
FEATURES_REQUIRED += tinyusb_device
endif
# tinyUSB host stack has to be supported if tinyusb_host is used
ifneq (,$(filter tinyusb_host,$(USEMODULE)))
FEATURES_REQUIRED += tinyusb_host
endif
# Following device classes work only with tinyUSB device stack
ifneq (,$(filter tinyusb_class_audio,$(USEMODULE)))
FEATURES_REQUIRED += tinyusb_device
endif
ifneq (,$(filter tinyusb_class_bth,$(USEMODULE)))
FEATURES_REQUIRED += tinyusb_device
endif
ifneq (,$(filter tinyusb_class_dfu,$(USEMODULE)))
FEATURES_REQUIRED += tinyusb_device
endif
ifneq (,$(filter tinyusb_class_dfu_runtime,$(USEMODULE)))
FEATURES_REQUIRED += tinyusb_device
endif
ifneq (,$(filter tinyusb_class_midi,$(USEMODULE)))
FEATURES_REQUIRED += tinyusb_device
endif
ifneq (,$(filter tinyusb_class_net_ecm_rndis,$(USEMODULE)))
FEATURES_REQUIRED += tinyusb_device
endif
ifneq (,$(filter tinyusb_class_net_ncm,$(USEMODULE)))
FEATURES_REQUIRED += tinyusb_device
endif
ifneq (,$(filter tinyusb_class_usbtmc,$(USEMODULE)))
FEATURES_REQUIRED += tinyusb_device
endif
ifneq (,$(filter tinyusb_class_video,$(USEMODULE)))
FEATURES_REQUIRED += tinyusb_device
endif
# other module dependencies
USEMODULE += periph_usbdev_clk
USEMODULE += sema
USEMODULE += ztimer_msec

View File

@ -0,0 +1,11 @@
INCLUDES += -I$(RIOTBASE)/pkg/tinyusb/contrib
INCLUDES += -I$(RIOTBASE)/pkg/tinyusb/contrib/include
INCLUDES += -I$(RIOTBASE)/pkg/tinyusb/hw/include
INCLUDES += -I$(PKGDIRBASE)/tinyusb/src
CFLAGS += -DCFG_TUSB_OS=OPT_OS_CUSTOM
CFLAGS += -Wno-format-nonliteral
ifneq (,$(filter tinyusb_class_net_ecm_rndis,$(USEMODULE)))
INCLUDES += -I$(PKGDIRBASE)/tinyusb/lib/networking
endif

View File

@ -0,0 +1,3 @@
MODULE = tinyusb_contrib
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,62 @@
/*
* Copyright (C) 2022 Gunar Schorcht
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup pkg_tinyusb
* @{
*
* @file
* @brief TinyUSB API
*
* @author Gunar Schorcht <gunar@schorcht.net>
*/
#ifndef TINYUSB_H
#define TINYUSB_H
#include "periph_conf.h"
#ifndef TINYUSB_THREAD_STACKSIZE_MAIN
/** Stack size used for the tinyUSB thread */
#define TINYUSB_THREAD_STACKSIZE (THREAD_STACKSIZE_DEFAULT)
#endif
#ifndef TINYUSB_PRIORITY
/** Priority used for the tinyUSB thread */
#define TINYUSB_PRIORITY (2)
#endif
#ifndef TINYUSB_TUD_RHPORT
/** tinyUSB RHPort number used for device, default value is 0 */
#define TINYUSB_TUD_RHPORT 0
#endif
#ifndef TINYUSB_TUH_RHPORT
/** tinyUSB RHPort number used for host, defaults value is 0 */
#define TINYUSB_TUH_RHPORT 0
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initialize the tinyUSB stack including used peripherals and start the tinyUSB thread
*
* @return 0 on success
* @return -ENODEV if peripherals couldn't be initialized
* @return -EINVAL or -EOVERFLOW if the thread couldn't be created
*/
int tinyusb_setup(void);
#ifdef __cplusplus
}
#endif
#endif /* TINYUSB_H */
/** @} */

View File

@ -0,0 +1,306 @@
/*
* Copyright (C) 2019 Ha Thach (tinyusb.org)
* 2022 Gunar Schorcht
*
* 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.
*/
/**
* @ingroup pkg_tinyusb
* @{
*
* @file
* @brief TinyUSB default configurations
*
* @author Gunar Schorcht <gunar@schorcht.net>
*/
#ifndef TINYUSB_CONFIG_H
#define TINYUSB_CONFIG_H
#include "tusb_config.h" /* defined by the application */
#include "tinyusb.h"
#if !DOXYGEN
/**
* @name Common tinyUSB configurations
* @{
*/
/** Sanity check, the MCU must be defined */
#ifndef CFG_TUSB_MCU
#error CFG_TUSB_MCU must be defined
#endif
/** RIOT provides the custom OS API */
#define CFG_TUSB_OS OPT_OS_CUSTOM
/** Debug log level */
#ifndef CFG_TUSB_DEBUG
#define CFG_TUSB_DEBUG 0
#endif
/**
* @brief DMA memory section and alignment
*
* USB DMA on some MCUs can only access a specific SRAM region with restriction
* on alignment.
* - 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 __attribute__ ((aligned(4)))
#endif
/** @} */
/**
* @name Common device configurations
* @{
*/
#define CFG_TUD_ENABLED MODULE_TINYUSB_DEVICE
#ifndef CFG_TUD_MAX_SPEED
#define CFG_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED
#endif
#ifndef CFG_TUD_ENDPOINT0_SIZE
#define CFG_TUD_ENDPOINT0_SIZE 64
#endif
#ifndef CFG_TUD_AUDIO
#if defined(MODULE_TINYUSB_DEVICE) && defined(MODULE_TINYUSB_CLASS_AUDIO)
#define CFG_TUD_AUDIO 1
#else
#define CFG_TUD_AUDIO 0
#endif
#endif
#ifndef CFG_TUD_BTH
#if defined(MODULE_TINYUSB_DEVICE) && defined(MODULE_TINYUSB_CLASS_BTH)
#define CFG_TUD_BTH 1
#else
#define CFG_TUD_BTH 0
#endif
#endif /* CFG_TUD_BTH */
#ifndef CFG_TUD_CDC
#if defined(MODULE_TINYUSB_DEVICE) && defined(MODULE_TINYUSB_CLASS_CDC)
#define CFG_TUD_CDC 1
#else
#define CFG_TUD_CDC 0
#endif
#endif /* CFG_TUD_CDC */
#ifndef CFG_TUD_DFU
#if defined(MODULE_TINYUSB_DEVICE) && defined(MODULE_TINYUSB_CLASS_DFU)
#define CFG_TUD_DFU 1
#else
#define CFG_TUD_DFU 0
#endif
#endif /* CFG_TUD_DFU */
#ifndef CFG_TUD_DFU_RUNTIME
#if defined(MODULE_TINYUSB_DEVICE) && defined(MODULE_TINYUSB_CLASS_DFU_RUNTIME)
#define CFG_TUD_DFU_RUNTIME 1
#else
#define CFG_TUD_DFU_RUNTIME 0
#endif
#endif /* CFG_TUD_DFU */
#ifndef CFG_TUD_HID
#if defined(MODULE_TINYUSB_DEVICE) && defined(MODULE_TINYUSB_CLASS_HID)
#define CFG_TUD_HID 1
#else
#define CFG_TUD_HID 0
#endif
#endif /* CFG_TUD_HID */
#ifndef CFG_TUD_MIDI
#if defined(MODULE_TINYUSB_DEVICE) && defined(MODULE_TINYUSB_CLASS_MIDI)
#define CFG_TUD_MIDI 1
#else
#define CFG_TUD_MIDI 0
#endif
#endif /* CFG_TUD_MIDI */
#ifndef CFG_TUD_MSC
#if defined(MODULE_TINYUSB_DEVICE) && defined(MODULE_TINYUSB_CLASS_MSC)
#define CFG_TUD_MSC 1
#else
#define CFG_TUD_MSC 0
#endif
#endif /* CFG_TUD_MSC */
#ifndef CFG_TUD_ECM_RNDIS
#if defined(MODULE_TINYUSB_DEVICE) && defined(MODULE_TINYUSB_CLASS_NET_ECM_RNDIS)
#define CFG_TUD_ECM_RNDIS 1
#else
#define CFG_TUD_ECM_RNDIS 0
#endif
#endif /* CFG_TUD_ECM_RNDIS */
#ifndef CFG_TUD_NCM
#if defined(MODULE_TINYUSB_DEVICE) && defined(MODULE_TINYUSB_CLASS_NET_NCM)
#define CFG_TUD_NCM 1
#else
#define CFG_TUD_NCM 0
#endif
#endif /* CFG_TUD_NCM */
#ifndef CFG_TUD_USBMTC
#if defined(MODULE_TINYUSB_DEVICE) && defined(MODULE_TINYUSB_CLASS_USBMTC)
#define CFG_TUD_USBMTC 1
#else
#define CFG_TUD_USBMTC 0
#endif
#endif /* CFG_TUD_USBMTC */
#ifndef CFG_TUD_VENDOR
#if defined(MODULE_TINYUSB_DEVICE) && defined(MODULE_TINYUSB_CLASS_VENDOR)
#define CFG_TUD_VENDOR 1
#else
#define CFG_TUD_VENDOR 0
#endif
#endif /* CFG_TUD_VENDOR */
#ifndef CFG_TUD_VIDEO
#if defined(MODULE_TINYUSB_DEVICE) && defined(MODULE_TINYUSB_CLASS_VIDEO)
#define CFG_TUD_VIDEO 1
#else
#define CFG_TUD_VIDEO 0
#endif
#endif /* CFG_TUD_VIDEO */
/** @} */
/**
* @name Common host configurations
* @{
*/
#define CFG_TUH_ENABLED MODULE_TINYUSB_HOST
#ifndef CFG_TUH_MAX_SPEED
#define CFG_TUH_MAX_SPEED OPT_MODE_DEFAULT_SPEED
#endif
#ifndef CFG_TUH_ENUMERATION_BUFSIZE
#define CFG_TUH_ENUMERATION_BUFSIZE 256
#endif
/** Hub typically has 4 ports */
#ifndef CFG_TUH_DEVICE_MAX
#define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1)
#endif
#ifndef CFG_TUH_CDC
#if defined(MODULE_TINYUSB_HOST) && defined(MODULE_TINYUSB_CLASS_CDC)
#define CFG_TUH_CDC 1
#else
#define CFG_TUH_CDC 0
#endif
#endif /* CFG_TUH_CDC */
#ifndef CFG_TUH_HID
#if defined(MODULE_TINYUSB_HOST) && defined(MODULE_TINYUSB_CLASS_HID)
#define CFG_TUH_HID 1
#else
#define CFG_TUH_HID 0
#endif
#endif /* CFG_TUH_HID */
#ifndef CFG_TUH_MSC
#if defined(MODULE_TINYUSB_HOST) && defined(MODULE_TINYUSB_CLASS_MSC)
#define CFG_TUH_MSC 1
#else
#define CFG_TUH_MSC 0
#endif
#endif /* CFG_TUH_MSC */
#ifndef CFG_TUD_VENDOR
#if defined(MODULE_TINYUSB_HOST) && defined(MODULE_TINYUSB_CLASS_VENDOR)
#define CFG_TUH_VENDOR 1
#else
#define CFG_TUH_VENDOR 0
#endif
#endif /* CFG_TUD_VENDOR */
/** @} */
/**
* @name Typical required CDC device class configurations
* @{
*/
/** CDC RX FIFO size */
#ifndef CFG_TUD_CDC_RX_BUFSIZE
#define CFG_TUD_CDC_RX_BUFSIZE CFG_TUD_CDC_EP_BUFSIZE
#endif
/** CDC RX FIFO size */
#ifndef CFG_TUD_CDC_TX_BUFSIZE
#define CFG_TUD_CDC_TX_BUFSIZE CFG_TUD_CDC_EP_BUFSIZE
#endif
/** @} */
/**
* @name Typical required DFU device class configurations
* @{
*/
#ifndef CFG_TUD_DFU_XFER_BUFSIZE
#define CFG_TUD_DFU_XFER_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
#endif
/** @} */
/**
* @name Typical required MIDI device class configurations
* @{
*/
#ifndef CFG_TUD_MIDI_RX_BUFSIZE
#define CFG_TUD_MIDI_RX_BUFSIZE CFG_TUD_MIDI_EP_BUFSIZE
#endif
#ifndef CFG_TUD_MIDI_TX_BUFSIZE
#define CFG_TUD_MIDI_TX_BUFSIZE CFG_TUD_MIDI_EP_BUFSIZE
#endif
/** @} */
/**
* @name Typical required MSC device class configurations
* @{
*/
#ifndef CFG_TUD_MSC_EP_BUFSIZE
#define CFG_TUD_MSC_EP_BUFSIZE 512
#endif
/** @} */
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* !DOXYGEN */
#endif /* TINYUSB_CONFIG_H */
/** @} */

View File

@ -0,0 +1,255 @@
/*
* Copyright (C) 2022 Gunar Schorcht
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup pkg_tinyusb
* @{
*
* @file
* @brief TinyUSB OS Abstraction Layer for RIOT
*
* @author Gunar Schorcht <gunar@schorcht.net>
*/
#ifndef TUSB_OS_CUSTOM_H
#define TUSB_OS_CUSTOM_H
#include "mutex.h"
#include "sema.h"
#include "ztimer.h"
#ifdef __cplusplus
extern "C" {
#endif
#if !DOXYGEN
/* set to 1 to use cancelable mutex in osal_mutex and osal_queue */
#ifndef TINYUSB_OSAL_MUTEX_CANCELABLE
#define TINYUSB_OSAL_MUTEX_CANCELABLE 0
#endif
/**
* Task API
*/
TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec)
{
ztimer_sleep(ZTIMER_MSEC, msec);
}
/**
* Semaphore API
*
* This API is only used by RNDIS-CDC.
*/
typedef sema_t osal_semaphore_def_t; /* semaphore */
typedef sema_t *osal_semaphore_t; /* semaphore handle */
TU_ATTR_ALWAYS_INLINE
static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef)
{
sema_create(semdef, 0);
return (osal_semaphore_t)semdef;
}
TU_ATTR_ALWAYS_INLINE
static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
{
(void)in_isr; /* hasn't to be considered since RIOT doesn't block in sema_post */
return sema_post(sem_hdl) == 0;
}
TU_ATTR_ALWAYS_INLINE
static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec)
{
assert(0);
return sema_wait_timed_ztimer(sem_hdl, ZTIMER_MSEC, msec) == 0;
}
TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl)
{
(void)sem_hdl;
/* TODO, function seems to be removed anyway */
}
/** Mutex API (priority inheritance) */
typedef mutex_t osal_mutex_def_t; /* RIOT mutex */
typedef mutex_t *osal_mutex_t; /* RIOT mutex handle */
TU_ATTR_ALWAYS_INLINE
static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
{
assert(mdef != NULL);
mutex_init((mutex_t *)mdef);
return (osal_mutex_t)mdef;
}
#if TINYUSB_OSAL_MUTEX_CANCELABLE
static void _osal_mutex_lock_timeout(void *arg)
{
mutex_cancel(arg);
}
#endif
TU_ATTR_ALWAYS_INLINE
static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec)
{
assert(mutex_hdl);
#if TINYUSB_OSAL_MUTEX_CANCELABLE
mutex_cancel_t _mc = mutex_cancel_init(mutex_hdl);
ztimer_t _timer = { .callback = _osal_mutex_lock_timeout, .arg = &_mc };
ztimer_set(ZTIMER_MSEC, &_timer, msec);
return mutex_lock_cancelable(&_mc) == 0;
#else
assert(msec == OSAL_TIMEOUT_WAIT_FOREVER);
mutex_lock(mutex_hdl);
return true;
#endif
}
TU_ATTR_ALWAYS_INLINE
static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
{
assert(mutex_hdl);
mutex_unlock(mutex_hdl);
return true;
}
/**
* Queue API
*/
#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \
/* _int_set is not used in RTOS */ \
static _type _name##_##q_items[_depth]; /* queue item data storage */ \
osal_queue_def_t _name = { \
.buffer = _name##_##q_items, \
.size = sizeof(_type), \
.depth = _depth, \
};
typedef struct {
list_node_t node;
void *data;
} osal_queue_entry;
typedef struct {
void *buffer; /* buffer used for queue item data */
uint16_t size; /* queue item size */
uint16_t depth; /* maximum number of queue items */
uint16_t front;
uint16_t tail;
sema_t smphr; /* semaphore value represents the queue fill level */
} osal_queue_def_t;
typedef osal_queue_def_t *osal_queue_t;
TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
{
assert(qdef != NULL);
qdef->front = 0;
qdef->tail = 0;
sema_create(&qdef->smphr, 0);
return (osal_queue_t)qdef;
}
TU_ATTR_ALWAYS_INLINE
static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr)
{
assert(qhdl != NULL);
assert(data != NULL);
if (sema_get_value(&qhdl->smphr) == qhdl->depth) {
/* queue is full */
if (in_isr) {
/* return in case of ISR */
return false;
}
/* We do not block the sending thread when `osal_queue_send` is called
* from a thread context and the queue is full. The call of function
* `osal_queue_send` is usually interrupt-driven and must not block
* anyway. There is only one exception in `src/class/msc/msc_device.c`
* where it is called in thread context. However, since the call of
* `osal_queue_send` would then be made in the same thread context as
* the call of the unlocking function `osal_queue_receive`, using a
* mutex to block the sending thread would not work here anyway.
* Therefore, we return with false in all cases when `NDEBUG` is
* defined, as most other implementations of `osal_queue_send` do,
* or point out the problem with assertion. */
#ifdef NDEBUG
return false;
#else
assert(0);
#endif
}
/* copy the data to the queue item data */
memcpy(qhdl->buffer + (qhdl->tail * (qhdl->size)), data, qhdl->size);
/* update write pointer */
qhdl->tail = (qhdl->tail + 1) % qhdl->depth;
/* unlock a possibly waiting receiving thread */
sema_post(&qhdl->smphr);
return true;
}
#if TINYUSB_OSAL_MUTEX_CANCELABLE
static void _osal_queue_lock_timeout(void *arg)
{
mutex_cancel(arg);
}
#endif
TU_ATTR_ALWAYS_INLINE
static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec)
{
assert(qhdl != NULL);
assert(data != NULL);
(void)msec;
/* In RIOT we use only `tusd_task` and `tush_task` functions which call
* `osal_queue_receive` with `OSAL_TIMEOUT_WAIT_FOREVER` (`UINT32_MAX`).
* Therefore we do not use `msec` and just call `sema_wait` without timeout
* handling here. */
if (sema_wait(&qhdl->smphr) != 0) {
/* timeout error or any other semaphore error on receiving */
return false;
}
/* at least one item should be in the queue now */
assert(qhdl->front != qhdl->tail);
/* copy data from queue item data */
memcpy(data, qhdl->buffer + (qhdl->front * (qhdl->size)), qhdl->size);
/* update read pointer */
qhdl->front = (qhdl->front + 1) % qhdl->depth;
return true;
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl)
{
assert(qhdl != NULL);
return sema_get_value(&qhdl->smphr) == 0;
}
#ifdef __cplusplus
}
#endif
#endif /* !DOXYGEN */
#endif /* TUSB_OS_CUSTOM_H */
/** @} */

View File

@ -0,0 +1,81 @@
/*
* Copyright (C) 2022 Gunar Schorcht
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
#include "kernel_defines.h"
#include "thread.h"
#include "tusb.h"
#include "device/usbd.h"
#include "host/usbh.h"
#include "tinyusb.h"
#include "tinyusb_hw.h"
#define ENABLE_DEBUG 0
#include "debug.h"
static void *_tinyusb_thread_impl(void *arg)
{
(void)arg;
if (IS_USED(MODULE_TINYUSB_DEVICE)) {
if (!tud_init(TINYUSB_TUD_RHPORT)) {
DEBUG("tinyUSB device stack couldn't be initialized\n");
assert(0);
}
DEBUG("tinyUSB device stack initialized\n");
}
if (IS_USED(MODULE_TINYUSB_HOST)) {
if (!tuh_init(TINYUSB_TUH_RHPORT)) {
DEBUG("tinyUSB host stack couldn't be initialized\n");
assert(0);
}
DEBUG("tinyUSB host stack initialized\n");
}
while (1) {
if (IS_USED(MODULE_TINYUSB_DEVICE)) {
/* call tinyUSB device task blocking */
tud_task();
DEBUG("tinyUSB device task executed\n");
}
if (IS_USED(MODULE_TINYUSB_HOST)) {
/* call tinyUSB device task blocking */
tuh_task();
DEBUG("tinyUSB host task executed\n");
}
}
return NULL;
}
static char _tinyusb_thread_stack[TINYUSB_THREAD_STACKSIZE];
int tinyusb_setup(void)
{
int res;
if ((res = tinyusb_hw_init()) != 0) {
DEBUG("tinyUSB peripherals couldn't be initialized\n");
return res;
}
DEBUG("tinyUSB peripherals initialized\n");
if ((res = thread_create(_tinyusb_thread_stack,
sizeof(_tinyusb_thread_stack),
TINYUSB_PRIORITY,
THREAD_CREATE_WOUT_YIELD | THREAD_CREATE_STACKTEST,
_tinyusb_thread_impl, NULL, "tinyusb")) < 0) {
DEBUG("tinyUSB thread couldn't be created, reason %d\n", res);
return res;
}
DEBUG("tinyUSB thread created\n");
return 0;
}

79
pkg/tinyusb/doc.txt Normal file
View File

@ -0,0 +1,79 @@
/**
* @defgroup pkg_tinyusb TinyUSB package
* @ingroup pkg
* @brief Provides the tinyUSB stack as package
* @author Gunar Schorcht <gunar@schorcht.net>
* @see https://github.com/hathach/tinyusb
*
* # TinyUSB
*
* tinyUSB is an open-source cross-platform USB Host/Device stack for
* embedded systems.
*
* # Usage
*
* Add the following entries to your application makefile:
* - Enable tinyUSB package
* ```makefile
* USEPKG += tinyusb
* ```
* - Select whether to use the tinyUSB device stack or the tinyUSB host stack or both:
* ```makefile
* USEMODULE += tinyusb_device
* ```
* - Select the device/host classes to be used, for example:
* ```makefile
* USEMODULE += tinyusb_class_cdc tinyusb_class_msc
* ```
*
* Add `tinyusb_setup()` to your main function to initialize the tinyUSB stack
* including used peripherals and to start the tinyUSB thread.
* ```c
* int main(void)
* {
* ...
* // initialize the tinyUSB stack including used peripherals and
* // start the tinyUSB thread
* tinyusb_setup();
*
* while (1) {
* ...
* }
*
* return 0;
* }
* ```
*
* Create a file `tusb_config.h` in your application directory which includes
* at least the file `tinyusb_config.h` from the tinyUSB package. This file is
* required by the tinyUSB stack and can be used to override the default
* configuration defined in `tinyusb_config.h`.
* ```c
* #define CFG_TUD_CDC 2
* #define CFG_TUD_CDC_EP_BUFSIZE 128
*
* #include "tinyusb_config.h"
* ```
*
* Add the application path to the include paths at the end of your
* application's Makefile. This is necessary so that the tinyUSB stack
* uses the file `tusb_config.h` from your application directory and thus the
* file `tinyusb_config.h` from the tinyUSB package.
* ```makefile
* USEPKG += tinyusb
* USEMODULE += tinyusb_class_cdc
* USEMODULE += tinyusb_class_msc
* USEMODULE += tinyusb_device
*
* include $(RIOTBASE)/Makefile.include
*
* INCLUDES += -I$(APPDIR)
* ```
*
* Implement required device descriptors and descriptor callbacks as well as
* the callbacks of the enabled classes.
*
* Please refer `$RIOTBASE/tests/pkg_tinyusb_cdc_msc` and the
* [tinyUSB documentation](https://docs.tinyusb.org/en/latest/reference/getting_started.html)
* for details.
*/

5
pkg/tinyusb/hw/Makefile Normal file
View File

@ -0,0 +1,5 @@
MODULE = tinyusb_hw
SRC = hw_$(CPU).c
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,41 @@
/*
* Copyright (C) 2022 Gunar Schorcht
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup pkg_tinyusb
* @{
*
* @file
* @brief TinyUSB hardware driver API
*
* @author Gunar Schorcht <gunar@schorcht.net>
*/
#ifndef TINYUSB_HW_H
#define TINYUSB_HW_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Initialize the peripherals for tinyUSB.
*
* This functions is called by #tinyusb_setup to initialize the peripherals.
*
* @return 0 on success
* @return -ENODEV if peripherals couldn't be initialized
*/
int tinyusb_hw_init(void);
#ifdef __cplusplus
}
#endif
#endif /* TINYUSB_HW_H */
/** @} */