/*******************************************************************************
* File Name: PRS.c
* Version 1.30
*
* Description:
*  This file provides the source code to the API for the PRS Component
*
* Note:
*  None
*
********************************************************************************
* 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 "PRS.h"

uint8 PRS_firstTime = 0;


/*******************************************************************************
* Function Name: PRS_Start
********************************************************************************
* Summary:
*  Initializes seed and polynomial registers. Computation of PRS
*  starts on rising edge of input clock.
*
* Parameters:
*  void
*
* Return:
*  void
* 
*******************************************************************************/
void PRS_Start(void)
{
    /* Writes seed value and ponynom value provided for customizer */
    if (PRS_firstTime == 0)
    {
        #if (PRS_PRS_SIZE <= 32)
            PRS_WritePolynomial(PRS_DEFAULT_POLYNOM);
            PRS_WriteSeed(PRS_DEFAULT_SEED);
        #else
            PRS_WritePolynomialUpper(PRS_DEFAULT_POLYNOM_UPPER);
            PRS_WritePolynomialLower(PRS_DEFAULT_POLYNOM_LOWER);
            PRS_WriteSeedUpper(PRS_DEFAULT_SEED_UPPER);
            PRS_WriteSeedLower(PRS_DEFAULT_SEED_LOWER);
        #endif
      
        PRS_firstTime = 0x01u;
    }
      
    PRS_CONTROL |= PRS_CTRL_ENABLE;
}


/*******************************************************************************
* Function Name: PRS_Stop
********************************************************************************
* Summary:
*  Stops PRS computation.
*
* Parameters:
*  void
*
* Return:
*  void
* 
*******************************************************************************/
 void PRS_Stop(void)
{
    PRS_CONTROL &= ~PRS_CTRL_ENABLE;
}


#if (PRS_RUN_MODE > 0)
/*******************************************************************************
* FUNCTION NAME: PRS_Step
********************************************************************************
* 
* Summary:
*  Increments the PRS by one when API single step mode is used.
*
* Parameters:
*  void
* 
* Return:
*  void
* 
*******************************************************************************/
void PRS_Step(void)
{
    PRS_CONTROL |= PRS_CTRL_RISING_EDGE;
    
    /* TODO
        need to immplement delay
    */
    
    PRS_CONTROL &= ~ PRS_CTRL_RISING_EDGE;
    
    /* Need two clock pulse because timemultiplexing implemented*/
    #if (PRS_PRS_SIZE > 8)
        PRS_CONTROL |= PRS_CTRL_RISING_EDGE;
    
        /* TODO
            need to immplement delay
        */
    
        PRS_CONTROL &= ~ PRS_CTRL_RISING_EDGE;
    #endif
}

#endif


#if(PRS_PRS_SIZE <= 32) /* 8-32bit - PRS */
/*******************************************************************************
* Function Name: PRS_Read
********************************************************************************
* Summary:
*  Reads PRS value.
*
* Parameters:
*  void
*
* Return:
*  Returns PRS value.
*
*******************************************************************************/
uint8 PRS_Read(void)
{
    uint8 seed;
    
    #if (PRS_PRS_SIZE <= 8)         /* 8bits - PRS */
        /* Read PRS */
        seed = PRS_SEED_A__A0_REG ;
        
    #elif (PRS_PRS_SIZE <= 16)      /* 16bits - PRS */
        /* Read PRS */
        seed = ((uint16) PRS_SEED_A__A1_REG) << 8;
        seed |= PRS_SEED_A__A0_REG;
        
    #elif (PRS_PRS_SIZE <= 24)      /* 24bits - PRS */
        /* Read PRS */
        seed = ((uint32) (PRS_SEED_B__A1_REG)) << 16;
        seed |= ((uint32) (PRS_SEED_B__A0_REG)) << 8;
        seed |= PRS_SEED_A__A0_REG;       
        
    #else   /* 32bits - PRS */
        /* Read PRS */
        seed = ((uint32) PRS_SEED_B__A1_REG) << 24;
        seed |= ((uint32) PRS_SEED_A__A1_REG) << 16;
        seed |= ((uint32) PRS_SEED_B__A0_REG) << 8;
        seed |= PRS_SEED_A__A0_REG;
    #endif
    
    return seed;
}


/*******************************************************************************
* Function Name: PRS_WriteSeed
********************************************************************************
* Summary:
*  Writes seed value.
*
* Parameters:
*  seed:  Seed value.
*
* Return:
*  void
*
*******************************************************************************/
void PRS_WriteSeed(uint8 seed)
{
    #if (PRS_PRS_SIZE <= 8)         /* 8bits - PRS */
        /* Write Seed */
        PRS_SEED_A__A0_REG = seed;
        
    #elif (PRS_PRS_SIZE <= 16)      /* 16bits - PRS */
        /* Write Seed */
        PRS_SEED_A__A1_REG = HI8(seed);
        PRS_SEED_A__A0_REG = LO8(seed);
        
        /* Reset triger */
        PRS_CONTROL |= PRS_CTRL_RESET_DFF;
        PRS_CONTROL &= ~PRS_CTRL_RESET_DFF;
        
    #elif (PRS_PRS_SIZE <= 24)      /* 24bits - PRS */
        /* Write Seed */
        PRS_SEED_B__A1_REG = LO8(HI16(seed));
        PRS_SEED_B__A0_REG = HI8(seed);
        PRS_SEED_A__A0_REG = LO8(seed);
        
        /* Reset triger */
        PRS_CONTROL |= PRS_CTRL_RESET_DFF;
        PRS_CONTROL &= ~PRS_CTRL_RESET_DFF;
        
    #else   /* 32bits - PRS */
        /* Write Seed */ 
        PRS_SEED_B__A1_REG = HI8(HI16(seed));
        PRS_SEED_A__A1_REG = LO8(HI16(seed));
        PRS_SEED_B__A0_REG = HI8(seed);
        PRS_SEED_A__A0_REG = LO8(seed);
        
        /* Reset triger */
        PRS_CONTROL |= PRS_CTRL_RESET_DFF;
        PRS_CONTROL &= ~PRS_CTRL_RESET_DFF;
    #endif
}


/*******************************************************************************
* Function Name: PRS_ReadPolynomial
********************************************************************************
* Summary:
*  Reads PRS polynomial value.
*
* Parameters:
*  void
*
* Return:
*  Returns PRS polynomial value.
*
*******************************************************************************/
uint8 PRS_ReadPolynomial(void)
{
    uint8 polynomial;
    
    #if (PRS_PRS_SIZE <= 8)         /* 8bits - PRS */
        /* Read polynomial */
        polynomial = PRS_POLYNOM_A__D0_REG;
        
    #elif (PRS_PRS_SIZE <= 16)      /* 16bits - PRS */
        /* Read polynomial */
        polynomial = ((uint16) PRS_POLYNOM_A__D1_REG) << 8;
        polynomial |= (PRS_POLYNOM_A__D0_REG);
        
    #elif (PRS_PRS_SIZE <= 24)      /* 24bits - PRS */
        /* Read polynomial */
        polynomial = ((uint32) PRS_POLYNOM_B__D1_REG) << 16;
        polynomial |= ((uint32) PRS_POLYNOM_B__D0_REG) << 8;
        polynomial |= PRS_POLYNOM_A__D0_REG;
        
    #else   /* 32bits - PRS */
        /* Read polynomial */
        polynomial = ((uint32) PRS_POLYNOM_B__D1_REG) << 24;
        polynomial |= ((uint32) PRS_POLYNOM_A__D1_REG) << 16;
        polynomial |= ((uint32) PRS_POLYNOM_B__D0_REG) << 8;
        polynomial |= PRS_POLYNOM_A__D0_REG;        
    #endif
    
    return polynomial;
}


/*******************************************************************************
* Function Name: PRS_WritePolynomial
********************************************************************************
* Summary:
*  Writes PRS polynomial value. 
*
* Parameters:
*  polynomial:  PRS polynomial.
*
* Return:
*  void
*
*******************************************************************************/
void PRS_WritePolynomial(uint8 polynomial)
{
    #if (PRS_PRS_SIZE <= 8)         /* 8bits - PRS */
        /* Write polynomial */
        PRS_POLYNOM_A__D0_REG = polynomial;
        
    #elif (PRS_PRS_SIZE <= 16)      /* 16bits - PRS */
        /* Write polynomial */
        PRS_POLYNOM_A__D1_REG = HI8(polynomial);
        PRS_POLYNOM_A__D0_REG = LO8(polynomial);
        
    #elif (PRS_PRS_SIZE <= 24)      /* 24bits - PRS */
        /* Write polynomial */
        PRS_POLYNOM_B__D1_REG = LO8(HI16(polynomial));
        PRS_POLYNOM_B__D0_REG = HI8(polynomial);
        PRS_POLYNOM_A__D0_REG = LO8(polynomial);
        
    #else   /* 32bits - PRS */
        /* Write polynomial */
        PRS_POLYNOM_B__D1_REG = HI8(HI16(polynomial));
        PRS_POLYNOM_A__D1_REG = LO8(HI16(polynomial));
        PRS_POLYNOM_B__D0_REG = HI8(polynomial);
        PRS_POLYNOM_A__D0_REG = LO8(polynomial);
        
    #endif
}


#else  /* 64bit - PRS */
/*******************************************************************************
*  Function Name: PRS_ReadUpper
********************************************************************************
* Summary:
*  Reads upper half of PRS value. Only generated for 33-64-bit PRS.
*
* Parameters:
*  void
*
* Return:
*  Returns upper half of PRS value.
*
*******************************************************************************/
uint32 PRS_ReadUpper(void)
{
    uint32 seed;
  
    #if (PRS_PRS_SIZE <= 40)            /* 40bits - PRS */
        /* Read PRS Upper */
        seed = PRS_SEED_UPPER_C__A1_REG;
        
    #elif (PRS_PRS_SIZE <= 48)          /* 48bits - PRS */
        /* Read PRS Upper */
        seed = ((uint32) PRS_SEED_UPPER_C__A1_REG) << 8;
        seed |= PRS_SEED_UPPER_B__A1_REG;
        
    #elif (PRS_PRS_SIZE <= 56)          /* 56bits - PRS */
        /* Read PRS Upper */
        seed = ((uint32) PRS_SEED_UPPER_D__A1_REG) << 16;
        seed |= ((uint32) PRS_SEED_UPPER_C__A1_REG) << 8;
        seed |= PRS_SEED_UPPER_B__A1_REG;
        
    #else    /* 64bits - PRS */
        /* Read PRS Upper */
        seed = ((uint32) PRS_SEED_UPPER_D__A1_REG) << 24;
        seed |= ((uint32) PRS_SEED_UPPER_C__A1_REG) << 16;
        seed |= ((uint32) PRS_SEED_UPPER_B__A1_REG) << 8;
        seed |= PRS_SEED_UPPER_A__A1_REG;
    #endif
    
    return seed;
}


/*******************************************************************************
*  Function Name: PRS_ReadLower
********************************************************************************
* Summary:
*  Reads lower half of PRS value. Only generated for 33-64-bit PRS.
*
* Parameters:
*  void
*
* Return:
*  Returns lower half of PRS value.
*
*******************************************************************************/
uint32 PRS_ReadLower(void)
{
    uint32 seed;
    
    #if (PRS_PRS_SIZE <= 40)            /* 40bits - PRS */
        /* Read PRS Lower */
        seed = ((uint32) PRS_SEED_LOWER_B__A1_REG) << 24;
        seed |= ((uint32) PRS_SEED_LOWER_C__A0_REG) << 16;
        seed |= ((uint32) PRS_SEED_LOWER_B__A0_REG) << 8;
        seed |= PRS_SEED_LOWER_A__A0_REG;
        
    #elif (PRS_PRS_SIZE <= 48)          /* 48bits - PRS */
        /* Read PRS Lower */
        seed = ((uint32) PRS_SEED_LOWER_A__A1_REG) << 24;
        seed |= ((uint32) PRS_SEED_LOWER_C__A0_REG) << 16;
        seed |= ((uint32) PRS_SEED_LOWER_B__A0_REG) << 8;
        seed |= PRS_SEED_LOWER_A__A0_REG;
        
    #else    /* 64bits - PRS */
        /* Read PRS Lower */
        seed = ((uint32) PRS_SEED_LOWER_D__A0_REG) << 24;
        seed |= ((uint32) PRS_SEED_LOWER_C__A0_REG) << 16;
        seed |= ((uint32) PRS_SEED_LOWER_B__A0_REG) << 8;
        seed |= PRS_SEED_LOWER_A__A0_REG;
    #endif
    
    return seed;
}


/*******************************************************************************
* Function Name: PRS_WriteSeedUpper
********************************************************************************
* Summary:
*  Writes upper half of seed value. Only generated for 33-64-bit PRS.
*
* Parameters:
*  seed:  Upper half of seed value.
*
* Return:
*  void
*
*******************************************************************************/
void PRS_WriteSeedUpper(uint32 seed)
{
    #if (PRS_PRS_SIZE <= 40)            /* 40bits - PRS */
        /* Write Seed Upper */
        PRS_SEED_UPPER_C__A1_REG = LO8(seed);
        
    #elif (PRS_PRS_SIZE <= 48)          /* 48bits - PRS */
        /* Write Seed Upper */
        PRS_SEED_UPPER_C__A1_REG = HI8(seed);
        PRS_SEED_UPPER_B__A1_REG = LO8(seed);
        
    #elif (PRS_PRS_SIZE <= 56)          /* 56bits - PRS */
        /* Write Seed Upper */
        PRS_SEED_UPPER_D__A1_REG = LO8(HI16(seed));
        PRS_SEED_UPPER_C__A1_REG = HI8(seed);
        PRS_SEED_UPPER_B__A1_REG = HI8(seed);
        
    #else    /* 64bits - PRS */
        /* Write Seed Upper */
        PRS_SEED_UPPER_D__A1_REG = HI8(HI16(seed));
        PRS_SEED_UPPER_C__A1_REG = LO8(HI16(seed));
        PRS_SEED_UPPER_B__A1_REG = HI8(seed);
        PRS_SEED_UPPER_A__A1_REG = LO8(seed);
    #endif
    
    /* Reset triger */
    PRS_CONTROL |= PRS_CTRL_RESET_DFF;
    PRS_CONTROL &= ~PRS_CTRL_RESET_DFF;
}


/*******************************************************************************
* Function Name: PRS_WriteSeedLower
********************************************************************************
* Summary:
*  Writes lower half of seed value. Only generated for 33-64-bit PRS.
*
* Parameters:
*  seed:  Lower half of seed value.
*
* Return:
*  void
*
*******************************************************************************/
void PRS_WriteSeedLower(uint32 seed)
{
    #if (PRS_PRS_SIZE <= 40)            /* 40bits - PRS */
        /* Write Seed Lower */
        PRS_SEED_LOWER_B__A1_REG = HI8(HI16(seed));
        PRS_SEED_LOWER_C__A0_REG = LO8(HI16(seed));
        PRS_SEED_LOWER_B__A0_REG = HI8(seed);
        PRS_SEED_LOWER_A__A0_REG = LO8(seed);
        
    #elif (PRS_PRS_SIZE <= 48)          /* 48bits - PRS */
        /* Write Seed Lower */
        PRS_SEED_LOWER_A__A1_REG = HI8(HI16(seed));
        PRS_SEED_LOWER_C__A0_REG = LO8(HI16(seed));
        PRS_SEED_LOWER_B__A0_REG = HI8(seed);
        PRS_SEED_LOWER_A__A0_REG = LO8(seed);
        
    #else    /* 64bits - PRS */
        /* Write Seed Lower */
        PRS_SEED_LOWER_D__A0_REG = HI8(HI16(seed));
        PRS_SEED_LOWER_C__A0_REG = LO8(HI16(seed));
        PRS_SEED_LOWER_B__A0_REG = HI8(seed);
        PRS_SEED_LOWER_A__A0_REG = LO8(seed);
    #endif
   
    /* Reset triger */
    PRS_CONTROL |= PRS_CTRL_RESET_DFF;
    PRS_CONTROL &= ~PRS_CTRL_RESET_DFF;
}


/*******************************************************************************
* Function Name: PRS_ReadPolynomialUpper
********************************************************************************
* Summary:
*  Reads upper half of PRS polynomial value. Only generated for 33-64-bit PRS.
*
* Parameters:
*  void
*
* Return:
*  Returns upper half of PRS polynomial value.
*
*******************************************************************************/
uint32 PRS_ReadPolynomialUpper(void)
{
    uint32 polynomial;
    
    #if (PRS_PRS_SIZE <= 40)            /* 40bits - PRS */
        /* Read Polynomial Upper */
        polynomial = PRS_POLYNOM_UPPER_C__D1_REG;
        
    #elif (PRS_PRS_SIZE <= 48)          /* 48bits - PRS */
        /* Read Polynomial Upper */
        polynomial = ((uint32) PRS_POLYNOM_UPPER_C__D1_REG) << 8;
        polynomial |= PRS_POLYNOM_UPPER_B__D1_REG;
        
    #elif (PRS_PRS_SIZE <= 56)          /* 56bits - PRS */
        /* Read Polynomial Upper */
        polynomial = ((uint32) PRS_POLYNOM_UPPER_D__D1_REG) << 16;
        polynomial |= ((uint32) PRS_POLYNOM_UPPER_C__D1_REG) << 8;
        polynomial |= PRS_POLYNOM_UPPER_B__D1_REG;
        
    #else    /* 64bits - PRS */
        /* Read Polynomial Upper */
        polynomial = ((uint32) PRS_POLYNOM_UPPER_D__D1_REG) << 24;
        polynomial |= ((uint32) PRS_POLYNOM_UPPER_C__D1_REG) << 16;
        polynomial |= ((uint32) PRS_POLYNOM_UPPER_B__D1_REG) << 8;
        polynomial |= PRS_POLYNOM_UPPER_A__D1_REG;
    #endif
    
    return polynomial;
}


/*******************************************************************************
* Function Name: PRS_ReadPolynomialLower
********************************************************************************
* Summary:
*  Reads lower half of PRS polynomial value. Only generated for 33-64-bit PRS.
*
* Parameters:
*  void
*
* Return:
*  Returns lower half of PRS polynomial value.
*
*******************************************************************************/
uint32 PRS_ReadPolynomialLower(void)
{
    uint32 polynomial;
    
    #if (PRS_PRS_SIZE <= 40)            /* 40bits - PRS */
        /* Read Polynomial Lower */
        polynomial = ( (uint32) PRS_POLYNOM_LOWER_B__D1_REG) << 24;
        polynomial |= ( (uint32) PRS_POLYNOM_LOWER_C__D0_REG) << 16;
        polynomial |= ( (uint32) PRS_POLYNOM_LOWER_B__D0_REG) << 8;
        polynomial |= PRS_POLYNOM_LOWER_A__D0_REG;
        
    #elif (PRS_PRS_SIZE <= 48)          /* 48bits - PRS */
        /* Read Polynomial Lower */
        polynomial = ((uint32) PRS_POLYNOM_LOWER_A__D1_REG) << 24;
        polynomial |= ((uint32) PRS_POLYNOM_LOWER_C__D0_REG) << 16;
        polynomial |= ((uint32) PRS_POLYNOM_LOWER_B__D0_REG) << 8;
        polynomial |= PRS_POLYNOM_LOWER_A__D0_REG;
        
    #else    /* 64bits - PRS */
        /* Read Polynomial Lower */
        polynomial = ((uint32) PRS_POLYNOM_LOWER_D__D0_REG) << 24;
        polynomial |= ((uint32) PRS_POLYNOM_LOWER_C__D0_REG) << 16;
        polynomial |= ((uint32) PRS_POLYNOM_LOWER_B__D0_REG) << 8;
        polynomial |= PRS_POLYNOM_LOWER_A__D0_REG;
    #endif
    
    return polynomial;
}


/*******************************************************************************
* Function Name: PRS_WritePolynomialUpper
********************************************************************************
* Summary:
*  Writes upper half of PRS polynomial value. Only generated for 33-64-bit PRS.
*
* Parameters:
*  polynomial:  Upper half PRS polynomial value.
*
* Return:
*  void
*
*******************************************************************************/
void PRS_WritePolynomialUpper(uint32 polynomial)
{
    #if (PRS_PRS_SIZE <= 40)            /* 40bits - PRS */
        /* Write Polynomial Lower */
        PRS_POLYNOM_UPPER_C__D1_REG = LO8(polynomial);
        
    #elif (PRS_PRS_SIZE <= 48)          /* 48bits - PRS */
        /* Write Polynomial Lower */
        PRS_POLYNOM_UPPER_C__D1_REG = HI8(polynomial);
        PRS_POLYNOM_UPPER_B__D1_REG = LO8(polynomial);
        
    #elif (PRS_PRS_SIZE <= 56)          /* 56bits - PRS */
        /* Write Polynomial Lower */
        PRS_POLYNOM_UPPER_D__D1_REG = LO8(HI16(polynomial));
        PRS_POLYNOM_UPPER_C__D1_REG = HI8(polynomial);
        PRS_POLYNOM_UPPER_B__D1_REG = LO8(polynomial);
        
    #else   /* 64bits - PRS */
        /* Write Polynomial Lower */
        PRS_POLYNOM_UPPER_D__D1_REG = HI8(HI16(polynomial));
        PRS_POLYNOM_UPPER_C__D1_REG = LO8(HI16(polynomial));
        PRS_POLYNOM_UPPER_B__D1_REG = HI8(polynomial);
        PRS_POLYNOM_UPPER_A__D1_REG = LO8(polynomial);
    #endif
}


/*******************************************************************************
* Function Name: PRS_WritePolynomialLower
********************************************************************************
* Summary:
*  Writes lower half of PRS polynomial value. Only generated for 33-64-bit PRS.
*
* Parameters:
*  polynomial:  Lower half of PRS polynomial value.
*
* Return:
*  void
*
*******************************************************************************/
void PRS_WritePolynomialLower(uint32 polynomial)
{
    #if (PRS_PRS_SIZE <= 40)            /* 40bits - PRS */
        /* Write Polynomial Lower */
        PRS_POLYNOM_LOWER_B__D1_REG = HI8(HI16(polynomial));
        PRS_POLYNOM_LOWER_C__D0_REG = LO8(HI16(polynomial));
        PRS_POLYNOM_LOWER_B__D0_REG = HI8(polynomial);
        PRS_POLYNOM_LOWER_A__D0_REG = LO8(polynomial);
        
    #elif (PRS_PRS_SIZE <= 48)          /* 48bits - PRS */
        /* Write Polynomial Lower */
        PRS_POLYNOM_LOWER_A__D1_REG = HI8(HI16(polynomial));
        PRS_POLYNOM_LOWER_C__D0_REG = LO8(HI16(polynomial));
        PRS_POLYNOM_LOWER_B__D0_REG = HI8(polynomial);
        PRS_POLYNOM_LOWER_A__D0_REG = LO8(polynomial);
        
    #else    /* 64bits - PRS */
        /* Write Polynomial Lower */
        PRS_POLYNOM_LOWER_D__D0_REG = HI8(HI16(polynomial));
        PRS_POLYNOM_LOWER_C__D0_REG = LO8(HI16(polynomial));
        PRS_POLYNOM_LOWER_B__D0_REG = HI8(polynomial);
        PRS_POLYNOM_LOWER_A__D0_REG = LO8(polynomial);
    #endif
}

#endif /* PRS_PRS_SIZE */

/* [] END OF FILE */

