Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sw spi bus: Added support for configured width and encoding #6633

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

bazarovdev
Copy link

@bazarovdev bazarovdev commented Jul 3, 2024

Adds option to work with any device/sensor unrelated to HW SPI bus width.
Implemented to work with YHCB2004 display on Geeetech A10/M/T printers that require 9-bit SPI commands.

Test results

5 bit command (less than byte)

5

12 bit command (non integer number of bytes)

12

32 bit command (standard for many sensors)

32

64 bit command (artifitially set max)

64

transmitting 20 bits 0x80f05

ff0

testing all 4 options of encoding of 0x80f05

big/little-endian
lsb/msb bit first
4 opt4

@bazarovdev bazarovdev force-pushed the work-swspiwidth-20240703 branch 2 times, most recently from 92fafa8 to 2ab93d7 Compare July 3, 2024 07:35
@bazarovdev bazarovdev marked this pull request as ready for review July 3, 2024 07:39
@bazarovdev bazarovdev changed the title sw spi bus: Support of any width (5..64 bits) and encoding (big/little-endian, lsb/msb-bit-first) sw spi bus: Added support for configured width and encoding Jul 3, 2024
Enables specifying any width (5 to 64 bits) for the SW SPI bus
and defining encoding big/little-endian and LSB/MSB bit-first.

Signed-off-by: Alexander Bazarov <[email protected]>
@nwash57
Copy link

nwash57 commented Jul 5, 2024

The code is black magic to me, but I can confirm this makes the display work on the A10T I converted to Klipper. At the very least it makes getting these junky and bug-ridden printers into a stable configuration that much easier.

Copy link

Thank you for your contribution to Klipper. Unfortunately, a reviewer has not assigned themselves to this GitHub Pull Request. All Pull Requests are reviewed before merging, and a reviewer will need to volunteer. Further information is available at: https://www.klipper3d.org/CONTRIBUTING.html

There are some steps that you can take now:

  1. Perform a self-review of your Pull Request by following the steps at: https://www.klipper3d.org/CONTRIBUTING.html#what-to-expect-in-a-review
    If you have completed a self-review, be sure to state the results of that self-review explicitly in the Pull Request comments. A reviewer is more likely to participate if the bulk of a review has already been completed.
  2. Consider opening a topic on the Klipper Discourse server to discuss this work. The Discourse server is a good place to discuss development ideas and to engage users interested in testing. Reviewers are more likely to prioritize Pull Requests with an active community of users.
  3. Consider helping out reviewers by reviewing other Klipper Pull Requests. Taking the time to perform a careful and detailed review of others work is appreciated. Regular contributors are more likely to prioritize the contributions of other regular contributors.

Unfortunately, if a reviewer does not assign themselves to this GitHub Pull Request then it will be automatically closed. If this happens, then it is a good idea to move further discussion to the Klipper Discourse server. Reviewers can reach out on that forum to let you know if they are interested and when they are available.

Best regards,
~ Your friendly GitIssueBot

PS: I'm just an automated script, not a human being.

@bazarovdev
Copy link
Author

Self review:

  1. Defects: the changes were minimized and instead of introducing new commands, added modification to spi_software_transfer() that depending on initialization treats the data instead of array of bytes as concatenated bits of specified width.
    It supports encodings big/small endian and transmittinglsb/msb bit first. So in all calls in Python the data is encoded/decoded and in C the bits are just transmitted without adding too much complexity.
    Attached the scope pictures of main tests.
  2. Impact: it makes software SPI flexible to meet any need of users. In addition, it gives option to integrate support to Geeetech A10/M/T, ender clones with mixing extruders (M=2in1out, T=3in1out) increasing user base of Klipper and potentially helping test features related to mixing.
    (Currently, most users stuck with Marlin or mainly replace stock board+display to work with Klipper. The facebook group of owners contains 6.3k users).
  3. Licensing: No new files introduced, commits signed-off.
  4. Guidelines: Tried to follow to my best understanding.
  5. Docs: PR contains update to docs related to new fields in spi_software_*section
  6. Commits: 1 commit with 1 feature.

@KevinOConnor
Copy link
Collaborator

Thanks. As high-level feedback, I am leery of making such an intricate change to a common component in support of very rare hardware. The concern is that a change to this common code could introduce a regression (either directly or via a performance degradation).

Which devices did you have in mind for this support? Is there any other way to drive these devices without requiring a full 9-bit (or other) byte order? For example, arranging to always send commands in multiples of nine 8-bit bytes.

I have not done a full code review, but I did notice that the C code on this PR introduces an arbitrary integer division (along with a modulo). Most micro-controllers do not directly support division (nor modulo) and using these operators can result in slow and bloated code being introduced by the compiler.

Cheers,
-Kevin

@bazarovdev
Copy link
Author

Thanks for the feedback.

  1. I got stuck on a problem with YHCB2004 display and, while solving it, dug into the software SPI code. The idea was that the change to make it completely generic wasn't that hard after I got what is going on. It solves my problem and might help others down the road (it took me a lot of time to understand and solve the problem, while initially it seemed just as minor change in the display driver).
  2. sending 8 commands that add up to 9 bytes might work, thanks for the idea, I will test it.
  3. I used division/mod for input checking and calculating number of chunks to avoid adding additional chunks_num parameter. But it seems, I can drop divisions and instead just track number of bits left as it sends them. And it seems, there is a bug of ambiguity for chunks less that 8 bits, so I will set lower limit to 8 bits.

Hopefully, the 8 commands solution will work, so I will be able to update #6639 without this PR (and I hope adding display driver doesn't fall in "no go zone":).
And will try to address division issues here, to make this PR more likely to be merged someday.

@bazarovdev
Copy link
Author

The proposed sending 8 commands as 9 bytes actually works.
Updated #6639

I'm not fixing this, as it is not intendent to be merged now.
For future, if somebody decides to use it, TODO:

  • limit minimal width to 8 bits (otherwise it might make mistake on number of commands encoded in byte list)
  • replace division/mod by counting actual number of commands econded as it goes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants