ソースを参照

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);

読み込み中…
キャンセル
保存