/*
 * Copyright 2020-2024 Yuntu Microelectronics co.,ltd
 * All rights reserved.
 *
 * YUNTU Confidential. This software is owned or controlled by YUNTU and may
 * only be used strictly in accordance with the applicable license terms. By expressly
 * accepting such terms or by downloading, installing, activating and/or otherwise
 * using the software, you are agreeing that you have read, and that you agree to
 * comply with and are bound by, such license terms. If you do not agree to be
 * bound by the applicable license terms, then you may not retain, install,
 * activate or otherwise use the software. The production use license in
 * Section 2.3 is expressly granted for this software.
 */
/*!
 * @file hw_pwm.c
 */


#include "hw_pwm.h"
#include "device_registers.h"
#include "motor_parameters.h"
#include "hw_config.h"

void HW_PwmSetup(void)
{
    /* Reset eTMR */
    IPC->CTRL[IPC_eTMR0_INDEX] |= IPC_CTRL_SWREN_MASK;
    IPC->CTRL[IPC_eTMR0_INDEX] &= ~IPC_CTRL_SWREN_MASK;

    /* Update channel output init value safe value */
    MC_PWM->CHINIT = eTMR_CHINIT_CH0INIT(0x0)         /* phase U high side off */
                    | eTMR_CHINIT_CH1INIT(0x1)       /* phase U low side on */
                    | eTMR_CHINIT_CH4INIT(0x0)       /* phase V high side off */
                    | eTMR_CHINIT_CH5INIT(0x1)       /* phase V low side on */
                    | eTMR_CHINIT_CH6INIT(0x0)       /* phase W high side off */
                    | eTMR_CHINIT_CH7INIT(0x1);      /* phase W low side on */
    /* PWM init */
    MC_PWM->MOD = PWM_PERIOD_TICK;
    
    /* PWM channel sync load */
    MC_PWM->SYNC |= eTMR_SYNC_REGLD(0x01U) | eTMR_SYNC_MASKLD(0x01);

    /* Enable channel reload */
    MC_PWM->CH[1].CTRL = eTMR_CH_CTRL_CHMODE(0x2U) | eTMR_CH_CTRL_LDEN_MASK;

    /* First default sample point is 7/16 */
    MC_PWM->CH[1].VAL0 = 1;
    MC_PWM->CH[1].VAL1 = 7000;
    /* By default enable trigger output */
    MC_PWM->CH[1].CTRL |= eTMR_CH_CTRL_VAL0TEN_MASK;

    /* PWM output 50% duty waveform */
    MC_PWM->CH[PWM_CHANNEL_U_PHASE].VAL0 = (PWM_HALF_PERIOD_TICK) - (PWM_HALF_PERIOD_TICK>>1);
    MC_PWM->CH[PWM_CHANNEL_U_PHASE].VAL1 = (PWM_HALF_PERIOD_TICK) + (PWM_HALF_PERIOD_TICK>>1);
    MC_PWM->CH[PWM_CHANNEL_V_PHASE].VAL0 = (PWM_HALF_PERIOD_TICK) - (PWM_HALF_PERIOD_TICK>>1);
    MC_PWM->CH[PWM_CHANNEL_V_PHASE].VAL1 = (PWM_HALF_PERIOD_TICK) + (PWM_HALF_PERIOD_TICK>>1);
    MC_PWM->CH[PWM_CHANNEL_W_PHASE].VAL0 = (PWM_HALF_PERIOD_TICK) - (PWM_HALF_PERIOD_TICK>>1);
    MC_PWM->CH[PWM_CHANNEL_W_PHASE].VAL1 = (PWM_HALF_PERIOD_TICK) + (PWM_HALF_PERIOD_TICK>>1);

    /* PWM deadtime */
    MC_PWM->DT = PWM_DEAD_TIME_WIDTH_TICK << eTMR_DT_DTEVEN_SHIFT |
                 PWM_DEAD_TIME_WIDTH_TICK << eTMR_DT_DTODD_SHIFT;


    /* PWM channel in PWM mode with reload enable */
    MC_PWM->CH[PWM_CHANNEL_U_PHASE].CTRL = eTMR_CH_CTRL_CHMODE(0x1U) | eTMR_CH_CTRL_LDEN_MASK;
    MC_PWM->CH[PWM_CHANNEL_V_PHASE].CTRL = eTMR_CH_CTRL_CHMODE(0x1U) | eTMR_CH_CTRL_LDEN_MASK;
    MC_PWM->CH[PWM_CHANNEL_W_PHASE].CTRL = eTMR_CH_CTRL_CHMODE(0x1U) | eTMR_CH_CTRL_LDEN_MASK;
    /* PWM CH0-CH1 CH2-CH3 CH4-CH5 complementary mode */
    MC_PWM->CTRL |= eTMR_CTRL_COMPL01_MASK | eTMR_CTRL_COMPL45_MASK | eTMR_CTRL_COMPL67_MASK;

    /* Set all duty to 0%, high side off, low side on */
    MC_PWM->CHMASK = eTMR_CHMASK_CH1MV(1) | eTMR_CHMASK_CH5MV(1) | eTMR_CHMASK_CH7MV(1) |
                     eTMR_CHMASK_CH0M(1) | eTMR_CHMASK_CH1M(1) |
                     eTMR_CHMASK_CH4M(1) | eTMR_CHMASK_CH5M(1) |
                     eTMR_CHMASK_CH6M(1) | eTMR_CHMASK_CH7M(1);

    MC_PWM->CTRL |= eTMR_CTRL_EN_MASK;
}

void HW_PwmStart(uint16_t duty)
{
    MC_PWM->SYNC |= eTMR_SYNC_CLDOK_MASK;
    MC_PWM->CHMASK = eTMR_CHMASK_CH1MV(1) | eTMR_CHMASK_CH5MV(1) | eTMR_CHMASK_CH7MV(1) |
                     eTMR_CHMASK_CH0M(0) | eTMR_CHMASK_CH1M(0) |
                     eTMR_CHMASK_CH4M(0) | eTMR_CHMASK_CH5M(0) |
                     eTMR_CHMASK_CH6M(0) | eTMR_CHMASK_CH7M(0);
   
    MC_PWM->CH[0].VAL0 =  PWM_HALF_PERIOD_TICK - (duty>>1);
    MC_PWM->CH[0].VAL1 =  PWM_HALF_PERIOD_TICK + (duty>>1);
    MC_PWM->CH[4].VAL0 =  PWM_HALF_PERIOD_TICK - (duty>>1);
    MC_PWM->CH[4].VAL1 =  PWM_HALF_PERIOD_TICK + (duty>>1);
    MC_PWM->CH[6].VAL0 =  PWM_HALF_PERIOD_TICK - (duty>>1);
    MC_PWM->CH[6].VAL1 =  PWM_HALF_PERIOD_TICK + (duty>>1);

    MC_PWM->SYNC |= eTMR_SYNC_LDOK_MASK;
}

void HW_PwmStop(void)
{
    MC_PWM->SYNC |= eTMR_SYNC_CLDOK_MASK;
    /* Set all duty to 0%, high side off, low side on */
    MC_PWM->CHMASK = eTMR_CHMASK_CH1MV(1) | eTMR_CHMASK_CH5MV(1) | eTMR_CHMASK_CH7MV(1) |
                     eTMR_CHMASK_CH0M(1) | eTMR_CHMASK_CH1M(1) |
                     eTMR_CHMASK_CH4M(1) | eTMR_CHMASK_CH5M(1) |
                     eTMR_CHMASK_CH6M(1) | eTMR_CHMASK_CH7M(1);

    /* Set load ok */
    MC_PWM->SYNC |= eTMR_SYNC_LDOK_MASK;
}

/*******************************************************************************
* EOF
******************************************************************************/
 