blob: db9bacb75f328651d55fbdc5e300111402a29faf [file] [log] [blame]
/*
* Copyright (c) 2016 Nordic Semiconductor ASA
* Copyright (c) 2016 Linaro Limited
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief System/hardware module for Nordic Semiconductor nRF51 family processor
*
* This module provides routines to initialize and support board-level hardware
* for the Nordic Semiconductor nRF51 family processor.
*/
#include <kernel.h>
#include <device.h>
#include <init.h>
#include <soc.h>
#ifdef CONFIG_RUNTIME_NMI
extern void _NmiInit(void);
#define NMI_INIT() _NmiInit()
#else
#define NMI_INIT()
#endif
#include "nrf.h"
#define __SYSTEM_CLOCK (16000000UL)
static bool ftpan_26(void);
static bool ftpan_59(void);
uint32_t SystemCoreClock __used = __SYSTEM_CLOCK;
static int nordicsemi_nrf51_init(struct device *arg)
{
u32_t key;
ARG_UNUSED(arg);
/* Note:
* Magic numbers below are obtained by reading the registers
* when the SoC was running the SAM-BA bootloader
* (with reserved bits set to 0).
*/
key = irq_lock();
/* Prepare the peripherals for use as indicated by the PAN 26 "System:
* Manual setup is required to enable the use of peripherals" found at
* Product Anomaly document for your device found at
* https://www.nordicsemi.com/. The side effect of executing these
* instructions in the devices that do not need it is that the new
* peripherals in the second generation devices (LPCOMP for example)
* will not be available.
*/
if (ftpan_26()) {
*(volatile u32_t *)0x40000504 = 0xC007FFDF;
*(volatile u32_t *)0x40006C18 = 0x00008000;
}
/* Disable PROTENSET registers under debug, as indicated by PAN 59
* "MPU: Reset value of DISABLEINDEBUG register is incorrect" found
* at Product Anomaly document for your device found at
* https://www.nordicsemi.com/.
*/
if (ftpan_59()) {
NRF_MPU->DISABLEINDEBUG =
MPU_DISABLEINDEBUG_DISABLEINDEBUG_Disabled <<
MPU_DISABLEINDEBUG_DISABLEINDEBUG_Pos;
}
/* Install default handler that simply resets the CPU
* if configured in the kernel, NOP otherwise
*/
NMI_INIT();
irq_unlock(key);
return 0;
}
static bool ftpan_26(void)
{
if ((((*(u32_t *)0xF0000FE0) & 0x000000FF) == 0x1) &&
(((*(u32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) {
if ((((*(u32_t *)0xF0000FE8) & 0x000000F0) == 0x00) &&
(((*(u32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) {
return true;
}
if ((((*(u32_t *)0xF0000FE8) & 0x000000F0) == 0x10) &&
(((*(u32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) {
return true;
}
if ((((*(u32_t *)0xF0000FE8) & 0x000000F0) == 0x30) &&
(((*(u32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) {
return true;
}
}
return false;
}
static bool ftpan_59(void)
{
if ((((*(u32_t *)0xF0000FE0) & 0x000000FF) == 0x1) &&
(((*(u32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) {
if ((((*(u32_t *)0xF0000FE8) & 0x000000F0) == 0x40) &&
(((*(u32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) {
return true;
}
}
return false;
}
SYS_INIT(nordicsemi_nrf51_init, PRE_KERNEL_1, 0);