diff --git a/arch/arm/src/nrf53/Kconfig b/arch/arm/src/nrf53/Kconfig index fc4a279b2b..c8a4853835 100644 --- a/arch/arm/src/nrf53/Kconfig +++ b/arch/arm/src/nrf53/Kconfig @@ -14,6 +14,10 @@ choice config ARCH_CHIP_NRF5340 bool "NRF5340" + select NRF53_CPUAPP_MEM_FLASH_1024 + select NRF53_CPUAPP_MEM_RAM_512 + select NRF53_CPUNET_MEM_FLASH_256 + select NRF53_CPUNET_MEM_RAM_64 endchoice # NRF53 Chip Selection @@ -50,6 +54,46 @@ config ARCH_CHIP_NRF5340_CPUNET endchoice # NRF5340 Core Selection +# RAM size for the app core + +config NRF53_CPUAPP_MEM_RAM_512 + bool + default n + +config NRF53_CPUAPP_MEM_RAM_SIZE + hex + default 0x080000 if NRF53_CPUAPP_MEM_RAM_512 + +# RAM size for the net core + +config NRF53_CPUNET_MEM_RAM_64 + bool + default n + +config NRF53_CPUNET_MEM_RAM_SIZE + hex + default 0x008000 if NRF53_CPUNET_MEM_RAM_64 + +# FLASH size for the app core + +config NRF53_CPUAPP_MEM_FLASH_1024 + bool + default n + +config NRF53_CPUAPP_MEM_FLASH_SIZE + hex + default 0x100000 if NRF53_CPUAPP_MEM_FLASH_1024 + +# FLASH size for the net core + +config NRF53_CPUNET_MEM_FLASH_256 + bool + default n + +config NRF53_CPUNET_MEM_FLASH_SIZE + hex + default 0x040000 if NRF53_CPUNET_MEM_FLASH_256 + if NRF53_APPCORE config NRF53_NET_BOOT @@ -398,6 +442,19 @@ endif endmenu # System Timer +config NRF53_FLASH_PREFETCH + bool "Enable FLASH Pre-fetch" + default y + ---help--- + Enable FLASH prefetch + +config NRF53_PROGMEM + bool "FLASH program memory" + default n + select ARCH_HAVE_PROGMEM + ---help--- + Enable support FLASH interfaces as defined in include/nuttx/progmem.h + menu "PWM configuration" config NRF53_PWM_MULTICHAN diff --git a/arch/arm/src/nrf53/Make.defs b/arch/arm/src/nrf53/Make.defs index faf0f4a698..3f35fb4fa8 100644 --- a/arch/arm/src/nrf53/Make.defs +++ b/arch/arm/src/nrf53/Make.defs @@ -36,6 +36,10 @@ ifeq ($(CONFIG_NRF53_APPCORE),y) CHIP_CSRCS += nrf53_oscconfig.c endif +ifeq ($(CONFIG_NRF53_PROGMEM),y) +CHIP_CSRCS += nrf53_flash.c +endif + ifneq ($(CONFIG_ARCH_IDLE_CUSTOM),y) CHIP_CSRCS += nrf53_idle.c endif diff --git a/arch/arm/src/nrf53/hardware/nrf53_ficr_cpuapp.h b/arch/arm/src/nrf53/hardware/nrf53_ficr_cpuapp.h index c67bc0b0d5..3542e660f5 100644 --- a/arch/arm/src/nrf53/hardware/nrf53_ficr_cpuapp.h +++ b/arch/arm/src/nrf53/hardware/nrf53_ficr_cpuapp.h @@ -49,6 +49,18 @@ /* FICR Register Addresses *************************************************/ +#define NRF53_FICR_INFO_CONFIGID (NRF53_FICR_BASE + NRF53_FICR_INFO_CONFIGID_OFFSET) +#define NRF53_FICR_INFO_DEVICEID0 (NRF53_FICR_BASE + NRF53_FICR_INFO_DEVICEID0_OFFSET) +#define NRF53_FICR_INFO_DEVICEID1 (NRF53_FICR_BASE + NRF53_FICR_INFO_DEVICEID1_OFFSET) +#define NRF53_FICR_INFO_PART (NRF53_FICR_BASE + NRF53_FICR_INFO_PART_OFFSET) +#define NRF53_FICR_INFO_VARIANT (NRF53_FICR_BASE + NRF53_FICR_INFO_VARIANT_OFFSET) +#define NRF53_FICR_INFO_PACKAGE (NRF53_FICR_BASE + NRF53_FICR_INFO_PACKAGE_OFFSET) +#define NRF53_FICR_INFO_RAM (NRF53_FICR_BASE + NRF53_FICR_INFO_RAM_OFFSET) +#define NRF53_FICR_INFO_FLASH (NRF53_FICR_BASE + NRF53_FICR_INFO_FLASH_OFFSET) +#define NRF53_FICR_INFO_CODEPAGESIZE (NRF53_FICR_BASE + NRF53_FICR_INFO_CODEPAGESIZE_OFFSET) +#define NRF53_FICR_INFO_CODESIZE (NRF53_FICR_BASE + NRF53_FICR_INFO_CODESIZE_OFFSET) +#define NRF53_FICR_INFO_DEVICETYPE (NRF53_FICR_BASE + NRF53_FICR_INFO_DEVICETYPE_OFFSET) + /* TODO */ #endif /* __ARCH_ARM_SRC_NRF53_HARDWARE_NRF53_FICR_CPUAPP_H */ diff --git a/arch/arm/src/nrf53/hardware/nrf53_ficr_cpunet.h b/arch/arm/src/nrf53/hardware/nrf53_ficr_cpunet.h index e79044b0ef..764956c5d6 100644 --- a/arch/arm/src/nrf53/hardware/nrf53_ficr_cpunet.h +++ b/arch/arm/src/nrf53/hardware/nrf53_ficr_cpunet.h @@ -45,20 +45,42 @@ #define NRF53_FICR_INFO_CODEPAGESIZE_OFFSET 0x220 /* Code memory page size in bytes */ #define NRF53_FICR_INFO_CODESIZE_OFFSET 0x224 /* Code memory size */ #define NRF53_FICR_INFO_DEVICETYPE_OFFSET 0x228 /* Device type */ -#define NRF52_FICR_ER0_OFFSET 0x280 /* Encryption Root, word 0 */ -#define NRF52_FICR_ER1_OFFSET 0x284 /* Encryption Root, word 1 */ -#define NRF52_FICR_ER2_OFFSET 0x288 /* Encryption Root, word 2 */ -#define NRF52_FICR_ER3_OFFSET 0x28c /* Encryption Root, word 3 */ -#define NRF52_FICR_IR0_OFFSET 0x290 /* Identity Root, word 0 */ -#define NRF52_FICR_IR1_OFFSET 0x294 /* Identity Root, word 1 */ -#define NRF52_FICR_IR2_OFFSET 0x298 /* Identity Root, word 2 */ -#define NRF52_FICR_IR3_OFFSET 0x29c /* Identity Root, word 3 */ -#define NRF52_FICR_DEVICEADDRTYPE_OFFSET 0x2a0 /* Device address type */ -#define NRF52_FICR_DEVICEADDR0_OFFSET 0x2a4 /* Device address 0 */ -#define NRF52_FICR_DEVICEADDR1_OFFSET 0x2a8 /* Device address 1 */ +#define NRF53_FICR_ER0_OFFSET 0x280 /* Encryption Root, word 0 */ +#define NRF53_FICR_ER1_OFFSET 0x284 /* Encryption Root, word 1 */ +#define NRF53_FICR_ER2_OFFSET 0x288 /* Encryption Root, word 2 */ +#define NRF53_FICR_ER3_OFFSET 0x28c /* Encryption Root, word 3 */ +#define NRF53_FICR_IR0_OFFSET 0x290 /* Identity Root, word 0 */ +#define NRF53_FICR_IR1_OFFSET 0x294 /* Identity Root, word 1 */ +#define NRF53_FICR_IR2_OFFSET 0x298 /* Identity Root, word 2 */ +#define NRF53_FICR_IR3_OFFSET 0x29c /* Identity Root, word 3 */ +#define NRF53_FICR_DEVICEADDRTYPE_OFFSET 0x2a0 /* Device address type */ +#define NRF53_FICR_DEVICEADDR0_OFFSET 0x2a4 /* Device address 0 */ +#define NRF53_FICR_DEVICEADDR1_OFFSET 0x2a8 /* Device address 1 */ /* FICR Register Addresses *************************************************/ +#define NRF53_FICR_INFO_CONFIGID (NRF53_FICR_BASE + NRF53_FICR_INFO_CONFIGID_OFFSET) +#define NRF53_FICR_INFO_DEVICEID0 (NRF53_FICR_BASE + NRF53_FICR_INFO_DEVICEID0_OFFSET) +#define NRF53_FICR_INFO_DEVICEID1 (NRF53_FICR_BASE + NRF53_FICR_INFO_DEVICEID1_OFFSET) +#define NRF53_FICR_INFO_PART (NRF53_FICR_BASE + NRF53_FICR_INFO_PART_OFFSET) +#define NRF53_FICR_INFO_VARIANT (NRF53_FICR_BASE + NRF53_FICR_INFO_VARIANT_OFFSET) +#define NRF53_FICR_INFO_PACKAGE (NRF53_FICR_BASE + NRF53_FICR_INFO_PACKAGE_OFFSET) +#define NRF53_FICR_INFO_RAM (NRF53_FICR_BASE + NRF53_FICR_INFO_RAM_OFFSET) +#define NRF53_FICR_INFO_FLASH (NRF53_FICR_BASE + NRF53_FICR_INFO_FLASH_OFFSET) +#define NRF53_FICR_INFO_CODEPAGESIZE (NRF53_FICR_BASE + NRF53_FICR_INFO_CODEPAGESIZE_OFFSET) +#define NRF53_FICR_INFO_CODESIZE (NRF53_FICR_BASE + NRF53_FICR_INFO_CODESIZE_OFFSET) +#define NRF53_FICR_INFO_DEVICETYPE (NRF53_FICR_BASE + NRF53_FICR_INFO_DEVICETYPE_OFFSET) +#define NRF53_FICR_ER0 (NRF53_FICR_BASE + NRF53_FICR_ER0_OFFSET) +#define NRF53_FICR_ER1 (NRF53_FICR_BASE + NRF53_FICR_ER1_OFFSET) +#define NRF53_FICR_ER2 (NRF53_FICR_BASE + NRF53_FICR_ER2_OFFSET) +#define NRF53_FICR_IR0 (NRF53_FICR_BASE + NRF53_FICR_IR0_OFFSET) +#define NRF53_FICR_IR1 (NRF53_FICR_BASE + NRF53_FICR_IR1_OFFSET) +#define NRF53_FICR_IR2 (NRF53_FICR_BASE + NRF53_FICR_IR2_OFFSET) +#define NRF53_FICR_IR3 (NRF53_FICR_BASE + NRF53_FICR_IR3_OFFSET) +#define NRF53_FICR_DEVICEADDRTYPE (NRF53_FICR_BASE + NRF53_FICR_DEVICEADDRTYPE_OFFSET) +#define NRF53_FICR_DEVICEADDR0 (NRF53_FICR_BASE + NRF53_FICR_DEVICEADDR0_OFFSET) +#define NRF53_FICR_DEVICEADDR1 (NRF53_FICR_BASE + NRF53_FICR_DEVICEADDR1_OFFSET) + /* TODO */ #endif /* __ARCH_ARM_SRC_NRF53_HARDWARE_NRF53_FICR_NET_H */ diff --git a/arch/arm/src/nrf53/nrf53_flash.c b/arch/arm/src/nrf53/nrf53_flash.c new file mode 100644 index 0000000000..80250018a3 --- /dev/null +++ b/arch/arm/src/nrf53/nrf53_flash.c @@ -0,0 +1,399 @@ +/**************************************************************************** + * arch/arm/src/nrf53/nrf53_flash.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "arm_internal.h" +#include "barriers.h" + +#include "hardware/nrf53_ficr.h" +#include "hardware/nrf53_nvmc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define MEMORY_SYNC() ARM_ISB(); ARM_DSB() + +/* Sizes and masks */ + +#define NRF53_FLASH_ERASEDVAL (0xff) + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static inline uint32_t nrf53_get_flash_size(void) +{ + return getreg32(NRF53_FICR_INFO_FLASH) * 1024; +} + +static inline uint32_t nrf53_get_page_size(void) +{ + return getreg32(NRF53_FICR_INFO_CODEPAGESIZE); +} + +static inline uint32_t nrf53_get_pages_num(void) +{ + return getreg32(NRF53_FICR_INFO_CODESIZE); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_progmem_pagesize + * + * Description: + * Return page size + * + ****************************************************************************/ + +size_t up_progmem_pagesize(size_t page) +{ + if (page >= up_progmem_neraseblocks()) + { + return 0; + } + else + { + return nrf53_get_page_size(); + } +} + +/**************************************************************************** + * Name: up_progmem_erasesize + * + * Description: + * Return erase block size + * + ****************************************************************************/ + +size_t up_progmem_erasesize(size_t block) +{ + return up_progmem_pagesize(block); +} + +/**************************************************************************** + * Name: up_progmem_getpage + * + * Description: + * Address to page conversion + * + * Input Parameters: + * addr - Address to be converted + * + * Returned Value: + * Page or negative value on error. The following errors are reported + * (errno is not set!): + * + * -EFAULT: On invalid address + * + ****************************************************************************/ + +ssize_t up_progmem_getpage(size_t addr) +{ + if (addr >= nrf53_get_flash_size()) + { + return -EFAULT; + } + + return addr / nrf53_get_page_size(); +} + +/**************************************************************************** + * Name: up_progmem_getaddress + * + * Description: + * Page to address conversion + * + * Input Parameters: + * page - Page to be converted + * + * Returned Value: + * Base address of given page, maximum size if page is not valid. + * + ****************************************************************************/ + +size_t up_progmem_getaddress(size_t page) +{ + if (page >= up_progmem_neraseblocks()) + { + return SIZE_MAX; + } + + return page * nrf53_get_page_size(); +} + +/**************************************************************************** + * Name: up_progmem_neraseblocks + * + * Description: + * Return number of erase blocks in the available FLASH memory. + * + ****************************************************************************/ + +size_t up_progmem_neraseblocks(void) +{ + return nrf53_get_flash_size() / nrf53_get_page_size(); +} + +/**************************************************************************** + * Name: up_progmem_isuniform + * + * Description: + * Page size is uniform? Say 'yes' even though that is not strictly + * true. + * + ****************************************************************************/ + +bool up_progmem_isuniform(void) +{ + return true; +} + +/**************************************************************************** + * Name: up_progmem_eraseblock + * + * Description: + * Erase selected block. + * + * Input Parameters: + * block - Block to be erased + * + * Returned Value: + * Page size or negative value on error. The following errors are reported + * (errno is not set!): + * + * -EFAULT: On invalid page + * -EIO: On unsuccessful erase + * -EROFS: On access to write protected area + * -EACCES: Insufficient permissions (read/write protected) + * -EPERM: If operation is not permitted due to some other constraints + * (i.e. some internal block is not running etc.) + * + ****************************************************************************/ + +ssize_t up_progmem_eraseblock(size_t block) +{ + size_t page_address; + + if (block >= up_progmem_neraseblocks()) + { + return -EFAULT; + } + + page_address = up_progmem_getaddress(block); + + /* Enable erase mode */ + + putreg32(NVMC_CONFIG_EEN, NRF53_NVMC_CONFIG); + + /* Memory sync */ + + MEMORY_SYNC(); + + /* Erase the page by writting 0xffffffff into the first 32-bit word of + * the flash page + */ + + putreg32(0xffffffff, page_address); + + /* Wait for flash */ + + while (!(getreg32(NRF53_NVMC_READY) & NVMC_READY_READY)) + { + } + + /* Read only access */ + + putreg32(NVMC_CONFIG_REN, NRF53_NVMC_CONFIG); + + /* Memory sync */ + + MEMORY_SYNC(); + + /* Verify */ + + if (up_progmem_ispageerased(block) == 0) + { + return up_progmem_erasesize(block); + } + else + { + return -EIO; + } +} + +/**************************************************************************** + * Name: up_progmem_ispageerased + * + * Description: + * Checks whether a page is erased + * + * Input Parameters: + * page - Page to be checked + * + * Returned Value: + * Returns number of bytes erased or negative value on error. If it + * returns zero then complete page is empty (erased). + * + * The following errors are reported (errno is not set!) + * -EFAULT: On invalid page + * + ****************************************************************************/ + +ssize_t up_progmem_ispageerased(size_t page) +{ + size_t addr; + size_t count; + size_t bwritten = 0; + + if (page >= nrf53_get_pages_num()) + { + return -EFAULT; + } + + /* Verify */ + + for (addr = up_progmem_getaddress(page), count = up_progmem_pagesize(page); + count; count--, addr++) + { + if (getreg8(addr) != NRF53_FLASH_ERASEDVAL) + { + bwritten++; + } + } + + return bwritten; +} + +/**************************************************************************** + * Name: up_progmem_write + * + * Description: + * Program data at given address + * + * Input Parameters: + * addr - Address with or without flash offset + * buf - Pointer to buffer + * count - Number of bytes to write + * + * Returned Value: + * Bytes written or negative value on error. The following errors are + * reported (errno is not set!) + * + * EINVAL: If buflen is not aligned with the flash boundaries (i.e. + * some MCU's require per half-word or even word access) + * EFAULT: On invalid address + * EIO: On unsuccessful write + * EROFS: On access to write protected area + * EACCES: Insufficient permissions (read/write protected) + * EPERM: If operation is not permitted due to some other constraints + * (i.e. some internal block is not running etc.) + * + ****************************************************************************/ + +ssize_t up_progmem_write(size_t addr, const void *buf, size_t count) +{ + uint32_t *pword = (uint32_t *)buf; + size_t written = count; + + /* NRF53 requires word access */ + + if (count & 0x3) + { + return -EINVAL; + } + + /* Check for valid address range */ + + if ((addr + count) > nrf53_get_flash_size()) + { + return -EFAULT; + } + + /* Flash offset */ + + addr += NRF53_FLASH_BASE; + + /* Begin flashing */ + + for (; count; count -= 4, pword++, addr += 4) + { + /* Enable write */ + + putreg32(NVMC_CONFIG_WEN, NRF53_NVMC_CONFIG); + + /* Memory sync */ + + MEMORY_SYNC(); + + /* Write the word */ + + *(uint32_t *)addr = *pword; + + /* Wait for flash */ + + while (!(getreg32(NRF53_NVMC_READY) & NVMC_READY_READY)) + { + } + + /* Read only access */ + + putreg32(NVMC_CONFIG_REN, NRF53_NVMC_CONFIG); + + /* Memory sync */ + + MEMORY_SYNC(); + + /* Verify */ + + if (getreg32(addr) != *pword) + { + return -EIO; + } + } + + return written; +} + +/**************************************************************************** + * Name: up_progmem_erasestate + * + * Description: + * Return value of erase state. + * + ****************************************************************************/ + +uint8_t up_progmem_erasestate(void) +{ + return NRF53_FLASH_ERASEDVAL; +} diff --git a/arch/arm/src/nrf53/nrf53_start.c b/arch/arm/src/nrf53/nrf53_start.c index 58e6173dc7..c5647768bf 100644 --- a/arch/arm/src/nrf53/nrf53_start.c +++ b/arch/arm/src/nrf53/nrf53_start.c @@ -36,6 +36,7 @@ #include "nvic.h" #include "nrf53_clockconfig.h" +#include "hardware/nrf53_nvmc.h" #include "hardware/nrf53_utils.h" #include "hardware/nrf53_uicr.h" #include "hardware/nrf53_ctrlap.h" @@ -100,6 +101,61 @@ void nrf53_approtect(void) #endif } +#ifdef CONFIG_NRF53_FLASH_PREFETCH + +/**************************************************************************** + * Name: nrf53_enable_icache + * + * Description: + * Enable I-Cache for Flash + * + * Input Parameter: + * enable - enable or disable I-Cache + * + * Returned Values: + * None + * + ****************************************************************************/ + +void nrf53_enable_icache(bool enable) +{ + if (enable) + { + modifyreg32(NRF53_NVMC_ICACHECNF, 0, NVMC_ICACHECNF_CACHEEN); + } + else + { + modifyreg32(NRF53_NVMC_ICACHECNF, NVMC_ICACHECNF_CACHEEN, 0); + } +} + +/**************************************************************************** + * Name: nrf53_enable_profile + * + * Description: + * Enable profiling I-Cache for flash + * + * Input Parameter: + * enable - enable or disable profiling for I-Cache + * + * Returned Values: + * None + * + ****************************************************************************/ + +void nrf53_enable_profile(bool enable) +{ + if (enable) + { + modifyreg32(NRF53_NVMC_ICACHECNF, 0, NVMC_ICACHECNF_CACHEPROFEN); + } + else + { + modifyreg32(NRF53_NVMC_ICACHECNF, NVMC_ICACHECNF_CACHEPROFEN, 0); + } +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -179,6 +235,11 @@ void __start(void) arm_fpuconfig(); #endif +#ifdef CONFIG_NRF53_FLASH_PREFETCH + nrf53_enable_icache(true); + nrf53_enable_profile(true); +#endif + showprogress('D'); #ifdef USE_EARLYSERIALINIT