Skip to content

Add display brightness control #83

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

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
5 changes: 4 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::{fs, path::PathBuf};
use anyhow::{Context, Result};
use badgemagic::{
ble::Device as BleDevice,
protocol::{Mode, PayloadBuffer, Speed, Style},
protocol::{Brightness, Mode, PayloadBuffer, Speed, Style},
usb_hid::Device as UsbDevice,
};
use base64::Engine;
Expand Down Expand Up @@ -63,6 +63,8 @@ enum TransportProtocol {
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct Config {
#[serde(default)]
brightness: Option<Brightness>,
#[serde(rename = "message")]
messages: Vec<Message>,
}
Expand Down Expand Up @@ -148,6 +150,7 @@ fn gnerate_payload(args: &mut Args) -> Result<PayloadBuffer> {
};

let mut payload = PayloadBuffer::new();
payload.set_brightness(config.brightness.unwrap_or_default());

for message in config.messages {
let mut style = Style::default();
Expand Down
68 changes: 60 additions & 8 deletions src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl Style {
self
}

/// Show a dotted border arround the display.
/// Show a dotted border around the display.
/// ```
/// use badgemagic::protocol::Style;
/// # (
Expand Down Expand Up @@ -161,7 +161,7 @@ impl TryFrom<u8> for Speed {
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
pub enum Mode {
/// Scroll thorugh the message from left to right
/// Scroll through the message from left to right
#[default]
Left,

Expand Down Expand Up @@ -193,14 +193,47 @@ pub enum Mode {
Laser,
}

/// Display Brightness
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
pub enum Brightness {
#[default]
Full = 0x00,
ThreeQuarters = 0x10,
Half = 0x20,
OneQuarter = 0x30,
}

impl From<Brightness> for u8 {
fn from(value: Brightness) -> Self {
value as u8
}
}

impl TryFrom<u8> for Brightness {
type Error = TryFromIntError;

fn try_from(value: u8) -> Result<Self, Self::Error> {
Ok(match value {
0x00 => Self::Full,
0x10 => Self::ThreeQuarters,
0x20 => Self::Half,
0x30 => Self::OneQuarter,
_ => return Err(u8::try_from(-1).unwrap_err()),
})
}
}

const MSG_PADDING_ALIGN: usize = 64;

const MAGIC: [u8; 6] = *b"wang\0\0";
const MAGIC: [u8; 5] = *b"wang\0";

#[derive(FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C)]
struct Header {
magic: [u8; 6],
magic: [u8; 5],
brightness: u8,
blink: u8,
border: u8,
speed_and_mode: [u8; 8],
Expand Down Expand Up @@ -241,7 +274,7 @@ impl Timestamp {

/// Buffer to create a payload
///
/// A payload consits of up to 8 messages
/// A payload consists of up to 8 messages
/// ```
/// # #[cfg(feature = "embedded-graphics")]
/// # fn main() {
Expand All @@ -252,7 +285,7 @@ impl Timestamp {
/// primitives::{PrimitiveStyle, Rectangle, Styled},
/// };
///
/// let mut buffer = PayloadBuffer::new();
/// let mut buffer = PayloadBuffer::default();
/// buffer.add_message_drawable(
/// Style::default(),
/// &Styled::new(
Expand Down Expand Up @@ -283,6 +316,7 @@ impl PayloadBuffer {
num_messages: 0,
data: Header {
magic: MAGIC,
brightness: 0,
blink: 0,
border: 0,
speed_and_mode: [0; 8],
Expand All @@ -300,6 +334,10 @@ impl PayloadBuffer {
Header::mut_from_prefix(&mut self.data).unwrap().0
}

pub fn set_brightness(&mut self, brightness: Brightness) {
self.header_mut().brightness = brightness.into();
}

/// Return the current number of messages
pub fn num_messages(&mut self) -> usize {
self.num_messages as usize
Expand Down Expand Up @@ -368,7 +406,7 @@ impl PayloadBuffer {
&self.data
}
Comment on lines 430 to 431

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: The num_messages method takes &mut self but does not mutate state.

Changing the receiver to &self would improve flexibility since no mutation occurs.

Suggested change
&self.data
}
/// Return the current number of messages
pub fn num_messages(&self) -> usize {
self.num_messages as usize
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not related to this change set, but should be fixed 😅


/// Convert the payload buffe into bytes (with padding)
/// Convert the payload buffer into bytes (with padding)
#[allow(clippy::missing_panics_doc)] // should never panic
#[must_use]
pub fn into_padded_bytes(self) -> impl AsRef<[u8]> {
Expand Down Expand Up @@ -486,7 +524,7 @@ impl DrawTarget for MessageBuffer<'_> {
mod test {
use std::ops::Range;

use super::Speed;
use super::{Brightness, Speed};

#[test]
fn speed_to_u8_and_back() {
Expand All @@ -499,4 +537,18 @@ mod test {
}
}
}

#[test]
fn brightness_to_u8() {
const VALID_BRIGHTNESS_VALUES: [(Brightness, u8); 4] = [
(Brightness::Full, 0x00),
(Brightness::ThreeQuarters, 0x10),
(Brightness::Half, 0x20),
(Brightness::OneQuarter, 0x30),
];

for (value, raw) in VALID_BRIGHTNESS_VALUES {
assert_eq!(u8::from(value), raw);
}
}
}