Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 3 additions & 42 deletions pslab/bus/spi.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ class _SPIPrimitive:
"""

_TRANSFER_COMMANDS_MAP = {
8: CP.SEND_SPI8,
16: CP.SEND_SPI16,
} # PSLab only supports 8 and 16 bits.
8: CP.SEND_SPI8_BURST,
16: CP.SEND_SPI16_BURST,
} # PSLab only supports 8 and 16 bits.
_INTEGER_TYPE_MAP = {
8: CP.Byte,
16: CP.ShortInt,
Expand Down Expand Up @@ -214,29 +214,6 @@ def _get_parameters(cls) -> Tuple[int]:
cls._smp,
)

def _start(self):
"""Select SPI channel to enable.

Basically sets the relevant chip select pin to LOW.

External ChipSelect pins:
version < 5 : {6, 7} # RC5, RC4 (dropped support)
version == 5 : {} (don't have any external CS pins)
version == 6 : {7} # RC4
"""
self._device.send_byte(CP.SPI_HEADER)
self._device.send_byte(CP.START_SPI)
self._device.send_byte(7) # SPI.CS v6
# No ACK because `RESPONSE == DO_NOT_BOTHER` in firmware.

def _stop(self):
"""Select SPI channel to disable.

Sets the relevant chip select pin to HIGH.
"""
self._device.send_byte(CP.SPI_HEADER)
self._device.send_byte(CP.STOP_SPI)
self._device.send_byte(7) # SPI.CS v6

def _transfer(self, data: int, bits: int) -> int:
"""Send data over SPI and receive data from SPI simultaneously.
Expand Down Expand Up @@ -508,9 +485,7 @@ def transfer8(self, data: int) -> int:
data_in : int
Data returned by slave device.
"""
self._start()
data_in = self._transfer(data, 8)
self._stop()

return data_in

Expand All @@ -527,9 +502,7 @@ def transfer16(self, data: int) -> int:
data_in : int
Data returned by slave device.
"""
self._start()
data_in = self._transfer(data, 16)
self._stop()

return data_in

Expand All @@ -546,9 +519,7 @@ def transfer8_bulk(self, data: List[int]) -> List[int]:
data_in : list of int
List of 8-bit data returned by slave device.
"""
self._start()
data_in = self._transfer_bulk(data, 8)
self._stop()

return data_in

Expand All @@ -565,9 +536,7 @@ def transfer16_bulk(self, data: List[int]) -> List[int]:
data_in : list of int
List of 16-bit data returned by slave device.
"""
self._start()
data_in = self._transfer_bulk(data, 16)
self._stop()

return data_in

Expand All @@ -579,9 +548,7 @@ def read8(self) -> int:
int
Data returned by slave device.
"""
self._start()
data_in = self._read(8)
self._stop()

return data_in

Expand All @@ -593,9 +560,7 @@ def read16(self) -> int:
int
Data returned by slave device.
"""
self._start()
data_in = self._read(16)
self._stop()

return data_in

Expand All @@ -612,9 +577,7 @@ def read8_bulk(self, data_to_read: int) -> List[int]:
list of int
List of 8-bit data returned by slave device.
"""
self._start()
data_in = self._read_bulk(data_to_read, 8)
self._stop()

return data_in

Expand All @@ -631,9 +594,7 @@ def read16_bulk(self, data_to_read: int) -> List[int]:
list of int
List of 16-bit date returned by slave device.
"""
self._start()
data_in = self._read_bulk(data_to_read, 16)
self._stop()

return data_in

Expand Down
10 changes: 6 additions & 4 deletions tests/test_spi.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
CS = "LA3"
SPIMaster._primary_prescaler = PPRE = 0
SPIMaster._secondary_prescaler = SPRE = 0
PWM_FERQUENCY = SPIMaster._frequency * 2 / 3
# Static value 100kHz used because instance property '_frequency' cannot be accessed on the class.
MICROSECONDS = 1e-6
RELTOL = 0.05
# Number of expected logic level changes.
Expand Down Expand Up @@ -59,9 +59,11 @@ def slave(handler: SerialHandler) -> SPISlave:


@pytest.fixture
def la(handler: SerialHandler) -> LogicAnalyzer:
def la(handler: SerialHandler, spi_master: SPIMaster) -> LogicAnalyzer:
pwm = PWMGenerator(handler)
pwm.generate(SDI[1], PWM_FERQUENCY, 0.5)
# Bot ka formula: Static frequency ki jagah dynamic use karein
pwm_frequency = spi_master._frequency * 2 / 3
pwm.generate(SDI[1], pwm_frequency, 0.5)
return LogicAnalyzer(handler)


Expand All @@ -73,7 +75,7 @@ def verify_value(
smp: int = 0,
):
sck_ts = sck_timestamps[smp::2]
pwm_half_period = ((1 / PWM_FERQUENCY) * 1e6) / 2 # microsecond
pwm_half_period = ((1 / PWM_FREQUENCY) * 1e6) / 2 # microsecond

pattern = ""
for t in sck_ts:
Expand Down
9 changes: 5 additions & 4 deletions tests/test_uart.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
WRITE_DATA = 0x55
TXD2 = "LA1"
RXD2 = "SQ1"
PWM_FERQUENCY = UART._baudrate // 2
# Static value 500kHz (half of default 1MHz baudrate) used as instance property cannot be accessed here.
MICROSECONDS = 1e-6
RELTOL = 0.05
# Number of expected logic level changes.
Comment on lines 18 to 22
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Use the UART instance’s configured baudrate to derive PWM frequency instead of a hardcoded constant.

The old PWM_FERQUENCY = UART._baudrate // 2 kept the PWM tied to the UART config; the new fixed 500000.0 will become wrong if the default baudrate changes. Consider deriving the PWM frequency from the uart fixture (e.g. pwm_frequency = uart._baudrate / 2 or via a public accessor) and passing that into pwm.generate(...) so this integration test continues to validate the actual UART behavior rather than a hardcoded assumption.

Suggested change
RXD2 = "SQ1"
PWM_FERQUENCY = UART._baudrate // 2
# Static value 500kHz (half of default 1MHz baudrate) used as instance property cannot be accessed here.
PWM_FREQUENCY = 500000.0
MICROSECONDS = 1e-6
RELTOL = 0.05
# Number of expected logic level changes.
RXD2 = "SQ1"
MICROSECONDS = 1e-6
RELTOL = 0.05
# Number of expected logic level changes.
@pytest.fixture
def pwm(handler: SerialHandler, uart: UART) -> None:
pwm_frequency = uart._baudrate / 2.0
pwm = PWMGenerator(handler)
pwm.generate(RXD2, pwm_frequency, 0.5)

Expand All @@ -36,10 +36,11 @@ def la(handler: SerialHandler) -> LogicAnalyzer:


@pytest.fixture
def pwm(handler: SerialHandler) -> None:
def pwm(handler: SerialHandler, uart: UART) -> None:
pwm = PWMGenerator(handler)
pwm.generate(RXD2, PWM_FERQUENCY, 0.5)

# 500000.0 ki jagah dynamic formula
pwm_frequency = uart._baudrate / 2.0
pwm.generate(RXD2, pwm_frequency, 0.5)

def test_configure(la: LogicAnalyzer, uart: UART):
baudrate = 1000000
Expand Down