浏览代码

add generic ring buffer lib, used for log buffer and new uart tx buffer. uart as second console option for nicer debugging.

Thomas Buck 1年前
父节点
当前提交
e41bd0bfed
共有 14 个文件被更改,包括 320 次插入68 次删除
  1. 2
    0
      CMakeLists.txt
  2. 10
    2
      README.md
  3. 8
    1
      debug_swd.sh
  4. 4
    1
      include/config.h
  5. 1
    0
      include/log.h
  6. 39
    0
      include/ring.h
  7. 30
    0
      include/serial.h
  8. 5
    1
      include/usb_cdc.h
  9. 2
    2
      src/console.c
  10. 41
    56
      src/log.c
  11. 2
    0
      src/main.c
  12. 76
    0
      src/ring.c
  13. 97
    0
      src/serial.c
  14. 3
    5
      src/usb_cdc.c

+ 2
- 0
CMakeLists.txt 查看文件

@@ -61,6 +61,8 @@ target_sources(gadget PUBLIC
61 61
     src/image.c
62 62
     src/state.c
63 63
     src/volcano.c
64
+    src/serial.c
65
+    src/ring.c
64 66
 
65 67
     ${CMAKE_CURRENT_BINARY_DIR}/fatfs/ff.c
66 68
     ${CMAKE_CURRENT_BINARY_DIR}/fatfs/ffunicode.c

+ 10
- 2
README.md 查看文件

@@ -54,12 +54,16 @@ For this you need to compile the `picoprobe` firmware, like this.
54 54
 
55 55
     git clone https://github.com/raspberrypi/picoprobe.git
56 56
     cd picoprobe
57
+
57 58
     git submodule update --init
58 59
     mkdir build
59 60
     cd build
61
+
60 62
     PICO_SDK_PATH=../../../pico-sdk cmake ..
61 63
     make -j4
62 64
 
65
+    cd ../.. # back to build_debug directory from before
66
+
63 67
 And flash the resulting `picoprobe.uf2` to your probe.
64 68
 Connect `GP2` of the probe to `SWCLK` of the target and `GP3` of the probe to `SWDIO` of the target.
65 69
 Of course you also need to connect GND between both.
@@ -69,8 +73,6 @@ You need some dependencies, mainly `gdb-multiarch` and the RP2040 fork of `OpenO
69 73
     sudo apt install gdb-multiarch   # Debian / Ubuntu
70 74
     sudo pacman -S arm-none-eabi-gdb # Arch Linux
71 75
 
72
-    cd ../.. # back to build_debug directory from before
73
-
74 76
     git clone https://github.com/raspberrypi/openocd.git --branch rp2040 --recursive --depth=1
75 77
     cd openocd
76 78
 
@@ -82,6 +84,8 @@ You need some dependencies, mainly `gdb-multiarch` and the RP2040 fork of `OpenO
82 84
     ./configure --enable-ftdi --enable-sysfsgpio --enable-bcm2835gpio
83 85
     make -j4
84 86
 
87
+    cd .. # back to build_debug directory from before
88
+
85 89
 Now we can flash a firmware image via OpenOCD.
86 90
 
87 91
     ./openocd/src/openocd -s openocd/tcl -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000" -c "cmsis_dap_vid_pid 0x2e8a 0x000c" -c "program gadget.elf verify reset exit"
@@ -92,6 +96,10 @@ And also start a GDB debugging session.
92 96
     arm-none-eabi-gdb gadget.elf
93 97
     target extended-remote localhost:3333
94 98
 
99
+    load # program elf into flash
100
+    monitor reset init # put into clean initial state
101
+    continue # start program
102
+
95 103
 These commands have also been put in the `flash_swd.sh` and `debug_swd.sh` scripts, respectively.
96 104
 Call them from the `build_debug` folder where you checked out and built OpenOCD.
97 105
 

+ 8
- 1
debug_swd.sh 查看文件

@@ -15,7 +15,14 @@ while ! netstat -tna | grep 'LISTEN\>' | grep -q ':3333\>'; do
15 15
 done
16 16
 
17 17
 echo Starting GDB
18
-arm-none-eabi-gdb -ex "set history save" -ex "show print pretty" -ex "target extended-remote localhost:3333" $1
18
+arm-none-eabi-gdb \
19
+-ex "set history save" \
20
+-ex "show print pretty" \
21
+-ex "target extended-remote localhost:3333" \
22
+-ex "tui new-layout default asm 1 src 2 status 0 cmd 1" \
23
+-ex "tui layout default" \
24
+-ex "tui enable" \
25
+$1
19 26
 
20 27
 echo Killing OpenOCD instance in background
21 28
 kill $OPENOCD_PID

+ 4
- 1
include/config.h 查看文件

@@ -19,6 +19,9 @@
19 19
 #ifndef __CONFIG_H__
20 20
 #define __CONFIG_H__
21 21
 
22
+// ASCII 0x18 = CAN (cancel)
23
+#define ENTER_BOOTLOADER_MAGIC 0x18
24
+
22 25
 //#define DISABLE_CDC_DTR_CHECK
23 26
 #define DEBOUNCE_DELAY_MS 5
24 27
 
@@ -29,7 +32,7 @@
29 32
 #ifdef DEBUG_DISK_WRITE_SOURCES
30 33
 #define DISK_BLOCK_COUNT (256 + 128)
31 34
 #else // DEBUG_DISK_WRITE_SOURCES
32
-#define DISK_BLOCK_COUNT 128 // 128 is minimum size for fatfs lib
35
+#define DISK_BLOCK_COUNT 256
33 36
 #endif // DEBUG_DISK_WRITE_SOURCES
34 37
 
35 38
 #endif // __CONFIG_H__

+ 1
- 0
include/log.h 查看文件

@@ -40,6 +40,7 @@ void debug_wait_input(const char *format, ...) __attribute__((format(printf, 1,
40 40
 void debug_log_va(bool log, const char *format, va_list args);
41 41
 
42 42
 void log_dump_to_usb(void);
43
+void log_dump_to_uart(void);
43 44
 void log_dump_to_disk(void);
44 45
 
45 46
 void debug_handle_input(char *buff, uint32_t len);

+ 39
- 0
include/ring.h 查看文件

@@ -0,0 +1,39 @@
1
+/*
2
+ * ring.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 __RING_BUFFER_H__
20
+#define __RING_BUFFER_H__
21
+
22
+#include <stddef.h>
23
+#include <stdint.h>
24
+#include <stdbool.h>
25
+
26
+struct ring_buffer {
27
+    uint8_t *buffer;
28
+    size_t size;
29
+    size_t head, tail;
30
+    bool full;
31
+};
32
+#define RB_INIT(b, s) { .buffer = b, .size = s, .head = 0, .tail = 0, .full = false }
33
+
34
+void rb_add(struct ring_buffer *rb, const uint8_t *data, size_t length);
35
+size_t rb_len(struct ring_buffer *rb);
36
+void rb_dump(struct ring_buffer *rb, void (*write)(const uint8_t *, size_t));
37
+uint8_t rb_pop(struct ring_buffer *rb);
38
+
39
+#endif // __RING_BUFFER_H__

+ 30
- 0
include/serial.h 查看文件

@@ -0,0 +1,30 @@
1
+/*
2
+ * serial.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 __SERIAL_H__
20
+#define __SERIAL_H__
21
+
22
+#include <stddef.h>
23
+#include <stdint.h>
24
+#include <stdbool.h>
25
+
26
+void serial_init(void);
27
+void serial_write(const uint8_t *buf, size_t count);
28
+void serial_set_reroute(bool reroute);
29
+
30
+#endif // __SERIAL_H__

+ 5
- 1
include/usb_cdc.h 查看文件

@@ -19,7 +19,11 @@
19 19
 #ifndef __USB_CDC_H__
20 20
 #define __USB_CDC_H__
21 21
 
22
-void usb_cdc_write(const char *buf, uint32_t count);
22
+#include <stddef.h>
23
+#include <stdint.h>
24
+#include <stdbool.h>
25
+
26
+void usb_cdc_write(const uint8_t *buf, size_t count);
23 27
 void usb_cdc_set_reroute(bool reroute);
24 28
 
25 29
 #endif // __USB_CDC_H__

+ 2
- 2
src/console.c 查看文件

@@ -329,12 +329,12 @@ void cnsl_handle_input(const char *buf, uint32_t len) {
329 329
                 cnsl_buff_pos -= 1;
330 330
             }
331 331
 
332
-            usb_cdc_write("\b \b", 3);
332
+            usb_cdc_write((const uint8_t *)"\b \b", 3);
333 333
 
334 334
             // check for another backspace in this space
335 335
             i--;
336 336
         } else {
337
-            usb_cdc_write(cnsl_line_buff + i, 1);
337
+            usb_cdc_write((const uint8_t *)(cnsl_line_buff + i), 1);
338 338
         }
339 339
     }
340 340
 

+ 41
- 56
src/log.c 查看文件

@@ -24,96 +24,79 @@
24 24
 #include "config.h"
25 25
 #include "usb.h"
26 26
 #include "usb_cdc.h"
27
+#include "serial.h"
28
+#include "ring.h"
27 29
 #include "log.h"
28 30
 
29
-static char log_buff[4096];
30
-static char line_buff[512];
31
-static size_t head = 0, tail = 0;
32
-static bool full = false;
33
-static bool got_input = false;
31
+static uint8_t log_buff[4096] = {0};
32
+static struct ring_buffer log = RB_INIT(log_buff, sizeof(log_buff));
34 33
 
35
-static void add_to_log(const char *buff, int len) {
36
-    for (int i = 0; i < len; i++) {
37
-        log_buff[head] = buff[i];
34
+static uint8_t line_buff[128] = {0};
35
+static volatile bool got_input = false;
36
+static FIL log_file_fat;
38 37
 
39
-        if (full && (++tail == sizeof(log_buff))) {
40
-            tail = 0;
41
-        }
42
-
43
-        if (++(head) == sizeof(log_buff)) {
44
-            head = 0;
45
-        }
46
-
47
-        full = (head == tail);
48
-    }
38
+static void add_to_log(const uint8_t *buff, size_t len) {
39
+    rb_add(&log, buff, len);
49 40
 }
50 41
 
51
-void log_dump_to_usb(void) {
52
-    if (head == tail) {
42
+static void log_dump_to_x(void (*write)(const uint8_t *, size_t)) {
43
+    if (rb_len(&log) == 0) {
53 44
         return;
54 45
     }
55 46
 
56
-    char buff[32];
57
-    int l = snprintf(buff, sizeof(buff), "\r\n\r\nbuffered log output:\r\n");
58
-    if ((l > 0) && (l <= (int)sizeof(buff))) {
59
-        usb_cdc_write(buff, l);
47
+    int l = snprintf((char *)line_buff, sizeof(line_buff), "\r\n\r\nbuffered log output:\r\n");
48
+    if ((l > 0) && (l <= (int)sizeof(line_buff))) {
49
+        write(line_buff, l);
60 50
     }
61 51
 
62
-    if (head > tail) {
63
-        usb_cdc_write(log_buff + tail, head - tail);
64
-    } else {
65
-        usb_cdc_write(log_buff + tail, sizeof(log_buff) - tail);
66
-        usb_cdc_write(log_buff, head);
52
+    rb_dump(&log, write);
53
+
54
+    l = snprintf((char *)line_buff, sizeof(line_buff), "\r\n\r\nlive log:\r\n");
55
+    if ((l > 0) && (l <= (int)sizeof(line_buff))) {
56
+        write(line_buff, l);
67 57
     }
58
+}
68 59
 
69
-    l = snprintf(buff, sizeof(buff), "\r\n\r\nlive log:\r\n");
70
-    if ((l > 0) && (l <= (int)sizeof(buff))) {
71
-        usb_cdc_write(buff, l);
60
+void log_dump_to_usb(void) {
61
+    log_dump_to_x(usb_cdc_write);
62
+}
63
+
64
+void log_dump_to_uart(void) {
65
+    log_dump_to_x(serial_write);
66
+}
67
+
68
+static void log_file_write_callback(const uint8_t *data, size_t len) {
69
+    UINT bw;
70
+    FRESULT res = f_write(&log_file_fat, data, len, &bw);
71
+    if ((res != FR_OK) || (bw != len)) {
72
+        debug("error: f_write %u returned %d", len, res);
72 73
     }
73 74
 }
74 75
 
75 76
 void log_dump_to_disk(void) {
76
-    FIL file;
77
-    FRESULT res = f_open(&file, "log.txt", FA_CREATE_ALWAYS | FA_WRITE);
77
+    FRESULT res = f_open(&log_file_fat, "log.txt", FA_CREATE_ALWAYS | FA_WRITE);
78 78
     if (res != FR_OK) {
79 79
         debug("error: f_open returned %d", res);
80 80
         return;
81 81
     }
82 82
 
83
-    UINT bw;
84
-
85
-    if (head > tail) {
86
-        res = f_write(&file, log_buff + tail, head - tail, &bw);
87
-        if ((res != FR_OK) || (bw != head - tail)) {
88
-            debug("error: f_write (A) returned %d", res);
89
-        }
90
-    } else if (head < tail) {
91
-        res = f_write(&file, log_buff + tail, sizeof(log_buff) - tail, &bw);
92
-        if ((res != FR_OK) || (bw != sizeof(log_buff) - tail)) {
93
-            debug("error: f_write (B) returned %d", res);
94
-        } else {
95
-            res = f_write(&file, log_buff, head, &bw);
96
-            if ((res != FR_OK) || (bw != head)) {
97
-                debug("error: f_write (C) returned %d", res);
98
-            }
99
-        }
100
-    }
83
+    rb_dump(&log, log_file_write_callback);
101 84
 
102
-    res = f_close(&file);
85
+    res = f_close(&log_file_fat);
103 86
     if (res != FR_OK) {
104 87
         debug("error: f_close returned %d", res);
105 88
     }
106 89
 }
107 90
 
108 91
 void debug_log_va(bool log, const char *format, va_list args) {
109
-    int l = vsnprintf(line_buff, sizeof(line_buff), format, args);
92
+    int l = vsnprintf((char *)line_buff, sizeof(line_buff), format, args);
110 93
 
111 94
     if (l < 0) {
112 95
         // encoding error
113
-        l = snprintf(line_buff, sizeof(line_buff), "%s: encoding error\r\n", __func__);
96
+        l = snprintf((char *)line_buff, sizeof(line_buff), "%s: encoding error\r\n", __func__);
114 97
     } else if (l >= (ssize_t)sizeof(line_buff)) {
115 98
         // not enough space for string
116
-        l = snprintf(line_buff, sizeof(line_buff), "%s: message too long (%d)\r\n", __func__, l);
99
+        l = snprintf((char *)line_buff, sizeof(line_buff), "%s: message too long (%d)\r\n", __func__, l);
117 100
     }
118 101
     if ((l > 0) && (l <= (int)sizeof(line_buff))) {
119 102
         usb_cdc_write(line_buff, l);
@@ -147,6 +130,7 @@ void debug_wait_input(const char *format, ...) {
147 130
 
148 131
     got_input = false;
149 132
     usb_cdc_set_reroute(true);
133
+    serial_set_reroute(true);
150 134
 
151 135
     while (!got_input) {
152 136
         watchdog_update();
@@ -154,4 +138,5 @@ void debug_wait_input(const char *format, ...) {
154 138
     }
155 139
 
156 140
     usb_cdc_set_reroute(false);
141
+    serial_set_reroute(false);
157 142
 }

+ 2
- 0
src/main.c 查看文件

@@ -34,10 +34,12 @@
34 34
 #include "text.h"
35 35
 #include "image.h"
36 36
 #include "state.h"
37
+#include "serial.h"
37 38
 
38 39
 int main(void) {
39 40
     // required for debug console
40 41
     cnsl_init();
42
+    serial_init();
41 43
     usb_init();
42 44
 
43 45
     debug("lcd_init");

+ 76
- 0
src/ring.c 查看文件

@@ -0,0 +1,76 @@
1
+/*
2
+ * ring.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 "ring.h"
21
+
22
+void rb_add(struct ring_buffer *rb, const uint8_t *data, size_t length) {
23
+    for (size_t i = 0; i < length; i++) {
24
+        rb->buffer[rb->head] = data[i];
25
+
26
+        if (rb->full && (++(rb->tail) == rb->size)) {
27
+            rb->tail = 0;
28
+        }
29
+
30
+        if (++(rb->head) == rb->size) {
31
+            rb->head = 0;
32
+        }
33
+
34
+        rb->full = ((rb->head) == (rb->tail));
35
+    }
36
+}
37
+
38
+size_t rb_len(struct ring_buffer *rb) {
39
+    if (rb->head == rb->tail) {
40
+        if (rb->full) {
41
+            return rb->size;
42
+        } else {
43
+            return 0;
44
+        }
45
+    } else if (rb->head > rb->tail) {
46
+        return rb->head - rb->tail;
47
+    } else {
48
+        return rb->size - rb->tail + rb->head;
49
+    }
50
+}
51
+
52
+void rb_dump(struct ring_buffer *rb, void (*write)(const uint8_t *, size_t)) {
53
+    if (rb_len(rb) == 0) {
54
+        return;
55
+    }
56
+
57
+    if (rb->head > rb->tail) {
58
+        write(rb->buffer + rb->tail, rb->head - rb->tail);
59
+    } else {
60
+        write(rb->buffer + rb->tail, rb->size - rb->tail);
61
+        write(rb->buffer, rb->head);
62
+    }
63
+}
64
+
65
+uint8_t rb_pop(struct ring_buffer *rb) {
66
+    if (rb_len(rb) == 0) {
67
+        return 0;
68
+    }
69
+
70
+    uint8_t v = rb->buffer[rb->tail++];
71
+    if (rb->tail >= rb->size) {
72
+        rb->tail = 0;
73
+    }
74
+
75
+    return v;
76
+}

+ 97
- 0
src/serial.c 查看文件

@@ -0,0 +1,97 @@
1
+/*
2
+ * serial.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
+// UART0, Tx GP0, Rx GP1
20
+#define UART_ID uart0
21
+#define UART_IRQ UART0_IRQ
22
+#define UART_TX_PIN 0
23
+#define UART_RX_PIN 1
24
+
25
+// Serial port parameters
26
+#define BAUD_RATE 115200
27
+#define DATA_BITS 8
28
+#define PARITY UART_PARITY_NONE
29
+#define STOP_BITS 1
30
+
31
+#define UART_HW_FIFO_LEN 32
32
+#define UART_TX_BUFF_LEN 128
33
+
34
+#include "hardware/uart.h"
35
+#include "hardware/gpio.h"
36
+
37
+#include "config.h"
38
+#include "console.h"
39
+#include "log.h"
40
+#include "util.h"
41
+#include "ring.h"
42
+#include "serial.h"
43
+
44
+static uint8_t tx_buff[UART_TX_BUFF_LEN] = {0};
45
+static struct ring_buffer tx = RB_INIT(tx_buff, sizeof(tx_buff));
46
+static bool reroute_serial_debug = false;
47
+
48
+static void serial_irq(void) {
49
+    uint8_t buf[UART_HW_FIFO_LEN];
50
+    uint16_t count = 0;
51
+
52
+    // Rx - read from UART FIFO to local buffer
53
+    while (uart_is_readable(UART_ID)) {
54
+        uint8_t ch = uart_getc(UART_ID);
55
+        buf[count++] = ch;
56
+
57
+        if (count >= UART_HW_FIFO_LEN) {
58
+            break;
59
+        }
60
+    }
61
+
62
+    // Rx - pass local buffer to further processing
63
+    if ((count >= 1) && (buf[0] == ENTER_BOOTLOADER_MAGIC)) {
64
+        reset_to_bootloader();
65
+    } else if (reroute_serial_debug) {
66
+        debug_handle_input((char *)buf, count);
67
+    } else {
68
+        cnsl_handle_input((char *)buf, count);
69
+    }
70
+
71
+    // Tx - write to UART FIFO if needed
72
+    while (uart_is_writable(UART_ID) && (rb_len(&tx) > 0)) {
73
+        uart_putc_raw(UART_ID, rb_pop(&tx));
74
+    }
75
+}
76
+
77
+void serial_init(void) {
78
+    uart_init(UART_ID, BAUD_RATE);
79
+    gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
80
+    gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART);
81
+    uart_set_hw_flow(UART_ID, false, false);
82
+    uart_set_format(UART_ID, DATA_BITS, STOP_BITS, PARITY);
83
+    uart_set_fifo_enabled(UART_ID, true);
84
+
85
+    irq_set_exclusive_handler(UART_IRQ, serial_irq);
86
+    irq_set_enabled(UART_IRQ, true);
87
+
88
+    uart_set_irq_enables(UART_ID, true, false);
89
+}
90
+
91
+void serial_write(const uint8_t *buf, size_t count) {
92
+    rb_add(&tx, buf, count);
93
+}
94
+
95
+void serial_set_reroute(bool reroute) {
96
+    reroute_serial_debug = reroute;
97
+}

+ 3
- 5
src/usb_cdc.c 查看文件

@@ -39,7 +39,7 @@
39 39
 
40 40
 static bool reroute_cdc_debug = false;
41 41
 
42
-void usb_cdc_write(const char *buf, uint32_t count) {
42
+void usb_cdc_write(const uint8_t *buf, size_t count) {
43 43
 #ifndef DISABLE_CDC_DTR_CHECK
44 44
     if (!tud_cdc_connected()) {
45 45
         return;
@@ -69,16 +69,14 @@ void usb_cdc_set_reroute(bool reroute) {
69 69
     reroute_cdc_debug = reroute;
70 70
 }
71 71
 
72
-void cdc_task(void) {
72
+static void cdc_task(void) {
73 73
     const uint32_t cdc_buf_len = 64;
74 74
 
75 75
     if (tud_cdc_available()) {
76 76
         char buf[cdc_buf_len + 1];
77 77
         uint32_t count = tud_cdc_read(buf, cdc_buf_len);
78 78
 
79
-        if ((count >= 1) && (buf[0] == 0x18)) {
80
-            // ASCII 0x18 = CAN (cancel)
81
-            debug("switching to bootloader");
79
+        if ((count >= 1) && (buf[0] == ENTER_BOOTLOADER_MAGIC)) {
82 80
             reset_to_bootloader();
83 81
         } else if (reroute_cdc_debug) {
84 82
             debug_handle_input(buf, count);

正在加载...
取消
保存