Struct erdnuss_comms::controller::Controller
source · pub struct Controller<R: RawMutex + 'static, const IN: usize = INCOMING_SIZE, const OUT: usize = OUTGOING_SIZE> { /* private fields */ }
Expand description
Controller interface and data storage
The static Controller is intended to be used in two separate places in an application:
- In one place, where Controller::step() is called periodically, to service bus operations
- In another place, where Controller::recv_from() or Controller::send() are called, to process or forward messages to/from the bus
In a typical example where the Controller is acting as a Bridge/Router over USB, place 1. would be a standalone task, calling step at some periodic polling rate, and place 2. would be grouped with the USB interface for sending/receiving frames over USB.
The Controller contains an async Mutex which provides interior mutable access to information such as the table of connected Targets, or any “in flight” messages.
Implementations§
source§impl<R: RawMutex + 'static, const IN: usize, const OUT: usize> Controller<R, IN, OUT>
impl<R: RawMutex + 'static, const IN: usize, const OUT: usize> Controller<R, IN, OUT>
Instantiation and Initialization methods
sourcepub const fn uninit() -> Controller<R, IN, OUT>
pub const fn uninit() -> Controller<R, IN, OUT>
Create a new, uninitialized controller structure
Intended to be used to create as a static to avoid large stack initializations.
Users must still call Controller::init()
before use.
use erdnuss_comms::controller::Controller;
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
// NOTE: you can use any mutex suitable for you, such as `ThreadModeRawMutex`
// if you not using this from an interrupt context
static CONTROLLER: Controller<CriticalSectionRawMutex> = Controller::uninit();
sourcepub async fn init(&self, sli: &mut RawFrameSlice)
pub async fn init(&self, sli: &mut RawFrameSlice)
Initialize the Controller
This initialization provides the backing storage for the incoming target
frames. RawFrameSlice must contain AT LEAST IN
times OUT
frame storage slots. sli
’s capacity will be reduced by this amount.
source§impl<R: RawMutex + 'static> Controller<R>
impl<R: RawMutex + 'static> Controller<R>
Bus management and operation method(s)
sourcepub async fn step<T, Rand>(
&self,
serial: &mut T,
rand: &mut Rand
) -> Result<(), Error<T::SerError>>where
T: FrameSerial,
Rand: RngCore,
pub async fn step<T, Rand>(
&self,
serial: &mut T,
rand: &mut Rand
) -> Result<(), Error<T::SerError>>where
T: FrameSerial,
Rand: RngCore,
Perform one “step” of the bus
One call to step
will:
- Send UP TO one message to any known Targets, and Receive UP TO one message from any known Target
- Attempt to complete any pending logical address offers
- Attempt to offer UP TO one unused logical address
This method should be called regularly.
The serial
and rand
resources are passed in on every call to step
,
rather than making them part of the entire Controller
entity for a couple
of stylistic reasons:
- Keep the static type-generics less complex
- Make initialization less complex
- Make these generics NOT required for the shared
send
/recv_from
interface methods
The inner async mutex will be locked for the entire duration of the call to
step
, which may be held for some amount of time, depending on the number of
bus timeouts and total amount of data transferred. This may be on the order of
millisecond(s).
source§impl<R: RawMutex + 'static> Controller<R>
impl<R: RawMutex + 'static> Controller<R>
Bus I/O methods
sourcepub async fn send(&self, mac: u64, frame: SendFrameBox) -> Result<(), SendError>
pub async fn send(&self, mac: u64, frame: SendFrameBox) -> Result<(), SendError>
Attempt to enqueue a message for sending
sourcepub async fn recv_from(&self, mac: u64) -> Result<WireFrameBox, RecvError>
pub async fn recv_from(&self, mac: u64) -> Result<WireFrameBox, RecvError>
Attempt to receive a message from the given unique address
sourcepub async fn connected(&self) -> Vec<u64, { _ }>
pub async fn connected(&self) -> Vec<u64, { _ }>
Get a list of all target devices on the bus
This list DOES NOT include the Controller’s MAC address, but the returned
heapless::Vec
does reserve enough room to contain all MAX_TARGETS
plus one.