Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ascii conversion and move_segments_raw #24

Merged
merged 11 commits into from
Sep 21, 2024
Merged
2 changes: 1 addition & 1 deletion examples/esp32/blocking/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 1 addition & 6 deletions tm1637/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,7 @@ keywords = ["tm1637", "embedded-hal", "no-std", "embedded"]
readme = "../README.md"

[features]
default = [
"async",
"impl-debug",
"mappings",
"formatters",
] # TODO remove mappings, formatters before release
default = ["async", "impl-debug"]
async = ["dep:embedded-hal", "dep:embedded-hal-async"]
blocking = ["dep:embedded-hal"]
mappings = []
Expand Down
34 changes: 33 additions & 1 deletion tm1637/src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ pub mod module {

/// Write the given bytes to the display starting from the given position.
///
/// ## Notes:
/// # Notes:
/// - Positions greater than [`TM1637::num_positions`] will be ignored.
/// - Bytes with index greater than [`TM1637::num_positions`] will be ignored.
///
Expand Down Expand Up @@ -279,6 +279,38 @@ pub mod module {
self.brightness = brightness;
self.write_cmd_raw(brightness as u8).await
}

/// Move all segments across the display starting and ending at `position`.
///
/// If the length of the bytes is less than or equal to [`TM1637::num_positions`] - `position`, the bytes will only be written to the display.
///
/// `N` is the size of the internal window used to move the segments. Please make sure that `N` is equal to [`TM1637::num_positions`].
/// [`TM1637::num_positions`] will be removed in the future in favor of a constant generic parameter representing the number of positions.
pub async fn move_segments_raw<const N: usize>(
&mut self,
position: u8,
bytes: &[u8],
delay_ms: u32,
) -> Result<(), ERR> {
let num_positions = self.num_positions as usize;

if bytes.len() <= num_positions - position as usize {
return self.write_segments_raw(position, bytes).await;
}

for i in 0..=bytes.len() {
let mut window = [0u8; N];
for j in 0..num_positions {
window[j] = bytes[(i + j) % bytes.len()];
}

tri!(self.write_segments_raw(position, &window).await);

self.delay.delay_ms(delay_ms).await;
}

Ok(())
}
}
}

Expand Down
76 changes: 76 additions & 0 deletions tm1637/src/mappings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,82 @@ pub const fn flip_mirror(byte: u8) -> u8 {
mirror(flip(byte))
}

/// Converts an `ASCII` byte to a 7-segment display byte.
///
/// Unknown characters are converted to `0` (all segments off).
///
/// # Note
///
/// Rust strings are `UTF-8` encoded, so what you see as a single character may be multiple bytes.
///
/// # Example
///
/// Display `Err` text on a 4-digit display:
///
/// ```rust,ignore
/// let err = "Err".as_bytes().iter().copied().map(from_ascii_byte);
/// tm.write_segments_raw_iter(0, err).ok();
/// ```
pub const fn from_ascii_byte(byte: u8) -> u8 {
match byte {
b'0' => DigitBits::Zero as u8,
b'1' => DigitBits::One as u8,
b'2' => DigitBits::Two as u8,
b'3' => DigitBits::Three as u8,
b'4' => DigitBits::Four as u8,
b'5' => DigitBits::Five as u8,
b'6' => DigitBits::Six as u8,
b'7' => DigitBits::Seven as u8,
b'8' => DigitBits::Eight as u8,
b'9' => DigitBits::Nine as u8,

b'A' => UpCharBits::UpA as u8,
b'B' => UpCharBits::UpB as u8,
b'C' => UpCharBits::UpC as u8,
b'E' => UpCharBits::UpE as u8,
b'F' => UpCharBits::UpF as u8,
b'G' => UpCharBits::UpG as u8,
b'H' => UpCharBits::UpH as u8,
b'I' => UpCharBits::UpI as u8,
b'J' => UpCharBits::UpJ as u8,
b'L' => UpCharBits::UpL as u8,
b'O' => UpCharBits::UpO as u8,
b'P' => UpCharBits::UpP as u8,
b'S' => UpCharBits::UpS as u8,
b'U' => UpCharBits::UpU as u8,
b'Z' => UpCharBits::UpZ as u8,

b'a' => LoCharBits::LoA as u8,
b'b' => LoCharBits::LoB as u8,
b'c' => LoCharBits::LoC as u8,
b'd' => LoCharBits::LoD as u8,
b'e' => LoCharBits::LoE as u8,
b'g' => LoCharBits::LoG as u8,
b'h' => LoCharBits::LoH as u8,
b'i' => LoCharBits::LoI as u8,
b'n' => LoCharBits::LoN as u8,
b'o' => LoCharBits::LoO as u8,
b'q' => LoCharBits::LoQ as u8,
b'r' => LoCharBits::LoR as u8,
b't' => LoCharBits::LoT as u8,
b'u' => LoCharBits::LoU as u8,
b'y' => LoCharBits::LoY as u8,

b' ' => SpecialCharBits::Space as u8,
b'-' => SpecialCharBits::Minus as u8,
b'_' => SpecialCharBits::Underscore as u8,
b'=' => SpecialCharBits::Equals as u8,
b'?' => SpecialCharBits::QuestionMark as u8,

_ => 0,
}
}

/// Converts a `char` to a 7-segment display byte. See [`from_ascii_byte`] for more information.
pub const fn from_char(c: char) -> u8 {
from_ascii_byte(c as u8)
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
Loading