1use crate::consts::{
2 DMX_MAX_PACKAGE_SIZE, DMX_NULL_START, PREAMBLE_BYTE, RDM_DISCOVERY_RESPONSE_SIZE,
3 RDM_MAX_PACKAGE_SIZE, SC_RDM, SEPARATOR_BYTE,
4};
5use crate::dmx_receiver::DmxFrame;
6use crate::dmx_uart_driver::{
7 DmxRecvUartDriver, DmxRespUartDriver, DmxUartDriver, DmxUartDriverError,
8};
9use crate::rdm_data::{deserialize_discovery_response, RdmData, RdmDeserializationError};
10use crate::unique_identifier::UniqueIdentifier;
11use crate::utils::{calculate_checksum, encode_disc_unique};
12
13#[derive(Debug, Copy, Clone, Eq, PartialEq)]
14#[cfg_attr(feature = "defmt", derive(defmt::Format))]
15pub enum DmxError<E> {
16 UartOverflow,
18 TimeoutError,
22 DeserializationError(RdmDeserializationError),
24 DriverError(E),
26}
27
28impl<E: core::fmt::Display> core::fmt::Display for DmxError<E> {
29 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
30 match self {
31 DmxError::UartOverflow => write!(f, "uart overflowed"),
32 DmxError::TimeoutError => write!(f, "request timed out"),
33 DmxError::DeserializationError(error) => error.fmt(f),
34 DmxError::DriverError(error) => error.fmt(f),
35 }
36 }
37}
38
39impl<E> From<E> for DmxError<E> {
40 fn from(value: E) -> Self {
41 Self::DriverError(value)
42 }
43}
44
45#[cfg(feature = "std")]
46impl<E: core::fmt::Display + core::fmt::Debug> std::error::Error for DmxError<E> {}
47
48#[derive(Debug, Copy, Clone, Eq, PartialEq)]
49pub enum DiscoveryOption {
50 NoDevice,
53 Collision,
56 Found(UniqueIdentifier),
59}
60
61impl<E> From<DmxUartDriverError<E>> for DmxError<E> {
62 fn from(value: DmxUartDriverError<E>) -> Self {
63 match value {
64 DmxUartDriverError::TimeoutError => Self::TimeoutError,
65 DmxUartDriverError::DriverError(driver_error) => Self::DriverError(driver_error),
66 }
67 }
68}
69
70pub trait ControllerDriverErrorDef {
72 type DriverError;
74}
75
76pub trait DmxControllerDriver: ControllerDriverErrorDef {
78 fn send_dmx_package(&mut self, package: &[u8]) -> Result<(), DmxError<Self::DriverError>>;
80}
81
82pub trait RdmControllerDriver: ControllerDriverErrorDef {
84 fn send_rdm(&mut self, package: RdmData) -> Result<(), DmxError<Self::DriverError>>;
86 fn receive_rdm(&mut self) -> Result<RdmData, DmxError<Self::DriverError>>;
88 fn receive_rdm_discovery_response(
91 &mut self,
92 ) -> Result<DiscoveryOption, DmxError<Self::DriverError>>;
93 fn send_rdm_discovery_response(
96 &mut self,
97 uid: UniqueIdentifier,
98 ) -> Result<(), DmxError<Self::DriverError>>;
99}
100
101pub trait CustomStartCodeControllerDriver: ControllerDriverErrorDef {
103 fn send_custom_package(
105 &mut self,
106 start_code: u8,
107 package: &[u8],
108 ) -> Result<(), DmxError<Self::DriverError>>;
109}
110
111impl<D: DmxUartDriver> ControllerDriverErrorDef for D {
112 type DriverError = D::DriverError;
113}
114
115impl<D: DmxRespUartDriver> CustomStartCodeControllerDriver for D {
116 fn send_custom_package(
117 &mut self,
118 start_code: u8,
119 package: &[u8],
120 ) -> Result<(), DmxError<Self::DriverError>> {
121 let mut frame_buffer: heapless::Vec<_, DMX_MAX_PACKAGE_SIZE> = heapless::Vec::new();
122 frame_buffer.push(start_code).unwrap();
123 frame_buffer
124 .extend_from_slice(package)
125 .or(Err(DmxError::UartOverflow))?;
126
127 if self.write_frames(&frame_buffer)? != package.len() {
128 return Err(DmxError::UartOverflow);
129 }
130
131 Ok(())
132 }
133}
134
135impl<D: DmxRespUartDriver> DmxControllerDriver for D {
136 fn send_dmx_package(&mut self, package: &[u8]) -> Result<(), DmxError<Self::DriverError>> {
137 self.send_custom_package(DMX_NULL_START, package)
138 }
139}
140
141const READ_TIMEOUT_US: u32 = 2800;
142impl<D: DmxRespUartDriver + DmxRecvUartDriver> RdmControllerDriver for D {
143 fn send_rdm(&mut self, rdm_package: RdmData) -> Result<(), DmxError<Self::DriverError>> {
144 let serialized_package = rdm_package.serialize();
145 let written_bytes = self.write_frames(&serialized_package)?;
146
147 if serialized_package.len() != written_bytes {
148 return Err(DmxError::UartOverflow);
149 }
150
151 Ok(())
152 }
153
154 fn receive_rdm(&mut self) -> Result<RdmData, DmxError<Self::DriverError>> {
155 let mut receive_buffer = [0u8; RDM_MAX_PACKAGE_SIZE];
157 let mut bytes_read = self.read_frames(&mut receive_buffer[0..3], READ_TIMEOUT_US)?;
158
159 let message_length = receive_buffer[2] as usize + 2;
161 if message_length < 3 {
162 return Err(DmxError::DeserializationError(
163 RdmDeserializationError::WrongMessageLength(message_length),
164 ));
165 }
166 if message_length > RDM_MAX_PACKAGE_SIZE {
167 return Err(DmxError::DeserializationError(
168 RdmDeserializationError::WrongMessageLength(message_length),
169 ));
170 }
171
172 bytes_read +=
173 self.read_frames_no_break(&mut receive_buffer[3..message_length], READ_TIMEOUT_US)?;
174 let response = RdmData::deserialize(&receive_buffer[..bytes_read])
175 .map_err(DmxError::DeserializationError)?;
176
177 Ok(response)
178 }
179
180 fn receive_rdm_discovery_response(
181 &mut self,
182 ) -> Result<DiscoveryOption, DmxError<Self::DriverError>> {
183 let mut receive_buffer = [0u8; 32]; let bytes_read = match self.read_frames_no_break(&mut receive_buffer, READ_TIMEOUT_US) {
185 Err(DmxUartDriverError::TimeoutError) => return Ok(DiscoveryOption::NoDevice),
186 result => result,
187 }?;
188
189 if bytes_read < RDM_DISCOVERY_RESPONSE_SIZE {
190 return Ok(DiscoveryOption::Collision);
191 }
192
193 Ok(
194 deserialize_discovery_response(&receive_buffer[..bytes_read])
195 .map_or(DiscoveryOption::Collision, DiscoveryOption::Found),
196 )
197 }
198
199 fn send_rdm_discovery_response(
200 &mut self,
201 uid: UniqueIdentifier,
202 ) -> Result<(), DmxError<Self::DriverError>> {
203 let mut frame_buffer = [PREAMBLE_BYTE; 24];
204 frame_buffer[7] = SEPARATOR_BYTE;
205
206 let uid_buffer = uid.to_bytes();
207 encode_disc_unique(&uid_buffer, &mut frame_buffer[8..20]);
208
209 let checksum = calculate_checksum(&frame_buffer[8..20]);
210 encode_disc_unique(&checksum.to_be_bytes(), &mut frame_buffer[20..24]);
211
212 if self.write_frames_no_break(&frame_buffer)? != frame_buffer.len() {
213 return Err(DmxError::UartOverflow);
214 }
215
216 Ok(())
217 }
218}
219
220pub trait DmxReceiver: ControllerDriverErrorDef {
221 fn receive_package(&mut self) -> Result<DmxFrame, DmxError<Self::DriverError>>;
223}
224
225impl<D: DmxRecvUartDriver> DmxReceiver for D {
226 fn receive_package(&mut self) -> Result<DmxFrame, DmxError<D::DriverError>> {
227 const READ_TIMEOUT_US: u32 = 1800;
228
229 let mut buffer = [0u8; DMX_MAX_PACKAGE_SIZE];
230 let mut bytes_read = self.read_frames(&mut buffer[0..3], READ_TIMEOUT_US)?;
231 if bytes_read < 2 {
232 return Err(DmxError::DeserializationError(
233 RdmDeserializationError::WrongMessageLength(bytes_read),
234 ));
235 }
236
237 let start_code = buffer[0];
239 let message_size = if start_code == SC_RDM && bytes_read == 3 {
240 buffer[2] as usize + 2
242 } else {
243 DMX_MAX_PACKAGE_SIZE
244 };
245
246 bytes_read += self.read_frames_no_break(&mut buffer[3..message_size], READ_TIMEOUT_US)?;
247 Ok(DmxFrame::from_slice(&buffer[..bytes_read]).unwrap())
248 }
249}