XMEGA32E5 ADC Troubles

Go To Last Post
20 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello All,

 

I have an ATxmega32E5 MCU on a custom target PCB.  There is an external 2.500V reference on AREF.  I wrote a test loop where an ADC conversion is started, waits until conversion is complete, then sends ASCII decimal conversion value over the UART.  This repeats indefinitely unless the use hits a key.

The first 20 (or so) converted values are garbage - bouncing around and totally unrelated to the voltage applied to the ADC input.  After that, everything seems to be fine.  What is it that causes the first 20 conversions to be garbaged?

 

There is obviously some trick to using this ADC peripheral.  If anyone knows what it is, I'd appreciate them sharing it.

 

I have gone through the documentation, such as it is.  Everything seems to be configured properly, else I wouldn't be getting the correct readings (after the garbage ends).

 

Thanks in advance!

 

Altazi

Last Edited: Sun. Mar 22, 2020 - 05:45 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You have been a member for 7 years.

 

Post your code if you want a sensible reply.

Just ZIP up your AS7.0 project and attach the ZIP.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
;------------------------------------------------------------------------------
; Initialize ADC
;------------------------------------------------------------------------------
;
; Port A	Pin	Func	Name		ADC/Other										Connector
;									
;PA0		6	AVREF	PA0_AVREF	ADC0/AREF										P2-8
;PA1		5	AIN		DC_MEAS		ADC1											-
;PA2		4	AIN		PA2_ANL		ADC2/DAC0										P2-7
;PA3		3	AIN		AMB_LIGHT	ADC3/DAC1										-

	LDI		R16,$01				; enable ADC
	STS		ADCA_CTRLA,R16		;
	LDI		R16,$10				; hi-speed, signed mode, no free run, 12-bit RA
;	LDI		R16,$18				; hi-speed, signed mode, free run, 12-bit RA
	STS		ADCA_CTRLB,R16		;
	LDI		R16,$23				; ext. reference AREFA, bandgap & temp enabled
	STS		ADCA_REFCTRL,R16	;
	LDI		R16,$01				; ADC prescaler PCLK/8
	STS		ADCA_PRESCALER,R16	;
	LDI		R16,$00				; sampling time = (SAMPVAL+1) * (ADC_CLK/2)
	STS		ADCA_SAMPCTRL,R16	;

; Get calibration data from production signature row

	LDI		R30,$20				; offset for ADCA Cal 1 value
	CALL	RD_SIG				; return byte in R16, increments R30 automatically
	STS		ADCA_CAL,R16		; store cal byte low
	CALL	RD_SIG				; return byte in R16, increments R30 automatically
	STS		ADCA_CAL+1,R16		; store cal byte low

That's the ADC initialization code.  Here is the channel config and conversion loop.

 

HC_AX_EXE:

; Get channel number from command string

	CALL	GETNUM8				; get numeric 8-bit value from command string in R16
	BRNE	HC_AX_99			; jump out on error

	CPI		R16,0				; 0 is invalid
	BREQ	HC_AX_99			; skip out if 0

	CPI		R16,4				; >3 is invalid
	BREQ	HC_AX_99			; skip out if >3

; Shift channel selection into bits 4 & 3

;								  b7 b6 b5 b4 b3 b2 b1 b0
;								  0  0  0  0  0  0  C1 C0	initial
	LSL		R16					; 0  0  0  0  0  C1 C0  0
	LSL		R16					; 0  0  0  0  C1 C0  0  0
	LSL		R16					; 0  0  0  C1 C0  0  0  0
	MOV		R17,R16				; save shifted channel selection in R17

; Start ADC conversion on selected external channel 1-3

	LDI		R16,$01				; 1x gain, external positive single-ended input mode
	STS		ADCA_CH0_CTRL,R16

	STS		ADCA_CH0_MUXCTRL,R17	; < selected channel in mux

; ADC conversion loop - check for keypress (exit?)

HC_AX_10:
	CALL	CHRCV				; get char in R16
	BRNE	HC_AX_95			; skip out if char detected

; Start ADC conversion

	LDS		R16,ADCA_CTRLA		; get ADCA control reg
	SBR		R16,$04				; set 'START' bit
;	SBR		R16,$06				; set 'START' and 'FLUSH' bits
	STS		ADCA_CTRLA,R16		;

; Wait for conversion to complete

HC_AX_20:
	LDS		R16,ADCA_INTFLAGS	; get ADC status
	SBRS	R16,0				; skip out if START is cleared
	RJMP	HC_AX_20			; loop until complete

	STS		ADCA_INTFLAGS,R16	; write '1' to clear interrupt flag

; Get ADC results

	LDS		R16,ADCA_CH0_RES	; get CH0 results low byte
	LDS		R17,ADCA_CH0_RES+1	; get CH0 results high byte
	CALL	DECO16				; send results
	CALL	CROUT				; new line

	RJMP	HC_AX_10			; loop until exit

; completed

HC_AX_95:
	LDI		R16,0				; no error possible
	STS		ERRCODE,R16			;

HC_AX_99:
	JMP		XMON_END			; done

HC_AX_END:

So let's have that sensible reply, please.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I strongly recommend that you use the official macros e.g.  ADC_CH_IF_bm

 

I am not going to go over your magic numbers with a fine tooth comb.

If you had posted a buildable ZIP,  I would probably have viewed the ADC bits in AS7.0 debugger with real hardware.   (i.e. my new 32E5 XPLD)

 

It is your job to check your magic numbers.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Altazi wrote:
What is it that causes the first 20 conversions to be garbaged?
What's the source resistance and impedance?

Reason : XMEGA have limits on source impedance versus sampling time duration though XMEGA E has an additional capability for high-impedance sensors (variable sampling time duration)

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

14k ohms in parallel with a 100nF MLCC.

 

Conversions on internal channels (temp, band gap, etc) are similarly screwed up.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have a page about these strange ADC's: http://barefootelectronics.com/x...

 

Did you know there is a minimum ADC frequency?

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have successfully used the ADC in the ATxmega128A1U, and (apparently) foolishly assumed that what I had learned would apply to the 32E5.  Not so, it seems.

 

It is difficult not to think that Atmel screwed the pooch with their ADC implementation.

 

Thanks for the link - I will work through it.

 

Altazi

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Altazi wrote:

 

It is difficult not to think that Atmel screwed the pooch with their ADC implementation.

 

 

I mention that they call it a feature, but looks like a bug to me. I wonder if the E5 series was made as a quick and dirty solution to somebody's immediate problem. Also, the SPI peripheral stops working as soon as you try to start any PWM on port C.

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Surely the 32E5 has got a full PORTC and a full PORTD.

 

It only gives you SPIC as SPI Slave.   And USART_MSPI on USARTC0, USARTD0 which can be remapped to different pins.

Of course you can also use SPIC as a Master (if you like crippled SPI)

 

Most PWM pins are on PORTC.   OC5A, OC5B can be on PORTD

 

Yes,  the E series is definitely cut-price.   But it is adequate for many projects.

When several peripheral functions are multiplexed you will always have conflicts.    After all,   there are not many legs on this device.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Altazi wrote:
... band gap ...
Therefore, the internal reference will malfunction.

Bandgap is dependent on AVCC of adequate stability and low enough noise (AVR don't have a PSRR spec, XMEGA ADC does have typical noise data)

AVR1300: Using the AVR XMEGA ADC

If the XMEGA is functional on a battery or cell then the board's power supply may have a defect.

Unconditionally stable, ultra-low noise, ultra reliable : battery or cell, resistor, zener diode (noise is very low frequency due to battery or cell discharge)

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In my application, the bandgap reference is used only as a voltage input on an internal ADC channel, and this only for experimental testing.  I have an LM4132 2.500V external reference on AREF, which is VERY stable.  The VDD for the device is also stable.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I see the E5's are discontinued at digikey.

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, that's not what it said yesterday. Perhaps my search got an old variant.

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

more likely is the ones in, with, and at Digi-Key having to make adjustments due to some of them working from their domiciles

stocking data rolls to the electronics search engines (dependencies abound)

COVID-19 Update | DigiKey

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have two suggestions. The first one is to discharge the sampling capacitor for the ADC by connecting it to the VSS channel. This might fix the problem, but seeing as you get around 20 garbage results, the problem might be from somewhere else. 

 

I suggest adding a delay at the beginning of the code equal to the number of conversions and check to see if it solves the problem. Maybe play with the ADC clock frequency a bit and see if that helps.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the suggestion. Slowing the ADC clock way down (125kHz) made a big difference. The datasheet said  1.8MHz Max for the external channels, and 125kHz typ. For the internal channels. It likes 125kHz better for everything.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The ones in, with, and at Dig-Key have been impacted by Minnesota Governor Tim Walz order that may be a stay-at-home order.

COVID-19 Update | DigiKey (updated 30-Mar'20)

 

"Dare to be naïve." - Buckminster Fuller