|
@@ -22,15 +22,9 @@ pub const PCA9685_SUB_CALL_1: u8 = 0x71; // Default disabled
|
|
|
pub const PCA9685_SUB_CALL_2: u8 = 0x72; // Default disabled
|
|
|
pub const PCA9685_SUB_CALL_3: u8 = 0x73; // Default disabled
|
|
|
|
|
|
-const MAP_DOT_ADDR: u8 = PCA9685_ADDR_2;
|
|
|
-const MAP_DOT_PIN: u8 = 15;
|
|
|
-
|
|
|
-const MAP_ADDR: usize = 0;
|
|
|
-const MAP_PIN: usize = 1;
|
|
|
-
|
|
|
-const DIGIT_FADE_DURATION_US: u32 = 1_000_000;
|
|
|
pub const REFRESH_RATE_HZ: u32 = 1000;
|
|
|
|
|
|
+const DIGIT_FADE_DURATION_US: u32 = 1_000_000;
|
|
|
const DIGIT_RNG_FADE_DURATION_US: u32 = 200_000;
|
|
|
const DIGIT_RNG_FADE_ITERATIONS: usize = 20;
|
|
|
const DIGIT_RNG_REFRESH_INTERVAL: usize = 60;
|
|
@@ -46,6 +40,12 @@ const DIGIT_MIN_BRIGHTNESS: u32 = 0;
|
|
|
const NUM_TUBES: usize = 4;
|
|
|
const NUM_DIGITS: usize = 10;
|
|
|
|
|
|
+const MAP_DOT_ADDR: u8 = PCA9685_ADDR_2;
|
|
|
+const MAP_DOT_PIN: u8 = 15;
|
|
|
+
|
|
|
+const MAP_ADDR: usize = 0;
|
|
|
+const MAP_PIN: usize = 1;
|
|
|
+
|
|
|
struct DigitToPin {
|
|
|
address: u8,
|
|
|
pin: usize,
|
|
@@ -247,14 +247,14 @@ static TUBE_MAPPING: PwmOutputMap = {
|
|
|
};
|
|
|
|
|
|
#[derive(PartialEq)]
|
|
|
-enum DigitState {
|
|
|
+enum State {
|
|
|
Idle,
|
|
|
Incrementing,
|
|
|
Decrementing,
|
|
|
}
|
|
|
|
|
|
struct Digit {
|
|
|
- current_state: DigitState,
|
|
|
+ state: State,
|
|
|
value: u32,
|
|
|
pwm_start: u32,
|
|
|
pwm_end: u32,
|
|
@@ -264,7 +264,7 @@ struct Digit {
|
|
|
impl Digit {
|
|
|
const fn default() -> Self {
|
|
|
Self {
|
|
|
- current_state: DigitState::Idle,
|
|
|
+ state: State::Idle,
|
|
|
value: 0,
|
|
|
pwm_start: 0,
|
|
|
pwm_end: 0,
|
|
@@ -312,9 +312,6 @@ impl Clock {
|
|
|
static mut CLOCK: Clock = Clock::default();
|
|
|
|
|
|
pub fn fade_in_out_digit(tube: usize, digit: Option<usize>, fade_duration: u32, refresh_cmd: bool) {
|
|
|
- // assert!(tube < NUM_TUBES);
|
|
|
- // assert!(Some(digit) < NUM_DIGITS);
|
|
|
-
|
|
|
unsafe {
|
|
|
// If the tube is in the middle of a refresh sequence and a call comes
|
|
|
// in to update the tube digit (for time), override the last value of
|
|
@@ -328,14 +325,14 @@ pub fn fade_in_out_digit(tube: usize, digit: Option<usize>, fade_duration: u32,
|
|
|
// Fade out all digits
|
|
|
for digit in 0..NUM_DIGITS {
|
|
|
if CLOCK.tubes[tube].digits[digit].value != DIGIT_MIN_BRIGHTNESS {
|
|
|
- CLOCK.tubes[tube].digits[digit].current_state = DigitState::Decrementing;
|
|
|
+ CLOCK.tubes[tube].digits[digit].state = State::Decrementing;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// Fade in the specified digit
|
|
|
if let Some(digit) = digit {
|
|
|
if CLOCK.tubes[tube].digits[digit].value != DIGIT_MAX_BRIGHTNESS {
|
|
|
- CLOCK.tubes[tube].digits[digit].current_state = DigitState::Incrementing;
|
|
|
+ CLOCK.tubes[tube].digits[digit].state = State::Incrementing;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -379,7 +376,12 @@ where
|
|
|
)
|
|
|
}
|
|
|
if STARTUP || PREV_HOUR % 10 != hour % 10 {
|
|
|
- fade_in_out_digit(1, Some((hour % 10) as usize), DIGIT_FADE_DURATION_US, false);
|
|
|
+ fade_in_out_digit(
|
|
|
+ 1,
|
|
|
+ Some((hour % 10) as usize),
|
|
|
+ DIGIT_FADE_DURATION_US,
|
|
|
+ false
|
|
|
+ );
|
|
|
}
|
|
|
if STARTUP || PREV_MINUTE / 10 != minute / 10 {
|
|
|
fade_in_out_digit(
|
|
@@ -398,10 +400,10 @@ where
|
|
|
);
|
|
|
}
|
|
|
|
|
|
- CLOCK.dot.current_state = match second % 2 {
|
|
|
- 0 => DigitState::Incrementing,
|
|
|
- 1 => DigitState::Decrementing,
|
|
|
- _ => DigitState::Idle,
|
|
|
+ CLOCK.dot.state = match second % 2 {
|
|
|
+ 0 => State::Incrementing,
|
|
|
+ 1 => State::Decrementing,
|
|
|
+ _ => State::Idle,
|
|
|
};
|
|
|
|
|
|
PREV_MINUTE = minute;
|
|
@@ -431,11 +433,11 @@ where
|
|
|
|
|
|
CLOCK.tubes.iter_mut().for_each(|tube| {
|
|
|
tube.digits.iter_mut().for_each(|digit| {
|
|
|
- match digit.current_state {
|
|
|
- DigitState::Incrementing => {
|
|
|
+ match digit.state {
|
|
|
+ State::Incrementing => {
|
|
|
if digit.value >= DIGIT_MAX_BRIGHTNESS {
|
|
|
digit.value = DIGIT_MAX_BRIGHTNESS;
|
|
|
- digit.current_state = DigitState::Idle;
|
|
|
+ digit.state = State::Idle;
|
|
|
} else {
|
|
|
digit.value = digit
|
|
|
.value
|
|
@@ -445,10 +447,10 @@ where
|
|
|
pending_refresh = true;
|
|
|
}
|
|
|
}
|
|
|
- DigitState::Decrementing => {
|
|
|
+ State::Decrementing => {
|
|
|
if digit.value <= DIGIT_MIN_BRIGHTNESS {
|
|
|
digit.value = DIGIT_MIN_BRIGHTNESS;
|
|
|
- digit.current_state = DigitState::Idle;
|
|
|
+ digit.state = State::Idle;
|
|
|
} else {
|
|
|
digit.value = digit
|
|
|
.value
|
|
@@ -458,15 +460,15 @@ where
|
|
|
pending_refresh = true;
|
|
|
}
|
|
|
}
|
|
|
- DigitState::Idle => (),
|
|
|
+ State::Idle => (),
|
|
|
};
|
|
|
});
|
|
|
});
|
|
|
|
|
|
// Handle dot
|
|
|
let steps = ((DOT_MAX_BRIGHTNESS - DOT_MIN_BRIGHTNESS) + ticks - 1) / ticks;
|
|
|
- match CLOCK.dot.current_state {
|
|
|
- DigitState::Incrementing => {
|
|
|
+ match CLOCK.dot.state {
|
|
|
+ State::Incrementing => {
|
|
|
CLOCK.dot.value = CLOCK
|
|
|
.dot
|
|
|
.value
|
|
@@ -474,12 +476,12 @@ where
|
|
|
.clamp(DOT_MIN_BRIGHTNESS, DOT_MAX_BRIGHTNESS);
|
|
|
if CLOCK.dot.value >= DOT_MAX_BRIGHTNESS {
|
|
|
CLOCK.dot.value = DOT_MAX_BRIGHTNESS;
|
|
|
- CLOCK.dot.current_state = DigitState::Idle;
|
|
|
+ CLOCK.dot.state = State::Idle;
|
|
|
}
|
|
|
CLOCK.dot.updated = true;
|
|
|
pending_refresh = true;
|
|
|
}
|
|
|
- DigitState::Decrementing => {
|
|
|
+ State::Decrementing => {
|
|
|
CLOCK.dot.value = CLOCK
|
|
|
.dot
|
|
|
.value
|
|
@@ -487,12 +489,12 @@ where
|
|
|
.clamp(DOT_MIN_BRIGHTNESS, DOT_MAX_BRIGHTNESS);
|
|
|
if CLOCK.dot.value <= DOT_MIN_BRIGHTNESS {
|
|
|
CLOCK.dot.value = DOT_MIN_BRIGHTNESS;
|
|
|
- CLOCK.dot.current_state = DigitState::Idle;
|
|
|
+ CLOCK.dot.state = State::Idle;
|
|
|
}
|
|
|
CLOCK.dot.updated = true;
|
|
|
pending_refresh = true;
|
|
|
}
|
|
|
- DigitState::Idle => (),
|
|
|
+ State::Idle => (),
|
|
|
}
|
|
|
}
|
|
|
|