/*******************************************************************************
* File Name: PWMI.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 "PWMI.h"

uint8 PWMI_initvar = 0;


/*******************************************************************************
* Function Name: PWMI_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 PWMI_Start(void) 
{
    if(PWMI_initvar == 0)
    {
        #if (PWMI_UsingFixedFunction || PWMI_UseControl)
        uint8 ctrl;
        #endif
        PWMI_initvar = 1;
        
        #if (PWMI_UsingFixedFunction)
            /* Mode Bit of the Configuration Register must be 1 before */
            /* you are allowed to write the compare value (FF only) */
            PWMI_CONTROL |= PWMI_CFG0_MODE;
            #if PWMI_DeadBand2_4
                PWMI_CONTROL |= PWMI_CFG0_DB;
            #endif
            ctrl = PWMI_CONTROL2 & ~PWMI_CTRL_CMPMODE1_MASK;
            PWMI_CONTROL2 = ctrl | PWMI_DEFAULT_COMPARE1_MODE;
        #elif (PWMI_UseControl)
            /* Set the default compare mode defined in the parameter */
            ctrl = PWMI_CONTROL & ~PWMI_CTRL_CMPMODE2_MASK & ~PWMI_CTRL_CMPMODE1_MASK;
            PWMI_CONTROL = ctrl | PWMI_DEFAULT_COMPARE2_MODE | PWMI_DEFAULT_COMPARE1_MODE;
        #endif 
        
        #if (!PWMI_UsingFixedFunction)
            #if (PWMI_Resolution == 8)
                /* Set FIFO 0 to 1 byte register for period*/
               PWMI_AUX_CONTROLDP0 |= (PWMI_AUX_CTRL_FIFO0_CLR);
            #else /* (PWMI_Resolution == 16)*/
               /* Set FIFO 0 to 1 byte register for period */
               PWMI_AUX_CONTROLDP0 |= (PWMI_AUX_CTRL_FIFO0_CLR);
               PWMI_AUX_CONTROLDP1 |= (PWMI_AUX_CTRL_FIFO0_CLR);
            #endif
        #endif
        
        PWMI_WritePeriod(PWMI_INIT_PERIOD_VALUE);
        //PWMI_WriteCounter(PWMI_INIT_PERIOD_VALUE);
        
        #if PWMI_UseOneCompareMode
            PWMI_WriteCompare(PWMI_INIT_COMPARE_VALUE1);
        #else
            PWMI_WriteCompare1(PWMI_INIT_COMPARE_VALUE1);
            PWMI_WriteCompare2(PWMI_INIT_COMPARE_VALUE2);
        #endif
        
        #if PWMI_KillModeMinTime
            PWMI_WriteKillTime(PWMI_MinimumKillTime);
        #endif
        
        #if PWMI_DeadBandUsed
            PWMI_WriteDeadTime( PWMI_INIT_DEAD_TIME );
        #endif

        #if (PWMI_UseStatus || PWMI_UsingFixedFunction)
        PWMI_SetInterruptMode(PWMI_INIT_INTERRUPTS_MODE);
        #endif
        
        #if (PWMI_UsingFixedFunction)
            /* Globally Enable the Fixed Function Block chosen */
            PWMI_GLOBAL_ENABLE |= PWMI_BLOCK_EN_MASK;
            /* Set the Interrupt source to come from the status register */
            PWMI_CONTROL2 |= PWMI_CTRL2_IRQ_SEL;
        #else
            #if(PWMI_UseStatus)
                /* Use the interrupt output of the status register for IRQ output */
                PWMI_STATUS_AUX_CTRL |= PWMI_STATUS_ACTL_INT_EN_MASK;
            #endif
        #endif
    }
    #if (PWMI_UseControl)
        PWMI_CONTROL |= PWMI_CTRL_ENABLE;
    #endif
}


/*******************************************************************************
* Function Name: PWMI_Stop
********************************************************************************
* Summary:
*  The stop function halts the PWM, but does not change any modes or disable
*  interrupts.
*
* Parameters:  
*  void  
*
* Return: 
*  void
*
*******************************************************************************/
void PWMI_Stop(void)
{
    #if (PWMI_UseControl || PWMI_UsingFixedFunction)
        PWMI_CONTROL &= ~PWMI_CTRL_ENABLE;
    #endif
}


#if (PWMI_UseStatus || PWMI_UsingFixedFunction)
/*******************************************************************************
* Function Name: PWMI_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 PWMI_SetInterruptMode(uint8 interruptMode)
{
    /* Set the status Registers Mask Register with the bit-field */
    PWMI_STATUS_MASK = interruptMode; 
}


/*******************************************************************************
* Function Name: PWMI_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 PWMI_GetInterruptSource(void)
{
    return PWMI_STATUS;
}


/*******************************************************************************
* Function Name: PWMI_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   PWMI_ReadStatusRegister(void)
{
    return PWMI_STATUS;
}
#endif /* (PWMI_UseStatus || PWMI_UsingFixedFunction) */


#if (PWMI_UseControl || PWMI_UsingFixedFunction)
/*******************************************************************************
* Function Name: PWMI_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   PWMI_ReadControlRegister(void)
{
    return PWMI_CONTROL;
}


/*******************************************************************************
* Function Name: PWMI_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    PWMI_WriteControlRegister(uint8 control)
{
    PWMI_CONTROL = control;
}
#endif  /* (PWMI_UseControl || PWMI_UsingFixedFunction) */


#if PWMI_UseOneCompareMode
#if PWMI_CompareMode1SW
/*******************************************************************************
* Function Name: PWMI_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 PWMI_SetCompareMode( uint8 comparemode )
{
    #if(PWMI_UsingFixedFunction)
        uint8 comparemodemasked = (comparemode << PWMI_CTRL_CMPMODE1_SHIFT);
        PWMI_CONTROL2 &= ~PWMI_CTRL_CMPMODE1_MASK; /*Clear Existing Data */
        PWMI_CONTROL2 |= comparemodemasked;
        
    #elif (PWMI_UseControl)
        uint8 comparemode1masked = (comparemode << PWMI_CTRL_CMPMODE1_SHIFT) & PWMI_CTRL_CMPMODE1_MASK;
        uint8 comparemode2masked = (comparemode << PWMI_CTRL_CMPMODE2_SHIFT) & PWMI_CTRL_CMPMODE2_MASK;
        PWMI_CONTROL &= ~(PWMI_CTRL_CMPMODE1_MASK | PWMI_CTRL_CMPMODE2_MASK); /*Clear existing mode */
        PWMI_CONTROL |= (comparemode1masked | comparemode2masked);
        
    #else
        uint8 temp = comparemode;
    #endif
}
#endif /* PWMI_CompareMode1SW */

#else /* UseOneCompareMode */

#if PWMI_CompareMode1SW
/*******************************************************************************
* Function Name: PWMI_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 PWMI_SetCompareMode1( uint8 comparemode )
{
    uint8 comparemodemasked = (comparemode << PWMI_CTRL_CMPMODE1_SHIFT) & PWMI_CTRL_CMPMODE1_MASK;
    #if(PWMI_UsingFixedFunction)
        PWMI_CONTROL2 &= PWMI_CTRL_CMPMODE1_MASK; /*Clear existing mode */
        PWMI_CONTROL2 |= comparemodemasked; 
    #elif (PWMI_UseControl)
        PWMI_CONTROL &= PWMI_CTRL_CMPMODE1_MASK; /*Clear existing mode */
        PWMI_CONTROL |= comparemodemasked;
    #endif    
}
#endif /* PWMI_CompareMode1SW */

#if PWMI_CompareMode2SW
/*******************************************************************************
* Function Name: PWMI_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 PWMI_SetCompareMode2( uint8 comparemode )
{
    #if(PWMI_UsingFixedFunction)
        /* Do Nothing because there is no second Compare Mode Register in FF block*/ 
    #elif (PWMI_UseControl)
    uint8 comparemodemasked = (comparemode << PWMI_CTRL_CMPMODE2_SHIFT) & PWMI_CTRL_CMPMODE2_MASK;
    PWMI_CONTROL &= PWMI_CTRL_CMPMODE2_MASK; /*Clear existing mode */
    PWMI_CONTROL |= comparemodemasked;
    #endif    
}
#endif /*PWMI_CompareMode2SW */
#endif /* UseOneCompareMode */

/*******************************************************************************
* Function Name: PWMI_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 PWMI_WriteCounter(uint8 counter)
{
    #if(PWMI_UsingFixedFunction)
        uint16 counter_temp = (uint16)counter;
        CY_SET_REG16(PWMI_COUNTER_LSB_PTR, counter_temp);
    #else
        CY_SET_REG8(PWMI_COUNTER_LSB_PTR, counter);
    #endif
}


#if (!PWMI_UsingFixedFunction)
/*******************************************************************************
* Function Name: PWMI_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.
*
*******************************************************************************/
uint8 PWMI_ReadCounter(void)
{
    CY_GET_REG8(PWMI_COUNTERCAP_LSB_PTR);
    return ( CY_GET_REG8(PWMI_CAPTURE_LSB_PTR) );
}


/*******************************************************************************
* Function Name: PWMI_ReadCapture
********************************************************************************
* Summary:
*  This function returns the last value captured.
*
* Parameters:  
*  void 
*
* Return: 
*  Present Capture value.
*
*******************************************************************************/
uint8 PWMI_ReadCapture( void )
{
   return ( CY_GET_REG8(PWMI_CAPTURE_LSB_PTR) );  
}


#if (PWMI_UseStatus)
/*******************************************************************************
* Function Name: PWMI_ClearFIFO
********************************************************************************
* Summary:
*  This function clears all capture data from the capture FIFO
*
* Parameters:  
*  void
*
* Return: 
*  void
*
*******************************************************************************/
void PWMI_ClearFIFO(void)
{
    while(PWMI_ReadStatusRegister() & PWMI_STATUS_FIFONEMPTY)
        PWMI_ReadCapture();
}
#endif /* PWMI_UseStatus */
#endif /* !PWMI_UsingFixedFunction */


/*******************************************************************************
* Function Name: PWMI_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 PWMI_WritePeriod(uint8 period)
{
    #if(PWMI_UsingFixedFunction)
        uint16 period_temp = (uint16)period;
        CY_SET_REG16(PWMI_PERIOD_LSB_PTR, period_temp);
    #else
        CY_SET_REG8(PWMI_PERIOD_LSB_PTR, period);
    #endif
}


/*******************************************************************************
* Function Name: PWMI_ReadPeriod
********************************************************************************
* Summary:
*  This function reads the period without affecting pwm operation.
*
* Parameters:  
*  uint8:  Current Period Value
*
* Return: 
*  (void)
*
*******************************************************************************/
uint8 PWMI_ReadPeriod( void )
{
   return ( CY_GET_REG8(PWMI_PERIOD_LSB_PTR) );
}


#if PWMI_UseOneCompareMode
/*******************************************************************************
* Function Name: PWMI_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 PWMI_WriteCompare(uint8 compare)
{
   CY_SET_REG8(PWMI_COMPARE1_LSB_PTR, compare);
   #if (PWMI_PWMMode == PWMI__B_PWM__DITHER)
        CY_SET_REG8(PWMI_COMPARE2_LSB_PTR, compare+1);
   #endif
}


/*******************************************************************************
* Function Name: PWMI_ReadCompare
********************************************************************************
* Summary:
*  This function returns the compare value.
*
* Parameters:  
*  void  
*
* Return: 
*  Current compare value.
*
*******************************************************************************/
uint8 PWMI_ReadCompare( void )
{
  return ( CY_GET_REG8(PWMI_COMPARE1_LSB_PTR) );
}


#else


/*******************************************************************************
* Function Name: PWMI_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 PWMI_WriteCompare1(uint8 compare)
{
    #if(PWMI_UsingFixedFunction)
        uint16 compare_temp = (uint16)compare;
        CY_SET_REG16(PWMI_COMPARE1_LSB_PTR, compare_temp);
    #else
        CY_SET_REG8(PWMI_COMPARE1_LSB_PTR, compare);
    #endif
}


/*******************************************************************************
* Function Name: PWMI_ReadCompare1
********************************************************************************
* Summary:
*  This function returns the compare1 value.
*
* Parameters:  
*  void  
*
* Return: 
*  Current compare value.
*
*******************************************************************************/
uint8 PWMI_ReadCompare1( void )
{
  return ( CY_GET_REG8(PWMI_COMPARE1_LSB_PTR) );
}


/*******************************************************************************
* Function Name: PWMI_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 PWMI_WriteCompare2(uint8 compare)
{
    #if(PWMI_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(PWMI_COMPARE2_LSB_PTR, compare_temp);
    #else
        CY_SET_REG8(PWMI_COMPARE2_LSB_PTR, compare);
    #endif
}


/*******************************************************************************
* Function Name: PWMI_ReadCompare2
********************************************************************************
* Summary:
*  This function returns the compare value, for the second compare output.
*
* Parameters:  
*  void
*
* Return: 
*  Present compare2 value.
*
*******************************************************************************/
uint8 PWMI_ReadCompare2( void )
{
    return ( CY_GET_REG8(PWMI_COMPARE2_LSB_PTR) );
}
#endif /* UseOneCompareMode */


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


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


#if ( PWMI_KillModeMinTime)
/*******************************************************************************
* Function Name: PWMI_WriteKillTime
********************************************************************************
* Summary:
*  This function writes the kill-time counts to the corresponding register
*
* Parameters:
*  killtime:  Number of counts for killtime 
*
* Return: 
*  void
*
*******************************************************************************/
void PWMI_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(PWMI_KILLMODEMINTIME_PTR, killtime);
}


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


/* [] END OF FILE */
