/**
  ******************************************************************************
  * @file    MDR1206_Led/src/main.c
  * @author  Milandr Application Team
  * @version V0.1
  * @date    10/11/2023
  * @brief   Main program body.
  ******************************************************************************
  * 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, MILANDR 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.
  */

/* Includes ------------------------------------------------------------------*/
#include "MDR32VF0xI.h"

#include "MDR32VF0xI_port.h"
#include "MDR32VF0xI_rst_clk.h"
#include "../drv/drv_display.h"
#include "../drv/drv_adcui.h"
#include "../drv/drv_clock.h"
#include "../drv/drv_button.h"
#include "../drv/drv_led.h"
#include "../drv/drv_adc.h"
#include "../drv/drv_flash.h"
#include "../utils/utils.h"
/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/
#define LED_PORT        MDR_PORTB
#define LED_PORT_CLK    RST_CLK_PORTB
#define LED_PIN_0       PORT_PIN_9
#define LED_PIN_1       PORT_PIN_10


/* Private macro -------------------------------------------------------------*/
#define __ramfunc  __attribute__ ((section (".ramfunc")))
#define __ahbram_data  __attribute__ ((section (".ahbram_data")))
#define __ahbram_bss   __attribute__ ((section (".ahbram_bss")))

/* Private variables ---------------------------------------------------------*/
uint64_t timeLastDisplayChange;

/* Private function prototypes -----------------------------------------------*/
/* Frequencies setup */
void Setup_CPU_Clock(void)
{
	RST_CLK_HCLK_InitTypeDef RST_CLK_CpuSpeed_InitStructure;

	delayUs(1000);
    RST_CLK_DeInit();
    RST_CLK_HSE_Cmd(ENABLE);
    RST_CLK_HSE_Config(RST_CLK_HSE_ON);
	RST_CLK_CpuSpeed_InitStructure.RST_CLK_CPU_C1_Source = RST_CLK_CPU_C1_CLK_SRC_HSE;
	RST_CLK_CpuSpeed_InitStructure.RST_CLK_CPU_C2_ClockSource = RST_CLK_CPU_C2_CLK_SRC_PLLCPU;
	RST_CLK_CpuSpeed_InitStructure.RST_CLK_CPU_C3_Prescaler =  RST_CLK_CPU_C3_PRESCALER_DIV_1;
	RST_CLK_CpuSpeed_InitStructure.RST_CLK_HCLK_ClockSource = RST_CLK_CPU_HCLK_CLK_SRC_CPU_C3;
	RST_CLK_CpuSpeed_InitStructure.RST_CLK_PLLCPU_ClockSource = RST_CLK_PLLCPU_CLK_SRC_HSE;
	RST_CLK_CpuSpeed_InitStructure.RST_CLK_PLLCPU_Multiplier = RST_CLK_PLLCPU_MUL_7;
	delayUs(1000);
	RST_CLK_HCLK_Init(&RST_CLK_CpuSpeed_InitStructure);
	delayUs(1000);
	RST_CLK_CPU_C1_ClkSelection(RST_CLK_CPU_C1_CLK_SRC_HSE);
	RST_CLK_PER1_C2_ClkSelection(RST_CLK_PER1_C2_CLK_SRC_PLLCPU);
    RST_CLK_PCLKCmd(RST_CLK_PCLK_FLASH, ENABLE);
}

void __ramfunc __attribute__ ((interrupt)) MTIP_IRQHandler(void)
{
	_TimeUpdate();
	CLINT_MTIMER_SetTime(0);
}

void Setup_MachineTimer(void)
{
    /* Disable SysTick interrupt */
	CLINT_SetSoftwareMachineIRQ(RESET);
    /* Safely set up SysTick cmp value */
	CLINT_MTIMER_SetTime(0);
    CLINT_MTIMER_SetCompareTime(28000);
    /* Enable SysTick interrupt */
    CLINT_SetSoftwareMachineIRQ(SET);
    CLIC_EnableIRQ(MTIP_IRQn);
    CLIC_SetLevelIRQ(MTIP_IRQn, 1);
}


void eveventOnClick(void)
{
	drv_display_ledOn();
	drv_display_setNextDisplay();
	timeLastDisplayChange = getMillis();
}

/* Private functions ---------------------------------------------------------*/


/* Main function */
int main(void)
{
	SystemInit();
	Setup_CPU_Clock();
	drv_display_init();
	drv_adcui_init();
	drv_clock_init();
	drv_Button_Init();
	drv_adc_init();
	drv_led_init();
	drv_flash_init();
	Setup_MachineTimer();

    drv_Button_SetEvent(ButtonFirst,ButtonClick,eveventOnClick);
    drv_Button_SetEvent(ButtonSecond,ButtonClick,drv_display_setNextSubDisplay);
    drv_Button_SetEvent(ButtonSecond,ButtonLongPress,drv_adcui_callibrate);


    while (1)
    {
    	drv_Button_Update();
    	drv_display_update();
    	drv_clock_update();
    	drv_adc_update();
    	if(getMillis() - timeLastDisplayChange>10000)//10 sec
    	{
     		drv_display_setNextDisplay();
    		timeLastDisplayChange = getMillis();
    	}
    }
}

