2022-04-07 18:46:57 +02:00

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
}