/** * Shows an assertion on the LCD and enters infinite blinking led loop. * @param filename Filename of assert * @param line Line number of assert */ void on_assert(const char *filename, uint16_t line) { char tmp[17]; lcd_init(); lcd_clear(); snprintf(tmp, sizeof(tmp), "ASSERT (%d)", line); lcd_write(0, 0, tmp, 0); snprintf(tmp, sizeof(tmp), "%s", filename); lcd_write(0, 1, tmp, 0); while (1) { DBG_LED_ON(); _delay_ms(500); DBG_LED_OFF(); _delay_ms(500); } }
byte conrad_state_get_dcf_data() { /* * Minutenstart erkennen * Wenn es 2 Sekunden keine Modulation gibt, beginnt Minute * eigentlich i >= 200; 155 aus Toleranz. */ if (i < 155) { /* DCF Signal unmoduliert (da es invertiert ist, ist es standartmaessig 1) */ if (DCF_VALUE != 0) { i++; j = 0; DBG_LED_OFF(); /* Wenn es moduliert ist (logisch 0) */ } else { j++; /* * Wenn mehr als 70 ms moduliert ist, erkenne es als moduliert an (eig 100 oder 200 ms) * damit beginnt die Minute hier noch nicht, also von vorne messen */ if (j > 7) { i = 0; j = 0; DBG_LED_ON(); } } /* * returne fehlerfrei. * Durch T2 wird diese Routine nach 10 ms wieder aufgerufen. * Entspricht also quasi _delay_ms(10) */ return T2_WAIT; } /* * Wenn wir hier sind, wurde Minutenanfang erkannt. * Jetzt die Daten in jeder Sekunde auslesen. * entweder 100ms (logisch 0) oder 200ms (logisch 1) moduliert. */ search_time = false; while (secs < 60) { if (is_start_of_sec) { /* Pausiere bis zum modulierten Signal */ if (DCF_VALUE != 0) { return T2_WAIT; } is_start_of_sec = false; } /* * Gehe 95 % der Sekunde durch * (Rest ist Zeittoleranz, damit naechstes modulierte Signal nicht verpasst wird) * Zaehle dabei modulierte und unmodulierte Messungen */ if (k < 95) { if (DCF_VALUE != 0) { unmodulated++; } else { /* * moduliertes Signal tritt nur am Anfang der Sekunde auf in den ersten 200 ms. * 400 fuer Toleranz (300 war nicht genug, kA warum) */ if (k < 40) { modulated++; } } k++; /* * returne fehlerfrei. * Durch T2 wird diese Routine nach 10 ms wieder aufgerufen. * Entspricht also quasi _delay_ms(10) */ return T2_WAIT; } /* * Werte vergangene Sekunde aus: * mindestens 500 ms und kleiner 1,4 s unmoduliert: Signal gueltig, sonst ungueltig und abbrechen */ if (unmodulated > 50 && unmodulated < 140) { /* Wenn moduliert zwischen 50 und 140 ms, liegt logisch 0 an */ if (modulated > 5 && modulated < 14) { dcf_data[secs] = 0; /* Zwischen 150 ms und 240 ms, liegt logisch 1 an */ } else if (modulated > 15 && modulated < 24) { dcf_data[secs] = 1; /* sonst ist es ungueltig */ } else { return ERROR; } } else { return ERROR; } /* Bereite die naechste Sekunde vor */ secs++; is_start_of_sec = true; k = 0; modulated = 0; unmodulated = 0; } return SUCCESS; }
byte conrad_get_dcf_data(byte* dcf_data) { byte i = 0; byte j = 0; byte secs; byte unmodulated; byte modulated; // Globale Interrupts verbieten fuer genauere Messung (die natuerlich immernoch ungenau ist ;)) cli(); // Minutenstart erkennen while (i < 155) { // DCF Signal unmoduliert if (DCF_VALUE != 0) { i++; j = 0; DBG_LED_OFF(); // DCF Signal moduliert } else { j++; // Fehlertoleranz, wenn ein Signal kleiner 90 ms erkannt wird if (j > 8) { i = 0; j = 0; DBG_LED_ON(); } } _delay_ms(10); } // Minutenanfang erkannt // Funkdaten auslesen for (secs = 0; secs < 60; secs++) { unmodulated = 0; modulated = 0; // Pausiere bis zum modulierten Signal while (DCF_VALUE != 0) ; // Gehe 90% der Sekunde durch (Rest ist Toleranz) und zaehle modulierte und unmodulierte Signale for (j = 0; j < 90; j++) { if (DCF_VALUE != 0) { unmodulated++; } else { if (j < 40) { modulated++; } } _delay_ms(10); } // Wenn mindestens 600 ms unmoduliert waren, deute Signal als gueltig, sonst ungueltig und abbrechen if (unmodulated > 60 && unmodulated < 130) { DBG_LED_OFF(); // Wenn moduliertes zwischen 60 und 130 ms liegt, liegt logisch 0 an if (modulated > 6 && modulated < 13) { dcf_data[secs] = 0; // Wenn moduliertes zwischen 160 und 230 ms liegt, liegt logisch 1 an } else if (modulated > 16 && modulated < 23) { dcf_data[secs] = 1; } } else { goto error; } } // Globale Interrupts wieder anschalten sei(); return 0; error: // Globale Interrupts wieder anschalten und mit Fehlerfall returnen sei(); clearAll(); return 1; }