Newer
Older
mbed-os / targets / TARGET_Cypress / TARGET_PSOC6 / mtb-pdl-cat1 / drivers / include / cy_lvd.h
@Dustin Crossman Dustin Crossman on 4 Jun 2021 20 KB Fix file modes.
/***************************************************************************//**
* \file cy_lvd.h
* \version 1.40
*
* The header file of the LVD driver.
*
********************************************************************************
* \copyright
* Copyright 2017-2020 Cypress Semiconductor Corporation
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/

/**
* \addtogroup group_lvd
* \{
* The LVD driver provides an API to manage the Low Voltage Detection block.
*
* The functions and other declarations used in this driver are in cy_lvd.h.
* You can include cy_pdl.h to get access to all functions
* and declarations in the PDL.
*
* The LVD block provides a status of currently observed VDDD voltage
* and triggers an interrupt when the observed voltage crosses an adjusted
* threshold.
*
* \section group_lvd_configuration_considerations Configuration Considerations
* To set up an LVD, configure the voltage threshold by the
* \ref Cy_LVD_SetThreshold function, ensure that the LVD block itself and LVD
* interrupt are disabled (by the \ref Cy_LVD_Disable and
* \ref Cy_LVD_ClearInterruptMask functions correspondingly) before changing the
* threshold to prevent propagating a false interrupt.
* Then configure interrupts by the \ref Cy_LVD_SetInterruptConfig function, do
* not forget to initialize an interrupt handler (the interrupt source number
* is srss_interrupt_IRQn).
* Then enable LVD by the \ref Cy_LVD_Enable function, then wait for at least 20us
* to get the circuit stabilized and clear the possible false interrupts by the
* \ref Cy_LVD_ClearInterrupt, and finally the LVD interrupt can be enabled by
* the \ref Cy_LVD_SetInterruptMask function.
*
* For example:
* \snippet lvd/snippet/main.c Cy_LVD_Snippet
*
* Note that the LVD circuit is available only in Low Power and Ultra Low Power
* modes. If an LVD is required in Deep Sleep mode, then the device
* should be configured to periodically wake up from Deep Sleep using a
* Deep Sleep wakeup source. This makes sure a LVD check is performed during
* Low Power or Ultra Low Power modes.
*
* \section group_lvd_more_information More Information
* See the LVD chapter of the device technical reference manual (TRM).
*
* \section group_lvd_changelog Changelog
* <table class="doxtable">
*   <tr><th>Version</th><th>Changes</th><th>Reason of Change</th></tr>
*   <tr>
*     <td>1.40</td>
*     <td>Added new device support.</td>
*     <td>Added new family of devices.</td>
*   </tr>
*   <tr>
*     <td>1.30</td>
*     <td>Fixed/documented MISRA 2012 violations.</td>
*     <td>MISRA 2012 compliance.</td>
*   </tr>
*   <tr>
*     <td>1.20</td>
*     <td>
            Updated the following functions for the PSoC 64 devices:
            \ref Cy_LVD_Enable, \ref Cy_LVD_Disable, \ref Cy_LVD_SetThreshold,
            \ref Cy_LVD_ClearInterrupt, \ref Cy_LVD_SetInterrupt,
            \ref Cy_LVD_SetInterruptMask, \ref Cy_LVD_ClearInterruptMask, and
            \ref Cy_LVD_SetInterruptConfig.
      </td>
*     <td>Added PSoC 64 device support.</td>
*   </tr>
*   <tr>
*     <td rowspan="2">1.10</td>
*     <td>Flattened the organization of the driver source code into the single
*         source directory and the single include directory.
*     </td>
*     <td>Driver library directory-structure simplification.</td>
*   </tr>
*   <tr>
*     <td>Added register access layer. Use register access macros instead
*         of direct register access using dereferenced pointers.</td>
*     <td>Makes register access device-independent, so that the PDL does
*         not need to be recompiled for each supported part number.</td>
*   </tr>
*   <tr>
*     <td>1.0.1</td>
*     <td>Added Low Power Callback section</td>
*     <td>Documentation update and clarification</td>
*   </tr>
*   <tr>
*     <td>1.0</td>
*     <td>Initial Version</td>
*     <td></td>
*   </tr>
* </table>
*
* \defgroup group_lvd_macros Macros
* \defgroup group_lvd_functions Functions
*   \{
*       \defgroup group_lvd_functions_syspm_callback  Low Power Callback
*   \}
* \defgroup group_lvd_enums Enumerated Types
*/


#if !defined(CY_LVD_H)
#define CY_LVD_H

#include "cy_device.h"

#if defined (CY_IP_MXS40SRSS) || defined (CY_IP_MXS40SSRSS)

#include "cy_pra.h"
#include "cy_syspm.h"

#ifdef __cplusplus
extern "C" {
#endif

/** \addtogroup group_lvd_macros
* \{
*/

/** The driver major version */
#define CY_LVD_DRV_VERSION_MAJOR       1

/** The driver minor version */
#define CY_LVD_DRV_VERSION_MINOR       40

/** The LVD driver identifier */
#define CY_LVD_ID                      (CY_PDL_DRV_ID(0x39U))

#if defined (CY_IP_MXS40SRSS)
/**
* \note
* These macros are available for CAT1A devices.
**/

/** Interrupt mask for \ref Cy_LVD_GetInterruptStatus(),
                       \ref Cy_LVD_ClearInterrupt() */
#define CY_LVD_SRSS_INTR_HVLVD1_MASK        (SRSS_SRSS_INTR_HVLVD1_Msk)

/** Interrupt mask for \ref Cy_LVD_SetInterrupt() */
#define CY_LVD_SRSS_INTR_SET_HVLVD1_MASK    (SRSS_SRSS_INTR_SET_HVLVD1_Msk)

/** Interrupt mask for \ref Cy_LVD_GetInterruptMask(),
                       \ref Cy_LVD_SetInterruptMask() and
                       \ref Cy_LVD_ClearInterruptMask() */
#define CY_LVD_SRSS_INTR_MASK_HVLVD1_MASK   (SRSS_SRSS_INTR_MASK_HVLVD1_Msk)

/** Interrupt mask for \ref Cy_LVD_GetInterruptStatusMasked() */
#define CY_LVD_SRSS_INTR_MASKED_HVLVD1_MASK (SRSS_SRSS_INTR_MASKED_HVLVD1_Msk)
#endif

#if defined (CY_IP_MXS40SSRSS)
/**
* \note
* These macros are available for devices having MXS40SSRSS IP.
**/

/** Interrupt mask for \ref Cy_LVD_GetInterruptStatus(),
                       \ref Cy_LVD_ClearInterrupt() */
#define CY_LVD_SRSS_INTR_HVLVD1_MASK        (SRSS_SRSS_AINTR_HVLVD1_Msk)

/** Interrupt mask for \ref Cy_LVD_SetInterrupt() */
#define CY_LVD_SRSS_INTR_SET_HVLVD1_MASK    (SRSS_SRSS_AINTR_SET_HVLVD1_Msk)

/** Interrupt mask for \ref Cy_LVD_GetInterruptMask(),
                       \ref Cy_LVD_SetInterruptMask() and
                       \ref Cy_LVD_ClearInterruptMask() */
#define CY_LVD_SRSS_INTR_MASK_HVLVD1_MASK   (SRSS_SRSS_AINTR_MASK_HVLVD1_Msk)

/** Interrupt mask for \ref Cy_LVD_GetInterruptStatusMasked() */
#define CY_LVD_SRSS_INTR_MASKED_HVLVD1_MASK (SRSS_SRSS_AINTR_MASKED_HVLVD1_Msk)
#endif

/** \} group_lvd_macros */


/** \addtogroup group_lvd_enums
* \{
*/


/**
 * LVD reference voltage select.
 */
typedef enum
{
    CY_LVD_THRESHOLD_1_2_V    = 0x0U, /**<Select LVD reference voltage: 1.2V */
    CY_LVD_THRESHOLD_1_4_V    = 0x1U, /**<Select LVD reference voltage: 1.4V */
    CY_LVD_THRESHOLD_1_6_V    = 0x2U, /**<Select LVD reference voltage: 1.6V */
    CY_LVD_THRESHOLD_1_8_V    = 0x3U, /**<Select LVD reference voltage: 1.8V */
    CY_LVD_THRESHOLD_2_0_V    = 0x4U, /**<Select LVD reference voltage: 2.0V */
    CY_LVD_THRESHOLD_2_1_V    = 0x5U, /**<Select LVD reference voltage: 2.1V */
    CY_LVD_THRESHOLD_2_2_V    = 0x6U, /**<Select LVD reference voltage: 2.2V */
    CY_LVD_THRESHOLD_2_3_V    = 0x7U, /**<Select LVD reference voltage: 2.3V */
    CY_LVD_THRESHOLD_2_4_V    = 0x8U, /**<Select LVD reference voltage: 2.4V */
    CY_LVD_THRESHOLD_2_5_V    = 0x9U, /**<Select LVD reference voltage: 2.5V */
    CY_LVD_THRESHOLD_2_6_V    = 0xAU, /**<Select LVD reference voltage: 2.6V */
    CY_LVD_THRESHOLD_2_7_V    = 0xBU, /**<Select LVD reference voltage: 2.7V */
    CY_LVD_THRESHOLD_2_8_V    = 0xCU, /**<Select LVD reference voltage: 2.8V */
    CY_LVD_THRESHOLD_2_9_V    = 0xDU, /**<Select LVD reference voltage: 2.9V */
    CY_LVD_THRESHOLD_3_0_V    = 0xEU, /**<Select LVD reference voltage: 3.0V */
    CY_LVD_THRESHOLD_3_1_V    = 0xFU  /**<Select LVD reference voltage: 3.1V */
} cy_en_lvd_tripsel_t;

/**
 * LVD interrupt configuration select.
 */
typedef enum
{
    CY_LVD_INTR_DISABLE    = 0x0U,  /**<Select LVD interrupt: disabled */
    CY_LVD_INTR_RISING     = 0x1U,  /**<Select LVD interrupt: rising edge */
    CY_LVD_INTR_FALLING    = 0x2U,  /**<Select LVD interrupt: falling edge */
    CY_LVD_INTR_BOTH       = 0x3U,  /**<Select LVD interrupt: both edges */
} cy_en_lvd_intr_config_t;

/**
 * LVD output status.
 */
typedef enum
{
    CY_LVD_STATUS_BELOW   = 0x0U,  /**<The voltage is below the threshold */
    CY_LVD_STATUS_ABOVE   = 0x1U,  /**<The voltage is above the threshold */
} cy_en_lvd_status_t;

/** \} group_lvd_enums */

/** \cond internal */
/* Macros for conditions used by CY_ASSERT calls */
#define CY_LVD_CHECK_TRIPSEL(threshold)  (((threshold) == CY_LVD_THRESHOLD_1_2_V) || \
                                          ((threshold) == CY_LVD_THRESHOLD_1_4_V) || \
                                          ((threshold) == CY_LVD_THRESHOLD_1_6_V) || \
                                          ((threshold) == CY_LVD_THRESHOLD_1_8_V) || \
                                          ((threshold) == CY_LVD_THRESHOLD_2_0_V) || \
                                          ((threshold) == CY_LVD_THRESHOLD_2_1_V) || \
                                          ((threshold) == CY_LVD_THRESHOLD_2_2_V) || \
                                          ((threshold) == CY_LVD_THRESHOLD_2_3_V) || \
                                          ((threshold) == CY_LVD_THRESHOLD_2_4_V) || \
                                          ((threshold) == CY_LVD_THRESHOLD_2_5_V) || \
                                          ((threshold) == CY_LVD_THRESHOLD_2_6_V) || \
                                          ((threshold) == CY_LVD_THRESHOLD_2_7_V) || \
                                          ((threshold) == CY_LVD_THRESHOLD_2_8_V) || \
                                          ((threshold) == CY_LVD_THRESHOLD_2_9_V) || \
                                          ((threshold) == CY_LVD_THRESHOLD_3_0_V) || \
                                          ((threshold) == CY_LVD_THRESHOLD_3_1_V))

#define CY_LVD_CHECK_INTR_CFG(intrCfg)   (((intrCfg) == CY_LVD_INTR_DISABLE) || \
                                          ((intrCfg) == CY_LVD_INTR_RISING) || \
                                          ((intrCfg) == CY_LVD_INTR_FALLING) || \
                                          ((intrCfg) == CY_LVD_INTR_BOTH))

/* Added for backward Compatibility */
#define CY_LVD_INTR        (SRSS_SRSS_INTR_HVLVD1_Msk)

/** \endcond */

/**
* \addtogroup group_lvd_functions
* \{
*/
__STATIC_INLINE void Cy_LVD_Enable(void);
__STATIC_INLINE void Cy_LVD_Disable(void);
__STATIC_INLINE void Cy_LVD_SetThreshold(cy_en_lvd_tripsel_t threshold);
__STATIC_INLINE cy_en_lvd_status_t Cy_LVD_GetStatus(void);
__STATIC_INLINE uint32_t Cy_LVD_GetInterruptStatus(void);
__STATIC_INLINE void Cy_LVD_ClearInterrupt(void);
__STATIC_INLINE void Cy_LVD_SetInterrupt(void);
__STATIC_INLINE uint32_t Cy_LVD_GetInterruptMask(void);
__STATIC_INLINE void Cy_LVD_SetInterruptMask(void);
__STATIC_INLINE void Cy_LVD_ClearInterruptMask(void);
__STATIC_INLINE uint32_t Cy_LVD_GetInterruptStatusMasked(void);
__STATIC_INLINE void Cy_LVD_SetInterruptConfig(cy_en_lvd_intr_config_t lvdInterruptConfig);
/** \addtogroup group_lvd_functions_syspm_callback
* The driver supports SysPm callback for Deep Sleep transition.
* \{
*/
cy_en_syspm_status_t Cy_LVD_DeepSleepCallback(cy_stc_syspm_callback_params_t * callbackParams, cy_en_syspm_callback_mode_t mode);
/** \} */

/*******************************************************************************
* Function Name: Cy_LVD_Enable
****************************************************************************//**
*
*  Enables the output of the LVD block when the VDDD voltage is
*  at or below the threshold.
*  See the Configuration Considerations section for details.
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_Enable(void)
{
    #if CY_CPU_CORTEX_M4 && defined(CY_DEVICE_SECURE)
        CY_PRA_REG32_CLR_SET(CY_PRA_INDX_SRSS_PWR_LVD_CTL, SRSS_PWR_LVD_CTL_HVLVD1_EN, 1U);
    #else
        SRSS_PWR_LVD_CTL |= SRSS_PWR_LVD_CTL_HVLVD1_EN_Msk;
    #endif
}


/*******************************************************************************
* Function Name: Cy_LVD_Disable
****************************************************************************//**
*
*  Disables the LVD block. A low voltage detection interrupt is disabled.
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_Disable(void)
{
    #if CY_CPU_CORTEX_M4 && defined(CY_DEVICE_SECURE)
        CY_PRA_REG32_CLR_SET(CY_PRA_INDX_SRSS_PWR_LVD_CTL, SRSS_PWR_LVD_CTL_HVLVD1_EN, 0U);
    #else
        SRSS_PWR_LVD_CTL &= (uint32_t) ~SRSS_PWR_LVD_CTL_HVLVD1_EN_Msk;
    #endif
}


/*******************************************************************************
* Function Name: Cy_LVD_SetThreshold
****************************************************************************//**
*
*  Sets a threshold for monitoring the VDDD voltage.
*  To prevent propagating a false interrupt, before changing the threshold
*  ensure that the LVD block itself and LVD interrupt are disabled by the
*  \ref Cy_LVD_Disable and \ref Cy_LVD_ClearInterruptMask functions
*  correspondingly.
*
*  \param threshold
*  Threshold selection for Low Voltage Detect circuit, \ref cy_en_lvd_tripsel_t.
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_SetThreshold(cy_en_lvd_tripsel_t threshold)
{
    CY_ASSERT_L3(CY_LVD_CHECK_TRIPSEL(threshold));

    #if CY_CPU_CORTEX_M4 && defined (CY_DEVICE_SECURE)
        CY_PRA_REG32_CLR_SET(CY_PRA_INDX_SRSS_PWR_LVD_CTL, SRSS_PWR_LVD_CTL_HVLVD1_TRIPSEL, threshold);
    #else
        SRSS_PWR_LVD_CTL = _CLR_SET_FLD32U(SRSS_PWR_LVD_CTL, SRSS_PWR_LVD_CTL_HVLVD1_TRIPSEL, threshold);
    #endif
}


/*******************************************************************************
* Function Name: Cy_LVD_GetStatus
****************************************************************************//**
*
*  Returns the status of LVD.
*  SRSS LVD Status Register (PWR_LVD_STATUS).
*
*  \return LVD status, \ref cy_en_lvd_status_t.
*
*******************************************************************************/
__STATIC_INLINE cy_en_lvd_status_t Cy_LVD_GetStatus(void)
{
    CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','SRSS_PWR_LVD_STATUS_HVLVD1_OK_Msk extracts only 1 bit value');
    return ((cy_en_lvd_status_t) _FLD2VAL(SRSS_PWR_LVD_STATUS_HVLVD1_OK, SRSS_PWR_LVD_STATUS));
}


/*******************************************************************************
* Function Name: Cy_LVD_GetInterruptStatus
****************************************************************************//**
*
*  Returns the status of LVD interrupt.
*  SRSS Interrupt Register (SRSS_INTR).
*
*  \return SRSS Interrupt status, \ref CY_LVD_SRSS_INTR_HVLVD1_MASK.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_LVD_GetInterruptStatus(void)
{
    return (SRSS_SRSS_INTR & CY_LVD_SRSS_INTR_HVLVD1_MASK);
}


/*******************************************************************************
* Function Name: Cy_LVD_ClearInterrupt
****************************************************************************//**
*
*  Clears LVD interrupt.
*  SRSS Interrupt Register (SRSS_INTR).
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_ClearInterrupt(void)
{
    #if CY_CPU_CORTEX_M4 && defined(CY_DEVICE_SECURE)
        CY_PRA_REG32_SET(CY_PRA_INDX_SRSS_SRSS_INTR, CY_LVD_SRSS_INTR_HVLVD1_MASK);
    #else
        SRSS_SRSS_INTR = CY_LVD_SRSS_INTR_HVLVD1_MASK;
    #endif

    (void) SRSS_SRSS_INTR;
}


/*******************************************************************************
* Function Name: Cy_LVD_SetInterrupt
****************************************************************************//**
*
*  Triggers the device to generate interrupt for LVD.
*  SRSS Interrupt Set Register (SRSS_INTR_SET).
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_SetInterrupt(void)
{
    #if CY_CPU_CORTEX_M4 && defined(CY_DEVICE_SECURE)
        CY_PRA_REG32_SET(CY_PRA_INDX_SRSS_SRSS_INTR_SET, CY_LVD_SRSS_INTR_SET_HVLVD1_MASK);
    #else
        SRSS_SRSS_INTR_SET = CY_LVD_SRSS_INTR_SET_HVLVD1_MASK;
    #endif
}


/*******************************************************************************
* Function Name:  Cy_LVD_GetInterruptMask
****************************************************************************//**
*
*  Returns the mask value of LVD interrupts.
*  SRSS Interrupt Mask Register (SRSS_INTR_MASK).
*
*  \return SRSS Interrupt Mask value, \ref CY_LVD_SRSS_INTR_HVLVD1_MASK.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_LVD_GetInterruptMask(void)
{
    return (SRSS_SRSS_INTR_MASK & CY_LVD_SRSS_INTR_MASK_HVLVD1_MASK);
}


/*******************************************************************************
* Function Name: Cy_LVD_SetInterruptMask
****************************************************************************//**
*
* Enables LVD interrupts.
* Sets the LVD interrupt mask in the SRSS_INTR_MASK register.
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_SetInterruptMask(void)
{
    #if CY_CPU_CORTEX_M4 && defined(CY_DEVICE_SECURE)
        CY_PRA_REG32_CLR_SET(CY_PRA_INDX_SRSS_SRSS_INTR_MASK, SRSS_SRSS_INTR_MASK_HVLVD1, 1U);
    #else
        SRSS_SRSS_INTR_MASK |= CY_LVD_SRSS_INTR_MASK_HVLVD1_MASK;
    #endif
}


/*******************************************************************************
* Function Name: Cy_LVD_ClearInterruptMask
****************************************************************************//**
*
* Disables LVD interrupts.
* Clears the LVD interrupt mask in the SRSS_INTR_MASK register.
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_ClearInterruptMask(void)
{
    #if CY_CPU_CORTEX_M4 && defined(CY_DEVICE_SECURE)
        CY_PRA_REG32_CLR_SET(CY_PRA_INDX_SRSS_SRSS_INTR_MASK, SRSS_SRSS_INTR_MASK_HVLVD1, 0U);
    #else
        SRSS_SRSS_INTR_MASK &= (uint32_t) ~CY_LVD_SRSS_INTR_MASK_HVLVD1_MASK;
    #endif
}


/*******************************************************************************
* Function Name: Cy_LVD_GetInterruptStatusMasked
****************************************************************************//**
*
*  Returns the masked interrupt status which is a bitwise AND between the
*  interrupt status and interrupt mask registers.
*  SRSS Interrupt Masked Register (SRSS_INTR_MASKED).
*
*  \return SRSS Interrupt Masked value, \ref CY_LVD_SRSS_INTR_MASKED_HVLVD1_MASK.
*
*******************************************************************************/
__STATIC_INLINE uint32_t Cy_LVD_GetInterruptStatusMasked(void)
{
    return (SRSS_SRSS_INTR_MASKED & CY_LVD_SRSS_INTR_MASKED_HVLVD1_MASK);
}


/*******************************************************************************
* Function Name: Cy_LVD_SetInterruptConfig
****************************************************************************//**
*
*  Sets a configuration for LVD interrupt.
*  SRSS Interrupt Configuration Register (SRSS_INTR_CFG).
*
*  \param lvdInterruptConfig \ref cy_en_lvd_intr_config_t.
*
*******************************************************************************/
__STATIC_INLINE void Cy_LVD_SetInterruptConfig(cy_en_lvd_intr_config_t lvdInterruptConfig)
{
    CY_ASSERT_L3(CY_LVD_CHECK_INTR_CFG(lvdInterruptConfig));

#if defined (CY_IP_MXS40SRSS)
    #if CY_CPU_CORTEX_M4 && defined(CY_DEVICE_SECURE)
        CY_PRA_REG32_CLR_SET(CY_PRA_INDX_SRSS_SRSS_INTR_CFG, SRSS_SRSS_INTR_CFG_HVLVD1_EDGE_SEL, lvdInterruptConfig);
    #else
        SRSS_SRSS_INTR_CFG = _CLR_SET_FLD32U(SRSS_SRSS_INTR_CFG, SRSS_SRSS_INTR_CFG_HVLVD1_EDGE_SEL, lvdInterruptConfig);
#endif

#if defined (CY_IP_MXS40SSRSS)
        SRSS_PWR_LVD_CTL = _CLR_SET_FLD32U(SRSS_PWR_LVD_CTL, SRSS_PWR_LVD_CTL_HVLVD1_EDGE_SEL, lvdInterruptConfig);
#endif
    #endif
}

/** \} group_lvd_functions */

#ifdef __cplusplus
}
#endif

#endif /* CY_IP_MXS40SRSS */

#endif /* CY_LVD_H */

/** \} group_lvd */


/* [] END OF FILE */