cogstop and port settings
rbehm
Posts: 102
in Propeller 1
What happens to port settings (DIRA and OUTA) when a cog gets stopped with cogstop? Will they get reset?
I could test this myself, of course, but perhaps somebody has already done this.
I have one cog running doing time critical I/O and another giving it instructions and watching that these get executed in time. If there is a problem talking to the attached device i just kill that cog and restart the task with cognew. Can it happen that the port setting of the stopped cog get stuck where they were at the time it got killed. cognew could select another cog and this would eventually be disturbed because the old cog has some port set to output and high.
If this is the case I will have to take care to start the same cog again.
I could test this myself, of course, but perhaps somebody has already done this.
I have one cog running doing time critical I/O and another giving it instructions and watching that these get executed in time. If there is a problem talking to the attached device i just kill that cog and restart the task with cognew. Can it happen that the port setting of the stopped cog get stuck where they were at the time it got killed. cognew could select another cog and this would eventually be disturbed because the old cog has some port set to output and high.
If this is the case I will have to take care to start the same cog again.
Comments
What Ive learned about the prop is never stop the cog that is doing:
DIRA, unless you don't care about those pins anymore.
If you need to work with those pins, don't control the dira with that cog only, do it with both the start cog and the one using it.
If you control the dira with a nonstop cog, then if you set outa and dira with a different cog , then stop it, that output remains in the static state you last set with the cog you stopped, because the direction output of that pin is still controlled by another cog.
When I stop cogs that control dira, my prop becomes Z, or an unkown pin out state, . In the microcontroller world, never expect the rest state of a cpu to be reliable in any way.
ALWAYS set the state of your pins, 24/7, and make sure a repeat looping cog controls the dira also all the time.
If you leave a cog running in a loop, it does continually use a little bit of power. This is usually an issue only if you're running off batteries and want to conserve as much power as possible. "hammers the ram" ... not really. Static RAM doesn't wear out like EEPROM might. It takes a little bit of power to read a RAM location ... again, only an issue if you're on battery power.
The I/O pins do behave the way the documentation describes. Each cog has its own copy of DIRA and OUTA and they're wired together in a chain of OR gates. When a cog is stopped for any reason, its control registers are cleared to zero. When a cog starts to execute code, DIRA and OUTA are zero. If one or more cogs set a DIRA bit to 1, that I/O pin becomes an output set to the state of that cog's OUTA bit (zero by default). If one or more cogs that have a DIRA bit set to 1 also have their OUTA bit to 1, that I/O pin gets set high.
I connected each output to a 1K/1K divider. This biased them to 1.6, so you could actually tell when they were not being driven.
The initial cog drives Pin1 from input to output low and then toggles (just like you would expect). It also drives pin2 low.
The RunOnce cog doesn't do anything because it never sets any ones into its DIRA.
The other two cogs produce a short pulse on their respective outputs which then become inputs when the cog stops.
There is no code that turns pin2 dira to 0 anywhere in the code at all.
So your saying the default dira of the cog that runs runonce needs to set the dira to use the io, ALSO? (its set in the start cog)
Wow, i thought the cog that launched from the start cog, can control any pins if the pins dira is already set in the start cog.
That is the intent. To show that dropping pin3, and no cog is controlling it, because the dira was set in zstateoutput, not in start.
Nor was the pin set to an input before exiting, and it probably should be.
Again, this is the intent. To show that turning an output to an input before turning the cog off is better than nothing.
Not saying it was more/less, just saying it uses power. Never said alot.
I never said anything about it "wearing out".
What this is talking about, is when loops run as fast as they can, they access the ram locations more often, this introduces delays when other cogs are also accessing those same memory locations,
why run loops at their max, when the variable you sample isn't expected to change that often? To catch it asap sure, but every thing has a limit to what is really needed.
from my own experience, i find that putting wait delays helps other programs access those memory locations with less lag or delay.
I find this when I make programs that use most of the cogs on a design, where the cogs all share the ram in the DAT section.
Some designs are similar to battery power in that they can pull power from limited sources.
It dosen't hurt to design optimally.
Isn't that what my program shows?
I wasn't saying anyone here was wrong.
My intent was to show that dir settings should probably be set in the START cog.
And it seems what I should have put is that dir settings should be in both locations.
The start cog and the cog you want to work with.
If I had known it was gonna get a visual rendering, I would have added wait counts, the scale on that scope is in seconds and the only output you can see on it is the watchdog loop, the other cogs run too fast for you to see.
And it seems what I should have said, and coded, initially, is dir settings should be in both locations.
The start cog and the cog you want to work with.
I will add it to the intitial code, making this the only change.
This was added to the RunOnce cog
The point being that the direction and output state of all pins used should really be controlled at all times in code (in the start cog) so you don't forget about the state of a pin.
Uhh, a bit harsh on saying it has little to do with the ops comment, its all about dir registers, launching cogs, stopping them, and I actually am the only brave soul here to post some code, risking public hanging, so i would like to take the time for saying your welcome for making the effort and time to produce some example code. (pats self on back)
Even if i did get it wrong. (a single line) Gosh, i think i would simply post the corrected code that someone was trying to do, instead of saying they offered no help, push it higher not lower?
Ive been hung so many times i like the noose, yours is kinda soft.
When a cog stops whether due to an explicit COGSTOP or simply running off the end of the method started by a COGINIT (or COGNEW), all control registers are zeroed including OUTA and DIRA. This effectively makes that cog disappear as far as the I/O circuitry is concerned. It is not necessary to explicitly set DIRA to zero.
One of the nice features of the Propeller and Spin is the use of objects to encapsulate functions and their behavior. It's usually not necessary for a program making use of a UART object to know whether the object makes use of a cog to perform its functions. The main program's initialization routine has to know which method to call to initialize the object and let the object know which I/O pin(s) to use. The main program normally would not explicitly affect the associated DIRA or OUTA bits and would leave them as zeroes.
-Phil
I am working with long sized variables, not sure if that changes the situation. Then I don't know why i see different behavior when I run a repeat loop with no delay versus a delay, the loop just checks a variable for a change.
I guess the reason behind it is different, but the problem was fixed by not letting a repeat loop run unlimited while checking a long sized variable for any change.
stating that one should set up IO in the start Cog is completely WRONG. Get this thought out of your brain.
Each COG needs to set up its DIRA and OUTA completely independent of a start COG or any other COG.
In the OPPOSITE you should AVOID setting the same pins in different COGs, except for some rare cases for sharing pins by say multiple COG video-driver.
Each COG has its OWN dira and outa, no other COG can change them.
From the software side each COG has his own pins and can set them to input or output and if output hi or low.
From the HW side all dira and outa are ORed together to finally drive the pin.
That means that if ONE or MORE COGS set a pin to output the physical pin is output for those COGS, but still input for all others. They will read the actual value, but are not able to change it.
Same goes for outa. If one (or more) COGS have set a pin to output, they can change the physical state, all other COGs can NOT change the physical state, just read it.
And if ONE (or more) COG having the pin as output, is setting it HIGH, then it is HIGH, else it stays low.
Usually you just use a pin by one COG so it does not matter, but if you use a pin as output from multiple COGS then it will be HIGH if one COG says so, else low.
Enjoy!
Mike
I got the idea that you were suggesting that terminated cogs somehow interfere with IO pins controlled by live cogs. Here is the first line of your first comment on this thread:
When I have used one of the cogs to declare dira and outa settings, once I stopped that cog, my i/o that I set in that cog became unusable by other cogs in the same way.
If I misunderstood your position, I apologize. Perhaps you could state your point differently.
I would be happy to fiddle your program to demonstrate that the Prop behaves exactly as described.
I don't think hijackin this thread is so great, i return the ball with the direction that someone might make a program to demonstrate some dir behavior, forget about my program if you like make a new.