fphammerle / python-cc1101

Python Library & Command Line Tool to Transmit RF Signals via CC1101 Transceivers
https://pypi.org/project/cc1101/
GNU General Public License v3.0
72 stars 14 forks source link

Empirical maximum SPI speed result in a EINVAL #128

Closed matteo-briani closed 1 year ago

matteo-briani commented 1 year ago

Hello, first of all thanks for sharing this code to everyone! I have been using it in a couple of projects during a prototyping phase, and I experienced an issue in one of my hardware settings.

Description

Using an Olimex STMP157 board and a E07-1101D transceiver, the default test command printf '\x01\x02\x03' | cc1101-transmit -f 433920000 -r 1000 results in an OSError: [Errno 22] Invalid argument. Here the python traceback:

Traceback (most recent call last):
  File "/home/olimex/boh/bin/cc1101-transmit", line 8, in <module>
    sys.exit(_transmit())
  File "/home/olimex/boh/lib/python3.9/site-packages/cc1101/_cli.py", line 157, in _transmit
    with cc1101.CC1101(lock_spi_device=True) as transceiver:
  File "/home/olimex/boh/lib/python3.9/site-packages/cc1101/__init__.py", line 563, in __enter__
    self._reset()
  File "/home/olimex/boh/lib/python3.9/site-packages/cc1101/__init__.py", line 270, in _reset
    self._command_strobe(StrobeAddress.SRES)
  File "/home/olimex/boh/lib/python3.9/site-packages/cc1101/__init__.py", line 250, in _command_strobe
    response = self._spi.xfer([register | self._WRITE_SINGLE_BYTE])
OSError: [Errno 22] Invalid argument

A workaround

The standard spidev_test linux command shows the SPI fully working with a maximum speed set to 500 KHz.

Tweaking the source and modifying the max_speed_hz solves the problem. In particular, change the following line:

https://github.com/fphammerle/python-cc1101/blob/1cd90b3f28d9f131e7571e8b2d8b45fce064f178/cc1101/__init__.py#L561

into

self._spi.max_speed_hz = 500000

Questions

Am I missing something obvious? Where is the 55700 coming from?

Would it be possible to override self._spi.max_speed_hz default value during an init phase? I might be able to write a patch if it can be of any help.

fphammerle commented 1 year ago

Hi,

thanks for the detailed description of the issue you experience!

Unfortunately, I do not remember why I set max_speed_hz = 55700 in the first commit: https://github.com/fphammerle/python-cc1101/commit/e764e064fc9a73ee3e7f281438d1f21b8887a55b#diff-319c0dd5b99765f9ec51a25fd100c899d6ce5009b654bd0763090f157a791a67R36

As I commented "empirical", I most likely increased the number until I experienced some issue. However, I am unable to reproduce that at the moment:

$ pip3 show cc1101 | grep Version
Version: 2.7.3
$ printf '\x01\x02\x03' | cc1101-transmit  -f 433920000 -r 1000 
CC1101(marcstate=idle, base_frequency=433.92MHz, symbol_rate=1.00kBaud, modulation_format=ASK_OOK, sync_mode=TRANSMIT_16_MATCH_16_BITS, preamble_length=4B, sync_word=0xd391, packet_length≤255B, output_power=(0xc6,0))
transmitting 0x03010203 (b'\x03\x01\x02\x03')
$ sed -i 's/55700 .*/500000/' ~/.local/lib/python3.9/site-packages/cc1101/__init__.py
$ grep -r max_speed_hz ~/.local/lib/python3.9/site-packages/cc1101/__init__.py 
            self._spi.max_speed_hz = 500000
$ printf '\x01\x02\x03' | cc1101-transmit  -f 433920000 -r 1000
CC1101(marcstate=idle, base_frequency=433.92MHz, symbol_rate=1.00kBaud, modulation_format=ASK_OOK, sync_mode=TRANSMIT_16_MATCH_16_BITS, preamble_length=4B, sync_word=0xd391, packet_length≤255B, output_power=(0xc6,0))
transmitting 0x03010203 (b'\x03\x01\x02\x03')

"max_speed_hz = 500000" seems to work fine.

I will capture the transmitted signal and check whether I can find any differences (which I do not expect).

fphammerle commented 1 year ago

20230429T141641

printf '\x01\x02\x03' | cc1101-transmit -f 433920000 -r 1000

self._spi.max_speed_hz = 55700: 20230429T141456_spi_max_speed_55700Hz

self._spi.max_speed_hz = 500000: 20230429T141611_spi_max_speed_500000Hz

Looks good! However, I worry that changing the hard-coded value might break the setup for some users.

Would it be possible to override self._spi.max_speed_hz default value during an init phase? I might be able to write a patch if it can be of any help.

Would changing the max speed via a new optional parameter in CC1101.__init__ (e.g. spi_max_speed_hz keeping current default 55700 Hz) work for you? If yes, could you create a patch?

matteo-briani commented 1 year ago

Thanks for your quick reply! That will work and yes, I can cook a patch.

fphammerle commented 1 year ago

Great, thank you!

matteo-briani commented 1 year ago

Tracked by PR #129

fphammerle commented 1 year ago

released in v3.0.0: https://pypi.org/project/cc1101/3.0.0/#files thanks!