1use crate::bindings;
17use crate::error::{Error, Result};
18
19#[repr(u32)]
23#[derive(Debug, Copy, Clone, PartialEq, Eq)]
24pub enum State {
25 Active = 0,
27 Idle = 1,
29 Standby = 2,
31 DeepSleep = 3,
33}
34
35#[repr(u32)]
37#[derive(Debug, Copy, Clone, PartialEq, Eq)]
38pub enum WakeType {
39 Gpio = 0,
41 Timer = 1,
43 Uart = 2,
45 Rtc = 3,
47}
48
49#[repr(u32)]
51#[derive(Debug, Copy, Clone, PartialEq, Eq)]
52pub enum Domain {
53 Radio = 0,
54 Sensor = 1,
55 Display = 2,
56 Audio = 3,
57 Storage = 4,
58 Comms = 5,
59 User0 = 6,
60 User1 = 7,
61}
62
63#[repr(u32)]
65#[derive(Debug, Copy, Clone, PartialEq, Eq)]
66pub enum Event {
67 PreSleep = 0,
69 PostWake = 1,
71}
72
73#[derive(Debug, Copy, Clone)]
77pub struct Cfg {
78 pub idle_threshold_ms: u32,
80 pub standby_threshold_ms: u32,
82 pub deep_sleep_threshold_ms: u32,
84}
85
86#[derive(Debug, Copy, Clone)]
88pub struct Stats {
89 pub time_in_state_us: [u64; 4],
91 pub transition_count: [u32; 4],
93 pub total_runtime_us: u64,
95 pub active_pct_x100: u32,
97}
98
99pub fn init(cfg: &Cfg) -> Result<()> {
106 let c_cfg = bindings::ove_pm_cfg {
107 idle_threshold_ms: cfg.idle_threshold_ms,
108 standby_threshold_ms: cfg.standby_threshold_ms,
109 deep_sleep_threshold_ms: cfg.deep_sleep_threshold_ms,
110 };
111 let rc = unsafe { bindings::ove_pm_init(&c_cfg) };
112 Error::from_code(rc)
113}
114
115pub fn deinit() {
117 unsafe { bindings::ove_pm_deinit() }
118}
119
120pub fn set_state(state: State) -> Result<()> {
127 let rc = unsafe { bindings::ove_pm_set_state(state as bindings::ove_pm_state_t) };
128 Error::from_code(rc)
129}
130
131pub fn get_state() -> State {
133 let raw = unsafe { bindings::ove_pm_get_state() };
134 match raw {
135 0 => State::Active,
136 1 => State::Idle,
137 2 => State::Standby,
138 3 => State::DeepSleep,
139 _ => State::Active,
140 }
141}
142
143pub fn activity() {
145 unsafe { bindings::ove_pm_activity() }
146}
147
148pub fn wake_register_gpio(port: u32, pin: u32, edge: u32) -> Result<()> {
155 let mut src: bindings::ove_pm_wake_src = unsafe { core::mem::zeroed() };
156 src.type_ = WakeType::Gpio as bindings::ove_pm_wake_type_t;
157 unsafe {
158 src.__bindgen_anon_1.gpio.port = port;
159 src.__bindgen_anon_1.gpio.pin = pin;
160 src.__bindgen_anon_1.gpio.edge = edge as bindings::ove_gpio_irq_mode_t;
161 }
162 let rc = unsafe { bindings::ove_pm_wake_register(&src) };
163 Error::from_code(rc)
164}
165
166pub fn wake_register_timer(timeout_ms: u32) -> Result<()> {
171 let mut src: bindings::ove_pm_wake_src = unsafe { core::mem::zeroed() };
172 src.type_ = WakeType::Timer as bindings::ove_pm_wake_type_t;
173 unsafe { src.__bindgen_anon_1.timer.timeout_ms = timeout_ms };
174 let rc = unsafe { bindings::ove_pm_wake_register(&src) };
175 Error::from_code(rc)
176}
177
178pub fn wake_register_uart(instance: u32) -> Result<()> {
183 let mut src: bindings::ove_pm_wake_src = unsafe { core::mem::zeroed() };
184 src.type_ = WakeType::Uart as bindings::ove_pm_wake_type_t;
185 unsafe { src.__bindgen_anon_1.uart.instance = instance };
186 let rc = unsafe { bindings::ove_pm_wake_register(&src) };
187 Error::from_code(rc)
188}
189
190pub fn wake_unregister_gpio(port: u32, pin: u32) -> Result<()> {
195 let mut src: bindings::ove_pm_wake_src = unsafe { core::mem::zeroed() };
196 src.type_ = WakeType::Gpio as bindings::ove_pm_wake_type_t;
197 unsafe {
198 src.__bindgen_anon_1.gpio.port = port;
199 src.__bindgen_anon_1.gpio.pin = pin;
200 }
201 let rc = unsafe { bindings::ove_pm_wake_unregister(&src) };
202 Error::from_code(rc)
203}
204
205pub fn domain_request(domain: Domain) -> Result<()> {
214 let rc = unsafe { bindings::ove_pm_domain_request(domain as bindings::ove_pm_domain_t) };
215 Error::from_code(rc)
216}
217
218pub fn domain_release(domain: Domain) -> Result<()> {
225 let rc = unsafe { bindings::ove_pm_domain_release(domain as bindings::ove_pm_domain_t) };
226 Error::from_code(rc)
227}
228
229pub fn domain_get_refcount(domain: Domain) -> Result<i32> {
234 let rc = unsafe { bindings::ove_pm_domain_get_refcount(domain as bindings::ove_pm_domain_t) };
235 if rc < 0 {
236 Error::from_code(rc)?;
237 }
238 Ok(rc)
239}
240
241pub unsafe fn set_policy(
249 policy: bindings::ove_pm_policy_fn,
250 user_data: *mut core::ffi::c_void,
251) -> Result<()> {
252 let rc = unsafe { bindings::ove_pm_set_policy(policy, user_data) };
253 Error::from_code(rc)
254}
255
256pub unsafe fn notify_register(
266 cb: bindings::ove_pm_notify_fn,
267 user_data: *mut core::ffi::c_void,
268) -> Result<()> {
269 let rc = unsafe { bindings::ove_pm_notify_register(cb, user_data) };
270 Error::from_code(rc)
271}
272
273pub unsafe fn notify_unregister(
281 cb: bindings::ove_pm_notify_fn,
282 user_data: *mut core::ffi::c_void,
283) -> Result<()> {
284 let rc = unsafe { bindings::ove_pm_notify_unregister(cb, user_data) };
285 Error::from_code(rc)
286}
287
288pub fn get_stats() -> Result<Stats> {
295 let mut raw: bindings::ove_pm_stats = unsafe { core::mem::zeroed() };
296 let rc = unsafe { bindings::ove_pm_get_stats(&mut raw) };
297 Error::from_code(rc)?;
298 Ok(Stats {
299 time_in_state_us: raw.time_in_state_us,
300 transition_count: raw.transition_count,
301 total_runtime_us: raw.total_runtime_us,
302 active_pct_x100: raw.active_pct_x100,
303 })
304}
305
306pub fn reset_stats() {
308 unsafe { bindings::ove_pm_reset_stats() }
309}
310
311pub fn set_budget(target_low_power_pct_x100: u32) -> Result<()> {
318 let rc = unsafe { bindings::ove_pm_set_budget(target_low_power_pct_x100) };
319 Error::from_code(rc)
320}
321
322pub fn get_budget_status() -> Result<u32> {
329 let mut actual: u32 = 0;
330 let rc = unsafe { bindings::ove_pm_get_budget_status(&mut actual) };
331 Error::from_code(rc)?;
332 Ok(actual)
333}