{ description = "AVR"; inputs = { nixpkgs.url = "nixpkgs/nixos-21.11"; }; outputs = { self, nixpkgs }: let version = builtins.string 0 8 self.lastModifiedDate; supportedSystems = [ "x86_64-linux" "avr-none" ]; mcu_cflags = { mcu, chip_select, f_cpu }: ''-O -finline-functions -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Werror -Wstrict-prototypes -DF_CPU=${f_cpu} -std=gnu99 -D__${chip_select}__=1 -mmcu=${mcu}''; attiny85 = { mcu = "attiny85"; chip_select = "AVR_ATtiny85"; f_cpu = "8000000"; }; atmega32u4 = { mcu = "atmega32u4"; chip_select = "AVR_ATmega32u4"; f_cpu = "8000000"; }; mkLibrary = { pkgs, gcc, cflags, pname, psrc, pbuildInputs ? [] }: pkgs.stdenv.mkDerivation rec { name = pname; src = psrc; buildInputs = pbuildInputs; include_dirs = pkgs.lib.concatStringsSep " " (map (dir: "-I${dir}/include") buildInputs); object_files = pkgs.lib.concatStringsSep " " (map (dir: "${dir}/*.o") buildInputs); dontUnpack = true; dontConfigure = true; buildPhase = '' for source in ${src}/*.c; do if [ -e $source ]; then ${gcc} ${cflags} ${include_dirs} -c $source fi done cp ${src}/*.h . || true ''; installPhase = '' mkdir -p $out/include $out/lib cp *.h $out/include || true cp *.o $out/lib || true ''; }; mkProgram = { pkgs, gcc, cflags, pname, psrc, pbuildInputs ? [], avr ? false }: let AVR = if avr == true then "1" else ""; in pkgs.stdenv.mkDerivation rec { name = pname; src = psrc; buildInputs = pbuildInputs; include_dirs = pkgs.lib.concatStringsSep " " (map (dir: "-I${dir}/include") buildInputs); object_files = pkgs.lib.concatStringsSep " " (map (dir: "${dir}/lib/*.o") buildInputs); dontUnpack = true; dontConfigure = true; buildPhase = '' for source in ${src}/*.c; do if [ -e $source ]; then ${gcc} ${cflags} ${include_dirs} -c $source fi done ${gcc} -o ${name}.elf ${cflags} ${object_files} *.o if $AVR; then $OBJCOPY -O ihex ${name}.elf ${name}.hex fi ''; installPhase = '' mkdir -p $out/bin cp ${name}.elf ${name}.hex $out/bin ''; }; in rec { defaultPackage."x86_64-linux" = let pkgs = import nixpkgs { system = "x86_64-linux"; }; avr = pkgs.pkgsCross.avr.buildPackages; in pkgs.symlinkJoin { name = "avr-monorepo"; paths = [ (packages."x86_64-linux"."prime-tx" { gcc = "${avr.gcc}/bin/avr-gcc"; cflags = mcu_cflags atmega32u4; }) (packages."x86_64-linux"."radio-rx" { gcc = "${avr.gcc}/bin/avr-gcc"; cflags = mcu_cflags atmega32u4; }) (packages."x86_64-linux"."lantern" { gcc = "${avr.gcc}/bin/avr-gcc"; cflags = mcu_cflags atmega32u4; avr = true; }) (packages."x86_64-linux"."lantern-controller" { gcc = "${avr.gcc}/bin/avr-gcc"; cflags = mcu_cflags atmega32u4; avr = true; }) ]; }; packages."x86_64-linux"."dio" = { gcc, cflags }: let pkgs = import nixpkgs { system = "x86_64-linux"; }; in mkLibrary { pkgs = pkgs; gcc = gcc; cflags = cflags; pname = "dio"; psrc = ./dio; }; packages."x86_64-linux"."animation" = { gcc, cflags }: let pkgs = import nixpkgs { system = "x86_64-linux"; }; in mkLibrary { pkgs = pkgs; gcc = gcc; cflags = cflags; pname = "animation"; psrc = ./animation; }; packages."x86_64-linux"."sk9822" = { gcc, cflags }: let pkgs = import nixpkgs { system = "x86_64-linux"; }; in mkLibrary { pkgs = pkgs; gcc = gcc; cflags = cflags; pname = "sk9822"; psrc = ./sk9822; pbuildInputs = [ (packages."x86_64-linux"."dio" { inherit gcc cflags; }) ]; }; packages."x86_64-linux"."shift-register" = { gcc, cflags }: let pkgs = import nixpkgs { system = "x86_64-linux"; }; in mkLibrary { pkgs = pkgs; gcc = gcc; cflags = cflags; pname = "shift-register"; psrc = ./shift-register; pbuildInputs = [ (packages."x86_64-linux"."dio" { inherit gcc cflags; }) ]; }; packages."x86_64-linux"."spi" = { gcc, cflags }: let pkgs = import nixpkgs { system = "x86_64-linux"; }; in mkLibrary { pkgs = pkgs; gcc = gcc; cflags = cflags; pname = "spi"; psrc = ./spi; pbuildInputs = [ (packages."x86_64-linux"."dio" { inherit gcc cflags; }) ]; }; packages."x86_64-linux"."rfm" = { gcc, cflags }: let pkgs = import nixpkgs { system = "x86_64-linux"; }; in mkLibrary { pkgs = pkgs; gcc = gcc; cflags = cflags; pname = "rfm"; psrc = ./rfm69hcw; pbuildInputs = [ (packages."x86_64-linux"."dio" { inherit gcc cflags; }) (packages."x86_64-linux"."spi" { inherit gcc cflags; }) ]; }; packages."x86_64-linux"."display" = { gcc, cflags }: let pkgs = import nixpkgs { system = "x86_64-linux"; }; in mkLibrary { pkgs = pkgs; gcc = gcc; cflags = cflags; pname = "display"; psrc = ./display; pbuildInputs = [ (packages."x86_64-linux"."dio" { inherit gcc cflags; }) (packages."x86_64-linux"."shift-register" { inherit gcc cflags; }) ]; }; packages."x86_64-linux"."prime-tx" = { gcc, cflags }: let pkgs = import nixpkgs { system = "x86_64-linux"; }; in mkProgram { pkgs = pkgs; gcc = gcc; cflags = cflags; pname = "prime-tx"; psrc = ./prime-tx; pbuildInputs = [ (packages."x86_64-linux"."dio" { inherit gcc cflags; }) (packages."x86_64-linux"."spi" { inherit gcc cflags; }) (packages."x86_64-linux"."shift-register" { inherit gcc cflags; }) (packages."x86_64-linux"."rfm" { inherit gcc cflags; }) (packages."x86_64-linux"."display" { inherit gcc cflags; }) ]; }; packages."x86_64-linux"."radio-rx" = { gcc, cflags }: let pkgs = import nixpkgs { system = "x86_64-linux"; }; in mkProgram { pkgs = pkgs; gcc = gcc; cflags = cflags; pname = "radio-rx"; psrc = ./radio-rx; pbuildInputs = [ (packages."x86_64-linux"."dio" { inherit gcc cflags; }) (packages."x86_64-linux"."spi" { inherit gcc cflags; }) (packages."x86_64-linux"."shift-register" { inherit gcc cflags; }) (packages."x86_64-linux"."rfm" { inherit gcc cflags; }) (packages."x86_64-linux"."display" { inherit gcc cflags; }) ]; }; packages."x86_64-linux"."lantern_" = let pkgs = import nixpkgs { system = "x86_64-linux"; }; avr = pkgs.pkgsCross.avr.buildPackages; in packages."x86_64-linux"."lantern" { gcc = "${avr.gcc}/bin/avr-gcc"; cflags = mcu_cflags atmega32u4; }; packages."x86_64-linux"."lantern" = { gcc, cflags, avr }: let pkgs = import nixpkgs { system = "x86_64-linux"; }; in mkProgram { pkgs = pkgs; gcc = gcc; cflags = cflags; pname = "lantern"; psrc = ./lantern; inherit avr; pbuildInputs = [ (packages."x86_64-linux"."animation" { inherit gcc cflags; }) (packages."x86_64-linux"."dio" { inherit gcc cflags; }) (packages."x86_64-linux"."display" { inherit gcc cflags; }) (packages."x86_64-linux"."rfm" { inherit gcc cflags; }) (packages."x86_64-linux"."shift-register" { inherit gcc cflags; }) (packages."x86_64-linux"."sk9822" { inherit gcc cflags; }) (packages."x86_64-linux"."spi" { inherit gcc cflags; }) ]; }; packages."x86_64-linux"."lantern-controller_" = let pkgs = import nixpkgs { system = "x86_64-linux"; }; avr = pkgs.pkgsCross.avr.buildPackages; in packages."x86_64-linux"."lantern-controller" { gcc = "${avr.gcc}/bin/avr-gcc"; cflags = mcu_cflags atmega32u4; avr = true; }; packages."x86_64-linux"."lantern-controller" = { gcc, cflags, avr }: let pkgs = import nixpkgs { system = "x86_64-linux"; }; in mkProgram { pkgs = pkgs; gcc = gcc; cflags = cflags; pname = "lantern-controller"; psrc = ./lantern-controller; inherit avr; pbuildInputs = [ (packages."x86_64-linux"."dio" { inherit gcc cflags; }) (packages."x86_64-linux"."spi" { inherit gcc cflags; }) (packages."x86_64-linux"."rfm" { inherit gcc cflags; }) ]; }; devShell."x86_64-linux" = let pkgs = import nixpkgs { system = "x86_64-linux"; }; avr = with pkgs.pkgsCross.avr.buildPackages; [ binutils gcc gdb avrdude simavr gtkwave ]; in pkgs.mkShell { name = "avr-shell"; buildInputs = avr; GCC = pkgs.pkgsCross.avr.buildPackages.gcc; SIMAVR = pkgs.pkgsCross.avr.buildPackages.simavr; }; }; }