commit 6defee37f9939991bbf3152e2cd4e18593baa541
parent 20c38dd87e618713ff9bd131e39cc95dfdb949c8
Author: Louis Burda <quent.burda@gmail.com>
Date: Tue, 29 Nov 2022 04:50:45 +0100
Fix pio uart integration with neopix pio
Diffstat:
6 files changed, 79 insertions(+), 59 deletions(-)
diff --git a/src/main.c b/src/main.c
@@ -45,11 +45,13 @@ main(void)
board_init();
tud_init(BOARD_TUD_RHPORT);
usb_stdio_init();
- neopix_init(&onboard_led, pio0, 0, 25);
+ neopix_init(&onboard_led, ONBOARD_LED_PIN);
matrix_init();
split_init();
//hid_init();
+ ASSERT(1 == 0);
+
while (true) {
tud_task();
blink_task();
diff --git a/src/neopix.c b/src/neopix.c
@@ -1,15 +1,19 @@
-#include "hardware/pio.h"
-
#include "neopix.h"
#include "ws2812.pio.h"
+#include "util.h"
+
+#include "hardware/pio.h"
void
-neopix_init(struct neopix *pix, PIO pio, uint sm, uint pin)
+neopix_init(struct neopix *pix, uint pin)
{
uint offset;
+ int sm;
- pix->sm = sm;
- pix->pio = pio;
+ pix->pio = pio0;
+ sm = pio_claim_unused_sm(pix->pio, true);
+ ASSERT(sm >= 0);
+ pix->sm = (uint) sm;
pix->pin = pin;
offset = pio_add_program(pix->pio, &ws2812_program);
ws2812_program_init(pix->pio, pix->sm, offset,
diff --git a/src/neopix.h b/src/neopix.h
@@ -12,7 +12,7 @@ struct neopix {
bool init;
};
-void neopix_init(struct neopix *pix, PIO pio, uint sm, uint pin);
+void neopix_init(struct neopix *pix, uint pin);
void neopix_put(struct neopix *pix, uint32_t rgb);
inline uint32_t
diff --git a/src/split.c b/src/split.c
@@ -1,4 +1,5 @@
#include "split.h"
+#include "class/cdc/cdc_device.h"
#include "util.h"
#include "matrix.h"
@@ -16,8 +17,10 @@
#define UART_TIMEOUT 20
#define UART_BAUD 115200
+
+/* same pin since half-duplex */
#define UART_TX_PIN 0
-#define UART_RX_PIN 1
+#define UART_RX_PIN 0
enum {
CMD_SCAN_MATRIX_REQ = 0x80,
@@ -30,12 +33,18 @@ enum { LEFT, RIGHT };
static void uart_tx_init(void);
static void uart_rx_init(void);
+
static void uart_enter_rx(void);
static void uart_leave_rx(void);
+
static int uart_sync_rx(void);
static int uart_sync_tx(void);
-static bool uart_recv(uint8_t *data, uint len);
-static bool uart_send(const uint8_t *data, uint len);
+
+static uint8_t uart_in_byte(void);
+static void uart_out_byte(uint8_t c);
+
+static uint uart_recv(uint8_t *data, uint len);
+static uint uart_send(const uint8_t *data, uint len);
static void irq_rx_cmd(uint8_t cmd);
static void irq_rx(void);
@@ -105,7 +114,7 @@ uart_tx_init(void)
sm_config_set_sideset_pins(&config, UART_TX_PIN);
sm_config_set_fifo_join(&config, PIO_FIFO_JOIN_TX);
sm_config_set_clkdiv(&config,
- (float) clock_get_hz(clk_sys) / (8.f * UART_BAUD));
+ (float) clock_get_hz(clk_sys) / (8 * UART_BAUD));
pio_sm_init(pio0, uart_tx_sm, offset, &config);
pio_sm_set_enabled(pio0, uart_tx_sm, true);
@@ -132,7 +141,7 @@ uart_rx_init(void)
sm_config_set_in_shift(&config, true, false, 32);
sm_config_set_fifo_join(&config, PIO_FIFO_JOIN_RX);
sm_config_set_clkdiv(&config,
- (float) clock_get_hz(clk_sys) / (8.f * UART_BAUD));
+ (float) clock_get_hz(clk_sys) / (8 * UART_BAUD));
pio_sm_init(pio0, uart_rx_sm, offset, &config);
pio_sm_set_enabled(pio0, uart_rx_sm, true);
@@ -201,7 +210,19 @@ uart_sync_tx(void)
return full;
}
-bool
+uint8_t
+uart_in_byte(void)
+{
+ return *(uint8_t*)((uintptr_t)&pio0->rxf[uart_rx_sm] + 3);
+}
+
+void
+uart_out_byte(uint8_t c)
+{
+ pio_sm_put(pio0, uart_tx_sm, c);
+}
+
+uint
uart_recv(uint8_t *data, uint len)
{
uint recv;
@@ -211,14 +232,14 @@ uart_recv(uint8_t *data, uint len)
if (pio_sm_is_rx_fifo_empty(pio0, uart_rx_sm)) {
if (uart_sync_rx()) break;
}
- *data++ = *(uint8_t*)((uintptr_t)&pio0->rxf[uart_rx_sm] + 3);
+ *data++ = uart_in_byte();
recv++;
}
- return recv == len;
+ return recv;
}
-bool
+uint
uart_send(const uint8_t *data, uint len)
{
uint sent;
@@ -229,20 +250,18 @@ uart_send(const uint8_t *data, uint len)
if (pio_sm_is_tx_fifo_full(pio0, uart_tx_sm)) {
if (uart_sync_tx()) break;
}
- pio_sm_put(pio0, uart_tx_sm, *data++);
+ uart_out_byte(*data++);
sent++;
}
uart_enter_rx();
- return sent == len;
+ return sent;
}
void
irq_rx_cmd(uint8_t cmd)
{
- char buf[64];
- uint8_t c;
- uint len;
+ uint8_t buf[64];
switch (cmd) {
case CMD_SCAN_MATRIX_REQ:
@@ -258,20 +277,9 @@ irq_rx_cmd(uint8_t cmd)
case CMD_STDIO_PUTS:
if (SPLIT_ROLE != MASTER)
break;
- len = 0;
- while (uart_recv(&c, 1) && c) {
- if (len == ARRLEN(buf)) {
- tud_cdc_write(buf, len);
- buf[0] = c;
- len = 1;
- } else {
- buf[len++] = c;
- }
- }
- if (len) {
- tud_cdc_write(buf, len);
- tud_cdc_write_flush();
- }
+ memset(buf, 0, sizeof(buf));
+ uart_recv(buf, sizeof(buf)-1);
+ printf("SLAVE: %s\n", buf);
return;
}
@@ -283,8 +291,10 @@ irq_rx(void)
{
uint8_t cmd;
- while (uart_is_readable(uart0)) {
- uart_recv(&cmd, 1);
+ DEBUG("UART IRQ\n");
+ while (!pio_sm_is_rx_fifo_empty(pio0, uart_rx_sm)) {
+ cmd = uart_in_byte();
+ DEBUG("UART RX CMD %i\n", cmd);
irq_rx_cmd(cmd);
}
}
@@ -296,17 +306,16 @@ split_init(void)
uart_rx_init();
pio_set_irq0_source_enabled(pio0,
- pis_sm0_rx_fifo_not_empty + uart_rx_sm, true);
+ pis_sm0_rx_fifo_not_empty + uart_rx_sm, false);
pio_set_irq0_source_enabled(pio0,
- pis_sm0_tx_fifo_not_full + uart_tx_sm, true);
- pio_set_irq0_source_enabled(pio0, pis_interrupt0, true);
+ pis_sm0_tx_fifo_not_full + uart_tx_sm, false);
+ pio_set_irq0_source_enabled(pio0, pis_interrupt0, false);
irq_set_priority(PIO0_IRQ_0, PICO_HIGHEST_IRQ_PRIORITY);
irq_set_exclusive_handler(PIO0_IRQ_0, irq_rx);
irq_set_enabled(PIO0_IRQ_0, true);
uart_enter_rx();
-
}
void
@@ -319,13 +328,13 @@ split_task(void)
if (scan_pending) {
scan_matrix();
cmd = CMD_SCAN_MATRIX_RESP;
- uart_send(&cmd, 1);
+ ASSERT(uart_send(&cmd, 1));
scan_pending = false;
}
} else if (SPLIT_ROLE == MASTER) {
scan_pending = true;
cmd = CMD_SCAN_MATRIX_REQ;
- uart_send(&cmd, 1);
+ ASSERT(uart_send(&cmd, 1));
scan_matrix(); /* scan our side in parallel */
start_ms = board_millis();
while (scan_pending && board_millis() < start_ms + 50)
diff --git a/src/util.c b/src/util.c
@@ -12,20 +12,24 @@ int loglevel = LOG_DEBUG;
static void
__attribute__((format(printf, 1, 0)))
-panic_task(const char *fmtstr, va_list ap)
+panic_task(const char *fmtstr, va_list ap, uint32_t sleep_ms)
{
+ static uint32_t start_ms = 0;
va_list cpy;
- char c;
if (!tud_cdc_available())
return;
- if (!tud_cdc_read(&c, 1))
+ if (!start_ms) start_ms = board_millis();
+
+ if (board_millis() < start_ms + sleep_ms)
return;
va_copy(cpy, ap);
vprintf(fmtstr, cpy);
printf("\n\r");
+
+ start_ms += sleep_ms;
}
static void
@@ -36,12 +40,12 @@ blink_task(struct neopix *pix, uint32_t blink_ms)
if (!start_ms) start_ms = board_millis();
- if (board_millis() - start_ms < blink_ms)
+ if (board_millis() < start_ms + blink_ms)
return;
neopix_put(pix, neopix_u32rgb(255 * led_state, 0, 0));
-
led_state ^= true;
+
start_ms += blink_ms;
}
@@ -71,13 +75,11 @@ blink_panic(const char *fmtstr, ...)
va_start(ap, fmtstr);
- if (!onboard_led.init)
- neopix_init(&onboard_led, pio0, 0, ONBOARD_LED_PIN);
-
while (1) {
tud_task();
- panic_task(fmtstr, ap);
- blink_task(&onboard_led, 200);
+ panic_task(fmtstr, ap, 1000);
+ if (onboard_led.init)
+ blink_task(&onboard_led, 200);
}
va_end(ap);
diff --git a/src/util.h b/src/util.h
@@ -5,13 +5,16 @@
#define ARRLEN(x) (sizeof(x) / sizeof((x)[0]))
-#define ERR(...) stdio_log(LOG_ERR, __VA_ARGS__)
-#define WARN(...) stdio_log(LOG_WARN, __VA_ARGS__)
-#define INFO(...) stdio_log(LOG_INFO, __VA_ARGS__)
-#define DEBUG(...) stdio_log(LOG_DEBUG, __VA_ARGS__)
+#define ERR(...) stdio_log(LOG_ERR, "ERR : " __VA_ARGS__)
+#define WARN(...) stdio_log(LOG_WARN, "WARN : " __VA_ARGS__)
+#define INFO(...) stdio_log(LOG_INFO, "INFO : " __VA_ARGS__)
+#define DEBUG(...) stdio_log(LOG_DEBUG, "DEBUG: " __VA_ARGS__)
+
#define PANIC(...) blink_panic(__VA_ARGS__);
-#define ASSERT(cond) blink_panic("Assertion failed: (%s) in %s:%i", \
- #cond, __FILE__, __LINE__)
+#define ASSERT(cond) do { \
+ if (!(cond)) blink_panic("Assertion failed: (%s) in %s:%i", \
+ #cond, __FILE__, __LINE__); \
+ } while (0)
enum {
LOG_NONE,