#include "fan_pwm.h"

void fan_pwm_init(void){
	uint16_t chno = FAN_PWM_CHAN;
    /* -----------------------------------------------------------------------
    TIMER1 configuration: generate 3 PWM signals with 3 different duty cycles:
    TIMER1CLK = SystemCoreClock / 108 = 1MHz

    TIMER1 channel1 duty cycle = (4000/ 16000)* 100  = 25%
    TIMER1 channel2 duty cycle = (8000/ 16000)* 100  = 50%
    TIMER1 channel3 duty cycle = (12000/ 16000)* 100 = 75%
    ----------------------------------------------------------------------- */
    timer_oc_parameter_struct timer_ocintpara;
    timer_parameter_struct timer_initpara;

	rcu_periph_clock_enable(GPIO_FAN_OUT_RCU);
    rcu_periph_clock_enable(RCU_AF);

    /*Configure PA1 PA2 PA3(TIMER1 CH1 CH2 CH3) as alternate function*/
    gpio_init(GPIO_FAN_OUT_GROUP, GPIO_FAN_OUT_MODE, GPIO_OSPEED_50MHZ, GPIO_FAN_OUT_PIN);	
	
    rcu_periph_clock_enable(FAN_TIMER_RCU);

    timer_deinit(FAN_PWM_TIMER);

    /* TIMER1 configuration 1M*/
    timer_initpara.prescaler         = 119;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = FAN_MAX_DUTY_COUNT;
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
    timer_initpara.repetitioncounter = 1;
    timer_init(FAN_PWM_TIMER,&timer_initpara);

    /* CH2 and CH3 configuration in PWM mode1 */
    timer_ocintpara.ocpolarity   = TIMER_OC_POLARITY_HIGH;
    timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
    timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_LOW;
    timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
    timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
    timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_HIGH;

    timer_channel_output_config(FAN_PWM_TIMER,chno,&timer_ocintpara);

    /* CH2 configuration in PWM mode1,duty cycle 46% */
    timer_channel_output_pulse_value_config(FAN_PWM_TIMER,chno,FAN_MAX_DUTY_COUNT-1);
    timer_channel_output_mode_config(FAN_PWM_TIMER,chno,TIMER_OC_MODE_PWM0);
    timer_channel_output_shadow_config(FAN_PWM_TIMER,chno,TIMER_OC_SHADOW_ENABLE);
    /* auto-reload preload enable */
    timer_auto_reload_shadow_enable(FAN_PWM_TIMER);

	timer_enable(FAN_PWM_TIMER);
}


void fan_stop(void) {
	timer_disable(FAN_PWM_TIMER);
}

void fan_set_duty(u8 duty) {
	uint16_t chno = FAN_PWM_CHAN;
	if (duty > 100) {
		duty = 100;
	}else if (duty > 0 && duty < 30) {
		duty = 30;
	}
	u32 count = (float)duty * (float)FAN_MAX_DUTY_COUNT / 100.0f;
	timer_channel_output_pulse_value_config(FAN_PWM_TIMER,chno, count);
	if (count == 0) {
		timer_primary_output_config(FAN_PWM_TIMER,DISABLE);
	}else {
		timer_primary_output_config(FAN_PWM_TIMER,ENABLE);
	}
}


bool fan_pwm_is_running(void) {
	if (TIMER_CCHP(FAN_PWM_TIMER) & (uint32_t)TIMER_CCHP_POEN) {
		return true;
	}
	return false;
}

