/**
 * @file	   grundfos.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 "grundfos.h"
#include "gpio.h"
#include "i2c.h"
/******************************************************************************
 * Type  declarations
 ******************************************************************************/

/******************************************************************************
 * Macro Constant Declarations
 ******************************************************************************/
#define GRUNDFOS_PMP_ADC_CHANNEL		5u
#define GRUNDFOS_PMP_ADC_REF_VOLTAGE	3.3f
#define GRUNDFOS_PMP_ADC_RESOLUTION		4095.0f		/* 12-bit ADC */
#define GRUNDFOS_PMP_ADC_MODULE			&hadc1

#define GRUNDFOS_PMP_ENABLE_GPIO_PORT	GPIOB
#define GRUNDFOS_PMP_ENABLE_GPIO_PIN	GPIO_PIN_15

#define GRUNDFOS_PMP_I2C_HANDLE			&hi2c4
#define GRUNDFOS_PMP_INTERNAL_DAC_ADDR	0x61
/******************************************************************************
 * Private function Declarations
 ******************************************************************************/
static uint32 GrundfosPmpReadVoltage(void);

/******************************************************************************
 * Extern Function Definitions
 ******************************************************************************/
void GrundfosPmpEnable(uint8 state_u8)
{
	if(state_u8 == 1u)
	{
		HAL_GPIO_WritePin(GRUNDFOS_PMP_ENABLE_GPIO_PORT, GRUNDFOS_PMP_ENABLE_GPIO_PIN, GPIO_PIN_SET);
	}
	else
	{
		HAL_GPIO_WritePin(GRUNDFOS_PMP_ENABLE_GPIO_PORT, GRUNDFOS_PMP_ENABLE_GPIO_PIN, GPIO_PIN_RESET);
	}
}


uint32 GrundfosPmpFeedbackSpeed(void)
{
	uint32 feedbackSpeed_u32 = (GrundfosPmpReadVoltage()) * 360uL;

	return feedbackSpeed_u32;
}


bool GrundfosPmpSetSpeed(float32 setSpeed_f32)
{
    uint8 data_au8[2];
    uint16 dacVal_u16;

    if (setSpeed_f32 < 0.0f)
    {
    	setSpeed_f32 = 0.0f;
    }
    else if (setSpeed_f32 > 10.0f)
    {
    	setSpeed_f32 = 10.0f;
    }
    else
    {
    	/* Do nothing. */
    }

    dacVal_u16 	= (uint16)(setSpeed_f32 * (GRUNDFOS_PMP_ADC_RESOLUTION / 10.0f));

    data_au8[0]	= (uint8)(dacVal_u16 >> 4);          /* Upper 8 bits */
    data_au8[1] = (uint8)((dacVal_u16 & 0x0F) << 4); /* Lower 4 bits shifted to the upper nibble */

    return HAL_I2C_Master_Transmit(GRUNDFOS_PMP_I2C_HANDLE, GRUNDFOS_PMP_INTERNAL_DAC_ADDR, data_au8, 2u, HAL_MAX_DELAY) == HAL_OK;
}

/******************************************************************************
 * Private function Definitions
 ******************************************************************************/
/**
 * @brief     Function to read ADC voltage data which is directly coming from the pump.
 *
 * @return	  ADC output voltage based on sensor reading.
 *
 */
static uint32 GrundfosPmpReadVoltage(void)
{
	uint32_t adcVal_u32 = 0uL;
	ADC_ChannelConfTypeDef sConfig = {0};
	sConfig.Channel      	= GRUNDFOS_PMP_ADC_CHANNEL;  /* Set the channel specific to this flowmeter */
	sConfig.Rank 			= ADC_REGULAR_RANK_1;
	sConfig.SamplingTime 	= ADC_SAMPLETIME_12CYCLES_5;

	if (HAL_ADC_ConfigChannel(GRUNDFOS_PMP_ADC_MODULE, &sConfig) != HAL_OK)
	{
		return 0.0f; /* ERROR */
	}

	if (HAL_ADC_Start(GRUNDFOS_PMP_ADC_MODULE) == HAL_OK)
	{
		if (HAL_ADC_PollForConversion(GRUNDFOS_PMP_ADC_MODULE, HAL_MAX_DELAY) == HAL_OK)
		{
			adcVal_u32 = HAL_ADC_GetValue(GRUNDFOS_PMP_ADC_MODULE);
		}
		HAL_ADC_Stop(GRUNDFOS_PMP_ADC_MODULE);
	}
	else
	{
		/* ERROR */
	}

	uint32 voltage_u32 = adcVal_u32 * (GRUNDFOS_PMP_ADC_REF_VOLTAGE / GRUNDFOS_PMP_ADC_RESOLUTION);

	return voltage_u32;
}
