|
|
@ -0,0 +1,134 @@ |
|
|
|
#include <stdint.h> |
|
|
|
#include "serial.h" |
|
|
|
|
|
|
|
// https://www.buydisplay.com/download/democode/ERM24064-1_DemoCode.txt |
|
|
|
|
|
|
|
volatile uint8_t *const SCREEN_ADDRESS_DATA = (uint8_t *)0xf40001; |
|
|
|
volatile uint8_t *const SCREEN_ADDRESS_INSTR = (uint8_t *)0xf40003; |
|
|
|
|
|
|
|
// Wait for read and write to not be busy |
|
|
|
void lcd_checkBusy_S0S1() |
|
|
|
{ |
|
|
|
uint8_t b; |
|
|
|
do |
|
|
|
{ |
|
|
|
b = *SCREEN_ADDRESS_INSTR; |
|
|
|
} while((b & 0x03) != 0x03); |
|
|
|
} |
|
|
|
|
|
|
|
// Wait for auto write to not be busy |
|
|
|
void lcd_checkBusy_S3() |
|
|
|
{ |
|
|
|
uint8_t b; |
|
|
|
do |
|
|
|
{ |
|
|
|
b = *SCREEN_ADDRESS_INSTR; |
|
|
|
} while((b & 0x08) != 0x08); |
|
|
|
} |
|
|
|
|
|
|
|
void lcd_writeData(uint8_t data) |
|
|
|
{ |
|
|
|
*SCREEN_ADDRESS_DATA = data; |
|
|
|
} |
|
|
|
|
|
|
|
uint8_t lcd_readData() |
|
|
|
{ |
|
|
|
return *SCREEN_ADDRESS_DATA; |
|
|
|
} |
|
|
|
|
|
|
|
void lcd_writeCommand(uint8_t data1, uint8_t data2, uint8_t instruction, int numParameters) |
|
|
|
{ |
|
|
|
if(numParameters >= 1) |
|
|
|
{ |
|
|
|
lcd_checkBusy_S0S1(); |
|
|
|
lcd_writeData(data1); |
|
|
|
} |
|
|
|
|
|
|
|
if(numParameters == 2) |
|
|
|
{ |
|
|
|
lcd_checkBusy_S0S1(); |
|
|
|
lcd_writeData(data2); |
|
|
|
} |
|
|
|
|
|
|
|
// lcd_checkBusy_S3(); |
|
|
|
|
|
|
|
*SCREEN_ADDRESS_INSTR = instruction; |
|
|
|
} |
|
|
|
|
|
|
|
uint8_t lcd_readByte() |
|
|
|
{ |
|
|
|
lcd_writeCommand(0, 0, 0xc5, 0); |
|
|
|
lcd_checkBusy_S0S1(); |
|
|
|
return lcd_readData(); |
|
|
|
} |
|
|
|
|
|
|
|
void lcd_setPos(uint8_t x, uint8_t y, uint8_t mode) |
|
|
|
{ |
|
|
|
if(mode) |
|
|
|
{ |
|
|
|
// graphics |
|
|
|
int a = y * 40 + x; |
|
|
|
uint8_t aLwr = a & 0xff; |
|
|
|
uint8_t aUpr = a >> 8; |
|
|
|
lcd_writeCommand(aLwr, aUpr + 0x08, 0x24, 2); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
// text |
|
|
|
int a = y * 40 + x; |
|
|
|
uint8_t aLwr = a & 0xff; |
|
|
|
uint8_t aUpr = a >> 8; |
|
|
|
lcd_writeCommand(aLwr, aUpr, 0x24, 2); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void lcd_init() |
|
|
|
{ |
|
|
|
lcd_writeCommand(0, 0, 0x40, 2); // Set text home address |
|
|
|
lcd_writeCommand(40, 0, 0x41, 2); // Set text area width |
|
|
|
lcd_writeCommand(0, 0x08, 0x42, 2); // Set graphics home address |
|
|
|
lcd_writeCommand(40, 0, 0x43, 2); // Set graphics area width |
|
|
|
lcd_writeCommand(0, 0, 0xa7, 0); // 8-line cursor |
|
|
|
lcd_writeCommand(0, 0, 0x80, 0); // OR mode |
|
|
|
lcd_writeCommand(0, 0, 0x9c, 0); // text & graphics on |
|
|
|
} |
|
|
|
|
|
|
|
void lcd_clear() |
|
|
|
{ |
|
|
|
lcd_setPos(0, 0, 0); |
|
|
|
lcd_writeCommand(0, 0, 0xb0, 0); |
|
|
|
for(int i = 0; i < 8192; i++) |
|
|
|
{ |
|
|
|
lcd_writeData(0); |
|
|
|
} |
|
|
|
lcd_writeCommand(0, 0, 0xb2, 0); |
|
|
|
} |
|
|
|
|
|
|
|
void lcd_writeString(uint8_t x, uint8_t y, char *str) |
|
|
|
{ |
|
|
|
lcd_setPos(x, y, 0); |
|
|
|
while(*str != 0) |
|
|
|
{ |
|
|
|
lcd_writeCommand(*str - 0x20, 0, 0xc0, 1); |
|
|
|
str++; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Very slow. Use sparingly |
|
|
|
void lcd_setpixel(uint8_t x, uint8_t y, uint8_t value) |
|
|
|
{ |
|
|
|
int byteX = x / 6; // 6 bits per character |
|
|
|
int bit = 5 - (x - byteX * 6); |
|
|
|
lcd_setPos(byteX, y, 1); |
|
|
|
uint8_t curValue = lcd_readByte(); |
|
|
|
if(value) |
|
|
|
{ |
|
|
|
curValue |= 1 << bit; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
curValue &= ~(1 << bit); |
|
|
|
} |
|
|
|
|
|
|
|
lcd_writeCommand(curValue, 0, 0xc4, 1); |
|
|
|
} |