1use crate::{
2 bindings,
3 error::{get_errno, Error},
4 rtos::DataSource,
5};
6
7pub struct AdiUltrasonic {
9 port: bindings::ext_adi_ultrasonic_t,
10}
11
12impl AdiUltrasonic {
13 pub unsafe fn new(
20 out_port: u8,
21 in_port: u8,
22 smart_port: u8,
23 ) -> Result<Self, AdiUltrasonicError> {
24 match bindings::ext_adi_ultrasonic_init(smart_port, out_port, in_port) {
25 bindings::PROS_ERR_ => Err(AdiUltrasonicError::from_errno()),
26 port => Ok(Self { port }),
27 }
28 }
29
30 pub fn get(&self) -> Result<u32, AdiUltrasonicError> {
32 match unsafe { bindings::ext_adi_ultrasonic_get(self.port) } {
33 bindings::PROS_ERR_ => Err(AdiUltrasonicError::from_errno()),
34 r if r < 0 => Err(AdiUltrasonicError::NoReading),
35 r => Ok(r as u32),
36 }
37 }
38}
39
40impl DataSource for AdiUltrasonic {
41 type Data = u32;
42
43 type Error = AdiUltrasonicError;
44
45 fn read(&self) -> Result<Self::Data, Self::Error> {
46 self.get()
47 }
48}
49
50impl Drop for AdiUltrasonic {
51 fn drop(&mut self) {
52 if unsafe { bindings::ext_adi_ultrasonic_shutdown(self.port) } == bindings::PROS_ERR_ {
53 panic!(
54 "failed to shutdown ADI ultrasonic: {:?}",
55 AdiUltrasonicError::from_errno()
56 )
57 }
58 }
59}
60
61#[derive(Debug)]
63pub enum AdiUltrasonicError {
64 PortsOutOfRange,
66 PortsNotAdiUltrasonic,
68 PortNonMatchingExtenders,
70 NoReading,
72 Unknown(i32),
74}
75
76impl AdiUltrasonicError {
77 fn from_errno() -> Self {
78 match get_errno() {
79 libc::ENXIO => Self::PortsOutOfRange,
80 libc::EADDRINUSE => Self::PortsNotAdiUltrasonic,
81 x => Self::Unknown(x),
82 }
83 }
84}
85
86impl From<AdiUltrasonicError> for Error {
87 fn from(err: AdiUltrasonicError) -> Self {
88 match err {
89 AdiUltrasonicError::PortsOutOfRange => Error::Custom("ports out of range".into()),
90 AdiUltrasonicError::PortsNotAdiUltrasonic => {
91 Error::Custom("ports not an adi ultrasonic".into())
92 }
93 AdiUltrasonicError::PortNonMatchingExtenders => {
94 Error::Custom("ports from non-matching extenders".into())
95 }
96 AdiUltrasonicError::NoReading => Error::Custom("sensor did not hear an echo".into()),
97 AdiUltrasonicError::Unknown(n) => Error::System(n),
98 }
99 }
100}