sd card detection works (own embassy task)

This commit is contained in:
Philipp_EndevourOS 2025-09-09 17:24:47 +02:00
parent adcbe87bd7
commit b551f4521f
3 changed files with 105 additions and 65 deletions

View File

@ -1,11 +1,11 @@
use embassy_time::{Delay, Duration, Timer}; use embassy_time::{Delay, Duration, Timer};
use esp_hal::{delay, gpio::Output, peripherals, rmt::ConstChannelAccess}; use esp_hal::{delay, gpio::Output, peripherals, rmt::ConstChannelAccess};
use esp_hal_smartled::SmartLedsAdapterAsync; use esp_hal_smartled::SmartLedsAdapterAsync;
use log::{debug, error, info};
use init::hardware; use init::hardware;
use log::{debug, error, info};
use smart_leds::SmartLedsWriteAsync;
use smart_leds::colors::{BLACK, GREEN, RED, YELLOW}; use smart_leds::colors::{BLACK, GREEN, RED, YELLOW};
use smart_leds::{brightness, colors::BLUE}; use smart_leds::{brightness, colors::BLUE};
use smart_leds::SmartLedsWriteAsync;
use crate::{FEEDBACK_STATE, init}; use crate::{FEEDBACK_STATE, init};
@ -24,21 +24,37 @@ const LED_LEVEL: u8 = 255;
//TODO ERROR STATE: 1 Blink = unknows error, 3 Blink = no sd card //TODO ERROR STATE: 1 Blink = unknows error, 3 Blink = no sd card
#[embassy_executor::task] #[embassy_executor::task]
pub async fn feedback_task(mut led: SmartLedsAdapterAsync<ConstChannelAccess<esp_hal::rmt::Tx, 0>, { init::hardware::LED_BUFFER_SIZE }>, buzzer: peripherals::GPIO21<'static>) { pub async fn feedback_task(
mut led: SmartLedsAdapterAsync<
ConstChannelAccess<esp_hal::rmt::Tx, 0>,
{ init::hardware::LED_BUFFER_SIZE },
>,
buzzer: peripherals::GPIO21<'static>,
) {
debug!("Starting feedback task"); debug!("Starting feedback task");
let mut buzzer = init::hardware::setup_buzzer(buzzer); let mut buzzer = init::hardware::setup_buzzer(buzzer);
loop { loop {
let feedback_state = FEEDBACK_STATE.wait().await; let feedback_state = FEEDBACK_STATE.wait().await;
match feedback_state { match feedback_state {
FeedbackState::Ack => { FeedbackState::Ack => {
led.write(brightness([GREEN; init::hardware::NUM_LEDS].into_iter(), LED_LEVEL)).await.unwrap(); led.write(brightness(
[GREEN; init::hardware::NUM_LEDS].into_iter(),
LED_LEVEL,
))
.await
.unwrap();
buzzer.set_high(); buzzer.set_high();
Timer::after(Duration::from_millis(100)).await; Timer::after(Duration::from_millis(100)).await;
buzzer.set_low(); buzzer.set_low();
Timer::after(Duration::from_millis(50)).await; Timer::after(Duration::from_millis(50)).await;
} }
FeedbackState::Nack => { FeedbackState::Nack => {
led.write(brightness([YELLOW; init::hardware::NUM_LEDS].into_iter(), LED_LEVEL)).await.unwrap(); led.write(brightness(
[YELLOW; init::hardware::NUM_LEDS].into_iter(),
LED_LEVEL,
))
.await
.unwrap();
buzzer.set_high(); buzzer.set_high();
Timer::after(Duration::from_millis(100)).await; Timer::after(Duration::from_millis(100)).await;
buzzer.set_low(); buzzer.set_low();
@ -46,10 +62,20 @@ pub async fn feedback_task(mut led: SmartLedsAdapterAsync<ConstChannelAccess<esp
buzzer.set_high(); buzzer.set_high();
Timer::after(Duration::from_millis(100)).await; Timer::after(Duration::from_millis(100)).await;
buzzer.set_low(); buzzer.set_low();
led.write(brightness([BLACK; init::hardware::NUM_LEDS].into_iter(), LED_LEVEL)).await.unwrap(); led.write(brightness(
[BLACK; init::hardware::NUM_LEDS].into_iter(),
LED_LEVEL,
))
.await
.unwrap();
} }
FeedbackState::Error => { FeedbackState::Error => {
led.write(brightness([RED; init::hardware::NUM_LEDS].into_iter(), LED_LEVEL)).await.unwrap(); led.write(brightness(
[RED; init::hardware::NUM_LEDS].into_iter(),
LED_LEVEL,
))
.await
.unwrap();
buzzer.set_high(); buzzer.set_high();
Timer::after(Duration::from_millis(500)).await; Timer::after(Duration::from_millis(500)).await;
buzzer.set_low(); buzzer.set_low();
@ -59,7 +85,12 @@ pub async fn feedback_task(mut led: SmartLedsAdapterAsync<ConstChannelAccess<esp
buzzer.set_low(); buzzer.set_low();
} }
FeedbackState::Startup => { FeedbackState::Startup => {
led.write(brightness([GREEN; init::hardware::NUM_LEDS].into_iter(), LED_LEVEL)).await.unwrap(); led.write(brightness(
[GREEN; init::hardware::NUM_LEDS].into_iter(),
LED_LEVEL,
))
.await
.unwrap();
buzzer.set_high(); buzzer.set_high();
Timer::after(Duration::from_millis(10)).await; Timer::after(Duration::from_millis(10)).await;
buzzer.set_low(); buzzer.set_low();
@ -71,20 +102,34 @@ pub async fn feedback_task(mut led: SmartLedsAdapterAsync<ConstChannelAccess<esp
buzzer.set_high(); buzzer.set_high();
Timer::after(Duration::from_millis(100)).await; Timer::after(Duration::from_millis(100)).await;
buzzer.set_low(); buzzer.set_low();
led.write(brightness([BLACK; init::hardware::NUM_LEDS].into_iter(), LED_LEVEL)).await.unwrap(); led.write(brightness(
[BLACK; init::hardware::NUM_LEDS].into_iter(),
LED_LEVEL,
))
.await
.unwrap();
} }
FeedbackState::WIFI => { FeedbackState::WIFI => {
led.write(brightness([BLUE; init::hardware::NUM_LEDS].into_iter(), LED_LEVEL)).await.unwrap(); led.write(brightness(
[BLUE; init::hardware::NUM_LEDS].into_iter(),
LED_LEVEL,
))
.await
.unwrap();
} }
FeedbackState::Idle => { FeedbackState::Idle => {
led.write(brightness([GREEN; init::hardware::NUM_LEDS].into_iter(), LED_LEVEL)).await.unwrap(); led.write(brightness(
[GREEN; init::hardware::NUM_LEDS].into_iter(),
LED_LEVEL,
))
.await
.unwrap();
} }
}; };
debug!("Feedback state: {:?}", feedback_state); debug!("Feedback state: {:?}", feedback_state);
} }
} }
// async fn beep_ack() { // async fn beep_ack() {
// buzzer.set_high(); // buzzer.set_high();
// buzzer.set_low(); // buzzer.set_low();

View File

@ -7,9 +7,8 @@ use embassy_executor::Spawner;
use embassy_net::Stack; use embassy_net::Stack;
use embassy_time::{Duration, Timer}; use embassy_time::{Duration, Timer};
use esp_hal::gpio::{Input, InputConfig, Io}; use esp_hal::gpio::{Input, InputConfig};
use esp_hal::i2c::master::Config; use esp_hal::i2c::master::Config;
use esp_hal::interrupt::InterruptHandler;
use esp_hal::peripherals::{ use esp_hal::peripherals::{
GPIO0, GPIO1, GPIO16, GPIO17, GPIO18, GPIO19, GPIO20, GPIO21, GPIO22, GPIO23, I2C0, RMT, SPI2, GPIO0, GPIO1, GPIO16, GPIO17, GPIO18, GPIO19, GPIO20, GPIO21, GPIO22, GPIO23, I2C0, RMT, SPI2,
UART1, UART1,
@ -17,7 +16,7 @@ use esp_hal::peripherals::{
use esp_hal::rmt::{ConstChannelAccess, Rmt}; use esp_hal::rmt::{ConstChannelAccess, Rmt};
use esp_hal::spi::master::{Config as Spi_config, Spi}; use esp_hal::spi::master::{Config as Spi_config, Spi};
use esp_hal::{Blocking, handler}; use esp_hal::Blocking;
use esp_hal::time::Rate; use esp_hal::time::Rate;
use esp_hal::timer::timg::TimerGroup; use esp_hal::timer::timg::TimerGroup;
use esp_hal::{ use esp_hal::{
@ -28,7 +27,6 @@ use esp_hal::{
timer::systimer::SystemTimer, timer::systimer::SystemTimer,
uart::Uart, uart::Uart,
}; };
use esp_hal_embassy::InterruptExecutor;
use esp_hal_smartled::{SmartLedsAdapterAsync, buffer_size_async}; use esp_hal_smartled::{SmartLedsAdapterAsync, buffer_size_async};
use esp_println::dbg; use esp_println::dbg;
use esp_println::logger::init_logger; use esp_println::logger::init_logger;
@ -80,6 +78,7 @@ pub async fn hardware_init(
I2c<'static, Async>, I2c<'static, Async>,
SmartLedsAdapterAsync<ConstChannelAccess<esp_hal::rmt::Tx, 0>, LED_BUFFER_SIZE>, SmartLedsAdapterAsync<ConstChannelAccess<esp_hal::rmt::Tx, 0>, LED_BUFFER_SIZE>,
GPIO21<'static>, GPIO21<'static>,
GPIO0<'static>,
) { ) {
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
let peripherals = esp_hal::init(config); let peripherals = esp_hal::init(config);
@ -105,17 +104,7 @@ pub async fn hardware_init(
let i2c_device = setup_i2c(peripherals.I2C0, peripherals.GPIO22, peripherals.GPIO23); let i2c_device = setup_i2c(peripherals.I2C0, peripherals.GPIO22, peripherals.GPIO23);
let mut io = Io::new(peripherals.IO_MUX); let mut sd_det_gpio = peripherals.GPIO0;
io.set_interrupt_handler(handler);
let mut sd_det = Input::new(peripherals.GPIO0, InputConfig::default());
critical_section::with(|cs| {
// Here we are listening for a low level to demonstrate
// that you need to stop listening for level interrupts,
// but usually you'd probably use `FallingEdge`.
sd_det.listen(esp_hal::gpio::Event::AnyEdge);
SD_DET.borrow_ref_mut(cs).replace(sd_det);
});
let spi_bus = setup_spi( let spi_bus = setup_spi(
peripherals.SPI2, peripherals.SPI2,
@ -140,10 +129,16 @@ pub async fn hardware_init(
debug!("hardware init done"); debug!("hardware init done");
(uart_device, stack, i2c_device, led, buzzer_gpio) (
uart_device,
stack,
i2c_device,
led,
buzzer_gpio,
sd_det_gpio,
)
} }
fn setup_uart( fn setup_uart(
uart1: UART1<'static>, uart1: UART1<'static>,
uart_tx: GPIO16<'static>, uart_tx: GPIO16<'static>,
@ -218,34 +213,3 @@ fn setup_led(
led led
} }
#[handler]
fn handler() {
critical_section::with(|cs| {
let mut sd_det = SD_DET.borrow_ref_mut(cs);
let Some(sd_det) = sd_det.as_mut() else {
// Some other interrupt has occurred
// before the button was set up.
return;
};
if sd_det.is_interrupt_set() {
//card is insert on high
if sd_det.is_high() {
debug!("card insert");
//FEEDBACK_STATE.signal(crate::feedback::FeedbackState::Ack);
//sd_det.unlisten();
//sd_det.listen(esp_hal::gpio::Event::FallingEdge);
}
//card is not insert on low
else {
debug!("card removed");
//FEEDBACK_STATE.signal(crate::feedback::FeedbackState::Nack);
//sd_det.unlisten();
sd_det.listen(esp_hal::gpio::Event::RisingEdge);
}
}
});
}

View File

@ -6,16 +6,21 @@
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_net::Stack; use embassy_net::Stack;
use embassy_sync::{ use embassy_sync::{
blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex}, channel::Channel, pubsub::{ blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex},
channel::Channel,
pubsub::{
PubSubChannel, Publisher, PubSubChannel, Publisher,
WaitResult::{Lagged, Message}, WaitResult::{Lagged, Message},
}, signal::Signal },
signal::Signal,
}; };
use embassy_time::{Duration, Timer}; use embassy_time::{Duration, Timer};
use esp_hal::gpio::Input;
use esp_hal::{gpio::InputConfig, peripherals};
use log::{debug, info}; use log::{debug, info};
use static_cell::make_static; use static_cell::make_static;
use crate::{store::TallyID}; use crate::store::TallyID;
extern crate alloc; extern crate alloc;
@ -32,7 +37,7 @@ type TallyPublisher = Publisher<'static, NoopRawMutex, TallyID, 8, 2, 1>;
#[esp_hal_embassy::main] #[esp_hal_embassy::main]
async fn main(mut spawner: Spawner) { async fn main(mut spawner: Spawner) {
let (uart_device, stack, _i2c, _led, buzzer_gpio) = let (uart_device, stack, _i2c, _led, buzzer_gpio, sd_det_gpio) =
init::hardware::hardware_init(&mut spawner).await; init::hardware::hardware_init(&mut spawner).await;
wait_for_stack_up(stack).await; wait_for_stack_up(stack).await;
@ -56,6 +61,9 @@ async fn main(mut spawner: Spawner) {
debug!("spawing feedback task.."); debug!("spawing feedback task..");
spawner.must_spawn(feedback::feedback_task(_led, buzzer_gpio)); spawner.must_spawn(feedback::feedback_task(_led, buzzer_gpio));
debug!("spawn sd detect task");
spawner.must_spawn(sd_detect_task(sd_det_gpio));
/******************************************************************************/ /******************************************************************************/
let mut sub = chan.subscriber().unwrap(); let mut sub = chan.subscriber().unwrap();
@ -76,6 +84,29 @@ async fn main(mut spawner: Spawner) {
} }
} }
#[embassy_executor::task]
async fn sd_detect_task(sd_det_gpio: peripherals::GPIO0<'static>) {
let mut sd_det = Input::new(sd_det_gpio, InputConfig::default());
sd_det.wait_for(esp_hal::gpio::Event::AnyEdge);
loop {
sd_det.wait_for_any_edge().await;
{
if sd_det.is_high() {
FEEDBACK_STATE.signal(feedback::FeedbackState::Ack);
debug!("card insert");
}
//card is not insert on low
else {
FEEDBACK_STATE.signal(feedback::FeedbackState::Nack);
debug!("card removed");
}
}
//debounce time
Timer::after(Duration::from_millis(100)).await;
}
}
async fn wait_for_stack_up(stack: Stack<'static>) { async fn wait_for_stack_up(stack: Stack<'static>) {
loop { loop {
if stack.is_link_up() { if stack.is_link_up() {