/*
 * 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.
 */

/**
 * @file
 * @brief System/hardware module for Nordic Semiconductor nRF52 family processor
 *
 * This module provides routines to initialize and support board-level hardware
 * for the Nordic Semiconductor nRF52 family processor.
 */

#include <nanokernel.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 "system_nrf52.h"

#define __SYSTEM_CLOCK_64M (64000000UL)

static bool ftpan_32(void);
static bool ftpan_37(void);
static bool ftpan_36(void);

uint32_t SystemCoreClock __used = __SYSTEM_CLOCK_64M;

static void clock_init(void)
{
	SystemCoreClock = __SYSTEM_CLOCK_64M;
}

static int nordicsemi_nrf52_init(struct device *arg)
{
	uint32_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();

	/* Setup the vector table offset register (VTOR),
	* which is located at the beginning of flash area.
	*/
	_scs_relocate_vector_table((void *)CONFIG_FLASH_BASE_ADDRESS);

	/* Workaround for FTPAN-32 "DIF: Debug session automatically
	* enables TracePort pins" found at Product Anomaly document
	* for your device located at https://www.nordicsemi.com/
	*/
	if (ftpan_32()) {
		CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk;
	}

	/* Workaround for FTPAN-37 "AMLI: EasyDMA is slow with Radio,
	* ECB, AAR and CCM." found at Product Anomaly document
	* for your device located at https://www.nordicsemi.com/
	*/
	if (ftpan_37()) {
		*(volatile uint32_t *)0x400005A0 = 0x3;
	}

	/* Workaround for FTPAN-36 "CLOCK: Some registers are not
	* reset when expected." found at Product Anomaly document
	* for your device located at https://www.nordicsemi.com/
	*/
	if (ftpan_36()) {
		NRF_CLOCK->EVENTS_DONE = 0;
		NRF_CLOCK->EVENTS_CTTO = 0;
	}

	/* Enable the FPU if the compiler used floating point unit
	* instructions. __FPU_USED is a MACRO defined by the
	* compiler. 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 (__FPU_USED == 1)

	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
	* 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[0] & 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] = 21;
		while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {
			;
		}
		NRF_UICR->PSELRESET[1] = 21;
		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;
	#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;
	#endif

	/* Clear all faults */
	_ScbMemFaultAllFaultsReset();
	_ScbBusFaultAllFaultsReset();
	_ScbUsageFaultAllFaultsReset();

	_ScbHardFaultAllFaultsReset();

	/* Setup master clock */
	clock_init();

	/* 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_32(void)
{
	if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) &&
	    (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) {
		if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30) &&
		    (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) {
			return true;
		}
	}

	return false;
}

static bool ftpan_37(void)
{
	if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) &&
	    (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) {
		if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30) &&
		    (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) {
			return true;
		}
	}

	return false;
}

static bool ftpan_36(void)
{
	if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) &&
	    (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) {
		if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30) &&
		    (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) {
			return true;
		}
	}

	return false;
}

SYS_INIT(nordicsemi_nrf52_init, PRIMARY, 0);
