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