#include "globalv.h"
#include "init.h"

void RCC_Configuration(void)
{
    PLL_InitTypeDef PLL_InitStruct = {
        .ClockSource = SYSCTRL_PLL_SOURCE_HSI_48M,
        .PLL_OutFreq = 64000000,
        .SourceFreq = 48000000,
        .WaitCycle = SYSCTRL_PLL_WAIT_CYCLE_2048
    };

    SYSCTRL_HSI_Enable(HSIOSC_TO_HSI96MHZ);
    SYSCTRL_HCLKPRS_Config(SYSCTRL_HCLK_DIV1);
    SYSCTRL_PCLKPRS_Config(SYSCTRL_PCLK_DIV1);

    __SYSCTRL_FLASH_CLK_ENABLE();
    FLASH_SetLatency(FLASH_Latency_3);

    if (SYSCTRL_PLL_Enable(&PLL_InitStruct) == 0)
    {
        SYSCTRL_SysClk_Switch(SYSCTRL_SYSCLKSRC_PLL);
        SYSCTRL_SystemCoreClockUpdate(64000000);
    }
    else
    {
        SYSCTRL_SystemCoreClockUpdate(96000000);
    }
}

void GPIOInit(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    __SYSCTRL_GPIOA_CLK_ENABLE();
    __SYSCTRL_GPIOB_CLK_ENABLE();
    __SYSCTRL_GPIOC_CLK_ENABLE();
    __SYSCTRL_GPIOF_CLK_ENABLE();

    GPIO_InitStruct.IT = GPIO_IT_NONE;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;

    GPIO_InitStruct.Pins = LED_GPIO_PIN;
    GPIO_Init(LED_GPIO_PORT, &GPIO_InitStruct);

    GPIO_InitStruct.Pins = VOUT_EN_GPIO_PIN;
    GPIO_Init(VOUT_EN_GPIO_PORT, &GPIO_InitStruct);
    GPIO_WritePin(VOUT_EN_GPIO_PORT, VOUT_EN_GPIO_PIN, GPIO_Pin_RESET);

    GPIO_InitStruct.Mode = GPIO_MODE_INPUT_PULLUP;
    GPIO_InitStruct.Pins = EN_GPIO_PIN;
    GPIO_Init(EN_GPIO_PORT, &GPIO_InitStruct);
    GPIO_InitStruct.Pins = DR_GPIO_PIN;
    GPIO_Init(DR_GPIO_PORT, &GPIO_InitStruct);
    GPIO_InitStruct.Pins = BKIN_GPIO_PIN;
    GPIO_Init(BKIN_GPIO_PORT, &GPIO_InitStruct);
}

static void ADC_UpdateSampleBuffer(void)
{
    SampleData[0] = ADC_GetConversionValue(CW_ADC1, 0);
    SampleData[1] = ADC_GetConversionValue(CW_ADC1, 1);
    SampleData[2] = ADC_GetConversionValue(CW_ADC1, 2);
    SampleData[3] = ADC_GetConversionValue(CW_ADC1, 3);
}

void ADC1_SampleCallback(void)
{
    if (ADC_GetITStatus(CW_ADC1, ADC_IT_EOS) != RESET)
    {
        ADC_ClearITPendingBit(CW_ADC1, ADC_IT_EOS);
        ADC_UpdateSampleBuffer();
    }
}

void ADC_Configuration(void)
{
    ADC_InitTypeDef ADC_InitStruct = {0};

    __SYSCTRL_GPIOA_CLK_ENABLE();
    __SYSCTRL_ADC_CLK_ENABLE();

    PA04_ANALOG_ENABLE();
    PA05_ANALOG_ENABLE();
    PA06_ANALOG_ENABLE();
    PA07_ANALOG_ENABLE();

    ADC_InitStruct.ADC_ClkDiv = ADC_Clk_Div2;
    ADC_InitStruct.ADC_SlaveMod = ADC_SlaveMode_Disable;
    ADC_InitStruct.ADC_ConvertMode = ADC_ConvertMode_Once;
    ADC_InitStruct.ADC_SQREns = ADC_SqrEns0to3;
    ADC_InitStruct.ADC_IN0.ADC_InputChannel = ADC_InputCH5;
    ADC_InitStruct.ADC_IN0.ADC_SampTime = ADC_SampTime70Clk;
    ADC_InitStruct.ADC_IN1.ADC_InputChannel = ADC_InputCH6;
    ADC_InitStruct.ADC_IN1.ADC_SampTime = ADC_SampTime70Clk;
    ADC_InitStruct.ADC_IN2.ADC_InputChannel = ADC_InputCH7;
    ADC_InitStruct.ADC_IN2.ADC_SampTime = ADC_SampTime70Clk;
    ADC_InitStruct.ADC_IN3.ADC_InputChannel = ADC_InputCH4;
    ADC_InitStruct.ADC_IN3.ADC_SampTime = ADC_SampTime70Clk;
    ADC_Init(CW_ADC1, &ADC_InitStruct);
    ADC_ClearITPendingAll(CW_ADC1);

    ADC_ExtTrigCfg(CW_ADC1, ADC_TRIG_ATIMOC4REFC, ENABLE);
    ADC_ITConfig(CW_ADC1, ADC_IT_EOS, ENABLE);
    ADC_Enable(CW_ADC1);

    __disable_irq();
    NVIC_EnableIRQ(ADC1_IRQn);
    __enable_irq();

    ADC_SoftwareStartConvCmd(CW_ADC1, ENABLE);
}

void BTIM_init(void)
{
    BTIM_TimeBaseInitTypeDef BTIM_InitStruct = {0};

    __SYSCTRL_BTIM123_CLK_ENABLE();

    __disable_irq();
    NVIC_EnableIRQ(BTIM1_IRQn);
    __enable_irq();

    BTIM_InitStruct.BTIM_Mode = BTIM_MODE_TIMER;
    BTIM_InitStruct.BTIM_CountMode = BTIM_COUNT_MODE_REPETITIVE;
    BTIM_InitStruct.BTIM_Period = 3999;
    BTIM_InitStruct.BTIM_Prescaler = 15;
    BTIM_TimeBaseInit(CW_BTIM1, &BTIM_InitStruct);

    BTIM_ITConfig(CW_BTIM1, BTIM_IT_UPDATE, ENABLE);
    BTIM_Cmd(CW_BTIM1, ENABLE);
}
