Skip to content

Commit 00ffe94

Browse files
karlpBOJIT
authored andcommitted
stm32l0/l1: flash: support half page flashing
Tested on L1 and L0 using the "dapboot" project, see devanlai/dapboot#27 for L1 and devanlai/dapboot#30 for L0
1 parent 9e9b799 commit 00ffe94

File tree

4 files changed

+46
-1
lines changed

4 files changed

+46
-1
lines changed

include/libopencm3/stm32/common/flash_common_l01.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,19 @@ void flash_unlock_progmem(void);
120120
void flash_lock_progmem(void);
121121
void flash_lock_option_bytes(void);
122122
void flash_unlock_acr(void);
123+
/** Erase a page in flash.
124+
* @param page_address For L1, must be first word in page, L0 doesn't care
125+
* Takes 1 tprog. Flash must already be unlocked!
126+
*/
127+
void flash_erase_page(uint32_t page_address);
128+
129+
/**
130+
* Write a half page from buf to dst.
131+
* This function _must_ be in ram! (See the Ref Man for more details)
132+
* @param dst where to write to, expected to be aligned and erased.
133+
* @param buf the half page to write, size required depends on target
134+
*/
135+
void flash_program_half_page(uint32_t *dst, void *buf);
123136

124137
void eeprom_program_word(uint32_t address, uint32_t data);
125138
void eeprom_program_words(uint32_t address, uint32_t *data, int length_in_words);

include/libopencm3/stm32/l0/flash.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@
5555
/* --- FLASH_OPTR values ----------------------------------------------------- */
5656
#define FLASH_OPTR_NBOOT1 (1 << 31)
5757

58+
#define FLASH_HALF_PAGE_SIZE 16
59+
5860
BEGIN_DECLS
5961

6062
END_DECLS

include/libopencm3/stm32/l1/flash.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
/* --- FLASH_SR values ----------------------------------------------------- */
5757
#define FLASH_SR_OPTVERRUSR (1 << 12)
5858

59-
/* --- Function prototypes ------------------------------------------------- */
59+
#define FLASH_HALF_PAGE_SIZE 32
6060

6161
BEGIN_DECLS
6262

lib/stm32/common/flash_common_l01.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,36 @@ void flash_unlock_acr(void)
9797
FLASH_PDKEYR = FLASH_PDKEYR_PDKEY2;
9898
}
9999

100+
/**
101+
* Erase a page in ram.
102+
* @param page_address must be first word in page for L1, any address in page for L0
103+
*/
104+
void flash_erase_page(uint32_t page_address)
105+
{
106+
FLASH_PECR |= FLASH_PECR_ERASE | FLASH_PECR_PROG;
107+
MMIO32(page_address) = 0;
108+
while ((FLASH_SR & FLASH_SR_BSY) == FLASH_SR_BSY);
109+
FLASH_PECR &= ~(FLASH_PECR_ERASE | FLASH_PECR_PROG);
110+
}
111+
112+
/* Must be run from RAM (per ref manual), and because it's in ram, more
113+
* than 64MB away from flash address space, must be a long_call. */
114+
__attribute__ ((long_call, section (".ramtext")))
115+
void flash_program_half_page(uint32_t *dst, void *buf)
116+
{
117+
uint32_t *src = buf;
118+
119+
/* Enable half page writes to program memory */
120+
FLASH_PECR |= FLASH_PECR_FPRG | FLASH_PECR_PROG;
121+
while ((FLASH_SR & FLASH_SR_BSY) == FLASH_SR_BSY);
122+
for (int i = 0; i < FLASH_HALF_PAGE_SIZE; i++) {
123+
*dst++ = *src++;
124+
}
125+
while ((FLASH_SR & FLASH_SR_BSY) == FLASH_SR_BSY);
126+
FLASH_PECR &= ~(FLASH_PECR_FPRG | FLASH_PECR_PROG);
127+
}
128+
129+
100130
/** @brief Write a word to eeprom
101131
*
102132
* @param address assumed to be in the eeprom space, no checking

0 commit comments

Comments
 (0)