max7219_driver/lib.rs
1//! This crate provides a platform agnostic driver for the MAX7219 LED Driver IC.
2//!
3//! This driver was built using the [embedded-hal](https://docs.rs/embedded-hal/0.2.7/embedded_hal/) traits.
4//!
5//! ## Usage
6//!
7//! An updated version of the library should be available on crates.io. Add the following to your Cargo.toml to get is a dependency.
8//! ```rust
9//! [dependencies]
10//! max7219-driver = "*"
11//! ```
12//!
13//! ### Instantiating
14//!
15//! Create an instance of the driver with the `new` method, by passing SPI and Output pin instances.
16//! ```rust
17//! use max7219-driver::MAX7219;
18//! let spi = // SPI instantiation code
19//! let cs = // Output pin instantiation code
20//! let mut max7219 = MAX7219::new(spi, cs).unwrap();
21//! ```
22//!
23//! ### Initializing
24//!
25//! Initialize the driver instance with the `init_display` method. A boolean needs to be specified to indicate whether to clear the display after init or not.
26//! ```rust
27//! max7219.init_display(true);
28//! ```
29//!
30//! ## Cascading Multiple MAX7219 Devices
31//!
32//! If you are cascading multiple devices that are driving 8x8 LED Dot Matrices instead use the `MAX7219LedMat` driver as follows:
33//!
34//! ### Instantiating
35//!
36//! ```rust
37//! use max7219-driver::MAX7219LedMat;
38//! let spi = // SPI instantiation code
39//! let cs = // Output pin instantiation code
40//! let mut max7219: MAX7219LedMat<_, _, BUFLEN, COUNT> = MAX7219LedMat::new(spi, cs).unwrap();
41//! ```
42//!
43//! `BUFLEN` should be replaced with value equivalent to the total number of pixels/LED in the cascaded displays
44//! and `COUNT` with the number of displays
45//!
46//! Example:
47//!
48//! If four displays are cascaded then `BUFLEN` should be replaced with 256 (= 8 x 8 x 4) and `COUNT` replaced with 4 resulting in
49//!
50//! ```rust
51//! let mut max7219: MAX7219LedMat<_, _, 256, 4> = MAX7219LedMat::new(spi, cs).unwrap();
52//! ```
53//!
54//! ### Initializing
55//!
56//! Exactly the same as earlier, the new driver takes care of initializing all the cscaded displays.
57//!
58//! ```rust
59//! max7219.init_display(true);
60//! ```
61
62#![no_std]
63
64use embedded_graphics::pixelcolor::BinaryColor;
65use embedded_hal as hal;
66
67use embedded_graphics::prelude::*;
68
69use num_enum::TryFromPrimitive;
70
71use hal::blocking::spi::Write;
72use hal::digital::v2::OutputPin;
73use hal::spi::{Mode, Phase, Polarity};
74
75/// This is a constant for convenience so that the SPI module can be configured with the correct SPI mode compatible the MAX7219 device
76pub const MODE: Mode = Mode {
77 phase: Phase::CaptureOnFirstTransition,
78 polarity: Polarity::IdleLow,
79};
80
81/// The MAX7219 Driver that initializes and communicates with a single MAX7219 IC or chain of ICs.
82/// This driver usage is specific to connecting the 8x8 LED Dot Matrix
83pub struct MAX7219LedMat<SPI, CS, const BUFLEN: usize, const COUNT: usize> {
84 spi: SPI,
85 cs: CS,
86 framebuffer: [u8; BUFLEN],
87}
88
89impl<SPI, CS, const BUFLEN: usize, const COUNT: usize> MAX7219LedMat<SPI, CS, BUFLEN, COUNT>
90where
91 SPI: Write<u8>,
92 CS: OutputPin,
93{
94 ///
95 /// Constructor method. Creates a new instance of the MAX7219 driver.
96 ///
97 /// # Arguments
98 ///
99 /// * `spi` - a SPI peripheral instance
100 /// * `cs` - a OutputPin instance
101 ///
102 /// # Errors
103 ///
104 /// * `DriverError` - returned if there is an error during transfer or addressing device
105 ///
106 pub fn new(spi: SPI, cs: CS) -> Result<Self, DriverError> {
107 let max7219 = MAX7219LedMat::<SPI, CS, BUFLEN, COUNT> {
108 spi: spi,
109 cs: cs,
110 framebuffer: [0; BUFLEN],
111 };
112 Ok(max7219)
113 }
114
115 /// Method to flush framebuffer to display. This method needs to be called everytime a new framebuffer is created,
116 /// otherwise the frame will not appear on the screen.
117 ///
118 /// # Arguments
119 ///
120 /// * None
121 ///
122 /// # Errors
123 ///
124 /// * `DriverError` - returned if there is an error during transfer or addressing device
125 ///
126 pub fn flush(&mut self) -> Result<(), DriverError> {
127 // Iterate over all row addresses
128 for addr in 0..8 {
129 // Prepare Device to accept data
130 self.cs.set_low().map_err(|_| DriverError::PinError)?;
131
132 // Send frame data for each Display
133 for disp in (0..COUNT).rev() {
134 let base = ((disp + addr) * COUNT) * 8;
135 let arr = &self.framebuffer[base..base + 8];
136 // Convert each row in the framebuffer to a decimal num
137 let mut res: u8 = 0;
138 for i in 0..arr.len() {
139 res |= arr[i] << arr.len() - 1 - i;
140 }
141 self.spi
142 .write(&[addr as u8 + 1, res])
143 .map_err(|_| DriverError::SpiError)?;
144 }
145
146 // Latch Data Sent to Device(s)
147 self.cs.set_high().map_err(|_| DriverError::PinError)?;
148 }
149 Ok(())
150 }
151
152 ///
153 /// Transmits raw data to the MAX7219 IC.
154 ///
155 /// # Arguments
156 ///
157 /// * `arr` - slice of data that needs to be transmitted
158 ///
159 /// # Errors
160 ///
161 /// * `DriverError` - returned if there is an error during transfer or addressing device
162 ///
163 pub fn transmit_raw_data(&mut self, arr: &[u8]) -> Result<(), DriverError> {
164 self.cs.set_low().map_err(|_| DriverError::PinError)?;
165 let transfer = self.spi.write(&arr).map_err(|_| DriverError::SpiError);
166 self.cs.set_high().map_err(|_| DriverError::PinError)?;
167 transfer
168 }
169
170 ///
171 /// Configures the power mode of the MAX7219 IC.
172 ///
173 /// # Arguments
174 ///
175 /// * `mode` - one of the options in the `Shutdown` enum
176 ///
177 pub fn config_power_mode(&mut self, mode: Shutdown) -> () {
178 let data: u8 = match mode {
179 Shutdown::NormalOperation => 0x01,
180 Shutdown::ShutDownMode => 0x00,
181 };
182
183 let send_array: [u8; 2] = [Command::Shutdown as u8, data];
184 // Transmit Data
185 self.transmit_raw_data(&send_array).unwrap();
186 }
187
188 ///
189 /// Configures the decode mode on the input sent to the MAX7219 IC.
190 ///
191 /// # Arguments
192 ///
193 /// * `mode` - one of the options in the `DecodeMode` enum
194 ///
195 pub fn config_decode_mode(&mut self, mode: DecodeMode) -> () {
196 // - Prepare Information to be Sent
197 // 8-bit Data/Command Corresponding to No Decode Mode
198 let data: u8 = match mode {
199 DecodeMode::NoDecode => 0x00,
200 DecodeMode::CodeB0 => 0x01,
201 DecodeMode::CodeB30 => 0x0F,
202 DecodeMode::CodeB70 => 0xFF,
203 };
204 // Package into array to pass to SPI write method
205 // Write method will grab array and send all data in it
206 let send_array: [u8; 2] = [Command::DecodeMode as u8, data];
207 // Transmit Data
208 self.transmit_raw_data(&send_array).unwrap();
209 }
210
211 ///
212 /// Configures the intensity of the LEDs on the display connected to the MAX7219 IC.
213 ///
214 /// # Arguments
215 ///
216 /// * `mode` - one of the options in the `Intensity` enum
217 ///
218 pub fn config_intensity(&mut self, mode: Intensity) -> () {
219 // - Prepare Information to be Sent
220 // 8-bit Data/Command Corresponding to No Decode Mode
221 let data: u8 = match mode {
222 Intensity::Min => 0x00,
223 Intensity::Ratio3_32 => 0x01,
224 Intensity::Ratio5_32 => 0x02,
225 Intensity::Ratio7_32 => 0x03,
226 Intensity::Ratio9_32 => 0x04,
227 Intensity::Ratio11_32 => 0x05,
228 Intensity::Ratio13_32 => 0x06,
229 Intensity::Ratio15_32 => 0x07,
230 Intensity::Ratio17_32 => 0x08,
231 Intensity::Ratio19_32 => 0x09,
232 Intensity::Ratio21_32 => 0x0A,
233 Intensity::Ratio23_32 => 0x0B,
234 Intensity::Ratio25_32 => 0x0C,
235 Intensity::Ratio27_32 => 0x0D,
236 Intensity::Ratio29_32 => 0x0E,
237 Intensity::Max => 0x0F,
238 };
239 // Package into array to pass to SPI write method
240 // Write method will grab array and send all data in it
241 let send_array: [u8; 2] = [Command::Intensity as u8, data];
242 // Transmit Data
243 self.transmit_raw_data(&send_array).unwrap();
244 }
245
246 ///
247 /// Configures the scanlimit for the MAX7219 IC.
248 /// Applicable mostly to seven segment displays if certain digits (ex. on the left)
249 /// need not to be shown.
250 ///
251 /// # Arguments
252 ///
253 /// * `mode` - one of the options in the `ScanLimit` enum
254 ///
255 pub fn config_scan_limit(&mut self, mode: ScanLimit) -> () {
256 // - Prepare Information to be Sent
257 // 8-bit Data/Command Corresponding to No Decode Mode
258 let data: u8 = match mode {
259 ScanLimit::Display0Only => 0x00,
260 ScanLimit::Display0And1 => 0x01,
261 ScanLimit::Display0To2 => 0x02,
262 ScanLimit::Display0To3 => 0x03,
263 ScanLimit::Display0To4 => 0x04,
264 ScanLimit::Display0To5 => 0x05,
265 ScanLimit::Display0To6 => 0x06,
266 ScanLimit::Display0To7 => 0x07,
267 };
268 // Package into array to pass to SPI write method
269 // Write method will grab array and send all data in it
270 let send_array: [u8; 2] = [Command::ScanLimit as u8, data];
271 // Transmit Data
272 self.transmit_raw_data(&send_array).unwrap();
273 }
274
275 ///
276 /// Method to perform a visual test of the display.
277 /// If performing a test, display needs to be put back in normal operation mode after done.
278 ///
279 /// # Arguments
280 ///
281 /// * `mode` - one of the options in the `DisplayTest` enum
282 ///
283 pub fn display_test(&mut self, mode: DisplayTest) -> () {
284 // - Prepare Information to be Sent
285 // 8-bit Data/Command Corresponding to No Decode Mode
286 let data: u8 = match mode {
287 DisplayTest::NormalOperationMode => 0x00,
288 DisplayTest::DisplayTestMode => 0x01,
289 };
290 // Package into array to pass to SPI write method
291 // Write method will grab array and send all data in it
292 let send_array: [u8; 2] = [Command::DisplayTest as u8, data];
293 // Transmit Data
294 self.transmit_raw_data(&send_array).unwrap();
295 }
296
297 ///
298 /// Method to draw a row if the MAX7219 is driving an 8x8 LED dot matrix display.
299 /// Alternatively method will draw a digit in case the MAX7219 is driving a seven-segment display
300 ///
301 /// # Arguments
302 ///
303 /// * `digit_addr` - one of the options in the `DigitRowAddress` enum
304 /// * `led_data` - the led row or seven segment digit activation data
305 ///
306 pub fn draw_row_or_digit(&mut self, digit_addr: DigitRowAddress, led_data: u8) -> () {
307 // Can do an exhaustive match of DigitRowAddress
308 // let addr: u8 = match digit_addr {
309 // DigitRowAddress::Digit0 => 0x01,
310 // DigitRowAddress::Digit1 => 0x02,
311 // DigitRowAddress::Digit2 => 0x03,
312 // DigitRowAddress::Digit3 => 0x04,
313 // DigitRowAddress::Digit4 => 0x05,
314 // DigitRowAddress::Digit5 => 0x06,
315 // DigitRowAddress::Digit6 => 0x07,
316 // DigitRowAddress::Digit7 => 0x08,
317 // };
318 // OR typecast DigitRowAddress passed through digit_addr as u8
319 let send_array: [u8; 2] = [digit_addr as u8, led_data];
320 self.transmit_raw_data(&send_array).unwrap();
321 ()
322 }
323
324 ///
325 /// Method to clear the display.
326 ///
327 pub fn clear_display(&mut self) -> () {
328 for i in 1..9 {
329 self.transmit_raw_data(&[i, 0]).unwrap();
330 }
331 }
332
333 ///
334 /// Method to initialize the MAX7219 and the connected display.
335 /// This method has to be called before doing any display operations otherwise the display will not operate properly.
336 /// The method provides an option to leave the display uncleared after initalization.
337 ///
338 /// # Arguments
339 ///
340 /// * `clr_display` - Boolean that reflects whether the display should be cleared or not after init
341 ///
342 pub fn init_display(&mut self, clr_display: bool) -> () {
343 // 1.a) Power Up Device
344 self.config_power_mode(Shutdown::NormalOperation);
345 // 1.b) Set up Decode Mode
346 self.config_decode_mode(DecodeMode::NoDecode);
347 // 1.c) Configure Scan Limit
348 self.config_scan_limit(ScanLimit::Display0To7);
349 // 1.d) Configure Intensity
350 self.config_intensity(Intensity::Ratio15_32);
351 // 1.e) Optional Screen Clear on Init
352 if clr_display {
353 self.clear_display();
354 }
355 }
356}
357
358/// The MAX7219 Driver that initializes and communicates with a single MAX7219 IC.
359pub struct MAX7219<SPI, CS> {
360 spi: SPI,
361 cs: CS,
362}
363
364///
365/// Possible Errors that can be raised either
366/// during communication with the MAX7219 chip over SPI
367/// or controlling the chip select pin.
368///
369#[derive(Debug)]
370pub enum DriverError {
371 /// An error occurred when working with SPI
372 SpiError,
373 /// An error occurred when working with a PIN
374 PinError,
375}
376
377impl<SPI, CS> MAX7219<SPI, CS>
378where
379 SPI: Write<u8>,
380 CS: OutputPin,
381{
382 ///
383 /// Constructor method. Creates a new instance of the MAX7219 driver.
384 ///
385 /// # Arguments
386 ///
387 /// * `spi` - a SPI peripheral instance
388 /// * `cs` - a OutputPin instance
389 ///
390 /// # Errors
391 ///
392 /// * `DriverError` - returned if there is an error during transfer or addressing device
393 ///
394 pub fn new(spi: SPI, cs: CS) -> Result<Self, DriverError> {
395 let max7219 = MAX7219 { spi: spi, cs: cs };
396 Ok(max7219)
397 }
398
399 ///
400 /// Transmits raw data to the MAX7219 IC.
401 ///
402 /// # Arguments
403 ///
404 /// * `arr` - slice of data that needs to be transmitted
405 ///
406 /// # Errors
407 ///
408 /// * `DriverError` - returned if there is an error during transfer or addressing device
409 ///
410 pub fn transmit_raw_data(&mut self, arr: &[u8]) -> Result<(), DriverError> {
411 self.cs.set_low().map_err(|_| DriverError::PinError)?;
412 let transfer = self.spi.write(&arr).map_err(|_| DriverError::SpiError);
413 self.cs.set_high().map_err(|_| DriverError::PinError)?;
414 transfer
415 }
416
417 ///
418 /// Configures the power mode of the MAX7219 IC.
419 ///
420 /// # Arguments
421 ///
422 /// * `mode` - one of the options in the `Shutdown` enum
423 ///
424 pub fn config_power_mode(&mut self, mode: Shutdown) -> () {
425 let data: u8 = match mode {
426 Shutdown::NormalOperation => 0x01,
427 Shutdown::ShutDownMode => 0x00,
428 };
429
430 let send_array: [u8; 2] = [Command::Shutdown as u8, data];
431 // Transmit Data
432 self.transmit_raw_data(&send_array).unwrap();
433 }
434
435 ///
436 /// Configures the decode mode on the input sent to the MAX7219 IC.
437 ///
438 /// # Arguments
439 ///
440 /// * `mode` - one of the options in the `DecodeMode` enum
441 ///
442 pub fn config_decode_mode(&mut self, mode: DecodeMode) -> () {
443 // - Prepare Information to be Sent
444 // 8-bit Data/Command Corresponding to No Decode Mode
445 let data: u8 = match mode {
446 DecodeMode::NoDecode => 0x00,
447 DecodeMode::CodeB0 => 0x01,
448 DecodeMode::CodeB30 => 0x0F,
449 DecodeMode::CodeB70 => 0xFF,
450 };
451 // Package into array to pass to SPI write method
452 // Write method will grab array and send all data in it
453 let send_array: [u8; 2] = [Command::DecodeMode as u8, data];
454 // Transmit Data
455 self.transmit_raw_data(&send_array).unwrap();
456 }
457
458 ///
459 /// Configures the intensity of the LEDs on the display connected to the MAX7219 IC.
460 ///
461 /// # Arguments
462 ///
463 /// * `mode` - one of the options in the `Intensity` enum
464 ///
465 pub fn config_intensity(&mut self, mode: Intensity) -> () {
466 // - Prepare Information to be Sent
467 // 8-bit Data/Command Corresponding to No Decode Mode
468 let data: u8 = match mode {
469 Intensity::Min => 0x00,
470 Intensity::Ratio3_32 => 0x01,
471 Intensity::Ratio5_32 => 0x02,
472 Intensity::Ratio7_32 => 0x03,
473 Intensity::Ratio9_32 => 0x04,
474 Intensity::Ratio11_32 => 0x05,
475 Intensity::Ratio13_32 => 0x06,
476 Intensity::Ratio15_32 => 0x07,
477 Intensity::Ratio17_32 => 0x08,
478 Intensity::Ratio19_32 => 0x09,
479 Intensity::Ratio21_32 => 0x0A,
480 Intensity::Ratio23_32 => 0x0B,
481 Intensity::Ratio25_32 => 0x0C,
482 Intensity::Ratio27_32 => 0x0D,
483 Intensity::Ratio29_32 => 0x0E,
484 Intensity::Max => 0x0F,
485 };
486 // Package into array to pass to SPI write method
487 // Write method will grab array and send all data in it
488 let send_array: [u8; 2] = [Command::Intensity as u8, data];
489 // Transmit Data
490 self.transmit_raw_data(&send_array).unwrap();
491 }
492
493 ///
494 /// Configures the scanlimit for the MAX7219 IC.
495 /// Applicable mostly to seven segment displays if certain digits (ex. on the left)
496 /// need not to be shown.
497 ///
498 /// # Arguments
499 ///
500 /// * `mode` - one of the options in the `ScanLimit` enum
501 ///
502 pub fn config_scan_limit(&mut self, mode: ScanLimit) -> () {
503 // - Prepare Information to be Sent
504 // 8-bit Data/Command Corresponding to No Decode Mode
505 let data: u8 = match mode {
506 ScanLimit::Display0Only => 0x00,
507 ScanLimit::Display0And1 => 0x01,
508 ScanLimit::Display0To2 => 0x02,
509 ScanLimit::Display0To3 => 0x03,
510 ScanLimit::Display0To4 => 0x04,
511 ScanLimit::Display0To5 => 0x05,
512 ScanLimit::Display0To6 => 0x06,
513 ScanLimit::Display0To7 => 0x07,
514 };
515 // Package into array to pass to SPI write method
516 // Write method will grab array and send all data in it
517 let send_array: [u8; 2] = [Command::ScanLimit as u8, data];
518 // Transmit Data
519 self.transmit_raw_data(&send_array).unwrap();
520 }
521
522 ///
523 /// Method to perform a visual test of the display.
524 /// If performing a test, display needs to be put back in normal operation mode after done.
525 ///
526 /// # Arguments
527 ///
528 /// * `mode` - one of the options in the `DisplayTest` enum
529 ///
530 pub fn display_test(&mut self, mode: DisplayTest) -> () {
531 // - Prepare Information to be Sent
532 // 8-bit Data/Command Corresponding to No Decode Mode
533 let data: u8 = match mode {
534 DisplayTest::NormalOperationMode => 0x00,
535 DisplayTest::DisplayTestMode => 0x01,
536 };
537 // Package into array to pass to SPI write method
538 // Write method will grab array and send all data in it
539 let send_array: [u8; 2] = [Command::DisplayTest as u8, data];
540 // Transmit Data
541 self.transmit_raw_data(&send_array).unwrap();
542 }
543
544 ///
545 /// Method to draw a row if the MAX7219 is driving an 8x8 LED dot matrix display.
546 /// Alternatively method will draw a digit in case the MAX7219 is driving a seven-segment display
547 ///
548 /// # Arguments
549 ///
550 /// * `digit_addr` - one of the options in the `DigitRowAddress` enum
551 /// * `led_data` - the led row or seven segment digit activation data
552 ///
553 pub fn draw_row_or_digit(&mut self, digit_addr: DigitRowAddress, led_data: u8) -> () {
554 // Can do an exhaustive match of DigitRowAddress
555 // let addr: u8 = match digit_addr {
556 // DigitRowAddress::Digit0 => 0x01,
557 // DigitRowAddress::Digit1 => 0x02,
558 // DigitRowAddress::Digit2 => 0x03,
559 // DigitRowAddress::Digit3 => 0x04,
560 // DigitRowAddress::Digit4 => 0x05,
561 // DigitRowAddress::Digit5 => 0x06,
562 // DigitRowAddress::Digit6 => 0x07,
563 // DigitRowAddress::Digit7 => 0x08,
564 // };
565 // OR typecast DigitRowAddress passed through digit_addr as u8
566 let send_array: [u8; 2] = [digit_addr as u8, led_data];
567 self.transmit_raw_data(&send_array).unwrap();
568 ()
569 }
570
571 ///
572 /// Method to clear the display.
573 ///
574 pub fn clear_display(&mut self) -> () {
575 for i in 1..9 {
576 self.transmit_raw_data(&[i, 0]).unwrap();
577 }
578 }
579
580 ///
581 /// Method to initialize the MAX7219 and the connected display.
582 /// This method has to be called before doing any display operations otherwise the display will not operate properly.
583 /// The method provides an option to leave the display uncleared after initalization.
584 ///
585 /// # Arguments
586 ///
587 /// * `clr_display` - Boolean that reflects whether the display should be cleared or not after init
588 ///
589 pub fn init_display(&mut self, clr_display: bool) -> () {
590 // 1.a) Power Up Device
591 self.config_power_mode(Shutdown::NormalOperation);
592 // 1.b) Set up Decode Mode
593 self.config_decode_mode(DecodeMode::NoDecode);
594 // 1.c) Configure Scan Limit
595 self.config_scan_limit(ScanLimit::Display0To7);
596 // 1.d) Configure Intensity
597 self.config_intensity(Intensity::Ratio15_32);
598 // 1.e) Optional Screen Clear on Init
599 if clr_display {
600 self.clear_display();
601 }
602 }
603}
604
605impl<SPI, CS, const BUFLEN: usize, const COUNT: usize> DrawTarget
606 for MAX7219LedMat<SPI, CS, BUFLEN, COUNT>
607{
608 type Color = BinaryColor;
609 type Error = core::convert::Infallible;
610
611 fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
612 where
613 I: IntoIterator<Item = Pixel<Self::Color>>,
614 {
615 let bb = self.bounding_box();
616 pixels
617 .into_iter()
618 .filter(|Pixel(pos, _color)| bb.contains(*pos))
619 .for_each(|Pixel(pos, color)| {
620 let index: u32 = pos.x as u32 + pos.y as u32 * 8;
621 self.framebuffer[index as usize] = color.is_on() as u8;
622 });
623 Ok(())
624 }
625}
626
627impl<SPI, CS, const BUFLEN: usize, const COUNT: usize> OriginDimensions
628 for MAX7219LedMat<SPI, CS, BUFLEN, COUNT>
629{
630 fn size(&self) -> Size {
631 Size::new(COUNT as u32 * 8, 8)
632 }
633}
634
635/// Enumeration of commands in the register map of the MAX7219.
636pub enum Command {
637 NoOp = 0x00,
638 DecodeMode = 0x09,
639 Intensity = 0x0A,
640 ScanLimit = 0x0B,
641 Shutdown = 0x0C,
642 DisplayTest = 0x0F,
643}
644
645/// Enumeration of the MAX7219 power modes.
646pub enum Shutdown {
647 ShutDownMode,
648 NormalOperation,
649}
650
651/// Enumeration of the MAX7219 decode modes for BCD encoded input.
652pub enum DecodeMode {
653 NoDecode = 0x00,
654 CodeB0 = 0x01,
655 CodeB30 = 0x0F,
656 CodeB70 = 0xFF,
657}
658
659/// Enumeration of the MAX7219 supported LED intensity values.
660pub enum Intensity {
661 Min = 0x00,
662 Ratio3_32 = 0x01,
663 Ratio5_32 = 0x02,
664 Ratio7_32 = 0x03,
665 Ratio9_32 = 0x04,
666 Ratio11_32 = 0x05,
667 Ratio13_32 = 0x06,
668 Ratio15_32 = 0x07,
669 Ratio17_32 = 0x08,
670 Ratio19_32 = 0x09,
671 Ratio21_32 = 0x0A,
672 Ratio23_32 = 0x0B,
673 Ratio25_32 = 0x0C,
674 Ratio27_32 = 0x0D,
675 Ratio29_32 = 0x0E,
676 Max = 0x0F,
677}
678
679/// Enumeration of the MAX7219 display scan limits
680pub enum ScanLimit {
681 Display0Only = 0x00,
682 Display0And1 = 0x01,
683 Display0To2 = 0x02,
684 Display0To3 = 0x03,
685 Display0To4 = 0x04,
686 Display0To5 = 0x05,
687 Display0To6 = 0x06,
688 Display0To7 = 0x07,
689}
690
691/// Enumeration of the MAX7219 display test modes
692pub enum DisplayTest {
693 NormalOperationMode = 0x00,
694 DisplayTestMode = 0x01,
695}
696
697/// Enumeration of the MAX7219 digit/row addresses
698#[repr(u8)]
699#[derive(Debug, TryFromPrimitive)]
700pub enum DigitRowAddress {
701 Digit0 = 0x01,
702 Digit1 = 0x02,
703 Digit2 = 0x03,
704 Digit3 = 0x04,
705 Digit4 = 0x05,
706 Digit5 = 0x06,
707 Digit6 = 0x07,
708 Digit7 = 0x08,
709}