microbit_bsp/display/
types.rs1use core::ops::{AddAssign, SubAssign};
2const BITMAP_WIDTH: usize = 1;
4const BITMAP_WORD_SIZE: usize = 8;
6
7#[derive(Clone, Copy, PartialEq)]
9pub struct Bitmap {
10 data: [u8; BITMAP_WIDTH],
11 nbits: usize,
12}
13
14impl core::fmt::Debug for Bitmap {
15 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
16 for i in 0..self.nbits {
17 if self.is_set(i) {
18 write!(f, "1")?;
19 } else {
20 write!(f, "0")?;
21 }
22 }
23 Ok(())
24 }
25}
26
27#[cfg(feature = "defmt")]
28impl defmt::Format for Bitmap {
29 fn format(&self, f: defmt::Formatter<'_>) {
30 let mut s: heapless::String<32> = heapless::String::new();
31 for i in 0..self.nbits {
32 if self.is_set(i) {
33 s.push('1').unwrap();
34 } else {
35 s.push('0').unwrap();
36 }
37 }
38 defmt::write!(f, "{}", s.as_str());
39 }
40}
41
42impl Bitmap {
43 pub const fn new(input: u8, nbits: usize) -> Self {
46 let mut data = [0; BITMAP_WIDTH];
47 if nbits < BITMAP_WORD_SIZE {
49 data[0] = input << (BITMAP_WORD_SIZE - nbits);
50 } else {
51 data[0] = input;
52 }
53 Self { data, nbits }
55 }
56
57 pub const fn empty(nbits: usize) -> Self {
59 Self { data: [0; 1], nbits }
60 }
61
62 pub fn set(&mut self, bit: usize) {
64 assert!(bit < self.nbits);
65 let idx: usize = bit / BITMAP_WORD_SIZE;
66 let p: usize = bit % BITMAP_WORD_SIZE;
67 self.data[idx] |= 1 << ((BITMAP_WORD_SIZE - 1) - p);
68 }
69
70 pub fn clear_all(&mut self) {
72 for i in 0..self.data.len() {
73 self.data[i] = 0;
74 }
75 }
76
77 pub fn clear(&mut self, bit: usize) {
79 assert!(bit < self.nbits);
80 let idx: usize = bit / BITMAP_WORD_SIZE;
81 let p: usize = bit % BITMAP_WORD_SIZE;
82 self.data[idx] &= !(1 << ((BITMAP_WORD_SIZE - 1) - p));
83 }
84
85 pub fn is_set(&self, bit: usize) -> bool {
87 assert!(bit < self.nbits);
88 let idx: usize = bit / BITMAP_WORD_SIZE;
89 let p: usize = bit % BITMAP_WORD_SIZE;
90 (self.data[idx] & (1 << ((BITMAP_WORD_SIZE - 1) - p))) != 0
91 }
92
93 pub fn shift_left(&mut self, nbits: usize) {
95 for b in self.data.iter_mut() {
96 *b <<= nbits;
97 }
98 }
99
100 pub fn shift_right(&mut self, nbits: usize) {
102 for b in self.data.iter_mut() {
103 *b >>= nbits;
104 }
105 }
106
107 pub fn or(&mut self, other: &Bitmap) {
109 for i in 0..self.data.len() {
110 self.data[i] |= other.data[i];
111 }
112 }
113
114 pub fn and(&mut self, other: &Bitmap) {
116 for i in 0..self.data.len() {
117 self.data[i] &= other.data[i];
118 }
119 }
120}
121
122#[derive(Clone, Copy, PartialEq)]
126pub struct Frame<const XSIZE: usize, const YSIZE: usize> {
127 bitmap: [Bitmap; YSIZE],
128}
129
130impl<const XSIZE: usize, const YSIZE: usize> core::fmt::Debug for Frame<XSIZE, YSIZE> {
131 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
132 for (i, b) in self.bitmap.iter().enumerate() {
133 for j in 0..b.nbits {
134 if self.bitmap[i].is_set(j) {
135 write!(f, "1")?;
136 } else {
137 write!(f, "0")?;
138 }
139 }
140 writeln!(f)?;
141 }
142 Ok(())
143 }
144}
145
146#[cfg(feature = "defmt")]
147impl<const XSIZE: usize, const YSIZE: usize> defmt::Format for Frame<XSIZE, YSIZE> {
148 fn format(&self, f: defmt::Formatter<'_>) {
149 let mut s: heapless::String<1056> = heapless::String::new();
150 for (i, b) in self.bitmap.iter().enumerate() {
151 for j in 0..b.nbits {
152 if self.bitmap[i].is_set(j) {
153 s.push('1').unwrap();
154 } else {
155 s.push('0').unwrap();
156 }
157 }
158 s.push('\n').unwrap();
159 }
160 defmt::write!(f, "{}", s.as_str());
161 }
162}
163
164impl<const XSIZE: usize, const YSIZE: usize> Frame<XSIZE, YSIZE> {
165 pub const fn empty() -> Self {
167 Self {
168 bitmap: [Bitmap::empty(XSIZE); YSIZE],
169 }
170 }
171
172 pub const fn new(bitmap: [Bitmap; YSIZE]) -> Self {
174 Self { bitmap }
175 }
176
177 pub fn clear(&mut self) {
179 for m in self.bitmap.iter_mut() {
180 m.clear_all();
181 }
182 }
183
184 pub fn set(&mut self, x: usize, y: usize) {
186 self.bitmap[y].set(x);
187 }
188
189 pub fn unset(&mut self, x: usize, y: usize) {
191 self.bitmap[y].clear(x);
192 }
193
194 pub fn is_set(&self, x: usize, y: usize) -> bool {
196 self.bitmap[y].is_set(x)
197 }
198
199 pub fn or(&mut self, other: &Frame<XSIZE, YSIZE>) {
201 for i in 0..self.bitmap.len() {
202 self.bitmap[i].or(&other.bitmap[i]);
203 }
204 }
205
206 pub fn shift_left(&mut self, nbits: usize) {
208 for i in 0..self.bitmap.len() {
209 self.bitmap[i].shift_left(nbits);
210 }
211 }
212
213 pub fn shift_right(&mut self, nbits: usize) {
215 for i in 0..self.bitmap.len() {
216 self.bitmap[i].shift_right(nbits);
217 }
218 }
219
220 pub fn and(&mut self, other: &Frame<XSIZE, YSIZE>) {
222 for i in 0..self.bitmap.len() {
223 self.bitmap[i].and(&other.bitmap[i]);
224 }
225 }
226}
227
228impl<const XSIZE: usize, const YSIZE: usize> Default for Frame<XSIZE, YSIZE> {
229 fn default() -> Self {
230 Frame::empty()
231 }
232}
233
234#[derive(Clone, Copy)]
236pub struct Brightness(u8);
237
238impl Brightness {
239 pub const MAX: Brightness = Brightness(10);
241
242 pub const MIN: Brightness = Brightness(0);
244
245 pub fn new(level: u8) -> Self {
247 Self(level.clamp(Self::MIN.0, Self::MAX.0))
248 }
249
250 pub fn level(&self) -> u8 {
252 self.0
253 }
254}
255
256impl Default for Brightness {
257 fn default() -> Self {
258 Self(5)
259 }
260}
261
262impl AddAssign<u8> for Brightness {
263 fn add_assign(&mut self, rhs: u8) {
264 self.0 += core::cmp::min(Self::MAX.level() - self.0, rhs);
265 }
266}
267
268impl SubAssign<u8> for Brightness {
269 fn sub_assign(&mut self, rhs: u8) {
270 self.0 -= core::cmp::min(self.0, rhs);
271 }
272}
273
274