Maximum pin frequency

tanvach
Posts: 2
Joined: Tue Jul 05, 2011 3:31 pm

Maximum pin frequency

Postby tanvach » Tue Jul 05, 2011 3:35 pm

I would like to use the UNO32 as a high frequency squarewave generator, and since the internal/core frequency is set to 80MHz, would that mean the maximum frequency output is 40MHz if I were to use a timer interrupt to toggle a digital pin on and off?

I'm not too familiar with PIC32, more from an AVR background.

User avatar
rtestardi
Posts: 79
Joined: Mon Jun 06, 2011 1:16 am
Location: Boulder, CO USA
Contact:

Re: Maximum pin frequency

Postby rtestardi » Tue Jul 05, 2011 7:39 pm

You can use a timer in conjunction with an output compare module to toggle a pin every time the timer expires (no interrupts). Or you can use programmatic pin control to toggle the pin. The program below shows a 20MHz square wave on rd0 (pin 3) and a 5MHz square wave on rd1 (pin 5). I thought the pic32 could go faster, so the config bits or SYSTEMConfigPerformance() in the bootloader may be wrong. You can go a bit faster with the programmatic pin control by unrolling the loop, but it introduces jitter. I thought the output compare module could go faster, too -- maybe with some magic and a compare value of 0 or OCM value 5?

Code: Select all

#define VALUE  1

void setup() {
  // set up timer 3 for fast period
  T3CONCLR = _T3CON_ON_MASK;
  TMR3 = 0;
  PR3 = VALUE;
  T3CON = _T3CON_ON_MASK; 
 
  // set up output compare 1 to track timer 3 on rd0 (pin 3)
  OC1CONCLR = _OC1CON_ON_MASK;
  OC1R = 0;
  OC1RS = VALUE;
  OC1CON = _OC1CON_ON_MASK|_OC1CON_OCTSEL_MASK|(3<<_OC1CON_OCM0_POSITION);
 
  // set rd1 for digital output
  TRISDCLR = 0x2;
}

void loop() {
  // invert rd1 (pin 5)
  LATDINV = 0x2;
}

Or maybe I have aliasing going on in my (40Ms/s) bitscope???
Embedded Systems Made Easy: http://www.cpustick.com .....

User avatar
hairymnstr
Posts: 50
Joined: Wed Jun 15, 2011 10:03 am
Location: Bristol, UK
Contact:

Re: Maximum pin frequency

Postby hairymnstr » Wed Jul 06, 2011 11:21 am

I'm pretty sure I got 40MHz 50% duty out of an output compare peripheral when I was experimenting.

Nyquist sampling theory states that to be able to see a repetitive signal you must sample at least twice as fast as the signal so for 40MHz you need at least 80MS/s. For non repetitive signals (like duty ratio other than 50%) you need 5 times faster or more usually.
#include <coffee.h> // The start of all good programming sessions

User avatar
rtestardi
Posts: 79
Joined: Mon Jun 06, 2011 1:16 am
Location: Boulder, CO USA
Contact:

Re: Maximum pin frequency

Postby rtestardi » Wed Jul 06, 2011 10:33 pm

Yeah, I'd buy the Nyquist explanation, except I also measured the following frequencies for differing values of VALUE:

VALUE = 1; frequency = 20MHz
VALUE = 3; frequency = 10MHz
VALUE = 7; frequency = 5MHz

So I'm pretty sure what I measured was correct since it follows the pattern established at the lower frequencies where Nyquist can't be an issue. (That and even with the bitscope sampling at 40Ms/s, the result was really consistent and predictable over many samples -- and it has an option to show raw data...)

With that said, I could not get VALUE = 0 to work... And I did not try any of the other Output Compare modes (like 5?).

Curiously, folks on the web claim 72MHz pin toggles using LATxINV... But the code we compile can't do anything like that:

Code: Select all

00000060 <loop>:
  60:   24030002        li      v1,2
  64:   3c020000        lui     v0,0x0
  68:   ac430000        sw      v1,0(v0)
  6c:   03e00008        jr      ra
  70:   00000000        nop
Embedded Systems Made Easy: http://www.cpustick.com .....

User avatar
svofski
Posts: 58
Joined: Sun Jul 03, 2011 3:23 am

Re: Maximum pin frequency

Postby svofski » Sat Jul 09, 2011 1:43 am

rtestardi wrote:Curiously, folks on the web claim 72MHz pin toggles using LATxINV... But the code we compile can't do anything like that:

Code: Select all

00000060 <loop>:
  60:   24030002        li      v1,2
  64:   3c020000        lui     v0,0x0
  68:   ac430000        sw      v1,0(v0)
  6c:   03e00008        jr      ra
  70:   00000000        nop

Maybe with an unrolled loop? Only useful for short bursts, but it should work, no?

tanvach
Posts: 2
Joined: Tue Jul 05, 2011 3:31 pm

Re: Maximum pin frequency

Postby tanvach » Wed Jul 13, 2011 10:16 am

Thank you, I'm curious why the programatic pin toggle is so slow, is this because of arduino compatibility layer?


rtestardi wrote:You can use a timer in conjunction with an output compare module to toggle a pin every time the timer expires (no interrupts). Or you can use programmatic pin control to toggle the pin. The program below shows a 20MHz square wave on rd0 (pin 3) and a 5MHz square wave on rd1 (pin 5). I thought the pic32 could go faster, so the config bits or SYSTEMConfigPerformance() in the bootloader may be wrong. You can go a bit faster with the programmatic pin control by unrolling the loop, but it introduces jitter. I thought the output compare module could go faster, too -- maybe with some magic and a compare value of 0 or OCM value 5?

Code: Select all

#define VALUE  1

void setup() {
  // set up timer 3 for fast period
  T3CONCLR = _T3CON_ON_MASK;
  TMR3 = 0;
  PR3 = VALUE;
  T3CON = _T3CON_ON_MASK; 
 
  // set up output compare 1 to track timer 3 on rd0 (pin 3)
  OC1CONCLR = _OC1CON_ON_MASK;
  OC1R = 0;
  OC1RS = VALUE;
  OC1CON = _OC1CON_ON_MASK|_OC1CON_OCTSEL_MASK|(3<<_OC1CON_OCM0_POSITION);
 
  // set rd1 for digital output
  TRISDCLR = 0x2;
}

void loop() {
  // invert rd1 (pin 5)
  LATDINV = 0x2;
}

Or maybe I have aliasing going on in my (40Ms/s) bitscope???

User avatar
svofski
Posts: 58
Joined: Sun Jul 03, 2011 3:23 am

Re: Maximum pin frequency

Postby svofski » Wed Jul 13, 2011 11:48 am

There are also 2 SPI modules, each of which can be used in frame mode. It's a mode in which the clock is running continuously and can be "misused" for other things as well.

User avatar
rtestardi
Posts: 79
Joined: Mon Jun 06, 2011 1:16 am
Location: Boulder, CO USA
Contact:

Re: Maximum pin frequency

Postby rtestardi » Wed Jul 13, 2011 2:58 pm

Thank you, I'm curious why the programatic pin toggle is so slow, is this because of arduino compatibility layer?

No, there is no compatibility layer there -- we're playing directly with MCU registers.

The main problem is probably just compiler options -- the compiler is generating un-optimized code (note the delay slot is completely unused, and you can't tell from the snip, but "ra" actually has the address of "loop", so the actual loop has *five* instructions in it, when it only needs two -- the jr and the sw, with the sw being in the delay slot of the jr).

There might be a secondary problem related to MCU setup (wait states, cache, SYSTEMConfigPerformance(), etc.), but I think that is actually right...

-- Rich
Embedded Systems Made Easy: http://www.cpustick.com .....

User avatar
hairymnstr
Posts: 50
Joined: Wed Jun 15, 2011 10:03 am
Location: Bristol, UK
Contact:

Re: Maximum pin frequency

Postby hairymnstr » Thu Jul 14, 2011 1:13 pm

There is some Arduino overhead there. The loop() function is called from the main so the main is something more like:

Code: Select all

void main(void) {
  init();

 while(1) {
  loop();
 }
}


So there's the overhead of the while operation and the call/return overhead.
#include <coffee.h> // The start of all good programming sessions

User avatar
rtestardi
Posts: 79
Joined: Mon Jun 06, 2011 1:16 am
Location: Boulder, CO USA
Contact:

Re: Maximum pin frequency

Postby rtestardi » Thu Jul 14, 2011 4:35 pm

Good point.

I didn't see any function call in the disassembly (it must have been automatically inlined), but this definitely helps:

Code: Select all

void loop() {
  for (;;) {
    // invert rd1 (pin 5)
    LATDINV = 0x2;
  }
}


And generates slightly better code:

Code: Select all

00000000 <loop>:
   0:   3c030000        lui     v1,0x0
   4:   24020002        li      v0,2
   8:   ac620000        sw      v0,0(v1)
   c:   ac620000        sw      v0,0(v1)
  10:   08000002        j       8 <loop+0x8>
  14:   00000000        nop


The delay slot is still unused (wasting an instruction), but at least the loop is shorter... And the compiler unrolled the loop once... So the pin toggle rate jumps to 20MHz (and I'm definitely seeing aliasing on my 40Ms/s bitscope now!).
Embedded Systems Made Easy: http://www.cpustick.com .....


Return to “chipKIT Boards”

Who is online

Users browsing this forum: No registered users and 3 guests