embedded_ccs811/
boot_mode.rs1use crate::hal::{
2 blocking::delay::{DelayMs, DelayUs},
3 digital::v2::OutputPin,
4};
5use crate::{
6 hal, mode, ActionInProgress, BitFlags, Ccs811, Ccs811Awake, Ccs811BootMode, Ccs811Device,
7 Error, ErrorAwake, ModeChangeError, Register,
8};
9
10impl<I2C, E> Ccs811BootMode for Ccs811Awake<I2C, mode::Boot>
11where
12 I2C: hal::blocking::i2c::Write<Error = E> + hal::blocking::i2c::WriteRead<Error = E>,
13{
14 type Error = ErrorAwake<E>;
15 type ModeChangeError = ModeChangeError<Self::Error, Self>;
16 type TargetType = Ccs811Awake<I2C, mode::App>;
17
18 fn start_application(mut self) -> Result<Self::TargetType, Self::ModeChangeError> {
19 match self.has_valid_app() {
20 Err(e) => Err(ModeChangeError::new(self, e)),
21 Ok(is_valid) => {
22 if !is_valid {
23 Err(ModeChangeError::new(self, ErrorAwake::NoValidApp))
24 } else {
25 match self.write_register_no_data(Register::APP_START) {
26 Err(e) => Err(ModeChangeError::new(self, e)),
27 Ok(_) => Ok(Ccs811Awake::create(self.i2c, self.address)),
28 }
29 }
30 }
31 }
32 }
33
34 fn verify_application(&mut self) -> nb::Result<(), Self::Error> {
35 let status = self.read_status().map_err(nb::Error::Other)?;
36 let verified = (status & BitFlags::APP_VERIFY) != 0;
37 if !verified {
38 if self.in_progress == ActionInProgress::Verification {
39 Err(nb::Error::WouldBlock)
40 } else {
41 let result = self
42 .i2c
43 .write(self.address, &[Register::APP_VERIFY])
44 .map_err(ErrorAwake::I2C);
45 match result {
46 Ok(_) => {
47 self.in_progress = ActionInProgress::Verification;
48 Err(nb::Error::WouldBlock)
49 }
50 Err(e) => Err(nb::Error::Other(e)),
51 }
52 }
53 } else {
54 self.in_progress = ActionInProgress::None;
55 Ok(())
56 }
57 }
58
59 fn erase_application(&mut self) -> nb::Result<(), Self::Error> {
60 let status = self.read_status().map_err(nb::Error::Other)?;
61 let erased = (status & BitFlags::APP_ERASE) != 0;
62 if !erased {
63 if self.in_progress == ActionInProgress::Erase {
64 Err(nb::Error::WouldBlock)
65 } else {
66 let result = self
67 .i2c
68 .write(self.address, &[Register::APP_ERASE, 0xE7, 0xA7, 0xE6, 0x09])
69 .map_err(ErrorAwake::I2C);
70 match result {
71 Ok(_) => {
72 self.in_progress = ActionInProgress::Erase;
73 Err(nb::Error::WouldBlock)
74 }
75 Err(e) => Err(nb::Error::Other(e)),
76 }
77 }
78 } else {
79 self.in_progress = ActionInProgress::None;
80 Ok(())
81 }
82 }
83
84 fn download_application<D: DelayMs<u16>>(
85 &mut self,
86 bin: &[u8],
87 delay: &mut D,
88 ) -> Result<(), Self::Error> {
89 if bin.len() % 8 != 0 {
90 return Err(ErrorAwake::InvalidInputData);
91 }
92 let mut data = [0; 9];
93 data[0] = Register::REG_BOOT_APP;
94 for chunk in bin.chunks(8) {
95 data[1..].copy_from_slice(chunk);
96 self.i2c
97 .write(self.address, &data)
98 .map_err(ErrorAwake::I2C)?;
99 delay.delay_ms(50);
100 }
101 self.check_status_error()
102 }
103
104 fn update_application<D: DelayMs<u16>>(
105 &mut self,
106 bin: &[u8],
107 delay: &mut D,
108 ) -> Result<(), Self::Error> {
109 self.write_sw_reset()?;
110 delay.delay_ms(20);
111 loop {
112 match self.erase_application() {
113 Err(nb::Error::WouldBlock) => delay.delay_ms(500),
114 Err(nb::Error::Other(e)) => return Err(e),
115 Ok(_) => break,
116 }
117 }
118 self.download_application(bin, delay)?;
119 loop {
120 match self.verify_application() {
121 Err(nb::Error::WouldBlock) => delay.delay_ms(70),
122 Err(nb::Error::Other(e)) => return Err(e),
123 Ok(_) => break,
124 }
125 }
126 Ok(())
127 }
128
129 fn software_reset(&mut self) -> Result<(), Self::Error> {
131 self.write_sw_reset()
132 }
133}
134
135impl<I2C, CommE, PinE, NWAKE, WAKEDELAY> Ccs811BootMode
136 for Ccs811<I2C, NWAKE, WAKEDELAY, mode::Boot>
137where
138 I2C: hal::blocking::i2c::Write<Error = CommE> + hal::blocking::i2c::WriteRead<Error = CommE>,
139 NWAKE: OutputPin<Error = PinE>,
140 WAKEDELAY: DelayUs<u8>,
141{
142 type Error = Error<CommE, PinE>;
143 type ModeChangeError = ModeChangeError<Self::Error, Self>;
144 type TargetType = Ccs811<I2C, NWAKE, WAKEDELAY, mode::App>;
145
146 fn start_application(self) -> Result<Self::TargetType, Self::ModeChangeError> {
147 self.wrap_mode_change(|s| s.start_application())
148 }
149
150 fn verify_application(&mut self) -> nb::Result<(), Self::Error> {
151 self.on_awaken_nb(|s| s.dev.verify_application())
152 }
153
154 fn erase_application(&mut self) -> nb::Result<(), Self::Error> {
155 self.on_awaken_nb(|s| s.dev.erase_application())
156 }
157
158 fn download_application<D: DelayMs<u16>>(
159 &mut self,
160 bin: &[u8],
161 delay: &mut D,
162 ) -> Result<(), Self::Error> {
163 self.on_awaken(|s| s.dev.download_application(bin, delay))
164 }
165
166 fn update_application<D: DelayMs<u16>>(
167 &mut self,
168 bin: &[u8],
169 delay: &mut D,
170 ) -> Result<(), Self::Error> {
171 self.on_awaken(|s| s.dev.update_application(bin, delay))
172 }
173
174 fn software_reset(&mut self) -> Result<(), Self::Error> {
175 self.on_awaken(|s| s.dev.software_reset())
176 }
177}