arch: arm: Add support for the Nordic nRF52840 IC
The new Nordic nRF52840 IC is the latest member of the nRF52 family. It supports the following features among others: * Cortex-M4F core at 64MHz * 1024KB of flash and 256KB of RAM * Bluetooth 5-ready and 802.15.4 compatible radio * USB device support * NFC Tag support * Quad-SPI * Hardware accelerated crypto engine http://www.nordicsemi.com/eng/Products/nRF52840 JIRA: ZEP-1418 Change-Id: I677c787bb33d02695e057d5dced7e3455b9f6c50 Signed-off-by: Vinayak Chettimada <vinayak.kariappa.chettimada@nordicsemi.no> Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
This commit is contained in:
parent
c5d2c4a65d
commit
ce8629c92b
4 changed files with 253 additions and 38 deletions
36
arch/arm/soc/nordic_nrf5/nrf52/Kconfig.defconfig.nrf52840
Normal file
36
arch/arm/soc/nordic_nrf5/nrf52/Kconfig.defconfig.nrf52840
Normal file
|
@ -0,0 +1,36 @@
|
|||
# Kconfig.defconfig.nrf52840 - Nordic Semiconductor nRF52840 MCU
|
||||
#
|
||||
# Copyright (c) 2016 Nordic Semiconductor ASA
|
||||
#
|
||||
# Licensed 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.
|
||||
#
|
||||
|
||||
|
||||
if SOC_NRF52840
|
||||
|
||||
config SOC
|
||||
string
|
||||
default nRF52840
|
||||
|
||||
config SRAM_SIZE
|
||||
default 256
|
||||
|
||||
config FLASH_SIZE
|
||||
default 1024
|
||||
|
||||
config NUM_IRQS
|
||||
int
|
||||
default 46
|
||||
|
||||
endif # SOC_NRF52840
|
||||
|
|
@ -22,4 +22,7 @@ depends on SOC_SERIES_NRF52X
|
|||
config SOC_NRF52832
|
||||
bool "NRF52832"
|
||||
|
||||
config SOC_NRF52840
|
||||
bool "NRF52840"
|
||||
|
||||
endchoice
|
||||
|
|
|
@ -4,6 +4,10 @@ ifdef CONFIG_SOC_NRF52832
|
|||
soc-cflags += -DNRF52832_XXAA
|
||||
endif
|
||||
|
||||
ifdef CONFIG_SOC_NRF52840
|
||||
soc-cflags += -DNRF52840_XXAA
|
||||
endif
|
||||
|
||||
obj-y += soc.o
|
||||
|
||||
zephyr: $(KERNEL_HEX_NAME)
|
||||
|
|
|
@ -104,44 +104,6 @@ static void nordicsemi_nrf52832_init(void)
|
|||
NRF_CLOCK->EVENTS_DONE = 0;
|
||||
NRF_CLOCK->EVENTS_CTTO = 0;
|
||||
}
|
||||
|
||||
/* Enable the FPU if the compiler used floating point unit
|
||||
* instructions. Since the FPU consumes energy, remember to
|
||||
* disable FPU use in the compiler if floating point unit
|
||||
* operations are not used in your code.
|
||||
*/
|
||||
#if defined(CONFIG_FLOAT)
|
||||
SCB->CPACR |= (3UL << 20) | (3UL << 22);
|
||||
__DSB();
|
||||
__ISB();
|
||||
#endif
|
||||
|
||||
/* Configure NFCT pins as GPIOs if NFCT is not to be used in
|
||||
* your code. If CONFIG_NFCT_PINS_AS_GPIOS is not defined,
|
||||
* two GPIOs (see Product Specification to see which ones)
|
||||
* will be reserved for NFC and will not be available as
|
||||
* normal GPIOs.
|
||||
*/
|
||||
#if defined(CONFIG_NFCT_PINS_AS_GPIOS)
|
||||
if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) ==
|
||||
(UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)) {
|
||||
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {
|
||||
;
|
||||
}
|
||||
NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {
|
||||
;
|
||||
}
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {
|
||||
;
|
||||
}
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Configure GPIO pads as pPin Reset pin if Pin Reset
|
||||
* capabilities desired. If CONFIG_GPIO_AS_PINRESET is not
|
||||
* defined, pin reset will not be available. One GPIO (see
|
||||
|
@ -196,6 +158,177 @@ static void nordicsemi_nrf52832_init(void)
|
|||
}
|
||||
#endif /* CONFIG_SOC_NRF52832 */
|
||||
|
||||
#ifdef CONFIG_SOC_NRF52840
|
||||
static bool errata_36(void)
|
||||
{
|
||||
if ((*(uint32_t *)0x10000130ul == 0x8ul) &&
|
||||
(*(uint32_t *)0x10000134ul == 0x0ul)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool errata_98(void)
|
||||
{
|
||||
if ((*(uint32_t *)0x10000130ul == 0x8ul) &&
|
||||
(*(uint32_t *)0x10000134ul == 0x0ul)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool errata_103(void)
|
||||
{
|
||||
if ((*(uint32_t *)0x10000130ul == 0x8ul) &&
|
||||
(*(uint32_t *)0x10000134ul == 0x0ul)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool errata_115(void)
|
||||
{
|
||||
if ((*(uint32_t *)0x10000130ul == 0x8ul) &&
|
||||
(*(uint32_t *)0x10000134ul == 0x0ul)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool errata_120(void)
|
||||
{
|
||||
if ((*(uint32_t *)0x10000130ul == 0x8ul) &&
|
||||
(*(uint32_t *)0x10000134ul == 0x0ul)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void nordicsemi_nrf52840_init(void)
|
||||
{
|
||||
/* Workaround for Errata 36 "CLOCK: Some registers are not reset when
|
||||
* expected" found at the Errata document for your device located at
|
||||
* https://infocenter.nordicsemi.com/
|
||||
*/
|
||||
if (errata_36()) {
|
||||
NRF_CLOCK->EVENTS_DONE = 0;
|
||||
NRF_CLOCK->EVENTS_CTTO = 0;
|
||||
NRF_CLOCK->CTIV = 0;
|
||||
}
|
||||
|
||||
/* Workaround for Errata 98 "NFCT: Not able to communicate with the
|
||||
* peer" found at the Errata document for your device located at
|
||||
* https://infocenter.nordicsemi.com/
|
||||
*/
|
||||
if (errata_98()) {
|
||||
*(volatile uint32_t *)0x4000568Cul = 0x00038148ul;
|
||||
}
|
||||
|
||||
/* Workaround for Errata 103 "CCM: Wrong reset value of CCM
|
||||
* MAXPACKETSIZE" found at the Errata document for your device
|
||||
* located at https://infocenter.nordicsemi.com/
|
||||
*/
|
||||
if (errata_103()) {
|
||||
NRF_CCM->MAXPACKETSIZE = 0xFBul;
|
||||
}
|
||||
|
||||
/* Workaround for Errata 115 "RAM: RAM content cannot be trusted upon
|
||||
* waking up from System ON Idle or System OFF mode" found at the
|
||||
* Errata document for your device located at
|
||||
* https://infocenter.nordicsemi.com/
|
||||
*/
|
||||
if (errata_115()) {
|
||||
*(volatile uint32_t *)0x40000EE4 =
|
||||
(*(volatile uint32_t *) 0x40000EE4 & 0xFFFFFFF0) |
|
||||
(*(uint32_t *)0x10000258 & 0x0000000F);
|
||||
}
|
||||
|
||||
/* Workaround for Errata 120 "QSPI: Data read or written is corrupted"
|
||||
* found at the Errata document for your device located at
|
||||
* https://infocenter.nordicsemi.com/
|
||||
*/
|
||||
if (errata_120()) {
|
||||
*(volatile uint32_t *)0x40029640ul = 0x200ul;
|
||||
}
|
||||
|
||||
/* Configure GPIO pads as pPin Reset pin if Pin Reset capabilities
|
||||
* desired.
|
||||
* If CONFIG_GPIO_AS_PINRESET is not defined, pin reset will not be
|
||||
* available. One GPIO (see Product Specification to see which one) will
|
||||
* then be reserved for PinReset and not available as normal GPIO.
|
||||
*/
|
||||
#if defined(CONFIG_GPIO_AS_PINRESET)
|
||||
if (((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) !=
|
||||
(UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos)) ||
|
||||
((NRF_UICR->PSELRESET[1] & UICR_PSELRESET_CONNECT_Msk) !=
|
||||
(UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos))) {
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {
|
||||
}
|
||||
NRF_UICR->PSELRESET[0] = 18;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {
|
||||
}
|
||||
NRF_UICR->PSELRESET[1] = 18;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {
|
||||
}
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {
|
||||
}
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
#endif
|
||||
/* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin
|
||||
* will be used as GPIO (see Product Specification to see which one).
|
||||
*/
|
||||
#if defined(ENABLE_SWO)
|
||||
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
||||
NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Serial <<
|
||||
CLOCK_TRACECONFIG_TRACEMUX_Pos;
|
||||
NRF_P1->PIN_CNF[0] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos)
|
||||
| (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
|
||||
(GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
|
||||
#endif
|
||||
/* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE
|
||||
* pins will be used as GPIOs (see Product Specification to see which
|
||||
* ones).
|
||||
*/
|
||||
#if defined(ENABLE_TRACE)
|
||||
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
||||
NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Parallel <<
|
||||
CLOCK_TRACECONFIG_TRACEMUX_Pos;
|
||||
NRF_P0->PIN_CNF[7] = (GPIO_PIN_CNF_DRIVE_H0H1 <<
|
||||
GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect <<
|
||||
GPIO_PIN_CNF_INPUT_Pos) |
|
||||
(GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
|
||||
NRF_P1->PIN_CNF[0] = (GPIO_PIN_CNF_DRIVE_H0H1 <<
|
||||
GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect <<
|
||||
GPIO_PIN_CNF_INPUT_Pos) |
|
||||
(GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
|
||||
NRF_P0->PIN_CNF[12] = (GPIO_PIN_CNF_DRIVE_H0H1 <<
|
||||
GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect <<
|
||||
GPIO_PIN_CNF_INPUT_Pos) |
|
||||
(GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
|
||||
NRF_P0->PIN_CNF[11] = (GPIO_PIN_CNF_DRIVE_H0H1 <<
|
||||
GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect <<
|
||||
GPIO_PIN_CNF_INPUT_Pos) |
|
||||
(GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
|
||||
NRF_P1->PIN_CNF[9] = (GPIO_PIN_CNF_DRIVE_H0H1 <<
|
||||
GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect <<
|
||||
GPIO_PIN_CNF_INPUT_Pos) |
|
||||
(GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_SOC_NRF52840 */
|
||||
|
||||
uint32_t SystemCoreClock __used = __SYSTEM_CLOCK_64M;
|
||||
|
||||
static void clock_init(void)
|
||||
|
@ -219,6 +352,45 @@ static int nordicsemi_nrf52_init(struct device *arg)
|
|||
#ifdef CONFIG_SOC_NRF52832
|
||||
nordicsemi_nrf52832_init();
|
||||
#endif
|
||||
#ifdef CONFIG_SOC_NRF52840
|
||||
nordicsemi_nrf52840_init();
|
||||
#endif
|
||||
/* Enable the FPU if the compiler used floating point unit
|
||||
* instructions. Since the FPU consumes energy, remember to
|
||||
* disable FPU use in the compiler if floating point unit
|
||||
* operations are not used in your code.
|
||||
*/
|
||||
#if defined(CONFIG_FLOAT)
|
||||
SCB->CPACR |= (3UL << 20) | (3UL << 22);
|
||||
__DSB();
|
||||
__ISB();
|
||||
#endif
|
||||
|
||||
/* Configure NFCT pins as GPIOs if NFCT is not to be used in
|
||||
* your code. If CONFIG_NFCT_PINS_AS_GPIOS is not defined,
|
||||
* two GPIOs (see Product Specification to see which ones)
|
||||
* will be reserved for NFC and will not be available as
|
||||
* normal GPIOs.
|
||||
*/
|
||||
#if defined(CONFIG_NFCT_PINS_AS_GPIOS)
|
||||
if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) ==
|
||||
(UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)) {
|
||||
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {
|
||||
;
|
||||
}
|
||||
NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {
|
||||
;
|
||||
}
|
||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
|
||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {
|
||||
;
|
||||
}
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Reset all faults */
|
||||
_ScbMemFaultAllFaultsReset();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue