ROM selection in 2066 controller
Hi,
I am trying to display characters from ROM A, but ROM C characters are bring displayed instead.
Here is a snipped of the initialization code:
ldi temp, 0x2A ; enter extended command set
rcall display_command
ldi temp, 0x72 ; function selection B
rcall display_command
ldi temp, 0 ; OPR[1:0] = 00b, ROM[1:0] = 00b (ROM A)
rcall display_data
I want to display an up carat (0x1D in ROM A), but a Greek capital letter Psi is displayed, instead. This character is 0x1D in Rom C.
I do not understand how ROM C was selected.
Here are the commands to check the busy flag, to send commands or data to the display.
delay_2_msec:
clr dlycnt
d12m:
cpi dlycnt, 1
brlt d12m
ret
check_ready:
ldi temp, $00 ; PORT C will be input for this routine ONLY
sts PORTC_DIR, temp ; all pins input
ldi temp, DC
sts PORTA_OUTCLR, temp ; This is a command
ldi temp, CS
sts PORTA_OUTCLR, temp ; Select the display
cr1: ldi temp, RD
sts PORTA_OUTCLR, temp ; command to read data to get the BUSY_FLAG
rcall delay_2_msec
lds temp1, PORTC_IN ; This is the first (dummy) byte to synchronize the display processor with this one
ldi temp, RD
sts PORTA_OUTSET, temp ; reset RD line to high, we are done reading
sbrc temp1, BUSY
rjmp cr1
ldi temp, CS
sts PORTA_OUTSET, temp ; reset CS line to high;
ldi temp, $FF
sts PORTC_DIR, temp ; PORT C is now set for output only
ret
display_command:
push temp ; save command on stack
rcall check_ready ; see if we are not busy for the next command
ldi temp, CS
sts PORTA_OUTCLR, temp ; Bring /CS line to low
ldi temp, DC
sts PORTA_OUTCLR, temp ; Bring D/C line to low for a command byte
ldi temp, WR
sts PORTA_OUTCLR, temp ; Bring /WR line to low to write
pop temp
sts PORTC_OUT, temp ; set all 8 bits of PORTC
nop
ldi temp, WR
sts PORTA_OUTSET, temp ; Bring WR line to high
ldi temp, DC
sts PORTA_OUTSET, temp
ldi temp, CS
sts PORTA_OUTSET, temp
ret
display_data:
push temp ; save the character on the stack
ldi temp, CS
sts PORTA_OUTCLR, temp ; Bring /CS line to low
pop temp
sts PORTC_OUT, temp ; set all 8 bits of PORTC
ldi temp, DC
sts PORTA_OUTSET, temp ; Bring D/C line to high for a data byte
ldi temp, WR
sts PORTA_OUTCLR, temp ; Bring /WR line to low to write
rcall delay_2_msec
ldi temp, WR
sts PORTA_OUTSET, temp ; Bring WR line to high
ldi temp, DC
sts PORTA_OUTCLR, temp
ldi temp, CS
sts PORTA_OUTSET, temp
ret
Thanks for looking,
Fred
0
-
Thanks for looking, problem has been solved (FINALLY - yes, I'm shouting).
It turns out that any command that precedes a data write (e.g., setting the ROM selection, setting the DDRAM address), there must be a short delay after the command and before the data write.
This also includes setting the DDRAM address command followed by a data byte. So, the initialization snippet becomes:
ldi temp, 0x2A
rcall display_command
ldi temp, 0x72
rcall display_command
rcall delay_2_msec
ldi temp, 0
rcall display_data
In addition, setting the cursor to the second row and outputting the cursor becomes
ldi 0xC0 ; Set DDRAM address to 1st character, 2nd line
rcall display_command
rcall delay_2_msec
ldi temp, 0x1D ; up carat character in ROM A
rcall display_data
Without the small delay before the cursor character is written, nothing shows up on the line. Adding the short delay, and the character does appear.
I'm running this XMEGA chip at 32 MHz, so very short delays aren't noticeable in display updates and optical encoder setting the operating frequency.
This was very instructive. And the problem is resolved.
Thanks!
Fred Love0 -
Hi Fred,
It's good to hear you have this working!
Thanks for sharing your solution as it will help others facing a similar issue.
Best Regards,0
Please sign in to leave a comment.
Comments
2 comments