diff options
author | Karl Palsson <karlp@remake.is> | 2013-01-23 20:24:47 +0400 |
---|---|---|
committer | Karl Palsson <karlp@remake.is> | 2014-07-14 21:54:20 +0400 |
commit | cf5fb002f6016242fb23b81fcbe98ee022bb84e9 (patch) | |
tree | 599b95c5228fb42bb250e91e54269ff98b4a582e | |
parent | 4d28c1b849673c8d216c75161e26bb1097894ab0 (diff) |
[l1-flash/eeprom] Add lock/unlock/eeprom helper routines
-rw-r--r-- | include/libopencm3/stm32/l1/flash.h | 11 | ||||
-rw-r--r-- | lib/stm32/l1/flash.c | 88 |
2 files changed, 97 insertions, 2 deletions
diff --git a/include/libopencm3/stm32/l1/flash.h b/include/libopencm3/stm32/l1/flash.h index a0c7a66e..680de5cc 100644 --- a/include/libopencm3/stm32/l1/flash.h +++ b/include/libopencm3/stm32/l1/flash.h @@ -138,6 +138,17 @@ void flash_64bit_disable(void); void flash_prefetch_enable(void); void flash_prefetch_disable(void); void flash_set_ws(uint32_t ws); +void flash_unlock_pecr(void); +void flash_lock_pecr(void); +void flash_unlock_progmem(void); +void flash_lock_progmem(void); +void flash_unlock_option_bytes(void); +void flash_lock_option_bytes(void); +void flash_unlock(void); +void flash_lock(void); + +void eeprom_program_word(uint32_t address, uint32_t data); +void eeprom_program_words(uint32_t address, uint32_t *data, int length_in_words); END_DECLS /**@}*/ diff --git a/lib/stm32/l1/flash.c b/lib/stm32/l1/flash.c index dc568654..fdd2cca3 100644 --- a/lib/stm32/l1/flash.c +++ b/lib/stm32/l1/flash.c @@ -29,7 +29,7 @@ * * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org> * Copyright (C) 2010 Mark Butler <mbutler@physics.otago.ac.nz> - * Copyright (C) 2012 Karl Palsson <karlp@tweak.net.au> + * Copyright (C) 2012-13 Karl Palsson <karlp@tweak.net.au> * * 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 @@ -120,5 +120,89 @@ void flash_set_ws(uint32_t ws) reg32 |= ws; FLASH_ACR = reg32; } -/**@}*/ +void flash_unlock_pecr(void) { + FLASH_PEKEYR = FLASH_PEKEYR_PEKEY1; + FLASH_PEKEYR = FLASH_PEKEYR_PEKEY2; +} + +void flash_lock_pecr(void) { + FLASH_PECR |= FLASH_PECR_PELOCK; +} + +void flash_unlock_progmem(void) { + flash_unlock_pecr(); + FLASH_PRGKEYR = FLASH_PRGKEYR_PRGKEY1; + FLASH_PRGKEYR = FLASH_PRGKEYR_PRGKEY2; +} + +void flash_lock_progmem(void) { + FLASH_PECR |= FLASH_PECR_PRGLOCK; +} + +void flash_unlock_option_bytes(void) { + flash_unlock_pecr(); + FLASH_OPTKEYR = FLASH_OPTKEYR_OPTKEY1; + FLASH_OPTKEYR = FLASH_OPTKEYR_OPTKEY2; +} + +void flash_lock_option_bytes(void) { + FLASH_PECR |= FLASH_PECR_OPTLOCK; +} + +/** @brief Unlock all segments of flash + * + */ +void flash_unlock(void) { + flash_unlock_pecr(); + flash_unlock_progmem(); + flash_unlock_option_bytes(); +} + +/** @brief Lock all segments of flash + * + */ +void flash_lock(void) { + flash_lock_option_bytes(); + flash_lock_progmem(); + flash_lock_pecr(); +} + +/** @brief Write a word to eeprom + * + * @param address assumed to be in the eeprom space, no checking + * @param data word to write + */ +void eeprom_program_word(uint32_t address, uint32_t data) { + flash_unlock_pecr(); + /* erase only if needed */ + FLASH_PECR &= ~FLASH_PECR_FTDW; + MMIO32(address) = data; + flash_lock_pecr(); +} + +/** @brief Write a block of words to eeprom + * + * Writes a block of words to EEPROM at the requested address, erasing if necessary, + * and locking afterwards. Only wordwise writing is safe for writing any value + * + * @param[in] address must point to EEPROM space, no checking! + * @param[in] data pointer to data to write + * @param[in] length size of of data in WORDS! + * */ +void eeprom_program_words(uint32_t address, uint32_t *data, int length_in_words) +{ + int i; + flash_unlock_pecr(); + while (FLASH_SR & FLASH_SR_BSY); + /* erase only if needed */ + FLASH_PECR &= ~FLASH_PECR_FTDW; + for (i = 0; i < length_in_words; i++) { + MMIO32(address + (i * sizeof(uint32_t))) = *(data+i); + while (FLASH_SR & FLASH_SR_BSY); + } + flash_lock_pecr(); +} + + +/**@}*/ |