/*******************************************************************************
 * @file	battery_saadc.c
 * @author	CandyPops Co.
 * @version	V1.0.0
 * @date	2022-09-05
 * @brief   
 ******************************************************************************/

#include "sdk_common.h"
			
#include <stdint.h>
#include <string.h>
#include "nrf.h"
#include "boards.h"
#include "app_error.h"
#include "nrf_drv_saadc.h"
#include "nrf_drv_timer.h"
#include "ble_nus.h"
#include "nrf_log.h"
#include "main.h"
#include "app_timer.h"
//#include "fstorage.h"
#include "battery_saadc.h"
#include "main_timer.h"
#include "meas_pd_48.h"
#include <cmd_parse.h>
#include "debug_print.h"
#define BATTERY_REF_VOLTAGE_IN_MILLIVOLTS   600                                     /**< Reference voltage (in milli volts) used by ADC while doing conversion. */
#define BATTERY_PRE_SCALING_COMPENSATION    6                                       /**< The ADC is configured to use VDD with 1/3 prescaling as input. And hence the result of conversion is to be multiplied by 3 to get the actual value of the battery voltage.*/
#define BATTERY_ADC_RES_10BITS              1023                                    /**< Maximum digital value for 10-bit ADC conversion. */
//#define PRESSURE_RESULT_IN_MILLI_VOLTS(adc)  ((adc * 3600) / 1023)

#define PRESSURE_OFFSET_DEFAULT   0      // Pressure offset (adjust for calibration)
#define MV_PER_ADC_STEP           805    // Approx 0.805mV per 1 LSB (nRF 12bit + scaling)
/**@brief Macro to convert the result of ADC conversion in millivolts.
 *
 * @param[in]  ADC_VALUE   ADC result.
 *
 * @retval     Result converted to millivolts.
 */
#define BATTERY_RESULT_IN_MILLI_VOLTS(ADC_VALUE)\
        ((((ADC_VALUE) * BATTERY_REF_VOLTAGE_IN_MILLIVOLTS) / BATTERY_ADC_RES_10BITS) * BATTERY_PRE_SCALING_COMPENSATION)

static nrf_saadc_value_t adc_bufs[2];
static int16_t pressure_adc_buf[2];  //cj add 25/11/19
static uint16_t convert_adc_to_mV(int16_t raw_adc); //cj add 25/11/19

APP_TIMER_DEF(m_battery_loop_timer_id);
#define BATTERY_LOOP_INTERVAL              5000

bool low_battery_check = false;
extern bool info4;   //cmd_parse

// cj add edit 25/11/24
extern volatile uint16_t info_p1;
extern volatile uint16_t info_p2;


extern char		ble_tx_buffer[BLE_NUS_MAX_DATA_LEN];
extern bool go_device_power_off;
extern volatile bool processing;

extern which_cmd_t cmd_type_t;

extern uint8_t ble_bin_buffer[BLE_NUS_MAX_DATA_LEN]	;
 extern volatile uint16_t info_batt;  //48_c
	extern bool go_temp;   //
		extern bool go_batt;   //cmd_parse

	extern bool motion_raw_data_enabled ;
	extern bool ble_got_new_data;
	extern bool motion_data_once ;
/**@brief Function for handling the ADC interrupt.
 *
 * @details  This function will fetch the conversion result from the ADC, convert the value into
 *           percentage and send it to peer.
 */
 static uint16_t convert_adc_to_mV(int16_t raw_adc)
{
    if (raw_adc < 0)
        raw_adc = 0;

    int32_t mv = (int32_t)raw_adc * MV_PER_ADC_STEP;   // ?: 805 uV
    mv /= 1000;

     /* Clamp output to valid range 0~3500mV */
    if (mv < 0)
        mv = 0;

    if (mv > 3500)
        mv = 3500;


    return (uint16_t)mv;
}
void pressure_all_event_handler(nrf_drv_saadc_evt_t const * p_event)
{
    if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
    {
        int16_t p1_adc = p_event->data.done.p_buffer[0];   // AIN7
        int16_t p2_adc = p_event->data.done.p_buffer[1];   // AIN4

     			
        uint16_t p1_mV = convert_adc_to_mV(p1_adc);
        uint16_t p2_mV = convert_adc_to_mV(p2_adc);

			 /* Update info_p1/info_p2 when in PD Full mode (info4=true) */ 
        if(info4 == true)
        {
            info_p1 = p1_mV;
            info_p2 = p2_mV;
        }
        // Re-buffer
        APP_ERROR_CHECK(nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, 2));

        // uninit
        nrf_drv_saadc_uninit();
        nrf_drv_saadc_channel_uninit(0);
        nrf_drv_saadc_channel_uninit(1);

        // UART send
			 
        if(cmd_type_t == CMD_UART)
        {
            DBG_PRINTF("P1:%d  P2:%d\r\n", p1_mV, p2_mV);
        }
       else if(cmd_type_t == CMD_BLE && info4 == false)
        {
				    DBG_PRINTF("P1:%d  P2:%d\r\n", p1_mV, p2_mV);						
         //   uint16_t len = sprintf((char*)ble_bin_buffer,
                            // "rpn:%04x,%04x", p1_mV, p2_mV);
				   	uint16_t result_data[2];
					    result_data[0] = p1_mV;
							result_data[1] = p2_mV;
							format_data(ble_bin_buffer, "rpn:", result_data,2);
							binary_tx_handler(ble_bin_buffer,4);
								
          
        }
			}
}





void battery_event_handler( nrf_drv_saadc_evt_t const * p_event )
{
	
	static uint8_t low_battery_cnt = 0;
	
	if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
	{
		nrf_saadc_value_t register_val = 0;
		uint16_t		  batt_lvl_in_milli_volt_0 = 0;
		uint16_t		  batt_lvl_in_milli_volt_1 = 0;
		uint32_t		  err_code = 0;
		
		register_val = p_event->data.done.p_buffer[0];

		err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, 1);
		APP_ERROR_CHECK(err_code);

		nrf_drv_saadc_uninit();
		nrf_drv_saadc_channel_uninit(0);

		batt_lvl_in_milli_volt_0 = BATTERY_RESULT_IN_MILLI_VOLTS(register_val);
		batt_lvl_in_milli_volt_1 = (batt_lvl_in_milli_volt_0) *1.42;
		if(low_battery_check == true) {

			low_battery_check = false;

			if(batt_lvl_in_milli_volt_1 <= LOW_BATTERY_VOLTAGE) {
				if(low_battery_cnt >= 10) {
					low_battery_cnt = 0;
					/*go to power off and fds save */
					DBG_PRINTF("Save FDS parameters and then Power OFF\r\n");
					go_device_power_off = true;
					main_timer_start();
				}else{
					low_battery_cnt++;
					DBG_PRINTF("WARNING!!! low_battery cnt = %d, Batt = %d(mV)\r\n", low_battery_cnt, batt_lvl_in_milli_volt_1);
				}
			}

		} 
		else if (info4 == true){
			
			info_batt = batt_lvl_in_milli_volt_1;
			DBG_PRINTF("INFOTn%d\r\n\r\n", batt_lvl_in_milli_volt_1);
			
		}
		
		
		else {
			if(cmd_type_t == CMD_UART) {
				DBG_PRINTF("Tn%d\r\n\r\n", batt_lvl_in_milli_volt_1);
			} else if(cmd_type_t == CMD_BLE) {
				
				single_format_data(ble_bin_buffer, "rsn:",  batt_lvl_in_milli_volt_1);

						binary_tx_handler(ble_bin_buffer,3);
				//data_tx_handler(ble_tx_buffer);
			}
		}
	}
	
	if (info4 == true){
		go_batt =false;
		go_temp = true;
		main_timer_start();
	}
}


/**@brief Function for configuring ADC to do battery level conversion.
 */
static void battery_configure(void)
{
	ret_code_t err_code = nrf_drv_saadc_init(NULL, battery_event_handler);
	APP_ERROR_CHECK(err_code);

	nrf_saadc_channel_config_t config =
		NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN2);
	err_code = nrf_drv_saadc_channel_init(0, &config);
	APP_ERROR_CHECK(err_code);

	err_code = nrf_drv_saadc_buffer_convert(&adc_bufs[0], 1);
	APP_ERROR_CHECK(err_code);

	err_code = nrf_drv_saadc_buffer_convert(&adc_bufs[1], 1);
	APP_ERROR_CHECK(err_code);
}
void pressure_all_configure(void)
{
    ret_code_t err_code;

    err_code = nrf_drv_saadc_init(NULL, pressure_all_event_handler);
    if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_INVALID_STATE) {
        DBG_PRINTF("SAADC init err=%d\r\n", err_code);
        return;
    }

    nrf_saadc_channel_config_t ch0_cfg =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN7);
    nrf_saadc_channel_config_t ch1_cfg =
        NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN4);

    err_code = nrf_drv_saadc_channel_init(0, &ch0_cfg);
    if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_INVALID_STATE) {
        DBG_PRINTF("SAADC ch0 init err=%d\r\n", err_code);
        return;
    }

    err_code = nrf_drv_saadc_channel_init(1, &ch1_cfg);
    if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_INVALID_STATE) {
        DBG_PRINTF("SAADC ch1 init err=%d\r\n", err_code);
        return;
    }

    err_code = nrf_drv_saadc_buffer_convert(pressure_adc_buf, 2);
    if (err_code != NRF_SUCCESS) {
        DBG_PRINTF("SAADC buf conv err=%d\r\n", err_code);
        return;
    }
}

void battery_level_meas(void)
{
    ret_code_t err_code;
	
    battery_configure();
    err_code = nrf_drv_saadc_sample();
    APP_ERROR_CHECK(err_code);

	
}
void pressure_all_level_meas(void)  //add cj add 25/11/19
{
    ret_code_t err_code;

   pressure_all_configure();   /* Configure 2 ADC channels */

    err_code = nrf_drv_saadc_sample();
    APP_ERROR_CHECK(err_code);
}

void battery_loop(void * p_context)	/* For 1sec */
{
	UNUSED_PARAMETER(p_context);
	if(processing==true)
	{ 
		processing = false ; // add 20241218
		//low_battery_check = true;
		return;}
	else{
	low_battery_check = true;
	battery_level_meas();
	}
}

void battery_timer_start(void)
{
	APP_ERROR_CHECK(app_timer_start(m_battery_loop_timer_id, APP_TIMER_TICKS(BATTERY_LOOP_INTERVAL), NULL));	
}

void battery_timer_stop(void)
{
	APP_ERROR_CHECK(app_timer_stop(m_battery_loop_timer_id));	
}

void battery_timer_init(void)
{
    APP_ERROR_CHECK(app_timer_create(&m_battery_loop_timer_id, APP_TIMER_MODE_REPEATED, battery_loop));	
}


