Shop OBEX P1 Docs P2 Docs Learn Events
200kHz +/- 5kHz pulse output? — Parallax Forums

200kHz +/- 5kHz pulse output?

StephenMooreStephenMoore Posts: 188
edited 2012-03-15 16:46 in Propeller 1
Anybody-

I have tried to use cog counter modules but can not seem to get a 200kHz pulse train and then vary it slightly within a few kHz. I either get jitter or have to jump by a factor of 2 up or down in frequency. However, if I use waitcnt in PASM I can get the resolution I am after. This does require a whole cog with only a few lines of code so I a kind of waste the power of the propeller. I need many of these pulse trains for my application.

Is there a way to do this with the counter feature?
DAT


'---------------------------
' Assembly language routines
'---------------------------
'assembly code pulses a pin rapidly without jitter


              org       0
              
mycode        or        dira, pin0                    


              mov       time, cnt
              add       time, period
              
:loop         xor       outa, pin0
              waitcnt   time, period                  
              jmp       #:loop                        
                            


              
pin0          long      |< 0                          
period        long      400
time          res       1
«1

Comments

  • MagIO2MagIO2 Posts: 2,243
    edited 2012-03-06 22:58
    I need many of these pulse trains for my application.
    How many is that? If it's more than 2 you need additional COGs which is also a waste. Depending on how many free COGs you have this might add some work to be done just for adding your code to the other drivers you need.

    If you really need many it makes sense let one COG do the job even if the code-size itself is by far not reaching 496 longs!
  • jmgjmg Posts: 15,183
    edited 2012-03-07 02:00
    Anybody-
    I have tried to use cog counter modules but can not seem to get a 200kHz pulse train and then vary it slightly within a few kHz.

    "vary it slightly within a few kHz" is to vague.
    Also, how much jitter can you tolerate ?
    If you take a 80MHz Clk and output 200KHz that is /400, jitter free.
    Another jitter free output is at /401, 199501.246Hz, and /399 is 200501.253
    Note these are 12.5ns more and less in period.
    That 12.5ns is the edge-limit, and you can get an average frequency between these values, by effectively outputting a dithered set.

    If you can accept a 10 cycle average, for example, you can define to 1.25ns apparent/average edge, but the absolute edges are always on 12.5ns time slots.
  • LeonLeon Posts: 7,620
    edited 2012-03-07 05:47
    A PLL is often used to remove jitter.
  • BeanBean Posts: 8,129
    edited 2012-03-07 06:49
    You could mix the two counter outputs and generate a difference frequency. This requires no code to work. Only a RC filter.

    Set counterA to output 10MHz on pin 0
    Set counterB to output 10.2MHz on pin 0 (note the same pin is used)

    Take the output from pin 0 and run it into a RC filter. The output of the RC filter will be a 200KHz triangle wave going from 1/2 Vcc to Vcc.

    The high frequencies can be adjusted by very small amounts. Giving very fine adjustment in the frequency of the output of the RC filter.

    The output from the RC may need to be buffered depending on what you are driving.

    Here is my PropBasic code:
    DEVICE P8X32A,XTAL1,PLL16X
    FREQ 80_000_000
    
    PROGRAM Main
    
    Main:
      OUTPUT 0
      COUNTERA 32, 0, 0, 536870912
      COUNTERB 32, 0, 0, 547608330
    END
    

    Bean
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-03-07 08:06
    Pursuant to Leon's comment:

    -Phil
  • Duane C. JohnsonDuane C. Johnson Posts: 955
    edited 2012-03-07 13:08
    Hi Bean & StephenMoore:

    This technique is very versatile. There is a wide range of frequencies and mile Hz resolution.
    Better yet the qitter is nearly non existent

    Duane J.
  • BeanBean Posts: 8,129
    edited 2012-03-07 13:23
    Looking at my method again, I should have used 20MHz and 20.2MHz to get a smoother triangle.
    The other nice thing about using both counters is that no code is needed for it to work.
    I'd like to see the output on a spectrum analyzer if someone is able to do that.

    Bean
  • jmgjmg Posts: 15,183
    edited 2012-03-07 13:52
    This would still have some phase jitter, as you are still granular to 12.5ns ?

    Taking the 10MHz values, we have a divide by 8 for 10Mhz and divide by 7.84313725833936821 for ~ 10.2MHz
    - ie 84.3% of the time, it divides by 8, and the other 100-84.3% it divides by 7.
    The Egyptian fraction of this is
    1/2 + 1/3 + 1/102 + 1/290917621
    The 1/2 and 1/3 you can filter, but the 1/102 is ~ 98Khz so roughly every second cycle will differ.
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2012-03-07 13:55
    With this object: http://obex.parallax.com/objects/422/ you can do 4 outputs with one cog at the frequencies you are asking for. But the frequencies aren't updatable on-the-fly (the cog must be restarted to change values), and since it includes PWM/duty considerations, it's about half the speed/resolution of what it could be.
    It could be easily re-written to do 8 outputs at ~200kHz, and probably not too much work to make the values changeable on-the-fly.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-03-07 14:21
    I did a test with the counter(s) output into an RC low-pass filter (2.2K/220pF). The first test was with just one counter set for 200kHz. Here's the spectrum in the vicinity of the fundamental:

    attachment.php?attachmentid=90368&d=1331158865

    The second test involved two counters
    640 x 480 - 11K
    640 x 480 - 11K
  • BeanBean Posts: 8,129
    edited 2012-03-07 14:29
    Phil, if you have time could you try 20.02Mhz?
    I would think that would be better.
    Or maybe a double RC filter.
    Bean
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-03-07 14:45
    Bean wrote:
    Phil, if you have time could you try 20.02Mhz?
    To get a 20 kHz signal, right, instead of 200 kHz? Sure, I can try it.
    Bean wrote:
    Or maybe a double RC filter.
    Filtering, unfortunately, will not remove jitter, since the jitter sidebands are so close to the fundamental.

    -Phil
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-03-07 14:58
    Here are the results of 20 kHz from one counter:

    attachment.php?attachmentid=90370&d=1331161087

    Here's the spectrum of 20.02 MHz mixed with 20 MHz:

    attachment.php?attachmentid=90371&d=1331161087

    The RC filter was 5.1K/1nF.

    -Phil
    640 x 480 - 10K
    640 x 480 - 11K
  • Duane C. JohnsonDuane C. Johnson Posts: 955
    edited 2012-03-07 15:04
    Hay Phil:

    Could you look in close to the 200KHz signal? Maybe +-1KHz or +-100Hz or tighter?

    Duane J
  • BeanBean Posts: 8,129
    edited 2012-03-07 15:26
    Drat, not what I had hoped for. Oh well. I was hoping the RC would filter most of the jitter out, but I guess not.

    Bean
  • CircuitsoftCircuitsoft Posts: 1,166
    edited 2012-03-07 15:28
    A sallen-key filter probably could, if you put enough stages in it.
  • jmgjmg Posts: 15,183
    edited 2012-03-07 15:41
    Not in a practical number of stages... ;)

    If we take that ~200KHz example, that will divide by 400 most of the time, and then every (appx) 111849 cycles, it will divide by 401, so a fast gated counter will show 200.000KHz most of the time, and it may catch that 199501.246Hz, for the average result of 199999.99553Hz

    This is why it is better to think in the time domain, than the frequency domain.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-03-08 09:35
    After further experimentation, I'm not sure how to interpret the spectral traces my scope was giving me. I sought to compare a jitter-free square wave (frqa = $0080_0000) with Stephen's 200 kHz square wave, expecting that the jitter-free version would exhibit no side lobes. But that proved not to be the case. I think the problem lies in how the sampled waveform fits within the sampling window. If an integral number of cycles (or power-or-two number of cycles?) fits perfectly, there should be no side lobes or sub-harmonics in the spectrum. But my scope does not allow fine control over the width of the sampling window -- only its shape (i.e. Hamming, Blackman-Harris, Hanning, Rectangular) -- and each produces a characteristic side-lobe distribution.

    This notwithstanding, I do know that spectral filtering (low-pass, high-pass, band-pass) will not remove jitter. The only exception might be an extremely high-Q band-pass filter. Bit it would ring so much as to render any attempts at modulation futile. An external PLL is simple to set up and the best way to go.

    -Phil
  • StephenMooreStephenMoore Posts: 188
    edited 2012-03-08 21:55
    Very interesting. The answer seems to be no can do with counter.

    This code gets the job done but you can't use the cog for anything else. (Like I had big plans for it anyway.)

    I think I can get 4-6 high frequency signals out of teh Propeller with around 1-2% resolution using 2-4 cogs for supervisory control/feedback functions


    CON 
            _clkmode = xtal1 + pll16x
            _xinfreq = 5_000_000
    
    
            maxFreq  = 36
            minFreq  = 200
            period   = minFreq - maxFreq
            
    VAR  
     
         long parameter 
    
    PUB main  | myCog
     
      
      repeat
       
        repeat parameter from minFreq to maxFreq             
         myCog := cognew(@myCode, @parameter)                     
         waitcnt(clkfreq / period + cnt)
         cogstop(myCog)        
        repeat parameter from maxFreq to minFreq             
         myCog := cognew(@myCode, @parameter)                     
         waitcnt(clkfreq / period + cnt)
         cogstop(myCog)        
    
    
    
    
    DAT
    
    
    '---------------------------
    ' Assembly language routines
    '---------------------------
    
    
                  org       0
                  
    mycode        or        dira, diraval                  
    
    
                  rdlong    pausePin, par                      
                  mov       time, cnt                     
                  add       time, pausePin                  
                  
    :loop         xor       outa, diraval
                  waitcnt   time, PausePin                  
                  jmp       #:loop                       
                                
    
    
                  
    diraval       long      |< 0
    pausePin      res       1                           
    time          res       1
    
  • Mark_TMark_T Posts: 1,981
    edited 2012-03-09 02:34
    After further experimentation, I'm not sure how to interpret the spectral traces my scope was giving me. I sought to compare a jitter-free square wave (frqa = $0080_0000) with Stephen's 200 kHz square wave, expecting that the jitter-free version would exhibit no side lobes. But that proved not to be the case. I think the problem lies in how the sampled waveform fits within the sampling window. If an integral number of cycles (or power-or-two number of cycles?) fits perfectly, there should be no side lobes or sub-harmonics in the spectrum. But my scope does not allow fine control over the width of the sampling window -- only its shape (i.e. Hamming, Blackman-Harris, Hanning, Rectangular) -- and each produces a characteristic side-lobe distribution.

    This notwithstanding, I do know that spectral filtering (low-pass, high-pass, band-pass) will not remove jitter. The only exception might be an extremely high-Q band-pass filter. Bit it would ring so much as to render any attempts at modulation futile. An external PLL is simple to set up and the best way to go.

    -Phil

    Kaiser-Bessel windows perform well - if you can use K-B with alpha = 3.0 or higher it should give good results.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-03-09 08:50
    Thanks, Mark. Unfortunately, that's not one of the options offered by my scope. The other issue is likely to be sample depth which, on my scope, is 10,000 (probably 8192 for the FFT). That makes it hard to cram enough cycles into a sample to resolve down to a fraction of a percent of the fundamental frequency. It's good as far as it goes, but it's just an oscilloscope with some extra features, not a full-fledged spectrum analyzer.

    -Phil
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2012-03-10 01:55
    I looked at this on a LeCroy 9374 'scope with the statistics module, as seen the the following three scope traces. These happen to be done with clkfreq=40MHz. The first trace is a perfect divisor, 78125Hz =40MHz/512, frqa:=8388607, and not surprisingly the sigma is at the detection level of the setup. 0.0001, with most periods at 12.8µs.

    The second trace is 100kHz, frqa:=10737418. Here again the sigma is at the limit of detection. Puzzling though, I'd expect to see an occasional bump to 10.025 microsecond but the scope shows 10.005µs as the maximum and 9.9999µs, pretty much the same spread as the perfect divisor. I should have let it run longer. There may be interaction with the 'scope triggering. This setting should have lots of cycles of length 400 through the phase accumulator before it make a cycle of length 401.

    The last trace is close to 110614 Hz, frqa := 11877087. You can see it did pick up a more variance and a larger spread. I let it run longer, but that is not the cause. The jitter was evident by eyeballing the bouncing edge of the trace on screen. I chose that frequency specifically. The first quotient is (232/frqa =361), to set the base frequency, but the remainder after the division is 0.618 which is close to (sqrt(5)+1)/2. The consequence is that the continued fraction from then on out has lots of 1s, converges slowly, jitters, and has lots of additional subharmonics. I'll go out on a limb again as I have done before, and posit that a numerical oscillator is really, in fact, a way of representing a number in the form of a continued fraction. The 'scope statistics show the expected difference between high and low periods, around 25ns (1/40MHz). It jumps back and forth often in a long repeating pattern between its two periods--361 clocks, 9.025µs cycle and 362 clocks, 9.050µs.


    100000Hz.JPG
    78125Hz.JPG
    110614Hz.JPG
    450 x 316 - 65K
    450 x 302 - 66K
    450 x 304 - 66K
  • StephenMooreStephenMoore Posts: 188
    edited 2012-03-10 10:54
    That is some fine scope work: does anybody know where I can get a good scope for cheap?

    I may have to re-evaluate my simplistic approach. What I am trying to do is set the harmonic frequency of an inverting power supply to a value around 2e+5 Hz. The exact resolution required is not known for the resonator circuits I have. It may be that these infrequent bumps do not impact the power flow at all. It is more important for me to find the harmonic resonance frequency (as indicated by phase shift in voltage) and then operate slightly above it.

    The advantage gained with the counter module feature is desirable. We are trying to run several dozen circuits in parallel and each may be tuned slightly differently.

    Thanks to those who have thought about this and taken some time to actually try stuff out.

    regards...sm.
  • jmgjmg Posts: 15,183
    edited 2012-03-10 12:00
    Puzzling though, I'd expect to see an occasional bump to 10.025 microsecond but the scope shows 10.005µs as the maximum and 9.9999µs, pretty much the same spread as the perfect divisor.

    You may be too fast for their stats update? If they grab a set every 50us, they will average over 5 cycles and give 5ns not 25.
    Does it have a high persistence mode ?
    I'll go out on a limb again as I have done before, and posit that a numerical oscillator is really, in fact, a way of representing a number in the form of a continued fraction.

    Yes, I use the Egyptian fractions, which are the same thing.
  • jmgjmg Posts: 15,183
    edited 2012-03-10 12:33
    What I am trying to do is set the harmonic frequency of an inverting power supply to a value around 2e+5 Hz. The exact resolution required is not known for the resonator circuits I have. It may be that these infrequent bumps do not impact the power flow at all. It is more important for me to find the harmonic resonance frequency (as indicated by phase shift in voltage) and then operate slightly above it.

    These dT bumps only occur in the counter/adder overflow and you could fit 8 channels in a single Prop.
    A counter will give you one part in 400 step size @ 80MHz and one in 500 at 100MHz
    In 'set and forget' it will have max edge variations of 12.5ns, so I'd try that first and see if it is a problem.

    The quasi resonant power supplies are lowish Q, so are reasonably tolerant of frequency.
    If this is also your primary regulation loop, frequency step size becomes more important.

    That low Q also means they are less able to smooth over many cycles.
    The advantage gained with the counter module feature is desirable. We are trying to run several dozen circuits in parallel and each may be tuned slightly differently.

    Hardware will always beat SW in precision, by an order of magnitude, & the timer will define to 12.5ns, give you x8/chip.
    Just use a lot of chips... It's only $1/channel.
    Edit: Oops, typo, there are of course 8 cogs, but 16 timers, per chip, makes it ~ 50c/chan.

    The other solution for "several dozen circuits" would be a moderate sized CPLD ?
    That would give ~twice+ the precision, and could have no jitter at all.
  • StephenMooreStephenMoore Posts: 188
    edited 2012-03-10 16:16
    jmg:

    The circuit is a half bridge resonator. Also, Q varies depending on the load ... initially it is low but will cycle to low-high states. Thus, I need to have some control in the setup.

    The Propeller USB board is actually a good choice for signal source and controller built into one both from a cost and development time standpoint. What other chips did you have in mind?

    Phil Pilgrim has recommended a PLL chip but I was hoping to avoid any additional complexity

    I have worked with National Instruments FPGA and they are beaucoup expensive.

    Do you have any experience with this item:

    [h=3]XC2C64A CoolRunner-II CPLD[/h]http://www.xilinx.com/support/documentation/data_sheets/ds311.pdf

    $15 board from http://www.seeedstudio.com/depot/xc2c64a-coolrunnerii-cpld-development-board-p-800:7a53928fa4dd31e82c6ef826f341daec.html

    It may be going up the learning curve once again to understand its use.

    regards,

    sm
  • jmgjmg Posts: 15,183
    edited 2012-03-10 20:52
    [QUOTE=StephenMoore;1081186
    Do you have any experience with this item:

    XC2C64A CoolRunner-II CPLD
    $15 board from http://www.seeedstudio.com/depot/xc2c64a-coolrunnerii-cpld-development-board-p-800:7a53928fa4dd31e82c6ef826f341daec.html

    It may be going up the learning curve once again to understand its use.
    [/QUOTE]

    I'd suggest you skip that level, and go straight to LCMXO2-1200ZE-B-EVN ($29)\
    http://www.latticesemi.com/products/developmenthardware/breakoutboardevalkits.cfm?source=topnav

    The XC2C64 has too few macrocells, and has no RAM.
    The MachXO2 is faster, and you could easily swallow 'several dozen circuits' (simple ones) in this.
    If you imagine the simplest 10 bit counters and 10 bit /N that's 20 macrocells per circuit, so a XC2C64 manages just 3 - less than a prop.

    If you want to expand to control both Freq and Duty cycle or Ton/Toff, (and I would allow for that) that's ~30MC/circuit. - so over 20 would fit in that board, via simple registers.

    There maybe a way to control these from RAM, which would pack even more, but RAM tends to suit fixed playback.

    I have not used LUT-RAM, but I think they would be well suited for the local stores, up to 16x4 RAM in 3 slices/6LUT. 3 x DPR16X4C would give 12b read width, 16 choices, and independent host writes.
    Ton.Toff would be paired, so you could have 8 pairs, one pair could be a reset value, and one a working value, and you could have sets, if you wanted to change ALL frequencies at once.
    (ripple write to B set, when running from A, then all switch on their next edge to new values.
    and vice versa for next update )


    My only beef with Lattice is they still do not offer smaller gull-wing packages than 100pins, and only one MLF32(coming).. Grr....
    Given they can do a 2.5mm x 2.5mm BGA, the die must be tiny ...
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2012-03-10 22:16
    jmg wrote: »
    You may be too fast for their stats update? If they grab a set every 50us, they will average over 5 cycles and give 5ns not 25.
    Does it have a high persistence mode ?

    It grabs samples from data that is on the screen display between the cursors. Triggering sync? I know the glitch is there, from theory, so finding it has to be a matter of using smart triggering modes or triggering from another prop pin.

    The scope does have persistent mode. Here are traces from 10MHz and 10.2MHz using the parameters from Bean's post#5. The jitter at 10.2MHz is evident both in the persistent trace and in the sigma, which becomes a larger fraction of the cycle length at higher frequencies. There is the evident bobble between 7 and 8 trips through the phsa. The time cursors that bound the measurements are shown, the start cursor being just prior to the trigger point. Sorry about the overshoot--long ground lead to the quickstart board.
    10.2MHz.JPG


    10.0MHz.JPG
    900 x 627 - 178K
    900 x 629 - 177K
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-03-10 22:58
    Here's a program you can use to get jitter-free counter output from up to 14 counters per Propeller chip (two per cog), up to 300 KHz apiece:
    '':::::::[ Jitter-free Counters ]::::::::::::::::::::::::::::::::::::::::::::::
     
    {{{
    &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
    &#9474;      Jitter-free Counter Driver       &#9474;
    &#9474;(c) Copyright 2012 Bueno Systems, Inc. &#9474;
    &#9474;   See end of file for terms of use.   &#9474;
    &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
    
    This program provides jitter-free counter outputs, two per cog, up to about 300 kHz
    (80 MHz clock). It uses the counters and works by forcing a phsx adjustment at each
    transition of the output, which results in a transition every n system clocks. The
    half periods for the high phase and low phase are independently adjustable, with a
    resolution of one system clock period. This permits limited duty cycle adjustment,
    so long as each half period is no longer than about 133 system clocks.
    
    }}
    
    CON
    
      _clkmode      = xtal1 + pll16x
      _xinfreq      = 5_000_000
    
      PIN0          = 0             'Assign pin numbers.
      PIN1          = 1
      PIN2          = 2
      PIN3          = 3
      PIN4          = 4
      PIN5          = 5
      PIN6          = 6
      PIN7          = 7
    
      NCO           = %000100000    'I field for NCO counter.
    
    PUB  start | i
    
      repeat i from 0 to 6 step 2                           'Start four cogs for eight counters.
        cognew(@clock, @periods[i])
      repeat while periods[6] or periods[7]                 'Wait for last cog to be ready.
      repeat i from 0 to 7                                  'Assign periods.
        periods[i] := (200 + i) * $1_0001
      repeat
    
    DAT
    
                  org       0
    clock         mov       addrb,par               'Compute address of periodb              
                  add       addrb,#4
    
                  rdlong    ctra,par                'Read pin for ctra.
                  mov       maska,#1                'Convert to mask.
                  shl       maska,ctra
                  mov       frqa,#1                 'Frequency is one.
                  
                  rdlong    ctrb,addrb              'Read pin for ctrb.
                  mov       maskb,#1                'Convert to mask.
                  shl       maskb,ctrb
                  mov       frqb,#1                 'Frequency is one.
    
                  mov       dira,maska              'Set pins to output.
                  or        dira,maskb
    
                  mov       acc,#0                  'Signal that we're ready to go.
                  wrlong    acc,par
                  wrlong    acc,addrb
    
    waitlp        rdlong    perioda,par wz          'Wait for non-zero periods to be loaded.
            if_nz rdlong    periodb,addrb wz
            if_z  jmp       #waitlp
    
                  mov       acc,phaseadj            'Initialize phases.
                  sub       acc,perioda
                  mov       phsa,acc
                  mov       acc,phaseadj
                  sub       acc,periodb
                  mov       phsb,acc
                  movi      ctra,#NCO               'Start counters.
                  movi      ctrb,#NCO               
    
    mainlp        mov       inp,ina                 'Read the pins.
                  and       inp,dira                'Mask out all but counter outputs.
                  xor       inp,prev                'XOR with previous pin reading.
                  
                  test      inp,maska wz            'Has pina changed?
            if_z  jmp       #testb                  '  No:  Try pinb.
    
                  rdlong    perioda,par             '  Yes: Read latest periods for ctra.
                  test      prev,maska wz           '       Was previous input a zero?
            if_z  shr       perioda,#16             '         Yes: Use high 16 bits of period.
                  and       perioda,_0xffff         '       Mask off period for other half cycle.
                  sub       perioda,phaseadj        '       Subtract the phase adjust constant.
                  sub       perioda,phsa            '       Subtract the current phase.
                  neg       phsa,perioda            '       Write adjusted phase to phsa.
    
    testb         test      inp,maskb wz            'Has pina changed?
            if_z  jmp       #fixprev                 '  No:  Update previous state.
    
                  rdlong    periodb,addrb           '  Yes: Read latest periods for ctrb.
                  test      prev,maskb wz           '       Was previous input a zero?
            if_nz shr       periodb,#16             '         Yes: Use high 16 bits of period.
                  and       periodb,_0xffff         '       Mask off period for other half cycle.
                  sub       periodb,phaseadj        '       Subtract the phase adjust constant.
                  sub       periodb,phsb            '       Subtract the current phase.
                  neg       phsb,periodb            '       Write adjusted phase to phsb.
    
    fixprev       xor       prev,inp                'Update previous pin state.
                  jmp       #mainlp                 'Back for more.
                  
    
                  
    
    prev          long      0                       'Previous pin states. Always starts out as low:low
    _0xffff       long      $ffff                   'Period mask.
    phaseadj      long      $8000_0000 + 6          'Phase adjustment added to phsa is $8000_0000 - period.
    
    acc           res       1                       'Scratch register.
    inp           res       1                       'Input anded with pin mask and XORed with previous input.
    maska         res       1                       'Mask for pina.
    maskb         res       1                       'Mask for pinb.
    addrb         res       1                       'Address of phaseb long in hub.
    perioda       res       1                       'Half period of ctra.
    periodb       res       1                       'Half period of ctrb.              
                  
    periods       long      PIN0, PIN1              'Initialized to pin numbers. Become periods when counters are ready.
                  long      PIN2, PIN3              'Low word is length of low half-period. High word is length of high half period.
                  long      PIN4, PIN5              'Half period length is value x system clock period.
                  long      PIN6, PIN7
    
    ''=======[ License ]===========================================================
    {{{
    &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
    &#9474;                            TERMS OF USE: MIT License                                 &#9474;                                                            
    &#9500;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9508;
    &#9474;Permission is hereby granted, free of charge, to any person obtaining a copy of this  &#9474;
    &#9474;software and associated documentation files (the "Software"), to deal in the Software &#9474;
    &#9474;without restriction, including without limitation the rights to use, copy, modify,    &#9474;
    &#9474;merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    &#9474;
    &#9474;permit persons to whom the Software is furnished to do so, subject to the following   &#9474;
    &#9474;conditions:                                                                           &#9474;
    &#9474;                                                                                      &#9474;
    &#9474;The above copyright notice and this permission notice shall be included in all copies &#9474;
    &#9474;or substantial portions of the Software.                                              &#9474;
    &#9474;                                                                                      &#9474;
    &#9474;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   &#9474;
    &#9474;INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         &#9474;
    &#9474;PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    &#9474;
    &#9474;HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  &#9474;
    &#9474;CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  &#9474;
    &#9474;OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         &#9474;
    &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
    }}
    

    It's not a proper object yet, but it could be made into one fairly easily.

    Enjoy!

    -Phil
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2012-03-11 00:08
    jmg wrote: »
    Yes, I use the Egyptian fractions, which are the same thing.

    I took a look at the wiki for Egyptian fractions, and at Wolfram, but it doesn't seem to me they are the same thing. It seems like Egyptian fractions covers a class of fractions that are written as reciprocals of integers, (1/integer), and questions revolve around how they can be added up to make other fractions in general. For example, the fractions 1/2, 1/4, 1/8, 1/16 ... would be such a class that can be added up in a general way. For arbitrary rational numbers are sums possible using a minimum number of terms. Which comes to,
    Taking the 10MHz values, we have a divide by 8 for 10Mhz and divide by 7.84313725833936821 for ~ 10.2MHz
    snip...The Egyptian fraction of this is
    1/2 + 1/3 + 1/102 + 1/290917621
    The 1/2 and 1/3 you can filter, but the 1/102 is ~ 98Khz so roughly every second cycle will differ.

    I see that those fractions add up to .8431372583393682, but how did you come up with those particular values? I agree that short cycles could be filtered and that those long cycles are out of reach of a practical filter or phase lock loop. It is the numerics that I question.

    The continued fraction is a sequence of divisions and remainders. Here is the development for that case of10.2MHz with clkfreq=80MHz and frqa:=547608330.
    frqa_547608330.png


    You see it is quite different numbers, but similar conclusion. The complete cycle is 2^31 cycles long, and repeats twice for one trip through phsa, because 547608330 has a factor of two that divides out. In this analysis, the pattern consists of levels of cycles that are included within levels of longer cycles. At the short end there is the alternating pattern 7878787878 as seen on the 'scope. The continued fraction suggests there is one cycle ~400 clocks long that repeats 111847 times. That is a 200kHz subharmonic.
    476 x 217 - 24K
Sign In or Register to comment.