/* * Copyright (C) 2015 Jan Wagner * 2016 Freie Universität Berlin * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. */ /** * @ingroup cpu_nrf52 * @{ * * @file * @brief Implementation of the CPU initialization * * @author Hauke Petersen * @author Jan Wagner * * @} */ #define DONT_OVERRIDE_NVIC #include "cpu.h" #include "periph_conf.h" /* FTPAN helper functions */ static bool ftpan_32(void); static bool ftpan_37(void); static bool ftpan_36(void); #ifdef SOFTDEVICE_PRESENT #include "softdevice_handler.h" uint8_t _ble_evt_buffer[BLE_STACK_EVT_MSG_BUF_SIZE]; #endif /** * @brief Initialize the CPU, set IRQ priorities */ void cpu_init(void) { /* Workaround for FTPAN-32 * "DIF: Debug session automatically enables TracePort pins." */ if (ftpan_32()) { CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk; } /* Workaround for FTPAN-37 * "AMLI: EasyDMA is slow with Radio, ECB, AAR and CCM." */ if (ftpan_37()) { *(volatile uint32_t *)0x400005A0 = 0x3; } /* Workaround for FTPAN-36 * "CLOCK: Some registers are not reset when expected." */ if (ftpan_36()) { NRF_CLOCK->EVENTS_DONE = 0; NRF_CLOCK->EVENTS_CTTO = 0; } /* set the correct clock source for HFCLK */ #if (CLOCK_CRYSTAL == 32) NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos); NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; NRF_CLOCK->TASKS_HFCLKSTART = 1; while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0); #endif /* softdevice needs to be enabled from ISR context */ #ifdef SOFTDEVICE_PRESENT softdevice_handler_init(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, &_ble_evt_buffer, BLE_STACK_EVT_MSG_BUF_SIZE, NULL); #endif /* call cortexm default initialization */ cortexm_init(); #ifdef SOFTDEVICE_PRESENT /* fixup swi0 (used as softdevice PendSV trampoline) */ NVIC_EnableIRQ(SWI0_EGU0_IRQn); NVIC_SetPriority(SWI0_EGU0_IRQn, 6); #endif } /** * @brief Check workaround for FTPAN-32 */ 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; } /** * @brief Check workaround for FTPAN-36 */ 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; } /** * @brief Check workaround for FTPAN-37 */ 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; }