seeed_lora_e5_at_commands/general/
commands.rs

1use super::responses::{LowPowerResponse, OkResponse, VerResponse};
2use crate::NoResponse;
3use atat::digest::ParseError;
4use atat::{AtatCmd, Error, InternalError};
5use atat_derive::AtatCmd;
6use core::str::FromStr;
7#[cfg(feature = "debug")]
8use defmt::error;
9use heapless::String;
10
11/// 4.1 AT
12/// Used to test if the communication with the device is working
13#[derive(Clone, Debug, AtatCmd)]
14#[at_cmd("AT", OkResponse, cmd_prefix = "", timeout_ms = 1000)]
15pub struct VerifyComIsWorking {}
16
17/// 4.2 VER
18/// Get the version of the firmware running on the unit
19#[derive(Clone, Debug)]
20pub struct FirmwareVersion {}
21impl AtatCmd for FirmwareVersion {
22    type Response = VerResponse;
23
24    const MAX_LEN: usize = 8;
25
26    fn write(&self, buf: &mut [u8]) -> usize {
27        buf.copy_from_slice(b"AT+VER\r\n");
28        8
29    }
30
31    fn parse(&self, resp: Result<&[u8], InternalError>) -> Result<Self::Response, Error> {
32        if resp.is_err() {
33            return Err(Error::Parse);
34        }
35        let buf = resp.unwrap();
36        let parse = Self::parse(buf).map_err(|_| Error::Parse);
37        if parse.is_err() {
38            return Err(Error::Parse);
39        }
40        let (major, minor, patch) = parse.unwrap();
41
42        match (
43            major.parse::<u8>(),
44            minor.parse::<u8>(),
45            patch.parse::<u8>(),
46        ) {
47            (Ok(major), Ok(minor), Ok(patch)) => Ok(VerResponse {
48                major,
49                minor,
50                patch,
51            }),
52            _ => {
53                #[cfg(feature = "debug")]
54                error!("Failed to parse u8 values for software version");
55                Err(Error::Parse)
56            }
57        }
58    }
59}
60
61impl FirmwareVersion {
62    fn parse(buf: &[u8]) -> Result<(&str, &str, &str), ParseError> {
63        let s = core::str::from_utf8(buf).map_err(|_| ParseError::NoMatch)?;
64        let mut s = s.split('.');
65
66        let major = s.next().ok_or(ParseError::NoMatch)?;
67        let minor = s.next().ok_or(ParseError::NoMatch)?;
68        let patch = s.next().ok_or(ParseError::NoMatch)?;
69        Ok((major, minor, patch))
70    }
71}
72
73/// 4.4 RESET
74/// Reset the module
75#[derive(Clone, Debug, AtatCmd)]
76#[at_cmd("+RESET", OkResponse, timeout_ms = 5000)]
77pub struct Reset {}
78
79/// 4.21 FDEFAULT
80#[derive(Clone, Debug)]
81pub struct FactoryReset {}
82
83impl AtatCmd for FactoryReset {
84    type Response = OkResponse;
85
86    const MAX_LEN: usize = 20;
87
88    const MAX_TIMEOUT_MS: u32 = 15000;
89
90    fn write(&self, buf: &mut [u8]) -> usize {
91        buf.copy_from_slice(b"+AT+FDEFAULT=Seeed\r\n");
92        20
93    }
94
95    fn parse(&self, _resp: Result<&[u8], InternalError>) -> Result<Self::Response, Error> {
96        Ok(OkResponse {
97            ok: String::from_str("OK").unwrap(),
98        })
99    }
100}
101
102/// 4.30 LOWPOWER until woken up
103/// Sleep until woken by RX
104#[derive(Clone, Debug, AtatCmd)]
105#[at_cmd("LOWPOWER", LowPowerResponse)]
106pub struct LowPowerUntilWokenUp {}
107
108/// 4.30 LOWPOWER for x milliseconds
109/// Sleep for x milliseconds
110#[derive(Clone, Debug, AtatCmd)]
111#[at_cmd("LOWPOWER", LowPowerResponse)]
112pub struct LowPowerForMilliseconds {
113    pub sleep_for_millis: u32,
114}
115
116/// 4.30 LOWPOWER deep sleep enable
117/// Enter deep power saving mode
118#[derive(Clone, Debug, AtatCmd)]
119#[at_cmd("LOWPOWER=AUTOON", NoResponse)]
120pub struct LowPowerDeepSleepEnable {}
121
122/// 4.30 LOWPOWER deep sleep disable
123/// Stop deep power saving mode
124/// Needs 4x 0xFF over UART to be first sent
125#[derive(Clone, Debug, AtatCmd)]
126#[at_cmd("LOWPOWER=AUTOOFF", NoResponse)]
127pub struct LowPowerDeepSleepDisable {}