From 1dc7d758f96dd2b9bd7b03f01ca032d68b696cf0 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 2 Nov 2014 10:14:39 +0000 Subject: fish --- libopencm3/lib/stm32/f1/flash.c | 306 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 306 insertions(+) create mode 100644 libopencm3/lib/stm32/f1/flash.c (limited to 'libopencm3/lib/stm32/f1/flash.c') diff --git a/libopencm3/lib/stm32/f1/flash.c b/libopencm3/lib/stm32/f1/flash.c new file mode 100644 index 0000000..5712e1c --- /dev/null +++ b/libopencm3/lib/stm32/f1/flash.c @@ -0,0 +1,306 @@ +/** @defgroup flash_file FLASH + * + * @ingroup STM32F1xx + * + * @brief libopencm3 STM32F1xx FLASH Memory + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2010 + * Thomas Otto + * @author @htmlonly © @endhtmlonly 2010 + * Mark Butler + * + * @date 14 January 2014 + * + * For the STM32F1xx, accessing FLASH memory is described briefly in + * section 3.3.3 of the STM32F10x Reference Manual. + * For detailed programming information see: + * PM0075 programming manual: STM32F10xxx Flash programming + * August 2010, Doc ID 17863 Rev 1 + * https://github.com/libopencm3/libopencm3-archive/blob/master/st_micro/CD00283419.pdf + * + * FLASH memory may be used for data storage as well as code, and may be + * programmatically modified. Note that for firmware upload the STM32F1xx + * provides a built-in bootloader in system memory that can be entered from a + * running program. + * + * FLASH must first be unlocked before programming. In this module a write to + * FLASH is a blocking operation until the end-of-operation flag is asserted. + * + * @note: don't forget to lock it again when all operations are complete. + * + * For the large memory XL series, with two banks of FLASH, the upper bank is + * accessed with a second set of registers. In principle both banks can be + * written simultaneously, or one read while the other is written. This module + * does not support the simultaneous write feature. + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2010 Mark Butler + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/**@{*/ + +#include + +/* Memory Size Register */ +#define MEMORY_SIZE_REG MMIO32(DESIG_FLASH_SIZE_BASE) + +/*---------------------------------------------------------------------------*/ +/** @brief Enable the FLASH Half Cycle Mode + +This mode is used for power saving during read access. It is disabled by default +on reset. + +Note carefully the clock restrictions under which the half cycle mode may be +enabled or disabled. This mode may only be used while the clock is running at +8MHz. See the reference manual for details. +*/ + +void flash_halfcycle_enable(void) +{ + FLASH_ACR |= FLASH_ACR_HLFCYA; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable the FLASH Half Cycle Mode + +*/ + +void flash_halfcycle_disable(void) +{ + FLASH_ACR &= ~FLASH_ACR_HLFCYA; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Unlock the Flash Program and Erase Controller, upper Bank + +This enables write access to the upper bank of the Flash memory in XL devices. +It is locked by default on reset. +*/ + +void flash_unlock_upper(void) +{ + if (MEMORY_SIZE_REG > 512) { + + /* Clear the unlock state. */ + FLASH_CR2 |= FLASH_CR_LOCK; + + /* Authorize the FPEC access. */ + FLASH_KEYR2 = FLASH_KEYR_KEY1; + FLASH_KEYR2 = FLASH_KEYR_KEY2; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Lock the Flash Program and Erase Controller, upper Bank + +Used to prevent spurious writes to FLASH. +*/ + +void flash_lock_upper(void) +{ + FLASH_CR2 |= FLASH_CR_LOCK; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Programming Error Status Flag, upper Bank + +*/ + +void flash_clear_pgerr_flag_upper(void) +{ + if (MEMORY_SIZE_REG > 512) + FLASH_SR2 |= FLASH_SR_PGERR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the End of Operation Status Flag, upper Bank + +*/ + +void flash_clear_eop_flag_upper(void) +{ + if (MEMORY_SIZE_REG > 512) + FLASH_SR2 |= FLASH_SR_EOP; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Write Protect Error Status Flag, upper Bank + +*/ + +void flash_clear_wrprterr_flag_upper(void) +{ + if (MEMORY_SIZE_REG > 512) + FLASH_SR2 |= FLASH_SR_WRPRTERR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Busy Status Flag, upper Bank + +*/ + +void flash_clear_bsy_flag_upper(void) +{ + if (MEMORY_SIZE_REG > 512) + FLASH_SR2 &= ~FLASH_SR_BSY; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear All Status Flags + +Program error, end of operation, write protect error, busy. Both banks cleared. +*/ + +void flash_clear_status_flags(void) +{ + flash_clear_pgerr_flag(); + flash_clear_eop_flag(); + flash_clear_wrprterr_flag(); + flash_clear_bsy_flag(); + if (MEMORY_SIZE_REG > 512) { + flash_clear_pgerr_flag_upper(); + flash_clear_eop_flag_upper(); + flash_clear_wrprterr_flag_upper(); + flash_clear_bsy_flag_upper(); + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Read All Status Flags + +The programming error, end of operation, write protect error and busy flags +are returned in the order of appearance in the status register. + +Flags for the upper bank, where appropriate, are combined with those for +the lower bank using bitwise OR, without distinction. + +@returns uint32_t. bit 0: busy, bit 2: programming error, bit 4: write protect +error, bit 5: end of operation. +*/ + +uint32_t flash_get_status_flags(void) +{ + uint32_t flags = (FLASH_SR & (FLASH_SR_PGERR | + FLASH_SR_EOP | + FLASH_SR_WRPRTERR | + FLASH_SR_BSY)); + if (MEMORY_SIZE_REG > 512) + flags |= (FLASH_SR2 & (FLASH_SR_PGERR | + FLASH_SR_EOP | + FLASH_SR_WRPRTERR | + FLASH_SR_BSY)); + return flags; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Program a Half Word to FLASH + +This performs all operations necessary to program a 16 bit word to FLASH memory. +The program error flag should be checked separately for the event that memory +was not properly erased. + +Status bit polling is used to detect end of operation. + +@param[in] uint32_t address. Full address of flash half word to be programmed. +@param[in] uint16_t data. +*/ + +void flash_program_half_word(uint32_t address, uint16_t data) +{ + flash_wait_for_last_operation(); + + if ((MEMORY_SIZE_REG > 512) && (address >= FLASH_BASE+0x00080000)) + FLASH_CR2 |= FLASH_CR_PG; + else FLASH_CR |= FLASH_CR_PG; + + MMIO16(address) = data; + + flash_wait_for_last_operation(); + + if ((MEMORY_SIZE_REG > 512) && (address >= FLASH_BASE+0x00080000)) + FLASH_CR2 &= ~FLASH_CR_PG; + else FLASH_CR &= ~FLASH_CR_PG; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Erase a Page of FLASH + +This performs all operations necessary to erase a page in FLASH memory. +The page should be checked to ensure that it was properly erased. A page must +first be fully erased before attempting to program it. + +Note that the page sizes differ between devices. See the reference manual or +the FLASH programming manual for details. + +@param[in] uint32_t page_address. Full address of flash page to be erased. +*/ + +void flash_erase_page(uint32_t page_address) +{ + flash_wait_for_last_operation(); + + if ((MEMORY_SIZE_REG > 512) && (page_address >= FLASH_BASE+0x00080000)) { + FLASH_CR2 |= FLASH_CR_PER; + FLASH_AR2 = page_address; + FLASH_CR2 |= FLASH_CR_STRT; + } else { + FLASH_CR |= FLASH_CR_PER; + FLASH_AR = page_address; + FLASH_CR |= FLASH_CR_STRT; + } + + flash_wait_for_last_operation(); + + if ((MEMORY_SIZE_REG > 512) && (page_address >= FLASH_BASE+0x00080000)) + FLASH_CR2 &= ~FLASH_CR_PER; + else + FLASH_CR &= ~FLASH_CR_PER; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Erase All FLASH + +This performs all operations necessary to erase all user pages in the FLASH +memory. The information block is unaffected. +*/ + +void flash_erase_all_pages(void) +{ + flash_wait_for_last_operation(); + + FLASH_CR |= FLASH_CR_MER; /* Enable mass erase. */ + FLASH_CR |= FLASH_CR_STRT; /* Trigger the erase. */ + + flash_wait_for_last_operation(); + FLASH_CR &= ~FLASH_CR_MER; /* Disable mass erase. */ + +/* Repeat for bank 2 */ + FLASH_CR2 |= FLASH_CR_MER; + FLASH_CR2 |= FLASH_CR_STRT; + + flash_wait_for_last_operation(); + FLASH_CR2 &= ~FLASH_CR_MER; +} + +/**@}*/ + -- cgit v1.2.3