use crate::Pipe;
const FLAG_BATTERY_CHARGING_ENABLE: u16 = 0b0000_0001;
const FLAG_NOTIFICATION_ENABLE_PIPE0: u16 = 0b0000_0100;
const FLAG_UNDERRUN_DISABLE_PIPE0: u16 = 0b0100_0000;
const FLAG_UNDERRUN_DISABLE: u16 = 0b0000_0010;
const FLAG_ALL_ENABLED: u16 = 0xFFFF;
const FLAG_CHARGING_MODE_DCP: u8 = 0xC0;
const FLAG_CHARGING_MODE_CDP: u8 = 0x30;
const FLAG_CHARGING_MODE_SDP: u8 = 0x0C;
const OFFSET_CHARGING_MODE_DCP: usize = 6;
const OFFSET_CHARGING_MODE_CDP: usize = 4;
const OFFSET_CHARGING_MODE_SDP: usize = 2;
pub struct OptionalFeatures {
flags: u16,
battery_charging: Option<BatteryChargingModes>,
}
impl OptionalFeatures {
pub(crate) fn new(flags: u16, battery_flags: u8) -> Self {
Self {
flags,
battery_charging: match flags & FLAG_BATTERY_CHARGING_ENABLE {
0 => None,
_ => Some(BatteryChargingModes(battery_flags)),
},
}
}
#[must_use]
pub fn all_disabled(&self) -> bool {
self.flags == 0
}
#[must_use]
pub fn all_enabled(&self) -> bool {
self.flags == FLAG_ALL_ENABLED
}
#[must_use]
pub fn battery_charging(&self) -> Option<&BatteryChargingModes> {
self.battery_charging.as_ref()
}
#[must_use]
pub fn notification_message_enabled(&self, in_pipe: Pipe) -> bool {
assert!(in_pipe.is_in());
self.flags & (FLAG_NOTIFICATION_ENABLE_PIPE0 << in_pipe as u16) != 0
}
#[must_use]
pub fn underrun_check_enabled(&self) -> bool {
self.flags & FLAG_UNDERRUN_DISABLE == 0
}
#[must_use]
pub fn underrun_disabled(&self, in_pipe: Pipe) -> bool {
assert!(in_pipe.is_in());
self.flags & (FLAG_UNDERRUN_DISABLE_PIPE0 << in_pipe as u16) != 0
}
}
pub struct BatteryChargingModes(u8);
impl BatteryChargingModes {
#[must_use]
pub fn dcp(&self) -> u8 {
(self.0 & FLAG_CHARGING_MODE_DCP) >> OFFSET_CHARGING_MODE_DCP
}
#[must_use]
pub fn cdp(&self) -> u8 {
(self.0 & FLAG_CHARGING_MODE_CDP) >> OFFSET_CHARGING_MODE_CDP
}
#[must_use]
pub fn sdp(&self) -> u8 {
(self.0 & FLAG_CHARGING_MODE_SDP) >> OFFSET_CHARGING_MODE_SDP
}
}