/**
 *@file    sr_led.c
 *@brief   LED抽象接口源码
 *@details 提供亮灭、闪烁控制、呼吸灯等具体功能实现
 *@copyright Copyright (c) 2024 lierda. All rights reserved.
 *@author  Lierda-RDC
 *@date    2024-04-01
 *@example ZhaoyangSDK\example\component\led_example.c
 */
#include "sr_config.h"
#include "sr_led.h"
#include "sr_gpio.h"

#ifdef SR_USE_LED

// LED电平设置
#ifndef LED_LVL_SET
#define SR_LED_LEVEL_SET_AC(id,level) SR_HalGpioWrite(ledTable[id].gpioId, !(level ^ ledTable[id].actLvl))
#define SR_LED_LEVEL_SET(id, level)   SR_HalGpioWrite(ledTable[id].gpioId, level)

#else
#define SR_LED_LEVEL_SET_AC(id,level) LED_LVL_SET(id,level)
#define SR_LED_LEVEL_SET(id, level)   LED_LVL_SET(id,level)

#endif


   
// #define SR_LED_NUM (sizeof(ledTable)/sizeof(SR_GPIO_ACT_LVL_T)) // 实际使用的LED总数量

#ifdef SR_LED_TABLE
SR_GPIO_ACT_LVL_T ledTable[] = SR_LED_TABLE; // LED的GPIO的列表
#endif


// LED管理数组：存放每个LED闪烁控制结构体
static SR_LED_MNG_T LED_MNG[SR_LED_NUM];

// LED亮灭控制
int SR_LedSwitch(SR_LED_ID_E id, SR_LED_LVL_E level)
{
	SR_ASSERT(id >= 0 && id < SR_LED_NUM);
	SR_ASSERT(IS_LED_LVL(level));

	LED_MNG[id].blink_count = 0;
	LED_MNG[id].breath_enable = 0;

	if ((SR_LED_ON == level) || (SR_LED_OFF == level)) // 亮或灭
	{
		return SR_LED_LEVEL_SET_AC(id, level);
	}
	else if (SR_LED_TOGGLE == level) // 翻转
	{
		return SR_LED_LEVEL_SET(id, level);
	}
	else
		return SR_INVALID;
}

// LED闪烁控制
int SR_LedBlink(SR_LED_ID_E id, uint8_t blinkCnt, uint16_t onTime, uint16_t offTime, uint16_t delayTime)
{
	SR_ASSERT(id >= 0 && id < SR_LED_NUM);

	LED_MNG[id].breath_enable = 0;

	LED_MNG[id].blink_count = blinkCnt;
	LED_MNG[id].on_time = onTime / 10;
	LED_MNG[id].off_time = offTime / 10;
	LED_MNG[id].delay_time = delayTime / 10;

	return SR_OK;
}

// LED闪烁控制任务，需要每10ms执行一次
void SR_LedBlinkTask(void)
{
	static uint8_t state[SR_LED_NUM] = {0};
	static uint16_t delay[SR_LED_NUM] = {0}; // 每10ms加1
	uint8_t i = 0;

	for (i = 0; i < SR_LED_NUM; i++) // 轮询所有灯
	{
		if (LED_MNG[i].blink_count)
		{
			switch (state[i])
			{
			case 0:
				if (LED_MNG[i].delay_time == 0)
				{
					SR_LED_LEVEL_SET_AC(i, SR_LED_ON); // 亮
					state[i] = 1;
					delay[i] = 0;
				}
				LED_MNG[i].delay_time--;

				break;
			case 1: // 控制亮的时长
				if (delay[i]++ >= LED_MNG[i].on_time)
				{
					SR_LED_LEVEL_SET_AC(i, SR_LED_OFF); // 灭
					delay[i] = 1;
					state[i] = 2;
				}
				break;
			case 2: // 控制灭的时长
				if (delay[i]++ >= LED_MNG[i].off_time)
				{
					if (LED_MNG[i].blink_count != 0xFF)
						LED_MNG[i].blink_count--;

					if (LED_MNG[i].blink_count)
					{
						SR_LED_LEVEL_SET_AC(i, SR_LED_ON); // 亮
						delay[i] = 1;
						state[i] = 1;
					}
					else
					{
						state[i] = delay[i] = 0; // 闪烁结束
					}
				}
				break;
			}
		}
		else
		{
			state[i] = delay[i] = 0;
		}
	}
}
SR_POLL_TASK_EXPORT(SR_LedBlinkTask, 1, SR_PRIORITY_0);

#endif
