|
@@ -25,7 +25,7 @@ typedef struct {
|
|
|
Digit Digits[NUM_DIGITS];
|
|
|
int LastActiveDigit;
|
|
|
int RefreshLastDigit;
|
|
|
- bool Refresh;
|
|
|
+ bool RefreshActive;
|
|
|
int FadeDuration;
|
|
|
} Tube;
|
|
|
|
|
@@ -78,36 +78,42 @@ TUBE_CALLBACK(2)
|
|
|
Timeout Tube3UpdateTimeout;
|
|
|
TUBE_CALLBACK(3)
|
|
|
|
|
|
-void FadeInOutDigit(int T, int D, int Duration, bool HighPrio = false) {
|
|
|
- for (int i = 0; i < NUM_DIGITS; i++) {
|
|
|
- Tubes[T].Digits[i].CurrentState = Decrementing;
|
|
|
- }
|
|
|
- if (D != -1) {
|
|
|
- Tubes[T].Digits[D].CurrentState = Incrementing;
|
|
|
- }
|
|
|
- Tubes[T].FadeDuration = Duration;
|
|
|
- Tubes[T].LastActiveDigit = D;
|
|
|
+void FadeInOutDigit(int T, int D, int Duration, bool RngUpdate = false) {
|
|
|
|
|
|
// 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
|
|
|
// the refresh sequence with the new digit.
|
|
|
- if (Tubes[T].Refresh && HighPrio) {
|
|
|
+ if (Tubes[T].RefreshActive && !RngUpdate) {
|
|
|
Tubes[T].RefreshLastDigit = D;
|
|
|
}
|
|
|
|
|
|
- if (T == 0) {
|
|
|
- Tube0UpdateTimeout.attach_us(Tube0UpdateCallback, REFRESH_RATE_US);
|
|
|
- } else if (T == 1) {
|
|
|
- Tube1UpdateTimeout.attach_us(Tube1UpdateCallback, REFRESH_RATE_US);
|
|
|
- } else if (T == 2) {
|
|
|
- Tube2UpdateTimeout.attach_us(Tube2UpdateCallback, REFRESH_RATE_US);
|
|
|
- } else if (T == 3) {
|
|
|
- Tube3UpdateTimeout.attach_us(Tube3UpdateCallback, REFRESH_RATE_US);
|
|
|
- }
|
|
|
+ // Dont update if actively refreshing tube unless RngUpdate is set
|
|
|
+ if ((!RngUpdate && !Tubes[T].RefreshActive) || (RngUpdate)) {
|
|
|
+ for (int i = 0; i < NUM_DIGITS; i++) {
|
|
|
+ Tubes[T].Digits[i].CurrentState = Decrementing;
|
|
|
+ }
|
|
|
+ if (D != -1) {
|
|
|
+ Tubes[T].Digits[D].CurrentState = Incrementing;
|
|
|
+ }
|
|
|
+
|
|
|
+ Tubes[T].FadeDuration = Duration;
|
|
|
+ Tubes[T].LastActiveDigit = D;
|
|
|
+
|
|
|
+ if (T == 0) {
|
|
|
+ Tube0UpdateTimeout.attach_us(Tube0UpdateCallback, REFRESH_RATE_US);
|
|
|
+ } else if (T == 1) {
|
|
|
+ Tube1UpdateTimeout.attach_us(Tube1UpdateCallback, REFRESH_RATE_US);
|
|
|
+ } else if (T == 2) {
|
|
|
+ Tube2UpdateTimeout.attach_us(Tube2UpdateCallback, REFRESH_RATE_US);
|
|
|
+ } else if (T == 3) {
|
|
|
+ Tube3UpdateTimeout.attach_us(Tube3UpdateCallback, REFRESH_RATE_US);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
bool RtcTick, RefreshTick, RngTick;
|
|
|
-Ticker RefreshTicker, RngRefreshTicker;
|
|
|
+Ticker RefreshTicker;
|
|
|
+Timeout RngRefreshTimeout;
|
|
|
|
|
|
// Callback from DS3231 interrupt (1Hz)
|
|
|
void RtcInterruptCallback(void) {
|
|
@@ -126,21 +132,26 @@ void RngTickerCallback(void) {
|
|
|
Timeout RngUpdateTimeout;
|
|
|
int RngUpdateIteration;
|
|
|
void RngUpdateCallback(void) {
|
|
|
- int newfadeDuration = DIGIT_RNG_FADE_DURATION_US + RngUpdateIteration * DIGIT_RNG_FADE_DURATION_US;
|
|
|
- if (newfadeDuration >= DIGIT_FADE_DURATION_US) newfadeDuration = DIGIT_FADE_DURATION_US;
|
|
|
+ int newfadeDuration = DIGIT_FADE_DURATION_US - RngUpdateIteration * DIGIT_RNG_FADE_DURATION_US;
|
|
|
+ if (newfadeDuration <= DIGIT_RNG_FADE_DURATION_US) newfadeDuration = DIGIT_RNG_FADE_DURATION_US;
|
|
|
for (int i = 0; i < NUM_TUBES; i++) {
|
|
|
- if (Tubes[i].Refresh) {
|
|
|
+ if (Tubes[i].RefreshActive) {
|
|
|
if (RngUpdateIteration) {
|
|
|
int nextDigit;
|
|
|
+#ifdef REFRESH_SEQUENTIAL
|
|
|
+ nextDigit = (Tubes[i].LastActiveDigit >= 9 || Tubes[i].LastActiveDigit < 0) ?
|
|
|
+ 0 : Tubes[i].LastActiveDigit + 1;;
|
|
|
+#endif
|
|
|
+#ifdef REFRESH_RANDOM
|
|
|
do {
|
|
|
nextDigit = rand() % NUM_DIGITS;
|
|
|
} while (nextDigit == Tubes[i].LastActiveDigit ||
|
|
|
(RngUpdateIteration == 1 && nextDigit == Tubes[i].RefreshLastDigit));
|
|
|
-
|
|
|
- FadeInOutDigit(i, nextDigit, newfadeDuration);
|
|
|
+#endif
|
|
|
+ FadeInOutDigit(i, nextDigit, newfadeDuration, true);
|
|
|
} else {
|
|
|
- FadeInOutDigit(i, Tubes[i].RefreshLastDigit, newfadeDuration);
|
|
|
- Tubes[i].Refresh = false;
|
|
|
+ FadeInOutDigit(i, Tubes[i].RefreshLastDigit, newfadeDuration, true);
|
|
|
+ Tubes[i].RefreshActive = false;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -159,7 +170,8 @@ int main() {
|
|
|
Tubes[i].Digits[j].Updated = false;
|
|
|
}
|
|
|
Tubes[i].LastActiveDigit = -1;
|
|
|
- Tubes[i].Refresh = false;
|
|
|
+ Tubes[i].RefreshLastDigit = -1;
|
|
|
+ Tubes[i].RefreshActive = true;
|
|
|
Tubes[i].FadeDuration = 0;
|
|
|
}
|
|
|
|
|
@@ -199,12 +211,16 @@ int main() {
|
|
|
// Setup a ticker to refresh the display at 1kHz
|
|
|
RefreshTicker.attach_us(RefreshTickerCallback, REFRESH_RATE_US);
|
|
|
|
|
|
- // Kick off the RNG ticker at 0.1Hz
|
|
|
- RngRefreshTicker.attach(RngTickerCallback, DIGIT_RNG_REFRESH_RATE);
|
|
|
+ // Kick off the RNG timeout
|
|
|
+ int nextRngTimeout = DIGIT_RNG_REFRESH_INTERVAL + (rand() % DIGIT_RNG_REFRESH_VARIANCE);
|
|
|
+ RngRefreshTimeout.attach(RngTickerCallback, nextRngTimeout);
|
|
|
|
|
|
// DS3231_SetTime(0, 55, 6, true);
|
|
|
// DS3231_SetDate(0, 2, 12, 18, 0);
|
|
|
|
|
|
+ RngUpdateIteration = DIGIT_RNG_FADE_ITERATIONS;
|
|
|
+ RngUpdateCallback();
|
|
|
+
|
|
|
while(1) {
|
|
|
|
|
|
// Animate_Cycle_Basic();
|
|
@@ -247,16 +263,16 @@ int main() {
|
|
|
|
|
|
// Update the display configuration based on the new/previous time
|
|
|
if (startup || prevHour / 10 != nextHour / 10) {
|
|
|
- FadeInOutDigit(0, (nextHour / 10 != 0) ? nextHour / 10 : -1 , DIGIT_FADE_DURATION_US, true);
|
|
|
+ FadeInOutDigit(0, (nextHour / 10 != 0) ? nextHour / 10 : -1 , DIGIT_FADE_DURATION_US);
|
|
|
}
|
|
|
if (startup || prevHour % 10 != nextHour % 10) {
|
|
|
- FadeInOutDigit(1, nextHour % 10, DIGIT_FADE_DURATION_US, true);
|
|
|
+ FadeInOutDigit(1, nextHour % 10, DIGIT_FADE_DURATION_US);
|
|
|
}
|
|
|
if (startup || prevMinute / 10 != nextMinute / 10) {
|
|
|
- FadeInOutDigit(2, nextMinute / 10, DIGIT_FADE_DURATION_US, true);
|
|
|
+ FadeInOutDigit(2, nextMinute / 10, DIGIT_FADE_DURATION_US);
|
|
|
}
|
|
|
if (startup || prevMinute % 10 != nextMinute % 10) {
|
|
|
- FadeInOutDigit(3, nextMinute % 10, DIGIT_FADE_DURATION_US, true);
|
|
|
+ FadeInOutDigit(3, nextMinute % 10, DIGIT_FADE_DURATION_US);
|
|
|
}
|
|
|
|
|
|
Dot.CurrentState = (Dot.CurrentState == Decrementing) ? Incrementing : Decrementing;
|
|
@@ -269,13 +285,15 @@ int main() {
|
|
|
if (RngTick) {
|
|
|
RngTick = false;
|
|
|
|
|
|
- int refreshTube = rand() % NUM_TUBES;
|
|
|
-
|
|
|
+ int refreshTube = rand() % NUM_TUBES;
|
|
|
Tubes[refreshTube].RefreshLastDigit = Tubes[refreshTube].LastActiveDigit;
|
|
|
- Tubes[refreshTube].Refresh = true;
|
|
|
+ Tubes[refreshTube].RefreshActive = true;
|
|
|
|
|
|
RngUpdateIteration = DIGIT_RNG_FADE_ITERATIONS;
|
|
|
RngUpdateCallback();
|
|
|
+
|
|
|
+ nextRngTimeout = DIGIT_RNG_REFRESH_INTERVAL + (rand() % DIGIT_RNG_REFRESH_VARIANCE);
|
|
|
+ RngRefreshTimeout.attach(RngTickerCallback, nextRngTimeout);
|
|
|
}
|
|
|
}
|
|
|
}
|