EVE 1.0
startup-nrf52.c
1 #include <stdio.h>
2 #include <stdint.h>
3 #include <dev/nvram.h>
4 #include <core/clk.h>
5 #include <core/uwork.h>
6 #include <contiki-conf.h>
7 #include <debug-uart.h>
8 #include <nrf_soc.h>
9 
10 extern uint8_t __bss_start__[];
11 extern uint8_t __bss_end__[];
12 extern uint32_t __isr_vector[];
13 extern void (*__preinit_array_start []) (void);
14 extern void (*__preinit_array_end []) (void);
15 extern void (*__init_array_start []) (void);
16 extern void (*__init_array_end []) (void);
17 
18 void _start(void) /*__attribute__((naked))*/;
19 
20 extern int main(void);
21 
22 static void
23 clear_bss(void)
24 {
25  uint8_t *m = __bss_start__;
26  while(m < __bss_end__) {
27  *m++ = 0;
28  }
29 }
30 
31 static void
32 enable_fault_exceptions(void)
33 {
34 #if 0
35  MPU_RegionInit_TypeDef flashInit = MPU_INIT_FLASH_DEFAULT;
36  MPU_RegionInit_TypeDef sramInit = MPU_INIT_SRAM_DEFAULT;
37  MPU_RegionInit_TypeDef peripheralInit = MPU_INIT_PERIPHERAL_DEFAULT;
38 
39  MPU_Disable();
40  /* TODO: Configure regions */
41  MPU_ConfigureRegion(&flashInit);
42  MPU_ConfigureRegion(&sramInit);
43  MPU_ConfigureRegion(&peripheralInit);
44  MPU_Enable(MPU_CTRL_PRIVDEFENA);
45 
46  SCB->SHCSR |= (SCB_SHCSR_MEMFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk
47  | SCB_SHCSR_USGFAULTENA_Msk);
48 #endif
49 }
50 
51 static void
52 select_clocks()
53 {
54 }
55 
56 #ifdef NRF52_ENABLE_SWO
57 static void setupSWO(void)
58 {
59  NRF_CLOCK->TRACECONFIG |= (CLOCK_TRACECONFIG_TRACEMUX_Serial << CLOCK_TRACECONFIG_TRACEMUX_Pos);
60  NRF_P0->PIN_CNF[18] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos)
61  | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos)
62  | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
63 }
64 #endif /* NRF52_ENABLE_SWO */
65 
66 static void libc_init(void)
67 {
68  unsigned Index, Count;
69 
70  Count = __preinit_array_end - __preinit_array_start;
71  for (Index = 0; Index < Count; Index++)
72  __preinit_array_start[Index]();
73 
74  Count = __init_array_end - __init_array_start;
75  for (Index = 0; Index < Count; Index++)
76  __init_array_start[Index]();
77 }
78 
79 void __attribute__((naked))
80 _start(void)
81 {
82  /* Init stack pointer */
83  __asm__ (
84  "ldr r3, =__isr_vector;"
85  "ldr sp, [r3];"
86  );
87 
88  /* Enable DC/DC */
89  //NRF_POWER->DCDCEN = POWER_DCDCEN_DCDCEN_Enabled;
90 
91  /* Setup core interrupt priorities */
92  NVIC_SetPriority(PendSV_IRQn, 0xFF);
93 
94 #ifdef NRF52_ENABLE_SWO
95  if (dbg_connected())
96  {
97  setupSWO();
98  }
99 #endif
100 
101  nvram_init();
102  clear_bss();
103  enable_fault_exceptions();
104  select_clocks();
105  uwork_init();
106  libc_init();
107 
108  main();
109  if (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk)
110  __BKPT(0);
111  NVIC_SystemReset();
112 }
113 
114 void
115 _xassert(const char *file, int lineno)
116 {
117  __disable_irq();
118  dbg_panic();
119  printf("Assertion failed: file %s, line %d.\n", file, lineno);
120  dbg_drain();
121 
122  if (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk)
123  __BKPT(0);
124  NVIC_SystemReset();
125 }
126 
127 void uip_log(char *msg)
128 {
129  printf("UIP: %s\r\n", msg);
130 }
131 
132 /* TODO: Implement handlers */
133 void
134 NMI_Handler(void)
135 {
136  __asm volatile (
137  " ldr r0, =%[cdbg] \n"
138  " ldr r0, [r0, %[dhcsr]]\n"
139  " lsls r0, r0, #31\n"
140  " bpl 3f \n"
141  " bkpt #0 \n"
142  "3: \n"
143  " b NVIC_SystemReset\n"
144  :
145  : [cdbg] "X" (CoreDebug)
146  , [dhcsr] "J" (offsetof(CoreDebug_Type, DHCSR))
147  );
148 }
149 
150 __attribute__((naked)) void
151 HardFault_Handler(void)
152 {
153  /*
154  Thanks to Erich Styger.
155  http://mcuoneclipse.com/2012/11/24/debugging-hard-faults-on-arm-cortex-m/
156  The assembly code checks which stack we are using (MSP or PSP),
157  and then loads the offending PC position on the stack into the register R1.
158  So R1 will contain the code address where the problem happened:
159  */
160  __asm volatile (
161  " movs r0, #4 \n"
162  " movs r1, lr \n"
163  " tst r0, r1 \n"
164  " beq 1f \n"
165  " mrs r0, psp \n"
166  " b 2f \n"
167  "1: \n"
168  " mrs r0, msp \n"
169  "2: \n"
170  " ldr r1, [r0,#24] \n"
171  " ldr r0, =%[cdbg] \n"
172  " ldr r0, [r0, %[dhcsr]]\n"
173  " lsls r0, r0, #31\n"
174  " bpl 3f \n"
175  " bkpt #0 \n"
176  "3: \n"
177  " b NVIC_SystemReset\n"
178  :
179  : [cdbg] "X" (CoreDebug)
180  , [dhcsr] "J" (offsetof(CoreDebug_Type, DHCSR))
181  );
182 }
183 
184 __attribute__((naked)) void
185 UsageFault_Handler(void)
186 {
187  /*
188  Thanks to Erich Styger.
189  http://mcuoneclipse.com/2012/11/24/debugging-hard-faults-on-arm-cortex-m/
190  The assembly code checks which stack we are using (MSP or PSP),
191  and then loads the offending PC position on the stack into the register R1.
192  So R1 will contain the code address where the problem happened:
193  */
194  __asm volatile (
195  " movs r0, #4 \n"
196  " movs r1, lr \n"
197  " tst r0, r1 \n"
198  " beq 1f \n"
199  " mrs r0, psp \n"
200  " b 2f \n"
201  "1: \n"
202  " mrs r0, msp \n"
203  "2: \n"
204  " ldr r1, [r0,#24] \n"
205  " ldr r0, =%[cdbg] \n"
206  " ldr r0, [r0, %[dhcsr]]\n"
207  " lsls r0, r0, #31\n"
208  " bpl 3f \n"
209  " bkpt #0 \n"
210  "3: \n"
211  " b NVIC_SystemReset\n"
212  :
213  : [cdbg] "X" (CoreDebug)
214  , [dhcsr] "J" (offsetof(CoreDebug_Type, DHCSR))
215  );
216 }
217 
218 void
219 MemManage_Handler(void)
220 {
221  __asm volatile (
222  " ldr r0, =%[cdbg] \n"
223  " ldr r0, [r0, %[dhcsr]]\n"
224  " lsls r0, r0, #31\n"
225  " bpl 3f \n"
226  " bkpt #0 \n"
227  "3: \n"
228  " b NVIC_SystemReset\n"
229  :
230  : [cdbg] "X" (CoreDebug)
231  , [dhcsr] "J" (offsetof(CoreDebug_Type, DHCSR))
232  );
233 }
234 
235 void
236 BusFault_Handler(void)
237 {
238  __asm volatile (
239  " ldr r0, =%[cdbg] \n"
240  " ldr r0, [r0, %[dhcsr]]\n"
241  " lsls r0, r0, #31\n"
242  " bpl 3f \n"
243  " bkpt #0 \n"
244  "3: \n"
245  " b NVIC_SystemReset\n"
246  :
247  : [cdbg] "X" (CoreDebug)
248  , [dhcsr] "J" (offsetof(CoreDebug_Type, DHCSR))
249  );
250 }
Driver of the nRF52 non-volatile RAM.
void uip_log(char *msg)
void uwork_init(void)
void nvram_init(void)
Name: nvram_init Initialize the NVRAM module.
__attribute__((always_inline)) static inline void swint_enable_indirect_adapter(swint_state_t *state)
Definition: work.h:245
Header file for the EVE clock management framework.
Header file for the EVE microsecond-scale work scheduling.