added RTR example
This commit is contained in:
@ -1,7 +1,6 @@
|
||||
use core::{
|
||||
future::Future,
|
||||
sync::atomic::{AtomicU8, Ordering},
|
||||
usize,
|
||||
};
|
||||
|
||||
use crate::can::regs::BufferState;
|
||||
|
@ -90,10 +90,7 @@ impl CanChannelLowLevel {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn configure_for_transmission(
|
||||
&mut self,
|
||||
tx_priority: Option<u4>,
|
||||
) -> Result<(), InvalidBufferIndexError> {
|
||||
pub fn configure_for_transmission(&mut self, tx_priority: Option<u4>) {
|
||||
self.msg_buf.modify_stat_ctrl(|mut val| {
|
||||
val.set_dlc(u4::new(0));
|
||||
if let Some(tx_priority) = tx_priority {
|
||||
@ -102,28 +99,18 @@ impl CanChannelLowLevel {
|
||||
val.set_state(BufferState::TxNotActive);
|
||||
val
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_standard_id(
|
||||
&mut self,
|
||||
standard_id: embedded_can::StandardId,
|
||||
set_rtr: bool,
|
||||
) -> Result<(), InvalidBufferIndexError> {
|
||||
pub fn set_standard_id(&mut self, standard_id: embedded_can::StandardId, set_rtr: bool) {
|
||||
let mut id1_reg = standard_id.as_raw() << 5;
|
||||
if set_rtr {
|
||||
id1_reg |= 1 << 4;
|
||||
}
|
||||
self.msg_buf
|
||||
.write_id1(BaseId::new_with_raw_value(id1_reg as u32));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_extended_id(
|
||||
&mut self,
|
||||
extended_id: embedded_can::ExtendedId,
|
||||
set_rtr: bool,
|
||||
) -> Result<(), InvalidBufferIndexError> {
|
||||
pub fn set_extended_id(&mut self, extended_id: embedded_can::ExtendedId, set_rtr: bool) {
|
||||
let id_raw = extended_id.as_raw();
|
||||
let id1_reg = (((id_raw >> 18) & 0x7FF) << 4) as u16 | ((id_raw >> 15) & 0b111) as u16;
|
||||
self.msg_buf
|
||||
@ -131,7 +118,6 @@ impl CanChannelLowLevel {
|
||||
let id0_reg = ((id_raw & 0x7FFF) << 1) as u16 | set_rtr as u16;
|
||||
self.msg_buf
|
||||
.write_id0(ExtendedId::new_with_raw_value(id0_reg as u32));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn configure_for_reception(&mut self) {
|
||||
@ -313,7 +299,9 @@ impl CanChannelLowLevel {
|
||||
} else {
|
||||
let dlc = self.msg_buf.read_stat_ctrl().dlc();
|
||||
read_data(dlc);
|
||||
CanFrameNormal::new(id, &data[0..dlc.as_usize()]).unwrap().into()
|
||||
CanFrameNormal::new(id, &data[0..dlc.as_usize()])
|
||||
.unwrap()
|
||||
.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -486,16 +486,23 @@ pub struct CanTx {
|
||||
|
||||
impl CanTx {
|
||||
pub fn new(mut ll: CanChannelLowLevel, tx_priority: Option<u4>) -> Self {
|
||||
ll.configure_for_transmission(tx_priority).unwrap();
|
||||
ll.configure_for_transmission(tx_priority);
|
||||
Self {
|
||||
ll,
|
||||
mode: TxState::Idle,
|
||||
}
|
||||
}
|
||||
|
||||
/// Start transmitting a frame.
|
||||
///
|
||||
/// The frame transmission can be polled/awaited to completion using the [Self::transfer_done]
|
||||
/// method.
|
||||
///
|
||||
/// This function will return a [state error][InvalidTxStateError] if a transmission is already
|
||||
/// active and/or the transmit buffer has an invalid state.
|
||||
pub fn transmit_frame(&mut self, frame: CanFrame) -> Result<(), InvalidTxStateError> {
|
||||
if self.mode == TxState::AwaitingRemoteFrameReply {
|
||||
self.ll.configure_for_transmission(None).unwrap();
|
||||
self.ll.configure_for_transmission(None);
|
||||
self.mode = TxState::Idle;
|
||||
}
|
||||
if self.mode != TxState::Idle {
|
||||
@ -515,7 +522,10 @@ impl CanTx {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn data_frame_transfer_done(&mut self) -> nb::Result<(), InvalidTxStateError> {
|
||||
/// Poll whether an active data frame transmission is done.
|
||||
///
|
||||
/// Returns a [state error][InvalidTxStateError] if no transmission is active.
|
||||
pub fn transfer_done(&mut self) -> nb::Result<(), InvalidTxStateError> {
|
||||
if self.mode != TxState::TransmittingDataFrame {
|
||||
return Err(nb::Error::Other(InvalidTxStateError(self.mode.into())));
|
||||
}
|
||||
@ -531,7 +541,10 @@ impl CanTx {
|
||||
Err(nb::Error::WouldBlock)
|
||||
}
|
||||
|
||||
pub fn remote_frame_transfer_done(&mut self) -> nb::Result<CanRx, InvalidTxStateError> {
|
||||
/// Poll whether an active remote frame transmission is done.
|
||||
///
|
||||
/// Returns a [state error][InvalidTxStateError] if no transmission is active.
|
||||
pub fn remote_transfer_done(&mut self) -> nb::Result<CanRx, InvalidTxStateError> {
|
||||
if self.mode != TxState::TransmittingRemoteFrame {
|
||||
return Err(nb::Error::Other(InvalidTxStateError(self.mode.into())));
|
||||
}
|
||||
@ -549,6 +562,11 @@ impl CanTx {
|
||||
}
|
||||
Err(nb::Error::WouldBlock)
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) {
|
||||
self.ll.reset();
|
||||
self.mode = TxState::Idle;
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CanRx {
|
||||
@ -567,20 +585,18 @@ impl CanRx {
|
||||
&mut self,
|
||||
standard_id: embedded_can::StandardId,
|
||||
set_rtr: bool,
|
||||
) -> Result<(), InvalidBufferIndexError> {
|
||||
self.ll.set_standard_id(standard_id, set_rtr)?;
|
||||
) {
|
||||
self.ll.set_standard_id(standard_id, set_rtr);
|
||||
self.configure_for_reception();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn configure_for_reception_with_extended_id(
|
||||
&mut self,
|
||||
extended_id: embedded_can::ExtendedId,
|
||||
set_rtr: bool,
|
||||
) -> Result<(), InvalidBufferIndexError> {
|
||||
self.ll.set_extended_id(extended_id, set_rtr)?;
|
||||
) {
|
||||
self.ll.set_extended_id(extended_id, set_rtr);
|
||||
self.configure_for_reception();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn configure_for_reception(&mut self) {
|
||||
@ -588,6 +604,14 @@ impl CanRx {
|
||||
self.mode = RxState::Receiving;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn frame_available(&self) -> bool {
|
||||
self.ll
|
||||
.read_state()
|
||||
.is_ok_and(|state| state == BufferState::RxFull || state == BufferState::RxOverrun)
|
||||
}
|
||||
|
||||
/// Poll for frame reception. Returns the frame if one is available.
|
||||
pub fn receive(
|
||||
&mut self,
|
||||
reconfigure_for_reception: bool,
|
||||
|
Reference in New Issue
Block a user