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}