From 332bd132cf41b382860907fd80d92cc31d12c6b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Sun, 8 Oct 2017 18:59:26 +0200 Subject: [PATCH] lib/flash_internal: re-add used library --- lib/flash_internal.c | 121 +++++++++++++++++++++++++++++++++++++++++++ lib/flash_internal.h | 36 +++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 lib/flash_internal.c create mode 100644 lib/flash_internal.h diff --git a/lib/flash_internal.c b/lib/flash_internal.c new file mode 100644 index 0000000..f149cf0 --- /dev/null +++ b/lib/flash_internal.c @@ -0,0 +1,121 @@ +/* This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +/** library to read/write internal flash (code) + * @file flash_internal.c + * @author King Kévin + * @date 2016 + * @note peripherals used: none + */ +/* standard libraries */ +#include // standard integer types +#include // general utilities + +/* STM32 (including CM3) libraries */ +#include // device signature utilities +#include // flash utilities + +#include "flash_internal.h" // flash storage library API +#include "global.h" // global definitions + +/** the flash page size (medium-density devices have 1KiB page size) */ +#define PAGE_SIZE 1024 + +bool flash_internal_read(uint32_t address, uint8_t *buffer, size_t size) +{ + // verify it's in the flash area and do other sanity checks + if (address(UINT32_MAX-size) || (address+size)>(FLASH_BASE+DESIG_FLASH_SIZE*1024) || buffer==NULL || size==0) { + return false; + } + + // copy data byte per byte (a more efficient way would be to copy words, than the remaining bytes) + for (size_t i=0; i(UINT32_MAX-size) || (address+size)>(FLASH_BASE+DESIG_FLASH_SIZE*1024) || buffer==NULL || size==0 || size%2) { + return false; + } + + flash_unlock(); // unlock flash to be able to write it + while (size) { // write page by page until all data has been written + uint32_t page_start = address-(address%PAGE_SIZE); // get start of the current page + bool erase = false; // verify if the flash to write is erased of if we need to erase the page + for (uint32_t flash=address; flash<(address+size) && flash<(page_start+PAGE_SIZE); flash += 2) { // go through page + if (*(uint16_t*)(flash)!=0xffff) { // is flash not erased + erase = true; // the erase flash + } + } + if (erase) { // make copy of the page to erase and erase it + uint8_t page_data[PAGE_SIZE]; // a copy of the complete page before the erase it + uint16_t page_i = 0; // index for page data + // copy page before address + for (uint32_t flash=page_start; flash
0 && page_i0 && address<(page_start+PAGE_SIZE)) { + flash_program_half_word(address, *((uint16_t*)(buffer))); + if (flash_get_status_flags()!=FLASH_SR_EOP) { // operation went wrong + flash_lock(); // lock back flash to protect it + return false; + } + if (*((uint16_t*)address)!=*((uint16_t*)buffer)) { // verify the programmed data is right + flash_lock(); // lock back flash to protect it + return false; + } + buffer += 2; + address += 2; + size -= 2; + } + } + } + flash_lock(); // lock back flash to protect it + + return true; +} diff --git a/lib/flash_internal.h b/lib/flash_internal.h new file mode 100644 index 0000000..9908209 --- /dev/null +++ b/lib/flash_internal.h @@ -0,0 +1,36 @@ +/* This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +/** library to read/write internal flash (API) + * @file flash_internal.h + * @author King Kévin + * @date 2016-2017 + * @note peripherals used: none + */ +#pragma once + +/** read data from internal flash + * @param[in] address start address of the data to read + * @param[out] buffer where to store the read data + * @param[in] size how much data to read, in bytes + * @return if read succeeded + */ +bool flash_internal_read(uint32_t address, uint8_t *buffer, size_t size); +/** write data to internal flash + * @param[in] address start address where to write data to + * @param[in] buffer data to be written + * @param[in] size how much data to write, in bytes + * @return if write succeeded + */ +bool flash_internal_write(uint32_t address, uint8_t *buffer, size_t size);