UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Observer arbona
Observer
4,445 Views
Registered: ‎08-22-2017

Temperature always zero from XADC

Jump to solution

Hello all,

 

I am having some trouble with the internal temperature and voltage monitor of the Kintex-7 XC7K160T. They always return 0 when reading them through the AXI interface, JTAG (hardware monitor of Vivado) and temperature output (the one used for the MIG IP).

 

I tried testing it by creating a simple project with only the XADC, microblaze and the bare minimum blocks. The C code resets the XADC (so this thread https://forums.xilinx.com/t5/7-Series-FPGAs/Can-t-read-temperature-from-XADC-IP/m-p/712327 does not apply because I do reset the core).

 

Other than that the code just reads the temperature using XSysMon_GetAdcData (blocking before waiting for the EOS bit to be set).

 

I tried several settings in the IP core GUI, but I guess the correct one is with the channel sequencer, in continuous mode and with only the temperature and the 2 internal voltages enabled. I disabled averaging and calibration because I had trouble with them (probably related).

 

I also tried without microblaze (just creating the XADC core and debugging it with probes) without success.

 

It is worth mentioning that the board is custom-made, with VP_0, VN_0, VREFP_0, VREFN_0, DXP_0 and DXN_0 connected to ground (the datasheet says that if no external ADC is needed, they can all be grounded).

 

The AXI clock is set to 100MHz, so the DCLK setting in the DRP Timing Option block is also set to 100MHz, 1000 KSPS  and a clock divider of 4 giving an internal ADC Clock frequency of 25MHz (inside the limits according to the datasheet).

 

Lastly, the FPGA is not the only device in the JTAG chain (there are 2 PROM before and the FPGA has a Flash memory too), and it gives us problems (see https://forums.xilinx.com/t5/Configuration/Device-order-in-JTAG-chain/td-p/760419 ) so we have to program the FPGA using IMPACT instead of Vivado (but that's another issue), but, as I said, JTAG reports also all internal readings to be 0, so it might be related.

 

Right now I don't know if it is a hardware design problem of our board or a settings problem or some kind of bug because of the JTAG chain... Any ideas or pointers to continue my research on the problem?

 

I am using Vivado 2016.4, and iMPACT 14.2 for uploading the bitfile.

 

Thanks in advance.

0 Kudos
1 Solution

Accepted Solutions
Observer arbona
Observer
6,414 Views
Registered: ‎08-22-2017

Re: Temperature always zero from XADC

Jump to solution

Problem solved.

VREFP_0 was incorrectly connected to GND via a capacitor instead of being directly connected. I guess that caused the XADC block to fail.

 

Thanks to probus and his thread https://forums.xilinx.com/t5/7-Series-FPGAs/XADC-Stops-Working/m-p/797943#M23568 for the help.

View solution in original post

0 Kudos
6 Replies
Scholar austin
Scholar
4,421 Views
Registered: ‎02-27-2008

Re: Temperature always zero from XADC

Jump to solution

Do you have the reference voltage for the XADC supplied on your board?

 

See xapp 554

Austin Lesea
Principal Engineer
Xilinx San Jose
0 Kudos
Observer arbona
Observer
4,364 Views
Registered: ‎08-22-2017

Re: Temperature always zero from XADC

Jump to solution

No, the reference voltage (Vrefn and Vrefp) are tied to GND.

 

UG480 (v1.9) says at page 77:

 

The XADC also has an on-chip reference option which is selected by connecting VREFP and
VREFN to ADCGND as shown in Figure 6-1. Due to reduced accuracy, the on-chip reference
does impact the measurement performance of the XADC as explained previously.

As we are only using the internal temperature monitor and internal voltages, we thought that we did not need an external reference voltage.

 

Vccadc is fed with 1.8V and GNDadc is connected to our common GND.

0 Kudos
Highlighted
Xilinx Employee
Xilinx Employee
4,315 Views
Registered: ‎09-05-2007

Re: Temperature always zero from XADC

Jump to solution

@arbona

 

Having just been through the following long saga involving XADC....

 

https://forums.xilinx.com/t5/7-Series-FPGAs/XADC-Invalid-channel-ouput/td-p/786592

 

...I'm inclined to say that it is well worth ruling out JTAG interference before anything else. Try observing the JTAGLOCKED status signal and/or try configuring your device with your design using master mode and Flash memory so that JTAG isn't involved (or connected) at all.

 

 

Ken Chapman
Principal Engineer, Xilinx UK
0 Kudos
Observer arbona
Observer
4,297 Views
Registered: ‎08-22-2017

Re: Temperature always zero from XADC

Jump to solution

@chapman

 

I tried without connecting the JTAG cable but I get the same result.

 

Our board has two PROM (and a Flash memory but currently unusable due to hardware problems) to configure the FPGA. I flashed the bitfile into the PROMs and disconnected the JTAG cable completely from the board. Note that the PROM's are part of the JTAG chain anyway, but I think that if the cable is disconnected from the board it shouldn't matter, right?

 

What I did is: after a successful flash and verification I powered down the board, disconnected the JTAG cable and power up the board again to make sure that the contents are loaded into the FPGA. Then, the values of the XADC are dumped periodically to an external UART by a small MicroBlaze program.

 

Just in case, this is my code:

#include <stdio.h>
#include "xil_printf.h"
#include "sleep.h"
#include "xparameters.h"

#include "xsysmon.h"

XSysMon_Config* config_;
XSysMon monitor_;

static
void XADCInit()
{
	config_ = XSysMon_LookupConfig(XPAR_SYSMON_0_DEVICE_ID);

	if(XSysMon_CfgInitialize(&monitor_, config_, config_->BaseAddress) != XST_SUCCESS)
	{
		print("Error at XSysMon_CfgInitialize\n");
		sleep(5);
		return;
	}

	if(XSysMon_SelfTest(&monitor_) != XST_SUCCESS)
	{
		print("Error at XSysMon_SelfTest\n");
		sleep(5);
		return;
	}



	XSysMon_Reset(&monitor_);

	XSysMon_SetSequencerMode(&monitor_, XSM_SEQ_MODE_SAFE);

	XSysMon_SetAlarmEnables(&monitor_, 0x0);

	XSysMon_SetAvg(&monitor_, XSM_AVG_0_SAMPLES);

	if(XSysMon_SetSeqInputMode(&monitor_, 0) != XST_SUCCESS)
	{
		print("Error at XSysMon_SetSeqInputMode\n");
		sleep(5);
		return;
	}

	if(XSysMon_SetSeqAcqTime(&monitor_,
	                         XSM_SEQ_CH_TEMP |
	                         XSM_SEQ_CH_VCCINT |
	                         XSM_SEQ_CH_VCCAUX) != XST_SUCCESS)
	{
		print("Error at XSysMon_SetSeqAcqTime\n");
		sleep(5);
		return;
	}

	if(XSysMon_SetSeqAvgEnables(&monitor_, 0/*
	                            XSM_SEQ_CH_TEMP |
	                            XSM_SEQ_CH_VCCINT |
	                            XSM_SEQ_CH_VCCAUX*/) != XST_SUCCESS)
	{
		print("Error at XSysMon_SetSeqAvgEnables\n");
		sleep(5);
		return;
	}

	/*
	if(XSysMon_SetSingleChParams(&monitor_, XSM_CH_TEMP, 0, 1, 0) != XST_SUCCESS)
	{
		print("Error at XSysMon_SetSeqChEnables\n");
		sleep(5);
		return;
	}
	*/

	if(XSysMon_SetSeqChEnables(&monitor_,
	                           XSM_SEQ_CH_TEMP |
	                           XSM_SEQ_CH_VCCINT |
	                           XSM_SEQ_CH_VCCAUX) != XST_SUCCESS)
	{
		print("Error at XSysMon_SetSeqChEnables\n");
		sleep(5);
		return;
	}

	XSysMon_SetAdcClkDivisor(&monitor_, 32);

	XSysMon_SetSequencerMode(&monitor_, XSM_SEQ_MODE_CONTINPASS);
}

static
float getTemperature(float* max, float* min)
{
	uint32_t raw;
	float current;

	if(max)
	{
		*max = 0;
	}

	if(min)
	{
		*min = 0;
	}

	raw = XSysMon_GetAdcData(&monitor_, XSM_CH_TEMP);
	current = XSysMon_RawToTemperature(raw);

	if(max)
	{
		raw = XSysMon_GetMinMaxMeasurement(&monitor_, XSM_MAX_TEMP);
		*max = XSysMon_RawToTemperature(raw);
	}

	if(min)
	{
		raw = XSysMon_GetMinMaxMeasurement(&monitor_, XSM_MIN_TEMP);
		*min = XSysMon_RawToTemperature(raw);
	}

	return current;
}

static
int fractToInt(float f)
{
	if(f < 0)
	{
		f = -f;
	}

	return ((int)((f -(float)((int)f)) * (1000.0f)));
}

int main()
{
	float adc_act, adc_max, adc_min;
	uint32_t adc_raw;

	print("Initializing\n\r");
	GPIOInit();
	XADCInit();

	print("Main loop\n\r");
	while(1)
	{
		sleep(1);

		//XSysMon_StartAdcConversion(&monitor_);

		while((XSysMon_GetStatus(&monitor_) & XSM_SR_EOS_MASK) != XSM_SR_EOS_MASK);
		adc_raw = *((volatile uint32_t*) XPAR_SYSMON_0_BASEADDR + 0x200);
		adc_act = getTemperature(&adc_max, &adc_min);
		xil_printf("\tSystem temperature: RAW: 0x%04X, %d.%03d (%d.%03d ~ %d.%03d)\n\r",
		           adc_raw,
		           (int)(adc_act), fractToInt(adc_act),
		           (int)(adc_min), fractToInt(adc_min),
		           (int)(adc_max), fractToInt(adc_max));
	}

	return 0;
}

At the beginning I was using 4 as my AdcClkDivisor but in the samples it is always set to 32 so I tried that too. I also tried with single channel mode without success.

0 Kudos
Observer arbona
Observer
4,296 Views
Registered: ‎08-22-2017

Re: Temperature always zero from XADC

Jump to solution

I just noticed that the way to access the raw register is:

adc_raw = *((volatile uint32_t*)(XPAR_SYSMON_0_BASEADDR + 0x200));

But I can't edit my post. The value reported is still 0 always.

0 Kudos
Observer arbona
Observer
6,415 Views
Registered: ‎08-22-2017

Re: Temperature always zero from XADC

Jump to solution

Problem solved.

VREFP_0 was incorrectly connected to GND via a capacitor instead of being directly connected. I guess that caused the XADC block to fail.

 

Thanks to probus and his thread https://forums.xilinx.com/t5/7-Series-FPGAs/XADC-Stops-Working/m-p/797943#M23568 for the help.

View solution in original post

0 Kudos