Переглянути джерело

lcd working, drawing logo as splash screen

Thomas Buck 7 місяці тому
джерело
коміт
86e238560d
7 змінених файлів з 3958 додано та 26 видалено
  1. 3
    0
      CMakeLists.txt
  2. 29
    0
      include/lcd.h
  3. 2
    0
      include/log.h
  4. 3615
    0
      include/logo.h
  5. 269
    0
      src/lcd.c
  6. 14
    25
      src/log.c
  7. 26
    1
      src/main.c

+ 3
- 0
CMakeLists.txt Переглянути файл

@@ -56,6 +56,7 @@ target_sources(gadget PUBLIC
56 56
     src/buttons.c
57 57
     src/lipo.c
58 58
     src/ble.c
59
+    src/lcd.c
59 60
 
60 61
     ${CMAKE_CURRENT_BINARY_DIR}/fatfs/ff.c
61 62
     ${CMAKE_CURRENT_BINARY_DIR}/fatfs/ffunicode.c
@@ -100,6 +101,8 @@ target_link_libraries(gadget
100 101
     tinyusb_board
101 102
     hardware_spi
102 103
     hardware_adc
104
+    hardware_gpio
105
+    hardware_pwm
103 106
     pico_btstack_ble
104 107
     pico_btstack_cyw43
105 108
     pico_cyw43_arch_threadsafe_background

+ 29
- 0
include/lcd.h Переглянути файл

@@ -0,0 +1,29 @@
1
+/*
2
+ * lipo.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 __LCD_H__
20
+#define __LCD_H__
21
+
22
+void lcd_init(void);
23
+
24
+uint16_t lcd_get_backlight(void);
25
+void lcd_set_backlight(uint16_t value);
26
+
27
+void lcd_write_point(uint16_t x, uint16_t y, uint32_t color);
28
+
29
+#endif // __LCD_H__

+ 2
- 0
include/log.h Переглянути файл

@@ -19,6 +19,7 @@
19 19
 #ifndef __LOG_H__
20 20
 #define __LOG_H__
21 21
 
22
+#include <stdarg.h>
22 23
 #include <stdbool.h>
23 24
 
24 25
 // for output that is stored in the debug log.
@@ -35,6 +36,7 @@
35 36
 
36 37
 void debug_log(bool log, const char *format, ...) __attribute__((format(printf, 2, 3)));
37 38
 void debug_wait_input(const char *format, ...) __attribute__((format(printf, 1, 2)));
39
+void debug_log_va(bool log, const char *format, va_list args);
38 40
 
39 41
 void log_dump_to_usb(void);
40 42
 void log_dump_to_disk(void);

+ 3615
- 0
include/logo.h
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 269
- 0
src/lcd.c Переглянути файл

@@ -0,0 +1,269 @@
1
+/*
2
+ * lcd.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/stdlib.h"
20
+#include "hardware/spi.h"
21
+#include "hardware/pwm.h"
22
+#include "driver_st7789.h"
23
+
24
+#include "config.h"
25
+#include "log.h"
26
+#include "lcd.h"
27
+
28
+#define LCD_PIN_DC 8
29
+#define LCD_PIN_CS 9
30
+#define LCD_PIN_CLK 10
31
+#define LCD_PIN_DIN 11
32
+#define LCD_PIN_RST 12
33
+#define LCD_PIN_BL 13
34
+
35
+#define ST7789_PICO_COLUMN                             240
36
+#define ST7789_PICO_ROW                                240
37
+
38
+#define ST7789_PICO_ACCESS                            (ST7789_ORDER_PAGE_TOP_TO_BOTTOM | \
39
+                                                       ST7789_ORDER_COLUMN_LEFT_TO_RIGHT | \
40
+                                                       ST7789_ORDER_PAGE_COLUMN_NORMAL | \
41
+                                                       ST7789_ORDER_LINE_TOP_TO_BOTTOM | \
42
+                                                       ST7789_ORDER_COLOR_RGB | \
43
+                                                       ST7789_ORDER_REFRESH_LEFT_TO_RIGHT)
44
+
45
+#define ST7789_PICO_RGB_INTERFACE_COLOR_FORMAT         0
46
+#define ST7789_PICO_CONTROL_INTERFACE_COLOR_FORMAT     ST7789_CONTROL_INTERFACE_COLOR_FORMAT_16_BIT
47
+
48
+#define ST7789_PICO_PORCH_NORMAL_BACK                  0x0C
49
+#define ST7789_PICO_PORCH_NORMAL_FRONT                 0x0C
50
+#define ST7789_PICO_PORCH_ENABLE                       ST7789_BOOL_FALSE
51
+#define ST7789_PICO_PORCH_IDEL_BACK                    0x03
52
+#define ST7789_PICO_PORCH_IDEL_FRONT                   0x03
53
+#define ST7789_PICO_PORCH_PART_BACK                    0x03
54
+#define ST7789_PICO_PORCH_PART_FRONT                   0x03
55
+
56
+#define ST7789_PICO_VGHS                               ST7789_VGHS_13P26_V
57
+#define ST7789_PICO_VGLS_NEGATIVE                      ST7789_VGLS_NEGATIVE_10P43
58
+
59
+#define ST7789_PICO_VCOMS                              0.725f
60
+
61
+#define ST7789_PICO_XMY                                ST7789_BOOL_FALSE
62
+#define ST7789_PICO_XBGR                               ST7789_BOOL_TRUE
63
+#define ST7789_PICO_XINV                               ST7789_BOOL_FALSE
64
+#define ST7789_PICO_XMX                                ST7789_BOOL_TRUE
65
+#define ST7789_PICO_XMH                                ST7789_BOOL_TRUE
66
+#define ST7789_PICO_XMV                                ST7789_BOOL_FALSE
67
+#define ST7789_PICO_XGS                                ST7789_BOOL_FALSE
68
+
69
+#define ST7789_PICO_VDV_VRH_FROM                       ST7789_VDV_VRH_FROM_CMD
70
+#define ST7789_PICO_VRHS                               4.45f
71
+#define ST7789_PICO_VDV                                0.0f
72
+
73
+#define ST7789_PICO_INVERSION_SELECTION                ST7789_INVERSION_SELECTION_DOT
74
+#define ST7789_PICO_FRAME_RATE                         ST7789_FRAME_RATE_60_HZ
75
+
76
+#define ST7789_PICO_AVDD                               ST7789_AVDD_6P8_V
77
+#define ST7789_PICO_AVCL_NEGTIVE                       ST7789_AVCL_NEGTIVE_4P8_V
78
+#define ST7789_PICO_VDS                                ST7789_VDS_2P3_V
79
+
80
+#define ST7789_PICO_POSITIVE_VOLTAGE_GAMMA            {0xD0, 0x04, 0x0D, 0x11, 0x13, 0x2B, 0x3F, \
81
+                                                       0x54, 0x4C, 0x18, 0x0D, 0x0B, 0x1F, 0x23}
82
+#define ST7789_PICO_NEGATIVA_VOLTAGE_GAMMA            {0xD0, 0x04, 0x0C, 0x11, 0x13, 0x2C, 0x3F, \
83
+                                                       0x44, 0x51, 0x2F, 0x1F, 0x1F, 0x20, 0x23}
84
+
85
+static st7789_handle_t gs_handle;
86
+static uint16_t bl_value = 0;
87
+
88
+static uint8_t st7789_interface_spi_init(void) {
89
+    // Use SPI1 at 100MHz
90
+    spi_init(spi1, 100 * 1000 * 1000);
91
+    gpio_set_function(LCD_PIN_CLK, GPIO_FUNC_SPI);
92
+    gpio_set_function(LCD_PIN_DIN, GPIO_FUNC_SPI);
93
+
94
+    // Chip select is active-low, so we'll initialise it to a driven-high state
95
+    gpio_init(LCD_PIN_CS);
96
+    gpio_set_dir(LCD_PIN_CS, GPIO_OUT);
97
+    gpio_put(LCD_PIN_CS, 1);
98
+
99
+    spi_set_format(spi1,
100
+                   8, // Number of bits per transfer
101
+                   0, // Polarity (CPOL)
102
+                   0, // Phase (CPHA)
103
+                   SPI_MSB_FIRST);
104
+
105
+    return 0;
106
+}
107
+
108
+static uint8_t st7789_interface_spi_deinit(void) {
109
+    spi_deinit(spi1);
110
+    gpio_deinit(LCD_PIN_CS);
111
+    return 0;
112
+}
113
+
114
+static uint8_t st7789_interface_spi_write_cmd(uint8_t *buf, uint16_t len) {
115
+    gpio_put(LCD_PIN_CS, 0);
116
+    spi_write_blocking(spi1, buf, len);
117
+    gpio_put(LCD_PIN_CS, 1);
118
+    return 0;
119
+}
120
+
121
+static void st7789_interface_delay_ms(uint32_t ms) {
122
+    sleep_ms(ms);
123
+}
124
+
125
+static void st7789_interface_debug_print(const char *const fmt, ...) {
126
+    va_list args;
127
+    va_start(args, fmt);
128
+    debug_log_va(true, fmt, args);
129
+    va_end(args);
130
+}
131
+
132
+static uint8_t st7789_interface_cmd_data_gpio_init(void) {
133
+    gpio_init(LCD_PIN_DC);
134
+    gpio_set_dir(LCD_PIN_DC, GPIO_OUT);
135
+    return 0;
136
+}
137
+
138
+static uint8_t st7789_interface_cmd_data_gpio_deinit(void) {
139
+    gpio_deinit(LCD_PIN_DC);
140
+    return 0;
141
+}
142
+
143
+static uint8_t st7789_interface_cmd_data_gpio_write(uint8_t value) {
144
+    gpio_put(LCD_PIN_DC, value);
145
+    return 0;
146
+}
147
+
148
+static uint8_t st7789_interface_reset_gpio_init(void) {
149
+    gpio_init(LCD_PIN_RST);
150
+    gpio_set_dir(LCD_PIN_RST, GPIO_OUT);
151
+    return 0;
152
+}
153
+
154
+static uint8_t st7789_interface_reset_gpio_deinit(void) {
155
+    gpio_deinit(LCD_PIN_RST);
156
+    return 0;
157
+}
158
+
159
+static uint8_t st7789_interface_reset_gpio_write(uint8_t value) {
160
+    gpio_put(LCD_PIN_RST, value);
161
+    return 0;
162
+}
163
+
164
+void lcd_init(void) {
165
+    uint8_t reg;
166
+
167
+    DRIVER_ST7789_LINK_INIT(&gs_handle, st7789_handle_t);
168
+    DRIVER_ST7789_LINK_SPI_INIT(&gs_handle, st7789_interface_spi_init);
169
+    DRIVER_ST7789_LINK_SPI_DEINIT(&gs_handle, st7789_interface_spi_deinit);
170
+    DRIVER_ST7789_LINK_SPI_WRITE_COMMAND(&gs_handle, st7789_interface_spi_write_cmd);
171
+    DRIVER_ST7789_LINK_COMMAND_DATA_GPIO_INIT(&gs_handle, st7789_interface_cmd_data_gpio_init);
172
+    DRIVER_ST7789_LINK_COMMAND_DATA_GPIO_DEINIT(&gs_handle, st7789_interface_cmd_data_gpio_deinit);
173
+    DRIVER_ST7789_LINK_COMMAND_DATA_GPIO_WRITE(&gs_handle, st7789_interface_cmd_data_gpio_write);
174
+    DRIVER_ST7789_LINK_RESET_GPIO_INIT(&gs_handle, st7789_interface_reset_gpio_init);
175
+    DRIVER_ST7789_LINK_RESET_GPIO_DEINIT(&gs_handle, st7789_interface_reset_gpio_deinit);
176
+    DRIVER_ST7789_LINK_RESET_GPIO_WRITE(&gs_handle, st7789_interface_reset_gpio_write);
177
+    DRIVER_ST7789_LINK_DELAY_MS(&gs_handle, st7789_interface_delay_ms);
178
+    DRIVER_ST7789_LINK_DEBUG_PRINT(&gs_handle, st7789_interface_debug_print);
179
+
180
+    st7789_init(&gs_handle);
181
+
182
+    st7789_set_column(&gs_handle, ST7789_PICO_COLUMN);
183
+
184
+    st7789_set_row(&gs_handle, ST7789_PICO_ROW);
185
+
186
+    st7789_set_memory_data_access_control(&gs_handle, ST7789_PICO_ACCESS);
187
+
188
+    st7789_set_interface_pixel_format(&gs_handle,
189
+                                      ST7789_PICO_RGB_INTERFACE_COLOR_FORMAT,
190
+                                      ST7789_PICO_CONTROL_INTERFACE_COLOR_FORMAT);
191
+
192
+    st7789_set_porch(&gs_handle,
193
+                     ST7789_PICO_PORCH_NORMAL_BACK,
194
+                     ST7789_PICO_PORCH_NORMAL_FRONT,
195
+                     ST7789_PICO_PORCH_ENABLE,
196
+                     ST7789_PICO_PORCH_IDEL_BACK,
197
+                     ST7789_PICO_PORCH_IDEL_FRONT,
198
+                     ST7789_PICO_PORCH_PART_BACK,
199
+                     ST7789_PICO_PORCH_PART_FRONT);
200
+
201
+    st7789_set_gate_control(&gs_handle, ST7789_PICO_VGHS, ST7789_PICO_VGLS_NEGATIVE);
202
+
203
+    st7789_vcom_convert_to_register(&gs_handle, ST7789_PICO_VCOMS, &reg);
204
+    st7789_set_vcoms(&gs_handle, reg);
205
+
206
+    st7789_set_lcm_control(&gs_handle,
207
+                           ST7789_PICO_XMY,
208
+                           ST7789_PICO_XBGR,
209
+                           ST7789_PICO_XINV,
210
+                           ST7789_PICO_XMX,
211
+                           ST7789_PICO_XMH,
212
+                           ST7789_PICO_XMV,
213
+                           ST7789_PICO_XGS);
214
+
215
+    st7789_set_vdv_vrh_from(&gs_handle, ST7789_PICO_VDV_VRH_FROM);
216
+
217
+    st7789_vrhs_convert_to_register(&gs_handle, ST7789_PICO_VRHS, &reg);
218
+    st7789_set_vrhs(&gs_handle, reg);
219
+
220
+    st7789_vdv_convert_to_register(&gs_handle, ST7789_PICO_VDV, &reg);
221
+    st7789_set_vdv(&gs_handle, reg);
222
+
223
+    st7789_set_frame_rate(&gs_handle, ST7789_PICO_INVERSION_SELECTION, ST7789_PICO_FRAME_RATE);
224
+
225
+    st7789_set_power_control_1(&gs_handle,
226
+                               ST7789_PICO_AVDD,
227
+                               ST7789_PICO_AVCL_NEGTIVE,
228
+                               ST7789_PICO_VDS);
229
+
230
+    uint8_t param_positive[14] = ST7789_PICO_POSITIVE_VOLTAGE_GAMMA;
231
+    st7789_set_positive_voltage_gamma_control(&gs_handle, param_positive);
232
+
233
+    uint8_t param_negative[14] = ST7789_PICO_NEGATIVA_VOLTAGE_GAMMA;
234
+    st7789_set_negative_voltage_gamma_control(&gs_handle, param_negative);
235
+
236
+    st7789_display_inversion_on(&gs_handle);
237
+
238
+    st7789_sleep_out(&gs_handle);
239
+
240
+    st7789_display_on(&gs_handle);
241
+
242
+    st7789_clear(&gs_handle);
243
+
244
+    // backlight
245
+    uint bl_slice = pwm_gpio_to_slice_num(LCD_PIN_BL);
246
+    uint bl_channel = pwm_gpio_to_channel(LCD_PIN_BL);
247
+    gpio_set_function(LCD_PIN_BL, GPIO_FUNC_PWM);
248
+    pwm_set_wrap(bl_slice, 0xFFFF);
249
+    pwm_set_clkdiv(bl_slice, 1.0f);
250
+    pwm_set_chan_level(bl_slice, bl_channel, bl_value);
251
+    pwm_set_enabled(bl_slice, true);
252
+}
253
+
254
+uint16_t lcd_get_backlight(void) {
255
+    return bl_value;
256
+}
257
+
258
+void lcd_set_backlight(uint16_t value) {
259
+    uint bl_slice = pwm_gpio_to_slice_num(LCD_PIN_BL);
260
+    uint bl_channel = pwm_gpio_to_channel(LCD_PIN_BL);
261
+    bl_value = value;
262
+    pwm_set_chan_level(bl_slice, bl_channel, bl_value);
263
+}
264
+
265
+void lcd_write_point(uint16_t x, uint16_t y, uint32_t color) {
266
+    st7789_draw_point(&gs_handle, x, y, color);
267
+
268
+    st7789_display_on(&gs_handle);
269
+}

+ 14
- 25
src/log.c Переглянути файл

@@ -16,7 +16,6 @@
16 16
  * See <http://www.gnu.org/licenses/>.
17 17
  */
18 18
 
19
-#include <stdarg.h>
20 19
 #include <stdio.h>
21 20
 
22 21
 #include "pico/stdlib.h"
@@ -29,6 +28,7 @@
29 28
 #include "log.h"
30 29
 
31 30
 static char log_buff[4096];
31
+static char line_buff[512];
32 32
 static size_t head = 0, tail = 0;
33 33
 static bool full = false;
34 34
 static bool got_input = false;
@@ -106,28 +106,16 @@ void log_dump_to_disk(void) {
106 106
     }
107 107
 }
108 108
 
109
-static int format_debug_log(char *buff, size_t len, const char *format, va_list args) {
110
-    int l = vsnprintf(buff, len, format, args);
109
+void debug_log_va(bool log, const char *format, va_list args) {
110
+    int l = vsnprintf(line_buff, sizeof(line_buff), format, args);
111 111
 
112 112
     if (l < 0) {
113 113
         // encoding error
114
-        l = snprintf(buff, len, "%s: encoding error\r\n", __func__);
115
-    } else if (l >= (ssize_t)len) {
114
+        l = snprintf(line_buff, sizeof(line_buff), "%s: encoding error\r\n", __func__);
115
+    } else if (l >= (ssize_t)sizeof(line_buff)) {
116 116
         // not enough space for string
117
-        l = snprintf(buff, len, "%s: message too long (%d)\r\n", __func__, l);
117
+        l = snprintf(line_buff, sizeof(line_buff), "%s: message too long (%d)\r\n", __func__, l);
118 118
     }
119
-
120
-    return l;
121
-}
122
-
123
-void debug_log(bool log, const char* format, ...) {
124
-    static char line_buff[512];
125
-
126
-    va_list args;
127
-    va_start(args, format);
128
-    int l = format_debug_log(line_buff, sizeof(line_buff), format, args);
129
-    va_end(args);
130
-
131 119
     if ((l > 0) && (l <= (int)sizeof(line_buff))) {
132 120
         usb_cdc_write(line_buff, l);
133 121
 
@@ -137,6 +125,13 @@ void debug_log(bool log, const char* format, ...) {
137 125
     }
138 126
 }
139 127
 
128
+void debug_log(bool log, const char* format, ...) {
129
+    va_list args;
130
+    va_start(args, format);
131
+    debug_log_va(log, format, args);
132
+    va_end(args);
133
+}
134
+
140 135
 void debug_handle_input(char *buff, uint32_t len) {
141 136
     (void)buff;
142 137
 
@@ -146,17 +141,11 @@ void debug_handle_input(char *buff, uint32_t len) {
146 141
 }
147 142
 
148 143
 void debug_wait_input(const char *format, ...) {
149
-    static char line_buff[512];
150
-
151 144
     va_list args;
152 145
     va_start(args, format);
153
-    int l = format_debug_log(line_buff, sizeof(line_buff), format, args);
146
+    debug_log_va(false, format, args);
154 147
     va_end(args);
155 148
 
156
-    if ((l > 0) && (l <= (int)sizeof(line_buff))) {
157
-        usb_cdc_write(line_buff, l);
158
-    }
159
-
160 149
     got_input = false;
161 150
     usb_cdc_set_reroute(true);
162 151
 

+ 26
- 1
src/main.c Переглянути файл

@@ -29,14 +29,39 @@
29 29
 #include "fat_disk.h"
30 30
 #include "buttons.h"
31 31
 #include "ble.h"
32
+#include "lcd.h"
33
+
34
+#pragma GCC diagnostic push
35
+#pragma GCC diagnostic ignored "-Wtrigraphs"
36
+#include "logo.h"
37
+#pragma GCC diagnostic pop
38
+
39
+static void draw_splash(void) {
40
+    char *data = logo_rgb_data;
41
+    for (uint x = 0; x < logo_width; x++) {
42
+        for (uint y = 0; y < logo_height; y++) {
43
+            uint32_t pixel[3];
44
+            HEADER_PIXEL(data, pixel);
45
+
46
+            uint32_t color = (pixel[0] >> 3) << 11;
47
+            color |= (pixel[1] >> 2) << 5;
48
+            color |= pixel[2] >> 3;
49
+            lcd_write_point(240 - x, y, color);
50
+        }
51
+    }
52
+}
32 53
 
33 54
 int main(void) {
34 55
     heartbeat_init();
35 56
     buttons_init();
36
-
37 57
     cnsl_init();
38 58
     usb_init();
39 59
 
60
+    debug("lcd_init");
61
+    lcd_init();
62
+    draw_splash();
63
+    lcd_set_backlight(0x8000);
64
+
40 65
     if (watchdog_caused_reboot()) {
41 66
         debug("reset by watchdog");
42 67
     }

Завантаження…
Відмінити
Зберегти