embedded_uart_config/
embedded_uart_config.rs

1/***************************************************************************
2 *
3 * AT Command Parser
4 * Copyright (C) 2026 Antonio Salsi <passy.linux@zresa.it>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 *
18 ***************************************************************************/
19
20//! Example: AT command table with UART and device configuration handling
21//! This example demonstrates code patterns suitable for no_std/embedded environments
22
23#![allow(dead_code)]
24
25extern crate at_parser_rs;
26
27use at_parser_rs::{Args, AtError, AtResult};
28use at_parser_rs::context::AtContext;
29
30// UART struct with AtContext implementation for UARTSEND command
31struct DummyUart {
32    baudrate: u32,
33    mode: u8,
34}
35
36impl DummyUart {
37    const fn new() -> Self {
38        Self { baudrate: 9600, mode: 0 }
39    }
40    
41    fn write(&self, data: &str) {
42        // In real embedded, this would send data over UART
43        let _ = data;
44    }
45}
46
47impl AtContext for DummyUart {
48    fn exec(&self) -> AtResult<'static> {
49        // Not supported for UARTSEND
50        Err(AtError::NotSupported)
51    }
52    fn set(&mut self, args: Args) -> AtResult<'static> {
53        if let Some(data) = args.get(0) {
54            self.write(data);
55            Ok("SENT")
56        } else {
57            Err(AtError::InvalidArgs)
58        }
59    }
60}
61
62// Device configuration context
63struct ConfigContext;
64
65impl AtContext for ConfigContext {
66    fn exec(&self) -> AtResult<'static> {
67        // Not supported for SETCFG
68        Err(AtError::NotSupported)
69    }
70    
71    fn query(&mut self) -> AtResult<'static> {
72        // Return current configuration as a static string
73        // In real implementation, format the values dynamically
74        Ok("115200,1")
75    }
76    
77    fn test(&mut self) -> AtResult<'static> {
78        // Return supported configuration options
79        Ok("+SETCFG: (baudrate),(mode)")
80    }
81    
82    fn set(&mut self, args: Args) -> AtResult<'static> {
83        let baud = args.get(0).and_then(|s| s.parse::<u32>().ok());
84        let mode = args.get(1).and_then(|s| s.parse::<u8>().ok());
85        match (baud, mode) {
86            (Some(b), Some(m)) => unsafe {
87                // Configure UART
88                UART.baudrate = b;
89                UART.mode = m;
90                Ok("CONFIGURED")
91            },
92            _ => Err(AtError::InvalidArgs),
93        }
94    }
95}
96
97static mut UART: DummyUart = DummyUart { baudrate: 9600, mode: 0 };
98static mut CONFIG_CTX: ConfigContext = ConfigContext;
99
100// Example using AtParser
101fn example_with_parser() -> Result<&'static str, AtError> {
102    // Simplified example for no_std
103    // In real embedded code, you would properly initialize the parser
104    Ok("OK")
105}
106
107// Example using the COMMANDS table generated by at_modules macro
108fn example_with_commands_macro() -> Result<&'static str, AtError> {
109    // Simple command parsing without the full parser
110    // In a real embedded system, you would use the parser properly
111    Ok("OK")
112}
113
114// Mock main for compilation (in real embedded code, this would be in your firmware)
115fn main() {
116    // Example usage - in embedded this would be called from your main loop
117    let _result = example_with_commands_macro();
118}