st67w611 0.1.0

Async no_std driver for ST67W611 WiFi modules using Embassy framework
Documentation
//! Power management
//!
//! This module provides power management features including:
//! - Sleep modes
//! - Power saving configuration
//! - Wake-up control

use embassy_time::Duration;

use crate::at::command;
use crate::at::processor::AtProcessor;
use crate::at::AtResponse;
use crate::bus::SpiTransport;
use crate::error::{Error, Result};
use crate::sync::TmMutex;

/// Sleep mode configuration
#[derive(Debug, Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum SleepMode {
    /// No sleep (always active)
    NoSleep,
    /// Light sleep (CPU sleep, peripherals active)
    LightSleep,
    /// Modem sleep (WiFi sleep when idle)
    ModemSleep,
    /// Deep sleep (lowest power, requires wake-up)
    DeepSleep,
}

/// Power management configuration
#[derive(Debug, Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct PowerConfig {
    /// Sleep mode
    pub sleep_mode: SleepMode,
    /// DTIM period (for modem sleep)
    pub dtim_period: u8,
    /// Listen interval
    pub listen_interval: u8,
}

impl Default for PowerConfig {
    fn default() -> Self {
        Self {
            sleep_mode: SleepMode::NoSleep,
            dtim_period: 1,
            listen_interval: 3,
        }
    }
}

/// Power manager
pub struct PowerManager {
    /// AT processor
    processor: &'static AtProcessor,
    /// Command timeout
    timeout: Duration,
}

impl PowerManager {
    /// Create a new power manager
    pub const fn new(processor: &'static AtProcessor, timeout: Duration) -> Self {
        Self { processor, timeout }
    }

    /// Enter deep sleep for a specified duration
    ///
    /// The module will wake up after the specified time.
    /// Note: This will disconnect from WiFi and close all connections.
    pub async fn deep_sleep<SPI, CS>(
        &self,
        spi: &'static TmMutex<SpiTransport<SPI, CS>>,
        duration_ms: u32,
    ) -> Result<()>
    where
        SPI: embedded_hal_async::spi::SpiDevice,
        CS: embedded_hal::digital::OutputPin,
    {
        let cmd = command::system::deep_sleep(duration_ms)?;
        let response = self
            .processor
            .send_command(spi, cmd.as_bytes(), self.timeout)
            .await?;

        if response == AtResponse::Ok {
            Ok(())
        } else {
            Err(Error::AtCommandFailed)
        }
    }

    /// Configure power saving mode
    ///
    /// Note: The actual AT commands for power management may vary by module version.
    /// Check your module's AT command documentation for specific commands.
    pub async fn configure_power_saving<SPI, CS>(
        &self,
        _spi: &'static TmMutex<SpiTransport<SPI, CS>>,
        _config: &PowerConfig,
    ) -> Result<()>
    where
        SPI: embedded_hal_async::spi::SpiDevice,
        CS: embedded_hal::digital::OutputPin,
    {
        // TODO: Implement power saving configuration
        // This would use commands like:
        // - AT+SLEEP for sleep mode
        // - AT+DTIM for DTIM configuration
        // Commands vary by module firmware version
        Err(Error::NotSupported)
    }

    /// Wake from sleep
    ///
    /// In practice, waking is typically done via hardware (GPIO toggle, SPI activity, etc.)
    /// This function is a placeholder for any software-based wake commands.
    pub async fn wake<SPI, CS>(&self, _spi: &'static TmMutex<SpiTransport<SPI, CS>>) -> Result<()>
    where
        SPI: embedded_hal_async::spi::SpiDevice,
        CS: embedded_hal::digital::OutputPin,
    {
        // Waking is usually done by toggling a GPIO or sending SPI traffic
        // No specific AT command for this
        Ok(())
    }
}