/**
  ******************************************************************************
  * @file           : main.c
  * @author         ：SINOMCU-AE
  * @brief          : Main program body
  *    
  *          This file provides example code for CMP2,OPAMP,ADC and printf by uart:
  *                                       |--> CMP2 INP,INN internal CRV 2.0V  --> OUT PA12
  *   PB5 --> OPAMP1 INP,internal Gain 2  |--> ADC(100ms software trig)        --> print
  *                                       |--> OUT PB7                                   
  * LED1 blink by sysTick soft timer,defualt blink period 1S;ADC Error blink 0.2S.
  * 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

/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)  {
  uint32_t count=0;
  ADCErrorStatus ADC_status = ADC_NO_ERROR;
  uint16_t adc_value = 0;
  uint16_t voltage   = 0;
  
  //sysclk_init();                  //sysclk 48M,HSI 8M /2*12;if not call this function,default HSI 8M
  SystemCoreClockUpdate();                                      // get System Core Clock
    
  sys_tick_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
  adc_init();
  opamp_init();
  cmp2_init();

  LED1_ON(); 
  printf("\r\n\r\n*****CMP2,OPAMP1 Gain2,ADC Example*****");
  printf("\r\n--Inf:System Core Clock %d Hz.",SystemCoreClock);
  printf("\r\n                                       |--> CMP2 INP,INN internal CRV 2.0V  --> OUT PA12");
  printf("\r\n   PB5 --> OPAMP1 INP,internal Gain 2  |--> ADC(100ms software trig)        --> print");
  printf("\r\n                                       |--> OUT PB7");  
    
  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(Get_State_100MS_SF_Timer() == SF_TIMER_OV) {
      Start_100MS_SF_Timer();                                   // clear SF_TIMER_OV
      adc_value = Gat_ADC_Conversion_Result( &ADC_status);
      
      if(ADC_status !=ADC_NO_ERROR ) {
        ADC_ERROR(ADC_status);
      }
      else {                                                    // get adc result OK,calc to mv
        voltage = __MS32_ADC_CALC_DATA_TO_VOLTAGE(USER_VDDA, adc_value, MS32_ADC_RESOLUTION_12B);
        printf("\r\n--Inf:OPAMP1-OUT(INx2): %d mV", voltage);
      } 
    }

    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 HSI/2 to PLL*12 sysclk 48M
  * @param  None
  * @retval None
  */
void sysclk_init(void) {
  MS32_RCC_OscInitTypeDef osc_cfg;
  MS32_RCC_PllInitTypeDef pll_cfg;
  MS32_RCC_ClkInitTypeDef clk_cfg;

  // get and clear reset flag 
  MS32_RCC_GetResetFlag(ENABLE);
  
  // osc config 
  osc_cfg.HSIState = MS32_RCC_HSI_ON;
  osc_cfg.HSEState = MS32_RCC_HSE_OFF;
  osc_cfg.LSIState = MS32_RCC_LSI_OFF;
//  osc_cfg.LSEState = MS32_RCC_LSE_ON_DRV_H;
  MS32_RCC_OscConfig(&osc_cfg);
  
  // pll config 
  pll_cfg.PLLState  = MS32_RCC_PLL_ON;
  pll_cfg.PLLSource = MS32_RCC_PLL_SOURCE_HSI_DIV_2;            // HSI/2 4M
  pll_cfg.PLLMUL    = MS32_RCC_PLL_MUL12;
  pll_cfg.PREDIV    = MS32_RCC_PLL_PREDIV_DIV1;
  MS32_RCC_PllConfig(&pll_cfg);
  
  // sysclk config 
  clk_cfg.SYSCLKSource   = MS32_RCC_SYSCLK_SOURCE_PLL;
  clk_cfg.AHBCLKDivider  = MS32_RCC_SYSCLK_DIV1;
  clk_cfg.APB1CLKDivider = MS32_RCC_HCLK_DIV1;
  MS32_RCC_ClockConfig(&clk_cfg);
}

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