257 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			257 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|   | /*
 | ||
|  | 
 | ||
|  | Copyright (c) 2009-2017 ARM Limited. All rights reserved. | ||
|  | 
 | ||
|  |     SPDX-License-Identifier: Apache-2.0 | ||
|  | 
 | ||
|  | 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 | ||
|  | 
 | ||
|  |     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. | ||
|  | 
 | ||
|  | NOTICE: This file has been modified by Nordic Semiconductor ASA. | ||
|  | 
 | ||
|  | */ | ||
|  | 
 | ||
|  | /* NOTE: Template files (including this one) are application specific and therefore expected to
 | ||
|  |    be copied into the application project folder prior to its use! */ | ||
|  |     | ||
|  | #include <stdint.h>
 | ||
|  | #include <stdbool.h>
 | ||
|  | #include "nrf.h"
 | ||
|  | #include "system_nrf52840.h"
 | ||
|  | 
 | ||
|  | /*lint ++flb "Enter library region" */ | ||
|  | 
 | ||
|  | #define __SYSTEM_CLOCK_64M      (64000000UL)
 | ||
|  | 
 | ||
|  | static bool errata_36(void); | ||
|  | static bool errata_66(void); | ||
|  | static bool errata_98(void); | ||
|  | static bool errata_103(void); | ||
|  | static bool errata_115(void); | ||
|  | static bool errata_120(void); | ||
|  | static bool errata_136(void); | ||
|  | 
 | ||
|  | 
 | ||
|  | #if defined ( __CC_ARM )
 | ||
|  |     uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M; | ||
|  | #elif defined ( __ICCARM__ )
 | ||
|  |     __root uint32_t SystemCoreClock = __SYSTEM_CLOCK_64M; | ||
|  | #elif defined ( __GNUC__ )
 | ||
|  |     uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M; | ||
|  | #endif
 | ||
|  | 
 | ||
|  | void SystemCoreClockUpdate(void) | ||
|  | { | ||
|  |     SystemCoreClock = __SYSTEM_CLOCK_64M; | ||
|  | } | ||
|  | 
 | ||
|  | void SystemInit(void) | ||
|  | { | ||
|  |     /* 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
 | ||
|  |      | ||
|  |     /* 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 66 "TEMP: Linearity specification not met with default settings" found at the Errata document
 | ||
|  |        for your device located at https://infocenter.nordicsemi.com/  */
 | ||
|  |     if (errata_66()){ | ||
|  |         NRF_TEMP->A0 = NRF_FICR->TEMP.A0; | ||
|  |         NRF_TEMP->A1 = NRF_FICR->TEMP.A1; | ||
|  |         NRF_TEMP->A2 = NRF_FICR->TEMP.A2; | ||
|  |         NRF_TEMP->A3 = NRF_FICR->TEMP.A3; | ||
|  |         NRF_TEMP->A4 = NRF_FICR->TEMP.A4; | ||
|  |         NRF_TEMP->A5 = NRF_FICR->TEMP.A5; | ||
|  |         NRF_TEMP->B0 = NRF_FICR->TEMP.B0; | ||
|  |         NRF_TEMP->B1 = NRF_FICR->TEMP.B1; | ||
|  |         NRF_TEMP->B2 = NRF_FICR->TEMP.B2; | ||
|  |         NRF_TEMP->B3 = NRF_FICR->TEMP.B3; | ||
|  |         NRF_TEMP->B4 = NRF_FICR->TEMP.B4; | ||
|  |         NRF_TEMP->B5 = NRF_FICR->TEMP.B5; | ||
|  |         NRF_TEMP->T0 = NRF_FICR->TEMP.T0; | ||
|  |         NRF_TEMP->T1 = NRF_FICR->TEMP.T1; | ||
|  |         NRF_TEMP->T2 = NRF_FICR->TEMP.T2; | ||
|  |         NRF_TEMP->T3 = NRF_FICR->TEMP.T3; | ||
|  |         NRF_TEMP->T4 = NRF_FICR->TEMP.T4; | ||
|  |     } | ||
|  |      | ||
|  |     /* 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; | ||
|  |     } | ||
|  |      | ||
|  |     /* Workaround for Errata 136 "System: Bits in RESETREAS are set when they should not be" found at the Errata document
 | ||
|  |        for your device located at https://infocenter.nordicsemi.com/  */
 | ||
|  |     if (errata_136()){ | ||
|  |         if (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk){ | ||
|  |             NRF_POWER->RESETREAS =  ~POWER_RESETREAS_RESETPIN_Msk; | ||
|  |         } | ||
|  |     } | ||
|  |      | ||
|  |     /* 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[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
 | ||
|  | 
 | ||
|  |     SystemCoreClockUpdate(); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | static bool errata_36(void) | ||
|  | { | ||
|  |     if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul)){ | ||
|  |         return true; | ||
|  |     } | ||
|  |      | ||
|  |     return false; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | static bool errata_66(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 bool errata_136(void) | ||
|  | { | ||
|  |     if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul)){ | ||
|  |         return true; | ||
|  |     } | ||
|  |      | ||
|  |     return false; | ||
|  | } | ||
|  | 
 | ||
|  | /*lint --flb "Leave library region" */ |