1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#![no_std]
use nb::block;
type ReadString = heapless::String<heapless::consts::U512>;
#[derive(Debug)]
pub struct EspAt<RX, TX>
where
TX: embedded_hal::serial::Write<u8>,
RX: embedded_hal::serial::Read<u8>,
{
tx: TX,
rx: RX,
}
impl<RX, TX> EspAt<RX, TX>
where
TX: embedded_hal::serial::Write<u8>,
RX: embedded_hal::serial::Read<u8>,
{
pub fn new(tx: TX, rx: RX) -> Self {
Self { tx, rx }
}
pub fn set_wifi_mode(&mut self, mode: WifiMode) -> Result<(), GenericError<TX::Error, RX::Error>> {
match mode {
WifiMode::Disabled => self.write_line(b"AT+CWMODE=0,1")?,
WifiMode::Station => self.write_line(b"AT+CWMODE=1,1")?,
WifiMode::SoftAP => self.write_line(b"AT+CWMODE=2,1")?,
WifiMode::StationAndSoftAP => self.write_line(b"AT+CWMODE=3,1")?,
}
let reply = self.read_line()?;
if reply == "OK" {
Ok(())
} else {
Err(GenericError::ATError(reply))
}
}
fn read_line(&mut self) -> Result<ReadString, GenericError<TX::Error, RX::Error>> {
let mut line = ReadString::new();
let mut prev_value = 'a';
loop {
let value = match block!(self.rx.read()) {
Ok(word) => word as char,
Err(e) => { return Err(GenericError::ReadError(e)); }
};
if value != '\r' && value != '\n' {
if let Err(()) = line.push(value) {
return Err(GenericError::ATResponseTooLong(line));
}
}
else if prev_value == '\r' && value == '\n' {
return Ok(line);
}
prev_value = value;
}
}
fn write_line(&mut self, data: &[u8]) -> Result<(), GenericError<TX::Error, RX::Error>> {
for x in data {
self.write_byte(*x)?;
}
self.write_byte(b'\r')?;
self.write_byte(b'\n')?;
Ok(())
}
fn write_byte(&mut self, data: u8) -> Result<(), GenericError<TX::Error, RX::Error>> {
match block!(self.tx.write(data)) {
Ok(()) => Ok(()),
Err(e) => Err(GenericError::WriteError(e)),
}
}
}
#[derive(Debug)]
pub enum GenericError<TXE, RXE> {
WriteError(TXE),
ReadError(RXE),
ATError(ReadString),
ATResponseTooLong(ReadString),
}
pub enum WifiMode {
Disabled,
Station,
SoftAP,
StationAndSoftAP,
}