1#![no_std]
7
8use embedded_hal as hal;
9
10mod interface;
11pub use interface::{DeviceInterface, SerialInterface};
12
13use hal::blocking::delay::DelayUs;
14
15#[allow(unused)]
16mod messages;
17use messages::*;
18
19#[derive(Debug)]
21pub enum Error<CommE> {
22 Comm(CommE),
24
25 Unresponsive,
27}
28
29pub fn new_serial_driver<UART, CommE>(
30 uart: UART,
31) -> UbxDriver<SerialInterface<UART>>
32where
33 UART: hal::serial::Read<u8, Error = CommE>,
34 CommE: core::fmt::Debug,
35{
36 let iface = interface::SerialInterface::new(uart);
37 UbxDriver::new_with_interface(iface)
38}
39
40const READ_BUF_LEN: usize = 128;
42
43pub struct UbxDriver<DI> {
44 di: DI,
46 read_buf: [u8; READ_BUF_LEN],
47
48 last_nav_pvt: Option<NavPosVelTimeM8>,
50 last_mon_hw: Option<MonHardwareM8>,
52 last_nav_dop: Option<NavDopM8>,
54}
55
56impl<DI, CommE> UbxDriver<DI>
57where
58 DI: DeviceInterface<InterfaceError = Error<CommE>>,
59 CommE: core::fmt::Debug,
60{
61 pub(crate) fn new_with_interface(device_interface: DI) -> Self {
62 Self {
63 di: device_interface,
64 read_buf: [0; READ_BUF_LEN],
65 last_nav_pvt: None,
66 last_mon_hw: None,
67 last_nav_dop: None,
68 }
69 }
70
71 pub fn setup(
72 &mut self,
73 _delay_source: &mut impl DelayUs<u32>,
74 ) -> Result<(), DI::InterfaceError> {
75 Ok(())
77 }
78
79 pub fn take_last_nav_pvt(&mut self) -> Option<NavPosVelTimeM8> {
80 self.last_nav_pvt.take()
81 }
82
83 pub fn take_last_nav_dop(&mut self) -> Option<NavDopM8> {
84 self.last_nav_dop.take()
85 }
86
87 pub fn take_last_mon_hw(&mut self) -> Option<MonHardwareM8> {
88 self.last_mon_hw.take()
89 }
90
91 fn checksum_for_payload(
93 payload: &[u8],
94 _dump_ck: bool,
95 ) -> [u8; UBX_CKSUM_LEN] {
96 let mut checksum = [0u8; UBX_CKSUM_LEN];
97 for word in payload {
98 checksum[0] = checksum[0].wrapping_add(*word);
99 checksum[1] = checksum[1].wrapping_add(checksum[0]);
100 }
101 checksum
102 }
103
104 fn read_ubx_message(
107 &mut self,
108 msg_len: usize,
109 dump_ck: bool,
110 ) -> Result<(bool, usize), DI::InterfaceError> {
111 let max_pay_idx = UBX_HEADER_LEN + msg_len;
116 let max_msg_idx = max_pay_idx + UBX_CKSUM_LEN;
117 let desired_count = max_msg_idx - UBX_HEADER_LEN;
118 self.read_buf[max_msg_idx] = 0;
119 let read_count = self
120 .di
121 .read_many(&mut self.read_buf[UBX_HEADER_LEN..max_msg_idx])?;
122 if read_count < desired_count {
123 return Ok((false, 0));
125 }
126 let calc_ck =
127 Self::checksum_for_payload(&self.read_buf[..max_pay_idx], dump_ck);
128 let recvd_ck =
129 &self.read_buf[(max_msg_idx - UBX_CKSUM_LEN)..max_msg_idx];
130 let matches = calc_ck[0] == recvd_ck[0] && calc_ck[1] == recvd_ck[1];
131 if matches {
132 Ok((true, max_pay_idx))
133 } else {
134 Ok((false, 0))
135 }
136 }
137
138 fn handle_msg_nav_pvt(&mut self) -> Result<(), DI::InterfaceError> {
140 let (ck_ok, max_pay_idx) =
141 self.read_ubx_message(UBX_MSG_LEN_NAV_PVT, false)?;
142 if ck_ok {
143 self.last_nav_pvt = messages::nav_pvt_from_bytes(
144 &self.read_buf[UBX_HEADER_LEN..max_pay_idx],
145 );
146 }
147 Ok(())
148 }
149
150 fn handle_msg_nav_dop(&mut self) -> Result<(), DI::InterfaceError> {
152 let (ck_ok, max_pay_idx) =
153 self.read_ubx_message(UBX_MSG_LEN_NAV_DOP, true)?;
154 if ck_ok {
155 self.last_nav_dop = messages::nav_dop_from_bytes(
156 &self.read_buf[UBX_HEADER_LEN..max_pay_idx],
157 );
158 }
159 Ok(())
160 }
161
162 fn handle_msg_mon_hw(&mut self) -> Result<(), DI::InterfaceError> {
164 let (ck_ok, max_pay_idx) =
165 self.read_ubx_message(UBX_MSG_LEN_MON_HW, false)?;
166 if ck_ok {
167 self.last_mon_hw = messages::mon_hw_from_bytes(
168 &self.read_buf[UBX_HEADER_LEN..max_pay_idx],
169 );
170 }
171 Ok(())
172 }
173
174 fn skip_unhandled_msg(&mut self) -> Result<(), DI::InterfaceError> {
176 let msg_len = ((self.read_buf[2] as u16)
180 + ((self.read_buf[3] as u16) << 8)) as usize;
181 let max_pay_idx = UBX_HEADER_LEN + msg_len;
182 let max_msg_idx = (max_pay_idx + UBX_CKSUM_LEN).min(READ_BUF_LEN);
183 self.di
184 .read_many(&mut self.read_buf[UBX_HEADER_LEN..max_msg_idx])?;
185
186 Ok(())
187 }
188
189 pub fn handle_all_messages(
190 &mut self,
191 delay_source: &mut impl DelayUs<u32>,
192 ) -> Result<usize, DI::InterfaceError> {
193 let mut msg_count = 0;
194 loop {
195 let handled_count = self.handle_one_message()?;
196 if handled_count > 0 {
197 msg_count += handled_count;
198 } else {
199 break;
200 }
201 delay_source.delay_us(1000);
202 }
203 return Ok(msg_count);
204 }
205
206 pub fn handle_one_message(&mut self) -> Result<usize, DI::InterfaceError> {
208 let mut msg_idx = 0;
209 let available = self.di.fill();
211 if available < UBX_MIN_MSG_LEN {
212 return Ok(0);
213 }
214
215 loop {
216 if msg_idx < 2 {
217 let byte = self.di.read()?;
218 if byte == UBX_PRELUDE_BYTES[msg_idx] {
219 msg_idx += 1;
220 } else {
221 msg_idx = 0;
223 }
224 } else {
225 let rc =
226 self.di.read_many(&mut self.read_buf[..UBX_HEADER_LEN]);
227 let header_fail = match rc {
228 Ok(read_count) => read_count != UBX_HEADER_LEN,
229 _ => true,
230 };
231 if header_fail {
232 return Ok(0);
233 }
234
235 let msg_unique_id: u16 =
236 (self.read_buf[0] as u16) << 8 | (self.read_buf[1] as u16);
237 return match msg_unique_id {
238 UBX_MSG_ID_NAV_PVT => {
239 self.handle_msg_nav_pvt()?;
240 Ok(1)
241 }
242 UBX_MSG_ID_NAV_DOP => {
243 self.handle_msg_nav_dop()?;
244 Ok(1)
245 }
246 UBX_MSG_ID_MON_HW => {
247 self.handle_msg_mon_hw()?;
248 Ok(1)
249 }
250 _ => {
251 self.skip_unhandled_msg()?;
253 Ok(1)
254 }
255 };
256 }
257 }
258 }
259}