Shop OBEX P1 Docs P2 Docs Learn Events
Read-modify-write on PHSx -- not supposed to work, but does. — Parallax Forums

Read-modify-write on PHSx -- not supposed to work, but does.

Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
edited 2008-08-13 17:45 in Propeller 1
According to the datasheet, phsa and phsb cannot be used as destinations of a read-modify-write instruction:
The datasheet (bottom of page 15) said...
Note 2 [noparse][[/noparse]for PHSA and PHSB]: Only readable as a Source Register (i.e. MOV Dest, Source); read-modify-write not possible as a Destination Register.
I had forgotten this caveat and wrote the following code to generate two waveforms in quadrature with each other:

              org       0
quadrature    mov       dira,dira0
              mov       ctra,ctra0
              mov       ctrb,ctrb0
              
:query        rdlong    freq,frq
              cmp       freq,frqa wz
        if_z  jmp       #:query

              mov       frqa,#0
              mov       frqb,#0
              mov       phsa,#0
              mov       phsb,_4000_0000
              [b]add[/b]       [b]phsb,freq[/b]
              [b]add[/b]       [b]phsb,freq[/b]
              [b]add[/b]       [b]phsb,freq[/b]
              [b]add[/b]       [b]phsb,freq[/b]
              mov       frqa,freq
              mov       frqb,freq
              jmp       #:query

frq           long      0-0
ctra0         long      %00100 << 26 | if_pin
ctrb0         long      %00100 << 26 | qf_pin
dira0         long      1 << if_pin | 1 << qf_pin
_4000_0000    long      $4000_0000




The four adds are there to make up for the four clocks that phsb misses between frqa being loaded and frqb being loaded. But these adds are read-modify-write instructions with phsb as the destination; therefore they should not work. The conundrum is that they do work. The correction takes place and I always get two waveforms in perfect quadrature, regardless of the frequency.

Why? Is this something I can depend on? What exactly are the circumstances where this will not work and which led to the note in the datasheet?

Thanks,
-Phil

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
'Still some PropSTICK Kit bare PCBs left!

Post Edited (Phil Pilgrim (PhiPi)) : 8/13/2008 5:15:22 AM GMT

Comments

  • cgraceycgracey Posts: 14,133
    edited 2008-08-13 08:17
    Well, you're doing a write followed by four read-modify-writes on shadow SRAM,·each of which is getting copied to PHSB's latch. Because FRQB is zero during all this, PHSB isn't changing, anyway, so it's all good.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Chip Gracey
    Parallax, Inc.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-08-13 15:10
    Chip,

    Thanks for the quick reply! ('Just sorry I hadn't stayed up longer!) I think I get it now, so let me try to rephrase: Any time a PHSx register is used as a destination, the operation is performed on its shadow register instead, then the result is latched into PHSx. The shadow register continues to hold the last value written by code, regardless of any subsequent increments PHSx receives from FRQx. Therefore, any such increments will be lost at the next read-modify-write, as if they never took place.

    So if I wanted to phase-shift an NCO on the fly, say, it would be easiest to do it with FRQx, by adding 1/4 of the desired phase shift, then subtracting it right away, rather than messing with PHSx and its shadow:

            add     frqa,qshft   'Phase shift phsa by 90 degrees.
            sub     frqa,qshft
            ...
    qshft   long $1000_0000
    
    
    


    -Phil

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    'Still some PropSTICK Kit bare PCBs left!
  • cgraceycgracey Posts: 14,133
    edited 2008-08-13 17:45
    You got it, Phil. I think the back-to-back add+sub on FRQx is the best way to modify PHSx when things are in motion.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Chip Gracey
    Parallax, Inc.
Sign In or Register to comment.