UC3A3 max pin toggle frequency

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

Hi !

 

In order to familiarize myself with the UC3 micros, I setup an ASF-based application, see below.

Purpose: toggle a single I/O pin as fast as possible.

 

Hardware: UC3A3256 Xplained board, I/O pin PB03, aka GPIO35.

The board has a 12 MHz Crystal connected to XIN0 / XOUT0; CPU clock is set up to be 6 MHz.

 

 

 

The disassembly also looks as expected:

 

 

 

We have a load-store sequence in an endless loop. The reference Manual on the UC3 tells me that the ld.w, mov, st.w and rjmp instructions all take one "issue latency" which I suppose to mean one machine cycle. So, we have seven instructions for one square wave at the pin.

 

At fCPU = 6 MHz, one instruction takes 166,7 ns, therefore one square wave on PB03 should take 166,7 * 7 = 1166,7 ns.

 

At least, this is what I expected to see.

 

 

My logic analyzer shows me this:

 

 

 

which is exactly half of the expected pin toggle frequency. The small deviation from 2,33333.... µs is due to the fact that the analyzer samples at 100 MHz / 10 ns intervals.

 

I then re-read the GPIO datasheet section 20.5.1.5 to find this:

 

I am not sure what this means - any access to GPIO over the Peripheral Bus always takes 2 instruction cycles ?

 

Any guidance appreciated.

 

best,

Chris

 

This topic has a solution.

Last Edited: Wed. Dec 9, 2015 - 06:09 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

c_bauer wrote:

 - any access to GPIO over the Peripheral Bus always takes 2 instruction cycles ?

 

Yes.  If you want to go faster you need to use the local bus:

 

Letting the smoke out since 1978

 

 

 

 

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

Thanks Dan. That was it.

 

For future reference, here are the steps needed:

 

 - declare / initialize pointers to local bus addresses

 - enable local bus (CPUCR.LOCEN = 1)

 - issue set / clear / toggle instructions by deref'ing the local bus pointers 

 

This way, there is actually one port access per CPU clock cycle.

BTW the project Name "led_toggle_interrupt"  is a remnant from another project. No Interrupts involved.

 

 

 

 

As can be seen, the pin toggle now only takes 166,7 ns - the same as one CPU instruction cycle.

 

 

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

Thank you c_bauer for posting the solution also. I have a doubt. Why you are measuring falling edge to rising edge in the second analyzer capture and not rising edge to rising edge (i.e one cycle) as before?

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

This was to emphasize the fact that there really _is_ one pin state change per CPU cycle.

So, using the local bus you can get down to half the CPU frequency, in this case it's fCPU = 6 MHz and the pin toggles at 3 MHz*.

If I'd use the peripheral bus for GPIOs it would be much less than that, as my first post says.

 

* This is is only true if you issue back-to-back read / write accesses, in a loop there is "rjmp" overhead.

 

And if you need the fastest possible square wave with duty cycle = 50 % I'd use one of the generic clocks.

They may output the undivided CPU frequency; very nice feature IMO.

 

Hope that helps.

Chris

 

Last Edited: Sun. Dec 13, 2015 - 05:35 PM