1#![no_std]
2use embedded_hal::digital::v2::OutputPin;
60use embedded_hal::{serial::Read, serial::Write};
61mod buffer;
62mod error;
63mod parser;
64mod protocol;
65
66use buffer::*;
67pub use error::*;
68use heapless::consts;
69use heapless::spsc::Queue;
70pub use protocol::*;
71
72const RECV_BUFFER_LEN: usize = 256;
73
74pub struct Rak811Driver<W, R, RST>
75where
76 W: Write<u8>,
77 R: Read<u8>,
78 RST: OutputPin,
79{
80 tx: W,
81 rx: R,
82 parse_buffer: Buffer,
83 rxq: Queue<Response, consts::U4>,
84 connect_mode: ConnectMode,
85 lora_mode: LoraMode,
86 lora_band: LoraRegion,
87 rst: RST,
88}
89
90impl<W, R, RST> Rak811Driver<W, R, RST>
91where
92 W: Write<u8>,
93 R: Read<u8>,
94 RST: OutputPin,
95{
96 pub fn new(tx: W, rx: R, rst: RST) -> Result<Rak811Driver<W, R, RST>, DriverError> {
99 let mut driver = Rak811Driver {
100 tx,
101 rx,
102 rst,
103 parse_buffer: Buffer::new(),
104 connect_mode: ConnectMode::OTAA,
105 lora_mode: LoraMode::WAN,
106 lora_band: LoraRegion::EU868,
107 rxq: Queue::new(),
108 };
109
110 driver.initialize()?;
111 Ok(driver)
112 }
113
114 pub fn initialize(&mut self) -> Result<(), DriverError> {
116 self.rst.set_high().ok();
117 self.rst.set_low().ok();
118 let response = self.recv_response()?;
119 match response {
120 Response::Initialized => Ok(()),
121 _ => Err(DriverError::NotInitialized),
122 }
123 }
124
125 pub fn reset(&mut self, mode: ResetMode) -> Result<(), DriverError> {
128 let response = self.send_command(Command::Reset(mode))?;
129 match response {
130 Response::Ok => {
131 let response = self.recv_response()?;
132 match response {
133 Response::Initialized => Ok(()),
134 _ => Err(DriverError::NotInitialized),
135 }
136 }
137 r => Err(DriverError::UnexpectedResponse(r)),
138 }
139 }
140
141 pub fn join(&mut self, mode: ConnectMode) -> Result<(), DriverError> {
143 self.connect_mode = mode;
144 let response = self.send_command(Command::Join(mode))?;
145 match response {
146 Response::Ok => {
147 let response = self.recv_response()?;
148 match response {
149 Response::Recv(EventCode::JoinedSuccess, _, _, _) => Ok(()),
150 r => Err(DriverError::UnexpectedResponse(r)),
151 }
152 }
153 r => Err(DriverError::UnexpectedResponse(r)),
154 }
155 }
156
157 pub fn set_band(&mut self, band: LoraRegion) -> Result<(), DriverError> {
159 self.lora_band = band;
160 let response = self.send_command(Command::SetBand(band))?;
161 match response {
162 Response::Ok => Ok(()),
163 r => Err(DriverError::UnexpectedResponse(r)),
164 }
165 }
166
167 pub fn set_mode(&mut self, mode: LoraMode) -> Result<(), DriverError> {
169 self.lora_mode = mode;
170 let response = self.send_command(Command::SetMode(mode))?;
171 match response {
172 Response::Ok => Ok(()),
173 r => Err(DriverError::UnexpectedResponse(r)),
174 }
175 }
176
177 pub fn set_device_address(&mut self, addr: &DevAddr) -> Result<(), DriverError> {
178 let response = self.send_command(Command::SetConfig(ConfigOption::DevAddr(addr)))?;
179 match response {
180 Response::Ok => Ok(()),
181 r => Err(DriverError::UnexpectedResponse(r)),
182 }
183 }
184 pub fn set_device_eui(&mut self, eui: &EUI) -> Result<(), DriverError> {
185 let response = self.send_command(Command::SetConfig(ConfigOption::DevEui(eui)))?;
186 match response {
187 Response::Ok => Ok(()),
188 r => Err(DriverError::UnexpectedResponse(r)),
189 }
190 }
191 pub fn set_app_eui(&mut self, eui: &EUI) -> Result<(), DriverError> {
192 let response = self.send_command(Command::SetConfig(ConfigOption::AppEui(eui)))?;
193 match response {
194 Response::Ok => Ok(()),
195 r => Err(DriverError::UnexpectedResponse(r)),
196 }
197 }
198
199 pub fn set_app_key(&mut self, key: &AppKey) -> Result<(), DriverError> {
200 let response = self.send_command(Command::SetConfig(ConfigOption::AppKey(key)))?;
201 match response {
202 Response::Ok => Ok(()),
203 r => Err(DriverError::UnexpectedResponse(r)),
204 }
205 }
206
207 pub fn send(&mut self, qos: QoS, port: Port, data: &[u8]) -> Result<(), DriverError> {
209 let response = self.send_command(Command::Send(qos, port, data))?;
210 match response {
211 Response::Ok => {
212 let response = self.recv_response()?;
213 let expected_code = match qos {
214 QoS::Unconfirmed => EventCode::TxUnconfirmed,
215 QoS::Confirmed => EventCode::TxConfirmed,
216 };
217 match response {
218 Response::Recv(c, 0, _, _) if expected_code == c => Ok(()),
219 r => Err(DriverError::UnexpectedResponse(r)),
220 }
221 }
222 r => Err(DriverError::UnexpectedResponse(r)),
223 }
224 }
225
226 pub fn try_recv(&mut self, port: Port, rx_buf: &mut [u8]) -> Result<usize, DriverError> {
229 self.digest()?;
230 let mut tries = self.rxq.len();
231 while tries > 0 {
232 match self.rxq.dequeue() {
233 None => return Ok(0),
234 Some(Response::Recv(EventCode::RecvData, p, len, Some(data))) if p == port => {
235 if len > rx_buf.len() {
236 self.rxq
237 .enqueue(Response::Recv(EventCode::RecvData, p, len, Some(data)))
238 .map_err(|_| DriverError::ReadError)?;
239 }
240
241 rx_buf[0..len].clone_from_slice(&data);
242 return Ok(len);
243 }
244 Some(event) => {
245 self.rxq
246 .enqueue(event)
247 .map_err(|_| DriverError::ReadError)?;
248 }
249 }
250 tries -= 1;
251 }
252 Ok(0)
253 }
254
255 pub fn process(&mut self) -> Result<(), DriverError> {
258 loop {
259 match self.rx.read() {
260 Err(nb::Error::WouldBlock) => {
261 break;
262 }
263 Err(nb::Error::Other(_)) => return Err(DriverError::ReadError),
264 Ok(b) => {
265 self.parse_buffer
266 .write(b)
267 .map_err(|_| DriverError::ReadError)?;
268 }
269 }
270 }
271 Ok(())
272 }
273
274 pub fn digest(&mut self) -> Result<(), DriverError> {
276 let result = self.parse_buffer.parse();
277 if let Ok(response) = result {
278 if !matches!(response, Response::None) {
279 log::debug!("Got response: {:?}", response);
280 self.rxq
281 .enqueue(response)
282 .map_err(|_| DriverError::ReadError)?;
283 }
284 }
285 Ok(())
286 }
287
288 fn recv_response(&mut self) -> Result<Response, DriverError> {
290 loop {
291 for _ in 0..1000 {
293 self.process()?;
294 }
295 self.digest()?;
296 if let Some(response) = self.rxq.dequeue() {
297 return Ok(response);
298 }
299 }
300 }
301
302 fn do_write(&mut self, buf: &[u8]) -> Result<(), DriverError> {
303 for b in buf.iter() {
304 match self.tx.write(*b) {
305 Err(nb::Error::WouldBlock) => {
306 nb::block!(self.tx.flush()).map_err(|_| DriverError::WriteError)?;
307 }
308 Err(_) => return Err(DriverError::WriteError),
309 _ => {}
310 }
311 }
312 nb::block!(self.tx.flush()).map_err(|_| DriverError::WriteError)?;
313 Ok(())
314 }
315
316 pub fn send_command(&mut self, command: Command) -> Result<Response, DriverError> {
318 let mut s = Command::buffer();
319 command.encode(&mut s);
320 log::debug!("Sending command {}", s.as_str());
321 self.do_write(s.as_bytes())?;
322 self.do_write(b"\r\n")?;
323
324 let response = self.recv_response()?;
325 Ok(response)
326 }
327}
328
329#[cfg(test)]
330mod tests {
331 #[test]
332 fn it_works() {
333 assert_eq!(2 + 2, 4);
334 }
335}