mirror of
https://github.com/mytechnotalent/Embedded-Hacking.git
synced 2026-09-04 17:16:47 +02:00
Fixed Rust drivers
This commit is contained in:
@@ -26,7 +26,7 @@
|
||||
//! SOFTWARE.
|
||||
|
||||
// Watchdog driver pure-logic functions and constants
|
||||
use crate::watchdog_driver;
|
||||
use crate::watchdog;
|
||||
// Microsecond duration type for watchdog timeout
|
||||
use fugit::ExtU32;
|
||||
// Rate extension trait for .Hz() baud rate construction
|
||||
@@ -227,16 +227,64 @@ pub(crate) fn feed_loop(
|
||||
uart: &EnabledUart,
|
||||
watchdog: &hal::Watchdog,
|
||||
delay: &mut cortex_m::delay::Delay,
|
||||
state: &mut watchdog_driver::WatchdogDriverState,
|
||||
state: &mut watchdog::WatchdogDriverState,
|
||||
) -> ! {
|
||||
loop {
|
||||
watchdog_feed(watchdog);
|
||||
state.feed();
|
||||
let mut buf = [0u8; 32];
|
||||
let n = watchdog_driver::format_fed(&mut buf);
|
||||
let n = watchdog::format_fed(&mut buf);
|
||||
uart.write_full_blocking(&buf[..n]);
|
||||
delay.delay_ms(watchdog_driver::FEED_INTERVAL_MS);
|
||||
delay.delay_ms(watchdog::FEED_INTERVAL_MS);
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialise all peripherals and run the watchdog feed demo.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `pac` - PAC Peripherals singleton (consumed).
|
||||
pub(crate) fn run(mut pac: hal::pac::Peripherals) -> ! {
|
||||
let mut wd = hal::Watchdog::new(pac.WATCHDOG);
|
||||
let clocks = init_clocks(pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut wd);
|
||||
let pins = init_pins(pac.IO_BANK0, pac.PADS_BANK0, pac.SIO, &mut pac.RESETS);
|
||||
let uart = init_uart(pac.UART0, pins.gpio0, pins.gpio1, &mut pac.RESETS, &clocks);
|
||||
let mut delay = init_delay(&clocks);
|
||||
report_reset_reason(&uart);
|
||||
let mut state = start_watchdog(&uart, &mut wd);
|
||||
feed_loop(&uart, &wd, &mut delay, &mut state)
|
||||
}
|
||||
|
||||
/// Print whether the last reset was caused by the watchdog.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `uart` - Reference to the enabled UART peripheral for serial output.
|
||||
fn report_reset_reason(uart: &EnabledUart) {
|
||||
let mut buf = [0u8; 64];
|
||||
let caused = watchdog_caused_reboot();
|
||||
let n = watchdog::format_reset_reason(&mut buf, caused);
|
||||
uart.write_full_blocking(&buf[..n]);
|
||||
}
|
||||
|
||||
/// Create the driver state, enable the hardware watchdog, and report.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `uart` - Reference to the enabled UART peripheral for serial output.
|
||||
/// * `wd` - Mutable reference to the HAL watchdog.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Initialised watchdog driver state.
|
||||
fn start_watchdog(uart: &EnabledUart, wd: &mut hal::Watchdog) -> watchdog::WatchdogDriverState {
|
||||
let mut state = watchdog::WatchdogDriverState::new();
|
||||
state.enable(watchdog::DEFAULT_TIMEOUT_MS);
|
||||
watchdog_enable(wd, watchdog::DEFAULT_TIMEOUT_MS);
|
||||
let mut buf = [0u8; 64];
|
||||
let n = watchdog::format_enabled(&mut buf, watchdog::DEFAULT_TIMEOUT_MS);
|
||||
uart.write_full_blocking(&buf[..n]);
|
||||
state
|
||||
}
|
||||
|
||||
// End of file
|
||||
|
||||
@@ -6,4 +6,4 @@
|
||||
#![no_std]
|
||||
|
||||
// Watchdog driver module
|
||||
pub mod watchdog_driver;
|
||||
pub mod watchdog;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//! @file main.rs
|
||||
//! @brief Watchdog feed demo using watchdog_driver.rs
|
||||
//! @brief Watchdog feed demo using watchdog.rs
|
||||
//! @author Kevin Thomas
|
||||
//! @date 2025
|
||||
//!
|
||||
@@ -28,7 +28,7 @@
|
||||
//! -----------------------------------------------------------------------------
|
||||
//!
|
||||
//! Demonstrates the hardware watchdog using the watchdog driver
|
||||
//! (watchdog_driver.rs). The watchdog is enabled with a 3-second
|
||||
//! (watchdog.rs). The watchdog is enabled with a 3-second
|
||||
//! timeout and fed every second. If the feed loop were removed, the
|
||||
//! chip would automatically reboot after 3 seconds.
|
||||
//!
|
||||
@@ -42,7 +42,7 @@
|
||||
mod board;
|
||||
// Watchdog driver module — suppress warnings for unused public API functions
|
||||
#[allow(dead_code)]
|
||||
mod watchdog_driver;
|
||||
mod watchdog;
|
||||
|
||||
// Debugging output over RTT
|
||||
use defmt_rtt as _;
|
||||
@@ -77,25 +77,7 @@ pub static IMAGE_DEF: hal::block::ImageDef = hal::block::ImageDef::secure_exe();
|
||||
/// Application entry point for the watchdog demo.
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let mut pac = hal::pac::Peripherals::take().unwrap();
|
||||
let mut watchdog = hal::Watchdog::new(pac.WATCHDOG);
|
||||
let clocks = board::init_clocks(
|
||||
pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS,
|
||||
&mut watchdog,
|
||||
);
|
||||
let pins = board::init_pins(pac.IO_BANK0, pac.PADS_BANK0, pac.SIO, &mut pac.RESETS);
|
||||
let uart = board::init_uart(pac.UART0, pins.gpio0, pins.gpio1, &mut pac.RESETS, &clocks);
|
||||
let mut delay = board::init_delay(&clocks);
|
||||
let mut buf = [0u8; 64];
|
||||
let caused = board::watchdog_caused_reboot();
|
||||
let n = watchdog_driver::format_reset_reason(&mut buf, caused);
|
||||
uart.write_full_blocking(&buf[..n]);
|
||||
let mut state = watchdog_driver::WatchdogDriverState::new();
|
||||
state.enable(watchdog_driver::DEFAULT_TIMEOUT_MS);
|
||||
board::watchdog_enable(&mut watchdog, watchdog_driver::DEFAULT_TIMEOUT_MS);
|
||||
let n = watchdog_driver::format_enabled(&mut buf, watchdog_driver::DEFAULT_TIMEOUT_MS);
|
||||
uart.write_full_blocking(&buf[..n]);
|
||||
board::feed_loop(&uart, &watchdog, &mut delay, &mut state);
|
||||
board::run(hal::pac::Peripherals::take().unwrap())
|
||||
}
|
||||
|
||||
// Picotool binary info metadata
|
||||
|
||||
+29
-22
@@ -1,4 +1,4 @@
|
||||
//! @file watchdog_driver.rs
|
||||
//! @file watchdog.rs
|
||||
//! @brief Pure-logic watchdog timer driver (host-testable, no HAL)
|
||||
//! @author Kevin Thomas
|
||||
//! @date 2025
|
||||
@@ -180,22 +180,19 @@ pub fn format_reset_reason(buf: &mut [u8], caused_reboot: bool) -> usize {
|
||||
pub fn format_enabled(buf: &mut [u8], timeout_ms: u32) -> usize {
|
||||
let prefix = b"Watchdog enabled (";
|
||||
let suffix = b"s timeout). Feeding every 1s...\r\n";
|
||||
let mut pos = 0usize;
|
||||
// Write prefix
|
||||
let n = prefix.len().min(buf.len());
|
||||
buf[..n].copy_from_slice(&prefix[..n]);
|
||||
pos += n;
|
||||
// Write timeout in seconds (integer division matches C printf)
|
||||
let secs = timeout_ms / 1000;
|
||||
let written = format_u32(&mut buf[pos..], secs);
|
||||
pos += written;
|
||||
// Write suffix
|
||||
let n = suffix.len().min(buf.len().saturating_sub(pos));
|
||||
buf[pos..pos + n].copy_from_slice(&suffix[..n]);
|
||||
pos += n;
|
||||
let mut pos = copy_slice(buf, 0, prefix);
|
||||
pos += format_u32(&mut buf[pos..], timeout_ms / 1000);
|
||||
pos += copy_slice(buf, pos, suffix);
|
||||
pos
|
||||
}
|
||||
|
||||
/// Copy a byte slice into `buf` at the given offset, returning bytes written.
|
||||
fn copy_slice(buf: &mut [u8], offset: usize, src: &[u8]) -> usize {
|
||||
let n = src.len().min(buf.len().saturating_sub(offset));
|
||||
buf[offset..offset + n].copy_from_slice(&src[..n]);
|
||||
n
|
||||
}
|
||||
|
||||
/// Format a `u32` as decimal ASCII into `buf`.
|
||||
///
|
||||
/// # Arguments
|
||||
@@ -215,18 +212,28 @@ pub fn format_u32(buf: &mut [u8], value: u32) -> usize {
|
||||
return 0;
|
||||
}
|
||||
let mut tmp = [0u8; 10];
|
||||
let n = u32_to_digits_reversed(&mut tmp, value);
|
||||
reverse_copy(buf, &tmp, n);
|
||||
n
|
||||
}
|
||||
|
||||
/// Convert a u32 to reversed decimal digits in a temporary buffer.
|
||||
fn u32_to_digits_reversed(tmp: &mut [u8; 10], mut value: u32) -> usize {
|
||||
let mut i = 0usize;
|
||||
let mut v = value;
|
||||
while v > 0 {
|
||||
tmp[i] = b'0' + (v % 10) as u8;
|
||||
v /= 10;
|
||||
while value > 0 {
|
||||
tmp[i] = b'0' + (value % 10) as u8;
|
||||
value /= 10;
|
||||
i += 1;
|
||||
}
|
||||
let n = i.min(buf.len());
|
||||
for j in 0..n {
|
||||
buf[j] = tmp[i - 1 - j];
|
||||
i
|
||||
}
|
||||
|
||||
/// Copy digits from a reversed temporary buffer into the output buffer.
|
||||
fn reverse_copy(buf: &mut [u8], tmp: &[u8], n: usize) {
|
||||
let count = n.min(buf.len());
|
||||
for j in 0..count {
|
||||
buf[j] = tmp[n - 1 - j];
|
||||
}
|
||||
n
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Reference in New Issue
Block a user