#[cfg(feature = "phy-linux")]
mod linux;
#[cfg(feature = "phy-linux")]
pub use linux::LinuxRs485Phy;
#[cfg(feature = "phy-serial")]
mod serial;
#[cfg(feature = "phy-serial")]
pub use serial::SerialPortPhy;
#[cfg(feature = "phy-simulator")]
pub mod simulator;
#[cfg(feature = "phy-simulator")]
pub use simulator::SimulatorPhy;
#[cfg(feature = "phy-rp2040")]
mod rp2040;
#[cfg(feature = "phy-rp2040")]
pub use rp2040::Rp2040Phy;
pub type BufferHandle<'a> = managed::ManagedSlice<'a, u8>;
pub trait ProfibusPhy {
fn poll_transmission(&mut self, now: crate::time::Instant) -> bool;
fn transmit_data<F, R>(&mut self, now: crate::time::Instant, f: F) -> R
where
F: FnOnce(&mut [u8]) -> (usize, R);
fn transmit_telegram<F>(
&mut self,
now: crate::time::Instant,
f: F,
) -> Option<crate::fdl::TelegramTxResponse>
where
F: FnOnce(crate::fdl::TelegramTx) -> Option<crate::fdl::TelegramTxResponse>,
{
self.transmit_data(now, |buffer| {
let ttx = crate::fdl::TelegramTx::new(buffer);
let response = f(ttx);
if let Some(response) = response {
let bytes_sent = response.bytes_sent();
if let Some(Ok(t)) = crate::fdl::Telegram::deserialize(buffer) {
log::trace!("PHY TX {:?}", t);
} else {
log::trace!("PHY TX {:?} (invalid!)", &buffer[..bytes_sent]);
}
(bytes_sent, Some(response))
} else {
(0, None)
}
})
}
fn receive_data<F, R>(&mut self, now: crate::time::Instant, f: F) -> R
where
F: FnOnce(&[u8]) -> (usize, R);
fn receive_telegram<F, R>(&mut self, now: crate::time::Instant, f: F) -> Option<R>
where
F: FnOnce(crate::fdl::Telegram) -> R,
{
self.receive_data(now, |buffer| {
match crate::fdl::Telegram::deserialize(buffer) {
Some(Err(_)) => (buffer.len(), None),
Some(Ok((telegram, length))) => {
log::trace!("PHY RX {:?}", telegram);
if length != buffer.len() {
log::trace!("Received more than one telegram at once!");
}
(length, Some(f(telegram)))
}
None => (0, None),
}
})
}
fn receive_all_telegrams<F, R>(&mut self, now: crate::time::Instant, mut f: F) -> Option<R>
where
F: FnMut(crate::fdl::Telegram, bool) -> R,
{
loop {
let (is_last, res) = self.receive_data(now, |buffer| {
match crate::fdl::Telegram::deserialize(buffer) {
Some(Err(_)) => (buffer.len(), (true, None)),
Some(Ok((telegram, length))) => {
log::trace!("PHY RX {:?}", telegram);
let telegram_is_last = length == buffer.len();
let res = f(telegram, telegram_is_last);
(length, (telegram_is_last, Some(res)))
}
None => (0, (true, None)),
}
});
if is_last {
return res;
} else {
log::trace!("Received more than one telegram at once, trying to keep up!");
}
}
}
fn poll_pending_received_bytes(&mut self, now: crate::time::Instant) -> usize {
self.receive_data(now, |buf| (0, buf.len()))
}
}