/**
 *******************************************************************************
 * @file    main.c
 *
 * @brief   Main program body.
 *
 * @author  DPM
 *
 * @version V1.0.0
 *
 * @date    2024-5-6
 *
 *******************************************************************************/

/*
    Copyright (c) 2024, DP Microelectronics Inc.

    Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice, this
       list of conditions and the following disclaimer.
    2. Redistributions in binary form must reproduce the above copyright notice,
       this list of conditions and the following disclaimer in the documentation
       and/or other materials provided with the distribution.
    3. Neither the name of the copyright holder nor the names of its contributors
       may be used to endorse or promote products derived from this software without
       specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/

/* Files include */
#include "main.h"
#include "dpm32m0xx.h"
#include "dpm32m0xx_eval.h"
#include "systick.h"
#include <stdio.h>

/**
  * @addtogroup DPM32M08X_LibSamples
  * @{
  */

/**
  * @addtogroup ADC
  * @{
  */

/**
  * @addtogroup ADC_TemperatureNTC
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
GPIO_InitTypeStruct ADC_GPIO_InitStruct;
ADCCOM_InitTypeStruct ADCCOM_InitStruct;
ADCCOM_ChannelStruct ADCCOM_ChannelConfigStruct;
ADC_InitTypeStruct ADC_InitStruct;
ADC_ChannelStruct ADC_ChannelConfigStruct;
DMA_InitTypeStruct DMA_InitStructType;

/* Private define ------------------------------------------------------------*/
#define SAMPLENUM 10
#define NTC_B_VALUE 3950
#define NTC_R25 10000
#define ADC_RESOLUTION 4096
#define ADC_REFERENCE_VOLTAGE 3.3
/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/
uint32_t ADCCode[SAMPLENUM] ;
uint16_t Code = 0 ;
float Temp = 0;
/* Private function prototypes -----------------------------------------------*/
uint32_t ADC_GetCode(void);
uint32_t ADC_AverageCode(void);
float ADC_GetTemp(uint16_t code);

/* Private functions ---------------------------------------------------------*/
/**
  * @brief  The program entry function.
  * @retval int
  */
int main(void)
{
  /* Configure the system clock */
  SystemClockInit();
  
  /* Configure the system tick */
  SystickInit();
  
  /* LED Init */
  EVAL_LedInit(LED1);
  
  /* Uart Init */
  EVAL_ComInit();

  /********************* User Code *********************/
  /* Enable clock */
  RCC_Unlock();
  RCC_AHBPeriphClockCmd(RCC_AHB_PERIPH_GPIO, ENABLE);
  RCC_APBPeriphClockCmd(RCC_APB_PERIPH_ADC, ENABLE);
  RCC_Lock();
  /* Config ADC Channel0 GPIO */
  ADC_GPIO_InitStruct.GPIO_Mode = GPIO_MODE_ANALOG;
  ADC_GPIO_InitStruct.GPIO_Speed = GPIO_SPEED_HIGH;
  ADC_GPIO_InitStruct.GPIO_OType = GPIO_OTYPE_PP;
  ADC_GPIO_InitStruct.GPIO_PuPd = GPIO_PUPD_NOPULL;
  ADC_GPIO_InitStruct.GPIO_Pin = GPIO_PIN_0;
  GPIO_Init(GPIOC, &ADC_GPIO_InitStruct);
  GPIO_AnaAFConfig(GPIOC, GPIO_PIN_0, GPIO_ANA_AF_0);
  /* Config ADC common parameters */
  ADCCOM_StructInit(&ADCCOM_InitStruct);
  ADCCOM_InitStruct.AdcSpeed = 1;
  ADCCOM_InitStruct.Vref = ADC_VREF_AVDD;
  ADCCOM_InitStruct.ClkDiv = ADC_CLK_DIV1;
  ADCCOM_InitStruct.SampleTime0 = ADC_SAMPLE_TIME_16Cycles;
  ADCCOM_InitStruct.SampleTime1 = ADC_SAMPLE_TIME_16Cycles;
  ADCCOM_InitStruct.SampleAccuracy = ADC_Sample_Accuracy_12Bit;
  ADCCOM_Init(&ADCCOM_InitStruct);
  /* Config ADC channel common parameters  */
  ADCCOM_ChannelStructInit(&ADCCOM_ChannelConfigStruct);
  ADCCOM_ChannelConfigStruct.Channel = ADC_Channel_10;
  ADCCOM_ChannelConfigStruct.BufferEnable = DISABLE;
  ADCCOM_ChannelConfigStruct.OversampleEnable = DISABLE;
  ADCCOM_ChannelConfigStruct.SampleTimeSel = ADC_SAMPLE_TIME_SEL0;
  ADCCOM_ChannelConfigStruct.Offset = 0;
  ADCCOM_ChannelConfig(&ADCCOM_ChannelConfigStruct);
  /* Config ADC channel0 */
  ADC_ChannelStructInit(&ADC_ChannelConfigStruct);
  ADC_ChannelConfigStruct.Channel = ADC_Channel_10;
  ADC_ChannelConfigStruct.DataAlign = ADC_DATA_ALIGN_RIGHT;
  ADC_ChannelConfigStruct.DataSign = ADC_DATA_UNSIGNED;
  ADC_ChannelConfigStruct.AWDEnable = DISABLE;
  ADC_ChannelConfig(ADC0, &ADC_ChannelConfigStruct);
  /* Config ADC0 */
  ADC_StructInit(&ADC_InitStruct);
  ADC_InitStruct.TrigMode = ADC_TRIG_SW_SINGLE_CONV;
  ADC_InitStruct.ContinueWait = ADC_CONTINUE_WAIT_CYCLE_0;
  ADC_InitStruct.SoftTrigChannel = ADC_Channel_10;
  ADC_Init(ADC0, &ADC_InitStruct);

  /* Enable ADC0 */
  ADC_Cmd(ADC0, ENABLE);

  /* Infinite loop */
  while(1)
  {
    /* Get ADC Code */
    Code = ADC_AverageCode();
    /* Get Temp value */
    Temp = ADC_GetTemp(Code);
    printf("Temperature = %0.2f\r\n", Temp);
    DelayMs(1000);

    EVAL_LedToggle(LED1);
  }
}

/**
  * @brief  This function is ADC Read.
  * @param  None
  * @retval None
  */
uint32_t ADC_GetCode(void)
{
  uint32_t ADCCode;

  /* ADCx StartConversion */
  ADC_StartConversion(ADC0);

  while(ADC_GetIntFlagStatus(ADC0, ADC_INT_FLAG_EOC) != SET);

  /* ADCx GetSingleData */
  ADCCode = ADC_GetSingleData(ADC0);

  /* ADCx StopConversion */
  ADC_StopConversion(ADC0);

  return ADCCode;
}

/**
  * @brief  This function obtains the average code value.
  * @param  None
  * @retval None
  */
uint32_t ADC_AverageCode(void)
{
  uint16_t AveCode = 0;
  uint32_t SumCode = 0;
  ADC_GetCode();
  DelayMs(5);

  /* ADC0 GetSingleData */
  for(uint16_t i = 0; i < SAMPLENUM; i++)
  {
    SumCode += ADC_GetCode();
    DelayMs(50);
  }

  AveCode = SumCode / SAMPLENUM;
  return AveCode;
}

/**
  * @brief  This function obtains the temp value.
  * @param  None
  * @retval None
  */
float ADC_GetTemp(uint16_t code)
{
  float temp;
  float voltage = 0;
  float Rt = 0;
  float logRt = 0;
  float Rp = 10000;
  float Rref = 10000;
  float T2 = 273.15 + 25;
  float B = 3950;
  float K = 273.15;
  //voltage value
  voltage = (float) code * 3300 / 4096;
  //Resistance value corresponding to voltage
  //Rt = (3300 - voltage) * Rref / voltage;
  Rt = Rref * ((3300 / voltage) - 1.0f);
  //Temp value
  logRt = log(Rt / Rp);
  temp = (float)1.0f / (1.0f / T2 + (1.0f / B) * logRt) - K + 0.5;
  return temp;
}

/* retarget the C library printf function to the usart */
int fputc(int ch, FILE *f)
{
  UART_SendData(EVAL_COM0, (uint8_t)ch);

  while(RESET == UART_GetIntFlagStatus(EVAL_COM0, UART_INT_FLAG_TXE));

  return ch;
}



/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */

/************************ (C) COPYRIGHT DP *****END OF FILE ***************************/
