/*******************************************************************************
* File Name: PWM_DACI.c  
* Version 1.10
*
* Description:
*  The PWM User Module consist of an 8 or 16-bit counter with two 8 or 16-bit
*  comparitors.  Each instance of this user module is capable of generating
*  two PWM outputs with the same period.  The pulse width is selectable
*  between 1 and 255/65535.  The period is selectable between 2 and 255/65536 clocks. 
*  The compare value output may be configured to be active when the present 
*  counter is less than or less than/equal to the compare value.
*  A terminal count output is also provided.  It generates a pulse one clock
*  width wide when the counter is equal to zero.
*
* Note:
*
*******************************************************************************
* Copyright 2008-2009, Cypress Semiconductor Corporation.  All rights reserved.
* You may use this file only in accordance with the license, terms, conditions, 
* disclaimers, and limitations in the end user license agreement accompanying 
* the software package with which this file was provided.
********************************************************************************/



#include "cytypes.h"
#include "PWM_DACI.h"

uint8 PWM_DACI_initvar = 0;


/*******************************************************************************
* Function Name: PWM_DACI_Start
********************************************************************************
* Summary:
*  The start function initializes the pwm with the default values, the 
*  enables the counter to begin counting.  It does not enable interrupts,
*  the EnableInt command should be called if interrupt generation is required.
*
* Parameters:  
*  void  
*
* Return: 
*  void
*
*******************************************************************************/
void PWM_DACI_Start(void) 
{
    if(PWM_DACI_initvar == 0)
    {
        #if (PWM_DACI_UsingFixedFunction || PWM_DACI_UseControl)
        uint8 ctrl;
        #endif
        PWM_DACI_initvar = 1;
        
        #if (PWM_DACI_UsingFixedFunction)
            /* Mode Bit of the Configuration Register must be 1 before */
            /* you are allowed to write the compare value (FF only) */
            PWM_DACI_CONTROL |= PWM_DACI_CFG0_MODE;
            #if PWM_DACI_DeadBand2_4
                PWM_DACI_CONTROL |= PWM_DACI_CFG0_DB;
            #endif
            ctrl = PWM_DACI_CONTROL2 & ~PWM_DACI_CTRL_CMPMODE1_MASK;
            PWM_DACI_CONTROL2 = ctrl | PWM_DACI_DEFAULT_COMPARE1_MODE;
        #elif (PWM_DACI_UseControl)
            /* Set the default compare mode defined in the parameter */
            ctrl = PWM_DACI_CONTROL & ~PWM_DACI_CTRL_CMPMODE2_MASK & ~PWM_DACI_CTRL_CMPMODE1_MASK;
            PWM_DACI_CONTROL = ctrl | PWM_DACI_DEFAULT_COMPARE2_MODE | PWM_DACI_DEFAULT_COMPARE1_MODE;
        #endif 
        
        #if (!PWM_DACI_UsingFixedFunction)
            #if (PWM_DACI_Resolution == 8)
                /* Set FIFO 0 to 1 byte register for period*/
               PWM_DACI_AUX_CONTROLDP0 |= (PWM_DACI_AUX_CTRL_FIFO0_CLR);
            #else /* (PWM_DACI_Resolution == 16)*/
               /* Set FIFO 0 to 1 byte register for period */
               PWM_DACI_AUX_CONTROLDP0 |= (PWM_DACI_AUX_CTRL_FIFO0_CLR);
               PWM_DACI_AUX_CONTROLDP1 |= (PWM_DACI_AUX_CTRL_FIFO0_CLR);
            #endif
        #endif
        
        PWM_DACI_WritePeriod(PWM_DACI_INIT_PERIOD_VALUE);
        //PWM_DACI_WriteCounter(PWM_DACI_INIT_PERIOD_VALUE);
        
        #if PWM_DACI_UseOneCompareMode
            PWM_DACI_WriteCompare(PWM_DACI_INIT_COMPARE_VALUE1);
        #else
            PWM_DACI_WriteCompare1(PWM_DACI_INIT_COMPARE_VALUE1);
            PWM_DACI_WriteCompare2(PWM_DACI_INIT_COMPARE_VALUE2);
        #endif
        
        #if PWM_DACI_KillModeMinTime
            PWM_DACI_WriteKillTime(PWM_DACI_MinimumKillTime);
        #endif
        
        #if PWM_DACI_DeadBandUsed
            PWM_DACI_WriteDeadTime( PWM_DACI_INIT_DEAD_TIME );
        #endif

        #if (PWM_DACI_UseStatus || PWM_DACI_UsingFixedFunction)
        PWM_DACI_SetInterruptMode(PWM_DACI_INIT_INTERRUPTS_MODE);
        #endif
        
        #if (PWM_DACI_UsingFixedFunction)
            /* Globally Enable the Fixed Function Block chosen */
            PWM_DACI_GLOBAL_ENABLE |= PWM_DACI_BLOCK_EN_MASK;
            /* Set the Interrupt source to come from the status register */
            PWM_DACI_CONTROL2 |= PWM_DACI_CTRL2_IRQ_SEL;
        #else
            #if(PWM_DACI_UseStatus)
                /* Use the interrupt output of the status register for IRQ output */
                PWM_DACI_STATUS_AUX_CTRL |= PWM_DACI_STATUS_ACTL_INT_EN_MASK;
            #endif
        #endif
    }
    #if (PWM_DACI_UseControl)
        PWM_DACI_CONTROL |= PWM_DACI_CTRL_ENABLE;
    #endif
}


/*******************************************************************************
* Function Name: PWM_DACI_Stop
********************************************************************************
* Summary:
*  The stop function halts the PWM, but does not change any modes or disable
*  interrupts.
*
* Parameters:  
*  void  
*
* Return: 
*  void
*
*******************************************************************************/
void PWM_DACI_Stop(void)
{
    #if (PWM_DACI_UseControl || PWM_DACI_UsingFixedFunction)
        PWM_DACI_CONTROL &= ~PWM_DACI_CTRL_ENABLE;
    #endif
}


#if (PWM_DACI_UseStatus || PWM_DACI_UsingFixedFunction)
/*******************************************************************************
* Function Name: PWM_DACI_SetInterruptMode
********************************************************************************
* Summary:
*  This function is used to set enable the individual interrupt sources.
*
* Parameters:  
*  irqMode:  Enables or disables the interrupt source, compare1, compare2, and 
*            terminal count.  Also, the Less Than or Less Than or equal To 
*            mode may be changed as well with this function. 
*
* Return: 
*  void
*
*******************************************************************************/
void PWM_DACI_SetInterruptMode(uint8 interruptMode)
{
    /* Set the status Registers Mask Register with the bit-field */
    PWM_DACI_STATUS_MASK = interruptMode; 
}


/*******************************************************************************
* Function Name: PWM_DACI_GetInterruptSource
********************************************************************************
* Summary:
*  This function is used to get the source of an interrupt by the ISR routine
*
* Parameters:  
*  void  
*
* Return: 
*  Status Register containing bit-field of interrupt source
*
* Side Effects:  The status register is clear on Read.  This will clear the 
*                interrupt.
*
*******************************************************************************/
uint8 PWM_DACI_GetInterruptSource(void)
{
    return PWM_DACI_STATUS;
}


/*******************************************************************************
* Function Name: PWM_DACI_ReadStatusRegister
********************************************************************************
* Summary:
*  Reads the status register and returns it's state. This function should use
*  defined types for the bit-field information as the bits in this register may
*  be permuteable.
*
* Parameters:  
*  void
*
* Return: 
*  The contents of the status register
*
* Side Effects:
*  Some status register bits are clear on read. 
*******************************************************************************/
uint8   PWM_DACI_ReadStatusRegister(void)
{
    return PWM_DACI_STATUS;
}
#endif /* (PWM_DACI_UseStatus || PWM_DACI_UsingFixedFunction) */


#if (PWM_DACI_UseControl || PWM_DACI_UsingFixedFunction)
/*******************************************************************************
* Function Name: PWM_DACI_ReadControlRegister
********************************************************************************
* Summary:
*  Reads the control register and returns it's state. This function should use
*  defined types for the bit-field information as the bits in this register may
*  be permuteable.
*
* Parameters:  
*  void
*
* Return: 
*  The contents of the control register
*
*******************************************************************************/
uint8   PWM_DACI_ReadControlRegister(void)
{
    return PWM_DACI_CONTROL;
}


/*******************************************************************************
* Function Name: PWM_DACI_WriteControlRegister
********************************************************************************
* Summary:
*  Sets the bit-field of the control register.  This function should use
*  defined types for the bit-field information as the bits in this
*  register may be permuteable.
*
* Parameters:  
*  void
*
* Return: 
*  The contents of the control register
*
*******************************************************************************/
void    PWM_DACI_WriteControlRegister(uint8 control)
{
    PWM_DACI_CONTROL = control;
}
#endif  /* (PWM_DACI_UseControl || PWM_DACI_UsingFixedFunction) */


#if PWM_DACI_UseOneCompareMode
#if PWM_DACI_CompareMode1SW
/*******************************************************************************
* Function Name: PWM_DACI_SetCompareMode
********************************************************************************
* Summary:
*  This function writes the Compare Mode for the pwm output when in Dither mode
*
* Parameters:
*  comparemode:  The new compare mode for the PWM output. Use the compare types
*                defined in the H file as input arguments.
*
* Return:
*  void
*
*******************************************************************************/
void PWM_DACI_SetCompareMode( uint8 comparemode )
{
    #if(PWM_DACI_UsingFixedFunction)
        uint8 comparemodemasked = (comparemode << PWM_DACI_CTRL_CMPMODE1_SHIFT);
        PWM_DACI_CONTROL2 &= ~PWM_DACI_CTRL_CMPMODE1_MASK; /*Clear Existing Data */
        PWM_DACI_CONTROL2 |= comparemodemasked;
        
    #elif (PWM_DACI_UseControl)
        uint8 comparemode1masked = (comparemode << PWM_DACI_CTRL_CMPMODE1_SHIFT) & PWM_DACI_CTRL_CMPMODE1_MASK;
        uint8 comparemode2masked = (comparemode << PWM_DACI_CTRL_CMPMODE2_SHIFT) & PWM_DACI_CTRL_CMPMODE2_MASK;
        PWM_DACI_CONTROL &= ~(PWM_DACI_CTRL_CMPMODE1_MASK | PWM_DACI_CTRL_CMPMODE2_MASK); /*Clear existing mode */
        PWM_DACI_CONTROL |= (comparemode1masked | comparemode2masked);
        
    #else
        uint8 temp = comparemode;
    #endif
}
#endif /* PWM_DACI_CompareMode1SW */

#else /* UseOneCompareMode */

#if PWM_DACI_CompareMode1SW
/*******************************************************************************
* Function Name: PWM_DACI_SetCompareMode1
********************************************************************************
* Summary:
*  This function writes the Compare Mode for the pwm or pwm1 output
*
* Parameters:  
*  comparemode:  The new compare mode for the PWM output. Use the compare types
*                defined in the H file as input arguments.
*
* Return: 
*  void
*
*******************************************************************************/
void PWM_DACI_SetCompareMode1( uint8 comparemode )
{
    uint8 comparemodemasked = (comparemode << PWM_DACI_CTRL_CMPMODE1_SHIFT) & PWM_DACI_CTRL_CMPMODE1_MASK;
    #if(PWM_DACI_UsingFixedFunction)
        PWM_DACI_CONTROL2 &= PWM_DACI_CTRL_CMPMODE1_MASK; /*Clear existing mode */
        PWM_DACI_CONTROL2 |= comparemodemasked; 
    #elif (PWM_DACI_UseControl)
        PWM_DACI_CONTROL &= PWM_DACI_CTRL_CMPMODE1_MASK; /*Clear existing mode */
        PWM_DACI_CONTROL |= comparemodemasked;
    #endif    
}
#endif /* PWM_DACI_CompareMode1SW */

#if PWM_DACI_CompareMode2SW
/*******************************************************************************
* Function Name: PWM_DACI_SetCompareMode2
********************************************************************************
* Summary:
*  This function writes the Compare Mode for the pwm or pwm2 output
*
* Parameters:  
*  comparemode:  The new compare mode for the PWM output. Use the compare types
*                defined in the H file as input arguments.
*
* Return: 
*  void
*
*******************************************************************************/
void PWM_DACI_SetCompareMode2( uint8 comparemode )
{
    #if(PWM_DACI_UsingFixedFunction)
        /* Do Nothing because there is no second Compare Mode Register in FF block*/ 
    #elif (PWM_DACI_UseControl)
    uint8 comparemodemasked = (comparemode << PWM_DACI_CTRL_CMPMODE2_SHIFT) & PWM_DACI_CTRL_CMPMODE2_MASK;
    PWM_DACI_CONTROL &= PWM_DACI_CTRL_CMPMODE2_MASK; /*Clear existing mode */
    PWM_DACI_CONTROL |= comparemodemasked;
    #endif    
}
#endif /*PWM_DACI_CompareMode2SW */
#endif /* UseOneCompareMode */

/*******************************************************************************
* Function Name: PWM_DACI_WriteCounter
********************************************************************************
* Summary:
*  This function is used to change the counter value.
*
* Parameters:  
*  counter:  This value may be between 1 and (2^Resolution)-1.   
*
* Return: 
*  void
*
*******************************************************************************/
void PWM_DACI_WriteCounter(uint16 counter)
{
    #if(PWM_DACI_UsingFixedFunction)
        uint16 counter_temp = (uint16)counter;
        CY_SET_REG16(PWM_DACI_COUNTER_LSB_PTR, counter_temp);
    #else
        CY_SET_REG16(PWM_DACI_COUNTER_LSB_PTR, counter);
    #endif
}


#if (!PWM_DACI_UsingFixedFunction)
/*******************************************************************************
* Function Name: PWM_DACI_ReadCounter
********************************************************************************
* Summary:
*  This function returns the current value of the counter.  It doesn't matter
*  if the counter is enabled or running.
*
* Parameters:  
*  void  
*
* Return: 
*  The current value of the counter.
*
*******************************************************************************/
uint16 PWM_DACI_ReadCounter(void)
{
    CY_GET_REG16(PWM_DACI_COUNTERCAP_LSB_PTR);
    return ( CY_GET_REG16(PWM_DACI_CAPTURE_LSB_PTR) );
}


/*******************************************************************************
* Function Name: PWM_DACI_ReadCapture
********************************************************************************
* Summary:
*  This function returns the last value captured.
*
* Parameters:  
*  void 
*
* Return: 
*  Present Capture value.
*
*******************************************************************************/
uint16 PWM_DACI_ReadCapture( void )
{
   return ( CY_GET_REG16(PWM_DACI_CAPTURE_LSB_PTR) );  
}


#if (PWM_DACI_UseStatus)
/*******************************************************************************
* Function Name: PWM_DACI_ClearFIFO
********************************************************************************
* Summary:
*  This function clears all capture data from the capture FIFO
*
* Parameters:  
*  void
*
* Return: 
*  void
*
*******************************************************************************/
void PWM_DACI_ClearFIFO(void)
{
    while(PWM_DACI_ReadStatusRegister() & PWM_DACI_STATUS_FIFONEMPTY)
        PWM_DACI_ReadCapture();
}
#endif /* PWM_DACI_UseStatus */
#endif /* !PWM_DACI_UsingFixedFunction */


/*******************************************************************************
* Function Name: PWM_DACI_WritePeriod
********************************************************************************
* Summary:
*  This function is used to change the period of the counter.  The new period 
*  will be loaded the next time terminal count is detected.
*
* Parameters:  
*  void  
*
* Return: 
*  Period value. May be between 1 and (2^Resolution)-1.  A value of 0 will result in
*  the counter remaining at zero.
*
*******************************************************************************/
void PWM_DACI_WritePeriod(uint16 period)
{
    #if(PWM_DACI_UsingFixedFunction)
        uint16 period_temp = (uint16)period;
        CY_SET_REG16(PWM_DACI_PERIOD_LSB_PTR, period_temp);
    #else
        CY_SET_REG16(PWM_DACI_PERIOD_LSB_PTR, period);
    #endif
}


/*******************************************************************************
* Function Name: PWM_DACI_ReadPeriod
********************************************************************************
* Summary:
*  This function reads the period without affecting pwm operation.
*
* Parameters:  
*  uint16:  Current Period Value
*
* Return: 
*  (void)
*
*******************************************************************************/
uint16 PWM_DACI_ReadPeriod( void )
{
   return ( CY_GET_REG16(PWM_DACI_PERIOD_LSB_PTR) );
}


#if PWM_DACI_UseOneCompareMode
/*******************************************************************************
* Function Name: PWM_DACI_WriteCompare
********************************************************************************
* Summary:
*  This funtion is used to change the compare1 value when the PWM is in Dither
*  mode.  The compare output will 
*  reflect the new value on the next UDB clock.  The compare output will be 
*  driven high when the present counter value is compared to the compare value
*  based on the compare mode defined in Dither Mode.
*
* Parameters:  
*  compare:  New compare value.  
*
* Return: 
*  void
*
*******************************************************************************/
void PWM_DACI_WriteCompare(uint16 compare)
{
   CY_SET_REG16(PWM_DACI_COMPARE1_LSB_PTR, compare);
   #if (PWM_DACI_PWMMode == PWM_DACI__B_PWM__DITHER)
        CY_SET_REG16(PWM_DACI_COMPARE2_LSB_PTR, compare+1);
   #endif
}


/*******************************************************************************
* Function Name: PWM_DACI_ReadCompare
********************************************************************************
* Summary:
*  This function returns the compare value.
*
* Parameters:  
*  void  
*
* Return: 
*  Current compare value.
*
*******************************************************************************/
uint16 PWM_DACI_ReadCompare( void )
{
  return ( CY_GET_REG16(PWM_DACI_COMPARE1_LSB_PTR) );
}


#else


/*******************************************************************************
* Function Name: PWM_DACI_WriteCompare1
********************************************************************************
* Summary:
*  This funtion is used to change the compare1 value.  The compare output will 
*  reflect the new value on the next UDB clock.  The compare output will be 
*  driven high when the present counter value is less than or less than or 
*  equal to the compare register, depending on the mode.
*
* Parameters:  
*  compare:  New compare value.  
*
* Return: 
*  void
*
*******************************************************************************/
void PWM_DACI_WriteCompare1(uint16 compare)
{
    #if(PWM_DACI_UsingFixedFunction)
        uint16 compare_temp = (uint16)compare;
        CY_SET_REG16(PWM_DACI_COMPARE1_LSB_PTR, compare_temp);
    #else
        CY_SET_REG16(PWM_DACI_COMPARE1_LSB_PTR, compare);
    #endif
}


/*******************************************************************************
* Function Name: PWM_DACI_ReadCompare1
********************************************************************************
* Summary:
*  This function returns the compare1 value.
*
* Parameters:  
*  void  
*
* Return: 
*  Current compare value.
*
*******************************************************************************/
uint16 PWM_DACI_ReadCompare1( void )
{
  return ( CY_GET_REG16(PWM_DACI_COMPARE1_LSB_PTR) );
}


/*******************************************************************************
* Function Name: PWM_DACI_WriteCompare2
********************************************************************************
* Summary:
*  This funtion is used to change the compare value, for compare1 output.  
*  The compare output will reflect the new value on the next UDB clock.  
*  The compare output will be driven high when the present counter value is 
*  less than or less than or equal to the compare register, depending on the 
*  mode.
*
* Parameters:  
*  compare:  New compare value.  
*
* Return: 
*  void
*
*******************************************************************************/
void PWM_DACI_WriteCompare2(uint16 compare)
{
    #if(PWM_DACI_UsingFixedFunction)
       //TODO: This should generate an error because the fixed function block doesn't have a compare 2 register
       uint16 compare_temp = (uint16)compare;
       CY_SET_REG16(PWM_DACI_COMPARE2_LSB_PTR, compare_temp);
    #else
        CY_SET_REG16(PWM_DACI_COMPARE2_LSB_PTR, compare);
    #endif
}


/*******************************************************************************
* Function Name: PWM_DACI_ReadCompare2
********************************************************************************
* Summary:
*  This function returns the compare value, for the second compare output.
*
* Parameters:  
*  void
*
* Return: 
*  Present compare2 value.
*
*******************************************************************************/
uint16 PWM_DACI_ReadCompare2( void )
{
    return ( CY_GET_REG16(PWM_DACI_COMPARE2_LSB_PTR) );
}
#endif /* UseOneCompareMode */


#if (PWM_DACI_DeadBandUsed)
/*******************************************************************************
* Function Name: PWM_DACI_WriteDeadTime
********************************************************************************
* Summary:
*  This function writes the dead-band counts to the corresponding register
*
* Parameters:  
*  deadtime:  Number of counts for dead time 
*
* Return: 
*  void
*
*******************************************************************************/
void PWM_DACI_WriteDeadTime( uint8 deadtime )
{
    /* If using the Dead Band 1-255 mode then just write the register */
    #if(!PWM_DACI_DeadBand2_4)
        CY_SET_REG8(PWM_DACI_DEADBAND_COUNT_PTR, deadtime);
    #else
        /* Otherwise the data has to be masked and offset */
        uint8 deadtimemasked = (deadtime << PWM_DACI_DEADBAND_COUNT_SHIFT) & PWM_DACI_DEADBAND_COUNT_MASK;
        PWM_DACI_DEADBAND_COUNT &= ~PWM_DACI_DEADBAND_COUNT_MASK; /* Clear existing data */
        PWM_DACI_DEADBAND_COUNT |= deadtimemasked; /* Set new dead time */
    #endif
}


/*******************************************************************************
* Function Name: PWM_DACI_ReadDeadTime
********************************************************************************
* Summary:
*  This function reads the dead-band counts from the corresponding register
*
* Parameters:  
*  void
*
* Return: 
*  Dead Band Counts
*
*******************************************************************************/
uint8 PWM_DACI_ReadDeadTime(void)
{
    /* If using the Dead Band 1-255 mode then just read the register */
    #if(!PWM_DACI_DeadBand2_4)
        return ( CY_GET_REG8(PWM_DACI_DEADBAND_COUNT_PTR) );
    #else
        /* Otherwise the data has to be masked and offset */
        return ((PWM_DACI_DEADBAND_COUNT & PWM_DACI_DEADBAND_COUNT_MASK) >> PWM_DACI_DEADBAND_COUNT_SHIFT);
    #endif
}
#endif /* DeadBandUsed */


#if ( PWM_DACI_KillModeMinTime)
/*******************************************************************************
* Function Name: PWM_DACI_WriteKillTime
********************************************************************************
* Summary:
*  This function writes the kill-time counts to the corresponding register
*
* Parameters:
*  killtime:  Number of counts for killtime 
*
* Return: 
*  void
*
*******************************************************************************/
void PWM_DACI_WriteKillTime( uint8 killtime )
{
    /* Not available in Fixed Function mode.  This is taken care of by the 
     * customizer to not allow the user to set Fixed Function and set 
     * the Kill Mode*/
    CY_SET_REG8(PWM_DACI_KILLMODEMINTIME_PTR, killtime);
}


/*******************************************************************************
* Function Name: PWM_DACI_ReadKillTime
********************************************************************************
* Summary:
*  This function reads the Kill-time counts from the corresponding register
*
* Parameters:  
*  void
*
* Return: 
*  Kill Time Counts
*
*******************************************************************************/
uint8 PWM_DACI_ReadKillTime(void)
{
    return ( CY_GET_REG8(PWM_DACI_KILLMODEMINTIME_PTR) );
}
#endif /* KillModeMinTime */


/* [] END OF FILE */
