use crate::error::{EmbeddedError, Result};
#[cfg(feature = "low-power")]
use crate::power::PowerMode;
#[cfg(not(feature = "low-power"))]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum PowerMode {
HighPerformance = 0,
Balanced = 1,
LowPower = 2,
UltraLowPower = 3,
}
#[derive(Debug, Clone, Copy)]
pub struct SystemConfig {
pub cpu_freq_mhz: u32,
pub ram_size: usize,
pub flash_size: usize,
pub power_mode: PowerMode,
pub debug_enabled: bool,
}
impl SystemConfig {
pub const fn new() -> Self {
Self {
cpu_freq_mhz: 80, ram_size: 512 * 1024, flash_size: 4 * 1024 * 1024, power_mode: PowerMode::Balanced,
debug_enabled: cfg!(debug_assertions),
}
}
pub const fn high_performance() -> Self {
Self {
cpu_freq_mhz: 240,
ram_size: 512 * 1024,
flash_size: 4 * 1024 * 1024,
power_mode: PowerMode::HighPerformance,
debug_enabled: false,
}
}
pub const fn low_power() -> Self {
Self {
cpu_freq_mhz: 40,
ram_size: 512 * 1024,
flash_size: 4 * 1024 * 1024,
power_mode: PowerMode::LowPower,
debug_enabled: false,
}
}
pub fn validate(&self) -> Result<()> {
if self.cpu_freq_mhz == 0 {
return Err(EmbeddedError::InvalidParameter);
}
if self.ram_size == 0 {
return Err(EmbeddedError::InvalidParameter);
}
Ok(())
}
}
impl Default for SystemConfig {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, Copy)]
pub struct MemoryConfig {
pub static_pool_size: usize,
pub block_size: usize,
pub num_blocks: usize,
pub enable_guards: bool,
}
impl MemoryConfig {
pub const fn new() -> Self {
Self {
static_pool_size: 64 * 1024, block_size: 256,
num_blocks: 256,
enable_guards: cfg!(debug_assertions),
}
}
pub const fn minimal() -> Self {
Self {
static_pool_size: 4 * 1024, block_size: 64,
num_blocks: 64,
enable_guards: false,
}
}
pub const fn total_size(&self) -> usize {
self.static_pool_size + (self.block_size * self.num_blocks)
}
}
impl Default for MemoryConfig {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, Copy)]
pub struct RealtimeConfig {
pub enabled: bool,
pub max_tasks: usize,
pub default_priority: u8,
pub monitor_deadlines: bool,
}
impl RealtimeConfig {
pub const fn new() -> Self {
Self {
enabled: false,
max_tasks: 8,
default_priority: 2,
monitor_deadlines: false,
}
}
pub const fn enabled() -> Self {
Self {
enabled: true,
max_tasks: 16,
default_priority: 2,
monitor_deadlines: true,
}
}
}
impl Default for RealtimeConfig {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, Copy)]
pub struct CommConfig {
pub uart_baud: u32,
pub i2c_freq: u32,
pub spi_freq: u32,
pub enable_crc: bool,
}
impl CommConfig {
pub const fn new() -> Self {
Self {
uart_baud: 115200,
i2c_freq: 100_000, spi_freq: 1_000_000, enable_crc: false,
}
}
pub const fn high_speed() -> Self {
Self {
uart_baud: 921600,
i2c_freq: 400_000, spi_freq: 10_000_000, enable_crc: true,
}
}
}
impl Default for CommConfig {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, Copy)]
pub struct EmbeddedConfig {
pub system: SystemConfig,
pub memory: MemoryConfig,
pub realtime: RealtimeConfig,
pub comm: CommConfig,
}
impl EmbeddedConfig {
pub const fn new() -> Self {
Self {
system: SystemConfig::new(),
memory: MemoryConfig::new(),
realtime: RealtimeConfig::new(),
comm: CommConfig::new(),
}
}
pub const fn high_performance() -> Self {
Self {
system: SystemConfig::high_performance(),
memory: MemoryConfig::new(),
realtime: RealtimeConfig::enabled(),
comm: CommConfig::high_speed(),
}
}
pub const fn low_power() -> Self {
Self {
system: SystemConfig::low_power(),
memory: MemoryConfig::minimal(),
realtime: RealtimeConfig::new(),
comm: CommConfig::new(),
}
}
pub fn validate(&self) -> Result<()> {
self.system.validate()?;
if self.memory.total_size() > self.system.ram_size {
return Err(EmbeddedError::BufferTooSmall {
required: self.memory.total_size(),
available: self.system.ram_size,
});
}
Ok(())
}
}
impl Default for EmbeddedConfig {
fn default() -> Self {
Self::new()
}
}
pub mod presets {
use super::*;
pub const fn esp32() -> EmbeddedConfig {
EmbeddedConfig {
system: SystemConfig {
cpu_freq_mhz: 240,
ram_size: 520 * 1024, flash_size: 4 * 1024 * 1024,
power_mode: PowerMode::HighPerformance,
debug_enabled: false,
},
memory: MemoryConfig {
static_pool_size: 128 * 1024,
block_size: 512,
num_blocks: 128,
enable_guards: false,
},
realtime: RealtimeConfig::enabled(),
comm: CommConfig::high_speed(),
}
}
pub const fn esp32c3() -> EmbeddedConfig {
EmbeddedConfig {
system: SystemConfig {
cpu_freq_mhz: 160,
ram_size: 400 * 1024, flash_size: 4 * 1024 * 1024,
power_mode: PowerMode::Balanced,
debug_enabled: false,
},
memory: MemoryConfig {
static_pool_size: 64 * 1024,
block_size: 256,
num_blocks: 128,
enable_guards: false,
},
realtime: RealtimeConfig::enabled(),
comm: CommConfig::new(),
}
}
pub const fn cortex_m4() -> EmbeddedConfig {
EmbeddedConfig {
system: SystemConfig {
cpu_freq_mhz: 168,
ram_size: 192 * 1024, flash_size: 1024 * 1024, power_mode: PowerMode::Balanced,
debug_enabled: false,
},
memory: MemoryConfig {
static_pool_size: 32 * 1024,
block_size: 128,
num_blocks: 128,
enable_guards: false,
},
realtime: RealtimeConfig::enabled(),
comm: CommConfig::new(),
}
}
pub const fn riscv() -> EmbeddedConfig {
EmbeddedConfig {
system: SystemConfig {
cpu_freq_mhz: 100,
ram_size: 128 * 1024, flash_size: 2 * 1024 * 1024, power_mode: PowerMode::Balanced,
debug_enabled: false,
},
memory: MemoryConfig {
static_pool_size: 16 * 1024,
block_size: 128,
num_blocks: 64,
enable_guards: false,
},
realtime: RealtimeConfig::new(),
comm: CommConfig::new(),
}
}
pub const fn ultra_low_power() -> EmbeddedConfig {
EmbeddedConfig {
system: SystemConfig {
cpu_freq_mhz: 32,
ram_size: 64 * 1024, flash_size: 512 * 1024, power_mode: PowerMode::UltraLowPower,
debug_enabled: false,
},
memory: MemoryConfig::minimal(),
realtime: RealtimeConfig::new(),
comm: CommConfig::new(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_system_config() {
let config = SystemConfig::new();
assert!(config.validate().is_ok());
let hp_config = SystemConfig::high_performance();
assert_eq!(hp_config.power_mode, PowerMode::HighPerformance);
}
#[test]
fn test_memory_config() {
let config = MemoryConfig::new();
assert!(config.total_size() > 0);
let minimal = MemoryConfig::minimal();
assert!(minimal.total_size() < config.total_size());
}
#[test]
fn test_embedded_config_validation() {
let config = EmbeddedConfig::new();
assert!(config.validate().is_ok());
let hp_config = EmbeddedConfig::high_performance();
assert!(hp_config.validate().is_ok());
}
#[test]
fn test_presets() {
let esp32_config = presets::esp32();
assert!(esp32_config.validate().is_ok());
assert_eq!(esp32_config.system.cpu_freq_mhz, 240);
let cortex_config = presets::cortex_m4();
assert!(cortex_config.validate().is_ok());
}
}