#include <stdio.h>
#include "Decection.h"


#include "esp_log.h"
#include "esp_adc/adc_oneshot.h"
#include "esp_adc/adc_cali.h"
#include "esp_adc/adc_cali_scheme.h"
#include "esp_heap_caps.h"
#include "hal/adc_hal.h"
#include "driver/gpio.h"
#include "esp_sleep.h"
const static char *TAG = "Decection";

//#include "LED.h"


static int adc_raw[2][10];
static int voltage[2][10];

#define USER_KEY_CHANNEL  ADC_CHANNEL_7

#define USER_ADC_CHANNEL  ADC_CHANNEL_2
#define USER_ADC_UNIT   ADC_UNIT_1
static bool adc_calibration_init(adc_unit_t unit, adc_atten_t atten, adc_cali_handle_t *out_handle);
static void adc_calibration_deinit(adc_cali_handle_t handle);

adc_cali_handle_t adc2_cali_handle = NULL;

// void adc1_deinit(adc_oneshot_unit_handle_t adc_handle)
// {
//     ESP_ERROR_CHECK(adc_oneshot_del_unit(adc_handle));
//     if (do_calibration) {
//         adc_calibration_deinit(adc2_cali_handle);
//     }
// }
int adc_read_power_pin(adc_oneshot_unit_handle_t adc_handle)
{
    bool do_calibration;

    adc_oneshot_chan_cfg_t config = {
    .bitwidth = ADC_BITWIDTH_DEFAULT,
    .atten = ADC_ATTEN_DB_11,
    };

    do_calibration = adc_calibration_init(USER_ADC_UNIT, ADC_ATTEN_DB_11, &adc2_cali_handle);
    //-------------ADC Config---------------//
    adc_oneshot_config_channel(adc_handle, USER_ADC_CHANNEL, &config);
    //adc_ll_set_power_manage(ADC_POWER_BY_FSM);
    adc_oneshot_read(adc_handle, USER_ADC_CHANNEL, &adc_raw[0][0]);
    //adc_ll_set_power_manage(ADC_POWER_SW_OFF);

    ESP_LOGD(TAG, "ADC%d Channel[%d] Raw Data: %d", USER_ADC_UNIT + 1, USER_ADC_CHANNEL, adc_raw[0][0]);

    if (do_calibration) {
        ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc2_cali_handle, adc_raw[0][0], &voltage[0][0]));
        ESP_LOGD(TAG, "ADC%d Channel[%d] Cali Voltage: %d mV", USER_ADC_UNIT + 1, USER_ADC_CHANNEL, voltage[0][0]);
        adc_calibration_deinit(adc2_cali_handle);
    }   
    int batt_percent;

    //电量范围映射
    float result_voltage = (float)(voltage[0][0]) / 1000.0/*4095.0 * 3.3*/; // 假设ADC参考电压为3.3V
    float battery_percentage = ((result_voltage - 1.8) / (2.2 - 1.8)) * 100.0;
    // 限制电量范围在0%到100%之间
    if (battery_percentage < 0) {
    battery_percentage = 0;
    } else if (battery_percentage > 100) {
    battery_percentage = 100;
    }

    batt_percent = (int )battery_percentage; 

    #if 0
        ESP_LOGI(TAG,"batt_percent = [%d],voltage[0][0] = [%d]",batt_percent, voltage[0][0]);
    #else
        printf("batt_percent = [%d],voltage[0][0] = [%d],adc value %d\r\n",batt_percent, voltage[0][0],(int)battery_percentage);
    #endif
    return batt_percent;
}




int adc_read_left_key_pin(adc_oneshot_unit_handle_t adc_handle)
{
    bool do_calibration;

    adc_oneshot_chan_cfg_t config = {
    .bitwidth = ADC_BITWIDTH_DEFAULT,
    .atten = ADC_ATTEN_DB_0,
    };

    do_calibration = adc_calibration_init(USER_ADC_UNIT, ADC_ATTEN_DB_0, &adc2_cali_handle);
    //-------------ADC Config---------------//
    ESP_ERROR_CHECK(adc_oneshot_config_channel(adc_handle, USER_KEY_CHANNEL, &config));
    //adc_ll_set_power_manage(ADC_POWER_BY_FSM);
    ESP_ERROR_CHECK(adc_oneshot_read(adc_handle, USER_KEY_CHANNEL, &adc_raw[0][0]));
    //adc_ll_set_power_manage(ADC_POWER_SW_OFF);

    ESP_LOGD(TAG, "ADC%d Channel[%d] Raw Data: %d", USER_ADC_UNIT + 1, USER_KEY_CHANNEL, adc_raw[0][0]);

    if (do_calibration) {
        ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc2_cali_handle, adc_raw[0][0], &voltage[0][0]));
        ESP_LOGD(TAG, "ADC%d Channel[%d] Cali Voltage: %d mV", USER_ADC_UNIT + 1, USER_KEY_CHANNEL, voltage[0][0]);
        adc_calibration_deinit(adc2_cali_handle);
    }   
    int batt_percent;

    #if 0
    //电量范围映射
    float result_voltage = (float)(voltage[0][0]) / 1000.0/*4095.0 * 3.3*/; // 假设ADC参考电压为3.3V
    float battery_percentage = ((result_voltage - 1.5) / (2.2 - 1.5)) * 100.0;
    // 限制电量范围在0%到100%之间
    if (battery_percentage < 0) {
    battery_percentage = 0;
    } else if (battery_percentage > 100) {
    battery_percentage = 100;
    }

    batt_percent = (int )battery_percentage; 

    #if 0
        ESP_LOGI(TAG,"batt_percent = [%d],voltage[0][0] = [%d]",batt_percent, voltage[0][0]);
    #else
        printf("batt_percent = [%d],voltage[0][0] = [%d],adc value %d\r\n",batt_percent, voltage[0][0],(int)battery_percentage);
    #endif
    #else


     printf("left key voltage:%d\r\n",voltage[0][0]);

    batt_percent = voltage[0][0];


    #endif
    return batt_percent;
}
extern adc_oneshot_unit_handle_t adc1_handle;


int read_battery_voltage()
{
    printf("读电量\n");
    return adc_read_power_pin(adc1_handle);
}

/*---------------------------------------------------------------
        ADC Calibration
---------------------------------------------------------------*/
static bool adc_calibration_init(adc_unit_t unit, adc_atten_t atten, adc_cali_handle_t *out_handle)
{
    adc_cali_handle_t handle = NULL;
    esp_err_t ret = ESP_FAIL;
    bool calibrated = false;

    if (!calibrated) {
        ESP_LOGD(TAG, "calibration scheme version is %s", "Curve Fitting");
        adc_cali_curve_fitting_config_t cali_config = {
            .unit_id = unit,
            .atten = atten,
            .bitwidth = ADC_BITWIDTH_DEFAULT,
        };
        ret = adc_cali_create_scheme_curve_fitting(&cali_config, &handle);
        if (ret == ESP_OK) {
            calibrated = true;
        }
    }

    *out_handle = handle;
    if (ret == ESP_OK) {
        ESP_LOGD(TAG, "Calibration Success");
    } else if (ret == ESP_ERR_NOT_SUPPORTED || !calibrated) {
        ESP_LOGW(TAG, "eFuse not burnt, skip software calibration");
    } else {
        ESP_LOGE(TAG, "Invalid arg or no memory");
    }

    return calibrated;
}

static void adc_calibration_deinit(adc_cali_handle_t handle)
{
    ESP_LOGD(TAG, "deregister %s calibration scheme", "Curve Fitting");
    ESP_ERROR_CHECK(adc_cali_delete_scheme_curve_fitting(handle));
}


 //返回充电中状态
int decection_state_0(void)
{
    return gpio_get_level(2);
}

//返回充满状态
int decection_state_1(void)
{

    return 0;//gpio_get_level(38);
}








#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "SPIFFS.h"
extern QueueHandle_t right_screen_queue;
extern RTC_FAST_ATTR Machine_info_t   Machine_info;
static void IRAM_ATTR gpio_isr_handler(void* arg)
{
    uint32_t gpio_num = (uint32_t) arg;
    switch(gpio_num)
    {

      case  2:

           // beep_blink(100,3);
            //printf("----------------gpio_num%ld中断------------------------\r\n",gpio_num);
        break;

        case 38:

           // beep_blink(100,4);//rintf("----------------gpio_num%ld中断------------------------\r\n",gpio_num);
        break;

        default :break;
    }
    // if(Machine_info.power_status!=0)
    // {
    //     xQueueSendFromISR(right_screen_queue, &Machine_info, NULL);
    // }

}

void decection_charging_init(void)
{
    //zero-initialize the config structure.
    gpio_config_t io_conf = {};
    //interrupt of rising edge
    io_conf.intr_type = GPIO_INTR_NEGEDGE;  //下降沿
    //bit mask of the pins
    io_conf.pin_bit_mask =((1ULL<<2) | (1ULL<<38));
    //set as input mode
    io_conf.mode = GPIO_MODE_INPUT;
    io_conf.pull_up_en = GPIO_PULLUP_DISABLE; // 禁用上拉电阻
    io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; // 禁用下拉电阻
    //configure GPIO with the given settings
    gpio_config(&io_conf);

    ESP_LOGW(TAG, "decection_charging_init");
   //install gpio isr service
    gpio_install_isr_service(ESP_INTR_FLAG_EDGE);
    gpio_isr_handler_add(2, gpio_isr_handler, (void*) 2);
    gpio_isr_handler_add(38, gpio_isr_handler, (void*) 38);
}
// void decection_charging_deinit(void)
// {
//     gpio_isr_handler_remove(2);
//     gpio_isr_handler_remove(38);
// }