Browse Source

Added support for async refresh

Kevin Lee 5 years ago
parent
commit
ce5ce1efb0
2 changed files with 121 additions and 45 deletions
  1. 120 44
      Nixie_Firmware_Mbed/main.cpp
  2. 1 1
      Nixie_Firmware_Mbed/pca9685.cpp

+ 120 - 44
Nixie_Firmware_Mbed/main.cpp

@@ -10,10 +10,89 @@
 I2C i2c(PA_10, PA_9);
 // SWO_Channel swo("swo");
 
-bool Tick = false;
+bool RtcTick = false;
+bool RefreshTick = false;
 
 void RtcCallback(void) {
-    Tick = true;
+    RtcTick = true;
+}
+
+void RefreshCallback(void) {
+    RefreshTick = true;
+}
+
+typedef union {
+    struct {
+        char Hour10;
+        char Hour1;
+        char Minute10;
+        char Minute1;
+    };
+} DigitValue;
+
+DigitValue DigitPrev, DigitNext;
+int DigitNextValue[4][10] = {0};
+int DigitPrevValue[4][10] = {0};
+int DotNextValue, DotPrevValue;
+
+bool StartupFlag = true;
+bool RuntimeFlag = false;
+bool DotIncrement = false;
+
+Ticker StartupTicker;
+int StartupTickerIter = 1024;
+
+void StartupTickerCallback(void) {
+
+    DigitNextValue[3][DigitNext.Minute1] += 4;
+    DigitNextValue[2][DigitNext.Minute10] += 4;
+    DigitNextValue[1][DigitNext.Hour1] += 4;
+    if (DigitNext.Hour10 != 0) {
+        DigitNextValue[0][DigitNext.Hour10] += 4;
+    }
+    DotNextValue += 4;
+
+    if (--StartupTickerIter == 0) {
+        StartupTicker.detach();
+        memcpy(&DigitPrev, &DigitNext, sizeof(DigitValue));
+        RuntimeFlag = true;
+    }
+}
+
+Ticker RuntimeTicker;
+int RuntimeTickerIter = 1024;
+
+void RuntimeTickerCallback(void) {
+
+    if (DigitPrev.Minute1 != DigitNext.Minute1) {
+        DigitNextValue[3][DigitPrev.Minute1] -= 4;
+        DigitNextValue[3][DigitNext.Minute1] += 4;
+    }
+
+    if (DigitPrev.Minute10 != DigitNext.Minute10) {
+        DigitNextValue[2][DigitPrev.Minute10] -= 4;
+        DigitNextValue[2][DigitNext.Minute10] += 4;
+    }
+
+    if (DigitPrev.Hour1 != DigitNext.Hour1) {
+        DigitNextValue[1][DigitPrev.Hour1] -= 4;
+        DigitNextValue[1][DigitNext.Hour1] += 4;
+    }
+
+    if (DigitPrev.Hour10 != DigitNext.Hour10) {
+        DigitNextValue[0][DigitPrev.Hour10] -= 4;
+        if (DigitNext.Hour10 != 0) {
+            DigitNextValue[0][DigitNext.Hour10] += 4;
+        }
+    }
+
+    DotNextValue = DotIncrement ? DotNextValue + 4 : DotNextValue - 4;
+
+    if (--RuntimeTickerIter == 0) {
+        RuntimeTicker.detach();
+        memcpy(&DigitPrev, &DigitNext, sizeof(DigitValue));
+        DotIncrement = !DotIncrement;
+    }
 }
 
 int main() {
@@ -39,13 +118,13 @@ int main() {
     // Bump I2C frequency to 1MHz
     i2c.frequency(1000000);
 
+    // Setup a ticker to refresh the display at 1kHz
+    Ticker refreshTicker;
+    refreshTicker.attach_us(RefreshCallback, 1000);
+
     // DS3231_SetTime(0, 55, 6, true);
     // DS3231_SetDate(0, 2, 12, 18, 0);
 
-    int currMinute = 0, currHour = 0;
-    int nextSecond, nextMinute, nextHour;
-    int rngTick = 0;
-
     while(1) {
 
         // Animate_Cycle_Basic();
@@ -57,58 +136,55 @@ int main() {
         // Animate_Cycle_Fast();
         // Animate_Cycle_Fast_Random();
 
-        rngTick = rand() % 60;
-
-        if (Tick) {
-            
-            Tick = false;
-
-            rngTick--;
-            if (rngTick == 0) {
+        if (RefreshTick) {
 
+            RefreshTick = false;
 
+            // On refresh, update the display with new values
 
-                rngTick = rand() % 60;
+            for (int i = 0; i < 4; i++) {
+                for (int j = 0; j < 10; j++) {
+                    if (DigitNextValue[i][j] != DigitPrevValue[i][j]) {
+                        PCA9685_SetDigit(i, j, DigitNextValue[i][j]);
+                    }
+                }
+            }
+            if (DotNextValue != DotPrevValue) {
+                PCA9685_SetDot(DotNextValue);
             }
 
-            DS3231_GetTime(&nextSecond, &nextMinute, &nextHour);
+            memcpy(DigitPrevValue, DigitNextValue, sizeof(DigitPrevValue));
+            DotPrevValue = DotNextValue;
+        }
 
-            // Fade dot/digits to show the updated time
-            for (int i = 0; i < PCA9685_Max_Brightness; i += 4) {
+        if (RtcTick) {
+            
+            RtcTick = false;
 
-                if (nextMinute % 10 != currMinute % 10) {
-                    PCA9685_SetDigit(3, currMinute % 10, PCA9685_Max_Brightness - i);
-                    PCA9685_SetDigit(3, nextMinute % 10, PCA9685_Min_Brightness + i);
-                }
+            // On RTC 1Hz ticks, get the time and begin update
 
-                if (nextMinute / 10 != currMinute / 10) {
-                    PCA9685_SetDigit(2, currMinute / 10, PCA9685_Max_Brightness - i);
-                    PCA9685_SetDigit(2, nextMinute / 10, PCA9685_Min_Brightness + i);
-                }
+            int nextSecond, nextMinute, nextHour;
+            DS3231_GetTime(&nextSecond, &nextMinute, &nextHour);
 
-                if (nextHour % 10 != currHour % 10 ) {
-                    PCA9685_SetDigit(1, currHour % 10, PCA9685_Max_Brightness - i);
-                    PCA9685_SetDigit(1, nextHour % 10, PCA9685_Min_Brightness + i);
-                }
+            DigitNext.Minute1 = nextMinute % 10;
+            DigitNext.Minute10 = nextMinute / 10;
+            DigitNext.Hour1 = nextHour % 10;
+            DigitNext.Hour10 = nextHour / 10;
 
-                if (nextHour / 10 != currHour / 10) {
-                    PCA9685_SetDigit(0, currHour / 10, PCA9685_Max_Brightness - i);
-                    if (nextHour / 10 != 0) {
-                        PCA9685_SetDigit(0, nextHour / 10, PCA9685_Min_Brightness + i);
-                    }
-                }
+            if (StartupFlag) {
 
-                PCA9685_SetDot(nextSecond % 2 ? i : PCA9685_Max_Brightness - i);
+                // Fade in the current time
+                StartupTicker.attach_us(StartupTickerCallback, 900);
+                StartupFlag = false;
+            } 
 
-                wait(0.0007);
-            }
+            if (RuntimeFlag) {
 
-            currMinute = nextMinute;
-            currHour = nextHour;
+                // Fade in the new time
+                RuntimeTickerIter = 1024;
+                RuntimeTicker.attach_us(RuntimeTickerCallback, 900);
+            }
         }
-
-        // Delay a bit to avoid constant polling
-        wait(0.001);
     }
 }
 

+ 1 - 1
Nixie_Firmware_Mbed/pca9685.cpp

@@ -71,7 +71,7 @@ void PCA9685_SetDigit(int Tube, int Digit, int Brightness) {
 void PCA9685_SetDot(int Brightness) {
     LED_CTRL reg = {0};
 
-    Brightness /= 2;
+    Brightness /= 3;
     
     if (Brightness >= PCA9685_Max_Brightness) {
         reg.ON_FULL = 1;