-
Notifications
You must be signed in to change notification settings - Fork 0
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
A common high-level API for GPIO handling? #1
Comments
Hi! Thanks for the suggestion - I've experimented with this a little bit a while ago, using register definitions generated from an SVD with https://github.com/Seelengrab/DeviceDefinitions.jl. The main thing to do with those register definitions is to create a struct representing the device, and use that for configuration & data transfor ( There are unfortunately a few difficulties here (not unsolvable, mostly annoyances):
In general, I very much subscribe to the philosophy of having a struct representing the device, and manipulating that in favor of just calling some magic functions (as is usually done in C). I find that this leads to more ergonomic APIs that are harder to misuse, because you can (in principle) check that what the user is intending to do is actually safe & makes sense to do with the current state of the device. Hope that helps! :) |
Wow, generating a chip's driver from the SVD file sounds like a super powerful idea. I was more thinking about something more on the high-level side of things (for example the MCP2221 chip is not a microcontroller, it's a USB to I2C/UART converter that happens to have GPIOs), in order to have a roughly unified interface for that kind of things. We could have something that's quite permissive. On the user-side it could look like (obviously very inspired from the Arduino API, something for interrupts should also be added I guess) function pinmode(device, pin) end
function pinmode!(device, pin, mode) end
function Base.read(device, pin) end
function Base.write(device, pin data) end where the
The interface could also provide a few helpers to the implementer of the device driver to signal capabilities of the device (in the style of what Tables.jl does) and simplify implementations: function iscompatible(device, pin, mode) end
function isreadable(device, pin) end
function iswriteable(device, pin) end
function hasinterrupts(device, pin) end
function write(device, pin, pinmode, data) end # or something smarter to find a type-stable way to allow writing small functions for writing/reading from a pin that's in `pinmode`. Something similar could probably be devised for I2C, UART, etc., maybe drawing inspiration from CMSIS? For the method ambiguities coming from |
It's not going to generate the entire driver for you (that would be a bit much, considering how many variations of chips there are), but it does give you register definitions and an API for accessing/setting their state.
I definitely want to have a higher level API at some point, and what you're proposing looks similar to what I've done for the RP2040. Like I said though, I just haven't gotten further in designing this because of issues with getting the chip to initialize properly. That being said, if I were to implement this multi-function GPIO from scratch, I'd attempt more of an RAII-style interface (kinda like what I describe here), where setting the GPIO function invalidates the previous state of the GPIO, passing a new token object into the following code. I'd have to experiment a bit, since the API would end up very nested, due to all of the involved function calls. Maybe a macro to delineate the thunk would be more appropriate? The reasoning behind this is that it would help prevent trying to write the wrong kind of data when the GPIO is using a function that's different from what is expected, which would help prevent bugs.
Some of these should be fairly trivial to implement, though things like
Yes, that's the entire reason :)
Subtyping |
That's interesting. I'll have to study a bit more, but I have a few atmegas and attinys at home so I think I'll try experimenting a bit in the coming weeks/months on that depending on how much free time I can spend on it. Do you mind if I come back to ask for your opinion after a few trials? It seems you have thought about it a lot. About the |
Sure - actual experiments with code are bound to be more fruitful than whatever I could come up with theoretically :) One problem I can foresee for example is lots of dynamic dispatches messing up the compilation, since that bit me in the past as well. |
Hi there, I'm starting to write a high-level API for the MCP2221 chip (I already have the low-level API working). Some of this involves GPIO handling, that is going to be very similar to what's done here (setting them as input/output, querying their current state, maybe analog IO, etc...). What do you think about specifying a common abstract API for this? Do you know any other projects that may be interesting to add to such a kind of API?
The text was updated successfully, but these errors were encountered: