To access the internal flash of STM32F042K6.
This library provides a Partition class used to segment the STM32F042K6 internal flash so that the caller can read/write/erase the partition.
Examples
FlashPartition config(0x7c00, 0x400); uint8_t buf[16]; config.Read(address, buf, sizeof(buf)); config.EraseAll(); config.Write(address, buf, sizeof(buf));
f042k6_flash.cpp@1:7a490a05943a, 2017-09-11 (annotated)
- Committer:
- yjlou
- Date:
- Mon Sep 11 05:09:15 2017 +0000
- Revision:
- 1:7a490a05943a
- Parent:
- 0:a71e3b72379a
Remove debug message.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
yjlou | 0:a71e3b72379a | 1 | #include "f042k6_flash.h" |
yjlou | 0:a71e3b72379a | 2 | |
yjlou | 0:a71e3b72379a | 3 | #include <string.h> |
yjlou | 0:a71e3b72379a | 4 | |
yjlou | 0:a71e3b72379a | 5 | // Read flash content in this partition. |
yjlou | 0:a71e3b72379a | 6 | void FlashPartition::Read(uint32_t offset, char* buf, size_t len) { |
yjlou | 0:a71e3b72379a | 7 | memcpy(buf, (void*)(USER_FLASH_AREA_START + start_addr_ + offset), len); |
yjlou | 0:a71e3b72379a | 8 | } |
yjlou | 0:a71e3b72379a | 9 | |
yjlou | 0:a71e3b72379a | 10 | // Write flash content into this partition. |
yjlou | 0:a71e3b72379a | 11 | // Returns true for success. |
yjlou | 0:a71e3b72379a | 12 | bool FlashPartition::Write(uint32_t offset, const char* buf, size_t len) { |
yjlou | 0:a71e3b72379a | 13 | UnlockControlRegister(); |
yjlou | 0:a71e3b72379a | 14 | |
yjlou | 0:a71e3b72379a | 15 | if (*REG32(FLASH_SR) & SR_BSY) { |
yjlou | 0:a71e3b72379a | 16 | return false; |
yjlou | 0:a71e3b72379a | 17 | } |
yjlou | 0:a71e3b72379a | 18 | |
yjlou | 0:a71e3b72379a | 19 | *REG32(FLASH_CR) |= CR_PG; |
yjlou | 0:a71e3b72379a | 20 | |
yjlou | 0:a71e3b72379a | 21 | const uint16_t* src = (uint16_t*)buf; |
yjlou | 0:a71e3b72379a | 22 | uint16_t* dst = (uint16_t*)(USER_FLASH_AREA_START + start_addr_ + offset); |
yjlou | 0:a71e3b72379a | 23 | for (int i = 0; i < (len + 1) / 2; i++) { |
yjlou | 0:a71e3b72379a | 24 | *(dst++) = *(src++); |
yjlou | 0:a71e3b72379a | 25 | while (*REG32(FLASH_SR) & SR_BSY); |
yjlou | 0:a71e3b72379a | 26 | } |
yjlou | 0:a71e3b72379a | 27 | |
yjlou | 0:a71e3b72379a | 28 | *REG32(FLASH_CR) &= ~CR_PG; |
yjlou | 0:a71e3b72379a | 29 | |
yjlou | 0:a71e3b72379a | 30 | return true; |
yjlou | 0:a71e3b72379a | 31 | } |
yjlou | 0:a71e3b72379a | 32 | |
yjlou | 0:a71e3b72379a | 33 | // Erase whole partition |
yjlou | 0:a71e3b72379a | 34 | // Returns true for success. |
yjlou | 0:a71e3b72379a | 35 | bool FlashPartition::EraseAll() { |
yjlou | 0:a71e3b72379a | 36 | UnlockControlRegister(); |
yjlou | 0:a71e3b72379a | 37 | |
yjlou | 0:a71e3b72379a | 38 | if (*REG32(FLASH_SR) & SR_BSY) { |
yjlou | 0:a71e3b72379a | 39 | return false; |
yjlou | 0:a71e3b72379a | 40 | } |
yjlou | 0:a71e3b72379a | 41 | |
yjlou | 0:a71e3b72379a | 42 | *REG32(FLASH_CR) |= CR_PER; |
yjlou | 0:a71e3b72379a | 43 | |
yjlou | 0:a71e3b72379a | 44 | for (uint32_t page = USER_FLASH_AREA_START + start_addr_; |
yjlou | 0:a71e3b72379a | 45 | page < (USER_FLASH_AREA_START + start_addr_ + size_); |
yjlou | 0:a71e3b72379a | 46 | page += kFlashPageInBytes) { |
yjlou | 0:a71e3b72379a | 47 | *REG32(FLASH_AR) = page; |
yjlou | 0:a71e3b72379a | 48 | *REG32(FLASH_CR) |= CR_STRT; |
yjlou | 0:a71e3b72379a | 49 | while (*REG32(FLASH_SR) & SR_BSY); |
yjlou | 0:a71e3b72379a | 50 | } |
yjlou | 0:a71e3b72379a | 51 | *REG32(FLASH_CR) &= ~CR_PER; |
yjlou | 0:a71e3b72379a | 52 | |
yjlou | 0:a71e3b72379a | 53 | return true; |
yjlou | 0:a71e3b72379a | 54 | } |
yjlou | 0:a71e3b72379a | 55 | |
yjlou | 0:a71e3b72379a | 56 | void FlashPartition::UnlockControlRegister() { |
yjlou | 0:a71e3b72379a | 57 | if (*REG32(FLASH_CR) & CR_LOCK) { |
yjlou | 0:a71e3b72379a | 58 | *REG32(FLASH_KEYR) = 0x45670123; |
yjlou | 0:a71e3b72379a | 59 | *REG32(FLASH_KEYR) = 0xCDEF89AB; |
yjlou | 0:a71e3b72379a | 60 | } |
yjlou | 0:a71e3b72379a | 61 | } |