feat: add NixOS module for HackerGadgets AIO v2 board (uConsole CM5)
- New module: hardware.uconsole-cm5-aio-v2 - GPIO rail control for GPS (27), LORA (16), SDR (7), USB (23) - Systemd oneshot service (aiov2-rails-boot) to apply states at boot - aiov2_ctl CLI tool packaged from GitHub source - GPS UART support (ttyAMA0, 9600 baud) with dialout group - Optional systemd user service for system tray GUI - Wired into uconsole-cm5 NixOS config + SD image All rails default OFF — activate on demand with: aiov2_ctl <GPS|LORA|SDR|USB> on
This commit is contained in:
@@ -120,6 +120,7 @@
|
|||||||
};
|
};
|
||||||
in { nix.package = lix-cross.lix; })
|
in { nix.package = lix-cross.lix; })
|
||||||
agenix.nixosModules.default
|
agenix.nixosModules.default
|
||||||
|
./modules/nixos/hardware/uconsole-cm5-aio-v2.nix
|
||||||
./hosts/uconsole-cm5/configuration.nix
|
./hosts/uconsole-cm5/configuration.nix
|
||||||
./hosts/uconsole-cm5/hardware-configuration.nix
|
./hosts/uconsole-cm5/hardware-configuration.nix
|
||||||
];
|
];
|
||||||
@@ -147,6 +148,7 @@
|
|||||||
nixos-raspberrypi.nixosModules.sd-image
|
nixos-raspberrypi.nixosModules.sd-image
|
||||||
nixos-uconsole.nixosModules.uconsole-cm5
|
nixos-uconsole.nixosModules.uconsole-cm5
|
||||||
agenix.nixosModules.default
|
agenix.nixosModules.default
|
||||||
|
./modules/nixos/hardware/uconsole-cm5-aio-v2.nix
|
||||||
./hosts/uconsole-cm5/configuration.nix
|
./hosts/uconsole-cm5/configuration.nix
|
||||||
];
|
];
|
||||||
}).config.system.build.sdImage;
|
}).config.system.build.sdImage;
|
||||||
|
|||||||
@@ -26,5 +26,20 @@
|
|||||||
# Firmware
|
# Firmware
|
||||||
hardware.enableRedistributableFirmware = true;
|
hardware.enableRedistributableFirmware = true;
|
||||||
|
|
||||||
# DSI display fix: le kernel patch est dans flake.nix (patches/0008-panel-cwu50-no-burst.patch)
|
# HackerGadgets AIO v2 board
|
||||||
|
hardware.uconsole-cm5-aio-v2 = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
# Rails actifs au boot
|
||||||
|
bootRails = {
|
||||||
|
GPS = false; # activé à la demande via aiov2_ctl GPS on
|
||||||
|
LORA = false; # activé à la demande via aiov2_ctl LORA on
|
||||||
|
SDR = false; # activé à la demande via aiov2_ctl SDR on
|
||||||
|
USB = false; # activé à la demande via aiov2_ctl USB on
|
||||||
|
};
|
||||||
|
|
||||||
|
enableGPS = false; # activer quand antenne GPS branchée
|
||||||
|
};
|
||||||
|
|
||||||
|
# DSI display fix: le kernel patch est dans flake.nix (patches/0008-panel-cwu50-fix-init-seq1.patch)
|
||||||
}
|
}
|
||||||
|
|||||||
169
modules/nixos/hardware/uconsole-cm5-aio-v2.nix
Normal file
169
modules/nixos/hardware/uconsole-cm5-aio-v2.nix
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.hardware.uconsole-cm5-aio-v2;
|
||||||
|
|
||||||
|
# GPIO pin map matching the AIO v2 board hardware
|
||||||
|
# SDR (RTL-SDR): GPIO 7
|
||||||
|
# LoRa (SX1262) : GPIO 16
|
||||||
|
# USB Hub Interne: GPIO 23
|
||||||
|
# GPS (GNSS) : GPIO 27
|
||||||
|
gpioMap = {
|
||||||
|
GPS = 27;
|
||||||
|
LORA = 16;
|
||||||
|
SDR = 7;
|
||||||
|
USB = 23;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Generate a script that applies boot rail states via pinctrl
|
||||||
|
applyRailsScript = pkgs.writeShellScript "apply-aio-v2-rails" (
|
||||||
|
''
|
||||||
|
set -e
|
||||||
|
PINCTRL=${pkgs.raspberrypi-tools}/bin/pinctrl
|
||||||
|
''
|
||||||
|
+ concatStringsSep "" (mapAttrsToList (name: pin: ''
|
||||||
|
if [ "${if cfg.bootRails.${name} then "1" else "0"}" = "1" ]; then
|
||||||
|
echo "AIO v2: ${name} (GPIO${toString pin}) → ON"
|
||||||
|
$PINCTRL set ${toString pin} op dh
|
||||||
|
else
|
||||||
|
echo "AIO v2: ${name} (GPIO${toString pin}) → OFF"
|
||||||
|
$PINCTRL set ${toString pin} op dl
|
||||||
|
fi
|
||||||
|
'') gpioMap)
|
||||||
|
);
|
||||||
|
|
||||||
|
# aiov2_ctl CLI tool — fetched from GitHub, available as `aiov2_ctl`
|
||||||
|
aiov2CtlPkg = pkgs.stdenv.mkDerivation rec {
|
||||||
|
pname = "aiov2_ctl";
|
||||||
|
version = "0-unstable-2026-06-16";
|
||||||
|
|
||||||
|
src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "hackergadgets";
|
||||||
|
repo = "aiov2_ctl";
|
||||||
|
rev = "main";
|
||||||
|
hash = lib.fakeSha256; # will fail with real hash on first build
|
||||||
|
};
|
||||||
|
|
||||||
|
dontUnpack = true;
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/bin $out/share/aiov2_ctl/img
|
||||||
|
cp $src/aiov2_ctl.py $out/bin/aiov2_ctl
|
||||||
|
chmod +x $out/bin/aiov2_ctl
|
||||||
|
patchShebangs $out/bin/aiov2_ctl
|
||||||
|
substituteInPlace $out/bin/aiov2_ctl \
|
||||||
|
--replace-fail '"/usr/local/share/aiov2_ctl/img/' '"'$out'/share/aiov2_ctl/img/'
|
||||||
|
cp -r $src/img/* $out/share/aiov2_ctl/img/
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "HackerGadgets uConsole AIO v2 GPIO control and telemetry tool";
|
||||||
|
homepage = "https://github.com/hackergadgets/aiov2_ctl";
|
||||||
|
license = lib.licenses.mit;
|
||||||
|
maintainers = with lib.maintainers; [ ];
|
||||||
|
platforms = [ "aarch64-linux" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
options.hardware.uconsole-cm5-aio-v2 = {
|
||||||
|
enable = mkEnableOption "HackerGadgets uConsole AIO v2 board support";
|
||||||
|
|
||||||
|
bootRails = {
|
||||||
|
GPS = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Enable GPS module at boot (GPIO 27)";
|
||||||
|
};
|
||||||
|
LORA = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Enable LoRa module at boot (GPIO 16)";
|
||||||
|
};
|
||||||
|
SDR = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Enable SDR module at boot (GPIO 7)";
|
||||||
|
};
|
||||||
|
USB = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Enable internal USB hub at boot (GPIO 23)";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = aiov2CtlPkg;
|
||||||
|
defaultText = literalExpression "aiov2CtlPkg";
|
||||||
|
description = "aiov2_ctl package to use";
|
||||||
|
};
|
||||||
|
|
||||||
|
enableGPS = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Enable GPS UART (/dev/ttyAMA0 at 9600 baud).
|
||||||
|
Requires enabling UART on the CM5 via boot.kernelParams.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
enableGUI = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Enable the system tray GUI for aiov2_ctl.
|
||||||
|
Requires a desktop environment with system tray support.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
# Package the aiov2_ctl tool + pinctrl
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
cfg.package
|
||||||
|
raspberrypi-tools # provides pinctrl
|
||||||
|
];
|
||||||
|
|
||||||
|
# Boot rail systemd oneshot service
|
||||||
|
systemd.services.aiov2-rails-boot = {
|
||||||
|
description = "Apply AIO v2 GPIO rail boot states";
|
||||||
|
after = [ "local-fs.target" ];
|
||||||
|
wants = [ "local-fs.target" ];
|
||||||
|
before = [ "multi-user.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
ExecStart = "${applyRailsScript}";
|
||||||
|
RemainAfterExit = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# GPS configuration
|
||||||
|
boot.kernelParams = mkIf cfg.enableGPS [ "uart0=on" ];
|
||||||
|
|
||||||
|
users.users = mkIf cfg.enableGPS {
|
||||||
|
gortium = {
|
||||||
|
extraGroups = [ "dialout" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# GUI autostart (XDG)
|
||||||
|
systemd.user.services.aiov2-ctl-gui = mkIf cfg.enableGUI {
|
||||||
|
description = "AIO v2 System Tray Controller";
|
||||||
|
after = [ "graphical-session.target" ];
|
||||||
|
wants = [ "graphical-session.target" ];
|
||||||
|
wantedBy = [ "graphical-session.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "simple";
|
||||||
|
ExecStart = "${cfg.package}/bin/aiov2_ctl --gui";
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = 5;
|
||||||
|
};
|
||||||
|
environment = {
|
||||||
|
AIOV2_CTL_DEBUG = "0";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user