Skip to content

Commit

Permalink
Initial DriveMode implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
mk868 committed Nov 2, 2024
1 parent 7243d7c commit bf4e0d8
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package eu.softpol.lib.jgpioit;

import static eu.softpol.lib.jgpio.DriveMode.OPEN_DRAIN;
import static eu.softpol.lib.jgpio.DriveMode.OPEN_DRAIN_PULL_UP;
import static eu.softpol.lib.jgpio.DriveMode.OPEN_SOURCE;
import static eu.softpol.lib.jgpio.DriveMode.OPEN_SOURCE_PULL_DOWN;
import static eu.softpol.lib.jgpio.DriveMode.PUSH_PULL;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.params.ParameterizedTest.INDEX_PLACEHOLDER;
import static org.junit.jupiter.params.provider.Arguments.of;

import eu.softpol.lib.jgpio.Bias;
import eu.softpol.lib.jgpio.DriveMode;
import eu.softpol.lib.jgpio.Jgpio;
import eu.softpol.lib.jgpioit.util.TestPin;
import eu.softpol.lib.jgpioit.util.TwoPins;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

class LineSessionWriteDriveIT {

private static final List<TwoPins> CONNECTED_PINS = List.of(
Defs.CONNECTED_PINS
);

private static Stream<Arguments> args() {
return Stream.of(
// PUSH_PULL
of(PUSH_PULL, Bias.HIGH_IMPEDANCE, false, false),
of(PUSH_PULL, Bias.HIGH_IMPEDANCE, true, true),
of(PUSH_PULL, Bias.PULL_UP, false, false),
of(PUSH_PULL, Bias.PULL_UP, true, true),
of(PUSH_PULL, Bias.PULL_DOWN, false, false),
of(PUSH_PULL, Bias.PULL_DOWN, true, true),
// OPEN_DRAIN
of(OPEN_DRAIN, Bias.HIGH_IMPEDANCE, false, false),
//of(OPEN_DRAIN, Bias.HIGH_IMPEDANCE, true, undefined),
of(OPEN_DRAIN, Bias.PULL_UP, false, false),
of(OPEN_DRAIN, Bias.PULL_UP, true, true),//???
of(OPEN_DRAIN, Bias.PULL_DOWN, false, false),
of(OPEN_DRAIN, Bias.PULL_DOWN, true, false),
// OPEN_DRAIN_PULL_UP
of(OPEN_DRAIN_PULL_UP, Bias.HIGH_IMPEDANCE, false, false),
of(OPEN_DRAIN_PULL_UP, Bias.HIGH_IMPEDANCE, true, true),
of(OPEN_DRAIN_PULL_UP, Bias.PULL_UP, false, false),
of(OPEN_DRAIN_PULL_UP, Bias.PULL_UP, true, true),
of(OPEN_DRAIN_PULL_UP, Bias.PULL_DOWN, false, false),
//of(OPEN_DRAIN_PULL_UP, Bias.PULL_DOWN, true, undefined),
// OPEN_SOURCE
//of(OPEN_SOURCE, Bias.HIGH_IMPEDANCE, false, undefined),
of(OPEN_SOURCE, Bias.HIGH_IMPEDANCE, true, true),
of(OPEN_SOURCE, Bias.PULL_UP, false, true),
of(OPEN_SOURCE, Bias.PULL_UP, true, true),
of(OPEN_SOURCE, Bias.PULL_DOWN, false, false),//???
of(OPEN_SOURCE, Bias.PULL_DOWN, true, true),
// OPEN_SOURCE_PULL_DOWN
of(OPEN_SOURCE_PULL_DOWN, Bias.HIGH_IMPEDANCE, false, false),
of(OPEN_SOURCE_PULL_DOWN, Bias.HIGH_IMPEDANCE, true, true),
//of(OPEN_SOURCE_PULL_DOWN, Bias.PULL_UP, false, undefined),
of(OPEN_SOURCE_PULL_DOWN, Bias.PULL_UP, true, true),
of(OPEN_SOURCE_PULL_DOWN, Bias.PULL_DOWN, false, false),
of(OPEN_SOURCE_PULL_DOWN, Bias.PULL_DOWN, true, true)
).flatMap(it ->
CONNECTED_PINS.stream()
.map(pins -> of(Stream.concat(
Stream.of(
pins.pin1(),
pins.pin2()
),
Arrays.stream(it.get())
).toArray()))
);
}

@ParameterizedTest(name = "[" + INDEX_PLACEHOLDER + "] "
+ "driveMode={2}, "
+ "bias={3}, "
+ "writeValue={4}, "
+ "readValue={5} ")
@MethodSource("args")
void should_read_value_depending_on_bias_and_drive_mode_on_coupled_line(
TestPin inputPin,
TestPin outputPin,
DriveMode driveMode,
Bias bias,
boolean writeValue,
boolean readValue
) {
var jgpio = Jgpio.getInstance();
try (var outputChip = jgpio.openChipByName(outputPin.chipName());
var outputLine = outputChip.getLine(outputPin.lineOffset())
.openAsOutput(driveMode);
var inputChip = jgpio.openChipByName(inputPin.chipName());
var inputLine = inputChip.getLine(inputPin.lineOffset())
.openAsInput(bias);
) {
outputLine.write(writeValue);
assertThat(inputLine.read())
.as("Input line level")
.isEqualTo(readValue);
}
}

@ParameterizedTest(name = "[" + INDEX_PLACEHOLDER + "] "
+ "driveMode={2}, "
+ "bias={3}, "
+ "writeValue={4}, "
+ "readValue={5} ")
@MethodSource("args")
void should_read_value_depending_on_bias_and_drive_mode_on_coupled_line2(
TestPin inputPin,
TestPin outputPin,
DriveMode driveMode,
Bias bias,
boolean writeValue,
boolean readValue
) {
var jgpio = Jgpio.getInstance();
try (var outputChip = jgpio.openChipByName(outputPin.chipName());
var outputLine = outputChip.getLine(outputPin.lineOffset())
.openAsOutput();
var inputChip = jgpio.openChipByName(inputPin.chipName());
var inputLine = inputChip.getLine(inputPin.lineOffset())
.openAsInput(bias);
) {
outputLine.setDriveMode(driveMode);
outputLine.write(writeValue);
assertThat(inputLine.read())
.as("Input line level")
.isEqualTo(readValue);
}
}
}
1 change: 1 addition & 0 deletions jgpio/src/jextract/gpiod-includes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
--include-function gpiod_line_request_input
--include-function gpiod_line_request_input_flags
--include-function gpiod_line_request_output
--include-function gpiod_line_request_output_flags
--include-function gpiod_line_get_value
--include-function gpiod_line_set_value
--include-function gpiod_line_set_flags
Expand Down
9 changes: 9 additions & 0 deletions jgpio/src/main/java/eu/softpol/lib/jgpio/DriveMode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package eu.softpol.lib.jgpio;

public enum DriveMode {
PUSH_PULL,
OPEN_DRAIN,
OPEN_DRAIN_PULL_UP,
OPEN_SOURCE,
OPEN_SOURCE_PULL_DOWN;
}
2 changes: 2 additions & 0 deletions jgpio/src/main/java/eu/softpol/lib/jgpio/Line.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,6 @@ public interface Line {
/// @return the session for the output line, which must be closed after use
LineOutputSession openAsOutput();

LineOutputSession openAsOutput(DriveMode driveMode);

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
/// The methods of this interface should not be called after [Chip#close()].
public interface LineOutputSession extends Closeable {

void setDriveMode(DriveMode driveMode);

/// Writes the new value of the output line.
///
/// @param value the signal level: `true` if the output line needs to be high, `false` if the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import eu.softpol.lib.jgpio.Line;
import eu.softpol.lib.jgpio.LineInputSession;
import eu.softpol.lib.jgpio.LineOutputSession;
import eu.softpol.lib.jgpio.DriveMode;
import eu.softpol.lib.jgpio.internal.ffm.libgpiod.gpiod_h;
import java.lang.foreign.MemorySegment;
import org.jspecify.annotations.Nullable;
Expand Down Expand Up @@ -99,6 +100,12 @@ public LineOutputSession openAsOutput() {
return new GpiodLineOutputSession(chip, linePtr);
}

@Override
public LineOutputSession openAsOutput(DriveMode driveMode) {
throwWhenChipClosed();
return new GpiodLineOutputSession(chip, linePtr, driveMode);
}

@Override
public String toString() {
if (chip.isClosed()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import eu.softpol.lib.jgpio.JgpioException;
import eu.softpol.lib.jgpio.LineOutputSession;
import eu.softpol.lib.jgpio.DriveMode;
import eu.softpol.lib.jgpio.internal.ffm.libgpiod.gpiod_h;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
Expand All @@ -39,6 +40,29 @@ public GpiodLineOutputSession(GpiodChip chip, MemorySegment linePtr) {
logger.log(Level.DEBUG, "Line requested");
}

public GpiodLineOutputSession(GpiodChip chip, MemorySegment linePtr, DriveMode driveMode) {
super(chip, linePtr);
int flags = toFlags(driveMode);
try (var arena = Arena.ofConfined()) {
var consumerPtr = arena.allocateFrom(GpiodChip.CONSUMER_NAME, StandardCharsets.US_ASCII);
if (gpiod_h.gpiod_line_request_output_flags(this.linePtr, consumerPtr, flags, 0) != 0) {
throw new JgpioException("JGPIO line request failed");
}
}
logger.log(Level.DEBUG, "Line requested");
}

@Override
public void setDriveMode(DriveMode driveMode) {
throwWhenChipClosed();
throwWhenLineSessionClosed();
int flags = toFlags(driveMode);
logger.log(Level.DEBUG, "Set driveMode to {0}", driveMode);
if (gpiod_h.gpiod_line_set_flags(linePtr, flags) != 0) {
throw new JgpioException("Cannot set driveMode");
}
}

@Override
public void write(boolean value) {
throwWhenChipClosed();
Expand All @@ -49,4 +73,15 @@ public void write(boolean value) {
}
}

private int toFlags(DriveMode driveMode) {
return switch (driveMode) {
case PUSH_PULL -> 0;
case OPEN_DRAIN -> gpiod_h.GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN();
case OPEN_DRAIN_PULL_UP -> gpiod_h.GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN()
+ gpiod_h.GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP();
case OPEN_SOURCE -> gpiod_h.GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE();
case OPEN_SOURCE_PULL_DOWN -> gpiod_h.GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE()
+ gpiod_h.GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN();
};
}
}

0 comments on commit bf4e0d8

Please sign in to comment.