Refactor input to use stdio drivers for Keyboard and TCP
This commit is contained in:
@@ -2,16 +2,25 @@
|
||||
#include "pico/cyw43_arch.h"
|
||||
#include "lwip/tcp.h"
|
||||
#include "pico/stdio/driver.h"
|
||||
#include "pico/sync.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define TCP_PORT 4242
|
||||
#define DEBUG_BUF_SIZE 2048
|
||||
#define TCP_IN_BUF_SIZE 128
|
||||
|
||||
// Circular buffer for debug output
|
||||
static char debug_buf[DEBUG_BUF_SIZE];
|
||||
static volatile int write_idx = 0;
|
||||
static volatile int read_idx = 0;
|
||||
|
||||
// Circular buffer for TCP input
|
||||
static char tcp_in_buf[TCP_IN_BUF_SIZE];
|
||||
static volatile int in_write_idx = 0;
|
||||
static volatile int in_read_idx = 0;
|
||||
static critical_section_t tcp_in_crit;
|
||||
|
||||
static struct tcp_pcb *server_pcb = NULL;
|
||||
static struct tcp_pcb *client_pcb = NULL;
|
||||
|
||||
@@ -39,10 +48,21 @@ static void tcp_out_chars(const char *buf, int len) {
|
||||
}
|
||||
}
|
||||
|
||||
static int tcp_in_chars(char *buf, int len) {
|
||||
int count = 0;
|
||||
critical_section_enter_blocking(&tcp_in_crit);
|
||||
while (count < len && in_read_idx != in_write_idx) {
|
||||
buf[count++] = tcp_in_buf[in_read_idx];
|
||||
in_read_idx = (in_read_idx + 1) % TCP_IN_BUF_SIZE;
|
||||
}
|
||||
critical_section_exit(&tcp_in_crit);
|
||||
return count > 0 ? count : PICO_ERROR_NO_DATA;
|
||||
}
|
||||
|
||||
static stdio_driver_t tcp_driver = {
|
||||
.out_chars = tcp_out_chars,
|
||||
.out_flush = NULL,
|
||||
.in_chars = NULL,
|
||||
.in_chars = tcp_in_chars,
|
||||
#if PICO_STDIO_ENABLE_CRLF_SUPPORT
|
||||
.crlf_enabled = false
|
||||
#endif
|
||||
@@ -84,8 +104,26 @@ static err_t tcp_server_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, er
|
||||
printf("TCP debug client disconnected\n");
|
||||
return ERR_OK;
|
||||
}
|
||||
// We don't expect input, just discard it
|
||||
tcp_recved(tpcb, p->tot_len);
|
||||
|
||||
// Process received data into input buffer
|
||||
if (p->tot_len > 0) {
|
||||
critical_section_enter_blocking(&tcp_in_crit);
|
||||
struct pbuf *q = p;
|
||||
while (q != NULL) {
|
||||
char *data = (char *)q->payload;
|
||||
for (int i = 0; i < q->len; i++) {
|
||||
int next_write = (in_write_idx + 1) % TCP_IN_BUF_SIZE;
|
||||
if (next_write != in_read_idx) {
|
||||
tcp_in_buf[in_write_idx] = data[i];
|
||||
in_write_idx = next_write;
|
||||
}
|
||||
}
|
||||
q = q->next;
|
||||
}
|
||||
critical_section_exit(&tcp_in_crit);
|
||||
tcp_recved(tpcb, p->tot_len);
|
||||
}
|
||||
|
||||
pbuf_free(p);
|
||||
return ERR_OK;
|
||||
}
|
||||
@@ -112,6 +150,8 @@ static err_t tcp_server_accept(void *arg, struct tcp_pcb *newpcb, err_t err) {
|
||||
bool tcp_debug_init(void) {
|
||||
if (server_pcb) return true;
|
||||
|
||||
critical_section_init(&tcp_in_crit);
|
||||
|
||||
// Register stdio driver
|
||||
stdio_set_driver_enabled(&tcp_driver, true);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user