Skip to content

Commit

Permalink
Allow restoring PWM back to default
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel Schaefer <[email protected]>
  • Loading branch information
JohnAZoidberg committed Oct 30, 2023
1 parent 956e616 commit b823200
Showing 1 changed file with 46 additions and 3 deletions.
49 changes: 46 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ where
I2C: Read<Error = I2cError>,
{
/// Fill all pixels of the display at once. The brightness should range from 0 to 255.
/// brightness slice must have 0xC5 elements
/// brightness slice must have 0xC6 elements
pub fn fill_matrix(&mut self, brightnesses: &[u8]) -> Result<(), I2cError> {
// Extend by one, to add address to the beginning
let mut buf = [0x00; 0xC7];
Expand All @@ -39,6 +39,15 @@ where
Ok(())
}

/// Read back the currently displayed matrix
pub fn read_matrix(&mut self) -> Result<[u8; 0xC6], I2cError> {
let mut buf = [0x00; 0xC6];
self.bank(Page::Pwm)?;
self.i2c.write(self.address, &[0x01])?;
self.i2c.read(self.address, &mut buf)?;
Ok(buf)
}

/// Fill the display with a single brightness. The brightness should range from 0 to 255.
pub fn fill(&mut self, brightness: u8) -> Result<(), I2cError> {
self.bank(Page::Pwm)?;
Expand Down Expand Up @@ -91,12 +100,33 @@ where
/// Send a reset message to the slave device. Delay is something that your device's HAL should
/// provide which allows for the process to sleep for a certain amount of time (in this case 10
/// MS to perform a reset).
/// This will result in all registers being restored to their defaults.
pub fn reset<DEL: DelayMs<u8>>(&mut self, delay: &mut DEL) -> Result<(), I2cError> {
self.write_register(Page::Config, addresses::RESET_REGISTER, addresses::RESET)?;
delay.delay_ms(10);
Ok(())
}

/// Reset the controller and restore all registers
pub fn reset_restore<DEL: DelayMs<u8>>(
&mut self,
delay: &mut DEL,
) -> Result<(), Error<I2cError>> {
// Back up registers
let prev_config = self.read_register(Page::Config, addresses::CONFIG_REGISTER)?;
// Assumes all scaling registers are set to the same value
let prev_scale = self.read_register(Page::Scale, 0x01)?;
let prev_brightness = self.read_matrix()?;

self.setup(delay)?;

// Restore registers
self.write_register(Page::Config, addresses::CONFIG_REGISTER, prev_config)?;
self.set_scaling(prev_scale)?;
self.fill_matrix(&prev_brightness)?;
Ok(())
}

/// Set the current available to each LED. 0 is none, 255 is the maximum available
pub fn set_scaling(&mut self, scale: u8) -> Result<(), I2cError> {
self.bank(Page::Scale)?;
Expand Down Expand Up @@ -126,7 +156,17 @@ where
}

/// Set the PWM frequency
pub fn set_pwm_freq(&mut self, pwm: PwmFreq) -> Result<(), I2cError> {
pub fn set_pwm_freq<DEL: DelayMs<u8>>(
&mut self,
delay: &mut DEL,
pwm: PwmFreq,
) -> Result<(), Error<I2cError>> {
// The default frequency, can't set it. Reset the controller and restore the registers
if let PwmFreq::P29k = pwm {
self.reset_restore(delay)?;
return Ok(());
}

// Enter test mode
self.write_register(Page::Config, addresses::TEST_MODE_REGISTER, 0x01)?;

Expand Down Expand Up @@ -220,6 +260,9 @@ enum Page {

#[repr(u8)]
pub enum PwmFreq {
/// 29kHz, the default. To set this, it'll reset the controller
P29k = 0xFF,
/// 31.25kHz
P31k25 = 0xE0,
/// 15.6kHz
P15k6 = 0x20,
Expand All @@ -232,7 +275,7 @@ pub enum PwmFreq {
/// 977Hz
P977 = 0xA0,
/// 488Hz
P448 = 0xC0,
P488 = 0xC0,
}

#[repr(u8)]
Expand Down

0 comments on commit b823200

Please sign in to comment.