Browse Source

serial console mostly working, but still losing some bytes when transmitting lots.

Thomas Buck 1 year ago
parent
commit
46f9c9a5da
13 changed files with 98 additions and 32 deletions
  1. 2
    1
      README.md
  2. 5
    2
      debug_swd.sh
  3. 3
    1
      flash_swd.sh
  4. 1
    1
      include/console.h
  5. 1
    1
      include/log.h
  6. 3
    0
      include/ring.h
  7. 1
    0
      include/serial.h
  8. 5
    2
      src/console.c
  9. 3
    1
      src/log.c
  10. 2
    0
      src/main.c
  11. 16
    0
      src/ring.c
  12. 54
    21
      src/serial.c
  13. 2
    2
      src/usb_cdc.c

+ 2
- 1
README.md View File

101
     continue # start program
101
     continue # start program
102
 
102
 
103
 These commands have also been put in the `flash_swd.sh` and `debug_swd.sh` scripts, respectively.
103
 These commands have also been put in the `flash_swd.sh` and `debug_swd.sh` scripts, respectively.
104
-Call them from the `build_debug` folder where you checked out and built OpenOCD.
104
+They require the `build_debug` folder where you checked out and built OpenOCD.
105
+Here are some [general GDB tips](https://beej.us/guide/bggdb/).
105
 
106
 
106
 ## License
107
 ## License
107
 
108
 

+ 5
- 2
debug_swd.sh View File

1
 #!/bin/bash
1
 #!/bin/bash
2
 set -euo pipefail
2
 set -euo pipefail
3
 
3
 
4
+cd "$(dirname "$0")"
5
+
4
 echo Starting OpenOCD in background
6
 echo Starting OpenOCD in background
5
-./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" &
7
+echo "\n\nstarting new openocd" >> openocd.log
8
+./build_debug/openocd/src/openocd -s build_debug/openocd/tcl -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000" -c "cmsis_dap_vid_pid 0x2e8a 0x000c" >> openocd.log 2>&1 &
6
 OPENOCD_PID=$!
9
 OPENOCD_PID=$!
7
 
10
 
8
 # give OpenOCD some time to output stuff
11
 # give OpenOCD some time to output stuff
19
 -ex "set history save" \
22
 -ex "set history save" \
20
 -ex "show print pretty" \
23
 -ex "show print pretty" \
21
 -ex "target extended-remote localhost:3333" \
24
 -ex "target extended-remote localhost:3333" \
22
--ex "tui new-layout default asm 1 src 2 status 0 cmd 1" \
25
+-ex "tui new-layout default src 1 status 1 cmd 2" \
23
 -ex "tui layout default" \
26
 -ex "tui layout default" \
24
 -ex "tui enable" \
27
 -ex "tui enable" \
25
 $1
28
 $1

+ 3
- 1
flash_swd.sh View File

1
 #!/bin/bash
1
 #!/bin/bash
2
 set -euo pipefail
2
 set -euo pipefail
3
 
3
 
4
-./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 $1 verify reset exit"
4
+cd "$(dirname "$0")"
5
+
6
+./build_debug/openocd/src/openocd -s build_debug/openocd/tcl -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c "adapter speed 5000" -c "cmsis_dap_vid_pid 0x2e8a 0x000c" -c "program $1 verify reset exit"

+ 1
- 1
include/console.h View File

21
 
21
 
22
 void cnsl_init(void);
22
 void cnsl_init(void);
23
 void cnsl_run(void);
23
 void cnsl_run(void);
24
-void cnsl_handle_input(const char *buf, uint32_t len);
24
+void cnsl_handle_input(const uint8_t *buf, size_t len);
25
 
25
 
26
 #endif // __CONSOLE_H__
26
 #endif // __CONSOLE_H__

+ 1
- 1
include/log.h View File

43
 void log_dump_to_uart(void);
43
 void log_dump_to_uart(void);
44
 void log_dump_to_disk(void);
44
 void log_dump_to_disk(void);
45
 
45
 
46
-void debug_handle_input(char *buff, uint32_t len);
46
+void debug_handle_input(const uint8_t *buff, size_t len);
47
 
47
 
48
 #endif // __LOG_H__
48
 #endif // __LOG_H__

+ 3
- 0
include/ring.h View File

32
 #define RB_INIT(b, s) { .buffer = b, .size = s, .head = 0, .tail = 0, .full = false }
32
 #define RB_INIT(b, s) { .buffer = b, .size = s, .head = 0, .tail = 0, .full = false }
33
 
33
 
34
 void rb_add(struct ring_buffer *rb, const uint8_t *data, size_t length);
34
 void rb_add(struct ring_buffer *rb, const uint8_t *data, size_t length);
35
+#define rb_push(rb, v) rb_add(rb, &v, 1)
35
 size_t rb_len(struct ring_buffer *rb);
36
 size_t rb_len(struct ring_buffer *rb);
36
 #define rb_space(rb) ((rb)->size - rb_len(rb))
37
 #define rb_space(rb) ((rb)->size - rb_len(rb))
37
 void rb_dump(struct ring_buffer *rb, void (*write)(const uint8_t *, size_t));
38
 void rb_dump(struct ring_buffer *rb, void (*write)(const uint8_t *, size_t));
39
+void rb_move(struct ring_buffer *rb, void (*write)(const uint8_t *, size_t));
40
+uint8_t rb_peek(struct ring_buffer *rb);
38
 uint8_t rb_pop(struct ring_buffer *rb);
41
 uint8_t rb_pop(struct ring_buffer *rb);
39
 
42
 
40
 #endif // __RING_BUFFER_H__
43
 #endif // __RING_BUFFER_H__

+ 1
- 0
include/serial.h View File

26
 void serial_init(void);
26
 void serial_init(void);
27
 void serial_write(const uint8_t *buf, size_t count);
27
 void serial_write(const uint8_t *buf, size_t count);
28
 void serial_set_reroute(bool reroute);
28
 void serial_set_reroute(bool reroute);
29
+void serial_run(void);
29
 
30
 
30
 #endif // __SERIAL_H__
31
 #endif // __SERIAL_H__

+ 5
- 2
src/console.c View File

35
 #include "lcd.h"
35
 #include "lcd.h"
36
 #include "image.h"
36
 #include "image.h"
37
 #include "volcano.h"
37
 #include "volcano.h"
38
+#include "serial.h"
38
 
39
 
39
 #define CNSL_BUFF_SIZE 1024
40
 #define CNSL_BUFF_SIZE 1024
40
 #define CNSL_REPEAT_MS 500
41
 #define CNSL_REPEAT_MS 500
303
     }
304
     }
304
 }
305
 }
305
 
306
 
306
-void cnsl_handle_input(const char *buf, uint32_t len) {
307
+void cnsl_handle_input(const uint8_t *buf, size_t len) {
307
     if ((cnsl_buff_pos + len) > CNSL_BUFF_SIZE) {
308
     if ((cnsl_buff_pos + len) > CNSL_BUFF_SIZE) {
308
         debug("error: console input buffer overflow! %lu > %u", cnsl_buff_pos + len, CNSL_BUFF_SIZE);
309
         debug("error: console input buffer overflow! %lu > %u", cnsl_buff_pos + len, CNSL_BUFF_SIZE);
309
         cnsl_init();
310
         cnsl_init();
312
     memcpy(cnsl_line_buff + cnsl_buff_pos, buf, len);
313
     memcpy(cnsl_line_buff + cnsl_buff_pos, buf, len);
313
     cnsl_buff_pos += len;
314
     cnsl_buff_pos += len;
314
 
315
 
315
-    // handle backspace
316
+    // handle backspace and local echo
316
     for (ssize_t i = cnsl_buff_pos - len; i < (ssize_t)cnsl_buff_pos; i++) {
317
     for (ssize_t i = cnsl_buff_pos - len; i < (ssize_t)cnsl_buff_pos; i++) {
317
         if ((cnsl_line_buff[i] == '\b') || (cnsl_line_buff[i] == 0x7F)) {
318
         if ((cnsl_line_buff[i] == '\b') || (cnsl_line_buff[i] == 0x7F)) {
318
             if (i > 0) {
319
             if (i > 0) {
330
             }
331
             }
331
 
332
 
332
             usb_cdc_write((const uint8_t *)"\b \b", 3);
333
             usb_cdc_write((const uint8_t *)"\b \b", 3);
334
+            serial_write((const uint8_t *)"\b \b", 3);
333
 
335
 
334
             // check for another backspace in this space
336
             // check for another backspace in this space
335
             i--;
337
             i--;
336
         } else {
338
         } else {
337
             usb_cdc_write((const uint8_t *)(cnsl_line_buff + i), 1);
339
             usb_cdc_write((const uint8_t *)(cnsl_line_buff + i), 1);
340
+            serial_write((const uint8_t *)(cnsl_line_buff + i), 1);
338
         }
341
         }
339
     }
342
     }
340
 
343
 

+ 3
- 1
src/log.c View File

100
     }
100
     }
101
     if ((l > 0) && (l <= (int)sizeof(line_buff))) {
101
     if ((l > 0) && (l <= (int)sizeof(line_buff))) {
102
         usb_cdc_write(line_buff, l);
102
         usb_cdc_write(line_buff, l);
103
+        serial_write(line_buff, l);
103
 
104
 
104
         if (log) {
105
         if (log) {
105
             add_to_log(line_buff, l);
106
             add_to_log(line_buff, l);
114
     va_end(args);
115
     va_end(args);
115
 }
116
 }
116
 
117
 
117
-void debug_handle_input(char *buff, uint32_t len) {
118
+void debug_handle_input(const uint8_t *buff, size_t len) {
118
     (void)buff;
119
     (void)buff;
119
 
120
 
120
     if (len > 0) {
121
     if (len > 0) {
135
     while (!got_input) {
136
     while (!got_input) {
136
         watchdog_update();
137
         watchdog_update();
137
         usb_run();
138
         usb_run();
139
+        serial_run();
138
     }
140
     }
139
 
141
 
140
     usb_cdc_set_reroute(false);
142
     usb_cdc_set_reroute(false);

+ 2
- 0
src/main.c View File

95
 
95
 
96
         heartbeat_run();
96
         heartbeat_run();
97
         buttons_run();
97
         buttons_run();
98
+
98
         usb_run();
99
         usb_run();
100
+        serial_run();
99
         cnsl_run();
101
         cnsl_run();
100
 
102
 
101
         battery_run();
103
         battery_run();

+ 16
- 0
src/ring.c View File

62
     }
62
     }
63
 }
63
 }
64
 
64
 
65
+void rb_move(struct ring_buffer *rb, void (*write)(const uint8_t *, size_t)) {
66
+    rb_dump(rb, write);
67
+    rb->head = 0;
68
+    rb->tail = 0;
69
+    rb->full = false;
70
+}
71
+
72
+uint8_t rb_peek(struct ring_buffer *rb) {
73
+    if (rb_len(rb) == 0) {
74
+        return 0;
75
+    }
76
+
77
+    uint8_t v = rb->buffer[rb->tail];
78
+    return v;
79
+}
80
+
65
 uint8_t rb_pop(struct ring_buffer *rb) {
81
 uint8_t rb_pop(struct ring_buffer *rb) {
66
     if (rb_len(rb) == 0) {
82
     if (rb_len(rb) == 0) {
67
         return 0;
83
         return 0;

+ 54
- 21
src/serial.c View File

1
 /*
1
 /*
2
  * serial.c
2
  * serial.c
3
  *
3
  *
4
+ * https://github.com/raspberrypi/pico-examples/blob/master/uart/uart_advanced/uart_advanced.c
5
+ * https://forums.raspberrypi.com/viewtopic.php?t=343110
6
+ *
4
  * Copyright (c) 2023 Thomas Buck (thomas@xythobuz.de)
7
  * Copyright (c) 2023 Thomas Buck (thomas@xythobuz.de)
5
  *
8
  *
6
  * This program is free software: you can redistribute it and/or modify
9
  * This program is free software: you can redistribute it and/or modify
28
 #define PARITY UART_PARITY_NONE
31
 #define PARITY UART_PARITY_NONE
29
 #define STOP_BITS 1
32
 #define STOP_BITS 1
30
 
33
 
31
-#define UART_HW_FIFO_LEN 32
34
+#define UART_RX_BUFF_LEN 64
32
 #define UART_TX_BUFF_LEN 128
35
 #define UART_TX_BUFF_LEN 128
33
 
36
 
34
 #include "hardware/uart.h"
37
 #include "hardware/uart.h"
41
 #include "ring.h"
44
 #include "ring.h"
42
 #include "serial.h"
45
 #include "serial.h"
43
 
46
 
47
+static uint8_t rx_buff[UART_RX_BUFF_LEN] = {0};
48
+static struct ring_buffer rx = RB_INIT(rx_buff, sizeof(rx_buff));
49
+
44
 static uint8_t tx_buff[UART_TX_BUFF_LEN] = {0};
50
 static uint8_t tx_buff[UART_TX_BUFF_LEN] = {0};
45
 static struct ring_buffer tx = RB_INIT(tx_buff, sizeof(tx_buff));
51
 static struct ring_buffer tx = RB_INIT(tx_buff, sizeof(tx_buff));
52
+
46
 static bool reroute_serial_debug = false;
53
 static bool reroute_serial_debug = false;
54
+static bool tx_irq_state = false;
47
 
55
 
48
 static void serial_irq(void) {
56
 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
57
     // Rx - read from UART FIFO to local buffer
53
-    while (uart_is_readable(UART_ID)) {
58
+    while (uart_is_readable(UART_ID) && (rb_space(&rx) > 0)) {
54
         uint8_t ch = uart_getc(UART_ID);
59
         uint8_t ch = uart_getc(UART_ID);
55
-        buf[count++] = ch;
60
+        rb_push(&rx, ch);
61
+    }
56
 
62
 
57
-        if (count >= UART_HW_FIFO_LEN) {
63
+    // Tx - write to UART FIFO if needed
64
+    while (uart_is_writable(UART_ID)) {
65
+        if (rb_len(&tx) > 0) {
66
+            uart_putc_raw(UART_ID, rb_pop(&tx));
67
+        } else {
68
+            uart_set_irq_enables(UART_ID, true, false);
69
+            tx_irq_state = false;
58
             break;
70
             break;
59
         }
71
         }
60
     }
72
     }
61
 
73
 
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
 }
74
 }
76
 
75
 
77
 void serial_init(void) {
76
 void serial_init(void) {
87
     irq_set_exclusive_handler(UART_IRQ, serial_irq);
86
     irq_set_exclusive_handler(UART_IRQ, serial_irq);
88
     irq_set_enabled(UART_IRQ, true);
87
     irq_set_enabled(UART_IRQ, true);
89
 
88
 
90
-    uart_set_irq_enables(UART_ID, true, true);
89
+    uart_set_irq_enables(UART_ID, true, false);
90
+    tx_irq_state = false;
91
 }
91
 }
92
 
92
 
93
 void serial_write(const uint8_t *buf, size_t count) {
93
 void serial_write(const uint8_t *buf, size_t count) {
94
     uart_set_irq_enables(UART_ID, true, false);
94
     uart_set_irq_enables(UART_ID, true, false);
95
+    tx_irq_state = false;
96
+
97
+    while ((rb_len(&tx) == 0) && uart_is_writable(UART_ID) && (count > 0)) {
98
+        uart_putc_raw(UART_ID, *buf++);
99
+        count--;
100
+    }
101
+
102
+    if (count == 0) {
103
+        return;
104
+    }
95
 
105
 
96
     size_t off = 0;
106
     size_t off = 0;
97
 
107
 
103
         off += space;
113
         off += space;
104
 
114
 
105
         uart_set_irq_enables(UART_ID, true, true);
115
         uart_set_irq_enables(UART_ID, true, true);
116
+        tx_irq_state = true;
117
+
106
         sleep_ms(1);
118
         sleep_ms(1);
119
+
107
         uart_set_irq_enables(UART_ID, true, false);
120
         uart_set_irq_enables(UART_ID, true, false);
121
+        tx_irq_state = false;
108
     }
122
     }
123
+
109
 #endif // SERIAL_WRITES_BLOCK_WHEN_BUFFER_FULL
124
 #endif // SERIAL_WRITES_BLOCK_WHEN_BUFFER_FULL
110
 
125
 
111
     rb_add(&tx, buf + off, count);
126
     rb_add(&tx, buf + off, count);
112
 
127
 
113
     uart_set_irq_enables(UART_ID, true, true);
128
     uart_set_irq_enables(UART_ID, true, true);
129
+    tx_irq_state = true;
114
 }
130
 }
115
 
131
 
116
 void serial_set_reroute(bool reroute) {
132
 void serial_set_reroute(bool reroute) {
117
     reroute_serial_debug = reroute;
133
     reroute_serial_debug = reroute;
118
 }
134
 }
135
+
136
+void serial_run(void) {
137
+    uart_set_irq_enables(UART_ID, false, tx_irq_state);
138
+
139
+    // Rx - pass local buffer to further processing
140
+    if (rb_len(&rx) >= 1) {
141
+        if (rb_peek(&rx) == ENTER_BOOTLOADER_MAGIC) {
142
+            reset_to_bootloader();
143
+        } else if (reroute_serial_debug) {
144
+            rb_move(&rx, debug_handle_input);
145
+        } else {
146
+            rb_move(&rx, cnsl_handle_input);
147
+        }
148
+    }
149
+
150
+    uart_set_irq_enables(UART_ID, true, tx_irq_state);
151
+}

+ 2
- 2
src/usb_cdc.c View File

79
         if ((count >= 1) && (buf[0] == ENTER_BOOTLOADER_MAGIC)) {
79
         if ((count >= 1) && (buf[0] == ENTER_BOOTLOADER_MAGIC)) {
80
             reset_to_bootloader();
80
             reset_to_bootloader();
81
         } else if (reroute_cdc_debug) {
81
         } else if (reroute_cdc_debug) {
82
-            debug_handle_input(buf, count);
82
+            debug_handle_input((const uint8_t *)buf, count);
83
         } else {
83
         } else {
84
-            cnsl_handle_input(buf, count);
84
+            cnsl_handle_input((const uint8_t *)buf, count);
85
         }
85
         }
86
     }
86
     }
87
 }
87
 }

Loading…
Cancel
Save