oze_canopen/
sync.rs

1use crate::{
2    error::CoError,
3    interface::{CanOpenInterface, SEND_TIMOUT},
4    transmitter::TxPacket,
5};
6use std::time::Duration;
7use tokio::{sync::watch, time::sleep};
8
9pub struct Server {
10    control: watch::Sender<Option<Duration>>,
11}
12
13impl Server {
14    pub fn set_period(&self, period: Option<Duration>) {
15        let _ = self.control.send(period);
16    }
17
18    pub fn start(interface: CanOpenInterface) -> Server {
19        let (snd, rcv) = watch::channel::<Option<Duration>>(None);
20        tokio::spawn(async move {
21            Self::task(&interface, rcv).await;
22        });
23
24        Server { control: snd }
25    }
26
27    async fn task(interface: &CanOpenInterface, mut rcv: watch::Receiver<Option<Duration>>) {
28        let mut control;
29        loop {
30            control = *rcv.borrow();
31            if let Some(period) = control {
32                _ = interface.send_sync().await;
33
34                tokio::select! {
35                    _ = sleep(period) => {},
36                    _ = rcv.changed() => {},
37                }
38            } else {
39                let _ = rcv.changed().await;
40            }
41        }
42    }
43}
44
45impl CanOpenInterface {
46    pub async fn send_sync(&self) -> Result<(), CoError> {
47        self.tx
48            .send_timeout(
49                TxPacket {
50                    cob_id: 0x080,
51                    data: Vec::new(),
52                },
53                Duration::from_millis(SEND_TIMOUT),
54            )
55            .await?;
56        Ok(())
57    }
58}