mirror of
https://github.com/mytechnotalent/Embedded-Hacking.git
synced 2026-07-10 06:18:40 +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"
|
version = "0.1.0"
|
||||||
license = "MIT or Apache-2.0"
|
license = "MIT or Apache-2.0"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "blink_lib"
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "blink"
|
||||||
|
path = "src/main.rs"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
regex = "1.11.0"
|
regex = "1.11.0"
|
||||||
|
|
||||||
|
|||||||
@@ -26,29 +26,25 @@
|
|||||||
//! SOFTWARE.
|
//! SOFTWARE.
|
||||||
|
|
||||||
use embedded_hal::digital::{OutputPin, StatefulOutputPin};
|
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.
|
/// GPIO output / LED blink driver that owns a single output pin.
|
||||||
pub struct BlinkDriver<I: hal::gpio::PinId> {
|
pub struct BlinkDriver<P: OutputPin + StatefulOutputPin> {
|
||||||
pin: Pin<I, FunctionSioOutput, PullDown>,
|
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.
|
/// 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).
|
/// The initial drive level is low (LED off).
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `pin` - GPIO pin number to configure as a digital output.
|
/// * `pin` - GPIO pin configured as a digital output.
|
||||||
///
|
///
|
||||||
/// # Returns
|
/// # Returns
|
||||||
///
|
///
|
||||||
/// A new BlinkDriver instance owning the configured pin.
|
/// A new BlinkDriver instance owning the configured pin.
|
||||||
pub fn init(pin: Pin<I, FunctionNull, PullDown>) -> Self {
|
pub fn init(mut pin: P) -> Self {
|
||||||
let mut pin = pin.into_push_pull_output();
|
|
||||||
pin.set_low().unwrap();
|
pin.set_low().unwrap();
|
||||||
Self { pin }
|
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
|
// End of 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 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 uart = init_uart(pac.UART0, pins.gpio0, pins.gpio1, &mut pac.RESETS, &clocks);
|
||||||
let mut delay = init_delay(&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");
|
uart.write_full_blocking(b"Blink driver initialized on GPIO 25\r\n");
|
||||||
loop {
|
loop {
|
||||||
led.toggle();
|
led.toggle();
|
||||||
|
|||||||
Reference in New Issue
Block a user