blob: f6e313a537037f2c387d9af8340a387ccd9932d7 (
plain)
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
|
#include <fe_global.h>
#include <fe_config_backend.h>
#include <bootloader.h>
#include <core_cm4.h>
typedef void (*void_func)(void);
extern int _Flash_Base;
size_t flash_base = (size_t)&_Flash_Base;
extern int _Flash_Size;
size_t flash_size = (size_t)&_Flash_Size;
extern int _Bootloader_Size;
size_t bootloader_size = (size_t)&_Bootloader_Size;
bool fe_check_img_valid(void) {
uint32_t *end_of_flash = (uint32_t *)(flash_base + flash_size);
end_of_flash -= 1;
return *end_of_flash != 0xffffffff;
}
void fe_jump_to_application() {
uint32_t *user_isr_vector = (uint32_t *)flash_base;
void_func user_reset_vector = (void_func)user_isr_vector[1];
SCB->VTOR = (uint32_t)flash_base;
__set_MSP(user_isr_vector[0]);
user_reset_vector();
}
void fe_system_reset(void) {
SCB->AIRCR |= SCB_AIRCR_SYSRESETREQ_Msk;
}
void flash_unlock() {
FLASH->KEYR = 0x45670123;
FLASH->KEYR = 0xCDEF89AB;
}
void flash_lock() {
FLASH->CR |= FLASH_CR_LOCK;
}
int flash_erase_page(size_t addr) {
while (FLASH->SR & FLASH_SR_BSY)
;
FLASH->CR |= FLASH_CR_PER;
FLASH->AR = addr;
FLASH->CR |= FLASH_CR_STRT;
/* RM0365, pg. 63: The software should start checking if the BSY bit equals ‘0’ at least one CPU cycle after setting
* the STRT bit */
asm volatile ("nop");
while (FLASH->SR & FLASH_SR_BSY)
;
if (FLASH->SR & FLASH_SR_EOP) {
FLASH->SR = FLASH_SR_EOP;
return 0;
}
return -1;
}
int flash_write(size_t addr, char *buf, size_t len) {
assert((len&1) == 0);
assert((addr&1) == 0);
uint16_t *dst = (uint16_t *)addr;
uint16_t *src = (uint16_t *)src;
len /= 2;
while (len--) {
*dst++ = *src++;
while (FLASH->SR & FLASH_SR_BSY)
;
}
if (FLASH->SR & FLASH_SR_EOP)
FLASH->SR = FLASH_SR_EOP;
else
return 1;
return 0;
}
int erase_user_flash() {
assert ((_Bootloader_Size & (PAGE_SIZE-1)) == 0);
size_t first_page = _Flash_Base + _Bootloader_Size;
size_t npages = (_Flash_Size - _Bootloader_Size) / PAGE_SIZE;
int rc = 0;
while (npages--)
rc |= flash_erase_page(first_page + npages); /* TODO error handling */
return rc;
}
|