1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
;
; Copyright (c) 2022 No0ne (https://github.com/No0ne)
; (c) 2023 Dustin Hoffman
;
; SPDX-License-Identifier: MIT
;
.program ps2device
.side_set 1 opt pindirs
//mov y ! null
start:
.wrap_target
set pindirs 0 side 0 // Clock and data to input mode.
jmp pin sendcheck // If clock is high, see if we have data to send.
// Clock is being pulled low.
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 start // Not receiving, restart.
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
//in null 1
.wrap
sendcheck:
jmp !osre wait_to_write // See if we have data to send.
jmp start // No data to send, restart.
wait_to_write:
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.
// Pin was low, host wants to send data.
// Notify of failure to send data..
//in null 8
//in y 2
jmp start
sendcontinue:
out pindirs, 1 [6] // Write out data.
set pindirs, 1 [6] // Set clock low.
jmp x-- sendloop [6]
//in y 10
jmp start
% c-sdk {
void ps2device_program_init(PIO pio, uint sm, uint offset, uint dat) {
pio_sm_config c = ps2device_program_get_default_config(offset);
uint 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 us, 640 is 5 us, 427 is 3.3333 us
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);
}
%}
|