ks0108 writes cmd and data ok, but read broken

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I can write data and commands perfectly, but cannot quite get LCD to send me any data, as usual, putting it in words provides an answer.

After letting the smoke out of the 1st GLCD I bought off ebay (it was a toshiba; I wired the contrast as all wrong), I got another, this time based on ks0107/ks0108 chipset. Simples I said to myselves, the data sheet on this one is far shorter. So I coded it up mostly straight off the datasheet, I did peek at some arduino code as a guide to the ordering of the RS(DI) RW and EN lines to get rid of the timing niggles. And viola.

But my status read function is broken, I got it to work by mistake, by turning the pull-ups off on the data port. It took me a day to find the fault, which meant my status read is really reading nothing(all zeroes) at all, so it never did do a wait.

void WaitReady(u8 chip)
{
	LCD_CTRL_PORT &= ~(1<<LCD_ENABLE);
	SelectChip(chip); // set the CSA or CSB
	LCD_DATA_DDR = 0;//set inputs
	//LCD_DATA_PORT = 0xFF; // CAUSES HANG!

	LCD_CTRL_PORT &= ~(1<<LCD_RS); //clear Data/Instruction
	LCD_CTRL_PORT |= ((1<<LCD_RW)| (1<<LCD_ENABLE));
	_delay_us(1);
	while(LCD_DATA_PORT & LCD_BUSY_FLAG);
	LCD_CTRL_PORT &= ~(1<<LCD_ENABLE);
}

You can see I commented out the line for pull-ups, which would HANG this function if I left it in.

Link to pic of the display http://www.flickr.com/photos/40917542@N03/6089978963/ drawing and controlling just fine.

This model is a 12864J LED backlight, blue.

It's late, I hope my 2 hours of reading the 2 really good GLCD threads on AVR would bear some fruit, but nothing arose. I have not posted all of my code because that would be daft, I would suspect a wiring problem, but that's unlikely since data/command both need the RS line working correctly,,, - a cursory glance at the veroboard reveals no short-circuits, eyes are tired.... :idea: which leaves me with the R/W line, which I think may be stuck low or floating... Will hang a scope on that line in the morning, sorry to bother anyone who is still awake, gnite. I hate it when I find my own bugs.

Further reading :https://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=48528&start=0
https://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=46614

Conrad Braam - www.softcircuitry.blogspot.com - www.plcsimulator.org
Always start off poorly, that way when you finally figure it out, you can get a few surprise hits in.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You have to read the PIN register (not PORT).

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, I don't read C...

But I recall that when I wrote my first KS0107/0108 driver I, also, could write to the display but had difficulty reading it.

Here are the notes from my GLCD Read routine which may be helpful to you in getting your read routine working:

Glcdread:
   'Read a Data Byte from Display Ram   
   'Note: Read each Data byte TWICE to clock the data onto the Data Bus!!!
   'Note: The data sheet is VERY POOR and VERY VAGUE on Reading the Display Ram.
   'It is not clear if two FULL READS, setup, addr, full handshake, etc. is needed,
   'or just clocking Enable twice, at the right time, will clock the data to the
   'output port.  I implimented TWO FULL READS, and with the 2 uS delays for
   'data setup after Enable goes high, it works.
   'Both of the 2 uS dealys are needed to allow it to clock the data each step.
   

JC

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks Stefan, too much C# coding will do that to your brain, read PIN not PORT doh!
Woot - suddenly the pixel plotter routine also works properly! I was worried about needing a dummy read, but it looks like a status read also doubles as a dummy read to shift/clock the data byte out onto the bus. I did need a 2us delay, for a full cycle, thanks all.

Conrad Braam - www.softcircuitry.blogspot.com - www.plcsimulator.org
Always start off poorly, that way when you finally figure it out, you can get a few surprise hits in.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Aha - with all that working, I have also got bitmaps working. The easiest way in a pinch for anyone with a google mobile, to create nice monochrome bitmaps is to use wiregoggles, which is an android app to take wireframe photos, its an edge-detection application. Which give everything an outline - a bit like a line-art sketch.
So I take some pics in black&white or grayscale, and move them to my PC to resize.
After discovering that converting bitmaps to 'C' requires you likely download some malware, or compile some code, I decided to write my own script, which took only 1 hour in the end. It generates just the "{0xnn,0xnn,0xnn....}", and is in powershell, so anyone with a current version of Windows can run it (WinXP and Vista will need to add the .NET updates).
It takes monocrome and 16-color bitmaps so long as it only has gray tones.

# posh code to convert a moncrome bitmap into a 'C' progmem structure
param([string]$inputFile)

[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
$Cave = [System.Drawing.Bitmap]::FromFile($inputFile)
write-host "W:"  $cave.width
write-host "H:"  $cave.height
#for ($y=0; $y -lt $cave.Height;$y++) 
#{ 
#	for ($x=0; $x -lt $cave.Width;$X++) 
#	{ 
#		if ($cave.GetPixel($x,$y).R) 
#		{
#			$bit="_"
#		}
#		else
#		{
#			$bit="#"
#		}
#		#Write-Host $bit -nonewline 
#	}
#	#Write-Host ""
#}

$y=0;
$row = "{"
while ($y -lt $cave.Height)
{
	for ($x=0; $x -lt $cave.Width;$X++) 
	{ 
		$data=0
		for ($bit=0; $bit -lt 8;$bit++)
		{
			if ($cave.GetPixel($x, $y + $bit).R)
			{
			}
			else
			{
				$data = $data -bor [math]::pow(2 ,$bit)
			}
		}
		$row += ("0x{0:X2}, "-f $data)
		if ($row.length -gt 120) { $row;$row=""}
	}
	$row
	$y+=8
	$row=""
}
"};" 

1. Go start/run, type powershell.exe
2. Take note of the folder you are currently in
3. Save the text as convert.ps1 in the directory from step2
4. In the console type

Set-executionpolicy remotesigned

5. type

.\convert.ps1 

the .\ on the front is very important, ask any linux user, to preach it straight. ; provide the full or relative path to your image file. None of the above are case sensitive though. The script will print out the file width &height, and then the data bytes ready to paste into your project.
I suspect it can accept files other than .BMP or .PNG, and since it took less than an hour to write it, has got some bugs, which will show if you do anything I never intended with it. If anyone actually tries it out, and complains nicely, I can update it so it does not print any garbage, and could then work as in like toolchain with a "|" pipe to automate conversions for you.

Attachment(s): 

Conrad Braam - www.softcircuitry.blogspot.com - www.plcsimulator.org
Always start off poorly, that way when you finally figure it out, you can get a few surprise hits in.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Zaphodikus wrote:
Thanks Stefan, too much C# coding will do that to your brain, read PIN not PORT doh!
Woot - suddenly the pixel plotter routine also works properly! I was worried about needing a dummy read, but it looks like a status read also doubles as a dummy read to shift/clock the data byte out onto the bus. I did need a 2us delay, for a full cycle, thanks all.

(The code in your first post seems to be changing around a bit but now seems to do what my ks0108 code does)

It is actually the strobing of E that does the clocking
from the holding register to the data bus on data reads.
None of the displays i've worked with need a 2us delay
before reading the data lines.
The ks0108 modules usually specify the needed timings.
tDDR (Data Delay Time) is the critical timing that you need to not violate on reads.
It is usually 320ns and is the time between when you raise
E to when you can look at the data bus for the data.

There is a difference between status reads and data reads.
The data reads need the extra E strobe to clock the data to the the data bus.
Status reads do not, so as you have noticed you can spin on the BUSY bit and not have to continually go through the "double read" process.

In my testing I noticed that leaving E high for long periods of time can upset some glcd modules. So it is best
to always drop E when done using the data bus.

As far as pullups go, I found no difference in operation on status or data reads whether they were on or off.
I actually let them flop around because they end up getting set/cleared by the last data write. I did it this way to save a few cycles.

There is also supposed to be a delay (tAS) between
when RW is raised before E is raised. It is usually 140ns.
While this is specified, my code violates this a bit but so far on many different displays, it seems to work ok.

One thing to keep in mind that _delay_us() from (unless you have the very latest version) doesn't work very well for small delays.
(I have written about this many times on these forums as it can really burn you when trying to do sub microsecond type delays).

BTW, I have a small routine to plot XBM format bitmaps
which will be appearing in the next version of the Arduino glcd v3 library. If you are interested PM me and I'll send you the code with an explanation of how to modify
standard XBM files to use it.
It is only about 30 lines of code.

It will allow you to use tools that support XBM format
(like gimp) to create bitmaps.
I like to use gimp because of its many capabilities and it is cross OS platform.

--- bill