249 lines
7.3 KiB
C
Executable File
249 lines
7.3 KiB
C
Executable File
#include "stdint.h"
|
|
#include "stddef.h"
|
|
#include "unistd.h"
|
|
|
|
|
|
#include "io.h"
|
|
|
|
// LT24 LCD Controller pixel format
|
|
typedef struct Pixel
|
|
{
|
|
unsigned r : 5;
|
|
unsigned g : 6;
|
|
unsigned b : 5;
|
|
} pixel_t;
|
|
|
|
static inline uint16_t encPixel(const struct Pixel *p)
|
|
{
|
|
return (p->r << (5 + 6)) | (p->g << 5) | (p->b);
|
|
}
|
|
|
|
// LT24 LCD Controller hardware address register layout
|
|
struct LT24
|
|
{
|
|
uint32_t writeReg;
|
|
uint32_t writeData;
|
|
uint32_t writeBase;
|
|
uint32_t refresh;
|
|
uint32_t ctrlReg;
|
|
uint32_t setHeight;
|
|
uint32_t setWidth;
|
|
uint32_t writeIRQ;
|
|
uint32_t setIRQ;
|
|
uint32_t clearIRQ;
|
|
uint32_t isBusy;
|
|
} __attribute__((__packed__));
|
|
|
|
|
|
static inline void SleepMS(int someTime)
|
|
{
|
|
usleep(1000*someTime);
|
|
}
|
|
|
|
#define LT24_WIDTH 320
|
|
#define LT24_HEIGHT 240
|
|
|
|
|
|
// LT24 Interrupt control register
|
|
#define LT24_IRQ_CTRL_ENABLE_OFFSET 0
|
|
#define LT24_IRQ_CTRL_ENABLE (1 << LT24_IRQ_CTRL_ENABLE_OFFSET)
|
|
#define LT24_IRQ_CTRL_CLEAR_ON_REFRESH_OFFSET 1
|
|
#define LT24_IRQ_CTRL_CLEAR_ON_REFRESH (1 << LT24_IRQ_CTRL_CLEAR_ON_REFRESH_OFFSET)
|
|
#define LT24_IRQ_CTRL_IRQ0_ACTIVE_OFFSET 2
|
|
#define LT24_IRQ_CTRL_IRQ0_ACTIVE (1 << LT24_IRQ_CTRL_IRQ0_ACTIVE_OFFSET)
|
|
|
|
// LT24 Control register
|
|
#define LT24_CTRL_LCD_ON_OFFSET 0
|
|
#define LT24_CTRL_LCD_ON (1 << LT24_CTRL_LCD_ON_OFFSET)
|
|
#define LT24_CTRL_RST_OFFSET 1
|
|
#define LT24_CTRL_RST (1 << LT24_CTRL_RST_OFFSET)
|
|
|
|
// LT24 Read convenience functions
|
|
#define LT24_DEFINE_32_RDFUNC(funcname, fieldName) \
|
|
static inline uint32_t LT24_##funcname(struct LT24 *lcd) \
|
|
{ \
|
|
return IORD_32DIRECT(lcd, offsetof(struct LT24, fieldName)); \
|
|
}
|
|
|
|
LT24_DEFINE_32_RDFUNC(isBusy, isBusy);
|
|
|
|
// LT24 write convenience functions
|
|
#define LT24_DEFINE_16_WRFUNC(funcname, fieldName) \
|
|
static inline void LT24_##funcname(struct LT24 *lcd, uint16_t value) \
|
|
{ \
|
|
IOWR_32DIRECT(lcd, offsetof(struct LT24, fieldName), value); \
|
|
}
|
|
|
|
LT24_DEFINE_16_WRFUNC(writeReg, writeReg)
|
|
LT24_DEFINE_16_WRFUNC(writeData, writeData)
|
|
LT24_DEFINE_16_WRFUNC(writeBase, writeBase)
|
|
LT24_DEFINE_16_WRFUNC(writeCtrlReg, ctrlReg)
|
|
LT24_DEFINE_16_WRFUNC(setHeight, setHeight)
|
|
LT24_DEFINE_16_WRFUNC(setWidth, setWidth)
|
|
LT24_DEFINE_16_WRFUNC(writeIRQ, writeIRQ)
|
|
LT24_DEFINE_16_WRFUNC(setIRQ, setIRQ)
|
|
LT24_DEFINE_16_WRFUNC(clearIRQ, clearIRQ)
|
|
|
|
static inline void LT24_setCursor(struct LT24 *lcd, alt_u16 x, alt_u16 y)
|
|
{
|
|
LT24_writeReg(lcd, 0x002A);
|
|
LT24_writeData(lcd, x>>8);
|
|
LT24_writeData(lcd, x&0XFF);
|
|
LT24_writeReg(lcd, 0x002B);
|
|
LT24_writeData(lcd, y>>8);
|
|
LT24_writeData(lcd, y&0XFF);
|
|
}
|
|
|
|
static inline void LT24_refresh(struct LT24 *lcd)
|
|
{
|
|
LT24_setCursor(lcd, 0, 0); // Initialize draw position to (0,0)
|
|
LT24_writeReg(lcd, 0x2C); //Memory Write
|
|
IOWR_32DIRECT(lcd, offsetof(struct LT24, refresh), 0);
|
|
}
|
|
|
|
static inline void LT24_manualRefresh(struct LT24 *lcd, uint16_t* buffer, unsigned width, unsigned height)
|
|
{
|
|
LT24_setCursor(lcd, 0, 0); // Initialize draw position to (0,0)
|
|
LT24_writeReg(lcd, 0x2C); //Memory Write
|
|
for(int i = 0; i < width*height; i++) {
|
|
LT24_writeData(lcd, *(buffer + i));
|
|
}
|
|
}
|
|
|
|
static inline void LT24_reset(struct LT24 *lcd) {
|
|
|
|
LT24_writeCtrlReg(lcd, LT24_CTRL_LCD_ON);
|
|
SleepMS(500);
|
|
LT24_writeCtrlReg(lcd, LT24_CTRL_LCD_ON | LT24_CTRL_RST);
|
|
SleepMS(10);
|
|
LT24_writeCtrlReg(lcd, LT24_CTRL_LCD_ON);
|
|
SleepMS(120);
|
|
LT24_writeReg(lcd, 0x11); //Sleep Out
|
|
SleepMS(10); // Docs: It will be necessary to wait 5msec before sending next to command, this is to allow time for the supply voltages and clock circuits to stabilize
|
|
}
|
|
|
|
static inline void LT24_initialize(struct LT24 *lcd)
|
|
{
|
|
LT24_reset(lcd);
|
|
|
|
LT24_writeReg(lcd, 0xCF); //Power Control B
|
|
LT24_writeData(lcd, 0x00); //Always0x00
|
|
LT24_writeData(lcd, 0x81);
|
|
LT24_writeData(lcd, 0xC0);
|
|
|
|
LT24_writeReg(lcd, 0xED); //Power on sequence control
|
|
LT24_writeData(lcd, 0x64); //Soft Start Keep1 frame
|
|
LT24_writeData(lcd, 0x03);
|
|
LT24_writeData(lcd, 0X12);
|
|
LT24_writeData(lcd, 0X81);
|
|
|
|
LT24_writeReg(lcd, 0xE8); //Driver timing control A
|
|
LT24_writeData(lcd, 0x85);
|
|
LT24_writeData(lcd, 0x01);
|
|
LT24_writeData(lcd, 0x0798); // 0x00798 ???
|
|
|
|
LT24_writeReg(lcd, 0xCB); // Power control A
|
|
LT24_writeData(lcd, 0x39);
|
|
LT24_writeData(lcd, 0x2C);
|
|
LT24_writeData(lcd, 0x00);
|
|
LT24_writeData(lcd, 0x34);
|
|
LT24_writeData(lcd, 0x02);
|
|
|
|
LT24_writeReg(lcd, 0xF7); // Pumpratio control
|
|
LT24_writeData(lcd, 0x20);
|
|
|
|
LT24_writeReg(lcd, 0xEA); // Driver timing control B
|
|
LT24_writeData(lcd, 0x00);
|
|
LT24_writeData(lcd, 0x00);
|
|
|
|
LT24_writeReg(lcd, 0xB1); // Frame Control (In Normal Mode)
|
|
LT24_writeData(lcd, 0x00);
|
|
LT24_writeData(lcd, 0x1b);
|
|
|
|
LT24_writeReg(lcd, 0xB6); // Display FunctionControl
|
|
LT24_writeData(lcd, 0x0A);
|
|
LT24_writeData(lcd, 0xA2);
|
|
|
|
LT24_writeReg(lcd, 0xC0); //Power control 1
|
|
LT24_writeData(lcd, 0x05); //VRH[5:0]
|
|
|
|
LT24_writeReg(lcd, 0xC1); //Power control 2
|
|
LT24_writeData(lcd, 0x11); //SAP[2:0];BT[3:0]
|
|
|
|
LT24_writeReg(lcd, 0xC5); //VCM control 1
|
|
LT24_writeData(lcd, 0x45); //3F
|
|
LT24_writeData(lcd, 0x45); //3C
|
|
|
|
LT24_writeReg(lcd, 0xC7); //VCM control 2
|
|
LT24_writeData(lcd, 0xA2);
|
|
|
|
LT24_writeReg(lcd, 0x36); //Memory Access Control
|
|
LT24_writeData(lcd, 0x68);
|
|
|
|
LT24_writeReg(lcd, 0x2A); // Column Addr
|
|
LT24_writeData(lcd, 0x00);
|
|
LT24_writeData(lcd, 0x00);
|
|
LT24_writeData(lcd, 0x01);
|
|
LT24_writeData(lcd, 0x3F);
|
|
|
|
LT24_writeReg(lcd, 0x2B); // Page Addr
|
|
LT24_writeData(lcd, 0x00);
|
|
LT24_writeData(lcd, 0x00);
|
|
LT24_writeData(lcd, 0x00);
|
|
LT24_writeData(lcd, 0xF0);
|
|
|
|
LT24_writeReg(lcd, 0xF2); //Disable 3Gamma
|
|
LT24_writeData(lcd, 0x00);
|
|
|
|
LT24_writeReg(lcd, 0x26); //Gamma Curve Selected
|
|
LT24_writeData(lcd, 0x01);
|
|
|
|
LT24_writeReg(lcd, 0xE0); //Positive Gamma Correction, Set Gamma
|
|
LT24_writeData(lcd, 0x0F);
|
|
LT24_writeData(lcd, 0x26);
|
|
LT24_writeData(lcd, 0x24);
|
|
LT24_writeData(lcd, 0x0B);
|
|
LT24_writeData(lcd, 0x0E);
|
|
LT24_writeData(lcd, 0x08);
|
|
LT24_writeData(lcd, 0x4B);
|
|
LT24_writeData(lcd, 0XA8);
|
|
LT24_writeData(lcd, 0x3B);
|
|
LT24_writeData(lcd, 0x0A);
|
|
LT24_writeData(lcd, 0x14);
|
|
LT24_writeData(lcd, 0x06);
|
|
LT24_writeData(lcd, 0x10);
|
|
LT24_writeData(lcd, 0x09);
|
|
LT24_writeData(lcd, 0x00);
|
|
|
|
LT24_writeReg(lcd, 0XE1); //NegativeGamma Correction, Set Gamma
|
|
LT24_writeData(lcd, 0x00);
|
|
LT24_writeData(lcd, 0x1C);
|
|
LT24_writeData(lcd, 0x20);
|
|
LT24_writeData(lcd, 0x04);
|
|
LT24_writeData(lcd, 0x10);
|
|
LT24_writeData(lcd, 0x08);
|
|
LT24_writeData(lcd, 0x34);
|
|
LT24_writeData(lcd, 0x47);
|
|
LT24_writeData(lcd, 0x44);
|
|
LT24_writeData(lcd, 0x05);
|
|
LT24_writeData(lcd, 0x0B);
|
|
LT24_writeData(lcd, 0x09);
|
|
LT24_writeData(lcd, 0x2F);
|
|
LT24_writeData(lcd, 0x36);
|
|
LT24_writeData(lcd, 0x0F);
|
|
|
|
LT24_writeReg(lcd, 0x3A); //COLMOD: Pixel Format Set
|
|
LT24_writeData(lcd, 0x55);
|
|
|
|
LT24_writeReg(lcd, 0xF6); //Interface Control
|
|
LT24_writeData(lcd, 0x01);
|
|
LT24_writeData(lcd, 0x30);
|
|
LT24_writeData(lcd, 0x00);
|
|
|
|
LT24_writeReg(lcd, 0x29); //Display on
|
|
|
|
LT24_setCursor(lcd, 0, 0); // Initialize draw position to (0,0)
|
|
|
|
LT24_writeReg(lcd, 0x2C); //Memory Write
|
|
}
|