#include "stm32f0xx_hal.h"
#include "systick.h"
//#include "string.h"
//#include "led.h"
//#include "buttons.h"
//#include <stdint.h>
#include <stdbool.h>


typedef struct
{
    TTimerHandler Handler;
    uint16_t      Countdown;
    uint16_t      Reload;
    bool          Run;    // Запущено
    bool          Fired;  // Сработало
    
} THandlers;


volatile uint32_t  TimingDelay;
volatile uint8_t   StopDelayFlag = 0;

static THandlers Handlers[TIMER_HANDLERS];
static uint32_t  TimerFrequency;
static int       TimerCount;

static uint8_t counter100hz = 0;

void IWDG_Feed(void);


//
void SysTick_Handler(void)
{
    //IWDG_Feed();
  
    HAL_IncTick();
  
    TimingDelay_Decrement();
      
    counter100hz++;

    if(counter100hz == 10)
    {
        counter100hz = 0;
        //LED_Blink();
        //BUTTON_CommonHandler();
    }
    
    for (int i = 0; i < TIMER_HANDLERS; i++)
    {
        if(Handlers[i].Run)
        {
            if(--Handlers[i].Countdown == 0)
            {
                Handlers[i].Countdown = Handlers[i].Reload;

                // Запишем, что сработало
                Handlers[i].Fired = true;
            }
        }
    }
}


// Запуск таймера с заданной частотой
void timer_Init(uint32_t Frequency)
{
#if 0  
    if(!Frequency) return;

    // Сбросим параметры
    TimerCount = 0;
    TimerFrequency = Frequency;
    memset(&Handlers[0], 0, sizeof(Handlers));

    // Настройка частоты
    SysTick_Config(clock_GetSYS() / Frequency);

    // Разрешение прерывания
//    NVIC_EnableIRQ(SysTick_IRQn);
#endif
}


// Добавить функцию в список вызова. Handler будет вызываться с заданной частотой
void timer_AddFunction(uint16_t Frequency, TTimerHandler Handler)
{
    for (int i = 0; i < TIMER_HANDLERS; i++)
    {
        // Найдем пустой слот
        if(!Handlers[i].Handler)
        {
            // Обработчик, частота опроса
            Handlers[i].Run       =  true;
            Handlers[i].Fired     =  false;
            Handlers[i].Handler   =  Handler;
            //Handlers[i].Reload    = (TimerFrequency / Frequency);
            Handlers[i].Reload    =  Frequency;
            Handlers[i].Countdown =  Handlers[i].Reload;
            
            TimerCount++;
            
            return;
        }
    }
}


// Изменить частоту таймера
void timer_ChangeFrequency(TTimerHandler Handler, uint16_t Frequency)
{
    for (int i = 0; i < TIMER_HANDLERS; i++)
	{
        if(Handlers[i].Handler == Handler)
        {
            Handlers[i].Reload = (TimerFrequency / Frequency);
            Handlers[i].Countdown = Handlers[i].Reload;
            break;
        }
    }
}


// Включить таймер
void timer_Resume(TTimerHandler Handler)
{
	for (int i = 0; i < TIMER_HANDLERS; i++)
	{
        if(Handlers[i].Handler == Handler)
        {
            Handlers[i].Run = true;
            break;
        }
    }
}


// Перезапустить таймер
void timer_Restart(TTimerHandler Handler)
{
	for (int i = 0; i < TIMER_HANDLERS; i++)
	{
        if(Handlers[i].Handler == Handler)
        {
            Handlers[i].Run = true;
            Handlers[i].Countdown = Handlers[i].Reload;
            break;
        }
    }
}


//
void timer_RestartAtOnce(TTimerHandler Handler)
{
	for (int i = 0; i < TIMER_HANDLERS; i++)
	{
        if(Handlers[i].Handler == Handler)
        {
            Handlers[i].Run = true;
            Handlers[i].Countdown = 1;
            break;
        }
    }
}


// Остановить таймер
void timer_Stop(TTimerHandler Handler)
{
	for (int i = 0; i < TIMER_HANDLERS; i++)
	{
		if(Handlers[i].Handler == Handler)
		{
            Handlers[i].Run = false;
            Handlers[i].Fired =  false;
            break;
        }
    }
}


//
void timer_Main(void)
{
	for(int i = 0; i < TIMER_HANDLERS; i++)
	{
        // Если сраотало - вызовем
        if(Handlers[i].Fired)
        {
            Handlers[i].Fired = false;
            Handlers[i].Handler();
        }
    }
}


// -----------------------------------------------------------------------------
// Вспомогательные функции
// -----------------------------------------------------------------------------

uint32_t clock_GetSYS(void)
{
    return SystemCoreClock;
}

// -----------------------------------------------------------------------------
/*
void Delay_ms(uint32_t nTime)
{
  TimingDelay = nTime;
  while(TimingDelay);
}
*/

//
void SYSTICK_SetDelayFlag()
{
    StopDelayFlag = 1;
}


//
uint8_t Delay_ms(uint32_t nTime)
{
    TimingDelay = nTime;
    
    while(TimingDelay);
    
    if (StopDelayFlag) {
        StopDelayFlag = 0;
        return 1;
    }
    else {
        return 0;
    }  
}


// -----------------------------------------------------------------------------
void TimingDelay_Decrement(void) 
{
    if (TimingDelay)
        TimingDelay--;
}



//******************************** (C) POTEK ***********************************