

#include "soc_pwm.h"
#include "tkl_gpio.h"
#include "tkl_pwm.h"
#include "tal_memory.h"
#include "light_printf.h"
#include <string.h>


STATIC TUYA_PWM_NUM_E sg_pwm_list[5];

#define ALLOW_CHANNEL_NUM     5

#define MODE_C_NUM            1
#define MODE_CW_NUM           2
#define MODE_RGB_NUM          3
#define MODE_RGBC_NUM         4
#define MODE_RGBCW_NUM        5

#define MIN_FREQUENCY        100
#define MAX_FREQUENCY        20000

#define PORT_PWM3    3      
#define PORT_PWM4    4

STATIC  BOOL_T pwm_mutex_flag = FALSE;
STATIC  UCHAR_T pwm_channel_num = 5;
UCHAR_T gpio_list[5] = {24, 9, 26, 6, 8};
opSocPwmInit(1000, 0, 5, gpio_list, FALSE, TRUE);
/**
 * @brief: SOC pwm初始化
 * @param[in]: frequency -->  PWM的频率, 单位: HZ(范围: 500 ~ 20KHz) 
 * @param[in]: duty --> 占空值(范围: 0 ~ 1000), 占空比 = duty / 1000
 * @param[in]: channel_num --> 输出PWM的通道数
 * @param[in]: gpio_list --> 输出PWM的GPIO口列表
 * @param[in]: cct_flag --> cct模式标志
 * @return: OPERATE_LIGHT 0表示成功，非0请参照tuya error code描述文档 
 */
//OPERATE_LIGHT opSocPwmInit(IN USHORT_T usFrequency, IN USHORT_T usPositiveDutyCycle, IN UCHAR_T ucChannelNum, IN UCHAR_T *pGpioList, IN BOOL_T bCCTFlag, IN BOOL_T bPolarity)
OPERATE_LIGHT opSocPwmInit(IN USHORT_T frequency, IN USHORT_T duty, IN UCHAR_T channel_num, IN UCHAR_T *gpio_list, IN BOOL_T cct_flag,IN BOOL_T bPolarity)
{
    UCHAR_T i = 0;
    OPERATE_LIGHT opRet;
    
    FLOAT_T duty_ratio = 0.0;   //占空比 duty / 1000

    //检查通道数
    if (channel_num > ALLOW_CHANNEL_NUM) {
        PR_ERR("set channel num error!");   
        goto INIT_ERROR;
    }
    //检查频率范围
    if ((frequency < MIN_FREQUENCY) || (frequency > MAX_FREQUENCY)) {    
        PR_ERR("set frequency error!");   
        goto INIT_ERROR;
    }
    pwm_channel_num = channel_num;

    duty_ratio = duty / 1000.0;

    //bk_printf("duty_ratio = %f, cct_flag = %d, channel_num = %d\r\n", duty_ratio, cct_flag, channel_num);
    PR_NOTICE("--->>duty_ratio = %f, cct_flag = %d, channel_num = %d\r\n", duty_ratio, cct_flag, channel_num);
    for (i = 0; i < channel_num; i++) {
        UCHAR_T pwm_index[6] = {6, 7, 8, 9, 24, 26}; 
        UCHAR_T port = channel_num < MODE_RGB_NUM ? MODE_RGB_NUM + i : i;    //固定 pwm0~4 对应 RGBCW 输出端口
        uint8_t j = 0;
        for (j = 0; j < 6; j++) {
            if (pwm_index[j] == gpio_list[i]) {
                PR_NOTICE("port = %d\r\n", port);
                sg_pwm_list[i] = TUYA_PWM_NUM_0 + j;
                break;
            }
        }
        if (j == 6) {
            PR_ERR("set gpio error!");
            continue;
        }
        

        TUYA_PWM_BASE_CFG_T pwm_cfg = {
            .duty = duty * 10, /* 1-10000 */
            .frequency = frequency,
            .polarity  = TUYA_PWM_NEGATIVE,
        };
        opRet = tkl_pwm_init(sg_pwm_list[i], &pwm_cfg);
        if(opRet == LIGHT_OK){
            
            if (port == PORT_PWM4) {
                    opRet = tkl_pwm_multichannel_start(&sg_pwm_list[i - 1], 2);
            } else if (port != PORT_PWM3) {
                opRet = tkl_pwm_start(sg_pwm_list[i]);
            }
            if(opRet != LIGHT_OK){
                PR_ERR("tuya_pwm start error !!!");
            }
        }else{
            PR_ERR("tuya_pwm init error !!!");
        }
        
    } 
#endif

    return OPRT_OK;

INIT_ERROR:
    return OPRT_INVALID_PARM;
}

/**
 * @brief: 设置pwm的占空比
 * @param[in]: channel -> pwm通道
 * @param[in]: duty   -> 占空值(范围: 0 ~ 1000)
 * @attention channel --> according to the initlize order
 * @return: none
 */
VOID vSocPwmSetDuty(IN UCHAR_T channel, IN USHORT_T duty) 
{
    FLOAT_T duty_ratio = 0.0;

    if (sg_pwm_list == NULL) {
        PR_ERR("SOC PWM NOT INIT");
        return;
    }
    duty_ratio = (FLOAT_T)(duty / 1000.0);
    duty_ratio = duty;

    if(pwm_channel_num == 2 && pwm_mutex_flag == TRUE) {
        tkl_pwm_duty_set(sg_pwm_list[channel], duty_ratio * 10);
        tkl_pwm_start(sg_pwm_list[channel]);
        // tkl_pwm_multichannel_start(sg_pwm_list, 2);
    } 
    
    else if (pwm_channel_num == 5 && channel >= 3 && pwm_mutex_flag == TRUE) {
        PR_NOTICE("duty_ratio:%f,sg_pwm_list[%d]:%d",duty_ratio,channel, sg_pwm_list[channel]);
        tkl_pwm_duty_set(sg_pwm_list[channel], duty_ratio * 10);
        tkl_pwm_start(sg_pwm_list[channel]);
        
        // tkl_pwm_multichannel_start(&sg_pwm_list[3], 2);
    } 
    else {
        if(duty_ratio == 0) {
            tkl_pwm_stop(sg_pwm_list[channel]);
        } 
        else {
            tkl_pwm_duty_set(sg_pwm_list[channel], duty_ratio * 10);
            tkl_pwm_start(sg_pwm_list[channel]);
        }

    }
    

    return;
}
