Shop OBEX P1 Docs P2 Docs Learn Events
Changing selected outputs ? — Parallax Forums

Changing selected outputs ?

HarleyHarley Posts: 997
edited 2010-11-02 10:29 in Propeller 1
I want to change three selected output states (A24..A26). Some time back I was told the code below would alter the desired bits in the least time.
        xor     temp,OUTA     ' combine with desired pin states
        xor     OUTA,temp     ' set/clear for desired pin states
However, checking it w/ pencil and paper, it seems the output is not right (that is, all the remaining bits become zeros.) What am I doing wrong? Here is an example:
           OUTA  = 0...01_011_10...0
   xor     temp  = 0...00_101_00...0
           --------------------------------
           temp  = 0...01_110_10...0  1st result
   xor     OUTA  = 0...01_011_10...0
           --------------------------------
           OUTA  = 0...00_101_00...0  2nd result
This is what I get when I work it out on paper! I'm confused. When I first got the '2 xor's' suggestion, it was difficult to work it out, for some reason. Think I'm in that rut again.

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2010-10-31 22:05
    The XOR trick is used for swapping two values without using a 3rd temporary location. It needs 3 XORs (XOR a,b; XOR b,a; XOR a,b) as I recall.

    To change output states, you need 3 instructions and one constant:
    OR     OUTA,temp   ' new bits are in "temp".  Set desired ones
        XOR   temp,invertBits ' all one bits in desired positions
        ANDN OUTA,temp   ' now clear desired zeroes
    
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2010-10-31 22:22
    To do it without glitching, try this:
            mov     temp,outa
            andn    temp,bitmask 'Bitmask has ones in all the bit positions to be written.
            or      temp,newbits 'Newbits contains the new data in the positions to change, zeros elsewhere.
            mov     outa,temp
    

    Or, if the bits to change correspond exactly to the one bits in dira,
            mov     outa,newbits
    
    -Phil
  • HarleyHarley Posts: 997
    edited 2010-11-01 10:23
    I should have stated a bit more info. Those three bits or outputs (A24..A26) can only have the values of 3, 5, or 6 (011, 101 or 011) and not have any 2 or 3 Zeros nor all Ones. Only one bit Low at any time. And totally NOT disturb any other outputs.

    Mike G's scheme changes the Ones two instructions before Zeros are output; which would produce a 111 state. Phil's changes the three outputs of interest, however the change is 150-200 nsec, @ 80 MHz clock, after reading the output states. That might be a problem as other cogs could change an output during that time and it be clobbered.

    As it is, presently the cog's loop is taking too long to complete vs. the external cycle it has to deal with, so I need minimal instructions to implement the control over these three bits (affecting A24..A26). (Oooh!, would Prop 2 ever be helpful here.(
  • HarleyHarley Posts: 997
    edited 2010-11-01 13:07
    While in the shower, it seems only addition needed is to mask off all other bits after the first XOR:
            xor     temp,OUTA     ' combine with desired pin states
            and     temp,mask     '   only retain desired bits        ADDED CODE
            xor     OUTA,temp     ' set/clear for desired pin states
    
    So now the results would be:
               OUTA  = 0...01_011_10...0
       xor     temp  = 0...00_101_00...0
               --------------------------------
               temp  = 0...01_110_10...0  1st result
       and     temp  = 0...00_111_00...0      mask off all but the 3 bits of interest
               --------------------------------
               temp  = 0...00_110_00...0  2nd result
       xor     OUTA  = 0...01_011_10...0
               --------------------------------
               OUTA  = 0...01_101_10...0  3rd result
    
    This appears to solve this problem. Don't know how I talked myself into believing the original code was right. Seemed to work in PASD; but now wonder if I was also observing all the bits being outputted. Costs only one extra instruction, another 50 nsec. Don't know why I couldn't see this earlier.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2010-11-01 15:00
    Harley,

    Your latest solution is correct.
    That might be a problem as other cogs could change an output during that time and it be clobbered.
    It's only a problem if your cog's dira has bits set to one that those other cogs are outputting on. Otherwise, your cog will not alter those outputs, even if they change during your three-instruction mod of outa.

    -Phil
  • HarleyHarley Posts: 997
    edited 2010-11-02 10:29
    It's only a problem if your cog's dira has bits set to one that those other cogs are outputting on. Otherwise, your cog will not alter those outputs, even if they change during your three-instruction mod of outa.

    -Phil
    OK, I do not use this cog to control other outputs (well, except for one output for flagging a particular time when viewed in ViewPort; and no other cog uses that output). It is easy to forget how separate/isolated the cogs are at times. Looking at the schematic of the pcb, only two other outputs could have been affected by this Prop (I'm using two Props). But the DIRA doesn't include them. I didn't have time yet check out my 'and' addition; but it may not even be a problem now. No wonder I didn't see any affect, even though I think my original scheme wasn't proper, with only a couple of other outpus on this Prop. Sometime two wrongs make a right, a 'don't care' situation.
Sign In or Register to comment.