Help with dira[ ] and outa[ ]
mynet43
Posts: 644
I'm having a problem using the dira[noparse][[/noparse] ] and outa[noparse][[/noparse] ] registers.
I wrote a simple program to show the problem I'm having. There are three cases shown, with an attached picture to go with each.
Here's the first code sample, this is the way I would like it to work:
If you look at the first picture called "Cog with Both Inits", you'll see that the CS line goes high but never gets toggled.
Here's the second set of code. Notice that I changed ONLY the cognew( ) call to a subroutine call, to keep everything in the same cog. That's all I changed and now it works perfectly. See the second picture called "Subroutine Call".
OK, so here's the final set of code. In this case, I eliminated the dira[noparse][[/noparse] ] and the outa[noparse][[/noparse] ] from the Main routine and left the cognew( ) in, instead of the subroutine call. Again, this worked perfectly. See the attachment called "Cog with One Init".
So there's the problem. The dira[noparse][[/noparse] ] and outa[noparse][[/noparse] ] references are supposed to act like wired OR's. So that setting them in the main program and setting them again in the second cog should result in them still being set. It's almost as if the second time dira[noparse][[/noparse]CS]~~ is executed (in another cog), that it's treated as an exclusive OR and turns the bit off. This would cause the behavior seen in the pics.
I'm probably doing something wrong here, so please help me out[noparse]:)[/noparse]
Thanks,
Jim
I wrote a simple program to show the problem I'm having. There are three cases shown, with an attached picture to go with each.
Here's the first code sample, this is the way I would like it to work:
CON _CLKMODE = XTAL1 + PLL16X _XINFREQ = 5_000_000 CS = 1 ' Chip Select Pin = P1 VAR long cog long Stack[noparse][[/noparse]150] PUB Main dira[noparse][[/noparse]CS]~~ ' set CS Pin to Output outa[noparse][[/noparse]CS]~~ ' set CS high to disable chip ' ToggleCS ' call as a subroutine to test outa[noparse][[/noparse]CS]... cog := cognew(ToggleCS, @Stack) 'Read logging cog waitcnt(clkfreq/4 + cnt) ' wait for cog to start repeat PUB ToggleCS | n dira[noparse][[/noparse]CS]~~ ' set CS Pin to Output outa[noparse][[/noparse]CS]~~ ' set CS high to disable chip n := 0 repeat if n == 0 outa[noparse][[/noparse]CS]~ else outa[noparse][[/noparse]CS]~~ n := 1 - n ' toggle n between 0 and 1
If you look at the first picture called "Cog with Both Inits", you'll see that the CS line goes high but never gets toggled.
Here's the second set of code. Notice that I changed ONLY the cognew( ) call to a subroutine call, to keep everything in the same cog. That's all I changed and now it works perfectly. See the second picture called "Subroutine Call".
PUB Main dira[noparse][[/noparse]CS]~~ ' set CS Pin to Output outa[noparse][[/noparse]CS]~~ ' set CS high to disable chip ToggleCS ' call as a subroutine to test outa[noparse][[/noparse]CS]... ' cog := cognew(ToggleCS, @Stack) 'Read logging cog ' waitcnt(clkfreq/4 + cnt) ' wait for cog to start repeat
OK, so here's the final set of code. In this case, I eliminated the dira[noparse][[/noparse] ] and the outa[noparse][[/noparse] ] from the Main routine and left the cognew( ) in, instead of the subroutine call. Again, this worked perfectly. See the attachment called "Cog with One Init".
PUB Main ' dira[noparse][[/noparse]CS]~~ ' set CS Pin to Output ' outa[noparse][[/noparse]CS]~~ ' set CS high to disable chip ' ToggleCS ' call as a subroutine to test outa[noparse][[/noparse]CS]... cog := cognew(ToggleCS, @Stack) 'Read logging cog waitcnt(clkfreq/4 + cnt) ' wait for cog to start repeat
So there's the problem. The dira[noparse][[/noparse] ] and outa[noparse][[/noparse] ] references are supposed to act like wired OR's. So that setting them in the main program and setting them again in the second cog should result in them still being set. It's almost as if the second time dira[noparse][[/noparse]CS]~~ is executed (in another cog), that it's treated as an exclusive OR and turns the bit off. This would cause the behavior seen in the pics.
I'm probably doing something wrong here, so please help me out[noparse]:)[/noparse]
Thanks,
Jim
Comments
The rules are simple and can be found on page 26 of the Manual, and can be checked by thorougly looking at the ANDs and ORs in the architecture diagram of the Propeller.
If a COG sets OUTA to high - then there is no escape
Post Edited (deSilva) : 10/7/2007 2:25:23 PM GMT
That's too bad. I was hoping to turn the chip off as the very first thing, and then toggle it when I needed it in the other cog.
Oh well, the best laid plans...
Thanks
Jim
It is a logical OR. If any cog sets the pin to output high, then the pin will be output high regardless of what any other cog does. There are many ways to coordinate the use of a pin among several cogs so that they share control of it, yet can ensure that the pin remains high unless some cog explicitly drives it low (if that's what you want to do), but they all take active coordination ... the programs in each cog that uses the pin have to talk to each other ... it's not automatic. If you want it to be automatic, you'll have to invert the pin with hardware or use a pull-up (a better solution) and only the cog actually using the pin would set it to output mode.
Yes, the pull-up is the best answer. Unfortunately, in this case it's a tight squeeze on an existing board... Maybe[noparse]:)[/noparse]
The next rev will have a pull-up, then it works with a little coordination between the cogs.
Jim
Hey! Great idea, as usual...
I tried it and it worked the 1st time:
Here's the code at the beginning of Main:
Here's the code when the cog is loaded:
Here's the code at the beginning of the cog that gets loaded:
Thanks for the help!
Jim