Thomas Buck 1 год назад
Родитель
Сommit
5af9bc8780
13 измененных файлов: 461 добавлений и 24 удалений
  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 Просмотреть файл

@@ -69,6 +69,8 @@ target_sources(gadget PUBLIC
69 69
     src/menu.c
70 70
     src/state_volcano_workflow.c
71 71
     src/state_volcano_run.c
72
+    src/crafty.c
73
+    src/state_crafty.c
72 74
 
73 75
     ${CMAKE_CURRENT_BINARY_DIR}/fatfs/ff.c
74 76
     ${CMAKE_CURRENT_BINARY_DIR}/fatfs/ffunicode.c

+ 1
- 0
include/config.h Просмотреть файл

@@ -43,5 +43,6 @@
43 43
 #endif // DEBUG_DISK_WRITE_SOURCES
44 44
 
45 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 48
 #endif // __CONFIG_H__

+ 38
- 0
include/crafty.h Просмотреть файл

@@ -0,0 +1,38 @@
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 Просмотреть файл

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

+ 30
- 0
include/state_crafty.h Просмотреть файл

@@ -0,0 +1,30 @@
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 Просмотреть файл

@@ -28,10 +28,10 @@
28 28
 #include "util.h"
29 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 35
 #define BLE_MAX_SCAN_AGE_MS (10 * 1000)
36 36
 #define BLE_MAX_SERVICES 8
37 37
 #define BLE_MAX_CHARACTERISTICS 8
@@ -545,6 +545,9 @@ int32_t ble_read(const uint8_t *characteristic, uint8_t *buff, uint16_t buff_len
545 545
         uint32_t now = to_ms_since_boot(get_absolute_time());
546 546
         if ((now - start_time) >= BLE_READ_TIMEOUT_MS) {
547 547
             debug("timeout waiting for read");
548
+            cyw43_thread_enter();
549
+            state = TC_READY;
550
+            cyw43_thread_exit();
548 551
             return -3;
549 552
         }
550 553
 
@@ -631,6 +634,9 @@ int8_t ble_write(const uint8_t *service, const uint8_t *characteristic,
631 634
             uint32_t now = to_ms_since_boot(get_absolute_time());
632 635
             if ((now - start_time) >= BLE_SRVC_TIMEOUT_MS) {
633 636
                 debug("timeout waiting for service");
637
+                cyw43_thread_enter();
638
+                state = TC_READY;
639
+                cyw43_thread_exit();
634 640
                 return -3;
635 641
             }
636 642
 
@@ -695,6 +701,9 @@ int8_t ble_write(const uint8_t *service, const uint8_t *characteristic,
695 701
             uint32_t now = to_ms_since_boot(get_absolute_time());
696 702
             if ((now - start_time) >= BLE_CHAR_TIMEOUT_MS) {
697 703
                 debug("timeout waiting for characteristic");
704
+                cyw43_thread_enter();
705
+                state = TC_READY;
706
+                cyw43_thread_exit();
698 707
                 return -5;
699 708
             }
700 709
 
@@ -736,6 +745,9 @@ int8_t ble_write(const uint8_t *service, const uint8_t *characteristic,
736 745
         uint32_t now = to_ms_since_boot(get_absolute_time());
737 746
         if ((now - start_time) >= BLE_WRTE_TIMEOUT_MS) {
738 747
             debug("timeout waiting for write");
748
+            cyw43_thread_enter();
749
+            state = TC_READY;
750
+            cyw43_thread_exit();
739 751
             return -7;
740 752
         }
741 753
 

+ 95
- 9
src/console.c Просмотреть файл

@@ -41,15 +41,16 @@
41 41
 #include "models.h"
42 42
 #include "workflow.h"
43 43
 #include "console.h"
44
+#include "crafty.h"
44 45
 
45 46
 #define CNSL_BUFF_SIZE 64
46 47
 #define CNSL_REPEAT_MS 500
47 48
 
48
-#define VOLCANO_AUTO_CONNECT {                                    \
49
+#define DEV_AUTO_CONNECT(s) {                                     \
49 50
     ble_scan(BLE_SCAN_OFF);                                       \
50 51
     bd_addr_t addr;                                               \
51 52
     bd_addr_type_t type;                                          \
52
-    const char *foo = TEST_VOLCANO_AUTO_CONNECT;                  \
53
+    const char *foo = s;                                          \
53 54
     sscanf(foo, "%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX %hhu", \
54 55
             &addr[0], &addr[1], &addr[2], &addr[3],               \
55 56
             &addr[4], &addr[5], &type);                           \
@@ -114,11 +115,17 @@ static void cnsl_interpret(const char *line) {
114 115
         println("   vrtt - Volcano read target temperature");
115 116
         println(" vwtt X - Volcano write target temperature");
116 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 119
         println("");
119 120
         println("    wfl - List available workflows");
120 121
         println("   wf X - Run workflow");
121 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 129
         println("Press Enter with no input to repeat last command.");
123 130
         println("Use repeat to continuously execute last command.");
124 131
         println("Stop this by calling repeat again.");
@@ -230,7 +237,7 @@ static void cnsl_interpret(const char *line) {
230 237
         draw_battery_indicator();
231 238
     } else if (strcmp(line, "vrct") == 0) {
232 239
 #ifdef TEST_VOLCANO_AUTO_CONNECT
233
-        VOLCANO_AUTO_CONNECT
240
+        DEV_AUTO_CONNECT(TEST_VOLCANO_AUTO_CONNECT);
234 241
 #endif // TEST_VOLCANO_AUTO_CONNECT
235 242
 
236 243
         int16_t r = volcano_get_current_temp();
@@ -241,7 +248,7 @@ static void cnsl_interpret(const char *line) {
241 248
 #endif // TEST_VOLCANO_AUTO_CONNECT
242 249
     } else if (strcmp(line, "vrtt") == 0) {
243 250
 #ifdef TEST_VOLCANO_AUTO_CONNECT
244
-        VOLCANO_AUTO_CONNECT
251
+        DEV_AUTO_CONNECT(TEST_VOLCANO_AUTO_CONNECT);
245 252
 #endif // TEST_VOLCANO_AUTO_CONNECT
246 253
 
247 254
         int16_t r = volcano_get_target_temp();
@@ -259,7 +266,7 @@ static void cnsl_interpret(const char *line) {
259 266
             uint16_t v = val * 10.0;
260 267
 
261 268
 #ifdef TEST_VOLCANO_AUTO_CONNECT
262
-            VOLCANO_AUTO_CONNECT
269
+            DEV_AUTO_CONNECT(TEST_VOLCANO_AUTO_CONNECT);
263 270
 #endif // TEST_VOLCANO_AUTO_CONNECT
264 271
 
265 272
             int8_t r = volcano_set_target_temp(v);
@@ -281,7 +288,7 @@ static void cnsl_interpret(const char *line) {
281 288
             println("invalid input (%d %d)", r, val);
282 289
         } else {
283 290
 #ifdef TEST_VOLCANO_AUTO_CONNECT
284
-            VOLCANO_AUTO_CONNECT
291
+            DEV_AUTO_CONNECT(TEST_VOLCANO_AUTO_CONNECT);
285 292
 #endif // TEST_VOLCANO_AUTO_CONNECT
286 293
 
287 294
             int8_t r = volcano_set_heater_state(val == 1);
@@ -303,7 +310,7 @@ static void cnsl_interpret(const char *line) {
303 310
             println("invalid input (%d %d)", r, val);
304 311
         } else {
305 312
 #ifdef TEST_VOLCANO_AUTO_CONNECT
306
-            VOLCANO_AUTO_CONNECT
313
+            DEV_AUTO_CONNECT(TEST_VOLCANO_AUTO_CONNECT);
307 314
 #endif // TEST_VOLCANO_AUTO_CONNECT
308 315
 
309 316
             int8_t r = volcano_set_pump_state(val == 1);
@@ -340,7 +347,7 @@ static void cnsl_interpret(const char *line) {
340 347
                 println("workflow in progress");
341 348
             } else {
342 349
 #ifdef TEST_VOLCANO_AUTO_CONNECT
343
-                VOLCANO_AUTO_CONNECT
350
+                DEV_AUTO_CONNECT(TEST_VOLCANO_AUTO_CONNECT);
344 351
 #endif // TEST_VOLCANO_AUTO_CONNECT
345 352
 
346 353
                 println("starting workflow");
@@ -360,6 +367,85 @@ static void cnsl_interpret(const char *line) {
360 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 449
     } else {
364 450
         println("unknown command \"%s\"", line);
365 451
     }

+ 121
- 0
src/crafty.c Просмотреть файл

@@ -0,0 +1,121 @@
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 Просмотреть файл

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

+ 127
- 0
src/state_crafty.c Просмотреть файл

@@ -0,0 +1,127 @@
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 Просмотреть файл

@@ -25,6 +25,7 @@
25 25
 #include "menu.h"
26 26
 #include "state.h"
27 27
 #include "state_volcano_run.h"
28
+#include "state_crafty.h"
28 29
 #include "state_scan.h"
29 30
 
30 31
 static struct ble_scan_result results[BLE_MAX_SCAN_RESULTS] = {0};
@@ -42,6 +43,9 @@ static void enter_cb(int selection) {
42 43
             if (dev == DEV_VOLCANO) {
43 44
                 state_volcano_run_target(results[i].addr, results[i].type);
44 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 50
             return;
47 51
         }

+ 4
- 3
src/state_volcano_run.c Просмотреть файл

@@ -27,9 +27,9 @@
27 27
 
28 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 33
 static bool wait_for_connect = false;
34 34
 static bool wait_for_disconnect = false;
35 35
 
@@ -55,6 +55,7 @@ void state_volcano_run_exit(void) {
55 55
 static void draw(struct menu_state *menu) {
56 56
     struct wf_state state = wf_status();
57 57
     snprintf(menu->buff, MENU_MAX_LEN, "%d / %d", state.step, state.count);
58
+    // TODO visualize
58 59
 }
59 60
 
60 61
 void state_volcano_run_run(void) {

+ 7
- 8
src/volcano.c Просмотреть файл

@@ -18,7 +18,6 @@
18 18
 
19 19
 #include "config.h"
20 20
 #include "log.h"
21
-#include "util.h"
22 21
 #include "ble.h"
23 22
 #include "volcano.h"
24 23
 
@@ -45,8 +44,8 @@ int16_t volcano_get_current_temp(void) {
45 44
     uuid_base[3] = UUID_CURRENT_TEMP;
46 45
 
47 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 49
         debug("ble_read unexpected value %ld", r);
51 50
         return -1;
52 51
     }
@@ -59,8 +58,8 @@ int16_t volcano_get_target_temp(void) {
59 58
     uuid_base[3] = UUID_TARGET_TEMP;
60 59
 
61 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 63
         debug("ble_read unexpected value %ld", r);
65 64
         return -1;
66 65
     }
@@ -77,7 +76,7 @@ int8_t volcano_set_target_temp(uint16_t value) {
77 76
     uint32_t *v = (uint32_t *)buff;
78 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 80
     if (r != 0) {
82 81
         debug("ble_write unexpected value %d", r);
83 82
     }
@@ -94,7 +93,7 @@ int8_t volcano_set_heater_state(bool value) {
94 93
     }
95 94
 
96 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 97
     if (r != 0) {
99 98
         debug("ble_write unexpected value %d", r);
100 99
     }
@@ -111,7 +110,7 @@ int8_t volcano_set_pump_state(bool value) {
111 110
     }
112 111
 
113 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 114
     if (r != 0) {
116 115
         debug("ble_write unexpected value %d", r);
117 116
     }

Загрузка…
Отмена
Сохранить