Deploying assembly code across multiple cogs - jm_freqin help
scocioba
Posts: 19
in Propeller 1
Hello Everyone,
This is my first post and it has to do with making the really lovely jm_freqin code work across multiple cogs. I am fairly new to the propeller system and am a biologist by training so please pardon my naivete in all this! So far, I tried just copying every single method and variable and labeled it incrementally from 1 through 6 representing the six signals I would like to read simultaneously. Every time I run the code for a single cog (original jm_freqin code), it works perfectly but when I set it up to initialize 6 cogs, I get zeros across the board as the signal value in hertz. I am using the Parallax Serial Terminal to output six independent values in one line separated by commas and a carriage return and new line so that every second a read of the six signal sources are printed as CSV values down the serial line. My question is: How does one deploy assembly code (specifically the jm_freqin code) properly across multiple cogs such that each cog runs the same method and outputs its own unique value at the same time as the other cogs. Below is the bastardization of the jm_freqin code I thought would "work" as reference. All I need is a way to read six signals at the same time and output their frequency values down the serial line. I am certain there is waaaay more elegant way to do this and any input would be much appreciated!
Assembly code repeating regions were removed so the code would fit the post. The serial demo side of the code is below:
This is my first post and it has to do with making the really lovely jm_freqin code work across multiple cogs. I am fairly new to the propeller system and am a biologist by training so please pardon my naivete in all this! So far, I tried just copying every single method and variable and labeled it incrementally from 1 through 6 representing the six signals I would like to read simultaneously. Every time I run the code for a single cog (original jm_freqin code), it works perfectly but when I set it up to initialize 6 cogs, I get zeros across the board as the signal value in hertz. I am using the Parallax Serial Terminal to output six independent values in one line separated by commas and a carriage return and new line so that every second a read of the six signal sources are printed as CSV values down the serial line. My question is: How does one deploy assembly code (specifically the jm_freqin code) properly across multiple cogs such that each cog runs the same method and outputs its own unique value at the same time as the other cogs. Below is the bastardization of the jm_freqin code I thought would "work" as reference. All I need is a way to read six signals at the same time and output their frequency values down the serial line. I am certain there is waaaay more elegant way to do this and any input would be much appreciated!
var long cog1 long cog2 long cog3 long cog4 long cog5 long cog6 long fcPin1 long fcPin2 long fcPin3 long fcPin4 long fcPin5 long fcPin6 long fcCycles1 long fcCycles2 long fcCycles3 long fcCycles4 long fcCycles5 long fcCycles6 pub init1(p) fcPin1 := p fcCycles1 := 0 cog1 := cognew(@frcntr1, @fcPin1) + 1 pub init2(p) fcPin2 := p fcCycles2 := 0 cog2 := cognew(@frcntr2, @fcPin2) + 1 pub init3(p) fcPin3 := p fcCycles3 := 0 cog3 := cognew(@frcntr3, @fcPin3) + 1 pub init4(p) fcPin4 := p fcCycles4 := 0 cog4 := cognew(@frcntr4, @fcPin4) + 1 pub init5(p) fcPin5 := p fcCycles5 := 0 cog5 := cognew(@frcntr5, @fcPin5) + 1 pub init6(p) fcPin6 := p fcCycles6 := 0 cog6 := cognew(@frcntr6, @fcPin6) + 1 pub period1 return fcCycles1 pub period2 return fcCycles2 pub period3 return fcCycles3 pub period4 return fcCycles4 pub period5 return fcCycles5 pub period6 return fcCycles6 pub freq1 | p1, f1 p1 := period1 f1 := clkfreq * 10 / p1 fcCycles1 := 0 return f1 pub freq2 | p2, f2 p2 := period2 f2 := clkfreq * 10 / p2 fcCycles2 := 0 return f2 pub freq3 | p3, f3 p3 := period3 f3 := clkfreq * 10 / p3 ' calculate frequency fcCycles3 := 0 ' clear for loss of input return f3 pub freq4 | p4, f4 p4 := period4 f4 := clkfreq * 10 / p4 ' calculate frequency fcCycles4 := 0 ' clear for loss of input return f4 pub freq5 | p5, f5 p5 := period5 f5 := clkfreq * 10 / p5 ' calculate frequency fcCycles5 := 0 ' clear for loss of input return f5 pub freq6 | p6, f6 p6 := period6 f6 := clkfreq * 10 / p6 ' calculate frequency fcCycles6 := 0 ' clear for loss of input return f6 dat org frcntr1 mov tmp11, par ' start of structure rdlong tmp12, tmp11 ' get pin# mov ctra, POS_DETECT1 ' ctra measures high phase add ctra, tmp12 mov frqa, #1 mov ctrb, NEG_DETECT1 ' ctrb measures low phase add ctrb, tmp12 mov frqb, #1 mov mask1, #1 ' create pin mask shl mask1, tmp12 andn dira, mask1 ' input in this cog add tmp11, #4 mov cyclepntr1, tmp11 ' save address of hub storage restart1 waitpne mask1, mask1 ' wait for 0 phase mov phsa, #0 ' clear high phase counter highphase1 waitpeq mask1, mask1 ' wait for pin == 1 mov phsb, #0 ' clear low phase counter lowphase1 waitpne mask1, mask1 ' wait for pin == 0 mov cycles1, phsa ' capture high phase cycles endcycle1 waitpeq mask1, mask1 ' let low phase finish add cycles1, phsb ' add low phase cycles wrlong cycles1, cyclepntr1 ' update hub jmp #restart1 ' -------------------------------------------------------------------------------------------------- POS_DETECT1 long %01000 << 26 NEG_DETECT1 long %01100 << 26 tmp11 res 1 tmp12 res 1 mask1 res 1 ' mask for frequency input pin cyclepntr1 res 1 ' hub address of cycle count cycles1 res 1 ' cycles in input period fit dat org 0 frcntr2 mov tmp21, par ' start of structure rdlong tmp22, tmp21 ' get pin# mov ctra, POS_DETECT2 ' ctra measures high phase add ctra, tmp22 mov frqa, #1 mov ctrb, NEG_DETECT2 ' ctrb measures low phase add ctrb, tmp22 mov frqb, #1 mov mask2, #1 ' create pin mask shl mask2, tmp22 andn dira, mask2 ' input in this cog add tmp21, #4 mov cyclepntr2, tmp21 ' save address of hub storage restart2 waitpne mask2, mask2 ' wait for 0 phase mov phsa, #0 ' clear high phase counter highphase2 waitpeq mask2, mask2 ' wait for pin == 1 mov phsb, #0 ' clear low phase counter lowphase2 waitpne mask2, mask2 ' wait for pin == 0 mov cycles2, phsa ' capture high phase cycles endcycle2 waitpeq mask2, mask2 ' let low phase finish add cycles2, phsb ' add low phase cycles wrlong cycles2, cyclepntr2 ' update hub jmp #restart2 ' -------------------------------------------------------------------------------------------------- POS_DETECT2 long %01000 << 26 NEG_DETECT2 long %01100 << 26 tmp21 res 1 tmp22 res 1 mask2 res 1 ' mask for frequency input pin cyclepntr2 res 1 ' hub address of cycle count cycles2 res 1 ' cycles in input period fit 492 dat
Assembly code repeating regions were removed so the code would fit the post. The serial demo side of the code is below:
con _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 obj fc : "jm_freqin" pst : "Parallax Serial Terminal" pub main EnablePST fc.init1(1) fc.init2(2) fc.init3(3) fc.init4(4) fc.init5(5) fc.init6(6) repeat pst.dec(fc.freq1) pst.char(",") pst.dec(fc.freq2) pst.char(",") pst.dec(fc.freq3) pst.char(",") pst.dec(fc.freq4) pst.char(",") pst.dec(fc.freq5) pst.char(",") pst.dec(fc.freq6) pst.NewLine pst.LineFeed waitcnt(clkfreq + cnt) PRI EnablePST pst.start(115200) pst.Home pst.Clear
Comments
obj fc[ 6 ] : "jm_freqin"
To initialize the six channels, each in its own cog, you'd do this (with i a local variable):
Obviously, if you need to use I/O pins other than 1-6, you'd have to change the above.
To display the results, you'd do something like:
Here's my version. It's pretty much the same as what Mike wrote.
One difference with Mike's code is the I/O pins used. Mike used pins 1 through 6, I used 0 through 5. As Mike points out, you'll need to modify the code to use different pins.
As you can see, I prefer to unroll objects of the same time so that I can name them -- it's more verbose, an I prefer to code this way.
What I want to point out is that I'm marking cog use. In your case you've got the main Spin cog and six frequency counters; you're down to one cog left for serial communications via Bluetooth - you're out of cogs.