/**
 * @file main.c
 * @brief HC32F003 RGBCW 补光固件主函数
 *
 * 功能：
 *   1. 捕获涂鸦/米家模块的 CW（W+C）和 RGB 五路 PWM 信号
 *   2. 算法一：CW→RGBWC 插值，输出补光 5 路值
 *   3. 算法二：RGB 恒功率修正
 *   4. 5 路 PWM 输出驱动 LED 补光
 *   5. UART 命令接口（9600bps）：调试、查看/设置查找表
 *
 * 主循环周期：20ms（50Hz）
 *
 * 中断向量（HC32F003）：
 *   - SysTick_Handler     → pwm_capture.c（1us 计数）
 *   - UART0_IRQHandler    → uart_cmd.c（接收字节入环形缓冲区）
 *   - EXTI0_1_IRQHandler  → pwm_capture.c（P01/P02 边沿）
 *   - EXTI2_3_IRQHandler  → pwm_capture.c（P03 边沿）
 *   - EXTI4_9_IRQHandler  → pwm_capture.c（P14/P15 边沿）
 */

#include <stdint.h>
#include "hc32f003_config.h"
#include "lut.h"
#include "rgb_power.h"
#include "uart_cmd.h"
#include "pwm_capture.h"
#include "pwm_output.h"
#include "flash_store.h"

/* =========================================================
 * 全局运行状态
 * ========================================================= */
static RunMode_t s_run_mode = MODE_AUTO;

/* =========================================================
 * 系统时钟初始化
 * ========================================================= */
static void SystemClock_Init(void)
{
    /*
     * DDL 调用说明：
     *
     * HC32F003 上电默认使用内部高速 RC 振荡器（HIRC）22.12MHz 或 24MHz，
     * 通常无需额外配置。若需要精确时钟，可参考以下：
     *
     * Sysctrl_SetHICRFreq(SysctrlHicrFreq24MHz)  — 设置 HIRC 为 24MHz
     * Sysctrl_ClkSourceEnable(SysctrlClkHICR, TRUE)  — 使能 HIRC
     * Sysctrl_SysClkSwitch(SysctrlClkHICR)            — 切换系统时钟为 HIRC
     *
     * 用户在此处插入 DDL 时钟初始化代码
     */
    (void)0;
}

/* =========================================================
 * 延时函数（基于 SysTick g_us_tick，粗略 ms 延时）
 * ========================================================= */
static void Delay_ms(uint32_t ms)
{
    extern volatile uint32_t g_us_tick;
    uint32_t start = g_us_tick;
    uint32_t target = ms * 1000;
    while ((g_us_tick - start) < target) {
        /* 等待 */
        __asm("NOP");
    }
}

/* =========================================================
 * UART0 中断服务函数（HC32F003 UART0 IRQ 向量）
 * ========================================================= */
void Uart0_IRQHandler(void)
{
    /*
     * HC32F003 向量名称可能为：
     *   UART0_IRQHandler 或 Uart0_IRQHandler（取决于启动文件）
     * 请与 startup_hc32f003.s 中的向量表名称保持一致
     */
    UartCmd_RxIsr();
}

/* =========================================================
 * GPIO 外部中断服务（P01/P02：IN_W / IN_C）
 * ========================================================= */
void Exti01_IRQHandler(void)
{
    /*
     * DDL 调用说明：
     *   uint8_t p01_level = Gpio_GetInputIO(GpioPort0, GpioPin1);
     *   uint8_t p02_level = Gpio_GetInputIO(GpioPort0, GpioPin2);
     *   Exti_ClearFlag(ExtiLine0);  // 清除 P01 中断标志
     *   Exti_ClearFlag(ExtiLine1);  // 清除 P02 中断标志
     */
    extern volatile uint32_t g_us_tick;
    uint32_t ts = g_us_tick;

    extern uint8_t Gpio_GetInputIO_P01(void);  /* 占位：读取 P01 电平 */
    extern uint8_t Gpio_GetInputIO_P02(void);  /* 占位：读取 P02 电平 */

    /* 实际调用 DDL GPIO 读取和 EXTI 清标志 */
    /* PwmCapture_EdgeIsr(0, p01_level, ts);  // IN_W */
    /* PwmCapture_EdgeIsr(1, p02_level, ts);  // IN_C */
    (void)ts;  /* 用户替换上面注释行后删除此行 */
}

/* =========================================================
 * GPIO 外部中断服务（P03：IN_R）
 * ========================================================= */
void Exti23_IRQHandler(void)
{
    extern volatile uint32_t g_us_tick;
    uint32_t ts = g_us_tick;
    /* PwmCapture_EdgeIsr(2, p03_level, ts);  // IN_R */
    (void)ts;
}

/* =========================================================
 * GPIO 外部中断服务（P14/P15：IN_G / IN_B）
 * ========================================================= */
void Exti49_IRQHandler(void)
{
    extern volatile uint32_t g_us_tick;
    uint32_t ts = g_us_tick;
    /* PwmCapture_EdgeIsr(3, p14_level, ts);  // IN_G */
    /* PwmCapture_EdgeIsr(4, p15_level, ts);  // IN_B */
    (void)ts;
}

/* =========================================================
 * main()
 * ========================================================= */
int main(void)
{
    /* 1. 系统时钟初始化 */
    SystemClock_Init();

    /* 2. 外设初始化 */
    PwmCapture_Init();   /* PWM 捕获（GPIO + 外部中断 + SysTick） */
    PwmOutput_Init();    /* PWM 输出（ATIM + BTIM0/1） */
    UartCmd_Init();      /* UART0（9600bps，接收中断） */

    /* 3. 查找表初始化：先尝试从 Flash 加载，失败则用默认值 */
    if (!FlashStore_Load(&g_lut)) {
        LUT_LoadDefault();
        /* Flash 无效或首次烧录，使用内置默认查找表 */
        UartCmd_SendStr("LUT: using default\r\n");
    } else {
        UartCmd_SendStr("LUT: loaded from flash\r\n");
    }

    /* 4. 全局中断使能 */
    __asm("CPSIE I");  /* Cortex-M0+ 使能全局中断 */

    /* 5. 上电提示 */
    UartCmd_SendStr("HC32F003 RGBCW FW v1.0\r\n");

    /* ========== 主循环 ========== */
    while (1) {
        /* --- 串口命令处理（每次循环执行，实时响应命令） --- */
        UartCmd_Process(&s_run_mode);

        /* --- AUTO 模式：20ms 周期处理 --- */
        if (s_run_mode == MODE_AUTO) {

            /* Step 1: 更新 PWM 捕获占空比 */
            PwmCapture_Update();

            /* Step 2: 读取 5 路捕获值 */
            uint8_t inputW = g_cap_w;
            uint8_t inputC = g_cap_c;
            uint8_t inputR = g_cap_r;
            uint8_t inputG = g_cap_g;
            uint8_t inputB = g_cap_b;

            /* Step 3: 算法一 — CW→RGBWC 补光插值 */
            RgbwcOut_t lut_out = {0, 0, 0, 0, 0};
            LUT_CalcCW(inputW, inputC, &lut_out);

            /* Step 4: 算法二 — RGB 恒功率修正（用于透传通道） */
            uint8_t rt, gt, bt;
            RGB_PowerCorrect(inputR, inputG, inputB, &rt, &gt, &bt);
            /*
             * 此固件版本：补光输出优先
             *   OUT_R/G/B = CW 插值得到的 RGB 补光值（lut_out.r/g/b）
             *   OUT_W/C   = CW 插值得到的 WC 补光值（lut_out.w/c）
             *
             * 若需要 RGB 透传恒功率，将 lut_out.r/g/b 替换为 rt/gt/bt
             */
            uint8_t out_r = lut_out.r;
            uint8_t out_g = lut_out.g;
            uint8_t out_b = lut_out.b;
            uint8_t out_w = lut_out.w;
            uint8_t out_c = lut_out.c;

            /* 消除未使用警告（算法二结果供扩展使用） */
            (void)rt; (void)gt; (void)bt;

            /* Step 5: 输出 5 路 PWM */
            PwmOutput_Set(out_r, out_g, out_b, out_w, out_c);

        } else {
            /* --- DEBUG 模式：串口命令直接控制输出 --- */
            if (g_debug_out.updated) {
                g_debug_out.updated = 0;
                PwmOutput_Set(g_debug_out.r, g_debug_out.g, g_debug_out.b,
                              g_debug_out.w, g_debug_out.c);
            }
        }

        /* 主循环延时 20ms */
        Delay_ms(MAIN_LOOP_PERIOD_MS);
    }

    /* 永远不会到达此处 */
    return 0;
}
