From 54c5fafe32f8649e90534ec6704bc06670e1d644 Mon Sep 17 00:00:00 2001
From: Benjamin Koch <bbbsnowball@gmail.com>
Date: Sun, 28 May 2023 04:15:15 +0200
Subject: [PATCH] add build script for UF2 files

---
 firmware/rust1/.gitignore |  1 +
 firmware/rust1/build.sh   | 32 ++++++++++++++++++++++
 firmware/rust1/uf2.py     | 56 +++++++++++++++++++++++++++++++++++++++
 flake.nix                 |  7 ++++-
 4 files changed, 95 insertions(+), 1 deletion(-)
 create mode 100755 firmware/rust1/build.sh
 create mode 100644 firmware/rust1/uf2.py

diff --git a/firmware/rust1/.gitignore b/firmware/rust1/.gitignore
index b83d222..8d92b5d 100644
--- a/firmware/rust1/.gitignore
+++ b/firmware/rust1/.gitignore
@@ -1 +1,2 @@
 /target/
+/.cargo-tools/
diff --git a/firmware/rust1/build.sh b/firmware/rust1/build.sh
new file mode 100755
index 0000000..2aa4549
--- /dev/null
+++ b/firmware/rust1/build.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+set -e
+cd "$(dirname "$0")"
+
+if ! [ -e .cargo-tools/bin/cargo-objcopy ] ; then
+    cargo install --root "$PWD/.cargo-tools/" cargo-binutils
+fi
+if ! [ -e .cargo-tools/bin/elf2uf2-rs ] ; then
+    cargo install --root "$PWD/.cargo-tools/" elf2uf2-rs
+fi
+if ! [ -e .cargo-tools/bin/probe-rs-cli ] ; then
+    cargo install --root "$PWD/.cargo-tools/" probe-rs-cli
+fi
+if ! [ -e .cargo-tools/bin/probe-rs-debugger ] ; then
+    cargo install --root "$PWD/.cargo-tools/" probe-rs-debugger
+fi
+
+( cd ../rust1-bootloader && cargo build --release )
+./.cargo-tools/bin/elf2uf2-rs ../rust1-bootloader/target/thumbv6m-none-eabi/release/heizung-bootloader
+
+cargo build --bin heizung
+cargo objdump --bin heizung -- -xd >target/thumbv6m-none-eabi/debug/heizung.map
+cargo build --bin heizung --release
+cargo objdump --bin heizung --release -- -xd >target/thumbv6m-none-eabi/release/heizung.map
+./.cargo-tools/bin/elf2uf2-rs target/thumbv6m-none-eabi/debug/heizung
+./.cargo-tools/bin/elf2uf2-rs target/thumbv6m-none-eabi/release/heizung
+
+cat ../rust1-bootloader/target/thumbv6m-none-eabi/release/heizung-bootloader.uf2 target/thumbv6m-none-eabi/debug/heizung.uf2 >heizung-debug.uf2
+cat ../rust1-bootloader/target/thumbv6m-none-eabi/release/heizung-bootloader.uf2 target/thumbv6m-none-eabi/release/heizung.uf2 >heizung-release.uf2
+
+size target/thumbv6m-none-eabi/debug/heizung
+size target/thumbv6m-none-eabi/release/heizung
diff --git a/firmware/rust1/uf2.py b/firmware/rust1/uf2.py
new file mode 100644
index 0000000..d6e71b9
--- /dev/null
+++ b/firmware/rust1/uf2.py
@@ -0,0 +1,56 @@
+import sys, struct
+
+with open(sys.argv[1], "rb") as f:
+    contents = f.read()
+
+# see https://github.com/JoNil/elf2uf2-rs/blob/master/src/uf2.rs
+UF2_MAGIC_START0 = 0x0A324655
+UF2_MAGIC_START1 = 0x9E5D5157
+UF2_MAGIC_END = 0x0AB16F30
+
+UF2_FLAG_NOT_MAIN_FLASH = 0x00000001
+UF2_FLAG_FILE_CONTAINER = 0x00001000
+UF2_FLAG_FAMILY_ID_PRESENT = 0x00002000
+UF2_FLAG_MD5_PRESENT = 0x00004000
+
+RP2040_FAMILY_ID = 0xe48bff56
+
+offset = 0
+while offset < len(contents):
+    frame = contents[offset:offset+512]
+    magic_start0, magic_start1, flags, target_addr, payload_size, block_no, num_blocks, file_size \
+        = struct.unpack_from("<IIIIIIII", frame, offset=0)
+    magic_end, = struct.unpack_from("<I", frame, offset=512-4)
+    if magic_start0 != UF2_MAGIC_START0 or magic_start1 != UF2_MAGIC_START1 or magic_end != UF2_MAGIC_END:
+        print("not UF2 at offset %r" % offset)
+        break
+
+    flags_str = []
+    flags2 = flags
+    if (flags & UF2_FLAG_NOT_MAIN_FLASH) != 0:
+        flags2 &= ~UF2_FLAG_NOT_MAIN_FLASH
+        flags_str.append("not_main")
+    if (flags & UF2_FLAG_FILE_CONTAINER) != 0:
+        flags2 &= ~UF2_FLAG_FILE_CONTAINER
+        flags_str.append("file")
+    if (flags & UF2_FLAG_FAMILY_ID_PRESENT) != 0:
+        flags2 &= ~UF2_FLAG_FAMILY_ID_PRESENT
+        flags_str.append("family")
+    if (flags & UF2_FLAG_MD5_PRESENT) != 0:
+        flags2 &= ~UF2_FLAG_MD5_PRESENT
+        flags_str.append("md5")
+    if flags2 != 0:
+        flags_str.append("0x08x" % flags2)
+
+    file_size_or_family = ""
+    if (flags & UF2_FLAG_FAMILY_ID_PRESENT) != 0:
+        if file_size == RP2040_FAMILY_ID:
+            file_size_or_family = "rp2040"
+        else:
+            file_size_or_family = "family 0x%08x" % file_size
+    else:
+            file_size_or_family = "file size %s" % file_size
+
+    print("block %-6s: target 0x%08x, size %3s, block %3s/%3s, %s, %s" % (
+        offset, target_addr, payload_size, block_no, num_blocks, file_size_or_family, " ".join(flags_str)))
+    offset += 512
diff --git a/flake.nix b/flake.nix
index 4b8e679..6cd4659 100644
--- a/flake.nix
+++ b/flake.nix
@@ -150,6 +150,11 @@
             #fi
           '';
         };
+        devShells.rust = with self.packages.${system}; pkgs.mkShell {
+          packages = with pkgs; [
+            rustup udev.dev pkg-config openssl.dev picotool
+          ];
+        };
       }
     );
-}
\ No newline at end of file
+}
-- 
GitLab