diff options
Diffstat (limited to 'hid/pico/src/ph_ps2_phy.pio')
-rw-r--r-- | hid/pico/src/ph_ps2_phy.pio | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/hid/pico/src/ph_ps2_phy.pio b/hid/pico/src/ph_ps2_phy.pio new file mode 100644 index 00000000..055cc6d7 --- /dev/null +++ b/hid/pico/src/ph_ps2_phy.pio @@ -0,0 +1,81 @@ +; +; Copyright (c) 2022 No0ne (https://github.com/No0ne) +; (c) 2023 Dustin Hoffman +; +; SPDX-License-Identifier: MIT +; + +.program ps2phy +.side_set 1 opt pindirs + +restart: + irq clear 0 rel + set pindirs 0 side 0 // clock and data to input mode + +receivecheck: + jmp pin sendcheck // if clock is high, see if we have data to send + irq set 0 rel // clock is being pulled low, set busy flag + wait 1 pin 1 // wait for clock to be pulled high + + // we are not sending, look for a start bit (clock high, data low) + in pins 1 // read in from data + mov x isr // move what we read to x + mov isr null // clear ISR. + jmp !x receive // if x is low, start the receive process. + jmp restart // not receiving + +receive: + set pindirs, 1 [6] // clock low. + set x, 8 // set loop counter. + +receiveloop: + set pindirs, 0 [6] // clock high + in pins, 1 [4] // read a bit into ISR. + set pindirs, 1 [6] // clock low + jmp x-- receiveloop [4] // iterate + set pindirs, 0 [6] // clock high + nop side 1 [6] // data low + set pindirs, 1 [7] // clock low + jmp restart + +sendcheck: + jmp !osre wait_to_write // see if we have data to send + jmp receivecheck // no data to send, restart + +wait_to_write: + irq set 0 rel + set x 10 // number of bits to write out + +sendloop: + set pindirs, 0 [6] // clock set to input (high) + jmp pin sendcontinue // if clock is high, host is still receiving data + irq set 1 rel // clock was low, host wants to send data, notify of failure to send data + mov osr null // clear OSR + jmp restart +sendcontinue: + out pindirs, 1 [6] // write out data + set pindirs, 1 [6] // set clock low + jmp x-- sendloop [6] + +% c-sdk { + void ps2phy_program_init(PIO pio, uint sm, uint offset, uint dat) { + pio_sm_config c = ps2phy_program_get_default_config(offset); + + u8 clk = dat + 1; + pio_gpio_init(pio, clk); + pio_gpio_init(pio, dat); + + // Use a frequency high enough to effectivly sample clock and data. + sm_config_set_clkdiv(&c, 427); // 2560 is 20 µs, 640 is 5 µs, 427 is 3.3333 µs + sm_config_set_jmp_pin(&c, clk); + sm_config_set_set_pins(&c, clk, 1); + sm_config_set_sideset_pins(&c, dat); + sm_config_set_out_pins(&c, dat, 1); + sm_config_set_out_shift(&c, true, true, 11); + sm_config_set_in_pins(&c, dat); + sm_config_set_in_shift(&c, true, true, 9); + + pio_sm_init(pio, sm, offset, &c); + pio_sm_set_enabled(pio, sm, true); + } +%}
\ No newline at end of file |