#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 }