Propeller DEMO: SYNCing multiple COGs together...and...SYNCing multiple Propell
Beau Schwabe
Posts: 6,568
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!!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.
Post Edited (Beau Schwabe (Parallax)) : 11/22/2007 5:25:28 AM GMT
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] ───────┐ ┣───── To Scope Pin[noparse][[/noparse]1] ───────┘ 330 Ohms What to expect from the circuit above: Both COG's in SYNC, the wave form should look like this... ─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌─┐ ┌ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘ └─┘ Both COG's in SYNC, one COG 90 out of phase with the other... ┐ ┌┐ ┌┐ ┌┐ ┌┐ ┌┐ ┌┐ ┌ └┐┌┘└┐┌┘└┐┌┘└┐┌┘└┐┌┘└┐┌┘└┐┌┘ └┘ └┘ └┘ └┘ └┘ └┘ └┘ Both COG's in SYNC, one COG 180 out of phase with the other... ──────────────────────────── }} 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
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
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
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 ··
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.
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 Schwabe
IC Layout Engineer
Parallax, Inc.
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?
Yes, that is correct "it makes the 90 degree division (/2) come out even"
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.
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
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
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?
Did you guys expect this to happen? it works out quite evenly. Brilliant.
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