-
Notifications
You must be signed in to change notification settings - Fork 44
/
Copy pathJumpToAppWithOffset.c
67 lines (56 loc) · 1.89 KB
/
JumpToAppWithOffset.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include "Arduino.h"
void jumpToApplicationAt0x38080() {
/* Load stack pointer and program counter from start of new program */
asm("movw r0, #0x8080");
asm("movt r0, #0x0003");
asm("ldr sp, [r0]");
asm("ldr pc, [r0, #4]");
}
void jumpToApplicationAt0x8080() {
/* Load stack pointer and program counter from start of new program */
asm("movw r0, #0x8080");
asm("ldr sp, [r0]");
asm("ldr pc, [r0, #4]");
}
/*
* These are the minimum peripherals that needed to be disabled to allow the
* uTasker USB-MSD application to work. You may need to reset more peripherals
* depending on the application you are running, and what other peripherals
* your sketch uses if you add more to this example than just blinking an LED
*/
void resetPeripherals() {
/* set (some of) USB back to normal */
NVIC_DISABLE_IRQ(IRQ_USBOTG);
NVIC_CLEAR_PENDING(IRQ_USBOTG);
SIM_SCGC4 &= ~(SIM_SCGC4_USBOTG);
/* disable all GPIO interrupts */
NVIC_DISABLE_IRQ(IRQ_PORTA);
NVIC_DISABLE_IRQ(IRQ_PORTB);
NVIC_DISABLE_IRQ(IRQ_PORTC);
NVIC_DISABLE_IRQ(IRQ_PORTD);
NVIC_DISABLE_IRQ(IRQ_PORTE);
/* set (some of) ADC1 back to normal */
// wait until calibration is complete
while (ADC1_SC3 & ADC_SC3_CAL);
// clear flag if calibration failed
if (ADC1_SC3 & 1 << 6)
ADC1_SC3 |= 1 << 6;
// clear conversion complete flag (which could trigger ISR otherwise)
if (ADC1_SC1A & 1 << 7)
ADC1_SC1A |= 1 << 7;
/* set some clocks back to default/reset settings */
MCG_C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(4);
SIM_CLKDIV1 = 0;
SIM_CLKDIV2 = 0;
}
void startup_late_hook(void) {
// look for the condition that indicates we want to jump to the application with offset
if (eeprom_read_byte(0) == 0xAE) {
// clear the condition
eeprom_write_byte(0, 0);
// set peripherals (mostly) back to normal then jump
__disable_irq();
resetPeripherals();
jumpToApplicationAt0x38080();
}
}