#include "drv_light_pwm.h"

#include "drv_config.h"
#include "mem_section.h"
#include <board.h>
#include "bf0_hal_rcc.h"
#include "drivers/rt_drv_pwm.h"

#include <drv_log.h>


#ifdef LIGHT_ENABLE

static struct light_pwm_drv g_light_pwm_drv;

/**
 * @brief 向灯光PWM设备写入占空比
 * 
 * @param[in] drv 灯光PWM驱动实例
 * @param[in] percentage PWM占空比百分比
 * @return rt_err_t 执行结果，RT_EOK表示成功，-RT_ERROR表示失败
 */
static rt_err_t light_pwm_write(struct light_pwm_drv *drv, uint16_t percentage)
{
    struct rt_pwm_configuration cfg;

    rt_memset((void *)&cfg, 0, sizeof(cfg));
    cfg.channel = drv->channel;
    cfg.period = LIGHT_DRV_PWM_PERIOD;
    cfg.pulse = (uint32_t)LIGHT_DRV_PWM_PERIOD * percentage / LIGHT_DRV_PERCENTAGE;

    rt_err_t err = rt_device_control((struct rt_device *)drv->pwm_dev, PWM_CMD_SET, (void *)&cfg);
    if (err != RT_EOK) {
        rt_kprintf("func: %s, PWM_CMD_SET failed with error %d.\r\n", __func__, err);
        return -RT_ERROR;
    }

    err = rt_device_control((struct rt_device *)drv->pwm_dev, PWM_CMD_ENABLE, (void *)&cfg);
    if (err != RT_EOK) {
        rt_kprintf("func: %s, PWM_CMD_ENABLE failed with error %d.\r\n", __func__, err);
        return -RT_ERROR;
    }   

    return RT_EOK;
}

/**
 * @brief 控制灯光PWM设备
 * 
 * @param[in] dev 灯光PWM设备指针
 * @param[in] cmd 控制命令
 * @param[in] arg 控制命令参数
 * @return rt_err_t 执行结果，RT_EOK表示成功，-RT_ERROR表示失败
 */
static rt_err_t light_pwm_control(rt_device_t dev, int cmd, void *arg)
{
    struct light_pwm_drv *drv = (struct light_pwm_drv *)dev->user_data;

    struct light_pwm_config *cfg = (struct light_pwm_config *)arg;
    if (!cfg || cfg->percentage > LIGHT_DRV_PERCENTAGE) {
        rt_kprintf("func: %s, Invalid configuration.\r\n", __func__);
        return -RT_ERROR;
    }

    return light_pwm_write(drv, cfg->percentage);
}

/**
 * @brief 初始化灯光PWM设备
 * 
 * @return int 初始化结果，RT_EOK表示成功，-RT_ERROR表示失败
 */
static int light_pwm_init(void)
{
    struct light_pwm_drv *drv = &g_light_pwm_drv;

    drv->pwm_dev = (struct rt_device_pwm *)rt_device_find(LIGHT_PWM_NAME);
    if (!drv->pwm_dev) {
        rt_kprintf("func: %s, find %s failed.\r\n", __func__, LIGHT_PWM_NAME);
        return -RT_ERROR;
    }

    drv->dev.control = (rt_err_t (*)(rt_device_t, int, void *))light_pwm_control;
    drv->dev.user_data = drv;
    drv->name = LIGHT_DRV_NAME;
    drv->channel = LIGHT_PWM_CH;

    if (rt_device_register(&drv->dev, drv->name, RT_DEVICE_FLAG_RDWR)) {
        rt_kprintf("func: %s, register %s failed.\r\n", __func__, drv->name);
        return -RT_ERROR;
    } else {
        rt_kprintf("func: %s, register %s success.\r\n", __func__, drv->name);
    }

    return RT_EOK;
}

/**
 * @brief 注册灯光PWM设备初始化函数
 */
//INIT_COMPONENT_EXPORT(light_pwm_init);

#endif  /* LIGHT_ENABLE */
