-
Notifications
You must be signed in to change notification settings - Fork 64
/
Copy pathflasher.c
105 lines (85 loc) · 2.37 KB
/
flasher.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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include "bl.h"
#include <libopencm3/stm32/flash.h>
#include <libopencm3/cm3/nvic.h>
#include <libopencm3/cm3/cortex.h>
#include <string.h>
#define BINDATA_SIZE (32 * 1024)
extern const uint8_t bindata[];
extern uint32_t vector_table[];
void flushFlash(void) {}
void delay(unsigned msec) {
int k = msec * 15000;
while (k--)
asm("nop");
}
void flash_bootloader(void) {
cm_disable_interrupts();
flash_unlock();
uint32_t dst = 0x08000000;
if (memcmp((void *)dst, bindata, BINDATA_SIZE) == 0) {
if (hasScreen()) {
screen_init();
print(3, 3, 6, "You already have\nthis bootloader");
print(3, 100, 5, "Press reset");
draw_screen();
}
for (;;) {
led_off(LED_ACTIVITY);
delay(500);
led_on(LED_ACTIVITY);
delay(100);
led_off(LED_ACTIVITY);
delay(100);
led_on(LED_ACTIVITY);
delay(100);
}
}
uint32_t optcr = FLASH_OPTCR;
optcr &= ~0x80000000;
optcr |= 0x00030000;
if (FLASH_OPTCR != optcr) {
flash_program_option_bytes(optcr);
resetIntoApp();
}
// erase bootloader
flash_erase_sector(0, FLASH_CR_PROGRAM_X32);
flash_erase_sector(1, FLASH_CR_PROGRAM_X32);
for (int i = 0; i < BINDATA_SIZE; i += 4) {
flash_program_word(dst + i, *(uint32_t *)(bindata + i));
}
if (memcmp((void *)dst, bindata, BINDATA_SIZE) != 0) {
if (hasScreen()) {
screen_init();
print(3, 3, 6, "Failed to erase!");
draw_screen();
}
for (;;) {
led_off(LED_ACTIVITY);
delay(300);
led_on(LED_ACTIVITY);
delay(300);
}
}
// self-destruct
flash_program_word((uint32_t)vector_table, 0);
flash_program_word((uint32_t)vector_table + 4, 0);
if (lookupCfg(CFG_BOOTLOADER_PROTECTION, 0)) {
// write-protect
optcr &= ~0x00030000;
flash_program_option_bytes(optcr);
}
if (hasScreen()) {
screen_init();
print(3, 3, 6, "Bootloader updated!");
print4(3, 40, 4, "Yay:)");
print(3, 100, 5, "Press reset");
draw_screen();
}
for (;;) {
led_off(LED_ACTIVITY);
delay(300);
led_on(LED_ACTIVITY);
delay(100);
}
// resetIntoBootloader();
}