package SBC; import com.sun.jna.Platform; import org.jetbrains.annotations.NotNull; import org.tinylog.Logger; import java.nio.file.Files; import java.nio.file.Path; public class GPIO { public static final Path gpioPath = Path.of("/sys/class/gpio"); private static final Path gpioExportPath = Path.of("/sys/class/gpio/export"); private static final Path gpioUnexportPath = Path.of("/sys/class/gpio/unexport"); public static boolean HaveGPIO(){ if (Platform.isLinux()){ if (gpioPath.toFile().isDirectory()){ if (gpioExportPath.toFile().isFile()){ if (gpioUnexportPath.toFile().isFile()){ return true; } else Logger.error("GPIO unexport path is not found"); } else Logger.error("GPIO export path is not found"); } else Logger.error("GPIO path is not found"); } else Logger.info("OS is not Linux"); return false; } /** * Check if the pin is already exported * @param pin GPIO pin number * @return true if the pin is already exported */ public static boolean GpioPinExists(@NotNull RaspberryPi5BPins pin){ Path pinPath = gpioPath.resolve("gpio"+pin.gpionumber); return pinPath.toFile().isDirectory(); } /** * Export the pin * @param pin GPIO pin number * @return true if the pin is successfully exported */ public static boolean ExportPin(@NotNull RaspberryPi5BPins pin){ try{ if (Files.isWritable(gpioExportPath)){ Files.write(gpioExportPath, String.valueOf(pin.gpionumber).getBytes()); Logger.info("Pin "+pin.pin+" exported"); return GpioPinExists(pin); } else Logger.error("GPIO export path is not writable"); } catch (Exception e){ Logger.error("Failed to export pin: "+pin.pin+", Message: "+e.getMessage()); } return false; } /** * Unexport the pin * @param pin GPIO pin number * @return true if the pin is successfully unexported */ public static boolean UnexportPin(@NotNull RaspberryPi5BPins pin){ if (Files.isWritable(gpioUnexportPath)){ try{ Files.write(gpioUnexportPath, String.valueOf(pin.gpionumber).getBytes()); Logger.info("Pin "+pin.pin+" unexported"); return true; } catch (Exception e){ Logger.error("Failed to unexport pin: "+pin.pin+", Message: "+e.getMessage()); } } else Logger.error("GPIO unexport path is not writable"); return false; } /** * Get Direction of the pin * @param pin GPIO pin number * @return "in" if the pin is input, "out" if the pin is output, "unknown" if the direction is unknown */ public static String GetPinDirection(@NotNull RaspberryPi5BPins pin){ Path pinPath = gpioPath.resolve("gpio"+pin.gpionumber).resolve("direction"); if (pinPath.toFile().isFile()){ if (Files.isReadable(pinPath)){ try{ return Files.readString(pinPath).trim(); } catch (Exception e){ Logger.error("Failed to read pin direction: "+pin.pin+", Message: "+e.getMessage()); } } else Logger.error("Pin direction file is not readable: "+pin.pin); } else Logger.error("Pin direction file not found: "+pin.pin); return "unknown"; } /** * Set the direction of the pin * @param pin GPIO pin number * @param direction "in" for input, "out" for output * @return true if the direction is successfully set */ public static boolean SetPinDirection(@NotNull RaspberryPi5BPins pin, String direction){ Path pinPath = gpioPath.resolve("gpio"+pin.gpionumber).resolve("direction"); if (pinPath.toFile().isFile()){ if (Files.isWritable(pinPath)){ direction = direction.trim().toLowerCase(); if ("in".equals(direction) || "out".equals(direction)){ try{ Files.write(pinPath, direction.getBytes()); Logger.info("Pin "+pin.pin+" direction set to "+direction); return true; } catch (Exception e){ Logger.error("Failed to set pin direction: "+pin.pin+", Message: "+e.getMessage()); } } else Logger.error("Invalid direction: "+direction); } else Logger.error("Pin direction file is not writable: "+pin.pin); } else Logger.error("Pin direction file not found: "+pin.pin); return false; } /** * Set the value of the output pin * @param pin GPIO pin number * @param isON true to set the pin value to 1, false to set the pin value to 0 * @return true if the value is successfully set */ public static boolean SetValue(@NotNull RaspberryPi5BPins pin, boolean isON){ Path pinPath = gpioPath.resolve("gpio"+pin.gpionumber).resolve("value"); if (pinPath.toFile().isFile()){ if (Files.isWritable(pinPath)){ try{ Files.write(pinPath, isON?"1".getBytes():"0".getBytes()); Logger.info("Pin "+pin.pin+" value set to "+(isON?"1":"0")); return true; } catch (Exception e){ Logger.error("Failed to set pin value: "+pin.pin+", Message: "+e.getMessage()); } } else Logger.error("Pin value file is not writable: "+pin.pin); } else Logger.error("Pin value file not found: "+pin.pin); return false; } /** * Get the value of the pin * @param pin GPIO pin number * @return "1" if the pin value is 1, "0" if the pin value is 0, "unknown" if the value is unknown */ public static String GetValue(@NotNull RaspberryPi5BPins pin){ Path pinPath = gpioPath.resolve("gpio"+pin.gpionumber).resolve("value"); if (pinPath.toFile().isFile()){ if (Files.isReadable(pinPath)){ try{ return Files.readString(pinPath).trim(); } catch (Exception e){ Logger.error("Failed to read pin value: "+pin.pin+", Message: "+e.getMessage()); } } else Logger.error("Pin value file is not readable: "+pin.pin); } else Logger.error("Pin value file not found: "+pin.pin); return "unknown"; } }