/*
 * @file exo_io_al_stm32f7xx_adc.c
 *
 * @brief This file contains wrapper function definition for ADC interface
 *
 * @copyright Copyright 2023 Antaris, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdint.h>
#include "exo_io_al_stm32f7xx_adc.h"
#include "exo_common.h"


#include "stm32f7xx_hal.h"
//#endif

ADC_HandleTypeDef hadc1;

/**
 * @brief  This function initializes the ADC peripheral according to the specified
 *         parameters.
 */
static void MX_ADC1_Init(ioal_adc_hdle *ioal_hadc1);

hal_ret_sts io_hal_stm32f7xx_adc_init(ioal_adc_hdle *ioal_hadc1)
{
	MX_ADC1_Init(ioal_hadc1);
	return 0;
}


/**
 * @brief this is ADC initialization function.
 */
static void MX_ADC1_Init(ioal_adc_hdle *ioal_hadc1)
{
	  __HAL_RCC_ADC1_CLK_ENABLE();
	  ADC_ChannelConfTypeDef sConfig = {0};
	  hadc1.Instance = ADC1;
	  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
	  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
	  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
	  hadc1.Init.ContinuousConvMode = ENABLE;
	  hadc1.Init.DiscontinuousConvMode = DISABLE;
	  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
	  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
	  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
	  hadc1.Init.NbrOfConversion = 1;
	  hadc1.Init.DMAContinuousRequests = DISABLE;
	  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
	  if (HAL_ADC_Init(&hadc1) != HAL_OK)
	  {
		  ioal_error_handler();
	  }

	  /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
	  */
	  sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
	  sConfig.Rank = ADC_REGULAR_RANK_1;
	  sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
	  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
	  {
		  ioal_error_handler();
	  }

	ioal_hadc1->intf_gen_info.vdp_intf_inst_hdle = (void*)&hadc1;
	ioal_hadc1->intf_gen_info.state = IO_FREE_STATE;
}

/**
 * @brief this function starts the ADC interface.
 */
hal_ret_sts io_hal_stm32f7xx_adc_start (ioal_adc_hdle *ioal_hadc)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;
	ADC_HandleTypeDef *hadc = ioal_hadc->intf_gen_info.vdp_intf_inst_hdle;

	if(HAL_OK == HAL_ADC_Start(hadc))
	{
		ret_sts = HAL_SCS;
	}
	else
	{
		ret_sts = HAL_IO_VDP_ERR;
	}
	return ret_sts;
}

/**
 * @brief this function stops the ADC interface.
 */
hal_ret_sts io_hal_stm32f7xx_adc_stop (ioal_adc_hdle *ioal_hadc)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;
	ADC_HandleTypeDef *hadc = ioal_hadc->intf_gen_info.vdp_intf_inst_hdle;

	if(HAL_OK == HAL_ADC_Stop(hadc))
	{
		ret_sts = HAL_SCS;
	}
	else
	{
		ret_sts = HAL_IO_VDP_ERR;
	}
	return ret_sts;
}

/**
 * @brief  this function start the ADC pollforconversion.
 */
hal_ret_sts io_hal_stm32f7xx_adc_pollforconversion (ioal_adc_hdle *ioal_hadc, uint32_t Timeout)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;
	ADC_HandleTypeDef *hadc = ioal_hadc->intf_gen_info.vdp_intf_inst_hdle;

	if(HAL_OK == HAL_ADC_PollForConversion(hadc, Timeout))
	{
		ret_sts = HAL_SCS;
	}
	else
	{
		ret_sts = HAL_IO_VDP_ERR;
	}
	return ret_sts;
}

/**
 * @brief  this function start the ADC pollforevent.
 */
hal_ret_sts io_hal_stm32f7xx_adc_pollforevent(ioal_adc_hdle *ioal_hadc, uint32_t EventType, uint32_t Timeout)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;
	ADC_HandleTypeDef *hadc = ioal_hadc->intf_gen_info.vdp_intf_inst_hdle;

	if(HAL_OK == HAL_ADC_PollForEvent(hadc, EventType, Timeout))
	{
		ret_sts = HAL_SCS;
	}
	else
	{
		ret_sts = HAL_IO_VDP_ERR;
	}
	return ret_sts;
}

/**
 * @brief this function start the ADC_it.
 */
hal_ret_sts io_hal_stm32f7xx_adc_start_it(ioal_adc_hdle *ioal_hadc)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;
	ADC_HandleTypeDef *hadc = ioal_hadc->intf_gen_info.vdp_intf_inst_hdle;

	if(HAL_OK == HAL_ADC_Start_IT(hadc))
	{
		ret_sts = HAL_SCS;
	}
	else
	{
		ret_sts = HAL_IO_VDP_ERR;
	}
	return ret_sts;
}

/**
 * @brief this function stop the ADC_it.
 */
hal_ret_sts io_hal_stm32f7xx_adc_stop_it(ioal_adc_hdle *ioal_hadc)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;
	ADC_HandleTypeDef *hadc = ioal_hadc->intf_gen_info.vdp_intf_inst_hdle;

	if(HAL_OK ==  HAL_ADC_Stop_IT(hadc))
	{
		ret_sts = HAL_SCS;
	}
	else
	{
		ret_sts = HAL_IO_VDP_ERR;
	}
	return ret_sts;
}

/**
 * @brief this function start the ADC in dma mode.
 */
hal_ret_sts io_hal_stm32f7xx_adc_start_dma(ioal_adc_hdle *ioal_hadc, uint32_t* pData, uint32_t Length)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;
	ADC_HandleTypeDef *hadc = ioal_hadc->intf_gen_info.vdp_intf_inst_hdle;

	if(HAL_OK ==   HAL_ADC_Start_DMA(hadc, pData, Length))
	{
		ret_sts = HAL_SCS;
	}
	else
	{
		ret_sts = HAL_IO_VDP_ERR;
	}
	return ret_sts;
}

/**
 * @brief this function stop the ADC in dma mode.
 */
hal_ret_sts io_hal_stm32f7xx_adc_stop_dma(ioal_adc_hdle *ioal_hadc)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;
	ADC_HandleTypeDef *hadc = ioal_hadc->intf_gen_info.vdp_intf_inst_hdle;

	if(HAL_OK ==  HAL_ADC_Stop_DMA(hadc))
	{
		ret_sts = HAL_SCS;
	}
	else
	{
		ret_sts = HAL_IO_VDP_ERR;
	}
	return ret_sts;
}

/**
 * @brief  this function used to getvalue from adc.
 */
uint32_t io_hal_stm32f7xx_adc_getvalue(ioal_adc_hdle *ioal_hadc)
{
	uint32_t ret_sts;
	ADC_HandleTypeDef *hadc = ioal_hadc->intf_gen_info.vdp_intf_inst_hdle;

	ret_sts = HAL_ADC_GetValue(hadc);

	return ret_sts;
}

/**
 * @brief  this function config the channel in adc.
 */
hal_ret_sts io_hal_stm32f7xx_adc_configchannel(ioal_adc_hdle *ioal_hadc, adc_channelconftypedef* sconfig)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;
	ADC_HandleTypeDef *hadc = ioal_hadc->intf_gen_info.vdp_intf_inst_hdle;

	if(HAL_OK ==  HAL_ADC_ConfigChannel(hadc,(ADC_ChannelConfTypeDef*)sconfig))
	{
		ret_sts = HAL_SCS;
	}
	else
	{
		ret_sts = HAL_IO_VDP_ERR;
	}
	return ret_sts;
}

/**
 * @brief this function configures the analog watchdog in ADC.
 */
hal_ret_sts io_hal_stm32f7xx_adc_analogwdgconfig(ioal_adc_hdle *ioal_hadc, adc_channelconftypedef* sconfig)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;
	ADC_HandleTypeDef *hadc = ioal_hadc->intf_gen_info.vdp_intf_inst_hdle;

	if(HAL_OK ==  HAL_ADC_AnalogWDGConfig(hadc,(ADC_AnalogWDGConfTypeDef*)sconfig))
	{
		ret_sts = HAL_SCS;
	}
	else
	{
		ret_sts = HAL_IO_VDP_ERR;
	}
	return ret_sts;
}

/**
 * @brief this function return the ADC state.
 */
hal_ret_sts io_hal_stm32f7xx_adc_getstate(ioal_adc_hdle *ioal_hadc)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;
	ADC_HandleTypeDef *hadc = ioal_hadc->intf_gen_info.vdp_intf_inst_hdle;

	if(HAL_OK == HAL_ADC_GetState(hadc))
	{
		ret_sts = HAL_SCS;
	}
	else
	{
		ret_sts = HAL_IO_VDP_ERR;
	}
	return ret_sts;
}

/**
 * @brief this function return the ADC error code.
 */
hal_ret_sts io_hal_stm32f7xx_adc_geterror(ioal_adc_hdle *ioal_hadc)
{
	hal_ret_sts ret_sts = HAL_MAX_ERR;
	ADC_HandleTypeDef *hadc = ioal_hadc->intf_gen_info.vdp_intf_inst_hdle;

	if(HAL_OK == HAL_ADC_GetError(hadc))
	{
		ret_sts = HAL_SCS;
	}
	else
	{
		ret_sts = HAL_IO_VDP_ERR;
	}
	return ret_sts;
}
