Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 19:55 17 May 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Frequency counter using PIO, work in progress for picomite

     Page 2 of 2    
Author Message
Pluto
Guru

Joined: 09/06/2017
Location: Finland
Posts: 375
Posted: 11:46am 10 Dec 2022
Copy link to clipboard 
Print this post



Test set-up: The signal source (in the middle) is a Si5351A-based oscillator controlled by a 28pin MicroMite. Cheap Chinese frequency meter on the left. PicoMite with Volhout's newest PIO-based frequency meter on the right, outputting 89998399Hz.
 
Amnesie
Guru

Joined: 30/06/2020
Location: Germany
Posts: 530
Posted: 01:53pm 17 Apr 2024
Copy link to clipboard 
Print this post

Hi, I was trying Volhouts latest code but got Syntax error:








This is the code (one page back <):




pio_freq_measure.zip


Has anyone some hints?

- Daniel
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 4875
Posted: 02:44pm 17 Apr 2024
Copy link to clipboard 
Print this post

Hi Daniel.

This is made for PicoMite V5.07.05RC3. Since then (i.e. V5.08.00) the format is corrected for PIO(execctrl a,b,c)

Change the first "0" in "gp0": (example for PIO 1.0)

e0 = Pio(execctrl 0,0,&h1f)


to

e0 = Pio(execctrl gp0,0,&h1f)


Regards,

Volhout
Edited 2024-04-18 00:51 by Volhout
PicomiteVGA PETSCII ROBOTS
 
Amnesie
Guru

Joined: 30/06/2020
Location: Germany
Posts: 530
Posted: 03:00pm 17 Apr 2024
Copy link to clipboard 
Print this post

Hi

thank you a lot, works fine now - impressive work!

-Daniel
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 4875
Posted: 06:17am 14 May 2025
Copy link to clipboard 
Print this post

Warning: below code is just a proof of concept for a new PIO core that allows for more accurate frequency measurement. It is by no means complete.

The essence is to increase resolution, so a different method is used. Note that this method uses MMBasic to generate the gate pulse, not PIO itself. The gate pulse need not to be accurate now. Note that the final accuracy depends on the crystal on the pico. The crystal accuracy can be calibrated out when you know what it is.

This code (as is) can only be assembled using the 6.00.02 PIO assembler.
You need V6.00.02rc7 or newer to run the code.

 ' test for the RC7 new PIO CONFIGURE
 'PIO Configure pio, sm, clock [,startaddress]
 '[,sidesetbase] [,sidesetno] [,sidesetout]
 '[,setbase] [,setno] [,setout] [,outbase] [,outno] [,outout] [,inbase]
 '[,jmppin] [,wraptarget] [,wrap] [,sideenable]
 '[,pushthreshold] [,pullthreshold] [,autopush] [,autopull] [,inshiftdir] [,outshiftdir]
 '[,joinrxfifo] [,jointxfifo] [,joinrxfifoget] [,joinrxfifoput]
 
 ' test for new assembler format
 ' requires picomite 6.00.02 beta 10 or newer because (PIO(NEXT LINE))
 
 'FC2 = frequency counter 2, OPTION CPUSPEED 252000 is accurate
 
 'idea from Bert Lemmens to increase accuracy frequency measurement
 'at start gate, wait for first edge, then start gate', and count pulses.
 'at end gate, wait for next edge, then stop gate', and stop counting
 'measure pulse width gate'
 'frequency = count / gate' time
 'period = gate' time / count
 'this should not jitter
 
 'current assignment
 'gp0 = count input
 'gp1 = gate pulse
 'gp2 = gate'pulse
 
 '-------------------------- version history ------------------------------
 'v00     'gate pulse works
 'v01     'pulse measurement from gate' pls works
 'v02     'counter works (not calibrated)
 'v03     'replace PIO gate generator with MMBasic pulse generator (free 1 SM))
 'v04     'implement pause measurement, new assembler directives in v6.00.02b10
 
 
 debug=1'0         'do you want debug output ?
 
 
 '-------------------------- system setup --------------------------------
 
 'MMBasic generate gate pulse (active low)
 p = 1                            'use PIO 1
 
 'assign frequency counter pins
 if p=1 then
   setpin gp0,pio1               ' = input
   setpin gp2,pio1               ' = gate'
 else
   setpin gp0,pio0               ' = input
   setpin gp2,pio0               ' = gate'
 end if
 setpin gp1,dout : pin(gp1) = 1  ' = gate output from MMBasic, active low
 
 assemble p        'assemble the code in PIO p
 configPio p       'configure PIO p state machines
 
 'defines
 puls_tick! = 2 / f0             ' pulse measurement tick
 
 'memory allocation
 dim altgate%(4)                 ' to read gate' value from fifo
 dim cntr%(4)                    ' to read count value from fifo
 
 
 
 '----------------------------- main --------------------------------------
 
 do
   'gat epulse generation in MMBasic
   pulse gp1,200         'generate gate pulse
   pause 300             'this is the loop time, the pulse 200 is not blocking
   
   'read what the PIO reads from gate'
   pio read 1,0,5,altgate%()
   
   'read what the PIO reads from counter
   pio read 1,1,5,cntr%()
   
   if cntr%(4)=0 then inc cntr%(4) 'prevent divide by zero
   
   'show period and frequency
   print altgate%(4)*puls_tick!/cntr%(4);" seconds period",
   print cntr%(4)/(altgate%(3)*puls_tick!);" Hz frequency"
   
 loop
 
 
end
 
 
 
 '----------------------------- subs --------------------------------------
 'this configures the state machines for PIO n
Sub configPio(p)
 
 'stop all PIO's
 PIO stop p,0: PIO stop p,1': PIO stop p,2: PIO stop p,3
 
 'PIO p.0 (measure pulse from GP2)
 f0=126e6                                      '126 MHz frequency
 e0=Pio(execctrl gp2,puls_target,puls_wrap)    'GP2 is jump pin
 p0=Pio(pinctrl 0,,,GP2,,,)                    'GP2 is input pin
 
 'PIO 1.1 (frequency A from GP0)
 f1=126e6                                       '126 MHz frequency
 e1=Pio(execctrl gp1,count_target,count_wrap,0,1)  'GP1 = cond jmp, side_set ena option
 p1=Pio(pinctrl 2,1,,gp0,gp2,GP2,)             'GP0 input, GP2 for SIDE SET and SET
 '2 = side enable + side set pins
 
 'Start all PIO sequencers
 'PIO init machine p,0,f0,p0,e0,0,puls_start
 PIO Configure p,0,f0,puls_start,GP2,2,,GP2,1,,,,,GP0,GP1,puls_target,puls_wrap
 PIO start p,0                       'this will start pulse measurement from GP2
 
 '  PIO init machine p,1,f1,p1,e1,0,count_start
 PIO Configure p,1,f1,count_start,,,,,,,,,,GP2,GP2,count_target,count_wrap,1
 PIO start p,1                       'start counter, count while GP1 low
 
End Sub
 
 
 
 'this sub assmebles the different PIO routines
sub assemble (p)
 
 'measure positive pulse, used for gate' time
 'require IN and JMP pin to be set equal to the gate' pin
 
 puls_start=0
 
 pio assemble p
 .program pulse
 .line 0
 .wrap target
 mov x,!null          'x=ffffffff
 wait 1 pin 0         'wait for pin to go high
 .label cnt:          'label
 jmp x-- always       'decrement x, and always go to the next instruction
 .label always:       'label
 jmp pin cnt          'while 1 jmp to cnt:
 mov isr,!x           'copy inverted value to isr
 push noblock         'push in fifo
 .wrap
 .end program list
 
 puls_target=pio(.wrap target)
 puls_wrap=pio(.wrap)
 if debug then print puls_start,puls_target,puls_wrap
 
 '
 'count pulses
 'uses side set 2 to control gate' and no-signal... gate' and no_count are same signal
 'set and side set base must point to the same pins
 'todo: add no-count via SET second bit
 
 count_start=pio(next line)
 
 pio assemble p
 .program count
 .line next            'continue assembling
 .side set 1 opt       'side set bits + option
 set pindirs,1         'gate' set output and low
 .wrap target          'return here
 mov x,!null side 0    'x=ffffffff, gate' low, no_count low
 .label wait:          'label
 jmp pin wait          'wait until gate opens (active low)
 .label countup:       'label
 wait 0 pin 0          'wait until count in low
 wait 1 pin 0          'wait until count in high
 jmp pin ready side 1  'set gate' and check if gate ready
 jmp x-- countup       'count down while not 0, gate high
 .label ready:         'label
 mov isr,!x side 0     'copy inverted value to isr, gate' low
 push noblock          'push in fifo
 .wrap                 'endless loop
 .end program list
 
 count_target=pio(.wrap target)
 count_wrap=pio(.wrap)
 if debug then print count_start,count_target,count_wrap
 
 
 'measure negative pulse, used for gate time
 'require IN and JMP pin to be set equal to the gate pin
 
 pause_start=pio(next line)
 
 pio assemble p
 .program pause
 .line next
 .wrap target
 mov x,!null          'x=ffffffff
 wait 0 pin 0         'wait for pin to go low
 .label cnt:          'label
 jmp pin done         'when 1 jmp to done:
 jmp x-- cnt          'decrement x, and always go to the next instruction
 .label done:         'label
 mov isr,!x           'copy inverted value to isr
 push noblock         'push in fifo
 .wrap
 .end program list
 
 pause_target=pio(.wrap target)
 pause_wrap=pio(.wrap)
 if debug then print pause_start,pause_target,pause_wrap
   
end sub


I run the pico at 252MHz, so PIO can run at 126MHz, which is a full divider from 252MHz. This is needed for low jitter.

Note above code still has the old "e0, e1, p0, p1" PIO helper variables, but these are not used, since the parameters are embedded in the new PIO CONFIGURE command (as listed in the comments at the top of the code).

Volhout
Edited 2025-05-14 16:43 by Volhout
PicomiteVGA PETSCII ROBOTS
 
pwillard
Guru

Joined: 07/06/2022
Location: United States
Posts: 308
Posted: 02:19pm 14 May 2025
Copy link to clipboard 
Print this post

Just wanted to say... thanks for this effort.

It might come in handy for one of my projects.
 
PhenixRising
Guru

Joined: 07/11/2023
Location: United Kingdom
Posts: 1170
Posted: 02:27pm 14 May 2025
Copy link to clipboard 
Print this post

  Volhout said  

I run the pico at 252MHz, so PIO can run at 126MHz, which is a full divider from 252MHz. This is needed for low jitter.

Volhout


Hi Harm,

But the PIO can run at sysclock, no?
 
Pluto
Guru

Joined: 09/06/2017
Location: Finland
Posts: 375
Posted: 02:31pm 14 May 2025
Copy link to clipboard 
Print this post

Thanks Volhout!
What would the max measurable frequency be?
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 4875
Posted: 06:37pm 14 May 2025
Copy link to clipboard 
Print this post

Hi Pluto,

The counting code is the same as in the previous tests you have performed, so the achievable frequency would be the same if you set the same PIO clock.

Volhout
PicomiteVGA PETSCII ROBOTS
 
     Page 2 of 2    
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025