; klavesnice
; (c) Jirka Chráska 2025; <jirka@lixis.cz>
.program keyboard
; 
; 
; 
.define KEYBOARD_IRQ 0
.wrap_target

nastav_radek_1:
    set pins, 1 [31]        ; nastavím 1 pro 1. řádek klávesnice
    set X, 0x1
    in pins, 4
    mov Y, isr
    jmp !Y, nastav_radek_2
    jmp rx_fifo

nastav_radek_2:
    set pins, 2 [31]        ; nastavím 1 pro 2. řádek klávesnice
    set X, 0x2
    in pins, 4
    mov Y, isr
    jmp !Y, nastav_radek_3
    jmp rx_fifo

nastav_radek_3:
    set pins, 4 [31]        ; nastavím 1 pro 3. řádek klávesnice
    set X, 0x4
    in pins, 4
    mov Y, isr
    jmp !Y, nastav_radek_4
    jmp rx_fifo

nastav_radek_4:
    set pins, 8 [31]        ; nastavím 1 pro 4. řádek klávesnice
    set X, 0x8
    in pins, 4
    mov Y, isr
    jmp !Y nastav_radek_1

rx_fifo:
    push                    ; pošlu souřadnici y (řádek)
    in X, 4 [2]
    push                    ; pošlu souřadnici x (sloupec)
    irq KEYBOARD_IRQ  rel    
    
    wait 0 pin 0            ; čekám, až bude klávesa uvolněna
    wait 0 pin 1
    wait 0 pin 2
    wait 0 pin 3
    
.wrap

% c-sdk {

#include "hardware/clocks.h"
#include "hardware/gpio.h"

static inline void keyboard_program_init (PIO pio, uint sm, uint offset, uint row_pin, uint col_pin) {

    // řádkové piny jsou nastaveny jako výstupní
    //
    pio_gpio_init(pio, row_pin);
    pio_gpio_init(pio, row_pin+1);
    pio_gpio_init(pio, row_pin+2);
    pio_gpio_init(pio, row_pin+3);
    pio_sm_set_consecutive_pindirs(pio, sm, row_pin, 4, true);
    
    // sloupcové piny
    pio_sm_set_consecutive_pindirs(pio, sm, col_pin, 4, false);

    
    // Konfigurace stavového stroje
    pio_sm_config c = keyboard_program_get_default_config (offset);

    // konfigurace vstupního posuvného registru (Input Shift Register)
    sm_config_set_in_shift (&c,
                            false,       // posunujeme doprava
                            false,       // autopush je vypnut
                            32);         // 

    
    // piny pro funkci IN
    sm_config_set_in_pins( &c, col_pin );
    // piny pro funkci SET
    sm_config_set_set_pins( &c, row_pin, 4 );
    
    // zvětšení fronty
    // sm_config_set_fifo_join (&c, PIO_FIFO_JOIN_RX);

    // Tik hodin stavového stroje nastavíme na 2 KHz
    float div = clock_get_hz (clk_sys) / 4000;
    sm_config_set_clkdiv (&c, div);
    
    // Konfiguraci šoupneme do stavového stroje
    pio_sm_init (pio, sm, offset, &c);

    // Stavový stroj spustíme
    pio_sm_set_enabled (pio, sm, true);
}
%}
