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.

Pommie! Why is a GLCD dummy read necessary?

Status
Not open for further replies.

futz

Active Member
Quoting myself:
I'm just debugging my rasterizer for the display. I'm getting unexpected and just plain wrong results from my display data reads, which of course scrambles what I write to the screen, as I read first and then OR my new pixel into that byte and write it back out. Much confusion and debugger time ensues.
I finally gave up and took a look at your code and saw that you were reading twice to get proper result. Why is that dummy read necessary? I put the 2nd read in my code and it fixed the bogus reads I was getting.

But why?
 
Assuming that it's a ks0108-based display (?), the dummy read is necessary because data are latched to the output register of the glcd in that access and become available with the next read operation. That applies for data and not for the status of the display.
 
Last edited:
eng1 said:
Assuming that it's a ks0108-based display (?), the dummy read is necessary because data are latched to the output register of the glcd in that access and become available with the next read operation. That applies for data and not for the status of the display.
Ah! Thank you eng1. That explains it. I was getting pretty bald there, pullin my hair out, trying to get a proper read out of it. :p
 
The most annoying thing about the dummy read requirement is that it isn't mentioned in the **broken link removed**.:(

Mike.
 
So I thought I'd try something, pulled the 4MHz and put a 20MHz crystal on it. I put all my busy checks back in, compiled, programmed and ran it. Major troubles. The program is running. You can see what's supposed to be a block moving around the screen. But the display is garbled. I've been going thru the code putting delays every place I can think of! :D :D No fix so far.
 
I have got the GLCD working on both the Unicorn and a 16f886 at both 8 & 20MHz without any delays anywhere. I think your problem is something else.

Mike.
 
Pommie said:
I have got the GLCD working on both the Unicorn and a 16f886 at both 8 & 20MHz without any delays anywhere. I think your problem is something else.
You are correct. I've just discovered that even when I go back to 4MHz it's still broken. Must have broke something when I was modifying things. Typing with my elbows or something. :p I'll have to go thru it carefully and find the problem.
 
eng1 said:
Here's the full datasheet of the ks0108b controller :p

The japlish in that data sheet is probably why the other data sheets don't mention it.

Mike.
Edit, I should quote it.
Output register stores the data temporarily from display data RAM when CS1B, CS2B, CS3 is in active mode and R/W and
RS=H, stored data in display data RAM is latched in output register. When CS1B to CS3 is in active mode and R/W=H, RS=L,
status data (busy check) can read out.
To read the contents of display data RAM, twice access of read instruction is needed. In first access, data in display data RAM
is latched into output register. In second access, MPU can read data which is latched. That is, to read the data in display data
RAM, it needs dummy read. But status read is not needed dummy read.
 
Last edited:
futz said:
You are correct. I've just discovered that even when I go back to 4MHz it's still broken. Must have broke something when I was modifying things. Typing with my elbows or something. :p I'll have to go thru it carefully and find the problem.
After a HUGE amount of testing and trying different things, I've nailed what the problem was with 20MHz. R/M/W was a large part of it. I switched to using a shadow register for all the control lines (they're all on PortC) and that helped a lot, but it was still missing a few reads even with a 9.8304MHz crystal. At 20MHz the display was still badly scrambled.

Turned out that what it wanted was lots more time between setting E high and the read. Much more than I expected, going by the datasheet. But that alone didn't help. The previously mentioned shadow register thing had to be done as well to cure the thing. Together they settle it down nicely. :p
 
Last edited:
I'm not sure this is your problem. These are my read/write data routines that run fine at 20MHz.
Code:
ReadLCD		bsf	b_LCD_E
		movfw	PORTB
		bcf	b_LCD_E
		btfsc	b_Inverted
		xorlw	0xff
		return

WriteCMD	movwf	LCDTemp
		call	WaitNotBusy
		movfw	LCDTemp
		movwf	PORTB
		bcf	b_LCD_RW
		bcf	b_LCD_RS
		bsf	b_LCD_E
		bcf	b_LCD_E
		return

WriteData	movwf	LCDTemp
		call	WaitNotBusy
		movfw	LCDTemp
		btfsc	b_Inverted
		xorlw	0xff
		movwf	PORTB
		bcf	b_LCD_RW
		bsf	b_LCD_RS	;rs=1 rw=0
		bsf	b_LCD_E
		bcf	b_LCD_E
		return

As you can see, I have no delays at all. Set Enable, read port next instruction. Also, no RMW problems even on a breadboard.

Mike.
 
Pommie said:
I'm not sure this is your problem. These are my read/write data routines that run fine at 20MHz.

As you can see, I have no delays at all. Set Enable, read port next instruction. Also, no RMW problems even on a breadboard.
In that case, I can't explain it. All I know is that it was totally not working right before I made the changes and it works perfect after. And I tried EVERYTHING until I came to my solution.

Maybe my GLCD is different than yours? (the straws, grasping, thing :p)

In fact, I was still noticing it getting a bit wrong here and there, so I added one more NOP at a time to the reads (between setting E high and reading the port) until it smartened up. The delay is longer than the datasheet says it needs to be, but I can't argue with results.

Once I clean up a few ugly, commented out sections in the code I'll post it to my site and you can see.

EDIT: **broken link removed** got me looking seriously at rmw. Tried his TRIS bit method, but that wouldn't work at all for me.

I have a different GLCD coming. Should have it this week. We shall see if it is happy to run without shadow reg and too-big delays...
 
Last edited:
Turned out that what it wanted was lots more time between setting E high and the read. Much more than I expected, going by the datasheet.
Like this much!!!
Code:
//	glcd_busy();		//unnecessary busy-check
	trisd = 0xff;		//dummy read
	DI = RW = 1;
	E = 1;
	portc = shadowC;
	nop();
	nop();
	nop();
	nop();
	nop();
	nop();
	nop();
	nop();
	nop();
	nop();
	nop();
	read_tmp = portd;
	E = 0;
	portc = shadowC;
//	glcd_busy();		//don't do this one - it kills the latched data
	nop();
	nop();
	nop();
	nop();
	nop();
	nop();
	nop();
	nop();
	nop();
	nop();
	nop();
	nop();
	DI = RW = 1;
	E = 1;
	portc = shadowC;
	nop();
	nop();
	nop();
	nop();
	nop();
	nop();
	nop();
	nop();
	nop();
	nop();
	nop();
	read_tmp = portd;
	E = 0;
	portc = shadowC;
	trisd = 0;

At 20MHz that makes 200nS per cycle. tWH should be minimum 450ns, so maybe 3 NOPs should be enough. But NO!! I can't get decent reads without 11 of em. If I cut back to 10 I get errors - worse and worse as I cut the number of NOPs down. And I need 12 NOPs for the tWL between reads. 11 won't do - errors again.

Am I totally out to lunch? Hmm... Here's a crazy idea: I'm powering the PIC and GLCD off the PICkit2. Is it possible that the GLCD is a little underpowered and that makes it a little slow? That sounds dumb to me, but maybe?

(futz goes away to test this... comes back)

Nope. Gave it fatty power and still wants lots of time to read without getting errors. No change.

Hmm... Could the reason these displays ended up on the surplus market be because they didn't meet spec? Maybe that's why they're so cheap.
 
The line,
Code:
//	glcd_busy();		//don't do this one - it kills the latched data

Doesn't make sense. Same with the earlier glcd_busy line. This is my read byte routine which I just call twice if it's the first byte. Reading the status doesn't kill the latched data.
Code:
ReadData	call	WaitNotBusy
		bsf	STATUS,RP0
		movlw	0xff
		movwf	TRISB
		bcf	STATUS,RP0
		bsf	b_LCD_RW
		bsf	b_LCD_RS
		bsf	b_LCD_E
		movfw	PORTB
		bcf	b_LCD_E
		btfsc	b_Inverted
		xorlw	0xff
		bsf	STATUS,RP0
		clrf	TRISB
		bcf	STATUS,RP0
		return

I think your problem is the display being busy.

Having now looked at the timing diagrams in the data sheet, I'll add a nop after setting the E bit so I'm in spec.

Mike.
 
Pommie's Maple Leaf Code

Futz,

I ran Pommie's Maple Leaf Demo at 20 mhz on my Unicorn with the GLCD from the same place and his GLCD.c code works fine.

???

:confused:
 
I just looked at your site and found the following comment,
2008-03-29 14:14:16

I did some calculating and realized that with the slowish 4MHz clock I'm running, I can get rid of all the busy checking and either don't delay at all or put the occasional NOP. That sped up the display a LOT. Much snappier now.

I'm now certain your display is busy.:D :D

Mike.
 
Pommie said:
I'm now certain your display is busy.:D :D
Well, I finally fixed it. And it wasn't anything either of us thought of. It was my stupid programming error. Remember how I was thinking my busy check routine was killing my data read? Well it was, but not the way I thought. It turned out to be because it reset the TRIS bit between the dummy read and the real read. At that time I didn't have separate subroutines for the writes and reads like you do (I do now) and forgot to reset the TRIS before the second read. I hadn't thought of that, and it cost me a couple or three days of total confusion.

And during that period when I had the busy taken out and replaced by NOPs, the errors were caused by the display being busy, as you said.

It's funny how as I rewrite over and over my code morphs until it looks more and more like yours. :D And though sometimes I looked at yours and thought, "That's very smart! I'm going to go write one of those", sometimes my code just ended up looking like yours without me cheating at all.
 
Last edited:
Good to hear it's working.

As for code looking the same. There are only so many ways you can write a routine and so it is inevitable that given 20 programmers (not novices) they will probably only come up with 3 different pieces of code. I remember having an argument about 15 years ago with an Intellectual Property Lawyer who thought that every subroutine should be unique.

Mike.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top