Shop OBEX P1 Docs P2 Docs Learn Events
Help with dira[ ] and outa[ ] — Parallax Forums

Help with dira[ ] and outa[ ]

mynet43mynet43 Posts: 644
edited 2007-10-08 00:54 in Propeller 1
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:

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

  • deSilvadeSilva Posts: 2,967
    edited 2007-10-07 14:18
    Yes that's how it is!

    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 smile.gif

    Post Edited (deSilva) : 10/7/2007 2:25:23 PM GMT
  • mynet43mynet43 Posts: 644
    edited 2007-10-07 14:49
    Very good! You're right as usualyeah.gif.

    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
  • Mike GreenMike Green Posts: 23,101
    edited 2007-10-07 14:54
    "If a COG sets OUTA to high - then there is no escape". - deSilva

    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.
  • mynet43mynet43 Posts: 644
    edited 2007-10-07 16:37
    Thanks Mike!

    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
  • Mike GreenMike Green Posts: 23,101
    edited 2007-10-07 17:37
    If the only purpose of the DIRA/OUTA in the main program is to initialize the I/O pin as soon as possible, the other cog initialization routine could do its DIRA/OUTA to make the pin a high output, then set a flag (flagVar := 1). The main cog would be periodically testing this flag and, if the flag is not zero, it would set its DIRA for the I/O pin to zero, then set the flag back to zero. When the second cog sees the flag become zero, it knows the main cog has freed up the I/O pin and it can continue on its way.
  • mynet43mynet43 Posts: 644
    edited 2007-10-08 00:54
    Mike,

    Hey! Great idea, as usual...

    I tried it and it worked the 1st time:

    Here's the code at the beginning of Main:

      dira[noparse][[/noparse]DF_CS]~~
      outa[noparse][[/noparse]DF_CS]~~                 ' set high to start
      CS_Ready := 0                 ' cleared to wait for DF cog to set CS line high
    
    



    Here's the code when the cog is loaded:

      cog := cognew(DF_Logging, @Stack2) 'Read logging cog
      waitcnt(clkfreq/4 + cnt) ' wait for cog to load
      
      repeat while CS_Ready == 0    ' wait for DF cog to take control of CS line
    
      outa[noparse][[/noparse]DF_CS]~                  ' turn off CS in this main cog
      dira[noparse][[/noparse]DF_CS]~                  ' release CS register to DF cog control
      CS_Ready := 0                 ' tell DF cog it's OK to continue, it has control
    
    



    Here's the code at the beginning of the cog that gets loaded:

      dira[noparse][[/noparse]DF_CS]~~                 ' take over CS control from main program
      outa[noparse][[/noparse]DF_CS]~~                 ' set high to start  
      CS_Ready++                    ' tell main program to release CS line
      repeat while CS_Ready         ' wait to hear back from it
    
    



    Thanks for the help!

    Jim
Sign In or Register to comment.