Hi everyone,
i'm doing some routines for interfacing with this 16x2 LCD character display from newhaven display (datasheet attached, controller chip datasheet also attached) in 4-bit mode and i found something weird. It seems that all datatransfer is hi-nibble first EXCEPT when doing the "read busy-flag/address counter (BFAC)" instruction, then it is lo nibble first followed by hi nibble. I found out because the the read busy-thing didnt work at all and my lcd-routine stopped working after writing exactly 8 characters to the screen (so the BF/AC byte would become 0b0000/1000 therfore when nibble-swapped the first (busy flag)bit would seem 1 forever. I checked it and when i swapped it in the code everything suddenly worked fine! I also double checked by printing out the read BFAC-byte on the display. Now, i couldnt find anything about this behaviour on the datasheet or anywhere else, the LCD controller chip actually even suggests the nibble order for this command is in the right order like all other transfers.
Does anyone have any experience with these kind of things and should i be
surprised/
mad at this lcd-producer/
mad at the controllerchip producer/just cautious in the future/
paranoid/...? Any advice would be nice!
I'll attach some code below, its two functions, one for a DataRead instruction, and one for a BFACRead instruction to the LCDmodule, they are almost identical EXCEPT i had to swap lo and hi at the end (and do a bit of cursing) to make it work for the BFACRead...
uint8_t lcd_readBFAC(){
uint8_t hi,lo;
TRIS_lcdData |= 0x0F;
LAT_lcdRS = 0;
LAT_lcdRW = 1;
__delay_us(1);
LAT_lcdE = 1;
__delay_us(1);
hi = PORT_lcdData & 0x0F;
LAT_lcdE = 0;
__delay_us(1);
LAT_lcdE = 1;
__delay_us(1);
lo = PORT_lcdData & 0x0F;
LAT_lcdE = 0;
LAT_lcdData &= 0xF0;
TRIS_lcdData &= 0xF0;
//return ((uint8_t)(hi<<4)|lo);
return((uint8_t)(lo<<4)|hi); //WTF!!!! its backwards!!!!
}
uint8_t lcd_readData(){
uint8_t hi,lo;
TRIS_lcdData |= 0x0F;
LAT_lcdRS = 1;
LAT_lcdRW = 1;
__delay_us(1);
LAT_lcdE = 1;
__delay_us(1);
hi = PORT_lcdData & 0x0F;
LAT_lcdE = 0;
__delay_us(1);
LAT_lcdE = 1;
__delay_us(1);
lo = PORT_lcdData & 0x0F;
LAT_lcdE = 0;
LAT_lcdData &= 0xF0;
TRIS_lcdData &= 0xF0;
return ((uint8_t)(hi<<4)|lo);
}