Closed michieltjampens closed 3 months ago
This should be a matter of creating a board definition file for this SBC. I've created one that might work based on the information here. This file needs to be in a folder named boarddefs
that is on your classpath. The file needs to be named as per the contents of the /proc/device-tree/compatible
file:
cat -v /proc/device-tree/compatible
For example, the boarddef for radxa,rock-4c-plus
is radxa_rockpi-4c-plus.txt
.
Thanks, I'll give that a try. Used the gpio bit before on a imx7 based board and didn't have to create such file, so didn't in think in that route. For testing i'm using a Raxda Rock pi S0. (final usage will be a custom sbc)
The code in this space is quite convoluted given the number of scenarios.
If there is no boarddef file, the DefaultDeviceFactory scans the gpio chips and line offsets and looks for lines named "GPIOnn" and automatically configures them.
You should be able to provision a GPIO using a PinInfo instance rather than GPIO number - DigitalInputDevice.builder(pininfo).build()
. You should be able to access the relevant PinInfo object by using the getByChipAndLineOffset
method on BoardPinInfo.
I'd be keen to hear how you get on with these options.
Well part of trying before this issue creation was looking into how to create those PinInfo objects, but the dead links made it hard to understand (hence the other issue created). Started altering the provided txt to suite the s0.
That cat returns: radxa,rock-s0^@rockchip,rk3308^@
Based on the filename you gave as example, so file should be ´raxda_rock-s0.txt´ ?
Apologies about that - the javadoc links should now be corrected. I do need to refine the documentation in this area, i.e. when there is no official support for a board. Unfortunately I tend to test on known boards.
Yes - that is the correct filename.
You can't be expected to test on all know hardware. I also might have be overlooking something, but just a simple 'getting started' would be nice. As in just short sample code to connect to a gpio or i2c bus.
Because I have been using this lib since 1.0.0 (maybe earlier, but didn't keep track before) and either the way to use it changed or I probably used it wrong from the start. Never used the 'builder' api and recently this started giving issues. Compared my code to one of the implementations of a device to figure out how the builder is used. Now the i2c is functional again.
Great that you're a long-time user and hear your feedback. Comments on any gaps in the documentation at diozero.com would be appreciated. Intended key pages include:
Key significant changes have been to steer users towards the builder APIs are the constructors were getting too complicated (but are still there) plus additional options for detecting and provisioning pins using the gpio chardev interface.
Always appreciate feedback and contributions.
Is this the correct way of using BoardPinInfo? Just trying to scan for available pins... It doesn't work, but not sure if i'm using the lib wrong or it's hardware related. Tried on both the raxda and a stm32mp151.
public static String checkGPIOS(){
var join = new StringJoiner("\r\n");
int cnt=0;
join.add("Trying boardpin info with factory: "+DeviceFactoryHelper.getNativeDeviceFactory());
var bpi = DeviceFactoryHelper.getNativeDeviceFactory().getBoardPinInfo();
join.add("Pins mapped: "+bpi.getGpios().size());
for( int chip=0;chip<4;chip++) {
for( int line=0;line<32;line++) {
var pin = bpi.getByChipAndLineOffset(chip,line);
if (pin.isPresent()) {
join.add("Found pin: " + chip+" "+line);
cnt++;
try( var device = DigitalInputDevice.Builder.builder(pin.get()).build();) {
join.add("Could build gpio -> "+device.toString());
cnt++;
}catch( com.diozero.api.NoSuchDeviceException e){
Logger.error(e);
}
}
}
}
join.add("Found "+cnt+" pins, while checking 4 chips, each with 32 lines.");
return join.toString();
}
Given that I didn't get any progress with the above, I've tried to get it to read the boarddefs file. Added is as a resource to the jar inside boarddefs, but somehow doesn't find it.
Next up was just adding it to resource root. First altered GenericLinuxArmBoardInfo to get some more feedback and then called the loadBoardPinInfoDefinition directly. That read the file fine.
Odd thing is that calling getGpios().size() results in 26 but iterating through it with getByChipAndLineOffset results in 28... Haven't checked yet which ones are missing/added. Nor if this actually reads the states properly etc.
My classpath is the jar file, so any boarddefs need to be added as resouce. Might be handy to have a method in the GenericLinuxArmBoardInfo that allows the boarddefs to be 'anywhere' on the local storage. Or make loadChipMapping etc protected instead of private, that way the user could make their own version of loadBoardPinInfoDefinition without having to copy those.
With this code on a Raspberry Pi CM4:
public class GpioChardev {
public static void main(String[] args) throws IOException {
final BoardPinInfo bpi = DeviceFactoryHelper.getNativeDeviceFactory().getBoardPinInfo();
Files.list(Path.of("/dev")).filter(path -> path.getFileName().toString().startsWith("gpiochip"))
.forEach(path -> testLines(bpi, path));
}
private static void testLines(BoardPinInfo bpi, Path gpioChipPath) {
int chip_num = Integer.parseInt(gpioChipPath.getFileName().toString().replace("gpiochip", ""));
try (final GpioChip gpio_chip = GpioChip.openChip(chip_num)) {
if (gpio_chip == null) {
Logger.error("Failed to open chip {}", Integer.valueOf(chip_num));
return;
}
for (GpioLine line : gpio_chip.getLines()) {
try {
final PinInfo pin_info = bpi.getByChipAndLineOffsetOrThrow(gpio_chip.getChipId(), line.getOffset());
final DigitalInputDevice did = DigitalInputDevice.Builder.builder(pin_info).build();
Logger.info("Provisioned digital input device {}-{}, value: {}",
Integer.valueOf(gpio_chip.getChipId()), Integer.valueOf(line.getOffset()),
Boolean.valueOf(did.getValue()));
} catch (Throwable t) {
Logger.info("Unable to provision digital input device {}-{}: {}",
Integer.valueOf(gpio_chip.getChipId()), Integer.valueOf(line.getOffset()), t);
}
line.close();
}
}
}
}
I get this output:
10:31:11.622 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 1-0: com.diozero.api.InvalidModeException: Invalid mode (digital input) for pin PinInfo [keyPrefix=GPIO, header=P5, deviceNumber=54, physicalPin=0, name=BT_ON, chip=1, lineOffset=0, modes=[]]
10:31:11.635 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 1-1: com.diozero.api.InvalidModeException: Invalid mode (digital input) for pin PinInfo [keyPrefix=GPIO, header=P5, deviceNumber=55, physicalPin=1, name=WL_ON, chip=1, lineOffset=1, modes=[]]
10:31:11.636 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 1-2: com.diozero.api.InvalidModeException: Invalid mode (digital input) for pin PinInfo [keyPrefix=GPIO, header=P5, deviceNumber=56, physicalPin=2, name=PWR_LED_OFF, chip=1, lineOffset=2, modes=[]]
10:31:11.637 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 1-3: com.diozero.api.InvalidModeException: Invalid mode (digital input) for pin PinInfo [keyPrefix=GPIO, header=P5, deviceNumber=57, physicalPin=3, name=ANT1, chip=1, lineOffset=3, modes=[]]
10:31:11.637 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 1-4: com.diozero.api.InvalidModeException: Invalid mode (digital input) for pin PinInfo [keyPrefix=GPIO, header=P5, deviceNumber=58, physicalPin=4, name=VDD_SD_IO_SEL, chip=1, lineOffset=4, modes=[]]
10:31:11.638 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 1-5: com.diozero.api.InvalidModeException: Invalid mode (digital input) for pin PinInfo [keyPrefix=GPIO, header=P5, deviceNumber=59, physicalPin=5, name=CAM_GPIO, chip=1, lineOffset=5, modes=[]]
10:31:11.639 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 1-6: com.diozero.api.InvalidModeException: Invalid mode (digital input) for pin PinInfo [keyPrefix=GPIO, header=P5, deviceNumber=60, physicalPin=6, name=SD_PWR_ON, chip=1, lineOffset=6, modes=[]]
10:31:11.640 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 1-7: com.diozero.api.InvalidModeException: Invalid mode (digital input) for pin PinInfo [keyPrefix=GPIO, header=P5, deviceNumber=61, physicalPin=7, name=ANT2, chip=1, lineOffset=7, modes=[]]
10:31:11.646 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-0, value: true
10:31:11.647 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-1, value: true
10:31:11.648 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-2, value: true
10:31:11.649 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-3, value: true
10:31:11.650 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-4, value: true
10:31:11.650 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-5, value: true
10:31:11.651 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-6, value: true
Error setting line event: Device or resource busy
10:31:11.653 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-7: com.diozero.api.RuntimeIOException: Error in provisionGpioInputDevice: -16
Error setting line event: Device or resource busy
10:31:11.654 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-8: com.diozero.api.RuntimeIOException: Error in provisionGpioInputDevice: -16
10:31:11.654 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-9, value: true
10:31:11.655 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-10, value: true
10:31:11.656 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-11, value: true
10:31:11.657 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-12, value: true
10:31:11.658 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-13, value: true
10:31:11.659 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-14, value: true
10:31:11.660 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-15, value: true
10:31:11.660 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-16, value: true
10:31:11.661 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-17, value: true
10:31:11.662 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-18, value: true
10:31:11.663 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-19, value: true
10:31:11.664 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-20, value: true
10:31:11.665 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-21, value: true
10:31:11.665 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-22, value: true
10:31:11.666 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-23, value: true
10:31:11.667 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-24, value: true
10:31:11.668 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-25, value: true
10:31:11.669 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-26, value: true
10:31:11.670 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Provisioned digital input device 0-27, value: true
10:31:11.678 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-28: com.diozero.api.NoSuchDeviceException: No such device #0:28
10:31:11.678 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-29: com.diozero.api.NoSuchDeviceException: No such device #0:29
10:31:11.679 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-30: com.diozero.api.NoSuchDeviceException: No such device #0:30
10:31:11.680 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-31: com.diozero.api.NoSuchDeviceException: No such device #0:31
10:31:11.680 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-32: com.diozero.api.NoSuchDeviceException: No such device #0:32
10:31:11.681 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-33: com.diozero.api.NoSuchDeviceException: No such device #0:33
10:31:11.681 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-34: com.diozero.api.NoSuchDeviceException: No such device #0:34
10:31:11.682 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-35: com.diozero.api.NoSuchDeviceException: No such device #0:35
10:31:11.682 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-36: com.diozero.api.NoSuchDeviceException: No such device #0:36
10:31:11.683 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-37: com.diozero.api.NoSuchDeviceException: No such device #0:37
10:31:11.683 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-38: com.diozero.api.NoSuchDeviceException: No such device #0:38
10:31:11.683 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-39: com.diozero.api.NoSuchDeviceException: No such device #0:39
10:31:11.684 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-40: com.diozero.api.NoSuchDeviceException: No such device #0:40
10:31:11.684 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-41: com.diozero.api.NoSuchDeviceException: No such device #0:41
10:31:11.685 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-42: com.diozero.api.NoSuchDeviceException: No such device #0:42
10:31:11.685 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-43: com.diozero.api.NoSuchDeviceException: No such device #0:43
10:31:11.686 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-44: com.diozero.api.NoSuchDeviceException: No such device #0:44
10:31:11.687 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-45: com.diozero.api.NoSuchDeviceException: No such device #0:45
10:31:11.687 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-46: com.diozero.api.NoSuchDeviceException: No such device #0:46
10:31:11.688 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-47: com.diozero.api.NoSuchDeviceException: No such device #0:47
10:31:11.689 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-48: com.diozero.api.NoSuchDeviceException: No such device #0:48
10:31:11.689 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-49: com.diozero.api.NoSuchDeviceException: No such device #0:49
10:31:11.689 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-50: com.diozero.api.NoSuchDeviceException: No such device #0:50
10:31:11.690 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-51: com.diozero.api.NoSuchDeviceException: No such device #0:51
10:31:11.690 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-52: com.diozero.api.NoSuchDeviceException: No such device #0:52
10:31:11.691 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-53: com.diozero.api.NoSuchDeviceException: No such device #0:53
10:31:11.692 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-54: com.diozero.api.NoSuchDeviceException: No such device #0:54
10:31:11.704 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-55: com.diozero.api.NoSuchDeviceException: No such device #0:55
10:31:11.704 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-56: com.diozero.api.NoSuchDeviceException: No such device #0:56
10:31:11.705 [main] INFO com.diozero.sampleapps.GpioChardev.testLines - Unable to provision digital input device 0-57: com.diozero.api.NoSuchDeviceException: No such device #0:57
Will test on a device without a boardinfo file.
Ok - I can confirm that the boarddef file is currently required and without one it isn't possible to provision a GPIO device. I will see what I can do to fix in 1.4.1.
Regarding adding a local boarddef file - it needs to be in a folder boarddefs
that is on the classpath. I.e.:
$ pwd
/home/matt/diozero/diozero-distribution-1.4.1
$ java -cp diozero-sampleapps-1.4.1.jar com.diozero.sampleapps.SystemInformation
Local System Info
diozero version: 1.4.1
Operating System: debian 12 (bookworm) - arm
CPU Temperature: 35.96
Detected Board Info
Device Factory: DefaultDeviceFactory
Board: FriendlyARM NanoPi Duo2 (RAM: 502,284 bytes, O/S: debian 12 (bookworm))
I2C Bus Numbers: 0
$ ls boarddefs
friendlyarm_nanopi-duo2.txt
$ java -cp diozero-sampleapps-1.4.1.jar:. com.diozero.sampleapps.SystemInformation
Local System Info
diozero version: 1.4.1
Operating System: debian 12 (bookworm) - arm
CPU Temperature: 35.59
Detected Board Info
Device Factory: DefaultDeviceFactory
Board: FriendlyARM NanoPi Duo2 (RAM: 502,284 bytes, O/S: debian 12 (bookworm))
I2C Bus Numbers: 0
Header: DEFAULT
+-----+----------+--------+----------+--------+----------+-----+
+ GP# + Name + gpiod + Physical + gpiod + Name + GP# +
+-----+----------+--------+----------+--------+----------+-----+
| | 5v | | 1 || 2 | 0:5 | PWM0 | 5 |
| | 5v | | 3 || 4 | 0:4 | PA4 | 4 |
| | 3v3 | | 5 || 6 | | GND | |
| | GND | | 7 || 8 | 0:11 | I2C0_SCL | 11 |
| 363 | PL11 | 1:11 | 9 || 10 | 0:12 | I2C0_SDA | 12 |
| 203 | PG11 | 0:203 | 11 || 12 | 0:13 | PA13 | 13 |
| | USB-DM3 | | 13 || 14 | 0:14 | PA14 | 14 |
| | USB-DP3 | | 15 || 16 | 0:16 | PA16 | 16 |
| | USB-DM2 | | 17 || 18 | 0:15 | PA15 | 15 |
| | USB-DP2 | | 19 || 20 | 0:199 | PG7 | 199 |
| | EPhyRXN | | 21 || 22 | 0:198 | PG6 | 198 |
| | EPhyRXP | | 23 || 24 | | CVBS | |
| | EPhyTXN | | 25 || 26 | | LineOutL | |
| | EPhyTXP | | 27 || 28 | | LineOutR | |
| | EPhyLinK | | 29 || 30 | | MIC_P | |
| | EPhySPD | | 31 || 32 | | MIC_N | |
+-----+----------+--------+----------+--------+----------+-----+
But isn't the classpath pointing to inside the jar file? Cause the only way i can het the boarddef to be read is in the root of the jar file.
Just needs to be in a boarddefs
folder which is on the classpath. Can be in a JAR file or exploded as per the example above.
$ jar tf diozero-core-1.4.1.jar| grep boarddef
boarddefs/
boarddefs/hardkernel_odroid-c2.txt
boarddefs/raspberrypi_aplus.txt
boarddefs/radxa_rock-4c-plus.txt
boarddefs/rockchip_rk3588s-orangepi-5.txt
boarddefs/raspberrypi_zero2w.txt
boarddefs/radxa_rockpis.txt
boarddefs/raspberrypi_cm4.txt
boarddefs/raspberrypi.txt
boarddefs/friendlyarm_nanopi-neo.txt
boarddefs/raspberrypi_b.txt
boarddefs/hardkernel_odroid-n2-plus.txt
boarddefs/raspberrypi_a.txt
boarddefs/raspberrypi_3b.txt
boarddefs/raspberrypi_b-r1.txt
boarddefs/radxa_rockpi4c-plus.txt
boarddefs/raspberrypi_zerow.txt
boarddefs/raspberrypi_zero.txt
boarddefs/raspberrypi_2b.txt
boarddefs/xunlong_orangepi-one-plus.txt
boarddefs/xunlong_orangepi-3-lts.txt
boarddefs/raspberrypi_5b.txt
boarddefs/xunlong_orangepi-zero-plus.txt
boarddefs/ti_am335x-bone.txt
boarddefs/raspberrypi_4b.txt
boarddefs/asus_rk3288-tinker.txt
Sigh, for some reason I always read is as Raxda instead of Radxa... (maybe because that's easier to say) So I named the file raxda... Even in the post with the cat result I wrote it wrong instead of copy pasting...
So this issue is resolved and the reason for the issue was missing boarddef file.
Maybe minor thing to add that's probably not worth opening another issue for. DigitalInputDevice getName return Native-GPIO-xx while PinInfo getName has the name found in the boarddef (if any). Might be handy if DigitalInputDevice returns the given name.
I'd like to use the lib for detecting falling edges on gpio pins on a Raxda Rockchip pi S0 (Rockchip RK3308B). The sample app finds the gpio banks java -cp diozero-sampleapps-1.4.0.jar com.diozero.sampleapps.GpioDetect
but
Fails on any value of a with NoSuchDeviceException.
Gpiod finds about 27 named gpio and can monitor them, so hardware wise it should work. I2C on the other hand works fine.
Using: sudo java -cp diozero-sampleapps-1.4.0.jar com.diozero.sampleapps.SystemInformation Results in:
Any ideas on what to try?