#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>
#include "inc/hw_memmap.h"
#include "inc/hw_adc.h"
#include "inc/tm4c129xnczad.h"
#include "driverlib/sysctl.h"
#include "driverlib/pin_map.h"
#include "driverlib/gpio.h"
#include "driverlib/adc.h"
#include "driverlib/interrupt.h"

#define MEM_BUFFER_SIZE 16
#define SCAN_BUFFER_SIZE 16
static uint32_t g_ui32DstBuf[MEM_BUFFER_SIZE];
static uint32_t g_ui32DstBuf1[MEM_BUFFER_SIZE];
static uint32_t g_ui32DstBuf2[MEM_BUFFER_SIZE];
static uint32_t g_ui32ScanBuf[SCAN_BUFFER_SIZE];

static uint32_t ui32Mode;

uint32_t pui32ADC0Value[8];
uint32_t pui32ADC1Value[4];
uint32_t pui32ADC2Value[4];
volatile uint8_t ui8ADCConvStat;

void sysclk()
{
	SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
			SYSCTL_CFG_VCO_480), 120000000);
}


  void SADC_Init()
    {
	    ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PIOSC | ADC_CLOCK_RATE_FULL, 8);
	    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
	    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
	    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
	    //SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK);
	    GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 |GPIO_PIN_3);
	    GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 |GPIO_PIN_7);
	    GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_4 | GPIO_PIN_5);
	    GPIOPinTypeADC(GPIO_PORTB_BASE, GPIO_PIN_4 | GPIO_PIN_5);
	    GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 |GPIO_PIN_3);
	   // GPIOPinTypeADC(GPIO_PORTK_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 |GPIO_PIN_3);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
        ADCSequenceStepConfigure(ADC0_BASE, 0,  0, ADC_CTL_CH0 );
        ADCSequenceStepConfigure(ADC0_BASE, 0,  1, ADC_CTL_CH1 );
        ADCSequenceStepConfigure(ADC0_BASE, 0,  2, ADC_CTL_CH2 );
        ADCSequenceStepConfigure(ADC0_BASE, 0,  3, ADC_CTL_CH3 );
        ADCSequenceStepConfigure(ADC0_BASE, 0,  4, ADC_CTL_CH4 );
        ADCSequenceStepConfigure(ADC0_BASE, 0,  5, ADC_CTL_CH5 );
        ADCSequenceStepConfigure(ADC0_BASE, 0,  6, ADC_CTL_CH6 );
        ADCSequenceStepConfigure(ADC0_BASE, 0,  7, ADC_CTL_CH7 | ADC_CTL_IE );
        ADCSequenceStepConfigure(ADC0_BASE, 1,  0, ADC_CTL_CH8 );
        ADCSequenceStepConfigure(ADC0_BASE, 1,  1, ADC_CTL_CH9 );
        ADCSequenceStepConfigure(ADC0_BASE, 1,  2, ADC_CTL_CH10);
        ADCSequenceStepConfigure(ADC0_BASE, 1,  3, ADC_CTL_CH11| ADC_CTL_IE);
        ADCSequenceStepConfigure(ADC0_BASE, 2,  0, ADC_CTL_CH12);
        ADCSequenceStepConfigure(ADC0_BASE, 2,  1, ADC_CTL_CH13);
        ADCSequenceStepConfigure(ADC0_BASE, 2,  2, ADC_CTL_CH14);
        ADCSequenceStepConfigure(ADC0_BASE, 2,  3, ADC_CTL_CH15| ADC_CTL_IE);// | ADC_CTL_END);

		ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_PROCESSOR, 0);
		ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 1);
		ADCSequenceConfigure(ADC0_BASE, 2, ADC_TRIGGER_PROCESSOR, 2);
		ADCReferenceSet(ADC0_BASE, ADC_REF_INT );//ADC_REF_EXT_3V);

		ADCSequenceEnable(ADC0_BASE, 0);
		ADCSequenceEnable(ADC0_BASE, 1);
		ADCSequenceEnable(ADC0_BASE, 2);
        
        ADCIntEnable(ADC0_BASE, 0);
        ADCIntEnable(ADC0_BASE, 1);
        ADCIntEnable(ADC0_BASE, 2);

		IntEnable(ADC_INT_SS0);
		IntEnable(ADC_INT_SS1);
		IntEnable(ADC_INT_SS2);

		IntMasterEnable();


}


void ADC00_IntHandler()
{
    ADCIntClear(ADC0_BASE, 0);
    ADCSequenceDataGet(ADC0_BASE, 0, pui32ADC0Value);
    ui8ADCConvStat |= 0x1;
}

void ADC01_IntHandler()
{
    ADCIntClear(ADC0_BASE, 1);
    ADCSequenceDataGet(ADC0_BASE, 1, pui32ADC1Value);
    ui8ADCConvStat |= 0x2;
}

void ADC02_IntHandler()
{
    ADCIntClear(ADC0_BASE, 3);
	ADCSequenceDataGet(ADC0_BASE, 3, pui32ADC3Value);
    ui8ADCConvStat |= 0x4;
}


int main(void) {
	sysclk();
	SADC_Init();

while(1)
{
    ADCProcessorTrigger(ADC0_BASE, 0);
    while(ADCBusy(ADC0_BASE));
    ADCProcessorTrigger(ADC0_BASE, 1);
    while(ADCBusy(ADC0_BASE));
    ADCProcessorTrigger(ADC0_BASE, 2);
    while(ADCBusy(ADC0_BASE));
    
    while(ui8ADCConvStat != 0x7);
	ui8ADCConvStat = 0x0;
}
}