diff options
Diffstat (limited to 'hid/arduino/lib/drivers-stm32')
-rw-r--r-- | hid/arduino/lib/drivers-stm32/README.md | 22 | ||||
-rw-r--r-- | hid/arduino/lib/drivers-stm32/backup-register.h | 53 | ||||
-rw-r--r-- | hid/arduino/lib/drivers-stm32/bluepill_sch.png | bin | 0 -> 179860 bytes | |||
-rw-r--r-- | hid/arduino/lib/drivers-stm32/board-stm32.h | 103 | ||||
-rw-r--r-- | hid/arduino/lib/drivers-stm32/factory.cpp | 94 | ||||
-rw-r--r-- | hid/arduino/lib/drivers-stm32/usb/hid-wrapper-stm32.h | 72 | ||||
-rw-r--r-- | hid/arduino/lib/drivers-stm32/usb/keyboard-stm32.h | 92 | ||||
-rw-r--r-- | hid/arduino/lib/drivers-stm32/usb/mouse-absolute-stm32.h | 86 | ||||
-rw-r--r-- | hid/arduino/lib/drivers-stm32/usb/mouse-relative-stm32.h | 86 |
9 files changed, 608 insertions, 0 deletions
diff --git a/hid/arduino/lib/drivers-stm32/README.md b/hid/arduino/lib/drivers-stm32/README.md new file mode 100644 index 00000000..93de3312 --- /dev/null +++ b/hid/arduino/lib/drivers-stm32/README.md @@ -0,0 +1,22 @@ +This is WIP. Use AVR version as reference. + +It was tested with bluepill. Most boards are clones. +If you have problem with USB please check https://stm32duinoforum.com/forum/wiki_subdomain/index_title_Blue_Pill.html for pull up resistor. If it still does not work check another board or cable. + +TODO: +- [x] Serial communication +- [x] USB keyboard +- [x] USB keyboard - add scroll status +- [x] USB keyboard - key sending +- [x] USB keyboard - test key mapping +- [x] Persistent storage +- [ ] SPI communication +- [ ] PS2 keyboard +- [x] USB absolute mouse +- [x] USB absolute mouse - add whele +- [x] USB relative mouse +- [x] USB relative mouse - add whele +- [ ] USB mouses - up down button +- [ ] WIN98 USB mouse +- [x] undefine SERIAL_USB +- [ ] boot keyboard diff --git a/hid/arduino/lib/drivers-stm32/backup-register.h b/hid/arduino/lib/drivers-stm32/backup-register.h new file mode 100644 index 00000000..196e4e1c --- /dev/null +++ b/hid/arduino/lib/drivers-stm32/backup-register.h @@ -0,0 +1,53 @@ +/***************************************************************************** +# # +# 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 <stm32f1_rtc.h> + +#include "storage.h" + + +namespace DRIVERS { + struct BackupRegister : public Storage { + BackupRegister() : Storage(NON_VOLATILE_STORAGE) { + _rtc.enableClockInterface(); + } + + void readBlock(void *dest, const void *src, size_t size) override { + uint8_t *dest_ = reinterpret_cast<uint8_t*>(dest); + for(size_t index = 0; index < size; ++index) { + dest_[index] = _rtc.getBackupRegister(reinterpret_cast<uintptr_t>(src) + index + 1); + } + } + + void updateBlock(const void *src, void *dest, size_t size) override { + const uint8_t *src_ = reinterpret_cast<const uint8_t*>(src); + for(size_t index = 0; index < size; ++index) { + _rtc.setBackupRegister(reinterpret_cast<uintptr_t>(dest) + index + 1, src_[index]); + } + } + + private: + STM32F1_RTC _rtc; + }; +} diff --git a/hid/arduino/lib/drivers-stm32/bluepill_sch.png b/hid/arduino/lib/drivers-stm32/bluepill_sch.png Binary files differnew file mode 100644 index 00000000..956448dd --- /dev/null +++ b/hid/arduino/lib/drivers-stm32/bluepill_sch.png diff --git a/hid/arduino/lib/drivers-stm32/board-stm32.h b/hid/arduino/lib/drivers-stm32/board-stm32.h new file mode 100644 index 00000000..1602edaa --- /dev/null +++ b/hid/arduino/lib/drivers-stm32/board-stm32.h @@ -0,0 +1,103 @@ +/***************************************************************************** +# # +# 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 "board.h" +#include <libmaple/iwdg.h> + + +namespace DRIVERS { + class BoardStm32 : public Board { + public: + BoardStm32() : Board(BOARD){ + //2 sec timeout + iwdg_init(IWDG_PRE_16, 0xFFF); + pinMode(LED_BUILTIN, OUTPUT); + } + + void reset() override { + nvic_sys_reset(); + } + + void periodic() override { + iwdg_feed(); + if (is_micros_timed_out(_prev_ts, 100000)) { + switch(_state) { + case 0: + digitalWrite(LED_BUILTIN, LOW); + break; + case 2: + if(_rx_data) { + _rx_data = false; + digitalWrite(LED_BUILTIN, LOW); + } + break; + case 4: + if(_keyboard_online) { + _keyboard_online = false; + digitalWrite(LED_BUILTIN, LOW); + } + break; + case 8: + if(_mouse_online) { + _mouse_online = false; + digitalWrite(LED_BUILTIN, LOW); + } + break; + case 1: // heartbeat off + case 3: // _rx_data off + case 7: // _keyboard_online off + case 11: // _mouse_online off + digitalWrite(LED_BUILTIN, HIGH); + break; + case 19: + _state = -1; + break; + } + ++_state; + _prev_ts = micros(); + } + } + + void updateStatus(status status) override { + switch (status) { + case RX_DATA: + _rx_data = true; + break; + case KEYBOARD_ONLINE: + _keyboard_online = true; + break; + case MOUSE_ONLINE: + _mouse_online = true; + break; + } + } + + private: + unsigned long _prev_ts = 0; + uint8_t _state = 0; + bool _rx_data = false; + bool _keyboard_online = false; + bool _mouse_online = false; + }; +} diff --git a/hid/arduino/lib/drivers-stm32/factory.cpp b/hid/arduino/lib/drivers-stm32/factory.cpp new file mode 100644 index 00000000..8f20e0ff --- /dev/null +++ b/hid/arduino/lib/drivers-stm32/factory.cpp @@ -0,0 +1,94 @@ +/***************************************************************************** +# # +# 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 "factory.h" +#include "usb/keyboard-stm32.h" +#include "usb/hid-wrapper-stm32.h" +#include "usb/mouse-absolute-stm32.h" +#include "usb/mouse-relative-stm32.h" +#include "backup-register.h" +#include "board-stm32.h" +#include "serial.h" + +#ifndef __STM32F1__ +# error "Only STM32F1 is supported" +#endif +#ifdef SERIAL_USB +# error "Disable random USB enumeration" +#endif + + +namespace DRIVERS { + HidWrapper _hidWrapper; + + Keyboard *Factory::makeKeyboard(type _type) { + switch (_type) { +# ifdef HID_WITH_USB + case USB_KEYBOARD: + return new UsbKeyboard(_hidWrapper); +# endif + default: + return new Keyboard(DUMMY); + } + } + + Mouse *Factory::makeMouse(type _type) { + switch(_type) { +# ifdef HID_WITH_USB + case USB_MOUSE_ABSOLUTE: + return new UsbMouseAbsolute(_hidWrapper); + case USB_MOUSE_RELATIVE: + return new UsbMouseRelative(_hidWrapper); +# endif + default: + return new Mouse(DRIVERS::DUMMY); + } + } + + Storage *Factory::makeStorage(type _type) { + switch (_type) { +# ifdef HID_DYNAMIC + case NON_VOLATILE_STORAGE: + return new BackupRegister(); +# endif + default: + return new Storage(DRIVERS::DUMMY); + } + } + + Board *Factory::makeBoard(type _type) { + switch (_type) { + case BOARD: + return new BoardStm32(); + default: + return new Board(DRIVERS::DUMMY); + } + } + + Connection *Factory::makeConnection(type _type) { +# ifdef CMD_SERIAL + return new Serial(); +# else +# error CMD phy is not defined +# endif + } +} diff --git a/hid/arduino/lib/drivers-stm32/usb/hid-wrapper-stm32.h b/hid/arduino/lib/drivers-stm32/usb/hid-wrapper-stm32.h new file mode 100644 index 00000000..62f58213 --- /dev/null +++ b/hid/arduino/lib/drivers-stm32/usb/hid-wrapper-stm32.h @@ -0,0 +1,72 @@ +/***************************************************************************** +# # +# 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 <USBComposite.h> + + +namespace DRIVERS { + class HidWrapper { + public: + void begin() { + if (_init) { + return; + } + _init = true; + + _report_descriptor_length = 0; + for (unsigned index = 0; index < _count; ++index) { + _report_descriptor_length += _descriptors_size[index]; + } + + _report_descriptor = new uint8[_report_descriptor_length]; + + size_t offset = 0; + for (unsigned index = 0; index < _count; ++index) { + memcpy(_report_descriptor + offset, _report_descriptors[index], _descriptors_size[index]); + offset += _descriptors_size[index]; + } + + usbHid.begin(_report_descriptor, _report_descriptor_length); + } + + void addReportDescriptor(const uint8_t *report_descriptor, uint16_t report_descriptor_length) { + _report_descriptors[_count] = report_descriptor; + _descriptors_size[_count] = report_descriptor_length; + ++_count; + } + + USBHID usbHid; + + private: + bool _init = false; + + static constexpr uint8_t MAX_USB_DESCRIPTORS = 2; + const uint8_t *_report_descriptors[MAX_USB_DESCRIPTORS]; + uint8_t _descriptors_size[MAX_USB_DESCRIPTORS]; + + uint8_t _count = 0; + uint8_t *_report_descriptor; + uint16_t _report_descriptor_length; + }; +} diff --git a/hid/arduino/lib/drivers-stm32/usb/keyboard-stm32.h b/hid/arduino/lib/drivers-stm32/usb/keyboard-stm32.h new file mode 100644 index 00000000..22dec04d --- /dev/null +++ b/hid/arduino/lib/drivers-stm32/usb/keyboard-stm32.h @@ -0,0 +1,92 @@ +/***************************************************************************** +# # +# 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 <USBComposite.h> + +#include "tools.h" +#include "keyboard.h" +#include "usb-keymap.h" +#include "hid-wrapper-stm32.h" + + +namespace DRIVERS { + const uint8_t reportDescriptionKeyboard[] = { + HID_KEYBOARD_REPORT_DESCRIPTOR(), + }; + + class UsbKeyboard : public Keyboard { + public: + UsbKeyboard(HidWrapper& _hidWrapper) : Keyboard(USB_KEYBOARD), + _hidWrapper(_hidWrapper), _keyboard(_hidWrapper.usbHid) { + _hidWrapper.addReportDescriptor(reportDescriptionKeyboard, sizeof(reportDescriptionKeyboard)); + } + + void begin() override { + _hidWrapper.begin(); + _keyboard.begin(); + } + + void clear() override { + _keyboard.releaseAll(); + } + + void sendKey(uint8_t code, bool state) override { + uint16_t usb_code = keymapUsb(code); + if (usb_code == 0) { + return; + } + + // 0xE0 is a prefix from HID-Project keytable + if (usb_code >= 0xE0 && usb_code <= 0xE7) { + usb_code = usb_code - 0xE0 + 0x80; + } else { + usb_code += KEY_HID_OFFSET; + } + + if (state) { + _keyboard.press(usb_code); + } else { + _keyboard.release(usb_code); + } + } + + bool isOffline() override { + return (USBComposite == false); + } + + KeyboardLedsState getLeds() override { + uint8_t leds = _keyboard.getLEDs(); + KeyboardLedsState result = { + .caps = leds & 0b00000010, + .scroll = leds & 0b00000100, + .num = leds & 0b00000001, + }; + return result; + } + + private: + HidWrapper& _hidWrapper; + HIDKeyboard _keyboard; + }; +} diff --git a/hid/arduino/lib/drivers-stm32/usb/mouse-absolute-stm32.h b/hid/arduino/lib/drivers-stm32/usb/mouse-absolute-stm32.h new file mode 100644 index 00000000..65195c78 --- /dev/null +++ b/hid/arduino/lib/drivers-stm32/usb/mouse-absolute-stm32.h @@ -0,0 +1,86 @@ +/***************************************************************************** +# # +# 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 <USBComposite.h> + +#include "mouse.h" +#include "hid-wrapper-stm32.h" + + +namespace DRIVERS { + const uint8_t reportDescriptionMouseAbsolute[] = { + HID_ABS_MOUSE_REPORT_DESCRIPTOR() + }; + + class UsbMouseAbsolute : public Mouse { + public: + UsbMouseAbsolute(HidWrapper& _hidWrapper) : Mouse(USB_MOUSE_ABSOLUTE), + _hidWrapper(_hidWrapper), _mouse(_hidWrapper.usbHid) { + _hidWrapper.addReportDescriptor(reportDescriptionMouseAbsolute, sizeof(reportDescriptionMouseAbsolute)); + } + + void begin() override { + _hidWrapper.begin(); + } + + void clear() override { + _mouse.release(0xFF); + } + + void sendButtons ( + bool left_select, bool left_state, + bool right_select, bool right_state, + bool middle_select, bool middle_state, + bool up_select, bool up_state, + bool down_select, bool down_state) override { + +# define SEND_BUTTON(x_low, x_up) { \ + if (x_low##_select) { \ + if (x_low##_state) _mouse.press(MOUSE_##x_up); \ + else _mouse.release(MOUSE_##x_up); \ + } \ + } + SEND_BUTTON(left, LEFT); + SEND_BUTTON(right, RIGHT); + SEND_BUTTON(middle, MIDDLE); +# undef SEND_BUTTON + } + + void sendMove(int x, int y) override { + _mouse.move(x, y); + } + + void sendWheel(int delta_y) override { + _mouse.move(0, 0, delta_y); + } + + bool isOffline() override { + return (USBComposite == false); + } + + private: + HidWrapper& _hidWrapper; + HIDAbsMouse _mouse; + }; +} diff --git a/hid/arduino/lib/drivers-stm32/usb/mouse-relative-stm32.h b/hid/arduino/lib/drivers-stm32/usb/mouse-relative-stm32.h new file mode 100644 index 00000000..4524e20b --- /dev/null +++ b/hid/arduino/lib/drivers-stm32/usb/mouse-relative-stm32.h @@ -0,0 +1,86 @@ +/***************************************************************************** +# # +# 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 <USBComposite.h> + +#include "mouse.h" +#include "hid-wrapper-stm32.h" + + +namespace DRIVERS { + const uint8_t reportDescriptionMouseRelative[] = { + HID_MOUSE_REPORT_DESCRIPTOR() + }; + + class UsbMouseRelative : public Mouse { + public: + UsbMouseRelative(HidWrapper& _hidWrapper) : Mouse(USB_MOUSE_RELATIVE), + _hidWrapper(_hidWrapper), _mouse(_hidWrapper.usbHid) { + _hidWrapper.addReportDescriptor(reportDescriptionMouseRelative, sizeof(reportDescriptionMouseRelative)); + } + + void begin() override { + _hidWrapper.begin(); + } + + void clear() override { + _mouse.release(0xFF); + } + + void sendButtons ( + bool left_select, bool left_state, + bool right_select, bool right_state, + bool middle_select, bool middle_state, + bool up_select, bool up_state, + bool down_select, bool down_state) override { + +# define SEND_BUTTON(x_low, x_up) { \ + if (x_low##_select) { \ + if (x_low##_state) _mouse.press(MOUSE_##x_up); \ + else _mouse.release(MOUSE_##x_up); \ + } \ + } + SEND_BUTTON(left, LEFT); + SEND_BUTTON(right, RIGHT); + SEND_BUTTON(middle, MIDDLE); +# undef SEND_BUTTON + } + + void sendRelative(int x, int y) override { + _mouse.move(x, y); + } + + void sendWheel(int delta_y) override { + _mouse.move(0, 0, delta_y); + } + + bool isOffline() override { + return (USBComposite == false); + } + + private: + HidWrapper& _hidWrapper; + HIDMouse _mouse; + }; +} |