/**********************************************************************
***********************************************************************
**
**         Filename: Utility_Routines.c
**
**           Author: J. Cely
**          Created: 05/10/2018
**
**      Description:
**   This file contains utility routines that are utilized by the
**   Tire Detect System.
**
**
** Revision History:
**
**
***********************************************************************
**********************************************************************/

/*===================================================================*/
/*  I N C L U D E    F I L E S                                       */
/*===================================================================*/
//-- Required --
#include <xdc/std.h>
#include <xdc/cfg/global.h>
#include <xdc/runtime/System.h>
#include <stdio.h>
#include <string.h>

#include <stdint.h>
#include <ti/csl/csl_types.h>
#include <soc_am335x.h>
//#include <ti/csl/hw_types.h>
#include <ti/csl/arch/csl_arch.h>
#include <ti/csl/csl_epwm.h>
#include <hw_cm_per.h>
#include <hw_control_am335x.h>
#include <hw_pwmss.h>

//-- Additional --
/* PWM Include Files */
/*#include <ti/csl/soc.h>
#include <ti/csl/csl_epwm.h>

#include <soc_am335x.h>
#include <hw_pwmss.h>
#include <hw_cm_per.h>
#include <hw_control_am335x.h>
*/

/*#include <ti/starterware/include/hw/hw_types.h>
#include <ti/starterware/include/types.h>
#include <ti/csl/soc.h>
#include <ti/csl/csl_epwm.h>
#include <soc_am335x.h>
#include <hw_pwmss.h>
#include <hw_cm_per.h>
#include <ti/starterware/include/hw/hw_control_am335x.h>
*/
#include "Utility_Routines.h"
#include "TD_hw_types.h"
#include <ti/board/board.h>
#include <ti/board/board_cfg.h>


/*===================================================================*/
/*  D E F I N I T I O N S                                            */
/*===================================================================*/
/*Module clock is the frequency of PWMSS operates*/
#define MODULE_CLK                              (100000000) /* 100MHz */
#define TBCLK_FREQ                              (MODULE_CLK/4)
#define CLEAR_PHASE_REG                         (0x0000U)
#define TB_COUNT_UP                             (0x0)
#define TB_COUNT_UP_DOWN                        (0x2)
#define AQ_NO_ACTION                            (0x0)
#define AQ_FORCE_OUTPUT_HIGH                    (0x2)
#define AQ_FORCE_OUTPUT_LOW                     (0x1)
#define AQ_TOGGLE                               (0x3)
#define PWM_FREQ                                (1250000) /*1.25 MHz */
#define CC_CTR_ZERO                             (0x0)
#define CC_SHADOW                               (0x0)
#define RESET_TB_COUNT_VALUE                    (0x00000000U)
#define OVER_WRITE_SHADOW_DISABLED              (0x0000)
#define TB_IMMEDIATE                            (0x1)
/* PRDLD bit */
//#define TB_IMMEDIATE                            (0x1)

#define APP_EHRPWM_INST_BASE_ADDR       (SOC_PWMSS2_REGS)

/**
 *  \brief Output channel - A or B.
 *
 *  Note: If changed to channel B, pinmux changes needs to be taken care
 *  in the application.
 */
#define APP_EHRPWM_OUTPUT_CH            (CSL_EPWM_OUTPUT_CH_A)

/** \brief Frequency of PWM output signal in Hz - 1 KHz is selected */
#define APP_EHRPWM_OUT_FREQ             (1U * 1000U)

/** \brief Duty Cycle of PWM output signal in % - give value from 0 to 100 */
#define APP_EHRPWM_DUTY_CYCLE           (25U)

/** \brief APP run time in seconds */
#define APP_RUN_TIME                    (10U)

/** \brief APP run count in event equal zero ISR count */
#define APP_RUN_TIME_ISRCOUNT           (APP_RUN_TIME * APP_EHRPWM_OUT_FREQ)

/**
 *  \brief Functional clock to the PWMSS.
 *  Fixed for the platform - can't be changed.
 */
#define SOC_EHRPWM_MODULE_FREQ          (133U * 1000U * 1000U)

/** \brief TB frequency in Hz - so that /4 divider is used */
#define APP_EHRPWM_TB_FREQ              (SOC_EHRPWM_MODULE_FREQ / 4U)

/**
 *  \brief PRD value - this determines the period
 *
 *  PRD = (TBCLK/PWM FREQ) / 2
 *  NOTE: /2 is added becasue up&down counter is selected. So period is 2 times
 */
#define APP_EHRPWM_PRD_VAL              ((APP_EHRPWM_TB_FREQ                   \
                                            / APP_EHRPWM_OUT_FREQ) / 2U)
/**
 *  \brief COMPA value - this determines the duty cycle
 *
 *  COMPA = (PRD - ((dutycycle * PRD) / 100)
 */
#define APP_EHRPWM_COMPA_VAL            (APP_EHRPWM_PRD_VAL -                  \
                                            ((APP_EHRPWM_DUTY_CYCLE *          \
                                                APP_EHRPWM_PRD_VAL) / 100U))

#define APP_EHRPWM_INT                  (32U)
#define APP_EHRPWM_XBAR_CPU             (CSL_XBAR_IRQ_CPU_ID_IPU1)
#define APP_EHRPWM_XBAR_INST            (CSL_XBAR_INST_IPU1_IRQ_32)
#define APP_EHRPWM_XBAR_INTR_SOURCE     (CSL_XBAR_PWMSS1_IRQ_ePWM0INT)

/*===================================================================*/
/*  F U N C T I O N   P R O T O T Y P E S                            */
/*===================================================================*/
void delay(void);


/*===================================================================*/
/*  V A R I A B L E S                                                */
/*===================================================================*/
//See AQCTLA & AQCTLB registers in ePWM section.
//  The structure below represents Bit0 --> 11

/*===================================================================*/
/*  T Y P E   D E C L A R A T I O N S                                */
/*===================================================================*/


/*===================================================================*/
/*  M A C R O S                                                      */
/*===================================================================*/


/*===================================================================*/
/*  M A J O R    R O U T I N E S                                     */
/*===================================================================*/

/***********************************************************************
**
**            Filename: Utility_Routines.c
**        Routine Name: StartSensorRefClk
**                      ConfigPWM2
**                      StopSensorRefClk
**
**              Author: Joe Cely
**             Created: 5/10/2018
**
**        Last Edit By:
**           Last Edit:
**
**  Function Arguments: None
**    Function Returns: TRUE - Operation Successful
**                      FALSE - Operation Failed
**
**         Description:
** The routine in this section are used to configure the Reference Clock
** used by the 8 LDC1101 Sensor Chips.  The Reference Clock is created
** using the PWMSS 2 peripheral.  This signal is configured as an up/down
** counter where EWPM2B is toggle low when the counter counts up and toggled
** high when the counter counts down.
**
** This reference clock has the following configuration:
** Frequency = 1.25MHz
** Duty Cycle = 50%
**
***********************************************************************/
void ConfigPWM2(void)
{
    uint32_t  regVal;
    uint32_t hspClkDiv = (MODULE_CLK/TBCLK_FREQ)/2;
    uint32_t lspClkDivSetting = 0;

    CSL_EpwmAqActionCfg_t aqctrla = {AQ_FORCE_OUTPUT_LOW, AQ_FORCE_OUTPUT_HIGH, AQ_NO_ACTION, AQ_NO_ACTION, AQ_NO_ACTION, AQ_NO_ACTION};


    /* Enable PRCM for PWMSS2 */
    HW_WR_REG32((SOC_CM_PER_REGS + CM_PER_EPWMSS2_CLKCTRL), 0x02);

    /*-- Configure the PinMux and Pin --*/
    // Output the PWM signal on GPMC_AD9
    // conf_gpmc_ad9 Register under the Control Module section of UM
    // Set the Signal Mux select to 4 (ehrpwm2B)
    regVal = HW_RD_REG32(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(9));
    regVal = ((regVal & ~0x07) | 0x04);
    HW_WR_REG32(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(9), regVal);


    // Time base clock for PWMSS2 module
    // pwmss_ctrl Register in Control Module section of UM
    HW_WR_REG32((SOC_CONTROL_REGS + CONTROL_PWMSS_CTRL), 0x04);

    // Configure the Timebase Clock using prescaler
   /* CSL_epwmTbTimebaseClkCfg(SOC_PWMSS2_REGS, TBCLK_FREQ, MODULE_CLK);*/
    regVal = 259;
    regVal = HW_RD_REG16((SOC_PWMSS2_REGS + PWMSS_EPWM_OFFSET) + PWMSS_EPWM_TBCTL);
    HW_SET_FIELD32(regVal, PWMSS_EPWM_TBCTL_CLKDIV, lspClkDivSetting);
    HW_SET_FIELD32(regVal, PWMSS_EPWM_TBCTL_HSPCLKDIV, hspClkDiv);
    HW_WR_REG16(((SOC_PWMSS2_REGS + PWMSS_EPWM_OFFSET) + PWMSS_EPWM_TBCTL),
        (uint16_t)regVal);



    // Clearing phase and direction set to count up
    /*CSL_epwmTbSyncEnable(SOC_PWMSS2_REGS, CLEAR_PHASE_REG, TB_COUNT_UP_DOWN);*/
    HW_WR_FIELD16(((SOC_PWMSS2_REGS + PWMSS_EPWM_OFFSET) + PWMSS_EPWM_TBCTL),
        PWMSS_EPWM_TBCTL_PHSDIR, (uint16_t)TB_COUNT_UP_DOWN);

    /* phase value configuration */
    HW_WR_FIELD16(((SOC_PWMSS2_REGS + PWMSS_EPWM_OFFSET) + PWMSS_EPWM_TBPHS),
       PWMSS_EPWM_TBPHS, (uint16_t)CLEAR_PHASE_REG);

    /* Enable sync: Load time base counter with phase register value. */
    HW_WR_FIELD16(((SOC_PWMSS2_REGS + PWMSS_EPWM_OFFSET) + PWMSS_EPWM_TBCTL),
        PWMSS_EPWM_TBCTL_PHSEN, (uint16_t)PWMSS_EPWM_TBCTL_PHSEN_LOAD);


    // Disabling the Sync
    CSL_epwmTbSyncDisable(SOC_PWMSS2_REGS);

    // Configuring the EPWM_AQCTLA register
    CSL_epwmAqActionOnOutputCfg(SOC_PWMSS2_REGS, CSL_EPWM_OUTPUT_CH_B, &aqctrla);

    /* -- Set the PWM Duty Cycle & Frequency --*/
    // PWM pulse frequency configuration
    CSL_epwmTbPwmFreqCfg(SOC_PWMSS2_REGS, TBCLK_FREQ, PWM_FREQ, TB_COUNT_UP_DOWN,
                                  TB_IMMEDIATE);
    // Resetting the counter
    CSL_epwmTbWriteTbCount(SOC_PWMSS2_REGS, RESET_TB_COUNT_VALUE);


}


Bool StartSensorRefClk(void)
{
    Bool retval = TRUE;
   //CSL_epwmClockEnable(SOC_PWMSS2_REGS);
/*    HW_WR_FIELD32((SOC_PWMSS2_REGS + CSL_PWMSS_CLKCONFIG),
            CSL_PWMSS_CLKCONFIG_EPWMCLK_EN,
            1);
*/

    return retval;
}


Bool StopSensorRefClk(void)
{
    Bool retval = TRUE;
   // CSL_epwmClockDisable(SOC_PWMSS2_REGS);
 /*   HW_WR_FIELD32((SOC_PWMSS2_REGS + CSL_PWMSS_CLKCONFIG),
                CSL_PWMSS_CLKCONFIG_EPWMCLK_EN,
                0);
*/
    return retval;
}




