diff options
Diffstat (limited to 'hid/pico/src/ph_ps2.c')
-rw-r--r-- | hid/pico/src/ph_ps2.c | 217 |
1 files changed, 110 insertions, 107 deletions
diff --git a/hid/pico/src/ph_ps2.c b/hid/pico/src/ph_ps2.c index caddc174..51c0a21b 100644 --- a/hid/pico/src/ph_ps2.c +++ b/hid/pico/src/ph_ps2.c @@ -24,15 +24,17 @@ #include "ph_types.h" #include "ph_outputs.h" -#include "ph_ps2.pio.h" +#include "ph_ps2_phy.h" #include "hardware/gpio.h" u8 ph_g_ps2_kbd_leds = 0; bool ph_g_ps2_kbd_online = 0; bool ph_g_ps2_mouse_online = 0; +ph_ps2_phy ph_ps2_kbd; +ph_ps2_phy ph_ps2_mouse; -uint8_t const mod2ps2[] = { 0x14, 0x12, 0x11, 0x1f, 0x14, 0x59, 0x11, 0x27 }; -uint8_t const hid2ps2[] = { +u8 const ph_ps2_mod2ps2[] = { 0x14, 0x12, 0x11, 0x1f, 0x14, 0x59, 0x11, 0x27 }; +u8 const ph_ps2_hid2ps2[] = { 0x00, 0x00, 0xfc, 0x00, 0x1c, 0x32, 0x21, 0x23, 0x24, 0x2b, 0x34, 0x33, 0x43, 0x3b, 0x42, 0x4b, 0x3a, 0x31, 0x44, 0x4d, 0x15, 0x2d, 0x1b, 0x2c, 0x3c, 0x2a, 0x1d, 0x22, 0x35, 0x1a, 0x16, 0x1e, 0x26, 0x25, 0x2e, 0x36, 0x3d, 0x3e, 0x46, 0x45, 0x5a, 0x76, 0x66, 0x0d, 0x29, 0x4e, 0x55, 0x54, @@ -42,119 +44,106 @@ uint8_t const hid2ps2[] = { 0x75, 0x7d, 0x70, 0x71, 0x61, 0x2f, 0x37, 0x0f, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38, 0x40, 0x48, 0x50, 0x57, 0x5f }; -uint8_t const maparray = sizeof(hid2ps2) / sizeof(uint8_t); +u8 const ph_ps2_maparray = sizeof(ph_ps2_hid2ps2); -PIO pio = pio0; -uint sm; -uint offset; - -uint16_t ph_ps2_frame(uint8_t data) { - uint8_t parity = 1; - for (uint8_t i = 0; i < 8; i++) { - parity = parity ^ (data >> i & 1); - } - - return ((1 << 10) | (parity << 9) | (data << 1)) ^ 0x7ff; -} - -void ph_ps2_kbd_send(uint8_t data) { - pio_sm_put(pio, sm, ph_ps2_frame(data)); +void ph_ps2_kbd_send(u8 byte) { + queue_try_add(&ph_ps2_kbd.qbytes, &byte); } -void ph_ps2_kbd_maybe_send_e0(uint8_t data) { - if (data == 0x46 || - (data >= 0x49 && data <= 0x52) || - data == 0x54 || data == 0x58 || - data == 0x65 || data == 0x66 || - data >= 0x81) { +void ph_ps2_kbd_maybe_send_e0(u8 byte) { + if (byte == 0x46 || + (byte >= 0x49 && byte <= 0x52) || + byte == 0x54 || byte == 0x58 || + byte == 0x65 || byte == 0x66 || + byte >= 0x81) { ph_ps2_kbd_send(0xe0); } } -void ph_ps2_init(void) { - if (PH_O_IS_KBD_PS2 || PH_O_IS_MOUSE_PS2) { - gpio_init(13); - gpio_set_dir(13, GPIO_OUT); - gpio_put(13, 1); // LV pull-up voltage - - sm = pio_claim_unused_sm(pio, true); - offset = pio_add_program(pio, &ps2device_program); - ps2device_program_init(pio, sm, offset, 14); - } -} - -void ph_ps2_task(void) { - if (PH_O_IS_KBD_PS2 || PH_O_IS_MOUSE_PS2) { - - if (!pio_sm_is_rx_fifo_empty(pio, sm)) { - uint32_t fifo = pio_sm_get(pio, sm); - fifo = fifo >> 23; +void ph_ps2_kbd_receive(u8 byte) { + switch(byte) { + case 0xed: // CMD: Set LEDs - uint8_t parity = 1; - for(uint8_t i = 0; i < 8; i++) { - parity = parity ^ (fifo >> i & 1); - } + break; + + case 0xf3: // CMD: Set typematic rate and delay - if(parity != fifo >> 8) { - ph_ps2_kbd_send(0xfe); + break; + + default: + switch(byte) { + case 0xff: // CMD: Reset + //pio_sm_clear_fifos(pio, sm); + //pio_sm_drain_tx_fifo(pio, sm); + ph_ps2_kbd_send(0xfa); + ph_ps2_kbd_send(0xaa); return; - } - - uint8_t data = fifo; - - /*switch() { + + case 0xfe: // CMD: Resend + + return; + + case 0xee: // CMD: Echo + ph_ps2_kbd_send(0xee); + return; + + case 0xf2: // CMD: Identify keyboard + ph_ps2_kbd_send(0xfa); + ph_ps2_kbd_send(0xab); + ph_ps2_kbd_send(0x83); + return; + + case 0xf3: // CMD: Set typematic rate and delay case 0xed: // CMD: Set LEDs break; - case 0xf3: // CMD: Set typematic rate and delay + case 0xf4: // CMD: Enable scanning break; - default:*/ - switch(data) { - case 0xff: // CMD: Reset - pio_sm_clear_fifos(pio, sm); - pio_sm_drain_tx_fifo(pio, sm); - ph_ps2_kbd_send(0xfa); - ph_ps2_kbd_send(0xaa); - return; - - case 0xfe: // CMD: Resend - - return; - - case 0xee: // CMD: Echo - ph_ps2_kbd_send(0xee); - return; - - case 0xf2: // CMD: Identify keyboard - ph_ps2_kbd_send(0xfa); - ph_ps2_kbd_send(0xab); - ph_ps2_kbd_send(0x83); - return; - - case 0xf3: // CMD: Set typematic rate and delay - case 0xed: // CMD: Set LEDs - - break; - - case 0xf4: // CMD: Enable scanning - - break; - - case 0xf5: // CMD: Disable scanning, restore default parameters - case 0xf6: // CMD: Set default parameters - - break; - } - /* break; - }*/ - - ph_ps2_kbd_send(0xfa); - } + case 0xf5: // CMD: Disable scanning, restore default parameters + case 0xf6: // CMD: Set default parameters + + break; + } + break; + } + + ph_ps2_kbd_send(0xfa); +} + +void ph_ps2_mouse_receive(u8 byte) { + switch(byte) { } +} + +void ph_ps2_init(void) { + if (PH_O_IS_KBD_PS2 || PH_O_IS_MOUSE_PS2) { + gpio_init(13); + gpio_set_dir(13, GPIO_OUT); + gpio_put(13, 1); // GPIO13=LV pull-up voltage + } + + if (PH_O_IS_KBD_PS2) { + ph_ps2_phy_init(&ph_ps2_kbd, pio0, 11, &ph_ps2_kbd_receive); // keyboard: GPIO11=data, GPIO12=clock + ph_ps2_kbd_send(0xaa); + } + + if (PH_O_IS_MOUSE_PS2) { + ph_ps2_phy_init(&ph_ps2_mouse, pio1, 14, &ph_ps2_mouse_receive); // mouse: GPIO14=data, GPIO15=clock + } +} + +void ph_ps2_task(void) { + if (PH_O_IS_KBD_PS2) { + ph_ps2_phy_task(&ph_ps2_kbd); + } + + if (PH_O_IS_MOUSE_PS2) { + ph_ps2_phy_task(&ph_ps2_mouse); + } // Here you should update some values: // - ph_g_ps2_kbd_leds - keyboard LEDs mask like on USB // - ph_g_ps2_kbd_online - if keyboard online (by clock?) @@ -167,25 +156,39 @@ void ph_ps2_kbd_send_key(u8 key, bool state) { if (PH_O_IS_KBD_PS2) { if (key >= 0xe0 && key <= 0xe7) { key -= 0xe0; - if(key > 2 && key != 5) { + + if (key > 2 && key != 5) { ph_ps2_kbd_send(0xe0); } - if(!state) { + if (!state) { ph_ps2_kbd_send(0xf0); } - ph_ps2_kbd_send(mod2ps2[key]); + ph_ps2_kbd_send(ph_ps2_mod2ps2[key]); - } else if (key < maparray) { - ph_ps2_kbd_maybe_send_e0(key); + } else if (key < ph_ps2_maparray) { - if(!state) { - ph_ps2_kbd_send(0xf0); + if (key == 0x48) { + if (state) { + + if (false) { // TODO: is shift + ph_ps2_kbd_send(0xe0); ph_ps2_kbd_send(0x7e); ph_ps2_kbd_send(0xe0); ph_ps2_kbd_send(0xf0); ph_ps2_kbd_send(0x7e); + } else { + ph_ps2_kbd_send(0xe1); ph_ps2_kbd_send(0x14); ph_ps2_kbd_send(0x77); ph_ps2_kbd_send(0xe1); + ph_ps2_kbd_send(0xf0); ph_ps2_kbd_send(0x14); ph_ps2_kbd_send(0xf0); ph_ps2_kbd_send(0x77); + } + + } + } else { + ph_ps2_kbd_maybe_send_e0(key); + + if (!state) { + ph_ps2_kbd_send(0xf0); + } + + ph_ps2_kbd_send(ph_ps2_hid2ps2[key]); } - - ph_ps2_kbd_send(hid2ps2[key]); - } } } |