diff --git a/deploy/nixos/hardware/upboard.nix b/deploy/nixos/hardware/upboard.nix index 2b990f7..163b795 100644 --- a/deploy/nixos/hardware/upboard.nix +++ b/deploy/nixos/hardware/upboard.nix @@ -1,55 +1,51 @@ -# UP Board Hardware Configuration -# Supports UP Board, UP Squared, and similar Intel Atom/Celeron boards -# commonly used in Lamassu ATM machines +# Tejo (UP Board / UP4000) Hardware Configuration +# Intel Atom/Celeron boards used in Lamassu Tejo ATM machines. +# Supports both UP Board and UP4000 variants — udev rules for both +# are included since they match different kernel paths and don't conflict. +# +# Serial port mapping: +# ttyJ4 = Printer (Nippon NP-2511D-2) +# ttyJ5 = Validator (iVizion, ID003 protocol) +# ttyJ7 = Dispenser (Fujitsu F53/F56) { config, lib, pkgs, ... }: { - # Boot configuration for UP Board - # UP Board uses 64-bit CPU but some models have 32-bit UEFI boot = { loader = { - # Use systemd-boot for UEFI systems systemd-boot.enable = true; efi.canTouchEfiVariables = true; - - # Timeout for boot menu (useful for remote debugging) timeout = 3; }; - # Kernel modules needed for UP Board hardware initrd.availableKernelModules = [ - "xhci_pci" # USB 3.0 - "ahci" # SATA - "usb_storage" # USB mass storage - "sd_mod" # SCSI disk - "sdhci_pci" # SD card (eMMC) - "i915" # Intel graphics + "xhci_pci" + "ahci" + "usb_storage" + "sd_mod" + "sdhci_pci" + "i915" ]; kernelModules = [ - "kvm-intel" # Virtualization (if needed) - "i2c-dev" # I2C for hardware control - "spi-dev" # SPI for hardware control + "kvm-intel" + "i2c-dev" + "spi-dev" + "usbserial" # USB-to-serial adapters + "ftdi_sio" # FTDI USB serial + "cp210x" # CP210x USB serial ]; - # UP Board specific kernel parameters kernelParams = [ - # Intel graphics "i915.enable_psr=0" - - # Serial console for debugging (UP Board has debug UART) "console=ttyS4,115200n8" "console=tty0" - - # Quiet boot for kiosk mode "quiet" "splash" ]; }; - # Filesystem configuration - # Adjust these to match your actual disk layout + # Disk layout: GPT with ESP + ext4 root (eMMC on UP Board) fileSystems."/" = { device = "/dev/disk/by-label/nixos"; fsType = "ext4"; @@ -60,30 +56,24 @@ fsType = "vfat"; }; - # Hardware-specific packages + # NixOS 24.05 uses hardware.opengl (not hardware.graphics) hardware = { - # Intel GPU support - graphics = { + opengl = { enable = true; extraPackages = with pkgs; [ - intel-media-driver # VAAPI driver for newer Intel - vaapiIntel # VAAPI driver (legacy) + intel-media-driver + vaapiIntel vaapiVdpau libvdpau-va-gl ]; }; - - # Enable firmware for Intel hardware enableRedistributableFirmware = true; - - # CPU microcode updates cpu.intel.updateMicrocode = true; }; - # Power management powerManagement = { enable = true; - cpuFreqGovernor = "performance"; # ATM should be responsive + cpuFreqGovernor = "performance"; }; # Disable suspend/hibernate for kiosk @@ -94,14 +84,45 @@ hybrid-sleep.enable = false; }; - # Serial port access for bill validator/dispenser - # UP Board GPIO/UART pins - services.udev.extraRules = '' - # UP Board serial ports + # Serial port permissions + tejo-specific symlinks + services.udev.extraRules = lib.mkAfter '' + # Generic serial port permissions KERNEL=="ttyS[0-9]*", MODE="0666" - - # USB serial adapters (common for bill validators) KERNEL=="ttyUSB[0-9]*", MODE="0666" KERNEL=="ttyACM[0-9]*", MODE="0666" + + # ── Tejo serial port symlinks ────────────────────────────────────── + # Both UP Board and UP4000 rules included (match different kernel paths) + + # Printer (ttyJ4) + KERNELS=="1-7.2:1.0", SYMLINK+="ttyJ4" + KERNEL=="ttyUSB0", SYMLINK+="ttyJ4" + + # Validator (ttyJ5) + KERNELS=="1-7.3:1.0", SYMLINK+="ttyJ5" + KERNEL=="ttyUSB1", SYMLINK+="ttyJ5" + + # Dispenser (ttyJ7) + KERNEL=="ttyS1", SYMLINK+="ttyJ7" + KERNEL=="ttyS5", SYMLINK+="ttyJ7" + + # Legacy ttyAMA0 alias + SUBSYSTEM=="tty", KERNEL=="ttyS1", SYMLINK+="ttyAMA0", GROUP="dialout" + + # ── Camera devices ───────────────────────────────────────────────── + SUBSYSTEM=="video4linux", ATTR{index}=="0", KERNELS=="1-5", ATTRS{idVendor}=="0ac8", ATTRS{idProduct}=="0345", SYMLINK+="video-scan" + SUBSYSTEM=="video4linux", ATTR{index}=="0", KERNELS=="1-2", ATTRS{idVendor}=="0ac8", ATTRS{idProduct}=="0345", SYMLINK+="video-scan" + SUBSYSTEM=="video4linux", ATTR{index}=="0", KERNELS=="1-6", ATTRS{idVendor}=="0ac8", ATTRS{idProduct}=="0345", SYMLINK+="video-front" + SUBSYSTEM=="video4linux", ATTR{index}=="0", KERNELS=="1-3", ATTRS{idVendor}=="0ac8", ATTRS{idProduct}=="0345", SYMLINK+="video-front" + + # ── LED SPI / peripherals ────────────────────────────────────────── + KERNEL=="spidev1.0", SYMLINK+="ledspi" + KERNEL=="spidev2.0", SYMLINK+="ledspi" + SUBSYSTEM=="spidev", GROUP="spi", MODE="0660" + SUBSYSTEM=="i2c-dev", GROUP="i2c", MODE="0660" + SUBSYSTEM=="leds", KERNEL=="upboard:*", ACTION=="add|change", RUN+="${pkgs.findutils}/bin/find /sys$devpath -type f -exec ${pkgs.coreutils}/bin/chmod g+u {} + -exec ${pkgs.coreutils}/bin/chown :leds {} +" + + # Disable USB autosuspend (prevents serial adapters from sleeping) + ACTION=="add", SUBSYSTEM=="usb", TEST=="power/control", ATTR{power/control}="on" ''; } diff --git a/deploy/nixos/live.nix b/deploy/nixos/live.nix index 630f32d..82e5b99 100644 --- a/deploy/nixos/live.nix +++ b/deploy/nixos/live.nix @@ -82,6 +82,10 @@ in "kvm-intel" "i2c-dev" "spi-dev" + ] ++ lib.optionals (machineModel == "tejo") [ + "usbserial" # USB-to-serial adapters (ttyUSB0/1 for validator/printer) + "ftdi_sio" # FTDI USB serial (common in ATM peripherals) + "cp210x" # CP210x USB serial (alternative adapter) ]; kernelParams = [ @@ -91,6 +95,10 @@ in ] ++ lib.optionals (machineModel == "douro") [ # Bay Trail: preserve BIOS display init (matches working kernel 5.4 config) "vt.handoff=7" + ] ++ lib.optionals (machineModel == "tejo") [ + # UP Board debug UART for serial console + "console=ttyS4,115200n8" + "console=tty0" ]; }; @@ -194,10 +202,53 @@ in # Allow SSH with password for initial setup on the live system services.openssh.settings.PasswordAuthentication = lib.mkForce true; - # Serial port udev rules (from hardware/upboard.nix) - services.udev.extraRules = lib.mkAfter '' + # Serial port udev rules — generic permissions for all models + services.udev.extraRules = lib.mkAfter ('' KERNEL=="ttyS[0-9]*", MODE="0666" KERNEL=="ttyUSB[0-9]*", MODE="0666" KERNEL=="ttyACM[0-9]*", MODE="0666" - ''; + '' + lib.optionalString (machineModel == "tejo") '' + + # ── Tejo serial port symlinks ────────────────────────────────────── + # Both UP Board and UP4000 rules are included so one ISO works on either. + # Rules match different kernel paths so they don't conflict. + + # Printer (ttyJ4): UP Board via USB hub path, UP4000 via ttyUSB0 + KERNELS=="1-7.2:1.0", SYMLINK+="ttyJ4" + KERNEL=="ttyUSB0", SYMLINK+="ttyJ4" + + # Validator (ttyJ5): UP Board via USB hub path, UP4000 via ttyUSB1 + KERNELS=="1-7.3:1.0", SYMLINK+="ttyJ5" + KERNEL=="ttyUSB1", SYMLINK+="ttyJ5" + + # Dispenser (ttyJ7): UP Board uses ttyS1, UP4000 uses ttyS5 + KERNEL=="ttyS1", SYMLINK+="ttyJ7" + KERNEL=="ttyS5", SYMLINK+="ttyJ7" + + # Legacy ttyAMA0 alias + SUBSYSTEM=="tty", KERNEL=="ttyS1", SYMLINK+="ttyAMA0", GROUP="dialout" + + # ── Camera devices ───────────────────────────────────────────────── + # QR scanner camera (A4tech USB, vendor 0ac8:0345) + SUBSYSTEM=="video4linux", ATTR{index}=="0", KERNELS=="1-5", ATTRS{idVendor}=="0ac8", ATTRS{idProduct}=="0345", SYMLINK+="video-scan" + SUBSYSTEM=="video4linux", ATTR{index}=="0", KERNELS=="1-2", ATTRS{idVendor}=="0ac8", ATTRS{idProduct}=="0345", SYMLINK+="video-scan" + + # Front-facing camera + SUBSYSTEM=="video4linux", ATTR{index}=="0", KERNELS=="1-6", ATTRS{idVendor}=="0ac8", ATTRS{idProduct}=="0345", SYMLINK+="video-front" + SUBSYSTEM=="video4linux", ATTR{index}=="0", KERNELS=="1-3", ATTRS{idVendor}=="0ac8", ATTRS{idProduct}=="0345", SYMLINK+="video-front" + + # ── LED SPI / peripherals ────────────────────────────────────────── + KERNEL=="spidev1.0", SYMLINK+="ledspi" + KERNEL=="spidev2.0", SYMLINK+="ledspi" + + # SPI and I2C group permissions + SUBSYSTEM=="spidev", GROUP="spi", MODE="0660" + SUBSYSTEM=="i2c-dev", GROUP="i2c", MODE="0660" + + # UP Board FPGA LED permissions + SUBSYSTEM=="leds", KERNEL=="upboard:*", ACTION=="add|change", RUN+="${pkgs.findutils}/bin/find /sys$devpath -type f -exec ${pkgs.coreutils}/bin/chmod g+u {} + -exec ${pkgs.coreutils}/bin/chown :leds {} +" + + # Disable USB autosuspend (prevents serial adapters from sleeping) + ACTION=="add", SUBSYSTEM=="usb", TEST=="power/control", ATTR{power/control}="on" + ''); } diff --git a/flake.nix b/flake.nix index 3a07c1e..a95827e 100644 --- a/flake.nix +++ b/flake.nix @@ -121,10 +121,10 @@ }; # Auto-upgrade: pulls latest flake and runs nixos-rebuild switch - # To update manually: sudo nixos-rebuild switch --flake git+ssh://forgejo@git.atitlan.io/aiolabs/lamassu-next.git#douro-installed + # To update manually: sudo nixos-rebuild switch --flake git+ssh://forgejo@git.atitlan.io/aiolabs/lamassu-next.git#-installed system.autoUpgrade = { enable = true; - flake = "git+ssh://forgejo@git.atitlan.io/aiolabs/lamassu-next.git#douro-installed"; + flake = "git+ssh://forgejo@git.atitlan.io/aiolabs/lamassu-next.git#${machineModel}-installed"; dates = "04:00"; # daily at 4am allowReboot = false; }; @@ -212,9 +212,7 @@ # Installed-to-disk configs (proper GPT + systemd-boot, supports nixos-rebuild) douro-installed = mkInstalledConfig "douro" ./deploy/nixos/hardware/douro.nix; - - # UP Board (tejo) installed config - lamassu-atm = mkInstalledConfig "tejo" ./deploy/nixos/hardware/upboard.nix; + tejo-installed = mkInstalledConfig "tejo" ./deploy/nixos/hardware/upboard.nix; }; # ── Standalone NixOS module ───────────────────────────────────