From bdc5e3d3bccebc78b05bcdadffa90f72b65644bb Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 7 Mar 2020 18:02:54 +0700 Subject: [PATCH] added feather sense and CLUE --- docs/boards.md | 5 +- hw/bsp/adafruit_clue/adafruit_clue.c | 192 +++++++++++++++++++++++ hw/bsp/adafruit_clue/board.mk | 63 ++++++++ hw/bsp/adafruit_clue/nrf52840_s140_v6.ld | 38 +++++ 4 files changed, 297 insertions(+), 1 deletion(-) create mode 100644 hw/bsp/adafruit_clue/adafruit_clue.c create mode 100644 hw/bsp/adafruit_clue/board.mk create mode 100755 hw/bsp/adafruit_clue/nrf52840_s140_v6.ld diff --git a/docs/boards.md b/docs/boards.md index cf5defb51..08342e0f0 100644 --- a/docs/boards.md +++ b/docs/boards.md @@ -19,8 +19,10 @@ This code base already had supported for a handful of following boards (sorted a ### Nordic nRF5x -- [Adafruit Feather nRF52840 Express](https://www.adafruit.com/product/4062) - [Adafruit Circuit Playground Bluefruit](https://www.adafruit.com/product/4333) +- [Adafruit CLUE](https://www.adafruit.com/product/4500) +- [Adafruit Feather nRF52840 Express](https://www.adafruit.com/product/4062) +- [Adafruit Feather nRF52840 Sense](https://www.adafruit.com/product/4516) - [Maker Diary nRF52840 MDK Dongle](https://wiki.makerdiary.com/nrf52840-mdk-usb-dongle) - [Nordic nRF52840 Development Kit (aka pca10056)](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) - [Nordic nRF52840 Dongle (aka pca10059)](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle) @@ -32,6 +34,7 @@ This code base already had supported for a handful of following boards (sorted a - [NuTiny NUC121S](https://direct.nuvoton.com/en/nutiny-nuc121s) - [NuTiny NUC125S](https://direct.nuvoton.com/en/nutiny-nuc125s) - [NuTiny NUC126V](https://direct.nuvoton.com/en/nutiny-nuc126v) +- [NuTiny SDK NUC505Y](https://direct.nuvoton.com/en/nutiny-nuc505y) ### NXP iMX RT diff --git a/hw/bsp/adafruit_clue/adafruit_clue.c b/hw/bsp/adafruit_clue/adafruit_clue.c new file mode 100644 index 000000000..67b5ffda4 --- /dev/null +++ b/hw/bsp/adafruit_clue/adafruit_clue.c @@ -0,0 +1,192 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * 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" + +#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, 1) +#define LED_STATE_ON 1 + +#define BUTTON_PIN _PINNUM(1, 02) + +// 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 + +#if TUSB_OPT_DEVICE_ENABLED + // 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); +#endif +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +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; +} + +#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 + +#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 diff --git a/hw/bsp/adafruit_clue/board.mk b/hw/bsp/adafruit_clue/board.mk new file mode 100644 index 000000000..3b2137d74 --- /dev/null +++ b/hw/bsp/adafruit_clue/board.mk @@ -0,0 +1,63 @@ +CFLAGS += \ + -flto \ + -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 -Wno-error=unused-parameter + +# due to tusb_hal_nrf_power_event +GCCVERSION = $(firstword $(subst ., ,$(shell arm-none-eabi-gcc -dumpversion))) +ifeq ($(shell expr $(GCCVERSION) \>= 8), 1) +CFLAGS += -Wno-error=cast-function-type +endif + +# All source paths should be relative to the top level. +LD_FILE = hw/bsp/$(BOARD)/nrf52840_s140_v6.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 \ + +INC += \ + $(TOP)/hw/mcu/nordic/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 + +# 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 + +# For uf2 conversion +UF2_FAMILY = 0xADA52840 + +$(BUILD)/$(BOARD)-firmware.zip: $(BUILD)/$(BOARD)-firmware.hex + adafruit-nrfutil dfu genpkg --dev-type 0x0052 --sd-req 0xFFFE --application $^ $@ + +# flash using adafruit-nrfutil dfu +flash: $(BUILD)/$(BOARD)-firmware.zip + @:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0) + adafruit-nrfutil --verbose dfu serial --package $^ -p $(SERIAL) -b 115200 --singlebank --touch 1200 diff --git a/hw/bsp/adafruit_clue/nrf52840_s140_v6.ld b/hw/bsp/adafruit_clue/nrf52840_s140_v6.ld new file mode 100755 index 000000000..5314a4e93 --- /dev/null +++ b/hw/bsp/adafruit_clue/nrf52840_s140_v6.ld @@ -0,0 +1,38 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0xED000 - 0x26000 + + /* SRAM required by S132 depend on + * - Attribute Table Size + * - Vendor UUID count + * - Max ATT MTU + * - Concurrent connection peripheral + central + secure links + * - Event Len, HVN queue, Write CMD queue + */ + RAM (rwx) : ORIGIN = 0x20003400, LENGTH = 0x20040000 - 0x20003400 +} + +SECTIONS +{ + . = ALIGN(4); + .svc_data : + { + PROVIDE(__start_svc_data = .); + KEEP(*(.svc_data)) + PROVIDE(__stop_svc_data = .); + } > RAM + + .fs_data : + { + PROVIDE(__start_fs_data = .); + KEEP(*(.fs_data)) + PROVIDE(__stop_fs_data = .); + } > RAM +} INSERT AFTER .data; + +INCLUDE "nrf52_common.ld"