#ifndef CONFIG_H_INCLUDED
#define CONFIG_H_INCLUDED

/* -------------- Standard Include Files ----------------- */
#include <stdbool.h>
#include <stdint.h>

/* --------------- Special Include Files / Librarys ------ */
#include "tm_stm32f4_bmp180.h"
#include "tm_stm32f4_rtc.h"

/* -------------- Projekt   Include Files ---------------- */


/* -------------- Defintionen ---------------------------- */

// Typdefinition diverser RAM Typen, Verwendung <Typ> <CCRAM> <Variablenname>
#define CCRAM  __attribute__((section(".ccram")))
#define BKRAM  __attribute__((section(".bkram")))
#define RAM    __attribute__((section(".ram")))

// Sys-Tick Counter - Messen der Anzahl der Befehle des Prozessors:
#define CORE_SysTickEn()      (*((u32*)0xE0001000)) = 0x40000001
#define CORE_SysTickDis()     (*((u32*)0xE0001000)) = 0x40000000
#define CORE_GetSysTick()     (*((u32*)0xE0001004))
#define CORE_ClearSysTick()   (*((u32*)0xE0001004)) = 0

// Steuersymbole für Pins

#define GPIO_SetPin(GPIOx, GPIO_Pin) 		((GPIOx)->BSRRL = (GPIO_Pin))
#define GPIO_ResetPin(GPIOx, GPIO_Pin) 		((GPIOx)->BSRRH = (GPIO_Pin))
#define GPIO_TogglePin(GPIOx, GPIO_Pin)		((GPIOx)->ODR ^= (GPIO_Pin))
#define GPIO_GetInputPin(GPIOx, GPIO_Pin)	(((GPIOx)->IDR & (GPIO_Pin)) == 0 ? 0 : 1)
#define GPIO_GetOutputPin(GPIOx, GPIO_Pin)	(((GPIOx)->ODR & (GPIO_Pin)) == 0 ? 0 : 1)
#define GPIO_SetPinValue(GPIOx, GPIO_Pin, val)	((val) ? GPIO_SetPin(GPIOx, GPIO_Pin) : GPIO_ResetPin(GPIOx, GPIO_Pin))

// Transformiert Koordinaten auf 0,0 bezogen auf linke, untere Ecke
#define TransX(x)           (x)
#define TransY(y)           (ILI9341_WIDTH - (y))
#define round(x) ((x) >= 0 ? (long)((x) + 0.5) : (long)((x)-0.5))       // Runded einen float Wert
#define HasChanged(x,y)     (abs(x-y) > 0.09)                       // Vergleicht zwei Float Werte auf 0.1 Abstand

// Hardware Port C
#define LCD_BACKLIGHT  GPIO_Pin_3

// Hardware Port D
#define LED_ROT         GPIO_Pin_0
#define LED_GLB         GPIO_Pin_1
#define LED_GRN         GPIO_Pin_2
#define RELAIS          GPIO_Pin_3
// Port E
#define DIP_Switch_1    GPIO_Pin_6
#define DIP_Switch_2    GPIO_Pin_7

// Wetter LED Hardware Pins (PORTE )
#define LEDPORT     GPIOE
#define WLED_ROT1   GPIO_Pin_8
#define WLED_ROT2   GPIO_Pin_9
#define WLED_GLB    GPIO_Pin_2
#define WLED_GRN    GPIO_Pin_3
#define WLED_BLAU   GPIO_Pin_4
#define WLED_ALL    WLED_ROT1 | WLED_ROT2 | WLED_GLB | WLED_GRN | WLED_BLAU

// Bezeichnung der Wetter LED
#define LROT1       0
#define LROT2       1
#define LGLB        2
#define LGRN        3
#define LBLAU       4

// Globale Defintionen
#define HISTORY_MAX_IDX     72                          // Anzahl Werte in der Historie
#define HOEHE_ORT           192                         // Barntrup Sonneborn Höhe ü. N.N.
#define PRES_TOLERANZ       3                           // 3mbar um 1013mb als Toleranz legen
#define PRESSURE_NORMAL     1013                        // Normaldruck auf Meereshoehe

// Remperaturskala
#define MIN_TEMP            10.0                        // Kleinste Temperatur links
#define MAX_TEMP            36.0                        // Maximale Raumtemperatur

// Druckskala
#define MIN_PRES            850.0                       // Absolute Grenzen im Flachland
#define MAX_PRES            1100.0
#define P_DELTA             3                           // Bei Skalenüberschreitung +-3 mbar addieren
#define RASTER              12                          // Zeitrahmen für Regressionsanalyse

/* -------------- Typen Deklarationen--------------------- */

typedef enum {Tief, Neutral, Hoch}
    gebiet_t;

// Haupt Datenbasis
struct data_t {
    float    Pressure;
    float    Temperature;
    uint32_t unix_stamp;
};

typedef struct{
        int32_t  id;                                         // = 0x1234 nach Initialisierung
        uint16_t ptr;
        float    P_Now,                               // Aktueller Druckwert
                 T_Now;                            // Aktueller Temperaturwert

        uint32_t P_MaxGraph,                                 // Aktuell oberer Druckwert im Bargraphen
                 P_MinGraph;

        float    T_MaxGraph,                            // Schwankungen um den Messpunkt
                 T_MinGraph;

        // Historie...
        float    T_MaxInHistory,                              // Maximaler gemessener Temperaturwert
                 T_MinInHistory,                              // Minimaler gemessener Temperaturwert
                 T_AvgInHistory;

        uint32_t P_MaxInHistory,                              // Maximaler gemessener Druckwert
                 P_MinInHistory;                              // Minimaler gemessener Druckwert
        float    P_AvgInHistory;

        struct   data_t History[HISTORY_MAX_IDX+1];          // Historie, stuendliche Eintragungen
        float    RegrSteigung;                               // Steigung der Regressionsgeraden
        uint8_t  ZFN;                                        // Zambretti Forecast Letter
        gebiet_t gebiet;                                     // Hoch, Tief, Neutral

}  Work_t;

// Interner Zaehler für Sekunden, Minuten, Stunden und Tage
typedef volatile struct {
    uint8_t  sec,
             min,
             min30,
             min15,
             hour,
             day;
    uint16_t init;           // init = 0xaffe
} event_timer_t;

// Flags für die Zeit
typedef volatile struct {
   _Bool   rtc_1s,
           rtc_1min,
           rtc_15min,
           rtc_30min,
           rtc_1hr,
           rtc_1day,
           night,
           gfx_need_update,
           backlight;

} flags_t;

// Betriebsstundenzaehler
typedef struct {
        uint16_t id;            // 0xefce wenn initialisiert
        uint32_t  seconds,      // Sekunden seit Systemstart
                  minutes,      // Minuten seit Systemstart
                  hours;
} TimeFromStart_t;

/* -------------- Public Variablen ----------------------- */

extern volatile flags_t            flags;
extern TM_RTC_Time_t               Time;
extern volatile event_timer_t      timer;               // Zeiten (ISR)
extern volatile TimeFromStart_t    TimeFromStart;

/* -------------- Public Funktionen Prototypen ----------- */

void cfg_Init_Runtime();

#endif /* CONFIG_H_INCLUDED */
