|
@@ -14,21 +14,25 @@ bool RtcTick, RefreshTick, RngTick;
|
|
|
bool StartupFlag, RuntimeFlag;
|
|
|
|
|
|
typedef struct {
|
|
|
- char PrevDigit;
|
|
|
- ushort PrevValue;
|
|
|
- char NextDigit;
|
|
|
- ushort NextValue;
|
|
|
+ char DigitA;
|
|
|
+ ushort DigitAValue;
|
|
|
+ char DigitB;
|
|
|
+ ushort DigitBValue;
|
|
|
+ bool DigitBActive;
|
|
|
+ bool Updated;
|
|
|
bool RefreshActive;
|
|
|
-} Digit;
|
|
|
+} TUBE;
|
|
|
|
|
|
-Digit Digits[NUM_DIGITS] = {0};
|
|
|
+TUBE Display[NUM_TUBES] = {0};
|
|
|
|
|
|
-int DotNextValue, DotPrevValue;
|
|
|
+int DotValue;
|
|
|
+bool DotUpdated = false;;
|
|
|
bool DotIncrement = false;
|
|
|
|
|
|
Ticker StartupUpdateTicker, RuntimeUpdateTicker, RngUpdateTicker;
|
|
|
int StartupTickerIter, RuntimeTickerIter, RngTickerIter;
|
|
|
|
|
|
+
|
|
|
void RtcTickCallback(void) {
|
|
|
RtcTick = true;
|
|
|
}
|
|
@@ -43,18 +47,18 @@ void RngTickCallback(void) {
|
|
|
|
|
|
void StartupTickerUpdate(void) {
|
|
|
|
|
|
- for (int i = 0; i < NUM_DIGITS; i++) {
|
|
|
- if (!Digits[i].RefreshActive) {
|
|
|
- Digits[i].NextValue = (i == 0 && Digits[i].NextDigit == 0) ? 0 : Digits[i].NextValue + FADE_TICK_STEP;
|
|
|
- }
|
|
|
+ for (int i = 0; i < NUM_TUBES; i++) {
|
|
|
+ Display[i].DigitAValue = (i == 0 && Display[i].DigitA == 0) ? 0 : Display[i].DigitAValue + FADE_TICK_STEP;
|
|
|
+ Display[i].Updated = true;
|
|
|
}
|
|
|
|
|
|
- DotNextValue += FADE_TICK_STEP;
|
|
|
+ DotValue += FADE_TICK_STEP;
|
|
|
+ DotUpdated = true;
|
|
|
|
|
|
if (--StartupTickerIter == 0) {
|
|
|
StartupUpdateTicker.detach();
|
|
|
- for (int i = 0; i < NUM_DIGITS; i++) {
|
|
|
- Digits[i].PrevDigit = Digits[i].NextDigit;
|
|
|
+ for (int i = 0; i < NUM_TUBES; i++) {
|
|
|
+ Display[i].DigitBActive = !Display[i].DigitBActive;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -64,19 +68,33 @@ void StartupTickerUpdate(void) {
|
|
|
|
|
|
void RuntimeTickerUpdate(void) {
|
|
|
|
|
|
- for (int i = 0; i < NUM_DIGITS; i++) {
|
|
|
- if(!Digits[i].RefreshActive && Digits[i].PrevDigit != Digits[i].NextDigit) {
|
|
|
- Digits[i].PrevValue -= FADE_TICK_STEP;
|
|
|
- Digits[i].NextValue = (i == 0 && Digits[i].NextDigit == 0) ? 0 : Digits[i].NextValue + FADE_TICK_STEP;
|
|
|
+ for (int i = 0; i < NUM_TUBES; i++) {
|
|
|
+ if(!Display[i].RefreshActive) {
|
|
|
+
|
|
|
+ if (Display[i].DigitA != Display[i].DigitB) {
|
|
|
+
|
|
|
+ if (Display[i].DigitBActive) {
|
|
|
+ Display[i].DigitAValue -= FADE_TICK_STEP;
|
|
|
+ Display[i].DigitBValue = (i == 0 && Display[i].DigitB == 0) ? 0 : Display[i].DigitBValue + FADE_TICK_STEP;
|
|
|
+ } else {
|
|
|
+ Display[i].DigitBValue -= FADE_TICK_STEP;
|
|
|
+ Display[i].DigitAValue = (i == 0 && Display[i].DigitA == 0) ? 0 : Display[i].DigitAValue + FADE_TICK_STEP;
|
|
|
+ }
|
|
|
+
|
|
|
+ Display[i].Updated = true;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- DotNextValue = DotIncrement ? DotNextValue + FADE_TICK_STEP: DotNextValue - FADE_TICK_STEP;
|
|
|
+ DotValue = DotIncrement ? DotValue + FADE_TICK_STEP: DotValue - FADE_TICK_STEP;
|
|
|
+ DotUpdated = true;
|
|
|
|
|
|
if (--RuntimeTickerIter == 0) {
|
|
|
RuntimeUpdateTicker.detach();
|
|
|
- for (int i = 0; i < NUM_DIGITS; i++) {
|
|
|
- Digits[i].PrevDigit = Digits[i].NextDigit;
|
|
|
+ for (int i = 0; i < NUM_TUBES; i++) {
|
|
|
+ if (Display[i].DigitA != Display[i].DigitB) {
|
|
|
+ Display[i].DigitBActive = !Display[i].DigitBActive;
|
|
|
+ }
|
|
|
}
|
|
|
DotIncrement = !DotIncrement;
|
|
|
}
|
|
@@ -124,8 +142,8 @@ int main() {
|
|
|
refreshTicker.attach_us(RefreshTickCallback, DIGIT_REFRESH_RATE_US);
|
|
|
|
|
|
|
|
|
- Ticker rngTicker;
|
|
|
- rngTicker.attach(RngTickCallback, DIGIT_RNG_REFRESH_RATE_S);
|
|
|
+
|
|
|
+
|
|
|
|
|
|
|
|
|
|
|
@@ -142,50 +160,61 @@ int main() {
|
|
|
|
|
|
|
|
|
if (RefreshTick) {
|
|
|
-
|
|
|
RefreshTick = false;
|
|
|
|
|
|
|
|
|
|
|
|
-
|
|
|
- for (int i = 0; i < NUM_DIGITS; i++) {
|
|
|
- if (Digits[i].NextValue != Digits[i].PrevValue) {
|
|
|
- PCA9685_SetDigit(i, Digits[i].PrevDigit, Digits[i].PrevValue);
|
|
|
- PCA9685_SetDigit(i, Digits[i].NextDigit, Digits[i].NextValue);
|
|
|
+
|
|
|
+ for (int i = 0; i < NUM_TUBES; i++) {
|
|
|
+ if (Display[i].Updated) {
|
|
|
+ PCA9685_SetDigit(i, Display[i].DigitA, Display[i].DigitAValue);
|
|
|
+ PCA9685_SetDigit(i, Display[i].DigitB, Display[i].DigitBValue);
|
|
|
+ Display[i].Updated = false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (DotNextValue != DotPrevValue) {
|
|
|
- PCA9685_SetDot(DotNextValue);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- for (int i = 0; i < NUM_DIGITS; i++) {
|
|
|
- Digits[i].PrevValue = Digits[i].NextValue;
|
|
|
+ if (DotUpdated) {
|
|
|
+ PCA9685_SetDot(DotValue);
|
|
|
+ DotUpdated = false;
|
|
|
}
|
|
|
- DotPrevValue = DotNextValue;
|
|
|
}
|
|
|
|
|
|
if (RtcTick) {
|
|
|
-
|
|
|
RtcTick = false;
|
|
|
|
|
|
|
|
|
-
|
|
|
int nextSecond, nextMinute, nextHour;
|
|
|
DS3231_GetTime(&nextSecond, &nextMinute, &nextHour);
|
|
|
|
|
|
- Digits[3].NextDigit = nextMinute % 10;
|
|
|
- Digits[2].NextDigit = nextMinute / 10;
|
|
|
- Digits[1].NextDigit = nextHour % 10;
|
|
|
- Digits[0].NextDigit = nextHour / 10;
|
|
|
+ if (Display[3].DigitBActive) {
|
|
|
+ Display[3].DigitB = nextMinute % 10;
|
|
|
+ } else {
|
|
|
+ Display[3].DigitA = nextMinute % 10;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Display[2].DigitBActive) {
|
|
|
+ Display[2].DigitB = nextMinute / 10;
|
|
|
+ } else {
|
|
|
+ Display[2].DigitA = nextMinute / 10;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Display[1].DigitBActive) {
|
|
|
+ Display[1].DigitB = nextHour % 10;
|
|
|
+ } else {
|
|
|
+ Display[1].DigitA = nextHour % 10;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Display[0].DigitBActive) {
|
|
|
+ Display[0].DigitB = nextHour / 10;
|
|
|
+ } else {
|
|
|
+ Display[0].DigitA = nextHour / 10;
|
|
|
+ }
|
|
|
|
|
|
if (StartupFlag) {
|
|
|
|
|
|
|
|
|
StartupTickerIter = FADE_TICKS;
|
|
|
- StartupUpdateTicker.attach(StartupTickerUpdate, (DIGIT_REFRESH_RATE_US/1000)/StartupTickerIter);
|
|
|
+ StartupUpdateTicker.attach(StartupTickerUpdate, (float)(DIGIT_REFRESH_RATE_US / 1000) / StartupTickerIter);
|
|
|
StartupFlag = false;
|
|
|
}
|
|
|
|
|
@@ -193,14 +222,14 @@ int main() {
|
|
|
|
|
|
|
|
|
RuntimeTickerIter = FADE_TICKS;
|
|
|
- RuntimeUpdateTicker.attach(RuntimeTickerUpdate, (DIGIT_REFRESH_RATE_US/1000)/RuntimeTickerIter);
|
|
|
+ RuntimeUpdateTicker.attach(RuntimeTickerUpdate, (float)(DIGIT_REFRESH_RATE_US / 1000) / RuntimeTickerIter);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (RngTick) {
|
|
|
|
|
|
|
|
|
- Digits[rand() % 4].RefreshActive = true;
|
|
|
+ Display[rand() % 4].RefreshActive = true;
|
|
|
|
|
|
RngTickerIter = DIGIT_RNG_REFRESH_ITER * FADE_TICKS;
|
|
|
RngUpdateTicker.attach(RngTickerUpdate, (DIGIT_REFRESH_RATE_US/1000)/FADE_TICKS);
|