/******************************************************************************
*  Filename:       adi.h
*  Revised:        2015-01-14 12:12:44 +0100 (on, 14 jan 2015)
*  Revision:       42373
*
*  Description:    Defines and prototypes for the ADI master interface.
*
*  Copyright (c) 2015, Texas Instruments Incorporated
*  All rights reserved.
*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions are met:
*
*  1) Redistributions of source code must retain the above copyright notice,
*     this list of conditions and the following disclaimer.
*
*  2) 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.
*
*  3) Neither the name of the ORGANIZATION 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 HOLDER 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.
*
******************************************************************************/

//*****************************************************************************
//
//! \addtogroup adi_api
//! @{
//
//*****************************************************************************

#ifndef __ADI_H__
#define __ADI_H__

//*****************************************************************************
//
// If building with a C++ compiler, make all of the definitions in this header
// have a C binding.
//
//*****************************************************************************
#ifdef __cplusplus
extern "C"
{
#endif

#include <stdbool.h>
#include <stdint.h>
#include <inc/hw_types.h>
#include <inc/hw_uart.h>
#include <inc/hw_memmap.h>
#include <inc/hw_ints.h>
#include <inc/hw_adi.h>
#include <driverlib/debug.h>
#include <driverlib/ddi.h>

//*****************************************************************************
//
// Number of registers in the ADI slave
//
//*****************************************************************************
#define ADI_SLAVE_REGS      16

//*****************************************************************************
//
// Defines that can be passed to the ADIConfigSet()
//
//*****************************************************************************
#define ADI_NO_WAIT         0x00000000
#define ADI_WAIT_FOR_ACK    0x00000004
#define ADI_SPEED_2         0x00000000
#define ADI_SPEED_4         0x00000001
#define ADI_SPEED_8         0x00000002
#define ADI_SPEED_16        0x00000003
#define ADI_CONFIG_MASK     0x00000007

//*****************************************************************************
//
// Defines that is used to control the ADI slave and master
//
//*****************************************************************************
#define ADI_PROTECT         0x00000080
#define ADI_ACK             0x00000001
#define ADI_SYNC            0x00000000

//*****************************************************************************
//
// API Functions and prototypes
//
//*****************************************************************************

#ifdef DRIVERLIB_DEBUG
//*****************************************************************************
//
//! \internal
//! \brief Checks an ADI base address.
//!
//! This function determines if an ADI port base address is valid.
//!
//! \param ui32Base is the base address of the ADI port.
//!
//! \return Returns \c true if the base address is valid and \c false
//! otherwise
//
//*****************************************************************************
static bool
ADIBaseValid(uint32_t ui32Base)
{
    return(ui32Base == ADI2_BASE || ui32Base == ADI3_BASE ||
           ui32Base == AUX_ADI4_BASE);
}
#endif

//*****************************************************************************
//
//! \brief Get the status of an ADI module.
//!
//! This function will return the value of the status register ADI_O_SLAVESTAT
//! which contains status of Request and Acklowledge signals.
//!
//! \param ui32Base is ADI base address. Allowed values are:
//! - ADI2_BASE : Status of ADI2.
//! - ADI3_BASE : Status of ADI3.
//! - AUX_ADI4_BASE : Status of AUX_ADI4.
//!
//! \return Returns the current value of the status register.
//
//*****************************************************************************
__STATIC_INLINE uint32_t
ADIStatusGet(uint32_t ui32Base)
{
    //
    // Check the arguments.
    //
    ASSERT(ADIBaseValid(ui32Base));

    //
    // Return the status value for the correct ADI Slave.
    //
    return(HWREG(ui32Base + ADI_O_SLAVESTAT));
}

//*****************************************************************************
//
//! \brief Configure the ADI Slave.
//!
//! Use this function to configure the interface between the ADI master and the
//! ADI slave. The configuration value for the ADI slave sets the
//! speed of the ADI interface and define if the master should wait for
//! acknowledge from the slave.
//!
//! If the \c bProtect parameter is set, the configuration register in the
//! ADI slave is locked for future writes.
//!
//! \note Once the \c bProtect parameter is set, it is no longer possible to modify
//! the configuration register.
//!
//! \note AUX_ADI4_BASE : Both the AUX module and the clock for the AUX SMPH module must be
//! enabled before calling this function.
//!
//! \param ui32Base is ADI base address.
//! \param ui32Config is the configuration of the ADI slave. Value must be a
//! bitwise OR'ed combination of one of each of the two following items:
//! - Speed: \ref ADI_SPEED_2, \ref ADI_SPEED_4, \ref ADI_SPEED_8, or \ref ADI_SPEED_16.
//! - Acknowledge: \ref ADI_NO_WAIT or \ref ADI_WAIT_FOR_ACK.
//! \param bProtect determines if the register access should be protected.
//! - \c false: Do not protect configuration register.
//! - \c true: Protect configuration register.
//!
//! \return None
//
//*****************************************************************************
__STATIC_INLINE void
ADIConfigSet(uint32_t ui32Base, uint32_t ui32Config, bool bProtect)
{
    //
    // Check the arguments.
    //
    ASSERT(ADIBaseValid(ui32Base));
    ASSERT(((ui32Config & 0x4) == ADI_NO_WAIT) ||
           ((ui32Config & 0x4) == ADI_WAIT_FOR_ACK));
    ASSERT(((ui32Config & 0x3) == ADI_SPEED_2) ||
           ((ui32Config & 0x3) == ADI_SPEED_4) ||
           ((ui32Config & 0x3) == ADI_SPEED_8) ||
           ((ui32Config & 0x3) == ADI_SPEED_16));

    //
    // Configure the ADI slave.
    //
    if (ui32Base==AUX_ADI4_BASE) {
        AuxAdiDdiSafeWrite(
            ui32Base + ADI_O_SLAVECONF,
            (ui32Config & 0x7) | (bProtect ? ADI_PROTECT : 0),
            4
        );
    } else {
        HWREG(ui32Base + ADI_O_SLAVECONF) = (ui32Config & 0x7) |
                                            (bProtect ? ADI_PROTECT : 0);
    }
}

//*****************************************************************************
//
//! \brief Synchronize the ADI slave.
//!
//! This function will perform a sync on the ADI slave by issuing a NOP
//! ADI command to the master with REQ=0. In other words, the master
//! performs a dummy write request to ensure the master and slave are
//! synchronized.
//!
//! \note It is recommended to sync with all the ADI slaves before a power down
//! of the ADI master.
//!
//! \note AUX_ADI4_BASE : Both the AUX module and the clock for the AUX SMPH module must be
//! enabled before calling this function.
//!
//! \param ui32Base is ADI base address.
//!
//! \return None
//
//*****************************************************************************
__STATIC_INLINE void
ADISync(uint32_t ui32Base)
{
    //
    // Check the arguments.
    //
    ASSERT(ADIBaseValid(ui32Base));

    //
    // Synchronize the ADI slave to guarantee future write operations.
    //
    if (ui32Base==AUX_ADI4_BASE) {
        AuxAdiDdiSafeWrite(ui32Base + ADI_O_SLAVESTAT, ADI_SYNC, 1);
    } else {
        HWREGB(ui32Base + ADI_O_SLAVESTAT) = ADI_SYNC;
    }
}

//*****************************************************************************
//
//! \brief Protect an ADI slave configuration by locking the configuration register access.
//!
//! This function will lock the configuration interface to the ADI slave.
//!
//! \note Once locked it is no longer possible to modify the configuration
//! register in the ADI slave.
//!
//! \note This function uses read-modify-write to guarantee the integrity of
//! the configuration. This might take exceedingly long time, so if the
//! configuration is known, it is advised to use ADIConfigSet() for
//! protecting the ADI slave configuration.
//!
//! \note AUX_ADI4_BASE : Both the AUX module and the clock for the AUX SMPH module must be
//! enabled before calling this function.
//!
//! \param ui32Base is ADI base address.
//!
//! \return None
//!
//! \sa ADIConfigSet()
//
//*****************************************************************************
__STATIC_INLINE void
ADIProtect(uint32_t ui32Base)
{
    uint32_t ui32Val;

    //
    // Check the arguments.
    //
    ASSERT(ADIBaseValid(ui32Base));

    //
    // Lock the register interface on the ADI slave.
    //
    if (ui32Base==AUX_ADI4_BASE) {
        ui32Val = AuxAdiDdiSafeRead(ui32Base + ADI_O_SLAVECONF, 4);
    } else {
        ui32Val = HWREG(ui32Base + ADI_O_SLAVECONF);
    }
    ui32Val |= ADI_PROTECT;
    if (ui32Base==AUX_ADI4_BASE) {
        AuxAdiDdiSafeWrite(ui32Base + ADI_O_SLAVECONF, ui32Val, 4);
    } else {
        HWREG(ui32Base + ADI_O_SLAVECONF) = ui32Val;
    }
}

//*****************************************************************************
//
//! \brief Write an 8 bit value to a register in an ADI slave.
//!
//! This function will write a value to a single register in the analog domain.
//! The access to the registers in the analog domain is either 8, 16, or 32 bit
//! aligned. You can only do 16 bit access on registers 0-1 / 2-3, etc. Similarly
//! 32 bit accesses are always performed on register 0-3 / 4-7, etc. Addresses
//! for the registers and values being written to the registers will be
//! truncated according to this access sceme.
//!
//! \note This operation is write only for the specified register. No
//! previous value of the register will be kept (i.e. this is NOT
//! read-modify-write on the register).
//!
//! \note AUX_ADI4_BASE : Both the AUX module and the clock for the AUX SMPH module must be
//! enabled before calling this function.
//!
//! \param ui32Base is ADI base address.
//! \param ui32Reg is the register to write.
//! \param ui8Val is the 8 bit value to write to the register.
//!
//! \return None
//!
//! \sa ADI16RegWrite(), ADI32RegWrite()
//
//*****************************************************************************
__STATIC_INLINE void
ADI8RegWrite(uint32_t ui32Base, uint32_t ui32Reg, uint8_t ui8Val)
{
    //
    // Check the arguments.
    //
    ASSERT(ADIBaseValid(ui32Base));
    ASSERT(ui32Reg < ADI_SLAVE_REGS);

    //
    // Write the value to the register.
    //
    if (ui32Base==AUX_ADI4_BASE) {
        AuxAdiDdiSafeWrite(ui32Base + ui32Reg, ui8Val, 1);
    } else {
        HWREGB(ui32Base + ui32Reg) = ui8Val;
    }
}

//*****************************************************************************
//
//! \brief Write a 16 bit value to 2 registers in the ADI slave.
//!
//! This function will write a value to 2 consecutive registers in the analog
//! domain. The access to the registers in the analog domain is either 8, 16
//! or 32 bit aligned. You can only do 16 bit access on registers 0-1 / 2-3,
//! etc. Similarly 32 bit accesses are always performed on register 0-3 / 4-7,
//! etc. Addresses for the registers and values being written
//! to the registers will be truncated according to this access sceme.
//!
//! \note The byte addressing bit will be ignored, to ensure 16 bit access
//! to the ADI slave.
//!
//! \note This operation is write only for the specified register. No
//! previous value of the register will be kept (i.e. this is NOT
//! read-modify-write on the register).
//!
//! \note AUX_ADI4_BASE : Both the AUX module and the clock for the AUX SMPH module must be
//! enabled before calling this function.
//!
//! \param ui32Base is ADI base address.
//! \param ui32Reg is the register to write.
//! \param ui16Val is the 16 bit value to write to the register.
//!
//! \return None
//!
//! \sa ADI8RegWrite(), ADI32RegWrite()
//
//*****************************************************************************
__STATIC_INLINE void
ADI16RegWrite(uint32_t ui32Base, uint32_t ui32Reg,
              uint16_t ui16Val)
{
    //
    // Check the arguments.
    //
    ASSERT(ADIBaseValid(ui32Base));
    ASSERT(ui32Reg < ADI_SLAVE_REGS);

    //
    // Write the value to the register.
    //
    if (ui32Base==AUX_ADI4_BASE) {
        AuxAdiDdiSafeWrite(ui32Base + (ui32Reg & 0xFE), ui16Val, 2);
    } else {
        HWREGH(ui32Base + (ui32Reg & 0xFE)) = ui16Val;
    }
}

//*****************************************************************************
//
//! \brief Write a 32 bit value to 4 registers in the ADI slave.
//!
//! This function will write a value to 4 consecutive registers in the analog
//! domain. The access to the registers in the analog domain is either 8, 16
//! or 32 bit aligned. You can only do 16 bit access on registers 0-1 / 2-3,
//! etc. Similarly 32 bit accesses are always performed on register 0-3 / 4-7,
//! etc. Addresses for the registers and values being written
//! to the registers will be truncated according to this access sceme.
//!
//! \note The byte and half word addressing bits will be ignored, to ensure
//! 32 bit access to the ADI slave.
//!
//! \note This operation is write only for the specified register. No
//! previous value of the register will be kept (i.e. this is NOT
//! read-modify-write on the register).
//!
//! \note AUX_ADI4_BASE : Both the AUX module and the clock for the AUX SMPH module must be
//! enabled before calling this function.
//!
//! \param ui32Base is ADI base address.
//! \param ui32Reg is the register to write.
//! \param ui32Val is the 32 bit value to write to the register.
//!
//! \return None
//!
//! \sa ADI8RegWrite(), ADI16RegWrite()
//
//*****************************************************************************
__STATIC_INLINE void
ADI32RegWrite(uint32_t ui32Base, uint32_t ui32Reg, uint32_t ui32Val)
{
    //
    // Check the arguments.
    //
    ASSERT(ADIBaseValid(ui32Base));
    ASSERT(ui32Reg < ADI_SLAVE_REGS);

    //
    // Write the value to the register.
    //
    if (ui32Base==AUX_ADI4_BASE) {
        AuxAdiDdiSafeWrite(ui32Base + (ui32Reg & 0xFC), ui32Val, 4);
    } else {
        HWREG(ui32Base + (ui32Reg & 0xFC)) = ui32Val;
    }
}

//*****************************************************************************
//
//! \brief Read the value of an 8 bit register in the ADI slave.
//!
//! This function will read an 8 bit register in the analog domain and return
//! the value as the lower 8 bits of an \c uint32_t. The access to the
//! registers in the analog domain is either 8, 16 or 32 bit aligned. You can
//! only do 16 bit access on registers 0-1 / 2-3, etc. Similarly 32 bit accesses
//! are always performed on register 0-3 / 4-7, etc. Addresses for the
//! registers and values being written to the registers will be truncated
//! according to this access sceme.
//!
//! \param ui32Base is ADI base address.
//! \param ui32Reg is the 8 bit register to read.
//!
//! \return Returns the 8 bit value of the analog register in the least
//! significant byte of the \c uint32_t.
//!
//! \sa ADI16RegRead(), ADI32RegRead()
//
//*****************************************************************************
__STATIC_INLINE uint32_t
ADI8RegRead(uint32_t ui32Base, uint32_t ui32Reg)
{
    //
    // Check the arguments.
    //
    ASSERT(ADIBaseValid(ui32Base));
    ASSERT(ui32Reg < ADI_SLAVE_REGS);

    //
    // Read the register and return the value.
    //
    if (ui32Base==AUX_ADI4_BASE) {
        return AuxAdiDdiSafeRead(ui32Base + ui32Reg, 1);
    } else {
        return(HWREGB(ui32Base + ui32Reg));
    }
}

//*****************************************************************************
//
//! \brief Read the value in a 16 bit register.
//!
//! This function will read 2 x 8 bit registers in the analog domain and return
//! the value as the lower 16 bits of an \c uint32_t. The access to the
//! registers in the analog domain is either 8, 16 or 32 bit aligned. You can
//! only do 16 bit access on registers 0-1 / 2-3, etc. Similarly 32 bit accesses
//! are always performed on register 0-3 / 4-7, etc. Addresses for the
//! registers and values being written to the registers will be truncated
//! according to this access sceme.
//!
//! \note The byte addressing bit will be ignored, to ensure 16 bit access
//! to the ADI slave.
//!
//! \param ui32Base is ADI base address.
//! \param ui32Reg is the 16 bit register to read.
//!
//! \return Returns the 16 bit value of the 2 analog register in the 2 least
//! significant bytes of the \c uint32_t.
//!
//! \sa ADI8RegRead(), ADI32RegRead()
//
//*****************************************************************************
__STATIC_INLINE uint32_t
ADI16RegRead(uint32_t ui32Base, uint32_t ui32Reg)
{
    //
    // Check the arguments.
    //
    ASSERT(ADIBaseValid(ui32Base));
    ASSERT(ui32Reg < ADI_SLAVE_REGS);

    //
    // Read the registers and return the value.
    //
    if (ui32Base==AUX_ADI4_BASE) {
        return AuxAdiDdiSafeRead(ui32Base + (ui32Reg & 0xFE), 2);
    } else {
        return(HWREGH(ui32Base + (ui32Reg & 0xFE)));
    }
}

//*****************************************************************************
//
//! \brief Read the value in a 32 bit register.
//!
//! This function will read 4 x 8 bit registers in the analog domain and return
//! the value as an \c uint32_t. The access to the registers in the analog
//! domain is either 8, 16 or 32 bit aligned. You can only do 16 bit access on
//! registers 0-1 / 2-3, etc. Similarly 32 bit accesses are always performed on
//! register 0-3 / 4-7, etc. Addresses for the registers and values being
//! written to the registers will be truncated according to this access sceme.
//!
//! \note The byte and half word addressing bits will be ignored, to ensure
//! 32 bit access to the ADI slave.
//!
//! \param ui32Base is ADI base address.
//! \param ui32Reg is the 32 bit register to read.
//!
//! \return Returns the 32 bit value of the 4 analog registers.
//!
//! \sa ADI8RegRead(), ADI16RegRead()
//
//*****************************************************************************
__STATIC_INLINE uint32_t
ADI32RegRead(uint32_t ui32Base, uint32_t ui32Reg)
{
    //
    // Check the arguments.
    //
    ASSERT(ADIBaseValid(ui32Base));
    ASSERT(ui32Reg < ADI_SLAVE_REGS);

    //
    // Read the registers and return the value.
    //
    if (ui32Base==AUX_ADI4_BASE) {
        return AuxAdiDdiSafeRead(ui32Base + (ui32Reg & 0xFC), 4);
    } else {
        return(HWREG(ui32Base + (ui32Reg & 0xFC)));
    }
}

//*****************************************************************************
//
//! \brief Set specific bits in a single 8 bit ADI register.
//!
//! This function will set bits in a single register in the analog domain.
//! The access to the registers in the analog domain is either 8, 16 or 32 bit
//! aligned, but arranged in chunck of 32 bits. You can only do 16 bit access
//! on registers 0-1 / 2-3, etc. Similarly 32 bit accesses are always
//! performed on register 0-3 / 4-7 etc. Addresses for the registers and values
//! being written to the registers will be truncated according to this access
//! sceme.
//!
//! \note This operation is write only for the specified register.
//! This function is used to set bits in a specific 8 bit register in the
//! ADI slave. Only bits in the selected register are affected by the
//! operation.
//!
//! \note AUX_ADI4_BASE : Both the AUX module and the clock for the AUX SMPH module must be
//! enabled before calling this function.
//!
//! \param ui32Base is ADI base address.
//! \param ui32Reg is the base register to assert the bits in.
//! \param ui8Val is the 8 bit one-hot encoded value specifying which
//! bits to set in the register.
//!
//! \return None
//!
//! \sa ADI16BitsSet(), ADI32BitsSet()
//
//*****************************************************************************
__STATIC_INLINE void
ADI8BitsSet(uint32_t ui32Base, uint32_t ui32Reg, uint8_t ui8Val)
{
    uint32_t ui32RegOffset;

    //
    // Check the arguments.
    //
    ASSERT(ADIBaseValid(ui32Base));
    ASSERT(ui32Reg < ADI_SLAVE_REGS);

    //
    // Get the correct address of the first register used for setting bits
    // in the ADI slave.
    //
    ui32RegOffset = ADI_O_SET;

    //
    // Set the selected bits.
    //
    if (ui32Base==AUX_ADI4_BASE) {
        AuxAdiDdiSafeWrite(ui32Base + ui32RegOffset + ui32Reg, ui8Val, 4);
    } else {
        HWREGB(ui32Base + ui32RegOffset + ui32Reg) = ui8Val;
    }
}

//*****************************************************************************
//
//! \brief Set specific bits in 2 x 8 bit ADI slave registers.
//!
//! This function will set bits in 2 registers in the analog domain.
//! The access to the registers in the analog domain is either 8, 16 or 32 bit
//! aligned, but arranged in chunck of 32 bits. You can only do 16 bit access
//! on registers 0-1 / 2-3, etc. Similarly 32 bit accesses are always
//! performed on register 0-3 / 4-7 etc. Addresses for the registers and values
//! being written to the registers will be truncated according to this access
//! sceme.
//!
//! \note This operation is write only for the specified register.
//! This function is used to set bits in 2 consecutive 8 bit registers in the
//! ADI slave. Only bits in the selected registers are affected by the
//! operation.
//!
//! \note AUX_ADI4_BASE : Both the AUX module and the clock for the AUX SMPH module must be
//! enabled before calling this function.
//!
//! \param ui32Base is ADI base address.
//! \param ui32Reg is the base register to assert the bits in.
//! \param ui16Val is the 16 bit one-hot encoded value specifying which
//! bits to set in the registers.
//!
//! \return None
//!
//! \sa ADI8BitsSet(), ADI32BitsSet()
//
//*****************************************************************************
__STATIC_INLINE void
ADI16BitsSet(uint32_t ui32Base, uint32_t ui32Reg, uint16_t ui16Val)
{
    uint32_t ui32RegOffset;

    //
    // Check the arguments.
    //
    ASSERT(ADIBaseValid(ui32Base));
    ASSERT(ui32Reg < ADI_SLAVE_REGS);

    //
    // Get the correct address of the first register used for setting bits
    // in the ADI slave.
    //
    ui32RegOffset = ADI_O_SET;

    //
    // Set the selected bits.
    //
    if (ui32Base==AUX_ADI4_BASE) {
        AuxAdiDdiSafeWrite(ui32Base + ui32RegOffset + (ui32Reg & 0xFE), ui16Val, 2);
    } else {
        HWREGH(ui32Base + ui32RegOffset + (ui32Reg & 0xFE)) = ui16Val;
    }
}

//*****************************************************************************
//
//! \brief Set specific bits in 4 x 8 bit ADI slave registers.
//!
//! This function will set bits in 4 registers in the analog domain.
//! The access to the registers in the analog domain is either 8, 16 or 32 bit
//! aligned, but arranged in chunck of 32 bits. You can only do 16 bit access
//! on registers 0-1 / 2-3, etc. Similarly 32 bit accesses are always
//! performed on register 0-3 / 4-7 etc. Addresses for the registers and values
//! being written to the registers will be truncated according to this access
//! sceme.
//!
//! \note This operation is write only for the specified register.
//! This function is used to set bits in 4 consecutive 8 bit registers in the
//! ADI slave. Only bits in the selected registers are affected by the
//! operation.
//!
//! \note AUX_ADI4_BASE : Both the AUX module and the clock for the AUX SMPH module must be
//! enabled before calling this function.
//!
//! \param ui32Base is ADI base address.
//! \param ui32Reg is the base register to assert the bits in.
//! \param ui32Val is the 32 bit one-hot encoded value specifying which
//! bits to set in the registers.
//!
//! \return None
//!
//! \sa ADI8BitsSet(), ADI16BitsSet()
//
//*****************************************************************************
__STATIC_INLINE void
ADI32BitsSet(uint32_t ui32Base, uint32_t ui32Reg, uint32_t ui32Val)
{
    uint32_t ui32RegOffset;

    //
    // Check the arguments.
    //
    ASSERT(ADIBaseValid(ui32Base));
    ASSERT(ui32Reg < ADI_SLAVE_REGS);

    //
    // Get the correct address of the first register used for setting bits
    // in the ADI slave.
    //
    ui32RegOffset = ADI_O_SET;

    //
    // Set the selected bits.
    //
    if (ui32Base==AUX_ADI4_BASE) {
        AuxAdiDdiSafeWrite(ui32Base + ui32RegOffset + (ui32Reg & 0xFC), ui32Val, 4);
    } else {
        HWREG(ui32Base + ui32RegOffset + (ui32Reg & 0xFC)) = ui32Val;
    }
}

//*****************************************************************************
//
//! \brief Clear specific bits in an 8 bit ADI register.
//!
//! This function will clear bits in a register in the analog domain.
//! The access to the registers in the analog domain is either 8, 16 or 32 bit
//! aligned, but arranged in chunck of 32 bits. You can only do 16 bit access
//! on registers 0-1 / 2-3, etc. Similarly 32 bit accesses are always
//! performed on register 0-3 / 4-7 etc. Addresses for the registers and values
//! being written to the registers will be truncated according to this access
//! sceme.
//!
//! \note This operation is write only for the specified register.
//! This function is used to clear bits in a specific 8 bit register in
//! the ADI slave. Only bits in the selected register are affected by the
//! operation.
//!
//! \note AUX_ADI4_BASE : Both the AUX module and the clock for the AUX SMPH module must be
//! enabled before calling this function.
//!
//! \param ui32Base is ADI base address.
//! \param ui32Reg is the base registers to clear the bits in.
//! \param ui8Val is the 8 bit one-hot encoded value specifying which
//! bits to clear in the register.
//!
//! \return None
//!
//! \sa ADI16BitsClear(), ADI32BitsClear()
//
//*****************************************************************************
__STATIC_INLINE void
ADI8BitsClear(uint32_t ui32Base, uint32_t ui32Reg, uint8_t ui8Val)
{
    uint32_t ui32RegOffset;

    //
    // Check the arguments.
    //
    ASSERT(ADIBaseValid(ui32Base));
    ASSERT(ui32Reg < ADI_SLAVE_REGS);

    //
    // Get the correct address of the first register used for setting bits
    // in the ADI slave.
    //
    ui32RegOffset = ADI_O_CLR;

    //
    // Set the selected bits.
    //
    if (ui32Base==AUX_ADI4_BASE) {
        AuxAdiDdiSafeWrite(ui32Base + ui32RegOffset + ui32Reg, ui8Val, 1);
    } else {
        HWREGB(ui32Base + ui32RegOffset + ui32Reg) = ui8Val;
    }
}

//*****************************************************************************
//
//! \brief Clear specific bits in two 8 bit ADI register.
//!
//! This function will clear bits in 2 registers in the analog domain.
//! The access to the registers in the analog domain is either 8, 16 or 32 bit
//! aligned, but arranged in chunck of 32 bits. You can only do 16 bit access
//! on registers 0-1 / 2-3, etc. Similarly 32 bit accesses are always
//! performed on register 0-3 / 4-7 etc. Addresses for the registers and values
//! being written to the registers will be truncated according to this access
//! sceme.
//!
//! \note This operation is write only for the specified register.
//! This function is used to clear bits in 2 consecutive 8 bit registers in
//! the ADI slave. Only bits in the selected registers are affected by the
//! operation.
//!
//! \note AUX_ADI4_BASE : Both the AUX module and the clock for the AUX SMPH module must be
//! enabled before calling this function.
//!
//! \param ui32Base is ADI base address.
//! \param ui32Reg is the base registers to clear the bits in.
//! \param ui16Val is the 16 bit one-hot encoded value specifying which
//! bits to clear in the registers.
//!
//! \return None
//!
//! \sa ADI8BitsClear(), ADI32BitsClear()
//
//*****************************************************************************
__STATIC_INLINE void
ADI16BitsClear(uint32_t ui32Base, uint32_t ui32Reg, uint16_t ui16Val)
{
    uint32_t ui32RegOffset;

    //
    // Check the arguments.
    //
    ASSERT(ADIBaseValid(ui32Base));
    ASSERT(ui32Reg < ADI_SLAVE_REGS);

    //
    // Get the correct address of the first register used for setting bits
    // in the ADI slave.
    //
    ui32RegOffset = ADI_O_CLR;

    //
    // Set the selected bits.
    //
    if (ui32Base==AUX_ADI4_BASE) {
        AuxAdiDdiSafeWrite(ui32Base + ui32RegOffset + (ui32Reg & 0xFE), ui16Val, 2);
    } else {
        HWREGH(ui32Base + ui32RegOffset + (ui32Reg & 0xFE)) = ui16Val;
    }
}

//*****************************************************************************
//
//! \brief Clear specific bits in four 8 bit ADI register.
//!
//! This function will clear bits in 4 registers in the analog domain.
//! The access to the registers in the analog domain is either 8, 16 or 32 bit
//! aligned, but arranged in chunck of 32 bits. You can only do 16 bit access
//! on registers 0-1 / 2-3, etc. Similarly 32 bit accesses are always
//! performed on register 0-3 / 4-7 etc. Addresses for the registers and values
//! being written to the registers will be truncated according to this access
//! sceme.
//!
//! \note This operation is write only for the specified register.
//! This function is used to clear bits in 4 consecutive 8 bit registers in
//! the ADI slave. Only bits in the selected registers are affected by the
//! operation.
//!
//! \note AUX_ADI4_BASE : Both the AUX module and the clock for the AUX SMPH module must be
//! enabled before calling this function.
//!
//! \param ui32Base is ADI base address.
//! \param ui32Reg is the base registers to clear the bits in.
//! \param ui32Val is the 32 bit one-hot encoded value specifying which
//! bits to clear in the registers.
//!
//! \return None
//!
//! \sa ADI8BitsClear(), ADI16BitsClear()
//
//*****************************************************************************
__STATIC_INLINE void
ADI32BitsClear(uint32_t ui32Base, uint32_t ui32Reg, uint32_t ui32Val)
{
    uint32_t ui32RegOffset;

    //
    // Check the arguments.
    //
    ASSERT(ADIBaseValid(ui32Base));
    ASSERT(ui32Reg < ADI_SLAVE_REGS);

    //
    // Get the correct address of the first register used for setting bits
    // in the ADI slave.
    //
    ui32RegOffset = ADI_O_CLR;

    //
    // Set the selected bits.
    //
    if (ui32Base==AUX_ADI4_BASE) {
        AuxAdiDdiSafeWrite(ui32Base + ui32RegOffset + (ui32Reg & 0xFC), ui32Val, 4);
    } else {
        HWREG(ui32Base + ui32RegOffset + (ui32Reg & 0xFC)) = ui32Val;
    }
}

//*****************************************************************************
//
//! \brief Set a value on any 4 bits inside an 8 bit register in the ADI slave.
//!
//! This function allows halfbyte (4 bit) access to the ADI slave registers.
//! The parameter \c bWriteHigh determines whether to write to the lower
//! or higher part of the 8 bit register.
//!
//! Use this function to write any value in the range 0-3 bits aligned on a
//! half byte boundary. Fx. for writing the value 0b101 to bits 1 to 3 the
//! \c ui8Val = 0xA and the \c ui8Mask = 0xE. Bit 0 will not be affected by
//! the operation, as the corresponding bit is not set in the \c ui8Mask.
//!
//! \note AUX_ADI4_BASE : Both the AUX module and the clock for the AUX SMPH module must be
//! enabled before calling this function.
//!
//! \param ui32Base is the base address of the ADI port.
//! \param ui32Reg is the Least Significant Register in the ADI slave that
//! will be affected by the write operation.
//! \param bWriteHigh defines which part of the register to write in.
//! - \c true: Write upper half byte of register.
//! - \c false: Write lower half byte of register.
//! \param ui8Mask is the mask defining which of the 4 bits that should be
//! overwritten. The mask must be defined in the lower half of the 8 bits of
//! the parameter.
//! \param ui8Val is the value to write. The value must be defined in the lower
//! half of the 8 bits of the parameter.
//!
//! \return None
//!
//! \sa ADI8SetValBit(), ADI16SetValBit
//
//*****************************************************************************
__STATIC_INLINE void
ADI4SetValBit(uint32_t ui32Base, uint32_t ui32Reg, bool bWriteHigh,
              uint8_t ui8Mask, uint8_t ui8Val)
{
    uint32_t ui32RegOffset;

    //
    // Check the arguments.
    //
    ASSERT(ADIBaseValid(ui32Base));
    ASSERT(ui32Reg < ADI_SLAVE_REGS);
    ASSERT(!(ui8Val & 0xF0));
    ASSERT(!(ui8Mask & 0xF0));

    //
    // Get the correct address of the first register used for setting bits
    // in the ADI slave.
    //
    ui32RegOffset = ADI_O_MASK4B + (ui32Reg << 1) + (bWriteHigh ? 1 : 0);

    //
    // Set the selected bits.
    //
    if (ui32Base==AUX_ADI4_BASE) {
        AuxAdiDdiSafeWrite(ui32Base + ui32RegOffset, (ui8Mask << 4) | ui8Val, 1);
    } else {
        HWREGB(ui32Base + ui32RegOffset) = (ui8Mask << 4) | ui8Val;
    }
}

//*****************************************************************************
//
//! \brief Set a value on any bits inside an 8 bit register in the ADI slave.
//!
//! This function allows byte (8 bit) access to the ADI slave registers.
//!
//! Use this function to write any value in the range 0-7 bits aligned on a
//! byte boundary. Fx. for writing the value 0b101 to bits 1 and 3 the
//! \c ui16Val = 0x0A and the \c ui16Mask = 0x0E. Bits 0 and 5-7 will not be affected
//! by the operation, as the corresponding bits are not set in the
//! \c ui16Mask.
//!
//! \note AUX_ADI4_BASE : Both the AUX module and the clock for the AUX SMPH module must be
//! enabled before calling this function.
//!
//! \param ui32Base is the base address of the ADI port.
//! \param ui32Reg is the Least Significant Register in the ADI slave that
//! will be affected by the write operation.
//! \param ui16Mask is the mask defining which of the 8 bit that should be
//! overwritten. The mask must be defined in the lower half of the 16 bits.
//! \param ui16Val is the value to write. The value must be defined in the lower
//! half of the 16 bits.
//!
//! \return None
//!
//! \sa ADI4SetValBit(), ADI16SetValBit()
//
//*****************************************************************************
__STATIC_INLINE void
ADI8SetValBit(uint32_t ui32Base, uint32_t ui32Reg, uint16_t ui16Mask,
              uint16_t ui16Val)
{
    uint32_t ui32RegOffset;

    //
    // Check the arguments.
    //
    ASSERT(ADIBaseValid(ui32Base));
    ASSERT(ui32Reg < ADI_SLAVE_REGS);
    ASSERT(!(ui16Val & 0xFF00));
    ASSERT(!(ui16Mask & 0xFF00));

    //
    // Get the correct address of the first register used for setting bits
    // in the ADI slave.
    //
    ui32RegOffset = ADI_O_MASK8B + (ui32Reg << 1);

    //
    // Set the selected bits.
    //
    if (ui32Base==AUX_ADI4_BASE) {
        AuxAdiDdiSafeWrite(ui32Base + ui32RegOffset, (ui16Mask << 8) | ui16Val, 2);
    } else {
        HWREGH(ui32Base + ui32RegOffset) = (ui16Mask << 8) | ui16Val;
    }
}

//*****************************************************************************
//
//! \brief Set a value on any bits inside an 2 x 8 bit register aligned on a
//! half-word (byte) boundary in the ADI slave.
//!
//! This function allows 2 byte (16 bit) access to the ADI slave registers.
//!
//! Use this function to write any value in the range 0-15 bits aligned on a
//! half-word (byte) boundary. Fx. for writing the value 0b101 to bits 1 and 3 the
//! \c ui32Val = 0x000A and the \c ui32Mask = 0x000E. Bits 0 and 5-15 will not
//! be affected by the operation, as the corresponding bits are not set
//! in the \c ui32Mask.
//!
//! \note AUX_ADI4_BASE : Both the AUX module and the clock for the AUX SMPH module must be
//! enabled before calling this function.
//!
//! \param ui32Base is the base address of the ADI port.
//! \param ui32Reg is the Least Significant Register in the ADI slave that
//! will be affected by the write operation.
//! \param ui32Mask is the mask defining which of the 16 bit that should be
//! overwritten. The mask must be defined in the lower half of the 32 bits.
//! \param ui32Val is the value to write. The value must be defined in the lower
//! half of the 32 bits.
//!
//! \return None
//!
//! \sa ADI4SetValBit(), ADI8SetValBit()
//
//*****************************************************************************
__STATIC_INLINE void
ADI16SetValBit(uint32_t ui32Base, uint32_t ui32Reg, uint32_t ui32Mask,
               uint32_t ui32Val)
{
    uint32_t ui32RegOffset;

    //
    // Check the arguments.
    //
    ASSERT(ADIBaseValid(ui32Base));
    ASSERT(ui32Reg < ADI_SLAVE_REGS);
    ASSERT(!(ui32Val & 0xFFFF0000));
    ASSERT(!(ui32Mask & 0xFFFF0000));

    //
    // Get the correct address of the first register used for setting bits
    // in the ADI slave.
    //
    ui32RegOffset = ADI_O_MASK16B + ((ui32Reg << 1) & 0xFC);

    //
    // Set the selected bits.
    //
    if (ui32Base==AUX_ADI4_BASE) {
        AuxAdiDdiSafeWrite(ui32Base + ui32RegOffset, (ui32Mask << 16) | ui32Val, 4);
    } else {
        HWREG(ui32Base + ui32RegOffset) = (ui32Mask << 16) | ui32Val;
    }
}

//*****************************************************************************
//
// Mark the end of the C bindings section for C++ compilers.
//
//*****************************************************************************
#ifdef __cplusplus
}
#endif

#endif //  __ADI_H__

//*****************************************************************************
//
//! Close the Doxygen group.
//! @}
//
//*****************************************************************************
