pico hid: uart support

This commit is contained in:
Maxim Devaev 2023-08-04 23:31:35 +03:00
parent b44c8516d7
commit 94025892f3
7 changed files with 140 additions and 14 deletions

View File

@ -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)

View File

@ -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);
}
}

View File

@ -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) {

View File

@ -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);

View File

@ -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);

75
hid/pico/src/ph_uart.c Normal file
View File

@ -0,0 +1,75 @@
/*****************************************************************************
# #
# KVMD - The main PiKVM daemon. #
# #
# Copyright (C) 2018-2023 Maxim Devaev <mdevaev@gmail.com> #
# #
# 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);
}

30
hid/pico/src/ph_uart.h Normal file
View File

@ -0,0 +1,30 @@
/*****************************************************************************
# #
# KVMD - The main PiKVM daemon. #
# #
# Copyright (C) 2018-2023 Maxim Devaev <mdevaev@gmail.com> #
# #
# 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);