Skip to content

Commit abe93ab

Browse files
authored
Merge pull request #35 from Jim-Hodapp-Coaching/refactor_error_handling
Refactor error handling
2 parents 285410a + 51507aa commit abe93ab

File tree

8 files changed

+354
-160
lines changed

8 files changed

+354
-160
lines changed

cross/get_fw_version/src/main.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,7 @@ fn main() -> ! {
6363
.ok()
6464
.unwrap();
6565

66-
let mut delay = cortex_m::delay::Delay::new(
67-
core.SYST,
68-
clocks.system_clock.freq().integer(),
69-
);
66+
let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().integer());
7067

7168
// The single-cycle I/O block controls our GPIO pins
7269
let sio = hal::Sio::new(pac.SIO);
@@ -89,14 +86,14 @@ fn main() -> ! {
8986
let spi = hal::Spi::<_, _, 8>::new(pac.SPI0);
9087

9188
// Exchange the uninitialized SPI driver for an initialized one
92-
let spi = spi.init(
89+
let mut spi = spi.init(
9390
&mut pac.RESETS,
9491
clocks.peripheral_clock.freq(),
9592
8_000_000u32.Hz(),
9693
&MODE_0,
9794
);
9895

99-
let esp_pins = esp32_wroom_rp::gpio::EspControlPins {
96+
let mut esp_pins = esp32_wroom_rp::gpio::EspControlPins {
10097
// CS on pin x (GPIO7)
10198
cs: pins.gpio7.into_mode::<hal::gpio::PushPullOutput>(),
10299
// GPIO0 on pin x (GPIO2)
@@ -106,7 +103,7 @@ fn main() -> ! {
106103
// ACK on pin x (GPIO10)
107104
ack: pins.gpio10.into_mode::<hal::gpio::FloatingInput>(),
108105
};
109-
let mut wifi = esp32_wroom_rp::wifi::Wifi::init(spi, esp_pins, &mut delay).unwrap();
106+
let mut wifi = esp32_wroom_rp::wifi::Wifi::init(&mut spi, &mut esp_pins, &mut delay).unwrap();
110107
let firmware_version = wifi.firmware_version();
111108
defmt::info!("NINA firmware version: {:?}", firmware_version);
112109

cross/join/src/main.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,7 @@ fn main() -> ! {
6666
.ok()
6767
.unwrap();
6868

69-
let mut delay = cortex_m::delay::Delay::new(
70-
core.SYST,
71-
clocks.system_clock.freq().integer(),
72-
);
69+
let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().integer());
7370

7471
// The single-cycle I/O block controls our GPIO pins
7572
let sio = hal::Sio::new(pac.SIO);
@@ -92,14 +89,14 @@ fn main() -> ! {
9289
let spi = hal::Spi::<_, _, 8>::new(pac.SPI0);
9390

9491
// Exchange the uninitialized SPI driver for an initialized one
95-
let spi = spi.init(
92+
let mut spi = spi.init(
9693
&mut pac.RESETS,
9794
clocks.peripheral_clock.freq(),
9895
8_000_000u32.Hz(),
9996
&MODE_0,
10097
);
10198

102-
let esp_pins = esp32_wroom_rp::gpio::EspControlPins {
99+
let mut esp_pins = esp32_wroom_rp::gpio::EspControlPins {
103100
// CS on pin x (GPIO7)
104101
cs: pins.gpio7.into_mode::<hal::gpio::PushPullOutput>(),
105102
// GPIO0 on pin x (GPIO2)
@@ -110,7 +107,8 @@ fn main() -> ! {
110107
ack: pins.gpio10.into_mode::<hal::gpio::FloatingInput>(),
111108
};
112109

113-
let mut wifi = esp32_wroom_rp::wifi::Wifi::init(spi, esp_pins, &mut delay).unwrap();
110+
let mut wifi = esp32_wroom_rp::wifi::Wifi::init(&mut spi, &mut esp_pins, &mut delay).unwrap();
111+
114112
let result = wifi.join(SSID, PASSPHRASE);
115113
defmt::info!("Join Result: {:?}", result);
116114

esp32-wroom-rp/src/gpio.rs

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ enum IOError {
4141

4242
/// Provides an internal pin interface that abstracts the extra control lines that
4343
/// are separate from a data bus (e.g. SPI/I2C).
44-
///
44+
///
4545
/// Not meant to be used outside of the crate.
4646
pub trait EspControlInterface {
4747
/// Initializes all controls pins to set ready communication with the NINA firmware.
@@ -75,7 +75,7 @@ pub trait EspControlInterface {
7575
/// A structured representation of all GPIO pins that control a ESP32-WROOM NINA firmware-based
7676
/// device outside of commands sent over the SPI/I²C bus. Pass a single instance of this struct
7777
/// into `Wifi::init()`.
78-
pub struct EspControlPins<CS: OutputPin, GPIO0: OutputPin, RESETN: OutputPin, ACK: InputPin> {
78+
pub struct EspControlPins<CS, GPIO0, RESETN, ACK> {
7979
/// Chip select pin to let the NINA firmware know we're going to send it a command over
8080
/// the SPI bus.
8181
pub cs: CS,
@@ -98,27 +98,27 @@ where
9898
{
9999
fn init(&mut self) {
100100
// Chip select is active-low, so we'll initialize it to a driven-high state
101-
self.cs.set_high().ok().unwrap();
102-
self.gpio0.set_high().ok().unwrap();
103-
self.resetn.set_high().ok().unwrap();
101+
self.cs.set_high().ok();
102+
self.gpio0.set_high().ok();
103+
self.resetn.set_high().ok();
104104
self.get_esp_ready();
105105
}
106106

107107
fn reset<D: DelayMs<u16>>(&mut self, delay: &mut D) {
108-
self.gpio0.set_high().ok().unwrap();
109-
self.cs.set_high().ok().unwrap();
110-
self.resetn.set_low().ok().unwrap();
108+
self.gpio0.set_high().ok();
109+
self.cs.set_high().ok();
110+
self.resetn.set_low().ok();
111111
delay.delay_ms(10);
112-
self.resetn.set_high().ok().unwrap();
112+
self.resetn.set_high().ok();
113113
delay.delay_ms(750);
114114
}
115115

116116
fn esp_select(&mut self) {
117-
self.cs.set_low().ok().unwrap();
117+
self.cs.set_low().ok();
118118
}
119119

120120
fn esp_deselect(&mut self) {
121-
self.cs.set_high().ok().unwrap();
121+
self.cs.set_high().ok();
122122
}
123123

124124
fn get_esp_ready(&self) -> bool {
@@ -131,13 +131,13 @@ where
131131

132132
fn wait_for_esp_ready(&self) {
133133
while self.get_esp_ready() != true {
134-
cortex_m::asm::nop(); // Make sure rustc doesn't optimize this loop out
134+
//cortex_m::asm::nop(); // Make sure rustc doesn't optimize this loop out
135135
}
136136
}
137137

138138
fn wait_for_esp_ack(&self) {
139139
while self.get_esp_ack() == false {
140-
cortex_m::asm::nop(); // Make sure rustc doesn't optimize this loop out
140+
//cortex_m::asm::nop(); // Make sure rustc doesn't optimize this loop out
141141
}
142142
}
143143

@@ -148,6 +148,17 @@ where
148148
}
149149
}
150150

151+
impl Default for EspControlPins<(), (), (), ()> {
152+
fn default() -> Self {
153+
Self {
154+
cs: (),
155+
gpio0: (),
156+
resetn: (),
157+
ack: (),
158+
}
159+
}
160+
}
161+
151162
#[cfg(test)]
152163
mod gpio_tests {
153164
use super::EspControlPins;

esp32-wroom-rp/src/lib.rs

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
//! ack: pins.gpio10.into_mode::<hal::gpio::FloatingInput>(),
7676
//! };
7777
//!
78-
//! let mut wifi = esp32_wroom_rp::spi::Wifi::init(spi, esp_pins, &mut delay).unwrap();
78+
//! let mut wifi = esp32_wroom_rp::spi::Wifi::init(&mut spi, &mut esp_pins, &mut delay).unwrap();
7979
//! let version = wifi.firmware_version();
8080
//! ```
8181
@@ -88,28 +88,41 @@ pub mod gpio;
8888
/// Fundamental interface for controlling a connected ESP32-WROOM NINA firmware-based Wifi board.
8989
pub mod wifi;
9090

91-
mod protocol;
91+
pub mod protocol;
9292
mod spi;
9393

94-
use protocol::ProtocolInterface;
94+
use protocol::{ProtocolError, ProtocolInterface};
9595

9696
use defmt::{write, Format, Formatter};
9797
use embedded_hal::blocking::delay::DelayMs;
9898

9999
const ARRAY_LENGTH_PLACEHOLDER: usize = 8;
100100

101101
/// Highest level error types for this crate.
102-
#[derive(Debug)]
102+
#[derive(Debug, PartialEq)]
103103
pub enum Error {
104104
/// SPI/I2C related communications error with the ESP32 WiFi target
105105
Bus,
106-
/// Timeout in communicating with the ESP32 WiFi target
107-
TimeOut,
106+
/// Protocol error in communicating with the ESP32 WiFi target
107+
Protocol(ProtocolError),
108108
}
109109

110110
impl Format for Error {
111111
fn format(&self, fmt: Formatter) {
112-
write!(fmt, "Generic ESP32-WROOM-RP Error")
112+
match self {
113+
Error::Bus => write!(fmt, "Bus error"),
114+
Error::Protocol(e) => write!(
115+
fmt,
116+
"Communication protocol error with ESP32 WiFi target: {}",
117+
e
118+
),
119+
}
120+
}
121+
}
122+
123+
impl From<protocol::ProtocolError> for Error {
124+
fn from(err: protocol::ProtocolError) -> Self {
125+
Error::Protocol(err)
113126
}
114127
}
115128

@@ -152,7 +165,7 @@ impl Format for FirmwareVersion {
152165
}
153166
}
154167

155-
#[derive(Debug, Default)]
168+
#[derive(Debug)]
156169
struct WifiCommon<PH> {
157170
protocol_handler: PH,
158171
}
@@ -170,20 +183,20 @@ where
170183
self.protocol_handler.reset(delay)
171184
}
172185

173-
fn firmware_version(&mut self) -> Result<FirmwareVersion, self::Error> {
174-
self.protocol_handler.get_fw_version()
186+
fn firmware_version(&mut self) -> Result<FirmwareVersion, Error> {
187+
Ok(self.protocol_handler.get_fw_version()?)
175188
}
176189

177190
fn join(&mut self, ssid: &str, passphrase: &str) -> Result<(), Error> {
178-
self.protocol_handler.set_passphrase(ssid, passphrase)
191+
Ok(self.protocol_handler.set_passphrase(ssid, passphrase)?)
179192
}
180193

181194
fn leave(&mut self) -> Result<(), Error> {
182-
self.protocol_handler.disconnect()
195+
Ok(self.protocol_handler.disconnect()?)
183196
}
184197

185-
fn get_connection_status(&mut self) -> Result<u8, self::Error> {
186-
self.protocol_handler.get_conn_status()
198+
fn get_connection_status(&mut self) -> Result<u8, Error> {
199+
Ok(self.protocol_handler.get_conn_status()?)
187200
}
188201
}
189202

esp32-wroom-rp/src/protocol.rs

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
pub mod operation;
1+
pub(crate) mod operation;
22

33
use super::*;
44

55
use embedded_hal::blocking::delay::DelayMs;
66

7+
use defmt::{write, Format, Formatter};
8+
79
use heapless::{String, Vec};
810

9-
pub const MAX_NINA_PARAM_LENGTH: usize = 255;
11+
pub(crate) const MAX_NINA_PARAM_LENGTH: usize = 255;
1012

1113
#[repr(u8)]
1214
#[derive(Copy, Clone, Debug)]
@@ -223,16 +225,39 @@ impl NinaParam for NinaLargeArrayParam {
223225
pub(crate) trait ProtocolInterface {
224226
fn init(&mut self);
225227
fn reset<D: DelayMs<u16>>(&mut self, delay: &mut D);
226-
fn get_fw_version(&mut self) -> Result<FirmwareVersion, self::Error>;
227-
fn set_passphrase(&mut self, ssid: &str, passphrase: &str) -> Result<(), Error>;
228-
fn disconnect(&mut self) -> Result<(), self::Error>;
229-
fn get_conn_status(&mut self) -> Result<u8, self::Error>;
228+
fn get_fw_version(&mut self) -> Result<FirmwareVersion, ProtocolError>;
229+
fn set_passphrase(&mut self, ssid: &str, passphrase: &str) -> Result<(), ProtocolError>;
230+
fn disconnect(&mut self) -> Result<(), ProtocolError>;
231+
fn get_conn_status(&mut self) -> Result<u8, ProtocolError>;
230232
}
231233

232-
#[derive(Debug, Default)]
233-
pub(crate) struct NinaProtocolHandler<B, C> {
234+
#[derive(Debug)]
235+
pub(crate) struct NinaProtocolHandler<'a, B, C> {
234236
/// A Spi or I2c instance
235-
pub bus: B,
237+
pub bus: &'a mut B,
236238
/// An EspControlPins instance
237-
pub control_pins: C,
239+
pub control_pins: &'a mut C,
240+
}
241+
242+
// TODO: look at Nina Firmware code to understand conditions
243+
// that lead to NinaProtocolVersionMismatch
244+
#[derive(Debug, PartialEq)]
245+
pub enum ProtocolError {
246+
NinaProtocolVersionMismatch,
247+
CommunicationTimeout,
248+
InvalidCommand,
249+
InvalidNumberOfParameters,
250+
TooManyParameters,
251+
}
252+
253+
impl Format for ProtocolError {
254+
fn format(&self, fmt: Formatter) {
255+
match self {
256+
ProtocolError::NinaProtocolVersionMismatch => write!(fmt, "Encountered an unsupported version of the NINA protocol."),
257+
ProtocolError::CommunicationTimeout => write!(fmt, "Communication with ESP32 target timed out."),
258+
ProtocolError::InvalidCommand => write!(fmt, "Encountered an invalid command while communicating with ESP32 target."),
259+
ProtocolError::InvalidNumberOfParameters => write!(fmt, "Encountered an unexpected number of parameters for a NINA command while communicating with ESP32 target."),
260+
ProtocolError::TooManyParameters => write!(fmt, "Encountered too many parameters for a NINA command while communicating with ESP32 target."),
261+
}
262+
}
238263
}

0 commit comments

Comments
 (0)