/**
 * @file	   flowmeter.c
 *
 * @copyright  Nehemis SARL reserves all rights even in the event of industrial
 *             property rights. We reserve all rights of disposal such as
 *             copying and passing on to third parties.
 *
 * @brief
 *
 */

/******************************************************************************
 * Include Header Files
 ******************************************************************************/
#include "nms_types.h"
#include "flowmeter.h"

/******************************************************************************
 * Type  declarations
 ******************************************************************************/

/******************************************************************************
 * Macro Constant Declarations
 ******************************************************************************/
#define FLOWMETER_ADC_REF_VOLTAGE	3.3f
#define FLOWMETER_ADC_RESOLUTION	4095.0f		/* 12-bit ADC */
/******************************************************************************
 * Private function Declarations
 ******************************************************************************/
static float32 FlowmeterReadVoltage(FlowmeterMain_st *flowmeter_pst);

/******************************************************************************
 * Extern Function Definitions
 ******************************************************************************/
void FlowmeterInit(FlowmeterMain_st *flowmeter_pst, ADC_HandleTypeDef *adcHandle_pst, uint32 channel_u32)
{
	if (flowmeter_pst == NULL || adcHandle_pst == NULL)
	{
		/* ERROR */
	}

	flowmeter_pst->adcHandle_pst = adcHandle_pst;
	flowmeter_pst->channel_u32   = channel_u32;
	flowmeter_pst->mKu_f32 = 5.0f; // Default value
}



void FlowmeterGetFlow(FlowmeterMain_st *flowmeter_pst)
{
	if (flowmeter_pst == NULL)
	{
		/* ERROR */
	}

	flowmeter_pst->rawQ_f32 = flowmeter_pst->mKu_f32 * FlowmeterReadVoltage(flowmeter_pst);
}


float32 FlowmeterGetKu(FlowmeterMain_st *flowmeter_pst)
{
	if (flowmeter_pst == NULL)
	{
		return 0.0f;
	}

	return flowmeter_pst->mKu_f32;
}


void FlowmeterSetKu(FlowmeterMain_st *flowmeter_pst, float32 ku_f32)
{
	if (flowmeter_pst != NULL)
	{
		flowmeter_pst->mKu_f32 = ku_f32;
	}
}


/******************************************************************************
 * Private function Definitions
 ******************************************************************************/
/**
 * @brief     Function to read ADC voltage data which is directly coming from the sensor.
 *
 * @param	  flowmeter_pst : Pointer to main strucutre of the module.
 *
 * @return	  ADC output voltage based on sensor reading.
 *
 */
static float32 FlowmeterReadVoltage(FlowmeterMain_st *flowmeter_pst)
{
	uint32 adcVal_u32 = 0uL;
	if (flowmeter_pst == NULL || flowmeter_pst->adcHandle_pst == NULL)
	{
		return 0.0f; /* Error Case */
	}

	ADC_ChannelConfTypeDef sConfig = {0};
	sConfig.Channel      	= flowmeter_pst->channel_u32;  /* Set the channel specific to this flowmeter */
	sConfig.Rank 			= ADC_REGULAR_RANK_1;
	sConfig.SamplingTime 	= ADC_SAMPLETIME_12CYCLES_5;

	if (HAL_ADC_ConfigChannel(flowmeter_pst->adcHandle_pst, &sConfig) != HAL_OK)
	{
		return 0.0f; /* ERROR */
	}

	/* Start ADC conversion and poll for completion */
	if (HAL_ADC_Start(flowmeter_pst->adcHandle_pst) == HAL_OK)
	{
		if (HAL_ADC_PollForConversion(flowmeter_pst->adcHandle_pst, HAL_MAX_DELAY) == HAL_OK)
		{
			adcVal_u32 = HAL_ADC_GetValue(flowmeter_pst->adcHandle_pst);
		}
		HAL_ADC_Stop(flowmeter_pst->adcHandle_pst);
	}
	else
	{
		/* ERROR */
	}

	/* Convert ADC value to voltage (assuming 12-bit resolution and 3.3V reference) */
	float32 voltage_f32 = (float)adcVal_u32 * (FLOWMETER_ADC_REF_VOLTAGE / FLOWMETER_ADC_RESOLUTION);

	return voltage_f32;
}
