Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 0:a71e3b72379a, committed 2017-08-29
- Comitter:
- yjlou
- Date:
- Tue Aug 29 02:36:52 2017 +0000
- Child:
- 1:7a490a05943a
- Commit message:
- First commit
Changed in this revision
| f042k6_flash.cpp | Show annotated file Show diff for this revision Revisions of this file |
| f042k6_flash.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/f042k6_flash.cpp Tue Aug 29 02:36:52 2017 +0000
@@ -0,0 +1,62 @@
+#include "f042k6_flash.h"
+
+#include <string.h>
+
+// Read flash content in this partition.
+void FlashPartition::Read(uint32_t offset, char* buf, size_t len) {
+ memcpy(buf, (void*)(USER_FLASH_AREA_START + start_addr_ + offset), len);
+}
+
+// Write flash content into this partition.
+// Returns true for success.
+bool FlashPartition::Write(uint32_t offset, const char* buf, size_t len) {
+ UnlockControlRegister();
+
+ if (*REG32(FLASH_SR) & SR_BSY) {
+ return false;
+ }
+
+ *REG32(FLASH_CR) |= CR_PG;
+
+ const uint16_t* src = (uint16_t*)buf;
+ uint16_t* dst = (uint16_t*)(USER_FLASH_AREA_START + start_addr_ + offset);
+ for (int i = 0; i < (len + 1) / 2; i++) {
+ *(dst++) = *(src++);
+ while (*REG32(FLASH_SR) & SR_BSY);
+ }
+
+ *REG32(FLASH_CR) &= ~CR_PG;
+
+ return true;
+}
+
+// Erase whole partition
+// Returns true for success.
+bool FlashPartition::EraseAll() {
+ UnlockControlRegister();
+
+ if (*REG32(FLASH_SR) & SR_BSY) {
+ return false;
+ }
+
+ *REG32(FLASH_CR) |= CR_PER;
+
+ for (uint32_t page = USER_FLASH_AREA_START + start_addr_;
+ page < (USER_FLASH_AREA_START + start_addr_ + size_);
+ page += kFlashPageInBytes) {
+ *REG32(FLASH_AR) = page;
+ *REG32(FLASH_CR) |= CR_STRT;
+ while (*REG32(FLASH_SR) & SR_BSY);
+ }
+ *REG32(FLASH_CR) &= ~CR_PER;
+
+ return true;
+}
+
+void FlashPartition::UnlockControlRegister() {
+ if (*REG32(FLASH_CR) & CR_LOCK) {
+ printf("Unlocking control register\r\n");
+ *REG32(FLASH_KEYR) = 0x45670123;
+ *REG32(FLASH_KEYR) = 0xCDEF89AB;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/f042k6_flash.h Tue Aug 29 02:36:52 2017 +0000
@@ -0,0 +1,76 @@
+// STM32F042K6 Flash driver
+//
+// In theory, this should be working on STM32F0x1/STM32F0x2/STM32F0x8, but only
+// tested on STM32F042K6.
+//
+// Please refer to STM RM0091 document for details.
+// http://www.st.com/content/ccc/resource/technical/document/reference_manual/c2/f8/8a/f2/18/e6/43/96/DM00031936.pdf/files/DM00031936.pdf/jcr:content/translations/en.DM00031936.pdf
+
+#ifndef F042K6_FLASH_H_
+#define F042K6_FLASH_H_
+
+#include "mbed.h"
+#include <stddef.h>
+#include <stdint.h>
+
+// Memory address to read flash content
+// FLASH_BASE and FLASH_BANK1_END are defined in mbed/TARGET_NUCLEO_F042K6/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/device/stm32f042x6.h
+#define USER_FLASH_AREA_START (FLASH_BASE)
+#define USER_FLASH_AREA_SIZE (FLASH_BANK1_END - FLASH_BASE) // 32KB for F042K6
+static const size_t kFlashPageInBytes = 1024;
+
+#define REG32(x) ((volatile uint32_t*)(x))
+
+// FLASH_R_BASE (0x40022000) is defined in mbed/TARGET_NUCLEO_F042K6/TARGET_STM/TARGET_STM32F0/TARGET_NUCLEO_F042K6/device/stm32f042x6.h
+// FIXME: looks like the definition in stm32f042x6.h is wrong.
+#undef FLASH_R_BASE
+#define FLASH_R_BASE (0x40022000)
+#define FLASH_ACR (FLASH_R_BASE + 0x00) // Flash access control register
+
+#define FLASH_KEYR (FLASH_R_BASE + 0x04) // Flash key register
+
+#define FLASH_OPTKEYR (FLASH_R_BASE + 0x08) // Flash option key register
+
+#define FLASH_SR (FLASH_R_BASE + 0x0c) // Flash status register
+#define SR_BSY (1 << 0) // Busy
+
+#define FLASH_CR (FLASH_R_BASE + 0x10) // Flash control register
+#define CR_LOCK (1 << 7) // Lock bit
+#define CR_STRT (1 << 6) // Start for erase
+#define CR_PER (1 << 1) // Page Erase
+#define CR_PG (1 << 0) // Program
+
+#define FLASH_AR (FLASH_R_BASE + 0x14) // Flash address register
+
+#define FLASH_OBR (FLASH_R_BASE + 0x1C) // Flash Option Byte register
+
+#define FLASH_WRPR (FLASH_R_BASE + 0x20) // Write prtotection register
+
+class FlashPartition {
+ public:
+ // Constructor:
+ // Args:
+ // start_addr: the starting address of the partition. Starting from 0.
+ FlashPartition(uint32_t start_addr, size_t size) :
+ start_addr_(start_addr),
+ size_(size) {} // TODO: add assertion to check address and size.
+
+ // Read flash content in this partition.
+ void Read(uint32_t offset, char* buf, size_t len);
+
+ // Write flash content into this partition.
+ // Returns true for success.
+ bool Write(uint32_t offset, const char* buf, size_t len);
+
+ // Erase whole partition
+ // Returns true for success.
+ bool EraseAll();
+
+ private:
+ void UnlockControlRegister();
+
+ const uint32_t start_addr_;
+ const size_t size_;
+};
+
+#endif // F042K6_FLASH_H_