From a563484f386bec7298d9b88c17128bc3939f5c57 Mon Sep 17 00:00:00 2001 From: TT Date: Mon, 17 Oct 2016 07:19:41 +0900 Subject: [PATCH] add missing flash.c, linker script in last commit --- STM32F072xB.ld | 96 +++++++++++++++++++++++++++++++++++++++++++++++++ flash.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 193 insertions(+) create mode 100644 STM32F072xB.ld create mode 100644 flash.c diff --git a/STM32F072xB.ld b/STM32F072xB.ld new file mode 100644 index 0000000..0e568f6 --- /dev/null +++ b/STM32F072xB.ld @@ -0,0 +1,96 @@ +/* + ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* + * STM32F072xB memory setup. + */ +MEMORY +{ + flash0 : org = 0x08000000, len = 124k + flash1 : org = 0x00000000, len = 0 + flash2 : org = 0x00000000, len = 0 + flash3 : org = 0x00000000, len = 0 + flash4 : org = 0x00000000, len = 0 + flash5 : org = 0x00000000, len = 0 + flash6 : org = 0x00000000, len = 0 + flash7 : org = 0x0801ec00, len = 5k + ram0 : org = 0x20000000, len = 16k + ram1 : org = 0x00000000, len = 0 + ram2 : org = 0x00000000, len = 0 + ram3 : org = 0x00000000, len = 0 + ram4 : org = 0x00000000, len = 0 + ram5 : org = 0x00000000, len = 0 + ram6 : org = 0x00000000, len = 0 + ram7 : org = 0x00000000, len = 0 +} + +/* For each data/text section two region are defined, a virtual region + and a load region (_LMA suffix).*/ + +/* Flash region to be used for exception vectors.*/ +REGION_ALIAS("VECTORS_FLASH", flash0); +REGION_ALIAS("VECTORS_FLASH_LMA", flash0); + +/* Flash region to be used for constructors and destructors.*/ +REGION_ALIAS("XTORS_FLASH", flash0); +REGION_ALIAS("XTORS_FLASH_LMA", flash0); + +/* Flash region to be used for code text.*/ +REGION_ALIAS("TEXT_FLASH", flash0); +REGION_ALIAS("TEXT_FLASH_LMA", flash0); + +/* Flash region to be used for read only data.*/ +REGION_ALIAS("RODATA_FLASH", flash0); +REGION_ALIAS("RODATA_FLASH_LMA", flash0); + +/* Flash region to be used for various.*/ +REGION_ALIAS("VARIOUS_FLASH", flash0); +REGION_ALIAS("VARIOUS_FLASH_LMA", flash0); + +/* Flash region to be used for RAM(n) initialization data.*/ +REGION_ALIAS("RAM_INIT_FLASH_LMA", flash0); + +/* Flash region to be saved calibration data */ +REGION_ALIAS("CALDATA_FLASH", flash7); + +/* RAM region to be used for Main stack. This stack accommodates the processing + of all exceptions and interrupts.*/ +REGION_ALIAS("MAIN_STACK_RAM", ram0); + +/* RAM region to be used for the process stack. This is the stack used by + the main() function.*/ +REGION_ALIAS("PROCESS_STACK_RAM", ram0); + +/* RAM region to be used for data segment.*/ +REGION_ALIAS("DATA_RAM", ram0); +REGION_ALIAS("DATA_RAM_LMA", flash0); + +/* RAM region to be used for BSS segment.*/ +REGION_ALIAS("BSS_RAM", ram0); + +/* RAM region to be used for the default heap.*/ +REGION_ALIAS("HEAP_RAM", ram0); + +/* Generic rules inclusion.*/ +INCLUDE rules.ld + +SECTIONS +{ + .calsave (NOLOAD) : ALIGN(4) + { + *(.calsave) + } > CALDATA_FLASH +} diff --git a/flash.c b/flash.c new file mode 100644 index 0000000..af9256e --- /dev/null +++ b/flash.c @@ -0,0 +1,97 @@ +#include "ch.h" +#include "hal.h" +#include "nanovna.h" +#include + +static int flash_wait_for_last_operation(void) +{ + while (FLASH->SR == FLASH_SR_BSY) { + //WWDG->CR = WWDG_CR_T; + } + return FLASH->SR; +} + +static void flash_erase_page0(uint32_t page_address) +{ + flash_wait_for_last_operation(); + FLASH->CR |= FLASH_CR_PER; + FLASH->AR = page_address; + FLASH->CR |= FLASH_CR_STRT; + flash_wait_for_last_operation(); + FLASH->CR &= ~FLASH_CR_PER; +} + +int flash_erase_page(uint32_t page_address) +{ + chSysLock(); + flash_erase_page0(page_address); + chSysUnlock(); + return 0; +} + +void flash_program_half_word(uint32_t address, uint16_t data) +{ + flash_wait_for_last_operation(); + FLASH->CR |= FLASH_CR_PG; + *(__IO uint16_t*)address = data; + flash_wait_for_last_operation(); + FLASH->CR &= ~FLASH_CR_PG; +} + +void flash_unlock(void) { + // unlock sequence + FLASH->KEYR = 0x45670123; + FLASH->KEYR = 0xCDEF89AB; +} + + +config_t cal_saved1 __attribute__ ((section(".calsave"))); + +static uint32_t +checksum(void *start, size_t len) +{ + uint32_t *p = (uint32_t*)start; + uint32_t *tail = (uint32_t*)(start + len); + uint32_t value = 0; + while (p < tail) + value ^= *p++; + return value; +} + +int +caldata_save(void) +{ + uint16_t *src = (uint16_t*)¤t_config; + uint16_t *dst = (uint16_t*)&cal_saved1; + int count = sizeof current_config / sizeof(uint16_t); + + current_config.magic = CONFIG_MAGIC; + current_config.checksum = 0; + current_config.checksum = checksum(¤t_config, sizeof current_config); + + flash_unlock(); + flash_erase_page(0x801e800); + flash_erase_page(0x801f000); + flash_erase_page(0x801f800); + flash_erase_page((uint32_t)dst); + while(count-- > 0) { + flash_program_half_word((uint32_t)dst, *src++); + dst++; + } + return 0; +} + +int +caldata_recall(void) +{ + void *src = &cal_saved1; + void *dst = ¤t_config; + + if (cal_saved1.magic != CONFIG_MAGIC) + return -1; + if (checksum(&cal_saved1, sizeof cal_saved1) != 0) + return -1; + + memcpy(dst, src, sizeof current_config); + return 0; +}