summary refs log tree commit diff
path: root/pkgs/development/embedded
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2022-05-31 09:59:33 +0000
committerAlyssa Ross <hi@alyssa.is>2022-05-31 09:59:57 +0000
commit9ff36293d1e428cd7bf03e8d4b03611b6d361c28 (patch)
tree1ab51a42b868c55b83f6ccdb80371b9888739dd9 /pkgs/development/embedded
parent1c4fcd0d4b0541e674ee56ace1053e23e562cc80 (diff)
parentddc3c396a51918043bb0faa6f676abd9562be62c (diff)
downloadnixpkgs-archive.tar
nixpkgs-archive.tar.gz
nixpkgs-archive.tar.bz2
nixpkgs-archive.tar.lz
nixpkgs-archive.tar.xz
nixpkgs-archive.tar.zst
nixpkgs-archive.zip
Last good Nixpkgs for Weston+nouveau? archive
I came this commit hash to terwiz[m] on IRC, who is trying to figure out
what the last version of Spectrum that worked on their NUC with Nvidia
graphics is.
Diffstat (limited to 'pkgs/development/embedded')
-rw-r--r--pkgs/development/embedded/arduino/arduino-ci/default.nix45
-rw-r--r--pkgs/development/embedded/arduino/arduino-cli/default.nix55
-rw-r--r--pkgs/development/embedded/arduino/arduino-core/chrootenv.nix36
-rw-r--r--pkgs/development/embedded/arduino/arduino-core/default.nix250
-rw-r--r--pkgs/development/embedded/arduino/arduino-core/downloads.nix217
-rw-r--r--pkgs/development/embedded/arduino/arduino-mk/default.nix32
-rw-r--r--pkgs/development/embedded/avrdude/default.nix34
-rw-r--r--pkgs/development/embedded/blackmagic/default.nix78
-rwxr-xr-xpkgs/development/embedded/blackmagic/helper.sh52
-rw-r--r--pkgs/development/embedded/bossa/bin2c.c122
-rw-r--r--pkgs/development/embedded/bossa/bossa-no-applet-build.patch16
-rw-r--r--pkgs/development/embedded/bossa/default.nix53
-rw-r--r--pkgs/development/embedded/cc-tool/default.nix42
-rw-r--r--pkgs/development/embedded/easypdkprog/default.nix27
-rw-r--r--pkgs/development/embedded/elf2uf2-rs/default.nix31
-rw-r--r--pkgs/development/embedded/fpga/apio/default.nix74
-rw-r--r--pkgs/development/embedded/fpga/ecpdap/default.nix37
-rw-r--r--pkgs/development/embedded/fpga/fujprog/default.nix39
-rw-r--r--pkgs/development/embedded/fpga/icestorm/default.nix70
-rw-r--r--pkgs/development/embedded/fpga/lattice-diamond/default.nix117
-rw-r--r--pkgs/development/embedded/fpga/openfpgaloader/default.nix36
-rw-r--r--pkgs/development/embedded/fpga/tinyprog/default.nix43
-rw-r--r--pkgs/development/embedded/fpga/trellis/default.nix72
-rw-r--r--pkgs/development/embedded/gputils/default.nix19
-rw-r--r--pkgs/development/embedded/openocd/default.nix69
-rw-r--r--pkgs/development/embedded/platformio/chrootenv.nix45
-rw-r--r--pkgs/development/embedded/platformio/core.nix166
-rw-r--r--pkgs/development/embedded/platformio/default.nix21
-rw-r--r--pkgs/development/embedded/platformio/fix-searchpath.patch13
-rw-r--r--pkgs/development/embedded/platformio/missing-udev-rules-nixos.patch12
-rw-r--r--pkgs/development/embedded/platformio/use-local-spdx-license-list.patch17
-rw-r--r--pkgs/development/embedded/rshell/default.nix31
-rw-r--r--pkgs/development/embedded/stm32/betaflight/default.nix64
-rw-r--r--pkgs/development/embedded/stm32/inav/default.nix56
-rw-r--r--pkgs/development/embedded/stm32/stm32cubemx/default.nix71
-rw-r--r--pkgs/development/embedded/stm32/stm32flash/default.nix27
-rw-r--r--pkgs/development/embedded/teensy-loader-cli/default.nix46
-rw-r--r--pkgs/development/embedded/tytools/default.nix26
-rw-r--r--pkgs/development/embedded/uisp/default.nix20
-rw-r--r--pkgs/development/embedded/xc3sprog/default.nix26
40 files changed, 2307 insertions, 0 deletions
diff --git a/pkgs/development/embedded/arduino/arduino-ci/default.nix b/pkgs/development/embedded/arduino/arduino-ci/default.nix
new file mode 100644
index 00000000000..fe28a962e10
--- /dev/null
+++ b/pkgs/development/embedded/arduino/arduino-ci/default.nix
@@ -0,0 +1,45 @@
+{ lib, stdenv, fetchFromGitHub,  makeWrapper, arduino-cli, ruby, python3 }:
+
+let
+
+  runtimePath = lib.makeBinPath [
+    arduino-cli
+    python3 # required by the esp8266 core
+  ];
+
+in
+stdenv.mkDerivation rec {
+  pname = "arduino-ci";
+  version = "0.2.0";
+
+  src = fetchFromGitHub {
+    owner  = "pololu";
+    repo   = "arduino-ci";
+    rev    = "v${version}";
+    sha256 = "sha256-9RbBxgwsSQ7oGGKr1Vsn9Ug9AsacoRgvQgd9jbRQ034=";
+  };
+
+  nativeBuildInputs = [ makeWrapper ];
+
+  installPhase = ''
+    runHook preInstall
+
+    mkdir -p $out/bin
+    install $src/ci.rb $out/bin/arduino-ci
+
+    runHook postInstall
+  '';
+
+  fixupPhase = ''
+    substituteInPlace $out/bin/arduino-ci --replace "/usr/bin/env nix-shell" "${ruby}/bin/ruby"
+    wrapProgram $out/bin/arduino-ci --prefix PATH ":" "${runtimePath}"
+  '';
+
+  meta = with lib; {
+    description = "CI for Arduino Libraries";
+    homepage = src.meta.homepage;
+    license = licenses.mit;
+    maintainers = with maintainers; [ ryantm ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/pkgs/development/embedded/arduino/arduino-cli/default.nix b/pkgs/development/embedded/arduino/arduino-cli/default.nix
new file mode 100644
index 00000000000..dc463c9fc4d
--- /dev/null
+++ b/pkgs/development/embedded/arduino/arduino-cli/default.nix
@@ -0,0 +1,55 @@
+{ lib, stdenv, buildGoModule, fetchFromGitHub, buildFHSUserEnv }:
+
+let
+
+  pkg = buildGoModule rec {
+    pname = "arduino-cli";
+    version = "0.20.2";
+
+    src = fetchFromGitHub {
+      owner = "arduino";
+      repo = pname;
+      rev = version;
+      sha256 = "sha256-q2uaJTfCcS/kv6xU5NjafzfcM3TixJlH5KzgEpLJKkQ=";
+    };
+
+    subPackages = [ "." ];
+
+    vendorSha256 = "sha256-VWoKHIRQfs4dbsOzV3AQpqWsCPDm/rVKGMsc4xZvbhU=";
+
+    doCheck = false;
+
+    ldflags = [
+      "-s" "-w" "-X github.com/arduino/arduino-cli/version.versionString=${version}" "-X github.com/arduino/arduino-cli/version.commit=unknown"
+    ] ++ lib.optionals stdenv.isLinux [ "-extldflags '-static'" ];
+
+    meta = with lib; {
+      inherit (src.meta) homepage;
+      description = "Arduino from the command line";
+      license = licenses.gpl3Only;
+      maintainers = with maintainers; [ ryantm ];
+    };
+
+  };
+
+in
+if stdenv.isLinux then
+# buildFHSUserEnv is needed because the arduino-cli downloads compiler
+# toolchains from the internet that have their interpreters pointed at
+# /lib64/ld-linux-x86-64.so.2
+  buildFHSUserEnv
+  {
+    inherit (pkg) name meta;
+
+    runScript = "${pkg.outPath}/bin/arduino-cli";
+
+    extraInstallCommands = ''
+      mv $out/bin/$name $out/bin/arduino-cli
+    '';
+
+    targetPkgs = pkgs: with pkgs; [
+      zlib
+    ];
+  }
+else
+  pkg
diff --git a/pkgs/development/embedded/arduino/arduino-core/chrootenv.nix b/pkgs/development/embedded/arduino/arduino-core/chrootenv.nix
new file mode 100644
index 00000000000..4c13b2493a9
--- /dev/null
+++ b/pkgs/development/embedded/arduino/arduino-core/chrootenv.nix
@@ -0,0 +1,36 @@
+{ lib, buildFHSUserEnv, arduino-core-unwrapped, withGui ? false, withTeensyduino ? false }:
+let
+  arduino-unwrapped = arduino-core-unwrapped.override { inherit withGui withTeensyduino; };
+in
+buildFHSUserEnv {
+  name = "arduino";
+
+  targetPkgs =
+    pkgs: (with pkgs; [
+      ncurses
+      arduino-unwrapped
+      zlib
+      (python3.withPackages (p: with p; [
+        pyserial
+      ]))
+    ]);
+  multiPkgs = null;
+
+  extraInstallCommands = ''
+    ${lib.optionalString withGui ''
+      # desktop file
+      mkdir -p $out/share/applications
+      cp ${arduino-core-unwrapped.src}/build/linux/dist/desktop.template $out/share/applications/arduino.desktop
+      substituteInPlace $out/share/applications/arduino.desktop \
+        --replace '<BINARY_LOCATION>' "$out/bin/arduino" \
+        --replace '<ICON_NAME>' "$out/share/arduino/icons/128x128/apps/arduino.png"
+      # icon file
+      mkdir -p $out/share/arduino
+      cp -r ${arduino-core-unwrapped.src}/build/shared/icons $out/share/arduino
+    ''}
+  '';
+
+  runScript = "arduino";
+
+  meta = arduino-core-unwrapped.meta;
+}
diff --git a/pkgs/development/embedded/arduino/arduino-core/default.nix b/pkgs/development/embedded/arduino/arduino-core/default.nix
new file mode 100644
index 00000000000..71f3c884868
--- /dev/null
+++ b/pkgs/development/embedded/arduino/arduino-core/default.nix
@@ -0,0 +1,250 @@
+{ stdenv
+, lib
+, fetchFromGitHub
+, fetchurl
+, jdk
+, ant
+, libusb-compat-0_1
+, libusb1
+, unzip
+, zlib
+, ncurses
+, readline
+, withGui ? false
+, gtk3
+, wrapGAppsHook
+, withTeensyduino ? false
+  /* Packages needed for Teensyduino */
+, upx
+, fontconfig
+, xorg
+, gcc
+, atk
+, glib
+, pango
+, gdk-pixbuf
+, gtk2
+, libpng12
+, expat
+, freetype
+, cairo
+, udev
+}:
+
+assert withTeensyduino -> withGui;
+let
+  externalDownloads = import ./downloads.nix {
+    inherit fetchurl;
+    inherit (lib) optionalAttrs;
+    inherit (stdenv.hostPlatform) system;
+  };
+  # Some .so-files are later copied from .jar-s to $HOME, so patch them beforehand
+  patchelfInJars =
+    lib.optional (stdenv.hostPlatform.system == "aarch64-linux") { jar = "share/arduino/lib/jssc-2.8.0-arduino4.jar"; file = "libs/linux/libjSSC-2.8_aarch64.so"; }
+    ++ lib.optional (builtins.match "armv[67]l-linux" stdenv.hostPlatform.system != null) { jar = "share/arduino/lib/jssc-2.8.0-arduino4.jar"; file = "libs/linux/libjSSC-2.8_armhf.so"; }
+    ++ lib.optional (stdenv.hostPlatform.system == "x86_64-linux") { jar = "share/arduino/lib/jssc-2.8.0-arduino4.jar"; file = "libs/linux/libjSSC-2.8_x86_64.so"; }
+    ++ lib.optional (stdenv.hostPlatform.system == "i686-linux") { jar = "share/arduino/lib/jssc-2.8.0-arduino4.jar"; file = "libs/linux/libjSSC-2.8_x86.so"; }
+  ;
+  # abiVersion 6 is default, but we need 5 for `avrdude_bin` executable
+  ncurses5 = ncurses.override { abiVersion = "5"; };
+  teensy_libpath = lib.makeLibraryPath [
+    atk
+    cairo
+    expat
+    fontconfig
+    freetype
+    gcc.cc.lib
+    gdk-pixbuf
+    glib
+    gtk2
+    libpng12
+    libusb-compat-0_1
+    pango
+    udev
+    xorg.libSM
+    xorg.libX11
+    xorg.libXext
+    xorg.libXft
+    xorg.libXinerama
+    xorg.libXxf86vm
+    zlib
+  ];
+  teensy_architecture =
+    if stdenv.hostPlatform.isx86_32 then "linux32"
+    else if stdenv.hostPlatform.isx86_64 then "linux64"
+    else if stdenv.hostPlatform.isAarch64 then "linuxaarch64"
+    else if stdenv.hostPlatform.isAarch32 then "linuxarm"
+    else throw "${stdenv.hostPlatform.system} is not supported in teensy";
+
+in
+stdenv.mkDerivation rec {
+  pname = (if withTeensyduino then "teensyduino" else "arduino") + lib.optionalString (!withGui) "-core";
+  version = "1.8.19";
+
+  src = fetchFromGitHub {
+    owner = "arduino";
+    repo = "Arduino";
+    rev = version;
+    sha256 = "sha256-I+PvfGc5F8H/NJOGRa18z7dKyKcO8I8Cg7Tj5yxkYAQ=";
+  };
+
+  teensyduino_version = "156";
+  teensyduino_src = fetchurl {
+    url = "https://www.pjrc.com/teensy/td_${teensyduino_version}/TeensyduinoInstall.${teensy_architecture}";
+    sha256 = {
+      linux64 = "sha256-4DbhmmYrx+rCBpDrYFaC0A88Qv9UEeNlQAkFi3zAstk=";
+      linux32 = "sha256-DlRPOtDxmMPv2Qzhib7vNZdKNZCxmm9YmVNnwUKXK/E=";
+      linuxarm = "sha256-d+DbpER/4lFPcPDFeMG5f3WaUGn8pFchdIDo7Hm0XWs=";
+      linuxaarch64 = "sha256-8keQzhWq7QlAGIbfHEe3lfxpJleMMvBORuPaNrLmM6Y=";
+    }.${teensy_architecture} or (throw "No arduino binaries for ${teensy_architecture}");
+  };
+  # Used because teensyduino requires jars be a specific size
+  arduino_dist_src = fetchurl {
+    url = "https://downloads.arduino.cc/arduino-${version}-${teensy_architecture}.tar.xz";
+    sha256 = {
+      linux64 = "sha256-62i93B0cASC+L8oTUKA+40Uxzzf1GEeyEhC25wVFvJs=";
+      linux32 = "sha256-wSxtx3BqXMQCeWQDK8PHkWLlQqQM1Csao8bIk98FrFg=";
+      linuxarm = "sha256-lJ/R1ePq7YtDk3bvloFcn8jswrJH+L63tvH5QpTqfXs=";
+      linuxaarch64 = "sha256-gm8cDjLKNfpcaeO7fw6Kyv1TnWV/ZmH4u++nun9X6jo=";
+    }.${teensy_architecture} or (throw "No arduino binaries for ${teensy_architecture}");
+  };
+
+  # the glib setup hook will populate GSETTINGS_SCHEMAS_PATH,
+  # wrapGAppHooks (among other things) adds it to XDG_DATA_DIRS
+  # so 'save as...' works:
+  nativeBuildInputs = [ glib wrapGAppsHook unzip ];
+  buildInputs = [
+    jdk
+    ant
+    libusb-compat-0_1
+    libusb1
+    zlib
+    ncurses5
+    readline
+  ] ++ lib.optionals withTeensyduino [ upx ];
+  downloadSrcList = builtins.attrValues externalDownloads;
+  downloadDstList = builtins.attrNames externalDownloads;
+
+  buildPhase = ''
+    # Copy pre-downloaded files to proper locations
+    download_src=($downloadSrcList)
+    download_dst=($downloadDstList)
+    while [[ "''${#download_src[@]}" -ne 0 ]]; do
+      file_src=''${download_src[0]}
+      file_dst=''${download_dst[0]}
+      mkdir -p $(dirname $file_dst)
+      download_src=(''${download_src[@]:1})
+      download_dst=(''${download_dst[@]:1})
+      cp -v $file_src $file_dst
+    done
+
+    # Deliberately break build.xml's download statement in order to cause
+    # an error if anything needed is missing from download.nix.
+    substituteInPlace build/build.xml \
+      --replace 'ignoreerrors="true"' 'ignoreerrors="false"'
+
+    cd ./arduino-core && ant
+    cd ../build && ant
+    cd ..
+  '';
+
+  # This will be patched into `arduino` wrapper script
+  # Java loads gtk dynamically, so we need to provide it using LD_LIBRARY_PATH
+  dynamicLibraryPath = lib.makeLibraryPath [ gtk3 ];
+  javaPath = lib.makeBinPath [ jdk ];
+
+  # Everything else will be patched into rpath
+  rpath = lib.makeLibraryPath [ zlib libusb-compat-0_1 libusb1 readline ncurses5 stdenv.cc.cc ];
+
+  installPhase = ''
+    mkdir -p $out/share/arduino
+    cp -r ./build/linux/work/* "$out/share/arduino/"
+    echo -n ${version} > $out/share/arduino/lib/version.txt
+
+    ${lib.optionalString withGui ''
+      mkdir -p $out/bin
+      substituteInPlace $out/share/arduino/arduino \
+        --replace "JAVA=java" "JAVA=$javaPath/java" \
+        --replace "LD_LIBRARY_PATH=" "LD_LIBRARY_PATH=$dynamicLibraryPath:"
+      ln -sr "$out/share/arduino/arduino" "$out/bin/arduino"
+
+      cp -r build/shared/icons $out/share/arduino
+      mkdir -p $out/share/applications
+      cp build/linux/dist/desktop.template $out/share/applications/arduino.desktop
+      substituteInPlace $out/share/applications/arduino.desktop \
+        --replace '<BINARY_LOCATION>' "$out/bin/arduino" \
+        --replace '<ICON_NAME>' "$out/share/arduino/icons/128x128/apps/arduino.png"
+    ''}
+
+    ${lib.optionalString withTeensyduino ''
+      # Back up the original jars
+      mv $out/share/arduino/lib/arduino-core.jar $out/share/arduino/lib/arduino-core.jar.bak
+      mv $out/share/arduino/lib/pde.jar $out/share/arduino/lib/pde.jar.bak
+      # Extract jars from the arduino distributable package
+      mkdir arduino_dist
+      cd arduino_dist
+      tar xfJ ${arduino_dist_src} arduino-${version}/lib/arduino-core.jar arduino-${version}/lib/pde.jar
+      cd ..
+      # Replace the built jars with the official arduino jars
+      mv arduino_dist/arduino-${version}/lib/{arduino-core,pde}.jar $out/share/arduino/lib/
+      # Delete the directory now that the jars are copied out
+      rm -r arduino_dist
+      # Extract and patch the Teensyduino installer
+      cp ${teensyduino_src} ./TeensyduinoInstall.${teensy_architecture}
+      chmod +w ./TeensyduinoInstall.${teensy_architecture}
+      upx -d ./TeensyduinoInstall.${teensy_architecture}
+      patchelf --set-interpreter $(cat $NIX_CC/nix-support/dynamic-linker) \
+        --set-rpath "${teensy_libpath}" \
+        ./TeensyduinoInstall.${teensy_architecture}
+      chmod +x ./TeensyduinoInstall.${teensy_architecture}
+      ./TeensyduinoInstall.${teensy_architecture} --dir=$out/share/arduino
+      # Check for successful installation
+      [ -d $out/share/arduino/hardware/teensy ] || exit 1
+      # After the install, copy the built jars back
+      mv $out/share/arduino/lib/arduino-core.jar.bak $out/share/arduino/lib/arduino-core.jar
+      mv $out/share/arduino/lib/pde.jar.bak $out/share/arduino/lib/pde.jar
+    ''}
+  '';
+
+  # So we don't accidentally mess with firmware files
+  dontStrip = true;
+  dontPatchELF = true;
+
+  preFixup = ''
+    for file in $(find $out -type f \( -perm /0111 -o -name \*.so\* \) ); do
+      patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" "$file" || true
+      patchelf --set-rpath ${rpath}:$out/lib $file || true
+    done
+
+    ${lib.concatMapStringsSep "\n"
+      ({ jar, file }:
+          ''
+            jar xvf $out/${jar} ${file}
+            patchelf --set-rpath $rpath ${file}
+            jar uvf $out/${jar} ${file}
+            rm -f ${file}
+          ''
+        )
+      patchelfInJars}
+
+    # avrdude_bin is linked against libtinfo.so.5
+    mkdir $out/lib/
+    ln -s ${lib.makeLibraryPath [ ncurses5 ]}/libtinfo.so.5 $out/lib/libtinfo.so.5
+
+    ${lib.optionalString withTeensyduino ''
+      # Patch the Teensy loader binary
+      patchelf --debug \
+        --set-interpreter $(cat $NIX_CC/nix-support/dynamic-linker) \
+        --set-rpath "${teensy_libpath}" \
+        $out/share/arduino/hardware/tools/teensy{,_ports,_reboot,_restart,_serialmon}
+    ''}
+  '';
+
+  meta = with lib; {
+    description = "Open-source electronics prototyping platform";
+    homepage = "https://www.arduino.cc/";
+    license = if withTeensyduino then licenses.unfreeRedistributable else licenses.gpl2;
+    platforms = platforms.linux;
+    maintainers = with maintainers; [ antono auntie robberer bjornfor bergey ];
+  };
+}
diff --git a/pkgs/development/embedded/arduino/arduino-core/downloads.nix b/pkgs/development/embedded/arduino/arduino-core/downloads.nix
new file mode 100644
index 00000000000..14ce93d2c50
--- /dev/null
+++ b/pkgs/development/embedded/arduino/arduino-core/downloads.nix
@@ -0,0 +1,217 @@
+{ fetchurl
+, optionalAttrs
+, system
+}:
+# This file preloads all the archives which Arduino's build/build.xml
+# would otherwise try to download itself. When updating this for a new
+# version of Arduino, check build.xml for version numbers and new
+# urls.
+{
+  "build/shared/reference-1.6.6-3.zip" = fetchurl {
+    url = "https://downloads.arduino.cc/reference-1.6.6-3.zip";
+    sha256 = "119nj1idz85l71fy6a6wwsx0mcd8y0ib1wy0l6j9kz88nkwvggy3";
+  };
+  "build/shared/Galileo_help_files-1.6.2.zip" = fetchurl {
+    url = "https://downloads.arduino.cc/Galileo_help_files-1.6.2.zip";
+    sha256 = "0qda0xml353sfhjmx9my4mlcyzbf531k40dcr1cnsa438xp2fw0w";
+  };
+  "build/shared/Edison_help_files-1.6.2.zip" = fetchurl {
+    url = "https://downloads.arduino.cc/Edison_help_files-1.6.2.zip";
+    sha256 = "1x25rivmh0zpa6lr8dafyxvim34wl3wnz3r9msfxg45hnbjqqwan";
+  };
+  "build/Ethernet-2.0.0.zip" = fetchurl {
+    url = "https://github.com/arduino-libraries/Ethernet/archive/2.0.0.zip";
+    sha256 = "0had46c1n1wx9fa7ki5dwidvchiy00pv7qj9msp6wgv199vm19m8";
+  };
+  "build/GSM-1.0.6.zip" = fetchurl {
+    url = "https://github.com/arduino-libraries/GSM/archive/1.0.6.zip";
+    sha256 = "1kmikxr07cyzsnhhymvgj9m4dxi671ni120l33gfmmm6079qfwbk";
+  };
+  "build/Stepper-1.1.3.zip" = fetchurl {
+    url = "https://github.com/arduino-libraries/Stepper/archive/1.1.3.zip";
+    sha256 = "1kyv6bmhmbjh7z8x77v04aywd2s54nm80g0j07gay2sa3f6k1p4v";
+  };
+  "build/TFT-1.0.6.zip" = fetchurl {
+    url = "https://github.com/arduino-libraries/TFT/archive/1.0.6.zip";
+    sha256 = "1d69xp3hrva58nrx0vy4skrr1h63649q1jnc2g55bpbaxjhf5j5w";
+  };
+  "build/WiFi-1.2.7.zip" = fetchurl {
+    url = "https://github.com/arduino-libraries/WiFi/archive/1.2.7.zip";
+    sha256 = "1fmj2q2672hivp5jn05xhc875ii3w54nfja3b1yrp8s2fwinh7f6";
+  };
+  "build/Firmata-2.5.8.zip" = fetchurl {
+    url = "https://github.com/firmata/arduino/archive/2.5.8.zip";
+    sha256 = "0jmlqrnw5fksyqkjhcsl6j1q7c0clnvfr8yknanqqssc19pxp722";
+  };
+  "build/Bridge-1.7.0.zip" = fetchurl {
+    url = "https://github.com/arduino-libraries/Bridge/archive/1.7.0.zip";
+    sha256 = "1qpnb2mj77jm4qczk1ndgjc9j2kqxnyahxdvlp0120x6w2jcq8s8";
+  };
+  "build/Robot_Control-1.0.4.zip" = fetchurl {
+    url = "https://github.com/arduino-libraries/Robot_Control/archive/1.0.4.zip";
+    sha256 = "1pkabrghx3h8l60x571vwkbhfm02nhyn5x2vqz4vhx9cczr70zq7";
+  };
+  "build/Robot_Motor-1.0.3.zip" = fetchurl {
+    url = "https://github.com/arduino-libraries/Robot_Motor/archive/1.0.3.zip";
+    sha256 = "1pkvrimg77jrhdsz4l81y59hv50h6cl7hvhk9w8ac7ckg70lvxkw";
+  };
+  "build/RobotIRremote-2.0.0.zip" = fetchurl {
+    url = "https://github.com/arduino-libraries/RobotIRremote/archive/2.0.0.zip";
+    sha256 = "0j5smap74j8p3wc6k0h73b1skj4gkr7r25jbjh1j1cg052dxri86";
+  };
+  "build/SpacebrewYun-1.0.2.zip" = fetchurl {
+    url = "https://github.com/arduino-libraries/SpacebrewYun/archive/1.0.2.zip";
+    sha256 = "1d8smmsx12qhf2ldvmi93h48cvdyz4id5gd68cvf076wfyv6dks8";
+  };
+  "build/Temboo-1.2.1.zip" = fetchurl {
+    url = "https://github.com/arduino-libraries/Temboo/archive/1.2.1.zip";
+    sha256 = "1fyzfihsbcjpjasqbmbbfcall2zl48nzrp4xk9pslppal31mvl8x";
+  };
+  "build/Esplora-1.0.4.zip" = fetchurl {
+    url = "https://github.com/arduino-libraries/Esplora/archive/1.0.4.zip";
+    sha256 = "1dflfrg38f0312nxn6wkkgq1ql4hx3y9kplalix6mkqmzwrdvna4";
+  };
+  "build/Mouse-1.0.1.zip" = fetchurl {
+    url = "https://github.com/arduino-libraries/Mouse/archive/1.0.1.zip";
+    sha256 = "106jjqxzpf5lrs9akwvamqsblj5w2fb7vd0wafm9ihsikingiypr";
+  };
+  "build/Keyboard-1.0.2.zip" = fetchurl {
+    url = "https://github.com/arduino-libraries/Keyboard/archive/1.0.2.zip";
+    sha256 = "17yfj95r1i7fb87q4krmxmaq07b4x2xf8cjngrj5imj68wgjck53";
+  };
+  "build/SD-1.2.4.zip" = fetchurl {
+    url = "https://github.com/arduino-libraries/SD/archive/1.2.4.zip";
+    sha256 = "123g9px9nqcrsx696wqwzjd5s4hr55nxgfz95b7ws3v007i1f3fz";
+  };
+  "build/Servo-1.1.8.zip" = fetchurl {
+    url = "https://github.com/arduino-libraries/Servo/archive/1.1.8.zip";
+    sha256 = "sha256-8mfRQG/HIRVvdiRApjMib6n1ENqAB63vGsxe6vwndeU=";
+  };
+  "build/LiquidCrystal-1.0.7.zip" = fetchurl {
+    url = "https://github.com/arduino-libraries/LiquidCrystal/archive/1.0.7.zip";
+    sha256 = "1wrxrqz3n4yrj9j1a2b7pdd7a1rlyi974ra7crv5amjng8817x9n";
+  };
+  "build/Adafruit_Circuit_Playground-1.11.3.zip" = fetchurl {
+    url = "https://github.com/adafruit/Adafruit_CircuitPlayground/archive/1.11.3.zip";
+    sha256 = "sha256-YL4ZAi9Fno+rG/bAdjxnXIglfZnbN6KpXFpj23Bf3LQ=";
+  };
+  "build/libastylej-2.05.1-5.zip" = fetchurl {
+    url = "https://downloads.arduino.cc/libastylej-2.05.1-5.zip";
+    sha256 = "11mlprwvqfq3nvmz6hdf1fcg02a7xi2a9qhffa1d8a4w15s2iwny";
+  };
+  "build/liblistSerials-1.4.2-2.zip" = fetchurl {
+    url = "https://downloads.arduino.cc/liblistSerials/liblistSerials-1.4.2-2.zip";
+    sha256 = "0sqzwp1lfjy452z3d4ma5c4blwsj7za72ymxf7crpq9dh9qd8f53";
+  };
+  "build/shared/WiFi101-Updater-ArduinoIDE-Plugin-0.12.0.zip" = fetchurl {
+    url = "https://github.com/arduino-libraries/WiFi101-FirmwareUpdater-Plugin/releases/download/v0.12.0/WiFi101-Updater-ArduinoIDE-Plugin-0.12.0.zip";
+    sha256 = "sha256-6RM7Sr/tk5PVeonhzaa6WvRaz+7av+MhSYKPAinaOkg=";
+  };
+  "build/avr-1.8.3.tar.bz2" = fetchurl {
+    url = "https://downloads.arduino.cc/cores/avr-1.8.3.tar.bz2";
+    sha256 = "051wnc0nmsmxvvs4c79zvjag33yx5il2pz2j7qyjsxkp4jc9p2ny";
+  };
+  "build/arduino-examples-1.9.1.zip" = fetchurl {
+    url = "https://github.com/arduino/arduino-examples/archive/refs/tags/1.9.1.zip";
+    sha256 = "sha256-kAxIhYQ8P2ULTzQwi6bUXXEXJ53mKNgQxuwX3QYhNoQ=";
+  };
+}
+
+// optionalAttrs (system == "x86_64-linux") {
+  "build/arduino-builder-linux64-1.6.1.tar.bz2" = fetchurl {
+    url = "https://downloads.arduino.cc/tools/arduino-builder-linux64-1.6.1.tar.bz2";
+    sha256 = "sha256-QUHuC+rE5vrMX8+Bkfuw+59UQdJAekeoaZd1Mch7UXE=";
+  };
+  "build/linux/avr-gcc-7.3.0-atmel3.6.1-arduino7-x86_64-pc-linux-gnu.tar.bz2" = fetchurl {
+    url = "https://downloads.arduino.cc/tools/avr-gcc-7.3.0-atmel3.6.1-arduino7-x86_64-pc-linux-gnu.tar.bz2";
+    sha256 = "07nrzv7gsq7bi7ichlw3xsdvgzk0lvv56b73ksn3089ajpv3g35x";
+  };
+  "build/linux/avrdude-6.3.0-arduino17-x86_64-pc-linux-gnu.tar.bz2" = fetchurl {
+    url = "https://downloads.arduino.cc/tools/avrdude-6.3.0-arduino17-x86_64-pc-linux-gnu.tar.bz2";
+    sha256 = "0gfic26af9vlcpkw8v914psn05vmq1rsrlk1fi7vzapj1a9gpkdc";
+  };
+  "build/linux/arduinoOTA-1.3.0-linux_amd64.tar.bz2" = fetchurl {
+    url = "https://downloads.arduino.cc/tools/arduinoOTA-1.3.0-linux_amd64.tar.bz2";
+    sha256 = "1ylz4pfa9np0nn0w9igmmm3sr8hz3na04n7cv8ia3hzz84jfwida";
+  };
+}
+
+// optionalAttrs (system == "i686-linux") {
+  "build/arduino-builder-linux32-1.6.1.tar.bz2" = fetchurl {
+    url = "https://downloads.arduino.cc/tools/arduino-builder-linux32-1.6.1.tar.bz2";
+    sha256 = "sha256-GX2oGUGYYyatLroASBCBOGjsdCws06907O+O5Rz7Kls=";
+  };
+  "build/linux/avr-gcc-7.3.0-atmel3.6.1-arduino5-i686-pc-linux-gnu.tar.bz2" = fetchurl {
+    url = "https://downloads.arduino.cc/tools/avr-gcc-7.3.0-atmel3.6.1-arduino5-i686-pc-linux-gnu.tar.bz2";
+    sha256 = "078f3rbpdrghk63mbaq73bd5p6znimp14b1wdf6nh2gdswwjgw9g";
+  };
+  "build/linux/avrdude-6.3.0-arduino17-i686-pc-linux-gnu.tar.bz2" = fetchurl {
+    url = "https://downloads.arduino.cc/tools/avrdude-6.3.0-arduino17-i686-pc-linux-gnu.tar.bz2";
+    sha256 = "0py0jvpim0frmv0dnvzfj122ni5hg1qwshgya4a0wc5rgp0wd32w";
+  };
+  "build/linux/arduinoOTA-1.3.0-linux_386.tar.bz2" = fetchurl {
+    url = "https://downloads.arduino.cc/tools/arduinoOTA-1.3.0-linux_386.tar.bz2";
+    sha256 = "1cl79019ldsq0sc3fd4pm0vx2kqcklld7w03hdcj99y7zgb5jzry";
+  };
+}
+
+// optionalAttrs (system == "x86_64-darwin") {
+  "build/arduino-builder-macosx-1.6.1-signed.tar.bz2" = fetchurl {
+    url = "https://downloads.arduino.cc/tools/arduino-builder-macosx-1.6.1-signed.tar.bz2";
+    sha256 = "sha256-icMXwovzT2UQAKry9sWyRvcNxPXaFdltAPyW/DDVEFA=";
+  };
+  "build/macosx/avr-gcc-7.3.0-atmel3.6.1-arduino5-x86_64-apple-darwin14-signed.tar.bz2" = fetchurl {
+    url = "https://downloads.arduino.cc/tools/avr-gcc-7.3.0-atmel3.6.1-arduino5-x86_64-apple-darwin14-signed.tar.bz2";
+    sha256 = "0lcnp525glnc2chcynnz2nllm4q6ar4n9nrjqd1jbj4m706zbv67";
+  };
+  "build/macosx/avrdude-6.3.0-arduino17-x86_64-apple-darwin12-signed.tar.bz2" = fetchurl {
+    url = "https://downloads.arduino.cc/tools/avrdude-6.3.0-arduino17-x86_64-apple-darwin12-signed.tar.bz2";
+    sha256 = "1m24dci8mjf70yrf033mp1834pbp870m8sns2jxs3iy2i4qviiki";
+  };
+  "build/linux/arduinoOTA-1.3.0-darwin_amd64-signed.tar.bz2" = fetchurl {
+    url = "https://downloads.arduino.cc/tools/arduinoOTA-1.3.0-darwin_amd64-signed.tar.bz2";
+    sha256 = "12pwfnikq3z3ji5wgjhzx1mfyaha5cym7mr63r8kfl5a85fhk8nz";
+  };
+  "build/macosx/appbundler/appbundler-1.0ea-arduino5.jar.zip" = fetchurl {
+    url = "https://downloads.arduino.cc/appbundler-1.0ea-arduino5.jar.zip";
+    sha256 = "1ims951z7ajprqms7yd8ll83c79n7krhd9ljw30yn61f6jk46x82";
+  };
+}
+
+// optionalAttrs (system == "aarch64-linux") {
+  "build/arduino-builder-linuxaarch64-1.6.1.tar.bz2" = fetchurl {
+    url = "https://downloads.arduino.cc/tools/arduino-builder-linuxaarch64-1.6.1.tar.bz2";
+    sha256 = "sha256-BLcAIvGt0OQfjN87W1aLpLAQchhdFHoBqJPCcIWyHxQ=";
+  };
+  "build/linux/avr-gcc-7.3.0-atmel3.6.1-arduino7-aarch64-pc-linux-gnu.tar.bz2" = fetchurl {
+    url = "https://downloads.arduino.cc/tools/avr-gcc-7.3.0-atmel3.6.1-arduino7-aarch64-pc-linux-gnu.tar.bz2";
+    sha256 = "sha256-A9Miud9toXKJ6efGIzw0qFNdnGRcGe/HcroZ5WkU8zk=";
+  };
+  "build/linux/avrdude-6.3.0-arduino17-aarch64-pc-linux-gnu.tar.bz2" = fetchurl {
+    url = "https://downloads.arduino.cc/tools/avrdude-6.3.0-arduino17-aarch64-pc-linux-gnu.tar.bz2";
+    sha256 = "1z59dx2j2j4675awjzag9fswhvkn3hlz4ds5d2b7pzmca7vliybc";
+  };
+  "build/linux/arduinoOTA-1.3.0-linux_aarch64.tar.bz2" = fetchurl {
+    url = "https://downloads.arduino.cc/tools/arduinoOTA-1.3.0-linux_aarch64.tar.bz2";
+    sha256 = "04s1is2w8xhvc7lg0lmyk0yjsnar2l2gdc6ig7lkgb7zgkrxhpl3";
+  };
+}
+
+// optionalAttrs (builtins.match "armv[67]l-linux" system != null) {
+  "build/arduino-builder-linuxarm-1.6.1.tar.bz2" = fetchurl {
+    url = "https://downloads.arduino.cc/tools/arduino-builder-linuxarm-1.6.1.tar.bz2";
+    sha256 = "sha256-VtJxhRaOOKdBxmTWjTYnSPAXl728hMksBKSKS49qiMU=";
+  };
+  "build/linux/avr-gcc-7.3.0-atmel3.6.1-arduino5-arm-linux-gnueabihf.tar.bz2" = fetchurl {
+    url = "https://downloads.arduino.cc/tools/avr-gcc-7.3.0-atmel3.6.1-arduino5-arm-linux-gnueabihf.tar.bz2";
+    sha256 = "0fcn0s0fdgbz3yma2gjv16s1idrzn6nhmypdw8awg0kb3i9xbb7l";
+  };
+  "build/linux/avrdude-6.3.0-arduino17-armhf-pc-linux-gnu.tar.bz2" = fetchurl {
+    url = "https://downloads.arduino.cc/tools/avrdude-6.3.0-arduino17-armhf-pc-linux-gnu.tar.bz2";
+    sha256 = "1lah9wvwvliajrrf5jw5blkjhk1sxivz26gj5s86zah3v32ni3ia";
+  };
+  "build/linux/arduinoOTA-1.3.0-linux_arm.tar.bz2" = fetchurl {
+    url = "https://downloads.arduino.cc/tools/arduinoOTA-1.3.0-linux_arm.tar.bz2";
+    sha256 = "0mm6spjlg0lhkfx5c9q27b6agjywnc1nf3mbl15yysmm15s5i20q";
+  };
+}
diff --git a/pkgs/development/embedded/arduino/arduino-mk/default.nix b/pkgs/development/embedded/arduino/arduino-mk/default.nix
new file mode 100644
index 00000000000..d5f506038ca
--- /dev/null
+++ b/pkgs/development/embedded/arduino/arduino-mk/default.nix
@@ -0,0 +1,32 @@
+{ stdenv, lib, fetchFromGitHub, python3Packages, installShellFiles }:
+
+stdenv.mkDerivation rec {
+  version = "1.6.0";
+  pname = "arduino-mk";
+
+  src = fetchFromGitHub {
+    owner  = "sudar";
+    repo   = "Arduino-Makefile";
+    rev    = version;
+    sha256 = "0flpl97d2231gp51n3y4qvf3y1l8xzafi1sgpwc305vwc2h4dl2x";
+  };
+
+  nativeBuildInputs = [ python3Packages.wrapPython installShellFiles ];
+  propagatedBuildInputs = with python3Packages; [ pyserial ];
+  installPhase = ''
+    mkdir $out
+    cp -rT $src $out
+    installManPage *.1
+  '';
+  postFixupPhase = ''
+    wrapPythonPrograms
+  '';
+
+  meta = with lib; {
+    description = "Makefile for Arduino sketches";
+    homepage = "https://github.com/sudar/Arduino-Makefile";
+    license = licenses.lgpl21;
+    maintainers = [ maintainers.eyjhb ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/pkgs/development/embedded/avrdude/default.nix b/pkgs/development/embedded/avrdude/default.nix
new file mode 100644
index 00000000000..995af6bb92b
--- /dev/null
+++ b/pkgs/development/embedded/avrdude/default.nix
@@ -0,0 +1,34 @@
+{ lib, stdenv, fetchurl, bison, flex, libusb-compat-0_1, libelf, libftdi1, readline
+# docSupport is a big dependency, disabled by default
+, docSupport ? false, texLive ? null, texinfo ? null, texi2html ? null
+}:
+
+assert docSupport -> texLive != null && texinfo != null && texi2html != null;
+
+stdenv.mkDerivation rec {
+  pname = "avrdude";
+  version = "6.4";
+
+  src = fetchurl {
+    url = "mirror://savannah/${pname}/${pname}-${version}.tar.gz";
+    sha256 = "sha256-qb5wZvcKnc9L8HNvz1MdtqMlCu0aJMxkOt0nZBtxEPk=";
+  };
+
+  configureFlags = lib.optionals docSupport "--enable-doc";
+
+  buildInputs = [ bison flex libusb-compat-0_1 libelf libftdi1 readline ]
+    ++ lib.optionals docSupport [ texLive texinfo texi2html ];
+
+  meta = with lib; {
+    description = "Command-line tool for programming Atmel AVR microcontrollers";
+    longDescription = ''
+      AVRDUDE (AVR Downloader/UploaDEr) is an utility to
+      download/upload/manipulate the ROM and EEPROM contents of AVR
+      microcontrollers using the in-system programming technique (ISP).
+    '';
+    homepage = "https://www.nongnu.org/avrdude/";
+    license = licenses.gpl2Plus;
+    platforms = with platforms; linux ++ darwin;
+    maintainers = [ maintainers.bjornfor ];
+  };
+}
diff --git a/pkgs/development/embedded/blackmagic/default.nix b/pkgs/development/embedded/blackmagic/default.nix
new file mode 100644
index 00000000000..f3b3b0b2d04
--- /dev/null
+++ b/pkgs/development/embedded/blackmagic/default.nix
@@ -0,0 +1,78 @@
+{ stdenv, lib, fetchFromGitHub, fetchpatch
+, gcc-arm-embedded, libftdi1, libusb-compat-0_1, pkg-config
+, python3
+}:
+
+with lib;
+
+stdenv.mkDerivation rec {
+  pname = "blackmagic";
+  version = "unstable-2020-08-05";
+  # `git describe --always`
+  firmwareVersion = "v1.6.1-539-gdd74ec8";
+
+  src = fetchFromGitHub {
+    owner = "blacksphere";
+    repo = "blackmagic";
+    rev = "dd74ec8e6f734302daa1ee361af88dfb5043f166";
+    sha256 = "18w8y64fs7wfdypa4vm3migk5w095z8nbd8qp795f322mf2bz281";
+    fetchSubmodules = true;
+  };
+
+  patches = [
+    # Fix deprecation warning with libftdi 1.5
+    (fetchpatch {
+      url = "https://github.com/blacksphere/blackmagic/commit/dea4be2539c5ea63836ec78dca08b52fa8b26ab5.patch";
+      sha256 = "0f81simij1wdhifsxaavalc6yxzagfbgwry969dbjmxqzvrsrds5";
+    })
+  ];
+
+  nativeBuildInputs = [
+    gcc-arm-embedded pkg-config
+    python3
+  ];
+
+  buildInputs = [
+    libftdi1
+    libusb-compat-0_1
+  ];
+
+  strictDeps = true;
+
+  postPatch = ''
+    # Prevent calling out to `git' to generate a version number:
+    substituteInPlace src/Makefile \
+      --replace '$(shell git describe --always --dirty)' '${firmwareVersion}'
+
+    # Fix scripts that generate headers:
+    for f in $(find scripts libopencm3/scripts -type f); do
+      patchShebangs "$f"
+    done
+  '';
+
+  buildPhase = "${stdenv.shell} ${./helper.sh}";
+  dontInstall = true;
+
+  enableParallelBuilding = true;
+
+  meta = {
+    description = "In-application debugger for ARM Cortex microcontrollers";
+    longDescription = ''
+      The Black Magic Probe is a modern, in-application debugging tool
+      for embedded microprocessors. It allows you to see what is going
+      on "inside" an application running on an embedded microprocessor
+      while it executes.
+
+      This package builds the firmware for all supported platforms,
+      placing them in separate directories under the firmware
+      directory.  It also places the FTDI version of the blackmagic
+      executable in the bin directory.
+    '';
+    homepage = "https://github.com/blacksphere/blackmagic";
+    license = licenses.gpl3Plus;
+    maintainers = with maintainers; [ pjones emily sorki ];
+    # fails on darwin with
+    # arm-none-eabi-gcc: error: unrecognized command line option '-iframework'
+    platforms = platforms.linux;
+  };
+}
diff --git a/pkgs/development/embedded/blackmagic/helper.sh b/pkgs/development/embedded/blackmagic/helper.sh
new file mode 100755
index 00000000000..bae57f633cf
--- /dev/null
+++ b/pkgs/development/embedded/blackmagic/helper.sh
@@ -0,0 +1,52 @@
+################################################################################
+# Build all of the platforms manually since the `all_platforms' target
+# doesn't preserve all of the build outputs and overrides CFLAGS.
+set -e
+set -u
+
+################################################################################
+# Prevent a warning from shellcheck:
+out=${out:-/tmp}
+
+################################################################################
+export CFLAGS=$NIX_CFLAGS_COMPILE
+export MAKEFLAGS="\
+  ${enableParallelBuilding:+-j${NIX_BUILD_CORES} -l${NIX_BUILD_CORES}}"
+
+################################################################################
+PRODUCTS="blackmagic.bin blackmagic.hex blackmagic_dfu.bin blackmagic_dfu.hex"
+
+################################################################################
+make_platform() {
+  echo "Building for hardware platform $1"
+
+  make clean
+  make PROBE_HOST="$1"
+
+  if [ "$1" = "hosted" ]; then
+    install -m 0555 blackmagic "$out/bin"
+  fi
+
+  for f in $PRODUCTS; do
+    if [ -r "$f" ]; then
+      mkdir -p "$out/firmware/$1"
+      install -m 0444 "$f" "$out/firmware/$1"
+    fi
+  done
+
+}
+
+################################################################################
+# Start by building libopencm3:
+make -C libopencm3
+
+################################################################################
+# And now all of the platforms:
+cd src
+
+mkdir -p "$out/bin"
+
+for platform in platforms/*/Makefile.inc; do
+  probe=$(basename "$(dirname "$platform")")
+  make_platform "$probe"
+done
diff --git a/pkgs/development/embedded/bossa/bin2c.c b/pkgs/development/embedded/bossa/bin2c.c
new file mode 100644
index 00000000000..f0b915de540
--- /dev/null
+++ b/pkgs/development/embedded/bossa/bin2c.c
@@ -0,0 +1,122 @@
+// bin2c.c
+//
+// convert a binary file into a C source vector
+//
+// THE "BEER-WARE LICENSE" (Revision 3.1415):
+// sandro AT sigala DOT it wrote this file. As long as you retain this notice you can do
+// whatever you want with this stuff.  If we meet some day, and you think this stuff is
+// worth it, you can buy me a beer in return.  Sandro Sigala
+//
+// syntax:  bin2c [-c] [-z] <input_file> <output_file>
+//
+//          -c    add the "const" keyword to definition
+//          -z    terminate the array with a zero (useful for embedded C strings)
+//
+// examples:
+//     bin2c -c myimage.png myimage_png.cpp
+//     bin2c -z sometext.txt sometext_txt.cpp
+ 
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+ 
+#ifndef PATH_MAX
+#define PATH_MAX 1024
+#endif
+ 
+int useconst = 0;
+int zeroterminated = 0;
+ 
+int myfgetc(FILE *f)
+{
+	int c = fgetc(f);
+	if (c == EOF && zeroterminated)
+	{
+		zeroterminated = 0;
+		return 0;
+	}
+	return c;
+}
+ 
+void process(const char *ifname, const char *ofname)
+{
+	FILE *ifile, *ofile;
+	ifile = fopen(ifname, "rb");
+	if (ifile == NULL)
+	{
+		fprintf(stderr, "cannot open %s for reading\n", ifname);
+		exit(1);
+	}
+	ofile = fopen(ofname, "wb");
+	if (ofile == NULL)
+	{
+		fprintf(stderr, "cannot open %s for writing\n", ofname);
+		exit(1);
+	}
+	char buf[PATH_MAX], *p;
+	const char *cp;
+	if ((cp = strrchr(ifname, '/')) != NULL)
+	{
+		++cp;
+	} else {
+		if ((cp = strrchr(ifname, '\\')) != NULL)
+			++cp;
+		else
+			cp = ifname;
+	}
+	strcpy(buf, cp);
+	for (p = buf; *p != '\0'; ++p)
+	{
+		if (!isalnum(*p))
+			*p = '_';
+	}
+	fprintf(ofile, "static %sunsigned char %s[] = {\n", useconst ? "const " : "", buf);
+	int c, col = 1;
+	while ((c = myfgetc(ifile)) != EOF)
+	{
+		if (col >= 78 - 6)
+		{
+			fputc('\n', ofile);
+			col = 1;
+		}
+		fprintf(ofile, "0x%.2x, ", c);
+		col += 6;
+	}
+	fprintf(ofile, "\n};\n");
+ 
+	fclose(ifile);
+	fclose(ofile);
+}
+ 
+void usage(void)
+{
+	fprintf(stderr, "usage: bin2c [-cz] <input_file> <output_file>\n");
+	exit(1);
+}
+ 
+int main(int argc, char **argv)
+{
+	while (argc > 3)
+	{
+		if (!strcmp(argv[1], "-c"))
+		{
+			useconst = 1;
+			--argc;
+			++argv;
+		} else if (!strcmp(argv[1], "-z"))
+		{
+			zeroterminated = 1;
+			--argc;
+			++argv;
+		} else {
+			usage();
+		}
+	}
+	if (argc != 3)
+	{
+		usage();
+	}
+	process(argv[1], argv[2]);
+	return 0;
+}
diff --git a/pkgs/development/embedded/bossa/bossa-no-applet-build.patch b/pkgs/development/embedded/bossa/bossa-no-applet-build.patch
new file mode 100644
index 00000000000..4284245f485
--- /dev/null
+++ b/pkgs/development/embedded/bossa/bossa-no-applet-build.patch
@@ -0,0 +1,16 @@
+diff --git a/Makefile b/Makefile
+index cc8882e..97b11ee 100644
+--- a/Makefile
++++ b/Makefile
+@@ -184,11 +184,6 @@ $(foreach src,$(COMMON_SRCS),$(eval $(call common_obj,$(src))))
+ # Applet rules
+ #
+ define applet_obj
+-$(SRCDIR)/$(1:%.asm=%.cpp): $(SRCDIR)/$(1)
+-	@echo APPLET $(1:%.asm=%)
+-	$$(Q)$$(ARMAS) -o $$(@:%.o=%.obj) $$<
+-	$$(Q)$$(ARMOBJCOPY) -O binary $$(@:%.o=%.obj) $$(@:%.o=%.bin)
+-	$$(Q)appletgen $(1:%.asm=%) $(SRCDIR) $(OBJDIR)
+ $(OBJDIR)/$(1:%.asm=%.o): $(SRCDIR)/$(1:%.asm=%.cpp)
+ 	@echo CPP APPLET $$<
+ 	$$(Q)$$(CXX) $$(COMMON_CXXFLAGS) -c -o $$(@) $$(<:%.asm=%.cpp)
diff --git a/pkgs/development/embedded/bossa/default.nix b/pkgs/development/embedded/bossa/default.nix
new file mode 100644
index 00000000000..4e35ff35f66
--- /dev/null
+++ b/pkgs/development/embedded/bossa/default.nix
@@ -0,0 +1,53 @@
+{ lib, stdenv, fetchgit, wxGTK, libX11, readline }:
+
+let
+  # BOSSA needs a "bin2c" program to embed images.
+  # Source taken from:
+  # http://wiki.wxwidgets.org/Embedding_PNG_Images-Bin2c_In_C
+  bin2c = stdenv.mkDerivation {
+    name = "bossa-bin2c";
+    src = ./bin2c.c;
+    dontUnpack = true;
+    buildPhase = "cc $src -o bin2c";
+    installPhase = "mkdir -p $out/bin; cp bin2c $out/bin/";
+  };
+
+in
+stdenv.mkDerivation {
+  pname = "bossa";
+  version = "1.8";
+
+  src = fetchgit {
+    url = "https://github.com/shumatech/BOSSA";
+    rev = "3be622ca0aa6214a2fc51c1ec682c4a58a423d62";
+    sha256 = "19ik86qbffcb04cgmi4mnascbkck4ynfj87ha65qdk6fmp5q35vm";
+  };
+
+  patches = [ ./bossa-no-applet-build.patch ];
+
+  nativeBuildInputs = [ bin2c ];
+  buildInputs = [ wxGTK libX11 readline ];
+
+  # Explicitly specify targets so they don't get stripped.
+  makeFlags = [ "bin/bossac" "bin/bossash" "bin/bossa" ];
+  NIX_CFLAGS_COMPILE = "-Wno-error=deprecated-declarations";
+
+  installPhase = ''
+    mkdir -p $out/bin
+    cp bin/bossa{c,sh,} $out/bin/
+  '';
+
+  meta = with lib; {
+    description = "A flash programming utility for Atmel's SAM family of flash-based ARM microcontrollers";
+    longDescription = ''
+      BOSSA is a flash programming utility for Atmel's SAM family of
+      flash-based ARM microcontrollers. The motivation behind BOSSA is
+      to create a simple, easy-to-use, open source utility to replace
+      Atmel's SAM-BA software. BOSSA is an acronym for Basic Open
+      Source SAM-BA Application to reflect that goal.
+    '';
+    homepage = "http://www.shumatech.com/web/products/bossa";
+    license = licenses.bsd3;
+    platforms = platforms.linux;
+  };
+}
diff --git a/pkgs/development/embedded/cc-tool/default.nix b/pkgs/development/embedded/cc-tool/default.nix
new file mode 100644
index 00000000000..e2a511a0e32
--- /dev/null
+++ b/pkgs/development/embedded/cc-tool/default.nix
@@ -0,0 +1,42 @@
+{ lib, stdenv
+, fetchFromGitHub
+, autoreconfHook
+, boost
+, libusb1
+, pkg-config
+}:
+
+stdenv.mkDerivation rec {
+  pname = "cc-tool";
+  version = "unstable-2020-05-19";
+
+  src = fetchFromGitHub {
+    owner = "dashesy";
+    repo = pname;
+    rev = "19e707eafaaddee8b996ad27a9f3e1aafcb900d2";
+    hash = "sha256:1f78j498fdd36xbci57jkgh25gq14g3b6xmp76imdpar0jkpyljv";
+  };
+
+  nativeBuildInputs = [ autoreconfHook pkg-config ];
+  buildInputs = [ boost libusb1 ];
+
+  postPatch = ''
+    substituteInPlace udev/90-cc-debugger.rules \
+      --replace 'MODE="0666"' 'MODE="0660", GROUP="plugdev", TAG+="uaccess"'
+  '';
+
+  postInstall = ''
+    install -D udev/90-cc-debugger.rules $out/lib/udev/rules.d/90-cc-debugger.rules
+  '';
+
+  meta = with lib; {
+    description = "Command line tool for the Texas Instruments CC Debugger";
+    longDescription = ''
+      cc-tool provides support for Texas Instruments CC Debugger
+    '';
+    homepage = "https://github.com/dashesy/cc-tool";
+    license = licenses.gpl2;
+    platforms = with platforms; linux ++ darwin;
+    maintainers = [ maintainers.CRTified ];
+  };
+}
diff --git a/pkgs/development/embedded/easypdkprog/default.nix b/pkgs/development/embedded/easypdkprog/default.nix
new file mode 100644
index 00000000000..92d1a550ea8
--- /dev/null
+++ b/pkgs/development/embedded/easypdkprog/default.nix
@@ -0,0 +1,27 @@
+{ stdenv, lib, fetchFromGitHub }:
+
+stdenv.mkDerivation rec {
+  pname = "easypdkprog";
+  version = "1.3";
+
+  src = fetchFromGitHub {
+    owner = "free-pdk";
+    repo = "easy-pdk-programmer-software";
+    rev = version;
+    sha256 = "0hc3gdmn6l01z63hzzwdhbdyy288gh5v219bsfm8fb1498vpnd6f";
+  };
+
+  installPhase = ''
+    install -Dm755 -t $out/bin easypdkprog
+  '' + lib.optionalString stdenv.isLinux ''
+    install -Dm644 -t $out/etc/udev/rules.d Linux_udevrules/70-stm32vcp.rules
+  '';
+
+  meta = with lib; {
+    description = "Read, write and execute programs on PADAUK microcontroller";
+    homepage = "https://github.com/free-pdk/easy-pdk-programmer-software";
+    license = licenses.gpl3Plus;
+    maintainers = with maintainers; [ david-sawatzke ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/pkgs/development/embedded/elf2uf2-rs/default.nix b/pkgs/development/embedded/elf2uf2-rs/default.nix
new file mode 100644
index 00000000000..fac10a28107
--- /dev/null
+++ b/pkgs/development/embedded/elf2uf2-rs/default.nix
@@ -0,0 +1,31 @@
+{ lib, stdenv, rustPlatform, fetchFromGitHub, pkg-config, udev }:
+
+rustPlatform.buildRustPackage rec {
+  pname = "elf2uf2-rs";
+  version = "unstable-2021-12-12";
+
+  src = fetchFromGitHub {
+    owner = "JoNil";
+    repo = pname;
+    rev = "91ae98873ed01971ab1543b98266a5ad2ec09210";
+    sha256 = "sha256-DGrT+YdDLdTYy5SWcQ+DNbpifGjrF8UTXyEeE/ug564=";
+  };
+
+  nativeBuildInputs = [
+    pkg-config
+  ];
+
+  buildInputs = [
+    udev
+  ];
+
+  cargoSha256 = "sha256-5ui1+987xICP2wUSHy4YzKskn52W51Pi4DbEh+GbSPE=";
+
+  meta = with lib; {
+    description = "Convert ELF files to UF2 for USB Flashing Bootloaders";
+    homepage = "https://github.com/JoNil/elf2uf2-rs";
+    license = with licenses; [ bsd0 ];
+    platforms = platforms.linux;
+    maintainers = with maintainers; [ polygon ];
+  };
+}
diff --git a/pkgs/development/embedded/fpga/apio/default.nix b/pkgs/development/embedded/fpga/apio/default.nix
new file mode 100644
index 00000000000..1bb5f336f1e
--- /dev/null
+++ b/pkgs/development/embedded/fpga/apio/default.nix
@@ -0,0 +1,74 @@
+{ lib
+, buildPythonApplication
+, fetchFromGitHub
+, click
+, semantic-version
+, requests
+, colorama
+, pyserial
+, wheel
+, scons
+, setuptools
+, tinyprog
+, pytestCheckHook
+}:
+
+buildPythonApplication rec {
+  pname = "apio";
+  version = "0.8.0";
+  format = "flit";
+
+  src = fetchFromGitHub {
+    owner = "FPGAwars";
+    repo = "apio";
+    rev = "v${version}";
+    sha256 = "sha256-nOZI+FHdZRnkJF/No8z0mZ4Q5aHFnF7c20ajTPI00N4=";
+  };
+
+  postPatch = ''
+    substituteInPlace pyproject.toml --replace \
+      'scons==4.2.0' 'scons'
+
+    substituteInPlace apio/managers/scons.py --replace \
+      'return "tinyprog --libusb --program"' \
+      'return "${tinyprog}/bin/tinyprog --libusb --program"'
+    substituteInPlace apio/util.py --replace \
+      '_command = join(get_bin_dir(), "tinyprog")' \
+      '_command = "${tinyprog}/bin/tinyprog"'
+
+    # semantic-version seems to not support version numbers like the one of tinyprog in Nixpkgs (1.0.24.dev114+gxxxxxxx).
+    # See https://github.com/rbarrois/python-semanticversion/issues/47.
+    # This leads to an error like "Error: Invalid version string: '1.0.24.dev114+g97f6353'"
+    # when executing "apio upload" for a TinyFPGA.
+    # Replace the dot with a dash to work around this problem.
+    substituteInPlace apio/managers/scons.py --replace \
+        'version = semantic_version.Version(pkg_version)' \
+        'version = semantic_version.Version(pkg_version.replace(".dev", "-dev"))'
+  '';
+
+  propagatedBuildInputs = [
+    click
+    semantic-version
+    requests
+    colorama
+    pyserial
+    wheel
+    scons
+    setuptools # needs pkg_resources at runtime (technically not needed when tinyprog is also in this list because of the propagatedBuildInputs of tinyprog)
+
+    tinyprog # needed for upload to TinyFPGA
+  ];
+
+  checkInputs = [
+    pytestCheckHook
+  ];
+
+  pytestFlagsArray = [ "--offline" ];
+
+  meta = with lib; {
+    description = "Open source ecosystem for open FPGA boards";
+    homepage = "https://github.com/FPGAwars/apio";
+    license = licenses.gpl2Only;
+    maintainers = with maintainers; [ Luflosi ];
+  };
+}
diff --git a/pkgs/development/embedded/fpga/ecpdap/default.nix b/pkgs/development/embedded/fpga/ecpdap/default.nix
new file mode 100644
index 00000000000..38ba9d78712
--- /dev/null
+++ b/pkgs/development/embedded/fpga/ecpdap/default.nix
@@ -0,0 +1,37 @@
+{ lib, stdenv, fetchFromGitHub, rustPlatform, pkg-config, libusb1, AppKit }:
+
+rustPlatform.buildRustPackage rec {
+  pname = "ecpdap";
+  version = "0.1.7";
+
+  src = fetchFromGitHub {
+    owner = "adamgreig";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "sha256-fdvpGmEy54i48H6YJ4E1LIuogimNEL8PJS5ScoW/6DM=";
+  };
+
+  cargoSha256 = "sha256-2YARNoHVDBwGr8FE/oRlNZMX/vCPIre7OnZbr04eF/M=";
+
+  nativeBuildInputs = [ pkg-config ];
+
+  buildInputs = [ libusb1 ]
+    ++ lib.optional stdenv.isDarwin AppKit;
+
+  postInstall = ''
+    mkdir -p $out/etc/udev/rules.d
+    cp drivers/*.rules $out/etc/udev/rules.d
+  '';
+
+  meta = with lib; {
+    description = "A tool to program ECP5 FPGAs";
+    longDescription = ''
+      ECPDAP allows you to program ECP5 FPGAs and attached SPI flash
+      using CMSIS-DAP probes in JTAG mode.
+    '';
+    homepage = "https://github.com/adamgreig/ecpdap";
+    license = licenses.asl20;
+    maintainers = with maintainers; [ expipiplus1 ];
+  };
+}
+
diff --git a/pkgs/development/embedded/fpga/fujprog/default.nix b/pkgs/development/embedded/fpga/fujprog/default.nix
new file mode 100644
index 00000000000..db1f42e3a26
--- /dev/null
+++ b/pkgs/development/embedded/fpga/fujprog/default.nix
@@ -0,0 +1,39 @@
+{ lib, stdenv
+, fetchFromGitHub
+, cmake
+, pkg-config
+, IOKit
+, libftdi1
+, libusb-compat-0_1
+}:
+
+stdenv.mkDerivation rec {
+  pname = "fujprog";
+  version = "4.8";
+
+  src = fetchFromGitHub {
+    owner = "kost";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "08kzkzd5a1wfd1aycywdynxh3qy6n7z9i8lihkahmb4xac3chmz5";
+  };
+
+  nativeBuildInputs = [
+    cmake
+    pkg-config
+  ];
+
+  buildInputs = [
+    libftdi1
+    libusb-compat-0_1
+  ] ++ lib.optionals stdenv.isDarwin [ IOKit ];
+
+  meta = with lib; {
+    description = "JTAG programmer for the ULX3S and ULX2S open hardware FPGA development boards";
+    homepage = "https://github.com/kost/fujprog";
+    license = licenses.bsd2;
+    maintainers = with maintainers; [ trepetti ];
+    platforms = platforms.all;
+    changelog = "https://github.com/kost/fujprog/releases/tag/v${version}";
+  };
+}
diff --git a/pkgs/development/embedded/fpga/icestorm/default.nix b/pkgs/development/embedded/fpga/icestorm/default.nix
new file mode 100644
index 00000000000..b660571eb3e
--- /dev/null
+++ b/pkgs/development/embedded/fpga/icestorm/default.nix
@@ -0,0 +1,70 @@
+{ lib, stdenv, fetchFromGitHub
+, pkg-config, libftdi1
+, python3, pypy3
+
+# PyPy yields large improvements in build time and runtime performance, and
+# IceStorm isn't intended to be used as a library other than by the nextpnr
+# build process (which is also sped up by using PyPy), so we use it by default.
+# See 18839e1 for more details.
+#
+# FIXME(aseipp, 3/1/2021): pypy seems a bit busted since stdenv upgrade to gcc
+# 10/binutils 2.34, so short-circuit this for now in passthru below (done so
+# that downstream overrides can't re-enable pypy and break their build somehow)
+, usePyPy ? stdenv.hostPlatform.system == "x86_64-linux"
+}:
+
+stdenv.mkDerivation rec {
+  pname = "icestorm";
+  version = "2020.12.04";
+
+  passthru = rec {
+    pythonPkg = if (false && usePyPy) then pypy3 else python3;
+    pythonInterp = pythonPkg.interpreter;
+  };
+
+  src = fetchFromGitHub {
+    owner  = "YosysHQ";
+    repo   = "icestorm";
+    rev    = "7afc64b480212c9ac2ce7cb1622731a69a7d212c";
+    sha256 = "0vxhqs2fampglg3xlfwb35229iv96kvlwp1gyxrdrmlpznhkqdrk";
+  };
+
+  nativeBuildInputs = [ pkg-config ];
+  buildInputs = [ passthru.pythonPkg libftdi1 ];
+  makeFlags = [ "PREFIX=$(out)" ];
+
+  enableParallelBuilding = true;
+
+  # fix icebox_vlog chipdb path. icestorm issue:
+  #   https://github.com/cliffordwolf/icestorm/issues/125
+  #
+  # also, fix up the path to the chosen Python interpreter. for pypy-compatible
+  # platforms, it offers significant performance improvements.
+  patchPhase = ''
+    substituteInPlace ./icebox/icebox_vlog.py \
+      --replace /usr/local/share "$out/share"
+
+    for x in icefuzz/Makefile icebox/Makefile icetime/Makefile; do
+      substituteInPlace "$x" --replace python3 "${passthru.pythonInterp}"
+    done
+
+    for x in $(find . -type f -iname '*.py'); do
+      substituteInPlace "$x" \
+        --replace '/usr/bin/env python3' '${passthru.pythonInterp}'
+    done
+  '';
+
+  meta = {
+    description = "Documentation and tools for Lattice iCE40 FPGAs";
+    longDescription = ''
+      Project IceStorm aims at reverse engineering and
+      documenting the bitstream format of Lattice iCE40
+      FPGAs and providing simple tools for analyzing and
+      creating bitstream files.
+    '';
+    homepage    = "https://github.com/YosysHQ/icestorm/";
+    license     = lib.licenses.isc;
+    maintainers = with lib.maintainers; [ shell thoughtpolice emily ];
+    platforms   = lib.platforms.all;
+  };
+}
diff --git a/pkgs/development/embedded/fpga/lattice-diamond/default.nix b/pkgs/development/embedded/fpga/lattice-diamond/default.nix
new file mode 100644
index 00000000000..e8bc4c1b1be
--- /dev/null
+++ b/pkgs/development/embedded/fpga/lattice-diamond/default.nix
@@ -0,0 +1,117 @@
+{ lib, stdenv, rpmextract, patchelf, makeWrapper, file, requireFile, glib, zlib,
+    freetype, fontconfig, xorg, libusb-compat-0_1 }:
+
+stdenv.mkDerivation {
+  pname = "diamond";
+  version = "3.10";
+
+  nativeBuildInputs = [ rpmextract patchelf makeWrapper file ];
+
+  src = requireFile {
+    name = "diamond_3_10-base_x64-111-2-x86_64-linux.rpm";
+    url = "http://www.latticesemi.com/view_document?document_id=52180";
+    sha256 = "ec0b370cf8bd55831eeed7c5eadcabacbd6e63ac657c20209d672119a07a5c0f";
+  };
+
+  buildCommand = ''
+    origprefix=usr/local/diamond/3.10_x64
+    prefix=diamond
+
+    echo "Unpacking $src..."
+    rpmextract $src
+
+    # Move $pwd/usr/local/diamond/VERS to $out/diamond, cd.
+    mkdir -p $out/$prefix
+    rmdir $out/$prefix
+    mv $origprefix $out/$prefix
+
+    cd $out
+
+    # Extract all tarballs.
+    for tb in \
+        cae_library/cae_library.tar.gz \
+        embedded_source/embedded_source.tar.gz \
+        ispfpga/ispfpga.tar.gz \
+        synpbase/synpbase.tar.gz \
+        tcltk/tcltk.tar.gz \
+        bin/bin.tar.gz \
+        examples/examples.tar.gz \
+        data/data.tar.gz ; do
+
+        echo "Extracting tarball $prefix/$tb"
+        cd $out/$prefix/$(dirname $tb)
+        tar xf $(basename $tb)
+        rm $(basename $tb)
+    done
+
+    # Patch shebangs in start scripts .
+    cd $out/$prefix/bin/lin64
+    for tool in \
+        programmer \
+        pgrcmd \
+        diamond_env \
+        powercal \
+        model300 \
+        update \
+        diamond \
+        debugger \
+        ddtcmd \
+        cableserver \
+        revealrva \
+        ipexpress \
+        fileutility \
+        diamond ; do
+
+        echo "Patching script $prefix/bin/lin64/$tool..."
+        patchShebangs $tool
+    done
+
+    # Patch executable ELFs.
+    for path in bin/lin64 ispfpga/bin/lin64; do
+        cd $out/$prefix/$path
+        for f in *; do
+            if ! file $f | grep -q "ELF 64-bit LSB executable" ; then
+                continue
+            fi
+            echo "Patching ELF $prefix/$path/$f..."
+            # We force RPATH otherwise libraries from LD_LIBRARY_PATH (which the
+            # tools mangle by themselves) will not be able to find their
+            # dependencies from nix.
+            patchelf \
+                --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
+                --set-rpath "$libPath" --force-rpath \
+                $f
+        done
+    done
+
+    # Remove 32-bit libz.
+    rm $out/$prefix/bin/lin64/libz.{so,so.1}
+
+    # Make wrappers (should these target more than the 'diamond' tool?).
+    # The purpose of these is just to call the target program using its
+    # absolute path - otherwise, it will crash.
+    mkdir -p bin
+    for tool in diamond ; do
+        makeWrapper $out/$prefix/bin/lin64/$tool $out/bin/$tool
+    done
+  '';
+
+  libPath = lib.makeLibraryPath [
+    glib zlib freetype fontconfig
+    xorg.libSM xorg.libICE xorg.libXrender xorg.libXext xorg.libX11 xorg.libXt
+    libusb-compat-0_1
+  ];
+
+  meta = {
+    description = "Vendor development tools for Lattice FPGA devices";
+    longDescription = ''
+      Lattice Diamond software is the leading-edge software design environment
+      for cost- sensitive, low-power Lattice FPGA architectures. It is the
+      next-generation replacement for ispLEVER.
+    '';
+    homepage = "https://www.latticesemi.com/latticediamond";
+    license = lib.licenses.unfree;
+    maintainers = with lib.maintainers; [ q3k ];
+    platforms = [ "x86_64-linux" ];
+  };
+}
diff --git a/pkgs/development/embedded/fpga/openfpgaloader/default.nix b/pkgs/development/embedded/fpga/openfpgaloader/default.nix
new file mode 100644
index 00000000000..b44f78c03c4
--- /dev/null
+++ b/pkgs/development/embedded/fpga/openfpgaloader/default.nix
@@ -0,0 +1,36 @@
+{ stdenv
+, lib
+, fetchFromGitHub
+, cmake
+, pkg-config
+, libftdi1
+, libusb1
+, udev
+}:
+
+stdenv.mkDerivation rec {
+  pname = "openfpgaloader";
+  version = "0.6.0";
+
+  src = fetchFromGitHub {
+    owner = "trabucayre";
+    repo = "openFPGALoader";
+    rev = "v${version}";
+    sha256 = "sha256-gPRBHy7WVra4IlGvzrhNqbEbOQtYtUC+zQ+SnJTMvRA=";
+  };
+
+  nativeBuildInputs = [ cmake pkg-config ];
+
+  buildInputs = [
+    libftdi1
+    libusb1
+    udev
+  ];
+
+  meta = with lib; {
+    description = "Universal utility for programming FPGAs";
+    homepage = "https://github.com/trabucayre/openFPGALoader";
+    license = licenses.agpl3Only;
+    maintainers = with maintainers; [ danderson ];
+  };
+}
diff --git a/pkgs/development/embedded/fpga/tinyprog/default.nix b/pkgs/development/embedded/fpga/tinyprog/default.nix
new file mode 100644
index 00000000000..06a8c3e9871
--- /dev/null
+++ b/pkgs/development/embedded/fpga/tinyprog/default.nix
@@ -0,0 +1,43 @@
+{ lib
+, python3Packages
+, fetchFromGitHub
+}:
+
+with python3Packages; buildPythonApplication rec {
+  pname = "tinyprog";
+  # `python setup.py --version` from repo checkout
+  version = "1.0.24.dev114+g${lib.substring 0 7 src.rev}";
+
+  src = fetchFromGitHub {
+    owner = "tinyfpga";
+    repo = "TinyFPGA-Bootloader";
+    rev = "97f6353540bf7c0d27f5612f202b48f41da75299";
+    sha256 = "0zbrvvb957z2lwbfd39ixqdsnd2w4wfjirwkqdrqm27bjz308731";
+  };
+
+  sourceRoot = "source/programmer";
+
+  propagatedBuildInputs = [
+    pyserial
+    jsonmerge
+    intelhex
+    tqdm
+    six
+    packaging
+    setuptools
+    pyusb
+  ];
+
+  nativeBuildInputs = [ setuptools-scm ];
+
+  preBuild = ''
+    export SETUPTOOLS_SCM_PRETEND_VERSION="${version}"
+  '';
+
+  meta = with lib; {
+    homepage = "https://github.com/tinyfpga/TinyFPGA-Bootloader/tree/master/programmer";
+    description = "Programmer for FPGA boards using the TinyFPGA USB Bootloader";
+    maintainers = with maintainers; [ emily ];
+    license = licenses.asl20;
+  };
+}
diff --git a/pkgs/development/embedded/fpga/trellis/default.nix b/pkgs/development/embedded/fpga/trellis/default.nix
new file mode 100644
index 00000000000..32a4bcdac07
--- /dev/null
+++ b/pkgs/development/embedded/fpga/trellis/default.nix
@@ -0,0 +1,72 @@
+{ lib, stdenv, fetchFromGitHub, python3, boost, cmake }:
+
+let
+  rev = "2f06397673bbca3da11928d538b8ab7d01c944c6";
+  # git describe --tags
+  realVersion = "1.0-534-g${builtins.substring 0 7 rev}";
+in stdenv.mkDerivation rec {
+  pname = "trellis";
+  version = "2021-12-14";
+
+  srcs = [
+    (fetchFromGitHub {
+       owner  = "YosysHQ";
+       repo   = "prjtrellis";
+       inherit rev;
+       hash   = "sha256-m5CalAIbzY2bhOvpBbPBeLZeDp+itk1HlRsSmtiddaA=";
+       name   = "trellis";
+     })
+
+    (fetchFromGitHub {
+      owner  = "YosysHQ";
+      repo   = "prjtrellis-db";
+      # note: the upstream submodule points to revision 0ee729d20eaf,
+      # but that's just the tip of the branch that was merged into master.
+      # fdf4bf275a is the merge commit itself
+      rev    = "fdf4bf275a7402654bc643db537173e2fbc86103";
+      sha256 = "eDq2wU2pnfK9bOkEVZ07NQPv02Dc6iB+p5GTtVBiyQA=";
+      name   = "trellis-database";
+    })
+  ];
+  sourceRoot = "trellis";
+
+  buildInputs = [ boost ];
+  nativeBuildInputs = [ cmake python3 ];
+  cmakeFlags = [
+    "-DCURRENT_GIT_VERSION=${realVersion}"
+    # TODO: should this be in stdenv instead?
+    "-DCMAKE_INSTALL_DATADIR=${placeholder "out"}/share"
+  ];
+
+  preConfigure = ''
+    rmdir database && ln -sfv ${builtins.elemAt srcs 1} ./database
+
+    cd libtrellis
+  '';
+
+  postInstall = lib.optionalString stdenv.isDarwin ''
+    for f in $out/bin/* ; do
+      install_name_tool -change "$out/lib/libtrellis.dylib" "$out/lib/trellis/libtrellis.dylib" "$f"
+    done
+  '';
+
+  doInstallCheck = true;
+
+  installCheckPhase = ''
+    $out/bin/ecppack $out/share/trellis/misc/basecfgs/empty_lfe5u-85f.config /tmp/test.bin
+  '';
+
+  meta = with lib; {
+    description     = "Documentation and bitstream tools for Lattice ECP5 FPGAs";
+    longDescription = ''
+      Project Trellis documents the Lattice ECP5 architecture
+      to enable development of open-source tools. Its goal is
+      to provide sufficient information to develop a free and
+      open Verilog to bitstream toolchain for these devices.
+    '';
+    homepage    = "https://github.com/YosysHQ/prjtrellis";
+    license     = licenses.isc;
+    maintainers = with maintainers; [ q3k thoughtpolice emily rowanG077 ];
+    platforms   = platforms.all;
+  };
+}
diff --git a/pkgs/development/embedded/gputils/default.nix b/pkgs/development/embedded/gputils/default.nix
new file mode 100644
index 00000000000..69a901ea80f
--- /dev/null
+++ b/pkgs/development/embedded/gputils/default.nix
@@ -0,0 +1,19 @@
+{ lib, stdenv, fetchurl }:
+
+stdenv.mkDerivation rec {
+  pname = "gputils";
+  version = "1.5.2";
+
+  src = fetchurl {
+    url = "mirror://sourceforge/gputils/${pname}-${version}.tar.bz2";
+    sha256 = "sha256-j7iCCzHXwffHdhQcyzxPBvQK+RXaY3QSjXUtHu463fI=";
+  };
+
+  meta = with lib; {
+    homepage = "https://gputils.sourceforge.io";
+    description = "A collection of tools for the Microchip (TM) PIC microcontrollers. It includes gpasm, gplink, and gplib";
+    license = licenses.gpl2;
+    maintainers = with maintainers; [ yorickvp ];
+    platforms = platforms.linux;
+  };
+}
diff --git a/pkgs/development/embedded/openocd/default.nix b/pkgs/development/embedded/openocd/default.nix
new file mode 100644
index 00000000000..c2f7d231b1a
--- /dev/null
+++ b/pkgs/development/embedded/openocd/default.nix
@@ -0,0 +1,69 @@
+{ stdenv
+, lib
+, fetchurl
+, pkg-config
+, hidapi
+, libftdi1
+, libusb1
+, libgpiod
+}:
+
+stdenv.mkDerivation rec {
+  pname = "openocd";
+  version = "0.11.0";
+  src = fetchurl {
+    url = "mirror://sourceforge/project/${pname}/${pname}/${version}/${pname}-${version}.tar.bz2";
+    sha256 = "0z8y7mmv0mhn2l5gs3vz6l7cnwak7agklyc7ml33f7gz99rwx8s3";
+  };
+
+  nativeBuildInputs = [ pkg-config ];
+
+  buildInputs = [ hidapi libftdi1 libusb1 ]
+    ++ lib.optional stdenv.isLinux libgpiod;
+
+  configureFlags = [
+    "--enable-jtag_vpi"
+    "--enable-usb_blaster_libftdi"
+    (lib.enableFeature (! stdenv.isDarwin) "amtjtagaccel")
+    (lib.enableFeature (! stdenv.isDarwin) "gw16012")
+    "--enable-presto_libftdi"
+    "--enable-openjtag_ftdi"
+    (lib.enableFeature (! stdenv.isDarwin) "oocd_trace")
+    "--enable-buspirate"
+    (lib.enableFeature stdenv.isLinux "sysfsgpio")
+    (lib.enableFeature stdenv.isLinux "linuxgpiod")
+    "--enable-remote-bitbang"
+  ];
+
+  NIX_CFLAGS_COMPILE = lib.optionals stdenv.cc.isGNU [
+    "-Wno-error=cpp"
+    "-Wno-error=strict-prototypes" # fixes build failure with hidapi 0.10.0
+  ];
+
+  postInstall = lib.optionalString stdenv.isLinux ''
+    mkdir -p "$out/etc/udev/rules.d"
+    rules="$out/share/openocd/contrib/60-openocd.rules"
+    if [ ! -f "$rules" ]; then
+        echo "$rules is missing, must update the Nix file."
+        exit 1
+    fi
+    ln -s "$rules" "$out/etc/udev/rules.d/"
+  '';
+
+  meta = with lib; {
+    description = "Free and Open On-Chip Debugging, In-System Programming and Boundary-Scan Testing";
+    longDescription = ''
+      OpenOCD provides on-chip programming and debugging support with a layered
+      architecture of JTAG interface and TAP support, debug target support
+      (e.g. ARM, MIPS), and flash chip drivers (e.g. CFI, NAND, etc.).  Several
+      network interfaces are available for interactiving with OpenOCD: HTTP,
+      telnet, TCL, and GDB.  The GDB server enables OpenOCD to function as a
+      "remote target" for source-level debugging of embedded systems using the
+      GNU GDB program.
+    '';
+    homepage = "https://openocd.sourceforge.net/";
+    license = licenses.gpl2Plus;
+    maintainers = with maintainers; [ bjornfor prusnak ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/pkgs/development/embedded/platformio/chrootenv.nix b/pkgs/development/embedded/platformio/chrootenv.nix
new file mode 100644
index 00000000000..138e7186624
--- /dev/null
+++ b/pkgs/development/embedded/platformio/chrootenv.nix
@@ -0,0 +1,45 @@
+{ lib, buildFHSUserEnv, version, src }:
+
+let
+  pio-pkgs = pkgs:
+    let
+      python = pkgs.python3.override {
+        packageOverrides = self: super: {
+          platformio = self.callPackage ./core.nix { inherit version src; };
+        };
+      };
+    in (with pkgs; [
+      zlib
+      git
+    ]) ++ (with python.pkgs; [
+      python
+      setuptools
+      pip
+      bottle
+      platformio
+    ]);
+
+in buildFHSUserEnv {
+  name = "platformio";
+
+  targetPkgs = pio-pkgs;
+  # disabled temporarily because fastdiff no longer support 32bit
+  # multiPkgs = pio-pkgs;
+
+  meta = with lib; {
+    description = "An open source ecosystem for IoT development";
+    homepage = "https://platformio.org";
+    maintainers = with maintainers; [ mog ];
+    license = licenses.asl20;
+    platforms = with platforms; linux;
+  };
+
+  extraInstallCommands = ''
+    mkdir -p $out/lib/udev/rules.d
+
+    ln -s $out/bin/platformio $out/bin/pio
+    ln -s ${src}/scripts/99-platformio-udev.rules $out/lib/udev/rules.d/99-platformio-udev.rules
+  '';
+
+  runScript = "platformio";
+}
diff --git a/pkgs/development/embedded/platformio/core.nix b/pkgs/development/embedded/platformio/core.nix
new file mode 100644
index 00000000000..f19458fa84f
--- /dev/null
+++ b/pkgs/development/embedded/platformio/core.nix
@@ -0,0 +1,166 @@
+{ stdenv, lib, python3
+, fetchFromGitHub
+, fetchPypi
+, git
+, spdx-license-list-data
+, version, src
+}:
+
+let
+  python = python3.override {
+    packageOverrides = self: super: {
+      semantic-version = super.semantic-version.overridePythonAttrs (oldAttrs: rec {
+        version = "2.9.0";
+        src = fetchPypi {
+          pname = "semantic_version";
+          version = version;
+          sha256 = "1chjd8019wnwb5mnd4x4jw9f8nhzg0xnapsdznk0fpiyamrlixdb";
+        };
+      });
+
+      starlette = super.starlette.overridePythonAttrs (oldAttrs: rec {
+        version = "0.18.0";
+        src = fetchFromGitHub {
+          owner = "encode";
+          repo = "starlette";
+          rev = version;
+          sha256 = "1dpj33cggjjvpd3qdf6hv04z5ckcn9f5dfn98p5a8hx262kgsr9p";
+        };
+      });
+
+      uvicorn = super.uvicorn.overridePythonAttrs (oldAttrs: rec {
+        version = "0.17.0";
+        src = fetchFromGitHub {
+          owner = "encode";
+          repo = "uvicorn";
+          rev = version;
+          sha256 = "142x8skb1yfys6gndfaay2r240j56dkr006p49pw4y9i0v85kynp";
+        };
+      });
+    };
+  };
+in
+with python.pkgs; buildPythonApplication rec {
+  pname = "platformio";
+  inherit version src;
+
+  propagatedBuildInputs = [
+    aiofiles
+    ajsonrpc
+    bottle
+    click
+    click-completion
+    colorama
+    git
+    lockfile
+    marshmallow
+    pyelftools
+    pyserial
+    requests
+    semantic-version
+    spdx-license-list-data.json
+    starlette
+    tabulate
+    uvicorn
+    wsproto
+    zeroconf
+  ];
+
+  HOME = "/tmp";
+
+  checkInputs = [
+    jsondiff
+    pytestCheckHook
+    tox
+  ];
+
+  pytestFlagsArray = (map (e: "--deselect tests/${e}") [
+    "commands/test_ci.py::test_ci_boards"
+    "commands/test_ci.py::test_ci_build_dir"
+    "commands/test_ci.py::test_ci_keep_build_dir"
+    "commands/test_ci.py::test_ci_lib_and_board"
+    "commands/test_ci.py::test_ci_project_conf"
+    "commands/test_init.py::test_init_custom_framework"
+    "commands/test_init.py::test_init_duplicated_boards"
+    "commands/test_init.py::test_init_enable_auto_uploading"
+    "commands/test_init.py::test_init_ide_atom"
+    "commands/test_init.py::test_init_ide_eclipse"
+    "commands/test_init.py::test_init_ide_vscode"
+    "commands/test_init.py::test_init_incorrect_board"
+    "commands/test_init.py::test_init_special_board"
+    "commands/test_lib.py::test_global_install_archive"
+    "commands/test_lib.py::test_global_install_registry"
+    "commands/test_lib.py::test_global_install_repository"
+    "commands/test_lib.py::test_global_lib_list"
+    "commands/test_lib.py::test_global_lib_uninstall"
+    "commands/test_lib.py::test_global_lib_update"
+    "commands/test_lib.py::test_global_lib_update_check"
+    "commands/test_lib.py::test_install_duplicates"
+    "commands/test_lib.py::test_lib_show"
+    "commands/test_lib.py::test_lib_stats"
+    "commands/test_lib.py::test_saving_deps"
+    "commands/test_lib.py::test_search"
+    "commands/test_lib.py::test_update"
+    "commands/test_lib_complex.py::test_global_install_archive"
+    "commands/test_lib_complex.py::test_global_install_registry"
+    "commands/test_lib_complex.py::test_global_install_repository"
+    "commands/test_lib_complex.py::test_global_lib_list"
+    "commands/test_lib_complex.py::test_global_lib_uninstall"
+    "commands/test_lib_complex.py::test_global_lib_update"
+    "commands/test_lib_complex.py::test_global_lib_update_check"
+    "commands/test_lib_complex.py::test_install_duplicates"
+    "commands/test_lib_complex.py::test_lib_show"
+    "commands/test_lib_complex.py::test_lib_stats"
+    "commands/test_lib_complex.py::test_search"
+    "commands/test_test.py::test_local_env"
+    "commands/test_test.py::test_multiple_env_build"
+    "commands/test_test.py::test_setup_teardown_are_compilable"
+    "package/test_manager.py::test_download"
+    "package/test_manager.py::test_install_force"
+    "package/test_manager.py::test_install_from_registry"
+    "package/test_manager.py::test_install_lib_depndencies"
+    "package/test_manager.py::test_registry"
+    "package/test_manager.py::test_uninstall"
+    "package/test_manager.py::test_update_with_metadata"
+    "package/test_manager.py::test_update_without_metadata"
+    "test_builder.py::test_build_flags"
+    "test_builder.py::test_build_unflags"
+    "test_builder.py::test_debug_custom_build_flags"
+    "test_builder.py::test_debug_default_build_flags"
+    "test_misc.py::test_api_cache"
+    "test_misc.py::test_ping_internet_ips"
+    "test_misc.py::test_platformio_cli"
+    "test_pkgmanifest.py::test_packages"
+  ]) ++ (map (e: "--ignore=tests/${e}") [
+    "commands/test_boards.py"
+    "commands/test_check.py"
+    "commands/test_platform.py"
+    "commands/test_update.py"
+    "test_maintenance.py"
+    "test_ino2cpp.py"
+  ]) ++ [
+    "tests"
+  ];
+
+  patches = [
+    ./fix-searchpath.patch
+    ./use-local-spdx-license-list.patch
+    ./missing-udev-rules-nixos.patch
+  ];
+
+  postPatch = ''
+    substitute platformio/package/manifest/schema.py platformio/package/manifest/schema.py \
+      --subst-var-by SPDX_LICENSE_LIST_DATA '${spdx-license-list-data.json}'
+
+    substituteInPlace setup.py \
+      --replace "zeroconf==0.37.*" "zeroconf"
+  '';
+
+  meta = with lib; {
+    broken = stdenv.isAarch64;
+    description = "An open source ecosystem for IoT development";
+    homepage = "https://platformio.org";
+    license = licenses.asl20;
+    maintainers = with maintainers; [ mog makefu ];
+  };
+}
diff --git a/pkgs/development/embedded/platformio/default.nix b/pkgs/development/embedded/platformio/default.nix
new file mode 100644
index 00000000000..31b7b8d4951
--- /dev/null
+++ b/pkgs/development/embedded/platformio/default.nix
@@ -0,0 +1,21 @@
+
+{ newScope, fetchFromGitHub }:
+
+let
+  callPackage = newScope self;
+
+  version = "5.2.5";
+
+  # pypi tarballs don't contain tests - https://github.com/platformio/platformio-core/issues/1964
+  src = fetchFromGitHub {
+    owner = "platformio";
+    repo = "platformio-core";
+    rev = "v${version}";
+    sha256 = "1x1jqprwzpb09ca953rqbh2jvizh7bz8yj30krphb6007bnjilwy";
+  };
+
+  self = {
+    platformio-chrootenv = callPackage ./chrootenv.nix { inherit version src; };
+  };
+
+in self
diff --git a/pkgs/development/embedded/platformio/fix-searchpath.patch b/pkgs/development/embedded/platformio/fix-searchpath.patch
new file mode 100644
index 00000000000..fe7f9f127a7
--- /dev/null
+++ b/pkgs/development/embedded/platformio/fix-searchpath.patch
@@ -0,0 +1,13 @@
+diff --git a/platformio/proc.py b/platformio/proc.py
+index 80e50201..15cee5a5 100644
+--- a/platformio/proc.py
++++ b/platformio/proc.py
+@@ -181,7 +181,7 @@ def copy_pythonpath_to_osenv():
+             conditions.append(isdir(join(p, "click")) or isdir(join(p, "platformio")))
+         if all(conditions):
+             _PYTHONPATH.append(p)
+-    os.environ["PYTHONPATH"] = os.pathsep.join(_PYTHONPATH)
++    os.environ["PYTHONPATH"] = os.pathsep.join(sys.path)
+ 
+ 
+ def where_is_program(program, envpath=None):
diff --git a/pkgs/development/embedded/platformio/missing-udev-rules-nixos.patch b/pkgs/development/embedded/platformio/missing-udev-rules-nixos.patch
new file mode 100644
index 00000000000..36af82245c5
--- /dev/null
+++ b/pkgs/development/embedded/platformio/missing-udev-rules-nixos.patch
@@ -0,0 +1,12 @@
+diff --git a/platformio/exception.py b/platformio/exception.py
+index ef1d3bab..445174fc 100644
+--- a/platformio/exception.py
++++ b/platformio/exception.py
+@@ -57,6 +57,7 @@ class MissedUdevRules(InvalidUdevRules):
+     MESSAGE = (
+         "Warning! Please install `99-platformio-udev.rules`. \nMore details: "
+         "https://docs.platformio.org/page/faq.html#platformio-udev-rules"
++        "On NixOS add the platformio package to services.udev.packages"
+     )
+ 
+ 
diff --git a/pkgs/development/embedded/platformio/use-local-spdx-license-list.patch b/pkgs/development/embedded/platformio/use-local-spdx-license-list.patch
new file mode 100644
index 00000000000..342fb120a0f
--- /dev/null
+++ b/pkgs/development/embedded/platformio/use-local-spdx-license-list.patch
@@ -0,0 +1,17 @@
+diff --git a/platformio/package/manifest/schema.py b/platformio/package/manifest/schema.py
+index 416dccfd..896c3649 100644
+--- a/platformio/package/manifest/schema.py
++++ b/platformio/package/manifest/schema.py
+@@ -253,9 +253,6 @@ class ManifestSchema(BaseSchema):
+     @staticmethod
+     @memoized(expire="1h")
+     def load_spdx_licenses():
+-        version = "3.16"
+-        spdx_data_url = (
+-            "https://raw.githubusercontent.com/spdx/license-list-data/"
+-            "v%s/json/licenses.json" % version
+-        )
+-        return json.loads(fetch_remote_content(spdx_data_url))
++        with open("@SPDX_LICENSE_LIST_DATA@/json/licenses.json") as f:
++            spdx = json.load(f)
++        return spdx
diff --git a/pkgs/development/embedded/rshell/default.nix b/pkgs/development/embedded/rshell/default.nix
new file mode 100644
index 00000000000..a537af3692b
--- /dev/null
+++ b/pkgs/development/embedded/rshell/default.nix
@@ -0,0 +1,31 @@
+{ lib
+, buildPythonApplication
+, fetchPypi
+, pyserial
+, pyudev
+, pythonOlder
+}:
+
+buildPythonApplication rec {
+  pname = "rshell";
+  version = "0.0.31";
+
+  disabled = pythonOlder "3.4";
+
+  src = fetchPypi {
+    inherit pname version;
+    sha256 = "7942b758a9ae5c6ff46516b0317f437dfce9f0721f3a3b635ebd501c9cd38fb9";
+  };
+
+  propagatedBuildInputs = [
+    pyserial
+    pyudev
+  ];
+
+  meta = with lib; {
+    homepage = "https://github.com/dhylands/rshell";
+    description = "Remote Shell for MicroPython";
+    license = licenses.mit;
+    maintainers = with maintainers; [ c0deaddict ];
+  };
+}
diff --git a/pkgs/development/embedded/stm32/betaflight/default.nix b/pkgs/development/embedded/stm32/betaflight/default.nix
new file mode 100644
index 00000000000..1ecf9be5d8d
--- /dev/null
+++ b/pkgs/development/embedded/stm32/betaflight/default.nix
@@ -0,0 +1,64 @@
+{ lib, stdenv, fetchFromGitHub
+, gcc-arm-embedded, binutils-arm-embedded, python2
+, skipTargets ? [
+  # These targets do not build, for the reasons listed, along with the last version checked.
+  # Probably all of the issues with these targets need to be addressed upstream.
+  "AG3X"       # 3.4.0-rc4: has not specified a valid STM group, must be one of F1, F3, F405, F411 or F7x5. Have you prepared a valid target.mk?
+  "ALIENWHOOP" # 3.4.0-rc4: has not specified a valid STM group, must be one of F1, F3, F405, F411 or F7x5. Have you prepared a valid target.mk?
+  "FURYF3"     # 3.4.0-rc4: flash region overflow
+  "OMNINXT"    # 3.4.0-rc4: has not specified a valid STM group, must be one of F1, F3, F405, F411 or F7x5. Have you prepared a valid target.mk?
+]}:
+
+stdenv.mkDerivation rec {
+
+  pname = "betaflight";
+  version = "3.4.0-rc4";
+
+  src = fetchFromGitHub {
+    owner = "betaflight";
+    repo = "betaflight";
+    rev = "8e9e7574481b1abba9354b24f41eb31054943785"; # Always use a commit id here!
+    sha256 = "1wyp23p876xbfi9z6gm4xn1nwss3myvrjjjq9pd3s0vf5gkclkg5";
+  };
+
+  nativeBuildInputs = [
+    gcc-arm-embedded binutils-arm-embedded
+    python2
+  ];
+
+  postPatch = ''
+    sed -ri "s/REVISION.*=.*git log.*/REVISION = ${builtins.substring 0 10 src.rev}/" Makefile # Simulate abbrev'd rev.
+    sed -ri "s/binary hex/hex/" Makefile # No need for anything besides .hex
+
+    substituteInPlace Makefile \
+      --replace "--specs=nano.specs" ""
+  '';
+
+  enableParallelBuilding = true;
+
+  preBuild = ''
+    buildFlagsArray=(
+      "NOBUILD_TARGETS=${toString skipTargets}"
+      "GCC_REQUIRED_VERSION=$(arm-none-eabi-gcc -dumpversion)"
+      all
+    )
+  '';
+
+  installPhase = ''
+    runHook preInstall
+
+    mkdir -p $out
+    cp obj/*.hex $out
+
+    runHook postInstall
+  '';
+
+  meta = with lib; {
+    description = "Flight controller software (firmware) used to fly multi-rotor craft and fixed wing craft";
+    homepage = "https://github.com/betaflight/betaflight";
+    license = licenses.gpl3;
+    maintainers = with maintainers; [ elitak ];
+    broken = true;
+  };
+
+}
diff --git a/pkgs/development/embedded/stm32/inav/default.nix b/pkgs/development/embedded/stm32/inav/default.nix
new file mode 100644
index 00000000000..c1f762e47d8
--- /dev/null
+++ b/pkgs/development/embedded/stm32/inav/default.nix
@@ -0,0 +1,56 @@
+{ lib, stdenv, fetchFromGitHub
+, gcc-arm-embedded, binutils-arm-embedded, ruby
+}:
+
+stdenv.mkDerivation rec {
+
+  pname = "inav";
+  version = "2.0.0-rc2";
+
+  src = fetchFromGitHub {
+    owner = "iNavFlight";
+    repo = "inav";
+    rev = "a8415e89c2956d133d8175827c079bcf3bc3766c"; # Always use a commit id here!
+    sha256 = "15zai8qf43b06fmws1sbkmdgip51zp7gkfj7pp9b6gi8giarzq3y";
+  };
+
+  nativeBuildInputs = [
+    gcc-arm-embedded binutils-arm-embedded
+    ruby
+  ];
+
+  postPatch = ''
+    sed -ri "s/REVISION.*=.*shell git.*/REVISION = ${builtins.substring 0 10 src.rev}/" Makefile # Simulate abbrev'd rev.
+    sed -ri "s/-j *[0-9]+//" Makefile # Eliminate parallel build args in submakes
+    sed -ri "s/binary hex/hex/" Makefile # No need for anything besides .hex
+
+    substituteInPlace Makefile \
+      --replace "--specs=nano.specs" ""
+  '';
+
+  enableParallelBuilding = true;
+
+  preBuild = ''
+    buildFlagsArray=(
+      all
+    )
+  '';
+
+  installPhase = ''
+    runHook preInstall
+
+    mkdir -p $out
+    cp obj/*.hex $out
+
+    runHook postInstall
+  '';
+
+  meta = with lib; {
+    description = "Navigation-enabled flight control software";
+    homepage = "https://inavflight.github.io";
+    license = licenses.gpl3;
+    maintainers = with maintainers; [ elitak ];
+    broken = true;
+  };
+
+}
diff --git a/pkgs/development/embedded/stm32/stm32cubemx/default.nix b/pkgs/development/embedded/stm32/stm32cubemx/default.nix
new file mode 100644
index 00000000000..e6ead8dd372
--- /dev/null
+++ b/pkgs/development/embedded/stm32/stm32cubemx/default.nix
@@ -0,0 +1,71 @@
+{ lib, stdenv, makeDesktopItem, copyDesktopItems, icoutils, fdupes, imagemagick, jdk11, fetchzip }:
+# TODO: JDK16 causes STM32CubeMX to crash right now, so we fixed the version to JDK11
+# This may be fixed in a future version of STM32CubeMX. This issue has been reported to ST:
+# https://community.st.com/s/question/0D53W00000jnOzPSAU/stm32cubemx-crashes-on-launch-with-openjdk16
+# If you're updating this derivation, check the link above to see if it's been fixed upstream
+# and try replacing all occurrences of jdk11 with jre and test whether it works.
+let
+  iconame = "STM32CubeMX";
+in
+stdenv.mkDerivation rec {
+  pname = "stm32cubemx";
+  version = "6.5.0";
+
+  src = fetchzip {
+    url = "https://sw-center.st.com/packs/resource/library/stm32cube_mx_v${builtins.replaceStrings ["."] [""] version}-lin.zip";
+    sha256 = "sha256-19RG+bJCmkaytMtDpDLbDvfKo27Z+Mo/sOrs8lOVV44=";
+    stripRoot = false;
+  };
+
+  nativeBuildInputs = [ icoutils fdupes imagemagick copyDesktopItems];
+  desktopItems = [
+    (makeDesktopItem {
+      name = "stm32CubeMX";
+      exec = "stm32cubemx";
+      desktopName = "STM32CubeMX";
+      categories = [ "Development" ];
+      comment = "STM32Cube initialization code generator";
+      icon = "stm32cubemx";
+    })
+  ];
+
+  buildCommand = ''
+    mkdir -p $out/{bin,opt/STM32CubeMX}
+    cp -r $src/MX/. $out/opt/STM32CubeMX/
+    chmod +rx $out/opt/STM32CubeMX/STM32CubeMX
+    cat << EOF > $out/bin/${pname}
+    #!${stdenv.shell}
+    ${jdk11}/bin/java -jar $out/opt/STM32CubeMX/STM32CubeMX
+    EOF
+    chmod +x $out/bin/${pname}
+
+    icotool --extract $out/opt/STM32CubeMX/help/${iconame}.ico
+    fdupes -dN . > /dev/null
+    ls
+    for size in 16 24 32 48 64 128 256; do
+      mkdir -pv $out/share/icons/hicolor/"$size"x"$size"/apps
+      if [ $size -eq 256 ]; then
+        mv ${iconame}_*_"$size"x"$size"x32.png \
+          $out/share/icons/hicolor/"$size"x"$size"/apps/${pname}.png
+      else
+        convert -resize "$size"x"$size" ${iconame}_*_256x256x32.png \
+          $out/share/icons/hicolor/"$size"x"$size"/apps/${pname}.png
+      fi
+    done;
+  '';
+
+  meta = with lib; {
+    description = "A graphical tool for configuring STM32 microcontrollers and microprocessors";
+    longDescription = ''
+      A graphical tool that allows a very easy configuration of STM32
+      microcontrollers and microprocessors, as well as the generation of the
+      corresponding initialization C code for the Arm® Cortex®-M core or a
+      partial Linux® Device Tree for Arm® Cortex®-A core), through a
+      step-by-step process.
+    '';
+    homepage = "https://www.st.com/en/development-tools/stm32cubemx.html";
+    license = licenses.unfree;
+    maintainers = with maintainers; [ wucke13 ];
+    platforms = platforms.all;
+  };
+}
diff --git a/pkgs/development/embedded/stm32/stm32flash/default.nix b/pkgs/development/embedded/stm32/stm32flash/default.nix
new file mode 100644
index 00000000000..52b30115499
--- /dev/null
+++ b/pkgs/development/embedded/stm32/stm32flash/default.nix
@@ -0,0 +1,27 @@
+{ lib, stdenv, fetchurl }:
+
+stdenv.mkDerivation rec {
+  pname = "stm32flash";
+  version = "0.6";
+
+  src = fetchurl {
+    url = "mirror://sourceforge/${pname}/${pname}-${version}.tar.gz";
+    sha256 = "sha256-7ptA1NPlzSi5k+CK4qLDxVm2vqhzDNfh1Acn3tsd2gk=";
+  };
+
+  buildFlags = [ "CC=${stdenv.cc.targetPrefix}cc" ];
+
+  installPhase = ''
+    # Manually copy, make install copies to /usr/local/bin
+    mkdir -pv $out/bin/
+    cp stm32flash $out/bin/
+  '';
+
+  meta = with lib; {
+    description = "Open source flash program for the STM32 ARM processors using the ST bootloader";
+    homepage = "https://sourceforge.net/projects/stm32flash/";
+    license = lib.licenses.gpl2;
+    platforms = platforms.all; # Should work on all platforms
+    maintainers = with maintainers; [ elitak ];
+  };
+}
diff --git a/pkgs/development/embedded/teensy-loader-cli/default.nix b/pkgs/development/embedded/teensy-loader-cli/default.nix
new file mode 100644
index 00000000000..ccae9377024
--- /dev/null
+++ b/pkgs/development/embedded/teensy-loader-cli/default.nix
@@ -0,0 +1,46 @@
+{ stdenv
+, lib
+, fetchFromGitHub
+, go-md2man
+, installShellFiles
+, libusb-compat-0_1
+}:
+
+stdenv.mkDerivation rec {
+  pname = "teensy-loader-cli";
+  version = "2.1+unstable=2021-04-10";
+
+  src = fetchFromGitHub {
+    owner = "PaulStoffregen";
+    repo = "teensy_loader_cli";
+    rev = "9dbbfa3b367b6c37e91e8a42dae3c6edfceccc4d";
+    sha256 = "lQ1XtaWPr6nvE8NArD1980QVOH6NggO3FlfsntUjY7s=";
+  };
+
+  nativeBuildInputs = [
+    go-md2man
+    installShellFiles
+  ];
+
+  buildInputs = [
+    libusb-compat-0_1
+  ];
+
+  installPhase = ''
+    runHook preInstall
+
+    install -Dm555 teensy_loader_cli $out/bin/teensy-loader-cli
+    install -Dm444 -t $out/share/doc/${pname} *.md *.txt
+    go-md2man -in README.md -out ${pname}.1
+    installManPage *.1
+
+    runHook postInstall
+  '';
+
+  meta = with lib; {
+    description = "Firmware uploader for the Teensy microcontroller boards";
+    homepage = "https://www.pjrc.com/teensy/";
+    license = licenses.gpl3Only;
+    platforms = platforms.unix;
+  };
+}
diff --git a/pkgs/development/embedded/tytools/default.nix b/pkgs/development/embedded/tytools/default.nix
new file mode 100644
index 00000000000..23bab058c59
--- /dev/null
+++ b/pkgs/development/embedded/tytools/default.nix
@@ -0,0 +1,26 @@
+{ lib, stdenv, fetchFromGitHub, cmake, pkg-config, wrapQtAppsHook , qtbase}:
+
+stdenv.mkDerivation rec {
+  pname = "tytools";
+  version = "0.9.7";
+
+  src = fetchFromGitHub {
+    owner = "Koromix";
+    repo = pname;
+    rev = "v${version}";
+    sha256 = "sha256-iF2XyWSBBCO23iY/ni+QlpgtOuWKN2JTMTz+9OLEadk=";
+  };
+
+  nativeBuildInputs = [ cmake pkg-config wrapQtAppsHook ];
+  buildInputs = [
+    qtbase
+  ];
+
+  meta = with lib; {
+    description = "Collection of tools to manage Teensy boards";
+    homepage = "https://koromix.dev/tytools";
+    license = licenses.unlicense;
+    platforms = platforms.unix;
+    maintainers = with maintainers; [ ahuzik ];
+  };
+}
diff --git a/pkgs/development/embedded/uisp/default.nix b/pkgs/development/embedded/uisp/default.nix
new file mode 100644
index 00000000000..986a560ff6e
--- /dev/null
+++ b/pkgs/development/embedded/uisp/default.nix
@@ -0,0 +1,20 @@
+{ lib, stdenv, fetchurl }:
+
+stdenv.mkDerivation rec {
+  pname = "uisp";
+  version = "20050207";
+
+  src = fetchurl {
+    url = "https://savannah.nongnu.org/download/uisp/uisp-${version}.tar.gz";
+    sha256 = "1bncxp5yxh9r1yrp04vvhfiva8livi1pwic7v8xj99q09zrwahvw";
+  };
+
+  NIX_CFLAGS_COMPILE = "-Wno-error";
+
+  meta = {
+    description = "Tool for AVR microcontrollers which can interface to many hardware in-system programmers";
+    license = lib.licenses.gpl2;
+    homepage = "https://savannah.nongnu.org/projects/uisp";
+    platforms = lib.platforms.linux;
+  };
+}
diff --git a/pkgs/development/embedded/xc3sprog/default.nix b/pkgs/development/embedded/xc3sprog/default.nix
new file mode 100644
index 00000000000..b9785bac7c5
--- /dev/null
+++ b/pkgs/development/embedded/xc3sprog/default.nix
@@ -0,0 +1,26 @@
+{ lib, stdenv, fetchsvn, cmake, libusb-compat-0_1, libftdi }:
+
+# The xc3sprog project doesn't seem to make proper releases, they only put out
+# prebuilt binary subversion snapshots on sourceforge.
+
+stdenv.mkDerivation rec {
+  version = "787";
+  pname = "xc3sprog";
+
+  src = fetchsvn {
+    url = "https://svn.code.sf.net/p/xc3sprog/code/trunk";
+    sha256 = "1rfhms3i7375kdlg0sdg5k52ix3xv5llj2dr30vamyg7pk74y8rx";
+    rev = version;
+  };
+
+  nativeBuildInputs = [ cmake ];
+  buildInputs = [ libusb-compat-0_1 libftdi ];
+
+  meta = with lib; {
+    description = "Command-line tools for programming FPGAs, microcontrollers and PROMs via JTAG";
+    homepage = "http://xc3sprog.sourceforge.net/";
+    license = licenses.gpl2Plus;
+    platforms = platforms.linux;
+    maintainers = [ maintainers.bjornfor ];
+  };
+}