Parcourir la source

custom picowota fork to show stuff on lcd and use flash wifi credentials

Thomas Buck il y a 11 mois
Parent
révision
a5644ba7a5
11 fichiers modifiés avec 205 ajouts et 13 suppressions
  1. 1
    1
      .gitmodules
  2. 40
    0
      CMakeLists.txt
  3. 7
    0
      include/log.h
  4. 1
    1
      include/ring.h
  5. 3
    0
      include/wifi.h
  6. 1
    1
      picowota
  7. 48
    4
      src/log.c
  8. 7
    0
      src/mem.c
  9. 77
    0
      src/ota_shim.c
  10. 16
    6
      src/ring.c
  11. 4
    0
      src/wifi.c

+ 1
- 1
.gitmodules Voir le fichier

@@ -12,4 +12,4 @@
12 12
 	url = https://github.com/hepingood/st7789
13 13
 [submodule "picowota"]
14 14
 	path = picowota
15
-	url = https://github.com/usedbytes/picowota
15
+	url = https://github.com/xythobuz/picowota

+ 40
- 0
CMakeLists.txt Voir le fichier

@@ -199,5 +199,45 @@ target_compile_definitions(gadget PUBLIC
199 199
     CYW43_HOST_NAME="pico-volcano"
200 200
 )
201 201
 
202
+set(PICOWOTA_ADDITIONAL_SOURCES
203
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/wifi.c
204
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/lcd.c
205
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/log.c
206
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/mem.c
207
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/ring.c
208
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/textbox.c
209
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/text.c
210
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/ota_shim.c
211
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/workflow_default.c
212
+
213
+    ${CMAKE_CURRENT_SOURCE_DIR}/st7789/src/driver_st7789.c
214
+
215
+    ${CMAKE_CURRENT_SOURCE_DIR}/mcufont/decoder/mf_encoding.c
216
+    ${CMAKE_CURRENT_SOURCE_DIR}/mcufont/decoder/mf_font.c
217
+    ${CMAKE_CURRENT_SOURCE_DIR}/mcufont/decoder/mf_justify.c
218
+    ${CMAKE_CURRENT_SOURCE_DIR}/mcufont/decoder/mf_kerning.c
219
+    ${CMAKE_CURRENT_SOURCE_DIR}/mcufont/decoder/mf_rlefont.c
220
+    ${CMAKE_CURRENT_SOURCE_DIR}/mcufont/decoder/mf_bwfont.c
221
+    ${CMAKE_CURRENT_SOURCE_DIR}/mcufont/decoder/mf_scaledfont.c
222
+    ${CMAKE_CURRENT_SOURCE_DIR}/mcufont/decoder/mf_wordwrap.c
223
+)
224
+set(PICOWOTA_ADDITIONAL_INCLUDES
225
+    ${CMAKE_CURRENT_SOURCE_DIR}/include
226
+    ${CMAKE_CURRENT_SOURCE_DIR}/conf
227
+    ${CMAKE_CURRENT_SOURCE_DIR}/data
228
+    ${CMAKE_CURRENT_SOURCE_DIR}/st7789/src
229
+    ${CMAKE_CURRENT_SOURCE_DIR}/st7789/interface
230
+    ${CMAKE_CURRENT_SOURCE_DIR}/mcufont/decoder
231
+    ${CMAKE_CURRENT_BINARY_DIR}/fatfs
232
+    ${CMAKE_CURRENT_SOURCE_DIR}/pico-sdk/src/rp2_common/pico_btstack/include
233
+    ${CMAKE_CURRENT_SOURCE_DIR}/pico-sdk/lib/btstack/platform/embedded
234
+)
235
+set(PICOWOTA_ADDITIONAL_LIBS
236
+    hardware_spi
237
+    hardware_pwm
238
+    hardware_flash
239
+    pico_flash
240
+)
241
+
202 242
 add_subdirectory(picowota)
203 243
 picowota_build_combined(gadget)

+ 7
- 0
include/log.h Voir le fichier

@@ -25,11 +25,17 @@
25 25
 
26 26
 // for output that is stored in the debug log.
27 27
 // will be re-played from buffer when terminal connects
28
+#ifndef PICOWOTA
28 29
 #define debug(fmt, ...) debug_log(true, \
29 30
         "%08lu %s: " fmt "\r\n", \
30 31
         to_ms_since_boot(get_absolute_time()), \
31 32
         __func__, \
32 33
         ##__VA_ARGS__)
34
+#else // PICOWOTA
35
+#define debug(fmt, ...) debug_log(true, \
36
+        fmt "\r\n", \
37
+        ##__VA_ARGS__)
38
+#endif // PICOWOTA
33 39
 
34 40
 // for interactive output. is not stored or re-played.
35 41
 #define print(fmt, ...) debug_log(false, fmt, ##__VA_ARGS__)
@@ -42,6 +48,7 @@ void debug_log_va(bool log, const char *format, va_list args);
42 48
 void log_dump_to_usb(void);
43 49
 void log_dump_to_uart(void);
44 50
 void log_dump_to_disk(void);
51
+void log_dump_to_lcd(void);
45 52
 
46 53
 void debug_handle_input(const void *buff, size_t len);
47 54
 

+ 1
- 1
include/ring.h Voir le fichier

@@ -36,7 +36,7 @@ void rb_add(struct ring_buffer *rb, const void *data, size_t length);
36 36
 #define rb_push(rb, v) rb_add(rb, v, 1)
37 37
 size_t rb_len(struct ring_buffer *rb);
38 38
 #define rb_space(rb) ((rb)->size - rb_len(rb))
39
-void rb_dump(struct ring_buffer *rb, void (*write)(const void *, size_t));
39
+void rb_dump(struct ring_buffer *rb, void (*write)(const void *, size_t), size_t skip);
40 40
 void rb_move(struct ring_buffer *rb, void (*write)(const void *, size_t));
41 41
 void rb_peek(struct ring_buffer *rb, void *buf);
42 42
 void rb_pop(struct ring_buffer *rb, void *buf);

+ 3
- 0
include/wifi.h Voir le fichier

@@ -19,6 +19,8 @@
19 19
 #ifndef __WIFI_H__
20 20
 #define __WIFI_H__
21 21
 
22
+#include <stdbool.h>
23
+
22 24
 #define WIFI_MAX_NET_COUNT 5
23 25
 #define WIFI_MAX_NAME_LEN 32
24 26
 #define WIFI_MAX_PASS_LEN 32
@@ -32,6 +34,7 @@ void wifi_init(void);
32 34
 void wifi_deinit(void);
33 35
 
34 36
 bool wifi_initialized(void);
37
+bool wifi_ready(void);
35 38
 const char *wifi_state(void);
36 39
 
37 40
 void wifi_run(void);

+ 1
- 1
picowota

@@ -1 +1 @@
1
-Subproject commit ac8960b274f0f76013364a9b83325036cb52f030
1
+Subproject commit 4abdeee20f2dd8f813f322b61ce1afee7b502d12

+ 48
- 4
src/log.c Voir le fichier

@@ -17,12 +17,15 @@
17 17
  */
18 18
 
19 19
 #include <stdio.h>
20
+#include <string.h>
20 21
 
21 22
 #include "hardware/watchdog.h"
22 23
 #include "ff.h"
23 24
 
24 25
 #include "config.h"
25 26
 #include "main.h"
27
+#include "lcd.h"
28
+#include "textbox.h"
26 29
 #include "usb_cdc.h"
27 30
 #include "serial.h"
28 31
 #include "ring.h"
@@ -33,12 +36,47 @@ static struct ring_buffer log = RB_INIT(log_buff, sizeof(log_buff), 1);
33 36
 
34 37
 static uint8_t line_buff[256] = {0};
35 38
 static volatile bool got_input = false;
39
+static int16_t lcd_off = 0;
40
+
41
+#ifndef PICOWOTA
36 42
 static FIL log_file_fat;
43
+#endif // PICOWOTA
37 44
 
38 45
 static void add_to_log(const void *buff, size_t len) {
39 46
     rb_add(&log, buff, len);
40 47
 }
41 48
 
49
+static void lcd_write(const void *buf, size_t len) {
50
+    char tmp[len + 1];
51
+    memcpy(tmp, buf, len);
52
+    tmp[len] = '\0';
53
+    lcd_off = text_box(tmp, false,
54
+                       "fixed_10x20",
55
+                       0, LCD_WIDTH,
56
+                       lcd_off, LCD_HEIGHT - lcd_off,
57
+                       0);
58
+}
59
+
60
+void log_dump_to_lcd(void) {
61
+    static size_t prev_len = 0;
62
+    size_t len = rb_len(&log);
63
+    if (len == prev_len) {
64
+        return;
65
+    }
66
+    prev_len = len;
67
+
68
+    lcd_off = 0;
69
+
70
+    const size_t todo = 120;
71
+    size_t text_off = 0;
72
+    if (len > todo) {
73
+        text_off = len - todo;
74
+    }
75
+
76
+    rb_dump(&log, lcd_write, text_off);
77
+}
78
+
79
+#ifndef PICOWOTA
42 80
 static void log_dump_to_x(void (*write)(const void *, size_t)) {
43 81
     if (rb_len(&log) == 0) {
44 82
         return;
@@ -49,7 +87,7 @@ static void log_dump_to_x(void (*write)(const void *, size_t)) {
49 87
         write(line_buff, l);
50 88
     }
51 89
 
52
-    rb_dump(&log, write);
90
+    rb_dump(&log, write, 0);
53 91
 
54 92
     l = snprintf((char *)line_buff, sizeof(line_buff), "\r\n\r\nlive log:\r\n");
55 93
     if ((l > 0) && (l <= (int)sizeof(line_buff))) {
@@ -64,7 +102,7 @@ void log_dump_to_usb(void) {
64 102
 void log_dump_to_uart(void) {
65 103
 #ifndef NDEBUG
66 104
     log_dump_to_x(serial_write);
67
-#endif
105
+#endif // NDEBUG
68 106
 }
69 107
 
70 108
 static void log_file_write_callback(const void *data, size_t len) {
@@ -82,7 +120,7 @@ void log_dump_to_disk(void) {
82 120
         return;
83 121
     }
84 122
 
85
-    rb_dump(&log, log_file_write_callback);
123
+    rb_dump(&log, log_file_write_callback, 0);
86 124
 
87 125
     res = f_close(&log_file_fat);
88 126
     if (res != FR_OK) {
@@ -90,6 +128,8 @@ void log_dump_to_disk(void) {
90 128
     }
91 129
 }
92 130
 
131
+#endif // PICOWOTA
132
+
93 133
 void debug_log_va(bool log, const char *format, va_list args) {
94 134
     int l = vsnprintf((char *)line_buff, sizeof(line_buff), format, args);
95 135
 
@@ -101,11 +141,13 @@ void debug_log_va(bool log, const char *format, va_list args) {
101 141
         l = snprintf((char *)line_buff, sizeof(line_buff), "%s: message too long (%d)\r\n", __func__, l);
102 142
     }
103 143
     if ((l > 0) && (l <= (int)sizeof(line_buff))) {
144
+#ifndef PICOWOTA
104 145
         usb_cdc_write(line_buff, l);
105 146
 
106 147
 #ifndef NDEBUG
107 148
         serial_write(line_buff, l);
108
-#endif
149
+#endif // NDEBUG
150
+#endif // PICOWOTA
109 151
 
110 152
         if (log) {
111 153
             add_to_log(line_buff, l);
@@ -120,6 +162,7 @@ void debug_log(bool log, const char* format, ...) {
120 162
     va_end(args);
121 163
 }
122 164
 
165
+#ifndef PICOWOTA
123 166
 void debug_handle_input(const void *buff, size_t len) {
124 167
     (void)buff;
125 168
 
@@ -145,3 +188,4 @@ void debug_wait_input(const char *format, ...) {
145 188
     usb_cdc_set_reroute(false);
146 189
     serial_set_reroute(false);
147 190
 }
191
+#endif // PICOWOTA

+ 7
- 0
src/mem.c Voir le fichier

@@ -87,9 +87,13 @@ void mem_load_defaults(void) {
87 87
     }
88 88
 
89 89
     // TODO better way to pre-define WiFi credentials
90
+#if defined(DEFAULT_WIFI_SSID) && defined(DEFAULT_WIFI_PASS)
90 91
     data_ram.data.net_count = 1;
91 92
     strcpy(data_ram.data.net[0].name, DEFAULT_WIFI_SSID);
92 93
     strcpy(data_ram.data.net[0].pass, DEFAULT_WIFI_PASS);
94
+#else
95
+    data_ram.data.net_count = 0;
96
+#endif
93 97
 }
94 98
 
95 99
 void mem_load(void) {
@@ -110,11 +114,13 @@ void mem_load(void) {
110 114
         } else {
111 115
             debug("loading from flash (0x%08lX)", checksum);
112 116
             data_ram = *flash_ptr;
117
+            debug("%s", data_ram.data.net[0].pass);
113 118
         }
114 119
     } else {
115 120
         debug("invalid config (0x%02X != 0x%02X)", flash_ptr->version, MEM_VERSION);
116 121
     }
117 122
 
123
+#if defined(DEFAULT_WIFI_SSID) && defined(DEFAULT_WIFI_PASS)
118 124
     // add default WiFi from #define to flash config, if it is not there yet
119 125
     bool found = false;
120 126
     for (uint16_t i = 0; i < data_ram.data.net_count; i++) {
@@ -133,6 +139,7 @@ void mem_load(void) {
133 139
         strcpy(data_ram.data.net[data_ram.data.net_count].pass, DEFAULT_WIFI_PASS);
134 140
         data_ram.data.net_count++;
135 141
     }
142
+#endif
136 143
 }
137 144
 
138 145
 static void mem_write_flash(void *param) {

+ 77
- 0
src/ota_shim.c Voir le fichier

@@ -0,0 +1,77 @@
1
+/*
2
+ * ota_shim.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 "pico/cyw43_arch.h"
20
+
21
+#include "config.h"
22
+#include "lcd.h"
23
+#include "log.h"
24
+#include "mem.h"
25
+#include "wifi.h"
26
+
27
+int picowota_network_init(void) {
28
+    debug("mem_load");
29
+    mem_load();
30
+
31
+    debug("lcd_init");
32
+    lcd_init();
33
+
34
+    lcd_set_backlight(mem_data()->backlight);
35
+    log_dump_to_lcd();
36
+
37
+    debug("cyw43_arch_init");
38
+    log_dump_to_lcd();
39
+
40
+    if (cyw43_arch_init_with_country(COUNTRY_CODE)) {
41
+        debug("failed to init cyw43");
42
+        log_dump_to_lcd();
43
+
44
+        return 1;
45
+    }
46
+
47
+    debug("wifi_init");
48
+    log_dump_to_lcd();
49
+
50
+    wifi_init();
51
+
52
+    const char *prev = NULL;
53
+    while (!wifi_ready()) {
54
+        cyw43_arch_poll();
55
+        wifi_run();
56
+
57
+        const char *state = wifi_state();
58
+        if (state != prev) {
59
+            prev = state;
60
+            debug("new state: %s", state);
61
+        }
62
+
63
+        log_dump_to_lcd();
64
+
65
+        // TODO open AP when timed out?
66
+    }
67
+
68
+    debug("wifi ready");
69
+    log_dump_to_lcd();
70
+
71
+    return 0;
72
+}
73
+
74
+void picowota_network_deinit(void) {
75
+    debug("wifi_deinit");
76
+    wifi_deinit();
77
+}

+ 16
- 6
src/ring.c Voir le fichier

@@ -16,6 +16,8 @@
16 16
  * See <http://www.gnu.org/licenses/>.
17 17
  */
18 18
 
19
+#define MIN(x, y) ((x < y) ? x : y)
20
+
19 21
 #include <string.h>
20 22
 
21 23
 #include "config.h"
@@ -51,21 +53,29 @@ size_t rb_len(struct ring_buffer *rb) {
51 53
     }
52 54
 }
53 55
 
54
-void rb_dump(struct ring_buffer *rb, void (*write)(const void *, size_t)) {
55
-    if (rb_len(rb) == 0) {
56
+void rb_dump(struct ring_buffer *rb, void (*write)(const void *, size_t), size_t skip) {
57
+    if (rb_len(rb) <= skip) {
56 58
         return;
57 59
     }
58 60
 
59 61
     if (rb->head > rb->tail) {
60
-        write(rb->buffer + rb->tail * rb->el_len, rb->head - rb->tail);
62
+        if ((rb->head - rb->tail) > skip) {
63
+            write(rb->buffer + ((rb->tail + skip) * rb->el_len), rb->head - rb->tail - skip);
64
+        }
61 65
     } else {
62
-        write(rb->buffer + rb->tail * rb->el_len, rb->size - rb->tail);
63
-        write(rb->buffer, rb->head);
66
+        if ((rb->size - rb->tail) > skip) {
67
+            write(rb->buffer + ((rb->tail + skip) * rb->el_len), rb->size - rb->tail - skip);
68
+        }
69
+
70
+        skip -= MIN(skip, rb->size - rb->tail);
71
+        if (rb->head > skip) {
72
+            write(rb->buffer + (skip + rb->el_len), rb->head - skip);
73
+        }
64 74
     }
65 75
 }
66 76
 
67 77
 void rb_move(struct ring_buffer *rb, void (*write)(const void *, size_t)) {
68
-    rb_dump(rb, write);
78
+    rb_dump(rb, write, 0);
69 79
     rb->head = 0;
70 80
     rb->tail = 0;
71 81
     rb->full = false;

+ 4
- 0
src/wifi.c Voir le fichier

@@ -112,6 +112,10 @@ bool wifi_initialized(void) {
112 112
     return (state != WS_IDLE);
113 113
 }
114 114
 
115
+bool wifi_ready(void) {
116
+    return (state == WS_READY);
117
+}
118
+
115 119
 const char *wifi_state(void) {
116 120
     switch (state) {
117 121
     case WS_IDLE:

Chargement…
Annuler
Enregistrer