summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDevaev Maxim <[email protected]>2020-11-10 13:38:55 +0300
committerDevaev Maxim <[email protected]>2020-11-11 22:24:25 +0300
commita8a075c203e2a458ff51ce0d4152ab09a4710d65 (patch)
tree77f9ddec476867f94895d0e32305473c6b87486b
parente07cdd60f393eb17184afe4ea1730f3c5745ea6f (diff)
another try
-rw-r--r--hid/platformio.ini1
-rw-r--r--hid/src/main.cpp115
-rw-r--r--kvmd/plugins/hid/spi.py57
-rw-r--r--testenv/linters/vulture-wl.py1
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