/**
 * \file    drv_pwm.c
 * \brief   
 * 
 * \par     Copyright (c) 2018 UWE Technologies Corp., Ltd. All Rights Reserved.
 * \author  James
 * \date    2018-03-21
 * \version 
 * 
 * \history 
 *  Date        Note
 *  2018-03-21  Original Creation
 * 
 */

#include "drv_pwm.h"
#include "utils.h"
#include "drv_chip.h"

#define SYS_PWM_CLK     (drv_pwm_sys_clock_get())

static u32_t drv_pwm_sys_clock_get(void)
{
    return ((SYSTEM_SLEEP_CLOCK_FREQ * DRV_REG_FIELD_GET(PLL_CFG_REG,DN)) >> (DRV_REG_FIELD_GET(PLL_CFG_REG,DP))) >> 1;
}

void drv_pwm_en_pair_set(int id1, int id2, bool_t flg)
{
    volatile u32_t reg_val = DRV_REG_GET(PWM_EN_REG);
    SAL_FIELD_SET2(reg_val,id1,1,flg);
    SAL_FIELD_SET2(reg_val,id2,1,flg);
    DRV_REG_SET(PWM_EN_REG,reg_val);
}

void drv_pwm_duty_set(int id, u32_t cmp1, u32_t cmp2)
{
    DRV_REG_SET(PWM0_CFG_REG_1+8*(id), (cmp1 << PWM0_CFG_REG_1_PWM_CMP_1) | cmp2);
}

void drv_pwm_set(int id, bool_t init_high, u16_t per, u16_t cmp1, u16_t cmp2)
{
    if (id >= DRV_PWM_CHN_MAX)
        return;

    DRV_REG_SET(PWM0_CFG_REG_0+8*id, (init_high << PWM0_CFG_REG_0_PWM_INIT_VAL) | per);
    DRV_REG_SET(PWM0_CFG_REG_1+8*id, (cmp1 << PWM0_CFG_REG_1_PWM_CMP_1) | cmp2);
}

void drv_pwm_freq_set(int id, bool_t init_high, u32_t freq, u32_t duty)
{
    if (id >= DRV_PWM_CHN_MAX)
        return;

    // Calculate PER = Fpwm / freq
    if (freq)
    {
        if (freq > drv_chip_freq_get())
            freq = drv_chip_freq_get();
        freq = SYS_PWM_CLK / freq;
    }
    else {
        freq = 0xFFFF;
    }

    if (duty > 100)
        duty = 100;
    
    DRV_REG_SET(PWM0_CFG_REG_0+8*id, (init_high << PWM0_CFG_REG_0_PWM_INIT_VAL) | (freq));
    DRV_REG_SET(PWM0_CFG_REG_1+8*id, ((freq * duty / 100) << PWM0_CFG_REG_1_PWM_CMP_1) | freq);
}

void drv_pwm_duty_set3(int id, u32_t duty)
{
    if (id >= DRV_PWM_CHN_MAX)
        return;

    u32_t freq = PWM0_CFG_REG_0_PWM_PER_FLDSET & DRV_REG_GET(PWM0_CFG_REG_0+8*id);
    DRV_REG_SET(PWM0_CFG_REG_1+8*id, ((freq * duty / 100) << PWM0_CFG_REG_1_PWM_CMP_1) | freq);
}


