//########################################################################### // // FILE: dac.h // // TITLE: C28x DAC 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 DAC_H #define DAC_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 dac_api DAC //! @{ // //***************************************************************************** #include #include #include "inc/hw_dac.h" #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "cpu.h" #include "debug.h" // // A 8-bit register mask // #define DAC_REG_BYTE_MASK (0xFFU) //!< Register Byte Mask // // Lock Key // #define DAC_LOCK_KEY (0xA000U) //!< DAC Lock Key #ifndef DOXYGEN_PDF_IGNORE //***************************************************************************** // // The following are defines for the reg parameter of the // DAC_lockRegister() and DAC_isRegisterLocked() functions. // //***************************************************************************** #define DAC_LOCK_CONTROL (0x1U) //!< Lock the control register #define DAC_LOCK_SHADOW (0x2U) //!< Lock the shadow value register #define DAC_LOCK_OUTPUT (0x4U) //!< Lock the output enable register #endif // DOXYGEN_PDF_IGNORE //***************************************************************************** // //! Values that can be passed to DAC_setReferenceVoltage() as the \e source //! parameter. // //***************************************************************************** typedef enum { DAC_REF_VDAC = 0, //!< VDAC reference voltage DAC_REF_ADC_VREFHI = 1 //!< ADC VREFHI reference voltage }DAC_ReferenceVoltage; //***************************************************************************** // //! Values that can be passed to DAC_setLoadMode() as the \e mode parameter. // //***************************************************************************** typedef enum { DAC_LOAD_SYSCLK = 0, //!< Load on next SYSCLK DAC_LOAD_PWMSYNC = 4 //!< Load on next PWMSYNC specified by SYNCSEL }DAC_LoadMode; //***************************************************************************** // // Prototypes for the APIs. // //***************************************************************************** //***************************************************************************** // //! \internal //! Checks DAC base address. //! //! \param base specifies the DAC module base address. //! //! This function determines if an DAC module base address is valid. //! //! \return Returns \b true if the base address is valid and \b false //! otherwise. // //***************************************************************************** #ifdef DEBUG static inline bool DAC_isBaseValid(uint32_t base) { return( (base == DACA_BASE) || (base == DACB_BASE) || (base == DACC_BASE) ); } #endif //***************************************************************************** // //! Get the DAC Revision value //! //! \param base is the DAC module base address //! //! This function gets the DAC revision value. //! //! \return Returns the DAC revision value. // //***************************************************************************** static inline uint16_t DAC_getRevision(uint32_t base) { // // Check the arguments. // ASSERT(DAC_isBaseValid(base)); // // Get the revision value. // return(HWREGH(base + DAC_O_REV) & DAC_REV_REV_M); } //***************************************************************************** // //! Sets the DAC Reference Voltage //! //! \param base is the DAC module base address //! \param source is the selected reference voltage //! //! This function sets the DAC reference voltage. //! //! The \e source parameter can have one of two values: //! - \b DAC_REF_VDAC - The VDAC reference voltage //! - \b DAC_REF_ADC_VREFHI - The ADC VREFHI reference voltage //! //! \return None. // //***************************************************************************** static inline void DAC_setReferenceVoltage(uint32_t base, DAC_ReferenceVoltage source) { // // Check the arguments. // ASSERT(DAC_isBaseValid(base)); // // Set the reference voltage // EALLOW; HWREGH(base + DAC_O_CTL) = (HWREGH(base + DAC_O_CTL) & ~DAC_CTL_DACREFSEL) | (uint16_t)source; EDIS; } //***************************************************************************** // //! Sets the DAC Load Mode //! //! \param base is the DAC module base address //! \param mode is the selected load mode //! //! This function sets the DAC load mode. //! //! The \e mode parameter can have one of two values: //! - \b DAC_LOAD_SYSCLK - Load on next SYSCLK //! - \b DAC_LOAD_PWMSYNC - Load on next PWMSYNC specified by SYNCSEL //! //! \return None. // //***************************************************************************** static inline void DAC_setLoadMode(uint32_t base, DAC_LoadMode mode) { // // Check the arguments. // ASSERT(DAC_isBaseValid(base)); // // Set the load mode // EALLOW; HWREGH(base + DAC_O_CTL) = (HWREGH(base + DAC_O_CTL) & ~DAC_CTL_LOADMODE) | (uint16_t)mode; EDIS; } //***************************************************************************** // //! Sets the DAC PWMSYNC Signal //! //! \param base is the DAC module base address //! \param signal is the selected PWM signal //! //! This function sets the DAC PWMSYNC signal. //! //! The \e signal parameter must be set to a number that represents the PWM //! signal that will be set. For instance, passing 2 into \e signal will //! select PWM sync signal 2. //! //! \return None. // //***************************************************************************** static inline void DAC_setPWMSyncSignal(uint32_t base, uint16_t signal) { // // Check the arguments. // ASSERT(DAC_isBaseValid(base)); ASSERT((signal > 0U) && (signal < 17U)); // // Set the PWM sync signal // EALLOW; HWREGH(base + DAC_O_CTL) = (HWREGH(base + DAC_O_CTL) & ~DAC_CTL_SYNCSEL_M) | ((uint16_t)(signal - 1U) << DAC_CTL_SYNCSEL_S); EDIS; } //***************************************************************************** // //! Get the DAC Active Output Value //! //! \param base is the DAC module base address //! //! This function gets the DAC active output value. //! //! \return Returns the DAC active output value. // //***************************************************************************** static inline uint16_t DAC_getActiveValue(uint32_t base) { // // Check the arguments. // ASSERT(DAC_isBaseValid(base)); // // Get the active value // return(HWREGH(base + DAC_O_VALA) & DAC_VALA_DACVALA_M); } //***************************************************************************** // //! Set the DAC Shadow Output Value //! //! \param base is the DAC module base address //! \param value is the 12-bit code to be loaded into the active value register //! //! This function sets the DAC shadow output value. //! //! \return None. // //***************************************************************************** static inline void DAC_setShadowValue(uint32_t base, uint16_t value) { // // Check the arguments. // ASSERT(DAC_isBaseValid(base)); ASSERT(value <= DAC_VALS_DACVALS_M); // // Set the shadow value // HWREGH(base + DAC_O_VALS) = (HWREGH(base + DAC_O_VALS) & ~DAC_VALS_DACVALS_M) | (uint16_t)(value & DAC_VALS_DACVALS_M); } //***************************************************************************** // //! Get the DAC Shadow Output Value //! //! \param base is the DAC module base address //! //! This function gets the DAC shadow output value. //! //! \return Returns the DAC shadow output value. // //***************************************************************************** static inline uint16_t DAC_getShadowValue(uint32_t base) { // // Check the arguments. // ASSERT(DAC_isBaseValid(base)); // // Get the shadow value // return(HWREGH(base + DAC_O_VALS) & DAC_VALS_DACVALS_M); } //***************************************************************************** // //! Enable the DAC Output //! //! \param base is the DAC module base address //! //! This function enables the DAC output. //! //! \note A delay is required after enabling the DAC. Further details //! regarding the exact delay time length can be found in the device datasheet. //! //! \return None. // //***************************************************************************** static inline void DAC_enableOutput(uint32_t base) { // // Check the arguments. // ASSERT(DAC_isBaseValid(base)); // // Enable the output // EALLOW; HWREGH(base + DAC_O_OUTEN) |= DAC_OUTEN_DACOUTEN; EDIS; } //***************************************************************************** // //! Disable the DAC Output //! //! \param base is the DAC module base address //! //! This function disables the DAC output. //! //! \return None. // //***************************************************************************** static inline void DAC_disableOutput(uint32_t base) { // // Check the arguments. // ASSERT(DAC_isBaseValid(base)); // // Disable the output // EALLOW; HWREGH(base + DAC_O_OUTEN) &= ~DAC_OUTEN_DACOUTEN; EDIS; } //***************************************************************************** // //! Set DAC Offset Trim //! //! \param base is the DAC module base address //! \param offset is the specified value for the offset trim //! //! This function sets the DAC offset trim. The \e offset value should be a //! signed number in the range of -128 to 127. //! //! \note The offset should not be modified unless specifically indicated by //! TI Errata or other documentation. Modifying the offset value could cause //! this module to operate outside of the datasheet specifications. //! //! \return None. // //***************************************************************************** static inline void DAC_setOffsetTrim(uint32_t base, int16_t offset) { // // Check the arguments. // ASSERT(DAC_isBaseValid(base)); ASSERT((offset > -129) && (offset < 128)); // // Set the offset trim value // EALLOW; HWREGH(base + DAC_O_TRIM) = (HWREGH(base + DAC_O_TRIM) & ~DAC_TRIM_OFFSET_TRIM_M) | (int16_t)offset; EDIS; } //***************************************************************************** // //! Get DAC Offset Trim //! //! \param base is the DAC module base address //! //! This function gets the DAC offset trim value. //! //! \return None. // //***************************************************************************** static inline int16_t DAC_getOffsetTrim(uint32_t base) { uint16_t value; // // Check the arguments. // ASSERT(DAC_isBaseValid(base)); // // Get the sign-extended offset trim value // value = (HWREGH(base + DAC_O_TRIM) & DAC_TRIM_OFFSET_TRIM_M); value = ((value & (uint16_t)DAC_REG_BYTE_MASK) ^ (uint16_t)0x80) - (uint16_t)0x80; return((int16_t)value); } //***************************************************************************** // //! Lock write-access to DAC Register //! //! \param base is the DAC module base address //! \param reg is the selected DAC registers //! //! This function locks the write-access to the specified DAC register. Only a //! system reset can unlock the register once locked. //! //! The \e reg parameter can be an ORed combination of any of the following //! values: //! - \b DAC_LOCK_CONTROL - Lock the DAC control register //! - \b DAC_LOCK_SHADOW - Lock the DAC shadow value register //! - \b DAC_LOCK_OUTPUT - Lock the DAC output enable/disable register //! //! \return None. // //***************************************************************************** static inline void DAC_lockRegister(uint32_t base, uint16_t reg) { // // Check the arguments. // ASSERT(DAC_isBaseValid(base)); ASSERT((reg & ~(DAC_LOCK_CONTROL | DAC_LOCK_SHADOW | DAC_LOCK_OUTPUT)) == 0U); // // Lock the specified registers // EALLOW; HWREGH(base + DAC_O_LOCK) |= reg; EDIS; } //***************************************************************************** // //! Check if DAC Register is locked //! //! \param base is the DAC module base address //! \param reg is the selected DAC register locks to check //! //! This function checks if write-access has been locked on the specified DAC //! register. //! //! The \e reg parameter can be an ORed combination of any of the following //! values: //! - \b DAC_LOCK_CONTROL - Lock the DAC control register //! - \b DAC_LOCK_SHADOW - Lock the DAC shadow value register //! - \b DAC_LOCK_OUTPUT - Lock the DAC output enable/disable register //! //! \return Returns \b true if any of the registers specified are locked, and //! \b false if all specified registers aren't locked. // //***************************************************************************** static inline bool DAC_isRegisterLocked(uint32_t base, uint16_t reg) { // // Check the arguments. // ASSERT(DAC_isBaseValid(base)); ASSERT((reg & ~(DAC_LOCK_CONTROL | DAC_LOCK_SHADOW | DAC_LOCK_OUTPUT)) == 0U); // // Return the lock status on the specified registers // return((bool)((HWREGH(base + DAC_O_LOCK) & reg) != 0U)); } //***************************************************************************** // //! Tune DAC Offset Trim //! //! \param base is the DAC module base address //! \param referenceVoltage is the reference voltage the DAC //! module is operating at. //! //! This function adjusts/tunes the DAC offset trim. The \e referenceVoltage //! value should be a floating point number in the range specified in the //! device data manual. //! //! \note Use this function to adjust the DAC offset trim if operating //! at a reference voltage other than 2.5v. Since this function modifies //! the DAC offset trim register, it should only be called once after //! Device_cal. If it is called multiple times after Device_cal, the offset //! value scaled would be the wrong value. //! //! \return None. // //***************************************************************************** extern void DAC_tuneOffsetTrim(uint32_t base, float32_t referenceVoltage); //***************************************************************************** // // Close the Doxygen group. //! @} // //***************************************************************************** //***************************************************************************** // // Mark the end of the C bindings section for C++ compilers. // //***************************************************************************** #ifdef __cplusplus } #endif #endif // DAC_H