XMEGA ADC Problems

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

I've been trying to follow the thread below to get my ATXMEGA128A1's ADC functioning.

https://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=68692&highlight=offset+adc+xmega

Unfortunately, I am still having problems. I am running with the 1V reference (I get the feeling around here that it is the only 'safe' way to go). I have tried running both in signed and unsigned mode, and both in differential and single ended mode. I am reading the inputs at the pins of the STK600 with multiple meters.

Here are some of my results:

Signed Differential Error = +6 LSB
Signed Single Ended Error = -25 LSB
Unsigned Single Ended Error = +48 LSB

I think I have a rev. H chip. Here is the backside, (I'm not sure how to tell other than assuming the H represents a rev.H chip)

8J1883
35953H
1-P
0904 e3

The rev.H Errata only says a +/-2LSB error when operating at a voltage refernce below 3V.

I have derived the code essentially from the ATMEL App Note. There is a discussion in the above thread that the CAL register is mislabled in AVR Studio. Is that still the case? I have attempted to read the adc with and without adding the calibration offset, and either way it only makes a difference by 2-4 LSB's. Perhaps the offset is much greater, and I'm not reading it right.

The IOX128a1.h file I am using in with WINAVR-20090313 defines the following adc registers. Are these correct at this point? The only reason I ask is there has been a discussion in the previous thead that these are wrong. If I'm not calibrating correctly, maybe that is the problem.

#define ADCA_CAL _SFR_MEM8(0x020c)
#define ADCA_CALCTRL _SFR_MEM8(0x0205)

So my ultimate question is if it is known that these two numbers need to be swapped? And I am also open to any other suggestions as to how to help figure out what I am doing wrong, if anything.

Sorry for the long, somewhat rambling post.

Jeff

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

Quote:

I think I have a rev. H chip. Here is the backside, (I'm not sure how to tell other than assuming the H represents a rev.H chip)

This code will tell you:

 device_id0_u8 = MCU.DEVID0;
 device_id1_u8 = MCU.DEVID1;
 device_id2_u8 = MCU.DEVID2;
 rev_leter_u8  = (uint8_t) (MCU.REVID+'A');
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

rev_leter_u8 = (uint8_t) (MCU.REVID+'A');

I didn't know that--nice. I remember the questions on unknown rev. G/H; apparently no-one else here noticed it either.
Quote:

• Bit 3:0 - REVID[3:0]: MCU Revision ID

As we are now at
Quote:
35.1 ATxmega128A1 rev. H
is that going to be enough bits? ;)

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

jcrollman wrote:

Unfortunately, I am still having problems.
Jeff

Hi Jeff,

I haven't played with the A/D much yet, but so far it looks good in single-ended signed mode here.

Without even applying calibrations, I am getting good numbers using 1V reference. I am running at 30Mhz for the test with ADC_PRESCALER_DIV256_gc, and 1X gain. These number are not averaged, just raw reads.

1.0018V input on channel 0, 16 reads:
0801, 0801, 0801, 0801, 0801, 0801, 0801, 0801, 0801, 0801, 0801, 0801, 0801, 0801, 0801,

0.5018V:
0409, 0412, 0415, 0419, 0409, 040e, 0417, 0416, 0407, 040d, 0410, 0413, 040c, 0410, 040f

11.2mV:
0017, 0017, 0014, 0017, 0010, 000f, 0010, 0010, 000f, 000f, 0017, 000f, 0007, 000a, 0013

Have you played with the prescaler?

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

Quote:
Without even applying calibrations, I am getting good numbers using 1V reference. I am running at 30Mhz for the test with ADC_PRESCALER_DIV256_gc, and 1X gain. These number are not averaged, just raw reads.

1.0018V input on channel 0, 16 reads:
0801, 0801, 0801, 0801, 0801, 0801, 0801, 0801, 0801, 0801, 0801, 0801, 0801, 0801, 0801,

0.5018V:
0409, 0412, 0415, 0419, 0409, 040e, 0417, 0416, 0407, 040d, 0410, 0413, 040c, 0410, 040f

11.2mV:
0017, 0017, 0014, 0017, 0010, 000f, 0010, 0010, 000f, 000f, 0017, 000f, 0007, 000a, 0013

Maybe I'm confused here, but shouldn't your raw readings for 1V be at 0x4095ish for signed single ended,and 0x204Aish for 1/2 volt?

I am using the prescaler at x16 with a peripheral clock of 2Mhz. Regardless of how I set my prescaler, the output readings are the same. I am also using x1 gain, and I verified the rev.H chip. Sorry for the delay in response, 4th of July and all...

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

jcrollman wrote:
Quote:

Maybe I'm confused here, but shouldn't your raw readings for 1V be at 0x4095ish for signed single ended,and 0x204Aish for 1/2 volt?

Sorry, I missed the 0x in the printf... those are base 16 numbers.

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

Quote:
Maybe I'm confused here, but shouldn't your raw readings for 1V be at 0x4095ish for signed single ended,and 0x204Aish for 1/2 volt?

Forget this, it is giberrish. I'm doing hex calculations on decimal numbers. That aside, shouldn't 1V volt reading with the 1V reference be 0x0FFF? And then 1/2V would be 0x0800? I'm just trying to understand in case I'm missing something.

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

jcrollman wrote:
Quote:
Maybe I'm confused here, but shouldn't your raw readings for 1V be at 0x4095ish for signed single ended,and 0x204Aish for 1/2 volt?

Forget this, it is giberrish. I'm doing hex calculations on decimal numbers. That aside, shouldn't 1V volt reading with the 1V reference be 0x0FFF? And then 1/2V would be 0x0800? I'm just trying to understand in case I'm missing something.

12-bits in signed mode would be 0x000 - 0x7ff for 0 to 1V. The xmega lets you go a little above and below the reference (very cool). 0xfff to 0x800 would be 0 to -1V (although I didn't test the negative inputs yet). Note, I could be wrong here. I've only played with the A/D long enough to respond to your post ;)

[edit] Now that I think about that some more, that would imply that there is some overlap and that wouldn't be too nice. I'm going to look into this more.

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

telliott wrote:

12-bits in signed mode would be 0x000 - 0x7ff for 0 to 1V. The xmega lets you go a little above and below the reference (very cool). 0xfff to 0x800 would be 0 to -1V

Oops. I'm way off here. It does read above and below the reference by about 0.3V volts from what I'm seeing (probably esd protection diode drop), but not to -1V. Sorry I'll do a little more testing and reading of the datasheet before I post again :oops:

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

Quote:
12-bits in signed mode would be 0x000 - 0x7ff for 0 to 1V. The xmega lets you go a little above and below the reference (very cool). 0xfff to 0x800 would be 0 to -1V (although I didn't test the negative inputs yet). Note, I could be wrong here. I've only played with the A/D long enough to respond to your post

Ah yes, for some reason I thought you were operating in unsigned mode. Then it all makes sense.

Quote:
It does read above and below the reference by about 0.3V volts from what I'm seeing (probably esd protection diode drop), but not to -1V. Sorry I'll do a little more testing and reading of the datasheet before I post again

I will have to look into this more, because I don't think I understand the nuances of the single ended mode yet. But I'm still off in even differential mode, which should be fairly straightforward.

One thing I am noticing is that when I input a voltage to the ADC, the voltage is different than when the line isn't connected. e.g. I have a .6V input to the ADC from a voltage divider when disconnected from the AVR, but when I connect the line to to ADCA (PORTA, pin0), the voltage drops to .45V. I don't have any pull-ups enabled. Why the voltage drop? Could this be clue?

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

Forget what I said about the 0.3V too... I should have quit while I was making more sense ;) The first measurements I posted appear to be correct. One thing that confuses me is that I can read up to 0x801 correctly (slightly above 1V reference). The A manual states that the top value should be 0x7ff (page 295). I can also see slightly negative voltages with respect to ground transistion from 0x000 to 0xfff and beyond. The values seem to be correct with respect to voltage. This seems like a very nice feature for calibration. I'll be working with the A/D some more over the next few days. I'll post if I find something interesting.

jcrollman wrote:
I have a .6V input to the ADC from a voltage divider when disconnected from the AVR, but when I connect the line to to ADCA (PORTA, pin0), the voltage drops to .45V. I don't have any pull-ups enabled. Why the voltage drop? Could this be clue?

hmm.. what values resistors in your voltage divider?

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

Is the pin configured as an output? Is it configured to have the AREF on it (what voltage do you read there when unconnected to your input signal? What voltage when a weak pullup (say 100k) is applied? what voltage when a weak pulldown is applied?)

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Quote:
hmm.. what values resistors in your voltage divider?

From 3.3V, 1.7k Ohms and 467 Ohms to ground, which divides a 3.3V line down to around .7V, which doesn't saturate the 1V reference. When I plug the line in, the voltage drops to <.45V.

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

jcrollman wrote:
[
From 3.3V, 1.7k Ohms and 467 Ohms to ground, which divides a 3.3V line down to around .7V, which doesn't saturate the 1V reference. When I plug the line in, the voltage drops to <.45V.

Something strange going on there.. I'll try and hook up something similar here and see what happens.

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

Quote:
Is the pin configured as an output?

It is an input.

Quote:
What voltage when a weak pullup (say 100k) is applied? what voltage when a weak pulldown is applied?)

Neither weak pullup does much (less than 10mV) regardless if the adc input is connected or not.

Quote:
Is it configured to have the AREF on it?

Not sure, could be tripping me up. I will look into it.

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

OK,
Just hooked up with 476 ohm on bottom and 1.62k on top with 3.29V in. The A/D reads 0x614 which should be ~ 0.759V with 1V internal reference. I am measuring 0.747V on the pin. Note that I'm not using any calibrations.

Not exactly sure what is causing your problem...

[edit]

Here is the init code I used:

/* Move stored calibration values to ADC A. */
        //ADC_CalibrationValues_Set(&ADCA);

        /* Get offset value for ADC A. */
        offset = ADC_Offset_Get(&ADCA);

        /* Set up ADC A to have signed conversion mode and 12 bit resolution. */
        ADC_ConvMode_and_Resolution_Config(&ADCA, true, ADC_RESOLUTION_12BIT_gc);

        /* Sample rate is CPUFREQ/128. Allow time for storing data. */
        ADC_Prescaler_Config(&ADCA, ADC_PRESCALER_DIV256_gc);

        /* Set referance voltage on ADC A to be VCC-0.6 V.*/
        //ADC_Referance_Config(&ADCA, ADC_REFSEL_VCC_gc);
        ADC_Referance_Config(&ADCA, ADC_REFSEL_INT1V_gc);

        /* Setup channel 0, 1, 2 and 3 to have single ended input. */
        ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH0,
                                         ADC_CH_INPUTMODE_SINGLEENDED_gc,
                                         ADC_CH_GAIN_1X_gc);

        ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH1,
                                         ADC_CH_INPUTMODE_SINGLEENDED_gc,
                                         ADC_CH_GAIN_1X_gc);

        ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH2,
                                         ADC_CH_INPUTMODE_SINGLEENDED_gc,
                                         ADC_CH_GAIN_1X_gc);

        ADC_Ch_InputMode_and_Gain_Config(&ADCA.CH3,
                                         ADC_CH_INPUTMODE_SINGLEENDED_gc,
                                         ADC_CH_GAIN_1X_gc);

        /* Set input to the channels in ADC A to be PIN 4, 5, 6 and 7. */
        ADC_Ch_InputMux_Config(&ADCA.CH0, ADC_CH_MUXPOS_PIN4_gc, ADC_CH_MUXNEG_PIN0_gc);
        ADC_Ch_InputMux_Config(&ADCA.CH1, ADC_CH_MUXPOS_PIN5_gc, ADC_CH_MUXNEG_PIN0_gc);
        ADC_Ch_InputMux_Config(&ADCA.CH2, ADC_CH_MUXPOS_PIN6_gc, ADC_CH_MUXNEG_PIN0_gc);
        ADC_Ch_InputMux_Config(&ADCA.CH3, ADC_CH_MUXPOS_PIN7_gc, ADC_CH_MUXNEG_PIN0_gc);

        /* Setup sweep of all four virtual channels. */
        ADC_SweepChannels_Config(&ADCA, ADC_SWEEP_0123_gc);

        /* Enable ADC A with free running mode, Vcc reference and unsigned conversion.*/
        ADC_Enable(&ADCA);

        /* Wait until common mode voltage is stable. Default clk is 30MHz and
         * therefore below the maximum frequency to use this function. */
        ADC_Wait_32MHz(&ADCA);

        /* Enable free running mode. */
        ADC_FreeRunning_Enable(&ADCA);

read with this:

 do{
  //wait for conversion               }while(!ADC_Ch_Conversion_Complete(&ADCA.CH0));
adcSamples[0][i] = ADC_ResultCh_GetWord(&ADCA.CH0, offset);
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Quote:
What voltage when a weak pullup (say 100k) is applied? what voltage when a weak pulldown is applied?)

Neither weak pullup does much (less than 10mV) regardless if the adc input is connected or not.


Repeating:

Quote:

(what voltage do you read there when unconnected to your input signal? What voltage when a weak pullup (say 100k) is applied? what voltage when a weak pulldown is applied?)

The key to this question is the first one: When your input is connected, what voltage do you read on the "floating" pin?

From your answers to the next questions, it appears that your floating input is not floating. So I'd think it is either the pin configuration, or Vref is being routed to the AREF pin for decoupling. (At least it can be that way in classic AVRs; I'm guessing the same can be true on Xmega.)

As PA2 is not AREF, what results do you get there?

[edit] From http://www.atmel.com/dyn/resourc...

Quote:
For the internal references, the user has the choice of connecting the internal voltage source to the external reference pins for decoupling purposes. It is imperative to decouple the voltage reference, internal and external, to be able to achieve the full 12-bit accuracy of the ADC module. Also, great care should be taken when designing the analog signal paths as well.
Note that the external reference pin VREF+ is shared with the DAC module. The voltage reference is configured using the Reference bitfield (REFSEL) in the Reference Control register (REFCTRL).

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Quote:
Quote:
Is it configured to have the AREF on it?

Not sure, could be tripping me up. I will look into it.

I can't seem to find how to change the AREF pin. I did a search (find) through the databook, but all it talks about how to select it for use with the ADC and DAC, and nothing about how to set it to a certain pin on the port, or which pin it is by default. I think that is why I started with the 1V reference in the first place because I couldn't find where the heck the external AREF is coming from. Could someone give me a page number where this is explained?

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

Quote:
As PA2 is not AREF, what results do you get there?

I will look. I'm not sure I'm understanding where the AREF is coming from. Is A0 AREF? Can this be changed?

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

jcrollman wrote:
Could someone give me a page number where this is explained?

Page 303 of the A Manual, Table 25-3

In the init code I posted above from the adc example, You could change the reference with one of these values:

ADC_Referance_Config(&ADCA, ADC_REFSEL_VCC_gc);

ADC_Referance_Config(&ADCA, ADC_REFSEL_INT1V_gc);

ADC_Referance_Config(&ADCA, ADC_REFSEL_AREFA_gc);

ADC_Referance_Config(&ADCA, ADC_REFSEL_AREFB_gc);

[edit]

Also look on page 51 of the A1 manual, Table 29-1 and 29-2. AREF for port A is PA0, AREF for port B is PB0.

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

Quote:
Quote:
As PA2 is not AREF, what results do you get there?

I will look.

Yes. This did it. The results are much better.

Quote:

Also look on page 51 of the A1 manual, Table 29-1 and 29-2. AREF for port A is PA0, AREF for port B is PB0.

I see it listed as A0. That is definitely my problem.

Thank you all for your help. I think I should be good to go!

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

jcrollman wrote:

Thank you all for your help. I think I should be good to go!

Glad to hear we could figure it out between the 3 of us ;)

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

Well, there still is a puzzlement here--so listen up.

1) What voltage do you see on the "floating" PA0 pin?

2) The app note quote above talks of

Quote:

the user has the choice of connecting the internal voltage source to the external reference pins for decoupling purposes.

However, I can find no register setting for that "choice".

2a) So I'll ask the same question of telliot: When you select the internal reference what voltage do you see on PA0?

It is a puzzlement, 'cause if you have external reference you burn PA0 for the Vref input. If you have internal reference, jc's problem would indicate it is always routed to PA0 for decoupling. Thus in both cases ADC0 is "dead" for A/D input channel purposes.

There is something that I don't understand.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Quote:
1) What voltage do you see on the "floating" PA0 pin?

I read 12mV when floating, 12mV when connected to a GND through the 100KOhm, and 32mV when connected to 3.3V. This would imply A0 is pulling my signal down regardless whether I am operating with internal or external references. Which would be a cause for some sort of errata?

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

theusch wrote:

2a) So I'll ask the same question of telliot: When you select the internal reference what voltage do you see on PA0?

Thus in both cases ADC0 is "dead" for A/D input channel purposes.

There is something that I don't understand.

Lee

Lee,
I see what you are saying. I thought I was using channel '0', but forgot that I mapped inputs 4-7 to channels 0-3. To answer your question, I don't see any voltage (~5mV) on PA0 with the internal 1V reference selected.

[edit]
I'm re-configuring to use A0 for res divider test on my end. Back in a few...

Last Edited: Tue. Jul 7, 2009 - 09:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Which would be a cause for some sort of errata?

Perhaps. Or maybe a blown pin from an oops during testing. But I'd really, really ensure that it was not configured as an output somewhere. As telliot has a working system he could perform the sanity check.

I was expecting you to answer like "1.05V" indicating the internal ref was being "bussed" to AREF/PA0 for decoupling.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

theusch wrote:
As telliot has a working system he could perform the sanity check.
Lee

Sanity check performed.. A0 works fine. I get identical readings that I did on A4 with 0.7466 volts being applied by the voltage divider described before.

So back to square one.

jcrollman:
I thought you solved the problem by selecting the correct reference. I didn't realize that you just used a different pin. Maybe you have a fried PA0? How about PB0 ?

[edit]

Oh another thing.. I discovered you can achieve latch-up on the A/D when I was playing around with negative voltages. Try completely removing power from your board and see if that makes a difference.

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

So, the remaining mystery then is the "decoupling" option from the app note.

If I had to make a guess, it used to be/was intended to be an option that was pulled. My only evidence is this "typo" from the family datasheet:

25.16.3 REFCTRL - ADC Reference Control register

• Bit 7:6 – Res: Reserved
These bits are unused and reserved for future use. For compatibility with future devices, always write these bits to zero when this register is written.

• Bits 6:4 – REFSEL[1:0]: ADC Reference Selection
These bits selects the reference and conversion range for the ADC according to Table 25-3 on page 303.

Note bit 6 is in both categories. Detail on REFSEL only has two bits, not three as if it really were 6:4.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

I put in a new processor and I'm still getting a pull-down on A0. There is a LED that is green on the STK600 right above the adapter plates that blinks red whenever I touch A0 to the voltage divider. I assume this is an LED that indicates when there is current shutdown of sorts (I don't know if there is any link to any info on the STK600, but when I was looking for some 2 months back, there was nothing). So I must have a software problem somewhere, but the only place I modify anything in PORTA is when I write DIR and PIN0CNTRL to all zeros during initialization. Any other ideas how I could be controlling that pin?

Edit: I put in a third processor, and with the 100K pull-up, I got the same +12mV and +32mV I got with the first chip. Maybe I'm not destroying the pin, but something isn't right. Some setting with the STK600?

Edit: Found the guide to the STK600 embedded in AVR Studio. (Why not a link to it on Atmel's website?)

Last Edited: Fri. Jul 10, 2009 - 12:50 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Maybe I haven't solved anything after all. The initial processor, using PA2 for the ADC input is spot on (1425/2047 = .696 for a .696 input). However, when I use the other two processors, they are not close when using the same pin and same .696 input (1459/2047 = .712 and 1442/2047 = .704). Calibration problem? The routine is taken straight from the app note. I assume the first processor accuracy was just coincidence.

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

I was seeing the same problem with an STK600 w/ XMEGA on A0 - it looked like this was being pulled down when I was trying to use an external reference.

Check to see if the AREF0 jumper (over by the JTAG connector) is present. If so, remove this since it will be driving A0 and by default it will be set to 0 volts. I found things work a lot better when this jumper isn't present when trying to use an external reference :)

Ken

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

Quote:
Check to see if the AREF0 jumper (over by the JTAG connector) is present.

Yes, that absolutely solved my A0 pulldown problem. Unfortunately didn't solve my overall ADC error issue. I'm still getting different significantly-sized errors on different uC's I use. Now I know the two issues are probably not related.

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

Hi guys, I've been playing with the Xmega ADC also and discovered that I can obtain most accurate (single ended) results when the ADC is configured as follows:

signed mode
prescaler is at least /16 (at seemingly any clock speed)
12bit resolution
reference = AREFA or AREFB @ 3.3v

However it is still unacceptably inaccurate. I measure 0v properly, but it seems that all values > 0v are inflated - for example, I measure 1.25v as 1.45v and 2.38v as 2.82v. The "real" values are taken with a multimeter, and I am measuring some AA batteries I have lying around...

Offset can't be the issue here because I properly measure 0v, right? To me this seems more like some kind of calibration issue. I of course investigated the CALIB and CALCTRL registers (documentation on these is practically non-existent) but to no avail.

To understand how they worked, I figured I would load arbitrary values into them (CALIB and CALCTRL) and see how my measurements reacted - hoping to reverse engineer whatever their functionality might be. Unfortunately not one of many interesting combinations of values (including the one read from the signature row) in either of these registers seems to have any effect whatsoever on the measurements. Has anyone successfully used these calibration mechanisms? How did you do it!?

Thanks if anyone has any suggestions,
Jesse

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

I've read most the the posts on the Xmega ADC issues and with the setting everyone is recommending (differential, signed, PORTA:0 external reference, 64+ prescaler) and I see the same issues on the Atxmega128A3 and Atxmega64A3 parts. 2.76V on PORTA:2 reads as 3.3V from the ADC, etc. On the plus side when I plot the ADC value versus the actual value on the pin it looks very linear and could probably be corrected by reading a known reference voltage on the ADC and creating a correction factor.

I'm going to contact Atmel and see if they can confirm the problem and suggest a workaround, but I suspect it will involve either an external voltage reference and calibration step or using the DAC to feed back into the ADC to calibrate. I tried the calibration registers and they appear to do nothing. :-(

-Paul

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

Okay. I've been able to fix the accuracy of the ADC on the Atxmega128A3 and ATxmega64a3. Turns out you can't set AREF > AVCC-0.6V. So for AVCC=3.3V you have to keep the external reference below 2.7V. By feeding a 2.5V external reference voltage into PORTB:0 and using that as the external reference the ADC looks pretty accurate. Very little offset at 0V. Applying the calibration values also improves things a couple of LSBs.

Yay!
-Paul

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

I haven't done any work with an xmega yet, so this comment might be garbage, but...

shaade said

Quote:
To understand how they worked, I figured I would load arbitrary values into them (CALIB and CALCTRL) and see how my measurements reacted

I recall in a recent thread on the DPLL in the xmega that someone pointed out that an appropriate signature value had to be written to the system configuration protection register before values could be written to some peripheral registers.

Maybe related?

Roger