-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathflasher.c
93 lines (75 loc) · 2.58 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
#include "ch.h"
#include "hal.h"
#include <string.h>
#include "portab.h"
#include "uf2cfg.h"
#include "bootloader.h"
#include "stm32h7xx_hal_flash.h"
#include "stm32h7xx_hal_flash_ex.h"
extern const unsigned long bindata_len;
extern const unsigned char bindata[];
/**
* Firmware version description on fixed flash address for bootloader
*/
__attribute__ ((section(".fwinfo"))) __attribute__((used))
const struct {
char fwversion[512];
uint32_t confightm[16];
} fwinfo = {
.fwversion = "Bootloader flasher\r\n",
};
void pre_clock_init(void) {}
int main(void) {
/*
* System initializations.
* - HAL initialization, this also initializes the configured device drivers
* and performs the board-specific initializations.
* - Kernel initialization, the main() function becomes a thread and the
* RTOS is active.
*/
halInit();
chSysInit();
palClearLine(PORTAB_FLASHER_LED);
uint32_t dst = 0x08000000;
if (memcmp((void *)dst, bindata, bindata_len) == 0) {
// already the same, don't flash
palSetLine(PORTAB_FLASHER_LED);
palClearLine(PORTAB_FLASHER_SKIP_LED);
chThdSleepMilliseconds(500);
reset_to_uf2_bootloader();
}
HAL_FLASH_Unlock();
// erase first sector
FLASH_EraseInitTypeDef eraseInit;
eraseInit.TypeErase = FLASH_TYPEERASE_SECTORS;
eraseInit.Banks = FLASH_BANK_1;
eraseInit.Sector = 0;
eraseInit.NbSectors = 1;
eraseInit.VoltageRange = FLASH_VOLTAGE_RANGE_3;
uint32_t sectorError = 0;
HAL_FLASHEx_Erase(&eraseInit, §orError);
// if (!is_blank(addr, size) | (sectorError != 0xffffffff))
// PANIC("failed to erase!");
for (uint32_t i = 0; i < bindata_len; i += 4) {
// flash_program_word(dst + i, *(uint32_t*)(src + i));
HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, dst + i,
(uint32_t)bindata + i);
palToggleLine(PORTAB_FLASHER_LED);
}
// TODO: implement error checking
// ccrc = CalcCRC32((uint8_t *)(SDRAM_BANK_ADDR + 0x010), flength);
// if (memcmp((void*)dst, src, len) != 0) {
// PANIC("failed to write");
// }
// self destruct
// note: writing flash that's not empty is dangerous, it could mess up ECC
// TODO: Check if this is safe
// For now disable self destruct, since it doesn't write flash if the bootloader is
// already equal it doesn't harm to run it again.
// uint32_t empty = 0;
// HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, APP_LOAD_ADDRESS, (uint32_t)&empty);
// HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, APP_LOAD_ADDRESS + 4, (uint32_t)&empty);
HAL_FLASH_Lock();
palClearLine(PORTAB_FLASHER_LED);
reset_to_uf2_bootloader();
}