nrf52/crt1.rs
1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5use cortexm4f::{
6 initialize_ram_jump_to_main, nvic, scb, unhandled_interrupt, CortexM4F, CortexMVariant,
7};
8
9/*
10 * Adapted from crt1.c which was relicensed by the original author from
11 * GPLv3 to Apache 2.0.
12 * The original version of the file, under GPL can be found at
13 * https://github.com/SoftwareDefinedBuildings/stormport/blob/rebase0/tos/platforms/storm/stormcrt1.c
14 *
15 * Copyright 2016, Michael Andersen <m.andersen@eecs.berkeley.edu>
16 */
17
18extern "C" {
19 // _estack is not really a function, but it makes the types work
20 // You should never actually invoke it!!
21 fn _estack();
22}
23
24#[cfg_attr(
25 all(target_arch = "arm", target_os = "none"),
26 link_section = ".vectors"
27)]
28// used Ensures that the symbol is kept until the final binary
29#[cfg_attr(all(target_arch = "arm", target_os = "none"), used)]
30/// ARM Cortex M Vector Table
31pub static BASE_VECTORS: [unsafe extern "C" fn(); 16] = [
32 // Stack Pointer
33 _estack,
34 // Reset Handler
35 initialize_ram_jump_to_main,
36 // NMI
37 unhandled_interrupt,
38 // Hard Fault
39 CortexM4F::HARD_FAULT_HANDLER,
40 // Memory Management Fault
41 unhandled_interrupt,
42 // Bus Fault
43 unhandled_interrupt,
44 // Usage Fault
45 unhandled_interrupt,
46 // Reserved
47 unhandled_interrupt,
48 // Reserved
49 unhandled_interrupt,
50 // Reserved
51 unhandled_interrupt,
52 // Reserved
53 unhandled_interrupt,
54 // SVCall
55 CortexM4F::SVC_HANDLER,
56 // Reserved for Debug
57 unhandled_interrupt,
58 // Reserved
59 unhandled_interrupt,
60 // PendSv
61 unhandled_interrupt,
62 // SysTick
63 CortexM4F::SYSTICK_HANDLER,
64];
65
66#[cfg_attr(
67 all(target_arch = "arm", target_os = "none"),
68 link_section = ".vectors"
69)]
70// used Ensures that the symbol is kept until the final binary
71#[cfg_attr(all(target_arch = "arm", target_os = "none"), used)]
72pub static IRQS: [unsafe extern "C" fn(); 80] = [CortexM4F::GENERIC_ISR; 80];
73
74#[no_mangle]
75pub unsafe extern "C" fn init() {
76 // Apply early initialization workarounds for anomalies documented on
77 // 2015-12-11 nRF52832 Errata v1.2
78 // http://infocenter.nordicsemi.com/pdf/nRF52832_Errata_v1.2.pdf
79
80 // Workaround for Errata 12
81 // "COMP: Reference ladder not correctly callibrated" found at the Errate doc
82 *(0x40013540i32 as *mut u32) = (*(0x10000324i32 as *mut u32) & 0x1f00u32) >> 8i32;
83
84 // Workaround for Errata 16
85 // "System: RAM may be corrupt on wakeup from CPU IDLE" found at the Errata doc
86 *(0x4007c074i32 as *mut u32) = 3131961357u32;
87
88 // Workaround for Errata 31
89 // "CLOCK: Calibration values are not correctly loaded from FICR at reset"
90 // found at the Errata doc
91 *(0x4000053ci32 as *mut u32) = (*(0x10000244i32 as *mut u32) & 0xe000u32) >> 13i32;
92
93 // Only needed for preview hardware
94 // // Workaround for Errata 32
95 // // "DIF: Debug session automatically enables TracePort pins" found at the Errata doc
96 // // CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk;
97 // *(0xe000edfcu32 as (*mut u32)) &= !0x01000000,
98
99 // Workaround for Errata 36
100 // "CLOCK: Some registers are not reset when expected" found at the Errata doc
101 // NRF_CLOCK->EVENTS_DONE = 0;
102 // NRF_CLOCK->EVENTS_CTTO = 0;
103 // NRF_CLOCK->CTIV = 0;
104 // }
105
106 // Workaround for Errata 37
107 // "RADIO: Encryption engine is slow by default" found at the Errata document doc
108 *(0x400005a0i32 as *mut u32) = 0x3u32;
109
110 // Workaround for Errata 57
111 // "NFCT: NFC Modulation amplitude" found at the Errata doc
112 *(0x40005610i32 as *mut u32) = 0x5u32;
113 *(0x40005688i32 as *mut u32) = 0x1u32;
114 *(0x40005618i32 as *mut u32) = 0x0u32;
115 *(0x40005614i32 as *mut u32) = 0x3fu32;
116
117 // Workaround for Errata 66
118 // "TEMP: Linearity specification not met with default settings" found at the Errata doc
119 // NRF_TEMP->A0 = NRF_FICR->TEMP.A0;
120 // NRF_TEMP->A1 = NRF_FICR->TEMP.A1;
121 // NRF_TEMP->A2 = NRF_FICR->TEMP.A2;
122 // NRF_TEMP->A3 = NRF_FICR->TEMP.A3;
123 // NRF_TEMP->A4 = NRF_FICR->TEMP.A4;
124 // NRF_TEMP->A5 = NRF_FICR->TEMP.A5;
125 // NRF_TEMP->B0 = NRF_FICR->TEMP.B0;
126 // NRF_TEMP->B1 = NRF_FICR->TEMP.B1;
127 // NRF_TEMP->B2 = NRF_FICR->TEMP.B2;
128 // NRF_TEMP->B3 = NRF_FICR->TEMP.B3;
129 // NRF_TEMP->B4 = NRF_FICR->TEMP.B4;
130 // NRF_TEMP->B5 = NRF_FICR->TEMP.B5;
131 // NRF_TEMP->T0 = NRF_FICR->TEMP.T0;
132 // NRF_TEMP->T1 = NRF_FICR->TEMP.T1;
133 // NRF_TEMP->T2 = NRF_FICR->TEMP.T2;
134 // NRF_TEMP->T3 = NRF_FICR->TEMP.T3;
135 // NRF_TEMP->T4 = NRF_FICR->TEMP.T4;
136 // }
137
138 // Workaround for Errata 108
139 // "RAM: RAM content cannot be trusted upon waking up from System ON Idle
140 // or System OFF mode" found at the Errata doc
141 *(0x40000ee4i32 as *mut u32) = *(0x10000258i32 as *mut u32) & 0x4fu32;
142
143 // Explicitly tell the core where Tock's vector table is located. If Tock is the
144 // only thing on the chip then this is effectively a no-op. If, however, there is
145 // a bootloader present then we want to ensure that the vector table is set
146 // correctly for Tock. The bootloader _may_ set this for us, but it may not
147 // so that any errors early in the Tock boot process trap back to the bootloader.
148 // To be safe we unconditionally set the vector table.
149 scb::set_vector_table_offset(BASE_VECTORS.as_ptr().cast::<()>());
150
151 nvic::enable_all();
152}