Przeglądaj źródła

add simplistic crafty support

Thomas Buck 6 miesięcy temu
rodzic
commit
5af9bc8780
13 zmienionych plików z 461 dodań i 24 usunięć
  1. 2
    0
      CMakeLists.txt
  2. 1
    0
      include/config.h
  3. 38
    0
      include/crafty.h
  4. 1
    0
      include/state.h
  5. 30
    0
      include/state_crafty.h
  6. 16
    4
      src/ble.c
  7. 95
    9
      src/console.c
  8. 121
    0
      src/crafty.c
  9. 15
    0
      src/state.c
  10. 127
    0
      src/state_crafty.c
  11. 4
    0
      src/state_scan.c
  12. 4
    3
      src/state_volcano_run.c
  13. 7
    8
      src/volcano.c

+ 2
- 0
CMakeLists.txt Wyświetl plik

69
     src/menu.c
69
     src/menu.c
70
     src/state_volcano_workflow.c
70
     src/state_volcano_workflow.c
71
     src/state_volcano_run.c
71
     src/state_volcano_run.c
72
+    src/crafty.c
73
+    src/state_crafty.c
72
 
74
 
73
     ${CMAKE_CURRENT_BINARY_DIR}/fatfs/ff.c
75
     ${CMAKE_CURRENT_BINARY_DIR}/fatfs/ff.c
74
     ${CMAKE_CURRENT_BINARY_DIR}/fatfs/ffunicode.c
76
     ${CMAKE_CURRENT_BINARY_DIR}/fatfs/ffunicode.c

+ 1
- 0
include/config.h Wyświetl plik

43
 #endif // DEBUG_DISK_WRITE_SOURCES
43
 #endif // DEBUG_DISK_WRITE_SOURCES
44
 
44
 
45
 //#define TEST_VOLCANO_AUTO_CONNECT "xx:xx:xx:xx:xx:xx 1"
45
 //#define TEST_VOLCANO_AUTO_CONNECT "xx:xx:xx:xx:xx:xx 1"
46
+//#define TEST_CRAFTY_AUTO_CONNECT "xx:xx:xx:xx:xx:xx 0"
46
 
47
 
47
 #endif // __CONFIG_H__
48
 #endif // __CONFIG_H__

+ 38
- 0
include/crafty.h Wyświetl plik

1
+/*
2
+ * crafty.h
3
+ *
4
+ * Copyright (c) 2023 Thomas Buck (thomas@xythobuz.de)
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * See <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+#ifndef __CRAFTY_H__
20
+#define __CRAFTY_H__
21
+
22
+#include <stdint.h>
23
+#include <stdbool.h>
24
+
25
+// in 1/10th degrees C, or < 0 on error
26
+int16_t crafty_get_current_temp(void);
27
+int16_t crafty_get_target_temp(void);
28
+
29
+// v in 1/10th degrees C, returns < 0 on error
30
+int8_t crafty_set_target_temp(uint16_t v);
31
+
32
+// returns < 0 on error
33
+int8_t crafty_set_heater_state(bool value);
34
+
35
+// in percent, or < 0 on error
36
+int8_t crafty_get_battery_state(void);
37
+
38
+#endif // __CRAFTY_H__

+ 1
- 0
include/state.h Wyświetl plik

24
     STATE_SCAN,
24
     STATE_SCAN,
25
     STATE_VOLCANO_WORKFLOW,
25
     STATE_VOLCANO_WORKFLOW,
26
     STATE_VOLCANO_RUN,
26
     STATE_VOLCANO_RUN,
27
+    STATE_CRAFTY,
27
 };
28
 };
28
 
29
 
29
 void state_switch(enum system_state next);
30
 void state_switch(enum system_state next);

+ 30
- 0
include/state_crafty.h Wyświetl plik

1
+/*
2
+ * state_crafty.h
3
+ *
4
+ * Copyright (c) 2023 Thomas Buck (thomas@xythobuz.de)
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * See <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+#ifndef __STATE_CRAFTY_H__
20
+#define __STATE_CRAFTY_H__
21
+
22
+#include <ble.h>
23
+
24
+void state_crafty_target(bd_addr_t addr, bd_addr_type_t type);
25
+
26
+void state_crafty_enter(void);
27
+void state_crafty_exit(void);
28
+void state_crafty_run(void);
29
+
30
+#endif // __STATE_CRAFTY_H__

+ 16
- 4
src/ble.c Wyświetl plik

28
 #include "util.h"
28
 #include "util.h"
29
 #include "ble.h"
29
 #include "ble.h"
30
 
30
 
31
-#define BLE_READ_TIMEOUT_MS 500
32
-#define BLE_SRVC_TIMEOUT_MS 500
33
-#define BLE_CHAR_TIMEOUT_MS 2000
34
-#define BLE_WRTE_TIMEOUT_MS 500
31
+#define BLE_READ_TIMEOUT_MS (2 * 500)
32
+#define BLE_SRVC_TIMEOUT_MS (2 * 500)
33
+#define BLE_CHAR_TIMEOUT_MS (2 * 2000)
34
+#define BLE_WRTE_TIMEOUT_MS (2 * 500)
35
 #define BLE_MAX_SCAN_AGE_MS (10 * 1000)
35
 #define BLE_MAX_SCAN_AGE_MS (10 * 1000)
36
 #define BLE_MAX_SERVICES 8
36
 #define BLE_MAX_SERVICES 8
37
 #define BLE_MAX_CHARACTERISTICS 8
37
 #define BLE_MAX_CHARACTERISTICS 8
545
         uint32_t now = to_ms_since_boot(get_absolute_time());
545
         uint32_t now = to_ms_since_boot(get_absolute_time());
546
         if ((now - start_time) >= BLE_READ_TIMEOUT_MS) {
546
         if ((now - start_time) >= BLE_READ_TIMEOUT_MS) {
547
             debug("timeout waiting for read");
547
             debug("timeout waiting for read");
548
+            cyw43_thread_enter();
549
+            state = TC_READY;
550
+            cyw43_thread_exit();
548
             return -3;
551
             return -3;
549
         }
552
         }
550
 
553
 
631
             uint32_t now = to_ms_since_boot(get_absolute_time());
634
             uint32_t now = to_ms_since_boot(get_absolute_time());
632
             if ((now - start_time) >= BLE_SRVC_TIMEOUT_MS) {
635
             if ((now - start_time) >= BLE_SRVC_TIMEOUT_MS) {
633
                 debug("timeout waiting for service");
636
                 debug("timeout waiting for service");
637
+                cyw43_thread_enter();
638
+                state = TC_READY;
639
+                cyw43_thread_exit();
634
                 return -3;
640
                 return -3;
635
             }
641
             }
636
 
642
 
695
             uint32_t now = to_ms_since_boot(get_absolute_time());
701
             uint32_t now = to_ms_since_boot(get_absolute_time());
696
             if ((now - start_time) >= BLE_CHAR_TIMEOUT_MS) {
702
             if ((now - start_time) >= BLE_CHAR_TIMEOUT_MS) {
697
                 debug("timeout waiting for characteristic");
703
                 debug("timeout waiting for characteristic");
704
+                cyw43_thread_enter();
705
+                state = TC_READY;
706
+                cyw43_thread_exit();
698
                 return -5;
707
                 return -5;
699
             }
708
             }
700
 
709
 
736
         uint32_t now = to_ms_since_boot(get_absolute_time());
745
         uint32_t now = to_ms_since_boot(get_absolute_time());
737
         if ((now - start_time) >= BLE_WRTE_TIMEOUT_MS) {
746
         if ((now - start_time) >= BLE_WRTE_TIMEOUT_MS) {
738
             debug("timeout waiting for write");
747
             debug("timeout waiting for write");
748
+            cyw43_thread_enter();
749
+            state = TC_READY;
750
+            cyw43_thread_exit();
739
             return -7;
751
             return -7;
740
         }
752
         }
741
 
753
 

+ 95
- 9
src/console.c Wyświetl plik

41
 #include "models.h"
41
 #include "models.h"
42
 #include "workflow.h"
42
 #include "workflow.h"
43
 #include "console.h"
43
 #include "console.h"
44
+#include "crafty.h"
44
 
45
 
45
 #define CNSL_BUFF_SIZE 64
46
 #define CNSL_BUFF_SIZE 64
46
 #define CNSL_REPEAT_MS 500
47
 #define CNSL_REPEAT_MS 500
47
 
48
 
48
-#define VOLCANO_AUTO_CONNECT {                                    \
49
+#define DEV_AUTO_CONNECT(s) {                                     \
49
     ble_scan(BLE_SCAN_OFF);                                       \
50
     ble_scan(BLE_SCAN_OFF);                                       \
50
     bd_addr_t addr;                                               \
51
     bd_addr_t addr;                                               \
51
     bd_addr_type_t type;                                          \
52
     bd_addr_type_t type;                                          \
52
-    const char *foo = TEST_VOLCANO_AUTO_CONNECT;                  \
53
+    const char *foo = s;                                          \
53
     sscanf(foo, "%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX %hhu", \
54
     sscanf(foo, "%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX %hhu", \
54
             &addr[0], &addr[1], &addr[2], &addr[3],               \
55
             &addr[0], &addr[1], &addr[2], &addr[3],               \
55
             &addr[4], &addr[5], &type);                           \
56
             &addr[4], &addr[5], &type);                           \
114
         println("   vrtt - Volcano read target temperature");
115
         println("   vrtt - Volcano read target temperature");
115
         println(" vwtt X - Volcano write target temperature");
116
         println(" vwtt X - Volcano write target temperature");
116
         println("  vwh X - Set heater to 1 or 0");
117
         println("  vwh X - Set heater to 1 or 0");
117
-        println("  vwp X - Set heater to 1 or 0");
118
+        println("  vwp X - Set pump to 1 or 0");
118
         println("");
119
         println("");
119
         println("    wfl - List available workflows");
120
         println("    wfl - List available workflows");
120
         println("   wf X - Run workflow");
121
         println("   wf X - Run workflow");
121
         println("");
122
         println("");
123
+        println("   crct - Crafty read current temperature");
124
+        println("   crtt - Crafty read target temperature");
125
+        println(" cwtt X - Crafty write target temperature");
126
+        println("  cwh X - Set heater to 1 or 0");
127
+        println("    crb - Crafty read battery state");
128
+        println("");
122
         println("Press Enter with no input to repeat last command.");
129
         println("Press Enter with no input to repeat last command.");
123
         println("Use repeat to continuously execute last command.");
130
         println("Use repeat to continuously execute last command.");
124
         println("Stop this by calling repeat again.");
131
         println("Stop this by calling repeat again.");
230
         draw_battery_indicator();
237
         draw_battery_indicator();
231
     } else if (strcmp(line, "vrct") == 0) {
238
     } else if (strcmp(line, "vrct") == 0) {
232
 #ifdef TEST_VOLCANO_AUTO_CONNECT
239
 #ifdef TEST_VOLCANO_AUTO_CONNECT
233
-        VOLCANO_AUTO_CONNECT
240
+        DEV_AUTO_CONNECT(TEST_VOLCANO_AUTO_CONNECT);
234
 #endif // TEST_VOLCANO_AUTO_CONNECT
241
 #endif // TEST_VOLCANO_AUTO_CONNECT
235
 
242
 
236
         int16_t r = volcano_get_current_temp();
243
         int16_t r = volcano_get_current_temp();
241
 #endif // TEST_VOLCANO_AUTO_CONNECT
248
 #endif // TEST_VOLCANO_AUTO_CONNECT
242
     } else if (strcmp(line, "vrtt") == 0) {
249
     } else if (strcmp(line, "vrtt") == 0) {
243
 #ifdef TEST_VOLCANO_AUTO_CONNECT
250
 #ifdef TEST_VOLCANO_AUTO_CONNECT
244
-        VOLCANO_AUTO_CONNECT
251
+        DEV_AUTO_CONNECT(TEST_VOLCANO_AUTO_CONNECT);
245
 #endif // TEST_VOLCANO_AUTO_CONNECT
252
 #endif // TEST_VOLCANO_AUTO_CONNECT
246
 
253
 
247
         int16_t r = volcano_get_target_temp();
254
         int16_t r = volcano_get_target_temp();
259
             uint16_t v = val * 10.0;
266
             uint16_t v = val * 10.0;
260
 
267
 
261
 #ifdef TEST_VOLCANO_AUTO_CONNECT
268
 #ifdef TEST_VOLCANO_AUTO_CONNECT
262
-            VOLCANO_AUTO_CONNECT
269
+            DEV_AUTO_CONNECT(TEST_VOLCANO_AUTO_CONNECT);
263
 #endif // TEST_VOLCANO_AUTO_CONNECT
270
 #endif // TEST_VOLCANO_AUTO_CONNECT
264
 
271
 
265
             int8_t r = volcano_set_target_temp(v);
272
             int8_t r = volcano_set_target_temp(v);
281
             println("invalid input (%d %d)", r, val);
288
             println("invalid input (%d %d)", r, val);
282
         } else {
289
         } else {
283
 #ifdef TEST_VOLCANO_AUTO_CONNECT
290
 #ifdef TEST_VOLCANO_AUTO_CONNECT
284
-            VOLCANO_AUTO_CONNECT
291
+            DEV_AUTO_CONNECT(TEST_VOLCANO_AUTO_CONNECT);
285
 #endif // TEST_VOLCANO_AUTO_CONNECT
292
 #endif // TEST_VOLCANO_AUTO_CONNECT
286
 
293
 
287
             int8_t r = volcano_set_heater_state(val == 1);
294
             int8_t r = volcano_set_heater_state(val == 1);
303
             println("invalid input (%d %d)", r, val);
310
             println("invalid input (%d %d)", r, val);
304
         } else {
311
         } else {
305
 #ifdef TEST_VOLCANO_AUTO_CONNECT
312
 #ifdef TEST_VOLCANO_AUTO_CONNECT
306
-            VOLCANO_AUTO_CONNECT
313
+            DEV_AUTO_CONNECT(TEST_VOLCANO_AUTO_CONNECT);
307
 #endif // TEST_VOLCANO_AUTO_CONNECT
314
 #endif // TEST_VOLCANO_AUTO_CONNECT
308
 
315
 
309
             int8_t r = volcano_set_pump_state(val == 1);
316
             int8_t r = volcano_set_pump_state(val == 1);
340
                 println("workflow in progress");
347
                 println("workflow in progress");
341
             } else {
348
             } else {
342
 #ifdef TEST_VOLCANO_AUTO_CONNECT
349
 #ifdef TEST_VOLCANO_AUTO_CONNECT
343
-                VOLCANO_AUTO_CONNECT
350
+                DEV_AUTO_CONNECT(TEST_VOLCANO_AUTO_CONNECT);
344
 #endif // TEST_VOLCANO_AUTO_CONNECT
351
 #endif // TEST_VOLCANO_AUTO_CONNECT
345
 
352
 
346
                 println("starting workflow");
353
                 println("starting workflow");
360
 #endif // TEST_VOLCANO_AUTO_CONNECT
367
 #endif // TEST_VOLCANO_AUTO_CONNECT
361
             }
368
             }
362
         }
369
         }
370
+    } else if (strcmp(line, "crct") == 0) {
371
+#ifdef TEST_CRAFTY_AUTO_CONNECT
372
+        DEV_AUTO_CONNECT(TEST_CRAFTY_AUTO_CONNECT);
373
+#endif // TEST_CRAFTY_AUTO_CONNECT
374
+
375
+        int16_t r = crafty_get_current_temp();
376
+        println("crafty current temp: %.1f", r / 10.0);
377
+
378
+#ifdef TEST_CRAFTY_AUTO_CONNECT
379
+        ble_disconnect();
380
+#endif // TEST_CRAFTY_AUTO_CONNECT
381
+    } else if (strcmp(line, "crtt") == 0) {
382
+#ifdef TEST_CRAFTY_AUTO_CONNECT
383
+        DEV_AUTO_CONNECT(TEST_CRAFTY_AUTO_CONNECT);
384
+#endif // TEST_CRAFTY_AUTO_CONNECT
385
+
386
+        int16_t r = crafty_get_target_temp();
387
+        println("crafty target temp: %.1f", r / 10.0);
388
+
389
+#ifdef TEST_CRAFTY_AUTO_CONNECT
390
+        ble_disconnect();
391
+#endif // TEST_CRAFTY_AUTO_CONNECT
392
+    } else if (str_startswith(line, "cwtt ")) {
393
+        float val;
394
+        int r = sscanf(line, "cwtt %f", &val);
395
+        if (r != 1) {
396
+            println("invalid input (%d)", r);
397
+        } else {
398
+            uint16_t v = val * 10.0;
399
+
400
+#ifdef TEST_CRAFTY_AUTO_CONNECT
401
+            DEV_AUTO_CONNECT(TEST_CRAFTY_AUTO_CONNECT);
402
+#endif // TEST_CRAFTY_AUTO_CONNECT
403
+
404
+            int8_t r = crafty_set_target_temp(v);
405
+
406
+#ifdef TEST_CRAFTY_AUTO_CONNECT
407
+            ble_disconnect();
408
+#endif // TEST_CRAFTY_AUTO_CONNECT
409
+
410
+            if (r < 0) {
411
+                println("error writing target temp %d", r);
412
+            } else {
413
+                println("success");
414
+            }
415
+        }
416
+    } else if (str_startswith(line, "cwh ")) {
417
+        int val;
418
+        int r = sscanf(line, "cwh %d", &val);
419
+        if ((r != 1) || ((val != 0) && (val != 1))) {
420
+            println("invalid input (%d %d)", r, val);
421
+        } else {
422
+#ifdef TEST_CRAFTY_AUTO_CONNECT
423
+            DEV_AUTO_CONNECT(TEST_CRAFTY_AUTO_CONNECT);
424
+#endif // TEST_CRAFTY_AUTO_CONNECT
425
+
426
+            int8_t r = crafty_set_heater_state(val == 1);
427
+
428
+#ifdef TEST_CRAFTY_AUTO_CONNECT
429
+            ble_disconnect();
430
+#endif // TEST_CRAFTY_AUTO_CONNECT
431
+
432
+            if (r < 0) {
433
+                println("error writing heater state %d", r);
434
+            } else {
435
+                println("success");
436
+            }
437
+        }
438
+    } else if (strcmp(line, "crb") == 0) {
439
+#ifdef TEST_CRAFTY_AUTO_CONNECT
440
+        DEV_AUTO_CONNECT(TEST_CRAFTY_AUTO_CONNECT);
441
+#endif // TEST_CRAFTY_AUTO_CONNECT
442
+
443
+        int16_t r = crafty_get_battery_state();
444
+        println("crafty battery: %d %%", r);
445
+
446
+#ifdef TEST_CRAFTY_AUTO_CONNECT
447
+        ble_disconnect();
448
+#endif // TEST_CRAFTY_AUTO_CONNECT
363
     } else {
449
     } else {
364
         println("unknown command \"%s\"", line);
450
         println("unknown command \"%s\"", line);
365
     }
451
     }

+ 121
- 0
src/crafty.c Wyświetl plik

1
+/*
2
+ * crafty.c
3
+ *
4
+ * Copyright (c) 2023 Thomas Buck (thomas@xythobuz.de)
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * See <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+#include "config.h"
20
+#include "log.h"
21
+#include "ble.h"
22
+#include "crafty.h"
23
+
24
+// serviceUuidCrafty1      "00000001-4c45-4b43-4942-265a524f5453"
25
+// characteristicWriteTemp "00000021-4c45-4b43-4942-265a524f5453"
26
+// charactersiticCurrTemp  "00000011-4c45-4b43-4942-265a524f5453"
27
+// characteristicPower     "00000041-4c45-4b43-4942-265a524f5453"
28
+// characteristicHeaterOn  "00000081-4c45-4b43-4942-265a524f5453"
29
+// characteristicHeaterOff "00000091-4c45-4b43-4942-265a524f5453"
30
+
31
+// "000000xx-4c45-4b43-4942-265a524f5453"
32
+static uint8_t uuid_base[16] = {
33
+    0x00, 0x00, 0x00, 0xFF, 0x4c, 0x45, 0x4b, 0x43,
34
+    0x49, 0x42, 0x26, 0x5a, 0x52, 0x4f, 0x54, 0x53,
35
+};
36
+static uint8_t uuid_base2[16] = {
37
+    0x00, 0x00, 0x00, 0xFF, 0x4c, 0x45, 0x4b, 0x43,
38
+    0x49, 0x42, 0x26, 0x5a, 0x52, 0x4f, 0x54, 0x53,
39
+};
40
+
41
+// Crafty UUIDs are always the same, except for the 4th byte
42
+#define UUID_WRITE_SRVC   0x01
43
+#define UUID_CURRENT_TEMP 0x11
44
+#define UUID_TARGET_TEMP  0x21
45
+#define UUID_BATTERY      0x41
46
+#define UUID_HEATER_ON    0x81
47
+#define UUID_HEATER_OFF   0x91
48
+
49
+int16_t crafty_get_current_temp(void) {
50
+    uuid_base[3] = UUID_CURRENT_TEMP;
51
+
52
+    uint8_t buff[2];
53
+    int32_t r = ble_read(uuid_base, buff, sizeof(buff));
54
+    if (r != sizeof(buff)) {
55
+        debug("ble_read unexpected value %ld", r);
56
+        return -1;
57
+    }
58
+
59
+    uint16_t *v = (uint16_t *)buff;
60
+    return *v;
61
+}
62
+
63
+int16_t crafty_get_target_temp(void) {
64
+    uuid_base[3] = UUID_TARGET_TEMP;
65
+
66
+    uint8_t buff[2];
67
+    int32_t r = ble_read(uuid_base, buff, sizeof(buff));
68
+    if (r != sizeof(buff)) {
69
+        debug("ble_read unexpected value %ld", r);
70
+        return -1;
71
+    }
72
+
73
+    uint16_t *v = (uint16_t *)buff;
74
+    return *v;
75
+}
76
+
77
+int8_t crafty_set_target_temp(uint16_t value) {
78
+    uuid_base[3] = UUID_WRITE_SRVC;
79
+    uuid_base2[3] = UUID_TARGET_TEMP;
80
+
81
+    uint8_t buff[2];
82
+    uint16_t *v = (uint16_t *)buff;
83
+    *v = value;
84
+
85
+    int8_t r = ble_write(uuid_base, uuid_base2, buff, sizeof(buff));
86
+    if (r != 0) {
87
+        debug("ble_write unexpected value %d", r);
88
+    }
89
+    return r;
90
+}
91
+
92
+int8_t crafty_set_heater_state(bool value) {
93
+    uuid_base[3] = UUID_WRITE_SRVC;
94
+
95
+    if (value) {
96
+        uuid_base2[3] = UUID_HEATER_ON;
97
+    } else {
98
+        uuid_base2[3] = UUID_HEATER_OFF;
99
+    }
100
+
101
+    uint16_t d = 0;
102
+    int8_t r = ble_write(uuid_base, uuid_base2, (uint8_t *)&d, sizeof(d));
103
+    if (r != 0) {
104
+        debug("ble_write unexpected value %d", r);
105
+    }
106
+    return r;
107
+}
108
+
109
+int8_t crafty_get_battery_state(void) {
110
+    uuid_base[3] = UUID_BATTERY;
111
+
112
+    uint8_t buff[2];
113
+    int32_t r = ble_read(uuid_base, buff, sizeof(buff));
114
+    if (r != sizeof(buff)) {
115
+        debug("ble_read unexpected value %ld", r);
116
+        return -1;
117
+    }
118
+
119
+    uint16_t *v = (uint16_t *)buff;
120
+    return *v;
121
+}

+ 15
- 0
src/state.c Wyświetl plik

21
 #include "state_scan.h"
21
 #include "state_scan.h"
22
 #include "state_volcano_workflow.h"
22
 #include "state_volcano_workflow.h"
23
 #include "state_volcano_run.h"
23
 #include "state_volcano_run.h"
24
+#include "state_crafty.h"
24
 #include "state.h"
25
 #include "state.h"
25
 
26
 
26
 static enum system_state state = STATE_INIT;
27
 static enum system_state state = STATE_INIT;
47
         state_volcano_run_exit();
48
         state_volcano_run_exit();
48
         break;
49
         break;
49
 
50
 
51
+    case STATE_CRAFTY:
52
+        debug("leaving STATE_CRAFTY");
53
+        state_crafty_exit();
54
+        break;
55
+
50
     default:
56
     default:
51
         break;
57
         break;
52
     }
58
     }
68
         state_volcano_run_enter();
74
         state_volcano_run_enter();
69
         break;
75
         break;
70
 
76
 
77
+    case STATE_CRAFTY:
78
+        debug("entering STATE_CRAFTY");
79
+        state_crafty_enter();
80
+        break;
81
+
71
     default:
82
     default:
72
         break;
83
         break;
73
     }
84
     }
92
         state_volcano_run_run();
103
         state_volcano_run_run();
93
         break;
104
         break;
94
 
105
 
106
+    case STATE_CRAFTY:
107
+        state_crafty_run();
108
+        break;
109
+
95
     default:
110
     default:
96
         debug("invalid main state %d", state);
111
         debug("invalid main state %d", state);
97
         state_switch(STATE_SCAN);
112
         state_switch(STATE_SCAN);

+ 127
- 0
src/state_crafty.c Wyświetl plik

1
+/*
2
+ * state_crafty.c
3
+ *
4
+ * Copyright (c) 2023 Thomas Buck (thomas@xythobuz.de)
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * See <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+#include <stdio.h>
20
+#include <string.h>
21
+
22
+#include "config.h"
23
+#include "buttons.h"
24
+#include "crafty.h"
25
+#include "log.h"
26
+#include "state.h"
27
+#include "state_crafty.h"
28
+
29
+#include "menu.h"
30
+
31
+#define CRAFTY_UPDATE_TIME_MS 1000
32
+
33
+static bd_addr_t ble_addr = {0};
34
+static bd_addr_type_t ble_type = 0;
35
+static bool wait_for_connect = false;
36
+static bool wait_for_disconnect = false;
37
+static bool heater_state = false;
38
+static int16_t target_temp = 0;
39
+
40
+static void crafty_buttons(enum buttons btn, bool state) {
41
+    if (state && (btn == BTN_Y)) {
42
+        if ((!wait_for_connect) && (!wait_for_disconnect)) {
43
+            debug("crafty disconnect");
44
+            ble_disconnect();
45
+            wait_for_disconnect = true;
46
+        } else {
47
+            debug("invalid state for disconnect");
48
+        }
49
+    } else if (state && (btn == BTN_A)) {
50
+        heater_state = !heater_state;
51
+        debug("crafty heater %s", heater_state ? "on" : "off");
52
+        crafty_set_heater_state(heater_state);
53
+    } else if (state && (btn == BTN_LEFT)) {
54
+        target_temp -= 10;
55
+        if (target_temp < 400) {
56
+            target_temp = 400;
57
+        } else if (target_temp > 2100) {
58
+            target_temp = 2100;
59
+        }
60
+        debug("crafty temp to %.1f", target_temp / 10.0f);
61
+        crafty_set_target_temp(target_temp);
62
+    } else if (state && (btn == BTN_RIGHT)) {
63
+        target_temp += 10;
64
+        if (target_temp < 400) {
65
+            target_temp = 400;
66
+        } else if (target_temp > 2100) {
67
+            target_temp = 2100;
68
+        }
69
+        debug("crafty temp to %.1f", target_temp / 10.0f);
70
+        crafty_set_target_temp(target_temp);
71
+    }
72
+}
73
+
74
+void state_crafty_target(bd_addr_t addr, bd_addr_type_t type) {
75
+    memcpy(ble_addr, addr, sizeof(bd_addr_t));
76
+    ble_type = type;
77
+}
78
+
79
+void state_crafty_enter(void) {
80
+    debug("crafty connect");
81
+    ble_connect(ble_addr, ble_type);
82
+    wait_for_connect = true;
83
+
84
+    buttons_callback(crafty_buttons);
85
+}
86
+
87
+void state_crafty_exit(void) {
88
+    buttons_callback(NULL);
89
+}
90
+
91
+static void draw(struct menu_state *menu) {
92
+    if (wait_for_connect) {
93
+        snprintf(menu->buff, MENU_MAX_LEN, "Connecting...");
94
+    } else if (wait_for_disconnect) {
95
+        snprintf(menu->buff, MENU_MAX_LEN, "Disconnecting...");
96
+    } else {
97
+        target_temp = crafty_get_target_temp();
98
+        int16_t ct = crafty_get_current_temp();
99
+        int8_t bs = crafty_get_battery_state();
100
+
101
+        snprintf(menu->buff, MENU_MAX_LEN,
102
+                 "Target: %.1f C\n"
103
+                 "Current: %.1f C\n"
104
+                 "Battery: %d %%",
105
+                 target_temp / 10.0f, ct / 10.0f, bs);
106
+    }
107
+}
108
+
109
+void state_crafty_run(void) {
110
+    if (wait_for_connect && ble_is_connected()) {
111
+        wait_for_connect = false;
112
+        debug("crafty start");
113
+    }
114
+
115
+    static uint32_t last = 0;
116
+    uint32_t now = to_ms_since_boot(get_absolute_time());
117
+    if (((now - last) >= CRAFTY_UPDATE_TIME_MS) || (last == 0)) {
118
+        last = now;
119
+        menu_run(draw);
120
+    }
121
+
122
+    if (wait_for_disconnect && !ble_is_connected()) {
123
+        wait_for_disconnect = false;
124
+        debug("crafty done");
125
+        state_switch(STATE_SCAN);
126
+    }
127
+}

+ 4
- 0
src/state_scan.c Wyświetl plik

25
 #include "menu.h"
25
 #include "menu.h"
26
 #include "state.h"
26
 #include "state.h"
27
 #include "state_volcano_run.h"
27
 #include "state_volcano_run.h"
28
+#include "state_crafty.h"
28
 #include "state_scan.h"
29
 #include "state_scan.h"
29
 
30
 
30
 static struct ble_scan_result results[BLE_MAX_SCAN_RESULTS] = {0};
31
 static struct ble_scan_result results[BLE_MAX_SCAN_RESULTS] = {0};
42
             if (dev == DEV_VOLCANO) {
43
             if (dev == DEV_VOLCANO) {
43
                 state_volcano_run_target(results[i].addr, results[i].type);
44
                 state_volcano_run_target(results[i].addr, results[i].type);
44
                 state_switch(STATE_VOLCANO_WORKFLOW);
45
                 state_switch(STATE_VOLCANO_WORKFLOW);
46
+            } else if (dev == DEV_CRAFTY) {
47
+                state_crafty_target(results[i].addr, results[i].type);
48
+                state_switch(STATE_CRAFTY);
45
             }
49
             }
46
             return;
50
             return;
47
         }
51
         }

+ 4
- 3
src/state_volcano_run.c Wyświetl plik

27
 
27
 
28
 #include "menu.h"
28
 #include "menu.h"
29
 
29
 
30
-static uint16_t wf_index;
31
-static bd_addr_t ble_addr;
32
-static bd_addr_type_t ble_type;
30
+static uint16_t wf_index = 0;
31
+static bd_addr_t ble_addr = {0};
32
+static bd_addr_type_t ble_type = 0;
33
 static bool wait_for_connect = false;
33
 static bool wait_for_connect = false;
34
 static bool wait_for_disconnect = false;
34
 static bool wait_for_disconnect = false;
35
 
35
 
55
 static void draw(struct menu_state *menu) {
55
 static void draw(struct menu_state *menu) {
56
     struct wf_state state = wf_status();
56
     struct wf_state state = wf_status();
57
     snprintf(menu->buff, MENU_MAX_LEN, "%d / %d", state.step, state.count);
57
     snprintf(menu->buff, MENU_MAX_LEN, "%d / %d", state.step, state.count);
58
+    // TODO visualize
58
 }
59
 }
59
 
60
 
60
 void state_volcano_run_run(void) {
61
 void state_volcano_run_run(void) {

+ 7
- 8
src/volcano.c Wyświetl plik

18
 
18
 
19
 #include "config.h"
19
 #include "config.h"
20
 #include "log.h"
20
 #include "log.h"
21
-#include "util.h"
22
 #include "ble.h"
21
 #include "ble.h"
23
 #include "volcano.h"
22
 #include "volcano.h"
24
 
23
 
45
     uuid_base[3] = UUID_CURRENT_TEMP;
44
     uuid_base[3] = UUID_CURRENT_TEMP;
46
 
45
 
47
     uint8_t buff[4];
46
     uint8_t buff[4];
48
-    int32_t r = ble_read(uuid_base, buff, 4);
49
-    if (r != 4) {
47
+    int32_t r = ble_read(uuid_base, buff, sizeof(buff));
48
+    if (r != sizeof(buff)) {
50
         debug("ble_read unexpected value %ld", r);
49
         debug("ble_read unexpected value %ld", r);
51
         return -1;
50
         return -1;
52
     }
51
     }
59
     uuid_base[3] = UUID_TARGET_TEMP;
58
     uuid_base[3] = UUID_TARGET_TEMP;
60
 
59
 
61
     uint8_t buff[4];
60
     uint8_t buff[4];
62
-    int32_t r = ble_read(uuid_base, buff, 4);
63
-    if (r != 4) {
61
+    int32_t r = ble_read(uuid_base, buff, sizeof(buff));
62
+    if (r != sizeof(buff)) {
64
         debug("ble_read unexpected value %ld", r);
63
         debug("ble_read unexpected value %ld", r);
65
         return -1;
64
         return -1;
66
     }
65
     }
77
     uint32_t *v = (uint32_t *)buff;
76
     uint32_t *v = (uint32_t *)buff;
78
     *v = value;
77
     *v = value;
79
 
78
 
80
-    int8_t r = ble_write(uuid_base, uuid_base2, buff, 4);
79
+    int8_t r = ble_write(uuid_base, uuid_base2, buff, sizeof(buff));
81
     if (r != 0) {
80
     if (r != 0) {
82
         debug("ble_write unexpected value %d", r);
81
         debug("ble_write unexpected value %d", r);
83
     }
82
     }
94
     }
93
     }
95
 
94
 
96
     uint8_t d = 0;
95
     uint8_t d = 0;
97
-    int8_t r = ble_write(uuid_base, uuid_base2, &d, 1);
96
+    int8_t r = ble_write(uuid_base, uuid_base2, &d, sizeof(d));
98
     if (r != 0) {
97
     if (r != 0) {
99
         debug("ble_write unexpected value %d", r);
98
         debug("ble_write unexpected value %d", r);
100
     }
99
     }
111
     }
110
     }
112
 
111
 
113
     uint8_t d = 0;
112
     uint8_t d = 0;
114
-    int8_t r = ble_write(uuid_base, uuid_base2, &d, 1);
113
+    int8_t r = ble_write(uuid_base, uuid_base2, &d, sizeof(d));
115
     if (r != 0) {
114
     if (r != 0) {
116
         debug("ble_write unexpected value %d", r);
115
         debug("ble_write unexpected value %d", r);
117
     }
116
     }

Ładowanie…
Anuluj
Zapisz