Shop OBEX P1 Docs P2 Docs Learn Events
Propeller DEMO: SYNCing multiple COGs together...and...SYNCing multiple Propell — Parallax Forums

Propeller DEMO: SYNCing multiple COGs together...and...SYNCing multiple Propell

Beau SchwabeBeau Schwabe Posts: 6,547
edited 2008-01-23 03:53 in Propeller 1
The subject of SYNCing more than one COG together has come up from time to time, so as a building block to another application that I have been working on, I thought that I would release this bit of code that might be useful to·others.

Enjoy!!

CON
  _clkmode      = xtal1 + pll16x
  _xinfreq      = 5_000_000
{{
Important Note:
Deterministic timing and SYNC are lost after any HUB instruction(s) or conditional jumping, however if the
'TotalTightLoopClocks' or TTLC encompass the total number of clocks for that loop including HUB and conditional
branching requirements, then deterministic timing can be ReSYNCed from a derivative of the original cnt obtained
from the initial Spin Launch.
 
The assembly loops that need to be SYNCed/reSYNCed should have any timing critical code at the beginning of
the loop structure, while any HUB or conditional branching needs to happen afterwards.  That's not to say that
a secondary waitcount can happen to re-SYNC the cogs before the loop starts over, but the order in which things
happen is important.
 
...And also very important... the TTLC value for each COG that needs to be SYNCed needs to be the same value or
the sum of multiple waitcount values need to add up to the same TTLC value.

Example Code Structure:
:Loop
          waitcount here
          Deterministic timing here
          HUB operations and/or conditional jumps here
.
.
.          
          [noparse][[/noparse]waitcount here]                                    '<- Optional
          [noparse][[/noparse]Deterministic timing here]                         '<- Optional
          [noparse][[/noparse]HUB operations and/or conditional jumps here]      '<- Optional
.
.
.          
          [noparse][[/noparse]waitcount here]                                    '<- Optional
          [noparse][[/noparse]Deterministic timing here]                         '<- Optional
          [noparse][[/noparse]HUB operations and/or conditional jumps here]      '<- Optional
 
          jmp to :Loop here
 
 
Test Circuit:
 
           330 Ohms
Pin[noparse][[/noparse]0] &#61609;&#9472;&#9472;&#9472;&#9472;&#9472;&#61629;&#61630;&#9472;&#9472;&#9488;
                 &#9507;&#9472;&#9472;&#9472;&#9472;&#9472;&#61627; To Scope
Pin[noparse][[/noparse]1] &#61609;&#9472;&#9472;&#9472;&#9472;&#9472;&#61629;&#61630;&#9472;&#9472;&#9496;
           330 Ohms
 
What to expect from the circuit above:
Both COG's in SYNC, the wave form should look like this...
      &#9472;&#9488; &#9484;&#9472;&#9488; &#9484;&#9472;&#9488; &#9484;&#9472;&#9488; &#9484;&#9472;&#9488; &#9484;&#9472;&#9488; &#9484;&#9472;&#9488; &#9484;
       &#9474; &#9474; &#9474; &#9474; &#9474; &#9474; &#9474; &#9474; &#9474; &#9474; &#9474; &#9474; &#9474; &#9474;
       &#9492;&#9472;&#9496; &#9492;&#9472;&#9496; &#9492;&#9472;&#9496; &#9492;&#9472;&#9496; &#9492;&#9472;&#9496; &#9492;&#9472;&#9496; &#9492;&#9472;&#9496;
       
Both COG's in SYNC, one COG 90 out of phase with the other...
      &#9488;  &#9484;&#9488;  &#9484;&#9488;  &#9484;&#9488;  &#9484;&#9488;  &#9484;&#9488;  &#9484;&#9488;  &#9484;
      &#9492;&#9488;&#9484;&#9496;&#9492;&#9488;&#9484;&#9496;&#9492;&#9488;&#9484;&#9496;&#9492;&#9488;&#9484;&#9496;&#9492;&#9488;&#9484;&#9496;&#9492;&#9488;&#9484;&#9496;&#9492;&#9488;&#9484;&#9496;
       &#9492;&#9496;  &#9492;&#9496;  &#9492;&#9496;  &#9492;&#9496;  &#9492;&#9496;  &#9492;&#9496;  &#9492;&#9496;
        
Both COG's in SYNC, one COG 180 out of phase with the other...
 
      &#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;

}}
TotalTightLoopClocks = 102      '<- This should be an even number for proper alignment
  _0Deg = 0
 _90Deg = TotalTightLoopClocks / 2                     
_180Deg = TotalTightLoopClocks  
SyncOffset = _90Deg
VAR
    long Sync1
    long Pin0
    long Sync2
    long Pin1
PUB Launch
    Sync1 := 30_000 + cnt                               'project future cnt event for Sync1 .... 10_337 minimum value
                                                        'Note: if cnt rolls over, this is ok... it will rollover in the offset as well maintaining
                                                        'an absolute reference.
    Sync2 := Sync1 + SyncOffset                         'Adjust Sync2 so that it is a product of Sync1 plus a specific offset value                          
    Pin0 := 0                                           '<- Can be anything from 0 to 31
    Pin1 := 1                                           '<- Can be anything from 0 to 31
    cognew(@COG_Sync,@Sync1)                            'Start an instance of COG_Sync
    coginit(0,@COG_Sync,@Sync2)                         'Restart COG0 (this COG) with another instance of COG_Sync  
                                                        'At this point no Spin is running, both COG's 
                                                        'synced together running in their own instance of COG_Sync
DAT
'############################################################################################
'############################################################################################
COG_Sync      org       0
              mov       :Temp1, par             'Get Sync Value
              rdlong    :Sync,  :Temp1
              add       :Temp1, #4              'Get Pin Value
              rdlong    :Pin,   :Temp1
              mov       :Temp1, #1              'Create PinMask
              shl       :Temp1, :Pin
              mov       :Pin,   :Temp1
              mov       dira,   :Pin            'make Selected Pin an output
'############################################################################################
'                              Deterministic timing SYNC/ReSYNCed Here 
'############################################################################################
:Loop         waitcnt   :Sync,  :TTLC           '(   5+ - Clocks)       'wait for the count
              xor       outa,   :Pin            '(   4  - Clocks)
'############################################################################################
'   Deterministic timing and SYNC lost after any HUB instruction(s) or conditional jumping
'############################################################################################
              rdlong    :Temp1, :Temp1          '( 7-22 - Clocks)       'Test JUNK HUB operation
              rdlong    :Temp1, :Temp1          '( 7-22 - Clocks)       'Test JUNK HUB operation              
              rdlong    :Temp1, :Temp1          '( 7-22 - Clocks)       'Test JUNK HUB operation
              rdlong    :Temp1, :Temp1          '( 7-22 - Clocks)       'Test JUNK HUB operation
              rdlong    :Temp1, :Temp1          '( 7-22 - Clocks)       'Test JUNK HUB operation
              jmp       #:Loop                  '(    4 - Clocks)
:Temp1        long      0
:TTLC         long      TotalTightLoopClocks
:Sync         long      0
:Pin          long      0

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe

IC Layout Engineer
Parallax, Inc.

Post Edited (Beau Schwabe (Parallax)) : 11/22/2007 5:25:28 AM GMT

Comments

  • mynet43mynet43 Posts: 644
    edited 2007-11-15 14:44
    Beau,

    Thanks for the great code. I think I'll be able to use it to sync double buffered audio output to a TI codec I'm working with.

    Keep up the good work!

    Jim
  • rjo_rjo_ Posts: 1,825
    edited 2007-11-15 16:22
    Like manna from heaven...

    Two problems.

    1. I gave my scope to a guy who actually needed one. So, now I would need another circuit so that I can use a second Prop to monitor the sync.
    We are getting into the holiday season, so please don't think about this until next year. I have enough on my plate already[noparse]:)[/noparse]

    and B.

    Let's say the second cog is on a second Propeller...same external oscillator ( I actually do have a pregnant application for this and it looks like a lot of other guys are getting close to needing it as well).

    Rich
  • Beau SchwabeBeau Schwabe Posts: 6,547
    edited 2007-11-15 19:39
    Rich,

    1) Sorry about your scope... It's mainly just to visually confirm that you have SYNCed, and the method that I used to check that I had SYNC.

    2) or B)smilewinkgrin.gif··

    The method that I provided won't work for Propellers that are external to each other, since it uses the cnt which even though both of the Propellers will be operating off of the same·external oscillator, the internal cnt values will most likely not be the same value.· What you could do·though is·dedicate an I/O pin so that one Propeller is an OUTPUT·"master", and the other Propeller is an INPUT "slave".· By making use of·the·waitpeq·and/or the waitpne instructions in combination with the waitcnt instructions you could SYNC multiple COGs from multiple Propellers in a similar fashion.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.
  • Beau SchwabeBeau Schwabe Posts: 6,547
    edited 2007-11-22 05:14
    Here is a follow-up on my original post.... A method to SYNC more than one Propeller·together.

    The Idea is that you would have a Master Propeller and a Slave Propeller.· Each would have their own 5MHz crystal, but you "throttle" the slave Propeller's clock input (XI) with the master Propeller's clock·output (XO).· This basically forces the slave Propeller(s)·to track the clock of the master Propeller.· Alternatively you could use an external oscillator driving both the master and the slave Propeller(s).

    In order for this to work, the Slave Propeller·needs to be up and running first, or at least in the program section that waits for a pulse from the Master Propeller.· Once the Slave is there, waiting for a pulse, the Master can then come up and begin to run, or start the SYNC sequence.·

    I am still in the early stages of this, but I envision a Slave Propeller awaiting·the SYNC sequence from the Master·Propeller, and then performing a·high-speed (<--at roughly 2.5M·BYTES per second) data packet dump from the Master Propeller to the Slave Propeller, or vise versa, from which the Slave will return to the·"wait mode"·to receive·additional data packets.

    Note:
    Results displayed are with the attached circuit and programs.·
    Propellers were approximately 1 foot away from one another... no special shielding on the wire (piece of 1 Foot 4-conductor Solid telephone wire)


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.

    Post Edited (Beau Schwabe (Parallax)) : 11/22/2007 8:21:46 AM GMT
  • Beau SchwabeBeau Schwabe Posts: 6,547
    edited 2007-11-22 05:18
    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.
    1271 x 709 - 101K
    900 x 600 - 110K
    900 x 600 - 161K
    900 x 600 - 160K
    900 x 600 - 165K
  • R BaggettR Baggett Posts: 124
    edited 2007-11-23 23:16
    In the cog sync code...

    TotalTightLoopClocks should be an even number because:

    1. it makes the 90 degree division (/2) come out even?

    2. Some other magic (to me) reason?
  • Beau SchwabeBeau Schwabe Posts: 6,547
    edited 2007-11-24 04:38
    R Baggett,

    Yes, that is correct "it makes the 90 degree division (/2) come out even"

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.
  • Sleazy - GSleazy - G Posts: 79
    edited 2008-01-20 12:23
    So is this PROP II?· The fabled numbers match the expected·numbers when using 2 props with a high speed dump from one to another. It seems that using 2 props like this should explain why The hub cycles·in prop·II are fabled to·be equivalent·timing of·cog cycles of prop I.

    I had a post about syncing 2 props with each in half step using a differential complementary oscillator and sharing output pins.
    http://forums.parallax.com/showthread.php?p=698042
    ·Paul Baker thinks that it should work.·You·should know this already, since you work with him right?



    Post Edited (Sleazy - G) : 1/20/2008 12:30:53 PM GMT
  • Beau SchwabeBeau Schwabe Posts: 6,547
    edited 2008-01-20 15:23
    Sleazy - G,

    The example that I gave uses two Prop I's... the timing difference between the two Props is actually half stepped with regard to the 5MHz clock. Which should produce a 100nS difference.
    Since each·Propeller multiplies·the frequency up by a factor of 16 through the PLL, making it 80MHz, each clock tick is 12.5nS. If each instruction requires approximately 4 clock ticks, then that's 50nS per instruction.· Because this (50nS per instruction) is a multiple of the 100nS offset difference, the two Propellers don't have much of a problem syncing. The differences that you see here...

    http://forums.parallax.com/attachment.php?attachmentid=50592

    ...where it should read a flat line, I believe can be contributed to propagation delays in drive strength between PMOS and NMOS transistors and also wire length/capacitive load effects.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.

    Post Edited (Beau Schwabe (Parallax)) : 1/21/2008 6:24:08 AM GMT
  • Sleazy - GSleazy - G Posts: 79
    edited 2008-01-23 00:45
    Wow, that sync is totally tight, judging·from the oscilloscope pic you linked.

    So I wonder how many props you could sync together with multiphase ·multi-oscillators?
    Could you get 3 props to work in a 3-phase setup? or more?

    Where does the limit top out?
  • Sleazy - GSleazy - G Posts: 79
    edited 2008-01-23 00:57
    Its totally great that 2 synced props in 4 clocks can do 1 instruction a piece per cog per 5mhz crystal cycle. You dont even have to sweat a thing!

    Did you guys expect this to happen? it works out quite evenly. Brilliant.
  • Beau SchwabeBeau Schwabe Posts: 6,547
    edited 2008-01-23 03:53
    Sleazy - G,

    That PIC is from the post in this thread from me on 11/21/2007 using this schematic... http://forums.parallax.com/forums/attach.aspx?a=18449

    The GND connections between props are shared and two NOP's are added in the "master" program just before the Loop, so that the output of the "master"
    is 180 deg out of phase from the output of the "slave". Ideally, the signal to the scope should cancel out and a flat line at 1/2 Vdd should be observed, but
    as stated, there are slight differences that prevent this.

    "Did you guys expect this to happen? it works out quite evenly. Brilliant."

    I had been working on a communication scheme between Props, that used Phase discrimination similar to digital QPSK. It was during the testing and writing
    of that code, that I made the observation pointed out here. So in a serendipitous way, you could say it was expected to happen.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.

    Post Edited (Beau Schwabe (Parallax)) : 1/23/2008 3:59:39 AM GMT
Sign In or Register to comment.