summaryrefslogtreecommitdiff
path: root/hid/pico
diff options
context:
space:
mode:
authorMaxim Devaev <[email protected]>2023-08-04 23:31:35 +0300
committerMaxim Devaev <[email protected]>2023-08-04 23:31:35 +0300
commit94025892f3ed51a594e568a2f0d5731031cc6a46 (patch)
tree0d262b08cbdf0767146e74d409813b110680b52c /hid/pico
parentb44c8516d7efec87a6ea5d96b175fedaf5252b7f (diff)
pico hid: uart support
Diffstat (limited to 'hid/pico')
-rw-r--r--hid/pico/src/CMakeLists.txt1
-rw-r--r--hid/pico/src/main.c27
-rw-r--r--hid/pico/src/ph_outputs.c16
-rw-r--r--hid/pico/src/ph_spi.c3
-rw-r--r--hid/pico/src/ph_spi.h2
-rw-r--r--hid/pico/src/ph_uart.c75
-rw-r--r--hid/pico/src/ph_uart.h30
7 files changed, 140 insertions, 14 deletions
diff --git a/hid/pico/src/CMakeLists.txt b/hid/pico/src/CMakeLists.txt
index e8b7583e..f8ca0b8c 100644
--- a/hid/pico/src/CMakeLists.txt
+++ b/hid/pico/src/CMakeLists.txt
@@ -9,6 +9,7 @@ target_sources(${target_name} PRIVATE
ph_usb_mouse.c
ph_cmds.c
ph_spi.c
+ ph_uart.c
ph_debug.c
)
target_link_options(${target_name} PRIVATE -Xlinker --print-memory-usage)
diff --git a/hid/pico/src/main.c b/hid/pico/src/main.c
index 26c7c922..2819bd7a 100644
--- a/hid/pico/src/main.c
+++ b/hid/pico/src/main.c
@@ -29,11 +29,21 @@
#include "ph_outputs.h"
#include "ph_usb.h"
#include "ph_spi.h"
+#include "ph_uart.h"
#include "ph_proto.h"
#include "ph_cmds.h"
#include "ph_debug.h"
+#define _COMM_PIN 22
+
+
+static bool _comm_use_spi = true;
+#define _COMM(x_func, ...) { \
+ if (_comm_use_spi) { ph_spi_##x_func(__VA_ARGS__); } \
+ else { ph_uart_##x_func(__VA_ARGS__); } \
+ }
+
static bool _reset_required = false;
@@ -93,28 +103,37 @@ static void _send_response(u8 code) {
ph_split16(ph_crc16(resp, 6), &resp[6], &resp[7]);
- ph_spi_write(resp);
+ _COMM(write, resp);
if (_reset_required) {
watchdog_reboot(0, 0, 100); // Даем немного времени чтобы отправить ответ, а потом ребутимся
}
}
-static void _spi_data_handler(const u8 *data) {
+static void _data_handler(const u8 *data) {
_send_response(_handle_request(data));
}
+static void _timeout_handler(void) {
+ _send_response(PH_PROTO_RESP_TIMEOUT_ERROR);
+}
+
int main(void) {
ph_debug_init(false); // No UART
ph_outputs_init();
ph_usb_init();
- ph_spi_init(_spi_data_handler);
+
+ gpio_init(_COMM_PIN);
+ gpio_set_dir(_COMM_PIN, GPIO_IN);
+ gpio_pull_up(_COMM_PIN);
+ _comm_use_spi = !gpio_get(_COMM_PIN);
+ _COMM(init, _data_handler, _timeout_handler);
while (true) {
ph_usb_task();
if (!_reset_required) {
- ph_spi_task();
+ _COMM(task);
ph_debug_act_pulse(100);
}
}
diff --git a/hid/pico/src/ph_outputs.c b/hid/pico/src/ph_outputs.c
index 40d10983..a1963f7d 100644
--- a/hid/pico/src/ph_outputs.c
+++ b/hid/pico/src/ph_outputs.c
@@ -48,7 +48,7 @@ static int _read_outputs(void);
void ph_outputs_init(void) {
-# define INIT_SWITCH(x_pin) { gpio_init(x_pin); gpio_set_dir(x_pin, GPIO_IN); gpio_pull_down(x_pin); }
+# define INIT_SWITCH(x_pin) { gpio_init(x_pin); gpio_set_dir(x_pin, GPIO_IN); gpio_pull_up(x_pin); }
INIT_SWITCH(_PS2_ENABLED_PIN);
INIT_SWITCH(_PS2_SET_KBD_PIN);
INIT_SWITCH(_PS2_SET_MOUSE_PIN);
@@ -59,14 +59,14 @@ void ph_outputs_init(void) {
INIT_SWITCH(_USB_SET_MOUSE_W98_PIN);
# undef INIT_SWITCH
- const bool o_ps2_enabled = gpio_get(_PS2_ENABLED_PIN);
- const bool o_ps2_kbd = gpio_get(_PS2_SET_KBD_PIN);
- const bool o_ps2_mouse = gpio_get(_PS2_SET_MOUSE_PIN);
+ const bool o_ps2_enabled = !gpio_get(_PS2_ENABLED_PIN); // Note: all pins are pulled up!
+ const bool o_ps2_kbd = !gpio_get(_PS2_SET_KBD_PIN);
+ const bool o_ps2_mouse = !gpio_get(_PS2_SET_MOUSE_PIN);
- const bool o_usb_disabled = gpio_get(_USB_DISABLED_PIN);
- const bool o_usb_enabled_w98 = gpio_get(_USB_ENABLE_W98_PIN);
- const bool o_usb_mouse_rel = gpio_get(_USB_SET_MOUSE_REL_PIN);
- const bool o_usb_mouse_w98 = gpio_get(_USB_SET_MOUSE_W98_PIN);
+ const bool o_usb_disabled = !gpio_get(_USB_DISABLED_PIN);
+ const bool o_usb_enabled_w98 = !gpio_get(_USB_ENABLE_W98_PIN);
+ const bool o_usb_mouse_rel = !gpio_get(_USB_SET_MOUSE_REL_PIN);
+ const bool o_usb_mouse_w98 = !gpio_get(_USB_SET_MOUSE_W98_PIN);
int outputs = _read_outputs();
if (outputs < 0) {
diff --git a/hid/pico/src/ph_spi.c b/hid/pico/src/ph_spi.c
index ef74bd7e..0a016f80 100644
--- a/hid/pico/src/ph_spi.c
+++ b/hid/pico/src/ph_spi.c
@@ -51,8 +51,9 @@ static void (*_data_cb)(const u8 *) = NULL;
static void _xfer_isr(void);
-void ph_spi_init(void (*data_cb)(const u8 *)) {
+void ph_spi_init(void (*data_cb)(const u8 *), void (*timeout_cb)(void)) {
_data_cb = data_cb;
+ (void)timeout_cb;
spi_init(_BUS, _FREQ);
spi_set_slave(_BUS, true);
diff --git a/hid/pico/src/ph_spi.h b/hid/pico/src/ph_spi.h
index ba613bb3..8ae6b792 100644
--- a/hid/pico/src/ph_spi.h
+++ b/hid/pico/src/ph_spi.h
@@ -25,6 +25,6 @@
#include "ph_types.h"
-void ph_spi_init(void (*data_cb)(const u8 *));
+void ph_spi_init(void (*data_cb)(const u8 *), void (*timeout_cb)(void));
void ph_spi_task(void);
void ph_spi_write(const u8 *data);
diff --git a/hid/pico/src/ph_uart.c b/hid/pico/src/ph_uart.c
new file mode 100644
index 00000000..705b0a13
--- /dev/null
+++ b/hid/pico/src/ph_uart.c
@@ -0,0 +1,75 @@
+/*****************************************************************************
+# #
+# KVMD - The main PiKVM daemon. #
+# #
+# Copyright (C) 2018-2023 Maxim Devaev <[email protected]> #
+# #
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program. If not, see <https://www.gnu.org/licenses/>. #
+# #
+*****************************************************************************/
+
+
+#include "ph_uart.h"
+
+#include "pico/stdlib.h"
+#include "hardware/gpio.h"
+#include "hardware/uart.h"
+
+#include "ph_types.h"
+
+
+#define _BUS uart1
+#define _SPEED 115200
+#define _RX_PIN 21
+#define _TX_PIN 20
+#define _TIMEOUT_US 100000
+
+
+static u8 _buf[8] = {0};
+static u8 _index = 0;
+static u64 _last_ts = 0;
+
+static void (*_data_cb)(const u8 *) = NULL;
+static void (*_timeout_cb)(void) = NULL;
+
+
+void ph_uart_init(void (*data_cb)(const u8 *), void (*timeout_cb)(void)) {
+ _data_cb = data_cb;
+ _timeout_cb = timeout_cb;
+ uart_init(_BUS, _SPEED);
+ gpio_set_function(_RX_PIN, GPIO_FUNC_UART);
+ gpio_set_function(_TX_PIN, GPIO_FUNC_UART);
+}
+
+void ph_uart_task(void) {
+ if (uart_is_readable(_BUS)) {
+ _buf[_index] = (u8)uart_getc(_BUS);
+ if (_index == 7) {
+ _data_cb(_buf);
+ _index = 0;
+ } else {
+ _last_ts = time_us_64();
+ ++_index;
+ }
+ } else if (_index > 0) {
+ if (_last_ts + _TIMEOUT_US < time_us_64()) {
+ _timeout_cb();
+ _index = 0;
+ }
+ }
+}
+
+void ph_uart_write(const u8 *data) {
+ uart_write_blocking(_BUS, data, 8);
+}
diff --git a/hid/pico/src/ph_uart.h b/hid/pico/src/ph_uart.h
new file mode 100644
index 00000000..e807f8b0
--- /dev/null
+++ b/hid/pico/src/ph_uart.h
@@ -0,0 +1,30 @@
+/*****************************************************************************
+# #
+# KVMD - The main PiKVM daemon. #
+# #
+# Copyright (C) 2018-2023 Maxim Devaev <[email protected]> #
+# #
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program. If not, see <https://www.gnu.org/licenses/>. #
+# #
+*****************************************************************************/
+
+
+#pragma once
+
+#include "ph_types.h"
+
+
+void ph_uart_init(void (*data_cb)(const u8 *), void (*timeout_cb)(void));
+void ph_uart_task(void);
+void ph_uart_write(const u8 *data);