/* Copyright Statement:
 *
 * This software/firmware and related documentation ("AutoChips Software") are
 * protected under relevant copyright laws. The information contained herein is
 * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
 * the prior written permission of AutoChips inc. and/or its licensors, any
 * reproduction, modification, use or disclosure of AutoChips Software, and
 * information contained herein, in whole or in part, shall be strictly
 * prohibited.
 *
 * AutoChips Inc. (C) 2023. All rights reserved.
 *
 * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
 * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
 * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
 * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
 * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
 * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
 * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
 * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
 * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
 * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
 * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
 * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
 * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
 * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
 * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
 * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
 * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
 */
/******************************************************************************
 * @version: V1.0.0 demo
 ******************************************************************************/

/*!
 * @file eio_pwm_sample.c
 *
 * @brief This file provides interface for EIO PWM functions.
 */

/* ===============================  Includes  =============================== */
#include "eio_pwm_sample.h"
#include "ac780x_eio_comm.h"
#include "ac780x_eio_hw.h"
#include "ac780x_gpio.h"

/* ===============================   Define   =============================== */
#define EIO_INDEX (0U)

#define EIO_PWM_TIMER_CH0 (0U)
#define EIO_PWM_TIMER_CH1 (1U)
#define EIO_PWM_TIMER_CH2 (2U)
#define EIO_PWM_TIMER_CH3 (3U)

#define EIO_PWM_OUTPUTPIN0 (0U)
#define EIO_PWM_OUTPUTPIN1 (1U)
#define EIO_PWM_OUTPUTPIN2 (2U)
#define EIO_PWM_OUTPUTPIN3 (3U)

#define PWMCH0_PERIOD    (80000U) /*EIO_D0 frequency */
#define PWMCH0_DUTYCYCLE (45U)    /*EIO_D0 duty*/
#define PWMCH1_PERIOD    (100000U) /*EIO_D1 frequency*/
#define PWMCH1_DUTYCYCLE (70U)    /*EIO_D1 duty*/
#define PWMCH2_PERIOD    (150000U) /*EIO_D2 frequency*/
#define PWMCH2_DUTYCYCLE (60U)    /*EIO_D2 duty*/
#define PWMCH3_PERIOD    (200000U) /*EI0_D3 frequency*/
#define PWMCH3_DUTYCYCLE (50U)    /*EIO_D3 duty*/

/* ===============================   Typedef  =============================== */

/* ===============================  Variables =============================== */

/* =========================  Functions declaration  ======================== */

/* =========================  Functions definition  ========================= */

/*!
 * @brief   EIO PWM output configuration
 * @param[in] timer: Number of timer
 * @param[in] period :period of PWM
 * @param[in] dutycycle: dutycycle of PWM
 * @param[in] pin: Number of pin
 * @return  none
 */
void EIO_PWM_Config(uint8_t timer, uint32_t period, uint32_t dutycycle, uint8_t pin)
{
    uint8_t lowerValue  = 0;
    uint8_t upperValue  = 0;
    uint32_t sum        = 0;

    /*Calculate timer comparison values for high and low levels*/
    sum        = g_periphAPBClock / period;
    upperValue = sum * dutycycle / 100;
    lowerValue = sum - upperValue;
    sum        = ((lowerValue - 1) << 8U) | (upperValue - 1); /*The low 8 bits represent the high level cycle comparison value, while the high 8 bits represent the low level cycle comparison value*/

    EIO_SetTimerCompare(EIO, timer, sum);
    EIO_SetTimerConfig(EIO,
                       timer,                             /*Timer channel selection*/
                       EIO_TIMER_START_BIT_DISABLED,      /*Timer start bit disabled*/
                       EIO_TIMER_STOP_BIT_DISABLED,       /*Timer stop bit disabled*/
                       EIO_TIMER_ENABLE_ALWAYS,           /*Timer Always On*/
                       EIO_TIMER_DISABLE_NEVER,           /*Timer never stops*/
                       EIO_TIMER_RESET_NEVER,             /*Timer never reset*/
                       EIO_TIMER_DECREMENT_CLK_SHIFT_TMR, /*The timer decreases on the EIO clock, and the shift clock is equal to the timer output*/
                       EIO_TIMER_INITOUT_ONE);            /*Timer output logic is 1 when enabled*/

    EIO_SetTimerControl(EIO,
                        timer,                       /*Timer channel selection*/
                        4 * timer + 3,               /*Trigger selection, timer N triggered*/
                        EIO_TRIGGER_POLARITY_LOW,    /*Trigger polarity is effective at low level*/
                        EIO_TRIGGER_SOURCE_INTERNAL, /*Trigger source is internal trigger*/
                        pin,                         /*Timer pin selection*/
                        EIO_PIN_POLARITY_HIGH,       /*Timer pin polarity is configured to be active at high level*/
                        EIO_PIN_CONFIG_OUTPUT,       /*Timer pin configured as output*/
                        EIO_TIMER_MODE_8BIT_PWM);    /*Timer mode selection: dual 8-bit counter PWM mode*/
}

/*!
 * @brief   EIO_PWM_Init
 *          EIO PWM mode is initialized, use timer0~timer3 to generate 4 channels pwm
 * 
 *          timer0 :Frequency 80Khz, duty cycle 45%
 *          timer1 :Frequency 100Khz, duty cycle 70%
 *          timer2 :Frequency 150Khz, duty cycle 60%
 *          timer3 :Frequency 200Khz, duty cycle 50%
 * @param   none
 * @return  none
 */
void EIO_PWM_Init(void)
{
    eio_device_state_t EIODeviceState;

    /*GPIO config for EIO*/
    GPIO_SetFunc(GPIOB, GPIO_PIN12, GPIO_FUN5);  /*PB12:EIO_D0 */
    GPIO_SetFunc(GPIOB, GPIO_PIN11, GPIO_FUN5);  /*PB11:EIO_D1 */
    GPIO_SetFunc(GPIOA, GPIO_PIN11, GPIO_FUN4);  /*PA11:EIO_D2 */
    GPIO_SetFunc(GPIOA, GPIO_PIN10, GPIO_FUN4);  /*PA10:EIO_D3 */

    (void)EIO_DRV_DeinitDevice(EIO_INDEX); 
    (void)EIO_DRV_InitDevice(EIO_INDEX, &EIODeviceState);

    EIO_PWM_Config(EIO_PWM_TIMER_CH0, PWMCH0_PERIOD, PWMCH0_DUTYCYCLE, EIO_PWM_OUTPUTPIN0); 
    EIO_PWM_Config(EIO_PWM_TIMER_CH1, PWMCH1_PERIOD, PWMCH1_DUTYCYCLE, EIO_PWM_OUTPUTPIN1); 
    EIO_PWM_Config(EIO_PWM_TIMER_CH2, PWMCH2_PERIOD, PWMCH2_DUTYCYCLE, EIO_PWM_OUTPUTPIN2); 
    EIO_PWM_Config(EIO_PWM_TIMER_CH3, PWMCH3_PERIOD, PWMCH3_DUTYCYCLE, EIO_PWM_OUTPUTPIN3); 
}

/* =================================   EOF  ================================= */
