diff options
Diffstat (limited to 'libopencm3/lib/stm32/common/flash_common_f24.c')
-rw-r--r-- | libopencm3/lib/stm32/common/flash_common_f24.c | 416 |
1 files changed, 416 insertions, 0 deletions
diff --git a/libopencm3/lib/stm32/common/flash_common_f24.c b/libopencm3/lib/stm32/common/flash_common_f24.c new file mode 100644 index 0000000..03883fb --- /dev/null +++ b/libopencm3/lib/stm32/common/flash_common_f24.c @@ -0,0 +1,416 @@ +/** @addtogroup flash_file + * + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org> + * Copyright (C) 2010 Mark Butler <mbutler@physics.otago.ac.nz> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +/**@{*/ + +#include <libopencm3/stm32/flash.h> + +/*---------------------------------------------------------------------------*/ +/** @brief Set the Program Parallelism Size + +Set the programming word width. Note carefully the power supply voltage +restrictions under which the different word sizes may be used. See the +programming manual for more information. + +@param psize: 0 (8-bit), 1 (16-bit), 2 (32-bit), 3 (64-bit) +*/ + +static inline void flash_set_program_size(uint32_t psize) +{ + FLASH_CR &= ~(((1 << 0) | (1 << 1)) << 8); + FLASH_CR |= psize; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable the Data Cache + +*/ + +void flash_dcache_enable(void) +{ + FLASH_ACR |= FLASH_ACR_DCE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable the Data Cache + +*/ + +void flash_dcache_disable(void) +{ + FLASH_ACR &= ~FLASH_ACR_DCE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable the Instruction Cache + +*/ + +void flash_icache_enable(void) +{ + FLASH_ACR |= FLASH_ACR_ICE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable the Instruction Cache + +*/ + +void flash_icache_disable(void) +{ + FLASH_ACR &= ~FLASH_ACR_ICE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable the FLASH Prefetch Buffer + +This buffer is used for instruction fetches and is enabled by default after +reset. + +Note carefully the clock restrictions under which the prefetch buffer may be +enabled or disabled. Changes are normally made while the clock is running in +the power-on low frequency mode before being set to a higher speed mode. +See the reference manual for details. +*/ + +void flash_prefetch_enable(void) +{ + FLASH_ACR |= FLASH_ACR_PRFTEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable the FLASH Prefetch Buffer + +Note carefully the clock restrictions under which the prefetch buffer may be +set to disabled. See the reference manual for details. +*/ + +void flash_prefetch_disable(void) +{ + FLASH_ACR &= ~FLASH_ACR_PRFTEN; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Reset the Data Cache + +The data cache must be disabled for this to have effect. +*/ + +void flash_dcache_reset(void) +{ + FLASH_ACR |= FLASH_ACR_DCRST; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Reset the Instruction Cache + +The instruction cache must be disabled for this to have effect. +*/ + +void flash_icache_reset(void) +{ + FLASH_ACR |= FLASH_ACR_ICRST; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Programming Sequence Error Flag + +This flag is set when incorrect programming configuration has been made. +*/ + +void flash_clear_pgserr_flag(void) +{ + FLASH_SR |= FLASH_SR_PGSERR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Programming Alignment Error Flag + +*/ + +void flash_clear_pgaerr_flag(void) +{ + FLASH_SR |= FLASH_SR_PGAERR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear the Write Protect Error Flag + +*/ + +void flash_clear_wrperr_flag(void) +{ + FLASH_SR |= FLASH_SR_WRPERR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Clear All Status Flags + +Program error, end of operation, write protect error, busy. +*/ + +void flash_clear_status_flags(void) +{ + flash_clear_pgserr_flag(); + flash_clear_pgaerr_flag(); + flash_clear_wrperr_flag(); + flash_clear_pgperr_flag(); + flash_clear_eop_flag(); + flash_clear_bsy_flag(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Unlock the Option Byte Access + +This enables write access to the option bytes. It is locked by default on +reset. +*/ + +void flash_unlock_option_bytes(void) +{ + /* Clear the unlock state. */ + FLASH_OPTCR |= FLASH_OPTCR_OPTLOCK; + + /* Unlock option bytes. */ + FLASH_OPTKEYR = FLASH_OPTKEYR_KEY1; + FLASH_OPTKEYR = FLASH_OPTKEYR_KEY2; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Lock the Option Byte Access + +This disables write access to the option bytes. It is locked by default on +reset. +*/ + +void flash_lock_option_bytes(void) +{ + FLASH_OPTCR |= FLASH_OPTCR_OPTLOCK; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Program a 64 bit Word to FLASH + +This performs all operations necessary to program a 64 bit word to FLASH memory. +The program error flag should be checked separately for the event that memory +was not properly erased. + +@param[in] uint32_t address +@param[in] uint64_t data. +*/ + +void flash_program_double_word(uint32_t address, uint64_t data) +{ + /* Ensure that all flash operations are complete. */ + flash_wait_for_last_operation(); + flash_set_program_size(FLASH_CR_PROGRAM_X64); + + /* Enable writes to flash. */ + FLASH_CR |= FLASH_CR_PG; + + /* Program the double_word. */ + MMIO64(address) = data; + + /* Wait for the write to complete. */ + flash_wait_for_last_operation(); + + /* Disable writes to flash. */ + FLASH_CR &= ~FLASH_CR_PG; +} + +/*---------------------------------------------------------------------------*/ +/** @brief Program a 32 bit Word to FLASH + +This performs all operations necessary to program a 32 bit word to FLASH memory. +The program error flag should be checked separately for the event that memory +was not properly erased. + +@param[in] uint32_t address +@param[in] uint32_t data. +*/ + +void flash_program_word(uint32_t address, uint32_t data) +{ + /* Ensure that all flash operations are complete. */ + flash_wait_for_last_operation(); + flash_set_program_size(FLASH_CR_PROGRAM_X32); + + /* Enable writes to flash. */ + FLASH_CR |= FLASH_CR_PG; + + /* Program the word. */ + MMIO32(address) = data; + + /* Wait for the write to complete. */ + flash_wait_for_last_operation(); + + /* Disable writes to flash. */ + FLASH_CR &= ~FLASH_CR_PG; +} + +/*---------------------------------------------------------------------------*/ +/** @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. + +@param[in] uint32_t address +@param[in] uint16_t data. +*/ + +void flash_program_half_word(uint32_t address, uint16_t data) +{ + flash_wait_for_last_operation(); + flash_set_program_size(FLASH_CR_PROGRAM_X16); + + FLASH_CR |= FLASH_CR_PG; + + MMIO16(address) = data; + + flash_wait_for_last_operation(); + + FLASH_CR &= ~FLASH_CR_PG; /* Disable the PG bit. */ +} + +/*---------------------------------------------------------------------------*/ +/** @brief Program an 8 bit Byte to FLASH + +This performs all operations necessary to program an 8 bit byte to FLASH memory. +The program error flag should be checked separately for the event that memory +was not properly erased. + +@param[in] uint32_t address +@param[in] uint8_t data. +*/ + +void flash_program_byte(uint32_t address, uint8_t data) +{ + flash_wait_for_last_operation(); + flash_set_program_size(FLASH_CR_PROGRAM_X8); + + FLASH_CR |= FLASH_CR_PG; + + MMIO8(address) = data; + + flash_wait_for_last_operation(); + + FLASH_CR &= ~FLASH_CR_PG; /* Disable the PG bit. */ +} + +/*---------------------------------------------------------------------------*/ +/** @brief Program a Data Block to FLASH + +This programs an arbitrary length data block to FLASH memory. +The program error flag should be checked separately for the event that memory +was not properly erased. + +@param[in] uint32_t address. Starting address in Flash. +@param[in] uint8_t *data. Pointer to start of data block. +@param[in] uint32_t len. Length of data block. +*/ + +void flash_program(uint32_t address, uint8_t *data, uint32_t len) +{ + /* TODO: Use dword and word size program operations where possible for + * turbo speed. + */ + uint32_t i; + for (i = 0; i < len; i++) { + flash_program_byte(address+i, data[i]); + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief Erase a Sector of FLASH + +This performs all operations necessary to erase a sector in FLASH memory. +The page should be checked to ensure that it was properly erased. A sector must +first be fully erased before attempting to program it. + +See the reference manual or the FLASH programming manual for details. + +@param[in] uint32_t sector (0 - 11). +@param program_size: 0 (8-bit), 1 (16-bit), 2 (32-bit), 3 (64-bit) +*/ + +void flash_erase_sector(uint8_t sector, uint32_t program_size) +{ + flash_wait_for_last_operation(); + flash_set_program_size(program_size); + + FLASH_CR &= ~(0xF << 3); + FLASH_CR |= (sector << 3) & 0x78; + FLASH_CR |= FLASH_CR_SER; + FLASH_CR |= FLASH_CR_STRT; + + flash_wait_for_last_operation(); + FLASH_CR &= ~FLASH_CR_SER; + FLASH_CR &= ~(0xF << 3); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Erase All FLASH + +This performs all operations necessary to erase all sectors in the FLASH +memory. + +@param program_size: 0 (8-bit), 1 (16-bit), 2 (32-bit), 3 (64-bit) +*/ + +void flash_erase_all_sectors(uint32_t program_size) +{ + flash_wait_for_last_operation(); + flash_set_program_size(program_size); + + 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. */ +} + +/*---------------------------------------------------------------------------*/ +/** @brief Program the Option Bytes + +This performs all operations necessary to program the option bytes. +The option bytes do not need to be erased first. + +@param[in] uint32_t data to be programmed. +*/ + +void flash_program_option_bytes(uint32_t data) +{ + flash_wait_for_last_operation(); + + if (FLASH_OPTCR & FLASH_OPTCR_OPTLOCK) { + flash_unlock_option_bytes(); + } + + FLASH_OPTCR = data & ~0x3; + FLASH_OPTCR |= FLASH_OPTCR_OPTSTRT; /* Enable option byte prog. */ + flash_wait_for_last_operation(); +} +/**@}*/ + |