Electronic – Assembly XMEGA program creating a longer than expected pin toggle

assemblyatmelatxmegaclockxmega

I'm trying to do the fastest pin toggle possible on an XMEGA32E5 running at 32MHz. My code is as follows:

.include "ATxmega32E5def.inc"

.ORG 0x0000     ;Code starts running from address 0x0000.
rjmp MAIN       ;Relative jump to start of program.
.ORG 0x0100     ;Start program at 0x0100 so we don't overwrite vectors that are at 0x0000-0x00FD

MAIN:
    ldi R17, 0x3            ;set R17 to 11
    sts PORTA_DIRSET, R17   ;set all the GPIO's in the four bit PORTA as outputs

LOOP:
   sts PORTA_OUTTGL, R17    ;toggle the state of all the pins in PORTA  

rjmp LOOP                   ;repeat forever!

According to Atmel, the instructions that are looped, sts and rjmp, should take two cycles each. However, when I probe either of the two pins that are being toggled, the wavelength is 2 microseconds, or half a MHz. This is way lower than the 32MHz clock. What am I missing? Is there a better way to do this?

Best Answer

It looks like the XMEGA E family defaults to the 2MHz internal oscillator, which is actually divided down from the 8MHz oscillator.

From section 7.2 of the manual:

After reset, the device will always start up running from the 2MHz output of 8MHz internal oscillator.

In order to use the 32MHz internal oscillator, you need to explicitly modify the Oscillator Control register CTRL:

enter image description here