#![no_std] #![no_main] #[cfg(feature = "rp2040")] teleprobe_meta::target!(b"rpi-pico"); #[cfg(feature = "rp235xb")] teleprobe_meta::target!(b"pimoroni-pico-plus-2"); use defmt::{assert, *}; use embassy_executor::Spawner; #[cfg(feature = "rp2040")] use embassy_rp::gpio::OutputOpenDrain; use embassy_rp::gpio::{Flex, Input, Level, Output, Pull}; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_rp::init(Default::default()); info!("Hello World!"); let (mut a, mut b) = (p.PIN_0, p.PIN_1); // Test initial output { let b = Input::new(b.reborrow(), Pull::None); { let a = Output::new(a.reborrow(), Level::Low); delay(); assert!(b.is_low()); assert!(!b.is_high()); assert!(a.is_set_low()); assert!(!a.is_set_high()); } { let mut a = Output::new(a.reborrow(), Level::High); delay(); assert!(!b.is_low()); assert!(b.is_high()); assert!(!a.is_set_low()); assert!(a.is_set_high()); // Test is_set_low / is_set_high a.set_low(); delay(); assert!(b.is_low()); assert!(a.is_set_low()); assert!(!a.is_set_high()); a.set_high(); delay(); assert!(b.is_high()); assert!(!a.is_set_low()); assert!(a.is_set_high()); // Test toggle a.toggle(); delay(); assert!(b.is_low()); assert!(a.is_set_low()); assert!(!a.is_set_high()); a.toggle(); delay(); assert!(b.is_high()); assert!(!a.is_set_low()); assert!(a.is_set_high()); } } // Test input inversion { let mut b = Input::new(b.reborrow(), Pull::None); b.set_inversion(true); // no pull, the status is undefined let mut a = Output::new(a.reborrow(), Level::Low); delay(); assert!(b.is_high()); a.set_high(); delay(); assert!(b.is_low()); b.set_inversion(false); a.set_inversion(true); a.set_low(); delay(); assert!(b.is_high()); a.set_high(); delay(); assert!(b.is_low()); b.set_inversion(true); a.set_high(); delay(); assert!(b.is_high()); a.set_high(); delay(); assert!(b.is_high()); } // Test input no pull { let b = Input::new(b.reborrow(), Pull::None); // no pull, the status is undefined let mut a = Output::new(a.reborrow(), Level::Low); delay(); assert!(b.is_low()); a.set_high(); delay(); assert!(b.is_high()); } // Test input pulldown #[cfg(feature = "rp2040")] { let b = Input::new(b.reborrow(), Pull::Down); delay(); assert!(b.is_low()); let mut a = Output::new(a.reborrow(), Level::Low); delay(); assert!(b.is_low()); a.set_high(); delay(); assert!(b.is_high()); } // Test input pullup { let b = Input::new(b.reborrow(), Pull::Up); delay(); assert!(b.is_high()); let mut a = Output::new(a.reborrow(), Level::Low); delay(); assert!(b.is_low()); a.set_high(); delay(); assert!(b.is_high()); } // OUTPUT OPEN DRAIN #[cfg(feature = "rp2040")] { let mut b = OutputOpenDrain::new(b.reborrow(), Level::High); let mut a = Flex::new(a.reborrow()); a.set_as_input(); // When an OutputOpenDrain is high, it doesn't drive the pin. b.set_high(); a.set_pull(Pull::Up); delay(); assert!(a.is_high()); a.set_pull(Pull::Down); delay(); assert!(a.is_low()); // When an OutputOpenDrain is low, it drives the pin low. b.set_low(); a.set_pull(Pull::Up); delay(); assert!(a.is_low()); a.set_pull(Pull::Down); delay(); assert!(a.is_low()); // Check high again b.set_high(); a.set_pull(Pull::Up); delay(); assert!(a.is_high()); a.set_pull(Pull::Down); delay(); assert!(a.is_low()); // When an OutputOpenDrain is high, it reads the input value in the pin. b.set_high(); a.set_as_input(); a.set_pull(Pull::Up); delay(); assert!(b.is_high()); a.set_as_output(); a.set_low(); delay(); assert!(b.is_low()); // When an OutputOpenDrain is low, it always reads low. b.set_low(); a.set_as_input(); a.set_pull(Pull::Up); delay(); assert!(b.is_low()); a.set_as_output(); a.set_low(); delay(); assert!(b.is_low()); } // FLEX // Test initial output { //Flex pin configured as input let mut b = Flex::new(b.reborrow()); b.set_as_input(); { //Flex pin configured as output let mut a = Flex::new(a.reborrow()); //Flex pin configured as output a.set_low(); // Pin state must be set before configuring the pin, thus we avoid unknown state a.set_as_output(); delay(); assert!(b.is_low()); } { //Flex pin configured as output let mut a = Flex::new(a.reborrow()); a.set_high(); a.set_as_output(); delay(); assert!(b.is_high()); } } // Test input no pull { let mut b = Flex::new(b.reborrow()); b.set_as_input(); // no pull by default. let mut a = Flex::new(a.reborrow()); a.set_low(); a.set_as_output(); delay(); assert!(b.is_low()); a.set_high(); delay(); assert!(b.is_high()); } // Test input pulldown #[cfg(feature = "rp2040")] { let mut b = Flex::new(b.reborrow()); b.set_as_input(); b.set_pull(Pull::Down); delay(); assert!(b.is_low()); let mut a = Flex::new(a.reborrow()); a.set_low(); a.set_as_output(); delay(); assert!(b.is_low()); a.set_high(); delay(); assert!(b.is_high()); } // Test input pullup { let mut b = Flex::new(b.reborrow()); b.set_as_input(); b.set_pull(Pull::Up); delay(); assert!(b.is_high()); let mut a = Flex::new(a.reborrow()); a.set_high(); a.set_as_output(); delay(); assert!(b.is_high()); a.set_low(); delay(); assert!(b.is_low()); } info!("Test OK"); cortex_m::asm::bkpt(); } fn delay() { cortex_m::asm::delay(10000); }