Shop OBEX P1 Docs P2 Docs Learn Events
Multiple Counters operating between 500kHz and 4MHz not syncronizing — Parallax Forums

Multiple Counters operating between 500kHz and 4MHz not syncronizing

Mag748Mag748 Posts: 266
edited 2013-01-10 08:29 in Propeller 1
Hello,

I have a program that runs launches 3 identical cogs that each simply control their counters based on the same global variables. I have been having an issue where the counters will not reliable start upon boot up. They work fine if I adjust the variables during runtime after initial boot up. The strange thing is that the boot up state that the counters end up in is not the same each time. For example, if I launch the 3 cogs into CogID 3, 4, and 5, I'll get a good signal coming from the counters on cog 2 only. But as soon as I move the switch (which changes the global variables) all cogs start working as expected. If someone could look over my code and see if there can spot any errors, that would be appreciated. It's not too long.

Thanks,

Word Clock Generator 1.3.13 - Archive [Date 2013.01.03 Time 15.38].zip

Comments

  • MagIO2MagIO2 Posts: 2,243
    edited 2013-01-03 15:59
    First quick thought:
    ctr := long[_ctr] |= Pin

    This looks like it could cause problems because you change the value of the variable that _ctr points to. Guess it should be enough to do a bitwise or instead of a or including assignment:
    ctr := Long[ _ctr ] | Pin

    ( This is my guess, did not test it by myself - that's your turn ;o)
  • Mark_TMark_T Posts: 1,981
    edited 2013-01-03 19:25
    Your run method repeatedly re-tests _start, so will repeatedly re-configure the counter, and in particular the second time
    through the loop it will do a waitcnt that cycles for 2^32 clocks as its already just been done... You either need to
    restructure the logic or add
           long [_start] := 0
    
    at the end of the counter-config code in run.
  • Mag748Mag748 Posts: 266
    edited 2013-01-04 10:04
    MagIO2 wrote: »
    First quick thought:
    ctr := long[_ctr] |= Pin

    This looks like it could cause problems because you change the value of the variable that _ctr points to. Guess it should be enough to do a bitwise or instead of a or including assignment:
    ctr := Long[ _ctr ] | Pin

    ( This is my guess, did not test it by myself - that's your turn ;o)

    MagIO2,

    Great catch! I see that that was definetley a mistake, and I believe that has solved the issue I was having, thanks alot!

    Mark_T wrote: »
    Your run method repeatedly re-tests _start, so will repeatedly re-configure the counter, and in particular the second time
    through the loop it will do a waitcnt that cycles for 2^32 clocks as its already just been done... You either need to
    restructure the logic or add
           long [_start] := 0
    
    at the end of the counter-config code in run.

    Mark_T,

    The way I believe this works is that the run method waits until the Main cog sets _start to 1, then almost imediately gets to the waitcnt and waits for the sync period. WHILE the run methods (in each cog) are waiting, the main cog resets _Start to 0, so after the counter cogs get through the waitcnt and return to the top of the repeat, Start is already reset. As you can see, the main cog does have the "long [_start] := 0" code in it.


    Here is another thing that I don't understand...The square wave created by cog 3 (the first counter control cog) does not see to be perfectly aligned to the square waves produced by cogs 4 and 5 as I would expect. See the images attached. The vertical positions have been offset so you can see the 2 different signals. Any idea as to why this could be?

    Cog 3&4 (Medium).jpg

    Here is the waveform produced by Cog 3&4 (Notice how they are offset slightly from one another)

    Cog 4&5 (Medium).jpg

    Here is the waveform produced by Cog 4&5 (Notice how they line up perfectly)


    Thanks again,
    Marcus
    1024 x 765 - 89K
    1024 x 765 - 87K
  • MagIO2MagIO2 Posts: 2,243
    edited 2013-01-04 11:45
    You run your code in SPIN, which means that each SPIN-COG will sooner or later be realligned to the HUB-access-window. Remember, each instruction is fetched from HUB-RAM as well.
    So, if you need the signals to be 100% alligned, you have to convert your CounterControl into PASM.

    1. copy the values of ALL variables from your HUB-RAM into COG-RAM
    2. do the wait
    3. set CTRA and FRQA
  • Mag748Mag748 Posts: 266
    edited 2013-01-07 07:35
    Hello again,

    I have attemped to write a PASM version of my counter controller, although it only seems to work for a few seconds. After I wait about 30 seconds or if I adjust the frequency too many times, it does not respond. Does somthing look wrong with my PASM code? I haven't changed the main cog Spin code, but that still works with my original Spin counter controller, so I don't think thats the issue.

    Thanks,
    Marcus

    CounterControl 1.4.13 - PASM.spin
  • AribaAriba Posts: 2,690
    edited 2013-01-07 10:08
    Mag748 wrote: »
    ...Does somthing look wrong with my PASM code?...

    Yes,
    jmp   run
    
    looks wrong, better would be:
    jmp   #run
    
    Andy
  • Mag748Mag748 Posts: 266
    edited 2013-01-07 11:17
    Yes!! Thanks Andy, now it all works great.

    This forum is awesome.

    Ok, one last thing that I don't understand. I have 3 counters running perfectly in sync with each other. This works for frequencies below 500kHz. But when I choose a frequency above 500k (when the counters switch to PLL mode) the waveform becomes distorted and they are no longer in sync. Any ideas why this could be? See images of the waveforms below.

    Thanks again,
    Marcus

    Good Sync below 500k (Medium).jpg

    When configuring with frequencies below 500kHz, the waveforms look great and are perfectly synchronized. (I only have 2ch on my scope but the 3rd waveform is good as well)

    Bad Sync above 500k (Medium).jpg

    But when selecting a frequency above 500kHz, the waveforms are distorted and not in sync. (The 3rd waveform is not in sync with either of these shown)
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2013-01-07 11:38
    The reason you have "distortion" is due to crosstalk among out-of-phase signals on your board or on the way to your scope. It's not an inherent characteristic of the PLL output.

    The reason the signals are out of phase in PLL mode is that the NCO frequency is first multiplied by 16 to feed to the phase detector. The resulting phase-locked x16 VCO frequency is then fed to the programmable divider, and any one of those x16 clock edges could be starting the divide counter from count zero.

    -Phil
  • Mag748Mag748 Posts: 266
    edited 2013-01-07 12:22
    The reason you have "distortion" is due to crosstalk among out-of-phase signals on your board or on the way to your scope. It's not an inherent characteristic of the PLL output.

    The reason the signals are out of phase in PLL mode is that the NCO frequency is first multiplied by 16 to feed to the phase detector. The resulting phase-locked x16 VCO frequency is then fed to the programmable divider, and any one of those x16 clock edges could be starting the divide counter from count zero.

    -Phil

    Thanks for the response Phil. The distortion is understandable, the signals coming from the board are in no way protected against crosstalk. As for the out-of-phaseness, is there any work around for this?

    Thanks,
    Marcus
  • kuronekokuroneko Posts: 3,623
    edited 2013-01-07 17:14
    Mag748 wrote: »
    But when selecting a frequency above 500kHz, the waveforms are distorted and not in sync. (The 3rd waveform is not in sync with either of these shown)
    That scope example looks like VCO/128, can you confirm? The thing is, for any divider up to 16 (/1, /2, /4, /8, /16) the PLL cycles will sync to the rising edge of the NCO feeding it. The remaining 3 (/32, /64, /128) can pick their NCO edge so to speak (up to 8 for /128) which means they may not be in sync. You could try avoiding those three dividers (depending on your setup/requirements) or explore other means of frequency generation.
  • Mag748Mag748 Posts: 266
    edited 2013-01-09 07:10
    kuroneko wrote: »
    That scope example looks like VCO/128, can you confirm? The thing is, for any divider up to 16 (/1, /2, /4, /8, /16) the PLL cycles will sync to the rising edge of the NCO feeding it. The remaining 3 (/32, /64, /128) can pick their NCO edge so to speak (up to 8 for /128) which means they may not be in sync. You could try avoiding those three dividers (depending on your setup/requirements) or explore other means of frequency generation.

    Dear kuroneko,

    The frequency of the signal in that image with the distorted square wave was at 576kHz. I believe this would confirm that the counter module was in VCO/128 mode. I will have to explore other means of frequency generation since it would seem that there is no way to generate a frequency between .5 and 4 MHz without using either /128, /64, or /32.

    Thanks,
    Marcus
  • kuronekokuroneko Posts: 3,623
    edited 2013-01-09 15:38
    Mag748 wrote: »
    ... no way to generate a frequency between .5 and 4 MHz without using either /128, /64, or /32.
    Why don't you stick with NCO mode all the way through (it goes up to clkfreq/2 as it is)?
  • Mag748Mag748 Posts: 266
    edited 2013-01-10 08:29
    kuroneko wrote: »
    Why don't you stick with NCO mode all the way through (it goes up to clkfreq/2 as it is)?

    kuroneko,

    This is a good suggestion.

    Thanks,
    Marcus
Sign In or Register to comment.