Skip to content

Commit 7647dd0

Browse files
committed
#454 Implemented DigitalInput, test setup and some unit tests
1 parent d748dd0 commit 7647dd0

29 files changed

+1084
-152
lines changed

plugins/pi4j-plugin-ffm/pom.xml

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@
1616
<description>Pi4J Library Plugin for FFM API Providers</description>
1717
<packaging>jar</packaging>
1818
<dependencies>
19+
<!-- https://mvnrepository.com/artifact/io.github.digitalsmile.native/annotation -->
20+
<dependency>
21+
<groupId>io.github.digitalsmile.native</groupId>
22+
<artifactId>annotation</artifactId>
23+
<version>1.1.5</version>
24+
<scope>compile</scope>
25+
</dependency>
1926
<dependency>
2027
<groupId>org.slf4j</groupId>
2128
<artifactId>slf4j-api</artifactId>
@@ -28,10 +35,49 @@
2835
<scope>test</scope>
2936
</dependency>
3037
</dependencies>
31-
3238
<!-- STANDARD BUILD INSTRUCTIONS -->
3339
<build>
40+
<pluginManagement>
41+
<plugins>
42+
<plugin>
43+
<groupId>org.apache.maven.plugins</groupId>
44+
<artifactId>maven-compiler-plugin</artifactId>
45+
<version>3.14.0</version>
46+
<configuration>
47+
<source>24</source>
48+
<target>24</target>
49+
<annotationProcessorPaths>
50+
<annotationProcessorPath>
51+
<groupId>io.github.digitalsmile.native</groupId>
52+
<artifactId>annotation-processor</artifactId>
53+
<version>1.1.5</version>
54+
</annotationProcessorPath>
55+
</annotationProcessorPaths>
56+
</configuration>
57+
</plugin>
58+
</plugins>
59+
</pluginManagement>
3460
<plugins>
61+
<plugin>
62+
<groupId>org.codehaus.mojo</groupId>
63+
<artifactId>properties-maven-plugin</artifactId>
64+
<version>1.2.1</version>
65+
<executions>
66+
<execution>
67+
<goals>
68+
<goal>set-system-properties</goal>
69+
</goals>
70+
<configuration>
71+
<properties>
72+
<property>
73+
<name>linux-headers</name>
74+
<value>6.8.0-52-generic</value>
75+
</property>
76+
</properties>
77+
</configuration>
78+
</execution>
79+
</executions>
80+
</plugin>
3581
<!-- DOWNLOAD RUNTIME DEPENDENCIES -->
3682
<plugin>
3783
<groupId>org.apache.maven.plugins</groupId>

plugins/pi4j-plugin-ffm/src/main/java/com/pi4j/plugin/ffm/FFMPlugin.java

Lines changed: 17 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,60 +4,32 @@
44
import com.pi4j.exception.ShutdownException;
55
import com.pi4j.extension.Plugin;
66
import com.pi4j.extension.PluginService;
7+
import com.pi4j.plugin.ffm.providers.gpio.PinInputProviderImpl;
8+
import com.pi4j.plugin.ffm.providers.gpio.PinOutputProviderImpl;
9+
import com.pi4j.plugin.ffm.providers.i2c.FFMI2CProviderImpl;
10+
import com.pi4j.plugin.ffm.providers.pwm.FFMPwmProviderImpl;
11+
import com.pi4j.plugin.ffm.providers.spi.FFMSpiProviderImpl;
712
import com.pi4j.provider.Provider;
813

9-
/**
10-
* <p>GpioDPlugin class.</p>
11-
*
12-
* @author Alexander Liggesmeyer (<a href="https://alexander.liggesmeyer.net/">https://alexander.liggesmeyer.net/</a>)
13-
* @version $Id: $Id
14-
*/
15-
public class FFMPlugin implements Plugin {
16-
17-
/**
18-
* Constant <code>NAME="GpioD"</code>
19-
*/
20-
public static final String NAME = "GpioD";
21-
/**
22-
* Constant <code>ID="gpiod"</code>
23-
*/
24-
public static final String ID = "gpiod";
25-
26-
// Digital Output (GPIO) Provider name and unique ID
27-
/**
28-
* Constant <code>DIGITAL_OUTPUT_PROVIDER_NAME="NAME + Digital Output (GPIO) Provider"</code>
29-
*/
30-
public static final String DIGITAL_OUTPUT_PROVIDER_NAME = NAME + " Digital Output (GPIO) Provider";
31-
/**
32-
* Constant <code>DIGITAL_OUTPUT_PROVIDER_ID="ID + -digital-output"</code>
33-
*/
34-
public static final String DIGITAL_OUTPUT_PROVIDER_ID = ID + "-digital-output";
14+
import java.util.Arrays;
3515

36-
/**
37-
* Constant <code>DIGITAL_INPUT_PROVIDER_NAME="NAME + Digital Input (GPIO) Provider"</code>
38-
*/
39-
public static final String DIGITAL_INPUT_PROVIDER_NAME = NAME + " Digital Input (GPIO) Provider";
40-
/**
41-
* Constant <code>DIGITAL_INPUT_PROVIDER_ID="ID + -digital-input"</code>
42-
*/
43-
public static final String DIGITAL_INPUT_PROVIDER_ID = ID + "-digital-input";
44-
45-
private Provider<?, ?, ?>[] providers;
16+
public class FFMPlugin implements Plugin {
17+
private Provider<?, ?, ?>[] providers = new Provider[]{};
4618

47-
/**
48-
* {@inheritDoc}
49-
*/
5019
@Override
5120
public void initialize(PluginService service) {
52-
21+
this.providers = new Provider[]{
22+
new PinInputProviderImpl(),
23+
new PinOutputProviderImpl(),
24+
new FFMI2CProviderImpl(),
25+
new FFMSpiProviderImpl(),
26+
new FFMPwmProviderImpl()
27+
};
28+
service.register(providers);
5329
}
5430

5531
@Override
5632
public void shutdown(Context context) throws ShutdownException {
57-
if (this.providers != null) {
58-
for (Provider<?, ?, ?> provider : providers) {
59-
provider.shutdown(context);
60-
}
61-
}
33+
Arrays.stream(this.providers).forEach(provider -> provider.shutdown(context));
6234
}
6335
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.pi4j.plugin.ffm.common.file;
2+
3+
import io.github.digitalsmile.annotation.NativeMemoryException;
4+
import io.github.digitalsmile.annotation.function.ByAddress;
5+
import io.github.digitalsmile.annotation.function.NativeManualFunction;
6+
import io.github.digitalsmile.annotation.function.Returns;
7+
8+
public interface FileDescriptor {
9+
@NativeManualFunction(name = "open64", useErrno = true)
10+
int open(@ByAddress String path, int openFlag) throws NativeMemoryException;
11+
12+
@NativeManualFunction(name = "close", useErrno = true)
13+
void close(int fd)throws NativeMemoryException;
14+
15+
@NativeManualFunction(name = "read", useErrno = true, nativeReturnType = int.class)
16+
byte[] read(int fd, @Returns @ByAddress byte[] buffer, int size) throws NativeMemoryException;
17+
18+
@NativeManualFunction(name = "write", useErrno = true)
19+
int write(int fd, @ByAddress byte[] data) throws NativeMemoryException;
20+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.pi4j.plugin.ffm.common.file;
2+
3+
/**
4+
* Kernel flags for open command.
5+
*/
6+
public final class FileFlag {
7+
8+
public static final int O_APPEND = 1024;
9+
public static final int O_ASYNC = 8192;
10+
public static final int O_CLOEXEC = 524288;
11+
public static final int O_CREAT = 64;
12+
public static final int O_DIRECT = 16384;
13+
public static final int O_DIRECTORY = 65536;
14+
public static final int O_DSYNC = 4096;
15+
public static final int O_EXCL = 128;
16+
public static final int O_LARGEFILE = 0;
17+
public static final int O_NOATIME = 262144;
18+
public static final int O_NONBLOCK = 2048;
19+
public static final int O_NOCTTY = 256;
20+
public static final int O_NOFOLLOW = 131072;
21+
public static final int O_PATH = 2097152;
22+
public static final int O_RDONLY = 0;
23+
public static final int O_RDWR = 2;
24+
public static final int O_SYNC = 1052672;
25+
public static final int O_TMPFILE = 4259840;
26+
public static final int O_TRUNC = 512;
27+
public static final int O_WRONLY = 1;
28+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.pi4j.plugin.ffm.common.gpio;
2+
3+
/**
4+
* Class-holder of detected pin events, which is filled upon successfully call of linux poll.
5+
*
6+
* @param timestamp timestamp in nanoseconds (best effort estimate)
7+
* @param pinEvent event type detected (rising of falling edge)
8+
* @param sequenceNumber number of event since detecting started on the pin
9+
*/
10+
public record DetectedEvent(long timestamp, PinEvent pinEvent, int sequenceNumber) {
11+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.pi4j.plugin.ffm.common.gpio;
2+
3+
import io.github.digitalsmile.annotation.NativeMemory;
4+
import io.github.digitalsmile.annotation.NativeMemoryOptions;
5+
import io.github.digitalsmile.annotation.structure.Enum;
6+
import io.github.digitalsmile.annotation.structure.Enums;
7+
import io.github.digitalsmile.annotation.structure.Struct;
8+
import io.github.digitalsmile.annotation.structure.Structs;
9+
10+
@NativeMemory(headers = "/usr/src/linux-headers-${linux-headers}/include/uapi/linux/gpio.h")
11+
@NativeMemoryOptions(processRootConstants = true)
12+
@Structs({
13+
@Struct(name = "gpiochip_info", javaName = "ChipInfo"),
14+
@Struct(name = "gpio_v2_line_info", javaName = "LineInfo"),
15+
@Struct(name = "gpio_v2_line_attribute", javaName = "LineAttribute"),
16+
@Struct(name = "gpio_v2_line_config", javaName = "LineConfig"),
17+
@Struct(name = "gpio_v2_line_config_attribute", javaName = "LineConfigAttribute"),
18+
@Struct(name = "gpio_v2_line_event", javaName = "LineEvent"),
19+
@Struct(name = "gpio_v2_line_request", javaName = "LineRequest"),
20+
@Struct(name = "gpio_v2_line_values", javaName = "LineValues")
21+
})
22+
@Enums({
23+
@Enum(name = "gpio_v2_line_attr_id", javaName = "LineAttributeId")
24+
})
25+
public interface GPIO {
26+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.pi4j.plugin.ffm.common.gpio;
2+
3+
4+
import java.util.Arrays;
5+
6+
/**
7+
* Events, that you can subscribe and receive callback on the GPIO Pin state change.
8+
*
9+
* @see PinEventProcessing
10+
*/
11+
public enum PinEvent {
12+
/**
13+
* If the state was LOW and changed to HIGH.
14+
*/
15+
RISING(1),
16+
/**
17+
* If the state was HIGH and changed to LOW.
18+
*/
19+
FALLING(1 << 1),
20+
/**
21+
* if the state is changed.
22+
*/
23+
BOTH((1) | (1 << 1));
24+
25+
private final int value;
26+
27+
/**
28+
* Creates PinEvent enum.
29+
*
30+
* @param value integer value of pin event
31+
*/
32+
PinEvent(int value) {
33+
this.value = value;
34+
}
35+
36+
/**
37+
* Gets the integer value of pin event.
38+
*
39+
* @return integer value of pin event
40+
*/
41+
public int getValue() {
42+
return value;
43+
}
44+
45+
/**
46+
* Gets pin event enum by given integer value.
47+
*
48+
* @param value given integer value
49+
* @return pin event
50+
*/
51+
public static PinEvent getByValue(int value) {
52+
return Arrays.stream(values()).filter(v -> v.getValue() == value).findFirst().orElseThrow();
53+
}
54+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.pi4j.plugin.ffm.common.gpio;
2+
3+
import java.util.List;
4+
5+
/**
6+
* Event processing callback. Can be used as functional interface in streams.
7+
*/
8+
@FunctionalInterface
9+
public interface PinEventProcessing {
10+
/**
11+
* Process the changed on the GPIO Pin.
12+
* WARNING: since the caller of this callback is heavily tight with linux poll, it is recommended to do processing as fast as possible in implementation part.
13+
* If there is any heavy processing call it is recommended to offload it into different thread.
14+
*
15+
* @param eventList list of detected events
16+
*/
17+
void process(List<DetectedEvent> eventList);
18+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package com.pi4j.plugin.ffm.common.gpio;
2+
3+
/**
4+
* Pin Flag for configuring / reading configuration from GPIO.
5+
*/
6+
public enum PinFlag {
7+
/**
8+
* line is not available for request
9+
*/
10+
USED(1),
11+
/**
12+
* line active state is physical low
13+
*/
14+
ACTIVE_LOW(1 << 1),
15+
/**
16+
* line is an input
17+
*/
18+
INPUT(1 << 2),
19+
/**
20+
* line is an output
21+
*/
22+
OUTPUT(1 << 3),
23+
/**
24+
* line detects rising (inactive to active) edges
25+
*/
26+
EDGE_RISING(1 << 4),
27+
/**
28+
* line detects rising (inactive to active) edges
29+
*/
30+
EDGE_FALLING(1 << 5),
31+
/**
32+
* line is an open drain output
33+
*/
34+
OPEN_DRAIN(1 << 6),
35+
/**
36+
* line is an open source output
37+
*/
38+
OPEN_SOURCE(1 << 7),
39+
/**
40+
* line has pull-up bias enabled
41+
*/
42+
BIAS_PULL_UP(1 << 8),
43+
/**
44+
* line has pull-down bias enabled
45+
*/
46+
BIAS_PULL_DOWN(1 << 9),
47+
/**
48+
* line has bias disabled
49+
*/
50+
BIAS_DISABLED(1 << 10),
51+
/**
52+
* line events contain REALTIME timestamps
53+
*/
54+
EVENT_CLOCK_REALTIME(1 << 11),
55+
/**
56+
* line events contain timestamps from the hardware timestamping engine (HTE) subsystem
57+
*/
58+
EVENT_CLOCK_HTE(1 << 12);
59+
60+
61+
private final int value;
62+
63+
/**
64+
* Creates Pin Flag enum by given integer value.
65+
*
66+
* @param value integer value
67+
*/
68+
PinFlag(int value) {
69+
this.value = value;
70+
}
71+
72+
/**
73+
* Gets integer value of Pin Flag enum
74+
*
75+
* @return integer value
76+
*/
77+
public int getValue() {
78+
return value;
79+
}
80+
}

0 commit comments

Comments
 (0)