Browse Source

Added rev. B and DST support

Kevin Lee 5 years ago
parent
commit
39ce26d4f9

+ 26 - 3
Nixie_Firmware_Mbed/ds3231.cpp

@@ -27,14 +27,13 @@ void DS3231_Init(void (*Callback)()) {
     IO_Rtc.rise(Callback);
 }
 
-void DS3231_SetTime(int Second, int Minute, int Hour, bool PM) {
+void DS3231_SetTime(int Second, int Minute, int Hour) {
     DS3231_REGS regs = {0};
 
     regs.Second.Value = DecimalToBCD(Second);
     regs.Minute.Value = DecimalToBCD(Minute);
     regs.Hour.Value = DecimalToBCD(Hour);
-    regs.Hour.nAM = PM;
-    regs.Hour.n24 = 1;
+    regs.Hour.n24 = 0;
 
     I2C_Write(DS3231_ADDR, FIELD_OFFSET(DS3231_REGS, Second),
         regs.AS_BYTE + FIELD_OFFSET(DS3231_REGS, Second),
@@ -66,3 +65,27 @@ void DS3231_GetTime(int *Second, int *Minute, int *Hour) {
     *Minute = BCDToDecimal(regs.Minute.Value);
     *Hour = BCDToDecimal(regs.Hour.Value);
 }
+
+void DS3231_GetDate(int *Day, int *Date, int *Month, int *Year) {
+    DS3231_REGS regs = {0};
+
+    I2C_Read(DS3231_ADDR, FIELD_OFFSET(DS3231_REGS, Day),
+        regs.AS_BYTE + FIELD_OFFSET(DS3231_REGS, Day),
+        FIELD_SIZE_THROUGH(DS3231_REGS, Day, Year));
+
+    *Day = BCDToDecimal(regs.Day.Value);
+    *Date = BCDToDecimal(regs.Date.Value);
+    *Month = BCDToDecimal(regs.Month.Value);
+    *Year = BCDToDecimal(regs.Year.Value);
+}
+
+bool IsDst(int Day, int Date, int Month, int Hour_24) {
+    // December through Feburary are always outside DST
+    if (Month < 3 || Month > 11) return false;
+    // April through October are always in DST
+    if (Month > 3 && Month < 11) return true;
+    // In March, in DST if previous sunday was on or after the 8th
+    if (Month == 3) return ((Date - Day) >= 8) && (Hour_24 >= 2);
+    // In November, in DST if before the first Sunday
+    return ((Date - Day) <= 0) && (Hour_24 < 2);
+}

+ 15 - 5
Nixie_Firmware_Mbed/ds3231.h

@@ -21,8 +21,7 @@ typedef union {
 
 typedef union {
     struct {
-        char Value : 5;
-        char nAM   : 1;
+        char Value : 6;
         char n24   : 1;
         char       : 1;
     };
@@ -79,8 +78,7 @@ typedef union {
 
 typedef union {
     struct {
-        char Value : 5;
-        char nAM   : 1;
+        char Value : 6;
         char n24   : 1;
         char M3    : 1;
     };
@@ -171,9 +169,21 @@ typedef union {
     char AS_BYTE[0x13];
 } DS3231_REGS;
 
+enum {
+    SUNDAY      = 0,
+    MONDAY      = 1,
+    TUESDAY     = 2,
+    WEDNESDAY   = 3,
+    THURSDAY    = 4,
+    FRIDAY      = 5,
+    SATURDAY    = 6
+};
+
 void DS3231_Init(void (*Callback)());
-void DS3231_SetTime(int Second, int Minute, int Hour, bool PM);
+void DS3231_SetTime(int Second, int Minute, int Hour);
 void DS3231_SetDate(int Day, int Date, int Month, int Year, int Century);
 void DS3231_GetTime(int *Second, int *Minute, int *Hour);
+void DS3231_GetDate(int *Day, int *Date, int *Month, int *Year);
+bool IsDst(int Day, int Date, int Month, int Hour_24);
 
 #endif

+ 4 - 0
Nixie_Firmware_Mbed/ioc.cpp

@@ -4,7 +4,11 @@
 
 InterruptIn IO_nFault(PA_3);
 DigitalOut  IO_HvEn(PA_2);
+#ifdef REVISION_A
 DigitalOut  IO_LED(PB_6);
+#else
+DigitalOut  IO_LED(PC_15);
+#endif
 AnalogIn    IO_Imon(PA_0);
 AnalogIn    IO_Vout(PA_1);
 

+ 14 - 2
Nixie_Firmware_Mbed/main.cpp

@@ -9,6 +9,9 @@
 
 I2C i2c(PA_10, PA_9);
 // SWO_Channel swo("swo");
+#ifdef REVISION_B
+Serial serial(PB_6, PB_7);
+#endif
 
 typedef enum {
     Decrementing = 0,
@@ -164,6 +167,10 @@ void RngUpdateCallback(void) {
 
 int main() {
 
+#ifdef REVISION_B
+    serial.baud(115200);
+#endif
+
     // Initialize pointers in global data structure
     for (int i = 0; i < NUM_TUBES; i++) {
         for (int j = 0; j < NUM_DIGITS; j++) {
@@ -187,6 +194,7 @@ int main() {
 
     int nextSecond, nextMinute, nextHour;
     int prevMinute, prevHour;
+    int day, date, month, year;
     bool startup = true;
     
     // Start I2C at 400kHz for DS3231 
@@ -221,8 +229,8 @@ int main() {
 
     // wait(3);
         
-    // DS3231_SetTime(00, 24, 10, true);
-    // DS3231_SetDate(6, 17, 2, 19, 0);
+    // DS3231_SetTime(00, 13, 21);
+    // DS3231_SetDate(MONDAY, 11, 3, 19, 0);
 
     // Setup a ticker to refresh the display at 1kHz
     RefreshTicker.attach_us(RefreshTickerCallback, REFRESH_RATE_US);
@@ -264,6 +272,10 @@ int main() {
             prevHour = nextHour;
 
             DS3231_GetTime(&nextSecond, &nextMinute, &nextHour);
+            DS3231_GetDate(&day, &date, &month, &year);
+
+            // Compensate for daylight savings time
+            nextHour = IsDst(day, date, month, nextHour) ? (nextHour + 1) % 12 : nextHour % 12;
 
             // Update the display configuration based on the new/previous time
             if (startup || prevHour / 10 != nextHour / 10) {

+ 4 - 1
Nixie_Firmware_Mbed/main.h

@@ -1,6 +1,9 @@
 #ifndef _MAIN_H_
 #define _MAIN_H_
 
+// #define REVISION_A
+#define REVISION_B
+
 // Calculate the byte offset of a field in a structure of type type.
 #define FIELD_OFFSET(type, field) ((uint32_t)(uint32_t*)&(((type *)0)->field))
 
@@ -21,7 +24,7 @@
 #define REFRESH_RATE_US 1000  
 
 #define DOT_MIN 256
-#define DOT_MAX 2048
+#define DOT_MAX 640
 #define DOT_FADE_DURATION_US 1000000
 
 #define DIGIT_MIN PCA9685_Min_Brightness