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):
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)
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:
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.
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??
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: