diff options
author | Devaev Maxim <[email protected]> | 2020-11-10 13:38:55 +0300 |
---|---|---|
committer | Devaev Maxim <[email protected]> | 2020-11-11 22:24:25 +0300 |
commit | a8a075c203e2a458ff51ce0d4152ab09a4710d65 (patch) | |
tree | 77f9ddec476867f94895d0e32305473c6b87486b | |
parent | e07cdd60f393eb17184afe4ea1730f3c5745ea6f (diff) |
another try
-rw-r--r-- | hid/platformio.ini | 1 | ||||
-rw-r--r-- | hid/src/main.cpp | 115 | ||||
-rw-r--r-- | kvmd/plugins/hid/spi.py | 57 | ||||
-rw-r--r-- | testenv/linters/vulture-wl.py | 1 |
4 files changed, 91 insertions, 83 deletions
diff --git a/hid/platformio.ini b/hid/platformio.ini index 8b49e0e5..3414d1d7 100644 --- a/hid/platformio.ini +++ b/hid/platformio.ini @@ -60,6 +60,7 @@ build_flags = build_flags = -DCMD_SERIAL=Serial1 -DCMD_SERIAL_SPEED=115200 + -DCMD_SERIAL_TIMEOUT=100000 upload_port = /dev/ttyACM0 [env:usb] diff --git a/hid/src/main.cpp b/hid/src/main.cpp index 0da6884b..3d0eb618 100644 --- a/hid/src/main.cpp +++ b/hid/src/main.cpp @@ -40,11 +40,11 @@ #endif -// #define CMD_SERIAL Serial1 -// #define CMD_SERIAL_SPEED 115200 +// #define CMD_SERIAL Serial1 +// #define CMD_SERIAL_SPEED 115200 +// #define CMD_SERIAL_TIMEOUT 100000 // -- OR -- // #define CMD_SPI -#define CMD_TIMEOUT 100000 // ----------------------------------------------------------------------------- @@ -150,52 +150,49 @@ uint8_t handleCmdBuffer(const uint8_t *buffer) { // 8 bytes #ifdef CMD_SPI volatile uint8_t spi_in[8] = {0}; volatile uint8_t spi_in_index = 0; -volatile uint8_t spi_in_read = 0; // Вычитанное spiRead() volatile uint8_t spi_out[4] = {0}; volatile uint8_t spi_out_index = 0; -uint8_t spiAvailable() { - return spi_in_index - spi_in_read; -} - -uint8_t spiRead() { - uint8_t value = 0; - if (spi_in_read < 8) { - value = spi_in[spi_in_read]; - ++spi_in_read; - } - return value; +bool spiReady() { + return (!spi_out[0] && spi_in_index == 8); } void spiWrite(const uint8_t *buffer) { - if (spi_out[0] == 0) { - spi_out[3] = buffer[3]; - spi_out[2] = buffer[2]; - spi_out[1] = buffer[1]; - spi_out[0] = buffer[0]; // Меджик разрешает начать ответ - } -} - -void spiReadReset() { - spi_in_index = 0; - spi_in_read = 0; + spi_out[3] = buffer[3]; + spi_out[2] = buffer[2]; + spi_out[1] = buffer[1]; + spi_out[0] = buffer[0]; // Меджик разрешает начать ответ +// digitalWrite(5, 1); } ISR(SPI_STC_vect) { - if (spi_in_index < 8) { - spi_in[spi_in_index] = SPDR; - ++spi_in_index; - SPDR = 0; - } else if (spi_out[0] && spi_out_index < 4) { + uint8_t in = SPDR; + if (spi_out[0] && spi_out_index < 4) { +// digitalWrite(4, !digitalRead(4)); SPDR = spi_out[spi_out_index]; - ++spi_out_index; - if (spi_out_index == 4) { - spiReadReset(); - spi_out[0] = 0; - spi_out_index = 0; + bool err = (SPSR & (1 << WCOL)); + if (!err) { + ++spi_out_index; + if (spi_out_index == 4) { + spi_out_index = 0; + spi_in_index = 0; + spi_out[0] = 0; +// digitalWrite(5, 0); + } } } else { + static bool receiving = false; + if (!receiving && in == PROTO_MAGIC) { + receiving = true; + } + if (receiving && spi_in_index < 8) { + spi_in[spi_in_index] = in; + ++spi_in_index; + } + if (spi_in_index == 8) { + receiving = false; + } SPDR = 0; } } @@ -225,20 +222,17 @@ void sendCmdResponse(uint8_t code) { # endif } -bool isCmdTimedOut(unsigned long last) { - unsigned long now = micros(); - return ( - (now >= last && now - last > CMD_TIMEOUT) - || (now < last && ((unsigned long)-1) - last + now > CMD_TIMEOUT) - ); -} - void setup() { hid_kbd.begin(); # ifdef HID_USB_MOUSE hid_mouse.begin(); # endif + pinMode(3, OUTPUT); + pinMode(4, OUTPUT); + pinMode(5, OUTPUT); + pinMode(6, OUTPUT); + # ifdef CMD_SERIAL CMD_SERIAL.begin(CMD_SERIAL_SPEED); # elif defined(CMD_SPI) @@ -248,9 +242,11 @@ void setup() { } void loop() { +# ifdef CMD_SERIAL unsigned long last = micros(); uint8_t buffer[8]; uint8_t index = 0; +# endif while (true) { # ifdef HID_PS2_KBD @@ -260,10 +256,6 @@ void loop() { # ifdef CMD_SERIAL if (CMD_SERIAL.available() > 0) { buffer[index] = (uint8_t)CMD_SERIAL.read(); -# elif defined(CMD_SPI) - if (spiAvailable() > 0) { - buffer[index] = spiRead(); -# endif if (index == 7) { sendCmdResponse(handleCmdBuffer(buffer)); index = 0; @@ -271,13 +263,26 @@ void loop() { last = micros(); ++index; } - } else if (index > 0 && isCmdTimedOut(last)) { -# ifdef CMD_SERIAL - sendCmdResponse(PROTO_RESP_TIMEOUT_ERROR); -# elif defined(CMD_SPI) - spiReadReset(); -# endif - index = 0; + } else if (index > 0) { + unsigned long now = micros(); + if ( + (now >= last && now - last > CMD_SERIAL_TIMEOUT) + || (now < last && ((unsigned long)-1) - last + now > CMD_SERIAL_TIMEOUT) + ) { + sendCmdResponse(PROTO_RESP_TIMEOUT_ERROR); + index = 0; + } + } +# elif defined(CMD_SPI) + if (SPSR & (1 << WCOL)) { + digitalWrite(3, HIGH); + uint8_t _ = SPDR; + delay(1); + digitalWrite(3, LOW); + } + if (spiReady()) { + sendCmdResponse(handleCmdBuffer(spi_in)); } +# endif } } diff --git a/kvmd/plugins/hid/spi.py b/kvmd/plugins/hid/spi.py index d71a4094..3dcd0dab 100644 --- a/kvmd/plugins/hid/spi.py +++ b/kvmd/plugins/hid/spi.py @@ -36,9 +36,9 @@ from ...logging import get_logger from ...yamlconf import Option +from ...validators.basic import valid_bool from ...validators.basic import valid_int_f0 from ...validators.basic import valid_int_f1 -from ...validators.basic import valid_float_f0 from ...validators.basic import valid_float_f01 from ._mcu import BasePhyConnection @@ -52,26 +52,33 @@ class _SpiPhyConnection(BasePhyConnection): self, xfer: Callable[[bytes], bytes], read_timeout: float, - read_delay: float, ) -> None: self.__xfer = xfer self.__read_timeout = read_timeout - self.__read_delay = read_delay def send(self, request: bytes) -> bytes: assert len(request) == 8 + assert request[0] == 0x33 + + deadline_ts = time.time() + self.__read_timeout + dummy = b"\x00" * 8 + while time.time() < deadline_ts: + if bytes(self.__xfer(dummy)) == dummy: + break + else: + get_logger(0).error("SPI timeout reached while garbage reading") + return b"" + self.__xfer(request) response: List[int] = [] deadline_ts = time.time() + self.__read_timeout found = False while time.time() < deadline_ts: - if not found: - time.sleep(self.__read_delay) for byte in self.__xfer(b"\x00" * (4 - len(response))): if not found: - if byte == 0: + if byte != 0x33: continue found = True response.append(byte) @@ -90,18 +97,18 @@ class _SpiPhy(BasePhy): self, bus: int, chip: int, + cs: bool, max_freq: int, block_usec: int, read_timeout: float, - read_delay: float, ) -> None: self.__bus = bus self.__chip = chip + self.__cs = cs self.__max_freq = max_freq self.__block_usec = block_usec self.__read_timeout = read_timeout - self.__read_delay = read_delay def has_device(self) -> bool: return os.path.exists(f"/dev/spidev{self.__bus}.{self.__chip}") @@ -110,6 +117,7 @@ class _SpiPhy(BasePhy): def connected(self) -> Generator[_SpiPhyConnection, None, None]: # type: ignore with contextlib.closing(spidev.SpiDev(self.__bus, self.__chip)) as spi: spi.mode = 0 + spi.no_cs = (not self.__cs) spi.max_speed_hz = self.__max_freq def xfer(data: bytes) -> bytes: @@ -118,36 +126,29 @@ class _SpiPhy(BasePhy): yield _SpiPhyConnection( xfer=xfer, read_timeout=self.__read_timeout, - read_delay=self.__read_delay, ) # ===== class Plugin(BaseMcuHid): - def __init__( - self, - bus: int, - chip: int, - max_freq: int, - block_usec: int, - read_timeout: float, - read_delay: float, - **kwargs: Any, - ) -> None: - - super().__init__( - phy=_SpiPhy(bus, chip, max_freq, block_usec, read_timeout, read_delay), - **kwargs, - ) + def __init__(self, **kwargs: Any) -> None: + phy_kwargs: Dict = {key: kwargs.pop(key) for key in self.__get_phy_options()} + super().__init__(phy=_SpiPhy(**phy_kwargs), **kwargs) @classmethod def get_plugin_options(cls) -> Dict: return { + **cls.__get_phy_options(), + **BaseMcuHid.get_plugin_options(), + } + + @classmethod + def __get_phy_options(cls) -> Dict: + return { "bus": Option(0, type=valid_int_f0), "chip": Option(0, type=valid_int_f0), - "max_freq": Option(400000, type=valid_int_f1), + "cs": Option(False, type=valid_bool), + "max_freq": Option(200000, type=valid_int_f1), "block_usec": Option(1, type=valid_int_f0), - "read_timeout": Option(2.0, type=valid_float_f01), - "read_delay": Option(0.001, type=valid_float_f0), - **BaseMcuHid.get_plugin_options(), + "read_timeout": Option(0.5, type=valid_float_f01), } diff --git a/testenv/linters/vulture-wl.py b/testenv/linters/vulture-wl.py index 75240082..62752f43 100644 --- a/testenv/linters/vulture-wl.py +++ b/testenv/linters/vulture-wl.py @@ -18,6 +18,7 @@ InotifyMask.UNMOUNT IpmiServer.handle_raw_request +SpiDev.no_cs SpiDev.max_speed_hz _AtxApiPart.switch_power |