-
Notifications
You must be signed in to change notification settings - Fork 8.2k
rp2040: Added PIO support #44316
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
rp2040: Added PIO support #44316
Conversation
nordicjm
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not tested it but looks good!
drivers/serial/uart_rpi_pico_pio.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment/details on what's special about the magic number 3?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a byte pointer to a 32 bit register, so adding 3 gives the MSB of the register, which is denoted in the variable name. But I can document it if it's not clear enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just browsing, but yes, the 3 needs documenting. I guess there's no need to be worried about big/little endianness because the PIO is built into the soc, but if it were me I would include a comment including "BYTE_ORDER" just to be clear.
|
This code is based on the uart examples from |
|
@petejohanson would you be able to take a look? |
|
@yonsch please rebase |
|
Hi, I wanted to thank you @yonsch for this PR, it gives wide perspective about PIO usage on ZephyrOS. It's better to have PIO initiator in driver. (It's good to have consts like frequency in rp2040.dtsi) taken from : https://medium.com/geekculture/raspberry-pico-programming-with-pio-state-machines-e4610e6b0f29 |
|
@MrGreensWorkshop Thanks for your feedback. Do I understand correctly that you are proposing a generic PIO driver instead of a per peripheral one? There were a few reasons for implementing it this way:
And finally, the current implementation still gives access to PIO API, so for special cases a user can still write a custom PIO driver, as part of an out of tree Zephyr driver, or simply as part of the application. |
|
@yonsch, Actually I gave my insights from hardware driver point of view. As user point view, probably users prefer to use ready to use peripherals and I agree with you. Does anyone have any thoughts? |
I don't think you can change the current API to be compatible with #56678, as the changes would break the current implementation. #56678 cannot really coexist with The PIO parent driver in #56678 was designed just as a resource allocator/interrupt router. All child devices need to use the PIO registers directly. For example, when you allocate SMs to different devices you will need to modify some bits in some registers applicable only to those SMs. This requires atomic operations and #56678 uses these to solve that: To summarize, my approach would be to break any dependencies on external rpi code (other that the HW structs). This might prove beneficial in the long run as external SW could change and break existing implementations. |
Okay, I'm convinced.
It will break some of the implementation, but the question is if it will break an API, or at least require massive changes. For example, if we merged this PR and then you'll need to move lots of DTS around, that would be counter productive. However if you're just replacing a call to |
Added a generic driver for RaspberryPi Pico PIO. This driver is an intermediate driver for abstracting the PIO device driver from physical pin configuration. Signed-off-by: TOKITA Hiroshi <[email protected]> Signed-off-by: Yonatan Schachter <[email protected]> Signed-off-by: Ionut Catalin Pavel <[email protected]>
Implements a UART driver using PIO. Both PIOs are supported. Only polling API is supported. Only 8N1 mode is supported. Signed-off-by: Yonatan Schachter <[email protected]>
Adds PIO documentation to the rpi_pico board. Signed-off-by: Yonatan Schachter <[email protected]>
Added a sample for the rpi_pico board showing how to use the UART over PIO driver. Signed-off-by: Yonatan Schachter <[email protected]>
#56678 breaks pretty much everything on the source code side: So, technically, it's a redesign. On a diff, the only similar thing remaining is Another issue is that going with incremental merges will not really work since the UART in #56678 needs the PIO in the same PR. So, it could be an incremental review, but needs to be within a single PR. As I said in the previous comment, #56678 is not compatible with So, to summarize: |
Thanks @iocapa. Will merge this one then, and then we can follow-up with improvements. |
|
Removed DNM as the Arch WG already decided in favor of this PR |
nordicjm
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, tested it and it works, with a general serial throughput test the error rate is about 15-20% but there isn't flow control and this is a simple demo so that's acceptable.
|
|
||
| Programmable I/O (PIO) | ||
| ********************** | ||
| The RP2040 SoC comes with two PIO periherals. These are two simple |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| The RP2040 SoC comes with two PIO periherals. These are two simple | |
| The RP2040 SoC comes with two PIO peripherals. These are two simple |
| @@ -0,0 +1 @@ | |||
| # nothing here | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Query on this sample: this has both UART drivers enabled, will that cause a problem?
| static int pio_rpi_pico_init(const struct device *dev) | ||
| { | ||
| return 0; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pretty sure this can be omitted and parameter set to NULL - @gmarull ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1, can be removed
| #include <zephyr/device.h> | ||
| #include <zephyr/drivers/uart.h> | ||
|
|
||
| void main(void) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
int
A note here: we should not merge something because it comes first, but evaluate both solutions and merge the one that is better. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, all of my concerns were fixed. @yonsch Thank you for your time and effort.
There may be a better solution than this, but in my humble opinion, I think we shouldn't be waiting for those to come for months. (fist PR was made on Mar 30, 2022) Let's give people a chance to use it and give some feedback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gmarull
When there is no sm left, I don't see any point in returning EBUSY (Mount device busy); it's not busy at all, so it can't be used.
If you still want to add ENOMEM or ENOSPC, that would be a better choice.
https://docs.zephyrproject.org/latest/develop/languages/c/minimal_libc.html#c.EBUSY
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please explain why you think so?
-EBUSY "Mount device busy" is used for busy. But in this situation, the state machine is not busy. It's not available. Because it's already taken. We are not checking a hardware process to see if it's finished or not. Using busy would be confusing.
EADDRNOTAVAIL would be a better choice. Or something else like EAGAIN (No more contexts).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yonsch Since you already changed to -EBUSY, just ignore my comment.
Agreed, this is not the case here. We took this to the architecture WG, and both PRs were scrutinized. No objections were raised to start with this one and then ask @iocapa and @yonsch to bring features from #56678 in progressively. |
|
Well there were still some unresolved issues (like moving the driver under gio/swio/whatever) but I guess @iocapa can take it from here |
|
Rebased #56678 Please have a look, and let's continue the discussion there. Ionut |
Adds support for PIO for the rp2040 soc. PIO programs are not assembled by Zephyr (currently). They should instead be assembled manually and embedded in source code.
The PIO API should preferably be used to implement drivers. For example, to implement UART over the PIO, it should be implemented as a serial driver, selectable by dts. (this is my suggestion at least).
The PIO API from
pico-sdkcan still be used in application code to implement custom applications.