Kamil Cukrowski / Mbed 2 deprecated STM32_Button_Interrupt_dla_taty

Dependencies:   mbed DS18B20 TextLCD

Revision:
0:55c37ea095b0
Child:
1:f8a4796e766e
diff -r 000000000000 -r 55c37ea095b0 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Feb 13 16:27:38 2020 +0000
@@ -0,0 +1,344 @@
+#include "mbed.h"
+#include "TextLCD.h"
+#include <atomic_flag.h>
+#include <string>
+#include <cstdio>
+#include <cassert>
+#include <cstdarg>
+#include <DS1820.h>
+#include <DebounceIn.h>
+#include <limits>
+#include <flash.h>
+#include <cassert>
+
+static DigitalOut led_on_board(PC_13);
+
+/* str --------------------------------------------- */
+
+void str_remove(char *str, const char *reject) {
+    while (1) {
+        const size_t s = strcspn(str, reject);
+        str += s;
+        if (str[0] == '\0') {
+            break;
+        }
+        memmove(str, str + 1, strlen(str + 1) + 1);
+    }
+}
+
+void str_pad_suffix(char *str, size_t len, char c) {
+    if (strlen(str) < len) {
+        memset(str + strlen(str), c, len - strlen(str));
+    }
+    str[len] = '\0';
+}
+
+char *str_filename(const char *file) {
+    return (char*)(strrchr(file, '/') ? strrchr(file, '/') + 1 : file);
+}
+
+/* lcd ------------------------------------------------- */
+
+static TextLCD& lcd() {
+    static TextLCD lcd(PB_15, PA_10, PB_3, PB_4, PB_5, PB_6, TextLCD::LCD16x2); // rs, e, d4-d7
+    // static TextLCD lcd(PA_0, PA_1, PA_2, PA_3, PA_4, PA_5, TextLCD::LCD16x2); // rs, e, d4-d7
+    return lcd;
+}
+
+void lcd_cls() {
+    lcd().cls();
+}
+
+void lcd_vprintln(const char *fmt, va_list va) {
+    char buf[20] = {0};
+    const size_t len = vsnprintf(buf, sizeof(buf), fmt, va);
+    str_remove(buf, "\r\n");
+    str_pad_suffix(buf, 16, ' ');
+    lcd().printf(buf);
+}
+
+__attribute__((__format__(__printf__, 1, 2)))
+void lcd_println(const char *fmt, ...) {
+    va_list va;
+    va_start(va, fmt);
+    lcd_vprintln(fmt, va);
+    va_end(va);
+}
+
+extern "C" {
+    void d(const char *fmt, ...) {
+        va_list va;
+        va_start(va, fmt);
+        lcd_vprintln(fmt, va);
+        va_end(va);
+        wait(1);
+    }
+}
+    
+/* system --------------------------------------------- */
+
+extern "C" void abort() {
+    for (int i = 0; i < 20 * 5; ++i) {
+        led_on_board = !led_on_board;
+        wait(0.05);
+    }
+    NVIC_SystemReset();
+}
+
+extern "C" void __assert_func(const char *file, int line, const char *func, const char *failedexpr) {
+  lcd_println("ASSERT %d", line);
+  lcd_println("%s", str_filename(file));
+  abort();
+}
+
+
+/* ds18b20 --------------------------------------------- */
+
+/**
+ * @return
+ *              0 - no errors ('temp' contains the temperature measured)
+ *              1 - sensor not present ('temp' is not updated)
+ *              2 - CRC error ('temp' is not updated)
+ */
+static int ds18b20_temp(float& temperature_f_C) {
+    static DS1820 probe('B', PB_1);
+    static Timer t;
+    static bool running = false;
+    
+    // start the conversion if not running
+    if (running == false) {
+        running = true;
+        probe.startConversion();
+        t.start();
+    }
+    
+    // wait for conversion end
+    const unsigned ms = t.read_ms();
+    const unsigned conversion_time_ms = 800;
+    if (ms < conversion_time_ms) {
+        wait((conversion_time_ms - ms) / 1000.0);
+    }
+    
+    // read temperature from buffer
+    temperature_f_C = -1000;
+    const uint8_t err = probe.read(temperature_f_C);
+    
+    // restart new conversion
+    probe.startConversion();
+    t.reset();
+    
+    return err;
+}
+
+/* output -------------------------------------------- */
+
+static DigitalOut output(PC_14);
+
+/* state --------------------------------------------- */
+
+struct state {
+    volatile int high;  // in Celcius
+    volatile int low;   // in Celcius
+    volatile bool inverted;
+    
+    state() : high(30), low(20) {}
+    
+    struct data {
+        static const int data_version = 0x11;
+        int version;
+        int high;
+        int low;
+        bool inverted : 1;
+        bool current : 1;
+        data() : version(data_version) {}
+        data(const state& s, const DigitalOut& o) : 
+            version(data_version),
+            high(s.high), 
+            low(s.low), 
+            inverted(s.inverted), 
+            current(output) 
+            {}
+        void put(state& s, DigitalOut& o) {
+            s.high = high;
+            s.low = low;
+            s.inverted = inverted;
+            o = current;
+        }
+    };
+    
+    static bool _low_high_valid(int high, int low) {
+        return -99 < high && high < 99 &&
+                -99 < low && low < 99 &&
+                low < high &&
+                low != high;
+    }
+    
+    void save() {
+        const struct data d(*this, output);
+        flash::write(d);
+    }
+    
+    void restore() {
+        struct data d;
+        const int e = flash::read(d);
+        if (e) {
+            lcd_println("New flash %d", e);
+            wait(1);
+            return;
+        }
+        if (!_low_high_valid(d.high, d.low)) {
+            lcd_println("Invalid flash vals");
+            lcd_println("%d %d", d.high, d.low);
+            wait(1);
+            return;
+        }
+        lcd_println("Flash load %d %d", d.high, d.low);
+        wait(1);
+        d.put(*this, output);
+    }
+    
+    void high_inc() { _inc_it(high, low); }
+    void high_dec() { _dec_it(high, low); }
+    void low_inc() { _inc_it(low, high); }
+    void low_dec() { _dec_it(low, high); }    
+    void invert_invert() {
+        inverted = !inverted;
+        save();
+    }
+    
+private:
+    void _inc_it(volatile int &val, volatile int &other) {
+        if (val + 1 == other) return;
+        if (val >= 99) return;
+        val++;
+        save();
+    }
+    void _dec_it(volatile int &val, volatile int &other) {
+        if (val - 1 == other) return;
+        if (val <= -99) return;
+        val--;
+        save();
+    }
+};
+
+static state state;
+
+
+/* buttons -------------------------------------------- */
+
+static DebounceIn button_h_inc(PA_6, PullDown);
+static DebounceIn button_h_dec(PA_5, PullDown);
+static DebounceIn button_l_inc(PA_4, PullDown);
+static DebounceIn button_l_dec(PA_3, PullDown);
+static DebounceIn button_inv(PA_2, PullDown);
+static DebounceIn button_refresh(PA_1, PullDown);
+
+static void button_h_inc_pressed() { state.high_inc(); }
+static void button_h_dec_pressed() { state.high_dec(); }
+static void button_l_inc_pressed() { state.low_inc(); }
+static void button_l_dec_pressed() { state.low_dec(); }
+static void button_inv_pressed() {
+    output = !output;
+    state.invert_invert();
+}
+
+static void button_init() {
+    const unsigned debounce_timeout_us = 200 * 1000;
+    button_h_inc.fall(button_h_inc_pressed, debounce_timeout_us);
+    button_h_dec.fall(button_h_dec_pressed, debounce_timeout_us);
+    button_l_inc.fall(button_l_inc_pressed, debounce_timeout_us);
+    button_l_dec.fall(button_l_dec_pressed, debounce_timeout_us);
+    button_inv.fall(button_inv_pressed, debounce_timeout_us * 2);
+}
+    
+
+static void button_check() {
+    while(1) {
+        DebounceIn *arr[6] = {
+            &button_h_inc,
+            &button_h_dec,
+            &button_l_inc,
+            &button_l_dec,
+            &button_inv,
+            &button_refresh
+        };
+        lcd_println("%d %d %d %d %d %d\n",
+            arr[0]->read(),
+            arr[1]->read(),
+            arr[2]->read(),
+            arr[3]->read(),
+            arr[4]->read(),
+            arr[5]->read());
+        lcd_println("");
+    }
+}
+
+/* main --------------------------- */
+
+static void setup() {    
+    // wait for voltage stability
+    wait(1);
+    // some info
+    lcd_cls();
+    lcd_println("Hello!");
+    lcd_println("clock=%ld", SystemCoreClock);
+    wait(1);
+    lcd_cls();
+    state.restore();
+    button_init();
+}
+
+static void loop() {
+    static bool alive;
+    alive = !alive;
+    
+    float temperature_f_C = 0;
+    const int ds18b20_err = ds18b20_temp(temperature_f_C);
+    
+    lcd_cls();
+    
+    char temperature_s[8] = "ERROR";
+    if (ds18b20_err == 0) {
+        const int temperature_dC = temperature_f_C * 10;
+        const int temperature_C = temperature_f_C;
+        
+        if (temperature_C < -100 || temperature_C > 100) {
+            snprintf(temperature_s, sizeof(temperature_s), "INVAL");
+        } else {
+                        
+            if (!output ^ state.inverted) {
+                if (temperature_C > state.high) {
+                    output = 1 ^ state.inverted;
+                }
+            } else {
+                if (temperature_C < state.low) {
+                    output = 0 ^ state.inverted;
+                }
+            }
+            
+            snprintf(temperature_s, sizeof(temperature_s), "%3d.%d'C", temperature_C, temperature_dC % 10);
+        }
+    }
+    
+    led_on_board = output;
+
+    lcd_println("%-7s %3s  %3s",
+            temperature_s,
+            state.inverted ? "INV" : "NOR",
+            output ? "ON" : "OFF"
+    );
+    lcd_println("H=%2d'C L=%2d'C %c%c", 
+            state.high,
+            state.low, 
+            !alive ? '\xff' : ' ',
+            alive ? '\xff' : ' '
+    );
+}
+
+int main() {
+    setup();
+    while (1) {
+        loop();
+    }
+    return 0;
+}