Kamil Cukrowski / Mbed 2 deprecated STM32_Button_Interrupt_dla_taty

Dependencies:   mbed DS18B20 TextLCD

Revision:
0:55c37ea095b0
diff -r 000000000000 -r 55c37ea095b0 flash.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flash.h	Thu Feb 13 16:27:38 2020 +0000
@@ -0,0 +1,109 @@
+#ifndef FLASH_H
+#define FLASH_H
+
+#include "mbed.h"
+#include <cassert>
+#include <limits>
+
+void lcd_println(const char *fmt, ...);
+extern "C" void d(const char *fmt, ...);
+
+namespace flash {
+    static inline void _page_erase(uint32_t page) {
+        uint32_t page_error = 0;
+        FLASH_EraseInitTypeDef s_eraseinit;
+        s_eraseinit.TypeErase   = FLASH_TYPEERASE_PAGES;
+        s_eraseinit.PageAddress = page;
+        s_eraseinit.NbPages     = 1;
+        const HAL_StatusTypeDef status = 
+            HAL_FLASHEx_Erase(&s_eraseinit, &page_error);
+        if (status) d("ERR: HFP %d", status);
+    }
+    
+    static const uintptr_t _page = 0x0800F400;
+    static const uint16_t _mark = 0xbeef + 1;
+    
+    static inline void _write16(uintptr_t address, uint16_t val) {
+        // d("W %lx=%04x", _page + address, val);
+        const HAL_StatusTypeDef status = 
+            HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, _page + address * 2, val);
+        if (status) d("ERR: HFP %d", status);
+    }
+    
+    static inline uint16_t _read16(uintptr_t address) {
+        const uint16_t val = *(volatile uint16_t *)(_page + address * 2);
+        // d("RR %lx=%04x", _page + address, val);
+        return val;
+    }
+
+    static inline void write(const void *data, size_t len) {
+        assert(len < FLASH_PAGE_SIZE - 2);
+        assert(len < std::numeric_limits<uint16_t>::max());
+        HAL_FLASH_Unlock();
+        _page_erase(_page);
+        flash::_write16(0, _mark);
+        flash::_write16(1, len);
+        for (size_t i = 0; i < len; i += 2) {
+            uint16_t var = 0;
+            const size_t to_copy = 1 + (i + 2 < len);
+            memcpy(&var, data, to_copy);    
+            flash::_write16(2 + i / 2, var);
+            data = (const char*)data + to_copy;
+        }   
+        HAL_FLASH_Lock();
+    }
+    
+    static inline int read(void *data, size_t len) {
+        assert(len < FLASH_PAGE_SIZE - 2);
+        assert(len < std::numeric_limits<uint16_t>::max());
+        const uint16_t read_mark = flash::_read16(0);
+        if (read_mark != _mark) {
+            memset(data, '0', len);
+            return -1;
+        }
+        const uint16_t read_len = flash::_read16(1);
+        if (read_len != len) {
+            memset(data, '0', len);
+            return -2;
+        }
+        for (size_t i = 0; i < len; i += 2) {
+            const uint16_t var = flash::_read16(2 + i / 2);
+            const size_t to_copy = 1 + (i + 2 < len);
+            memcpy(data, &var, to_copy);
+            data = (char*)data + to_copy;
+        }
+        return 0;
+    }
+    
+    template<typename T>
+    static inline void write(const T &t) {
+        flash::write((const void*)&t, sizeof(t));
+    }
+    
+    template<typename T>
+    static inline int read(T &t) {
+        return flash::read((void*)&t, sizeof(t));
+    }
+        
+    static inline void test() {
+        lcd_println("testing flash");
+        lcd_println("testing flash 2");
+        wait(1);
+        
+        while (1) {
+            char buf[6] = {0};
+            const int e = flash::read(buf, 5);
+            int i = atoi(buf);
+            if (i == 0) i = 12345;
+            lcd_println("FR%d %d: %s", e, i, buf);
+            
+            snprintf(buf, sizeof(buf), "%d", i + 1);
+            lcd_println("FW: %s", buf);
+            flash::write(buf, 5);
+            
+            wait(1);
+        }        
+    }
+};
+
+#endif