/*
 * BP_osc.c
 *
 *  Created on: 30. 10. 2016
 *      Author:
 */


#ifndef F_CPU
#define F_CPU 16000000UL // 16 MHz clock freq.
#endif

#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <stdint.h>
#include <avr/interrupt.h>

// LCD I/O defines + display lib include
#define LCD_Data 				PORTC
#define LCD_Data_Dir 			DDRC
#define LCD_Control 			PORTD
#define LCD_Control_Data_Dir	DDRD
#define LCD_Enable				5
#define LCD_ReadWrite			7
#define LCD_RS					1

#include "BP_LCD.h"


//Button I/O defines
#define Button_Port				PORTD   //Same as LCD_Control
#define Left_button				4
#define Mode_Button				0
#define Right_button			6
#define	INT0_Pin				2
#define	INT1_Pin				3


//SPI bus defines + SPI lib include
#define SPI_Port				PORTB
#define SPI_Data_Dir			DDRB
#define SPI_MOSI				5
#define SPI_MISO				6
#define SPI_SCK					7
#define SPI_SS					4
#define SPI_LDAC				3

#include "BP_SPI.h"

//Constant defines
#define timer_preset			64860					//Value of TCNT1 count register
//64860


//Function prototypes
static void AD_init(void);								//ADC0 initialization + global interrupt enable
static void EXT_INT_init(void);							//External interrupts initialization
static void TC1_init();									//Timer1 initialization
static void int_to_printStr(uint8_t number);			//Converts uint8_t to char[] and save to printStr
static void Read_AD(void);								//If ADIF flag is set, function copies 8 MSBs to adcParam variable
static void Read_AD_wait(void);							//Waits until ADIF flag is set, then copies 8 MSBs to adcParam variable
static void Set_DAC_val(uint16_t val_a, uint16_t val_b);//Sends data to D/A (MCP4822) via SPI
static void Left_button_event(void);					//Function called by debouncing routine when the Left button is pressed
static void Left_button_long_press_event(void);			//Function called by debouncing routine when the Left button is longpressed
static void Mode_button_event(void);					//Function called by debouncing routine when the Mode(Parameter) button is pressed
static void Mode_button_long_press_event(void);			//Function called by debouncing routine when the Mode(Parameter) button is longpressed
static void Right_button_event(void);					//Function called by debouncing routine when the Right button is pressed
static void Piezo_event(void);							//Function called from ISR INT1_vect
static void Set_step_parameters(void);					//Reads values from sequence_* arrays and writes them to the oscillator variables
static void Next_waveform_step(void);					//Calculates values for the D/A converter for both oscillators, according to phase accumulator and oscillator variables set at the moment
static uint16_t Sine_value(uint16_t acc);				//Function returns a 12bit value of a sine func. in 16bit variable, according to value of phase acc
static uint16_t Triangle_value(uint16_t acc);			//Function returns a 12bit value of a triangle func. in 16bit variable, according to value of phase acc
static uint16_t Square_value(uint16_t acc);				//Function returns a 12bit value of a square func. in 16bit variable, according to value of phase acc
static uint16_t Saw_value(uint16_t acc);				//Function returns a 12bit value of a saw func. in 16bit variable, according to value of phase acc


//Variables
static volatile uint8_t adcParam = 0;					//Stores value from A/D converter (potentiometer)
static volatile uint8_t adcParam_old = 0;				//Stores value from A/D converter (potentiometer) from the last change
static char printStr[6];								//String of chars used to print to display
static volatile uint8_t keyEnable = 1;					//If 1, the program responds to button presses, if 0, it doesn't
static volatile uint16_t debounce_count = 0;			//Counter used for debouncing
static volatile uint16_t long_press_count = 0;			//Counter used for button long-press recognition
static volatile uint8_t mode = 1;						//1-play/edit, 0-set tempo
static volatile uint8_t play_enable = 0;				//1-sequence playing, 0-sequence stopped
//									  C      C#      D       D#      E       F       F#     G      G#      A      A#      B
static float frequency_table[24] = { 65.41,  69.3,   73.42,  77.78,  82.41,  87.31,  92.5,  98.0,  103.83, 110.0, 116.54, 123.47,
									 130.81, 138.59, 146.83, 155.56, 164.81, 174.61, 185.0, 196.0, 207.65, 220.0, 233.08, 246.94}; //C to B
static char notes[12] =			   { 'C',    'C',    'D',    'D',    'E',    'F',    'F',   'G',   'G',    'A',   'A',    'B'};
static uint8_t sequence_position = 0;					//Stores current step of the sequence selected
static uint16_t sequence_timer = 0;						//Counter of TC1 overflow cycles - used for sequence timing
static uint16_t step_time = 6000;						//Stores the amount of cycles that one step lasts (time - "tempo")
static uint8_t edit_parameter = 0;						//Stores the number of currently selected parameter
static uint8_t parameter_set_enable = 0;				//1-current parameter change enabled, 0-disabled
static uint8_t time_measure_enable = 0;

//Step parameters arrays
static uint8_t sequence_tones[16] = 		{4, 4, 4, 4, 7, 6, 4, 4, 7, 7, 7, 6, 6, 6, 11, 3};
static uint8_t sequence_octave[16] = 		{2, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2};
static uint8_t sequence_osc1_waveform[16] = {1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 3, 3, 2, 2, 1, 1};
static uint8_t sequence_osc2_waveform[16] = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
static uint8_t sequence_osc2_phase[16] = {20, 150, 20, 30, 40, 50, 60, 70, 80, 90, 180, 180, 60, 50, 90, 120};
static float sequence_osc2_freq[16] = {0};
static uint8_t sequence_osc1_gain[16] = {3, 10, 12, 10, 12, 12, 12, 12, 12, 12, 3, 3, 12, 12, 3, 3};
static uint8_t sequence_osc2_gain[16] = {12, 10, 12, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12};

//Oscillator variables
float frequency_Hz = 0;		//Oscillator 1 currently selected frequency in Hz
float frequency_Hz2 = 0;	//Oscillator 2 currently selected frequency in Hz
uint32_t frequency = 0;		//Stores an increment to a phase accumulator for osc1
uint32_t frequency2 = 0;	//Stores an increment to a phase accumulator for osc2
uint16_t accumulator = 0;  	//Phase accumulator for osc1
uint16_t accumulator2 = 0;	//Phase accumulator for osc2
uint8_t osc1_waveform = 3; 	//Stores currently set waveform of osc1 0=off, 1=sin, 2=tri, 3=sqr, 4=saw
uint8_t osc2_waveform = 2;	//Stores currently set waveform of osc2 0=off, 1=sin, 2=tri, 3=sqr, 4=saw
uint8_t osc2_phase = 0;		//Stores phase shift between osc1 and osc2
uint8_t osc1_gain = 16;		//Stores currently set volume of osc1
uint8_t osc2_gain = 16;		//Stores currently set volume of osc2
uint16_t DACa_out_val,DACb_out_val;		//Variables with a 12bit value to be output to DAC converters
static volatile uint8_t mute_enable = 0;	//When 1, outputs are set to 0
static volatile uint8_t step_preview = 0;	//When 1, oscillators are working even when sequence is stopped


// Table of sine 256 values
uint8_t sineTable[]={
  0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,
  0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,
  0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5,
  0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,
  0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,
  0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3,
  0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,
  0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x63,0x60,0x5d,0x5a,0x57,0x54,0x51,
  0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,0x38,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,
  0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x12,0x10,0x0f,0x0d,0x0c,0x0a,
  0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,
  0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,
  0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b,0x3e,0x40,0x43,0x46,0x49,0x4c,
  0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c};


//MAIN ****************************************************************


int main() {


	// INIT calls
	LCD_init();		//see BP_LCD.h
	EXT_INT_init();	//external interrupts initialization
	SPI_init();		//SPI initialization func.
	TC1_init();		//TC1 initialization func.
	AD_init();		//A/D converter initialization, global interrupt sei() called within this proc.
	Read_AD_wait(); //Wait until A/D conv data ready and store into adcParam var
	adcParam_old = adcParam;	//Copy to adcParam_old


	while(1) {		//main loop start

		Set_step_parameters();	//Read osc1 and osc2 parameters for current step from sequence arrays
		frequency = (frequency_Hz * 65536.0) / 22000.0;		//Calculate an increment to a phase accumulator for osc1
		frequency2 = ((frequency_Hz2) * 65536.0) / 22000.0;	//Calculate an increment to a phase accumulator for osc2

		Read_AD();	//IF A/D conv data ready than store into adcParam var

		if (play_enable==0) {		//If sequence is stopped, then...
			if ( (adcParam<(adcParam_old-5)) || (adcParam>(adcParam_old+5)) ) parameter_set_enable = 1;  //If newly read adcParam differs from the old by more than 5 then allow changes to be done

			if (parameter_set_enable==1){		//Take the value of adcParam, convert and store to currently set parameter's sequence array, to a place corresponding to current step
				adcParam_old = adcParam;
				switch (edit_parameter) {
					case 0:
						sequence_tones[sequence_position] = (adcParam*11)/255;
						break;
					case 1:
						if (adcParam<128) {
							sequence_octave[sequence_position] = 1;
						} else {
							sequence_octave[sequence_position] = 2;
						}
						break;
					case 2:
						sequence_osc1_waveform[sequence_position] = (adcParam*4)/255;
						break;
					case 3:
						sequence_osc2_waveform[sequence_position] = (adcParam*4)/255;
						break;
					case 4:
						sequence_osc2_freq[sequence_position] = ((float)((adcParam*25)/255)/10)*2;
						break;
					case 5:
						sequence_osc1_gain[sequence_position] = (adcParam*16)/255;
						break;
					case 6:
						sequence_osc2_gain[sequence_position] = (adcParam*16)/255;
						break;
					case 7:
						sequence_osc2_phase[sequence_position] = (adcParam*181)/255;
						break;

					default:
						break;
				}
			}
		}

		if (mode==1) {		//If in mode 1 (playing or step editing), print out currently set parameter and it's value
			LCD_change_cursor_pos(0, 0);
			LCD_send_a_string("Step: \n");
			int_to_printStr(sequence_position+1);
			LCD_send_a_string(printStr);
			LCD_send_a_string("/ 16       \n");

			LCD_change_cursor_pos(0, 1);
			switch (edit_parameter) {
				case 0:
					LCD_send_a_string("Note: \n");
					printStr[0] = notes[sequence_tones[sequence_position]];
					printStr[1] = 0x0A;
					LCD_send_a_string(printStr);
					if ((sequence_tones[sequence_position]==1) || (sequence_tones[sequence_position]==3)
							|| (sequence_tones[sequence_position]==6) || (sequence_tones[sequence_position]==8)
							|| (sequence_tones[sequence_position]==10)) {
						LCD_send_a_string("#\n");
					}
					break;
				case 1:
					LCD_send_a_string("Octave: \n");
					int_to_printStr(sequence_octave[sequence_position]);
					LCD_send_a_string(printStr);
					break;
				case 2:
					LCD_send_a_string("Waveform1: \n");
					switch (sequence_osc1_waveform[sequence_position]) {
						case 1:
							LCD_send_a_string("sin\n");
							break;
						case 2:
							LCD_send_a_string("tri\n");
							break;
						case 3:
							LCD_send_a_string("sqr\n");
							break;
						case 4:
							LCD_send_a_string("saw\n");
							break;
						default:
							LCD_send_a_string("off\n");
							break;
					}
					break;
				case 3:
					LCD_send_a_string("Waveform2: \n");
					switch (sequence_osc2_waveform[sequence_position]) {
						case 1:
							LCD_send_a_string("sin\n");
							break;
						case 2:
							LCD_send_a_string("tri\n");
							break;
						case 3:
							LCD_send_a_string("sqr\n");
							break;
						case 4:
							LCD_send_a_string("saw\n");
							break;
						default:
							LCD_send_a_string("off\n");
							break;
					}
					break;
				case 4:
					LCD_send_a_string("F.diff: \n");
					int_to_printStr((uint8_t)(sequence_osc2_freq[sequence_position]*10));
					LCD_send_a_string(printStr);
					LCD_send_a_string("/10Hz\n");
					break;
				case 5:
					LCD_send_a_string("Volume1: \n");
					int_to_printStr(sequence_osc1_gain[sequence_position]);
					LCD_send_a_string(printStr);
					break;
				case 6:
					LCD_send_a_string("Volume2: \n");
					int_to_printStr(sequence_osc2_gain[sequence_position]);
					LCD_send_a_string(printStr);
					break;
				case 7:
					LCD_send_a_string("Phase: \n");
					int_to_printStr(sequence_osc2_phase[sequence_position]);
					LCD_send_a_string(printStr);
					break;
			}
			LCD_send_a_string("        \n");

		} else {	//If in mode 0 (tempo setting), print out instructions to set the tempo
			LCD_change_cursor_pos(0, 0);
			LCD_send_a_string("Hit trigger 2x\n");
			LCD_change_cursor_pos(0, 1);
			LCD_send_a_string("                \n");
		}
		_delay_ms(1);	//1 ms delay at the end of the infinite loop
	}

}




//FUNCTIONS ****************************************************************

static void Left_button_event() {	//If the left button is pressed, change the sequence position -1
	sequence_position--;
	if (sequence_position==255) sequence_position = 15;
	parameter_set_enable = 0;
}

static void Left_button_long_press_event() {	//If the left button is long pressed, change mode from/to set-tempo/play-edit
	mode++;
	if (mode==2) mode = 0;
	play_enable = 0;
}

static void Mode_button_event() {				//If parameter button is pressed, change currently set parameter to the next one
	edit_parameter++;
	if (edit_parameter==8) edit_parameter = 0;
	parameter_set_enable = 0;
}

static void Mode_button_long_press_event() {	//If parameter button is long pressed, turn on/off the step preview (toggle)
	step_preview++;
	if (step_preview==2) step_preview = 0;
}

static void Right_button_event() {				//If the right button is pressed, change the sequence position +1
	sequence_position++;
	if (sequence_position==16) sequence_position = 0;
	parameter_set_enable = 0;
}

static void Piezo_event() {						//When the pad is hit:
												//In mode 1, start the sequence if stopped
	if (mode==1) {								//or stop the sequence and set step to first if played
		if (play_enable==0) {
			play_enable = 1;
			sequence_timer = 0;
			sequence_position = 0;
			parameter_set_enable = 0;
		} else {
			play_enable = 0;
		}
		sequence_timer = 0;
	} else {									//In mode 0, start or stop measuring the time between hits and store the result
		if (time_measure_enable==0) {
			time_measure_enable = 1;
			step_time = 0;
		} else {
			step_time /= 2;
			time_measure_enable = 0;
			mode = 1;
		}
	}
}


static void Set_step_parameters() {				//Reads values from sequence_* arrays and writes them to the oscillator variables

	if (sequence_octave[sequence_position]==1) {
		frequency_Hz = frequency_table[sequence_tones[sequence_position]];
	} else {
		frequency_Hz = frequency_table[sequence_tones[sequence_position] + 12];
	}

	frequency_Hz2 = frequency_Hz + sequence_osc2_freq[sequence_position];

	osc1_waveform = sequence_osc1_waveform[sequence_position];
	osc2_waveform = sequence_osc2_waveform[sequence_position];
	osc2_phase = sequence_osc2_phase[sequence_position];
	osc1_gain = sequence_osc1_gain[sequence_position];
	osc2_gain = sequence_osc2_gain[sequence_position];

}

static void Next_waveform_step() {			//Calculates values for the D/A converter for both oscillators, according
											//to phase accumulator and oscillator variables set at the moment

	uint16_t phase = osc2_phase*182;		//Recalculate the phase shift from degrees, so that 180deg is half the size of phase acc.
	accumulator = accumulator + frequency;  //Add the increase to the phase acc. of osc1
	accumulator2 = accumulator2 + frequency2;//Add the increase to the phase acc. of osc2
	// add in pith, the higher the number, the faster it rolls over, the more cycles per second

	switch(osc1_waveform) {					//Get the values for the DACs, according to waveforms set
		case 1:
			DACa_out_val = Sine_value(accumulator);
			break;
		case 2:
			DACa_out_val = Triangle_value(accumulator);
			break;
		case 3:
			DACa_out_val = Square_value(accumulator);
			break;
		case 4:
			DACa_out_val = Saw_value(accumulator);
			break;
		default:
			DACa_out_val = 0;
	}

	switch(osc2_waveform) {					//For osc2 with the phase shift added to the phase acc.
		case 1:
			DACb_out_val = Sine_value(accumulator2 + phase);
			break;
		case 2:
			DACb_out_val = Triangle_value(accumulator2 + phase);
			break;
		case 3:
			DACb_out_val = Square_value(accumulator2 + phase);
			break;
		case 4:
			DACb_out_val = Saw_value(accumulator2 + phase);
			break;
		default:
			DACb_out_val = 0;
	}


	DACa_out_val = (DACa_out_val*osc1_gain)/16;		//Recalculate for output values, according to the volume that is set in gain parameters
	DACb_out_val = (DACb_out_val*osc2_gain)/16;

	if (mute_enable==1) {		//If mute_enable is on, set outputs to zero
		DACa_out_val = 0;
		DACb_out_val = 0;
	}

}

static uint16_t Sine_value(uint16_t acc) {		//Function returns a 12bit value of a sine func. in 16bit variable, according to value of phase acc
	return sineTable[acc>>8]<<4;
}

static uint16_t Triangle_value(uint16_t acc) {	//Function returns a 12bit value of a triangle func. in 16bit variable, according to value of phase acc
	acc += 16384;
	if (acc<32768) {
		return 2*(acc/16);
	} else {
		return 2*((65535-acc)/16);
	}
}

static uint16_t Saw_value(uint16_t acc) {		//Function returns a 12bit value of a saw func. in 16bit variable, according to value of phase acc
	return ((65535-acc)/16);
}



static uint16_t Square_value(uint16_t acc) {	//Function returns a 12bit value of a square func. in 16bit variable, according to value of phase acc
	if (acc<32768) {
		return 4095;
	} else {
		return 0;
	}
}



static void Set_DAC_val(uint16_t val_a, uint16_t val_b) {		//Sends data to DAC (MCP4822) via SPI

	uint8_t SPI_ret, lowVal, highVal;

	//Setting DACa value
	val_a &= ~(0xF000);		//Zero the four MSbits
	val_a |= 0x1000; 		//0 - DACa, 0 - unused, 0 - gain 2x, 1 - active
	highVal = (uint8_t) (val_a >> 8);
	lowVal = (uint8_t) (val_a & ~(0xFF00));

	SPI_Port &= ~(1<<SPI_SS);
	//_delay_us(1);
	SPI_ret = SPI_send(highVal);
	SPI_ret = SPI_send(lowVal);
	SPI_Port |= 1<<SPI_SS;

	//Setting DACb value
	val_b &= ~(0xF000);		//Zero the four MSbits
	val_b |= 0x9000; 		//1 - DACb, 0 - unused, 0 - gain 2x, 1 - active
	highVal = (uint8_t) (val_b >> 8);
	lowVal = (uint8_t) (val_b & ~(0xFF00));

	SPI_Port &= ~(1<<SPI_SS);
	//_delay_us(1);
	SPI_ret = SPI_send(highVal);
	SPI_ret = SPI_send(lowVal);
	SPI_Port |= 1<<SPI_SS;

	//Synchronization LDAC impulse
	SPI_Port &= ~(1<<SPI_LDAC);
	_delay_us(1);
	SPI_Port |= 1<<SPI_LDAC;
}

static void Read_AD() {				//If ADIF flag is set, function copies 8 MSBs to adcParam variable
	if ((ADCSRA&(1<<ADIF)) != 0) {
		adcParam = ADCH;
		ADCSRA |= 1<<ADSC;
	}
}

static void Read_AD_wait() {		//Waits until ADIF flag is set, then copies 8 MSBs to adcParam variable
	while ((ADCSRA&(1<<ADIF))==0) {
		_delay_ms(1);
	}
		adcParam = ADCH;
		ADCSRA |= 1<<ADSC;
}

static void int_to_printStr(uint8_t number) {	//Number to string with \n
	itoa(number, printStr, 10);
	if (number<10) {
		printStr[1]=0x20;
		printStr[2]=0x20;
	}
	if (number<100) {
		printStr[2]=0x20;
	}
	printStr[3]=0x0A;
}





//INIT functions ***************************************************


static void AD_init() {
	ADCSRA |= (1<<ADPS2) | (1<<ADPS1); //Prescaler = 64
	ADMUX |= 1<<ADLAR;		//Shift to left
	ADMUX |= 1<<REFS0;		//Ref. source - AVCC with external cap at AREF
	ADCSRA &= ~(1<<ADIE);	//ADIE bit  AD interrupt disable
	ADCSRA |= 1<<ADEN;		//AD enable
	sei();					//Interrupt global enable
	ADCSRA |= 1<<ADSC;		//AD start conversion
}

static void EXT_INT_init() {

	LCD_Control_Data_Dir &= ~((1<<Left_button) | (1<<Mode_Button) | (1<<Right_button) | (1<<INT0_Pin) | (1<<INT1_Pin)); //Set button and interrupt pins as inputs
	LCD_Control	|= ((1<<Left_button) | (1<<Mode_Button) | (1<<Right_button) | (1<<INT0_Pin) | (1<<INT1_Pin)); //Pull-up resistors on
	SPI_Data_Dir |= (1<<PB0);//LED out as output
	SPI_Data_Dir |= (1<<PB1);
	SPI_Port |= (1<<PB1);
	//SPI_Port &= ~(1<<PB0);
	SPI_Port |= (1<<PB0);
	MCUCR |= 1<<ISC01;		//ISC01=1, ISC00=0 - Falling edge generates an interrupt request 0
	GICR |= 1<<INT0;		//INT0=1 - External interrupt request 0 enable
	MCUCR |= 1<<ISC11;		//ISC11=1, ISC10=0 - Falling edge generates an interrupt request 1
	GICR |= 1<<INT1;		//INT1=1 - External interrupt request 1 enable
}

static void TC1_init() {
	TCNT1 = timer_preset;
	TCCR1B |= (1<<CS10);
	TIMSK |= (1<<TOIE1);
	// no prescaler and start the timer
}





//INTERRUPT VECTORS ***************************************************

ISR(TIMER1_OVF_vect) {		//Timer TC1 overflow interrupt routine
							//(called with 22kHz freq.)

	TCNT1 = timer_preset;	//Set the TCNT1 count register
	//PORTB |= (1<<PB1);
	Set_DAC_val(DACa_out_val, DACb_out_val);	//Send output values to the DACs

	if (time_measure_enable==1) step_time++;	//If we are measuring time now, increment the "tempo" variable

	if (play_enable==1) {						//If a sequence is being played, unmute output and incerement sequence timer
		mute_enable = 0;
		sequence_timer++;
		if (sequence_timer>=step_time) {		//If the time of 1 step is over, increment position in sequence to another step
			sequence_timer = 0;
			sequence_position++;
			accumulator = 0;
			accumulator2 = 0;
			PORTB ^= (1<<PB0); 					//invert LED state
			if (sequence_position==16) {		//If we are at the end of the sequence, jump to the start
				sequence_position = 0;
				//play_enable = 0;
			}
		}
	} else {									//If the sequence is stopped and the step_preview activated, play,
		if (step_preview==0) {					//otherwise mute the output
			mute_enable = 1;
		} else {
			mute_enable = 0;
		}
	}

	Next_waveform_step();						//Next output values calculation, see the proc..

	//Button debouncing timing
	if (keyEnable==0) {
		debounce_count++;
		if (debounce_count == 1100) {
			if ( (PIND & ((1<<Mode_Button) | (1<<Left_button) | (1<<Right_button))) == ((1<<Mode_Button) | (1<<Left_button) | (1<<Right_button)) ) {
				keyEnable = 1;												//If none of the buttons are pressed,
				debounce_count = 0;											//then enable keys, otherwise wait
			} else {														//another 36 milliseconds
				debounce_count = 800;
			}
		}
		long_press_count++;
		if ((long_press_count>=15000) && ((PIND & (1<<Mode_Button))==0)) {  //If Parameter or mode button is pressed longer than 680ms
			Mode_button_long_press_event();									//call the long_press proc. corresponding to the button
			long_press_count = 0;
		}
		if ((long_press_count>=15000) && ((PIND & (1<<Left_button))==0)) {
			Left_button_long_press_event();
			long_press_count = 0;
		}

	} else {
		long_press_count = 0;
	}
	//PORTB &= ~(1<<PB1);
}


ISR(INT0_vect) {			//BUTTON interrupt vector
	uint8_t button_state;
	uint8_t button_resolved = 0;
	uint8_t resolve_attempts = 0;
	button_state = PIND;
	button_state &= ((1<<Left_button) | (1<<Mode_Button) | (1<<Right_button));
	if (keyEnable==1) {
		keyEnable = 0;
		while(button_resolved==0) {									//Because the buttons are bouncing, we need to resolve, which one
				resolve_attempts++;									//has been pressed in a cycle
					if ((button_state & (1<<Left_button)) == 0) {
						Left_button_event();
						button_resolved = 1;
					}
					if ((button_state & (1<<Mode_Button)) == 0) {
						Mode_button_event();
						button_resolved = 1;
					}
					if ((button_state & (1<<Right_button)) == 0) {
						Right_button_event();
						button_resolved = 1;
					}

				button_state = PIND;
				button_state &= ((1<<Left_button) | (1<<Mode_Button) | (1<<Right_button));
				if (resolve_attempts==50) button_resolved = 1;
		}
	}
}



ISR(INT1_vect) {			//PIEZO interrupt vector
	Piezo_event();
}

