Skip to content

Commit 51b6661

Browse files
committed
WIP: type-c service now builds
1 parent a6b3735 commit 51b6661

File tree

4 files changed

+144
-79
lines changed

4 files changed

+144
-79
lines changed

type-c-service/src/wrapper/backing.rs

Lines changed: 103 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
//! use embedded_services::type_c::ControllerId;
2222
//! use embedded_services::power;
2323
//! use embedded_usb_pd::GlobalPortId;
24-
//! use type_c_service::wrapper::backing::{Storage, ReferencedStorage};
24+
//! use type_c_service::wrapper::backing::{Storage, IntermediateStorage, ReferencedStorage};
2525
//!
2626
//!
2727
//! const NUM_PORTS: usize = 2;
@@ -33,8 +33,10 @@
3333
//! 0x0,
3434
//! [(GlobalPortId(0), power::policy::DeviceId(0)), (GlobalPortId(1), power::policy::DeviceId(1))],
3535
//! ));
36+
//! static INTERMEDIATE: StaticCell<IntermediateStorage<NUM_PORTS, NoopRawMutex>> = StaticCell::new();
37+
//! let intermediate = INTERMEDIATE.init(storage.create_intermediate());
3638
//! static REFERENCED: StaticCell<ReferencedStorage<NUM_PORTS, NoopRawMutex>> = StaticCell::new();
37-
//! let referenced = REFERENCED.init(storage.create_referenced().unwrap());
39+
//! let referenced = REFERENCED.init(intermediate.create_referenced());
3840
//! let _backing = referenced.create_backing().unwrap();
3941
//! }
4042
//! ```
@@ -49,7 +51,10 @@ use embassy_time::Instant;
4951
use embedded_cfu_protocol::protocol_definitions::ComponentId;
5052
use embedded_services::{
5153
event,
52-
power::{self, policy::policy},
54+
power::{
55+
self,
56+
policy::{DeviceId, policy},
57+
},
5358
type_c::{
5459
ControllerId,
5560
controller::PortStatus,
@@ -104,14 +109,11 @@ impl Default for ControllerState {
104109
struct InternalState<'a, const N: usize, S: event::Sender<policy::RequestData>> {
105110
controller_state: ControllerState,
106111
port_states: [PortState<'a>; N],
107-
port_power: [PortPower<'a, S>; N],
112+
port_power: [PortPower<S>; N],
108113
}
109114

110115
impl<'a, const N: usize, S: event::Sender<policy::RequestData>> InternalState<'a, N, S> {
111-
fn try_new<M: RawMutex>(
112-
storage: &'a Storage<N, M>,
113-
power_events: [(S, PowerProxyReceiver<'a>); N],
114-
) -> Option<Self> {
116+
fn try_new<M: RawMutex>(storage: &'a Storage<N, M>, power_events: [S; N]) -> Option<Self> {
115117
Some(Self {
116118
controller_state: ControllerState::default(),
117119
port_states: from_fn(|i| PortState {
@@ -124,9 +126,8 @@ impl<'a, const N: usize, S: event::Sender<policy::RequestData>> InternalState<'a
124126
storage.pd_alerts[i].dyn_subscriber()?,
125127
),
126128
}),
127-
port_power: power_events.map(|(sender, receiver)| PortPower {
129+
port_power: power_events.map(|sender| PortPower {
128130
sender,
129-
receiver,
130131
state: Default::default(),
131132
}),
132133
})
@@ -154,11 +155,11 @@ impl<'a, const N: usize, S: event::Sender<policy::RequestData>> DynPortState<'a,
154155
&mut self.controller_state
155156
}
156157

157-
fn port_power(&self) -> &[PortPower<'a, S>] {
158+
fn port_power(&self) -> &[PortPower<S>] {
158159
&self.port_power
159160
}
160161

161-
fn port_power_mut(&mut self) -> &mut [PortPower<'a, S>] {
162+
fn port_power_mut(&mut self) -> &mut [PortPower<S>] {
162163
&mut self.port_power
163164
}
164165
}
@@ -173,8 +174,8 @@ pub trait DynPortState<'a, S: event::Sender<policy::RequestData>> {
173174
fn controller_state(&self) -> &ControllerState;
174175
fn controller_state_mut(&mut self) -> &mut ControllerState;
175176

176-
fn port_power(&self) -> &[PortPower<'a, S>];
177-
fn port_power_mut(&mut self) -> &mut [PortPower<'a, S>];
177+
fn port_power(&self) -> &[PortPower<S>];
178+
fn port_power_mut(&mut self) -> &mut [PortPower<S>];
178179
}
179180

180181
/// Service registration objects
@@ -193,9 +194,8 @@ impl<'a, M: RawMutex, R: event::Receiver<policy::RequestData>> Registration<'a,
193194
/// PD alerts should be fairly uncommon, four seems like a reasonable number to start with.
194195
const MAX_BUFFERED_PD_ALERTS: usize = 4;
195196

196-
pub struct PortPower<'a, S: event::Sender<policy::RequestData>> {
197+
pub struct PortPower<S: event::Sender<policy::RequestData>> {
197198
pub sender: S,
198-
pub receiver: PowerProxyReceiver<'a>,
199199
pub state: power::policy::device::InternalState,
200200
}
201201

@@ -222,53 +222,110 @@ impl<const N: usize, M: RawMutex> Storage<N, M> {
222222
}
223223
}
224224

225-
/// Create referenced storage from this storage
226-
pub fn create_referenced<S: event::Sender<policy::RequestData>>(
227-
&self,
228-
policy_senders: [S; N],
229-
) -> Option<ReferencedStorage<'_, N, M, S>> {
230-
ReferencedStorage::try_from_storage(self, policy_senders)
225+
/// Create intermediate storage from this storage
226+
pub fn create_intermediate(&self) -> IntermediateStorage<'_, N, M> {
227+
IntermediateStorage::from_storage(self)
228+
}
229+
}
230+
231+
/// Intermediate storage that holds power proxy devices
232+
pub struct IntermediateStorage<'a, const N: usize, M: RawMutex> {
233+
storage: &'a Storage<N, M>,
234+
power_proxy_devices: [Mutex<M, PowerProxyDevice<'a>>; N],
235+
power_proxy_receivers: [Mutex<M, PowerProxyReceiver<'a>>; N],
236+
}
237+
238+
impl<'a, const N: usize, M: RawMutex> IntermediateStorage<'a, N, M> {
239+
fn from_storage(storage: &'a Storage<N, M>) -> Self {
240+
let mut power_proxy_devices = heapless::Vec::<_, N>::new();
241+
let mut power_proxy_receivers = heapless::Vec::<_, N>::new();
242+
243+
for power_proxy_channel in storage.power_proxy_channels.iter() {
244+
// Safe because everything has a length of N
245+
power_proxy_devices
246+
.push(Mutex::new(power_proxy_channel.get_device()))
247+
.expect("Failed to insert power proxy device");
248+
power_proxy_receivers
249+
.push(Mutex::new(power_proxy_channel.get_receiver()))
250+
.expect("Failed to insert power proxy receiver");
251+
}
252+
253+
Self {
254+
storage,
255+
// Safe because both have N elements
256+
power_proxy_devices: power_proxy_devices
257+
.into_array()
258+
.expect("Failed to create power devices"),
259+
power_proxy_receivers: power_proxy_receivers
260+
.into_array()
261+
.expect("Failed to create power receivers"),
262+
}
263+
}
264+
265+
/// Create referenced storage from this intermediate storage
266+
pub fn create_referenced<'b, S: event::Sender<policy::RequestData>, R: event::Receiver<policy::RequestData>>(
267+
&'b self,
268+
policy_args: [(DeviceId, S, R); N],
269+
) -> ReferencedStorage<'b, N, M, S, R>
270+
where
271+
'b: 'a,
272+
{
273+
ReferencedStorage::from_intermediate(self, policy_args)
231274
}
232275
}
233276

234277
/// Contains any values that need to reference [`Storage`]
235278
///
236279
/// To simplify usage, we use interior mutability through a ref cell to avoid having to declare the state
237280
/// completely separately.
238-
pub struct ReferencedStorage<'a, const N: usize, M: RawMutex, S: event::Sender<policy::RequestData>> {
239-
storage: &'a Storage<N, M>,
281+
pub struct ReferencedStorage<
282+
'a,
283+
const N: usize,
284+
M: RawMutex,
285+
S: event::Sender<policy::RequestData>,
286+
R: event::Receiver<policy::RequestData>,
287+
> {
288+
intermediate: &'a IntermediateStorage<'a, N, M>,
240289
state: RefCell<InternalState<'a, N, S>>,
241290
pd_controller: embedded_services::type_c::controller::Device<'a>,
242-
power_proxy_devices: [Mutex<M, PowerProxyDevice<'a>>; N],
291+
power_devices: [embedded_services::power::policy::device::Device<'a, Mutex<M, PowerProxyDevice<'a>>, R>; N],
243292
}
244293

245-
impl<'a, const N: usize, M: RawMutex, S: event::Sender<policy::RequestData>> ReferencedStorage<'a, N, M, S> {
246-
/// Create a new referenced storage from the given storage and controller ID
247-
fn try_from_storage(storage: &'a Storage<N, M>, policy_senders: [S; N]) -> Option<Self> {
248-
let mut power_proxy_devices = heapless::Vec::<_, N>::new();
249-
let mut power_events = heapless::Vec::<_, N>::new();
250-
251-
for (power_proxy_channel, policy_sender) in storage.power_proxy_channels.iter().zip(policy_senders.into_iter())
252-
{
253-
power_proxy_devices.push(Mutex::new(power_proxy_channel.get_device()));
254-
power_events.push((policy_sender, power_proxy_channel.get_receiver()));
294+
impl<'a, const N: usize, M: RawMutex, S: event::Sender<policy::RequestData>, R: event::Receiver<policy::RequestData>>
295+
ReferencedStorage<'a, N, M, S, R>
296+
{
297+
/// Create a new referenced storage from the given intermediate storage
298+
fn from_intermediate(intermediate: &'a IntermediateStorage<'a, N, M>, policy_args: [(DeviceId, S, R); N]) -> Self {
299+
let mut power_senders = heapless::Vec::<_, N>::new();
300+
let mut power_devices = heapless::Vec::<_, N>::new();
301+
302+
for (i, (device_id, policy_sender, policy_receiver)) in policy_args.into_iter().enumerate() {
303+
power_senders
304+
.push(policy_sender)
305+
.unwrap_or_else(|_| panic!("Failed to insert policy sender"));
306+
power_devices
307+
.push(embedded_services::power::policy::device::Device::new(
308+
device_id,
309+
&intermediate.power_proxy_devices[i],
310+
policy_receiver,
311+
))
312+
.unwrap_or_else(|_| panic!("Failed to insert power device"));
255313
}
256314

257-
Some(Self {
258-
storage,
315+
Self {
316+
intermediate,
259317
state: RefCell::new(InternalState::new(
260-
storage,
318+
intermediate.storage,
261319
// Safe because both have N elements
262-
power_events
320+
power_senders
263321
.into_array()
264322
.unwrap_or_else(|_| panic!("Failed to create power events")),
265323
)),
266324
pd_controller: embedded_services::type_c::controller::Device::new(
267-
storage.controller_id,
268-
storage.pd_ports.as_slice(),
325+
intermediate.storage.controller_id,
326+
intermediate.storage.pd_ports.as_slice(),
269327
),
270-
// Safe because both have N elements
271-
power_proxy_devices: power_proxy_devices
328+
power_devices: power_devices
272329
.into_array()
273330
.unwrap_or_else(|_| panic!("Failed to create power devices")),
274331
})
@@ -282,10 +339,11 @@ impl<'a, const N: usize, M: RawMutex, S: event::Sender<policy::RequestData>> Ref
282339
self.state.try_borrow_mut().ok().map(|state| Backing::<M, S, R> {
283340
registration: Registration {
284341
pd_controller: &self.pd_controller,
285-
cfu_device: &self.storage.cfu_device,
342+
cfu_device: &self.intermediate.storage.cfu_device,
286343
power_devices: &self.power_devices,
287344
},
288345
state,
346+
power_receivers: &self.intermediate.power_proxy_receivers,
289347
})
290348
}
291349
}
@@ -294,4 +352,5 @@ impl<'a, const N: usize, M: RawMutex, S: event::Sender<policy::RequestData>> Ref
294352
pub struct Backing<'a, M: RawMutex, S: event::Sender<policy::RequestData>, R: event::Receiver<policy::RequestData>> {
295353
pub(crate) registration: Registration<'a, M, R>,
296354
pub(crate) state: RefMut<'a, dyn DynPortState<'a, S>>,
355+
pub(crate) power_receivers: &'a [Mutex<M, PowerProxyReceiver<'a>>],
297356
}

type-c-service/src/wrapper/message.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,11 @@ pub struct EventPortNotification {
3131
}
3232

3333
/// Power policy command event data
34-
pub struct EventPowerPolicyCommand<'a> {
34+
pub struct EventPowerPolicyCommand {
3535
/// Port ID
3636
pub port: LocalPortId,
3737
/// Power policy request
38-
pub request:
39-
deferred::Request<'a, GlobalRawMutex, policy::device::CommandData, policy::device::InternalResponseData>,
38+
pub request: policy::device::CommandData,
4039
}
4140

4241
/// CFU events
@@ -58,7 +57,7 @@ pub enum Event<'a> {
5857
/// Port notification
5958
PortNotification(EventPortNotification),
6059
/// Power policy command received
61-
PowerPolicyCommand(EventPowerPolicyCommand<'a>),
60+
PowerPolicyCommand(EventPowerPolicyCommand),
6261
/// Command from TCPM
6362
ControllerCommand(deferred::Request<'a, GlobalRawMutex, controller::Command, controller::Response<'static>>),
6463
/// Cfu event
@@ -88,12 +87,9 @@ pub struct OutputPdAlert {
8887
}
8988

9089
/// Power policy command output data
91-
pub struct OutputPowerPolicyCommand<'a> {
90+
pub struct OutputPowerPolicyCommand {
9291
/// Port ID
9392
pub port: LocalPortId,
94-
/// Power policy request
95-
pub request:
96-
deferred::Request<'a, GlobalRawMutex, policy::device::CommandData, policy::device::InternalResponseData>,
9793
/// Response
9894
pub response: policy::device::InternalResponseData,
9995
}
@@ -158,7 +154,7 @@ pub enum Output<'a> {
158154
/// Vendor-defined messaging.
159155
Vdm(vdm::Output),
160156
/// Power policy command received
161-
PowerPolicyCommand(OutputPowerPolicyCommand<'a>),
157+
PowerPolicyCommand(OutputPowerPolicyCommand),
162158
/// TPCM command response
163159
ControllerCommand(OutputControllerCommand<'a>),
164160
/// CFU recovery tick

type-c-service/src/wrapper/mod.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,19 @@ use embassy_sync::mutex::Mutex;
2727
use embassy_sync::signal::Signal;
2828
use embassy_time::Instant;
2929
use embedded_cfu_protocol::protocol_definitions::{FwUpdateOffer, FwUpdateOfferResponse, FwVersion};
30+
use embedded_services::event;
3031
use embedded_services::power::policy::device::StateKind;
3132
use embedded_services::power::policy::policy;
3233
use embedded_services::sync::Lockable;
3334
use embedded_services::type_c::controller::{self, Controller, PortStatus};
3435
use embedded_services::type_c::event::{PortEvent, PortNotificationSingle, PortPending, PortStatusChanged};
35-
use embedded_services::{GlobalRawMutex, event};
3636
use embedded_services::{debug, error, info, trace, warn};
3737
use embedded_usb_pd::ado::Ado;
3838
use embedded_usb_pd::{Error, LocalPortId, PdError};
3939

4040
use crate::wrapper::backing::{DynPortState, PortPower};
4141
use crate::wrapper::message::*;
42+
use crate::wrapper::proxy::PowerProxyReceiver;
4243
use crate::{PortEventStreamer, PortEventVariant};
4344

4445
pub mod backing;
@@ -92,6 +93,8 @@ pub struct ControllerWrapper<
9293
sw_status_event: Signal<M, ()>,
9394
/// General config
9495
config: config::Config,
96+
/// Power proxy receivers
97+
power_proxy_receivers: &'device [Mutex<M, PowerProxyReceiver<'device>>],
9598
}
9699

97100
impl<
@@ -127,6 +130,7 @@ where
127130
registration: backing.registration,
128131
state: Mutex::new(backing.state),
129132
sw_status_event: Signal::new(),
133+
power_proxy_receivers: backing.power_receivers,
130134
})
131135
}
132136

@@ -504,13 +508,9 @@ where
504508
}
505509
Event::PowerPolicyCommand(EventPowerPolicyCommand { port, request }) => {
506510
let response = self
507-
.process_power_command(&mut controller, state.deref_mut().deref_mut(), port, &request.command)
511+
.process_power_command(&mut controller, state.deref_mut().deref_mut(), port, &request)
508512
.await;
509-
Ok(Output::PowerPolicyCommand(OutputPowerPolicyCommand {
510-
port,
511-
request,
512-
response,
513-
}))
513+
Ok(Output::PowerPolicyCommand(OutputPowerPolicyCommand { port, response }))
514514
}
515515
Event::ControllerCommand(request) => {
516516
let response = self
@@ -553,9 +553,18 @@ where
553553
Output::PdAlert(OutputPdAlert { port, ado }) => {
554554
self.finalize_pd_alert(state.deref_mut().deref_mut(), port, ado)
555555
}
556-
Output::Vdm(vdm) => self.finalize_vdm(state.deref_mut().deref_mut(), vdm).map_err(Error::Pd),
557-
Output::PowerPolicyCommand(OutputPowerPolicyCommand { request, response, .. }) => {
558-
request.respond(response);
556+
Output::Vdm(vdm) => self
557+
.finalize_vdm(state.deref_mut().deref_mut(), vdm)
558+
.await
559+
.map_err(Error::Pd),
560+
Output::PowerPolicyCommand(OutputPowerPolicyCommand { port, response }) => {
561+
self.power_proxy_receivers
562+
.get(port.0 as usize)
563+
.ok_or(Error::Pd(PdError::InvalidPort))?
564+
.lock()
565+
.await
566+
.send(response)
567+
.await;
559568
Ok(())
560569
}
561570
Output::ControllerCommand(OutputControllerCommand { request, response }) => {

0 commit comments

Comments
 (0)