nrf: Add nrf9160 base support.

This patch add basic building blocks for nrf9P60.

It also includes a secure bootloader which forwards all
possible peripherals that are user selectable to become
non-secure. After configuring Flash, RAM and peripherals
the secure bootloader will jump to the non-secure domain
where MicroPython is placed.

The minimum size of a secure boot has to be a flash
block of 32Kb, hence why the linker scripts are
offsetting the main application this much.

The RAM offset is set to 128K, to allow for later
integration of Nordic Semiconductor's BSD socket
library which reserves the range 0x20010000 - 0x2001FFFF.
This commit is contained in:
Glenn Ruben Bakke 2019-09-26 22:25:16 +02:00
parent 01a3110e36
commit 82fe6b0526
14 changed files with 771 additions and 15 deletions

View File

@ -82,6 +82,9 @@ else ifeq ($(MCU_SUB_VARIANT),nrf52832)
else ifeq ($(MCU_SUB_VARIANT),nrf52840)
SYSTEM_C_SRC += $(addprefix lib/nrfx/mdk/, system_nrf52840.c)
# Do not pass MCU_VARIANT_UPPER flag, as NRF52 defines NRF52832 only.
else ifeq ($(MCU_SUB_VARIANT),nrf9160)
SYSTEM_C_SRC += $(addprefix lib/nrfx/mdk/, system_nrf9160.c)
NRF_DEFINES += -D$(MCU_VARIANT_UPPER)
endif
NRF_DEFINES += -D$(MCU_SUB_VARIANT_UPPER)
@ -89,6 +92,8 @@ NRF_DEFINES += -DCONFIG_GPIO_AS_PINRESET
CFLAGS_CORTEX_M = -mthumb -mabi=aapcs -fsingle-precision-constant -Wdouble-promotion
CFLAGS_MCU_m33 = $(CFLAGS_CORTEX_M) -mcpu=cortex-m33 -march=armv8-m.main+dsp -mcmse -mfpu=fpv5-sp-d16 -mfloat-abi=hard
CFLAGS_MCU_m4 = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard
CFLAGS_MCU_m0 = $(CFLAGS_CORTEX_M) -fshort-enums -mtune=cortex-m0 -mcpu=cortex-m0 -mfloat-abi=soft -fno-builtin
@ -125,10 +130,6 @@ endif
LIBS = \
ifeq ($(MCU_VARIANT), nrf52)
LIBGCC_FILE_NAME = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
LIBS += -L $(dir $(LIBGCC_FILE_NAME)) -lgcc
SRC_LIB += $(addprefix lib/,\
libm/math.c \
@ -153,6 +154,38 @@ SRC_LIB += $(addprefix lib/,\
endif
ifeq ($(MCU_VARIANT), nrf91)
SRC_LIB += $(addprefix lib/,\
libm/math.c \
libm/fmodf.c \
libm/nearbyintf.c \
libm/ef_sqrt.c \
libm/kf_rem_pio2.c \
libm/kf_sin.c \
libm/kf_cos.c \
libm/kf_tan.c \
libm/ef_rem_pio2.c \
libm/sf_sin.c \
libm/sf_cos.c \
libm/sf_tan.c \
libm/sf_frexp.c \
libm/sf_modf.c \
libm/sf_ldexp.c \
libm/asinfacosf.c \
libm/atanf.c \
libm/atan2f.c \
)
SRC_NRFX += $(addprefix lib/nrfx/drivers/src/,\
nrfx_uarte.c \
nrfx_twim.c \
)
include drivers/secureboot/secureboot.mk
endif
SRC_LIB += $(addprefix lib/,\
libc/string0.c \
mp-readline/readline.c \
@ -271,13 +304,16 @@ FROZEN_MPY_PY_FILES := $(shell find -L $(FROZEN_MPY_DIR) -type f -name '*.py')
FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/,$(FROZEN_MPY_PY_FILES:.py=.mpy))
endif
LIBGCC_FILE_NAME = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
LIBS += -L $(dir $(LIBGCC_FILE_NAME)) -lgcc
OBJ += $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_LIB:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_NRFX:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_NRFX_HAL:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(DRIVERS_SRC_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SYSTEM_C_SRC:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_LIB:.c=.o))
OBJ += $(BUILD)/pins_gen.o
$(BUILD)/$(FATFS_DIR)/ff.o: COPT += -Os
@ -285,7 +321,11 @@ $(filter $(PY_BUILD)/../extmod/vfs_fat_%.o, $(PY_O)): COPT += -Os
.PHONY: all flash deploy sd binary hex
ifeq ($(MCU_VARIANT), nrf91)
all: binary hex secureboot
else
all: binary hex
endif
OUTPUT_FILENAME = firmware
@ -305,10 +345,21 @@ FLASHER ?=
ifeq ($(FLASHER),)
ifeq ($(MCU_VARIANT), nrf91)
deploy: $(BUILD)/$(OUTPUT_FILENAME).hex $(BUILD)/secureboot.hex
nrfjprog --program $(BUILD)/secureboot.hex --sectorerase -f $(MCU_VARIANT)
nrfjprog --program $(BUILD)/$(OUTPUT_FILENAME).hex --sectorerase -f $(MCU_VARIANT)
nrfjprog --reset -f $(MCU_VARIANT)
else
deploy: $(BUILD)/$(OUTPUT_FILENAME).hex
nrfjprog --program $< --sectorerase -f $(MCU_VARIANT)
nrfjprog --reset -f $(MCU_VARIANT)
endif
sd: $(BUILD)/$(OUTPUT_FILENAME).hex
nrfjprog --eraseall -f $(MCU_VARIANT)
nrfjprog --program $(SOFTDEV_HEX) -f $(MCU_VARIANT)

View File

@ -0,0 +1,13 @@
/*
GNU linker script for NRF9160 NS
*/
_flash_size = 1M;
_ram_size = 256K;
_sd_size = 0x00008000;
_sd_ram = 0x00020000;
_fs_size = 80K;
/* produce a link error if there is not this amount of RAM for these sections */
_stack_size = 32K;
_minimum_heap_size = 64K;

View File

@ -0,0 +1,6 @@
/* Specify the memory areas */
MEMORY
{
FLASH_TEXT (rx) : ORIGIN = 0x00000000, LENGTH = 32K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K
}

View File

@ -0,0 +1,29 @@
// nrf91_prefix.c becomes the initial portion of the generated pins file.
#include <stdio.h>
#include "py/obj.h"
#include "py/mphal.h"
#include "pin.h"
#define AF(af_idx, af_fn, af_unit, af_type, af_ptr) \
{ \
{ &pin_af_type }, \
.name = MP_QSTR_AF ## af_idx ## _ ## af_fn ## af_unit, \
.idx = (af_idx), \
.fn = AF_FN_ ## af_fn, \
.unit = (af_unit), \
.type = AF_PIN_TYPE_ ## af_fn ## _ ## af_type, \
.af_fn = (af_ptr) \
}
#define PIN(p_pin, p_af, p_adc_num, p_adc_channel) \
{ \
{ &pin_type }, \
.name = MP_QSTR_P ## p_pin, \
.pin = (p_pin), \
.num_af = (sizeof(p_af) / sizeof(pin_af_obj_t)), \
.af = p_af, \
.adc_num = p_adc_num, \
.adc_channel = p_adc_channel, \
}

View File

@ -0,0 +1,270 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2018 Glenn Ruben Bakke
*
* 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 <stdint.h>
extern uint32_t _estack;
extern uint32_t _sidata;
extern uint32_t _sdata;
extern uint32_t _edata;
extern uint32_t _sbss;
extern uint32_t _ebss;
typedef void (*func)(void);
extern void _start(void) __attribute__((noreturn));
extern void SystemInit(void);
void Default_Handler(void) { while (1); }
void Reserved_Handler1(void) { while (1); }
void Reserved_Handler2(void) { while (1); }
void Reserved_Handler3(void) { while (1); }
void Reserved_Handler4(void) { while (1); }
void Reserved_Handler5(void) { while (1); }
void Reserved_Handler6(void) { while (1); }
void Reserved_Handler7(void) { while (1); }
void Reserved_Handler8(void) { while (1); }
void Reserved_Handler9(void) { while (1); }
void Reserved_Handler10(void) { while (1); }
void Reserved_Handler11(void) { while (1); }
void Reserved_Handler12(void) { while (1); }
void Reserved_Handler13(void) { while (1); }
void Reserved_Handler14(void) { while (1); }
void Reserved_Handler15(void) { while (1); }
void Reserved_Handler16(void) { while (1); }
void Reserved_Handler17(void) { while (1); }
void Reserved_Handler18(void) { while (1); }
void Reserved_Handler19(void) { while (1); }
void Reserved_Handler20(void) { while (1); }
void Reserved_Handler21(void) { while (1); }
void Reserved_Handler22(void) { while (1); }
void Reserved_Handler23(void) { while (1); }
void Reserved_Handler24(void) { while (1); }
void Reserved_Handler25(void) { while (1); }
void Reserved_Handler26(void) { while (1); }
void Reserved_Handler27(void) { while (1); }
void Reserved_Handler28(void) { while (1); }
void Reserved_Handler29(void) { while (1); }
void Reserved_Handler30(void) { while (1); }
void Reserved_Handler31(void) { while (1); }
void Reserved_Handler32(void) { while (1); }
void Reserved_Handler33(void) { while (1); }
void Reserved_Handler34(void) { while (1); }
void Reserved_Handler35(void) { while (1); }
void Reserved_Handler36(void) { while (1); }
void Reserved_Handler37(void) { while (1); }
void Reserved_Handler38(void) { while (1); }
void Default_NMI_Handler (void) { while (1); }
void Default_HardFault_Handler (void) { while (1); }
void Default_MemoryManagement_Handler (void) { while (1); }
void Default_BusFault_Handler (void) { while (1); }
void Default_UsageFault_Handler (void) { while (1); }
void Default_SecureFault_Handler (void) { while (1); }
void Default_SVC_Handler (void) { while (1); }
void Default_DebugMon_Handler (void) { while (1); }
void Default_PendSV_Handler (void) { while (1); }
void Default_SysTick_Handler (void) { while (1); }
void Default_SPU_IRQHandler (void) { while (1); }
void Default_CLOCK_POWER_IRQHandler (void) { while (1); }
void Default_UARTE0_SPIM0_SPIS0_TWIM0_TWIS0_IRQHandler (void) { while (1); }
void Default_UARTE1_SPIM1_SPIS1_TWIM1_TWIS1_IRQHandler (void) { while (1); }
void Default_UARTE2_SPIM2_SPIS2_TWIM2_TWIS2_IRQHandler (void) { while (1); }
void Default_UARTE3_SPIM3_SPIS3_TWIM3_TWIS3_IRQHandler (void) { while (1); }
void Default_GPIOTE0_IRQHandler (void) { while (1); }
void Default_SAADC_IRQHandler (void) { while (1); }
void Default_TIMER0_IRQHandler (void) { while (1); }
void Default_TIMER1_IRQHandler (void) { while (1); }
void Default_TIMER2_IRQHandler (void) { while (1); }
void Default_RTC0_IRQHandler (void) { while (1); }
void Default_RTC1_IRQHandler (void) { while (1); }
void Default_WDT_IRQHandler (void) { while (1); }
void Default_EGU0_IRQHandler (void) { while (1); }
void Default_EGU1_IRQHandler (void) { while (1); }
void Default_EGU2_IRQHandler (void) { while (1); }
void Default_EGU3_IRQHandler (void) { while (1); }
void Default_EGU4_IRQHandler (void) { while (1); }
void Default_EGU5_IRQHandler (void) { while (1); }
void Default_PWM0_IRQHandler (void) { while (1); }
void Default_PWM1_IRQHandler (void) { while (1); }
void Default_PWM2_IRQHandler (void) { while (1); }
void Default_PWM3_IRQHandler (void) { while (1); }
void Default_PDM_IRQHandler (void) { while (1); }
void Default_I2S_IRQHandler (void) { while (1); }
void Default_IPC_IRQHandler (void) { while (1); }
void Default_FPU_IRQHandler (void) { while (1); }
void Default_GPIOTE1_IRQHandler (void) { while (1); }
void Default_KMU_IRQHandler (void) { while (1); }
void Default_CRYPTOCELL_IRQHandler (void) { while (1); }
void Reset_Handler(void) {
uint32_t * p_src = &_sidata;
uint32_t * p_dest = &_sdata;
while (p_dest < &_edata) {
*p_dest++ = *p_src++;
}
uint32_t * p_bss = &_sbss;
uint32_t * p_bss_end = &_ebss;
while (p_bss < p_bss_end) {
*p_bss++ = 0ul;
}
SystemInit();
_start();
}
void NMI_Handler (void) __attribute__ ((weak, alias("Default_Handler")));
void HardFault_Handler (void) __attribute__ ((weak, alias("Default_HardFault_Handler")));
void MemoryManagement_Handler (void) __attribute__ ((weak, alias("Default_MemoryManagement_Handler")));
void BusFault_Handler (void) __attribute__ ((weak, alias("Default_BusFault_Handler")));
void UsageFault_Handler (void) __attribute__ ((weak, alias("Default_UsageFault_Handler")));
void SecureFault_Handler (void) __attribute__ ((weak, alias("Default_SecureFault_Handler")));
void SVC_Handler (void) __attribute__ ((weak, alias("Default_SVC_Handler")));
void DebugMon_Handler (void) __attribute__ ((weak, alias("Default_DebugMon_Handler")));
void PendSV_Handler (void) __attribute__ ((weak, alias("Default_PendSV_Handler")));
void SysTick_Handler (void) __attribute__ ((weak, alias("Default_SysTick_Handler")));
void SPU_IRQHandler (void) __attribute__ ((weak, alias("Default_SPU_IRQHandler")));
void CLOCK_POWER_IRQHandler (void) __attribute__ ((weak, alias("Default_CLOCK_POWER_IRQHandler")));
void UARTE0_SPIM0_SPIS0_TWIM0_TWIS0_IRQHandler (void) __attribute__ ((weak, alias("Default_UARTE0_SPIM0_SPIS0_TWIM0_TWIS0_IRQHandler")));
void UARTE1_SPIM1_SPIS1_TWIM1_TWIS1_IRQHandler (void) __attribute__ ((weak, alias("Default_UARTE1_SPIM1_SPIS1_TWIM1_TWIS1_IRQHandler")));
void UARTE2_SPIM2_SPIS2_TWIM2_TWIS2_IRQHandler (void) __attribute__ ((weak, alias("Default_UARTE2_SPIM2_SPIS2_TWIM2_TWIS2_IRQHandler")));
void UARTE3_SPIM3_SPIS3_TWIM3_TWIS3_IRQHandler (void) __attribute__ ((weak, alias("Default_UARTE3_SPIM3_SPIS3_TWIM3_TWIS3_IRQHandler")));
void GPIOTE0_IRQHandler (void) __attribute__ ((weak, alias("Default_GPIOTE0_IRQHandler")));
void SAADC_IRQHandler (void) __attribute__ ((weak, alias("Default_SAADC_IRQHandler")));
void TIMER0_IRQHandler (void) __attribute__ ((weak, alias("Default_TIMER0_IRQHandler")));
void TIMER1_IRQHandler (void) __attribute__ ((weak, alias("Default_TIMER1_IRQHandler")));
void TIMER2_IRQHandler (void) __attribute__ ((weak, alias("Default_TIMER2_IRQHandler")));
void RTC0_IRQHandler (void) __attribute__ ((weak, alias("Default_RTC0_IRQHandler")));
void RTC1_IRQHandler (void) __attribute__ ((weak, alias("Default_RTC1_IRQHandler")));
void WDT_IRQHandler (void) __attribute__ ((weak, alias("Default_WDT_IRQHandler")));
void EGU0_IRQHandler (void) __attribute__ ((weak, alias("Default_EGU0_IRQHandler")));
void EGU1_IRQHandler (void) __attribute__ ((weak, alias("Default_EGU1_IRQHandler")));
void EGU2_IRQHandler (void) __attribute__ ((weak, alias("Default_EGU2_IRQHandler")));
void EGU3_IRQHandler (void) __attribute__ ((weak, alias("Default_EGU3_IRQHandler")));
void EGU4_IRQHandler (void) __attribute__ ((weak, alias("Default_EGU4_IRQHandler")));
void EGU5_IRQHandler (void) __attribute__ ((weak, alias("Default_EGU5_IRQHandler")));
void PWM0_IRQHandler (void) __attribute__ ((weak, alias("Default_PWM0_IRQHandler")));
void PWM1_IRQHandler (void) __attribute__ ((weak, alias("Default_PWM1_IRQHandler")));
void PWM2_IRQHandler (void) __attribute__ ((weak, alias("Default_PWM2_IRQHandler")));
void PWM3_IRQHandler (void) __attribute__ ((weak, alias("Default_PWM3_IRQHandler")));
void PDM_IRQHandler (void) __attribute__ ((weak, alias("Default_PDM_IRQHandler")));
void I2S_IRQHandler (void) __attribute__ ((weak, alias("Default_I2S_IRQHandler")));
void IPC_IRQHandler (void) __attribute__ ((weak, alias("Default_IPC_IRQHandler")));
void FPU_IRQHandler (void) __attribute__ ((weak, alias("Default_FPU_IRQHandler")));
void GPIOTE1_IRQHandler (void) __attribute__ ((weak, alias("Default_GPIOTE1_IRQHandler")));
void KMU_IRQHandler (void) __attribute__ ((weak, alias("Default_KMU_IRQHandler")));
void CRYPTOCELL_IRQHandler (void) __attribute__ ((weak, alias("Default_CRYPTOCELL_IRQHandler")));
const func __Vectors[] __attribute__ ((section(".isr_vector"),used)) = {
(func)&_estack,
Reset_Handler,
NMI_Handler,
HardFault_Handler,
MemoryManagement_Handler,
BusFault_Handler,
UsageFault_Handler,
SecureFault_Handler,
Reserved_Handler1,
Reserved_Handler2,
Reserved_Handler3,
SVC_Handler,
DebugMon_Handler,
Reserved_Handler4,
PendSV_Handler,
SysTick_Handler,
/* External Interrupts */
Reserved_Handler5,
Reserved_Handler6,
Reserved_Handler7,
SPU_IRQHandler,
Reserved_Handler8,
CLOCK_POWER_IRQHandler,
Reserved_Handler9,
Reserved_Handler10,
UARTE0_SPIM0_SPIS0_TWIM0_TWIS0_IRQHandler,
UARTE1_SPIM1_SPIS1_TWIM1_TWIS1_IRQHandler,
UARTE2_SPIM2_SPIS2_TWIM2_TWIS2_IRQHandler,
UARTE3_SPIM3_SPIS3_TWIM3_TWIS3_IRQHandler,
Reserved_Handler11,
GPIOTE0_IRQHandler,
SAADC_IRQHandler,
TIMER0_IRQHandler,
TIMER1_IRQHandler,
TIMER2_IRQHandler,
Reserved_Handler12,
Reserved_Handler13,
RTC0_IRQHandler,
RTC1_IRQHandler,
Reserved_Handler14,
Reserved_Handler15,
WDT_IRQHandler,
Reserved_Handler16,
Reserved_Handler17,
EGU0_IRQHandler,
EGU1_IRQHandler,
EGU2_IRQHandler,
EGU3_IRQHandler,
EGU4_IRQHandler,
EGU5_IRQHandler,
PWM0_IRQHandler,
PWM1_IRQHandler,
PWM2_IRQHandler,
PWM3_IRQHandler,
Reserved_Handler18,
PDM_IRQHandler,
Reserved_Handler19,
I2S_IRQHandler,
Reserved_Handler20,
IPC_IRQHandler,
Reserved_Handler21,
FPU_IRQHandler,
Reserved_Handler22,
Reserved_Handler23,
Reserved_Handler24,
Reserved_Handler25,
GPIOTE1_IRQHandler,
Reserved_Handler26,
Reserved_Handler27,
Reserved_Handler28,
Reserved_Handler29,
Reserved_Handler30,
Reserved_Handler31,
Reserved_Handler32,
KMU_IRQHandler,
Reserved_Handler33,
Reserved_Handler34,
Reserved_Handler35,
Reserved_Handler36,
Reserved_Handler37,
Reserved_Handler38,
CRYPTOCELL_IRQHandler,
};

View File

@ -34,6 +34,10 @@
#elif defined(NRF52_SERIES)
#define FLASH_PAGESIZE (4096)
#elif defined(NRF91_SERIES)
#define FLASH_PAGESIZE (4096)
#else
#error Unknown chip
#endif

View File

@ -0,0 +1,55 @@
DRIVERS_SECUREBOOT_DIR = drivers/secureboot
SRC_SECUREBOOT += $(addprefix $(DRIVERS_SECUREBOOT_DIR)/,\
secureboot_main.c \
)
SRC_SECUREBOOT += $(addprefix device/,\
startup_nrf9160.c \
)
SRC_SECUREBOOT += $(addprefix $(TOP)/lib/nrfx/mdk/,\
system_nrf9160.c \
)
.PHONY: secureboot clean
INC_SECUREBOOT += -I./../../lib/nrfx/mdk
INC_SECUREBOOT += -I./../../lib/cmsis/inc
MCU_SERIES = m33
CFLAGS_CORTEX_M = -mthumb -mabi=aapcs -fsingle-precision-constant -Wdouble-promotion
CFLAGS_MCU_m33 = $(CFLAGS_CORTEX_M) -mcpu=cortex-m33 -march=armv8-m.main+dsp -mcmse -mfpu=fpv5-sp-d16 -mfloat-abi=hard
CFLAGS_SECUREBOOT += -DNRF9160_XXAA
CFLAGS_SECUREBOOT += $(CFLAGS_MCU_$(MCU_SERIES))
CFLAGS_SECUREBOOT += -Wall -Werror -g -ansi -std=c11 -nostdlib $(COPT)
CFLAGS_SECUREBOOT += -fno-strict-aliasing
LD_FILES_SECUREBOOT += nrf9160_1M_256k_secure.ld common.ld
LDFLAGS_SECUREBOOT = $(CFLAGS_SECUREBOOT)
LDFLAGS_SECUREBOOT += -Xlinker -Map=$(@:.elf=.map)
LDFLAGS_SECUREBOOT += -mthumb -mabi=aapcs $(addprefix -T,$(LD_FILES_SECUREBOOT)) -L ./boards
CC = arm-none-eabi-gcc
SIZE = arm-none-eabi-size
OBJCOPY = arm-none-eabi-objcopy
LIBGCC_FILE_NAME = $(shell $(CC) $(CFLAGS_SECUREBOOT) -print-libgcc-file-name)
LIBC_FILE_NAME = $(shell $(CC) $(CFLAGS_SECUREBOOT) -print-file-name=libc.a)
LIBS_SECUREBOOT += -L $(dir $(LIBGCC_FILE_NAME)) -lgcc
LIBS_SECUREBOOT += -L $(dir $(LIBC_FILE_NAME)) -lc
$(BUILD)/secureboot.elf:
$(Q)$(CC) $(LDFLAGS_SECUREBOOT) $(SRC_SECUREBOOT) $(INC_SECUREBOOT) -O3 -o $@ $(LIBS_SECUREBOOT)
$(SIZE) $@
$(BUILD)/secureboot.hex: $(BUILD)/secureboot.elf
$(OBJCOPY) -O ihex $< $@
secureboot: $(BUILD)/secureboot.hex
@echo "Secure boot"

View File

@ -0,0 +1,194 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2019 Glenn Ruben Bakke
*
* 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 <arm_cmse.h>
#include <nrf.h>
// Secure flash 32K.
#define SECURE_32K_FLASH_PAGE_START (0)
#define SECURE_32K_FLASH_PAGE_END (0)
// Non-secure flash 992K.
#define NONSECURE_32K_FLASH_PAGE_START (1)
#define NONSECURE_32K_FLASH_PAGE_END (31)
// Secure RAM 64K.
#define SECURE_8K_RAM_BLOCK_START (0)
#define SECURE_8K_RAM_BLOCK_END (7)
// Non-secure RAM 128K + 64K BSD lib.
#define NONSECURE_8K_RAM_BLOCK_START (8)
#define NONSECURE_8K_RAM_BLOCK_END (31)
#define PERIPHERAL_ID_GET(base_addr) (((uint32_t)(base_addr) >> 12) & 0xFF)
#if !defined(__ARM_FEATURE_CMSE)
#pragma warning "CMSE not enabled"
#endif
static void configure_flash(void) {
for (uint8_t i = SECURE_32K_FLASH_PAGE_START; i <= SECURE_32K_FLASH_PAGE_END; i++) {
uint32_t perm = 0;
perm |= (SPU_FLASHREGION_PERM_EXECUTE_Enable << SPU_FLASHREGION_PERM_EXECUTE_Pos);
perm |= (SPU_FLASHREGION_PERM_WRITE_Enable << SPU_FLASHREGION_PERM_WRITE_Pos);
perm |= (SPU_FLASHREGION_PERM_READ_Enable << SPU_FLASHREGION_PERM_READ_Pos);
perm |= (SPU_FLASHREGION_PERM_LOCK_Locked << SPU_FLASHREGION_PERM_LOCK_Pos);
perm |= (SPU_FLASHREGION_PERM_SECATTR_Secure << SPU_FLASHREGION_PERM_SECATTR_Pos);
NRF_SPU_S->FLASHREGION[i].PERM = perm;
}
for (uint8_t i = NONSECURE_32K_FLASH_PAGE_START; i <= NONSECURE_32K_FLASH_PAGE_END; i++) {
uint32_t perm = 0;
perm |= (SPU_FLASHREGION_PERM_EXECUTE_Enable << SPU_FLASHREGION_PERM_EXECUTE_Pos);
perm |= (SPU_FLASHREGION_PERM_WRITE_Enable << SPU_FLASHREGION_PERM_WRITE_Pos);
perm |= (SPU_FLASHREGION_PERM_READ_Enable << SPU_FLASHREGION_PERM_READ_Pos);
perm |= (SPU_FLASHREGION_PERM_LOCK_Locked << SPU_FLASHREGION_PERM_LOCK_Pos);
perm |= (SPU_FLASHREGION_PERM_SECATTR_Non_Secure << SPU_FLASHREGION_PERM_SECATTR_Pos);
NRF_SPU_S->FLASHREGION[i].PERM = perm;
}
}
static void configure_ram(void) {
for (uint8_t i = SECURE_8K_RAM_BLOCK_START; i <= SECURE_8K_RAM_BLOCK_END; i++) {
uint32_t perm = 0;
perm |= (SPU_RAMREGION_PERM_EXECUTE_Enable << SPU_RAMREGION_PERM_EXECUTE_Pos);
perm |= (SPU_RAMREGION_PERM_WRITE_Enable << SPU_RAMREGION_PERM_WRITE_Pos);
perm |= (SPU_RAMREGION_PERM_READ_Enable << SPU_RAMREGION_PERM_READ_Pos);
perm |= (SPU_RAMREGION_PERM_LOCK_Locked << SPU_RAMREGION_PERM_LOCK_Pos);
perm |= (SPU_RAMREGION_PERM_SECATTR_Secure << SPU_RAMREGION_PERM_SECATTR_Pos);
NRF_SPU_S->RAMREGION[i].PERM = perm;
}
for (uint8_t i = NONSECURE_8K_RAM_BLOCK_START; i <= NONSECURE_8K_RAM_BLOCK_END; i++) {
uint32_t perm = 0;
perm |= (SPU_RAMREGION_PERM_EXECUTE_Enable << SPU_RAMREGION_PERM_EXECUTE_Pos);
perm |= (SPU_RAMREGION_PERM_WRITE_Enable << SPU_RAMREGION_PERM_WRITE_Pos);
perm |= (SPU_RAMREGION_PERM_READ_Enable << SPU_RAMREGION_PERM_READ_Pos);
perm |= (SPU_RAMREGION_PERM_LOCK_Locked << SPU_RAMREGION_PERM_LOCK_Pos);
perm |= (SPU_RAMREGION_PERM_SECATTR_Non_Secure << SPU_RAMREGION_PERM_SECATTR_Pos);
NRF_SPU_S->RAMREGION[i].PERM = perm;
}
}
static void peripheral_setup(uint8_t peripheral_id)
{
NVIC_DisableIRQ(peripheral_id);
uint32_t perm = 0;
perm |= (SPU_PERIPHID_PERM_PRESENT_IsPresent << SPU_PERIPHID_PERM_PRESENT_Pos);
perm |= (SPU_PERIPHID_PERM_SECATTR_NonSecure << SPU_PERIPHID_PERM_SECATTR_Pos);
perm |= (SPU_PERIPHID_PERM_LOCK_Locked << SPU_PERIPHID_PERM_LOCK_Pos);
NRF_SPU_S->PERIPHID[peripheral_id].PERM = perm;
NVIC_SetTargetState(peripheral_id);
}
static void configure_peripherals(void)
{
NRF_SPU_S->GPIOPORT[0].PERM = 0;
peripheral_setup(PERIPHERAL_ID_GET(NRF_REGULATORS_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_CLOCK_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_UARTE0_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_UARTE1_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_UARTE2_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_UARTE3_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_SAADC_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_TIMER0_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_TIMER1_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_TIMER2_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_RTC0_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_RTC1_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_DPPIC_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_WDT_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_EGU1_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_EGU2_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_EGU3_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_EGU4_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_EGU5_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_PWM0_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_PWM1_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_PWM2_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_PWM3_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_PDM_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_I2S_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_IPC_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_FPU_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_GPIOTE1_NS));
peripheral_setup(PERIPHERAL_ID_GET(NRF_NVMC_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_VMC_S));
peripheral_setup(PERIPHERAL_ID_GET(NRF_P0_NS));
}
typedef void __attribute__((cmse_nonsecure_call)) nsfunc(void);
static void jump_to_non_secure(void)
{
TZ_SAU_Disable();
SAU->CTRL |= SAU_CTRL_ALLNS_Msk;
// Set NS vector table.
uint32_t * vtor_ns = (uint32_t *)0x8000;
SCB_NS->VTOR = (uint32_t)vtor_ns;
// Allow for FPU to be used by NS.
SCB->NSACR |= (1UL << SCB_NSACR_CP10_Pos) | (1UL << SCB_NSACR_CP11_Pos);
// Set stack pointers.
__TZ_set_MSP_NS(vtor_ns[0]);
__TZ_set_PSP_NS(0);
uint32_t control_ns = __TZ_get_CONTROL_NS();
control_ns &= ~(CONTROL_SPSEL_Msk | CONTROL_nPRIV_Msk);
__TZ_set_CONTROL_NS(control_ns);
// Cast NS Reset_Handler to a non-secure function.
nsfunc *fp = (nsfunc *)vtor_ns[1];
fp = (nsfunc *)((intptr_t)(fp) & ~1);
if (cmse_is_nsfptr(fp)) {
__DSB();
__ISB();
// Jump to Non-Secure function.
fp();
}
}
int main(void) {
configure_flash();
configure_ram();
configure_peripherals();
jump_to_non_secure();
while (1) {
;
}
return 0;
}
void _start(void) {main();}

View File

@ -299,9 +299,10 @@ MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
#endif
#endif
void HardFault_Handler(void)
{
#if defined(NRF52_SERIES)
#if defined(NRF52_SERIES) || defined(NRF91_SERIES)
static volatile uint32_t reg;
static volatile uint32_t reg2;
static volatile uint32_t bfar;

View File

@ -78,8 +78,10 @@ void machine_init(void) {
reset_cause = PYB_RESET_LOCKUP;
} else if (state & POWER_RESETREAS_OFF_Msk) {
reset_cause = PYB_RESET_POWER_ON;
#if !defined(NRF9160_XXAA)
} else if (state & POWER_RESETREAS_LPCOMP_Msk) {
reset_cause = PYB_RESET_LPCOMP;
#endif
} else if (state & POWER_RESETREAS_DIF_Msk) {
reset_cause = PYB_RESET_DIF;
#if defined(NRF52_SERIES)

View File

@ -98,7 +98,6 @@ void mp_hal_delay_us(mp_uint_t us)
if (us == 0) {
return;
}
register uint32_t delay __ASM ("r0") = us;
__ASM volatile (
#ifdef NRF51
@ -118,7 +117,7 @@ void mp_hal_delay_us(mp_uint_t us)
" NOP\n"
" NOP\n"
" NOP\n"
#ifdef NRF52
#if defined(NRF52) || defined(NRF9160_XXAA)
" NOP\n"
" NOP\n"
" NOP\n"

32
ports/nrf/nrf91_af.csv Normal file
View File

@ -0,0 +1,32 @@
P0,P0
P1,P1
P2,P2
P3,P3
P4,P4
P5,P5
P6,P6
P7,P7
P8,P8
P9,P9
P10,P10
P11,P11
P12,P12
P13,P13
P14,P14
P15,P15
P16,P16
P17,P17
P18,P18
P19,P19
P20,P20
P21,P21
P22,P22
P23,P23
P24,P24
P25,P25
P26,P26
P27,P27
P28,P28
P29,P29
P30,P30
P31,P31
1 P0 P0
2 P1 P1
3 P2 P2
4 P3 P3
5 P4 P4
6 P5 P5
7 P6 P6
8 P7 P7
9 P8 P8
10 P9 P9
11 P10 P10
12 P11 P11
13 P12 P12
14 P13 P13
15 P14 P14
16 P15 P15
17 P16 P16
18 P17 P17
19 P18 P18
20 P19 P19
21 P20 P20
22 P21 P21
23 P22 P22
24 P23 P23
25 P24 P24
26 P25 P25
27 P26 P26
28 P27 P27
29 P28 P28
30 P29 P29
31 P30 P30
32 P31 P31

View File

@ -45,6 +45,8 @@
#define GPIO_COUNT 1
#elif NRF52840 || NRF52840_XXAA
#define GPIO_COUNT 2
#elif NRF9160_XXAA
#define GPIO_COUNT 1
#endif
#if defined(NRF52840)
@ -63,12 +65,27 @@
#define NRFX_GPIOTE_CONFIG_IRQ_PRIORITY 6
#endif
#define NRFX_UART_ENABLED 1
#define NRFX_UART0_ENABLED 1
#if defined(NRF51) || defined(NRF52_SERIES)
#define NRFX_UART_ENABLED 1
#define NRFX_UART0_ENABLED 1
#define NRFX_UART1_ENABLED 1
#else
#define NRFX_UARTE_ENABLED 1
#define NRFX_UARTE0_ENABLED 1
#define NRFX_UARTE1_ENABLED 1
#define NRFX_UARTE2_ENABLED 1
#define NRFX_UARTE3_ENABLED 1
#endif
#define NRFX_TWI_ENABLED (MICROPY_PY_MACHINE_I2C)
#define NRFX_TWI0_ENABLED 1
#define NRFX_TWI1_ENABLED 1
#if defined(NRF51) || defined(NRF52_SERIES)
#define NRFX_TWI_ENABLED (MICROPY_PY_MACHINE_I2C)
#define NRFX_TWI0_ENABLED 1
#define NRFX_TWI1_ENABLED 1
#elif defined(NRF9160_XXAA)
#define NRFX_TWIM_ENABLED (MICROPY_PY_MACHINE_I2C)
#define NRFX_TWIM0_ENABLED 1
#define NRFX_TWIM1_ENABLED 1
#endif
#if defined(NRF51) || defined(NRF52832)
#define NRFX_SPI_ENABLED (MICROPY_PY_MACHINE_HW_SPI)
@ -84,6 +101,15 @@
#define NRFX_SPIM1_ENABLED 1
#define NRFX_SPIM2_ENABLED 1
#define NRFX_SPIM3_ENABLED (NRF52840)
#elif defined(NRF9160_XXAA)
#define NRFX_SPIM_ENABLED (MICROPY_PY_MACHINE_HW_SPI)
#define NRFX_SPIM0_ENABLED 1
#define NRFX_SPIM1_ENABLED 1
// 0 NRF_GPIO_PIN_NOPULL
// 1 NRF_GPIO_PIN_PULLDOWN
// 3 NRF_GPIO_PIN_PULLUP
#define NRFX_SPIM_MISO_PULL_CFG 1
#endif // NRF51
// 0 NRF_GPIO_PIN_NOPULL
@ -101,8 +127,8 @@
#define NRFX_TIMER0_ENABLED 1
#define NRFX_TIMER1_ENABLED (!MICROPY_PY_MACHINE_SOFT_PWM)
#define NRFX_TIMER2_ENABLED 1
#define NRFX_TIMER3_ENABLED (!NRF51)
#define NRFX_TIMER4_ENABLED (!NRF51)
#define NRFX_TIMER3_ENABLED (!NRF51) && (!NRF9160_XXAA)
#define NRFX_TIMER4_ENABLED (!NRF51) && (!NRF9160_XXAA)
#define NRFX_PWM_ENABLED (!NRF51) && MICROPY_PY_MACHINE_HW_PWM
@ -125,6 +151,10 @@
#define NRFX_PRS_BOX_0_ENABLED (NRFX_TWI_ENABLED && NRFX_TWI0_ENABLED && NRFX_SPIM_ENABLED && NRFX_SPIM0_ENABLED)
#define NRFX_PRS_BOX_1_ENABLED (NRFX_TWI_ENABLED && NRFX_TWI1_ENABLED && NRFX_SPIM_ENABLED && NRFX_SPIM1_ENABLED)
#define NRFX_PRS_BOX_2_ENABLED (NRFX_TWI_ENABLED && NRFX_TWI2_ENABLED && NRFX_SPIM_ENABLED && NRFX_SPIM2_ENABLED)
#elif defined(NRF9160_XXAA)
#define NRFX_PRS_BOX_0_ENABLED (NRFX_TWIM_ENABLED && NRFX_TWIM0_ENABLED && NRFX_SPIM_ENABLED && NRFX_SPIM0_ENABLED)
#define NRFX_PRS_BOX_1_ENABLED (NRFX_TWIM_ENABLED && NRFX_TWIM1_ENABLED && NRFX_SPIM_ENABLED && NRFX_SPIM1_ENABLED)
#define NRFX_PRS_BOX_2_ENABLED (NRFX_TWIM_ENABLED && NRFX_TWIM2_ENABLED && NRFX_SPIM_ENABLED && NRFX_SPIM2_ENABLED)
#endif
#define NRFX_PRS_ENABLED (NRFX_PRS_BOX_0_ENABLED || NRFX_PRS_BOX_1_ENABLED || NRFX_PRS_BOX_2_ENABLED)
@ -132,4 +162,69 @@
#define NRFX_SAADC_ENABLED !(NRF51) && (MICROPY_PY_MACHINE_ADC)
#define NRFX_ADC_ENABLED (NRF51) && (MICROPY_PY_MACHINE_ADC)
#if defined(NRF9160_XXAA)
#define NRF_CLOCK NRF_CLOCK_NS
#define NRF_DPPIC NRF_DPPIC_NS
#define NRF_EGU0 NRF_EGU0_NS
#define NRF_EGU1 NRF_EGU1_NS
#define NRF_EGU2 NRF_EGU2_NS
#define NRF_EGU3 NRF_EGU3_NS
#define NRF_EGU4 NRF_EGU4_NS
#define NRF_EGU5 NRF_EGU5_NS
#define NRF_FPU NRF_FPU_NS
#define NRF_P0 NRF_P0_NS
#define NRF_I2S NRF_I2S_NS
#define NRF_KMU NRF_KMU_NS
#define NRF_NVMC NRF_NVMC_NS
#define NRF_PDM NRF_PDM_NS
#define NRF_POWER NRF_POWER_NS
#define NRF_PWM0 NRF_PWM0_NS
#define NRF_PWM1 NRF_PWM1_NS
#define NRF_PWM2 NRF_PWM2_NS
#define NRF_PWM3 NRF_PWM3_NS
#define NRF_REGULATORS NRF_REGULATORS_NS
#define NRF_RTC0 NRF_RTC0_NS
#define NRF_RTC1 NRF_RTC1_NS
#define NRF_SAADC NRF_SAADC_NS
#define NRF_SPIM0 NRF_SPIM0_NS
#define NRF_SPIM1 NRF_SPIM1_NS
#define NRF_SPIM2 NRF_SPIM2_NS
#define NRF_SPIM3 NRF_SPIM3_NS
#define NRF_SPIS0 NRF_SPIS0_NS
#define NRF_SPIS1 NRF_SPIS1_NS
#define NRF_SPIS2 NRF_SPIS2_NS
#define NRF_SPIS3 NRF_SPIS3_NS
#define NRF_TIMER0 NRF_TIMER0_NS
#define NRF_TIMER1 NRF_TIMER1_NS
#define NRF_TIMER2 NRF_TIMER2_NS
#define NRF_TWIM0 NRF_TWIM0_NS
#define NRF_TWIM1 NRF_TWIM1_NS
#define NRF_TWIM2 NRF_TWIM2_NS
#define NRF_TWIM3 NRF_TWIM3_NS
#define NRF_TWIS0 NRF_TWIS0_NS
#define NRF_TWIS1 NRF_TWIS1_NS
#define NRF_TWIS2 NRF_TWIS2_NS
#define NRF_TWIS3 NRF_TWIS3_NS
#define NRF_UARTE0 NRF_UARTE0_NS
#define NRF_UARTE1 NRF_UARTE1_NS
#define NRF_UARTE2 NRF_UARTE2_NS
#define NRF_UARTE3 NRF_UARTE3_NS
#define NRF_VMC NRF_VMC_NS
#define NRF_WDT NRF_WDT_NS
#define NRF_IPC NRF_IPC_NS
#define NRF_CRYPTOCELL NRF_CRYPTOCELL_S
#define NRF_FICR NRF_FICR_S
#define NRF_GPIOTE0 NRF_GPIOTE0_S
#define NRF_GPIOTE1 NRF_GPIOTE1_NS
#define NRF_SPU NRF_SPU_S
#define NRF_UICR NRF_UICR_S
#define NRF_GPIOTE NRF_GPIOTE1_NS
#define GPIOTE_IRQn GPIOTE1_IRQn
#define GPIOTE_IRQHandler GPIOTE1_IRQHandler
#endif
#endif // NRFX_CONFIG_H

View File

@ -52,10 +52,15 @@ enum {
AF_PIN_TYPE_SPI_NSS,
};
#if defined(NRF51) || defined(NRF52_SERIES)
#define PIN_DEFS_PORT_AF_UNION \
NRF_UART_Type *UART;
// NRF_SPI_Type *SPIM;
// NRF_SPIS_Type *SPIS;
#elif defined(NRF91_SERIES)
#define PIN_DEFS_PORT_AF_UNION \
NRF_UARTE_Type *UART;
#endif
enum {
PIN_ADC1 = (1 << 0),