1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
use super::{
response::{self, IntRadix},
Command,
GencmdCmdError
};
pub struct CmdCommands;
impl<'a> Command<'a> for CmdCommands {
type Response = Vec<&'a str>;
const COMMAND_STR: &'static str = "commands";
fn parse_response(response: &'a str) -> Result<Self::Response, GencmdCmdError> {
let (_, commands) = response::parse_field_simple::<&str>(response, "commands")
.map_err(GencmdCmdError::from_invalid_format)?;
Ok(commands.split(", ").collect())
}
}
pub struct CmdMeasureTemp;
impl<'a> Command<'a> for CmdMeasureTemp {
type Response = f32;
const COMMAND_STR: &'static str = "measure_temp";
fn parse_response(response: &'a str) -> Result<Self::Response, GencmdCmdError> {
let (_, temperature) = response::parse_field::<f32>(response, "temp", None, Some("'C"))
.map_err(GencmdCmdError::from_invalid_format)?;
Ok(temperature)
}
}
pub struct CmdMeasureClockArm;
impl<'a> Command<'a> for CmdMeasureClockArm {
type Response = u64;
const COMMAND_STR: &'static str = "measure_clock arm";
fn parse_response(response: &'a str) -> Result<Self::Response, GencmdCmdError> {
let (_, frequency) = response::parse_field_simple::<u64>(response, "frequency(48)")
.map_err(GencmdCmdError::from_invalid_format)?;
Ok(frequency)
}
}
#[derive(Default, Debug, Clone, Copy)]
pub struct ThrottleStatus {
pub under_voltage: bool,
pub frequency_capped: bool,
pub throttled: bool,
pub soft_temperature_limit: bool
}
#[rustfmt::skip]
impl ThrottleStatus {
pub const BIT_UNDER_VOLTAGE: u32 = 1;
pub const BIT_FREQUENCT_CAPPED: u32 = 2;
pub const BIT_THROTTLED: u32 = 4;
pub const BIT_SOFT_TEMPERATURE_LIMIT: u32 = 8;
pub const SHIFT_OCCURED: usize = 16;
}
impl ThrottleStatus {
pub fn from_current(value: u32) -> Self {
ThrottleStatus {
under_voltage: value & Self::BIT_UNDER_VOLTAGE != 0,
frequency_capped: value & Self::BIT_FREQUENCT_CAPPED != 0,
throttled: value & Self::BIT_THROTTLED != 0,
soft_temperature_limit: value & Self::BIT_SOFT_TEMPERATURE_LIMIT != 0
}
}
pub fn from_occured(value: u32) -> Self {
Self::from_current(value >> Self::SHIFT_OCCURED)
}
pub fn to_current(self) -> u32 {
(self.under_voltage as u32) * Self::BIT_UNDER_VOLTAGE
| (self.frequency_capped as u32) * Self::BIT_FREQUENCT_CAPPED
| (self.throttled as u32) * Self::BIT_THROTTLED
| (self.soft_temperature_limit as u32) * Self::BIT_SOFT_TEMPERATURE_LIMIT
}
pub fn to_occured(self) -> u32 {
self.to_current() << Self::SHIFT_OCCURED
}
}
#[derive(Debug, Default)]
pub struct CpuThrottled {
pub current: ThrottleStatus,
pub occured: ThrottleStatus
}
impl From<u32> for CpuThrottled {
fn from(value: u32) -> Self {
CpuThrottled {
current: ThrottleStatus::from_current(value),
occured: ThrottleStatus::from_occured(value)
}
}
}
impl From<CpuThrottled> for u32 {
fn from(value: CpuThrottled) -> Self {
value.current.to_current() | value.occured.to_occured()
}
}
pub struct CmdGetThrottled;
impl<'a> Command<'a> for CmdGetThrottled {
type Response = CpuThrottled;
const COMMAND_STR: &'static str = "get_throttled";
fn parse_response(response: &'a str) -> Result<Self::Response, GencmdCmdError> {
let (_, throttled) =
response::parse_field::<IntRadix<u32, 16>>(response, "throttled", Some("0x"), None)
.map_err(GencmdCmdError::from_invalid_format)?;
Ok(CpuThrottled::from(throttled.0))
}
}