1use crate::{
2 bindings,
3 error::{get_errno, Error},
4 rtos::DataSource,
5};
6
7pub struct AdiEncoder {
9 port: bindings::ext_adi_encoder_t,
10}
11
12impl AdiEncoder {
13 pub unsafe fn new(
21 top_port: u8,
22 bottom_port: u8,
23 reverse: bool,
24 extender_port: u8,
25 ) -> Result<AdiEncoder, AdiEncoderError> {
26 match bindings::ext_adi_encoder_init(extender_port, top_port, bottom_port, reverse) {
27 bindings::PROS_ERR_ => Err(AdiEncoderError::from_errno()),
28 x => Ok(AdiEncoder { port: x }),
29 }
30 }
31
32 pub fn reset(&mut self) -> Result<(), AdiEncoderError> {
36 match unsafe { bindings::ext_adi_encoder_reset(self.port) } {
37 bindings::PROS_ERR_ => Err(AdiEncoderError::from_errno()),
38 _ => Ok(()),
39 }
40 }
41
42 pub fn get(&self) -> Result<i32, AdiEncoderError> {
45 match unsafe { bindings::ext_adi_encoder_get(self.port) } {
46 bindings::PROS_ERR_ => Err(AdiEncoderError::from_errno()),
47 x => Ok(x),
48 }
49 }
50}
51
52impl DataSource for AdiEncoder {
53 type Data = i32;
54
55 type Error = AdiEncoderError;
56
57 fn read(&self) -> Result<Self::Data, Self::Error> {
58 self.get()
59 }
60}
61
62impl Drop for AdiEncoder {
63 fn drop(&mut self) {
64 if let bindings::PROS_ERR_ = unsafe { bindings::ext_adi_encoder_shutdown(self.port) } {
65 panic!(
66 "failed to shutdown ADI encoder: {:?}",
67 AdiEncoderError::from_errno()
68 );
69 }
70 }
71}
72
73#[derive(Debug)]
75pub enum AdiEncoderError {
76 PortsOutOfRange,
78 PortsNotAdiEncoder,
80 PortNonMatchingExtenders,
82 Unknown(i32),
84}
85
86impl AdiEncoderError {
87 fn from_errno() -> Self {
88 match get_errno() {
89 libc::ENXIO => Self::PortsOutOfRange,
90 libc::ENODEV => Self::PortsNotAdiEncoder,
91 x => Self::Unknown(x),
92 }
93 }
94}
95
96impl From<AdiEncoderError> for Error {
97 fn from(err: AdiEncoderError) -> Self {
98 match err {
99 AdiEncoderError::PortsOutOfRange => Error::Custom("ports out of range".into()),
100 AdiEncoderError::PortsNotAdiEncoder => Error::Custom("ports not an adi encoder".into()),
101 AdiEncoderError::PortNonMatchingExtenders => {
102 Error::Custom("ports from non-matching extenders".into())
103 }
104 AdiEncoderError::Unknown(n) => Error::System(n),
105 }
106 }
107}