mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2025-12-12 01:00:29 +08:00
another try
This commit is contained in:
parent
e07cdd60f3
commit
a8a075c203
@ -60,6 +60,7 @@ build_flags =
|
|||||||
build_flags =
|
build_flags =
|
||||||
-DCMD_SERIAL=Serial1
|
-DCMD_SERIAL=Serial1
|
||||||
-DCMD_SERIAL_SPEED=115200
|
-DCMD_SERIAL_SPEED=115200
|
||||||
|
-DCMD_SERIAL_TIMEOUT=100000
|
||||||
upload_port = /dev/ttyACM0
|
upload_port = /dev/ttyACM0
|
||||||
|
|
||||||
[env:usb]
|
[env:usb]
|
||||||
|
|||||||
115
hid/src/main.cpp
115
hid/src/main.cpp
@ -40,11 +40,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// #define CMD_SERIAL Serial1
|
// #define CMD_SERIAL Serial1
|
||||||
// #define CMD_SERIAL_SPEED 115200
|
// #define CMD_SERIAL_SPEED 115200
|
||||||
|
// #define CMD_SERIAL_TIMEOUT 100000
|
||||||
// -- OR --
|
// -- OR --
|
||||||
// #define CMD_SPI
|
// #define CMD_SPI
|
||||||
#define CMD_TIMEOUT 100000
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@ -150,52 +150,49 @@ uint8_t handleCmdBuffer(const uint8_t *buffer) { // 8 bytes
|
|||||||
#ifdef CMD_SPI
|
#ifdef CMD_SPI
|
||||||
volatile uint8_t spi_in[8] = {0};
|
volatile uint8_t spi_in[8] = {0};
|
||||||
volatile uint8_t spi_in_index = 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[4] = {0};
|
||||||
volatile uint8_t spi_out_index = 0;
|
volatile uint8_t spi_out_index = 0;
|
||||||
|
|
||||||
uint8_t spiAvailable() {
|
bool spiReady() {
|
||||||
return spi_in_index - spi_in_read;
|
return (!spi_out[0] && spi_in_index == 8);
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t spiRead() {
|
|
||||||
uint8_t value = 0;
|
|
||||||
if (spi_in_read < 8) {
|
|
||||||
value = spi_in[spi_in_read];
|
|
||||||
++spi_in_read;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void spiWrite(const uint8_t *buffer) {
|
void spiWrite(const uint8_t *buffer) {
|
||||||
if (spi_out[0] == 0) {
|
spi_out[3] = buffer[3];
|
||||||
spi_out[3] = buffer[3];
|
spi_out[2] = buffer[2];
|
||||||
spi_out[2] = buffer[2];
|
spi_out[1] = buffer[1];
|
||||||
spi_out[1] = buffer[1];
|
spi_out[0] = buffer[0]; // Меджик разрешает начать ответ
|
||||||
spi_out[0] = buffer[0]; // Меджик разрешает начать ответ
|
// digitalWrite(5, 1);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void spiReadReset() {
|
|
||||||
spi_in_index = 0;
|
|
||||||
spi_in_read = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ISR(SPI_STC_vect) {
|
ISR(SPI_STC_vect) {
|
||||||
if (spi_in_index < 8) {
|
uint8_t in = SPDR;
|
||||||
spi_in[spi_in_index] = SPDR;
|
if (spi_out[0] && spi_out_index < 4) {
|
||||||
++spi_in_index;
|
// digitalWrite(4, !digitalRead(4));
|
||||||
SPDR = 0;
|
|
||||||
} else if (spi_out[0] && spi_out_index < 4) {
|
|
||||||
SPDR = spi_out[spi_out_index];
|
SPDR = spi_out[spi_out_index];
|
||||||
++spi_out_index;
|
bool err = (SPSR & (1 << WCOL));
|
||||||
if (spi_out_index == 4) {
|
if (!err) {
|
||||||
spiReadReset();
|
++spi_out_index;
|
||||||
spi_out[0] = 0;
|
if (spi_out_index == 4) {
|
||||||
spi_out_index = 0;
|
spi_out_index = 0;
|
||||||
|
spi_in_index = 0;
|
||||||
|
spi_out[0] = 0;
|
||||||
|
// digitalWrite(5, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} 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;
|
SPDR = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -225,20 +222,17 @@ void sendCmdResponse(uint8_t code) {
|
|||||||
# endif
|
# 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() {
|
void setup() {
|
||||||
hid_kbd.begin();
|
hid_kbd.begin();
|
||||||
# ifdef HID_USB_MOUSE
|
# ifdef HID_USB_MOUSE
|
||||||
hid_mouse.begin();
|
hid_mouse.begin();
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
pinMode(3, OUTPUT);
|
||||||
|
pinMode(4, OUTPUT);
|
||||||
|
pinMode(5, OUTPUT);
|
||||||
|
pinMode(6, OUTPUT);
|
||||||
|
|
||||||
# ifdef CMD_SERIAL
|
# ifdef CMD_SERIAL
|
||||||
CMD_SERIAL.begin(CMD_SERIAL_SPEED);
|
CMD_SERIAL.begin(CMD_SERIAL_SPEED);
|
||||||
# elif defined(CMD_SPI)
|
# elif defined(CMD_SPI)
|
||||||
@ -248,9 +242,11 @@ void setup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
# ifdef CMD_SERIAL
|
||||||
unsigned long last = micros();
|
unsigned long last = micros();
|
||||||
uint8_t buffer[8];
|
uint8_t buffer[8];
|
||||||
uint8_t index = 0;
|
uint8_t index = 0;
|
||||||
|
# endif
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
# ifdef HID_PS2_KBD
|
# ifdef HID_PS2_KBD
|
||||||
@ -260,10 +256,6 @@ void loop() {
|
|||||||
# ifdef CMD_SERIAL
|
# ifdef CMD_SERIAL
|
||||||
if (CMD_SERIAL.available() > 0) {
|
if (CMD_SERIAL.available() > 0) {
|
||||||
buffer[index] = (uint8_t)CMD_SERIAL.read();
|
buffer[index] = (uint8_t)CMD_SERIAL.read();
|
||||||
# elif defined(CMD_SPI)
|
|
||||||
if (spiAvailable() > 0) {
|
|
||||||
buffer[index] = spiRead();
|
|
||||||
# endif
|
|
||||||
if (index == 7) {
|
if (index == 7) {
|
||||||
sendCmdResponse(handleCmdBuffer(buffer));
|
sendCmdResponse(handleCmdBuffer(buffer));
|
||||||
index = 0;
|
index = 0;
|
||||||
@ -271,13 +263,26 @@ void loop() {
|
|||||||
last = micros();
|
last = micros();
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
} else if (index > 0 && isCmdTimedOut(last)) {
|
} else if (index > 0) {
|
||||||
# ifdef CMD_SERIAL
|
unsigned long now = micros();
|
||||||
sendCmdResponse(PROTO_RESP_TIMEOUT_ERROR);
|
if (
|
||||||
# elif defined(CMD_SPI)
|
(now >= last && now - last > CMD_SERIAL_TIMEOUT)
|
||||||
spiReadReset();
|
|| (now < last && ((unsigned long)-1) - last + now > CMD_SERIAL_TIMEOUT)
|
||||||
# endif
|
) {
|
||||||
index = 0;
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,9 +36,9 @@ from ...logging import get_logger
|
|||||||
|
|
||||||
from ...yamlconf import Option
|
from ...yamlconf import Option
|
||||||
|
|
||||||
|
from ...validators.basic import valid_bool
|
||||||
from ...validators.basic import valid_int_f0
|
from ...validators.basic import valid_int_f0
|
||||||
from ...validators.basic import valid_int_f1
|
from ...validators.basic import valid_int_f1
|
||||||
from ...validators.basic import valid_float_f0
|
|
||||||
from ...validators.basic import valid_float_f01
|
from ...validators.basic import valid_float_f01
|
||||||
|
|
||||||
from ._mcu import BasePhyConnection
|
from ._mcu import BasePhyConnection
|
||||||
@ -52,26 +52,33 @@ class _SpiPhyConnection(BasePhyConnection):
|
|||||||
self,
|
self,
|
||||||
xfer: Callable[[bytes], bytes],
|
xfer: Callable[[bytes], bytes],
|
||||||
read_timeout: float,
|
read_timeout: float,
|
||||||
read_delay: float,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
self.__xfer = xfer
|
self.__xfer = xfer
|
||||||
self.__read_timeout = read_timeout
|
self.__read_timeout = read_timeout
|
||||||
self.__read_delay = read_delay
|
|
||||||
|
|
||||||
def send(self, request: bytes) -> bytes:
|
def send(self, request: bytes) -> bytes:
|
||||||
assert len(request) == 8
|
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)
|
self.__xfer(request)
|
||||||
|
|
||||||
response: List[int] = []
|
response: List[int] = []
|
||||||
deadline_ts = time.time() + self.__read_timeout
|
deadline_ts = time.time() + self.__read_timeout
|
||||||
found = False
|
found = False
|
||||||
while time.time() < deadline_ts:
|
while time.time() < deadline_ts:
|
||||||
if not found:
|
|
||||||
time.sleep(self.__read_delay)
|
|
||||||
for byte in self.__xfer(b"\x00" * (4 - len(response))):
|
for byte in self.__xfer(b"\x00" * (4 - len(response))):
|
||||||
if not found:
|
if not found:
|
||||||
if byte == 0:
|
if byte != 0x33:
|
||||||
continue
|
continue
|
||||||
found = True
|
found = True
|
||||||
response.append(byte)
|
response.append(byte)
|
||||||
@ -90,18 +97,18 @@ class _SpiPhy(BasePhy):
|
|||||||
self,
|
self,
|
||||||
bus: int,
|
bus: int,
|
||||||
chip: int,
|
chip: int,
|
||||||
|
cs: bool,
|
||||||
max_freq: int,
|
max_freq: int,
|
||||||
block_usec: int,
|
block_usec: int,
|
||||||
read_timeout: float,
|
read_timeout: float,
|
||||||
read_delay: float,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
self.__bus = bus
|
self.__bus = bus
|
||||||
self.__chip = chip
|
self.__chip = chip
|
||||||
|
self.__cs = cs
|
||||||
self.__max_freq = max_freq
|
self.__max_freq = max_freq
|
||||||
self.__block_usec = block_usec
|
self.__block_usec = block_usec
|
||||||
self.__read_timeout = read_timeout
|
self.__read_timeout = read_timeout
|
||||||
self.__read_delay = read_delay
|
|
||||||
|
|
||||||
def has_device(self) -> bool:
|
def has_device(self) -> bool:
|
||||||
return os.path.exists(f"/dev/spidev{self.__bus}.{self.__chip}")
|
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
|
def connected(self) -> Generator[_SpiPhyConnection, None, None]: # type: ignore
|
||||||
with contextlib.closing(spidev.SpiDev(self.__bus, self.__chip)) as spi:
|
with contextlib.closing(spidev.SpiDev(self.__bus, self.__chip)) as spi:
|
||||||
spi.mode = 0
|
spi.mode = 0
|
||||||
|
spi.no_cs = (not self.__cs)
|
||||||
spi.max_speed_hz = self.__max_freq
|
spi.max_speed_hz = self.__max_freq
|
||||||
|
|
||||||
def xfer(data: bytes) -> bytes:
|
def xfer(data: bytes) -> bytes:
|
||||||
@ -118,36 +126,29 @@ class _SpiPhy(BasePhy):
|
|||||||
yield _SpiPhyConnection(
|
yield _SpiPhyConnection(
|
||||||
xfer=xfer,
|
xfer=xfer,
|
||||||
read_timeout=self.__read_timeout,
|
read_timeout=self.__read_timeout,
|
||||||
read_delay=self.__read_delay,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# =====
|
# =====
|
||||||
class Plugin(BaseMcuHid):
|
class Plugin(BaseMcuHid):
|
||||||
def __init__(
|
def __init__(self, **kwargs: Any) -> None:
|
||||||
self,
|
phy_kwargs: Dict = {key: kwargs.pop(key) for key in self.__get_phy_options()}
|
||||||
bus: int,
|
super().__init__(phy=_SpiPhy(**phy_kwargs), **kwargs)
|
||||||
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,
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_plugin_options(cls) -> Dict:
|
def get_plugin_options(cls) -> Dict:
|
||||||
return {
|
return {
|
||||||
"bus": Option(0, type=valid_int_f0),
|
**cls.__get_phy_options(),
|
||||||
"chip": Option(0, type=valid_int_f0),
|
|
||||||
"max_freq": Option(400000, 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(),
|
**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),
|
||||||
|
"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(0.5, type=valid_float_f01),
|
||||||
|
}
|
||||||
|
|||||||
@ -18,6 +18,7 @@ InotifyMask.UNMOUNT
|
|||||||
|
|
||||||
IpmiServer.handle_raw_request
|
IpmiServer.handle_raw_request
|
||||||
|
|
||||||
|
SpiDev.no_cs
|
||||||
SpiDev.max_speed_hz
|
SpiDev.max_speed_hz
|
||||||
|
|
||||||
_AtxApiPart.switch_power
|
_AtxApiPart.switch_power
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user