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