#pragma once
typedef unsigned char byte;
typedef unsigned short WORD;
typedef unsigned long DWORD;
#define elemof(x) (sizeof(x)/sizeof(*(x)))
/* Hardware:
PB0 (5) Akku zuschalten / laden mittels MOSFET
PB1 (6) USB D+
PB2 (7) USB D- = INT0 (Interrupts auch bei SOF)
PB3 (2) DCF77-Zeitzeichensignal, LOW = Trägerabsenkung
PB4 (3) Freigabe des Funkempfangsmoduls, LOW = aktiv
PB5 (1) Akkuspannung messen (nur wenn PB0 = HIGH möglich)
Erfordert „wegprogrammiertes“ RESET
*/
#define BAT_BIT 0 // Akku laden
#define BAT_INV 0 // 1 = LOW-aktiv, 0 = HIGH-aktiv
#define SIG_BIT 3 // DCF77-Trägerabsenkung
#define SIG_INV 1 // 1 = LOW-aktiv, 0 = HIGH-aktiv
#define SIG_PU 1 // Eingang benötigt PullUp?
#define ENA_BIT 4 // Empfänger-Freigabe
#define ENA_INV 1 // 1 = LOW-aktiv, 0 = HIGH-aktiv
#define ANA_BIT 5 // Analogeingang (lt. Doku geht der auch mitsamt !RESET)
// Nützt bloß nicht allzu viel.
byte tage(byte m, byte y); // letzter Tag des Monats, Monat <m> 1-basiert
struct Clocktime{
byte sec, // Sekunde, 0..59 (Schaltsekunde: 60)
min, // Minute, 0..59
hour, // Stunde, 0..23
day, // Tag des Monats, 1..31
wday, // Wochentag, 0..6, 0 = Sonntag
month, // Monat, 0..11
year, // Jahr, 0..99
info; // Bit 0 = Ankündigung Zeitumstellung
// Bit 1 = MESZ
// Bit 2 = MEZ
// Bit 3 = Ankündigung Schaltsekunde
byte ZoneMJD() const;
void IncSec();
void IncMin();
void IncDate();
// void SetZone(char z) {hour+=z-tz; tz=z;} // Darf nicht an Datumsgrenze Zonenzeit verändern! Hierzulande zwischen 2:00 Uhr und 3:00 Uhr okay.
};
struct Report{
byte reportID;
operator const byte*() const {return &reportID;}
operator byte*() {return &reportID;}
};
extern struct JoyReport: public Report{ // Länge: 4, reportID = 1
byte joyKey; // Bit 0 = Trägerabsenkung
// Bit 7:1 = Millisekunden bis zum GetReport
WORD timems; // Zeitstempel als Joystick-Achse, in ms
}joyReport;
extern struct TimeReport: public Report{ // Länge: 12, reportID = 2
byte gr_delay; // GetReport-Verzögerung
WORD ms; // Zehntel Millisekunden? (0..8055)
Clocktime t; // Uhrzeit, Lokalzeit (nicht GMT)
}timeReport; // wie's vom DCF-77 kommt
extern struct SetupReport: public Report{ // Länge: 6, reportID = 3
byte jh; // Jahrhundert (für die Kalenderrechnung)
byte msLow,msMid,msHigh;
byte AkkuTyp; // Low-Nibble = Akkutyp:
// 0 = kein, 1 = LiIon, 2 = 2xNiMH, 3 = 3xNiMH, 4 = Alkali, 5 = benutzerdefiniert
// Bit 4 = SIG negiert (mittels Histogramm)
// Bit 5 = ENA negiert
short Ladeschluss; // A/D-Wert Ladeschluss, 0..1023
short Endladeschluss; // A/D-Wert zum Abschalten, 0..1023
}setupReport; // für den EEPROM
extern struct StatusReport: public Report{ // Länge: 8, reportID = 4
byte someBits; // Bit 0 = Trägerabsenkung
// Bit 1 = Uhrzeit einfach gültig
// Bit 2 = Uhrzeit doppelt gültig
// Bit 4 = Neue Minute
// Bit 5 = Neue Wetterdaten
// Bit 6 = Neue Stunde
// Bit 7 = Neuer Tag, Zonenzeit
WORD timems; // Zeitstempel, in ms
short Akkuspannung; // A/D-Wert, 0..1023 0x06/0x20
short Chiptemperatur; // A/D-Wert, 0..1023 0x0C/0x105
}statusReport; // Input-Report (bei jedem Trägerwechsel, oder jede Sekunde für A/D-Wert)
extern struct HistoryReport: public Report{ // Länge: 262, reportID = 5
byte nMinu; // Low-Nibble = Anzahl, High-Nibble = Schreib-Index
unsigned long long Data[10],Okay[10];
WORD histo[50]; // Eimerbreite 10 ms
}historyReport;
extern struct WetterReport: public Report{ // Länge: 1924 (der Rest im Flash, nicht im RAM), reportID = 6
byte cur_mjd;
WORD cur_index;
}wetterReport;
extern WORD T0Capture;
extern WORD lastStart;
#define F_TMR (F_CPU/8/256) // Timer-Frequenz, ergibt 8056 Hz
// PROBLEM: Beim Flash-Schreiben gehen eine Menge Timer-Interrupts flöten.
// Dasselbe auch bei USB-Interrupts.
// LÖSUNG: Timer1 muss als High-Teil-Generator herhalten. (Frisst >1 mA Strom)
// Interruptfrequenz: F_CPU/2048/256 = 31 Hz
// Besser nicht bei Batteriebetrieb.
// Hält die Empfangsdaten im BCD-Format
// Das erspart long-long-Schiebeoperationen in der Firmware des 8-Bit-Controllers.
extern struct Frame{
byte recvbit; // Die Bitnummer ist /nicht/ die Sekunde sondern springt etwas umher
union{
byte data[8];
WORD w; // Wetterdaten als WORD
struct{
byte wl, // 0 StartM W0 W1 W2 W3 W4 W5 W6
wh, // 8 W7 W8 W9 W10 W11 W12 W13 Rufbit
inf, //16 ANK MESZ MEZ SSek StartZ - - - 21->24
min, //24 M1 M2 M4 M8 M10 M20 M40 MPar
hod, //32 H1 H2 H4 H8 H10 H20 HPar - 39->42
day, //40 DPar (0) D1 D2 D4 D8 D10 D20 42->41
wdm, //48 W1 W2 W4 N1 N2 N4 N8 N10
rok; //56 Y1 Y2 Y4 Y8 Y10 Y20 Y40 Y80 64->40
};
};
void GrabWetter0() const; // Wetterbits abgreifen in Minute%3 = 0
void GrabWetter1() const; // Wetterbits abgreifen in Minute%3 = 1: Mit Uhrzeit, d.h. die Minute in cipher_key lässt stets Rest 2
void GrabWetter2() const; // Wetterbits abgreifen in Minute%3 = 2
}frame;
extern DWORD Cache24[480]; // im Flash
void dcf77Poll();
//void SaveWetter(DWORD dw, int index);
extern byte cipher_key[10];
/* crypt.S */
extern "C" long DecodeData(byte ck[10]);
#include "flash_rw.h"
| Detected encoding: ANSI (CP1252) | 4
|
|
|