1#![no_std]
2#![allow(incomplete_features)]
3#![feature(generic_const_exprs)]
4
5use core::marker::PhantomData;
6use embassy_futures::select::*;
7use esp_hal::{
8 gpio::{
9 interconnect::*, DriveMode, DriveStrength, Flex, InputConfig, Level, OutputConfig, Pin,
10 Pull,
11 },
12 rmt::{
13 Channel, PulseCode, RxChannelAsync, RxChannelConfig, RxChannelCreator, RxChannelInternal,
14 TxChannelAsync, TxChannelConfig, TxChannelCreator, TxChannelInternal,
15 },
16 Async,
17};
18
19pub trait OneWireConfig {
20 type Rx: RxChannelAsync;
21 type Tx: TxChannelAsync;
22 type TxRaw: TxChannelInternal;
23}
24
25#[derive(Default)]
26pub struct OneWireConfigZST<Rx: RxChannelAsync, Tx: TxChannelAsync, TxRaw: TxChannelInternal>(
27 PhantomData<Rx>,
28 PhantomData<Tx>,
29 PhantomData<TxRaw>,
30);
31
32impl<R: RxChannelAsync, T: TxChannelAsync, TR: TxChannelInternal> OneWireConfig
33 for OneWireConfigZST<R, T, TR>
34{
35 type Rx = R;
36 type Tx = T;
37 type TxRaw = TR;
38}
39
40pub struct OneWire<'a, C: OneWireConfig> {
41 rx: C::Rx,
42 tx: C::Tx,
43 input: InputSignal<'a>,
44 txchan: C::TxRaw, }
46
47impl<'a, Rx: RxChannelInternal, Tx: TxChannelInternal>
48 OneWire<'a, OneWireConfigZST<Channel<Async, Rx>, Channel<Async, Tx>, Tx>>
49{
50 pub fn new<
51 Txc: TxChannelCreator<'a, Async, Raw = Tx>,
52 Rxc: RxChannelCreator<'a, Async, Raw = Rx>,
53 P: Pin + 'a,
54 >(
55 txcc: Txc,
56 rxcc: Rxc,
57 pin: P,
58 ) -> Result<Self, Error> {
59 let rx_config = RxChannelConfig::default()
60 .with_clk_divider(80)
61 .with_idle_threshold(1000)
62 .with_filter_threshold(10)
63 .with_carrier_modulation(false);
64 let tx_config = TxChannelConfig::default()
65 .with_clk_divider(80)
66 .with_carrier_modulation(false);
67
68 let mut pin: Flex = Flex::new(pin);
69
70 pin.apply_input_config(&InputConfig::default().with_pull(Pull::Up));
71 pin.apply_output_config(
72 &OutputConfig::default()
73 .with_drive_mode(DriveMode::OpenDrain)
74 .with_drive_strength(DriveStrength::_40mA),
75 );
76 pin.set_input_enable(true);
77 pin.set_output_enable(true);
78 let (input, output) = pin.split();
79
80 let tx = txcc
81 .configure_tx(output.with_output_inverter(true), tx_config)
82 .map_err(Error::SendError)?;
83 let rx = rxcc
84 .configure_rx(input.clone().with_input_inverter(true), rx_config)
85 .map_err(Error::ReceiveError)?;
86
87 Ok(OneWire {
88 rx,
89 tx,
90 input,
91 txchan: Txc::RAW,
92 })
93 }
94}
95
96impl<'a, CFG: OneWireConfig> OneWire<'a, CFG> {
97 pub async fn reset(&mut self) -> Result<bool, Error> {
98 let data = [
99 PulseCode::new(Level::Low, 60, Level::High, 600),
100 PulseCode::new(Level::Low, 600, Level::Low, 0),
101 PulseCode::empty(),
102 ];
103 let mut indata = [PulseCode::empty(); 10];
104
105 let _res = self.send_and_receive(&mut indata, &data).await?;
106
107 Ok(indata[0].length1() > 0
108 && indata[0].length2() > 0
109 && indata[1].length1() > 100
110 && indata[1].length1() < 200)
111 }
112
113 pub async fn send_and_receive(
114 &mut self,
115 indata: &mut [u32],
116 data: &[u32],
117 ) -> Result<(), Error> {
118 let delay = [PulseCode::new(Level::Low, 30000, Level::Low, 0)]; if self.input.level() == Level::Low {
120 Err(Error::InputNotHigh)?;
121 }
122 let res = select(self.rx.receive(indata), async {
124 let r = self.tx.transmit(data).await;
125 let _ = self.tx.transmit(&delay).await;
126 r
127 })
128 .await;
129 self.txchan.stop_tx();
131
132 match res {
133 Either::First(Ok(r)) => Ok(r),
134 Either::First(Err(r)) => Err(Error::ReceiveError(r)),
135 Either::Second(Ok(())) => Err(Error::ReceiveTimedOut),
136 Either::Second(Err(e)) => Err(Error::SendError(e)),
137 }
138 }
139
140 const ZERO_BIT_LEN: u16 = 70;
141 const ONE_BIT_LEN: u16 = 3;
142
143 pub fn encode_bit(bit: bool) -> u32 {
144 if bit {
145 PulseCode::new(
146 Level::High,
147 Self::ONE_BIT_LEN,
148 Level::Low,
149 Self::ZERO_BIT_LEN,
150 )
151 } else {
152 PulseCode::new(
153 Level::High,
154 Self::ZERO_BIT_LEN,
155 Level::Low,
156 Self::ONE_BIT_LEN,
157 )
158 }
159 }
160
161 pub fn decode_bit(code: u32) -> bool {
162 let len = code.length1();
163 if len < 20 {
164 true
165 } else {
166 false
167 }
168 }
169
170 pub async fn exchange_byte(&mut self, byte: u8) -> Result<u8, Error> {
171 let mut data = [PulseCode::empty(); 10];
172 let mut indata = [PulseCode::empty(); 10];
173 for n in 0..8 {
174 data[n] = Self::encode_bit(0 != byte & 1 << n);
175 }
176 let _res = self.send_and_receive(&mut indata, &data).await?;
177 let mut res: u8 = 0;
178 for n in 0..8 {
179 if Self::decode_bit(indata[n]) {
180 res |= 1 << n;
181 }
182 }
183 Ok(res)
184 }
185
186 pub async fn send_byte(&mut self, byte: u8) -> Result<(), Error> {
187 let mut data = [PulseCode::empty(); 10];
188 for n in 0..8 {
189 data[n] = Self::encode_bit(0 != byte & 1 << n);
190 }
191 let _res = self.tx.transmit(&data).await?;
192 Ok(())
193 }
194
195 pub async fn exchange_bits<const N: usize>(
196 &mut self,
197 bits: [bool; N],
198 ) -> Result<[bool; N], Error>
199 where
200 [(); N + 1]:,
201 {
202 let mut data = [PulseCode::empty(); N + 1];
203 let mut indata = [PulseCode::empty(); N + 1];
204 for n in 0..N {
205 data[n] = Self::encode_bit(bits[n]);
206 }
207 let _res = self.send_and_receive(&mut indata, &data).await?;
208 let mut res: [bool; N] = [false; N];
209 for n in 0..N {
210 res[n] = Self::decode_bit(indata[n]);
211 }
212 Ok(res)
213 }
214
215 pub async fn send_u64(&mut self, val: u64) -> Result<(), Error> {
216 for byte in val.to_le_bytes() {
217 self.send_byte(byte).await?;
218 }
219 Ok(())
220 }
221
222 pub async fn send_address(&mut self, val: Address) -> Result<(), Error> {
223 self.send_u64(val.0).await
224 }
225}
226
227#[derive(Debug)]
228pub enum Error {
229 InputNotHigh,
230 ReceiveTimedOut,
231 ReceiveError(esp_hal::rmt::Error),
232 SendError(esp_hal::rmt::Error),
233}
234
235impl From<esp_hal::rmt::Error> for Error {
236 fn from(e: esp_hal::rmt::Error) -> Error {
237 Error::SendError(e)
238 }
239}
240
241#[derive(PartialEq, Eq, Clone, Copy)]
242pub struct Address(pub u64);
243
244impl core::fmt::Debug for Address {
245 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
246 core::write!(f, "{:X?}", self.0.to_le_bytes())
247 }
248}
249
250impl core::fmt::Display for Address {
251 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
252 for k in self.0.to_le_bytes() {
253 core::write!(f, "{:X}", k)?;
254 }
255 Ok(())
256 }
257}
258
259pub struct Search {
260 command: u8,
261 address: u64,
262 #[cfg(feature = "search-masks")]
263 address_mask: u64,
264 last_discrepancy: Option<usize>,
265 complete: bool,
266}
267
268#[derive(Debug)]
269pub enum SearchError {
270 SearchComplete,
271 NoDevicesPresent,
272 BusError(Error),
273}
274
275impl From<Error> for SearchError {
276 fn from(e: Error) -> SearchError {
277 SearchError::BusError(e)
278 }
279}
280
281impl Search {
282 pub fn new() -> Search {
283 Search {
284 command: 0xF0,
285 address: 0,
286 #[cfg(feature = "search-masks")]
287 address_mask: 0,
288 last_discrepancy: None,
289 complete: false,
290 }
291 }
292 pub fn new_alarm() -> Search {
293 Search {
294 command: 0xEC,
295 address: 0,
296 #[cfg(feature = "search-masks")]
297 address_mask: 0,
298 last_discrepancy: None,
299 complete: false,
300 }
301 }
302 #[cfg(feature = "search-masks")]
303 pub fn new_with_mask(fixed_bits: u64, bit_mask: u64) {
304 Search {
305 command: 0xEC,
306 address: fixed_bits,
307 address_mask: bit_mask,
308 last_discrepancy: None,
309 complete: false,
310 }
311 }
312 pub async fn next<'d, CFG: OneWireConfig>(
313 &mut self,
314 ow: &mut OneWire<'d, CFG>,
315 ) -> Result<Address, SearchError> {
316 if self.complete {
317 return Err(SearchError::SearchComplete);
318 }
319 let have_devices = ow.reset().await?;
320 let mut last_zero = None;
321 ow.send_byte(self.command).await?;
322 if have_devices {
323 for id_bit_number in 0..64 {
324 let id_bits = ow.exchange_bits([true, true]).await?;
325 let search_direction = match id_bits {
326 #[cfg(feature = "search-masks")]
327 _ if address_mask & (1 << id_bit_number) != 0 => {
328 address & (1 << id_bit_number) != 0
329 }
330 [false, true] => false,
331 [true, false] => true,
332 [true, true] => {
333 return Err(SearchError::NoDevicesPresent);
334 }
335 [false, false] => {
336 if self.last_discrepancy == Some(id_bit_number) {
337 true
338 } else if Some(id_bit_number) > self.last_discrepancy {
339 last_zero = Some(id_bit_number);
340 false
341 } else {
342 self.address & (1 << id_bit_number) != 0
343 }
344 }
345 };
346 if search_direction {
347 self.address |= 1 << id_bit_number;
348 } else {
349 self.address &= !(1 << id_bit_number);
350 }
351 ow.exchange_bits([search_direction]).await?;
352 }
353 self.last_discrepancy = last_zero;
354 self.complete = last_zero.is_none();
355 Ok(Address(self.address))
356 } else {
357 Err(SearchError::NoDevicesPresent)
358 }
359 }
360}