SparkFun Forums 

Where electronics enthusiasts find answers.

Your source for all things Atmel.
By OrlandoArias
#130434
So I got bored and decided to implement a library for a ks0108b controlled LCD, specifically:
http://www.sparkfun.com/products/710

Everything is fine and dandy, except when I'm about to read the busy flag. I can't seem to get the timing right. Relevant bits follow:
Code: Select all
#define wait_until_free() while( !(ks_strobe(1, _cs) & 0x80 ) )

/* [snip] */

uint8_t ks_strobe(uint8_t status, uint8_t cs){
        // TODO: Optimize
        uint8_t t = 0;
        CTRLOUT &= ~(_BV(CS1) | _BV(CS2));      // deselect both chips
        CTRLOUT |= (1 << cs);

        if (status){
                DATADDR = 0x00;
                __asm("nop");
                CTRLOUT |= _BV(RW);
                CTRLOUT &= ~_BV(RS);
        }

        _delay_us(1);
        CTRLOUT |= _BV(EN);
        _delay_us(1);

        if (status){
                t = DATAIN;
                DATADDR = 0xff;
                __asm("nop");
        }

        CTRLOUT &= ~_BV(EN);

        return t;
}
Full code at: http://code.google.com/p/breadstick-ent ... s/ks0108b/

If you're wondering about the method for chip select: I wired the LCD to a bunch of switches and drove it by hand. CS is active high for this LCD, not active low as the datasheet states.
Giving a delay of 25µs between data/command sends makes the LCD work properly. This is bad practice, however, the busy flag should be used instead. Test case:
Code: Select all
#include <avr/io.h>
#include <inttypes.h>
#include <util/delay.h>

#include <ks0108b.h>

void main(void) __attribute__((noreturn));
FILE ks_out = ks_createStream();

void main(void){
	stdout = &ks_out;

	DDRD = 0xff;
	ks_init();
	PORTD = 0x01;		// debug: initialization finished

	for (uint8_t a = 0; a<8; a++){	// fills the LCD black
		ks_sendCommand(KS_SET_PAGE | a, 0);
		ks_sendCommand(KS_SET_PAGE | a, 1);
		for (uint8_t i = 0; i< 64; i++){
			ks_sendData(0xff, 1);
			ks_sendData(0xff, 0);
		}
	}
	for (uint8_t a = 0; a<8; a++){	// make a grid
		ks_sendCommand(KS_SET_PAGE | a, 0);
		ks_sendCommand(KS_SET_PAGE | a, 1);
		for (uint8_t i = 0; i< 64; i++){
			ks_sendData((i % 8) ? 0x80 : 0xff, 1);
			ks_sendData((i % 8) ? 0x80 : 0xff, 0);
			_delay_ms(5);
		}
	}
	PORTD |= 0x80;		// debug: grid printed.
	ks_sendCommand(KS_SET_Y, 0);
	ks_sendCommand(KS_SET_PAGE | 0x03, 0);
	printf("Hello, world!");
	uint8_t i = 0;
	while(1){
		ks_sendCommand(KS_SET_Z | i, 0);
		ks_sendCommand(KS_SET_Z | i, 1);
		i++;
		if(i == 64) i = 0;
		_delay_ms(150);
	}
}
At this point, the datasheet's bad English combined with an afternoon of searching the web for solutions have evolved into a nice migraine. No, I do not have an oscilloscope to test out the signals, sadly. Any help would be greatly appreciated. Cheers and thank you.