RE: Launching New COG
schwiegjc
Posts: 41
When launching a new cog, the following code will blink the applicable LED. If the function call from the newcog includes other functions, then the process does not work. The connew functions indicates success, but the operation is not working. The BS2.Serin_Wait function works in the main program, but when embedded into a newcog function does not. The only difference is that the BEATStart function does not have any functions calls.
WORKS:
PUB BEATStart(led): Success
{{Start new blinking process in new cog; return True if successful.}}
Stop
Success := (Cog := cognew(Heartbeat(led), @Stack) + 1)
PUB Heartbeat(led)
dira[noparse][[/noparse]led] := out
outa[noparse][[/noparse]led] := off
repeat
outa[noparse][[/noparse]led] := on
waitcnt(clkfreq / 4 + cnt)
outa[noparse][[/noparse]led] := off
waitcnt(clkfreq / 6 + cnt)
outa[noparse][[/noparse]led] := on
waitcnt(clkfreq / 6 + cnt)
outa[noparse][[/noparse]led] := off
waitcnt(clkfreq + cnt)
Cog~ 'Clear Cog ID variable
DOES NOT WORK:
PUB MaretronStart(roll,rolldir,pitch,pitchdir): Success 'roll,rolldir,pitch, and pitchdir are address pointers to the main global variables.
'' Start COILREAD - starts a cog
'' returns false if no cog available
''
stop
Success := (Cog := cognew(Maretron(roll,rolldir,pitch,pitchdir),@Stack)+1)
PUB Maretron(roll,rolldir,pitch,pitchdir)
BS2_Start (30,31) '--- function in Object file
repeat
Serin_Wait(COMPASS_RX,@DataIn,"A",4800,1,8) ;--- function in Object file
repeat i from 0 to 49 step 1
if (DataIn=>"0" AND DataIn=<"9") OR DataIn=="." OR DataIn=="-"
if (DataIn=="-") AND (k==0)
Byte[noparse][[/noparse]rolldir] := 1
i++
elseif k==0
Byte[noparse][[/noparse]rolldir] := 0
elseif (DataIn=="-") AND (k==1)
Byte[noparse][[/noparse]pitchdir] := 1
i++
else
Byte[noparse][[/noparse]pitchdir] := 0
if (DataIn[noparse][[/noparse]i+1]==".") OR (DataIn[noparse][[/noparse]i+2]=<"9" AND DataIn[noparse][[/noparse]i+2]=>"0")
IntegerTemp := (DataIn-48)*10 + (DataIn[noparse][[/noparse]i+2]-48)
i := i+3
elseif (DataIn[noparse][[/noparse]i+2]==".") OR (DataIn[noparse][[/noparse]i+3]=<"9" AND DataIn[noparse][[/noparse]i+2]=>"0")
IntegerTemp := (DataIn-48)*100 + (DataIn[noparse][[/noparse]i+1]-48)*10 + (DataIn[noparse][[/noparse]i+3]-48)
i := i+4
if (k==0)
Long[noparse][[/noparse]roll] := IntegerTemp
k++
else
Long[noparse][[/noparse]pitch] := IntegerTemp
i := 50
PUB BS2_Start (Debug_rx, Debug_tx)
'' Initialize variables and pins for DEBUGIN and DEBUG
'' AND TIMING FOR MANY FUNCTION, typically:
'' BS2.Start(31,30)
Debug_Pin := Debug_tx ' DEBUG Tx Pin
DebugIn_Pin := Debug_rx ' DEBUG Rx Pin
dira[noparse][[/noparse]debug_Pin]~~
outa[noparse][[/noparse]debug_Pin]~~
dira[noparse][[/noparse]debugIn_Pin]~
s:= clkfreq ' Clock cycles for 1 s
ms:= clkfreq / 1_000 ' Clock cycles for 1 ms
us:= clkfreq / 1_000_000 ' Clock cycles for 1 us
Last_Freq := 0 ' Holds last setting for FREQOUT_SET
PUB PAUSE_uS(Duration) | clkCycles
{{
Causes a pause for the duration in uS
Smallest value is 20 at clkfreq = 80Mhz
Largest value is around 50 seconds at 80Mhz.
BS2.Pause_uS(1000) ' 1 mS pause
}}
clkCycles := Duration * uS #> cntMin ' duration * clk cycles for us
' - inst. time, min cntMin
waitcnt(clkcycles + cnt) ' wait until clk gets there
PUB SERIN_CHAR(pin, Baud, Mode, Bits) : ByteVal | x, BR
{{
Accepts asynchronous character (byte) on defined pin, at Baud, in Mode for #bits
Mode: 0 = Inverted - Normally low Constant: BS2#Inv
1 = Non-Inverted - Normally High Constant: BS2#NInv
x:= BS2.SERIN_Char(5,DEBUG_Baud,BS2#NInv,8)
BS2.Debug_Char(x)
BS2.Debug_DEC(x)
}}
BR := 1_000_000 / Baud ' Calculate bit rate
dira[noparse][[/noparse]PIN]~ ' Set as input
waitpeq(Mode << PIN, |< PIN, 0) ' Wait for idle
waitpne(Mode << PIN, |< PIN, 0) ' WAit for Start bit
pause_us(BR*100/90) ' Pause to be centered in 1st bit time
byteVal := ina[noparse][[/noparse]Pin] ' Read LSB
If Mode == 1
Repeat x from 1 to Bits-1 ' Number of bits - 1
pause_us(BR-70) ' Wait until center of next bit
ByteVal := ByteVal | (ina[noparse][[/noparse]Pin] << x) ' Read next bit, shift and store
else
Repeat x from 1 to Bits-1 ' Number of bits - 1
pause_us(BR-70) ' Wait until center of next bit
ByteVal := ByteVal | ((ina[noparse][[/noparse]Pin]^1)<< x) ' Read next bit, shift and store
PUB SERIN_WAIT (Pin,stringptr,char,Baud,Mode,Bits) | ptr,x
{{
Wait for the defined character, then
accepts a character string on defnined Pin at Baud for bits/char, up through a CR (13)
Maximum is 49 character, such as "abc, 123, you and me!"
Will cause cog-lockup while waiting without a cog-watchdog (see distributed example)
NOTE: There is NO buffer overflow protection.
VAR
Byte myString[noparse][[/noparse]50]
Repeat
BS2.Serin_Wait(5,@myString,"j",9600,1,8) ' Accept string passing pointer for variable,
wait for character j
BS2.Debug_Str(@myString) ' display string at pointer
BS2.Debug_Char(13) ' CR
BS2.Debug_Char(myString) ' show 6th character
}}
dira[noparse][[/noparse]pin]~ ' Set pin to input
ptr:=0
bytefill(@dataIn,0,49) ' Fill string memory with 0's (null)
repeat while dataIn[noparse][[/noparse]0] <> char ' accept character until wait character
dataIn[noparse][[/noparse]0] := SERIN_CHAR(Pin, Baud, Mode, Bits)
dataIn[noparse][[/noparse]0] := SERIN_CHAR(Pin, Baud, Mode, Bits) ' get 1st character
ptr++ ' increment pointer
repeat while DataIn[noparse][[/noparse]ptr-1] <> 13 ' repeat until CR was last
dataIn[noparse][[/noparse]ptr] := SERIN_CHAR(Pin, Baud, Mode, Bits) ' Store character in string
ptr++
dataIn[noparse][[/noparse]ptr]:=0 ' set last character to null
byteMove(stringptr,@datain,50) ' move into string pointer position
WORKS:
PUB BEATStart(led): Success
{{Start new blinking process in new cog; return True if successful.}}
Stop
Success := (Cog := cognew(Heartbeat(led), @Stack) + 1)
PUB Heartbeat(led)
dira[noparse][[/noparse]led] := out
outa[noparse][[/noparse]led] := off
repeat
outa[noparse][[/noparse]led] := on
waitcnt(clkfreq / 4 + cnt)
outa[noparse][[/noparse]led] := off
waitcnt(clkfreq / 6 + cnt)
outa[noparse][[/noparse]led] := on
waitcnt(clkfreq / 6 + cnt)
outa[noparse][[/noparse]led] := off
waitcnt(clkfreq + cnt)
Cog~ 'Clear Cog ID variable
DOES NOT WORK:
PUB MaretronStart(roll,rolldir,pitch,pitchdir): Success 'roll,rolldir,pitch, and pitchdir are address pointers to the main global variables.
'' Start COILREAD - starts a cog
'' returns false if no cog available
''
stop
Success := (Cog := cognew(Maretron(roll,rolldir,pitch,pitchdir),@Stack)+1)
PUB Maretron(roll,rolldir,pitch,pitchdir)
BS2_Start (30,31) '--- function in Object file
repeat
Serin_Wait(COMPASS_RX,@DataIn,"A",4800,1,8) ;--- function in Object file
repeat i from 0 to 49 step 1
if (DataIn=>"0" AND DataIn=<"9") OR DataIn=="." OR DataIn=="-"
if (DataIn=="-") AND (k==0)
Byte[noparse][[/noparse]rolldir] := 1
i++
elseif k==0
Byte[noparse][[/noparse]rolldir] := 0
elseif (DataIn=="-") AND (k==1)
Byte[noparse][[/noparse]pitchdir] := 1
i++
else
Byte[noparse][[/noparse]pitchdir] := 0
if (DataIn[noparse][[/noparse]i+1]==".") OR (DataIn[noparse][[/noparse]i+2]=<"9" AND DataIn[noparse][[/noparse]i+2]=>"0")
IntegerTemp := (DataIn-48)*10 + (DataIn[noparse][[/noparse]i+2]-48)
i := i+3
elseif (DataIn[noparse][[/noparse]i+2]==".") OR (DataIn[noparse][[/noparse]i+3]=<"9" AND DataIn[noparse][[/noparse]i+2]=>"0")
IntegerTemp := (DataIn-48)*100 + (DataIn[noparse][[/noparse]i+1]-48)*10 + (DataIn[noparse][[/noparse]i+3]-48)
i := i+4
if (k==0)
Long[noparse][[/noparse]roll] := IntegerTemp
k++
else
Long[noparse][[/noparse]pitch] := IntegerTemp
i := 50
PUB BS2_Start (Debug_rx, Debug_tx)
'' Initialize variables and pins for DEBUGIN and DEBUG
'' AND TIMING FOR MANY FUNCTION, typically:
'' BS2.Start(31,30)
Debug_Pin := Debug_tx ' DEBUG Tx Pin
DebugIn_Pin := Debug_rx ' DEBUG Rx Pin
dira[noparse][[/noparse]debug_Pin]~~
outa[noparse][[/noparse]debug_Pin]~~
dira[noparse][[/noparse]debugIn_Pin]~
s:= clkfreq ' Clock cycles for 1 s
ms:= clkfreq / 1_000 ' Clock cycles for 1 ms
us:= clkfreq / 1_000_000 ' Clock cycles for 1 us
Last_Freq := 0 ' Holds last setting for FREQOUT_SET
PUB PAUSE_uS(Duration) | clkCycles
{{
Causes a pause for the duration in uS
Smallest value is 20 at clkfreq = 80Mhz
Largest value is around 50 seconds at 80Mhz.
BS2.Pause_uS(1000) ' 1 mS pause
}}
clkCycles := Duration * uS #> cntMin ' duration * clk cycles for us
' - inst. time, min cntMin
waitcnt(clkcycles + cnt) ' wait until clk gets there
PUB SERIN_CHAR(pin, Baud, Mode, Bits) : ByteVal | x, BR
{{
Accepts asynchronous character (byte) on defined pin, at Baud, in Mode for #bits
Mode: 0 = Inverted - Normally low Constant: BS2#Inv
1 = Non-Inverted - Normally High Constant: BS2#NInv
x:= BS2.SERIN_Char(5,DEBUG_Baud,BS2#NInv,8)
BS2.Debug_Char(x)
BS2.Debug_DEC(x)
}}
BR := 1_000_000 / Baud ' Calculate bit rate
dira[noparse][[/noparse]PIN]~ ' Set as input
waitpeq(Mode << PIN, |< PIN, 0) ' Wait for idle
waitpne(Mode << PIN, |< PIN, 0) ' WAit for Start bit
pause_us(BR*100/90) ' Pause to be centered in 1st bit time
byteVal := ina[noparse][[/noparse]Pin] ' Read LSB
If Mode == 1
Repeat x from 1 to Bits-1 ' Number of bits - 1
pause_us(BR-70) ' Wait until center of next bit
ByteVal := ByteVal | (ina[noparse][[/noparse]Pin] << x) ' Read next bit, shift and store
else
Repeat x from 1 to Bits-1 ' Number of bits - 1
pause_us(BR-70) ' Wait until center of next bit
ByteVal := ByteVal | ((ina[noparse][[/noparse]Pin]^1)<< x) ' Read next bit, shift and store
PUB SERIN_WAIT (Pin,stringptr,char,Baud,Mode,Bits) | ptr,x
{{
Wait for the defined character, then
accepts a character string on defnined Pin at Baud for bits/char, up through a CR (13)
Maximum is 49 character, such as "abc, 123, you and me!"
Will cause cog-lockup while waiting without a cog-watchdog (see distributed example)
NOTE: There is NO buffer overflow protection.
VAR
Byte myString[noparse][[/noparse]50]
Repeat
BS2.Serin_Wait(5,@myString,"j",9600,1,8) ' Accept string passing pointer for variable,
wait for character j
BS2.Debug_Str(@myString) ' display string at pointer
BS2.Debug_Char(13) ' CR
BS2.Debug_Char(myString) ' show 6th character
}}
dira[noparse][[/noparse]pin]~ ' Set pin to input
ptr:=0
bytefill(@dataIn,0,49) ' Fill string memory with 0's (null)
repeat while dataIn[noparse][[/noparse]0] <> char ' accept character until wait character
dataIn[noparse][[/noparse]0] := SERIN_CHAR(Pin, Baud, Mode, Bits)
dataIn[noparse][[/noparse]0] := SERIN_CHAR(Pin, Baud, Mode, Bits) ' get 1st character
ptr++ ' increment pointer
repeat while DataIn[noparse][[/noparse]ptr-1] <> 13 ' repeat until CR was last
dataIn[noparse][[/noparse]ptr] := SERIN_CHAR(Pin, Baud, Mode, Bits) ' Store character in string
ptr++
dataIn[noparse][[/noparse]ptr]:=0 ' set last character to null
byteMove(stringptr,@datain,50) ' move into string pointer position
Comments
I made a quick crossreading of your code. From this I can't say what's the problem.
One part of this is that the indentions get lost
In this case I have my own kind and style how to analyze problems like this.
Therefore I need the complete sourcecode to run your program on my propeller
Could you please use the Post Reply-button which gives you a menu where you can format your code by clicking on the button "code" in a non-proportional font
that keeps the indention.
Or even better use the archive-function of the PropTool to archive your whole project and attach the ZIP-File
with the attachment-manager to a posting
As this forum is based as a kind of "freeware" I feel free to answer NOT to a posting if I think it's too much effort to get into it
In this case the effort would be to indent the codelines again.
For you it's a breeze to archive and attach the complete code.
best regards
Stefan
I inserted the code using the CODE button. The BS2.Serin_Wait function work in the main program, but not in this format. I am trying to read ascii formatted data stream and extract out four(4) data values and display it on a TV. The code works using the main. The problem is the data are transmitted at different rates, so the current code is only as fast as the slowest data value. If I could use an another cog to capture the data, then I could increase the data thorough put.
PUB MaretronStart(roll,rolldir,pitch,pitchdir): Success
'' Start COILREAD - starts a cog
'' returns false if no cog available
''
stop
Success := (Cog := cognew(Maretron(roll,rolldir,pitch,pitchdir),@Stack)+1)
PUB Stop
{{Stop toggling process, if any.}}
if Cog
cogstop(Cog~ - 1)
PUB Active: YesNo
{{Return TRUE if process is active, FALSE otherwise.}}
YesNo := Cog > 0
PUB Maretron(roll,rolldir,pitch,pitchdir)
BS2_Start (30,31)
repeat
Serin_Wait(COMPASS_RX,@DataIn,"A",4800,1,8)
repeat i from 0 to 49 step 1
if (DataIn=>"0" AND DataIn=<"9") OR DataIn=="." OR DataIn=="-"
if (DataIn=="-") AND (k==0)
Byte[noparse][[/noparse]rolldir] := 1
i++
elseif k==0
Byte[noparse][[/noparse]rolldir] := 0
elseif (DataIn=="-") AND (k==1)
Byte[noparse][[/noparse]pitchdir] := 1
i++
else
Byte[noparse][[/noparse]pitchdir] := 0
if (DataIn[noparse][[/noparse]i+1]==".") OR (DataIn[noparse][[/noparse]i+2]=<"9" AND DataIn[noparse][[/noparse]i+2]=>"0")
IntegerTemp := (DataIn-48)*10 + (DataIn[noparse][[/noparse]i+2]-48)
i := i+3
elseif (DataIn[noparse][[/noparse]i+2]==".") OR (DataIn[noparse][[/noparse]i+3]=<"9" AND DataIn[noparse][[/noparse]i+2]=>"0")
IntegerTemp := (DataIn-48)*100 + (DataIn[noparse][[/noparse]i+1]-48)*10 + (DataIn[noparse][[/noparse]i+3]-48)
i := i+4
if (k==0)
Long[noparse][[/noparse]roll] := IntegerTemp
k++
else
Long[noparse][[/noparse]pitch] := IntegerTemp
i := 50 [noparse][[/noparse]code]
PUB BS2_Start (Debug_rx, Debug_tx)
'' Initialize variables and pins for DEBUGIN and DEBUG
'' AND TIMING FOR MANY FUNCTION, typically:
'' BS2.Start(31,30)
Debug_Pin := Debug_tx ' DEBUG Tx Pin
DebugIn_Pin := Debug_rx ' DEBUG Rx Pin
dira[noparse][[/noparse]debug_Pin]~~
outa[noparse][[/noparse]debug_Pin]~~
dira[noparse][[/noparse]debugIn_Pin]~
s:= clkfreq ' Clock cycles for 1 s
ms:= clkfreq / 1_000 ' Clock cycles for 1 ms
us:= clkfreq / 1_000_000 ' Clock cycles for 1 us
Last_Freq := 0 ' Holds last setting for FREQOUT_SET
PUB PAUSE_uS(Duration) | clkCycles
{{
Causes a pause for the duration in uS
Smallest value is 20 at clkfreq = 80Mhz
Largest value is around 50 seconds at 80Mhz.
BS2.Pause_uS(1000) ' 1 mS pause
}}
clkCycles := Duration * uS #> cntMin ' duration * clk cycles for us
' - inst. time, min cntMin
waitcnt(clkcycles + cnt) ' wait until clk gets there
PUB SERIN_CHAR(pin, Baud, Mode, Bits) : ByteVal | x, BR
{{
Accepts asynchronous character (byte) on defined pin, at Baud, in Mode for #bits
Mode: 0 = Inverted - Normally low Constant: BS2#Inv
1 = Non-Inverted - Normally High Constant: BS2#NInv
x:= BS2.SERIN_Char(5,DEBUG_Baud,BS2#NInv,8)
BS2.Debug_Char(x)
BS2.Debug_DEC(x)
}}
BR := 1_000_000 / Baud ' Calculate bit rate
dira[noparse][[/noparse]PIN]~ ' Set as input
waitpeq(Mode << PIN, |< PIN, 0) ' Wait for idle
waitpne(Mode << PIN, |< PIN, 0) ' WAit for Start bit
pause_us(BR*100/90) ' Pause to be centered in 1st bit time
byteVal := ina[noparse][[/noparse]Pin] ' Read LSB
If Mode == 1
Repeat x from 1 to Bits-1 ' Number of bits - 1
pause_us(BR-70) ' Wait until center of next bit
ByteVal := ByteVal | (ina[noparse][[/noparse]Pin] << x) ' Read next bit, shift and store
else
Repeat x from 1 to Bits-1 ' Number of bits - 1
pause_us(BR-70) ' Wait until center of next bit
ByteVal := ByteVal | ((ina[noparse][[/noparse]Pin]^1)<< x) ' Read next bit, shift and store
PUB SERIN_WAIT (Pin,stringptr,char,Baud,Mode,Bits) | ptr,x
{{
Wait for the defined character, then
accepts a character string on defnined Pin at Baud for bits/char, up through a CR (13)
Maximum is 49 character, such as "abc, 123, you and me!"
Will cause cog-lockup while waiting without a cog-watchdog (see distributed example)
NOTE: There is NO buffer overflow protection.
VAR
Byte myString[noparse][[/noparse]50]
Repeat
BS2.Serin_Wait(5,@myString,"j",9600,1,8) ' Accept string passing pointer for variable,
wait for character j
BS2.Debug_Str(@myString) ' display string at pointer
BS2.Debug_Char(13) ' CR
BS2.Debug_Char(myString) ' show 6th character
}}
dira[noparse][[/noparse]pin]~ ' Set pin to input
ptr:=0
bytefill(@dataIn,0,49) ' Fill string memory with 0's (null)
repeat while dataIn[noparse][[/noparse]0] <> char ' accept character until wait character
dataIn[noparse][[/noparse]0] := SERIN_CHAR(Pin, Baud, Mode, Bits)
dataIn[noparse][[/noparse]0] := SERIN_CHAR(Pin, Baud, Mode, Bits) ' get 1st character
ptr++ ' increment pointer
repeat while DataIn[noparse][[/noparse]ptr-1] <> 13 ' repeat until CR was last
dataIn[noparse][[/noparse]ptr] := SERIN_CHAR(Pin, Baud, Mode, Bits) ' Store character in string
ptr++
dataIn[noparse][[/noparse]ptr]:=0 ' set last character to null
byteMove(stringptr,@datain,50) ' move into string pointer position
The last code does not look any better. Maybe it is because I do not have the SPIN application on my computer. I have already checked the proper space. Having embedded functions in the function called by the cognew should work?
from your code posted i cannot analyze what's going on
question:
- how big is the variable named stack ?
if stack is too small this MIGHT be a reason why it does not work
for beeing sure there is enough stackspace make it something like 200
long stack[noparse][[/noparse]200]
there are two methods to add code to postings in a way that it is readable
see PDF-attachment
instead of the BS2-library you can use Extended_FDSerial-object from the obex
to receive serial data.
other suggestions:
The Extended_FDSerial-object starts a cog with an assemblerdriver with a 15 byte-buffer for receieved data
It is possible to increase the buffersize if needed
If you describe the whole project it might be possible to find another solution
best regards
Stefan
Post Edited (StefanL38) : 10/17/2008 7:36:39 PM GMT