#ifndef __MAIN_H
#define __MAIN_H

#include <ioavr.h>
#include <intrinsics.h>
#include <stdint.h>
#include "rtos.h"
#include "twim.h"

/* Timers */
// T0 period 4 ms == 0x100 - (8000000 / 256 * 0.004) 
#define TIM0_PRESCALER  1<<CS02
#define TIM0_CNT        0x83
#define TIM0_CHANNEL    0x00

/* LEDs */
#define LED_PORT        PORTC
#define LED_DDR         DDRC
#define LED_1           (1<<PC2)
#define LED_2           (1<<PC3)

#define LED_ON(led)     LED_PORT |= led
#define LED_OFF(led)    LED_PORT &= ~led
#define LED_TOGGLE(led) LED_PORT ^= led

/* 7-segment LED indikators */
#define INDCTR_NUMS                4

#define INDCTR_SEGMENT_PORT        PORTB
#define INDCTR_SEGMENT_DDR         DDRB
#define INDCTR_SEGMENT_A           PB0
#define INDCTR_SEGMENT_B           PB2
#define INDCTR_SEGMENT_C           PB4
#define INDCTR_SEGMENT_D           PB6
#define INDCTR_SEGMENT_E           PB7
#define INDCTR_SEGMENT_F           PB1
#define INDCTR_SEGMENT_G           PB3
#define INDCTR_SEGMENT_H           PB5

#define INDCTR_COMMON_PORT         PORTD
#define INDCTR_COMMON_DDR          DDRD
#define INDCTR_COMMON_1            (1<<PD0)
#define INDCTR_COMMON_2            (1<<PD1)
#define INDCTR_COMMON_3            (1<<PD2)
#define INDCTR_COMMON_4            (1<<PD3)
#define INDCTR_COMMON_ALL          (INDCTR_COMMON_1 | INDCTR_COMMON_2 | INDCTR_COMMON_3 | INDCTR_COMMON_4)

#define INDCTR_COMMON_DOT          1

typedef enum {
  Sym_0 = ~0x28,
  Sym_1 = ~0xEB,
  Sym_2 = ~0x32,
  Sym_3 = ~0xA2,
  Sym_4 = ~0xE1,
  Sym_5 = ~0xA4,
  Sym_6 = ~0x24,
  Sym_7 = ~0xEA,
  Sym_8 = ~0x20,
  Sym_9 = ~0xA0,
  Sym_a = ~0x60,
  Sym_b = ~0x25,
  Sym_c = ~0x37,
  Sym_d = ~0x23,
  Sym_e = ~0x34,
  Sym_f = ~0x74,
  Sym_minus = ~0xF7,
  Sym_gradus = ~0xF0,
  Sym_t = ~0x35,
  Sym_dot = 1<<INDCTR_SEGMENT_H
} indctr_sym_t;

/* Convert 0x0-0xF digit to 7-seg indicators symbol */
const indctr_sym_t IndctrNums[16] = {
  Sym_0, Sym_1, Sym_2, Sym_3,
  Sym_4, Sym_5, Sym_6, Sym_7,
  Sym_8, Sym_9, Sym_a, Sym_b,
  Sym_c, Sym_d, Sym_e, Sym_f
};


/* DS18B20 termometer */
#define DS18B20_PORT            PORTD
#define DS18B20_DDR             DDRD
#define DS18B20_PIN             PIND
#define DS18B20_PAD             PD7

/* BTN */
#define BTN_LVL_NO              0xED
#define BTN_LVL_7               0xD8
#define BTN_LVL_6               0xD0
#define BTN_LVL_5               0xC5
#define BTN_LVL_4               0xB4
#define BTN_LVL_3               0x94
#define BTN_LVL_2               0x3F

typedef enum {
  btn_no = 0,
  btn_1,
  btn_2,
  btn_3,
  btn_4,
  btn_5,
  btn_6,
  btn_7
} btn_t;

/* DS1307 */
#define DS1307_ADR              0x68
#define DS1307_ADR_RD           0xD0
#define DS1307_ADR_WR           0xD1
typedef struct {
  uint8_t seconds;
  uint8_t minutes;
  uint8_t hours;
} time_t;

/* Global varaibles */
volatile struct {
  uint8_t needDot       : 1;
  uint8_t newTime       : 1;
  uint8_t newBTN        : 1;
  uint8_t               : 5; // дополнение до 8 бит (резерв) 
} Flag;

volatile static indctr_sym_t Display[4];
volatile static uint8_t resultADC;
static uint8_t twi_buf[8];
static time_t Clock;
static void setTime(void);

/* Functions prototypes */
static void startADC(void);
static btn_t getBTN(void);
static void getTime(void);

#endif // __MAIN_H
