/**
  ******************************************************************************
  * @file           : main.c
  * @author         : SINOMCU-AE
  * @brief          : Main program body
  *    
  *          This file provides example code for UART RX and printf by uart:
  * UART RX interrupt,Start $ ,END 0x0A;Buff len 64;send back recv frame if it is currect.
  * 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"

/* LED blink half cycle*/
#define LED_BLINK_ERROR      10000     // run count for led Freq,HSI 8M,this main applicaiton, about 100ms?
#define LED_BLINK_SLOWE      25000     // run count for led Freq,HSI 8M,this main applicaiton, about 200ms?
#define LED_BLINK_NOMAL      50000     // run count for led Freq,HSI 8M,this main applicaiton, about 500ms?

UartRecvStatus recv_status = WAIT_STAR;
UartRecvFinishFlag recv_finsh = NO_FINISH;

uint8_t uart_buff[UART_BUFF_LEN]={0};

/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void) {
  uint32_t count_LED = 0;
  uint32_t led_blink_period = LED_BLINK_NOMAL;
          
  //sysclk_init();        // sysclk 48M,HSI/2 *12;if not call this function,default HSI 8M
  SystemCoreClockUpdate();
  
  SysTick_Init();
  gpio_init();

  MS32_RCC_SetUSARTClockSource(MS32_RCC_USART1_CLKSOURCE_HSI);                           // uart clk HSI 8M
  usart1_uart_init(115500);                                                              // HSI 8M 115500 for 115200
  
  LED1_ON();   
  printf("\r\n\r\n*****UART Printf loop RX IT Example*****");
  printf("\r\n--Inf:System Core Clock %d Hz.",SystemCoreClock);
  printf("\r\n");
  
  while (1) {
    if(recv_status == UART_ERROR_ORE) {                                                  // uart error interrupt occur
      recv_status =UART_ERROR_CLR;
      led_blink_period = LED_BLINK_SLOWE;
      printf("\r\n--!!!UART ORE Occur!!!");
    }
    else if((recv_status == UART_ERROR_NIOSE)||(recv_status == UART_ERROR_NO_DEF)) {     // uart error interrupt occur
      recv_status =UART_ERROR_CLR;
      led_blink_period = LED_BLINK_ERROR;
      printf("\r\n--!!!UART ERROR!!!");
      printf("\r\n--!!!UART RX IRQ Disable!!!");
    }
    else if(recv_finsh == RECV_ERROR) {                                                  // frame format not corrent
      recv_finsh =RECV_ERROR_CLR;
      led_blink_period = LED_BLINK_SLOWE;
      printf("\r\n--###recv char not the correct frame format");
    }
    else if(recv_finsh == FINISH) {
      recv_finsh = FINISH_CLR;
      led_blink_period =LED_BLINK_NOMAL;
      Send_buff_Uart(uart_buff);                                                         // recv one frame,send back
    }

    count_LED++;
    if(count_LED >= led_blink_period) {
      LED1_TOGGLE();
      //printf("\r\n--Inf:LED Toggle");
      count_LED =0;
    }    
  }
}

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