]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_R5_UltraScale_MPSoC/RTOSDemo_R5_bsp/psu_cortexr5_0/libsrc/sysmonpsu_v2_3/src/xsysmonpsu.c
Update Zynq, MPSoc Cortex-A53 and MPSoc Cortex-R5 demo projects to build with the...
[freertos] / FreeRTOS / Demo / CORTEX_R5_UltraScale_MPSoC / RTOSDemo_R5_bsp / psu_cortexr5_0 / libsrc / sysmonpsu_v2_3 / src / xsysmonpsu.c
1 /******************************************************************************
2 *
3 * Copyright (C) 2016 Xilinx, Inc.  All rights reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * Use of the Software is limited solely to applications:
16 * (a) running on a Xilinx device, or
17 * (b) that interact with a Xilinx device through a bus or interconnect.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * SOFTWARE.
26 *
27 * Except as contained in this notice, the name of the Xilinx shall not be used
28 * in advertising or otherwise to promote the sale, use or other dealings in
29 * this Software without prior written authorization from Xilinx.
30 *
31 ******************************************************************************/
32 /*****************************************************************************/
33 /**
34 *
35 * @file xsysmonpsu.c
36 *
37 * Functions in this file are the minimum required functions for the XSysMonPsu
38 * driver. See xsysmonpsu.h for a detailed description of the driver.
39 *
40 * @note         None.
41 *
42 * <pre>
43 *
44 * MODIFICATION HISTORY:
45 *
46 * Ver   Who    Date         Changes
47 * ----- -----  -------- -----------------------------------------------
48 * 1.0   kvn    12/15/15 First release.
49 *              02/15/16 Corrected Assert function call in
50 *                       XSysMonPsu_GetMonitorStatus API.
51 *              03/03/16 Added Temperature remote channel for Setsingle
52 *                       channel API. Also corrected external mux channel
53 *                       numbers.
54 * 1.1   kvn    05/05/16 Modified code for MISRA-C:2012 Compliance.
55 * 2.0   vns    08/14/16 Fixed CR #956780, added support for enabling/disabling
56 *                       SEQ_CH2 and SEQ_AVG2 registers, modified function
57 *                       prototypes of XSysMonPsu_GetSeqAvgEnables,
58 *                       XSysMonPsu_SetSeqAvgEnables, XSysMonPsu_SetSeqChEnables,
59 *                       XSysMonPsu_GetSeqChEnables,
60 *                       XSysMonPsu_SetSeqInputMode, XSysMonPsu_GetSeqInputMode,
61 *                       XSysMonPsu_SetSeqAcqTime
62 *                       and XSysMonPsu_GetSeqAcqTime to provide support for
63 *                       set/get 64 bit value.
64 * 2.1   sk     03/03/16 Check for PL reset before doing PL Sysmon reset.
65 * 2.3   mn     12/13/17 Correct the AMS block channel numbers
66 *       mn     03/08/18 Update Clock Divisor to the proper value
67 *
68 * </pre>
69 *
70 ******************************************************************************/
71
72 /***************************** Include Files *********************************/
73
74 #include "xsysmonpsu.h"
75
76 /************************** Constant Definitions ****************************/
77
78 /**************************** Type Definitions ******************************/
79
80 /***************** Macros (Inline Functions) Definitions ********************/
81
82 /************************** Function Prototypes *****************************/
83
84 static void XSysMonPsu_StubHandler(void *CallBackRef);
85
86 /************************** Variable Definitions ****************************/
87
88 /*****************************************************************************/
89 /**
90 *
91 * This function initializes XSysMonPsu device/instance. This function
92 * must be called prior to using the System Monitor device.
93 *
94 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
95 * @param        ConfigPtr points to the XSysMonPsu device configuration structure.
96 * @param        EffectiveAddr is the device base address in the virtual memory
97 *               address space. If the address translation is not used then the
98 *               physical address is passed.
99 *               Unexpected errors may occur if the address mapping is changed
100 *               after this function is invoked.
101 *
102 * @return
103 *               - XST_SUCCESS if successful.
104 *
105 * @note         The user needs to first call the XSysMonPsu_LookupConfig() API
106 *               which returns the Configuration structure pointer which is
107 *               passed as a parameter to the XSysMonPsu_CfgInitialize() API.
108 *
109 ******************************************************************************/
110 s32 XSysMonPsu_CfgInitialize(XSysMonPsu *InstancePtr, XSysMonPsu_Config *ConfigPtr,
111                           u32 EffectiveAddr)
112 {
113         u32 PsSysmonControlStatus;
114         u32 PlSysmonControlStatus;
115         u32 IntrStatus;
116
117         /* Assert the input arguments. */
118         Xil_AssertNonvoid(InstancePtr != NULL);
119         Xil_AssertNonvoid(ConfigPtr != NULL);
120
121         /* Set the values read from the device config and the base address. */
122         InstancePtr->Config.DeviceId = ConfigPtr->DeviceId;
123         InstancePtr->Config.BaseAddress = EffectiveAddr;
124         InstancePtr->Config.InputClockMHz = ConfigPtr->InputClockMHz;
125
126         /* Set all handlers to stub values, let user configure this data later. */
127         InstancePtr->Handler = XSysMonPsu_StubHandler;
128
129         XSysMonPsu_UpdateAdcClkDivisor(InstancePtr, XSYSMON_PS);
130         XSysMonPsu_UpdateAdcClkDivisor(InstancePtr, XSYSMON_PL);
131
132         /* Reset the device such that it is in a known state. */
133         XSysMonPsu_Reset(InstancePtr);
134
135         PsSysmonControlStatus = XSysmonPsu_ReadReg(InstancePtr->Config.BaseAddress +
136                         XSYSMONPSU_PS_SYSMON_CSTS_OFFSET);
137
138         /* Check if the PS Sysmon is in Idle / ready state or not */
139         while(PsSysmonControlStatus != XSYSMONPSU_PS_SYSMON_READY) {
140                 PsSysmonControlStatus = XSysmonPsu_ReadReg(InstancePtr->Config.BaseAddress +
141                                         XSYSMONPSU_PS_SYSMON_CSTS_OFFSET);
142         }
143
144         PlSysmonControlStatus = XSysmonPsu_ReadReg(InstancePtr->Config.BaseAddress +
145                         XSYSMONPSU_PL_SYSMON_CSTS_OFFSET);
146
147         /* Check if the PL Sysmon is accessible to PS Sysmon or not */
148         while((PlSysmonControlStatus & XSYSMONPSU_PL_SYSMON_CSTS_ACESBLE_MASK)
149                                 != XSYSMONPSU_PL_SYSMON_CSTS_ACESBLE_MASK) {
150                 PlSysmonControlStatus = XSysmonPsu_ReadReg(InstancePtr->Config.BaseAddress +
151                                         XSYSMONPSU_PL_SYSMON_CSTS_OFFSET);
152         }
153
154         /* Indicate the instance is now ready to use, initialized without error */
155         InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
156
157         /* Clear any bits set in the Interrupt Status Register. */
158         IntrStatus = XSysMonPsu_IntrGetStatus(InstancePtr);
159         XSysMonPsu_IntrClear(InstancePtr, IntrStatus);
160
161         return XST_SUCCESS;
162 }
163
164 /****************************************************************************/
165 /**
166 *
167 * This function is a stub handler that is the default handler such that if the
168 * application has not set the handler when interrupts are enabled, this
169 * function will be called.
170 *
171 * @param        CallBackRef is unused by this function.
172 *
173 * @return       None.
174 *
175 * @note         None.
176 *
177 *****************************************************************************/
178 static void XSysMonPsu_StubHandler(void *CallBackRef)
179 {
180         (void) CallBackRef;
181
182         /* Assert occurs always since this is a stub and should never be called */
183         Xil_AssertVoidAlways();
184 }
185
186 /*****************************************************************************/
187 /**
188 *
189 * This function resets the SystemMonitor
190 *
191 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
192 *
193 * @return       None.
194 *
195 * @note         Upon reset, all Maximum and Minimum status registers will be
196 *               reset to their default values. Currently running and any averaging
197 *               will restart. Refer to the device data sheet for the device status and
198 *               register values after the reset.
199 *
200 ******************************************************************************/
201 void XSysMonPsu_Reset(XSysMonPsu *InstancePtr)
202 {
203         u8 IsPlReset;
204         /* Assert the arguments. */
205         Xil_AssertVoid(InstancePtr != NULL);
206
207         /* RESET the PS SYSMON */
208         XSysmonPsu_WriteReg(InstancePtr->Config.BaseAddress + XPS_BA_OFFSET +
209                         XSYSMONPSU_VP_VN_OFFSET, XSYSMONPSU_VP_VN_MASK);
210
211         /* Check for PL is under reset or not */
212         IsPlReset = (XSysmonPsu_ReadReg(CSU_BASEADDR + PCAP_STATUS_OFFSET) &
213                                                 PL_CFG_RESET_MASK) >> PL_CFG_RESET_SHIFT;
214         if (IsPlReset != 0U) {
215                 /* RESET the PL SYSMON */
216                 XSysmonPsu_WriteReg(InstancePtr->Config.BaseAddress + XPL_BA_OFFSET +
217                                 XSYSMONPSU_VP_VN_OFFSET, XSYSMONPSU_VP_VN_MASK);
218         }
219
220 }
221
222 /****************************************************************************/
223 /**
224 *
225 * This function reads the contents of the Status Register.
226 *
227 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
228 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
229 *       block or PL Sysmon block register region.
230 *
231 * @return       A 32-bit value representing the contents of the Status Register.
232 *               Use the XSYSMONPSU_MON_STS_* constants defined in xsysmonpsu_hw.h to
233 *               interpret the returned value.
234 *
235 * @note         None.
236 *****************************************************************************/
237 u32 XSysMonPsu_GetStatus(XSysMonPsu *InstancePtr, u32 SysmonBlk)
238 {
239         u32 Status;
240         u32 EffectiveBaseAddress;
241
242         /* Assert the arguments. */
243         Xil_AssertNonvoid(InstancePtr != NULL);
244         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
245         Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
246
247         /* Calculate the effective baseaddress based on the Sysmon instance. */
248         EffectiveBaseAddress =
249                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
250                                         SysmonBlk);
251
252         /* Read the Sysmon Status Register and return the value. */
253         Status = XSysmonPsu_ReadReg(EffectiveBaseAddress + XSYSMONPSU_MON_STS_OFFSET);
254
255         return Status;
256 }
257
258 /****************************************************************************/
259 /**
260 *
261 * This function starts the ADC conversion in the Single Channel event driven
262 * sampling mode. The EOC bit in Status Register will be set once the conversion
263 * is finished. Refer to the device specification for more details.
264 *
265 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
266 *
267 * @return       None.
268 *
269 * @note         The default state of the CONVST bit is a logic 0. The conversion
270 *               is started when the CONVST bit is set to 1 from 0.
271 *               This bit is self-clearing so that the next conversion
272 *               can be started by setting this bit.
273 *
274 *****************************************************************************/
275 void XSysMonPsu_StartAdcConversion(XSysMonPsu *InstancePtr)
276 {
277         u32 ControlStatus;
278
279         /* Assert the arguments. */
280         Xil_AssertVoid(InstancePtr != NULL);
281         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
282
283         /*
284          * Start the conversion by setting the CONVST bit to 1 only if auto-convst
285          * bit is not enabled. This convst bit is self-clearing.
286          */
287         ControlStatus = XSysmonPsu_ReadReg(InstancePtr->Config.BaseAddress +
288                         XSYSMONPSU_PS_SYSMON_CSTS_OFFSET);
289
290         if ((ControlStatus & XSYSMONPSU_PS_SYSMON_CSTS_AUTO_CONVST_MASK )
291                         != XSYSMONPSU_PS_SYSMON_CSTS_AUTO_CONVST_MASK) {
292                 XSysmonPsu_WriteReg(InstancePtr->Config.BaseAddress +
293                                         XSYSMONPSU_PS_SYSMON_CSTS_OFFSET,
294                                         (ControlStatus | (u32)XSYSMONPSU_PS_SYSMON_CSTS_CONVST_MASK));
295         }
296 }
297
298 /****************************************************************************/
299 /**
300 *
301 * Get the ADC converted data for the specified channel.
302 *
303 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
304 * @param        Channel is the channel number. Use the XSM_CH_* defined in
305 *               the file xsysmonpsu.h. The valid channels for PS / PL SysMon are 0 - 6,
306 *               8 - 10 and 13 - 37. For AMS, 38 - 53 channels are valid.
307 * @param        Block is the value that tells whether it is for PS Sysmon block
308 *       or PL Sysmon block or the AMS controller register region.
309 *
310 * @return       A 16-bit value representing the ADC converted data for the
311 *               specified channel. The System Monitor device guarantees
312 *               a 10 bit resolution for the ADC converted data and data is the
313 *               10 MSB bits of the 16 data read from the device.
314 *
315 * @note         Please make sure that the proper channel number is passed.
316 *
317 *****************************************************************************/
318 u16 XSysMonPsu_GetAdcData(XSysMonPsu *InstancePtr, u8 Channel, u32 Block)
319 {
320         u16 AdcData;
321         u32 EffectiveBaseAddress;
322
323         /* Assert the arguments. */
324         Xil_AssertNonvoid(InstancePtr != NULL);
325         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
326         Xil_AssertNonvoid((Channel <= XSM_CH_SUPPLY3) ||
327                           ((Channel >= XSM_CH_SUPPLY_CALIB) &&
328                           (Channel <= XSM_CH_GAINERR_CALIB)) ||
329                           ((Channel >= XSM_CH_SUPPLY4) &&
330                           (Channel <= XSM_CH_RESERVE1)));
331         Xil_AssertNonvoid((Block == XSYSMON_PS)||(Block == XSYSMON_PL)
332                                                 ||(Block == XSYSMON_AMS));
333
334         /* Calculate the effective baseaddress based on the Sysmon instance. */
335         EffectiveBaseAddress =
336                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
337                                         Block);
338
339         /*
340          * Read the selected ADC converted data for the specified channel
341          * and return the value.
342          */
343         if (Channel <= XSM_CH_AUX_MAX) {
344                 AdcData = (u16) (XSysmonPsu_ReadReg(EffectiveBaseAddress + ((u32)Channel << 2U)));
345         } else if ((Channel >= XSM_CH_SUPPLY7) && (Channel <= XSM_CH_TEMP_REMTE)){
346                 AdcData = (u16) (XSysmonPsu_ReadReg(EffectiveBaseAddress + XSM_ADC_CH_OFFSET +
347                                 (((u32)Channel - XSM_CH_SUPPLY7) << 2U)));
348         } else {
349                 AdcData = (u16) (XSysmonPsu_ReadReg(EffectiveBaseAddress + XSM_AMS_CH_OFFSET +
350                                 (((u32)Channel - XSM_CH_VCC_PSLL0) << 2U)));
351         }
352
353         return AdcData;
354 }
355
356 /****************************************************************************/
357 /**
358 *
359 * This function gets the calibration coefficient data for the specified
360 * parameter.
361 *
362 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
363 * @param        CoeffType specifies the calibration coefficient
364 *               to be read. Use XSM_CALIB_* constants defined in xsysmonpsu.h to
365 *               specify the calibration coefficient to be read.
366 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
367 *       block or PL Sysmon block register region.
368 *
369 * @return       A 16-bit value representing the calibration coefficient.
370 *               The System Monitor device guarantees a 10 bit resolution for
371 *               the ADC converted data and data is the 10 MSB bits of the 16
372 *               data read from the device.
373 *
374 * @note         None.
375 *
376 *****************************************************************************/
377 u16 XSysMonPsu_GetCalibCoefficient(XSysMonPsu *InstancePtr, u8 CoeffType,
378                 u32 SysmonBlk)
379 {
380         u16 CalibData;
381         u32 EffectiveBaseAddress;
382
383         /* Assert the arguments. */
384         Xil_AssertNonvoid(InstancePtr != NULL);
385         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
386         Xil_AssertNonvoid(CoeffType <= XSM_CALIB_GAIN_ERROR_COEFF);
387         Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
388
389         /* Calculate the effective baseaddress based on the Sysmon instance. */
390         EffectiveBaseAddress =
391                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
392                                         SysmonBlk);
393
394         /* Read the selected calibration coefficient. */
395         CalibData = (u16) XSysmonPsu_ReadReg(EffectiveBaseAddress +
396                         XSYSMONPSU_CAL_SUP_OFF_OFFSET + ((u32)CoeffType << 2U));
397
398         return CalibData;
399 }
400
401 /****************************************************************************/
402 /**
403 *
404 * This function reads the Minimum/Maximum measurement for one of the
405 * XSM_MIN_* or XSM_MAX_* constants defined in xsysmonpsu.h
406 *
407 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
408 * @param        MeasurementType specifies the parameter for which the
409 *               Minimum/Maximum measurement has to be read.
410 *               Use XSM_MAX_* and XSM_MIN_* constants defined in xsysmonpsu.h to
411 *               specify the data to be read.
412 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
413 *       block or PL Sysmon block register region.
414 *
415 * @return       A 16-bit value representing the maximum/minimum measurement for
416 *               specified parameter.
417 *               The System Monitor device guarantees a 10 bit resolution for
418 *               the ADC converted data and data is the 10 MSB bits of  16 bit
419 *               data read from the device.
420 *
421 *****************************************************************************/
422 u16 XSysMonPsu_GetMinMaxMeasurement(XSysMonPsu *InstancePtr, u8 MeasurementType,
423                 u32 SysmonBlk)
424 {
425         u16 MinMaxData;
426         u32 EffectiveBaseAddress;
427
428         /* Assert the arguments. */
429         Xil_AssertNonvoid(InstancePtr != NULL);
430         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
431         Xil_AssertNonvoid((MeasurementType <= XSM_MAX_SUPPLY6) ||
432                         ((MeasurementType >= XSM_MIN_SUPPLY4) &&
433                         (MeasurementType <= XSM_MIN_SUPPLY6)) ||
434                         ((MeasurementType >= XSM_MAX_SUPPLY7) &&
435                         (MeasurementType <= XSM_MAX_TEMP_REMOTE)) ||
436                         ((MeasurementType >= XSM_MIN_SUPPLY7) &&
437                         (MeasurementType <= XSM_MIN_TEMP_REMOTE)));
438         Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
439
440         /* Calculate the effective baseaddress based on the Sysmon instance. */
441         EffectiveBaseAddress =
442                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
443                                         SysmonBlk);
444
445         /* Read and return the specified Minimum/Maximum measurement. */
446         MinMaxData = (u16) (XSysmonPsu_ReadReg(EffectiveBaseAddress +
447                                                         XSM_MIN_MAX_CH_OFFSET + ((u32)MeasurementType << 2U)));
448
449         return MinMaxData;
450 }
451
452 /****************************************************************************/
453 /**
454 *
455 * This function sets the number of samples of averaging that is to be done for
456 * all the channels in both the single channel mode and sequence mode of
457 * operations.
458 *
459 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
460 * @param        Average is the number of samples of averaging programmed to the
461 *               Configuration Register 0. Use the XSM_AVG_* definitions defined
462 *               in xsysmonpsu.h file :
463 *               - XSM_AVG_0_SAMPLES for no averaging
464 *               - XSM_AVG_16_SAMPLES for 16 samples of averaging
465 *               - XSM_AVG_64_SAMPLES for 64 samples of averaging
466 *               - XSM_AVG_256_SAMPLES for 256 samples of averaging
467 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
468 *       block or PL Sysmon block register region.
469 *
470 * @return       None.
471 *
472 * @note         None.
473 *
474 *****************************************************************************/
475 void XSysMonPsu_SetAvg(XSysMonPsu *InstancePtr, u8 Average, u32 SysmonBlk)
476 {
477         u32 RegValue;
478         u32 EffectiveBaseAddress;
479
480         /* Assert the arguments. */
481         Xil_AssertVoid(InstancePtr != NULL);
482         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
483         Xil_AssertVoid(Average <= XSM_AVG_256_SAMPLES);
484         Xil_AssertVoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
485
486         /* Calculate the effective baseaddress based on the Sysmon instance. */
487         EffectiveBaseAddress =
488                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
489                                         SysmonBlk);
490
491         /* Write the averaging value into the Configuration Register 0. */
492         RegValue = XSysmonPsu_ReadReg(EffectiveBaseAddress + XSYSMONPSU_CFG_REG0_OFFSET)
493                                                 & (u32)(~XSYSMONPSU_CFG_REG0_AVRGNG_MASK);
494         RegValue |= (((u32) Average << XSYSMONPSU_CFG_REG0_AVRGNG_SHIFT));
495         XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_CFG_REG0_OFFSET,
496                          RegValue);
497 }
498
499 /****************************************************************************/
500 /**
501 *
502 * This function returns the number of samples of averaging configured for all
503 * the channels in the Configuration Register 0.
504 *
505 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
506 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
507 *       block or PL Sysmon block register region.
508 *
509 * @return       The averaging read from the Configuration Register 0 is
510 *               returned. Use the XSM_AVG_* bit definitions defined in xsysmonpsu.h
511 *               file to interpret the returned value :
512 *               - XSM_AVG_0_SAMPLES means no averaging
513 *               - XSM_AVG_16_SAMPLES means 16 samples of averaging
514 *               - XSM_AVG_64_SAMPLES means 64 samples of averaging
515 *               - XSM_AVG_256_SAMPLES means 256 samples of averaging
516 *
517 * @note         None.
518 *
519 *****************************************************************************/
520 u8 XSysMonPsu_GetAvg(XSysMonPsu *InstancePtr, u32 SysmonBlk)
521 {
522         u32 Average;
523         u32 EffectiveBaseAddress;
524
525         /* Assert the arguments. */
526         Xil_AssertNonvoid(InstancePtr != NULL);
527         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
528         Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
529
530         /* Calculate the effective baseaddress based on the Sysmon instance. */
531         EffectiveBaseAddress =
532                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
533                                         SysmonBlk);
534
535         /* Read the averaging value from the Configuration Register 0. */
536         Average = XSysmonPsu_ReadReg(EffectiveBaseAddress +
537                                 XSYSMONPSU_CFG_REG0_OFFSET) & XSYSMONPSU_CFG_REG0_AVRGNG_MASK;
538
539         return (u8)(Average >> XSYSMONPSU_CFG_REG0_AVRGNG_SHIFT);
540 }
541
542 /****************************************************************************/
543 /**
544 *
545 * The function sets the given parameters in the Configuration Register 0 in
546 * the single channel mode.
547 *
548 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
549 * @param        Channel is the channel number for conversion. The valid
550 *               channels are 0 - 6, 8 - 10, 13 - 37.
551 * @param        IncreaseAcqCycles is a boolean parameter which specifies whether
552 *               the Acquisition time for the external channels has to be
553 *               increased to 10 ADCCLK cycles (specify TRUE) or remain at the
554 *               default 4 ADCCLK cycles (specify FALSE). This parameter is
555 *               only valid for the external channels.
556 * @param        IsEventMode is a boolean parameter that specifies continuous
557 *               sampling (specify FALSE) or event driven sampling mode (specify
558 *               TRUE) for the given channel.
559 * @param        IsDifferentialMode is a boolean parameter which specifies
560 *               unipolar(specify FALSE) or differential mode (specify TRUE) for
561 *               the analog inputs. The  input mode is only valid for the
562 *               external channels.
563 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
564 *       block or PL Sysmon block register region.
565 *
566 * @return
567 *               - XST_SUCCESS if the given values were written successfully to
568 *               the Configuration Register 0.
569 *               - XST_FAILURE if the channel sequencer is enabled or the input
570 *               parameters are not valid for the selected channel.
571 *
572 * @note
573 *               - The number of samples for the averaging for all the channels
574 *               is set by using the function XSysMonPsu_SetAvg.
575 *               - The calibration of the device is done by doing a ADC
576 *               conversion on the calibration channel(channel 8). The input
577 *               parameters IncreaseAcqCycles, IsDifferentialMode and
578 *               IsEventMode are not valid for this channel.
579 *
580 *****************************************************************************/
581 s32 XSysMonPsu_SetSingleChParams(XSysMonPsu *InstancePtr, u8 Channel,
582                                 u32 IncreaseAcqCycles, u32 IsEventMode,
583                                 u32 IsDifferentialMode, u32 SysmonBlk)
584 {
585         u32 RegValue;
586         u32 EffectiveBaseAddress;
587         s32 Status;
588
589         /* Assert the arguments. */
590         Xil_AssertNonvoid(InstancePtr != NULL);
591         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
592         Xil_AssertNonvoid((Channel <= XSM_CH_SUPPLY3) ||
593                           ((Channel >= XSM_CH_SUPPLY_CALIB) &&
594                           (Channel <= XSM_CH_GAINERR_CALIB)) ||
595                           ((Channel >= XSM_CH_SUPPLY4) &&
596                           (Channel <= XSM_CH_TEMP_REMTE)) ||
597                           ((Channel >= XSM_CH_VCC_PSLL0) &&
598                           (Channel <= XSM_CH_RESERVE1)));
599         Xil_AssertNonvoid((IncreaseAcqCycles == TRUE) ||
600                           (IncreaseAcqCycles == FALSE));
601         Xil_AssertNonvoid((IsEventMode == TRUE) || (IsEventMode == FALSE));
602         Xil_AssertNonvoid((IsDifferentialMode == TRUE) ||
603                           (IsDifferentialMode == FALSE));
604         Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
605
606         /* Check if the device is in single channel mode else return failure */
607         if ((XSysMonPsu_GetSequencerMode(InstancePtr, SysmonBlk)
608                                 != XSM_SEQ_MODE_SINGCHAN)) {
609                 Status = (s32)XST_FAILURE;
610                 goto End;
611         }
612
613         /* Calculate the effective baseaddress based on the Sysmon instance. */
614         EffectiveBaseAddress =
615                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
616                                         SysmonBlk);
617
618         /* Read the Configuration Register 0 and extract out Averaging value. */
619         RegValue = XSysmonPsu_ReadReg(EffectiveBaseAddress +
620                         XSYSMONPSU_CFG_REG0_OFFSET) & XSYSMONPSU_CFG_REG0_AVRGNG_MASK;
621
622         /*
623          * Select the number of acquisition cycles. The acquisition cycles is
624          * only valid for the external channels.
625          */
626         if (IncreaseAcqCycles == TRUE) {
627                 if (((Channel >= XSM_CH_AUX_MIN) && (Channel <= XSM_CH_AUX_MAX))
628                     || (Channel == XSM_CH_VPVN)) {
629                         RegValue |= XSYSMONPSU_CFG_REG0_ACQ_MASK;
630                 } else {
631                         Status = (s32)XST_FAILURE;
632                         goto End;
633                 }
634         }
635
636         /*
637          * Select the input mode. The input mode is only valid for the
638          * external channels.
639          */
640         if (IsDifferentialMode == TRUE) {
641
642                 if (((Channel >= XSM_CH_AUX_MIN) && (Channel <= XSM_CH_AUX_MAX))
643                     || (Channel == XSM_CH_VPVN)) {
644                         RegValue |= XSYSMONPSU_CFG_REG0_BU_MASK;
645                 } else {
646                         Status = (s32)XST_FAILURE;
647                         goto End;
648                 }
649         }
650
651         /* Select the ADC mode. */
652         if (IsEventMode == TRUE) {
653                 RegValue |= XSYSMONPSU_CFG_REG0_EC_MASK;
654         }
655
656         /* Write the given values into the Configuration Register 0. */
657         RegValue |= ((u32)Channel & XSYSMONPSU_CFG_REG0_MUX_CH_MASK);
658         XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_CFG_REG0_OFFSET,
659                          RegValue);
660
661         Status = (s32)XST_SUCCESS;
662
663 End:
664         return Status;
665 }
666
667 /****************************************************************************/
668 /**
669 *
670 * This function enables the alarm outputs for the specified alarms in the
671 * Configuration Registers 1:
672 *
673 *               - OT for Over Temperature (XSYSMONPSU_CFR_REG1_ALRM_OT_MASK)
674 *               - ALM0 for On board Temperature (XSYSMONPSU_CFR_REG1_ALRM_TEMP_MASK)
675 *               - ALM1 for SUPPLY1 (XSYSMONPSU_CFR_REG1_ALRM_SUPPLY1_MASK)
676 *               - ALM2 for SUPPLY2 (XSYSMONPSU_CFR_REG1_ALRM_SUPPLY2_MASK)
677 *               - ALM3 for SUPPLY3 (XSYSMONPSU_CFR_REG1_ALRM_SUPPLY3_MASK)
678 *               - ALM4 for SUPPLY4 (XSYSMONPSU_CFR_REG1_ALRM__SUPPLY4_MASK)
679 *               - ALM5 for SUPPLY5 (XSYSMONPSU_CFR_REG1_ALRM_SUPPLY5_MASK)
680 *               - ALM6 for SUPPLY6 (XSYSMONPSU_CFR_REG1_ALRM_SUPPLY6_MASK)
681 *
682 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
683 * @param        AlmEnableMask is the bit-mask of the alarm outputs to be enabled
684 *               in the Configuration Registers 1 and 3.
685 *               Bit positions of 1 will be enabled. Bit positions of 0 will be
686 *               disabled. This mask is formed by OR'ing XSYSMONPSU_CFR_REG1_ALRM_*_MASK
687 *               masks defined in xsysmonpsu.h, but XSM_CFR_ALM_SUPPLY8_MASK to
688 *               XSM_CFR_ALM_SUPPLY13_MASK are applicable only for PS.
689 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
690 *       block or PL Sysmon block register region.
691 *
692 * @return       None.
693 *
694 * @note         The implementation of the alarm enables in the Configuration
695 *               register 1 is such that the alarms for bit positions of 0 will
696 *               be enabled and alarms for bit positions of 1 will be disabled.
697 *               The alarm outputs specified by the AlmEnableMask are negated
698 *               before writing to the Configuration Register 1 because it
699 *               was Disable register bits.
700 *               Upper 16 bits of AlmEnableMask are applicable only for PS.
701 *
702 *****************************************************************************/
703 void XSysMonPsu_SetAlarmEnables(XSysMonPsu *InstancePtr, u32 AlmEnableMask,
704                 u32 SysmonBlk)
705 {
706         u32 RegValue;
707         u32 EffectiveBaseAddress;
708
709         /* Assert the arguments. */
710         Xil_AssertVoid(InstancePtr != NULL);
711         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
712         Xil_AssertVoid(AlmEnableMask <=
713                         (XSYSMONPSU_CFG_REG1_ALRM_ALL_MASK |
714                         (XSYSMONPSU_CFG_REG3_ALRM_ALL_MASK << XSM_CFG_ALARM_SHIFT)));
715         Xil_AssertVoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
716
717         /* Calculate the effective baseaddress based on the Sysmon instance. */
718         EffectiveBaseAddress =
719                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
720                                         SysmonBlk);
721
722         RegValue = XSysmonPsu_ReadReg(EffectiveBaseAddress +
723                                         XSYSMONPSU_CFG_REG1_OFFSET);
724         RegValue &= (u32)(~XSYSMONPSU_CFG_REG1_ALRM_ALL_MASK);
725         RegValue |= (~AlmEnableMask & (u32)XSYSMONPSU_CFG_REG1_ALRM_ALL_MASK);
726
727         /*
728          * Enable/disables the alarm enables for the specified alarm bits in the
729          * Configuration Register 1.
730          */
731         XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_CFG_REG1_OFFSET,
732                          RegValue);
733         /* Upper 16 bits of AlmEnableMask are valid only for PS */
734         if (SysmonBlk == XSYSMON_PS) {
735                 RegValue = XSysmonPsu_ReadReg(EffectiveBaseAddress +
736                                         XSYSMONPSU_CFG_REG3_OFFSET);
737                 RegValue &= (u32)(~XSYSMONPSU_CFG_REG3_ALRM_ALL_MASK);
738                 RegValue |= (~(AlmEnableMask >> XSM_CFG_ALARM_SHIFT) &
739                                 (u32)XSYSMONPSU_CFG_REG3_ALRM_ALL_MASK);
740                 XSysmonPsu_WriteReg(EffectiveBaseAddress +
741                         XSYSMONPSU_CFG_REG3_OFFSET, RegValue);
742         }
743 }
744
745 /****************************************************************************/
746 /**
747 *
748 * This function gets the status of the alarm output enables in the
749 * Configuration Register 1.
750 *
751 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
752 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
753 *       block or PL Sysmon block register region.
754 *
755 * @return       This is the bit-mask of the enabled alarm outputs in the
756 *               Configuration Register 1. Use the masks XSYSMONPSU_CFG_REG1_ALRM_*_MASK
757 *               masks defined in xsysmonpsu.h to interpret the returned value.
758 *
759 *               Bit positions of 1 indicate that the alarm output is enabled.
760 *               Bit positions of 0 indicate that the alarm output is disabled.
761 *
762 *
763 * @note         The implementation of the alarm enables in the Configuration
764 *               register 1 is such that alarms for the bit positions of 1 will
765 *               be disabled and alarms for bit positions of 0 will be enabled.
766 *               The enabled alarm outputs returned by this function is the
767 *               negated value of the the data read from the Configuration
768 *               Register 1. Upper 16 bits of return value are valid only if the
769 *               channel selected is PS.
770 *
771 *****************************************************************************/
772 u32 XSysMonPsu_GetAlarmEnables(XSysMonPsu *InstancePtr, u32 SysmonBlk)
773 {
774         u32 RegValue;
775         u32 EffectiveBaseAddress;
776         u32 ReadReg;
777
778         /* Assert the arguments. */
779         Xil_AssertNonvoid(InstancePtr != NULL);
780         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
781         Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
782
783         /* Calculate the effective baseaddress based on the Sysmon instance. */
784         EffectiveBaseAddress =
785                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
786                                         SysmonBlk);
787
788         /*
789          * Read the status of alarm output enables from the Configuration
790          * Register 1.
791          */
792         RegValue = XSysmonPsu_ReadReg(EffectiveBaseAddress +
793                         XSYSMONPSU_CFG_REG1_OFFSET) & XSYSMONPSU_CFG_REG1_ALRM_ALL_MASK;
794         RegValue = (~RegValue & XSYSMONPSU_CFG_REG1_ALRM_ALL_MASK);
795
796         if (SysmonBlk == XSYSMON_PS) {
797                 ReadReg = XSysmonPsu_ReadReg(EffectiveBaseAddress +
798                         XSYSMONPSU_CFG_REG3_OFFSET) & XSYSMONPSU_CFG_REG3_ALRM_ALL_MASK;
799                 ReadReg = (~ReadReg & XSYSMONPSU_CFG_REG3_ALRM_ALL_MASK);
800                 RegValue |= ReadReg << XSM_CFG_ALARM_SHIFT;
801         }
802
803         return RegValue;
804 }
805
806 /****************************************************************************/
807 /**
808 *
809 * This function sets the specified Channel Sequencer Mode in the Configuration
810 * Register 1 :
811 *               - Default safe mode (XSM_SEQ_MODE_SAFE)
812 *               - One pass through sequence (XSM_SEQ_MODE_ONEPASS)
813 *               - Continuous channel sequencing (XSM_SEQ_MODE_CONTINPASS)
814 *               - Single Channel/Sequencer off (XSM_SEQ_MODE_SINGCHAN)
815 *               - Olympus sampling mode (XSM_SEQ_MODE_OYLMPUS)
816 *
817 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
818 * @param        SequencerMode is the sequencer mode to be set.
819 *               Use XSM_SEQ_MODE_* bits defined in xsysmonpsu.h.
820 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
821 *       block or PL Sysmon block register region.
822 *
823 * @return       None.
824 *
825 * @note         Only one of the modes can be enabled at a time.
826 *
827 *****************************************************************************/
828 void XSysMonPsu_SetSequencerMode(XSysMonPsu *InstancePtr, u8 SequencerMode,
829                 u32 SysmonBlk)
830 {
831         u32 RegValue;
832         u32 EffectiveBaseAddress;
833
834         /* Assert the arguments. */
835         Xil_AssertVoid(InstancePtr != NULL);
836         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
837         Xil_AssertVoid((SequencerMode <= XSM_SEQ_MODE_SINGCHAN) ||
838                         (SequencerMode == XSM_SEQ_MODE_OYLMPUS));
839         Xil_AssertVoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
840
841         /* Calculate the effective baseaddress based on the Sysmon instance. */
842         EffectiveBaseAddress =
843                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
844                                         SysmonBlk);
845
846         /* Set the specified sequencer mode in the Configuration Register 1. */
847         RegValue = XSysmonPsu_ReadReg(EffectiveBaseAddress +
848                                         XSYSMONPSU_CFG_REG1_OFFSET);
849         RegValue &= (u32)(~ XSYSMONPSU_CFG_REG1_SEQ_MDE_MASK);
850         RegValue |= (((u32)SequencerMode  << XSYSMONPSU_CFG_REG1_SEQ_MDE_SHIFT) &
851                                         XSYSMONPSU_CFG_REG1_SEQ_MDE_MASK);
852         XSysmonPsu_WriteReg(EffectiveBaseAddress +
853                                         XSYSMONPSU_CFG_REG1_OFFSET, RegValue);
854 }
855
856 /****************************************************************************/
857 /**
858 *
859 * This function gets the channel sequencer mode from the Configuration
860 * Register 1.
861 *
862 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
863 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
864 *       block or PL Sysmon block register region.
865 *
866 * @return       The channel sequencer mode :
867 *               - XSM_SEQ_MODE_SAFE : Default safe mode
868 *               - XSM_SEQ_MODE_ONEPASS : One pass through sequence
869 *               - XSM_SEQ_MODE_CONTINPASS : Continuous channel sequencing
870 *               - XSM_SEQ_MODE_SINGCHAN : Single channel/Sequencer off
871 *               - XSM_SEQ_MODE_OLYMPUS : Olympus sampling mode
872 *
873 * @note         None.
874 *
875 *****************************************************************************/
876 u8 XSysMonPsu_GetSequencerMode(XSysMonPsu *InstancePtr, u32 SysmonBlk)
877 {
878         u8 SequencerMode;
879         u32 EffectiveBaseAddress;
880
881         /* Assert the arguments. */
882         Xil_AssertNonvoid(InstancePtr != NULL);
883         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
884         Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
885
886         /* Calculate the effective baseaddress based on the Sysmon instance. */
887         EffectiveBaseAddress =
888                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
889                                         SysmonBlk);
890
891         /* Read the channel sequencer mode from the Configuration Register 1. */
892         SequencerMode =  ((u8) ((XSysmonPsu_ReadReg(EffectiveBaseAddress +
893                         XSYSMONPSU_CFG_REG1_OFFSET) & XSYSMONPSU_CFG_REG1_SEQ_MDE_MASK) >>
894                         XSYSMONPSU_CFG_REG1_SEQ_MDE_SHIFT));
895
896         return SequencerMode;
897 }
898
899 /****************************************************************************/
900 /**
901 *
902 * The function enables the Event mode or Continuous mode in the sequencer mode.
903 *
904 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
905 * @param        IsEventMode is a boolean parameter that specifies continuous
906 *               sampling (specify FALSE) or event driven sampling mode (specify
907 *               TRUE) for the channel.
908 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
909 *       block or PL Sysmon block register region.
910 *
911 * @return       None.
912 *
913 * @note         None.
914 *
915 *****************************************************************************/
916 void XSysMonPsu_SetSequencerEvent(XSysMonPsu *InstancePtr, u32 IsEventMode,
917                 u32 SysmonBlk)
918 {
919         u32 RegValue;
920         u32 EffectiveBaseAddress;
921
922         /* Assert the arguments. */
923         Xil_AssertVoid(InstancePtr != NULL);
924         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
925         Xil_AssertVoid((IsEventMode == TRUE) || (IsEventMode == FALSE));
926         Xil_AssertVoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
927
928         /* Calculate the effective baseaddress based on the Sysmon instance. */
929         EffectiveBaseAddress =
930                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
931                                         SysmonBlk);
932
933         /* Read the Configuration Register 0. */
934         RegValue = XSysmonPsu_ReadReg(EffectiveBaseAddress +
935                                         XSYSMONPSU_CFG_REG0_OFFSET);
936
937         /* Set the ADC mode. */
938         if (IsEventMode == TRUE) {
939                 RegValue |= XSYSMONPSU_CFG_REG0_EC_MASK;
940         } else {
941                 RegValue &= (u32)(~XSYSMONPSU_CFG_REG0_EC_MASK);
942         }
943
944         XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_CFG_REG0_OFFSET,
945                          RegValue);
946 }
947
948 /****************************************************************************/
949 /**
950 *
951 * The function returns the mode of the sequencer.
952 *
953 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
954 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
955 *       block or PL Sysmon block register region.
956 *
957 * @return       Returns the Sequencer mode. XSYSMONPSU_EVENT_MODE for Event mode
958 *               and XSYSMONPSU_CONTINUOUS_MODE for continuous mode.
959 *
960 * @note         None.
961 *
962 *****************************************************************************/
963 s32 XSysMonPsu_GetSequencerEvent(XSysMonPsu *InstancePtr, u32 SysmonBlk)
964 {
965         s32 Mode;
966         u32 RegValue;
967         u32 EffectiveBaseAddress;
968
969         /* Assert the arguments. */
970         Xil_AssertNonvoid(InstancePtr != NULL);
971         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
972         Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
973
974         /* Calculate the effective baseaddress based on the Sysmon instance. */
975         EffectiveBaseAddress =
976                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
977                                         SysmonBlk);
978
979         /* Read the Configuration Register 0. */
980         RegValue = XSysmonPsu_ReadReg(EffectiveBaseAddress +
981                                         XSYSMONPSU_CFG_REG0_OFFSET);
982
983         RegValue &= XSYSMONPSU_CFG_REG0_EC_MASK;
984
985         if (RegValue == XSYSMONPSU_CFG_REG0_EC_MASK) {
986                 Mode = XSYSMONPSU_EVENT_MODE;
987         } else {
988                 Mode = XSYSMONPSU_CONTINUOUS_MODE;
989         }
990
991         return Mode;
992 }
993
994 /****************************************************************************/
995 /**
996 *
997 * The function enables the external mux and connects a channel to the mux.
998 *
999 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
1000 * @param        Channel is the channel number used to connect to the external
1001 *               Mux. The valid channels are 0 to 5 and 16 to 31.
1002 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
1003 *       block or PL Sysmon block register region.
1004 *
1005 * @return
1006 *               - XST_SUCCESS if the given values were written successfully to
1007 *               the Configuration Register 0.
1008 *               - XST_FAILURE if the channel sequencer is enabled or the input
1009 *               parameters are not valid for the selected channel.
1010 *
1011 * @note         None.
1012 *
1013 *****************************************************************************/
1014 void XSysMonPsu_SetExtenalMux(XSysMonPsu *InstancePtr, u8 Channel, u32 SysmonBlk)
1015 {
1016         u32 RegValue;
1017         u32 EffectiveBaseAddress;
1018
1019         /* Assert the arguments. */
1020         Xil_AssertVoid(InstancePtr != NULL);
1021         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1022         Xil_AssertVoid((Channel <= XSM_CH_VREFN) ||
1023                           ((Channel >= XSM_CH_AUX_MIN) &&
1024                           (Channel <= XSM_CH_AUX_MAX)));
1025         Xil_AssertVoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
1026
1027         /* Calculate the effective baseaddress based on the Sysmon instance. */
1028         EffectiveBaseAddress =
1029                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
1030                                         SysmonBlk);
1031
1032         /*
1033          * Read the Configuration Register 0 and the clear the channel selection
1034          * bits.
1035          */
1036         RegValue = XSysmonPsu_ReadReg(EffectiveBaseAddress +
1037                                         XSYSMONPSU_CFG_REG0_OFFSET);
1038         RegValue &= ~(XSYSMONPSU_CFG_REG0_MUX_CH_MASK);
1039
1040         /* Enable the External Mux and select the channel. */
1041         RegValue |= (XSYSMONPSU_CFG_REG0_XTRNL_MUX_MASK | (u32)Channel);
1042         XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_CFG_REG0_OFFSET,
1043                          RegValue);
1044 }
1045
1046 /****************************************************************************/
1047 /**
1048 *
1049 * The function returns the external mux channel.
1050 *
1051 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
1052 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
1053 *       block or PL Sysmon block register region.
1054 *
1055 * @return       Returns the channel number used to connect to the external
1056 *               Mux. The valid channels are 0 to 6, 8 to 16, and 31 to 36..
1057 *
1058 * @note         None.
1059 *
1060 *****************************************************************************/
1061 u32 XSysMonPsu_GetExtenalMux(XSysMonPsu *InstancePtr, u32 SysmonBlk)
1062 {
1063         u32 RegValue;
1064         u32 EffectiveBaseAddress;
1065
1066         /* Assert the arguments. */
1067         Xil_AssertNonvoid(InstancePtr != NULL);
1068         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1069         Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
1070
1071         /* Calculate the effective baseaddress based on the Sysmon instance. */
1072         EffectiveBaseAddress =
1073                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
1074                                         SysmonBlk);
1075
1076         /*
1077          * Read the Configuration Register 0 and derive the channel selection
1078          * bits.
1079          */
1080         RegValue = XSysmonPsu_ReadReg(EffectiveBaseAddress +
1081                                         XSYSMONPSU_CFG_REG0_OFFSET);
1082         RegValue &= XSYSMONPSU_CFG_REG0_MUX_CH_MASK;
1083
1084         return RegValue;
1085 }
1086
1087 /****************************************************************************/
1088 /**
1089 *
1090 * The function sets the frequency of the ADCCLK by configuring the DCLK to
1091 * ADCCLK ratio in the Configuration Register #2.
1092 *
1093 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
1094 * @param        Divisor is clock divisor used to derive ADCCLK from DCLK.
1095 *               Valid values of the divisor are
1096 *               PS:
1097 *                - 0 means divide by 8.
1098 *                - 1,2 means divide by 2.
1099 *                - 3 to 255 means divide by that value.
1100 *       PL:
1101 *                - 0,1,2 means divide by 2.
1102 *                - 3 to 255 means divide by that value.
1103 *               Refer to the device specification for more details.
1104 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
1105 *       block or PL Sysmon block register region.
1106 *
1107 * @return       None.
1108 *
1109 * @note         - The ADCCLK is an internal clock used by the ADC and is
1110 *               synchronized to the DCLK clock. The ADCCLK is equal to DCLK
1111 *               divided by the user selection in the Configuration Register 2.
1112 *               - There is no Assert on the minimum value of the Divisor.
1113 *
1114 *****************************************************************************/
1115 void XSysMonPsu_SetAdcClkDivisor(XSysMonPsu *InstancePtr, u8 Divisor,
1116             u32 SysmonBlk)
1117 {
1118         u32 RegValue;
1119         u32 EffectiveBaseAddress;
1120
1121         /* Assert the arguments. */
1122         Xil_AssertVoid(InstancePtr != NULL);
1123         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1124         Xil_AssertVoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
1125
1126         /* Calculate the effective baseaddress based on the Sysmon instance. */
1127         EffectiveBaseAddress =
1128                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
1129                                         SysmonBlk);
1130
1131         /*
1132          * Read the Configuration Register 2 and the clear the clock divisor
1133          * bits.
1134          */
1135         RegValue = XSysmonPsu_ReadReg(EffectiveBaseAddress +
1136                                         XSYSMONPSU_CFG_REG2_OFFSET);
1137         RegValue &= ~(XSYSMONPSU_CFG_REG2_CLK_DVDR_MASK);
1138
1139         /* Write the divisor value into the Configuration Register 2. */
1140         RegValue |= ((u32)Divisor << XSYSMONPSU_CFG_REG2_CLK_DVDR_SHIFT) &
1141                                         XSYSMONPSU_CFG_REG2_CLK_DVDR_MASK;
1142         XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_CFG_REG2_OFFSET,
1143                          RegValue);
1144
1145 }
1146
1147 /****************************************************************************/
1148 /**
1149 *
1150 * The function gets the ADCCLK divisor from the Configuration Register 2.
1151 *
1152 * @param        InstancePtr is a pointer to the XSysMon instance.
1153 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
1154 *       block or PL Sysmon block register region.
1155 *
1156 * @return       The divisor read from the Configuration Register 2.
1157 *
1158 * @note         The ADCCLK is an internal clock used by the ADC and is
1159 *               synchronized to the DCLK clock. The ADCCLK is equal to DCLK
1160 *               divided by the user selection in the Configuration Register 2.
1161 *
1162 *****************************************************************************/
1163 u8 XSysMonPsu_GetAdcClkDivisor(XSysMonPsu *InstancePtr, u32 SysmonBlk)
1164 {
1165         u16 Divisor;
1166         u32 EffectiveBaseAddress;
1167
1168         /* Assert the arguments. */
1169         Xil_AssertNonvoid(InstancePtr != NULL);
1170         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1171         Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
1172
1173         /* Calculate the effective baseaddress based on the Sysmon instance. */
1174         EffectiveBaseAddress =
1175                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
1176                                         SysmonBlk);
1177
1178         /* Read the divisor value from the Configuration Register 2. */
1179         Divisor = (u16) XSysmonPsu_ReadReg(EffectiveBaseAddress +
1180                                                         XSYSMONPSU_CFG_REG2_OFFSET);
1181
1182         return (u8) (Divisor >> XSYSMONPSU_CFG_REG2_CLK_DVDR_SHIFT);
1183 }
1184
1185 u8 XSysMonPsu_UpdateAdcClkDivisor(XSysMonPsu *InstancePtr, u32 SysmonBlk)
1186 {
1187         u16 Divisor;
1188         u32 EffectiveBaseAddress;
1189         u32 RegValue;
1190         u32 InputFreq = InstancePtr->Config.InputClockMHz;
1191
1192         /* Assert the arguments. */
1193         Xil_AssertNonvoid(InstancePtr != NULL);
1194         Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
1195
1196         /* Calculate the effective baseaddress based on the Sysmon instance. */
1197         EffectiveBaseAddress =
1198                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
1199                                         SysmonBlk);
1200
1201         /* Read the divisor value from the Configuration Register 2. */
1202         Divisor = (u16) XSysmonPsu_ReadReg(EffectiveBaseAddress +
1203                                                         XSYSMONPSU_CFG_REG2_OFFSET);
1204         Divisor = Divisor >> XSYSMONPSU_CFG_REG2_CLK_DVDR_SHIFT;
1205
1206         while (1) {
1207                 if (!Divisor) {
1208                         if ((SysmonBlk == XSYSMON_PS) &&
1209                         (InputFreq/8 >= 1) && (InputFreq/8 <= 26)) {
1210                                 break;
1211                         } else if ((SysmonBlk == XSYSMON_PL) &&
1212                         (InputFreq/2 >= 1) && (InputFreq/2 <= 26)) {
1213                                 break;
1214                         }
1215                 } else if ((InputFreq/Divisor >= 1) &&
1216                                 (InputFreq/Divisor <= 26)) {
1217                         break;
1218                 } else {
1219                         Divisor += 1;
1220                 }
1221         }
1222
1223         /*
1224          * Read the Configuration Register 2 and the clear the clock divisor
1225          * bits.
1226          */
1227         RegValue = XSysmonPsu_ReadReg(EffectiveBaseAddress +
1228                                         XSYSMONPSU_CFG_REG2_OFFSET);
1229         RegValue &= ~(XSYSMONPSU_CFG_REG2_CLK_DVDR_MASK);
1230
1231         /* Write the divisor value into the Configuration Register 2. */
1232         RegValue |= ((u32)Divisor << XSYSMONPSU_CFG_REG2_CLK_DVDR_SHIFT) &
1233                                         XSYSMONPSU_CFG_REG2_CLK_DVDR_MASK;
1234         XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_CFG_REG2_OFFSET,
1235                          RegValue);
1236
1237         return (u8)Divisor;
1238 }
1239 /****************************************************************************/
1240 /**
1241 *
1242 * This function enables the specified channels in the ADC Channel Selection
1243 * Sequencer Registers. The sequencer must be in the Safe Mode before writing
1244 * to these registers.
1245 *
1246 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
1247 * @param        ChEnableMask is the bit mask of all the channels to be enabled.
1248 *               Use XSYSMONPSU_SEQ_CH* defined in xsysmon_hw.h to specify the Channel
1249 *               numbers. Bit masks of 1 will be enabled and bit mask of 0 will
1250 *               be disabled.
1251 *               The ChEnableMask is a 64 bit mask that is written to the three
1252 *               16 bit ADC Channel Selection Sequencer Registers.
1253 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
1254 *       block or PL Sysmon block register region.
1255 *
1256 * @return
1257 *               - XST_SUCCESS if the given values were written successfully to
1258 *               the ADC Channel Selection Sequencer Registers.
1259 *               - XST_FAILURE if the channel sequencer is enabled.
1260 *
1261 * @note         None.
1262 *
1263 *****************************************************************************/
1264 s32 XSysMonPsu_SetSeqChEnables(XSysMonPsu *InstancePtr, u64 ChEnableMask,
1265                 u32 SysmonBlk)
1266 {
1267         s32 Status;
1268         u32 EffectiveBaseAddress;
1269
1270         /* Assert the arguments. */
1271         Xil_AssertNonvoid(InstancePtr != NULL);
1272         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1273         Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
1274
1275         /*
1276          * The sequencer must be in the Default Safe Mode before writing
1277          * to these registers. Return XST_FAILURE if the channel sequencer
1278          * is enabled.
1279          */
1280         if ((XSysMonPsu_GetSequencerMode(InstancePtr,SysmonBlk) != XSM_SEQ_MODE_SAFE)) {
1281                 Status = (s32)XST_FAILURE;
1282                 goto End;
1283         }
1284
1285         /* Calculate the effective baseaddress based on the Sysmon instance. */
1286         EffectiveBaseAddress =
1287                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
1288                                         SysmonBlk);
1289
1290         /*
1291          * Enable the specified channels in the ADC Channel Selection Sequencer
1292          * Registers.
1293          */
1294         XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_SEQ_CH0_OFFSET,
1295                          (ChEnableMask & XSYSMONPSU_SEQ_CH0_VALID_MASK));
1296
1297         XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_SEQ_CH1_OFFSET,
1298                          (ChEnableMask >> XSM_SEQ_CH_SHIFT) &
1299                          XSYSMONPSU_SEQ_CH1_VALID_MASK);
1300
1301         XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_SEQ_CH2_OFFSET,
1302                                  (ChEnableMask >> XSM_SEQ_CH2_SHIFT) &
1303                          XSYSMONPSU_SEQ_CH2_VALID_MASK);
1304
1305         Status = (s32)XST_SUCCESS;
1306
1307 End:
1308         return Status;
1309 }
1310
1311 /****************************************************************************/
1312 /**
1313 *
1314 * This function gets the channel enable bits status from the ADC Channel
1315 * Selection Sequencer Registers.
1316 *
1317 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
1318 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
1319 *       block or PL Sysmon block register region.
1320 *
1321 * @return       Gets the channel enable bits. Use XSYSMONPSU_SEQ_CH* defined in
1322 *               xsysmonpsu_hw.h to interpret the Channel numbers. Bit masks of 1
1323 *               are the channels that are enabled and bit mask of 0 are
1324 *               the channels that are disabled.
1325 *
1326 * @return       None.
1327 *
1328 * @note         None.
1329 *
1330 *****************************************************************************/
1331 u64 XSysMonPsu_GetSeqChEnables(XSysMonPsu *InstancePtr, u32 SysmonBlk)
1332 {
1333         u64 RegVal;
1334         u32 EffectiveBaseAddress;
1335
1336         /* Assert the arguments. */
1337         Xil_AssertNonvoid(InstancePtr != NULL);
1338         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1339         Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
1340
1341         /* Calculate the effective baseaddress based on the Sysmon instance. */
1342         EffectiveBaseAddress =
1343                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
1344                                         SysmonBlk);
1345
1346         /*
1347          * Read the channel enable bits for all the channels from the ADC
1348          * Channel Selection Register.
1349          */
1350         RegVal = XSysmonPsu_ReadReg(EffectiveBaseAddress +
1351                         XSYSMONPSU_SEQ_CH0_OFFSET) & XSYSMONPSU_SEQ_CH0_VALID_MASK;
1352         RegVal |= (XSysmonPsu_ReadReg(EffectiveBaseAddress +
1353                         XSYSMONPSU_SEQ_CH1_OFFSET) & XSYSMONPSU_SEQ_CH1_VALID_MASK) <<
1354                                         XSM_SEQ_CH_SHIFT;
1355         RegVal |= (u64)(XSysmonPsu_ReadReg(EffectiveBaseAddress +
1356                         XSYSMONPSU_SEQ_CH2_OFFSET) &
1357                         XSYSMONPSU_SEQ_CH2_VALID_MASK) << XSM_SEQ_CH2_SHIFT;
1358
1359         return RegVal;
1360 }
1361
1362 /****************************************************************************/
1363 /**
1364 *
1365 * This function enables the averaging for the specified channels in the ADC
1366 * Channel Averaging Enable Sequencer Registers. The sequencer must be in
1367 * the Safe Mode before writing to these registers.
1368 *
1369 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
1370 * @param        AvgEnableChMask is the bit mask of all the channels for which
1371 *               averaging is to be enabled. Use XSYSMONPSU_SEQ_AVERAGE* defined in
1372 *               xsysmonpsu_hw.h to specify the Channel numbers. Averaging will be
1373 *               enabled for bit masks of 1 and disabled for bit mask of 0.
1374 *               The AvgEnableChMask is a 64 bit mask that is written to the
1375 *               three 16 bit ADC Channel Averaging Enable Sequencer Registers.
1376 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
1377 *       block or PL Sysmon block register region.
1378 *
1379 * @return
1380 *               - XST_SUCCESS if the given values were written successfully to
1381 *               the ADC Channel Averaging Enables Sequencer Registers.
1382 *               - XST_FAILURE if the channel sequencer is enabled.
1383 *
1384 * @note         None.
1385 *
1386 *****************************************************************************/
1387 s32 XSysMonPsu_SetSeqAvgEnables(XSysMonPsu *InstancePtr, u64 AvgEnableChMask,
1388                 u32 SysmonBlk)
1389 {
1390         s32 Status;
1391         u32 EffectiveBaseAddress;
1392
1393         /* Assert the arguments. */
1394         Xil_AssertNonvoid(InstancePtr != NULL);
1395         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1396         Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
1397
1398         /*
1399          * The sequencer must be disabled for writing any of these registers.
1400          * Return XST_FAILURE if the channel sequencer is enabled.
1401          */
1402         if ((XSysMonPsu_GetSequencerMode(InstancePtr,SysmonBlk)
1403                                              != XSM_SEQ_MODE_SAFE)) {
1404                 Status = (s32)XST_FAILURE;
1405         } else {
1406                 /* Calculate the effective baseaddress based on the Sysmon instance. */
1407                 EffectiveBaseAddress =
1408                                 XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
1409                                                 SysmonBlk);
1410                 /*
1411                  * Enable/disable the averaging for the specified channels in the
1412                  * ADC Channel Averaging Enables Sequencer Registers.
1413                  */
1414                 XSysmonPsu_WriteReg(EffectiveBaseAddress +
1415                                 XSYSMONPSU_SEQ_AVERAGE0_OFFSET,
1416                                 (AvgEnableChMask & XSYSMONPSU_SEQ_AVERAGE0_MASK));
1417
1418                 XSysmonPsu_WriteReg(EffectiveBaseAddress +
1419                                 XSYSMONPSU_SEQ_AVERAGE1_OFFSET,
1420                                  (AvgEnableChMask >> XSM_SEQ_CH_SHIFT) &
1421                                  XSYSMONPSU_SEQ_AVERAGE1_MASK);
1422
1423                 XSysmonPsu_WriteReg(EffectiveBaseAddress +
1424                                 XSYSMONPSU_SEQ_AVERAGE2_OFFSET,
1425                                  (AvgEnableChMask >> XSM_SEQ_CH2_SHIFT) &
1426                                  XSYSMONPSU_SEQ_AVERAGE2_MASK);
1427
1428                 Status = (s32)XST_SUCCESS;
1429         }
1430
1431         return Status;
1432 }
1433
1434 /****************************************************************************/
1435 /**
1436 *
1437 * This function returns the channels for which the averaging has been enabled
1438 * in the ADC Channel Averaging Enables Sequencer Registers.
1439 *
1440 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
1441 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
1442 *       block or PL Sysmon block register region.
1443 *
1444 * @returns      The status of averaging (enabled/disabled) for all the channels.
1445 *               Use XSYSMONPSU_SEQ_AVERAGE* defined in xsysmonpsu_hw.h to interpret the
1446 *               Channel numbers. Bit masks of 1 are the channels for which
1447 *               averaging is enabled and bit mask of 0 are the channels for
1448 *               averaging is disabled.
1449 *
1450 * @note         None.
1451 *
1452 *****************************************************************************/
1453 u64 XSysMonPsu_GetSeqAvgEnables(XSysMonPsu *InstancePtr, u32 SysmonBlk)
1454 {
1455         u64 RegVal;
1456         u32 EffectiveBaseAddress;
1457
1458         /* Assert the arguments. */
1459         Xil_AssertNonvoid(InstancePtr != NULL);
1460         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1461         Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
1462
1463         /* Calculate the effective baseaddress based on the Sysmon instance. */
1464         EffectiveBaseAddress =
1465                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
1466                                         SysmonBlk);
1467
1468         /*
1469          * Read the averaging enable status for all the channels from the
1470          * ADC Channel Averaging Enables Sequencer Registers.
1471          */
1472         RegVal = XSysmonPsu_ReadReg(EffectiveBaseAddress +
1473                         XSYSMONPSU_SEQ_AVERAGE0_OFFSET) & XSYSMONPSU_SEQ_AVERAGE0_MASK;
1474         RegVal |= (XSysmonPsu_ReadReg(EffectiveBaseAddress +
1475                         XSYSMONPSU_SEQ_AVERAGE1_OFFSET) & XSYSMONPSU_SEQ_AVERAGE1_MASK) <<
1476                         XSM_SEQ_CH_SHIFT;
1477         RegVal |= (u64)(XSysmonPsu_ReadReg(EffectiveBaseAddress +
1478                         XSYSMONPSU_SEQ_AVERAGE2_OFFSET) &
1479                         XSYSMONPSU_SEQ_AVERAGE2_MASK) << XSM_SEQ_CH2_SHIFT;
1480
1481         return RegVal;
1482 }
1483
1484 /****************************************************************************/
1485 /**
1486 *
1487 * This function sets the Analog input mode for the specified channels in the
1488 * ADC Channel Analog-Input Mode Sequencer Registers. The sequencer must be in
1489 * the Safe Mode before writing to these registers.
1490 *
1491 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
1492 * @param        InputModeChMask is the bit mask of all the channels for which
1493 *               the input mode is differential mode. Use XSYSMONPSU_SEQ_INPUT_MDE*
1494 *               defined in xsysmonpsu_hw.h to specify the channel numbers. Differential
1495 *               or  Bipolar input mode will be set for bit masks of 1 and unipolar input
1496 *               mode for bit masks of 0.
1497 *               The InputModeChMask is a 64 bit mask that is written to the three
1498 *               16 bit ADC Channel Analog-Input Mode Sequencer Registers.
1499 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
1500 *       block or PL Sysmon block register region.
1501 *
1502 * @return
1503 *               - XST_SUCCESS if the given values were written successfully to
1504 *               the ADC Channel Analog-Input Mode Sequencer Registers.
1505 *               - XST_FAILURE if the channel sequencer is enabled.
1506 *
1507 * @note         None.
1508 *
1509 *****************************************************************************/
1510 s32 XSysMonPsu_SetSeqInputMode(XSysMonPsu *InstancePtr, u64 InputModeChMask,
1511                 u32 SysmonBlk)
1512 {
1513         s32 Status;
1514         u32 EffectiveBaseAddress;
1515
1516         /* Assert the arguments. */
1517         Xil_AssertNonvoid(InstancePtr != NULL);
1518         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1519         Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
1520
1521         /*
1522          * The sequencer must be in the Safe Mode before writing to
1523          * these registers. Return XST_FAILURE if the channel sequencer
1524          * is enabled.
1525          */
1526         if ((XSysMonPsu_GetSequencerMode(InstancePtr,SysmonBlk)
1527                                               != XSM_SEQ_MODE_SAFE)) {
1528                 Status = (s32)XST_FAILURE;
1529                 goto End;
1530         }
1531
1532         /* Calculate the effective baseaddress based on the Sysmon instance. */
1533         EffectiveBaseAddress =
1534                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
1535                                         SysmonBlk);
1536
1537         /*
1538          * Set the input mode for the specified channels in the ADC Channel
1539          * Analog-Input Mode Sequencer Registers.
1540          */
1541         XSysmonPsu_WriteReg(EffectiveBaseAddress +
1542                         XSYSMONPSU_SEQ_INPUT_MDE0_OFFSET,
1543                          (InputModeChMask & XSYSMONPSU_SEQ_INPUT_MDE0_MASK));
1544
1545         XSysmonPsu_WriteReg(EffectiveBaseAddress +
1546                         XSYSMONPSU_SEQ_INPUT_MDE1_OFFSET,
1547                          (InputModeChMask >> XSM_SEQ_CH_SHIFT) &
1548                          XSYSMONPSU_SEQ_INPUT_MDE1_MASK);
1549
1550         XSysmonPsu_WriteReg(EffectiveBaseAddress +
1551                 XSYSMONPSU_SEQ_INPUT_MDE2_OFFSET,
1552                  (InputModeChMask >> XSM_SEQ_CH2_SHIFT) &
1553                  XSYSMONPSU_SEQ_INPUT_MDE2_MASK);
1554
1555         Status = (s32)XST_SUCCESS;
1556
1557 End:
1558         return Status;
1559 }
1560
1561 /****************************************************************************/
1562 /**
1563 *
1564 * This function gets the Analog input mode for all the channels from
1565 * the ADC Channel Analog-Input Mode Sequencer Registers.
1566 *
1567 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
1568 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
1569 *       block or PL Sysmon block register region.
1570 *
1571 * @returns      The input mode for all the channels.
1572 *               Use XSYSMONPSU_SEQ_INPUT_MDE* defined in xsysmonpsu_hw.h to interpret the
1573 *               Channel numbers. Bit masks of 1 are the channels for which
1574 *               input mode is differential/Bipolar and bit mask of 0 are the channels
1575 *               for which input mode is unipolar.
1576 *
1577 * @note         None.
1578 *
1579 *****************************************************************************/
1580 u64 XSysMonPsu_GetSeqInputMode(XSysMonPsu *InstancePtr, u32 SysmonBlk)
1581 {
1582         u64 InputMode;
1583         u32 EffectiveBaseAddress;
1584
1585         /* Assert the arguments. */
1586         Xil_AssertNonvoid(InstancePtr != NULL);
1587         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1588         Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
1589
1590         /* Calculate the effective baseaddress based on the Sysmon instance. */
1591         EffectiveBaseAddress =
1592                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
1593                                         SysmonBlk);
1594
1595         /*
1596          *  Get the input mode for all the channels from the ADC Channel
1597          * Analog-Input Mode Sequencer Registers.
1598          */
1599         InputMode = XSysmonPsu_ReadReg(EffectiveBaseAddress +
1600                         XSYSMONPSU_SEQ_INPUT_MDE0_OFFSET) & XSYSMONPSU_SEQ_INPUT_MDE0_MASK;
1601         InputMode |= (XSysmonPsu_ReadReg(EffectiveBaseAddress +
1602                         XSYSMONPSU_SEQ_INPUT_MDE1_OFFSET) & XSYSMONPSU_SEQ_INPUT_MDE1_MASK) <<
1603                                 XSM_SEQ_CH_SHIFT;
1604         InputMode |= (u64)(XSysmonPsu_ReadReg(EffectiveBaseAddress +
1605                         XSYSMONPSU_SEQ_INPUT_MDE2_OFFSET) &
1606                         XSYSMONPSU_SEQ_INPUT_MDE2_MASK) << XSM_SEQ_CH2_SHIFT;
1607
1608         return InputMode;
1609 }
1610
1611 /****************************************************************************/
1612 /**
1613 *
1614 * This function sets the number of Acquisition cycles in the ADC Channel
1615 * Acquisition Time Sequencer Registers. The sequencer must be in the Safe Mode
1616 * before writing to these registers.
1617 *
1618 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
1619 * @param        AcqCyclesChMask is the bit mask of all the channels for which
1620 *               the number of acquisition cycles is to be extended.
1621 *               Use XSYSMONPSU_SEQ_ACQ* defined in xsysmonpsu_hw.h to specify the Channel
1622 *               numbers. Acquisition cycles will be extended to 10 ADCCLK cycles
1623 *               for bit masks of 1 and will be the default 4 ADCCLK cycles for
1624 *               bit masks of 0.
1625 *               The AcqCyclesChMask is a 64 bit mask that is written to the three
1626 *               16 bit ADC Channel Acquisition Time Sequencer Registers.
1627 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
1628 *       block or PL Sysmon block register region.
1629 *
1630 * @return
1631 *               - XST_SUCCESS if the given values were written successfully to
1632 *               the Channel Sequencer Registers.
1633 *               - XST_FAILURE if the channel sequencer is enabled.
1634 *
1635 * @note         None.
1636 *
1637 *****************************************************************************/
1638 s32 XSysMonPsu_SetSeqAcqTime(XSysMonPsu *InstancePtr, u64 AcqCyclesChMask,
1639                 u32 SysmonBlk)
1640 {
1641         s32 Status;
1642         u32 EffectiveBaseAddress;
1643
1644         /* Assert the arguments. */
1645         Xil_AssertNonvoid(InstancePtr != NULL);
1646         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1647         Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
1648
1649         /*
1650          * The sequencer must be in the Safe Mode before writing
1651          * to these registers. Return XST_FAILURE if the channel
1652          * sequencer is enabled.
1653          */
1654         if ((XSysMonPsu_GetSequencerMode(InstancePtr,SysmonBlk)
1655                                              != XSM_SEQ_MODE_SAFE)) {
1656                 Status = (s32)XST_FAILURE;
1657                 goto End;
1658         }
1659
1660         /* Calculate the effective baseaddress based on the Sysmon instance. */
1661         EffectiveBaseAddress =
1662                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
1663                                         SysmonBlk);
1664
1665         /*
1666          * Set the Acquisition time for the specified channels in the
1667          * ADC Channel Acquisition Time Sequencer Registers.
1668          */
1669         XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_SEQ_ACQ0_OFFSET,
1670                          (AcqCyclesChMask & XSYSMONPSU_SEQ_ACQ0_MASK));
1671
1672         XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_SEQ_ACQ1_OFFSET,
1673                          (AcqCyclesChMask >> XSM_SEQ_CH_SHIFT) & XSYSMONPSU_SEQ_ACQ1_MASK);
1674
1675         XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_SEQ_ACQ2_OFFSET,
1676                         (AcqCyclesChMask >> XSM_SEQ_CH2_SHIFT) &
1677                                         XSYSMONPSU_SEQ_ACQ2_MASK);
1678
1679         Status = (s32)XST_SUCCESS;
1680
1681 End:
1682         return Status;
1683 }
1684
1685 /****************************************************************************/
1686 /**
1687 *
1688 * This function gets the status of acquisition time from the ADC Channel Acquisition
1689 * Time Sequencer Registers.
1690 *
1691 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
1692 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
1693 *       block or PL Sysmon block register region.
1694 *
1695 * @returns      The acquisition time for all the channels.
1696 *               Use XSYSMONPSU_SEQ_ACQ* defined in xsysmonpsu_hw.h to interpret the
1697 *               Channel numbers. Bit masks of 1 are the channels for which
1698 *               acquisition cycles are extended and bit mask of 0 are the
1699 *               channels for which acquisition cycles are not extended.
1700 *
1701 * @note         None.
1702 *
1703 *****************************************************************************/
1704 u64 XSysMonPsu_GetSeqAcqTime(XSysMonPsu *InstancePtr, u32 SysmonBlk)
1705 {
1706         u64 RegValAcq;
1707         u32 EffectiveBaseAddress;
1708
1709         /* Assert the arguments. */
1710         Xil_AssertNonvoid(InstancePtr != NULL);
1711         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1712         Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
1713
1714         /* Calculate the effective baseaddress based on the Sysmon instance. */
1715         EffectiveBaseAddress =
1716                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
1717                                         SysmonBlk);
1718
1719         /*
1720          * Get the Acquisition cycles for the specified channels from the ADC
1721          * Channel Acquisition Time Sequencer Registers.
1722          */
1723         RegValAcq = XSysmonPsu_ReadReg(EffectiveBaseAddress +
1724                                         XSYSMONPSU_SEQ_ACQ0_OFFSET) & XSYSMONPSU_SEQ_ACQ0_MASK;
1725         RegValAcq |= (XSysmonPsu_ReadReg(EffectiveBaseAddress +
1726                                         XSYSMONPSU_SEQ_ACQ1_OFFSET) & XSYSMONPSU_SEQ_ACQ1_MASK) <<
1727                                         XSM_SEQ_CH_SHIFT;
1728         RegValAcq |= (u64)(XSysmonPsu_ReadReg(EffectiveBaseAddress +
1729                         XSYSMONPSU_SEQ_ACQ2_OFFSET) &
1730                         XSYSMONPSU_SEQ_ACQ2_MASK) << XSM_SEQ_CH2_SHIFT;
1731
1732         return RegValAcq;
1733 }
1734
1735 /****************************************************************************/
1736 /**
1737 *
1738 * This functions sets the contents of the given Alarm Threshold Register.
1739 *
1740 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
1741 * @param        AlarmThrReg is the index of an Alarm Threshold Register to
1742 *               be set. Use XSM_ATR_* constants defined in xsysmonpsu.h to
1743 *               specify the index.
1744 * @param        Value is the 16-bit threshold value to write into the register.
1745 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
1746 *       block or PL Sysmon block register region.
1747 *
1748 * @return       None.
1749 *
1750 * @note         None.
1751 *
1752 *****************************************************************************/
1753 void XSysMonPsu_SetAlarmThreshold(XSysMonPsu *InstancePtr, u8 AlarmThrReg,
1754                 u16 Value, u32 SysmonBlk)
1755 {
1756         u32 EffectiveBaseAddress;
1757
1758         /* Assert the arguments. */
1759         Xil_AssertVoid(InstancePtr != NULL);
1760         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1761         Xil_AssertVoid((AlarmThrReg <= XSM_ATR_TEMP_RMTE_UPPER) ||
1762                         ((AlarmThrReg >= XSM_ATR_SUP7_LOWER) &&
1763                         (AlarmThrReg <= XSM_ATR_TEMP_RMTE_LOWER)));
1764         Xil_AssertVoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
1765
1766         /* Calculate the effective baseaddress based on the Sysmon instance. */
1767         EffectiveBaseAddress =
1768                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
1769                                         SysmonBlk);
1770
1771         /* Write the value into the specified Alarm Threshold Register. */
1772         XSysmonPsu_WriteReg(EffectiveBaseAddress + XSYSMONPSU_ALRM_TEMP_UPR_OFFSET +
1773                         ((u32)AlarmThrReg << 2U), Value);
1774 }
1775
1776 /****************************************************************************/
1777 /**
1778 *
1779 * This function returns the contents of the specified Alarm Threshold Register.
1780 *
1781 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
1782 * @param        AlarmThrReg is the index of an Alarm Threshold Register
1783 *               to be read. Use XSM_ATR_* constants defined in xsysmonpsu.h
1784 *               to specify the index.
1785 * @param        SysmonBlk is the value that tells whether it is for PS Sysmon
1786 *       block or PL Sysmon block register region.
1787 *
1788 * @return       A 16-bit value representing the contents of the selected Alarm
1789 *               Threshold Register.
1790 *
1791 * @note         None.
1792 *
1793 *****************************************************************************/
1794 u16 XSysMonPsu_GetAlarmThreshold(XSysMonPsu *InstancePtr, u8 AlarmThrReg,
1795                 u32 SysmonBlk)
1796 {
1797         u16 AlarmThreshold;
1798         u32 EffectiveBaseAddress;
1799
1800         /* Assert the arguments. */
1801         Xil_AssertNonvoid(InstancePtr != NULL);
1802         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1803         Xil_AssertNonvoid((AlarmThrReg <= XSM_ATR_TEMP_RMTE_UPPER) ||
1804                         ((AlarmThrReg >= XSM_ATR_SUP7_LOWER) &&
1805                         (AlarmThrReg <= XSM_ATR_TEMP_RMTE_LOWER)));
1806         Xil_AssertNonvoid((SysmonBlk == XSYSMON_PS)||(SysmonBlk == XSYSMON_PL));
1807
1808         /* Calculate the effective baseaddress based on the Sysmon instance. */
1809         EffectiveBaseAddress =
1810                         XSysMonPsu_GetEffBaseAddress(InstancePtr->Config.BaseAddress,
1811                                         SysmonBlk);
1812
1813         /*
1814          * Read the specified Alarm Threshold Register and return
1815          * the value.
1816          */
1817         AlarmThreshold = (u16) XSysmonPsu_ReadReg(EffectiveBaseAddress +
1818                         XSYSMONPSU_ALRM_TEMP_UPR_OFFSET + ((u32)AlarmThrReg << 2));
1819
1820         return AlarmThreshold;
1821 }
1822
1823 /****************************************************************************/
1824 /**
1825 *
1826 * This function sets the conversion to be automatic for PS SysMon.
1827 *
1828 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
1829 *
1830 * @return       None
1831 *
1832 * @note         In the auto-trigger mode, sample rate is of 1 Million samples.
1833 *
1834 *****************************************************************************/
1835 void XSysMonPsu_SetPSAutoConversion(XSysMonPsu *InstancePtr)
1836 {
1837         u32 PSSysMonStatusReg;
1838
1839         /* Assert the arguments. */
1840         Xil_AssertVoid(InstancePtr != NULL);
1841         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1842
1843         /* Set the automatic conversion triggering in PS control register. */
1844         PSSysMonStatusReg = XSysmonPsu_ReadReg(InstancePtr->Config.BaseAddress +
1845                         XSYSMONPSU_PS_SYSMON_CSTS_OFFSET);
1846         PSSysMonStatusReg |= XSYSMONPSU_PS_SYSMON_CSTS_AUTO_CONVST_MASK;
1847         XSysmonPsu_WriteReg(InstancePtr->Config.BaseAddress +
1848                         XSYSMONPSU_PS_SYSMON_CSTS_OFFSET, PSSysMonStatusReg);
1849 }
1850
1851 /****************************************************************************/
1852 /**
1853 *
1854 * This function gets the AMS monitor status.
1855 *
1856 * @param        InstancePtr is a pointer to the XSysMonPsu instance.
1857 *
1858 * @return       Returns the monitor status. See XSYSMONPSU_MON_STS_*_MASK
1859 *               definations present in xsysmonpsu_hw.h for knowing the status.
1860 *
1861 * @note         None
1862 * .
1863 *****************************************************************************/
1864 u32 XSysMonPsu_GetMonitorStatus(XSysMonPsu *InstancePtr)
1865 {
1866         u32 AMSMonStatusReg;
1867
1868         /* Assert the arguments. */
1869         Xil_AssertNonvoid(InstancePtr != NULL);
1870         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
1871
1872         /*
1873          * Read the AMS monitor status. This gives tells about JTAG Locked / ADC
1874          * busy / ADC Current Channel number and its ADC output.
1875          */
1876         AMSMonStatusReg = XSysmonPsu_ReadReg(InstancePtr->Config.BaseAddress +
1877                         XSYSMONPSU_MON_STS_OFFSET);
1878
1879         return AMSMonStatusReg;
1880 }
1881
1882 /** @} */