Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

rrf INDF - doesn't seem to work properly

Status
Not open for further replies.

LabRat

New Member
Hello again everyone...time for my annual "I've got some time to play with Micro's" session.

I've been making a small board based on the 16F688, that is intended to act as a serial to parallel converter (with some smarts) to drive a massive 16x48 LED matrix. The board will receive serial info, store the "image" to be displayed, and clock the data out to the panel (refreshing as it goes).

Amongst the commands to be implemented is a "roll left" which will push a new column of incoming pixels onto the right most side of the display, and roll all the rows to the left (scrolling left).

I was progressing very well until two nights ago when I started on the "Roll Left" command. No matter what I tried, the data in the buffer just isn't correct, so I've been chasing it down ever since. There is definitely something *amiss* here (and I'm not 100% certain it's my code).

Here's the relevant info (I hope):

  • BANK0 contains the "Top 1/2" of the frame
  • BANK1 contains the "Bottom 1/2"
  • In the 16 bytes of "common" data, exist the shared rxBuffer, which includes:bitShifter (countdown from 8 to zero), column_count (6 to 0), and row_count (8 to 0). Input1&Input2 - the new bits for the roll, and Voldemort the "BYTE that shall not be named" which simply contains a flag that indicates whether I'm processing the top or bottom portion of the frame (need to know when to exit the loop).
  • No ISR's running at all.

As I am are "shifting Left", I'm processing the buffer in reverse, and "C"arrying in the new bit from the bitShift register. (lsb first)


Code:
cmdLeft
	BANKISEL Fr0Row0		
		movlw	Fr0End
		movwf	FSR		; Point in the BANK 
		movf	input2,W	; Get the appropriate byte from the payload
		movwf	bitShifter	; Everything is where we want it.
		clrf	voldemort	; Indicate 1st time throught this loop

cml_forEachBank 
		movlw 	d'8'		; 8 rows per frame
		movwf	row_count	; 
cml_forEachRow
		movlw	d'6'		; 6 bytes per row
		movwf	column_count	;
		rrf	bitShifter,F	; Put the "next" lowest bit into 'C'
cml_forEachColumn
		decf	FSR,F		; Decrement to the next BYTE in the stream
		rrf	INDF,F		; Rotate the payload NOTE: inverse rotate due to msb output ordering
		decfsz	column_count	; Count down all 6 bytes in the ROW
		goto 	cml_forEachColumn

		decfsz	row_count
		goto 	cml_forEachRow

		btfsc	voldemort,1		; Was this the second frame?
		goto	doneCmd			; Yes - we are done
		
	BANKISEL Fr1Row0
		movlw	Fr1End
		movwf	FSR
		movf	input1,W
		movwf	bitShifter
		bsf		voldemort,1		; Flag that we are executing the SECOND 1/2 of the shiftloop
		goto	cml_forEachBank

Ok that's the setup.. here's the bizarre problem. The rrf INDF command, appears to be shifting 3 times, instead of 1. (Yeah.. I know it sounds unreal.. ).

My debugging attempts:
I tweaked the code to exit after processing the first memory location only.
It contained 0x80 at the start, and after the shift... I'm left with 0x10??​

I've tried all sorts of tests, to narrow this down. I've copied the value from the INDF into W, output it into a new location (still 0x80), did an rrf of W and spat that out into yet ANOTHER location.. 0x10!!​


It gets worse... if I double up the RRF INDF, so that I perform the operation twice.. the output is... 0x10?!?​

(I'm not making this up)

To make things even more confusing.. if I add some "wait" time at the very start of the routine.. 3+ms (of thereabouts). The output will be... 0x20 .
If I go larger.. around 4-5 ms, then I get the expected values.

Anyone have any ideas on where I could look next? (For now I've left the wait states in there.. but that just seems oh so wrong.)

Thanks for any feedback.

Oh.. the Roll Right command which uses a rlf INDF works without issue.
 
Last edited:
I hate it when I get half the story. Post code that is complete otherwise I'm guessing at what the rest of your code is doing. One thing I will state is that the error is in your code. Post code that I can assemble and I will find your error.

Mike.
 
Can you even do "rrf INDF,F"?, I don't know as it's a valid instruction - and certainly nothing I would ever have considered trying, nor ever seen been used.
 
I hate it when I get half the story. Post code that is complete otherwise I'm guessing at what the rest of your code is doing. One thing I will state is that the error is in your code. Post code that I can assemble and I will find your error.

Mike.

Sorry Mike, I was trying not to flood the posting with the extraneous code.
I will attempt to post the entire listing here.

The code receives a byte string which contains: <SYNC><CMD><payload>
with the payload size varying based on the CMD.

This gets parsed, and based on the command, I will attempt to "shift" the 16x48 array (split with 1/2 in Bank0 and 1/2 in BANK1), one bit to the left.
(note that I'm adhering to an existing protocol, which parsed the incoming data such that he MSb of the MSB is shifted out first. (In case you wonder why I'm doing an rrf, while shifting the image to the left)).

In this particular version of the code, the w4Cmdtable has been modified for debugging to call the Left/Right/ and FrameWrite commands.

(FrameWrite0 = copy the 2 half banks to a single EEPROM array at the start of EEPOM, FrameWrite1 = copy to the end of EEPROM)


Debugging involved sending CMD 6 - cmdLeft, followed by CMD 0 - FrameWrite . I could then read back the eeprom via the JuneBug, and review the results.

(Final note - again hope I'm not overloading here) The "call BlinkStatus" at the top of the cmdLeft is introducing the delay necessary for things to work. When I remove this, the problems with the rrf INDF occur.

ASM file should be attached.
 

Attachments

  • pikc.asm
    33.8 KB · Views: 128
Can you even do "rrf INDF,F"?, I don't know as it's a valid instruction - and certainly nothing I would ever have considered trying, nor ever seen been used.

Yes, that means rotate right and put it back in the file. Indirectly of course.

Mike.
 
Can you even do "rrf INDF,F"?, I don't know as it's a valid instruction - and certainly nothing I would ever have considered trying, nor ever seen been used.

Well I've scoured the "NET" and seen it done numerous times, and I can't find any mention from Microchip (errata or otherwise) that says to avoid this. I don't see why this shouldn't work. It would read the value, rotate it right (through the carry bit) and push it back out to the register being pointed at by the FSR.

Well.. that's what it's *SUPPOSED* to be doing. ;)
 
LabRat,

I'll look at your code in the morning. Late here, 11:30pm and I have had a good drinking session with my mates.

Mike.
 
I know what it means, but does it work? - I've never seen it used (and like I said, would never have thought to try it).

I'll go with this thought.. if I *am* doing something irregular, what approach would you take to shift an array (say 6 bytes long) one bit to the right (or left)?
(I'm open to alternate solutions :) )

ps. Realized I didn't make it clear that when I said 16x48.. I was talking BITS not BYTES. (Kind of makes a difference.. doesn't it)
 
LabRat,

I'll look at your code in the morning. Late here, 11:30pm and I have had a good drinking session with my mates.

Mike.

"No worries" (see.. I can try and speak the local language)

I appreciate all the assistance.
 
I'll go with this thought.. if I *am* doing something irregular, what approach would you take to shift an array (say 6 bytes long) one bit to the right (or left)?
(I'm open to alternate solutions :) )

If you check my tutorials the LED matrix one does this with 8 bytes, shifting an 8x8 LED matrix in all four directions.
 
Labrat,

Sorry this went off topic. Our moderator appears to be confused.

Mike.
 
Hardly, you seem to be avoiding the question, have you EVER used INDF with RRF or not?.

If not, as you seem not to have, have you ever seen it done?.

If not, as seems likely, how do you know it works?.

Of course I have. I thought that was obvious.

Mike.
 
Hardly, you seem to be avoiding the question, have you EVER used INDF with RRF or not?.

If not, as you seem not to have, have you ever seen it done?.

If not, as seems likely, how do you know it works?.

Google "rrf indf,f"

Which means that I *personally* have not seen it work, but it seems that others have. (Conspiracy theorists may argue differently :D )
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top