2021-04-07 23:14:45 +02:00
|
|
|
#include "flash-writer.h"
|
|
|
|
#include <stm32/stm32f4xx.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
|
|
|
static bool flash_op_busy(void)
|
|
|
|
{
|
|
|
|
return !!(FLASH->SR & FLASH_SR_BSY);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void lock_flash_cr(void)
|
|
|
|
{
|
|
|
|
FLASH->CR |= FLASH_CR_LOCK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void flash_writer_enable_access(void)
|
|
|
|
{
|
|
|
|
const uint32_t key1 = 0x45670123UL;
|
|
|
|
const uint32_t key2 = 0xCDEF89ABUL;
|
|
|
|
|
|
|
|
FLASH->KEYR = key1;
|
|
|
|
FLASH->KEYR = key2;
|
|
|
|
}
|
|
|
|
|
|
|
|
void flash_writer_perform_mass_erase(void)
|
|
|
|
{
|
|
|
|
flash_writer_enable_access();
|
|
|
|
while (flash_op_busy());
|
|
|
|
|
|
|
|
FLASH->CR = DMA_SxCR_PSIZE_1;
|
|
|
|
FLASH->CR |= FLASH_CR_MER;
|
|
|
|
FLASH->CR |= FLASH_CR_STRT;
|
|
|
|
|
|
|
|
while(flash_op_busy());
|
|
|
|
lock_flash_cr();
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t flash_writer_get_flash_size(void)
|
|
|
|
{
|
|
|
|
uint32_t flash_size;
|
2021-04-08 21:23:25 +02:00
|
|
|
const uint16_t *flash_size_ptr = (const uint16_t *)0x1FFF7A22UL;
|
2021-04-07 23:14:45 +02:00
|
|
|
|
2021-04-08 21:23:25 +02:00
|
|
|
flash_size = (uint32_t)*flash_size_ptr;
|
2021-04-07 23:14:45 +02:00
|
|
|
flash_size *= 1024;
|
|
|
|
|
|
|
|
return flash_size;
|
|
|
|
}
|
|
|
|
|
2021-04-08 21:23:25 +02:00
|
|
|
int flash_writer_write_to_memory(void *dest, const void *src, uint32_t size)
|
2021-04-07 23:14:45 +02:00
|
|
|
{
|
|
|
|
uint32_t full_word_cnt;
|
|
|
|
uint32_t byte_cnt;
|
|
|
|
uint32_t idx;
|
2021-04-08 21:23:25 +02:00
|
|
|
const uint32_t *word_src_ptr;
|
2021-04-07 23:14:45 +02:00
|
|
|
uint32_t *word_dest_ptr;
|
2021-04-08 21:23:25 +02:00
|
|
|
const char *char_src_ptr;
|
2021-04-07 23:14:45 +02:00
|
|
|
char *char_dest_ptr;
|
|
|
|
|
|
|
|
flash_writer_enable_access();
|
|
|
|
while (flash_op_busy());
|
|
|
|
|
|
|
|
/* Do the full words */
|
|
|
|
full_word_cnt = size / 4u;
|
|
|
|
byte_cnt = size % 4;
|
|
|
|
|
|
|
|
word_dest_ptr = dest;
|
|
|
|
word_src_ptr = src;
|
|
|
|
|
|
|
|
if (full_word_cnt) {
|
|
|
|
FLASH->CR = FLASH_CR_PSIZE_1;
|
|
|
|
FLASH->CR |= FLASH_CR_PG;
|
|
|
|
|
|
|
|
for (idx = 0; idx < full_word_cnt; idx++) {
|
|
|
|
*word_dest_ptr = *word_src_ptr;
|
|
|
|
word_dest_ptr++;
|
|
|
|
word_src_ptr++;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (flash_op_busy());
|
|
|
|
FLASH->CR = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* write remaining bytes */
|
|
|
|
if (byte_cnt) {
|
|
|
|
char_src_ptr = (char *)word_src_ptr;
|
|
|
|
char_dest_ptr = (char *)word_dest_ptr;
|
|
|
|
|
|
|
|
FLASH->CR = 0;
|
|
|
|
FLASH->CR |= FLASH_CR_PG;
|
|
|
|
|
|
|
|
for (idx = 0; idx < byte_cnt; idx++) {
|
|
|
|
*char_dest_ptr = *char_src_ptr;
|
|
|
|
char_dest_ptr++;
|
|
|
|
char_src_ptr++;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (flash_op_busy());
|
|
|
|
FLASH->CR = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
lock_flash_cr();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t flash_writer_get_base_address(void)
|
|
|
|
{
|
|
|
|
return FLASH_BASE;
|
|
|
|
}
|