Xmega DFLL, does it work?

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

Does anyone know any magic words that makes it work?

I have the Xmega 128a1 rev H and tried to use DFLL for the 2 MHz RC oscillator. It doesn't do anything.

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

Did I stump the experts? I should have spelled out Digital Frequency Lock Loop. I don't see anything about it being non-functional, but it looks that way to me.

This thing should be able to set the 2 MHz oscillator to a USART friendly frequency by using the watch crystal oscillator as a reference. Some of us do this in software on the mega, but the Xmega DFLL should be able to do it in hardware.

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

CodeVision's new Xmega Wizard seems to know what you are talking about. The routine generated is quite extensive and decently commented.

I don't know if I'm free to share that generated code. Perhaps see if the eval version has the Xmega Wizard and check it out.

App note AVR1606: XMEGA Internal RC Oscillator Calibration mentions the feature in chapter 7, and refers back to the AVR1003 app note. Is there any discussion or code there to help you out?

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

You can calibrate / lock the 2MHz RC system oscillator off of the 32768Hz watch crystal.
Then set the PLL off of the 2MHz to get integer multiples of 2MHz.

Unless you have a special reason for an odd system clock, the USARTs do not need "friendly" frequencies. e.g. from the CodeVision Wizard using a 2MHz system clock:

// Required Baud rate: 115200
// Real Baud Rate: 115107.9, Error: 0.1 %
USARTC0.BAUDCTRLA=0x0B;
USARTC0.BAUDCTRLB=((0xF9 << USART_BSCALE_bp) & USART_BSCALE_gm) | 0x00;

David.

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

david.prentice wrote:
You can calibrate / lock the 2MHz RC system oscillator off of the 32768Hz watch crystal.
No, I can't. I presume you mean the DFLL. It doesn't work for me with the Xmega 128a1 on the Xplain board. Maybe there is a specific order I need to flip the bits.

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

Quote:

No, I can't.

As I mentioned, the CV Wizard sure seems to indicate that you can.

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

Again, for instance N+1, how do you know that it does not work?

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

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

david.prentice wrote:

Unless you have a special reason for an odd system clock, the USARTs do not need "friendly" frequencies. e.g. from the CodeVision Wizard using a 2MHz system clock:

// Required Baud rate: 115200
// Real Baud Rate: 115107.9, Error: 0.1 %
USARTC0.BAUDCTRLA=0x0B;
USARTC0.BAUDCTRLB=((0xF9 << USART_BSCALE_bp) & USART_BSCALE_gm) | 0x00;

David.

A USART friendly frequency eliminates the need for the scale factor. As one who uses the USART, I think 2 MHz is odd.

The AVR can calculate the numbers to put in the baudrate registers for any baudrate I desire as long as I use a zero scale factor. As far as I know, I would have to teach the AVR to use a spread sheet to figure out the scale factor, if I wanted to use a non-friendly frequency.

The way I see it, I could use an "oddball" frequency like 2 MHz and teach the AVR to do the spreadsheet thing or use a practical frequency like 1.844 MHz and dispense with the spread sheet.

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

ka7ehk wrote:
Again, for instance N+1, how do you know that it does not work?

Jim

I don't understand N+1. I know it doesn't work for me because I tried it. The oscillator calibration numbers (CALA and CALB) don't change and neither does the frequency of the 2 MHz oscillator.

I can "manually" change the frequency of the oscillator by changing the calibration numbers. But the DFLL never changes them. I tried changing the values of the compare registers (COMP0, COMP1, and COMP2) but still the DFLL doesn't do anything with the oscillator calibration.

Maybe I'm failing to do something before I enable DFLL, but I've spent a couple of hours reading the datasheet and twiddling bits, and I get nothing.

To quote Spock, "It's dead Jim".

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

I could add that the datasheet is obviously wrong regarding the 32MHz DFLL. I don't want that, but the fact that the datasheet is inconsistent tells me that something is fishy. The datasheet shows 2 and a half bytes are used for the compare registers (20 bits), but the AVR loads all 3 bytes (24 bits) after reset for the 32 MHz DFLL.

Also I'm suspicious of the byte order. The datasheet says the low order register (COMP0) is the low order byte of the compare value. But I notice that both DFLLs load 0x3D into COMP0. 0x3D (61 decimal) is about what you get when you divide 2 MHz by 32.768 kHZ. 32 MHz is 16 time 2 MHz so that division would also produce a number that starts with 0x3D.

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

I was only aware of the high frequency DFLL. But, I do see now that there is a second one intended for RC oscillator calibration. I see nothing in the XMega128A1 spec sheet on using it.

AVR1003 does say some things. One caught my eye (Section 2.8 ):

Quote:
Hardware will disregard any attempts to use an unstable clock source.

Do you follow the procedure for enabling the DFLL at the end of section 2.8?

Do you ever get the RC2MRDY bit set?

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

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

The Xmega A manual (doc 8077) says you can change the compare registers to have the DFLL tune to a different frequency. I just noticed it says "It is possible to write these bits from software and then enable the oscillator to tune to a different frequency". I wonder if it should say to enable the DFLL, not the oscillator. It would take some scheming to enable the 2 MHz oscillator as I would have to first disable it, and I'm using it as the system clock. I would have to switch to a different system clock first.

AVR1003 mentions a 3 byte counter reference which it calls OSC.DFLLx.OSCCNTn. There is no such terminology in the datasheet but I assume they are COMP0, 1, and 2. AVR1003 says the values in these registers should not be changed by the user. The XMega A manual says you can change them. Maybe AVR1003 says not to change them because if you do, it becomes obvious the DFLL doesn't work. :)

This thing has more oscillators than I can handle. RC2MRDY is for the 2 MHz RC oscillator. That thing is ready shortly after reset and it is the default system clock. I never change that, and I've never seen it not ready.

If I use the watch crystal osc. for a reference, I enable it and make sure it's ready. (XOSCRDY)
If I use the 32kHz RC oscillator as a reference, I enable it and make sure it's ready. (RC32KRDY)

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

Steve,

What exactly do you want to do?

1. You can achieve all the standard baud rates from 300 to 115200 baud while using a 2MHz clock. I doubt if you want to go faster than 115200 without using a faster clock.
2. If you want or need non-standard baud rates, your 'usart_init()' function just makes the appropriate calculation.

I normally find that most timing / counting calculations are always easier off of a 'round number' clock period like 1us rather than the 'odd' periods that you get from 'usart-friendly' clocks.

Meanwhile, I may have a little experiment to run off 'strange' clock frequencies. In practice I have only used 2MHz and 32MHz.

David.

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

I wanted to try the DFLL. If a crystal oscillator is used as a reference, this should give the RC oscillator a similar stability. Maybe the RC oscillator on the Xmega is stable enough without DFLL. I just wanted to see DFLL work.

The Xmega on my Xplain board has a correct 2 MHz RC oscillator frequency when using the factory calibration. I measure 2.009 MHz with my cheap ($40) DMM. That is good enough for me now. I wonder if it will be good enough if the temperature or voltage vary.

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

So your 2MHz RC is factory calibrated to 0.45%.
Mine is calibrated to 0.20% accuracy.

Both my Xplain and your Xplain board are going to be absolutely fine for reliable USART comms. And even when you apply temperature and voltage curves to our boards, we will still both be fine.

The Xplain RTC running off of the watch crystal will be accurate to the 20ppm or whatever for the crystal. 20ppm is 0.002%.

And if you runtime calibrate the 2MHz RC to the watch crystal, the system clock will be an improvement on the factory calibration. Remember that the xmega factory calibration is guaranteed to be far better than the mega's 10% worst case.

David.

Edit. Using the runtime calibration from the external watch crystal seems to achieve nothing much better than the factory calibration. (i.e. 0.2% in my case)
Perhaps you may achieve 0.2% with your specific xmega.

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

So you did a runtime calibration? Did you do it in software or did you get DFLL to work?

Does the Xmega RC oscillator vary less with temperature and voltage than the mega?

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

Manual A does not mention that ALL of the CLOCK registers (not the OSCILLATOR or DFLL)are protected. So you need to use the write to protected register system for all writes. I had a lot of trouble getting clocking to work until I worked that out.

After I understood that I found clocking including DFLL & PLL worked fine.

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

You have DFLL working? On a 128a1 rev. H? On the 2 MHz RC oscillator?

I think I can tell what is protected by using JTAG. If I try to change some of the clock registers, they don't change unless I set the CCP signature. I can do that from JTAG also. And I don't think the ready bits are lying to me. Anyway I know the watch crystal osc. is working because I'm using it for keeping time and blinking LEDs and I can measure it's frequency. I know the 2 MHz osc is working because I use it for the system clock, and I can measure it's frequency.

I know I can change the 2 MHz RC osc. frequency by changing the calibragion bytes. But the DFLL does nothing.

How did you confirm the DFLL? Can you change the compare registers and see the calibration registers or the osc. frequency change?

Can you change the calibration bytes, and see them change back to the original when you enable DFLL?

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

It appears to me that you have several "likely" design choices with the xmega.

1. Use the 2MHz internal RC oscillator and set the BAUDCTRLB,BAUDCTRLA fields:

  2400    4800    9600   19200   38400   57600  115200 
0xAC85, 0x9C85, 0x9603, 0x92C1, 0x9121, 0x9093, 0x900B

2. Use the 32MHz internal oscillator and reach 1200 to 115200 baud with the BSCALE field at zero.

3. Use an external 400k..20MHz crystal oscillator

You can calculate the values at runtime very easily. Personally I would calculate BSEL with the following formula:

128 * F_CPU / 16 / baud - 128    // BSCALE = 9 -> 128 multiplier

If the BSEL value is too large for the 12 bits, you just divide by two until it fits. (and increment BSCALE)

It is possible that you want to use the USART at 75 baud or some other ridiculously low rate. Then you would be using the +ve BSCALE values 1..7.

I am sure that it is possible to use the DFLL to lock onto baud-friendly frequencies. I just do not like having to do non-USART timing with weird periods.

Incidentally I have observed the clock frequency using both 2MHz and 32MHz/16. I found +0.2% and -0.7% accuracy wrt to a crystal controlled tiny2313. Since the BSEL calculations all give better than 0.1% accuracy, I am only looking at 0.3% or 0.8% USART accuracy. Even with temperature and voltage changes, I should remain within the necessary 5% timing window for 8-N-1.

David.

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

Yes David, but the subject of this thread is DFLL. The question is, does it work? I think the answer is no.

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

steve17 wrote:
You have DFLL working? On a 128a1 rev. H?
....

How did you confirm the DFLL? Can you change the compare registers and see the calibration registers or the osc. frequency change?

Can you change the calibration bytes, and see them change back to the original when you enable DFLL?

Actually I am using 16A4 rev A. I would hope that this is the same clock module but of course there is no guarantee.

I determined that DFLL was working by watching the clock frequency change. On enabling DFLL the clock frequency rose by just under 0.1%.

You may have noticed the only way to turn DFLL off is to perform a reset.

As for the behaviour of the registers the documentation is less than helful (even if you assume it is error free). The DFLL calibration register changes the frequency with the DFLL on or off according to the documentation. While this seems rather odd I can confirm that this occurs. The exact operation of the compare registers is unclear from the documentation. However the following was observed:

    1)Reset
    2)Change the compare value from the default
    3)Enable DFLL
    4)Run
    5)Halt
    6) At this point the compare register has set back to its default value
If you perfom the above omitting stage 3 (i.e. no DFLL)the compare register is unchanged.

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

Trevor_G wrote:
Manual A does not mention that ALL of the CLOCK registers (not the OSCILLATOR or DFLL)are protected. So you need to use the write to protected register system for all writes. I had a lot of trouble getting clocking to work until I worked that out.

After I understood that I found clocking including DFLL & PLL worked fine.

Trevor,

How did you manage to get the DFLL to operate at runtime?

As far as I can see, you can read and write to the DFLL.OSCCNTn and DFLL.CALn registers. But only the CALn registers take effect.

    DFLLRC2M.CALA = 0x39;    // produces a 1.8432MHz clock
    DFLLRC2M.CALB = 0;       // on my Xplain board
    DFLLRC2M.OSCCNT2 = 7;    // 1800 counts  
    DFLLRC2M.OSCCNT1 = 8;    // for 1.8432MHz
    DFLLRC2M.OSCCNT0 = 0;

I note that the AVR1606 app note seems to just do a runtime calibration (OSCCNT = 1953.3 counts for 2MHz) and then writes to eeprom. Presumably you write the new value back into a signature row of the xmega.

Altering OSCCCNT seems to have no effect.

David.

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

I'll have to re-visit this when I get around to setting up my Xmega, as the Wizard-generated code seems to address the situation. (When it first came up, I picked the internal 32k 'cause I thought that was what was required.)

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

Trevor_G wrote:
The DFLL calibration register changes the frequency with the DFLL on or off according to the documentation. While this seems rather odd
That is not odd. The so-called "DFLL calibration register" is actually the RC oscillator calibration register. The mega called it OSCCAL.

The odd thing is that changing the compare registers and then enabling DFLL, does nothing. In other words, the DFLL is dead on my machine.

As for DFLL changing the frequency 0.1 percent, I can hardly measure that with my meter. If the calibration register didn't change, then DFLL didn't do it. Either the AVR or your frequency meter warmed up a bit, or if you opened a window, they cooled off.

If you change the compare registers, do the calibration registers change when you enable DFLL? If you change the calibration, does it go back to the original value when you enable DFLL?

What are the default values of your calibration registers? Mine is 0x0f40 and the frequency is 2.009 MHz. I found by trial and error that 0x0f11 gives me the usart friendly 1.844 MHz.

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

By the way, when DFLL is enabled and I disable it, the "OSCCAL" changes to 0x0f00. That is, the low byte gets zeroed. That gives me a frequency of under 1.8 MHz. I have to set it back to the original.

I didn't notice that register clobber at first and I spent an hour of total confusion. :)

So I guess I was wrong when I said DFLL does nothing. It does clobber a register, so it must not be completely dead.

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

I have played a little bit with DFLL on my xplain board (xmega128a1) to calibrate the 32 MHz oscillator RC32M from the 32.728 kHz crystal.

The short story: I can activate DFLL for the RC32M, but it does not calibrate the oscillator.

The long story:

First I checked if the 32.768 kHz crystal and oscillator works stand-alone, by just using it as the system clock source. I output the clock source to PD7 and the frequency counter shows a nice and stable 32.7679 kHz.

Then I used the 32 MHz oscillator without DFLL. I got a clock frequency, drifting between 32.3 MHz and 32.5 MHz.

Finally, I set up DFLL, all nicely according to the book (datasheet, manual, app. note, CPP for the CLK registers). The clock frequency still drifts between 32.3 MHz and 32.5 MHz. :-(

I would have expected that the 32 MHz oscillator is pulled towards 32.0 MHz, instead of sticking at > 32.3 MHz. Just to make sure I cross-checked the PD7 signal with a DSO.

How do I know that DFLL is activated?

I can not write to DFLLRC32M.CALA. Any values written to it are ignored. Which is in line with the documentation.

How do I know something strange is going on?

I constantly monitor the DFLLRC32M.CALA value by writing it to the LEDs (PORTE.OUT = DFLLRC32M.CALA;). The value doesn't change. I can cool down the xmega with a cooling spray, the clock frequency drifts wildly, but DFLLRC32M.CALA doesn't change. I can heat up the xmega, DFLLRC32M.CALA doesn't change.

And of course the clock frequency continues to drift at room temperature.

(remove spaces before % characters - forum bug)

#define F_CPU 32000000L

#include 

#include 
#include 
#include 

// Modelled after CCPWrite from AVR1003
void  __attribute__((noinline))
CCP_IOREG_store( volatile uint8_t * address, uint8_t value )
{
        uint8_t volatile sreg = SREG;
        cli();
        volatile uint8_t * tmpAddr = address;
        RAMPZ = 0;
        asm volatile(
                "movw r30,  % 0"       "\n\t"
                "ldi  r16,  % 2"       "\n\t"
                "out   % 3, r16"       "\n\t"
                "st     Z,  % 1"       "\n\t"
                :
                : "r" (tmpAddr), "r" (value), "M" (CCP_IOREG_gc), "i" (&CCP)
                : "r16", "r30", "r31"
        );
        SREG = sreg;
}


int __attribute__((OS_main))
main(void)
{
        // PD7 as clock output
        PORTD.DIRSET = PIN7_bm;
        PORTCFG.CLKEVOUT = PORTCFG_CLKOUT_PD7_gc;

        // LED outputs
        PORTE.DIR = 0xFF;
        PORTCFG.MPCMASK = 0xFF;
        PORTE.PIN0CTRL |= PORT_INVEN_bm;

        // Set up the two oscillators and DFLL

        OSC.CTRL |= OSC_RC32MEN_bm;
        OSC.XOSCCTRL = OSC_XOSCSEL_32KHz_gc;
        OSC.CTRL |= OSC_XOSCEN_bm;

        while((OSC.STATUS & (OSC_RC32MRDY_bm | OSC_XOSCRDY_bm))
              != (OSC_RC32MRDY_bm | OSC_XOSCRDY_bm))
                ;

        OSC.DFLLCTRL |= OSC_RC32MCREF_bm;
        DFLLRC32M.CTRL = DFLL_ENABLE_bm;

        CCP_IOREG_store(&CLK.PSCTRL, CLK_PSADIV_1_gc | CLK_PSBCDIV_1_1_gc);
        CCP_IOREG_store(&CLK.CTRL,(CLK.CTRL & ~CLK_SCLKSEL_gm)
                | CLK_SCLKSEL_RC32M_gc);

        OSC.CTRL &= ~OSC_RC2MEN_bm;

        uint8_t junk = 0;
        while (1)
        {
                DFLLRC32M.CALA = junk;  // should not work
                junk = ~junk;
                PORTE.OUT = DFLLRC32M.CALA;
                _delay_ms(500);
        }
        return 0;
}

Stealing Proteus doesn't make you an engineer.

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

Thank you Arnold. Your results do not surprise me. Like you, I can't get DFLL to do anything.

I did not use it with the 32 MHz oscillator, I used it with the 2 MHz oscillator.

I do hereby pronounce that DFLL is dead as a doornail. At least the one in my Xmega 128a1 rev H.

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

steve17 wrote:
I do hereby pronounce that DFLL is dead as a doornail. At least the one in my Xmega 128a1 rev H.
That, or there is some magic spell that Atmel didn't publish to revive DFLL from the dead.

Stealing Proteus doesn't make you an engineer.

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

Atmel has now officially declared DFLL as broken. From the latest errata (including original Atmel spelling and grammar errors):

Quote:

19. Both DFLLs and both oscillators has to be enabled for one to work

In order to use the automatic runtime calibration for the 2 MHz or the 32 MHz internal oscillators, the DFLL for both oscillators and both oscillators has to be enabled for one to work.

Problem fix/Workarund

Enabled both the DFLLs and both oscillators when using automtic runtime calibration for one of the internal oscillators.

Stealing Proteus doesn't make you an engineer.

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

Thanks for the tip.

DFLL now works if I enable both of them.

I am running with a constant voltage and temperature and I don't need DFLL. The RC oscillators are stable and fairly accurate at room temperature and 3.3V VCC. If the Xmega was subject to temperature or voltage variations, I think DFLL would be useful.