Skip to content

Conversation

@ThreeEights
Copy link
Contributor

Add fundamental feature support for RP2040 PIO SPI peripherals. This commit implements synchronous transfer with 8-bit MSB format. Using PIO allows any GPIO pins to be assigned the roles of CS, CLK, MOSI, and MISO.

Optional features not implemented yet:

  • Interrupt based transfer
  • DMA transfer
  • Slave mode
  • Varying word size
  • 3-wire SPI support
  • LSB-first

@zephyrbot zephyrbot added area: Devicetree Binding PR modifies or adds a Device Tree binding area: SPI SPI bus platform: Raspberry Pi Pico Raspberry Pi Pico (RPi Pico) labels Jul 14, 2023
@zephyrbot zephyrbot requested review from galak, soburi and teburd July 14, 2023 15:11
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Hello @ThreeEights, and thank you very much for your first pull request to the Zephyr project!

A project maintainer just triggered our CI pipeline to run it against your PR and ensure it's compliant and doesn't cause any issues. You might want to take this opportunity to review the project's Contributor Expectations and make any updates to your pull request if necessary. 😊

@ThreeEights
Copy link
Contributor Author

I have a sample based on the zephyr/samples/sensor/bme280 sample that demonstrates using the PIO SPI driver. I thought that ought to be a separate commit, but that requires approval of this commit first. One option is to create a new samples/boards/rpi_pico/spi_pio sample, though the only change is the addition of the rpi_pico.overlay and updating the prj.cfg.
The other option is to just update the existing sample with the .overlay. Please advise on the best steps to include sample code.

@carlescufi carlescufi requested a review from anangl July 14, 2023 16:12
@carlescufi
Copy link
Member

@ThreeEights I am curious, why PIO instead of using the Pico's native SPI IP? Regarding your sample questions, @yonsch should be able to answer that.

@ThreeEights
Copy link
Contributor Author

@carlescufi - There are 3 main reasons for adding PIO SPI support, in addition to the two built-in SPI devices:

  1. Any arrangement of GPIO pins can be used instead of the pre-defined pin assignments.
  2. More than 2 SPI devices can be supported, up to 4.
  3. But the biggest reason is that SPI support through PIO is required to work with the CYW43439 chip on the Raspberry Pi Pico W. The hard-wired configuration on that board is not supported by the built-in SPI blocks.

@ThreeEights
Copy link
Contributor Author

@iocapa - Would you be willing to join the review for this pull request?
Thanks,
Steve

@ThreeEights
Copy link
Contributor Author

@fabiobaltieri - I saw you triggered a re-run of the Coding Guidelines checks, but that failed due to apt-get not being able to access the Ubuntu repositories. Is there a way I can restart the job, or do I need assistance from the build team?

Thanks,
Steve

@fabiobaltieri
Copy link
Member

@fabiobaltieri - I saw you triggered a re-run of the Coding Guidelines checks, but that failed due to apt-get not being able to access the Ubuntu repositories. Is there a way I can restart the job, or do I need assistance from the build team?

Hey, I retried it again, not sure what level of permissions you need to retry the individual checks but you can always do a dummy git commit --amend and push force again to restart the checks. That'll lose the approvals, but if you don't have any that's fine, if you have some I guess ask the reviewers (or #pr-help on Discord). Good call poking me on it, I wasn't tracking this one.

@fabiobaltieri
Copy link
Member

Hey while we are at it...

But the biggest reason is that SPI support through PIO is required to work with the CYW43439 chip on the Raspberry Pi Pico W. The hard-wired configuration on that board is not supported by the built-in SPI blocks.

Does this actually work on the pico W? Thought it was some odd single-wire SPI-ish thing.

Comment on lines 63 to 74
Copy link
Member

Choose a reason for hiding this comment

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

Is it cannot obtain frequencies from clock-control?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@soburi - clock-control is not supported on the Raspberry Pi Pico (or Pico W). Those boards use a fixed clock. However, looking back at this, it makes more sense to just use the clock frequency from the devicetree, so I've updated those functions to use that instead of calling into the Pico SDK and pushed the change to GitHub. Thanks for pointing this out.

@ThreeEights
Copy link
Contributor Author

@fabiobaltieri - Thanks! That run completed successfully.

You asked:

Does this actually work on the pico W? Thought it was some odd single-wire SPI-ish thing.

Not yet. This is a work in progress. I wanted to get this baseline out there for review while adding the other pieces needed for the Pico W.

@ThreeEights
Copy link
Contributor Author

@soburi - Thanks for the pointer. Since clock-control didn't appear in any of the SPI drivers I was using for references, I didn't know about it. (There are so many parts of Zephyr I don't know about!) I'll try getting the system clock speed through the API and, if that succeeds, I'll push an update.

@ThreeEights ThreeEights force-pushed the rpi-pico-spi-pio branch 2 times, most recently from 0a41457 to bede792 Compare July 19, 2023 13:53
@yonsch
Copy link
Contributor

yonsch commented Jul 19, 2023

@ThreeEights Thanks for this PR, I will take a look later. In the meantime:

But the biggest reason is that SPI support through PIO is required to work with the CYW43439 chip on the Raspberry Pi Pico W. The hard-wired configuration on that board is not supported by the built-in SPI blocks.

The SPI used for the wifi module is a special one wire version of SPI, which I haven't looked at thoroughly enough to say how different it is from normal SPI. It may be similar enough to share code with notmal SPI, but not necessarily so.

In any case, there's another use for a PIO SPI - the PL022 SPI peripheral only supports MSB first communication. The only way to add LSB first SPI is via PIO. So I think any PIO implementation of SPI should support both.

@ThreeEights
Copy link
Contributor Author

@yonsch - Thanks. So far, other than needing 3-wire support, it looks like the CYW43439 SPI is pretty conventional. And LSB support is on my longer list of features to add, though that will be a number of pull requests in the future. For now, I wanted to get this first version of the driver reviewed while I add the additional features needed to support the Pico W.

@ThreeEights
Copy link
Contributor Author

@yonsch - Turns out supporting LSB first just involves flipping one bit in a control register. Do you know of any (inexpensive, readily acquired) peripherals that use SPI in LSB mode? Changing the driver is simple, but I don't want to push a change without being able to test it.

Thanks,
Steve

@yonsch
Copy link
Contributor

yonsch commented Jul 24, 2023

@yonsch - Turns out supporting LSB first just involves flipping one bit in a control register. Do you know of any (inexpensive, readily acquired) peripherals that use SPI in LSB mode? Changing the driver is simple, but I don't want to push a change without being able to test it.

Thanks,
Steve

I think @petejohanson has a keyboard with LSB first SPI

@petejohanson
Copy link
Contributor

Adafruit sells sharp memory display breakouts that use the ls0xx driver and are LSB: https://github.com/zephyrproject-rtos/zephyr/blob/main/drivers/display/ls0xx.c#L306

https://www.adafruit.com/product/3502

Can often be found on Mouser/DigiKey too.

@nashif nashif assigned yonsch and unassigned tbursztyka Aug 9, 2023
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this not handled by pinctrl?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Turns out you're right - it IS handled by pinctrl. That code is redundant; I deleted it.

@fabiobaltieri fabiobaltieri removed the DNM This PR should not be merged (Do Not Merge) label Aug 10, 2023
@ThreeEights
Copy link
Contributor Author

@soburi @fabiobaltieri @yonsch - Yet another update to incorporate review comments from @yonsch. Can someone restart the workflows now that the git conflicts have been resolved?

@ThreeEights ThreeEights requested a review from yonsch August 11, 2023 13:16
@ThreeEights ThreeEights force-pushed the rpi-pico-spi-pio branch 4 times, most recently from b8e6563 to 5fec1a6 Compare August 11, 2023 20:22
@ThreeEights
Copy link
Contributor Author

@yonsch - Can you please take a look at my changes and let me know if there's anything else required?
@soburi @fabiobaltieri - Can you please review the latest changes?
Thanks!

fabiobaltieri
fabiobaltieri previously approved these changes Aug 18, 2023
soburi
soburi previously approved these changes Aug 18, 2023
@ThreeEights
Copy link
Contributor Author

@yonsch - Could you please review the changes made in response to your review comments? Thanks!

@ThreeEights ThreeEights dismissed stale reviews from soburi and fabiobaltieri via 0f1cb89 August 28, 2023 20:46
@ThreeEights
Copy link
Contributor Author

@yonsch - I'd like to complete this pull request, preferably before another merge conflict shows up. The last response was over 2 weeks ago. This driver makes minimal use of zephyr/drivers/misc/pio_rpi_pico, so it should be possible to quickly adapt to any changes in #56678. I'm going to ask dev-review to look at this PR and get their recommendation.

Copy link
Contributor

@yonsch yonsch left a comment

Choose a reason for hiding this comment

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

This seems to need a rebase but otherwise looks good

Add fundamental feature support for RP2040 PIO SPI peripherals.
This commit implements synchronous transfer with 8-bit MSB
format.  Using PIO allows any GPIO pins to be assigned the roles
of CS, CLK, MOSI, and MISO.

Optional features not implemented yet:

  - Interrupt based transfer
  - DMA transfer
  - Slave mode
  - Varying word size
  - 3-wire SPI support
  - LSB-first

Updated in response to review comments.
Further updates from second round of review.
Rename spi_pico_pio.c source to match zephyr/MAINTAINERS.yml
Remove unnecessary initialization code.
Resolve merge conflicts

Signed-off-by: Steve Boylan <[email protected]>
@carlescufi carlescufi merged commit 85cbc7a into zephyrproject-rtos:main Sep 1, 2023
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Hi @ThreeEights!
Congratulations on getting your very first Zephyr pull request merged 🎉🥳. This is a fantastic achievement, and we're thrilled to have you as part of our community!

To celebrate this milestone and showcase your contribution, we'd love to award you the Zephyr Technical Contributor badge. If you're interested, please claim your badge by filling out this form: Claim Your Zephyr Badge.

Thank you for your valuable input, and we look forward to seeing more of your contributions in the future! 🪁

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

Labels

area: Devicetree Binding PR modifies or adds a Device Tree binding area: SPI SPI bus platform: Raspberry Pi Pico Raspberry Pi Pico (RPi Pico)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants