Browse Source

Remove pin ordering restriction in RP2040 ps2 driver (#26256)

gitaen 1 month ago
parent
commit
4f6c5d2745
2 changed files with 36 additions and 28 deletions
  1. 1 1
      docs/features/ps2_mouse.md
  2. 35 27
      platforms/chibios/drivers/vendor/RP/RP2040/ps2_vendor.c

+ 1 - 1
docs/features/ps2_mouse.md

@@ -166,7 +166,7 @@ In your keyboard config.h:
 
 The `PIO` subsystem is a Raspberry Pi RP2040 specific implementation, using the integrated PIO peripheral and is therefore only available on this MCU.
 
-There are strict requirements for pin ordering but any pair of GPIO pins can be used. The GPIO used for clock must be directly after data, see the included info.json snippet for an example of correct order.
+The GPIOs used for clock and data must be consecutive (in either order).
 
 You may optionally switch the PIO peripheral used with the following define in config.h:
 ```c

+ 35 - 27
platforms/chibios/drivers/vendor/RP/RP2040/ps2_vendor.c

@@ -21,8 +21,16 @@
 #    endif
 #endif
 
-#if PS2_DATA_PIN + 1 != PS2_CLOCK_PIN
-#    error PS/2 clock pin must be data pin + 1!
+#if PS2_DATA_PIN + 1 == PS2_CLOCK_PIN
+#    define PS2_FIRST_PIN PS2_DATA_PIN
+#    define PS2_DATA_PINDIR_BIT 1
+#    define PS2_CLOCK_PINDIR_BIT 2
+#elif PS2_DATA_PIN - 1 == PS2_CLOCK_PIN
+#    define PS2_FIRST_PIN PS2_CLOCK_PIN
+#    define PS2_DATA_PINDIR_BIT 2
+#    define PS2_CLOCK_PINDIR_BIT 1
+#else
+#    error PS/2 clock and data pin must be consecutive!
 #endif
 
 static inline void pio_serve_interrupt(void);
@@ -50,29 +58,29 @@ OSAL_IRQ_HANDLER(RP_PIO0_IRQ_0_HANDLER) {
 
 // clang-format off
 static const uint16_t ps2_program_instructions[] = {
-            //     .wrap_target
-    0x00c7, //  0: jmp    pin, 7
-    0xe02a, //  1: set    x, 10
-    0x2021, //  2: wait   0 pin, 1
-    0x4001, //  3: in     pins, 1
-    0x20a1, //  4: wait   1 pin, 1
-    0x0042, //  5: jmp    x--, 2
-    0x0000, //  6: jmp    0
-    0x00e9, //  7: jmp    !osre, 9
-    0x0000, //  8: jmp    0
-    0xff81, //  9: set    pindirs, 1             [31]
-    0xe280, // 10: set    pindirs, 0             [2]
-    0xe082, // 11: set    pindirs, 2
-    0x2021, // 12: wait   0 pin, 1
-    0xe029, // 13: set    x, 9
-    0x6081, // 14: out    pindirs, 1
-    0x20a1, // 15: wait   1 pin, 1
-    0x2021, // 16: wait   0 pin, 1
-    0x004e, // 17: jmp    x--, 14
-    0xe083, // 18: set    pindirs, 3
-    0x2021, // 19: wait   0 pin, 1
-    0x20a1, // 20: wait   1 pin, 1
-            //     .wrap
+                                        //     .wrap_target
+    0x00c7,                             //  0: jmp    pin, 7
+    0xe02a,                             //  1: set    x, 10
+    0x2000 | PS2_CLOCK_PIN,             //  2: wait   0 gpio, CLK
+    0x4001,                             //  3: in     pins, 1
+    0x2080 | PS2_CLOCK_PIN,             //  4: wait   1 gpio, CLK
+    0x0042,                             //  5: jmp    x--, 2
+    0x0000,                             //  6: jmp    0
+    0x00e9,                             //  7: jmp    !osre, 9
+    0x0000,                             //  8: jmp    0
+    0xff80 | PS2_DATA_PINDIR_BIT,       //  9: set    pindirs, DATA         [31]
+    0xe280,                             // 10: set    pindirs, 0             [2]
+    0xe080 | PS2_CLOCK_PINDIR_BIT,      // 11: set    pindirs, CLK
+    0x2000 | PS2_CLOCK_PIN,             // 12: wait   0 gpio, CLK
+    0xe029,                             // 13: set    x, 9
+    0x6081,                             // 14: out    pindirs, 1
+    0x2080 | PS2_CLOCK_PIN,             // 15: wait   1 gpio, CLK
+    0x2000 | PS2_CLOCK_PIN,             // 16: wait   0 gpio, CLK
+    0x004e,                             // 17: jmp    x--, 14
+    0xe083,                             // 18: set    pindirs, 3
+    0x2000 | PS2_CLOCK_PIN,             // 19: wait   0 gpio, CLK
+    0x2080 | PS2_CLOCK_PIN,             // 20: wait   1 gpio, CLK
+                                        //     .wrap
 };
 // clang-format on
 
@@ -133,9 +141,9 @@ void ps2_host_init(void) {
     sm_config_set_wrap(&c, offset + PS2_WRAP_TARGET, offset + PS2_WRAP);
 
     // Set pindirs to input (output enable is inverted below)
-    pio_sm_set_consecutive_pindirs(pio, state_machine, PS2_DATA_PIN, 2, true);
+    pio_sm_set_consecutive_pindirs(pio, state_machine, PS2_FIRST_PIN, 2, true);
     sm_config_set_clkdiv(&c, (float)clock_get_hz(clk_sys) / (200.0f * KHZ));
-    sm_config_set_set_pins(&c, PS2_DATA_PIN, 2);
+    sm_config_set_set_pins(&c, PS2_FIRST_PIN, 2);
     sm_config_set_out_pins(&c, PS2_DATA_PIN, 1);
     sm_config_set_out_shift(&c, true, true, 10);
     sm_config_set_in_shift(&c, true, true, 11);