From 9d2ca58a06a91ab90f67b7e73598bb87238a1c6d Mon Sep 17 00:00:00 2001
From: Samuel Tardieu <sam@rfc1149.net>
Date: Tue, 30 Jul 2024 18:30:32 +0200
Subject: [PATCH] Check if a firmware is installed

---
 Cargo.lock                         |  4 ++--
 README.org                         |  1 +
 bootloader/Cargo.toml              |  2 +-
 bootloader/src/flash.rs            |  7 ++++---
 firmware-updater/Cargo.toml        |  2 +-
 firmware-updater/src/bootloader.rs |  2 ++
 firmware-updater/src/cli.rs        |  4 +++-
 firmware-updater/src/main.rs       | 10 +++++++++-
 8 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 8f4e3e8..31bc357 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -122,7 +122,7 @@ checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
 
 [[package]]
 name = "bootloader"
-version = "0.1.0"
+version = "0.2.0"
 dependencies = [
  "bootloader-params",
  "build-support",
@@ -679,7 +679,7 @@ dependencies = [
 
 [[package]]
 name = "firmware-updater"
-version = "0.1.0"
+version = "0.2.0"
 dependencies = [
  "bootloader-params",
  "clap",
diff --git a/README.org b/README.org
index 7af08af..204fa42 100644
--- a/README.org
+++ b/README.org
@@ -211,6 +211,7 @@ Returns two bytes:
     - 0x01: system is in programming mode
     - 0x02: at least one error was detected since the last time the
       system has been put in programming mode
+    - 0x04: a program is currently present in flash
 - A XORed version of all data received so far since the programming
   address was last set, either by entering programming mode, or by
   using the SET PROGRAMMING ADDRESS command.
diff --git a/bootloader/Cargo.toml b/bootloader/Cargo.toml
index 10e7008..93dae20 100644
--- a/bootloader/Cargo.toml
+++ b/bootloader/Cargo.toml
@@ -2,7 +2,7 @@
 name = "bootloader"
 description = "I²C bootloader for DC Motor Driver Hat DFR0592"
 authors = ["Samuel Tardieu <sam@rfc1149.net>"]
-version = "0.1.0"
+version = "0.2.0"
 edition = "2021"
 
 [dependencies]
diff --git a/bootloader/src/flash.rs b/bootloader/src/flash.rs
index 1ed99d8..096df8c 100644
--- a/bootloader/src/flash.rs
+++ b/bootloader/src/flash.rs
@@ -11,7 +11,7 @@ use embassy_stm32::{
 };
 use heapless::Vec;
 use i2c2_target::MESSAGE_SIZE;
-use support::boot_control::APPLICATION_MAGIC;
+use support::boot_control::{self, APPLICATION_MAGIC};
 
 pub struct ProgrammingState {
     flash: Flash<'static, Blocking>,
@@ -87,8 +87,9 @@ impl ProgrammingState {
     ) -> bool {
         match command {
             [CMD_STATUS] => {
-                let flags =
-                    u8::from(self.programming_mode) | (u8::from(self.programming_error) << 1);
+                let flags = u8::from(self.programming_mode)
+                    | (u8::from(self.programming_error) << 1)
+                    | (u8::from(boot_control::is_application_present()) << 2);
                 response.push(flags).unwrap();
                 response.push(self.checksum).unwrap();
             }
diff --git a/firmware-updater/Cargo.toml b/firmware-updater/Cargo.toml
index 64043c4..41a7a09 100644
--- a/firmware-updater/Cargo.toml
+++ b/firmware-updater/Cargo.toml
@@ -2,7 +2,7 @@
 name = "firmware-updater"
 description = "Firmware updater for DC Motor Driver Hat DFR0592"
 authors = ["Samuel Tardieu <sam@rfc1149.net>"]
-version = "0.1.0"
+version = "0.2.0"
 edition = "2021"
 rust-version = "1.80.0"
 
diff --git a/firmware-updater/src/bootloader.rs b/firmware-updater/src/bootloader.rs
index f592b9e..eaaae3c 100644
--- a/firmware-updater/src/bootloader.rs
+++ b/firmware-updater/src/bootloader.rs
@@ -67,6 +67,7 @@ pub type Result<T, E = Error> = std::result::Result<T, E>;
 pub struct Status {
     pub programming_mode: bool,
     pub error_detected: bool,
+    pub application_present: bool,
     pub checksum: u8,
 }
 
@@ -98,6 +99,7 @@ pub fn get_status(i2c: &I2c) -> Result<Status> {
     Ok(Status {
         programming_mode: data[0] & 1 != 0,
         error_detected: data[0] & 2 != 0,
+        application_present: data[0] & 4 != 0,
         checksum: data[1],
     })
 }
diff --git a/firmware-updater/src/cli.rs b/firmware-updater/src/cli.rs
index f8cd635..81c1ed8 100644
--- a/firmware-updater/src/cli.rs
+++ b/firmware-updater/src/cli.rs
@@ -14,7 +14,9 @@ pub enum Command {
     CheckFile(CheckFileArgs),
     /// Flash firmware
     Flash(FlashArgs),
-    /// Read the status of the program currently running
+    /// Read the status of the program currently running, and
+    /// check if there is a firmware installed if we are in
+    /// bootloader mode.
     Status(StatusArgs),
 }
 
diff --git a/firmware-updater/src/main.rs b/firmware-updater/src/main.rs
index 40349af..6b6bba6 100644
--- a/firmware-updater/src/main.rs
+++ b/firmware-updater/src/main.rs
@@ -233,6 +233,14 @@ fn cmd_flash(args: FlashArgs) -> Result<()> {
 
 fn cmd_status(args: StatusArgs) -> Result<()> {
     let mut i2c = I2c::with_bus(args.i2c_bus)?;
-    println!("Running program: {}", bootloader::active_program(&mut i2c)?);
+    let active_program = bootloader::active_program(&mut i2c)?;
+    println!("Running program: {active_program}");
+    if matches!(active_program, ActiveProgram::Bootloader(_)) {
+        if bootloader::get_status(&i2c)?.application_present {
+            println!("Application present in flash memory");
+        } else {
+            println!("No application present in flash memory");
+        }
+    }
     Ok(())
 }
-- 
GitLab