luwen_api/chip/init/
mod.rs1use std::convert::Infallible;
5
6use crate::{error::PlatformError, ChipImpl};
7
8use status::InitStatus;
9
10pub mod status;
11
12pub enum CallReason<'a> {
13 NewChip,
14 NotNew,
15 InitWait(&'a InitStatus),
16 ChipInitCompleted(&'a InitStatus),
17}
18
19#[allow(dead_code)]
20pub struct ChipDetectState<'a> {
21 pub chip: &'a dyn ChipImpl,
22 pub call: CallReason<'a>,
23}
24
25#[derive(thiserror::Error)]
26pub enum InitError<E> {
27 #[error(transparent)]
28 PlatformError(#[from] PlatformError),
29
30 CallbackError(E),
31}
32
33impl From<InitError<Infallible>> for PlatformError {
34 fn from(val: InitError<Infallible>) -> Self {
35 match val {
36 InitError::PlatformError(err) => err,
37 InitError::CallbackError(_) => unreachable!(),
38 }
39 }
40}
41
42pub fn wait_for_init<E>(
53 chip: &mut impl ChipImpl,
54 callback: &mut impl FnMut(ChipDetectState) -> Result<(), E>,
55 allow_failure: bool,
56 noc_safe: bool,
57) -> Result<InitStatus, InitError<E>> {
58 callback(ChipDetectState {
60 chip,
61 call: CallReason::NewChip,
62 })
63 .map_err(|v| InitError::CallbackError(v))?;
64
65 let mut status = InitStatus::new_unknown();
66 status.init_options.noc_safe = noc_safe;
67 loop {
68 match chip.update_init_state(&mut status)? {
69 super::ChipInitResult::NoError => {
70 }
72 super::ChipInitResult::ErrorContinue(error, bt_tracker) => {
73 if !allow_failure {
76 Err(PlatformError::Generic(
77 format!("Chip initialization failed: {error} \n{status}"),
78 crate::error::BtWrapper(bt_tracker),
79 ))?;
80 } else {
81 callback(ChipDetectState {
82 chip,
83 call: CallReason::ChipInitCompleted(&status),
84 })
85 .map_err(InitError::CallbackError)?;
86 return Ok(status);
87 }
88 }
89 super::ChipInitResult::ErrorAbort(error, bt_tracker) => {
90 Err(PlatformError::Generic(
91 format!("Chip initialization failed (aborted): {error} \n{status}"),
92 crate::error::BtWrapper(bt_tracker),
93 ))?;
94 }
95 }
96
97 let call = if !status.init_complete() {
98 CallReason::InitWait(&status)
99 } else {
100 callback(ChipDetectState {
103 chip,
104 call: CallReason::ChipInitCompleted(&status),
105 })
106 .map_err(InitError::CallbackError)?;
107 if status.has_error() {
108 Err(PlatformError::Generic(
109 format!("Chip initialization failed:\n{status} "),
110 crate::error::BtWrapper::capture(),
111 ))?;
112 }
113
114 return Ok(status);
115 };
116
117 callback(ChipDetectState { chip, call }).map_err(InitError::CallbackError)?;
118 }
119}