Skip to content
41 changes: 41 additions & 0 deletions embedded-service/src/event.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Common traits for event senders and receivers

use core::marker::PhantomData;

use embassy_sync::channel::{DynamicReceiver, DynamicSender};

/// Common event sender trait
Expand Down Expand Up @@ -41,3 +43,42 @@ impl<E> Receiver<E> for DynamicReceiver<'_, E> {
self.receive()
}
}

/// A sender that discards all events sent to it.
pub struct DiscardSender;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor nit: I think NoopSender might be a slightly preferrable name here and matches conventions other crates use (e.g. NoopRawMutex in embassy). Makes it clear it's just a type meant to satisfy the type system but doesn't do anything.


impl<E> Sender<E> for DiscardSender {
fn try_send(&mut self, _event: E) -> Option<()> {
Some(())
}

async fn send(&mut self, _event: E) {}
}

/// Applies a function on events before passing them to the wrapped sender
pub struct MapSender<I, O, S: Sender<O>, F: FnMut(I) -> O> {
sender: S,
map_fn: F,
_phantom: PhantomData<(I, O)>,
}

impl<I, O, S: Sender<O>, F: FnMut(I) -> O> MapSender<I, O, S, F> {
/// Create a new self
pub fn new(sender: S, map_fn: F) -> Self {
Self {
sender,
map_fn,
_phantom: PhantomData,
}
}
}

impl<I, O, S: Sender<O>, F: FnMut(I) -> O> Sender<I> for MapSender<I, O, S, F> {
fn try_send(&mut self, event: I) -> Option<()> {
self.sender.try_send((self.map_fn)(event))
}

fn send(&mut self, event: I) -> impl Future<Output = ()> {
self.sender.send((self.map_fn)(event))
}
}
1 change: 1 addition & 0 deletions embedded-service/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub mod hid;
pub mod init;
pub mod ipc;
pub mod keyboard;
pub mod named;
pub mod relay;
pub mod sync;

Expand Down
7 changes: 7 additions & 0 deletions embedded-service/src/named.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//! Traits for things that have names.

/// Trait for anything that has a name.
pub trait Named {
/// Return name
fn name(&self) -> &'static str;
}
18 changes: 15 additions & 3 deletions examples/rt685s-evk/src/bin/type_c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use embassy_sync::once_lock::OnceLock;
use embassy_sync::pubsub::PubSubChannel;
use embassy_time::{self as _, Delay};
use embedded_cfu_protocol::protocol_definitions::{FwUpdateOffer, FwUpdateOfferResponse, FwVersion, HostToken};
use embedded_services::event::DiscardSender;
use embedded_services::{GlobalRawMutex, IntrusiveList};
use embedded_services::{error, info};
use embedded_usb_pd::GlobalPortId;
Expand Down Expand Up @@ -81,7 +82,10 @@ async fn interrupt_task(mut int_in: Input<'static>, mut interrupt: Interrupt<'st
#[embassy_executor::task]
async fn power_policy_task(
psu_events: EventReceivers<'static, 2, DeviceType, DynamicReceiver<'static, psu::event::EventData>>,
power_policy: &'static Mutex<GlobalRawMutex, power_policy_service::service::Service<'static, DeviceType>>,
power_policy: &'static Mutex<
GlobalRawMutex,
power_policy_service::service::Service<'static, 'static, 'static, DeviceType, DiscardSender>,
>,
) {
power_policy_service::service::task::task(psu_events, power_policy).await;
}
Expand Down Expand Up @@ -207,10 +211,18 @@ async fn main(spawner: Spawner) {
static POWER_POLICY_PSU_REGISTRATION: StaticCell<[&DeviceType; 2]> = StaticCell::new();
let psu_registration = POWER_POLICY_PSU_REGISTRATION.init([&wrapper.ports[0].proxy, &wrapper.ports[1].proxy]);

static POWER_SERVICE: StaticCell<Mutex<GlobalRawMutex, power_policy_service::service::Service<DeviceType>>> =
StaticCell::new();
static POWER_POLICY_EVENT_SENDERS: StaticCell<[DiscardSender; 1]> = StaticCell::new();
let power_policy_event_senders = POWER_POLICY_EVENT_SENDERS.init([DiscardSender]);

static POWER_SERVICE: StaticCell<
Mutex<
GlobalRawMutex,
power_policy_service::service::Service<'static, 'static, 'static, DeviceType, DiscardSender>,
>,
> = StaticCell::new();
let power_service = POWER_SERVICE.init(Mutex::new(power_policy_service::service::Service::new(
psu_registration,
power_policy_event_senders.as_mut_slice(),
power_service_context,
power_policy_service::service::config::Config::default(),
)));
Expand Down
18 changes: 15 additions & 3 deletions examples/rt685s-evk/src/bin/type_c_cfu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use embassy_time::Timer;
use embassy_time::{self as _, Delay};
use embedded_cfu_protocol::protocol_definitions::*;
use embedded_cfu_protocol::protocol_definitions::{FwUpdateOffer, FwUpdateOfferResponse, FwVersion};
use embedded_services::event::DiscardSender;
use embedded_services::{GlobalRawMutex, IntrusiveList};
use embedded_services::{error, info};
use embedded_usb_pd::GlobalPortId;
Expand Down Expand Up @@ -165,7 +166,10 @@ async fn fw_update_task() {
#[embassy_executor::task]
async fn power_policy_task(
psu_events: EventReceivers<'static, 2, DeviceType, DynamicReceiver<'static, psu::event::EventData>>,
power_policy: &'static Mutex<GlobalRawMutex, power_policy_service::service::Service<'static, DeviceType>>,
power_policy: &'static Mutex<
GlobalRawMutex,
power_policy_service::service::Service<'static, 'static, 'static, DeviceType, DiscardSender>,
>,
) {
power_policy_service::service::task::task(psu_events, power_policy).await;
}
Expand Down Expand Up @@ -285,10 +289,18 @@ async fn main(spawner: Spawner) {
static POWER_POLICY_PSU_REGISTRATION: StaticCell<[&DeviceType; 2]> = StaticCell::new();
let psu_registration = POWER_POLICY_PSU_REGISTRATION.init([&wrapper.ports[0].proxy, &wrapper.ports[1].proxy]);

static POWER_SERVICE: StaticCell<Mutex<GlobalRawMutex, power_policy_service::service::Service<DeviceType>>> =
StaticCell::new();
static POWER_POLICY_EVENT_SENDERS: StaticCell<[DiscardSender; 1]> = StaticCell::new();
let power_policy_event_senders = POWER_POLICY_EVENT_SENDERS.init([DiscardSender]);

static POWER_SERVICE: StaticCell<
Mutex<
GlobalRawMutex,
power_policy_service::service::Service<'static, 'static, 'static, DeviceType, DiscardSender>,
>,
> = StaticCell::new();
let power_service = POWER_SERVICE.init(Mutex::new(power_policy_service::service::Service::new(
psu_registration,
power_policy_event_senders.as_mut_slice(),
power_service_context,
power_policy_service::service::config::Config::default(),
)));
Expand Down
21 changes: 17 additions & 4 deletions examples/std/src/bin/power_policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use embassy_sync::{
mutex::Mutex,
};
use embassy_time::{self as _, Timer};
use embedded_services::GlobalRawMutex;
use embedded_services::{GlobalRawMutex, event::DiscardSender, named::Named};
use log::*;
use power_policy_interface::psu::{Error, Psu};
use power_policy_interface::{
Expand Down Expand Up @@ -96,7 +96,9 @@ impl Psu for ExampleDevice<'_> {
fn state_mut(&mut self) -> &mut psu::State {
&mut self.state
}
}

impl Named for ExampleDevice<'_> {
fn name(&self) -> &'static str {
self.name
}
Expand Down Expand Up @@ -134,10 +136,18 @@ async fn run(spawner: Spawner) {
static POWER_POLICY_PSU_REGISTRATION: StaticCell<[&DeviceType; 2]> = StaticCell::new();
let psu_registration = POWER_POLICY_PSU_REGISTRATION.init([device0, device1]);

static SERVICE: StaticCell<Mutex<GlobalRawMutex, power_policy_service::service::Service<'static, DeviceType>>> =
StaticCell::new();
static POWER_POLICY_EVENT_SENDERS: StaticCell<[DiscardSender; 1]> = StaticCell::new();
let power_policy_event_senders = POWER_POLICY_EVENT_SENDERS.init([DiscardSender]);

static SERVICE: StaticCell<
Mutex<
GlobalRawMutex,
power_policy_service::service::Service<'static, 'static, 'static, DeviceType, DiscardSender>,
>,
> = StaticCell::new();
let service = SERVICE.init(Mutex::new(power_policy_service::service::Service::new(
psu_registration.as_slice(),
power_policy_event_senders.as_mut_slice(),
service_context,
power_policy_service::service::config::Config::default(),
)));
Expand Down Expand Up @@ -281,7 +291,10 @@ async fn power_policy_task(
DeviceType,
channel::DynamicReceiver<'static, power_policy_interface::psu::event::EventData>,
>,
power_policy: &'static Mutex<GlobalRawMutex, power_policy_service::service::Service<'static, DeviceType>>,
power_policy: &'static Mutex<
GlobalRawMutex,
power_policy_service::service::Service<'static, 'static, 'static, DeviceType, DiscardSender>,
>,
) {
power_policy_service::service::task::task(psu_events, power_policy).await;
}
Expand Down
18 changes: 15 additions & 3 deletions examples/std/src/bin/type_c/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use embassy_sync::mutex::Mutex;
use embassy_sync::once_lock::OnceLock;
use embassy_sync::pubsub::PubSubChannel;
use embassy_time::Timer;
use embedded_services::event::DiscardSender;
use embedded_services::{GlobalRawMutex, IntrusiveList};
use embedded_usb_pd::GlobalPortId;
use embedded_usb_pd::ado::Ado;
Expand Down Expand Up @@ -75,10 +76,18 @@ async fn task(spawner: Spawner) {
static POWER_POLICY_PSU_REGISTRATION: StaticCell<[&DeviceType; 1]> = StaticCell::new();
let psu_registration = POWER_POLICY_PSU_REGISTRATION.init([&wrapper.ports[0].proxy]);

static POWER_SERVICE: StaticCell<Mutex<GlobalRawMutex, power_policy_service::service::Service<DeviceType>>> =
StaticCell::new();
static POWER_POLICY_EVENT_SENDERS: StaticCell<[DiscardSender; 1]> = StaticCell::new();
let power_policy_event_senders = POWER_POLICY_EVENT_SENDERS.init([DiscardSender]);

static POWER_SERVICE: StaticCell<
Mutex<
GlobalRawMutex,
power_policy_service::service::Service<'static, 'static, 'static, DeviceType, DiscardSender>,
>,
> = StaticCell::new();
let power_service = POWER_SERVICE.init(Mutex::new(power_policy_service::service::Service::new(
psu_registration,
power_policy_event_senders.as_mut_slice(),
power_service_context,
power_policy_service::service::config::Config::default(),
)));
Expand Down Expand Up @@ -144,7 +153,10 @@ async fn task(spawner: Spawner) {
#[embassy_executor::task]
async fn power_policy_task(
psu_events: EventReceivers<'static, 1, DeviceType, DynamicReceiver<'static, psu::event::EventData>>,
power_policy: &'static Mutex<GlobalRawMutex, power_policy_service::service::Service<'static, DeviceType>>,
power_policy: &'static Mutex<
GlobalRawMutex,
power_policy_service::service::Service<'static, 'static, 'static, DeviceType, DiscardSender>,
>,
) {
power_policy_service::service::task::task(psu_events, power_policy).await;
}
Expand Down
15 changes: 12 additions & 3 deletions examples/std/src/bin/type_c/ucsi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use embassy_sync::once_lock::OnceLock;
use embassy_sync::pubsub::PubSubChannel;
use embedded_services::GlobalRawMutex;
use embedded_services::IntrusiveList;
use embedded_services::event::DiscardSender;
use embedded_usb_pd::GlobalPortId;
use embedded_usb_pd::ucsi::lpm::get_connector_capability::OperationModeFlags;
use embedded_usb_pd::ucsi::ppm::ack_cc_ci::Ack;
Expand Down Expand Up @@ -180,7 +181,10 @@ async fn wrapper_task(wrapper: &'static mock_controller::Wrapper<'static>) {
#[embassy_executor::task]
async fn power_policy_task(
psu_events: EventReceivers<'static, 2, DeviceType, DynamicReceiver<'static, psu::event::EventData>>,
power_policy: &'static Mutex<GlobalRawMutex, power_policy_service::service::Service<'static, DeviceType>>,
power_policy: &'static Mutex<
GlobalRawMutex,
power_policy_service::service::Service<'static, 'static, 'static, DeviceType, DiscardSender>,
>,
) {
power_policy_service::service::task::task(psu_events, power_policy).await;
}
Expand Down Expand Up @@ -305,10 +309,15 @@ async fn task(spawner: Spawner) {
static POWER_POLICY_PSU_REGISTRATION: StaticCell<[&DeviceType; 2]> = StaticCell::new();
let psu_registration = POWER_POLICY_PSU_REGISTRATION.init([&wrapper0.ports[0].proxy, &wrapper1.ports[0].proxy]);

static POWER_SERVICE: StaticCell<Mutex<GlobalRawMutex, power_policy_service::service::Service<DeviceType>>> =
StaticCell::new();
static POWER_POLICY_EVENT_SENDERS: StaticCell<[DiscardSender; 1]> = StaticCell::new();
let power_policy_event_senders = POWER_POLICY_EVENT_SENDERS.init([DiscardSender]);

static POWER_SERVICE: StaticCell<
Mutex<GlobalRawMutex, power_policy_service::service::Service<DeviceType, DiscardSender>>,
> = StaticCell::new();
let power_service = POWER_SERVICE.init(Mutex::new(power_policy_service::service::Service::new(
psu_registration,
power_policy_event_senders.as_mut_slice(),
power_service_context,
power_policy_service::service::config::Config::default(),
)));
Expand Down
18 changes: 15 additions & 3 deletions examples/std/src/bin/type_c/unconstrained.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use embassy_sync::mutex::Mutex;
use embassy_sync::once_lock::OnceLock;
use embassy_sync::pubsub::PubSubChannel;
use embassy_time::Timer;
use embedded_services::event::DiscardSender;
use embedded_services::{GlobalRawMutex, IntrusiveList};
use embedded_usb_pd::GlobalPortId;
use log::*;
Expand Down Expand Up @@ -179,10 +180,18 @@ async fn task(spawner: Spawner) {
&wrapper2.ports[0].proxy,
]);

static POWER_SERVICE: StaticCell<Mutex<GlobalRawMutex, power_policy_service::service::Service<DeviceType>>> =
StaticCell::new();
static POWER_POLICY_EVENT_SENDERS: StaticCell<[DiscardSender; 1]> = StaticCell::new();
let power_policy_event_senders = POWER_POLICY_EVENT_SENDERS.init([DiscardSender]);

static POWER_SERVICE: StaticCell<
Mutex<
GlobalRawMutex,
power_policy_service::service::Service<'static, 'static, 'static, DeviceType, DiscardSender>,
>,
> = StaticCell::new();
let power_service = POWER_SERVICE.init(Mutex::new(power_policy_service::service::Service::new(
psu_registration,
power_policy_event_senders.as_mut_slice(),
power_service_context,
power_policy_service::service::config::Config::default(),
)));
Expand Down Expand Up @@ -284,7 +293,10 @@ async fn task(spawner: Spawner) {
#[embassy_executor::task]
async fn power_policy_task(
psu_events: EventReceivers<'static, 3, DeviceType, DynamicReceiver<'static, psu::event::EventData>>,
power_policy: &'static Mutex<GlobalRawMutex, power_policy_service::service::Service<'static, DeviceType>>,
power_policy: &'static Mutex<
GlobalRawMutex,
power_policy_service::service::Service<'static, 'static, 'static, DeviceType, DiscardSender>,
>,
) {
power_policy_service::service::task::task(psu_events, power_policy).await;
}
Expand Down
6 changes: 3 additions & 3 deletions power-policy-interface/src/psu/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
//! Device struct and methods
use embedded_services::named::Named;

use crate::capability::{ConsumerPowerCapability, PowerCapability, ProviderPowerCapability};

pub mod event;
Expand Down Expand Up @@ -280,7 +282,7 @@ pub struct Response {
}

/// Trait for PSU devices
pub trait Psu {
pub trait Psu: Named {
/// Disconnect power from this device
fn disconnect(&mut self) -> impl Future<Output = Result<(), Error>>;
/// Connect this device to provide power to an external connection
Expand All @@ -291,6 +293,4 @@ pub trait Psu {
fn state(&self) -> &State;
/// Return a mutable reference to the current PSU state
fn state_mut(&mut self) -> &mut State;
/// Return the name of the PSU
fn name(&self) -> &'static str;
}
Loading
Loading