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

pkg/tinyusb: add nRF52 support

This commit is contained in:
Gunar Schorcht 2022-10-21 07:20:49 +02:00
parent f02113081b
commit e26d8523a4
7 changed files with 205 additions and 0 deletions

View File

@ -38,6 +38,8 @@ menuconfig PACKAGE_TINYUSB
select MODULE_TINYUSB_PORTABLE_MICROCHIP if CPU_FAM_SAMD21 || CPU_FAM_SAMR21 \
|| CPU_COMMON_SAMD5X || CPU_FAM_SAML21 || CPU_FAM_SAMR34 \
|| CPU_FAM_SAMR30
select MODULE_TINYUSB_PORTABLE_NRF5X if CPU_FAM_NRF52
select PACKAGE_NRFX if CPU_FAM_NRF52
select MODULE_ZTIMER_MSEC
help
tinyUSB is an open-source cross-platform USB Host/Device stack for
@ -101,6 +103,11 @@ config MODULE_TINYUSB_PORTABLE_MICROCHIP
help
tinyUSB Microchip SAM0 driver is used
config MODULE_TINYUSB_PORTABLE_NRF5X
bool
help
tinyUSB nRFx device driver is used
menu "Device Classes"
config MODULE_TINYUSB_CLASS_AUDIO
bool "Audio Class 2.0 (UAC2)"

View File

@ -74,6 +74,9 @@ tinyusb_portable_espressif:
tinyusb_portable_microchip:
$(QQ)"$(MAKE)" -C $(PSRC)/portable/microchip/samd -f $(RIOTBASE)/Makefile.base MODULE=$@
tinyusb_portable_nrf5x:
$(QQ)"$(MAKE)" -C $(PSRC)/portable/nordic/nrf5x -f $(RIOTPKG)/$(PKG_NAME)/Makefile.nrf52
tinyusb_portable_stm32_fsdev:
$(QQ)"$(MAKE)" -C $(PSRC)/portable/st/stm32_fsdev -f $(RIOTBASE)/Makefile.base MODULE=$@

View File

@ -54,6 +54,9 @@ endif
# tinyUSB hardware driver selection
ifneq (,$(filter esp32s2 esp32s3,$(CPU_FAM)))
USEMODULE += tinyusb_portable_espressif
else ifeq (nrf52,$(CPU))
USEPKG += nrfx
USEMODULE += tinyusb_portable_nrf5x
else ifneq (,$(filter saml21 samd5x samd21,$(CPU)))
USEMODULE += tinyusb_portable_microchip
else ifeq (stm32,$(CPU))

View File

@ -10,6 +10,13 @@ ifeq (esp32s2,$(CPU_FAM))
CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_ESP32S2
else ifeq (esp32s3,$(CPU_FAM))
CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_ESP32S3
else ifeq (nrf52,$(CPU))
CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_NRF5X
CFLAGS += -Wno-cast-align
CFLAGS += -Wno-unused-parameter
INCLUDES += -I$(PKGDIRBASE)/nrfx/hal
INCLUDES += -I$(PKGDIRBASE)/nrfx/drivers/include
INCLUDES += -I$(PKGDIRBASE)/nrfx/drivers/src
else ifeq (stm32,$(CPU))
CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_STM32$(call uppercase_and_underscore,$(CPU_FAM))
else ifeq (saml21,$(CPU))

View File

@ -0,0 +1,5 @@
MODULE = tinyusb_portable_nrf5x
INCLUDES := -I$(RIOTBASE)/pkg/tinyusb/hw/include/nrf52 $(INCLUDES)
include $(RIOTBASE)/Makefile.base

71
pkg/tinyusb/hw/hw_nrf52.c Normal file
View File

@ -0,0 +1,71 @@
/*
* 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
* @brief
* @{
*
* @brief tinyUSB hardware driver for nRF52 MCUs
* @author Gunar Schorcht <gunar@schorcht.net>
*/
#include <errno.h>
#include "periph_conf.h"
#include "periph/gpio.h"
#include "periph/pm.h"
#include "tusb.h"
#include "device/usbd.h"
#include "host/usbh.h"
/*
* Definition of events as used by the tinyusb/portable/nordic/nrf5x/dcd_nrf5x.c
* https://github.com/hathach/tinyusb/blob/0.14.0/src/portable/nordic/nrf5x/dcd_nrf5x.c#L954
*/
#define USB_EVT_DETECTED 0
#define USB_EVT_REMOVED 1
#define USB_EVT_READY 2
int tinyusb_hw_init(void)
{
if (IS_USED(MODULE_TINYUSB_DEVICE)) {
NVIC_SetPriority(USBD_IRQn, 2);
}
extern void tusb_hal_nrf_power_event(uint32_t event);
if ( NRF_POWER->USBREGSTATUS & POWER_USBREGSTATUS_VBUSDETECT_Msk ) {
tusb_hal_nrf_power_event(USB_EVT_DETECTED);
}
/* it requires some time to activate the clock */
ztimer_sleep(ZTIMER_MSEC, 1);
if ( NRF_POWER->USBREGSTATUS & POWER_USBREGSTATUS_OUTPUTRDY_Msk ) {
tusb_hal_nrf_power_event(USB_EVT_READY);
}
return 0;
}
void isr_usbd(void)
{
/* call device interrupt handler with the first device */
if (IS_USED(MODULE_TINYUSB_DEVICE)) {
tud_int_handler(0);
}
/* call host interrupt handler with the first device */
if (IS_USED(MODULE_TINYUSB_HOST)) {
tuh_int_handler(0);
}
cortexm_isr_end();
}

View File

@ -0,0 +1,109 @@
/*
* 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
* @brief
* @{
*
* @brief nRF52 specific clock definitions as required by tinyUSB
*
* RIOT does not use the clock module from `pkg/nrfx/drivers`. Therefore
* the part of the clock module interface needed by tinyUSB in
* `tinyusb/src/portable/nordic/dcd_nrf5x.c` has to be defined explicitly.
*
* @author Gunar Schorcht <gunar@schorcht.net>
*/
#ifndef NRF52_NRF_CLOCK_H
#define NRF52_NRF_CLOCK_H
#include <stdbool.h>
#include "nrf.h"
#include_next "nrf_clock.h"
#if !DOXYGEN
#ifdef __cplusplus
extern "C" {
#endif
#define NRF_CLOCK_HFCLK_HIGH_ACCURACY (1UL)
#define NRF_CLOCK_EVENT_HFCLKSTARTED offsetof(NRF_CLOCK_Type, EVENTS_HFCLKSTARTED)
typedef enum {
NRF_CLOCK_TASK_HFCLKSTART,
NRF_CLOCK_TASK_HFCLKSTOP,
} nrf_clock_task_t;
/**
* @brief Status HF clock acitvation/deactivation in `dcd_nrf52.c`
*
* The `clock_hfxo_request` and `clock_hfxo_release` functions are used in
* RIOT to enable/disable the HF clock if necessary. Since `hfclk_enable`
* in `tinyusb/src/portable/nordic/dcd_nrf5x.c` activates the RF clock only
* if it is not already running, the status of the RF clock cannot be
* determined via registers. It therefore needs its own static variable
* that holds the current state of activation/deactivation by the function
* `nrf_clock_task_trigger`.
*/
static bool _nrf_clock_hf_running = false;
/**
* @brief Check whether HF clock is running
*/
static inline bool nrf_clock_hf_is_running(NRF_CLOCK_Type const *reg,
uint32_t clk_src)
{
return _nrf_clock_hf_running;
}
/**
* @brief Clear a specific event
*
* This function is not required in RIOT, it is therefore defined as dummy
* function.
*/
static inline bool nrf_clock_event_clear(NRF_CLOCK_Type *reg, uint32_t event)
{
(void)reg;
(void)event;
return true;
}
/**
* @brief Function used in tinyUSB to start and stop the HF clock
*
* This function is mapped to `clock_hfxo_request`/`clock_hfxo_release` in RIOT.
*/
static inline void nrf_clock_task_trigger(NRF_CLOCK_Type *reg,
nrf_clock_task_t task)
{
switch (task) {
case NRF_CLOCK_TASK_HFCLKSTART:
clock_hfxo_request();
_nrf_clock_hf_running = true;
break;
case NRF_CLOCK_TASK_HFCLKSTOP:
clock_hfxo_release();
_nrf_clock_hf_running = false;
break;
default:
break;
}
}
#ifdef __cplusplus
}
#endif
#endif /* !DOXYGEN */
#endif /* NRF52_NRF_CLOCK_H */
/** @} */