◸code

惯例先放两张成品图,没有 ATX 部分

就直接说魔改部分吧,os 按照官网 build 步骤来走

  1. de3. 逻辑跑不通,直接干掉
  2. 拉一些资源拉不到,直接加 ALL_PROXY=socks5://x.x.x.x:xxx 代理过去
  3. tesseract 包依赖的测试数据 tessdata 拉不到,经查这是为了 ocr 功能,对我没用,删掉相关两个依赖
  4. make install 不成功,可能是读卡器或者卡的问题,魔改让他不走 xz 然后 make image 出来镜像,烧录,另外我发现镜像里 config.txtcmdline.txt 都没有,过程中也报了 mv 失败,但是能启动,就没管他
  5. 最坑的部分,sparkfun pro micro 一开始用 arduino ide 测试的时候,很容易就刷错了,然后串口就出不来了,我一度认为可能需要重新买一个了,结果搜索到短接两次 RSTGND8 秒的 bootloader 时间,因此修好了
  6. 手头有电阻,没三极管,reset hid 功能不好使,本来半夜了就没多想,第二天上班的时候想了想:rpi3b+ 把针脚设置为 IN 并关闭掉内置上下拉电阻就可以模拟高阻抗也就是悬空态;因为共地所以可以近似认为低电平达到 GND 效果;两个状态刚好是 RST 所需状态,所以修改代码顺利跑通,附代码

我只是注释掉原来的部分,并没有删除,改用 RPi.GPIO 是因为用的比较熟悉

文件:/usr/lib/python3.10/site-packages/kvmd/plugins/hid/_mcu/gpio.py

# ========================================================================== #
#                                                                            #
#    KVMD - The main PiKVM daemon.                                           #
#                                                                            #
#    Copyright (C) 2018-2022  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/>.  #
#                                                                            #
# ========================================================================== #


import types
import time

from typing import Type
from typing import Optional

import gpiod

from ....logging import get_logger

import RPi.GPIO as GPIO


# =====
class Gpio:
    def __init__(
        self,
        device_path: str,
        reset_pin: int,
        reset_inverted: bool,
        reset_delay: float,
    ) -> None:
        GPIO.setmode(GPIO.BOARD)
        # self.__device_path = device_path
        self.__reset_pin = reset_pin
        # self.__reset_inverted = reset_inverted
        self.__reset_delay = reset_delay
        # self.__chip: Optional[gpiod.Chip] = None
        # self.__reset_line: Optional[gpiod.Line] = None

    def __enter__(self) -> None:
        GPIO.setup(self.__reset_pin, GPIO.IN, pull_up_down=GPIO.PUD_OFF)
        # if self.__reset_pin >= 0:
        #     assert self.__chip is None
        #     assert self.__reset_line is None
        #     self.__chip = gpiod.Chip(self.__device_path)
        #     self.__reset_line = self.__chip.get_line(self.__reset_pin)
        #     self.__reset_line.request("kvmd::hid::reset", gpiod.LINE_REQ_DIR_OUT, default_vals=[int(self.__reset_inverted)])

    def __exit__(
        self,
        _exc_type: Type[BaseException],
        _exc: BaseException,
        _tb: types.TracebackType,
    ) -> None:
        GPIO.cleanup()
        # if self.__chip:
        #     try:
        #         self.__chip.close()
        #     except Exception:
        #         pass
        #     self.__reset_line = None
        #     self.__chip = None

    def reset(self) -> None:
        GPIO.setup(self.__reset_pin, GPIO.OUT)
        GPIO.output(self.__reset_pin, GPIO.LOW)
        time.sleep(self.__reset_delay)
        GPIO.setup(self.__reset_pin, GPIO.IN, pull_up_down=GPIO.PUD_OFF)
        time.sleep(1)
        get_logger(0).info("Reset HID performed")
        # if self.__reset_pin >= 0:
        #     assert self.__reset_line
        #     try:
        #         self.__reset_line.set_value(int(not self.__reset_inverted))
        #         time.sleep(self.__reset_delay)
        #     finally:
        #         self.__reset_line.set_value(int(self.__reset_inverted))
        #         time.sleep(1)
        #     get_logger(0).info("Reset HID performed")