/*
 * my_interrupt.c
 *
 *  Created on: gg/mmm/ccaa
 *      Author: cognome.nome
 *
 * fondamentale!!!
 * gestione dell'acquisizione analogica e della gestione degli interrupt
 * devo solo cambiare i valori di fondoscala
 *
 */

//==============================================================================
// Include files

#include "string.h"
#include "stdbool.h"
#include "stdint.h"

#include "inc/hw_memmap.h"
#include "inc/hw_ints.h"

#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "driverlib/rom.h"

//#include "drivers/AD7193.h"
#include "drivers/my_interrupt.h"
#include "drivers/my_semaphore.h"
#include "drivers/my_GPIO.h"
#include "drivers/my_SPI.h"
#include "drivers/my_timer.h"
#include "my_debug.h"
#include "drivers/my_flash.h"
#include "drivers/my_params_prod.h"

#include "TLGB/TLGB_flash.h"
#include "TLGB/TLGB_Diginout.h"
#include "TLGB/TLGB_Pagine_Selettore.h"

//==============================================================================
// Constants

// Interrupt priority definitions.  The top 3 bits of these values are
// significant with lower values indicating higher priority interrupts.
#define SYSTICK_INT_PRIORITY    0x80
#define ETHERNET_INT_PRIORITY   0xC0
#define GPIOA_INT_PRIORITY      0xE0
#define GPIOJ_INT_PRIORITY      0xE0
#define TIMER_INT_PRIORITY      0xE0
#define FLASH_INT_PRIORITY      0xE0
#define INPUTS_INT_PRIORITY     0xE0

//==============================================================================
// Types

//==============================================================================
// Static global variables

static volatile unsigned long GPIOPIntHandlerCounter = 0;
static volatile unsigned long GPIOTIntHandlerCounter = 0;
static volatile unsigned long GPIOBIntHandlerCounter = 0;
static volatile unsigned long GPIOQIntHandlerCounter = 0;

static volatile unsigned long GPIOAIntHandlerCounter = 0;
static volatile unsigned long count  = 0;
static volatile unsigned long count1 = 0;
static volatile unsigned long count2 = 0;
static volatile unsigned long count3 = 0;
static volatile unsigned long count4 = 0;
static volatile unsigned long count5 = 0;
static volatile unsigned long count6 = 0;
static volatile unsigned long count7 = 0;

//==============================================================================
// Static functions

//==============================================================================
// Global variables

TChannelValues ChannelValues = {0,0,0,0,0,0,0,0};
unsigned long microcheck_in_run = 0;
volatile unsigned long AD_data_ready[4] = {0};

//==============================================================================
// Global functions

long EnableInterrupts(void)
{
	//---------------------------------------------------
	// ETHERNET
	ROM_IntPrioritySet(INT_EMAC0, ETHERNET_INT_PRIORITY);
	//---------------------------------------------------
	// TIMER
	ROM_IntPrioritySet(FAULT_SYSTICK, SYSTICK_INT_PRIORITY);
	//---------------------------------------------------
	// SPI
	ROM_IntPrioritySet(INT_TIMER0A, TIMER_INT_PRIORITY);
	ROM_IntPrioritySet(INT_TIMER1A, TIMER_INT_PRIORITY);
	ROM_IntPrioritySet(INT_TIMER2A, TIMER_INT_PRIORITY);
	//---------------------------------------------------
	// DAC
	 ROM_IntPrioritySet(INT_TIMER3A, TIMER_INT_PRIORITY);
	//---------------------------------------------------
	ROM_IntPrioritySet(INT_GPIOA, GPIOA_INT_PRIORITY);
	ROM_IntPrioritySet(INT_GPIOJ, GPIOJ_INT_PRIORITY);
	//---------------------------------------------------
	// KEYBOARD
	 ROM_IntPrioritySet(INT_TIMER4A, TIMER_INT_PRIORITY);
	//---------------------------------------------------
	 ROM_IntPrioritySet(INT_FLASH, FLASH_INT_PRIORITY);
	//---------------------------------------------------

	//---------------------------------------------------
	// INPUTS
	ROM_IntPrioritySet(INT_GPIOP0, INPUTS_INT_PRIORITY);
	ROM_IntPrioritySet(INT_GPIOT, INPUTS_INT_PRIORITY);
	ROM_IntPrioritySet(INT_GPIOB, INPUTS_INT_PRIORITY);
	ROM_IntPrioritySet(INT_GPIOQ0, INPUTS_INT_PRIORITY);
	//---------------------------------------------------

	 // Enable processor interrupts
	ROM_IntMasterEnable();

	return 0;
}

void GPIOAIntHandler(void)
{
	ROM_GPIOIntClear(GPIO_PORTA_BASE, GPIO_PIN_5);
    // devo disabilitare l'interrupt perchè il fronte di discesa dei dati non va confuso con la trasmissione
    SPI_Continuous_Read_Disable();

    GPIOAIntHandlerCounter++;

	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Data23 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Data22 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Data21 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Data20 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Data19 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Data18 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Data17 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Data16 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Data15 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Data14 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Data13 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Data12 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Data11 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Data10 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Data9 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Data8 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Data7 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Data6 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Data5 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Data4 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Data3 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Data2 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Data1 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Data0 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.nRDY = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.ERR = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.NOREF = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.Parity = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.CHD3 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.CHD2 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.CHD1 = GPIO_get_ADC_DOUT();
	GPIO_set_ADC_SCLK(WRITE_0);
	GPIO_set_ADC_SCLK(WRITE_1);
	Data.CHD0 = GPIO_get_ADC_DOUT();

	// Formula Single Ended
	// Code = (2^N * AIN * Gain) / Vref;
	// AIN = (Code * Vref) / (2^N * Gain);

	// Formula Differenziale
	// Code = 2^(N-1) * ((AIN x Gain/Vref) + 1);
	// AIN = ( (Code / 2^(N-1)) - 1) * Vref / Gain;

	switch(Data.Status_CHD)
	{
		case 1:
		{
			count1++;
			if(Configuration.U_B == 0)
			{
		        //voltage = (((float)rawData / (1ul << 23)) - 1) * vRef / currentGain;
				ChannelValues.DifferentialValue1_Tensione    = (((float)Data.Data / (1ul << 23)) - 1) * AcquisitionManage.ReferenceValue / AcquisitionManage.Gain;
				ChannelValues.DifferentialValue1_Grandezza = linearizza_ingressi(ChannelValues.DifferentialValue1_Tensione, 0);
				ChannelValues.DifferentialValue1Err = (unsigned long)Data.ERR;

				if(AD_data_ready[0] == 0)
				{
					AD_data_ready[0] = 1;
				}
			}
			else
			{
				//voltage = ((float)rawData * vRef) / (1ul << 24) / currentGain;
				ChannelValues.SingleEndedValue1_Tensione     = ((float)Data.Data * AcquisitionManage.ReferenceValue) / (1ul << 24) / AcquisitionManage.Gain;
				ChannelValues.SingleEndedValue1_Grandezza = linearizza_ingressi(ChannelValues.SingleEndedValue1_Tensione, 0);
				ChannelValues.SingleEndedValue1Err  = (unsigned long)Data.ERR;

				if(AD_data_ready[0] == 0)
				{
					AD_data_ready[0] = 1;
				}
			}

		}
		break;
		case 3:
		{
			count3++;
			if(Configuration.U_B == 0)
			{
				ChannelValues.DifferentialValue3_Tensione    = (((float)Data.Data / (1ul << 23)) - 1) * AcquisitionManage.ReferenceValue / AcquisitionManage.Gain;
				ChannelValues.DifferentialValue3_Grandezza = linearizza_ingressi(ChannelValues.DifferentialValue3_Tensione, 2);
				ChannelValues.DifferentialValue3Err = (unsigned long)Data.ERR;

				if(AD_data_ready[2] == 0)
				{
					AD_data_ready[2] = 1;
				}
			}
			else
			{
				ChannelValues.SingleEndedValue2_Tensione     = ((float)Data.Data * AcquisitionManage.ReferenceValue) / (1ul << 24) / AcquisitionManage.Gain;
				ChannelValues.SingleEndedValue2_Grandezza = linearizza_ingressi(ChannelValues.SingleEndedValue2_Tensione, 1);
				ChannelValues.SingleEndedValue2Err  = (unsigned long)Data.ERR;

				if(AD_data_ready[1] == 0)
				{
					AD_data_ready[1] = 1;
				}
			}

		}
		break;
		case 5:
		{
			count5++;
			if(Configuration.U_B == 0)
			{
				ChannelValues.DifferentialValue2_Tensione = (((float)Data.Data / (1ul << 23)) - 1) * AcquisitionManage.ReferenceValue / AcquisitionManage.Gain;
				ChannelValues.DifferentialValue2_Grandezza = linearizza_ingressi(ChannelValues.DifferentialValue2_Tensione, 1);
				ChannelValues.DifferentialValue2Err = (unsigned long)Data.ERR;

				if(AD_data_ready[1] == 0)
				{
					AD_data_ready[1] = 1;
				}
			}
			else
			{
				ChannelValues.SingleEndedValue3_Tensione = ((float)Data.Data * AcquisitionManage.ReferenceValue) / (1ul << 24) / AcquisitionManage.Gain;
				ChannelValues.SingleEndedValue3_Grandezza = linearizza_ingressi(ChannelValues.SingleEndedValue3_Tensione, 2);
				ChannelValues.SingleEndedValue3Err  = (unsigned long)Data.ERR;

				if(AD_data_ready[2] == 0)
				{
					AD_data_ready[2] = 1;
				}
			}
		}
		break;
		case 7:
		{
			count7++;
			if(Configuration.U_B == 0)
			{
				ChannelValues.DifferentialValue4_Tensione = (((float)Data.Data / (1ul << 23)) - 1) * AcquisitionManage.ReferenceValue / AcquisitionManage.Gain;
				ChannelValues.DifferentialValue4_Grandezza = linearizza_ingressi(ChannelValues.DifferentialValue4_Tensione, 3);
				ChannelValues.DifferentialValue4Err = (unsigned long)Data.ERR;

				if(AD_data_ready[3] == 0)
				{
					AD_data_ready[3] = 1;
				}
			}
			else
			{
				ChannelValues.SingleEndedValue4_Tensione = ((float)Data.Data * AcquisitionManage.ReferenceValue) / (1ul << 24) / AcquisitionManage.Gain;
				ChannelValues.SingleEndedValue4_Grandezza = linearizza_ingressi(ChannelValues.SingleEndedValue4_Tensione, 3);
				ChannelValues.SingleEndedValue4Err  = (unsigned long)Data.ERR;

				if(AD_data_ready[3] == 0)
				{
					AD_data_ready[3] = 1;
				}
			}
		}
		break;
		default:
		{
			count++;
		};
	};

	if(AcquisitionManage.WaitDisableInterruptAD == 1)
	{
		// Segnalo che posso disabilitare l'acquisizione
		AcquisitionManage.WaitDisableInterruptAD = 0;
	}
	else
	{
		SPI_Continuous_Read_Enable();
	}
}

void GPIOModule1Handler(void)
{
	unsigned long ulInts;

    // Get and clear the current interrupt source(s)
    ulInts = ROM_GPIOIntStatus(GPIO_PORTT_BASE, true);
    ROM_GPIOIntClear(GPIO_PORTT_BASE, ulInts);

    GPIOPIntHandlerCounter++;

    if(ulInts & GPIO_PIN_0)
    {
    	// ingresso 1 modulo 1
    	in[0].in1 = ROM_GPIOPinRead(GPIO_PORTT_BASE, GPIO_PIN_0);
		//in = ROM_GPIOPinRead(GPIO_PORTT_BASE, GPIO_PIN_0);
    }
    if(ulInts & GPIO_PIN_1)
    {
    	// ingresso 2 modulo 1
    	in[0].in2 = ROM_GPIOPinRead(GPIO_PORTT_BASE, GPIO_PIN_1) >> 1;
    	//in = ROM_GPIOPinRead(GPIO_PORTT_BASE, GPIO_PIN_1) >> 1;
    }
    if(ulInts & GPIO_PIN_2)
    {
    	// ingresso 3 modulo 1
    	in[0].in3 = ROM_GPIOPinRead(GPIO_PORTT_BASE, GPIO_PIN_2) >> 2;
		//in = ROM_GPIOPinRead(GPIO_PORTT_BASE, GPIO_PIN_2) >> 2;
    }
    if(ulInts & GPIO_PIN_3)
    {
    	// ingresso 4 modulo 1
    	in[0].in4 = ROM_GPIOPinRead(GPIO_PORTT_BASE, GPIO_PIN_3) >> 3;
		//in = ROM_GPIOPinRead(GPIO_PORTT_BASE, GPIO_PIN_3) >> 3;
    }

}

void GPIOModule2Handler(void)
{
	unsigned long ulInts;

    // Get and clear the current interrupt source(s)
    ulInts = ROM_GPIOIntStatus(GPIO_PORTP_BASE, true);
    ROM_GPIOIntClear(GPIO_PORTP_BASE, ulInts);

    GPIOTIntHandlerCounter++;

    if(ulInts & GPIO_PIN_0)
    {
    	// ingresso 1 modulo 2
    	in[1].in1 = ROM_GPIOPinRead(GPIO_PORTP_BASE, GPIO_PIN_0);
		//in = ROM_GPIOPinRead(GPIO_PORTP_BASE, GPIO_PIN_0);
    }
    if(ulInts & GPIO_PIN_1)
    {
    	// ingresso 2 modulo 2
    	in[1].in2 = ROM_GPIOPinRead(GPIO_PORTP_BASE, GPIO_PIN_1) >> 1;
		//in = ROM_GPIOPinRead(GPIO_PORTP_BASE, GPIO_PIN_1) >> 1;
    }
    if(ulInts & GPIO_PIN_2)
    {
    	// ingresso 3 modulo 2
    	in[1].in3 = ROM_GPIOPinRead(GPIO_PORTP_BASE, GPIO_PIN_2) >> 2;
		//in = ROM_GPIOPinRead(GPIO_PORTP_BASE, GPIO_PIN_2) >> 2;
    }
    if(ulInts & GPIO_PIN_3)
    {
    	// ingresso 4 modulo 2
    	in[1].in4 = ROM_GPIOPinRead(GPIO_PORTP_BASE, GPIO_PIN_3) >> 3;
		//in = ROM_GPIOPinRead(GPIO_PORTP_BASE, GPIO_PIN_3) >> 3;
    }
}

void GPIOModule3Handler(void)
{
	unsigned long ulInts;

    // Get and clear the current interrupt source(s)
    ulInts = ROM_GPIOIntStatus(GPIO_PORTB_BASE, true);
    ROM_GPIOIntClear(GPIO_PORTB_BASE, ulInts);

    GPIOBIntHandlerCounter++;

    if(ulInts & GPIO_PIN_4)
    {
    	// ingresso 1 modulo 3
    	in[2].in1 = ROM_GPIOPinRead(GPIO_PORTB_BASE, GPIO_PIN_4) >> 4;
		//in = ROM_GPIOPinRead(GPIO_PORTB_BASE, GPIO_PIN_4) >> 4;
    }
    if(ulInts & GPIO_PIN_5)
    {
    	// ingresso 2 modulo 3
    	in[2].in2 = ROM_GPIOPinRead(GPIO_PORTB_BASE, GPIO_PIN_5) >> 5;
    	//in = ROM_GPIOPinRead(GPIO_PORTB_BASE, GPIO_PIN_5) >> 5;
    }
    if(ulInts & GPIO_PIN_6)
    {
    	// ingresso 3 modulo 3
    	in[2].in3 = ROM_GPIOPinRead(GPIO_PORTB_BASE, GPIO_PIN_6) >> 6;
		//in = ROM_GPIOPinRead(GPIO_PORTB_BASE, GPIO_PIN_6) >> 6;
    }
    if(ulInts & GPIO_PIN_7)
    {
    	// ingresso 4 modulo 3
    	in[2].in4 = ROM_GPIOPinRead(GPIO_PORTB_BASE, GPIO_PIN_7) >> 7;
		//in = ROM_GPIOPinRead(GPIO_PORTB_BASE, GPIO_PIN_7) >> 7;
    }
}

void GPIOSelectorHandler(void)
{
	unsigned long ulInts;

    // Get and clear the current interrupt source(s)
    ulInts = ROM_GPIOIntStatus(GPIO_PORTQ_BASE, true);
    ROM_GPIOIntClear(GPIO_PORTQ_BASE, ulInts);

    GPIOQIntHandlerCounter++;

    if(ulInts & GPIO_PIN_2)
    {
    	// selettore
    	// leggo il valore del selettore
    	microcheck_in_run = GPIO_SEL_PROG_RUN_read();
    	selettore_pagina();
    }
}
