// ***********************************************************************
// main - HEADER
// ***********************************************************************

#ifndef MAIN_H_
#define MAIN_H_

// direct acces of multi-byte variables
#define _BYTEX(val, x)                          (*((uint8_t*)&val+x))

// direct copy of U8 variable to selected position of multi-byte variables
#define _MOVE_TO_BYTE0(dest,src)                (*((uint8_t*)&dest) = src)
#define _MOVE_TO_BYTE1(dest,src)                (*((uint8_t*)&dest+1) = *&src)

// ______________________ C o n s t a n t s___________________ //

// EEPROM adresses
#define EEPROM_ID			(uint8_t*)0x00
#define EEPROM_DROP_SOFT	(uint16_t*)0x02

// ADC Channel
#define ADC_DROP_CH			3

// ADC Voltage Calculation
#define ADC_MUL_FORMAT		12
#define RES_RATIO_FORMAT	10

#define MIN_SOFT_CYCLES		1		// 5 ms
#define MAX_SOFT_CYCLES		10		// 50 ms
#define MAX_RC				20		// 20 ms


typedef enum t_Vrefs 
{
	VREF_4V34, VREF_0V55, VREF_ENUM_COUNT
} t_Vrefs;

typedef enum t_swStatus
{
	SW_STATUS_OFF, SW_STATUS_SOFT, SW_STATUS_ON, SW_STATUS_OFF_SHORT, SW_STATUS_ENUM_COUNT
} t_swStatus;

typedef enum t_tasks
{
	TASK_NONE = -1, TASK_ADC_TRIGGER, TASK_SW_CONTROL
} t_tasks;

// ______________________ C o n t r o l_______________________ //

#define SLEEP()				asm("SLEEP")

// ADC
#define ADC_START(ch)		ADC0_MUXPOS = ch, \
							ADC0_COMMAND = ADC_STCONV_bm
							
#define ADC_RESULT			ADC0_RES

// Clock Timer
#define CLK_TIM_OVF_CLR()	TCA0_SINGLE_INTFLAGS |= TCA_SINGLE_OVF_bm
#define CLK_TIM_STOP()		TCA0_SINGLE_CTRLA &= ~TCA_SINGLE_ENABLE_bm
#define CLK_TIM_START()		TCA0_SINGLE_CTRLA |= TCA_SINGLE_ENABLE_bm

// _________________________ I N I T _________________________ //

// System Clock 10 MHz
#define CLK_INIT()			CCP = CCP_IOREG_gc, \
							CLKCTRL_MCLKCTRLB = (CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm)
							
// Sleep Mode Idle
#define SLEEP_INIT()		SLPCTRL_CTRLA = (SLPCTRL_SMODE_IDLE_gc | SLPCTRL_SEN_bm)

// USART on alternate pins
#define PORTMUX_INIT()		PORTMUX_CTRLB = PORTMUX_USART0_ALTERNATE_gc

// Watchdog
#define WDT_INIT()			CCP = CCP_IOREG_gc, \
							WDT_CTRLA = WDT_PERIOD_32CLK_gc

//________ A D C ________ //

// Vref = 4.3V
#define VREF_4V34_INIT()	VREF_CTRLA = VREF_ADC0REFSEL_4V34_gc
#define VREF_0V55_INIT()	VREF_CTRLA = VREF_ADC0REFSEL_0V55_gc

// Variable delay between samples
// Clock = SYSCLK / 128
// 8 samples per run
// Single conversion mode
// Interrupt on result ready
#define ADC_INIT()			ADC0_CTRLD = ADC_ASDV_ASVON_gc, \
							ADC0_CTRLC = ADC_PRESC_DIV64_gc, \
							ADC0_CTRLB = ADC_SAMPNUM_ACC8_gc, \
							ADC0_CTRLA = ADC_ENABLE_bm, \
							ADC0_INTCTRL = ADC_RESRDY_bm

// Pin map
#define SW_SOFT_bm			PIN6_bm
#define SW_HARD_bm			PIN7_bm

#define SW_ON( sw_bm )		PORTA_OUT |= (sw_bm);
#define SW_OFF( sw_bm )		PORTA_OUT &= ~(sw_bm);


// IO init
#define PORTA_INIT()		PORTA_DIR = ( PIN2_bm | PIN6_bm | PIN7_bm );

//______ T I M E R S ______ //
							
// Period = 1 / 10 MHz / 16 / 3125 = 5 ms
// Overflow interrupt
// Do not change the clock prescaler! Clock source for USART timeout.

#define CLK_TIM_INIT()		TCA0_SINGLE_PER = 3125, \
							TCA0_SINGLE_CTRLA = (TCA_SINGLE_CLKSEL_DIV16_gc | TCA_SINGLE_ENABLE_bm), \
							TCA0_SINGLE_INTCTRL = (TCA_SINGLE_OVF_bm)
							
#endif /* MAIN_H_ */