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:
-Phil
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
'Still some PropSTICK Kit bare PCBs left!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chip Gracey
Parallax, Inc.