Read-modify-write on PHSx -- not supposed to work, but does.
Phil Pilgrim (PhiPi)
Posts: 23,514
According to the datasheet, phsa and phsb cannot be used as destinations of a read-modify-write instruction:
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
I had forgotten this caveat and wrote the following code to generate two waveforms in quadrature with each other: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.
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
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chip Gracey
Parallax, Inc.
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!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chip Gracey
Parallax, Inc.