software cs

This commit is contained in:
Devaev Maxim 2020-11-12 18:33:35 +03:00
parent 55a6828039
commit 0140cba0dc
3 changed files with 50 additions and 20 deletions

View File

@ -171,8 +171,7 @@ ISR(SPI_STC_vect) {
if (spi_out[0] && spi_out_index < 4) { if (spi_out[0] && spi_out_index < 4) {
// digitalWrite(4, !digitalRead(4)); // digitalWrite(4, !digitalRead(4));
SPDR = spi_out[spi_out_index]; SPDR = spi_out[spi_out_index];
bool err = (SPSR & (1 << WCOL)); if (!(SPSR & (1 << WCOL))) {
if (!err) {
++spi_out_index; ++spi_out_index;
if (spi_out_index == 4) { if (spi_out_index == 4) {
spi_out_index = 0; spi_out_index = 0;
@ -274,12 +273,12 @@ void loop() {
} }
} }
# elif defined(CMD_SPI) # elif defined(CMD_SPI)
if (SPSR & (1 << WCOL)) { /*if (SPSR & (1 << WCOL)) {
digitalWrite(3, HIGH); digitalWrite(3, HIGH);
uint8_t _ = SPDR; uint8_t _ = SPDR;
delay(1); delay(1);
digitalWrite(3, LOW); digitalWrite(3, LOW);
} }*/
if (spiReady()) { if (spiReady()) {
sendCmdResponse(handleCmdBuffer(spi_in)); sendCmdResponse(handleCmdBuffer(spi_in));
} }

View File

@ -28,9 +28,11 @@ from typing import List
from typing import Dict from typing import Dict
from typing import Generator from typing import Generator
from typing import Callable from typing import Callable
from typing import Optional
from typing import Any from typing import Any
import spidev import spidev
import gpiod
from ...logging import get_logger from ...logging import get_logger
@ -40,6 +42,9 @@ 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_f01 from ...validators.basic import valid_float_f01
from ...validators.hw import valid_gpio_pin_optional
from ... import env
from ._mcu import BasePhyConnection from ._mcu import BasePhyConnection
from ._mcu import BasePhy from ._mcu import BasePhy
@ -92,12 +97,14 @@ class _SpiPhyConnection(BasePhyConnection):
return bytes(response) return bytes(response)
class _SpiPhy(BasePhy): class _SpiPhy(BasePhy): # pylint: disable=too-many-instance-attributes
def __init__( def __init__(
self, self,
bus: int, bus: int,
chip: int, chip: int,
cs: bool, hw_cs: bool,
sw_cs_pin: int,
cs_high: bool,
max_freq: int, max_freq: int,
block_usec: int, block_usec: int,
read_timeout: float, read_timeout: float,
@ -105,7 +112,9 @@ class _SpiPhy(BasePhy):
self.__bus = bus self.__bus = bus
self.__chip = chip self.__chip = chip
self.__cs = cs self.__hw_cs = hw_cs
self.__sw_cs_pin = sw_cs_pin
self.__cs_high = cs_high
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
@ -115,18 +124,37 @@ class _SpiPhy(BasePhy):
@contextlib.contextmanager @contextlib.contextmanager
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 self.__sw_cs_connected() as sw_cs_line:
spi.mode = 0 with contextlib.closing(spidev.SpiDev(self.__bus, self.__chip)) as spi:
spi.no_cs = (not self.__cs) spi.mode = 0
spi.max_speed_hz = self.__max_freq spi.no_cs = (not self.__hw_cs)
if self.__hw_cs:
spi.cshigh = self.__cs_high
spi.max_speed_hz = self.__max_freq
def xfer(data: bytes) -> bytes: def xfer(data: bytes) -> bytes:
return spi.xfer(data, self.__max_freq, self.__block_usec) try:
if sw_cs_line is not None:
sw_cs_line.set_value(int(self.__cs_high))
return spi.xfer(data, self.__max_freq, self.__block_usec)
finally:
if sw_cs_line is not None:
sw_cs_line.set_value(int(not self.__cs_high))
yield _SpiPhyConnection( yield _SpiPhyConnection(
xfer=xfer, xfer=xfer,
read_timeout=self.__read_timeout, read_timeout=self.__read_timeout,
) )
@contextlib.contextmanager
def __sw_cs_connected(self) -> Generator[Optional[gpiod.Line], None, None]:
if self.__sw_cs_pin > 0:
with contextlib.closing(gpiod.Chip(env.GPIO_DEVICE_PATH)) as chip:
line = chip.get_line(self.__sw_cs_pin)
line.request("kvmd::hid-mcu::sw_cs", gpiod.LINE_REQ_DIR_OUT, default_vals=[int(not self.__cs_high)])
yield line
else:
yield None
# ===== # =====
@ -145,9 +173,11 @@ class Plugin(BaseMcuHid):
@classmethod @classmethod
def __get_phy_options(cls) -> Dict: def __get_phy_options(cls) -> Dict:
return { return {
"bus": Option(0, type=valid_int_f0), "bus": Option(-1, type=valid_int_f0),
"chip": Option(0, type=valid_int_f0), "chip": Option(-1, type=valid_int_f0),
"cs": Option(False, type=valid_bool), "hw_cs": Option(False, type=valid_bool),
"sw_cs_pin": Option(-1, type=valid_gpio_pin_optional),
"cs_high": Option(False, type=valid_bool),
"max_freq": Option(200000, type=valid_int_f1), "max_freq": Option(200000, type=valid_int_f1),
"block_usec": Option(1, type=valid_int_f0), "block_usec": Option(1, type=valid_int_f0),
"read_timeout": Option(0.5, type=valid_float_f01), "read_timeout": Option(0.5, type=valid_float_f01),

View File

@ -19,6 +19,7 @@ InotifyMask.UNMOUNT
IpmiServer.handle_raw_request IpmiServer.handle_raw_request
SpiDev.no_cs SpiDev.no_cs
SpiDev.cshigh
SpiDev.max_speed_hz SpiDev.max_speed_hz
_AtxApiPart.switch_power _AtxApiPart.switch_power