sxkbd

Firmware for RP2040-based corne split keyboard
git clone https://git.sinitax.com/sinitax/sxkbd
Log | Files | Refs | Submodules | README | LICENSE | sfeed.txt

commit cbb0ac4dac395ea287cf5e7cc211f81aef16e78f
parent b5e98f03ac60a725838367c58ab6a1fbc99f2831
Author: Louis Burda <quent.burda@gmail.com>
Date:   Tue, 13 Dec 2022 10:50:59 +0100

Switch to full-duplex uart

Diffstat:
MCMakeLists.txt | 2+-
MMakefile | 2+-
Msrc/split.c | 136++++++++++++++++++++++++++++---------------------------------------------------
Msrc/uart_tx.pio | 4++--
4 files changed, 52 insertions(+), 92 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt @@ -51,7 +51,7 @@ target_compile_options(pico_stdio INTERFACE ) target_compile_options(${PROJECT} PRIVATE - "-DSPLIT_SIDE=${SPLIT_LEFT}" + "-DSPLIT_SIDE=${SPLIT_SIDE}" "-DSPLIT_ROLE=${SPLIT_ROLE}" ) diff --git a/Makefile b/Makefile @@ -1,7 +1,7 @@ FAMILY ?= rp2040 PICO_SDK_PATH ?= lib/picosdk -all: left +all: left right clean: rm -rf .build diff --git a/src/split.c b/src/split.c @@ -25,7 +25,20 @@ #define UART_TIMEOUT 20 #define UART_BAUD 9600 -#define UART_PIN 1 + +#define LEFT 0 +#define RIGHT 1 + +#define SLAVE 0 +#define MASTER 1 + +#if SPLIT_SIDE == LEFT +#define UART_TX_PIN 0 +#define UART_RX_PIN 1 +#elif SPLIT_SIDE == RIGHT +#define UART_TX_PIN 1 +#define UART_RX_PIN 0 +#endif enum { CMD_SCAN_MATRIX_REQ = 0xA0, @@ -33,16 +46,10 @@ enum { CMD_STDIO_PUTS }; -enum { SLAVE, MASTER }; -enum { LEFT, RIGHT }; - -static void uart_tx_init(void); -static void uart_rx_init(void); +static void uart_tx_sm_init(void); +static void uart_rx_sm_init(void); static void uart_full_init(void); -static void uart_leave_rx(void); -static void uart_enter_rx(void); - static bool uart_await_rx(uint32_t timeout_ms); static bool uart_await_tx(uint32_t timeout_ms); @@ -64,7 +71,7 @@ static uint uart_rx_sm_offset; static bool scan_pending = false; void -uart_tx_init(void) +uart_tx_sm_init(void) { pio_sm_config config; @@ -73,8 +80,8 @@ uart_tx_init(void) config = uart_tx_program_get_default_config(uart_tx_sm_offset); sm_config_set_out_shift(&config, true, false, 32); - sm_config_set_out_pins(&config, UART_PIN, 1); - sm_config_set_sideset_pins(&config, UART_PIN); + sm_config_set_out_pins(&config, UART_TX_PIN, 1); + 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 * UART_BAUD)); @@ -84,7 +91,7 @@ uart_tx_init(void) } void -uart_rx_init(void) +uart_rx_sm_init(void) { pio_sm_config config; @@ -92,8 +99,8 @@ uart_rx_init(void) uart_rx_sm_offset = pio_add_program(pio0, &uart_rx_program); config = uart_rx_program_get_default_config(uart_rx_sm_offset); - sm_config_set_in_pins(&config, UART_PIN); - sm_config_set_jmp_pin(&config, UART_PIN); + sm_config_set_in_pins(&config, UART_RX_PIN); + sm_config_set_jmp_pin(&config, UART_RX_PIN); sm_config_set_in_shift(&config, true, false, 32); sm_config_set_fifo_join(&config, PIO_FIFO_JOIN_RX); sm_config_set_clkdiv(&config, @@ -106,77 +113,31 @@ uart_rx_init(void) void uart_full_init(void) { - pio_sm_set_pins_with_mask(pio0, uart_tx_sm, 0U, 1U << UART_PIN); - pio_sm_set_consecutive_pindirs(pio0, uart_tx_sm, UART_PIN, 1, false); - - pio_gpio_init(pio0, UART_PIN); - gpio_pull_up(UART_PIN); - gpio_set_slew_rate(UART_PIN, GPIO_SLEW_RATE_FAST); - /* 1 => set INPUT and pull line HIGH from pullup - * 0 => set OUTPUT and pull line LOW from signal */ - gpio_set_oeover(UART_PIN, GPIO_OVERRIDE_INVERT); + pio_gpio_init(pio0, UART_RX_PIN); + pio_sm_set_pins_with_mask(pio0, uart_rx_sm, 1U, 1U << UART_RX_PIN); + pio_sm_set_consecutive_pindirs(pio0, uart_rx_sm, UART_RX_PIN, 1, false); - gpio_set_drive_strength(UART_PIN, GPIO_DRIVE_STRENGTH_12MA); + pio_gpio_init(pio0, UART_TX_PIN); + gpio_set_slew_rate(UART_TX_PIN, GPIO_SLEW_RATE_FAST); + gpio_set_drive_strength(UART_TX_PIN, GPIO_DRIVE_STRENGTH_12MA); + pio_sm_set_pins_with_mask(pio0, uart_tx_sm, 1U, 1U << UART_TX_PIN); + pio_sm_set_consecutive_pindirs(pio0, uart_tx_sm, UART_TX_PIN, 1, true); - uart_rx_init(); - uart_tx_init(); + uart_rx_sm_init(); + uart_tx_sm_init(); pio_set_irq0_source_enabled(pio0, 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, false); pio_set_irq0_source_enabled(pio0, pis_interrupt0, true); - pio_set_irq0_source_enabled(pio0, pis_interrupt1, true); 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); - pio_sm_set_enabled(pio0, uart_tx_sm, true); - uart_enter_rx(); -} - -void -uart_leave_rx(void) -{ - irq_set_enabled(USBCTRL_IRQ, false); - pio_sm_set_enabled(pio0, uart_rx_sm, false); - - /* because of OE override pindir true = INPUT (!) */ - //pio_sm_set_consecutive_pindirs(pio0, uart_tx_sm, UART_PIN, 1, true); - - /* drive LOW with high drive-current for steep falling edges */ - //pio_sm_set_pins_with_mask(pio0, uart_tx_sm, 0U, 1 << UART_PIN); - //gpio_set_drive_strength(UART_PIN, GPIO_DRIVE_STRENGTH_12MA); - - /* input */ - pio_sm_set_consecutive_pindirs(pio0, uart_tx_sm, UART_PIN, 1, true); - - pio_sm_restart(pio0, uart_tx_sm); - pio_sm_set_enabled(pio0, uart_tx_sm, true); -} - -void -uart_enter_rx(void) -{ - /* wait for tx fifo to empty and final byte to transmit - * + extra 1 start + 8 data + 1 stop bit time*/ - while (!pio_sm_is_tx_fifo_empty(pio0, uart_tx_sm)); - sleep_us(1000000U * 10 / UART_BAUD); - pio_sm_set_enabled(pio0, uart_tx_sm, false); - - /* pull HIGH with low drive-current for steeper rising edge */ - //gpio_set_drive_strength(UART_PIN, GPIO_DRIVE_STRENGTH_2MA); - //pio_sm_set_pins_with_mask(pio0, uart_tx_sm, ~0U, 1 << UART_PIN); - - /* because of OE override pindir false = OUTPUT (!) */ - //pio_sm_set_consecutive_pindirs(pio0, uart_tx_sm, UART_PIN, 1, true); - - /* input */ - pio_sm_set_consecutive_pindirs(pio0, uart_tx_sm, UART_PIN, 1, true); - pio_sm_set_enabled(pio0, uart_rx_sm, true); - irq_set_enabled(USBCTRL_IRQ, true); + pio_sm_set_enabled(pio0, uart_tx_sm, true); } bool @@ -209,6 +170,7 @@ uart_await_tx(uint32_t timeout_ms) } while (board_millis() < start_ms + timeout_ms); return !full; + pio_sm_set_enabled(pio0, uart_tx_sm, true); } uint8_t @@ -244,7 +206,6 @@ uart_send(const uint8_t *data, uint len) { uint sent; - uart_leave_rx(); for (sent = 0; sent < len; sent++) { if (pio_sm_is_tx_fifo_full(pio0, uart_tx_sm)) { if (!uart_await_tx(UART_TIMEOUT)) @@ -252,7 +213,6 @@ uart_send(const uint8_t *data, uint len) } uart_tx_byte(*data++); } - uart_enter_rx(); return sent; } @@ -314,38 +274,38 @@ split_task(void) uint32_t start_ms; uint8_t cmd; - // if (!uart_await_tx(20)) - // return; - // DEBUG("Sending"); - // uart_leave_rx(); - // uart_tx_byte(CMD_SCAN_MATRIX_RESP); - // uart_enter_rx(); - // return; + //if (!uart_await_tx(20)) + // return; + //DEBUG("Sending"); + //uart_tx_byte(CMD_SCAN_MATRIX_RESP); + //return; if (SPLIT_ROLE == MASTER) { scan_pending = true; cmd = CMD_SCAN_MATRIX_REQ; ASSERT(uart_send(&cmd, 1) == 1); - //scan_matrix(); /* scan our side in parallel */ + scan_matrix(); /* scan our side in parallel */ start_ms = board_millis(); - while (scan_pending && board_millis() < start_ms + 1000) { + while (scan_pending && board_millis() < start_ms + 20) { if (!pio_sm_is_rx_fifo_empty(pio0, uart_rx_sm)) handle_cmd(uart_rx_byte()); tud_task(); } - if (scan_pending) WARN("Slave matrix scan timeout"); - else DEBUG("Slave matrix scan success"); + if (scan_pending) { + WARN("Slave matrix scan timeout"); + } else { + DEBUG("Slave matrix scan success"); + } scan_pending = false; } else { start_ms = board_millis(); - while (!scan_pending && board_millis() < start_ms + 1000) { + while (!scan_pending && board_millis() < start_ms + 20) { if (!pio_sm_is_rx_fifo_empty(pio0, uart_rx_sm)) handle_cmd(uart_rx_byte()); tud_task(); } if (scan_pending) { - sleep_ms(8); /* ensure tranmitter is ready */ - //scan_matrix(); + scan_matrix(); cmd = CMD_SCAN_MATRIX_RESP; DEBUG("Sending SCAN_MATRIX_RESP %i", cmd); ASSERT(uart_send(&cmd, 1) == 1); diff --git a/src/uart_tx.pio b/src/uart_tx.pio @@ -1,10 +1,10 @@ .program uart_tx -.side_set 1 opt pindirs +.side_set 1 opt .wrap_target pull block side 1 [7] ; IDLE / STOP bit set x, 7 side 0 [7] ; START bit bitloop: - out pindirs, 1 ; 8 DATA bits + out pins, 1 ; 8 DATA bits jmp x--, bitloop [6] .wrap