Closed Darin755 closed 2 months ago
There is a GPIO interface in Linux which is used at the moment mostly for SC129 and Z80 PIO devices on 8bit systems. So you could add it.
See CONFIG_DEV_GPIO Kernel/include/gpio.h Kernel/platform-rc2014/devgpio.c
for an example. It might need extending for the Pico as I guess the Pico has rather more functionality than simple on/off and directionality. That should be fine though as tiny Z80 machines can just not implement them.
I'm fairly new at this and doing something this complex is quite the learning curve. I don't mind giving it a shot but please keep in mind the quality of my code may not be as high as someone with more experience.
The first one is a byte sized mask of pins that are controllable (so if there were 8 gpio pins it would be 0xFF) - the SC129 entries are wrong. I've just fixed that!
The second is a group which is used to group together pins whose properties have to change together. On the Z80 PIO there are none but on the 82C55 for example 4 pins are either all read or all write. If it's all independent then you don't need group numbers so they can all be zero
The third is the flags - right now just bit config (can set direction R or W per bit) or GRP_CONFIG - everything with the same group number changes direction at once
wmask is the mask of writable bits (so if you set it to 0 then it's all read).
wdata is the current write value
imask isn't yet used but the idea was for interrupt bits so you could block on the GPIO eventually.
name[] is a name with meaning to the platform - so you can work out in software what is what.
So in the example the Z80 PIO ports are configurable directionally, but the SC129 and console switches are fixed direction.
This seems like is a bit over my head for the time being. Anyone reading this is more than welcome to work on this but I think I'll wait until I have a little more practice in C
You can control them using fforth. I created these forth words for that:
: PIN_OE DUP 8 * 40014004 + 5 SWAP ! 1 SWAP LSHIFT D0000024 ! ; : PIN_TOGGLE 1 SWAP LSHIFT D000001C ! ; : PIN_HIGH 1 SWAP LSHIFT D0000014 ! ; : PIN_LOW 1 SWAP LSHIFT D0000018 ! ;
All need to be run in hex mode, so issue HEX word before their stack operation is as follows: ( n -- ) Where n is a GPIO pin number you want to operate on. PIN_OE - switch pin under software control and enable it for output PIN_TOGGLE - toggle output of the pin from high to low or from low to high PIN_HIGH, PIN_LOW - self explanatory
Based on the info from EtchedPixels in the answer above, I have made a small change to use the gpio interface with the pico: https://github.com/napicella/FUZIX/commit/44411276edbd01f841ab894f54ba6c7243bb8e68 It's an old issue, but maybe it's useful for someone.
The picoctl binary can be used to turn on/off the pins on the pico, e.g.:
picoctl 7 1
which turns pin 7 on.
Nice. You appear to return 0 on an invalid or unsupported case though rather than -1 though ? Otherwise looks good and would be nice to add.
Cool. I hadn't originally planned to send a PR because my experience with the project is limited to the few hours I spent making the change. However, your comment encouraged me to go ahead and submit it :)
Is there any plans to add gpio access in userland? I think it would be really useful to enable to access some of the low level hardware from a program running in userland.
I think the easiest way to do this is to create simple character devices that can can be toggled with a 1 or a 0.