Shop OBEX P1 Docs P2 Docs Learn Events
DRVH instruction causes DIRx issues — Parallax Forums

DRVH instruction causes DIRx issues

Hi Chip
The last few days I've been trying to hunt down a weird program issue and discovered an issue with the DRVH instruction.
On their own DRVH seem to work Ok but any instructions that access the releveant DIRx register goes weird.
Here's some code snippets that demonstrate the issue.
'code_a & code_e are the only code snippets that work as expected.

dat	org

	jmp	#code_a

code_a	drvh	#32
	drvh	#33
	drvh	#34
	drvh	#35		'all leds on as expected
	jmp	#$

code_b	drvh	#32
	drvh	#33
	drvh	#34
	drvh	#35
	bitl	dirb,#1		'turns all leds off ????????
	jmp	#$

code_c	drvh	#32
	drvh	#33
	drvh	#34
	drvh	#35
	or	dirb,#0		'turns all leds off ????????
	jmp	#$

code_d	drvh	#32
	drvh	#33
	drvh	#34
	drvh	#35
	or	dirb,#%110000	'turns all leds off ????????
	or	outb,#%100000	'turns led #5 on as expected
	jmp	#$

code_e	bmask	dirb,#3
	bmask	outb,#3
	or	dirb,#%110000	'all leds remain on as expected
	or	outb,#%100000	'turns led #5 on Ok
	jmp	#$

code_f	drvh	#32
	drvh	#33
	drvh	#34
	drvh	#35
	bitl	dirb,#33	'turns all leds off ????????
	jmp	#$

I went back to V16 and the issue is still there if that helps.
Sorry to get you back to Quartus ;)

Comments

  • I'm not that familiar with the P2, but I think there's an issue with your logic in code_c and code_d.

    You're attempting to use
    or
    
    instructions to turn off bits. You should be using
    andn
    
    instead.

    Or'ing a bit with zero doesn't change it.
  • evanhevanh Posts: 15,170
    That's what Oz is pointing out. He's pointedly not trying to turn them off but they turn off anyway.
  • evanh wrote: »
    That's what Oz is pointing out. He's pointedly not trying to turn them off but they turn off anyway.
    wmosscrop, evanh is correct!
    	or	dirb,#0		'turns all leds off ????????
    
    This shouldn't change the dira register at all.

  • Dave HeinDave Hein Posts: 6,347
    edited 2017-07-17 14:49
    If you add a "mov dirb, #15" before the failing cases they will now work. I suspect that reads are performed from the shadow ram, and a drvh is not setting the shadow ram, whereas a "mov dirb" sets both the dirb register and the shadow ram. A drvh must set both dirx and outx, so it's not possible to set both shadow rams. At least that's my theory. If that's the case this limitation should be documented.

    EDIT: I tried the following code, and all the LEDs are lit. This is consistent with the theory that drvh/flth doesn't set the shadow ram, and that the shadow ram is accessed on reads.
    code_c
            mov     dirb,#15
    	flth	#32
    	flth	#33
    	flth	#34
    	flth	#35
    	or	dirb,#0		'turns all leds on ????????
    	jmp	#$
    
  • evanhevanh Posts: 15,170
    Hmmmmmm ... makes sense ... tricky. Lots of details all round to document. Chip has his work cut out for ... forever.
  • jmgjmg Posts: 15,144
    Dave Hein wrote: »
    If you add a "mov dirb, #15" before the failing cases they will now work. I suspect that reads are performed from the shadow ram, and a drvh is not setting the shadow ram, whereas a "mov dirb" sets both the dirb register and the shadow ram. A drvh must set both dirx and outx, so it's not possible to set both shadow rams. At least that's my theory. If that's the case this limitation should be documented.

    Nicely spotted.
    Could this not be fixed, so reads do not access shadow ram, but the real value instead ?

  • cgraceycgracey Posts: 14,133
    Hello from China!

    This is due to the DIRA/DIRB values not being data-forwarded in the pipeline during DRVx/FLTx instructions, though OUTA/OUTB values ARE forwarded. In other words, if you want to do an operation on DIRA/DIRB after a DRVx/FLTx instruction, do some other instruction in-between. This will overcome the need for the missing data-forwarding.
  • Hi Chip
    Hope you are having a pleasant and productive time in China! :)
    cgracey wrote: »
    In other words, if you want to do an operation on DIRA/DIRB after a DRVx/FLTx instruction, do some other instruction in-between. This will overcome the need for the missing data-forwarding.
    I tried putting some spacer instructions in and still get the same result.
    	drvh	#32  'led on
    	nop
    	nop
    	nop
    	nop
    	or	dirb,#0  'turn's led off
    
    Something to think about when you get back. No rush.



  • cgraceycgracey Posts: 14,133
    edited 2017-08-17 17:01
    Ay, ay, ay!

    I just realized why this fails:
    code_b	drvh	#32
    	drvh	#33
    	drvh	#34
    	drvh	#35
    	bitl	dirb,#1		'turns all leds off ????????
    	jmp	#$
    

    For ALU-type interactions with DIRA/DIRB (BITL, in this case), the DIRA/DIRB shadow RAM registers are used as the data source, not the actual DIRA/DIRB register bits. DRVH just affects the register bits and doesn't update the shadow RAM register that BITL depends upon. What an oversight on my part! Okay, so this is fixable by making mux's to pull in the register data for D and S, and ignore the shadow register. This is not a big deal, but it does generate more logic.
  • cgraceycgracey Posts: 14,133
    Okay, this is fixed. Also, I got around the data-forwarding problem, as well, by not just reading the DIRA/DIRB bits for S and D, but reading the updating DIRA/DIRB bits that may be getting affected by DRVx/FLTx, outside of the data-forwarding circuitry. So, no more surprises, at all:

    https://drive.google.com/file/d/0B9NbgkdrupkHcEpydFkxZFRtNTg/view?usp=sharing
  • V20C is working fine Chip. Thanks!
Sign In or Register to comment.