/********************************************************* * 
@file		:adc_convert_test.c 
@brief  	:adc convert function test
@author 	:zhongfeng
@version	:v1.0 
@date 		:19/10/28
Copyright (C) 2019 Panchip Technology Corp. All rights reserved. 
***********************************************************/
#include "pan271x.h"
#include "adc_common.h"

//uint16_t WeightArr[16] = {8, 8, 8, 16, 32, 64, 96, 192, 0, 0, 0, 0, 0, 0, 0, 0};
uint16_t WeightArr[16] = {0, 0, 0, 0, 0, 0, 0, 0,};

void ADC_InitWeight(void)
{
	memset(WeightArr, 0, sizeof(WeightArr));
	WeightArr[0] = 8;
	WeightArr[1] = 8;
	WeightArr[2] = 8;
	WeightArr[3] = 16;
	WeightArr[4] = 32;
	WeightArr[5] = 64;
	WeightArr[6] = 96;
	WeightArr[7] = 192;
}

void ADC_SetConfig(void)
{
	uint32_t adc_ctl2, adc_temp;
	adc_ctl2 = ADC->ADC_CTL2;
	adc_temp = ADC->ADC_TEMP;
//	/* ctlr2 reg */

	adc_temp = (adc_temp & ~(0x1 << 25)) | (0x1 << 25); //adc cal cmp vos
	adc_temp = (adc_temp & ~(0x1 << 24)) | (0x0 << 24); //adc cal cmp vos
	adc_temp = (adc_temp & ~(0xf << 20)) | (0x0 << 20); //adc cal cmp vos

	adc_temp = (adc_temp & ~(0x1u << 31)) | (0x1u << 31); //adc cal cap en	 1bit
	adc_temp = (adc_temp & ~(0x1 << 18)) | (0x1 << 18); //adc vrefp byp en	
	adc_temp = (adc_temp & ~(0x1 << 17)) | (0x0 << 17); //adc vbg en

	adc_ctl2 = (adc_ctl2 & ~(0x1 << 26)) | (0x0 << 26); //buffer en   1bit

	adc_temp = (adc_temp & ~(0x1 << 16)) | (0x1 << 16); //diff mode en
	adc_temp = (adc_temp & ~(0x1 << 12)) | (0x1 << 12); //GPADC_VBOOST_BYP_EN

	ADC->ADC_CTL2 = adc_ctl2;
	ADC->ADC_TEMP = adc_temp;

	_ADC_LoadWeightCfg(WeightArr[0], WeightArr[1], WeightArr[2], WeightArr[3],
						WeightArr[4], WeightArr[5], WeightArr[6], WeightArr[7],
						WeightArr[8], WeightArr[9], WeightArr[10], WeightArr[11],
						WeightArr[12], WeightArr[13], WeightArr[14], WeightArr[15]);
}

void ADC_UpdateWeight(uint16_t Sn, uint8_t Offset)
{
	if (Offset >= 8) {
		WeightArr[Offset] = Sn;
		_ADC_LoadWeightCfg(WeightArr[0], WeightArr[1], WeightArr[2], WeightArr[3],
							WeightArr[4], WeightArr[5], WeightArr[6], WeightArr[7],
							WeightArr[8], WeightArr[9], WeightArr[10], WeightArr[11],
							WeightArr[12], WeightArr[13], WeightArr[14], WeightArr[15]);
	}
}

uint32_t ADC_CapAutoCalTest(void)
{
    uint16_t Sn_Val = 0;
    uint32_t SP, SN, data_sum = 0;
    uint8_t cnt = 0, i;

	CLK->APB1_CLK_CTRL0 |= APB1_CLK_CTRL0_ADC_CLK_SEL_Msk;

	ADC_IntEnable(ADC, ADC_CTL_EMPTY_INT_EN_Msk|ADC_CTL_OV_INT_EN_Msk
				|ADC_CTL_HALF_INT_EN_Msk|ADC_CTL_FULL_INT_EN_Msk|ADC_CTL_ADCIEN_Msk, DISABLE);
	ADC_HwTrigEnable(ADC, DISABLE);
	ADC_InitWeight();
	

	while (cnt < 8) {
		ADC_SetConfig();
		ADC_SetWeightRatio(ADC, weight_dif);
		ADC->ADC_TEMP = (ADC->ADC_TEMP & ~(0x7 << 27)) | ((0x7 - cnt) << 27); //adc cal cap sel
		ADC->ADC_TEMP = (ADC->ADC_TEMP & ~(0x1 << 26)) | (0x1 << 26); //adc cal cap side sel
		ADC_SetSampleCount(ADC, 7); // SAMPLE 128+2 times
		ADC_SetDiscardCount(ADC, 0x0); //discard 2 times
		ADC_EnableAverage(ADC, ENABLE);
		ADC_DecimalReadEnable(ADC, ENABLE);

		ADC_PowerOn(ADC);

//		while(ADC_IsBusy(ADC)){}
//		ADC_StartConvert(ADC);
//		while(!ADC_IsDataValid(ADC)){}
//		SP = ADC_GetConversionData(ADC);
		i = 10;
		while(i--){
			while(ADC_IsBusy(ADC)){}
			ADC_StartConvert(ADC);
			while(!ADC_IsDataValid(ADC)){}
			data_sum += ADC_GetConversionData(ADC);
		}
		SP = data_sum / 10;
		data_sum = 0;
		// Power down ADC
		ADC_PowerDown(ADC);

		SYS_delay_10nop(100000);

		//calc sn
		ADC_SetConfig();
		ADC_SetWeightRatio(ADC, weight_dif);
		ADC->ADC_TEMP = (ADC->ADC_TEMP & ~(0x7 << 27)) | ((0x7 - cnt) << 27); //adc cal cap sel
		ADC->ADC_TEMP = (ADC->ADC_TEMP & ~(0x1 << 26)) | (0x0 << 26); //adc cal cap side sel
		ADC_SetSampleCount(ADC, 7); // SAMPLE 128+2 times
		ADC_SetDiscardCount(ADC, 0x0); //discard 2 times
		ADC_EnableAverage(ADC, ENABLE);
		ADC_DecimalReadEnable(ADC, ENABLE);

		ADC_PowerOn(ADC);

		i = 10;
		while(i--){
			while(ADC_IsBusy(ADC)){}
			ADC_StartConvert(ADC);
			while(!ADC_IsDataValid(ADC)){}
			data_sum += ADC_GetConversionData(ADC);
		}
		SN = data_sum / 10;
		data_sum = 0;
		// Power down ADC
		ADC_PowerDown(ADC);

		Sn_Val = (SP - SN) / 2;
		SYS_TEST("SP/SN = %d/%d, S%d = %d\n", SP, SN, cnt+8, Sn_Val);
		ADC_UpdateWeight(Sn_Val, cnt+8);
		cnt++;
	}
    return 0;
}

