#ifndef CONFIG_H_INCLUDED
#define CONFIG_H_INCLUDED

#include <stdbool.h>
#include <stdint.h>

#include "tm_stm32f4_bmp180.h"
#include "tm_stm32f4_rtc.h"

// 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((float)x-(float)(y) > 0.09))              // Vergleicht zwei Float Werte auf 0.1 Abstand


// Hardware
#define HWPORT      GPIOD
#define LED_ROT     GPIO_Pin_0
#define LED_GLB     GPIO_Pin_1
#define LED_GRN     GPIO_Pin_2
#define RELAIS      GPIO_Pin_3

// Wetter LED Hardware Pins (PORTE )
#define LEDPORT     GPIOE
#define WLED_ROT1   GPIO_Pin_0
#define WLED_ROT2   GPIO_Pin_1
#define WLED_GLB    GPIO_Pin_2
#define WLED_GRN    GPIO_Pin_3
#define WLED_BLAU   GPIO_Pin_4

// 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     60                          // Anzahl Werte in der Historie
#define HOEHE_ORT           230                         // Barntrup Höhe ü. N.N.
#define DISPLAY_CUTOFF_AT_NIGHT
#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            35.0                        // Maximale Raumtemperatur

// Druckskala
#define MIN_PRES            800.0                      // Absolute Grenzen im Flachland
#define MAX_PRES            1200.0
#define P_DELTA             5                           // Bei Skalenüberschreitung +-5 mbar addieren

// Haupt Datenbasis
struct data_t {
    float    Pressure;
    float    Temperature;
//    _Bool    MinVal,                                   // Markierung für Minimalwert
//             MaxVal;                                   // Markierung für Maximalwert

    uint32_t unix_stamp;
};

typedef struct{
    int32_t  id;                                         // = 0x1234 nach Initialisierung
    uint16_t ptr;
    float    Pressure_Now,                               // Aktueller Druckwert
             Temperature_Now;                            // Aktueller Temperaturwert
    uint32_t Pressure_Max,                               // Aktuell oberer Druckwert
             Pressure_Min;
    float    Temperature_Max,                            // Schwankungen um den Messpunkt
             Temperature_Min;

    // Historie...
    float    T_History_Max,                              // Maximaler gemessener Temperaturwert
             T_History_Min,                              // Minimaler gemessener Temperaturwert
             T_History_Avg;

    uint32_t P_History_Max,                              // Maximaler gemessener Druckwert
             P_History_Min;                              // Minimaler gemessener Druckwert
    float    P_History_Avg;

    struct   data_t History[HISTORY_MAX_IDX+1];          // Historie, stuendliche Eintragungen
    float    RegrSteigung;                               // Steigung der Regressionsgeraden

}  Work_t;

extern Work_t Work BKRAM;


// 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,
           drawalways;      // Immer zeichnen auch wenn unverändert
} flags_t;

// Betriebsstundenzaehler
typedef struct {
        uint16_t id;          // 0xefce wenn initialisiert
        uint8_t  seconds,
                 minutes,
                 hours;
} TimeFromStart_t;

TimeFromStart_t TimeFromStart;

// Variablen, die alle Modulen bekannt gemacht werden
flags_t                     flags;
TM_BMP180_t                 BMP180_Data;                  // Drucksensor Daten
TM_RTC_Time_t               Time;

#endif /* CONFIG_H_INCLUDED */
