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

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