Skip to content

Commit f46b047

Browse files
committed
control word refactor
1 parent 94f84f4 commit f46b047

File tree

2 files changed

+77
-56
lines changed

2 files changed

+77
-56
lines changed

src/control.rs src/control_word.rs

+39-24
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,27 @@ pub const DEVICE_CHARS: usize = 4;
66
pub struct ControlWord0(u8);
77

88
impl ControlWord0 {
9+
pub const WORD_SELECT_BIT: u8 = 0b1000_0000; // MSB is 1 for control word 1
910
pub const WAKE_BIT: u8 = 0b0100_0000;
1011
pub const PEAK_CURRENT_MASK: u8 = 0b0011_0000;
1112
pub const BRIGHTNESS_MASK: u8 = 0b0000_1111;
13+
pub const BRIGHTNESS_DEFAULT: u8 = 0b0000_1100;
1214

1315
pub fn new() -> Self {
14-
ControlWord0(0b0000_0000) // MSB is always 0
16+
let mut word = ControlWord0(Self::WORD_SELECT_BIT); // MSB is always 0
17+
word.set_brightness_bits(Self::BRIGHTNESS_DEFAULT);
18+
word.set_peak_current_bits(PeakCurrent::default());
19+
word.set_wake_bit(SleepMode::default());
20+
word
1521
}
1622

17-
pub fn set_brightness_bits(&mut self, bits: u8) {
23+
pub fn set_brightness_bits(&mut self, brightness: u8) {
1824
// just truncate the bits rather than enforce or check for a max value
19-
self.0 = (self.0 & !Self::BRIGHTNESS_MASK) | (bits & Self::BRIGHTNESS_MASK);
25+
self.0 = (self.0 & !Self::BRIGHTNESS_MASK) | (brightness & Self::BRIGHTNESS_MASK);
2026
}
2127

22-
pub fn set_peak_current_bits(&mut self, bits: PeakCurrent) {
23-
self.0 = (self.0 & !Self::PEAK_CURRENT_MASK) | bits as u8;
28+
pub fn set_peak_current_bits(&mut self, current: PeakCurrent) {
29+
self.0 = (self.0 & !Self::PEAK_CURRENT_MASK) | current as u8;
2430
}
2531

2632
pub fn set_wake_bit(&mut self, mode: SleepMode) {
@@ -37,6 +43,12 @@ pub enum SleepMode {
3743
Normal = 0b0100_0000,
3844
}
3945

46+
impl Default for SleepMode {
47+
fn default() -> Self {
48+
SleepMode::Normal
49+
}
50+
}
51+
4052
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4153
pub enum PeakCurrent {
4254
Max4_0Ma = 0b0010_0000,
@@ -45,35 +57,38 @@ pub enum PeakCurrent {
4557
Max12_8Ma = 0b0011_0000,
4658
}
4759

48-
impl PeakCurrent {
49-
pub fn bitmask(&self) -> u8 {
50-
*self as u8
60+
// impl PeakCurrent {
61+
// pub fn bitmask(&self) -> u8 {
62+
// *self as u8
63+
// }
64+
// }
65+
66+
impl Default for PeakCurrent {
67+
fn default() -> Self {
68+
PeakCurrent::Max12_8Ma
5169
}
5270
}
5371

5472
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5573
pub struct ControlWord1(u8);
5674

5775
impl ControlWord1 {
76+
pub const WORD_SELECT_BIT: u8 = 0b1000_0000; // MSB is 1 for control word 1
5877
pub const DATA_OUT_BIT: u8 = 0b0000_0001;
5978
pub const EXT_OSC_PRESCALER_BIT: u8 = 0b0000_0010;
6079

6180
pub fn new() -> Self {
62-
ControlWord1(0b1000_0000) // MSB is always 1
63-
}
64-
65-
pub fn data_out_mode(&self) -> DataOutModeBit {
66-
match self.0 & Self::DATA_OUT_BIT {
67-
0 => DataOutModeBit::Serial,
68-
_ => DataOutModeBit::Simultaneous,
69-
}
81+
let mut word = ControlWord1(Self::WORD_SELECT_BIT);
82+
word.set_data_out_mode_bit(DataOutMode::default());
83+
word.set_ext_osc_prescaler_bit(ExtOscPrescaler::default());
84+
word
7085
}
7186

72-
pub fn set_data_out_mode_bit(&mut self, bit: DataOutModeBit) {
87+
pub fn set_data_out_mode_bit(&mut self, bit: DataOutMode) {
7388
self.0 = (self.0 & !Self::DATA_OUT_BIT) | (bit as u8);
7489
}
7590

76-
pub fn set_ext_osc_prescaler_bit(&mut self, bit: ExtOscPrescalerBit) {
91+
pub fn set_ext_osc_prescaler_bit(&mut self, bit: ExtOscPrescaler) {
7792
self.0 = (self.0 & !Self::EXT_OSC_PRESCALER_BIT) | (bit as u8);
7893
}
7994

@@ -83,25 +98,25 @@ impl ControlWord1 {
8398
}
8499

85100
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
86-
pub enum DataOutModeBit {
101+
pub enum DataOutMode {
87102
Serial = 0b0000_0000,
88103
Simultaneous = 0b0000_0001,
89104
}
90105

91-
impl Default for DataOutModeBit {
106+
impl Default for DataOutMode {
92107
fn default() -> Self {
93-
DataOutModeBit::Serial
108+
DataOutMode::Serial
94109
}
95110
}
96111

97112
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
98-
pub enum ExtOscPrescalerBit {
113+
pub enum ExtOscPrescaler {
99114
Clock1 = 0b0000_0000,
100115
Clock8 = 0b0000_0001,
101116
}
102117

103-
impl Default for ExtOscPrescalerBit {
118+
impl Default for ExtOscPrescaler {
104119
fn default() -> Self {
105-
ExtOscPrescalerBit::Clock1
120+
ExtOscPrescaler::Clock1
106121
}
107122
}

src/lib.rs

+38-32
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
#![no_std]
22

3-
pub mod control;
3+
4+
mod control_word;
45
mod font5x7;
56

6-
use crate::control::*;
7+
pub use control_word::PeakCurrent;
8+
9+
use control_word::*;
710
use core::cell::RefCell;
811
use embedded_hal::digital::{ErrorType, OutputPin};
912

@@ -46,7 +49,8 @@ pub struct Hcms29xx<
4649
reset: Option<RefCell<ResetPin>>,
4750
control_word_0: ControlWord0,
4851
control_word_1: ControlWord1,
49-
data_out_mode: DataOutModeBit, // we keep track of just this to avoid more bookkeeping when updating local state of control word before updating
52+
// state kept locally to simplify/reduce overall code size
53+
data_out_mode: DataOutMode,
5054
font_ascii_start_index: u8,
5155
}
5256

@@ -125,29 +129,29 @@ where
125129
reset: reset_ref_cell,
126130
control_word_0: ControlWord0::new(),
127131
control_word_1: ControlWord1::new(),
128-
data_out_mode: DataOutModeBit::Serial,
132+
data_out_mode: DataOutMode::Serial,
129133
font_ascii_start_index: font5x7::FONT5X7.load_at(0) - 1,
130134
})
131135
}
132136

133-
pub fn begin(&mut self) -> Result<(), Hcms29xxError<PinErr>> {
134-
self.clear()?;
137+
// pub fn begin(&mut self) -> Result<(), Hcms29xxError<PinErr>> {
138+
// self.clear()?;
135139

136-
self.update_control_word(
137-
control::control_word_0::WAKE_BIT
138-
| control::control_word_0::DEFAULT_CURRENT
139-
| control::control_word_0::DEFAULT_BRIGHTNESS,
140-
)?;
141-
self.update_control_word(
142-
control::CONTROL_WORD_SELECT_BIT | control::control_word_1::DEFAULT_DATA_OUT_MODE,
143-
)?;
140+
// self.update_control_word(
141+
// control::control_word_0::WAKE_BIT
142+
// | control::control_word_0::DEFAULT_CURRENT
143+
// | control::control_word_0::DEFAULT_BRIGHTNESS,
144+
// )?;
145+
// self.update_control_word(
146+
// control::CONTROL_WORD_SELECT_BIT | control::control_word_1::DEFAULT_DATA_OUT_MODE,
147+
// )?;
144148

145-
Ok(())
146-
}
149+
// Ok(())
150+
// }
147151

148152
pub fn clear(&mut self) -> Result<(), Hcms29xxError<PinErr>> {
149153
self.set_dot_data()?;
150-
for _ in 0..NUM_CHARS * control::CHAR_WIDTH {
154+
for _ in 0..NUM_CHARS * control_word::CHAR_WIDTH {
151155
self.send_byte(0x00)?;
152156
}
153157
self.end_transfer()?;
@@ -161,8 +165,8 @@ where
161165
break;
162166
}
163167
let char_start_index: usize =
164-
(c_str[i] - self.font_ascii_start_index) as usize * control::CHAR_WIDTH;
165-
for j in 0..control::CHAR_WIDTH {
168+
(c_str[i] - self.font_ascii_start_index) as usize * control_word::CHAR_WIDTH;
169+
for j in 0..control_word::CHAR_WIDTH {
166170
self.send_byte(font5x7::FONT5X7.load_at(char_start_index + j))?;
167171
}
168172
}
@@ -292,24 +296,32 @@ where
292296
}
293297

294298
pub fn set_serial_data_out(&mut self) -> Result<(), Hcms29xxError<PinErr>> {
295-
self.control_word_1.set_data_out_mode_bit(DataOutModeBit::Serial);
299+
self.control_word_1
300+
.set_data_out_mode_bit(DataOutMode::Serial);
296301
self.update_control_word(self.control_word_1.bits())?;
302+
303+
// update local state once change is sent to device
304+
self.data_out_mode = DataOutMode::Serial;
305+
297306
Ok(())
298307
}
299308

300309
pub fn set_simultaneous_data_out(&mut self) -> Result<(), Hcms29xxError<PinErr>> {
301-
self.control_word_1.set_data_out_mode_bit(DataOutModeBit::Simultaneous);
310+
self.control_word_1
311+
.set_data_out_mode_bit(DataOutMode::Simultaneous);
302312
self.update_control_word(self.control_word_1.bits())?;
313+
314+
// update local state once change is sent to device
315+
self.data_out_mode = DataOutMode::Simultaneous;
316+
303317
Ok(())
304318
}
305319

306320
fn update_control_word(&mut self, control_word: u8) -> Result<(), Hcms29xxError<PinErr>> {
307-
// read current data out mode before potentially changing it
308-
let times_to_send = if (self.control_word_1 & control::control_word_1::DATA_OUT_BIT) != 0
309-
{
310-
1
321+
let times_to_send = if self.data_out_mode == DataOutMode::Serial {
322+
NUM_CHARS as u8 / control_word::DEVICE_CHARS as u8
311323
} else {
312-
NUM_CHARS as u8 / control::DEVICE_CHARS as u8
324+
1
313325
};
314326

315327
self.set_control_data()?;
@@ -318,12 +330,6 @@ where
318330
}
319331
self.end_transfer()?;
320332

321-
if (control_word & control::CONTROL_WORD_SELECT_BIT) != 0 {
322-
self.control_word_1 = control_word;
323-
} else {
324-
self.control_word_0 = control_word;
325-
}
326-
327333
Ok(())
328334
}
329335

0 commit comments

Comments
 (0)