#include "OSAL.h"
#include "gpio.h"
#include "clock.h"
#include "adc.h"
#include "adc_conf.h"
#include "log.h"
#include "pwm.h"
#include "key_conf.h"
//**************************************************************************//

//**************************************************************************//


#define MAX_SAMPLE_POINT    64
static uint16_t adc_debug[6][MAX_SAMPLE_POINT];
static uint8_t channel_done_flag = 0;


#define PWM0_PIN P23
#define PWM1_PIN P0
#define PWM_TOP_VALUE      250

/*********************************************************************
    EXTERNAL VARIABLES
*/

/*********************************************************************
    EXTERNAL FUNCTIONS
*/

/*********************************************************************
    LOCAL VARIABLES
*/

//-15°~ 50°
float ntc_10k[66] ={
	73401.8, 69382.3, 65607.7, 62061.6, 58728.8, 55595.3, 52648, 49874.7, 47264.3, 44806.2, 42490.6,
	40308.6, 38251.6, 36311.7, 34481.7, 32754.7, 31124.3, 29584.7, 28130.1, 26755.6, 25456.2, 24227.4,
	23065, 21965, 20923.9, 19938, 19004.1, 18119.3, 17280.7, 16485.7, 15731.7, 15016.4, 14337.6, 
	13693.3, 13081.6, 12500.5, 11948.5, 11423.9, 10925.2, 10451, 10000,9570.9, 9162.6, 8773.8, 8403.7,
	8051.2, 7715.4, 7395.3, 7090.3, 6799.5, 6522.1, 6257.6, 6005.1, 5764.2, 5534.2, 5314.6, 5104.9, 
	4904.5, 4713, 4530, 4355.1, 4187.8, 4027.8, 3874.8, 3728.3, 3588.2
	
	
};

uint8 AAC_Adc_Task_Id;   // Task ID for internal task/event processing
/*
    channel:
    is_differential_mode:
    is_high_resolution:
    [bit7~bit2]=[p20,p15~p11],ignore[bit1,bit0]
    when measure adc(not battery),we'd better use high_resolution.
    when measure battery,we'd better use no high_resolution and keep the gpio alone.

    differential_mode is rarely used,
    if use please config channel as one of [ADC_CH3DIFF,ADC_CH2DIFF,ADC_CH1DIFF],
    and is_high_resolution as one of [0x80,0x20,0x08],
    then the pair of [P20~P15,P14~P13,P12~P11] will work.
    other adc channel cannot work.
*/
static adc_Cfg_t adc_cfg =
{

    .channel = ADC_BIT(ADC_CH1N_P11),//|ADC_BIT(ADC_CH2P_P14)
    .is_continue_mode = FALSE,
    .is_differential_mode = 0x00,
    .is_high_resolution = 0x00,

};


/*********************************************************************
    LOCAL FUNCTIONS
*/

static void adcPoilling_MeasureTask( void );


int Get_Temperature(float ntc_volt)
{
	float value =0;
	
	value = ntc_volt;
	for(short i =0; i<66;i++)
	{
		if(ntc_10k[i]>=value&&value>=ntc_10k[i+1])
		{
//			printf("温度为：%d\r\n",(i-30));
			return (i-15);
		}

	}
	return 0xff;
}




/// @brief adc循环初始化
/// @param task_id 
void AAC_adc_Init( uint8_t task_id )
{
//	hal_gpio_pin_init(P0, GPIO_OUTPUT);
//	hal_gpioretention_register(P0);
//	hal_gpio_pull_set(P0, GPIO_FLOATING);
//	hal_gpio_write(P0, 1);
	
//	hal_pwm_module_init();
//	hal_pwm_init(PWM_CH2,PWM_CLK_DIV_16,PWM_CNT_UP, 	PWM_POLARITY_FALLING);
//	hal_pwm_set_count_val(PWM_CH2, 125, PWM_TOP_VALUE);
//	hal_pwm_open_channel(PWM_CH2, PWM1_PIN);
//	hal_pwm_start();
	
	
    hal_adc_init();
    AAC_Adc_Task_Id = task_id;
    adcPoilling_MeasureTask();
}




//ADC采集轮询事件
uint16_t AAC_Adc_ProcessEvent( uint8_t task_id, uint16_t events )
{
    

    VOID task_id; // OSAL required parameter that isn't used in this function

    if ( events & adcMeasureTask_Poilling_EVT )
    {
        //LOG("[Fun:Bsp_Adc_ProcessEvent-->adcMeasureTask_Poilling_EVT]\n");
        // Perform periodic heart rate task
        extern void clear_adcc_cfg(void);
        clear_adcc_cfg();
        adcPoilling_MeasureTask();
        return (events ^ adcMeasureTask_Poilling_EVT);
    }

    return 0;
}



static void adc_Poilling_evt(adc_Evt_t* pev)
{
    float value = 0;
    int i = 0;
	float voltage;	//电压
	float E_value;	//电流
	float R_value;	//阻值
    bool is_high_resolution = FALSE;
    bool is_differential_mode = FALSE;
    uint8_t ch = 0;
	int8_t temp_value= 0;
	int8_t old_temp_value= 0;
    if((pev->type != HAL_ADC_EVT_DATA) || (pev->ch < 2))
        return;

    osal_memcpy(adc_debug[pev->ch-2],pev->data,2*(pev->size));
    channel_done_flag |= BIT(pev->ch);
	
    if(channel_done_flag == adc_cfg.channel)
    {
        for(i=2; i<8; i++)
        {
            if(channel_done_flag & BIT(i))
            {
                is_high_resolution = (adc_cfg.is_high_resolution & BIT(i))?TRUE:FALSE;
                is_differential_mode = (adc_cfg.is_differential_mode & BIT(i))?TRUE:FALSE;
                value = hal_adc_value_cal((adc_CH_t)i,adc_debug[i-2], pev->size, is_high_resolution,is_differential_mode);

                switch(i)
                {
                    case ADC_CH1N_P11:
                        ch=11;
                    break;

//                    case ADC_CH2P_P14:
//                        ch=14;
//                    break;


                default:
                    break;
                }

                if(ch!=0)
                {
					voltage = (value-0.08)/4.0;
					voltage = 3.3-voltage;
					E_value = ((value-0.08)/4.0)/4.72;
					R_value = (voltage/E_value)-14.15;
//					LOG("P%d %d mv  \n",ch,(int)(value/4.0*1000));
					temp_value= Get_Temperature(R_value*1000);
					if(ch == 14)  LOG("P%d %d mv   R_value: %d  temp: %d\n",ch,(int)(value*1000),(int)(R_value*1000),temp_value);
					else LOG("P%d %d mv   R_value: %d  \n",ch,(int)(value*1000),(int)(R_value*1000));
//					if(old_temp_value !=temp_value) 
//					{
//						old_temp_value =temp_value;
//						Temper_change(temp_value);
//					}
                }
                else
                {
                    LOG("invalid channel\r\n");
                }
            }
        }

//        LOG(" mode:%d \n",adc_cfg.is_continue_mode);
        channel_done_flag = 0;

        if(adc_cfg.is_continue_mode == FALSE)
        {
            osal_start_timerEx(AAC_Adc_Task_Id, adcMeasureTask_Poilling_EVT,1000);
        }

    }
}

static void adcPoilling_MeasureTask( void )
{
    int ret;

    //LOG("adc_Poilling_evt\n");

    ret = hal_adc_config_channel(adc_cfg, adc_Poilling_evt);//初始化 adc参数 事件

    if(ret)
    {
        LOG("ret = %d\n",ret);
        return;
    }

    hal_adc_start(POLLING_MODE);

    hal_adc_value_read(ADC_CH1N_P11);
//    hal_adc_value_read(ADC_CH2P_P14);

    hal_poilling_adc_stop();

}























