301 lines
8.9 KiB
C
301 lines
8.9 KiB
C
/***************************************************************************
|
|
* Copyright (C) 2024 by Silvano Seva IU2KWO *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 3 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/> *
|
|
***************************************************************************/
|
|
|
|
#include <peripherals/gpio.h>
|
|
#include <interfaces/display.h>
|
|
#include <interfaces/delays.h>
|
|
#include <interfaces/platform.h>
|
|
#include <backlight.h>
|
|
#include <hwconfig.h>
|
|
#include <string.h>
|
|
|
|
enum ST775RCmd
|
|
{
|
|
ST775R_CMD_NOP = 0x00,
|
|
ST775R_CMD_SWRESET = 0x01,
|
|
ST775R_CMD_RDID = 0x04,
|
|
ST775R_CMD_RDDST = 0x09,
|
|
ST775R_CMD_RDDPM = 0x0A,
|
|
ST775R_CMD_RDDMADCTL = 0x0B,
|
|
ST775R_CMD_RDDCOLMOD = 0x0C,
|
|
ST775R_CMD_RDDIM = 0x0D,
|
|
ST775R_CMD_RDDSM = 0x0E,
|
|
ST775R_CMD_SLPIN = 0x10,
|
|
ST775R_CMD_SLPOUT = 0x11,
|
|
ST775R_CMD_PTLON = 0x12,
|
|
ST775R_CMD_NORON = 0x13,
|
|
ST775R_CMD_INVOFF = 0x20,
|
|
ST775R_CMD_INVON = 0x21,
|
|
ST775R_CMD_GAMSET = 0x26,
|
|
ST775R_CMD_DISPOFF = 0x28,
|
|
ST775R_CMD_DISPON = 0x29,
|
|
ST775R_CMD_CASET = 0x2A,
|
|
ST775R_CMD_RASET = 0x2B,
|
|
ST775R_CMD_RAMWR = 0x2C,
|
|
ST775R_CMD_RGBSET = 0x2D,
|
|
ST775R_CMD_RAMRD = 0x2E,
|
|
ST775R_CMD_PTLAR = 0x30,
|
|
ST775R_CMD_TEOFF = 0x34,
|
|
ST775R_CMD_TEON = 0x35,
|
|
ST775R_CMD_MADCTL = 0x36,
|
|
ST775R_CMD_IDMOFF = 0x38,
|
|
ST775R_CMD_IDMON = 0x39,
|
|
ST775R_CMD_COLMOD = 0x3A,
|
|
ST775R_CMD_RDID1 = 0xDA,
|
|
ST775R_CMD_RDID2 = 0xDB,
|
|
ST775R_CMD_RDID3 = 0xDC
|
|
};
|
|
|
|
static inline void sendCmd(uint8_t cmd)
|
|
{
|
|
// Set D/C low (command mode), clear WR and data lines
|
|
GPIOD->BSRR = 0x30FF0000;
|
|
#ifdef PLATFORM_CS7000P
|
|
asm volatile(" mov r1, #65 \n"
|
|
#else
|
|
asm volatile(" mov r1, #21 \n"
|
|
#endif
|
|
"___loop_d: cmp r1, #0 \n"
|
|
" itt ne \n"
|
|
" subne r1, r1, #1 \n"
|
|
" bne ___loop_d \n":::"r1");
|
|
GPIOD->BSRR = cmd | (1 << 13);
|
|
}
|
|
|
|
static inline void sendData(uint8_t val)
|
|
{
|
|
// Set D/C high (data mode), clear WR and data lines
|
|
GPIOD->BSRR = 0x20FF1000;
|
|
#ifdef PLATFORM_CS7000P
|
|
asm volatile(" mov r1, #65 \n"
|
|
#else
|
|
asm volatile(" mov r1, #21 \n"
|
|
#endif
|
|
"___loop_e: cmp r1, #0 \n"
|
|
" itt ne \n"
|
|
" subne r1, r1, #1 \n"
|
|
" bne ___loop_e \n":::"r1");
|
|
GPIOD->BSRR = val | (1 << 13);
|
|
}
|
|
|
|
void display_init()
|
|
{
|
|
backlight_init();
|
|
|
|
/* Set up gpios */
|
|
gpio_setMode(LCD_D0, OUTPUT);
|
|
gpio_setMode(LCD_D1, OUTPUT);
|
|
gpio_setMode(LCD_D2, OUTPUT);
|
|
gpio_setMode(LCD_D3, OUTPUT);
|
|
gpio_setMode(LCD_D4, OUTPUT);
|
|
gpio_setMode(LCD_D5, OUTPUT);
|
|
gpio_setMode(LCD_D6, OUTPUT);
|
|
gpio_setMode(LCD_D7, OUTPUT);
|
|
gpio_setMode(LCD_WR, OUTPUT);
|
|
gpio_setMode(LCD_RD, OUTPUT);
|
|
gpio_setMode(LCD_DC, OUTPUT);
|
|
gpio_setMode(LCD_RST, OUTPUT);
|
|
gpio_setMode(LCD_CS, OUTPUT);
|
|
|
|
gpio_setOutputSpeed(LCD_D0, HIGH);
|
|
gpio_setOutputSpeed(LCD_D1, HIGH);
|
|
gpio_setOutputSpeed(LCD_D2, HIGH);
|
|
gpio_setOutputSpeed(LCD_D3, HIGH);
|
|
gpio_setOutputSpeed(LCD_D4, HIGH);
|
|
gpio_setOutputSpeed(LCD_D5, HIGH);
|
|
gpio_setOutputSpeed(LCD_D6, HIGH);
|
|
gpio_setOutputSpeed(LCD_D7, HIGH);
|
|
gpio_setOutputSpeed(LCD_WR, HIGH);
|
|
gpio_setOutputSpeed(LCD_RD, HIGH);
|
|
gpio_setOutputSpeed(LCD_DC, HIGH);
|
|
gpio_setOutputSpeed(LCD_RST, HIGH);
|
|
gpio_setOutputSpeed(LCD_CS, HIGH);
|
|
|
|
gpio_clearPin(LCD_RST); /* Put LCD in reset mode */
|
|
gpio_setPin(LCD_CS); /* CS idle state is high level */
|
|
gpio_setPin(LCD_DC); /* Idle state for DC line */
|
|
gpio_setPin(LCD_WR); /* Idle state for WR line */
|
|
gpio_setPin(LCD_RD); /* Idle state for RD line */
|
|
gpio_setPin(LCD_RST); /* Exit from reset */
|
|
|
|
delayMs(10);
|
|
|
|
gpio_clearPin(LCD_CS);
|
|
|
|
sendCmd(ST775R_CMD_SWRESET);
|
|
sendCmd(0xb1); /* Undocumented command */
|
|
sendData(5);
|
|
sendData(8);
|
|
sendData(5);
|
|
sendCmd(0xb2); /* Undocumented command */
|
|
sendData(5);
|
|
sendData(8);
|
|
sendData(5);
|
|
sendCmd(0xb3); /* Undocumented command */
|
|
sendData(5);
|
|
sendData(8);
|
|
sendData(5);
|
|
sendData(5);
|
|
sendData(8);
|
|
sendData(5);
|
|
sendCmd(0xb4); /* Undocumented command */
|
|
sendData(0);
|
|
sendCmd(0xb6); /* Undocumented command */
|
|
sendData(0xb4);
|
|
sendData(0xf0);
|
|
sendCmd(0xc0); /* Undocumented command */
|
|
sendData(0xa2);
|
|
sendData(2);
|
|
/* sendData(0x85); TODO: see original fw */
|
|
sendData(0x84);
|
|
sendCmd(0xc1); /* Undocumented command */
|
|
sendData(5);
|
|
sendCmd(0xc2); /* Undocumented command */
|
|
sendData(10);
|
|
sendData(0);
|
|
sendCmd(0xc3); /* Undocumented command */
|
|
sendData(0x8a);
|
|
sendData(0x2a);
|
|
sendCmd(0xc4); /* Undocumented command */
|
|
sendData(0x8a);
|
|
sendData(0xee);
|
|
sendCmd(0xc5); /* Undocumented command */
|
|
sendData(0xe);
|
|
sendCmd(ST775R_CMD_MADCTL);
|
|
sendData(0xB0);
|
|
sendCmd(0xe0); /* Undocumented command */
|
|
sendData(5);
|
|
/* sendData(0x28); TODO: see original fw */
|
|
/* sendData(0x28); TODO: see original fw */
|
|
sendData(0x16);
|
|
sendData(0xf);
|
|
sendData(0x18);
|
|
sendData(0x2f);
|
|
sendData(0x28);
|
|
sendData(0x20);
|
|
sendData(0x22);
|
|
sendData(0x1f);
|
|
sendData(0x1b);
|
|
sendData(0x23);
|
|
sendData(0x37);
|
|
sendData(0);
|
|
sendData(7);
|
|
sendData(2);
|
|
sendData(0x10);
|
|
sendCmd(0xe1); /* Undocumented command */
|
|
sendData(7);
|
|
/* sendData(0x28); TODO: see original fw */
|
|
/* sendData(0x28); TODO: see original fw */
|
|
sendData(0x1b);
|
|
sendData(0xf);
|
|
sendData(0x17);
|
|
sendData(0x33);
|
|
sendData(0x2c);
|
|
sendData(0x29);
|
|
sendData(0x2e);
|
|
sendData(0x30);
|
|
sendData(0x30);
|
|
sendData(0x39);
|
|
sendData(0x3f);
|
|
sendData(0);
|
|
sendData(7);
|
|
sendData(3);
|
|
sendData(0x10);
|
|
sendCmd(0xf0); /* Undocumented command */
|
|
sendData(1);
|
|
sendCmd(0xf6); /* Undocumented command */
|
|
sendData(0);
|
|
sendCmd(ST775R_CMD_COLMOD);
|
|
sendData(0x05); /* 16bpp - RGB 565 */
|
|
sendCmd(ST775R_CMD_RASET);
|
|
sendData(0);
|
|
sendData(0);
|
|
sendData(0);
|
|
sendData(0x7f); /* 128 rows */
|
|
sendCmd(ST775R_CMD_CASET);
|
|
sendData(0);
|
|
sendData(0);
|
|
sendData(0);
|
|
sendData(0x9f); /* 160 columns */
|
|
|
|
/* Exit from sleep */
|
|
sendCmd(ST775R_CMD_SLPOUT);
|
|
delayMs(120);
|
|
|
|
/* Enable display */
|
|
sendCmd(ST775R_CMD_DISPON);
|
|
|
|
gpio_setPin(LCD_CS);
|
|
}
|
|
|
|
void display_terminate()
|
|
{
|
|
}
|
|
|
|
void display_renderRows(uint8_t startRow, uint8_t endRow, void *fb)
|
|
{
|
|
/*
|
|
* Put screen data lines back to output mode, since they are in common with
|
|
* keyboard buttons and the keyboard driver sets them as inputs.
|
|
*/
|
|
gpio_setMode(LCD_D0, OUTPUT);
|
|
gpio_setMode(LCD_D1, OUTPUT);
|
|
gpio_setMode(LCD_D2, OUTPUT);
|
|
gpio_setMode(LCD_D3, OUTPUT);
|
|
gpio_setMode(LCD_D4, OUTPUT);
|
|
gpio_setMode(LCD_D5, OUTPUT);
|
|
gpio_setMode(LCD_D6, OUTPUT);
|
|
gpio_setMode(LCD_D7, OUTPUT);
|
|
|
|
/*
|
|
* Select the display, configure start and end rows in display driver and
|
|
* write to display memory.
|
|
*/
|
|
gpio_clearPin(LCD_CS);
|
|
|
|
sendCmd(ST775R_CMD_RASET);
|
|
sendData(0x00);
|
|
sendData(startRow);
|
|
sendData(0x00);
|
|
sendData(endRow);
|
|
sendCmd(ST775R_CMD_RAMWR);
|
|
|
|
for(uint8_t y = startRow; y < endRow; y++)
|
|
{
|
|
for(uint8_t x = 0; x < CONFIG_SCREEN_WIDTH; x++)
|
|
{
|
|
size_t pos = x + y * CONFIG_SCREEN_WIDTH;
|
|
uint16_t pixel = ((uint16_t *) fb)[pos];
|
|
sendData((pixel >> 8) & 0xff);
|
|
sendData(pixel & 0xff);
|
|
}
|
|
}
|
|
|
|
gpio_setPin(LCD_CS);
|
|
}
|
|
|
|
void display_render(void *fb)
|
|
{
|
|
display_renderRows(0, CONFIG_SCREEN_HEIGHT, fb);
|
|
}
|
|
|
|
void display_setContrast(uint8_t contrast)
|
|
{
|
|
/* This controller does not support contrast regulation */
|
|
(void) contrast;
|
|
}
|