/**
  ******************************************************************************
  * File Name          : u_saadc.c
  * Description        : This file provides code for the xxx operation
  *                      of smoke modules.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2022 WONZ.
  * All rights reserved.</center></h2>
  *
  * @version			V1.0.01
  * @date				2022-5-10
  ******************************************************************************
  */
#include "nrf_drv_saadc.h"
#include "u_saadc.h"
#include "u_heat.h"
#include "nrf_temp.h"
#include "u_timer.h"

#define ADC_CHINAL_NUM						8
#define ADC_CIRCLE_NUM						10
#define SAMPLES_IN_BUFFER 					(ADC_CHINAL_NUM)
#define ADC_AVERAGE_CAL(sum,max,min)		(((sum) - (max) - (min))/(ADC_CIRCLE_NUM-2))
#define CH_RES_OFFSET						(3)


void Get_ADC_Stop(void);
SensorTypedef sensor_val;
static nrf_saadc_value_t     m_buffer_pool[SAMPLES_IN_BUFFER];
static int16_t adc_buf[ADC_CHINAL_NUM*ADC_CIRCLE_NUM];
static uint8_t adc_circle_num = 0;
uint8_t sw_bat_p4;

/**
  * @brief	saadc_callback      
  * @param			   
  *			
  * @retval	none
  * @author	Ethan.deng
  */
void Saadc_Callback(nrf_drv_saadc_evt_t const * p_event)
{   
	uint8_t n;
    if (p_event->type == NRF_DRV_SAADC_EVT_DONE){
        ret_code_t err_code;
		for(n = 0;n < ADC_CHINAL_NUM;n++)adc_buf[adc_circle_num*ADC_CHINAL_NUM + n] = p_event->data.done.p_buffer[n];
        err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);
        APP_ERROR_CHECK(err_code);
		
		adc_circle_num++;
		if(adc_circle_num >= ADC_CIRCLE_NUM)
		{
			Get_ADC_Value(adc_buf,ADC_CHINAL_NUM*ADC_CIRCLE_NUM);
			adc_circle_num = 0;
		}
		else nrf_drv_saadc_sample();
    }
}
int16_t voltage_val[ADC_CHINAL_NUM] = {0};
static int16_t adc_offset;
int16_t adc_bak[ADC_CHINAL_NUM*2+2];
/**
  * @brief	Get_ADC_Value      
  * @param			   
  *			
  * @retval	none
  * @author	Ethan.deng
  */
void Get_ADC_Value(int16_t * p_buffer, uint16_t size)
{
	int32_t adc_val_sum[ADC_CHINAL_NUM] = {0};
	int16_t adc_val_max[ADC_CHINAL_NUM] = {0};
	int16_t adc_val_min[ADC_CHINAL_NUM] = {16384,16384,16384,16384,16384,16384,16384,16384};
	//int16_t voltage_val[ADC_CHINAL_NUM] = {0};
	
	Get_ADC_Stop();
	//最大最小赋值
	for(char i=0; i<(ADC_CHINAL_NUM*ADC_CIRCLE_NUM); i++){
		char chl_num = i % ADC_CHINAL_NUM;
		adc_val_sum[chl_num] += p_buffer[i];
		if(p_buffer[i] > adc_val_max[chl_num]){
			adc_val_max[chl_num] = p_buffer[i];
		}	
		else if(p_buffer[i] < adc_val_min[chl_num]){
			adc_val_min[chl_num] = p_buffer[i];
		}
	}

	extern uint8_t res_check_ch;
	for(char i=0; i<ADC_CHINAL_NUM; i++){
		if(sw_bat_p4 == 0)voltage_val[i] = ADC_AVERAGE_CAL(adc_val_sum[i],adc_val_max[i],adc_val_min[i])*7200 / 16384;
		else voltage_val[i] = ADC_AVERAGE_CAL(adc_val_sum[i],adc_val_max[i],adc_val_min[i]);
	}
	
	if(sw_bat_p4 == 0)sensor_val.bat_voltage = voltage_val[7];
	else
	{
		if(res_check_ch == 1)
		{
			sensor_val.ch1_res_val = RES_SIMPLE_CAL(voltage_val[1]-adc_offset,voltage_val[0]);
			sensor_val.ch2_res_val = RES_SIMPLE_CAL(voltage_val[3]-adc_offset,voltage_val[2]);
			adc_offset = (voltage_val[4]+voltage_val[5]+voltage_val[6]+voltage_val[7])/4;
			for(char i=0; i<ADC_CHINAL_NUM; i++)adc_bak[i] = voltage_val[i];
			adc_bak[ADC_CHINAL_NUM*2] = adc_offset;
		}
		else if(res_check_ch == 2)
		{
			sensor_val.ch3_res_val = RES_SIMPLE_CAL(voltage_val[5]-adc_offset,voltage_val[4]) + CH_RES_OFFSET;
			sensor_val.ch4_res_val = RES_SIMPLE_CAL(voltage_val[7]-adc_offset,voltage_val[6]) + CH_RES_OFFSET;
			adc_offset = (voltage_val[0]+voltage_val[1]+voltage_val[2]+voltage_val[3])/4;
			for(char i=ADC_CHINAL_NUM; i<ADC_CHINAL_NUM*2; i++)adc_bak[i] = voltage_val[i-ADC_CHINAL_NUM];
			adc_bak[ADC_CHINAL_NUM*2+1] = adc_offset;
		}
	}
}

/**
  * @brief	SAADC_Init      
  * @param			   
  *			
  * @retval	none
  * @author	Ethan.deng
  */
void Saadc_Init(void)
{
    //五个通道缓冲
    ret_code_t err_code;
	
	nrf_gpio_cfg(        
		AD_CH_SW_PIN,
		NRF_GPIO_PIN_DIR_OUTPUT,
		NRF_GPIO_PIN_INPUT_DISCONNECT,
		NRF_GPIO_PIN_NOPULL,
		NRF_GPIO_PIN_S0S1,
		NRF_GPIO_PIN_NOSENSE);
	
//	nrf_saadc_channel_config_t channel_0_config =
//        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_DIFFERENTIAL(NRF_SAADC_INPUT_AIN0,NRF_SAADC_INPUT_AIN1);
//	nrf_saadc_channel_config_t channel_1_config =
//        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_DIFFERENTIAL(NRF_SAADC_INPUT_AIN2,NRF_SAADC_INPUT_AIN3);
//	nrf_saadc_channel_config_t channel_2_config =
//        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_DIFFERENTIAL(NRF_SAADC_INPUT_AIN4,NRF_SAADC_INPUT_AIN5);
//	nrf_saadc_channel_config_t channel_3_config =
//        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_DIFFERENTIAL(NRF_SAADC_INPUT_AIN6,NRF_SAADC_INPUT_AIN7);
	
	
	nrf_saadc_channel_config_t channel_0_config =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0);
    nrf_saadc_channel_config_t channel_1_config =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN1);
	nrf_saadc_channel_config_t channel_2_config =
		NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN2);
	nrf_saadc_channel_config_t channel_3_config =
		NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN3);
	nrf_saadc_channel_config_t channel_4_config =
		NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN4);	
	nrf_saadc_channel_config_t channel_5_config =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN5);
    nrf_saadc_channel_config_t channel_6_config =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN6);
	nrf_saadc_channel_config_t channel_7_config =
		NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN7);
	
    err_code = nrf_drv_saadc_init(NULL, Saadc_Callback);
    APP_ERROR_CHECK(err_code);
    
    err_code = nrf_drv_saadc_channel_init(0, &channel_0_config);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_saadc_channel_init(1, &channel_1_config);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_saadc_channel_init(2, &channel_2_config);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_saadc_channel_init(3, &channel_3_config);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_saadc_channel_init(4, &channel_4_config);
    APP_ERROR_CHECK(err_code);
	err_code = nrf_drv_saadc_channel_init(5, &channel_5_config);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_saadc_channel_init(6, &channel_6_config);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_saadc_channel_init(7, &channel_7_config);
    APP_ERROR_CHECK(err_code);

	//配置申请一个缓冲区
    err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool,SAMPLES_IN_BUFFER);
    APP_ERROR_CHECK(err_code);

	//nrf_temp_init();
}
/**
  * @brief	SAADC_Deinit      
  * @param			   
  *			
  * @retval	none
  * @author	Ethan.deng
  */
void Saadc_Deinit(void)
{
	nrf_drv_saadc_channel_uninit(0);
	nrf_drv_saadc_channel_uninit(1);
	nrf_drv_saadc_channel_uninit(2);
	nrf_drv_saadc_channel_uninit(3);
	nrf_drv_saadc_channel_uninit(4);
	nrf_drv_saadc_channel_uninit(5);
	nrf_drv_saadc_channel_uninit(6);
	nrf_drv_saadc_channel_uninit(7);
	nrf_drv_saadc_uninit();
	nrf_gpio_cfg_default(AD_CH_SW_PIN);
}


/**
  * @brief	Get_ADC_Start      
  * @param			   
  *			
  * @retval	none
  * @author	Ethan.deng
  */
volatile uint8_t adc_on_flag = 0;
void Get_ADC_Start(void)
{
	if(adc_on_flag == 1)return;
	adc_on_flag = 1;
	SW_TO_BAT();
	sw_bat_p4 = 0;
	nrf_drv_saadc_sample();
}

/**
  * @brief	Get_ADC_Stop      
  * @param			   
  *			
  * @retval	none
  * @author	Ethan.deng
  */
void Get_ADC_Stop(void)
{
	adc_on_flag = 0;
	RES_CHECK_OFF_CH1();
	RES_CHECK_OFF_CH2();
}

/**
  * @brief	Get_Mcu_Temperature      
  * @param			   
  *			
  * @retval	none
  * @author	Ethan.deng
  */
void Get_Mcu_Temperature(void)
{
	NRF_TEMP->TASKS_START = 1;
	while (NRF_TEMP->EVENTS_DATARDY == 0){}
	NRF_TEMP->EVENTS_DATARDY = 0;
	sensor_val.mcu_temp = nrf_temp_read()/4;
	NRF_TEMP->TASKS_STOP = 1;
}



/************************ (C) COPYRIGHT WONZ **************************/
                          /*****END OF FILE*****/
