Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,24 @@
pub mod asynchronous;
pub mod pdo;
pub mod type_c;
pub mod ucsi;

/// Port ID new type
/// Port ID new type.
///
/// This differs from [`GlobalPortId`] in that it refers to a port on a specific controller. If
/// there are multiple controllers, the same port ID may be used on different controllers.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct PortId(pub u8);

/// Global port ID, used to unique identify a port
///
/// This differs from [`PortId`] in that it is not limited to the number of ports on a single
/// controller. If there are multiple controllers, each port should have a unique global port ID.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct GlobalPortId(pub u8);

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
/// General PD-related errors
Expand Down
33 changes: 33 additions & 0 deletions src/ucsi/lpm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use crate::{GlobalPortId, PdError};

/// Connector reset types
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum ResetType {
Hard,
Data,
}

/// LPM command data
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum CommandData {
ConnectorReset(ResetType),
}

/// LPM commands
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Command {
pub port: GlobalPortId,
pub operation: CommandData,
}

/// LPM response data
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum ResponseData {
Complete,
}

pub type Response = Result<ResponseData, PdError>;
83 changes: 83 additions & 0 deletions src/ucsi/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//! Ucsi types, see spec at https://www.usb.org/document-library/usb-type-cr-connector-system-software-interface-ucsi-specification
#![allow(missing_docs)]

use bitfield::bitfield;

pub mod lpm;
pub mod ppm;

/// Ucsi opcodes, see spec for more detail
#[repr(u8)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum UsciOpcode {
PpmReset = 0x01,
Cancel,
ConnectorReset,
AckCcCi,
SetNotificationEnable,
GetCapability,
GetConnectorCapability,
SetCcom,
SetUor,
SetPdm,
SetPdr,
GetAlternateModes,
GetCamSupported,
GetCurrentCam,
SetNewCam,
GetPdos,
GetCableProperty,
GetConnectorStatus,
GetErrorStatus,
SetPowerLevel,
GetPdMessage,
GetAttentionVdo,
GetCamCs = 0x18,
LpmFwUpdateRequest,
SecurityRequest,
SetRetimerMode,
SetSinkPath,
SetPdos,
ReadPowerLevel,
ChunkingSupport,
SetUsb = 0x21,
GetLpmPpmInfo,
}

bitfield! {
/// Command status and connect change indicator, see spec for more details
#[derive(Copy, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Cci(u32);
impl Debug;
pub eom, set_eom: 0, 0;
pub port, set_port: 1, 7;
pub data_len, set_data_len: 8, 15;
pub vdm, set_vdm: 16, 16;
pub reserved, _: 17, 22;
pub security_req, set_security_req: 23, 23;
pub fw_update_req, set_fw_update_req: 24, 24;
pub not_supported, set_not_supported: 25, 25;
pub cancel_complete, set_cancel_complete: 26, 26;
pub reset_complete, set_reset_complete: 27, 27;
pub busy, set_busy: 28, 28;
pub ack_command, set_ack_command: 29, 29;
pub error, set_error: 30, 30;
pub cmd_complete, set_cmd_complete: 31, 31;
}

/// UCSI commands
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Command {
PpmCommand(ppm::Command),
LpmCommand(lpm::Command),
}

/// UCSI command responses
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Response {
PpmResponse(ppm::Response),
LpmResponse(lpm::Response),
}
47 changes: 47 additions & 0 deletions src/ucsi/ppm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use bitfield::bitfield;

use crate::PdError;

bitfield! {
/// PPM notifications that can be enabled, see spec for more details
#[derive(Copy, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct SetNotificationEnableData(u32);
impl Debug;
pub cmd_complete, set_cmd_complete: 0, 0;
pub external_supply_change, set_external_supply_change: 1, 1;
pub power_op_mode_change, set_power_op_mode_change: 2, 2;
pub attention, set_attention: 3, 3;
pub fw_update_req, set_fw_update_req: 4, 4;
pub provider_caps_change, set_provider_caps_change: 5, 5;
pub power_lvl_change, set_power_lvl_change: 6, 6;
pub pd_reset_complete, set_pd_reset_complete: 7, 7;
pub cam_change, set_cam_change: 8, 8;
pub battery_charge_change, set_battery_charge_change: 9, 9;
pub security_req, set_security_req: 10, 10;
pub connector_partner_change, set_connector_partner_change: 11, 11;
pub power_dir_change, set_power_dir_change: 12, 12;
pub set_retimer_mode, set_set_retimer_mode: 13, 13;
pub connect_change, set_connect_change: 14, 14;
pub error, set_error: 15, 15;
pub sink_path_change, set_sink_path_change: 16, 16;
}

/// Commands that only affect the PPM level and don't need to be sent to an LPM
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Command {
Reset,
Cancel,
AckCcCi,
SetNotificationEnable(SetNotificationEnableData),
}

/// PPM command response data
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum ResponseData {
Complete,
}

pub type Response = Result<ResponseData, PdError>;