IPC_Server_C28/EFC_IPC_Server_C28/device/driverlib/hrcap.h

618 lines
19 KiB
C

//###########################################################################
//
// FILE: hrcap.h
//
// TITLE: C28x HRCAP Driver.
//
//#############################################################################
// $Copyright:
// Copyright (C) 2022 Texas Instruments Incorporated - http://www.ti.com
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the
// distribution.
//
// Neither the name of Texas Instruments Incorporated nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// $
//#############################################################################
#ifndef HRCAP_H
#define HRCAP_H
//*****************************************************************************
//
// If building with a C++ compiler, make all of the definitions in this header
// have a C binding.
//
//*****************************************************************************
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
//! \addtogroup hrcap_api HRCAP
//! @{
//
//*****************************************************************************
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_hrcap.h"
#include "cpu.h"
#include "debug.h"
//*****************************************************************************
//
// Values that can be passed to HRCAP_enableCalibrationInterrupt(),
// HRCAP_disableCalibrationInterrupt() as the intFlags parameter and
// HRCAP_clearCalibrationFlags() and HRCAP_forceCalibrationFlags() as the flags
// parameter and returned by HRCAP_getCalibrationFlags().
//
//*****************************************************************************
//! Global calibration interrupt flag
//!
#define HRCAP_GLOBAL_CALIBRATION_INTERRUPT 0x1U
//! Calibration done flag
//!
#define HRCAP_CALIBRATION_DONE 0x2U
//! Calibration period overflow flag
//!
#define HRCAP_CALIBRATION_PERIOD_OVERFLOW 0x4U
//*****************************************************************************
//
//! Values that can be passed to HRCAP_getCalibrationClockPeriod() as the
//! \e clockSource parameter.
//
//*****************************************************************************
typedef enum
{
HRCAP_CALIBRATION_CLOCK_SYSCLK = 0x0, //!< Use SYSCLK for period match.
HRCAP_CALIBRATION_CLOCK_HRCLK = 0x4 //!< Use HRCLK for period match.
}HRCAP_CalibrationClockSource;
//*****************************************************************************
//
//! Values that can be passed to HRCAP_setCalibrationMode(),
//! as the \e continuousMode parameter.
//
//*****************************************************************************
typedef enum
{
//! Continuous calibration disabled.
HRCAP_CONTINUOUS_CALIBRATION_DISABLED = 0x00,
//! Continuous calibration enabled.
HRCAP_CONTINUOUS_CALIBRATION_ENABLED = 0x20
}HRCAP_ContinuousCalibrationMode;
//*****************************************************************************
//
//! \internal
//! Checks HRCAP base address.
//!
//! \param base specifies the HRCAP module base address.
//!
//! This function determines if an HRCAP module base address is valid.
//!
//! \return Returns \b true if the base address is valid and \b false
//! otherwise.
//
//*****************************************************************************
#ifdef DEBUG
static inline bool
HRCAP_isBaseValid(uint32_t base)
{
return(
(base == HRCAP6_BASE) ||
(base == HRCAP7_BASE)
);
}
#endif
//*****************************************************************************
//
//! enables HRCAP.
//!
//! \param base is the base address of the HRCAP instance used.
//!
//! This function enables High Resolution Capture module.
//!
//! \note High resolution clock must be enabled before High Resolution Module
//! is enabled.
//!
//! \return None.
//
//*****************************************************************************
static inline void
HRCAP_enableHighResolution(uint32_t base)
{
ASSERT(HRCAP_isBaseValid(base));
EALLOW;
//
// Set HRE bit.
//
HWREGH(base + HRCAP_O_HRCTL) |= HRCAP_HRCTL_HRE;
EDIS;
}
//*****************************************************************************
//
//! Disables HRCAP.
//!
//! \param base is the base address of the HRCAP instance used.
//!
//! This function disable High Resolution Capture module.
//!
//!
//! \return None.
//
//*****************************************************************************
static inline void
HRCAP_disableHighResolution(uint32_t base)
{
ASSERT(HRCAP_isBaseValid(base));
EALLOW;
//
// Set HRE bit.
//
HWREGH(base + HRCAP_O_HRCTL) &= ~HRCAP_HRCTL_HRE;
EDIS;
}
//*****************************************************************************
//
//! Enables high resolution clock.
//!
//! \param base is the base address of the HRCAP instance used.
//!
//! This function enables High Resolution clock.
//!
//! \return None.
//
//*****************************************************************************
static inline void
HRCAP_enableHighResolutionClock(uint32_t base)
{
ASSERT(HRCAP_isBaseValid(base));
EALLOW;
//
// Set HRCLKE bit.
//
HWREGH(base + HRCAP_O_HRCTL) |= HRCAP_HRCTL_HRCLKE;
EDIS;
}
//*****************************************************************************
//
//! Disables High resolution clock.
//!
//! \param base is the base address of the HRCAP instance used.
//!
//! This function disables High Resolution clock.
//!
//! \return None.
//
//*****************************************************************************
static inline void
HRCAP_disbleHighResolutionClock(uint32_t base)
{
ASSERT(HRCAP_isBaseValid(base));
EALLOW;
//
// Clear HRCLKE bit.
//
HWREGH(base + HRCAP_O_HRCTL) &= ~HRCAP_HRCTL_HRCLKE;
EDIS;
}
//*****************************************************************************
//
//! Starts calibration.
//!
//! \param base is the base address of the HRCAP instance used.
//!
//! This function starts calibration.
//!
//! \return None.
//
//*****************************************************************************
static inline void
HRCAP_startCalibration(uint32_t base)
{
ASSERT(HRCAP_isBaseValid(base));
EALLOW;
//
// Set CALIBSTART bit.
//
HWREGH(base + HRCAP_O_HRCTL) |= HRCAP_HRCTL_CALIBSTART;
EDIS;
}
//*****************************************************************************
//
//! Sets the calibration mode.
//!
//! \param base is the base address of the HRCAP instance used.
//!
//! This function sets the the calibration mode by turning on continuous
//! calibration.
//!
//! \return None.
//
//*****************************************************************************
static inline void
HRCAP_setCalibrationMode(uint32_t base)
{
ASSERT(HRCAP_isBaseValid(base));
EALLOW;
//
// Write to CALIBSTS and CALIBCONT bits.
//
HWREGH(base + HRCAP_O_HRCTL) |= HRCAP_HRCTL_CALIBCONT;
EDIS;
}
//*****************************************************************************
//
//! Enables calibration interrupt.
//!
//! \param base is the base address of the HRCAP module.
//! \param intFlags is the calibration interrupt flags to be enabled.
//!
//! This function enables HRCAP calibration interrupt flags.
//! Valid values for intFlags are:
//! - HRCAP_CALIBRATION_DONE - Calibration done interrupt.
//! - HRCAP_CALIBRATION_PERIOD_OVERFLOW - Calibration period overflow
//! check interrupt.
//! \return None.
//
//*****************************************************************************
static inline void
HRCAP_enableCalibrationInterrupt(uint32_t base, uint16_t intFlags)
{
ASSERT(HRCAP_isBaseValid(base));
ASSERT((intFlags & ~(HRCAP_CALIBRATION_DONE |
HRCAP_CALIBRATION_PERIOD_OVERFLOW)) == 0);
EALLOW;
//
// Set CALIBDONE or CALPRDCHKSTS.
//
HWREGH(base + HRCAP_O_HRINTEN) |= intFlags;
EDIS;
}
//*****************************************************************************
//
//! Disables calibration interrupt source.
//!
//! \param base is the base address of the HRCAP module.
//! \param intFlags is the calibration interrupt flags to be disabled.
//!
//! This function disables HRCAP calibration interrupt flags.
//! Valid values for intFlags are:
//! - HRCAP_CALIBRATION_DONE - Calibration done interrupt.
//! - HRCAP_CALIBRATION_PERIOD_OVERFLOW - Calibration period check
//! interrupt.
//! \return None.
//
//*****************************************************************************
static inline void
HRCAP_disableCalibrationInterrupt(uint32_t base, uint16_t intFlags)
{
ASSERT(HRCAP_isBaseValid(base));
ASSERT((intFlags & ~(HRCAP_CALIBRATION_DONE |
HRCAP_CALIBRATION_PERIOD_OVERFLOW)) == 0);
EALLOW;
//
// Clear CALIBDONE or CALPRDCHKSTS.
//
HWREGH(base + HRCAP_O_HRINTEN) &= ~intFlags;
EDIS;
}
//*****************************************************************************
//
//! Returns the calibration interrupt source.
//!
//! \param base is the base address of the HRCAP module.
//!
//! This function returns the HRCAP calibration interrupt source.
//!
//! \return Returns the HRCAP interrupt that has occurred. The following are
//! valid return values.
//! - HRCAP_GLOBAL_CALIBRATION_INTERRUPT - Global calibration
//! interrupt.
//! - HRCAP_CALIBRATION_DONE - Calibration done interrupt.
//! - HRCAP_CALIBRATION_PERIOD_OVERFLOW - Calibration period overflow
//! interrupt.
//!
//! \note - User can check if a combination of the interrupts have occurred
//! by ORing the above return values.
//
//*****************************************************************************
static inline uint16_t
HRCAP_getCalibrationFlags(uint32_t base)
{
ASSERT(HRCAP_isBaseValid(base));
//
// Return contents of HRFLG register.
//
return((uint16_t)(HWREGH(base + HRCAP_O_HRFLG) & 0x7U));
}
//*****************************************************************************
//
//! Clears calibration flags.
//!
//! \param base is the base address of the HRCAP module.
//! \param flags is the calibration flags to be cleared.
//!
//! This function clears HRCAP calibration flags.
//! The following are valid values for flags.
//! - HRCAP_GLOBAL_CALIBRATION_INTERRUPT - Global calibration interrupt.
//! - HRCAP_CALIBRATION_DONE - Calibration done flag.
//! - HRCAP_CALIBRATION_PERIOD_OVERFLOW - Calibration period overflow flag.
//!
//! \return None.
//
//*****************************************************************************
static inline void
HRCAP_clearCalibrationFlags(uint32_t base, uint16_t flags)
{
ASSERT(HRCAP_isBaseValid(base));
ASSERT((flags == (HRCAP_CALIBRATION_DONE |
HRCAP_GLOBAL_CALIBRATION_INTERRUPT)) ||
(flags == (HRCAP_CALIBRATION_PERIOD_OVERFLOW |
HRCAP_GLOBAL_CALIBRATION_INTERRUPT)) ||
(flags == (HRCAP_CALIBRATION_DONE |
HRCAP_GLOBAL_CALIBRATION_INTERRUPT |
HRCAP_CALIBRATION_PERIOD_OVERFLOW)));
//
// Write to HRCLR register.
//
HWREGH(base + HRCAP_O_HRCLR) |= flags;
}
//*****************************************************************************
//
//! Return the Calibration status
//!
//! \param base is the base address of the HRCAP instance used.
//!
//! This function returns the calibration status.
//!
//! \return This functions returns true if the calibration is in process,false
//! if there is no active calibration.
//
//*****************************************************************************
static inline bool
HRCAP_isCalibrationBusy(uint32_t base)
{
ASSERT(HRCAP_isBaseValid(base));
//
// Read CALIBSTS bit.
//
return((HWREGH(base + HRCAP_O_HRCTL) & HRCAP_HRCTL_CALIBSTS) ==
HRCAP_HRCTL_CALIBSTS);
}
//*****************************************************************************
//
//! Force a software based calibration
//!
//! \param base is the base address of the HRCAP instance used.
//! \param flag is the calibration flag source.
//!
//! This function forces a software based calibration done flag.
//! The following are valid values for flag.
//! - HRCAP_CALIBRATION_DONE - Calibration done flag.
//! - HRCAP_CALIBRATION_PERIOD_OVERFLOW - Calibration period overflow flag.
//!
//! \return None.
//
//*****************************************************************************
static inline void
HRCAP_forceCalibrationFlags(uint32_t base, uint16_t flag)
{
ASSERT(HRCAP_isBaseValid(base));
ASSERT((flag & ~(HRCAP_CALIBRATION_DONE |
HRCAP_CALIBRATION_PERIOD_OVERFLOW)) == 0);
EALLOW;
//
// Write to CALIBDONE or CALPRDCHKSTS bit.
//
HWREGH(base + HRCAP_O_HRFRC) |= flag;
EDIS;
}
//*****************************************************************************
//
//! Sets the calibration period count
//!
//! \param base is the base address of the HRCAP instance used.
//! \param sysclkHz is the rate of the SYSCLK in Hz.
//!
//! This function sets the calibration period count value to achieve a period
//! of 1.6 milliseconds given the SYSCLK frequency in Hz (the \e sysclkHz
//! parameter).
//!
//! \return None.
//
//*****************************************************************************
static inline void
HRCAP_setCalibrationPeriod(uint32_t base, uint32_t sysclkHz)
{
ASSERT(HRCAP_isBaseValid(base));
EALLOW;
HWREG(base + HRCAP_O_HRCALPRD) = (sysclkHz * 16U) / 10000U;
EDIS;
}
//*****************************************************************************
//
//! Sets the calibration period count at a user configurable value.
//!
//! \param base is the base address of the HRCAP instance used.
//! \param sysclkHz is the rate of the SYSCLK in Hz.
//! \param periodInMs is the calibration period to be configured.
//!
//! This function sets the calibration period count value to the provided
//! period in milliseconds given the SYSCLK frequency in Hz (the \e sysclkHz
//! parameter).
//!
//! \return None.
//
//*****************************************************************************
static inline void
HRCAP_configCalibrationPeriod(uint32_t base, uint32_t sysclkHz,
float periodInMs)
{
ASSERT(HRCAP_isBaseValid(base));
EALLOW;
HWREG(base + HRCAP_O_HRCALPRD) =
(uint32_t)((float32_t)sysclkHz * periodInMs / 1000.0F);
EDIS;
}
//*****************************************************************************
//
//! Returns the calibration clock period
//!
//! \param base is the base address of the HRCAP instance used.
//! \param clockSource is the calibration clock source
//! (\b HRCAP_CALIBRATION_CLOCK_SYSCLK or \b HRCAP_CALIBRATION_CLOCK_HRCLK).
//!
//! This function returns the period match value of the calibration clock. The
//! return value has a valid count when a period match occurs.
//!
//! \return This function returns the captured value of the clock counter
//! specified by clockSource.
//
//*****************************************************************************
static inline uint32_t
HRCAP_getCalibrationClockPeriod(uint32_t base,
HRCAP_CalibrationClockSource clockSource)
{
ASSERT(HRCAP_isBaseValid(base));
//
// Return HRCAP_O_HRSYSCLKCAP or HRCAP_O_HRCLKCAP.
//
return(HWREG(base + HRCAP_O_HRSYSCLKCAP + (uint32_t)clockSource));
}
//*****************************************************************************
//
//! Calculates the scale factor
//!
//! \param base is the base address of the HRCAP instance used.
//!
//! This function reads the SYSCLK and HRCLK calibration periods and then
//! uses them to calculate the scale factor.
//!
//! \return This function returns the calculated scale factor.
//
//*****************************************************************************
static inline float32_t
HRCAP_getScaleFactor(uint32_t base)
{
ASSERT(HRCAP_isBaseValid(base));
//
// Calculate and return the scale factor.
//
return((float32_t)HRCAP_getCalibrationClockPeriod(base,
HRCAP_CALIBRATION_CLOCK_SYSCLK) /
(float32_t)HRCAP_getCalibrationClockPeriod(base,
HRCAP_CALIBRATION_CLOCK_HRCLK));
}
//*****************************************************************************
//
//! Returns event time stamp in nanoseconds
//!
//! \param timeStamp is a raw time stamp count returned by
//! ECAP_getEventTimeStamp().
//! \param scaleFactor is the calculated scale factor returned by
//! HRCAP_getScaleFactor().
//!
//! This function converts a raw CAP time stamp (the \e timeStamp parameter) to
//! nanoseconds using the provided scale factor (the \e scaleFactor parameter).
//!
//! \return Returns the converted time stamp in nanoseconds.
//
//*****************************************************************************
static inline float32_t
HRCAP_convertEventTimeStampNanoseconds(uint32_t timeStamp,
float32_t scaleFactor)
{
//
// Convert the raw count value to nanoseconds using the given scale factor.
//
return((float32_t)timeStamp * scaleFactor * ((float32_t)5.0 /
(float32_t)128.0));
}
//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
// Mark the end of the C bindings section for C++ compilers.
//
//*****************************************************************************
#ifdef __cplusplus
}
#endif
#endif // HRCAP_H