/**
  ******************************************************************************
  * @file           : main.c
  * @author         ：SINOMCU-AE
  * @brief          : Main program body
  *  
  *          This file provides example code for Power stop mode and printf by uart:
  * TEST_STOP_CURRENT 0 (defualt):
  *     run 5S,than enter stop LDO low power mode,Press Key2(PB4,EXIT line4) up core go on.
  * TEST_STOP_CURRENT 1 :
  *     for stop LDO low power mode current test.you need powerup again for next timer.
  * 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 SYSCLK_USE_PLL_48M   0         // 1:sysclk PLL48M,0:HSI 8M 

#define COUNT_PERIOD         500       // count period in ms

FlagStatus EXIT_Trigger = RESET;

int main(void) {
  uint32_t run_count = 0;
#if( defined(TEST_STOP_CURRENT) && (TEST_STOP_CURRENT) )
#else 
  uint8_t stop_enter_count = 0;
#endif

#if(defined(SYSCLK_USE_PLL_48M) && SYSCLK_USE_PLL_48M) 
  sysclk_init();                       // sysclk 48M,HSI 8M /2*12;if not call this function,default HSI 8M
#endif
  SystemCoreClockUpdate();             // get System Core Clock

  sys_tick_init();
  gpio_init();
#if( defined(TEST_STOP_CURRENT) && (TEST_STOP_CURRENT) )
#else    
  exit_line_init();
#endif //#if( defined(TEST_STOP_CURRENT) && (TEST_STOP_CURRENT) )

#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

#if( defined(TEST_STOP_CURRENT) && (TEST_STOP_CURRENT) )
  printf("\r\n\r\n*****Power STOP LDO LP Enter Example*****");
  printf("\r\n--Inf:System Core Clock %d Hz.",SystemCoreClock);  
#else 
  printf("\r\n\r\n*****Power STOP LDO LP Exit PB4 Example*****");
  printf("\r\n--Inf:System Core Clock %d Hz.",SystemCoreClock);    
  Start_User_MS_SF_Timer(COUNT_PERIOD);
#endif

  while(1) {
#if( defined(TEST_STOP_CURRENT) && (TEST_STOP_CURRENT) )  
    for(run_count =0 ; run_count < ENTER_STOP_DELAY_COUNT; run_count++) {
      LED1_TOGGLE();
      MS32_mDelay(ENTER_STOP_DELAY_BASE_MS);
    }
    LED1_OFF(); 
    printf("\r\n--Inf:Enter STOP... ... ");  
    MS32_mDelay(DELAY_FOR_UART_SEND);  

    EnterSTOP_LPREGUMode();    
#else
    if(EXIT_Trigger == SET) {
      EXIT_Trigger = RESET;  
      printf("\r\n--Inf:EXIT PB4 Trigger");
    }    
    
    if(Get_State_User_MS_SF_Timer() == SF_TIMER_OV) {      // clear Software timer OV
      Start_User_MS_SF_Timer(COUNT_PERIOD);
      LED1_TOGGLE();
      
      run_count++;
      printf("\r\n--Inf: running count:%d",run_count);

      stop_enter_count++;                   
      if(stop_enter_count == ENTER_STOP_DELAY_COUNT) {     // enter low power count 5S               
        stop_enter_count =0;

        LED1_OFF(); 
        printf("\r\n--Inf:Enter STOP;PB4 Key Press Exit Stop."); 
        MS32_mDelay(DELAY_FOR_UART_SEND);

        LED2_ON();                                         // LED2 light on
        EnterSTOP_LPREGUMode();
#if(defined(SYSCLK_USE_PLL_48M) && SYSCLK_USE_PLL_48M) 
        sysclk_init();
#endif
        LED2_OFF();                                        // exit low power mode LED2 OFF
      }
    }
#endif
  }
}

/**
  * @brief  EXTI4 to 15 IRQ callback function.
  * @param  None
  * @retval None
  */
void EXTI4_15_Callback(void) {
  EXIT_Trigger = SET;
}

/**
  * @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 *********************************/
