PDA

View Full Version : new cogs will not launch



sciguy
05-13-2008, 09:30 PM
Hey there, I'm brand new to the propeller chip, and I have read through all of the documentation. I can't seem to get my chip to launch anything in a new cog.

Here is an except from my code:




VAR
long stack [30]

PUB main
DIRA[0..5]~
DIRA[16..21]~~

cognew( act(1,16), @stack)

PUB act(distance, outputPIN) | delay
delay := ((clkfreq / 1_000)*distance)

repeat 'inifinte loop
waitcnt(delay + cnt)
!OUTA [outputPIN]




When I do that, the act method does not run.

But if i simply use


act(1,16)

, it works fine.

Any suggestions.

hippy
05-13-2008, 09:40 PM
When you are setting DIRA you need to do that in the Cog which is going to alter the output. The DIRA in
PUB Main set P16 to P21 as outputs for that Cog, but the Cog invoked ( PUB Act ) will have its DIRA still
as all inputs.

Mike Green
05-13-2008, 09:41 PM
You're launching the 2nd cog, but you can't see what it's doing. Each cog has its own copy of DIRA and OUTA. You're enabling I/O pin #1 in one cog and using it in the 2nd cog where it's still configured as an input. At the beginning of "act", put a "DIRA[ outputPIN ]~~" and, in your "main" method, don't initialize DIRA for the pin # you pass to "act".

There is a section of the Propeller manual that shows how all the DIRA and OUTA registers are connected together to control the actual I/O circuitry.

sciguy
05-13-2008, 10:17 PM
ok, thanks alot. that will fix it.

sciguy
05-14-2008, 01:13 AM
Ok, now I've got a new question:

I'm trying to light up 5 different LEDs blinking at once, by using multiple cogs (I know I can do this serially, but I'm trying to learn). Only the first (green) LED is blinking, and the other's stay off.

MAIN FILE




CON

{{Output PINS}}
{{Output Pins must be consecutive}}
greenOUT =16 'Output PIN for Green Button
redOUT =17 'Output PIN for Red Button
yellowOUT =18 'Output PIN for Yellow Button
blueOUT =19 'Output PIN for Blue Button
orangeOUT =20 'Output PIN for Orange Button

DAT
green byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
red byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
yellow byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
blue byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
orange byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

VAR

long stack [20] 'Stack space for new cogs



OBJ

output : "check"

PUB main


coginit(1, output[0].act(1, greenOUT, green), @stack)
coginit(2, output.act(1, redOUT, red), @stack)
coginit(3, output.act(1, yellowOUT, yellow), @stack)
coginit(4, output.act(1, blueOUT, blue), @stack)
coginit(5, output.act(1, orangeOUT, orange), @stack)




check



CON

{{Output PINS}}
{{Output Pins must be consecutive}}
greenOUT =16 'Output PIN for Green Button
redOUT =17 'Output PIN for Red Button
yellowOUT =18 'Output PIN for Yellow Button
blueOUT =19 'Output PIN for Blue Button
orangeOUT =20 'Output PIN for Orange Button



PUB act(distance, outputPIN, color) | delay
delay := ((clkfreq / 1_000)*distance)

DIRA[greenOUT..orangeOUT]~~

repeat
waitcnt(delay + cnt)
color[0]++
if color[0]==800
color [0] := 0
!OUTA [outputPIN]

Mike Green
05-14-2008, 01:17 AM
1) You have to put a space after the opening subscript bracket or the forum software may "gobble" the index ("i" or a digit).

2) You cannot use the same stack for two cogs running at the same time. You have to have a stack space for each one.

3) Don't use "DIRA[greenOUT..orangeOUT]~~", use "DIRA[outputPIN]~~" as I suggested. In your case, the former will work, but it won't work as a general case. Only set the direction bits to output mode (1) for those I/O pins that you want to control from that specific cog.

Post Edited (Mike Green) : 5/13/2008 6:24:08 PM GMT

sciguy
05-14-2008, 01:39 AM
I made the changes you suggested, but only the first LED is still blinking:
(Thanks, by the way, you've been very helpful)

MAIN FILE




CON

{{Output PINS}}
{{Output Pins must be consecutive}}
greenOUT =16 'Output PIN for Green Button
redOUT =17 'Output PIN for Red Button
yellowOUT =18 'Output PIN for Yellow Button
blueOUT =19 'Output PIN for Blue Button
orangeOUT =20 'Output PIN for Orange Button

DAT
green byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
red byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
yellow byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
blue byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
orange byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

VAR

long stack1 [ 20] 'Stack space for cog1
long stack2 [ 20] 'Stack space for cog2
long stack3 [ 20] 'Stack space for cog3
long stack4 [ 20] 'Stack space for cog4
long stack5 [ 20] 'Stack space for cog5
long stack6 [ 20] 'Stack space for cog6
long stack7 [ 20] 'Stack space for cog7



OBJ

output[ 5] : "check"

PUB main


coginit(1, output[ 0].act(1, greenOUT, green), @stack1)
coginit(2, output[ 1].act(1, redOUT, red), @stack2)
coginit(3, output[ 2].act(1, yellowOUT, yellow), @stack3)
coginit(4, output[ 3].act(1, blueOUT, blue), @stack4)
coginit(5, output[ 4].act(1, orangeOUT, orange), @stack5)




check



CON

{{Output PINS}}
{{Output Pins must be consecutive}}
greenOUT =16 'Output PIN for Green Button
redOUT =17 'Output PIN for Red Button
yellowOUT =18 'Output PIN for Yellow Button
blueOUT =19 'Output PIN for Blue Button
orangeOUT =20 'Output PIN for Orange Button



PUB act(distance, outputPIN, color) | delay
delay := ((clkfreq / 1_000)*distance)

DIRA[ outputPIN]~~

repeat
waitcnt(delay + cnt)
color[ 0]++
if color[ 0]==800
color [ 0] := 0
!OUTA [ outputPIN]

sciguy
05-14-2008, 08:55 PM
Anybody have any ideas?

Mike Green
05-14-2008, 10:37 PM
1) I didn't notice originally that you're calling COGINIT from your main object, but giving the initial routine as a method in another object. Unfortunately this doesn't work and the compiler doesn't catch it. Convention is that the start routine is part of the object containing the actual routines that run in the other cog(s).

2) It's not a good idea to use COGINIT to start a new cog. You never know whether some other object is also using the same cog, even by mistake (because of a COGNEW). It's better to use COGNEW except where you absolutely know the cog number that you want to use.

3) Try something like:


OBJ output[6] : "check"
PUB main
repeat i from 0 to 5
output[ i ].start(firstPin+i,firstColor+i,1)
----------------
VAR long cog, stack[20]
PUB start(pin,color,distance)
cog := cognew(act(pin,color,distance),@stack) + 1 ' save cog# + 1 or zero if can't start
return cog > 0 ' return true if successful, false if fails
PUB stop
if cog > 0 ' stop the associated cog if it was started
cogstop(cog~ - 1) ' clear cog # to zero if it was non-zero

PRI act(pin,color,distance)
...

hippy
05-14-2008, 10:37 PM
sciguy said...
I made the changes you suggested, but only the first LED is still blinking


You've gone well beyond making just the changes suggested. You've jumped from a single Cog
invoked from the main program to multiple Cogs invoked in sub-objects.




coginit(5, output[ 4].act(1, orangeOUT, orange), @stack5)




If I recall right, it's not possible to launch a method in a new Cog that way, where the method
to run is in a sub-object.

You need to move the coginit into the object itself, so your coginits in the main program
would become something like ...




output[ 4].DoCogInit(5,1, orangeOUT, orange, @stack5)




And you'd need to add the DoCogInit mrthod to the object, something like ...




PUB DoCogInit( cogNum, distance, outputPIN, color, stackPtr )
coginit( cogNum, act(distance, outputPIN, color), stackPtr )




You would be better off using cognew rather than coginit and you'd probably
also benefit from moving the stack array into the object.

sciguy
05-14-2008, 11:32 PM
Thank you, it works now!

sciguy
05-16-2008, 02:22 AM
More questions now...

So I am trying to get things working with a circular buffer. Basically, I want information about when the lights should flash to be stored in an array, and pulled up a little while later, and be used to light an LED (basically just a delay). The lights seem to flash at intervals, but not as a result of my inputs.

CON
{INPUT PINS}
greenIN =0 'Input PIN for Green PhotoDiode
redIN =1 'Input PIN for Red PhotoDiode
yellowIN =2 'Input PIN for Yellow PhotoDiode
blueIN =3 'Input PIN for Blue PhotoDiode
orangeIN =4 'Input PIN for Orange PhotoDiode

{Output PINS}
greenOUT =16 'Output PIN for Green Button
redOUT =17 'Output PIN for Red Button
yellowOUT =18 'Output PIN for Yellow Button
blueOUT =19 'Output PIN for Blue Button
orangeOUT =20 'Output PIN for Orange Button
strumOUT =21 'Output PIN for Strum Bar

VAR
{THESE LENGTHS MUST EQUAL THE VALUE OF BUFFERLENGTH BELOW}
long green ]
long red[ 55]
long yellow[ 55]
long blue[ 55]
long orange[ 55]
long default[ 55]

PUB DoCogInit (cogNum, distance, inputPIN, outputPIN, stackPtr)

__coginit(cogNum, act(distance, inputPIN, outputPIN), stackPtr)

PUB act(distance, inputPIN, outputPIN) | delay, i, j, bufferLength, checkBack, color

{IMPORTANT}
bufferLength := (distance/10)+5

delay := (clkfreq / 100) 'sets the delay in clock cycles

checkBack:= distance/10 'sets checkBack location for color array

DIRA[ inputPIN]~ 'Sets inputPIN to input mode
DIRA[ outputPIN]~~ 'Sets outputPIN to output mode
color:=default
if inputPIN == greenIN
__color:=green
if inputPIN == redIN
__color:=red
if inputPIN == yellowIN
__color:=yellow
if inputPIN == blueIN
__color:=blue
if inputPIN == orangeIN
__color:=orange


i:=0 'Initializes i to 0 for repeat loop
j:=0 'Initializes j to 0 for repeat loop



repeat while i<bufferLength 'Repeat for the circular buffer
__if INA[ inputPIN] == 1 'if the pin is active...
____color[ i] := 1 'set value to 1 in array
__else
_____color[ i ] := 0
__if (i - checkBack) < 0 'if distance back loops...
_____j:=(i - checkBack) + (bufferLength - 1) 'loop the value to find j
__else 'else...
_____j:=i-checkBack 'otherwise, set j normally
__if color[ j] == 1 'if j was on...
_____OUTA[ outputPIN]~~ 'press the button
__color[ j] := 0
__i++ 'increment i
__if i==bufferLength 'if end of circular buffer is reached...
_____i:=0 'reset i to initial array value
__waitcnt(cnt+delay) 'waits necessary time
__OUTA[ outputPIN]~ 'releases button

Post Edited (sciguy) : 5/15/2008 7:27:24 PM GMT

Mike Green
05-16-2008, 03:09 AM
This is getting too long and too complicated to deal with as a conversation in a forum. Please
1) Simplify this to a single cog and a single pin as best you can so it still illustrates the problem
2) Document better what you're trying to do, preferably with comments in the source.
3) Attach the source file to your message or use the [ code ] [ /code ] tags to maintain formatting.
Keep in mind that some subscripts like some single letters and digits are gobbled by the forum software.
4) Your main method just initiates the second cog without doing anything further. In that case, you
don't really need to have a separate cog since the first cog terminates itself.

sciguy
05-16-2008, 08:17 PM
ok thanks for the suggestions. Sorry...I'm new to this.