/******************************************************************************
*
* Copyright (C) 2016 Xilinx, Inc.  All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xsysmonpsu.c
*
* Functions in this file are the minimum required functions for the XSysMonPsu
* driver. See xsysmonpsu.h for a detailed description of the driver.
*
* @note 	None.
*
* <pre>
*
* MODIFICATION HISTORY:
*
* Ver   Who    Date	    Changes
* ----- -----  -------- -----------------------------------------------
* 1.0   kvn    12/15/15 First release.
*              02/15/16 Corrected Assert function call in
*                       XSysMonPsu_GetMonitorStatus API.
*              03/03/16 Added Temperature remote channel for Setsingle
*                       channel API. Also corrected external mux channel
*                       numbers.
* 1.1   kvn    05/05/16 Modified code for MISRA-C:2012 Compliance.
* 2.0   vns    08/14/16 Fixed CR #956780, added support for enabling/disabling
*                       SEQ_CH2 and SEQ_AVG2 registers, modified function
*                       prototypes of XSysMonPsu_GetSeqAvgEnables,
*                       XSysMonPsu_SetSeqAvgEnables, XSysMonPsu_SetSeqChEnables,
*                       XSysMonPsu_GetSeqChEnables,
*                       XSysMonPsu_SetSeqInputMode, XSysMonPsu_GetSeqInputMode,
*                       XSysMonPsu_SetSeqAcqTime
*                       and XSysMonPsu_GetSeqAcqTime to provide support for
*                       set/get 64 bit value.
* 2.1   sk     03/03/16 Check for PL reset before doing PL Sysmon reset.
* 2.3   mn     12/13/17 Correct the AMS block channel numbers
*       mn     03/08/18 Update Clock Divisor to the proper value
*
* </pre>
*
******************************************************************************/

/***************************** Include Files *********************************/

#include "xsysmonpsu.h"

/************************** Constant Definitions ****************************/

/**************************** Type Definitions ******************************/

/***************** Macros (Inline Functions) Definitions ********************/

/************************** Function Prototypes *****************************/

static void XSysMonPsu_StubHandler(void *CallBackRef);

/************************** Variable Definitions ****************************/

/*****************************************************************************/
/**
*
* This function initializes XSysMonPsu device/instance. This function
* must be called prior to using the System Monitor device.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	ConfigPtr points to the XSysMonPsu device configuration structure.
* @param	EffectiveAddr is the device base address in the virtual memory
*		address space. If the address translation is not used then the
*		physical address is passed.
*		Unexpected errors may occur if the address mapping is changed
*		after this function is invoked.
*
* @return
*		- XST_SUCCESS if successful.
*
* @note		The user needs to first call the XSysMonPsu_LookupConfig() API
*		which returns the Configuration structure pointer which is
*		passed as a parameter to the XSysMonPsu_CfgInitialize() API.
*
******************************************************************************/
s32 XSysMonPsu_CfgInitialize(XSysMonPsu *InstancePtr, XSysMonPsu_Config *ConfigPtr,
			  u32 EffectiveAddr)
{
	u32 PsSysmonControlStatus;
	u32 PlSysmonControlStatus;
	u32 IntrStatus;

	/* Assert the input arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(ConfigPtr != NULL);

	/* Set the values read from the device config and the base address. */
	InstancePtr->Config.DeviceId = ConfigPtr->DeviceId;
	InstancePtr->Config.BaseAddress = EffectiveAddr;
	InstancePtr->Config.InputClockMHz = ConfigPtr->InputClockMHz;

	/* Set all handlers to stub values, let user configure this data later. */
	InstancePtr->Handler = XSysMonPsu_StubHandler;

	XSysMonPsu_UpdateAdcClkDivisor(InstancePtr, XSYSMON_PS);
	XSysMonPsu_UpdateAdcClkDivisor(InstancePtr, XSYSMON_PL);

	/* Reset the device such that it is in a known state. */
	XSysMonPsu_Reset(InstancePtr);

	PsSysmonControlStatus = XSysmonPsu_ReadReg(InstancePtr->Config.BaseAddress +
			XSYSMONPSU_PS_SYSMON_CSTS_OFFSET);

	/* Check if the PS Sysmon is in Idle / ready state or not */
	while(PsSysmonControlStatus != XSYSMONPSU_PS_SYSMON_READY) {
		PsSysmonControlStatus = XSysmonPsu_ReadReg(InstancePtr->Config.BaseAddress +
					XSYSMONPSU_PS_SYSMON_CSTS_OFFSET);
	}

	PlSysmonControlStatus = XSysmonPsu_ReadReg(InstancePtr->Config.BaseAddress +
			XSYSMONPSU_PL_SYSMON_CSTS_OFFSET);

	/* Check if the PL Sysmon is accessible to PS Sysmon or not */
	while((PlSysmonControlStatus & XSYSMONPSU_PL_SYSMON_CSTS_ACESBLE_MASK)
				!= XSYSMONPSU_PL_SYSMON_CSTS_ACESBLE_MASK) {
		PlSysmonControlStatus = XSysmonPsu_ReadReg(InstancePtr->Config.BaseAddress +
					XSYSMONPSU_PL_SYSMON_CSTS_OFFSET);
	}

	/* Indicate the instance is now ready to use, initialized without error */
	InstancePtr->IsReady = XIL_COMPONENT_IS_READY;

	/* Clear any bits set in the Interrupt Status Register. */
	IntrStatus = XSysMonPsu_IntrGetStatus(InstancePtr);
	XSysMonPsu_IntrClear(InstancePtr, IntrStatus);

	return XST_SUCCESS;
}

/****************************************************************************/
/**
*
* This function is a stub handler that is the default handler such that if the
* application has not set the handler when interrupts are enabled, this
* function will be called.
*
* @param	CallBackRef is unused by this function.
*
* @return	None.
*
* @note		None.
*
*****************************************************************************/
static void XSysMonPsu_StubHandler(void *CallBackRef)
{
	(void) CallBackRef;

	/* Assert occurs always since this is a stub and should never be called */
	Xil_AssertVoidAlways();
}

/*****************************************************************************/
/**
*
* This function resets the SystemMonitor
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
*
* @return	None.
*
* @note		Upon reset, all Maximum and Minimum status registers will be
*		reset to their default values. Currently running and any averaging
*		will restart. Refer to the device data sheet for the device status and
*		register values after the reset.
*
******************************************************************************/
void XSysMonPsu_Reset(XSysMonPsu *InstancePtr)
{
	u8 IsPlReset;
	/* Assert the arguments. */
	Xil_AssertVoid(InstancePtr != NULL);

	/* RESET the PS SYSMON */
	XSysmonPsu_WriteReg(InstancePtr->Config.BaseAddress + XPS_BA_OFFSET +
			XSYSMONPSU_VP_VN_OFFSET, XSYSMONPSU_VP_VN_MASK);

	/* Check for PL is under reset or not */
	IsPlReset = (XSysmonPsu_ReadReg(CSU_BASEADDR + PCAP_STATUS_OFFSET) &
						PL_CFG_RESET_MASK) >> PL_CFG_RESET_SHIFT;
	if (IsPlReset != 0U) {
		/* RESET the PL SYSMON */
		XSysmonPsu_WriteReg(InstancePtr->Config.BaseAddress + XPL_BA_OFFSET +
				XSYSMONPSU_VP_VN_OFFSET, XSYSMONPSU_VP_VN_MASK);
	}

}

/****************************************************************************/
/**
*
* This function reads the contents of the Status Register.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @return	A 32-bit value representing the contents of the Status Register.
*		Use the XSYSMONPSU_MON_STS_* constants defined in xsysmonpsu_hw.h to
*		interpret the returned value.
*
* @note		None.
*****************************************************************************/
u32 XSysMonPsu_GetStatus(XSysMonPsu *InstancePtr, u32 SysmonBlk)
{
	u32 Status;
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/* Read the Sysmon Status Register and return the value. */
	Status = XSysmonPsu_ReadReg(EffectiveBaseAddress + XSYSMONPSU_MON_STS_OFFSET);

	return Status;
}

/****************************************************************************/
/**
*
* This function starts the ADC conversion in the Single Channel event driven
* sampling mode. The EOC bit in Status Register will be set once the conversion
* is finished. Refer to the device specification for more details.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
*
* @return	None.
*
* @note		The default state of the CONVST bit is a logic 0. The conversion
*		is started when the CONVST bit is set to 1 from 0.
*		This bit is self-clearing so that the next conversion
*		can be started by setting this bit.
*
*****************************************************************************/
void XSysMonPsu_StartAdcConversion(XSysMonPsu *InstancePtr)
{
	u32 ControlStatus;

	/* Assert the arguments. */
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	/*
	 * Start the conversion by setting the CONVST bit to 1 only if auto-convst
	 * bit is not enabled. This convst bit is self-clearing.
	 */
	ControlStatus = XSysmonPsu_ReadReg(InstancePtr->Config.BaseAddress +
			XSYSMONPSU_PS_SYSMON_CSTS_OFFSET);

	if ((ControlStatus & XSYSMONPSU_PS_SYSMON_CSTS_AUTO_CONVST_MASK )
			!= XSYSMONPSU_PS_SYSMON_CSTS_AUTO_CONVST_MASK) {
		XSysmonPsu_WriteReg(InstancePtr->Config.BaseAddress +
					XSYSMONPSU_PS_SYSMON_CSTS_OFFSET,
					(ControlStatus | (u32)XSYSMONPSU_PS_SYSMON_CSTS_CONVST_MASK));
	}
}

/****************************************************************************/
/**
*
* Get the ADC converted data for the specified channel.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	Channel is the channel number. Use the XSM_CH_* defined in
*		the file xsysmonpsu.h. The valid channels for PS / PL SysMon are 0 - 6,
*		8 - 10 and 13 - 37. For AMS, 38 - 53 channels are valid.
* @param	Block is the value that tells whether it is for PS Sysmon block
*       or PL Sysmon block or the AMS controller register region.
*
* @return	A 16-bit value representing the ADC converted data for the
*		specified channel. The System Monitor device guarantees
* 		a 10 bit resolution for the ADC converted data and data is the
*		10 MSB bits of the 16 data read from the device.
*
* @note		Please make sure that the proper channel number is passed.
*
*****************************************************************************/
u16 XSysMonPsu_GetAdcData(XSysMonPsu *InstancePtr, u8 Channel, u32 Block)
{
	u16 AdcData;
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid((Channel <= XSM_CH_SUPPLY3) ||
			  ((Channel >= XSM_CH_SUPPLY_CALIB) &&
			  (Channel <= XSM_CH_GAINERR_CALIB)) ||
			  ((Channel >= XSM_CH_SUPPLY4) &&
			  (Channel <= XSM_CH_RESERVE1)));
	Xil_AssertNonvoid((Block == XSYSMON_PS)||(Block == XSYSMON_PL)
						||(Block == XSYSMON_AMS));

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					Block);

	/*
	 * Read the selected ADC converted data for the specified channel
	 * and return the value.
	 */
	if (Channel <= XSM_CH_AUX_MAX) {
		AdcData = (u16) (XSysmonPsu_ReadReg(EffectiveBaseAddress + ((u32)Channel << 2U)));
	} else if ((Channel >= XSM_CH_SUPPLY7) && (Channel <= XSM_CH_TEMP_REMTE)){
		AdcData = (u16) (XSysmonPsu_ReadReg(EffectiveBaseAddress + XSM_ADC_CH_OFFSET +
				(((u32)Channel - XSM_CH_SUPPLY7) << 2U)));
	} else {
		AdcData = (u16) (XSysmonPsu_ReadReg(EffectiveBaseAddress + XSM_AMS_CH_OFFSET +
				(((u32)Channel - XSM_CH_VCC_PSLL0) << 2U)));
	}

	return AdcData;
}

/****************************************************************************/
/**
*
* This function gets the calibration coefficient data for the specified
* parameter.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	CoeffType specifies the calibration coefficient
*		to be read. Use XSM_CALIB_* constants defined in xsysmonpsu.h to
*		specify the calibration coefficient to be read.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @return	A 16-bit value representing the calibration coefficient.
*		The System Monitor device guarantees a 10 bit resolution for
*		the ADC converted data and data is the 10 MSB bits of the 16
*		data read from the device.
*
* @note		None.
*
*****************************************************************************/
u16 XSysMonPsu_GetCalibCoefficient(XSysMonPsu *InstancePtr, u8 CoeffType,
		u32 SysmonBlk)
{
	u16 CalibData;
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid(CoeffType <= XSM_CALIB_GAIN_ERROR_COEFF);
	Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/* Read the selected calibration coefficient. */
	CalibData = (u16) XSysmonPsu_ReadReg(EffectiveBaseAddress +
			XSYSMONPSU_CAL_SUP_OFF_OFFSET + ((u32)CoeffType << 2U));

	return CalibData;
}

/****************************************************************************/
/**
*
* This function reads the Minimum/Maximum measurement for one of the
* XSM_MIN_* or XSM_MAX_* constants defined in xsysmonpsu.h
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	MeasurementType specifies the parameter for which the
*		Minimum/Maximum measurement has to be read.
*		Use XSM_MAX_* and XSM_MIN_* constants defined in xsysmonpsu.h to
*		specify the data to be read.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @return	A 16-bit value representing the maximum/minimum measurement for
*		specified parameter.
*		The System Monitor device guarantees a 10 bit resolution for
*		the ADC converted data and data is the 10 MSB bits of  16 bit
*		data read from the device.
*
*****************************************************************************/
u16 XSysMonPsu_GetMinMaxMeasurement(XSysMonPsu *InstancePtr, u8 MeasurementType,
		u32 SysmonBlk)
{
	u16 MinMaxData;
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid((MeasurementType <= XSM_MAX_SUPPLY6) ||
			((MeasurementType >= XSM_MIN_SUPPLY4) &&
			(MeasurementType <= XSM_MIN_SUPPLY6)) ||
			((MeasurementType >= XSM_MAX_SUPPLY7) &&
			(MeasurementType <= XSM_MAX_TEMP_REMOTE)) ||
			((MeasurementType >= XSM_MIN_SUPPLY7) &&
			(MeasurementType <= XSM_MIN_TEMP_REMOTE)));
	Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/* Read and return the specified Minimum/Maximum measurement. */
	MinMaxData = (u16) (XSysmonPsu_ReadReg(EffectiveBaseAddress +
							XSM_MIN_MAX_CH_OFFSET + ((u32)MeasurementType << 2U)));

	return MinMaxData;
}

/****************************************************************************/
/**
*
* This function sets the number of samples of averaging that is to be done for
* all the channels in both the single channel mode and sequence mode of
* operations.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	Average is the number of samples of averaging programmed to the
*		Configuration Register 0. Use the XSM_AVG_* definitions defined
*		in xsysmonpsu.h file :
*		- XSM_AVG_0_SAMPLES for no averaging
*		- XSM_AVG_16_SAMPLES for 16 samples of averaging
*		- XSM_AVG_64_SAMPLES for 64 samples of averaging
*		- XSM_AVG_256_SAMPLES for 256 samples of averaging
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @return	None.
*
* @note		None.
*
*****************************************************************************/
void XSysMonPsu_SetAvg(XSysMonPsu *InstancePtr, u8 Average, u32 SysmonBlk)
{
	u32 RegValue;
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertVoid(Average <= XSM_AVG_256_SAMPLES);
	Xil_AssertVoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/* Write the averaging value into the Configuration Register 0. */
	RegValue = XSysmonPsu_ReadReg(EffectiveBaseAddress + XSYSMONPSU_CFG_REG0_OFFSET)
						& (u32)(~XSYSMONPSU_CFG_REG0_AVRGNG_MASK);
	RegValue |= (((u32) Average << XSYSMONPSU_CFG_REG0_AVRGNG_SHIFT));
	XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_CFG_REG0_OFFSET,
			 RegValue);
}

/****************************************************************************/
/**
*
* This function returns the number of samples of averaging configured for all
* the channels in the Configuration Register 0.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @return	The averaging read from the Configuration Register 0 is
*		returned. Use the XSM_AVG_* bit definitions defined in xsysmonpsu.h
*		file to interpret the returned value :
*		- XSM_AVG_0_SAMPLES means no averaging
*		- XSM_AVG_16_SAMPLES means 16 samples of averaging
*		- XSM_AVG_64_SAMPLES means 64 samples of averaging
*		- XSM_AVG_256_SAMPLES means 256 samples of averaging
*
* @note		None.
*
*****************************************************************************/
u8 XSysMonPsu_GetAvg(XSysMonPsu *InstancePtr, u32 SysmonBlk)
{
	u32 Average;
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/* Read the averaging value from the Configuration Register 0. */
	Average = XSysmonPsu_ReadReg(EffectiveBaseAddress +
				XSYSMONPSU_CFG_REG0_OFFSET) & XSYSMONPSU_CFG_REG0_AVRGNG_MASK;

	return (u8)(Average >> XSYSMONPSU_CFG_REG0_AVRGNG_SHIFT);
}

/****************************************************************************/
/**
*
* The function sets the given parameters in the Configuration Register 0 in
* the single channel mode.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	Channel is the channel number for conversion. The valid
*		channels are 0 - 6, 8 - 10, 13 - 37.
* @param	IncreaseAcqCycles is a boolean parameter which specifies whether
*		the Acquisition time for the external channels has to be
*		increased to 10 ADCCLK cycles (specify TRUE) or remain at the
*		default 4 ADCCLK cycles (specify FALSE). This parameter is
*		only valid for the external channels.
* @param	IsEventMode is a boolean parameter that specifies continuous
*		sampling (specify FALSE) or event driven sampling mode (specify
*		TRUE) for the given channel.
* @param	IsDifferentialMode is a boolean parameter which specifies
*		unipolar(specify FALSE) or differential mode (specify TRUE) for
*		the analog inputs. The 	input mode is only valid for the
*		external channels.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @return
*		- XST_SUCCESS if the given values were written successfully to
*		the Configuration Register 0.
*		- XST_FAILURE if the channel sequencer is enabled or the input
*		parameters are not valid for the selected channel.
*
* @note
*		- The number of samples for the averaging for all the channels
*		is set by using the function XSysMonPsu_SetAvg.
*		- The calibration of the device is done by doing a ADC
*		conversion on the calibration channel(channel 8). The input
*		parameters IncreaseAcqCycles, IsDifferentialMode and
*		IsEventMode are not valid for this channel.
*
*****************************************************************************/
s32 XSysMonPsu_SetSingleChParams(XSysMonPsu *InstancePtr, u8 Channel,
				u32 IncreaseAcqCycles, u32 IsEventMode,
				u32 IsDifferentialMode, u32 SysmonBlk)
{
	u32 RegValue;
	u32 EffectiveBaseAddress;
	s32 Status;

	/* Assert the arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid((Channel <= XSM_CH_SUPPLY3) ||
			  ((Channel >= XSM_CH_SUPPLY_CALIB) &&
			  (Channel <= XSM_CH_GAINERR_CALIB)) ||
			  ((Channel >= XSM_CH_SUPPLY4) &&
			  (Channel <= XSM_CH_TEMP_REMTE)) ||
			  ((Channel >= XSM_CH_VCC_PSLL0) &&
			  (Channel <= XSM_CH_RESERVE1)));
	Xil_AssertNonvoid((IncreaseAcqCycles == TRUE) ||
			  (IncreaseAcqCycles == FALSE));
	Xil_AssertNonvoid((IsEventMode == TRUE) || (IsEventMode == FALSE));
	Xil_AssertNonvoid((IsDifferentialMode == TRUE) ||
			  (IsDifferentialMode == FALSE));
	Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/* Check if the device is in single channel mode else return failure */
	if ((XSysMonPsu_GetSequencerMode(InstancePtr, SysmonBlk)
				!= XSM_SEQ_MODE_SINGCHAN)) {
		Status = (s32)XST_FAILURE;
		goto End;
	}

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/* Read the Configuration Register 0 and extract out Averaging value. */
	RegValue = XSysmonPsu_ReadReg(EffectiveBaseAddress +
			XSYSMONPSU_CFG_REG0_OFFSET) & XSYSMONPSU_CFG_REG0_AVRGNG_MASK;

	/*
	 * Select the number of acquisition cycles. The acquisition cycles is
	 * only valid for the external channels.
	 */
	if (IncreaseAcqCycles == TRUE) {
		if (((Channel >= XSM_CH_AUX_MIN) && (Channel <= XSM_CH_AUX_MAX))
		    || (Channel == XSM_CH_VPVN)) {
			RegValue |= XSYSMONPSU_CFG_REG0_ACQ_MASK;
		} else {
			Status = (s32)XST_FAILURE;
			goto End;
		}
	}

	/*
	 * Select the input mode. The input mode is only valid for the
	 * external channels.
	 */
	if (IsDifferentialMode == TRUE) {

		if (((Channel >= XSM_CH_AUX_MIN) && (Channel <= XSM_CH_AUX_MAX))
		    || (Channel == XSM_CH_VPVN)) {
			RegValue |= XSYSMONPSU_CFG_REG0_BU_MASK;
		} else {
			Status = (s32)XST_FAILURE;
			goto End;
		}
	}

	/* Select the ADC mode. */
	if (IsEventMode == TRUE) {
		RegValue |= XSYSMONPSU_CFG_REG0_EC_MASK;
	}

	/* Write the given values into the Configuration Register 0. */
	RegValue |= ((u32)Channel & XSYSMONPSU_CFG_REG0_MUX_CH_MASK);
	XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_CFG_REG0_OFFSET,
			 RegValue);

	Status = (s32)XST_SUCCESS;

End:
	return Status;
}

/****************************************************************************/
/**
*
* This function enables the alarm outputs for the specified alarms in the
* Configuration Registers 1:
*
*		- OT for Over Temperature (XSYSMONPSU_CFR_REG1_ALRM_OT_MASK)
*		- ALM0 for On board Temperature (XSYSMONPSU_CFR_REG1_ALRM_TEMP_MASK)
*		- ALM1 for SUPPLY1 (XSYSMONPSU_CFR_REG1_ALRM_SUPPLY1_MASK)
*		- ALM2 for SUPPLY2 (XSYSMONPSU_CFR_REG1_ALRM_SUPPLY2_MASK)
* 		- ALM3 for SUPPLY3 (XSYSMONPSU_CFR_REG1_ALRM_SUPPLY3_MASK)
* 		- ALM4 for SUPPLY4 (XSYSMONPSU_CFR_REG1_ALRM__SUPPLY4_MASK)
*		- ALM5 for SUPPLY5 (XSYSMONPSU_CFR_REG1_ALRM_SUPPLY5_MASK)
* 		- ALM6 for SUPPLY6 (XSYSMONPSU_CFR_REG1_ALRM_SUPPLY6_MASK)
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	AlmEnableMask is the bit-mask of the alarm outputs to be enabled
*		in the Configuration Registers 1 and 3.
*		Bit positions of 1 will be enabled. Bit positions of 0 will be
*		disabled. This mask is formed by OR'ing XSYSMONPSU_CFR_REG1_ALRM_*_MASK
*		masks defined in xsysmonpsu.h, but XSM_CFR_ALM_SUPPLY8_MASK to
*		XSM_CFR_ALM_SUPPLY13_MASK are applicable only for PS.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @return	None.
*
* @note		The implementation of the alarm enables in the Configuration
*		register 1 is such that the alarms for bit positions of 0 will
*		be enabled and alarms for bit positions of 1 will be disabled.
*		The alarm outputs specified by the AlmEnableMask are negated
*		before writing to the Configuration Register 1 because it
*		was Disable register bits.
*		Upper 16 bits of AlmEnableMask are applicable only for PS.
*
*****************************************************************************/
void XSysMonPsu_SetAlarmEnables(XSysMonPsu *InstancePtr, u32 AlmEnableMask,
		u32 SysmonBlk)
{
	u32 RegValue;
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertVoid(AlmEnableMask <=
			(XSYSMONPSU_CFG_REG1_ALRM_ALL_MASK |
			(XSYSMONPSU_CFG_REG3_ALRM_ALL_MASK << XSM_CFG_ALARM_SHIFT)));
	Xil_AssertVoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	RegValue = XSysmonPsu_ReadReg(EffectiveBaseAddress +
					XSYSMONPSU_CFG_REG1_OFFSET);
	RegValue &= (u32)(~XSYSMONPSU_CFG_REG1_ALRM_ALL_MASK);
	RegValue |= (~AlmEnableMask & (u32)XSYSMONPSU_CFG_REG1_ALRM_ALL_MASK);

	/*
	 * Enable/disables the alarm enables for the specified alarm bits in the
	 * Configuration Register 1.
	 */
	XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_CFG_REG1_OFFSET,
			 RegValue);
	/* Upper 16 bits of AlmEnableMask are valid only for PS */
	if (SysmonBlk == XSYSMON_PS) {
		RegValue = XSysmonPsu_ReadReg(EffectiveBaseAddress +
					XSYSMONPSU_CFG_REG3_OFFSET);
		RegValue &= (u32)(~XSYSMONPSU_CFG_REG3_ALRM_ALL_MASK);
		RegValue |= (~(AlmEnableMask >> XSM_CFG_ALARM_SHIFT) &
				(u32)XSYSMONPSU_CFG_REG3_ALRM_ALL_MASK);
		XSysmonPsu_WriteReg(EffectiveBaseAddress +
			XSYSMONPSU_CFG_REG3_OFFSET, RegValue);
	}
}

/****************************************************************************/
/**
*
* This function gets the status of the alarm output enables in the
* Configuration Register 1.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @return	This is the bit-mask of the enabled alarm outputs in the
*		Configuration Register 1. Use the masks XSYSMONPSU_CFG_REG1_ALRM_*_MASK
*		masks defined in xsysmonpsu.h to interpret the returned value.
*
*		Bit positions of 1 indicate that the alarm output is enabled.
*		Bit positions of 0 indicate that the alarm output is disabled.
*
*
* @note		The implementation of the alarm enables in the Configuration
*		register 1 is such that alarms for the bit positions of 1 will
*		be disabled and alarms for bit positions of 0 will be enabled.
*		The enabled alarm outputs returned by this function is the
*		negated value of the the data read from the Configuration
*		Register 1. Upper 16 bits of return value are valid only if the
*		channel selected is PS.
*
*****************************************************************************/
u32 XSysMonPsu_GetAlarmEnables(XSysMonPsu *InstancePtr, u32 SysmonBlk)
{
	u32 RegValue;
	u32 EffectiveBaseAddress;
	u32 ReadReg;

	/* Assert the arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/*
	 * Read the status of alarm output enables from the Configuration
	 * Register 1.
	 */
	RegValue = XSysmonPsu_ReadReg(EffectiveBaseAddress +
			XSYSMONPSU_CFG_REG1_OFFSET) & XSYSMONPSU_CFG_REG1_ALRM_ALL_MASK;
	RegValue = (~RegValue & XSYSMONPSU_CFG_REG1_ALRM_ALL_MASK);

	if (SysmonBlk == XSYSMON_PS) {
		ReadReg = XSysmonPsu_ReadReg(EffectiveBaseAddress +
			XSYSMONPSU_CFG_REG3_OFFSET) & XSYSMONPSU_CFG_REG3_ALRM_ALL_MASK;
		ReadReg = (~ReadReg & XSYSMONPSU_CFG_REG3_ALRM_ALL_MASK);
		RegValue |= ReadReg << XSM_CFG_ALARM_SHIFT;
	}

	return RegValue;
}

/****************************************************************************/
/**
*
* This function sets the specified Channel Sequencer Mode in the Configuration
* Register 1 :
*		- Default safe mode (XSM_SEQ_MODE_SAFE)
*		- One pass through sequence (XSM_SEQ_MODE_ONEPASS)
*		- Continuous channel sequencing (XSM_SEQ_MODE_CONTINPASS)
*		- Single Channel/Sequencer off (XSM_SEQ_MODE_SINGCHAN)
*		- Olympus sampling mode (XSM_SEQ_MODE_OYLMPUS)
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	SequencerMode is the sequencer mode to be set.
*		Use XSM_SEQ_MODE_* bits defined in xsysmonpsu.h.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @return	None.
*
* @note		Only one of the modes can be enabled at a time.
*
*****************************************************************************/
void XSysMonPsu_SetSequencerMode(XSysMonPsu *InstancePtr, u8 SequencerMode,
		u32 SysmonBlk)
{
	u32 RegValue;
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertVoid((SequencerMode <= XSM_SEQ_MODE_SINGCHAN) ||
			(SequencerMode == XSM_SEQ_MODE_OYLMPUS));
	Xil_AssertVoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/* Set the specified sequencer mode in the Configuration Register 1. */
	RegValue = XSysmonPsu_ReadReg(EffectiveBaseAddress +
					XSYSMONPSU_CFG_REG1_OFFSET);
	RegValue &= (u32)(~ XSYSMONPSU_CFG_REG1_SEQ_MDE_MASK);
	RegValue |= (((u32)SequencerMode  << XSYSMONPSU_CFG_REG1_SEQ_MDE_SHIFT) &
					XSYSMONPSU_CFG_REG1_SEQ_MDE_MASK);
	XSysmonPsu_WriteReg(EffectiveBaseAddress +
					XSYSMONPSU_CFG_REG1_OFFSET, RegValue);
}

/****************************************************************************/
/**
*
* This function gets the channel sequencer mode from the Configuration
* Register 1.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @return	The channel sequencer mode :
*		- XSM_SEQ_MODE_SAFE : Default safe mode
*		- XSM_SEQ_MODE_ONEPASS : One pass through sequence
*		- XSM_SEQ_MODE_CONTINPASS : Continuous channel sequencing
*		- XSM_SEQ_MODE_SINGCHAN : Single channel/Sequencer off
*		- XSM_SEQ_MODE_OLYMPUS : Olympus sampling mode
*
* @note		None.
*
*****************************************************************************/
u8 XSysMonPsu_GetSequencerMode(XSysMonPsu *InstancePtr, u32 SysmonBlk)
{
	u8 SequencerMode;
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/* Read the channel sequencer mode from the Configuration Register 1. */
	SequencerMode =  ((u8) ((XSysmonPsu_ReadReg(EffectiveBaseAddress +
			XSYSMONPSU_CFG_REG1_OFFSET) & XSYSMONPSU_CFG_REG1_SEQ_MDE_MASK) >>
			XSYSMONPSU_CFG_REG1_SEQ_MDE_SHIFT));

	return SequencerMode;
}

/****************************************************************************/
/**
*
* The function enables the Event mode or Continuous mode in the sequencer mode.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	IsEventMode is a boolean parameter that specifies continuous
*		sampling (specify FALSE) or event driven sampling mode (specify
*		TRUE) for the channel.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @return	None.
*
* @note		None.
*
*****************************************************************************/
void XSysMonPsu_SetSequencerEvent(XSysMonPsu *InstancePtr, u32 IsEventMode,
		u32 SysmonBlk)
{
	u32 RegValue;
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertVoid((IsEventMode == TRUE) || (IsEventMode == FALSE));
	Xil_AssertVoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/* Read the Configuration Register 0. */
	RegValue = XSysmonPsu_ReadReg(EffectiveBaseAddress +
					XSYSMONPSU_CFG_REG0_OFFSET);

	/* Set the ADC mode. */
	if (IsEventMode == TRUE) {
		RegValue |= XSYSMONPSU_CFG_REG0_EC_MASK;
	} else {
		RegValue &= (u32)(~XSYSMONPSU_CFG_REG0_EC_MASK);
	}

	XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_CFG_REG0_OFFSET,
			 RegValue);
}

/****************************************************************************/
/**
*
* The function returns the mode of the sequencer.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @return	Returns the Sequencer mode. XSYSMONPSU_EVENT_MODE for Event mode
* 		and XSYSMONPSU_CONTINUOUS_MODE for continuous mode.
*
* @note		None.
*
*****************************************************************************/
s32 XSysMonPsu_GetSequencerEvent(XSysMonPsu *InstancePtr, u32 SysmonBlk)
{
	s32 Mode;
	u32 RegValue;
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/* Read the Configuration Register 0. */
	RegValue = XSysmonPsu_ReadReg(EffectiveBaseAddress +
					XSYSMONPSU_CFG_REG0_OFFSET);

	RegValue &= XSYSMONPSU_CFG_REG0_EC_MASK;

	if (RegValue == XSYSMONPSU_CFG_REG0_EC_MASK) {
		Mode = XSYSMONPSU_EVENT_MODE;
	} else {
		Mode = XSYSMONPSU_CONTINUOUS_MODE;
	}

	return Mode;
}

/****************************************************************************/
/**
*
* The function enables the external mux and connects a channel to the mux.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	Channel is the channel number used to connect to the external
*		Mux. The valid channels are 0 to 5 and 16 to 31.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @return
*		- XST_SUCCESS if the given values were written successfully to
*		the Configuration Register 0.
*		- XST_FAILURE if the channel sequencer is enabled or the input
*		parameters are not valid for the selected channel.
*
* @note		None.
*
*****************************************************************************/
void XSysMonPsu_SetExtenalMux(XSysMonPsu *InstancePtr, u8 Channel, u32 SysmonBlk)
{
	u32 RegValue;
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertVoid((Channel <= XSM_CH_VREFN) ||
			  ((Channel >= XSM_CH_AUX_MIN) &&
			  (Channel <= XSM_CH_AUX_MAX)));
	Xil_AssertVoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/*
	 * Read the Configuration Register 0 and the clear the channel selection
	 * bits.
	 */
	RegValue = XSysmonPsu_ReadReg(EffectiveBaseAddress +
					XSYSMONPSU_CFG_REG0_OFFSET);
	RegValue &= ~(XSYSMONPSU_CFG_REG0_MUX_CH_MASK);

	/* Enable the External Mux and select the channel. */
	RegValue |= (XSYSMONPSU_CFG_REG0_XTRNL_MUX_MASK | (u32)Channel);
	XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_CFG_REG0_OFFSET,
			 RegValue);
}

/****************************************************************************/
/**
*
* The function returns the external mux channel.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @return	Returns the channel number used to connect to the external
*		Mux. The valid channels are 0 to 6, 8 to 16, and 31 to 36..
*
* @note		None.
*
*****************************************************************************/
u32 XSysMonPsu_GetExtenalMux(XSysMonPsu *InstancePtr, u32 SysmonBlk)
{
	u32 RegValue;
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/*
	 * Read the Configuration Register 0 and derive the channel selection
	 * bits.
	 */
	RegValue = XSysmonPsu_ReadReg(EffectiveBaseAddress +
					XSYSMONPSU_CFG_REG0_OFFSET);
	RegValue &= XSYSMONPSU_CFG_REG0_MUX_CH_MASK;

	return RegValue;
}

/****************************************************************************/
/**
*
* The function sets the frequency of the ADCCLK by configuring the DCLK to
* ADCCLK ratio in the Configuration Register #2.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	Divisor is clock divisor used to derive ADCCLK from DCLK.
*		Valid values of the divisor are
*		PS:
*		 - 0 means divide by 8.
*		 - 1,2 means divide by 2.
*		 - 3 to 255 means divide by that value.
*       PL:
*		 - 0,1,2 means divide by 2.
*		 - 3 to 255 means divide by that value.
*		Refer to the device specification for more details.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @return	None.
*
* @note		- The ADCCLK is an internal clock used by the ADC and is
*		synchronized to the DCLK clock. The ADCCLK is equal to DCLK
*		divided by the user selection in the Configuration Register 2.
*		- There is no Assert on the minimum value of the Divisor.
*
*****************************************************************************/
void XSysMonPsu_SetAdcClkDivisor(XSysMonPsu *InstancePtr, u8 Divisor,
            u32 SysmonBlk)
{
	u32 RegValue;
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertVoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/*
	 * Read the Configuration Register 2 and the clear the clock divisor
	 * bits.
	 */
	RegValue = XSysmonPsu_ReadReg(EffectiveBaseAddress +
					XSYSMONPSU_CFG_REG2_OFFSET);
	RegValue &= ~(XSYSMONPSU_CFG_REG2_CLK_DVDR_MASK);

	/* Write the divisor value into the Configuration Register 2. */
	RegValue |= ((u32)Divisor << XSYSMONPSU_CFG_REG2_CLK_DVDR_SHIFT) &
					XSYSMONPSU_CFG_REG2_CLK_DVDR_MASK;
	XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_CFG_REG2_OFFSET,
			 RegValue);

}

/****************************************************************************/
/**
*
* The function gets the ADCCLK divisor from the Configuration Register 2.
*
* @param	InstancePtr is a pointer to the XSysMon instance.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @return	The divisor read from the Configuration Register 2.
*
* @note		The ADCCLK is an internal clock used by the ADC and is
*		synchronized to the DCLK clock. The ADCCLK is equal to DCLK
*		divided by the user selection in the Configuration Register 2.
*
*****************************************************************************/
u8 XSysMonPsu_GetAdcClkDivisor(XSysMonPsu *InstancePtr, u32 SysmonBlk)
{
	u16 Divisor;
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/* Read the divisor value from the Configuration Register 2. */
	Divisor = (u16) XSysmonPsu_ReadReg(EffectiveBaseAddress +
							XSYSMONPSU_CFG_REG2_OFFSET);

	return (u8) (Divisor >> XSYSMONPSU_CFG_REG2_CLK_DVDR_SHIFT);
}

u8 XSysMonPsu_UpdateAdcClkDivisor(XSysMonPsu *InstancePtr, u32 SysmonBlk)
{
	u16 Divisor;
	u32 EffectiveBaseAddress;
	u32 RegValue;
	u32 InputFreq = InstancePtr->Config.InputClockMHz;

	/* Assert the arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/* Read the divisor value from the Configuration Register 2. */
	Divisor = (u16) XSysmonPsu_ReadReg(EffectiveBaseAddress +
							XSYSMONPSU_CFG_REG2_OFFSET);
	Divisor = Divisor >> XSYSMONPSU_CFG_REG2_CLK_DVDR_SHIFT;

	while (1) {
		if (!Divisor) {
			if ((SysmonBlk == XSYSMON_PS) &&
			(InputFreq/8 >= 1) && (InputFreq/8 <= 26)) {
				break;
			} else if ((SysmonBlk == XSYSMON_PL) &&
			(InputFreq/2 >= 1) && (InputFreq/2 <= 26)) {
				break;
			}
		} else if ((InputFreq/Divisor >= 1) &&
				(InputFreq/Divisor <= 26)) {
			break;
		} else {
			Divisor += 1;
		}
	}

	/*
	 * Read the Configuration Register 2 and the clear the clock divisor
	 * bits.
	 */
	RegValue = XSysmonPsu_ReadReg(EffectiveBaseAddress +
					XSYSMONPSU_CFG_REG2_OFFSET);
	RegValue &= ~(XSYSMONPSU_CFG_REG2_CLK_DVDR_MASK);

	/* Write the divisor value into the Configuration Register 2. */
	RegValue |= ((u32)Divisor << XSYSMONPSU_CFG_REG2_CLK_DVDR_SHIFT) &
					XSYSMONPSU_CFG_REG2_CLK_DVDR_MASK;
	XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_CFG_REG2_OFFSET,
			 RegValue);

	return (u8)Divisor;
}
/****************************************************************************/
/**
*
* This function enables the specified channels in the ADC Channel Selection
* Sequencer Registers. The sequencer must be in the Safe Mode before writing
* to these registers.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	ChEnableMask is the bit mask of all the channels to be enabled.
*		Use XSYSMONPSU_SEQ_CH* defined in xsysmon_hw.h to specify the Channel
*		numbers. Bit masks of 1 will be enabled and bit mask of 0 will
*		be disabled.
*		The ChEnableMask is a 64 bit mask that is written to the three
*		16 bit ADC Channel Selection Sequencer Registers.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @return
*		- XST_SUCCESS if the given values were written successfully to
*		the ADC Channel Selection Sequencer Registers.
*		- XST_FAILURE if the channel sequencer is enabled.
*
* @note		None.
*
*****************************************************************************/
s32 XSysMonPsu_SetSeqChEnables(XSysMonPsu *InstancePtr, u64 ChEnableMask,
		u32 SysmonBlk)
{
	s32 Status;
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/*
	 * The sequencer must be in the Default Safe Mode before writing
	 * to these registers. Return XST_FAILURE if the channel sequencer
	 * is enabled.
	 */
	if ((XSysMonPsu_GetSequencerMode(InstancePtr,SysmonBlk) != XSM_SEQ_MODE_SAFE)) {
		Status = (s32)XST_FAILURE;
		goto End;
	}

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/*
	 * Enable the specified channels in the ADC Channel Selection Sequencer
	 * Registers.
	 */
	XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_SEQ_CH0_OFFSET,
			 (ChEnableMask & XSYSMONPSU_SEQ_CH0_VALID_MASK));

	XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_SEQ_CH1_OFFSET,
			 (ChEnableMask >> XSM_SEQ_CH_SHIFT) &
			 XSYSMONPSU_SEQ_CH1_VALID_MASK);

	XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_SEQ_CH2_OFFSET,
				 (ChEnableMask >> XSM_SEQ_CH2_SHIFT) &
			 XSYSMONPSU_SEQ_CH2_VALID_MASK);

	Status = (s32)XST_SUCCESS;

End:
	return Status;
}

/****************************************************************************/
/**
*
* This function gets the channel enable bits status from the ADC Channel
* Selection Sequencer Registers.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @return	Gets the channel enable bits. Use XSYSMONPSU_SEQ_CH* defined in
*		xsysmonpsu_hw.h to interpret the Channel numbers. Bit masks of 1
*		are the channels that are enabled and bit mask of 0 are
*		the channels that are disabled.
*
* @return	None.
*
* @note		None.
*
*****************************************************************************/
u64 XSysMonPsu_GetSeqChEnables(XSysMonPsu *InstancePtr, u32 SysmonBlk)
{
	u64 RegVal;
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/*
	 * Read the channel enable bits for all the channels from the ADC
	 * Channel Selection Register.
	 */
	RegVal = XSysmonPsu_ReadReg(EffectiveBaseAddress +
			XSYSMONPSU_SEQ_CH0_OFFSET) & XSYSMONPSU_SEQ_CH0_VALID_MASK;
	RegVal |= (XSysmonPsu_ReadReg(EffectiveBaseAddress +
			XSYSMONPSU_SEQ_CH1_OFFSET) & XSYSMONPSU_SEQ_CH1_VALID_MASK) <<
					XSM_SEQ_CH_SHIFT;
	RegVal |= (u64)(XSysmonPsu_ReadReg(EffectiveBaseAddress +
			XSYSMONPSU_SEQ_CH2_OFFSET) &
			XSYSMONPSU_SEQ_CH2_VALID_MASK) << XSM_SEQ_CH2_SHIFT;

	return RegVal;
}

/****************************************************************************/
/**
*
* This function enables the averaging for the specified channels in the ADC
* Channel Averaging Enable Sequencer Registers. The sequencer must be in
* the Safe Mode before writing to these registers.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	AvgEnableChMask is the bit mask of all the channels for which
*		averaging is to be enabled. Use XSYSMONPSU_SEQ_AVERAGE* defined in
*		xsysmonpsu_hw.h to specify the Channel numbers. Averaging will be
*		enabled for bit masks of 1 and disabled for bit mask of 0.
*		The AvgEnableChMask is a 64 bit mask that is written to the
*		three 16 bit ADC Channel Averaging Enable Sequencer Registers.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @return
*		- XST_SUCCESS if the given values were written successfully to
*		the ADC Channel Averaging Enables Sequencer Registers.
*		- XST_FAILURE if the channel sequencer is enabled.
*
* @note		None.
*
*****************************************************************************/
s32 XSysMonPsu_SetSeqAvgEnables(XSysMonPsu *InstancePtr, u64 AvgEnableChMask,
		u32 SysmonBlk)
{
	s32 Status;
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/*
	 * The sequencer must be disabled for writing any of these registers.
	 * Return XST_FAILURE if the channel sequencer is enabled.
	 */
	if ((XSysMonPsu_GetSequencerMode(InstancePtr,SysmonBlk)
	                                     != XSM_SEQ_MODE_SAFE)) {
		Status = (s32)XST_FAILURE;
	} else {
		/* Calculate the effective baseaddress based on the Sysmon instance. */
		EffectiveBaseAddress =
				XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
						SysmonBlk);
		/*
		 * Enable/disable the averaging for the specified channels in the
		 * ADC Channel Averaging Enables Sequencer Registers.
		 */
		XSysmonPsu_WriteReg(EffectiveBaseAddress +
				XSYSMONPSU_SEQ_AVERAGE0_OFFSET,
				(AvgEnableChMask & XSYSMONPSU_SEQ_AVERAGE0_MASK));

		XSysmonPsu_WriteReg(EffectiveBaseAddress +
				XSYSMONPSU_SEQ_AVERAGE1_OFFSET,
				 (AvgEnableChMask >> XSM_SEQ_CH_SHIFT) &
				 XSYSMONPSU_SEQ_AVERAGE1_MASK);

		XSysmonPsu_WriteReg(EffectiveBaseAddress +
				XSYSMONPSU_SEQ_AVERAGE2_OFFSET,
				 (AvgEnableChMask >> XSM_SEQ_CH2_SHIFT) &
				 XSYSMONPSU_SEQ_AVERAGE2_MASK);

		Status = (s32)XST_SUCCESS;
	}

	return Status;
}

/****************************************************************************/
/**
*
* This function returns the channels for which the averaging has been enabled
* in the ADC Channel Averaging Enables Sequencer Registers.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @returns 	The status of averaging (enabled/disabled) for all the channels.
*		Use XSYSMONPSU_SEQ_AVERAGE* defined in xsysmonpsu_hw.h to interpret the
*		Channel numbers. Bit masks of 1 are the channels for which
*		averaging is enabled and bit mask of 0 are the channels for
*		averaging is disabled.
*
* @note		None.
*
*****************************************************************************/
u64 XSysMonPsu_GetSeqAvgEnables(XSysMonPsu *InstancePtr, u32 SysmonBlk)
{
	u64 RegVal;
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/*
	 * Read the averaging enable status for all the channels from the
	 * ADC Channel Averaging Enables Sequencer Registers.
	 */
	RegVal = XSysmonPsu_ReadReg(EffectiveBaseAddress +
			XSYSMONPSU_SEQ_AVERAGE0_OFFSET) & XSYSMONPSU_SEQ_AVERAGE0_MASK;
	RegVal |= (XSysmonPsu_ReadReg(EffectiveBaseAddress +
			XSYSMONPSU_SEQ_AVERAGE1_OFFSET) & XSYSMONPSU_SEQ_AVERAGE1_MASK) <<
			XSM_SEQ_CH_SHIFT;
	RegVal |= (u64)(XSysmonPsu_ReadReg(EffectiveBaseAddress +
			XSYSMONPSU_SEQ_AVERAGE2_OFFSET) &
			XSYSMONPSU_SEQ_AVERAGE2_MASK) << XSM_SEQ_CH2_SHIFT;

	return RegVal;
}

/****************************************************************************/
/**
*
* This function sets the Analog input mode for the specified channels in the
* ADC Channel Analog-Input Mode Sequencer Registers. The sequencer must be in
* the Safe Mode before writing to these registers.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	InputModeChMask is the bit mask of all the channels for which
*		the input mode is differential mode. Use XSYSMONPSU_SEQ_INPUT_MDE*
*		defined in xsysmonpsu_hw.h to specify the channel numbers. Differential
*		or  Bipolar input mode will be set for bit masks of 1 and unipolar input
*		mode for bit masks of 0.
*		The InputModeChMask is a 64 bit mask that is written to the three
*		16 bit ADC Channel Analog-Input Mode Sequencer Registers.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @return
*		- XST_SUCCESS if the given values were written successfully to
*		the ADC Channel Analog-Input Mode Sequencer Registers.
*		- XST_FAILURE if the channel sequencer is enabled.
*
* @note		None.
*
*****************************************************************************/
s32 XSysMonPsu_SetSeqInputMode(XSysMonPsu *InstancePtr, u64 InputModeChMask,
		u32 SysmonBlk)
{
	s32 Status;
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/*
	 * The sequencer must be in the Safe Mode before writing to
	 * these registers. Return XST_FAILURE if the channel sequencer
	 * is enabled.
	 */
	if ((XSysMonPsu_GetSequencerMode(InstancePtr,SysmonBlk)
	                                      != XSM_SEQ_MODE_SAFE)) {
		Status = (s32)XST_FAILURE;
		goto End;
	}

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/*
	 * Set the input mode for the specified channels in the ADC Channel
	 * Analog-Input Mode Sequencer Registers.
	 */
	XSysmonPsu_WriteReg(EffectiveBaseAddress +
			XSYSMONPSU_SEQ_INPUT_MDE0_OFFSET,
			 (InputModeChMask & XSYSMONPSU_SEQ_INPUT_MDE0_MASK));

	XSysmonPsu_WriteReg(EffectiveBaseAddress +
			XSYSMONPSU_SEQ_INPUT_MDE1_OFFSET,
			 (InputModeChMask >> XSM_SEQ_CH_SHIFT) &
			 XSYSMONPSU_SEQ_INPUT_MDE1_MASK);

	XSysmonPsu_WriteReg(EffectiveBaseAddress +
		XSYSMONPSU_SEQ_INPUT_MDE2_OFFSET,
		 (InputModeChMask >> XSM_SEQ_CH2_SHIFT) &
		 XSYSMONPSU_SEQ_INPUT_MDE2_MASK);

	Status = (s32)XST_SUCCESS;

End:
	return Status;
}

/****************************************************************************/
/**
*
* This function gets the Analog input mode for all the channels from
* the ADC Channel Analog-Input Mode Sequencer Registers.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @returns 	The input mode for all the channels.
*		Use XSYSMONPSU_SEQ_INPUT_MDE* defined in xsysmonpsu_hw.h to interpret the
*		Channel numbers. Bit masks of 1 are the channels for which
*		input mode is differential/Bipolar and bit mask of 0 are the channels
*		for which input mode is unipolar.
*
* @note		None.
*
*****************************************************************************/
u64 XSysMonPsu_GetSeqInputMode(XSysMonPsu *InstancePtr, u32 SysmonBlk)
{
	u64 InputMode;
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/*
	 *  Get the input mode for all the channels from the ADC Channel
	 * Analog-Input Mode Sequencer Registers.
	 */
	InputMode = XSysmonPsu_ReadReg(EffectiveBaseAddress +
			XSYSMONPSU_SEQ_INPUT_MDE0_OFFSET) & XSYSMONPSU_SEQ_INPUT_MDE0_MASK;
	InputMode |= (XSysmonPsu_ReadReg(EffectiveBaseAddress +
			XSYSMONPSU_SEQ_INPUT_MDE1_OFFSET) & XSYSMONPSU_SEQ_INPUT_MDE1_MASK) <<
				XSM_SEQ_CH_SHIFT;
	InputMode |= (u64)(XSysmonPsu_ReadReg(EffectiveBaseAddress +
			XSYSMONPSU_SEQ_INPUT_MDE2_OFFSET) &
			XSYSMONPSU_SEQ_INPUT_MDE2_MASK) << XSM_SEQ_CH2_SHIFT;

	return InputMode;
}

/****************************************************************************/
/**
*
* This function sets the number of Acquisition cycles in the ADC Channel
* Acquisition Time Sequencer Registers. The sequencer must be in the Safe Mode
* before writing to these registers.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	AcqCyclesChMask is the bit mask of all the channels for which
*		the number of acquisition cycles is to be extended.
*		Use XSYSMONPSU_SEQ_ACQ* defined in xsysmonpsu_hw.h to specify the Channel
*		numbers. Acquisition cycles will be extended to 10 ADCCLK cycles
*		for bit masks of 1 and will be the default 4 ADCCLK cycles for
*		bit masks of 0.
*		The AcqCyclesChMask is a 64 bit mask that is written to the three
*		16 bit ADC Channel Acquisition Time Sequencer Registers.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @return
*		- XST_SUCCESS if the given values were written successfully to
*		the Channel Sequencer Registers.
*		- XST_FAILURE if the channel sequencer is enabled.
*
* @note		None.
*
*****************************************************************************/
s32 XSysMonPsu_SetSeqAcqTime(XSysMonPsu *InstancePtr, u64 AcqCyclesChMask,
		u32 SysmonBlk)
{
	s32 Status;
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/*
	 * The sequencer must be in the Safe Mode before writing
	 * to these registers. Return XST_FAILURE if the channel
	 * sequencer is enabled.
	 */
	if ((XSysMonPsu_GetSequencerMode(InstancePtr,SysmonBlk)
	                                     != XSM_SEQ_MODE_SAFE)) {
		Status = (s32)XST_FAILURE;
		goto End;
	}

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/*
	 * Set the Acquisition time for the specified channels in the
	 * ADC Channel Acquisition Time Sequencer Registers.
	 */
	XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_SEQ_ACQ0_OFFSET,
			 (AcqCyclesChMask & XSYSMONPSU_SEQ_ACQ0_MASK));

	XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_SEQ_ACQ1_OFFSET,
			 (AcqCyclesChMask >> XSM_SEQ_CH_SHIFT) & XSYSMONPSU_SEQ_ACQ1_MASK);

	XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_SEQ_ACQ2_OFFSET,
			(AcqCyclesChMask >> XSM_SEQ_CH2_SHIFT) &
					XSYSMONPSU_SEQ_ACQ2_MASK);

	Status = (s32)XST_SUCCESS;

End:
	return Status;
}

/****************************************************************************/
/**
*
* This function gets the status of acquisition time from the ADC Channel Acquisition
* Time Sequencer Registers.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @returns 	The acquisition time for all the channels.
*		Use XSYSMONPSU_SEQ_ACQ* defined in xsysmonpsu_hw.h to interpret the
*		Channel numbers. Bit masks of 1 are the channels for which
*		acquisition cycles are extended and bit mask of 0 are the
*		channels for which acquisition cycles are not extended.
*
* @note		None.
*
*****************************************************************************/
u64 XSysMonPsu_GetSeqAcqTime(XSysMonPsu *InstancePtr, u32 SysmonBlk)
{
	u64 RegValAcq;
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/*
	 * Get the Acquisition cycles for the specified channels from the ADC
	 * Channel Acquisition Time Sequencer Registers.
	 */
	RegValAcq = XSysmonPsu_ReadReg(EffectiveBaseAddress +
					XSYSMONPSU_SEQ_ACQ0_OFFSET) & XSYSMONPSU_SEQ_ACQ0_MASK;
	RegValAcq |= (XSysmonPsu_ReadReg(EffectiveBaseAddress +
					XSYSMONPSU_SEQ_ACQ1_OFFSET) & XSYSMONPSU_SEQ_ACQ1_MASK) <<
					XSM_SEQ_CH_SHIFT;
	RegValAcq |= (u64)(XSysmonPsu_ReadReg(EffectiveBaseAddress +
			XSYSMONPSU_SEQ_ACQ2_OFFSET) &
			XSYSMONPSU_SEQ_ACQ2_MASK) << XSM_SEQ_CH2_SHIFT;

	return RegValAcq;
}

/****************************************************************************/
/**
*
* This functions sets the contents of the given Alarm Threshold Register.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	AlarmThrReg is the index of an Alarm Threshold Register to
*		be set. Use XSM_ATR_* constants defined in xsysmonpsu.h to
*		specify the index.
* @param	Value is the 16-bit threshold value to write into the register.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @return	None.
*
* @note		None.
*
*****************************************************************************/
void XSysMonPsu_SetAlarmThreshold(XSysMonPsu *InstancePtr, u8 AlarmThrReg,
		u16 Value, u32 SysmonBlk)
{
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertVoid((AlarmThrReg <= XSM_ATR_TEMP_RMTE_UPPER) ||
			((AlarmThrReg >= XSM_ATR_SUP7_LOWER) &&
			(AlarmThrReg <= XSM_ATR_TEMP_RMTE_LOWER)));
	Xil_AssertVoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/* Write the value into the specified Alarm Threshold Register. */
	XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_ALRM_TEMP_UPR_OFFSET +
			((u32)AlarmThrReg << 2U), Value);
}

/****************************************************************************/
/**
*
* This function returns the contents of the specified Alarm Threshold Register.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
* @param	AlarmThrReg is the index of an Alarm Threshold Register
*		to be read. Use XSM_ATR_* constants defined in xsysmonpsu.h
*		to specify the index.
* @param	SysmonBlk is the value that tells whether it is for PS Sysmon
*       block or PL Sysmon block register region.
*
* @return	A 16-bit value representing the contents of the selected Alarm
*		Threshold Register.
*
* @note		None.
*
*****************************************************************************/
u16 XSysMonPsu_GetAlarmThreshold(XSysMonPsu *InstancePtr, u8 AlarmThrReg,
		u32 SysmonBlk)
{
	u16 AlarmThreshold;
	u32 EffectiveBaseAddress;

	/* Assert the arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid((AlarmThrReg <= XSM_ATR_TEMP_RMTE_UPPER) ||
			((AlarmThrReg >= XSM_ATR_SUP7_LOWER) &&
			(AlarmThrReg <= XSM_ATR_TEMP_RMTE_LOWER)));
	Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));

	/* Calculate the effective baseaddress based on the Sysmon instance. */
	EffectiveBaseAddress =
			XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
					SysmonBlk);

	/*
	 * Read the specified Alarm Threshold Register and return
	 * the value.
	 */
	AlarmThreshold = (u16) XSysmonPsu_ReadReg(EffectiveBaseAddress +
			XSYSMONPSU_ALRM_TEMP_UPR_OFFSET + ((u32)AlarmThrReg << 2));

	return AlarmThreshold;
}

/****************************************************************************/
/**
*
* This function sets the conversion to be automatic for PS SysMon.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
*
* @return	None
*
* @note		In the auto-trigger mode, sample rate is of 1 Million samples.
*
*****************************************************************************/
void XSysMonPsu_SetPSAutoConversion(XSysMonPsu *InstancePtr)
{
	u32 PSSysMonStatusReg;

	/* Assert the arguments. */
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	/* Set the automatic conversion triggering in PS control register. */
	PSSysMonStatusReg = XSysmonPsu_ReadReg(InstancePtr->Config.BaseAddress +
			XSYSMONPSU_PS_SYSMON_CSTS_OFFSET);
	PSSysMonStatusReg |= XSYSMONPSU_PS_SYSMON_CSTS_AUTO_CONVST_MASK;
	XSysmonPsu_WriteReg(InstancePtr->Config.BaseAddress +
			XSYSMONPSU_PS_SYSMON_CSTS_OFFSET, PSSysMonStatusReg);
}

/****************************************************************************/
/**
*
* This function gets the AMS monitor status.
*
* @param	InstancePtr is a pointer to the XSysMonPsu instance.
*
* @return	Returns the monitor status. See XSYSMONPSU_MON_STS_*_MASK
* 		definations present in xsysmonpsu_hw.h for knowing the status.
*
* @note		None
* .
*****************************************************************************/
u32 XSysMonPsu_GetMonitorStatus(XSysMonPsu *InstancePtr)
{
	u32 AMSMonStatusReg;

	/* Assert the arguments. */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	/*
	 * Read the AMS monitor status. This gives tells about JTAG Locked / ADC
	 * busy / ADC Current Channel number and its ADC output.
	 */
	AMSMonStatusReg = XSysmonPsu_ReadReg(InstancePtr->Config.BaseAddress +
			XSYSMONPSU_MON_STS_OFFSET);

	return AMSMonStatusReg;
}

/** @} */
