/*
 * drv_led.c
 *
 *  Created on: 17 мар. 2025 г.
 *      Author: basov.g
 */
#include "drv_led.h"
#include "drv_adcui.h"
#include "MDR32VF0xI_rst_clk.h"
#include "MDR32VF0xI_port.h"
#include "MDR32VF0xI_timer.h"
#include "../utils/utils.h"
#include "stdbool.h"
#include "stdint.h"
#define LEDERRORPIN		PORT_PIN_9
#define LEDSTATUSPIN	PORT_PIN_10
#define LEDFIRSTPIN		PORT_PIN_4
#define LEDSECONDPIN	PORT_PIN_6
#define LEDPORT			MDR_PORTB
#define	LED_CLK			RST_CLK_PCLK_PORTB

static uint16_t ledPin[COUNTLED] = {LEDERRORPIN, LEDSTATUSPIN, LEDFIRSTPIN, LEDSECONDPIN};
static LedMode ledMode[COUNTLED] = {0};
void __attribute__ ((interrupt)) TIMER2_IRQHandler( void )
{
	MDR_TIMER2->STATUS = 0;
	#define IMPULSEPERWAT 5
	int active = (drv_adcui_getActiveImp()/(100/IMPULSEPERWAT))%2;
	int reactive = (drv_adcui_getReactiveImp()/(100/IMPULSEPERWAT))%2;
	for(uint8_t i = 0; i < COUNTLED; i++)
	{
		switch(ledMode[i])
		{
		case LedModeOff				: if(1)  					PORT_SetBits(LEDPORT, ledPin[i]); else  PORT_ResetBits(LEDPORT, ledPin[i]); break;
		case LedModeOn				: if(0)  					PORT_SetBits(LEDPORT, ledPin[i]); else  PORT_ResetBits(LEDPORT, ledPin[i]); break;
		case LedModeToogle			: if((getMillis()/1000)%2)  PORT_SetBits(LEDPORT, ledPin[i]); else  PORT_ResetBits(LEDPORT, ledPin[i]); break;
		case LedModeFastToogle		: if((getMillis()/200)%2)  	PORT_SetBits(LEDPORT, ledPin[i]); else  PORT_ResetBits(LEDPORT, ledPin[i]); break;
		case LedModeActiveEnergy	: if(!active)  				PORT_SetBits(LEDPORT, ledPin[i]); else  PORT_ResetBits(LEDPORT, ledPin[i]); break;
		case LedModeReactiveEnergy	: if(!reactive)  			PORT_SetBits(LEDPORT, ledPin[i]); else  PORT_ResetBits(LEDPORT, ledPin[i]); break;
		}
	}
}

void drv_led_initTimer(void)
{
	RST_CLK_PCLKCmd(RST_CLK_PCLK_TIMER2, ENABLE);
	RST_CLK_PER1_C2_Cmd(RST_CLK_PER1_C2_TIM2,ENABLE);
	RST_CLK_PER1_C2_SetPrescaler(RST_CLK_PER1_C2_TIM2,RST_CLK_PER1_PRESCALER_DIV_2);

	TIMER_CNT_InitTypeDef timerCntInitTypeDef = {0};
	timerCntInitTypeDef.TIMER_CNT_Counter		= 0;
	timerCntInitTypeDef.TIMER_CNT_Prescaler  		= 479;
	timerCntInitTypeDef.TIMER_CNT_Period     	 	= 9999;
	timerCntInitTypeDef.TIMER_CNT_EventSource      	= TIMER_CNT_EVNT_SRC_TIM_CLK;
	timerCntInitTypeDef.TIMER_CNT_Mode		   	= TIMER_CNT_MODE_CLK_FIXED_DIR;
	timerCntInitTypeDef.TIMER_CNT_Direction   	= TIMER_CNT_DIR_UP;
	timerCntInitTypeDef.TIMER_FDTS_Prescaler 	= TIMER_FDTS_PRESCALER_DIV_1;
	timerCntInitTypeDef.TIMER_ETR_Filter 	= TIMER_ETR_FILTER_1FF_AT_FDTS;
	timerCntInitTypeDef.TIMER_ETR_Prescaler  	= TIMER_ETR_PRESCALER_DIV_1;
	timerCntInitTypeDef.TIMER_ETR_Polarity  	= TIMER_ETR_POLARITY_NON_INV;
	timerCntInitTypeDef.TIMER_BRK_Polarity  	= TIMER_BRK_POLARITY_NON_INV;
	TIMER_CNT_Init(MDR_TIMER2,&timerCntInitTypeDef);
	MDR_TIMER2->CNTRL = 0;
	CLIC_SetPriorityIRQ(TIMER2_IRQn,4);
	CLIC_EnableIRQ(TIMER2_IRQn);
	TIMER_ITConfig(MDR_TIMER2,TIMER_FLAG_CNT_ARR,ENABLE);
	TIMER_CNT_Cmd(MDR_TIMER2,ENABLE);
}

void drv_led_initPins(void)
{
	RST_CLK_PCLKCmd(LED_CLK, ENABLE);
	PORT_InitTypeDef PORT_InitStructure;
	PORT_InitStructure.PORT_Direction    = PORT_DIRECTION_OUTPUT;
	PORT_InitStructure.PORT_Function  = PORT_FUNCTION_PORT;
	PORT_InitStructure.PORT_Mode  = PORT_MODE_DIGITAL;
	PORT_InitStructure.PORT_Power = PORT_POWER_INCREASED_UPTO_4mA;
	PORT_InitStructure.PORT_PullDown  = PORT_PULL_DOWN_OFF;
	PORT_InitStructure.PORT_PullUp  = PORT_PULL_UP_OFF;
	PORT_InitStructure.PORT_Pin = (LEDERRORPIN | LEDSTATUSPIN | LEDFIRSTPIN | LEDSECONDPIN);
	PORT_Init(LEDPORT, &PORT_InitStructure);
}

void drv_led_init(void)
{
	drv_led_initPins();
	drv_led_initTimer();
	ledMode[LedError] = LedModeOff;
	ledMode[LedStatus] = LedModeToogle;
	ledMode[LedFirst] = LedModeActiveEnergy;
	ledMode[LedSecond] = LedModeReactiveEnergy;
}

void drv_led_update(void)
{

}

void drv_led_setMode(LedName name, LedMode mode)
{
	ledMode[name] = mode;
}
