diff --git a/Cargo.lock b/Cargo.lock
index a36da1424e28a8641303c940af0f665ddaf0b34d..1dea7a6d50c5421632d57d200e752c9e8f720dd1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2003,19 +2003,6 @@ dependencies = [
  "regex-automata 0.1.10",
 ]
 
-[[package]]
-name = "mavlink-bindgen"
-version = "0.14.0"
-dependencies = [
- "crc-any",
- "lazy_static",
- "proc-macro2",
- "quick-xml 0.36.2",
- "quote",
- "serde",
- "thiserror 1.0.69",
-]
-
 [[package]]
 name = "mavlink-bindgen"
 version = "0.14.0"
@@ -2987,7 +2974,7 @@ dependencies = [
  "egui_plot",
  "egui_tiles",
  "enum_dispatch",
- "mavlink-bindgen 0.14.0",
+ "mavlink-bindgen",
  "profiling",
  "rand 0.9.0",
  "ring-channel",
@@ -3162,9 +3149,10 @@ checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
 [[package]]
 name = "skyward_mavlink"
 version = "0.1.1"
+source = "git+https://git.skywarder.eu/avn/swd/mavlink/mavlink-skyward-lib.git?branch=rust-strum#8f0700acc0def0cdb2d2ae490e0703fd6c820643"
 dependencies = [
  "bitflags 2.9.0",
- "mavlink-bindgen 0.14.0 (git+https://git.skywarder.eu/avn/swd/mavlink/rust-mavlink.git?rev=b7446436b3c96ca4c40d28b54eeed346e7bf021e)",
+ "mavlink-bindgen",
  "mavlink-core",
  "num-derive",
  "num-traits",
diff --git a/Cargo.toml b/Cargo.toml
index f6be7f44b8911bbc0326646437d784ddc6eb244a..d7507aa49ed77f86c2121a11b03fd0b0e2607599 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -18,20 +18,11 @@ egui_file = "0.22"
 # =========== Asynchronous ===========
 tokio = { version = "1.41", features = ["rt-multi-thread", "net", "sync"] }
 # =========== Mavlink ===========
-# skyward_mavlink = { git = "https://git.skywarder.eu/avn/swd/mavlink/mavlink-skyward-lib.git", branch = "rust-strum", features = [
-#     "reflection",
-#     "orion",
-#     "serde",
-# ] }
-skyward_mavlink = { path = "../mavlink-skyward-lib/mavlink_rust", features = [
+skyward_mavlink = { git = "https://git.skywarder.eu/avn/swd/mavlink/mavlink-skyward-lib.git", branch = "rust-strum", features = [
     "reflection",
     "orion",
     "serde",
 ] }
-# mavlink-bindgen = { version = "0.14", features = ["serde"] }
-mavlink-bindgen = { path = "../rust-mavlink/mavlink-bindgen", features = [
-    "serde",
-] }
 serialport = "4.7.0"
 # ========= Persistency =========
 serde = { version = "1.0", features = ["derive"] }
@@ -51,5 +42,10 @@ anyhow = "1.0"
 ring-channel = "0.12.0"
 thiserror = "2.0.7"
 
+[dependencies.mavlink-bindgen]
+git = "https://git.skywarder.eu/avn/swd/mavlink/rust-mavlink.git"
+rev = "b7446436b3c96ca4c40d28b54eeed346e7bf021e"
+features = ["serde"]
+
 [dev-dependencies]
 rand = "0.9.0"
diff --git a/src/communication/serial.rs b/src/communication/serial.rs
index 8f1c6fa73b6c4c924357f0050857d371f02d4762..b4d3897c8b563727e67dfb15e277cd9cae91dccd 100644
--- a/src/communication/serial.rs
+++ b/src/communication/serial.rs
@@ -51,6 +51,40 @@ pub fn find_first_stm32_port() -> Result<Option<SerialPortInfo>, serialport::Err
     Ok(None)
 }
 
+pub mod cached {
+    use egui::Context;
+
+    use crate::ui::cache::CacheCall;
+
+    use super::*;
+
+    /// Returns a cached list of all available USB ports.
+    ///
+    /// # Arguments
+    /// * `ctx` - The egui context used for caching.
+    ///
+    /// # Returns
+    /// * A Result containing a vector of `SerialPortInfo` or a `serialport::Error`.
+    pub fn cached_list_all_usb_ports(
+        ctx: &Context,
+    ) -> Result<Vec<SerialPortInfo>, serialport::Error> {
+        ctx.call_cached_short(&"list_usb_ports", list_all_usb_ports)
+    }
+
+    /// Returns the first cached STM32 port found, if any.
+    ///
+    /// # Arguments
+    /// * `ctx` - The egui context used for caching.
+    ///
+    /// # Returns
+    /// * A Result containing an Option of `SerialPortInfo` or a `serialport::Error`.
+    pub fn cached_first_stm32_port(
+        ctx: &Context,
+    ) -> Result<Option<SerialPortInfo>, serialport::Error> {
+        ctx.call_cached_short(&"find_first_stm32_port", find_first_stm32_port)
+    }
+}
+
 /// Configuration for a serial connection.
 #[derive(Debug, Clone)]
 pub struct SerialConfiguration {
diff --git a/src/mavlink/reflection.rs b/src/mavlink/reflection.rs
index 68937c62c5b549a27abf81fa5bed5ae09f4540e8..c9f8a7fc585cee4d3fae97cdd3124ee9fc85a22f 100644
--- a/src/mavlink/reflection.rs
+++ b/src/mavlink/reflection.rs
@@ -128,10 +128,7 @@ impl IndexedField<'_> {
 }
 
 pub trait MessageLike {
-    fn to_mav_message<'a, 'b>(
-        &'a self,
-        ctx: &'b ReflectionContext,
-    ) -> Result<&'b MavMessage, String>;
+    fn to_mav_message<'b>(&self, ctx: &'b ReflectionContext) -> Result<&'b MavMessage, String>;
 }
 
 pub trait FieldLike<'a, 'b> {
@@ -143,10 +140,7 @@ pub trait FieldLike<'a, 'b> {
 }
 
 impl MessageLike for u32 {
-    fn to_mav_message<'a, 'b>(
-        &'a self,
-        ctx: &'b ReflectionContext,
-    ) -> Result<&'b MavMessage, String> {
+    fn to_mav_message<'b>(&self, ctx: &'b ReflectionContext) -> Result<&'b MavMessage, String> {
         ctx.id_msg_map
             .get(self)
             .ok_or_else(|| format!("Message {} not found", self))
@@ -154,10 +148,7 @@ impl MessageLike for u32 {
 }
 
 impl MessageLike for &str {
-    fn to_mav_message<'a, 'b>(
-        &'a self,
-        ctx: &'b ReflectionContext,
-    ) -> Result<&'b MavMessage, String> {
+    fn to_mav_message<'b>(&self, ctx: &'b ReflectionContext) -> Result<&'b MavMessage, String> {
         ctx.mavlink_profile
             .messages
             .iter()
@@ -203,6 +194,7 @@ impl<'b> FieldLike<'b, 'b> for IndexedField<'b> {
         })
     }
 }
+
 impl<'b> FieldLike<'_, 'b> for usize {
     fn to_mav_field(
         &self,
@@ -221,6 +213,7 @@ impl<'b> FieldLike<'_, 'b> for usize {
             .ok_or_else(|| format!("Field {} not found in message {}", self, msg_id))
     }
 }
+
 impl<'b> FieldLike<'_, 'b> for &str {
     fn to_mav_field(
         &self,
diff --git a/src/ui.rs b/src/ui.rs
index 383fabd62708460d45dd65f105faf3feb5f75975..077abdba17c67d09579d71aa56bf547fbe52910f 100644
--- a/src/ui.rs
+++ b/src/ui.rs
@@ -1,5 +1,5 @@
 mod app;
-mod cache;
+pub mod cache;
 mod panes;
 mod persistency;
 mod shortcuts;
diff --git a/src/ui/cache.rs b/src/ui/cache.rs
index 23d894d5b73859904f6767094245adcc0f44356a..9835924607803fe30d82dc326ae6d8541970abb2 100644
--- a/src/ui/cache.rs
+++ b/src/ui/cache.rs
@@ -13,6 +13,8 @@ use serialport::SerialPortInfo;
 use crate::{communication, error::ErrInstrument};
 
 const SERIAL_PORT_REFRESH_INTERVAL: Duration = Duration::from_millis(500);
+const SHORT_REFRESH_INTERVAL: Duration = Duration::from_millis(500);
+const INDEF_REFRESH_INTERVAL: Duration = Duration::MAX;
 
 /// Internal helper function that caches the result of a given function call for a specified duration.
 ///
@@ -42,7 +44,9 @@ where
 
 /// A trait to extend egui's Context with a caching function.
 pub trait CacheCall {
-    /// Calls the provided function and caches its result.
+    /// Calls the provided function and caches its result. Every time this
+    /// function is called, it will return the cached value if it is still
+    /// valid.
     ///
     /// # Arguments
     /// * `id` - A unique identifier for the cached value.
@@ -52,6 +56,26 @@ pub trait CacheCall {
     where
         F: Fn() -> T,
         T: Clone + Send + Sync + 'static;
+
+    fn call_cached_short<F, T, H>(&self, hashable: &H, fun: F) -> T
+    where
+        F: Fn() -> T,
+        T: Clone + Send + Sync + 'static,
+        H: Hash,
+    {
+        let id = egui::Id::new(hashable);
+        self.call_cached(id, fun, SHORT_REFRESH_INTERVAL)
+    }
+
+    fn call_cached_indef<F, T, H>(&self, hashable: &H, fun: F) -> T
+    where
+        F: Fn() -> T,
+        T: Clone + Send + Sync + 'static,
+        H: Hash,
+    {
+        let id = egui::Id::new(hashable);
+        self.call_cached(id, fun, INDEF_REFRESH_INTERVAL)
+    }
 }
 
 impl CacheCall for egui::Context {
@@ -65,36 +89,6 @@ impl CacheCall for egui::Context {
     }
 }
 
-/// Returns a cached list of all available USB ports.
-///
-/// # Arguments
-/// * `ctx` - The egui context used for caching.
-///
-/// # Returns
-/// * A Result containing a vector of `SerialPortInfo` or a `serialport::Error`.
-pub fn cached_list_all_usb_ports(ctx: &Context) -> Result<Vec<SerialPortInfo>, serialport::Error> {
-    ctx.call_cached(
-        egui::Id::new("list_usb_ports"),
-        communication::serial::list_all_usb_ports,
-        SERIAL_PORT_REFRESH_INTERVAL,
-    )
-}
-
-/// Returns the first cached STM32 port found, if any.
-///
-/// # Arguments
-/// * `ctx` - The egui context used for caching.
-///
-/// # Returns
-/// * A Result containing an Option of `SerialPortInfo` or a `serialport::Error`.
-pub fn cached_first_stm32_port(ctx: &Context) -> Result<Option<SerialPortInfo>, serialport::Error> {
-    ctx.call_cached(
-        egui::Id::new("list_usb_ports"),
-        communication::serial::find_first_stm32_port,
-        SERIAL_PORT_REFRESH_INTERVAL,
-    )
-}
-
 /// ChangeTracker manages the tracking of state changes using an integrity digest.
 ///
 /// The `integrity_digest` field holds a 64-bit unsigned integer that represents
diff --git a/src/ui/panes/plot.rs b/src/ui/panes/plot.rs
index 7c2e27d0ce9ed07888f0d8a41d9982874d3a05e0..9d9ad095dedb335b8a35c6ad7c3c6a7532c037bf 100644
--- a/src/ui/panes/plot.rs
+++ b/src/ui/panes/plot.rs
@@ -61,7 +61,7 @@ impl PaneBehavior for Plot2DPane {
                 {
                     plot_ui.line(
                         Line::new(PlotPoints::from(
-                            &points[points.len().saturating_sub(100)..],
+                            &points[points.len().saturating_sub(100)..], // FIXME: don't show just the last 100 points
                         ))
                         .color(settings.color)
                         .width(settings.width)
diff --git a/src/ui/windows/connections.rs b/src/ui/windows/connections.rs
index ebc34c32fcfd24d57cba0a17ff7f126d79b48e0b..30ffe5eae5606c493f4a37aae420f1b3d3254b2f 100644
--- a/src/ui/windows/connections.rs
+++ b/src/ui/windows/connections.rs
@@ -4,12 +4,15 @@ use tracing::{error, warn};
 
 use crate::{
     communication::{
-        ConnectionError, EthernetConfiguration, SerialConfiguration, serial::DEFAULT_BAUD_RATE,
+        ConnectionError, EthernetConfiguration, SerialConfiguration,
+        serial::{
+            DEFAULT_BAUD_RATE,
+            cached::{cached_first_stm32_port, cached_list_all_usb_ports},
+        },
     },
     error::ErrInstrument,
     mavlink::DEFAULT_ETHERNET_PORT,
     message_broker::MessageBroker,
-    ui::cache::{cached_first_stm32_port, cached_list_all_usb_ports},
 };
 
 #[derive(Default)]