diff --git a/Makefile b/Makefile index 372828b..bdffcfe 100644 --- a/Makefile +++ b/Makefile @@ -41,6 +41,9 @@ else NRFJPROG = nrfjprog endif +# auto-detect BMP on macOS, otherwise have to specify +BMP_PORT ?= $(shell ls -1 /dev/cu.usbmodem????????1 | head -1) + ifeq ($(OS),Windows_NT) PROGFILES = C:/Program Files (x86) GNU_INSTALL_ROOT = $(PROGFILES)/GNU Tools ARM Embedded/7 2018-q2-update/bin/ @@ -67,6 +70,9 @@ NM := '$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-nm' OBJDUMP := '$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-objdump' OBJCOPY := '$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-objcopy' SIZE := '$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-size' +GDB := '$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-gdb' + +GDB_BMP = arm-none-eabi-gdb -ex 'target extended-remote $(BMP_PORT)' -ex 'monitor swdp_scan' -ex 'attach 1' #function for removing duplicates in a list remduplicates = $(strip $(if $1,$(firstword $1) $(call remduplicates,$(filter-out $(firstword $1),$1)))) @@ -115,6 +121,7 @@ C_SOURCE_FILES += $(SRC_PATH)/boards.c C_SOURCE_FILES += $(SRC_PATH)/flash_nrf5x.c C_SOURCE_FILES += $(SRC_PATH)/dfu_ble_svc.c C_SOURCE_FILES += $(SRC_PATH)/dfu_init.c +C_SOURCE_FILES += $(SRC_PATH)/pinconfig.c # nrfx C_SOURCE_FILES += $(NRFX_PATH)/drivers/src/nrfx_power.c @@ -340,6 +347,13 @@ erase: @echo Erasing chip $(NRFJPROG) --eraseall -f nrf52 +gdbflash: $(BUILD)/$(MERGED_FNAME).hex + @echo Flashing: $< + @$(GDB_BMP) -nx --batch -ex 'load $<' -ex 'compare-sections' -ex 'kill' + +gdb: $(BUILD)/$(OUTPUT_FILENAME)-nosd.out + $(GDB_BMP) $< + #******************* Compile rules ******************* ## Create build directories diff --git a/src/boards/arcade_feather_nrf52840_express/board.h b/src/boards/arcade_feather_nrf52840_express/board.h new file mode 100644 index 0000000..6d37acf --- /dev/null +++ b/src/boards/arcade_feather_nrf52840_express/board.h @@ -0,0 +1,139 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018 Ha Thach for Adafruit Industries + * + * 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 _ARCARDE_FEATHER_NRF52840_H +#define _ARCARDE_FEATHER_NRF52840_H + +#define _PINNUM(port, pin) ((port)*32 + (pin)) + +/*------------------------------------------------------------------*/ +/* LED + *------------------------------------------------------------------*/ +#define LEDS_NUMBER 2 +#define LED_PRIMARY_PIN _PINNUM(1, 15) +#define LED_SECONDARY_PIN _PINNUM(1, 10) +#define LED_STATE_ON 1 + +#define LED_NEOPIXEL _PINNUM(0, 16) +#define NEOPIXELS_NUMBER 1 +#define BOARD_RGB_BRIGHTNESS 0x040404 + +/*------------------------------------------------------------------*/ +/* BUTTON + *------------------------------------------------------------------*/ +#define BUTTONS_NUMBER 2 +#define BUTTON_1 _PINNUM(1, 02) +#define BUTTON_2 _PINNUM(0, 10) +#define BUTTON_PULL NRF_GPIO_PIN_PULLUP + +/*------------------------------------------------------------------*/ +/* UART (only used by nRF52832) + *------------------------------------------------------------------*/ +#define RX_PIN_NUMBER 8 +#define TX_PIN_NUMBER 6 +#define CTS_PIN_NUMBER 0 +#define RTS_PIN_NUMBER 0 +#define HWFC false + +//--------------------------------------------------------------------+ +// BLE OTA +//--------------------------------------------------------------------+ +#define BLEDIS_MANUFACTURER "Adafruit Industries" +#define BLEDIS_MODEL "Feather nRF52840 Express" + +//--------------------------------------------------------------------+ +// USB +//--------------------------------------------------------------------+ +#define USB_DESC_VID 0x239A +#define USB_DESC_UF2_PID 0x0029 +#define USB_DESC_CDC_ONLY_PID 0x002A + +//------------- UF2 -------------// +#define UF2_PRODUCT_NAME "Adafruit Feather nRF52840 Express" +#define UF2_VOLUME_LABEL "ARCADE-N4" +#define UF2_BOARD_ID "nRF52840-Feather-revD" +#define UF2_INDEX_URL "https://www.adafruit.com/product/4062" + +#define BOOTLOADER_CONFIG_CF2 \ + /* CF2 START */ \ + 513675505, 539130489, /* magic */ \ + 49 , 100 , /* used entries, total entries */ \ + 4 , 0x18 , /* PIN_BTN_A = PIN_RX */ \ + 5 , 0xa , /* PIN_BTN_B = PIN_D2 */ \ + 13 , 0x29 , /* PIN_LED = PIN_D13 */ \ + 18 , 0xf , /* PIN_MISO = PA15 */ \ + 19 , 0xd , /* PIN_MOSI = PA13 */ \ + 20 , 0x23 , /* PIN_NEOPIXEL = PB03 */ \ + 21 , 0x18 , /* PIN_RX = PA24 */ \ + 23 , 0xe , /* PIN_SCK = PA14 */ \ + 24 , 0xb , /* PIN_SCL = PA11 */ \ + 25 , 0xc , /* PIN_SDA = PA12 */ \ + 28 , 0x19 , /* PIN_TX = PA25 */ \ + 32 , 0xe , /* PIN_DISPLAY_SCK = PIN_SCK */ \ + 34 , 0xd , /* PIN_DISPLAY_MOSI = PIN_MOSI */ \ + 35 , 0x1e , /* PIN_DISPLAY_CS = PIN_A2 */ \ + 36 , 0x1c , /* PIN_DISPLAY_DC = PIN_A3 */ \ + 37 , 0xa0 , /* DISPLAY_WIDTH = 160 */ \ + 38 , 0x80 , /* DISPLAY_HEIGHT = 128 */ \ + 39 , 0x80 , /* DISPLAY_CFG0 = 0x80 */ \ + 40 , 0x603 , /* DISPLAY_CFG1 = 0x603 */ \ + 41 , 0x20 , /* DISPLAY_CFG2 = 0x20 */ \ + 43 , 0x2 , /* PIN_DISPLAY_RST = PIN_A4 */ \ + 44 , 0x3 , /* PIN_DISPLAY_BL = PIN_A5 */ \ + 47 , 0x6 , /* PIN_BTN_LEFT = PIN_D11 */ \ + 48 , 0x1a , /* PIN_BTN_RIGHT = PIN_D9 */ \ + 49 , 0x1b , /* PIN_BTN_UP = PIN_D10 */ \ + 50 , 0x7 , /* PIN_BTN_DOWN = PIN_D6 */ \ + 51 , 0x8 , /* PIN_BTN_MENU = PIN_D12 */ \ + 56 , 0x2a , /* PIN_LED2 = PB10 */ \ + 60 , 0x19 , /* PIN_JACK_TX = PIN_TX */ \ + 100, 0x4 , /* PIN_A0 = PA04 */ \ + 101, 0x5 , /* PIN_A1 = PA05 */ \ + 102, 0x1e , /* PIN_A2 = PA30 */ \ + 103, 0x1c , /* PIN_A3 = PA28 */ \ + 104, 0x2 , /* PIN_A4 = PA02 */ \ + 105, 0x3 , /* PIN_A5 = PA03 */ \ + 152, 0xa , /* PIN_D2 = PA10 */ \ + 155, 0x28 , /* PIN_D5 = PB08 */ \ + 156, 0x7 , /* PIN_D6 = PA07 */ \ + 159, 0x1a , /* PIN_D9 = PA26 */ \ + 160, 0x1b , /* PIN_D10 = PA27 */ \ + 161, 0x6 , /* PIN_D11 = PA06 */ \ + 162, 0x8 , /* PIN_D12 = PA08 */ \ + 163, 0x29 , /* PIN_D13 = PB09 */ \ + 200, 0x1 , /* NUM_NEOPIXELS = 1 */ \ + 204, 0x100000 , /* FLASH_BYTES = 0x100000 */ \ + 205, 0x40000 , /* RAM_BYTES = 0x40000 */ \ + 208, 0xd7688ea1, /* BOOTLOADER_BOARD_ID = 0xd7688ea1 */ \ + 209, 0xada52840, /* UF2_FAMILY = 0xada52840 */ \ + 210, 0x20 , /* PINS_PORT_SIZE = PA_32 */ \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \ + 0, 0, 0, 0, 0, 0 \ + /* CF2 END */ + + +#endif // _ARCARDE_FEATHER_NRF52840_H + diff --git a/src/boards/arcade_feather_nrf52840_express/board.mk b/src/boards/arcade_feather_nrf52840_express/board.mk new file mode 100644 index 0000000..9d29ac6 --- /dev/null +++ b/src/boards/arcade_feather_nrf52840_express/board.mk @@ -0,0 +1 @@ +MCU_SUB_VARIANT = nrf52840 diff --git a/src/linker/nrf52840_s140_v6.ld b/src/linker/nrf52840_s140_v6.ld index bddaa26..3358c98 100644 --- a/src/linker/nrf52840_s140_v6.ld +++ b/src/linker/nrf52840_s140_v6.ld @@ -11,7 +11,9 @@ MEMORY * those values do not match. The check is performed in main.c, see * APP_ERROR_CHECK_BOOL(*((uint32_t *)NRF_UICR_BOOT_START_ADDRESS) == BOOTLOADER_REGION_START); */ - FLASH (rx) : ORIGIN = 0xF4000, LENGTH = 0xFE000-0xF4000 /* 40 KB */ + FLASH (rx) : ORIGIN = 0xF4000, LENGTH = 0xFE000-0xF4000-2048 /* 38 KB */ + + BOOTLOADER_CONFIG (r): ORIGIN = 0xFE000 - 2048, LENGTH = 2048 /** Location of mbr params page in flash. */ MBR_PARAMS_PAGE (rw) : ORIGIN = 0xFE000, LENGTH = 0x1000 @@ -50,6 +52,11 @@ SECTIONS PROVIDE( __stop_fs_data = .); } = 0 + .bootloaderConfig : + { + KEEP(*(.bootloaderConfig)) + } > BOOTLOADER_CONFIG + /* Place the bootloader settings page in flash. */ .bootloaderSettings(NOLOAD) : { diff --git a/src/main.c b/src/main.c index 5a74640..5c974c1 100644 --- a/src/main.c +++ b/src/main.c @@ -61,6 +61,7 @@ #include "nrf_error.h" #include "boards.h" +#include "uf2/uf2.h" #include "pstorage_platform.h" #include "nrf_mbr.h" @@ -105,12 +106,17 @@ void usb_teardown(void); #define DFU_MAGIC_UF2_RESET 0x57 #define DFU_DBL_RESET_MAGIC 0x5A1AD5 // SALADS +#define DFU_DBL_RESET_APP 0x4ee5677e #define DFU_DBL_RESET_DELAY 500 #define DFU_DBL_RESET_MEM 0x20007F7C #define BOOTLOADER_VERSION_REGISTER NRF_TIMER2->CC[0] #define DFU_SERIAL_STARTUP_INTERVAL 1000 +// Allow for using reset button essentially to swap between application and bootloader. +// This is controlled by a flag in the app and is the behavior of CPX and all Arcade boards when using MakeCode. +#define APP_ASKS_FOR_SINGLE_TAP_RESET() (*((uint32_t*)(USER_FLASH_START + 0x200)) == 0x87eeb07c) + // These value must be the same with one in dfu_transport_ble.c #define BLEGAP_EVENT_LENGTH 6 #define BLEGATT_ATT_MTU_MAX 247 @@ -197,9 +203,13 @@ int main(void) _ota_dfu = _ota_dfu || ( button_pressed(BUTTON_DFU) && button_pressed(BUTTON_FRESET) ) ; bool const valid_app = bootloader_app_is_valid(DFU_BANK_0_REGION_START); + bool const just_start_app = valid_app && !dfu_start && (*dbl_reset_mem) == DFU_DBL_RESET_APP; + + if (!just_start_app && APP_ASKS_FOR_SINGLE_TAP_RESET()) + dfu_start = 1; // App mode: register 1st reset and DFU startup (nrf52832) - if ( ! (dfu_start || !valid_app) ) + if ( ! (just_start_app || dfu_start || !valid_app) ) { // Register our first reset for double reset detection (*dbl_reset_mem) = DFU_DBL_RESET_MAGIC; @@ -218,7 +228,10 @@ int main(void) #endif } - (*dbl_reset_mem) = 0; + if (APP_ASKS_FOR_SINGLE_TAP_RESET()) + (*dbl_reset_mem) = DFU_DBL_RESET_APP; + else + (*dbl_reset_mem) = 0; if ( dfu_start || !valid_app ) { @@ -261,6 +274,9 @@ int main(void) // MBR must be init before start application if ( !sd_inited ) softdev_mbr_init(); + // clear in case we kept DFU_DBL_RESET_APP there + (*dbl_reset_mem) = 0; + // Select a bank region to use as application region. // @note: Only applications running from DFU_BANK_0_REGION_START is supported. bootloader_app_start(DFU_BANK_0_REGION_START); diff --git a/src/pinconfig.c b/src/pinconfig.c new file mode 100644 index 0000000..ee08b95 --- /dev/null +++ b/src/pinconfig.c @@ -0,0 +1,10 @@ +#include "boards.h" + +#ifdef BOOTLOADER_CONFIG_CF2 + +__attribute__((used, section(".bootloaderConfig"))) +const uint32_t bootloaderConfig[] = { + BOOTLOADER_CONFIG_CF2 +}; + +#endif