Go Down

Topic: PIO Set/Clear Frequency (Read 1 time) previous topic - next topic

stimmer

This is the fastest I have managed so far. I haven't verified the output signal but it looks plausible.
Code: [Select]

void setup(){
  Serial.begin(115200);
  for(int p=2;p<70;p++)pinMode(p,OUTPUT);
}

#define do10(x) x x x x x x x x x x
void loop(){
  uint32_t s=0x7fffffff;
  uint32_t r=0x0;
  typeof(REG_PIOC_ODSR) *p=&REG_PIOC_ODSR;
 
  long t=micros();
  for(int x=0;x<1000;x++){
    do10(do10(do10( *p=s;*p=r; )))
  }
  t=micros()-t;
 
  Serial.print("1 million write pairs in ");
  Serial.print(t);
  Serial.print(" uS = ");
  Serial.print(1000000.0/double(t));
  Serial.println(" MHz");
}


1 million write pairs in 47797 uS = 20.92 MHz

Disassembly looks like this:
Code: [Select]

f00:   6019            str     r1, [r3, #0]
f02:   601a            str     r2, [r3, #0]
f04:   6019            str     r1, [r3, #0]
f06:   601a            str     r2, [r3, #0]
f08:   6019            str     r1, [r3, #0]
f0a:   601a            str     r2, [r3, #0]
f0c:   6019            str     r1, [r3, #0]
f0e:   601a            str     r2, [r3, #0]
.....


Remember that there are other ways of getting a signal out of a pin (SPI, timers, PWM, even DMA to the port might do it)

DuaneB

Unless I am missing something, its also a bit pointless - programmatically toggling pins when timers can do it faster and more consistently - i.e. not loop over head or asymmetry.

Duane B

brichs

Thank you all for your responses, I was unaware of a method for getting the assembly from the compiler, so DuaneB that was tremendous help. Using a method similar to the post by stimmer, I was able to scope a 21 MHz signal.

And yes, I am aware of the methods for producing a reliable clock through other protocols, timers, etc. The current application is a user-controlled clocking of data in a finite state machine, I just wanted to see my max pin switching frequency.   


Go Up