/**
 * @file pwm_output.c
 * @brief PWM 输出控制实现
 *
 * PWM 参数：
 *   频率：2kHz（周期 500us）
 *   分辨率：8 位（0-255 映射到定时器比较值）
 *   时钟：24MHz，分频后得到 PWM 时钟
 *
 * 计算：
 *   定时器计数周期 ARR = 255（8 位分辨率）
 *   所需预分频 PSC = 24000000 / (2000 * 256) = 46.875 ≈ 47
 *   实际 PWM 频率 = 24000000 / (47 * 256) ≈ 1.996kHz ≈ 2kHz
 */

#include "pwm_output.h"
#include "hc32f003_config.h"
#include "bt.h"    /* BT 驱动：Bt_ARRSet(en_bt_unit_t, uint16_t) 等函数声明 */
#include "adt.h"   /* ADT 驱动：Adt_SetCompareValue(en_adt_unit_t, en_adt_compare_t, uint16_t) 等 */

/* PWM 预分频值（得到约 2kHz PWM） */
#define PWM_PRESCALER   47
/* PWM 计数器最大值（8 位分辨率，ARR = 255） */
#define PWM_PERIOD      255

/* =========================================================
 * PwmOutput_Init：初始化所有 PWM 输出定时器
 * ========================================================= */
void PwmOutput_Init(void)
{
    /*
     * DDL 调用说明（HC32F003 标准驱动库）：
     *
     * ---- ATIM 初始化（OUT_R/G/B，3路 PWM）----
     *
     * 1. 引脚复用配置：
     *    Gpio_SetFunc(GpioPort2, GpioPin3, GpioFuncAtimCH1, FALSE)  // P23 → ATIM CH1
     *    Gpio_SetFunc(GpioPort2, GpioPin4, GpioFuncAtimCH2, FALSE)  // P24 → ATIM CH2
     *    Gpio_SetFunc(GpioPort2, GpioPin5, GpioFuncAtimCH3, FALSE)  // P25 → ATIM CH3
     *
     * 2. ATIM 基础配置：
     *    stc_atim_mode23_cfg_t atim_base;
     *    atim_base.enWorkMode  = AtimWorkMode3;  // PWM 模式3（标准 PWM）
     *    atim_base.enCntDir    = AtimCntUp;      // 向上计数
     *    atim_base.enPRS       = AtimPRS_Div1;   // 预分频 47（若 DDL 不支持直接写，用寄存器操作）
     *    Adt_Init(AdtTIM4, &atim_base);
     *
     * 3. 设置计数周期（ARR=255）：
     *    Adt_SetPeriod(AdtTIM4, PWM_PERIOD);
     *
     * 4. 三通道 PWM 输出配置（CompareA=CH1, CompareB=CH2）：
     *    stc_adt_compare_t ch_cfg;
     *    Adt_SetCompareValue(AdtTIM4, AdtCompareA, 0);  // 初始占空比 0
     *    Adt_SetCompareValue(AdtTIM4, AdtCompareB, 0);
     *
     * 5. 启动 ADT：
     *    Adt_StartCount(AdtTIM4);
     *
     * ---- BT0 初始化（OUT_B）/ BT1 初始化（OUT_W）----
     *
     * 1. 引脚复用：
     *    Gpio_SetFunc(GpioPort2, GpioPin5, GpioFuncBt0Togp, FALSE)  // P25 → BT0
     *    Gpio_SetFunc(GpioPort2, GpioPin6, GpioFuncBt1Togp, FALSE)  // P26 → BT1
     *
     * 2. BT 配置（用枚举选单元，参数见 bt.h stc_bt_mode0_cfg_t）：
     *    stc_bt_mode0_cfg_t bt_cfg = { BtPCLKDiv1, BtCnt16, BtOneShot, ... };
     *    Bt_Mode0_Init(BtUnit0, &bt_cfg);
     *    Bt_Run(BtUnit0);
     *    Bt_Mode0_Init(BtUnit1, &bt_cfg);
     *    Bt_Run(BtUnit1);
     */

    /* 用户在此处插入 DDL 初始化代码 */
    (void)0;
}

/* =========================================================
 * PwmOutput_Set：设置 5 路 PWM 占空比
 * ========================================================= */
void PwmOutput_Set(uint8_t r, uint8_t g, uint8_t b, uint8_t w, uint8_t c)
{
    /*
     * 占空比映射：
     *   CCR 值 = duty_255（ARR=255，CCR=duty 即为 duty/255 占空比）
     *
     * DDL 调用说明：
     *
     * ATIM 比较值更新（PWM 模式1：CCR > CNT 时输出高）：
     *   Atim_SetCaptureCompare(M0P_TIM3, Atim_CH1, r);  // OUT_R
     *   Atim_SetCaptureCompare(M0P_TIM3, Atim_CH2, g);  // OUT_G
     *   Atim_SetCaptureCompare(M0P_TIM3, Atim_CH3, b);  // OUT_B
     *   （若使用影子寄存器，还需触发更新：Atim_GenerateUEV(M0P_TIM3)）
     *
     * BTIM 比较值更新：
     *   Bt_SetARR(M0P_TIM0, w);   // OUT_W（BTIM0 的 CRR 即 ARR）
     *   Bt_SetARR(M0P_TIM1, c);   // OUT_C（BTIM1）
     *   注：部分 DDL 版本 BTIM PWM 占空比通过 ARR 或 CRR 寄存器控制，
     *       请参考对应 DDL 文档确认接口名称。
     */

    /* ---- ADT：设置 R/G 两路 PWM 比较值 ----
     * Adt_SetCompareValue(en_adt_unit_t enAdtUnit, en_adt_compare_t enAdtCompare, uint16_t u16Compare)
     * enAdtUnit 枚举值请查 adt.h 中 en_adt_unit_t（常见值: AdtTIM3 或 AdtUnit0）
     * Adt_SetCompareValue 由 adt.h 声明 */
    Adt_SetCompareValue(AdTIM4, AdtCompareA, (uint16_t)r);  /* OUT_R — TIM4 CH_A */
    Adt_SetCompareValue(AdTIM4, AdtCompareB, (uint16_t)g);  /* OUT_G — TIM4 CH_B */

    /* ---- BTIM：设置 B/W/C 三路 PWM 比较值 ----
     * DDL 实际函数名（来自 bt.h）：
     *   Bt_ARRSet(M0P_TIM0_TypeDef *pstcBt, uint16_t u16Arr, boolean_t bImme)
     * M0P_TIM0/TIM1 是 CMSIS 宏，由 hc32f003.h 定义，无需 extern 声明 */
    /* Bt_ARRSet(en_bt_unit_t enUnit, uint16_t u16Data) — 用枚举选 BT 单元，无第三参数 */
    Bt_ARRSet(BtUnit0, (uint16_t)b);   /* OUT_B（BT0 复用做蓝光） */
    Bt_ARRSet(BtUnit1, (uint16_t)w);   /* OUT_W（BT1） */
    /* 若需要第5路 OUT_C，可使用 PCA 模块或复用其他定时器 */
    (void)c;
}
