/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_conf.h"
#include "Interrupts.h"

/* Private variables ---------------------------------------------------------*/
Interrupts_Callback _callback[INTERRUPTS_SourcesEnd];

/* Exported functions --------------------------------------------------------*/

// Interrupts_RegisterCallback()
// -----------------------------
// Register an event handler for a given interrupt source
// Note: current implementation allows for only one handler per interrupt source
extern void Interrupts_RegisterCallback(Interrupts_Sources source, Interrupts_Callback callback)
{
	_callback[source] = callback;
}

// Interrupts_UnregisterCallback()
// -----------------------------
// Unregister the current event handler for a given interrupt source
extern void Interrupts_UnregisterCallback(Interrupts_Sources source)
{
	_callback[source] = 0;
}

/* Private functions ---------------------------------------------------------*/
extern void SysTick_Handler(void)
{
	if (_callback[INTERRUPTS_SysTick] != 0)
    {
	    _callback[INTERRUPTS_SysTick]();
	}
}

extern void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
	{
	    if (_callback[INTERRUPTS_TIM2] != 0)
	    {
	        _callback[INTERRUPTS_TIM2]();
	    }

	    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}

extern void RTC_IRQHandler(void)
{
    // If counter is equal to 86399: one day was elapsed.
    // This takes care of date change and resetting of counter in case of
    // power on - Run mode/ Main supply switched on condition.
    if(RTC_GetCounter() == 86399)
    {
        RTC_WaitForLastTask();
        RTC_SetCounter(0);
        RTC_WaitForLastTask();
    }
  
    if (_callback[INTERRUPTS_RTC] != 0)
    {
	    _callback[INTERRUPTS_RTC]();
    }
  
    NVIC_ClearPendingIRQ(RTC_IRQn);
    RTC_ClearITPendingBit(RTC_IT_SEC);
}

extern void RTCAlarm_IRQHandler(void)
{
    if (_callback[INTERRUPTS_RTCAlarm] != 0)
    {
        _callback[INTERRUPTS_RTCAlarm]();
    }

    RTC_ClearITPendingBit(RTC_IT_ALR);
    EXTI_ClearITPendingBit(EXTI_Line17);
}

extern void ADC1_2_IRQHandler(void)
{
    if (_callback[INTERRUPTS_ADC] != 0)
	{
	    _callback[INTERRUPTS_ADC]();
	}

	ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);
}
