From 3c25be8aff299a48a455d02e1e1d9d9b7af2ccf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charlotte=20=F0=9F=A6=9D=20Delenk?= Date: Mon, 25 Jul 2022 08:49:34 +0100 Subject: [PATCH] add broken custom matrix code --- keyboards/rkb1/keymaps/default/keymap.c | 2 + keyboards/rkb1/matrix.c | 104 ++++++++++++++++++++++++ keyboards/rkb1/matrix.pio | 37 +++++++++ keyboards/rkb1/matrix.pio.h | 61 ++++++++++++++ keyboards/rkb1/rules.mk | 3 + platforms/chibios/vendors/RP/RP2040.mk | 4 +- 6 files changed, 210 insertions(+), 1 deletion(-) create mode 100644 keyboards/rkb1/matrix.c create mode 100644 keyboards/rkb1/matrix.pio create mode 100644 keyboards/rkb1/matrix.pio.h diff --git a/keyboards/rkb1/keymaps/default/keymap.c b/keyboards/rkb1/keymaps/default/keymap.c index b1aab66019..89a20ee5ec 100644 --- a/keyboards/rkb1/keymaps/default/keymap.c +++ b/keyboards/rkb1/keymaps/default/keymap.c @@ -295,7 +295,9 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { } void matrix_init_user(void) { +#ifdef STENO_ENABLE steno_set_mode(STENO_MODE_GEMINI); +#endif #ifdef OLED_ENABLE oled_turn_on_for(60000); #endif diff --git a/keyboards/rkb1/matrix.c b/keyboards/rkb1/matrix.c new file mode 100644 index 0000000000..4786267714 --- /dev/null +++ b/keyboards/rkb1/matrix.c @@ -0,0 +1,104 @@ +#include QMK_KEYBOARD_H +#undef PARAM_ASSERTIONS_ENABLED +#define PARAM_ASSERTIONS_ENABLED(x) 0 +#include "hardware/pio.h" +#include "hardware/dma.h" +#include "hardware/irq.h" +#include "matrix.pio.h" +#include "split_util.h" + +// Faster, PIO based matrix scanning routines +// It sets up two DMAs that feed a PIO FSM to scan the matrix. + +static uint32_t matrix_scan_input[] __attribute__((aligned(8))) = {0x01020408, 0x10200000}; +static int tx_chan, rx_chan; +static volatile uint32_t matrix_scan_result; + +static void dma_handler(void) { + // Restart the DMAs when they have finished + if (!dma_channel_is_busy(tx_chan)) { + dma_channel_acknowledge_irq0(tx_chan); + dma_channel_set_trans_count(tx_chan, ~0, true); + if (debug_matrix) { + uprintf("TX DMA restarted\n"); + } + } + if (!dma_channel_is_busy(rx_chan)) { + dma_channel_acknowledge_irq0(rx_chan); + dma_channel_set_trans_count(rx_chan, ~0, true); + if (debug_matrix) { + uprintf("RX DMA restarted\n"); + } + } +} + +void matrix_init_custom(void) { + PIO pio = pio0; + uint offset = pio_add_program(pio, &matrix_program); + uint sm = pio_claim_unused_sm(pio, true); + matrix_program_init(pio, sm, offset, 0); + + uint tx_dreq = pio_get_dreq(pio, sm, true); + uint rx_dreq = pio_get_dreq(pio, sm, false); + + tx_chan = dma_claim_unused_channel(true); + + dma_channel_config tx_cfg = dma_channel_get_default_config(tx_chan); + + channel_config_set_read_increment(&tx_cfg, true); + channel_config_set_write_increment(&tx_cfg, false); + channel_config_set_dreq(&tx_cfg, tx_dreq); + channel_config_set_transfer_data_size(&tx_cfg, DMA_SIZE_32); + channel_config_set_ring(&tx_cfg, false, 3); // wrap read around + + dma_channel_set_config(tx_chan, &tx_cfg, false); + dma_channel_set_irq0_enabled(tx_chan, true); + dma_channel_set_read_addr(tx_chan, matrix_scan_input, false); + dma_channel_set_write_addr(tx_chan, &pio0_hw->txf[sm], false); + + // Set up the rx channel + rx_chan = dma_claim_unused_channel(true); + + dma_channel_config rx_cfg = dma_channel_get_default_config(rx_chan); + channel_config_set_read_increment(&rx_cfg, false); + channel_config_set_write_increment(&rx_cfg, false); + channel_config_set_dreq(&rx_cfg, rx_dreq); + channel_config_set_transfer_data_size(&rx_cfg, DMA_SIZE_32); + + dma_channel_set_config(rx_chan, &rx_cfg, false); + dma_channel_set_irq0_enabled(rx_chan, true); + dma_channel_set_read_addr(rx_chan, &pio0_hw->rxf[sm], false); + dma_channel_set_write_addr(rx_chan, &matrix_scan_result, false); + + // Set up IRQs for restarting the DMAs + irq_set_exclusive_handler(DMA_IRQ_0, dma_handler); + irq_set_enabled(DMA_IRQ_0, true); + // Call the IRQ handler manually to reset the trans counts and start the DMA channels + dma_handler(); +} + +bool matrix_scan_custom(matrix_row_t current_matrix[]) { + bool matrix_has_changed = false; + + // Copy over the matrix scan result to avoid concurrent access from DMA + uint32_t local_state = matrix_scan_result; + uint32_t local_state_copy = local_state; + + int start_row = isLeftHand ? 0 : 5; + + for (int row = 0; row < 5; row++) { + // get a new matrix row by shifting it out of the state + matrix_row_t new_row = local_state & 0x1F; + local_state >>= 5; + // check if the row has changed + matrix_has_changed |= (current_matrix[start_row + row] != new_row); + // update the current matrix + current_matrix[start_row + row] = new_row; + } + + if (debug_matrix && matrix_has_changed) { + uprintf("Matrix scan: %08lx\n", local_state_copy); + } + + return matrix_has_changed; +} diff --git a/keyboards/rkb1/matrix.pio b/keyboards/rkb1/matrix.pio new file mode 100644 index 0000000000..864ac88112 --- /dev/null +++ b/keyboards/rkb1/matrix.pio @@ -0,0 +1,37 @@ +.program matrix +; INPUT: repeated bit pattern +; 0000_0100_0000_1000_0001_0000_0010_0000_0100_0000_1000_0001_0000_0000_0000_0000 +; So, like: 0x0408_1020, 0x4081_0000 + set x, 7 +loop: + pull ifempty [31] + ; Assert the column pins + out pins, 8 [31] + ; Read the row pins + in pins, 5 [31] + jmp x--, loop [31] + ; Output the two missing bits and push + in null, 2 [31] + push [31] + +% c-sdk { +static inline void matrix_program_init(PIO pio, uint sm, uint offset, uint pin) { + pio_sm_config c = matrix_program_get_default_config(offset); + + // The row inputs start at the pin base + sm_config_set_in_pins(&c, pin); + // The 6 output bits come after the 5 input bits + sm_config_set_out_pins(&c, pin + 5, 6); + // Set up the pins for PIO + for(int i = 0; i < 11; i++) + pio_gpio_init(pio, pin + i); + // Set the pin directions + pio_sm_set_consecutive_pindirs(pio, sm, pin, 5, false); + pio_sm_set_consecutive_pindirs(pio, sm, pin + 5, 6, true); + + // Load our configuration, and jump to the start of the program + pio_sm_init(pio, sm, offset, &c); + // Set the state machine running + pio_sm_set_enabled(pio, sm, true); +} +%} diff --git a/keyboards/rkb1/matrix.pio.h b/keyboards/rkb1/matrix.pio.h new file mode 100644 index 0000000000..1aa7289202 --- /dev/null +++ b/keyboards/rkb1/matrix.pio.h @@ -0,0 +1,61 @@ +// -------------------------------------------------- // +// This file is autogenerated by pioasm; do not edit! // +// -------------------------------------------------- // + +#pragma once + +#if !PICO_NO_HARDWARE +# include "hardware/pio.h" +#endif + +// ------ // +// matrix // +// ------ // + +#define matrix_wrap_target 0 +#define matrix_wrap 6 + +static const uint16_t matrix_program_instructions[] = { + // .wrap_target + 0xe027, // 0: set x, 7 + 0x9fe0, // 1: pull ifempty block [31] + 0x7f08, // 2: out pins, 8 [31] + 0x5f05, // 3: in pins, 5 [31] + 0x1f41, // 4: jmp x--, 1 [31] + 0x5f62, // 5: in null, 2 [31] + 0x9f20, // 6: push block [31] + // .wrap +}; + +#if !PICO_NO_HARDWARE +static const struct pio_program matrix_program = { + .instructions = matrix_program_instructions, + .length = 7, + .origin = -1, +}; + +static inline pio_sm_config matrix_program_get_default_config(uint offset) { + pio_sm_config c = pio_get_default_sm_config(); + sm_config_set_wrap(&c, offset + matrix_wrap_target, offset + matrix_wrap); + return c; +} + +static inline void matrix_program_init(PIO pio, uint sm, uint offset, uint pin) { + pio_sm_config c = matrix_program_get_default_config(offset); + // The row inputs start at the pin base + sm_config_set_in_pins(&c, pin); + // The 6 output bits come after the 5 input bits + sm_config_set_out_pins(&c, pin + 5, 6); + // Set up the pins for PIO + for (int i = 0; i < 11; i++) + pio_gpio_init(pio, pin + i); + // Set the pin directions + pio_sm_set_consecutive_pindirs(pio, sm, pin, 5, false); + pio_sm_set_consecutive_pindirs(pio, sm, pin + 5, 6, true); + // Load our configuration, and jump to the start of the program + pio_sm_init(pio, sm, offset, &c); + // Set the state machine running + pio_sm_set_enabled(pio, sm, true); +} + +#endif diff --git a/keyboards/rkb1/rules.mk b/keyboards/rkb1/rules.mk index 5d021a8f1b..33b6786f83 100644 --- a/keyboards/rkb1/rules.mk +++ b/keyboards/rkb1/rules.mk @@ -10,3 +10,6 @@ COMMON_VPATH += $(QUANTUM_PATH)/split_common EXTRAINCDIRS += $(BOARD_PATH) CFLAGS += -Wl,--defsym=__unhandled_user_irq=_unhandled_exception + +#SRC += matrix.c +#CUSTOM_MATRIX = lite diff --git a/platforms/chibios/vendors/RP/RP2040.mk b/platforms/chibios/vendors/RP/RP2040.mk index df450704ba..4ef94ef74e 100644 --- a/platforms/chibios/vendors/RP/RP2040.mk +++ b/platforms/chibios/vendors/RP/RP2040.mk @@ -35,6 +35,7 @@ PICOSDKSRC = $(PICOSDKROOT)/src/rp2_common/hardware_clocks/clocks.c \ $(PICOSDKROOT)/src/rp2_common/hardware_irq/irq.c \ $(PICOSDKROOT)/src/rp2_common/hardware_irq/irq_handler_chain.S \ $(PICOSDKROOT)/src/rp2_common/hardware_timer/timer.c \ + $(PICOSDKROOT)/src/rp2_common/hardware_dma/dma.c \ $(PICOSDKROOT)/src/rp2_common/pico_bootrom/bootrom.c \ $(PICOSDKROOT)/src/common/pico_time/time.c \ $(PICOSDKROOT)/src/common/pico_time/timeout_helper.c \ @@ -64,13 +65,14 @@ PICOSDKINC = $(CHIBIOS)//os/various/pico_bindings/dumb/include \ $(PICOSDKROOT)/src/rp2_common/hardware_xosc/include \ $(PICOSDKROOT)/src/rp2_common/hardware_i2c/include \ $(PICOSDKROOT)/src/rp2_common/hardware_timer/include \ + $(PICOSDKROOT)/src/rp2_common/hardware_dma/include \ $(PICOSDKROOT)/src/rp2040/hardware_regs/include \ $(PICOSDKROOT)/src/rp2040/hardware_structs/include \ $(PICOSDKROOT)/src/boards/include \ $(PICOSDKROOT)/src/rp2_common/pico_bootrom/include \ $(PICOSDKROOT)/src/common/pico_time/include \ $(PICOSDKROOT)/src/common/pico_util/include \ - $(PICOSDKROOT)/src/common/pico_sync/include + $(PICOSDKROOT)/src/common/pico_sync/include PLATFORM_SRC += $(PICOSDKSRC) EXTRAINCDIRS += $(PICOSDKINC)