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:
#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:
#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.