mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2025-12-12 01:00:29 +08:00
using ps2x2pico as a library
This commit is contained in:
parent
a03c3c2367
commit
2189b77c07
1
hid/pico/.gitignore
vendored
1
hid/pico/.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
/.pico-sdk*
|
||||
/.tinyusb*
|
||||
/.ps2x2pico*
|
||||
/.build/
|
||||
/*.uf2
|
||||
|
||||
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
set(PICO_SDK_PATH ${CMAKE_CURRENT_LIST_DIR}/.pico-sdk)
|
||||
set(PICO_TINYUSB_PATH ${CMAKE_CURRENT_LIST_DIR}/.tinyusb)
|
||||
# TODO: PS2: set(PS2_PATH ${CMAKE_CURRENT_LIST_DIR}/.yourlib/subdir)
|
||||
SET(PS2_PATH ${CMAKE_CURRENT_LIST_DIR}/.ps2x2pico)
|
||||
|
||||
# For TinyUSB
|
||||
set(FAMILY rp2040)
|
||||
|
||||
@ -15,7 +15,7 @@ install: all
|
||||
clean:
|
||||
rm -rf .build hid.uf2
|
||||
clean-all: clean
|
||||
rm -rf .pico-sdk* .tinyusb*
|
||||
rm -rf .pico-sdk* .tinyusb* .ps2x2pico
|
||||
|
||||
|
||||
define libdep
|
||||
@ -30,8 +30,9 @@ endef
|
||||
$(call libdep,pico-sdk,raspberrypi/pico-sdk,6a7db34ff63345a7badec79ebea3aaef1712f374)
|
||||
.tinyusb:
|
||||
$(call libdep,tinyusb,hathach/tinyusb,d713571cd44f05d2fc72efc09c670787b74106e0)
|
||||
# TODO: PS2: Add your library here and add it to "all" and "clean-all" targets
|
||||
deps: .pico-sdk .tinyusb
|
||||
.ps2x2pico:
|
||||
$(call libdep,ps2x2pico,No0ne/ps2x2pico,706b5c34cb6a2fcefeb7f1ee0f673c7de9452fc6)
|
||||
deps: .pico-sdk .tinyusb .ps2x2pico
|
||||
|
||||
|
||||
.PHONY: deps
|
||||
|
||||
@ -8,7 +8,6 @@ target_sources(${target_name} PRIVATE
|
||||
ph_usb_kbd.c
|
||||
ph_usb_mouse.c
|
||||
ph_ps2.c
|
||||
ph_ps2_phy.c
|
||||
ph_ps2_kbd.c
|
||||
ph_ps2_mouse.c
|
||||
ph_cmds.c
|
||||
@ -17,12 +16,14 @@ target_sources(${target_name} PRIVATE
|
||||
ph_com_spi.c
|
||||
ph_com_uart.c
|
||||
ph_debug.c
|
||||
|
||||
${PS2_PATH}/ps2phy.c
|
||||
)
|
||||
target_link_options(${target_name} PRIVATE -Xlinker --print-memory-usage)
|
||||
target_compile_options(${target_name} PRIVATE -Wall -Wextra)
|
||||
target_include_directories(${target_name} PRIVATE ${CMAKE_CURRENT_LIST_DIR})
|
||||
target_include_directories(${target_name} PRIVATE ${CMAKE_CURRENT_LIST_DIR} ${PS2_PATH})
|
||||
|
||||
pico_generate_pio_header(${target_name} ${CMAKE_CURRENT_LIST_DIR}/ph_ps2_phy.pio)
|
||||
pico_generate_pio_header(${target_name} ${PS2_PATH}/ps2phy.pio)
|
||||
|
||||
target_link_libraries(${target_name} PRIVATE
|
||||
pico_stdlib
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
#include "ps2phy.h"
|
||||
|
||||
#include "ph_outputs.h"
|
||||
#include "ph_ps2_phy.h"
|
||||
|
||||
extern u8 ph_g_ps2_kbd_leds;
|
||||
extern bool ph_g_ps2_kbd_online;
|
||||
|
||||
ph_ps2_phy ph_ps2_kbd;
|
||||
ps2phy ph_ps2_kbd;
|
||||
bool ph_ps2_kbd_scanning;
|
||||
u32 ph_ps2_kbd_repeat_us;
|
||||
u16 ph_ps2_kbd_delay_ms;
|
||||
@ -212,11 +213,11 @@ void ph_ps2_kbd_receive(u8 byte, u8 prev_byte) {
|
||||
}
|
||||
|
||||
void ph_ps2_kbd_task(void) {
|
||||
ph_ps2_phy_task(&ph_ps2_kbd);
|
||||
ps2phy_task(&ph_ps2_kbd);
|
||||
ph_g_ps2_kbd_online = ph_ps2_kbd_scanning && !ph_ps2_kbd.busy;
|
||||
}
|
||||
|
||||
void ph_ps2_kbd_init(u8 gpio) {
|
||||
ph_ps2_phy_init(&ph_ps2_kbd, pio0, gpio, &ph_ps2_kbd_receive);
|
||||
ps2phy_init(&ph_ps2_kbd, pio0, gpio, &ph_ps2_kbd_receive);
|
||||
ph_ps2_kbd_reset();
|
||||
}
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
#include "ps2phy.h"
|
||||
|
||||
#include "ph_outputs.h"
|
||||
#include "ph_ps2_phy.h"
|
||||
|
||||
extern bool ph_g_ps2_mouse_online;
|
||||
|
||||
ph_ps2_phy ph_ps2_mouse;
|
||||
ps2phy ph_ps2_mouse;
|
||||
bool ph_ps2_mouse_streaming = false;
|
||||
u32 ph_ps2_mouse_magic_seq = 0;
|
||||
u8 ph_ps2_mouse_type = 0;
|
||||
@ -138,10 +139,10 @@ void ph_ps2_mouse_receive(u8 byte, u8 prev_byte) {
|
||||
}
|
||||
|
||||
void ph_ps2_mouse_task(void) {
|
||||
ph_ps2_phy_task(&ph_ps2_mouse);
|
||||
ps2phy_task(&ph_ps2_mouse);
|
||||
ph_g_ps2_mouse_online = ph_ps2_mouse_streaming && !ph_ps2_mouse.busy;
|
||||
}
|
||||
|
||||
void ph_ps2_mouse_init(u8 gpio) {
|
||||
ph_ps2_phy_init(&ph_ps2_mouse, pio0, gpio, &ph_ps2_mouse_receive);
|
||||
ps2phy_init(&ph_ps2_mouse, pio0, gpio, &ph_ps2_mouse_receive);
|
||||
}
|
||||
|
||||
@ -1,100 +0,0 @@
|
||||
// Source: https://github.com/No0ne/ps2x2pico/blob/main/ps2phy.c
|
||||
// replace ps2phy with ph_ps2_phy
|
||||
|
||||
#include "ph_ps2_phy.h"
|
||||
#include "ph_ps2_phy.pio.h"
|
||||
|
||||
s8 prog = -1;
|
||||
|
||||
u32 ph_ps2_phy_frame(u8 byte) {
|
||||
bool parity = 1;
|
||||
for (u8 i = 0; i < 8; i++) {
|
||||
parity = parity ^ (byte >> i & 1);
|
||||
}
|
||||
return ((1 << 10) | (parity << 9) | (byte << 1)) ^ 0x7ff;
|
||||
}
|
||||
|
||||
void ph_ps2_phy_init(ph_ps2_phy* this, PIO pio, u8 data_pin, rx_callback rx) {
|
||||
if (prog == -1) {
|
||||
prog = pio_add_program(pio, &ph_ps2_phy_program);
|
||||
}
|
||||
|
||||
queue_init(&this->qbytes, sizeof(u8), 9);
|
||||
queue_init(&this->qpacks, sizeof(u8) * 9, 16);
|
||||
|
||||
this->sm = pio_claim_unused_sm(pio, true);
|
||||
ph_ps2_phy_program_init(pio, this->sm, prog, data_pin);
|
||||
|
||||
this->pio = pio;
|
||||
this->sent = 0;
|
||||
this->rx = rx;
|
||||
this->last_rx = 0;
|
||||
this->last_tx = 0;
|
||||
this->busy = 0;
|
||||
}
|
||||
|
||||
void ph_ps2_phy_task(ph_ps2_phy* this) {
|
||||
u8 i = 0;
|
||||
u8 byte;
|
||||
u8 pack[9];
|
||||
|
||||
if (!queue_is_empty(&this->qbytes)) {
|
||||
while (i < 9 && queue_try_remove(&this->qbytes, &byte)) {
|
||||
i++;
|
||||
pack[i] = byte;
|
||||
}
|
||||
|
||||
pack[0] = i;
|
||||
queue_try_add(&this->qpacks, &pack);
|
||||
}
|
||||
|
||||
if (pio_interrupt_get(this->pio, this->sm)) {
|
||||
this->busy = 1;
|
||||
} else {
|
||||
this->busy &= 2;
|
||||
}
|
||||
|
||||
if (pio_interrupt_get(this->pio, this->sm + 4)) {
|
||||
this->sent--;
|
||||
pio_interrupt_clear(this->pio, this->sm + 4);
|
||||
}
|
||||
|
||||
if (!queue_is_empty(&this->qpacks) && pio_sm_is_tx_fifo_empty(this->pio, this->sm) && !this->busy) {
|
||||
if (queue_try_peek(&this->qpacks, &pack)) {
|
||||
if (this->sent == pack[0]) {
|
||||
this->sent = 0;
|
||||
queue_try_remove(&this->qpacks, &pack);
|
||||
} else {
|
||||
this->sent++;
|
||||
this->last_tx = pack[this->sent];
|
||||
this->busy |= 2;
|
||||
pio_sm_put(this->pio, this->sm, ph_ps2_phy_frame(this->last_tx));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!pio_sm_is_rx_fifo_empty(this->pio, this->sm)) {
|
||||
u32 fifo = pio_sm_get(this->pio, this->sm) >> 23;
|
||||
|
||||
bool parity = 1;
|
||||
for (i = 0; i < 8; i++) {
|
||||
parity = parity ^ (fifo >> i & 1);
|
||||
}
|
||||
|
||||
if (parity != fifo >> 8) {
|
||||
pio_sm_put(this->pio, this->sm, ph_ps2_phy_frame(0xfe));
|
||||
return;
|
||||
}
|
||||
|
||||
if (fifo == 0xfe) {
|
||||
pio_sm_put(this->pio, this->sm, ph_ps2_phy_frame(this->last_tx));
|
||||
return;
|
||||
}
|
||||
|
||||
while (queue_try_remove(&this->qbytes, &byte));
|
||||
while (queue_try_remove(&this->qpacks, &pack));
|
||||
|
||||
(*this->rx)(fifo, this->last_rx);
|
||||
this->last_rx = fifo;
|
||||
}
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "ph_types.h"
|
||||
#include "hardware/pio.h"
|
||||
#include "pico/util/queue.h"
|
||||
|
||||
typedef void (*rx_callback)(u8 byte, u8 prev_byte);
|
||||
|
||||
typedef struct {
|
||||
PIO pio;
|
||||
uint sm;
|
||||
queue_t qbytes;
|
||||
queue_t qpacks;
|
||||
rx_callback rx;
|
||||
u8 last_rx;
|
||||
u8 last_tx;
|
||||
u8 sent;
|
||||
u8 busy;
|
||||
} ph_ps2_phy;
|
||||
|
||||
void ph_ps2_phy_init(ph_ps2_phy* this, PIO pio, u8 data_pin, rx_callback rx);
|
||||
void ph_ps2_phy_task(ph_ps2_phy* this);
|
||||
@ -1,83 +0,0 @@
|
||||
;
|
||||
; Copyright (c) 2022 No0ne (https://github.com/No0ne)
|
||||
; (c) 2023 Dustin Hoffman
|
||||
;
|
||||
; SPDX-License-Identifier: MIT
|
||||
;
|
||||
; Source: https://github.com/No0ne/ps2x2pico/blob/main/ps2phy.pio
|
||||
|
||||
.program ph_ps2_phy
|
||||
.side_set 1 opt pindirs
|
||||
|
||||
restart:
|
||||
set pindirs, 0 // set clock to input mode
|
||||
irq clear 0 rel side 0 // clear busy flag, set data to input mode
|
||||
|
||||
receivecheck:
|
||||
jmp pin, sendcheck // if clock is high, see if we have data to send
|
||||
irq nowait 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 [7]
|
||||
|
||||
sendcheck:
|
||||
jmp !osre, send // see if we have data to send
|
||||
jmp receivecheck // no data to send, restart
|
||||
|
||||
send:
|
||||
irq nowait 0 rel // set busy flag
|
||||
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
|
||||
out null, 32 // clear OSR
|
||||
irq wait 4 rel // clock was low, host wants to send data, notify of failure to send data
|
||||
jmp restart // and wait for restart
|
||||
|
||||
sendcontinue:
|
||||
out pindirs, 1 [6] // write out data
|
||||
set pindirs, 1 [6] // set clock low
|
||||
jmp x--, sendloop [6]
|
||||
|
||||
% c-sdk {
|
||||
void ph_ps2_phy_program_init(PIO pio, uint sm, uint offset, uint dat) {
|
||||
pio_sm_config c = ph_ps2_phy_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);
|
||||
}
|
||||
%}
|
||||
Loading…
x
Reference in New Issue
Block a user