mirror of
https://github.com/mytechnotalent/Embedded-Hacking.git
synced 2026-04-01 09:00:18 +02:00
feat: add unit tests for blink driver with mock pin
This commit is contained in:
@@ -5,6 +5,14 @@ name = "blink"
|
||||
version = "0.1.0"
|
||||
license = "MIT or Apache-2.0"
|
||||
|
||||
[lib]
|
||||
name = "blink_lib"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "blink"
|
||||
path = "src/main.rs"
|
||||
|
||||
[build-dependencies]
|
||||
regex = "1.11.0"
|
||||
|
||||
|
||||
@@ -26,29 +26,25 @@
|
||||
//! SOFTWARE.
|
||||
|
||||
use embedded_hal::digital::{OutputPin, StatefulOutputPin};
|
||||
use rp235x_hal as hal;
|
||||
use hal::gpio::{FunctionNull, FunctionSio, FunctionSioOutput, Pin, PullDown, SioOutput, ValidFunction};
|
||||
|
||||
/// GPIO output / LED blink driver that owns a single output pin.
|
||||
pub struct BlinkDriver<I: hal::gpio::PinId> {
|
||||
pin: Pin<I, FunctionSioOutput, PullDown>,
|
||||
pub struct BlinkDriver<P: OutputPin + StatefulOutputPin> {
|
||||
pin: P,
|
||||
}
|
||||
|
||||
impl<I: hal::gpio::PinId + ValidFunction<FunctionSio<SioOutput>>> BlinkDriver<I> {
|
||||
impl<P: OutputPin + StatefulOutputPin> BlinkDriver<P> {
|
||||
/// Initialize a GPIO pin as a push-pull digital output.
|
||||
///
|
||||
/// Calls into_push_pull_output() to configure the pin for output.
|
||||
/// The initial drive level is low (LED off).
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `pin` - GPIO pin number to configure as a digital output.
|
||||
/// * `pin` - GPIO pin configured as a digital output.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A new BlinkDriver instance owning the configured pin.
|
||||
pub fn init(pin: Pin<I, FunctionNull, PullDown>) -> Self {
|
||||
let mut pin = pin.into_push_pull_output();
|
||||
pub fn init(mut pin: P) -> Self {
|
||||
pin.set_low().unwrap();
|
||||
Self { pin }
|
||||
}
|
||||
@@ -97,4 +93,108 @@ impl<I: hal::gpio::PinId + ValidFunction<FunctionSio<SioOutput>>> BlinkDriver<I>
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use core::convert::Infallible;
|
||||
use embedded_hal::digital::ErrorType;
|
||||
|
||||
struct MockPin {
|
||||
state: bool,
|
||||
}
|
||||
|
||||
impl MockPin {
|
||||
fn new() -> Self {
|
||||
Self { state: false }
|
||||
}
|
||||
}
|
||||
|
||||
impl ErrorType for MockPin {
|
||||
type Error = Infallible;
|
||||
}
|
||||
|
||||
impl OutputPin for MockPin {
|
||||
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||
self.state = false;
|
||||
Ok(())
|
||||
}
|
||||
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||
self.state = true;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl StatefulOutputPin for MockPin {
|
||||
fn is_set_high(&mut self) -> Result<bool, Self::Error> {
|
||||
Ok(self.state)
|
||||
}
|
||||
fn is_set_low(&mut self) -> Result<bool, Self::Error> {
|
||||
Ok(!self.state)
|
||||
}
|
||||
fn toggle(&mut self) -> Result<(), Self::Error> {
|
||||
self.state = !self.state;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn init_starts_low() {
|
||||
let drv = BlinkDriver::init(MockPin::new());
|
||||
assert!(!drv.pin.state);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn on_sets_high() {
|
||||
let mut drv = BlinkDriver::init(MockPin::new());
|
||||
drv.on();
|
||||
assert!(drv.pin.state);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn off_sets_low() {
|
||||
let mut drv = BlinkDriver::init(MockPin::new());
|
||||
drv.on();
|
||||
drv.off();
|
||||
assert!(!drv.pin.state);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn toggle_from_low_goes_high() {
|
||||
let mut drv = BlinkDriver::init(MockPin::new());
|
||||
drv.toggle();
|
||||
assert!(drv.pin.state);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn toggle_from_high_goes_low() {
|
||||
let mut drv = BlinkDriver::init(MockPin::new());
|
||||
drv.on();
|
||||
drv.toggle();
|
||||
assert!(!drv.pin.state);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_state_reflects_on() {
|
||||
let mut drv = BlinkDriver::init(MockPin::new());
|
||||
drv.on();
|
||||
assert!(drv.get_state());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_state_reflects_off() {
|
||||
let mut drv = BlinkDriver::init(MockPin::new());
|
||||
drv.on();
|
||||
drv.off();
|
||||
assert!(!drv.get_state());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn double_toggle_returns_to_original() {
|
||||
let mut drv = BlinkDriver::init(MockPin::new());
|
||||
drv.toggle();
|
||||
drv.toggle();
|
||||
assert!(!drv.get_state());
|
||||
}
|
||||
}
|
||||
|
||||
// End of file
|
||||
|
||||
8
drivers/0x02_blink_rust/src/lib.rs
Normal file
8
drivers/0x02_blink_rust/src/lib.rs
Normal file
@@ -0,0 +1,8 @@
|
||||
//! @file lib.rs
|
||||
//! @brief Library root for the blink driver crate
|
||||
//! @author Kevin Thomas
|
||||
//! @date 2025
|
||||
|
||||
#![no_std]
|
||||
|
||||
pub mod blink;
|
||||
@@ -207,7 +207,7 @@ fn main() -> ! {
|
||||
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);
|
||||
let mut led = blink::BlinkDriver::init(pins.gpio25);
|
||||
let mut led = blink::BlinkDriver::init(pins.gpio25.into_push_pull_output());
|
||||
uart.write_full_blocking(b"Blink driver initialized on GPIO 25\r\n");
|
||||
loop {
|
||||
led.toggle();
|
||||
|
||||
Reference in New Issue
Block a user