/**
  ******************************************************************************
  * @file           : main.c
  * @author         ：SINOMCU-AE
  * @brief          : Main program body
  *    
   *          This file provides example code for ADC Basic and printf by uart.
  * ADC IN1,IN4 interval 100ms software trig,DMA Transfer,no result filter.
  * Example time out:USE_TIMEOUT 1, when error LED blink cycle ADC_ERROR_LED_BLINK_HALF_PER *2.
  * LED1 blink by sysTick soft timer,defualt blink period 1S;
  * uart send information of running count(redirect printf).
  * For details,see "readme.txt"   
  *         
  ******************************************************************************
   * @attention 
  *                           DISCLAIMER
  * The present firmware which is for guidance only aims at providing customers
  * with coding information regarding their products in order for them to save
  * time. As a result, SinoMCU shall not be held liable for any direct,indirect
  * or consequential damages with respect to any claims arising from the content 
  * of such firmware and/or the use made by customers of the coding information 
  * contained herein in connection with their products.
  *
  * <h2><center>&copy; Copyright (c) 2021 sinomcu All rights reserved.</center></h2>
  *
  ******************************************************************************
  */  
  
#include "system_define.h"

#define USER_VDDA                 3300           // unit mv

// LED blink half cycle in ms 
#define LED_BLINK_HALF_PER        500            // unit ms

FlagStatus DMA_CH1_TC_Trigger = RESET;
uint16_t ADC_result_buff[ADC_BUFF_LEN]={0};

/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void) 
{
  uint32_t count=0;
  ADCErrorStatus ADC_status = ADC_NO_ERROR;
  uint16_t voltage   = 0;

  //SystemClock_Config();           // sysclk 48M,HSI 8M /2*12;if not call this function,default HSI 8M
  SystemCoreClockUpdate();        // get System Core Clock

  SysTick_Init();
  GPIO_Init();
#if(defined(EN_PRINT_UART) && EN_PRINT_UART)   
  MS32_RCC_SetUSARTClockSource(MS32_RCC_USART1_CLKSOURCE_HSI);  // uart clk HSI 8M      
  USART1_UART_Init(115200);
#endif

  LED1_ON(); 
  printf("\r\n\r\n*****ADC DMA SW Trig Example*****");
  printf("\r\n--Inf:System Core Clock %d Hz.",SystemCoreClock);

  DMA_CH1ADC_Init();
  ADC_Init();
  
  ADC_status = Activate_ADC();
  if(ADC_status !=ADC_NO_ERROR )
  {
    ADC_ERROR(ADC_status);
  }
  
  Start_100MS_SF_Timer();
  Start_User_MS_SF_Timer(LED_BLINK_HALF_PER);
  while(1) 
  {
    if(DMA_CH1_TC_Trigger == SET)                               // DMA interrupt callback set flag,DMA transfer one time finish
    {
      DMA_CH1_TC_Trigger = RESET;
      printf("\r\n--Inf:DMA CH1 Transfer Complete"); 

      voltage = __MS32_ADC_CALC_DATA_TO_VOLTAGE(USER_VDDA, ADC_result_buff[0], MS32_ADC_RESOLUTION_12B);
      printf("\r\nADC CH1 voltage: %d mV", voltage);
      voltage = __MS32_ADC_CALC_DATA_TO_VOLTAGE(USER_VDDA, ADC_result_buff[0 + ADC_CH_NUM], MS32_ADC_RESOLUTION_12B);
      printf(", %d mV", voltage);                               // MS32 Sometimes ADC Software trigger one time,but resualt two

      voltage = __MS32_ADC_CALC_DATA_TO_VOLTAGE(USER_VDDA, ADC_result_buff[1], MS32_ADC_RESOLUTION_12B);
      printf("\r\nADC CH2 voltage: %d mV", voltage);
      voltage = __MS32_ADC_CALC_DATA_TO_VOLTAGE(USER_VDDA, ADC_result_buff[1 + ADC_CH_NUM], MS32_ADC_RESOLUTION_12B);
      printf(", %d mV", voltage);
    }
    
    if(Get_State_100MS_SF_Timer() == SF_TIMER_OV)
    {
      Start_100MS_SF_Timer();                                   // clear SF_TIMER_OV

      MS32_ADC_REG_StartConversion(ADC1);                       // interval 100ms，software start ADC
    }

    if(Get_State_User_MS_SF_Timer() == SF_TIMER_OV)
    {
      Start_User_MS_SF_Timer(LED_BLINK_HALF_PER);               // clear SF_TIMER_OV
      LED1_TOGGLE();
      count++;
      printf("\r\n--Inf: running count:%d",count);
    }
  }
}

/**
  * @brief  SystemClock_Config PLL 48M
  * @param  None
  * @retval None
  */
void SystemClock_Config(void)
{
  MS32_FLASH_SetLatency(MS32_FLASH_LATENCY_1);
  while(MS32_FLASH_GetLatency() != MS32_FLASH_LATENCY_1){ ; }
  MS32_RCC_HSI_Enable();

  // Wait HSI is ready
  while(MS32_RCC_HSI_IsReady() != 1){ ; }
 
  MS32_RCC_PLL_ConfigDomain_SYS(MS32_RCC_PLLSOURCE_HSI_DIV_2, MS32_RCC_PLL_MUL_12);
  MS32_RCC_PLL_Enable();

  // Wait PLL is ready 
  while(MS32_RCC_PLL_IsReady() != 1){ ; }

  MS32_RCC_SetAHBPrescaler(MS32_RCC_SYSCLK_DIV_1);
  MS32_RCC_SetAPB1Prescaler(MS32_RCC_APB1_DIV_1);
  MS32_RCC_SetSysClkSource(MS32_RCC_SYS_CLKSOURCE_PLL);

  // Wait System clock is ready
  while(MS32_RCC_GetSysClkSource() != MS32_RCC_SYS_CLKSOURCE_STATUS_PLL){ ; }
}

/******************************** END OF FILE *********************************/
