#include "hal_adc.h"

static uint16_t m_au16AdcValue[16];

#define DMA_UNIT                        (CM_DMA1)
#define DMA_PERIPH_CLK                  (FCG0_PERIPH_DMA1)
#define DMA_CH                          (DMA_CH0)
#define DMA_AOS_TRIG_SEL                 AOS_DMA1_0 

#define DMA_TRANS_CNT                   (0U)
#define DMA_BLOCK_SIZE                  (16U)
#define DMA_DATA_WIDTH                  (DMA_DATAWIDTH_16BIT)
#define DMA_SRC_ADDR                    ((uint32_t)&CM_ADC1->DR0) 
#define DMA_DEST_ADDR                   ((uint32_t)(&m_au16AdcValue[0U]))

#define DMA_TRIG_EVT                    (EVT_SRC_ADC1_EOCA)

#define DMA_INT_TYPE                    (DMA_INT_BTC_CH0)
#define DMA_INT_IRQn                    (DMA1_TC0_BTC0_IRQn)
#define DMA_INT_PRIO                    (DDL_IRQ_PRIO_03)
#define DMA_INT_FLAG                    (DMA_FLAG_BTC_CH0)
#define DMA_IRQ_HANDLER                  DMA1_TC0_BTC0_Handler
 
 


void adc_init(void)
{
    stc_adc_init_t stcAdcInit;
	
		CLK_SetClockDiv((CLK_BUS_PCLK2 | CLK_BUS_PCLK4), (CLK_PCLK2_DIV8 | CLK_PCLK4_DIV2));
    CLK_SetPeriClockSrc(CLK_PERIPHCLK_PCLK);
	
    /* 1. Enable ADC peripheral clock. */
    FCG_Fcg3PeriphClockCmd(FCG3_PERIPH_ADC1, ENABLE);
    /* 2. Modify the default value depends on the application. */
    (void)ADC_StructInit(&stcAdcInit);
    /* 3. Initializes ADC. */
    (void)ADC_Init(CM_ADC1, &stcAdcInit);
    /* 4. ADC channel configuration. */
    /* 4.1 Set the ADC pin to analog input mode. */
    	/*
		CH0  PA0  ADC1_IN0  
		CH1  PA1  ADC1_IN1 
		CH2  PA2  ADC1_IN2 
		CH3  PA3  ADC1_IN3 
		CH4  PA4  ADC12_IN4
		CH5  PA5  ADC12_IN5 
		CH6  PA6  ADC123_IN6
		CH7  PA7  ADC123_IN7
		
		CH10 PC0  ADC12_IN10 
		CH11 PC1  ADC12_IN11 
		CH12 PC2  ADC1_IN12
		CH13 PC3  ADC1_IN13	
		CH14 PC6  ADC1_IN14
		CH15 PC7  ADC1_IN15	
		*/
		stc_gpio_init_t stcGpioInit;

		GPIO_StructInit(&stcGpioInit);
		stcGpioInit.u16PinAttr = PIN_ATTR_ANALOG;
			
		GPIO_Init(GPIO_PORT_A, GPIO_PIN_00, &stcGpioInit);
		GPIO_Init(GPIO_PORT_A, GPIO_PIN_01, &stcGpioInit);
		//GPIO_Init(GPIO_PORT_A, GPIO_PIN_02, &stcGpioInit);
		GPIO_Init(GPIO_PORT_A, GPIO_PIN_03, &stcGpioInit);
		GPIO_Init(GPIO_PORT_A, GPIO_PIN_04, &stcGpioInit);
		GPIO_Init(GPIO_PORT_A, GPIO_PIN_05, &stcGpioInit);
		GPIO_Init(GPIO_PORT_A, GPIO_PIN_06, &stcGpioInit);
		GPIO_Init(GPIO_PORT_A, GPIO_PIN_07, &stcGpioInit);

		GPIO_Init(GPIO_PORT_C, GPIO_PIN_00, &stcGpioInit);
		GPIO_Init(GPIO_PORT_C, GPIO_PIN_01, &stcGpioInit);
		GPIO_Init(GPIO_PORT_C, GPIO_PIN_02, &stcGpioInit);
		GPIO_Init(GPIO_PORT_C, GPIO_PIN_03, &stcGpioInit);
		GPIO_Init(GPIO_PORT_C, GPIO_PIN_04, &stcGpioInit);
		GPIO_Init(GPIO_PORT_C, GPIO_PIN_05, &stcGpioInit);
		
	
		ADC_ChCmd(CM_ADC1, ADC_SEQ_A, ADC_CH0,ENABLE);
		ADC_ChCmd(CM_ADC1, ADC_SEQ_A, ADC_CH1,ENABLE);
		ADC_ChCmd(CM_ADC1, ADC_SEQ_A, ADC_CH2,ENABLE);
		ADC_ChCmd(CM_ADC1, ADC_SEQ_A, ADC_CH3,ENABLE);
		ADC_ChCmd(CM_ADC1, ADC_SEQ_A, ADC_CH4,ENABLE);
		ADC_ChCmd(CM_ADC1, ADC_SEQ_A, ADC_CH5,ENABLE);
		ADC_ChCmd(CM_ADC1, ADC_SEQ_A, ADC_CH6,ENABLE);
		ADC_ChCmd(CM_ADC1, ADC_SEQ_A, ADC_CH7,ENABLE);
		ADC_ChCmd(CM_ADC1, ADC_SEQ_A, ADC_CH10,ENABLE);
		ADC_ChCmd(CM_ADC1, ADC_SEQ_A, ADC_CH11,ENABLE);
		ADC_ChCmd(CM_ADC1, ADC_SEQ_A, ADC_CH12,ENABLE);
		ADC_ChCmd(CM_ADC1, ADC_SEQ_A, ADC_CH13,ENABLE);
		ADC_ChCmd(CM_ADC1, ADC_SEQ_A, ADC_CH14,ENABLE);
		ADC_ChCmd(CM_ADC1, ADC_SEQ_A, ADC_CH15,ENABLE);

    ADC_ConvDataAverageConfig(CM_ADC1, ADC_AVG_CNT8);
		
		ADC_ConvDataAverageChCmd(CM_ADC1, ADC_CH0,ENABLE);
		ADC_ConvDataAverageChCmd(CM_ADC1, ADC_CH1,ENABLE);
		ADC_ConvDataAverageChCmd(CM_ADC1, ADC_CH2,ENABLE);
		ADC_ConvDataAverageChCmd(CM_ADC1, ADC_CH3,ENABLE);
		ADC_ConvDataAverageChCmd(CM_ADC1, ADC_CH4,ENABLE);
		ADC_ConvDataAverageChCmd(CM_ADC1, ADC_CH5,ENABLE);
		ADC_ConvDataAverageChCmd(CM_ADC1, ADC_CH6,ENABLE);
		ADC_ConvDataAverageChCmd(CM_ADC1, ADC_CH7,ENABLE);
		ADC_ConvDataAverageChCmd(CM_ADC1, ADC_CH10,ENABLE);
		ADC_ConvDataAverageChCmd(CM_ADC1, ADC_CH11,ENABLE);
		ADC_ConvDataAverageChCmd(CM_ADC1, ADC_CH12,ENABLE);
		ADC_ConvDataAverageChCmd(CM_ADC1, ADC_CH13,ENABLE);
		ADC_ConvDataAverageChCmd(CM_ADC1, ADC_CH14,ENABLE);
		ADC_ConvDataAverageChCmd(CM_ADC1, ADC_CH15,ENABLE);
		


//    stc_dma_init_t stcDmaInit;
//    stc_dma_repeat_init_t stcDmaRptInit;

//    (void)DMA_StructInit(&stcDmaInit);
//    stcDmaInit.u32IntEn       = DMA_INT_ENABLE;
//    stcDmaInit.u32SrcAddr     = DMA_SRC_ADDR;
//    stcDmaInit.u32DestAddr    = DMA_DEST_ADDR;
//    stcDmaInit.u32DataWidth   = DMA_DATA_WIDTH;
//    stcDmaInit.u32BlockSize   = DMA_BLOCK_SIZE;
//    stcDmaInit.u32TransCount  = DMA_TRANS_CNT;
//    stcDmaInit.u32SrcAddrInc  = DMA_SRC_ADDR_INC;
//    stcDmaInit.u32DestAddrInc = DMA_DEST_ADDR_INC;
//    /* Enable DMA peripheral clock and AOS function. */
//    FCG_Fcg0PeriphClockCmd(DMA_PERIPH_CLK, ENABLE);
//    (void)DMA_Init(DMA_UNIT, DMA_CH, &stcDmaInit);

//    stcDmaRptInit.u32Mode      = DMA_RPT_BOTH;
//    stcDmaRptInit.u32SrcCount  = DMA_BLOCK_SIZE;
//    stcDmaRptInit.u32DestCount = DMA_BLOCK_SIZE;
//    (void)DMA_RepeatInit(DMA_UNIT, DMA_CH, &stcDmaRptInit);

//    /* Enable AOS clock */
//    FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_AOS, ENABLE);
//    /* Set DMA trigger source */
//    AOS_SetTriggerEventSrc(DMA_AOS_TRIG_SEL, DMA_TRIG_EVT);
//    /* DMA IRQ configuration. */
//     
//		DMA_ClearTransCompleteStatus(DMA_UNIT, DMA_INT_FLAG);
//    /* NVIC setting */
//    NVIC_ClearPendingIRQ(DMA_INT_IRQn);
//    NVIC_SetPriority(DMA_INT_IRQn, DDL_IRQ_PRIO_03);
//    NVIC_EnableIRQ(DMA_INT_IRQn);
//		
//    DMA_Cmd(DMA_UNIT, ENABLE);
//    DMA_ChCmd(DMA_UNIT, DMA_CH, ENABLE);
		
		    
}

//uint8_t m_u8AdcValUpdated = 0;
//void DMA_IRQ_HANDLER(void)
//{
//    if (DMA_GetTransCompleteStatus(DMA_UNIT, DMA_INT_FLAG) == SET) 
//		{
//        DMA_ClearTransCompleteStatus(DMA_UNIT, DMA_INT_FLAG);
//        m_u8AdcValUpdated = 1U;
//    }
//}

//#include "FreeRTOS.h"
//#include "task.h"

//void test_task3(void *pvParameters)
//{
//	while(1)
//	{
//		if(m_u8AdcValUpdated==0)
//		{
//			ADC_Start(CM_ADC1);
//		}
//		else
//		{
//			ADC_Stop(CM_ADC1);
//			for(int i=0;i < 16;i++)
//			{
//				printf("%dV ",m_au16AdcValue[9]/*(float)m_au16AdcValue[9]/4095*3.3*/);
//			}
//			printf("\n");
//			m_u8AdcValUpdated = 0;
//		}
//		vTaskDelay(500);
//	}
//}


uint16_t u16AdcValue;
uint16_t get_adc_value(uint8_t ch)
{
  
    int32_t iRet = LL_ERR;
    __IO uint32_t u32TimeCount = 0UL;

    /* Can ONLY start sequence A conversion.
       Sequence B needs hardware trigger to start conversion. */
    ADC_Start(CM_ADC1);
    do {
        if (ADC_GetStatus(CM_ADC1, ADC_FLAG_EOCA) == SET) {
            ADC_ClearStatus(CM_ADC1, ADC_FLAG_EOCA);
            iRet = LL_OK;
            break;
        }
    } while (u32TimeCount++ < ADC_TIMEOUT_VAL);

    if (iRet == LL_OK) 
		{
        /* Get any ADC value of sequence A channel that needed. */
        u16AdcValue = ADC_GetValue(CM_ADC1,ch);
    } 
		else 
		{
        ADC_Stop(CM_ADC1);        
    }
		
		return u16AdcValue;
}

 
 


