Browse Source

Finished refresh functionality

Kevin Lee 5 years ago
parent
commit
dfceb45691
2 changed files with 68 additions and 48 deletions
  1. 61 40
      Nixie_Firmware_Mbed/main.cpp
  2. 7 8
      Nixie_Firmware_Mbed/main.h

+ 61 - 40
Nixie_Firmware_Mbed/main.cpp

@@ -10,8 +10,6 @@
 I2C i2c(PA_10, PA_9);
 // SWO_Channel swo("swo");
 
-bool RtcTick, RefreshTick, RngTick;
-
 typedef enum {
     Decrementing = 0,
     Incrementing = 1,
@@ -24,12 +22,14 @@ typedef struct {
 } Digit;
 
 typedef struct {
-    Digit Digits[10];
+    Digit Digits[NUM_DIGITS];
+    int LastActiveDigit;
+    int RefreshLastDigit;
     bool Refresh;
     int FadeDuration;
 } Tube;
 
-Tube Tubes[4];  // Active per-tube configuration
+Tube Tubes[NUM_TUBES];  // Active per-tube configuration
 Digit Dot;
 
 Timeout DotUpdateTimeout;
@@ -42,29 +42,30 @@ void DotUpdateCallback(void) {
     Dot.Updated = true;
 
     if (Dot.Value != DOT_MAX && Dot.Value != DOT_MIN) {
-        DotUpdateTimeout.attach_us(DotUpdateCallback, DOT_FADE_DURATION_US / REFRESH_RATE_US);
+        DotUpdateTimeout.attach_us(DotUpdateCallback, REFRESH_RATE_US);
     } 
 }
 
-// Macro the tube callback function as each callback needs to be defined as
+// Macro the per-tube callback function as each callback needs to be defined as
 // a unique function (callbacks cannot have arguments and are not reentrant)
 #define TUBE_CALLBACK(x) \
 void Tube##x##UpdateCallback(void) { \
-    int step = (DOT_MAX + (Tubes[x].FadeDuration / REFRESH_RATE_US) - 1) / (Tubes[x].FadeDuration / REFRESH_RATE_US); \
+    int ticks = Tubes[x].FadeDuration / REFRESH_RATE_US; \
+    int step = (DOT_MAX + ticks - 1) / ticks; \
     bool activeTube = false; \
-    for (int i = 0; i < 10; i++) { \
+    for (int i = 0; i < NUM_DIGITS; i++) { \
         Digit *digit = &Tubes[x].Digits[i]; \
-        if (digit->CurrentState == Incrementing && digit->Value < DIGIT_MAX) { \
+        if (digit->CurrentState == Incrementing && digit->Value <= DIGIT_MAX) { \
             digit->Value = (digit->Value + step >= DIGIT_MAX) ? DIGIT_MAX : digit->Value + step; \
             digit->Updated = true; \
-        } else if (digit->CurrentState == Decrementing && digit->Value > DOT_MIN) { \
+        } else if (digit->CurrentState == Decrementing && digit->Value >= DOT_MIN) { \
             digit->Value = (digit->Value - step <= DIGIT_MIN) ? DIGIT_MIN : digit->Value - step; \
             digit->Updated = true; \
         } \
         activeTube |= (digit->Value != DIGIT_MAX && digit->Value != DIGIT_MIN); \
     } \
     if (activeTube) { \
-        Tube##x##UpdateTimeout.attach_us(Tube##x##UpdateCallback, DIGIT_FADE_DURATION_US / REFRESH_RATE_US); \
+        Tube##x##UpdateTimeout.attach_us(Tube##x##UpdateCallback, REFRESH_RATE_US); \
     } \
 } 
 
@@ -78,58 +79,77 @@ Timeout Tube3UpdateTimeout;
 TUBE_CALLBACK(3)
 
 void FadeInOutDigit(int T, int D, int Duration) {
-    for (int i = 0; i < 10; i++) {
+    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, DIGIT_FADE_DURATION_US / REFRESH_RATE_US);
+        Tube0UpdateTimeout.attach_us(Tube0UpdateCallback, REFRESH_RATE_US);
     } else if (T == 1) {
-        Tube1UpdateTimeout.attach_us(Tube1UpdateCallback, DIGIT_FADE_DURATION_US / REFRESH_RATE_US);
+        Tube1UpdateTimeout.attach_us(Tube1UpdateCallback, REFRESH_RATE_US);
     } else if (T == 2) {
-        Tube2UpdateTimeout.attach_us(Tube2UpdateCallback, DIGIT_FADE_DURATION_US / REFRESH_RATE_US);
+        Tube2UpdateTimeout.attach_us(Tube2UpdateCallback, REFRESH_RATE_US);
     } else if (T == 3) {
-        Tube3UpdateTimeout.attach_us(Tube3UpdateCallback, DIGIT_FADE_DURATION_US / REFRESH_RATE_US);
+        Tube3UpdateTimeout.attach_us(Tube3UpdateCallback, REFRESH_RATE_US);
     } 
 }
 
-Ticker RefreshTicker, RngUpdateTicker;
-int RngTickerIter;
-void RngTickerUpdate(void) {
-
-
-    if (--RngTickerIter == 0) {
-        RngUpdateTicker.detach();
-    }
-}
+bool RtcTick, RefreshTick, RngTick;
+Ticker RefreshTicker, RngRefreshTicker;
 
 // Callback from DS3231 interrupt (1Hz)
-void RtcTickCallback(void) {
+void RtcInterruptCallback(void) {
     RtcTick = true;
 }
 
 // Callback from RefreshTicker (REFRESH_RATE_US)
-void RefreshTickCallback(void) {
+void RefreshTickerCallback(void) {
     RefreshTick = true;
 }
 
-void RngTickCallback(void) {
+void RngTickerCallback(void) {
     RngTick = true;
 }
 
+Timeout RngUpdateTimeout;
+int RngUpdateIteration;
+void RngUpdateCallback(void) {
+    for (int i = 0; i < NUM_TUBES; i++) {
+        if (Tubes[i].Refresh) {
+            if (RngUpdateIteration) {
+                int nextDigit;
+                do {
+                    nextDigit = rand() % NUM_DIGITS;
+                } while (nextDigit == Tubes[i].LastActiveDigit || 
+                    (RngUpdateIteration == 1 && nextDigit == Tubes[i].RefreshLastDigit));
+
+                FadeInOutDigit(i, nextDigit, DIGIT_RNG_FADE_DURATION_US);
+            } else {
+                FadeInOutDigit(i, Tubes[i].RefreshLastDigit, DIGIT_RNG_FADE_DURATION_US);
+                Tubes[i].Refresh = false;
+            }
+        }
+    }
+    if (RngUpdateIteration-- != 0) {
+        RngUpdateTimeout.attach_us(RngUpdateCallback, DIGIT_RNG_FADE_DURATION_US);
+    }
+}
+
 int main() {
 
     // Initialize pointers in global data structure
     for (int i = 0; i < NUM_TUBES; i++) {
-        for (int j = 0; j < 10; j++) {
+        for (int j = 0; j < NUM_DIGITS; j++) {
             Tubes[i].Digits[j].CurrentState = Decrementing;
             Tubes[i].Digits[j].Value = 0;
             Tubes[i].Digits[j].Updated = false;
         }
+        Tubes[i].LastActiveDigit = -1;
         Tubes[i].Refresh = false;
         Tubes[i].FadeDuration = 0;
     }
@@ -154,7 +174,7 @@ int main() {
     
     TUSB322_Init();
     PCA9685_Init();
-    DS3231_Init(RtcTickCallback);
+    DS3231_Init(RtcInterruptCallback);
 
     // Enable HV PSU
     HV_EnableOutput(true);
@@ -168,11 +188,10 @@ int main() {
     // i2c.frequency(1000000);
 
     // Setup a ticker to refresh the display at 1kHz
-    RefreshTicker.attach_us(RefreshTickCallback, REFRESH_RATE_US);
+    RefreshTicker.attach_us(RefreshTickerCallback, REFRESH_RATE_US);
 
     // Kick off the RNG ticker at 0.1Hz
-    // Ticker rngTicker;
-    // rngTicker.attach(RngTickCallback, DIGIT_RNG_REFRESH_RATE_S);
+    RngRefreshTicker.attach(RngTickerCallback, DIGIT_RNG_REFRESH_RATE);
 
     // DS3231_SetTime(0, 55, 6, true);
     // DS3231_SetDate(0, 2, 12, 18, 0);
@@ -192,8 +211,8 @@ int main() {
         if (RefreshTick) {
             RefreshTick = false;
 
-            for (int i = 0; i < 4; i++) {
-                for (int j = 0; j < 10; j++) {
+            for (int i = 0; i < NUM_TUBES; i++) {
+                for (int j = 0; j < NUM_DIGITS; j++) {
                     if (Tubes[i].Digits[j].Updated) {
                         PCA9685_SetDigit(i, j, Tubes[i].Digits[j].Value);
                         Tubes[i].Digits[j].Updated = false;
@@ -239,13 +258,15 @@ int main() {
         }
 
         if (RngTick) {
+            RngTick = false;
+
+            int refreshTube = rand() % NUM_TUBES;
 
-            // Choose a random tube to refresh
-            // Tube[rand() % 4].RefreshActive = true;
+            Tubes[refreshTube].RefreshLastDigit = Tubes[refreshTube].LastActiveDigit;
+            Tubes[refreshTube].Refresh = true;
 
-            // RngTickerIter = DIGIT_RNG_REFRESH_ITER * FADE_TICKS;
-            // RngUpdateTicker.attach(RngTickerUpdate, (DIGIT_REFRESH_RATE_US/1000)/FADE_TICKS);
-            // RngTick = false;
+            RngUpdateIteration = DIGIT_RNG_FADE_ITERATIONS;
+            RngUpdateCallback();
         }
     }
 }

+ 7 - 8
Nixie_Firmware_Mbed/main.h

@@ -13,27 +13,26 @@
 
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
 
-#define NUM_TUBES 4
-#define MAX_FADE_DIGITS 2
-
 #define I2C_MAX_BUFFER 20
 
+#define NUM_TUBES 4
+#define NUM_DIGITS 10
+
 #define REFRESH_RATE_US 1000  
 
 #define DOT_MIN PCA9685_Min_Brightness
 #define DOT_MAX PCA9685_Max_Brightness
-#define DOT_FADE_DURATION_US 900000
+#define DOT_FADE_DURATION_US 1000000
 #define DOT_FADE_TICK (DOT_FADE_DURATION_US / REFRESH_RATE_US)
 #define DOT_FADE_STEP ((DOT_MAX + DOT_FADE_TICK - 1) / DOT_FADE_TICK)
 
 #define DIGIT_MIN PCA9685_Min_Brightness
 #define DIGIT_MAX PCA9685_Max_Brightness
 #define DIGIT_FADE_DURATION_US 1000000
-// #define DIGIT_FADE_TICK (DOT_FADE_DURATION_US / REFRESH_RATE_US)
-// #define DIGIT_FADE_STEP ((DOT_MAX + DIGIT_FADE_TICK - 1) / DIGIT_FADE_TICK)
 
-#define DIGIT_RNG_REFRESH_RATE_S 30
-#define DIGIT_RNG_REFRESH_ITER 20
+#define DIGIT_RNG_FADE_DURATION_US 100000
+#define DIGIT_RNG_FADE_ITERATIONS 20
+#define DIGIT_RNG_REFRESH_RATE 10 
 
 void I2C_Write(int DeviceAddress, char RegAddress, char *Data, int Length);
 void I2C_Read(int DeviceAddress, char RegAddress, char *Data, int Length);