参考 SF32快速点屏指南
代码如下
/**
******************************************************************************
* @file ST77916.c
* @author Sifli software development team
* @brief This file includes the LCD driver for ST77916 LCD.
* @attention
******************************************************************************
*/
/**
* @attention
* Copyright (c) 2019 - 2022, Sifli Technology
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Sifli integrated circuit
* in a product or a software update for such product, must reproduce the above
* copyright notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of Sifli nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Sifli integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY SIFLI TECHNOLOGY "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL SIFLI TECHNOLOGY OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <rtthread.h>
#include "string.h"
#include "board.h"
#include "drv_io.h"
#include "drv_lcd.h"
#include "log.h"
#define ROW_OFFSET (0x00)
#define COL_OFFSET (0x00)
/**
* @brief ST77916 chip IDs
*/
#define THE_LCD_ID 0x61977
/**
* @brief ST77916 Size
*/
#define THE_LCD_PIXEL_WIDTH ((uint16_t)360)
#define THE_LCD_PIXEL_HEIGHT ((uint16_t)360)
/**
* @brief ST77916 Registers
*/
#define REG_LCD_ID 0xDB /*Read ID1 , Read ID2 DBh , Read ID3 DCh*/
#define REG_POWER_MODE 0x09
#define REG_SLEEP_IN 0x10 /* Dispaly Sleep IN*/
#define REG_SLEEP_OUT 0x11 /* Dispaly Sleep OUT*/
#define REG_PARTIAL_DISPLAY 0x12
#define REG_DISPLAY_INVERSION 0x21
#define REG_DISPLAY_OFF 0x28 /* Display Off*/
#define REG_DISPLAY_ON 0x29 /* Display On */
#define REG_WRITE_RAM 0x2C
#define REG_READ_RAM 0x2E
#define REG_CASET 0x2A
#define REG_RASET 0x2B
#define REG_SWRESET 0x01
#define REG_TEARING_EFFECT 0x35
#define REG_IDLE_MODE_OFF 0x38
#define REG_IDLE_MODE_ON 0x39
#define REG_COLOR_MODE 0x3A
#define REG_WBRIGHT 0x51
#define REG_MACTL 0x36
#define REG_VDV_VRH_EN 0xC2
#define REG_VDV_SET 0xC4
#define DEBUG
#ifdef DEBUG
#define DEBUG_PRINTF(...) LOG_I(__VA_ARGS__)
#else
#define DEBUG_PRINTF(...)
#endif
static void LCD_WriteReg(LCDC_HandleTypeDef *hlcdc, uint16_t LCD_Reg, uint8_t *Parameters, uint32_t NbParameters);
static uint32_t LCD_ReadData(LCDC_HandleTypeDef *hlcdc, uint16_t RegValue, uint8_t ReadSize);
static uint32_t LCD_ESDCehck(LCDC_HandleTypeDef *hlcdc);
static void LCD_TimeoutDbg(LCDC_HandleTypeDef *hlcdc);
static void LCD_TimeoutReset(LCDC_HandleTypeDef *hlcdc);
#define QAD_SPI_ITF LCDC_INTF_SPI_DCX_4DATA
/**
* @brief
*
*/
static LCDC_InitTypeDef lcdc_int_cfg =
{
.lcd_itf = QAD_SPI_ITF,
.freq = 60000000,
.color_mode = LCDC_PIXEL_FORMAT_RGB565,
.cfg = {
.spi = {
.dummy_clock = 1, //fixme : dafult : 0
#ifdef LCD_ST77916_VSYNC_ENABLE
.syn_mode = HAL_LCDC_SYNC_VER, //open TE
#else
.syn_mode = HAL_LCDC_SYNC_DISABLE,
#endif
.vsyn_polarity = 1,
//default_vbp=2, frame rate=82, delay=115us,
//TODO: use us to define delay instead of cycle, delay_cycle=115*48
.vsyn_delay_us = 0, //fixme : dafult : 100
.hsyn_num = 0, //fixme : dafult : 100
},
},
};
#define MAX_CMD_LEN 16
#if 1
static const uint8_t lcd_init_cmds[][MAX_CMD_LEN] =
{
{0xF0,1, 0x28},
{0xF2,1, 0x28},
{0x73,1, 0xF0},
{0x7C,1, 0xD1},
{0x83,1, 0xE0},
{0x84,1, 0x61},
{0xF2,1, 0x82},
{0xF0,1, 0x00},
{0xF0,1, 0x01},
{0xF1,1, 0x01},
{0xB0,1, 0x40},
{0xB1,1, 0x33},
{0xB2,1, 0x26},
{0xB4,1, 0x66},
{0xB5,1, 0x44},
{0xB6,1, 0xA5},
{0xB7,1, 0x40},
{0xB8,1, 0x8C},
{0xBA,1, 0x00},
{0xBB,1, 0x08},
{0xBC,1, 0x08},
{0xBD,1, 0x00},
{0xC0,1, 0x80},
{0xC1,1, 0x10},
{0xC2,1, 0x37},
{0xC3,1, 0x80},
{0xC4,1, 0x10},
{0xC5,1, 0x37},
{0xC6,1, 0xA9},
{0xC7,1, 0x41},
{0xC8,1, 0x01},
{0xC9,1, 0xA9},
{0xCA,1, 0x41},
{0xCB,1, 0x01},
{0xCD,1, 0x7F},
{0xD0,1, 0x91},
{0xD1,1, 0x68},
{0xD2,1, 0x68},
{ 0xF5,2,0x00, 0xA5},
{0xF1, 1,0x10},
{0xF0, 1,0x00},
{0xF0, 1,0x02},
{0xE0,14,
0xF0 , 0x06,
0x0B , 0x09,
0x09 , 0x16,
0x32 , 0x44,
0x4A , 0x37,
0x13 , 0x13,
0x2E , 0x34},
{0xE1, 14,
0xF0 , 0x06,
0x0B , 0x09,
0x08 , 0x05,
0x32 , 0x33,
0x49 , 0x17,
0x13 , 0x13,
0x2E , 0x34},
{0X35,1, 0X00},
{0xF0,1, 0x10},
{0xF3,1, 0x10},
{0xE0,1, 0x0A},
{0xE1,1, 0x00},
{0xE2,1, 0x00},
{0xE3,1, 0x00},
{0xE4,1, 0xE0},
{0xE5,1, 0x06},
{0xE6,1, 0x21},
{0xE7,1, 0x00},
{0xE8,1, 0x05},
{0xE9,1, 0xF2},
{0xEA,1, 0xDF},
{0xEB,1, 0x80},
{0xEC,1, 0x26},
{0xED,1, 0x14},
{0xEE,1, 0xFF},
{0xEF,1, 0x00},
{0xF8,1, 0xFF},
{0xF9,1, 0x00},
{0xFA,1, 0x00},
{0xFB,1, 0x30},
{0xFC,1, 0x00},
{0xFD,1, 0x00},
{0xFE,1, 0x00},
{0xFF,1, 0x00},
{0x60,1, 0x42},
{0x61,1, 0xE0},
{0x62,1, 0x40},
{0x63,1, 0x40},
{0x64,1, 0x02},
{0x65,1, 0x00},
{0x66,1, 0x40},
{0x67,1, 0x03},
{0x68,1, 0x00},
{0x69,1, 0x00},
{0x6A,1, 0x00},
{0x6B,1, 0x00},
{0x70,1, 0x42},
{0x71,1, 0xE0},
{0x72,1, 0x40},
{0x73,1, 0x40},
{0x74,1, 0x02},
{0x75,1, 0x00},
{0x76,1, 0x40},
{0x77,1, 0x03},
{0x78,1, 0x00},
{0x79,1, 0x00},
{0x7A,1, 0x00},
{0x7B,1, 0x00},
{0x80,1, 0x48},
{0x81,1, 0x00},
{0x82,1, 0x05},
{0x83,1, 0x02},
{0x84,1, 0xDD},
{0x85,1, 0x00},
{0x86,1, 0x00},
{0x87,1, 0x00},
{0x88,1, 0x48},
{0x89,1, 0x00},
{0x8A,1, 0x07},
{0x8B,1, 0x02},
{0x8C,1, 0xDF},
{0x8D,1, 0x00},
{0x8E,1, 0x00},
{0x8F,1, 0x00},
{0x90,1, 0x48},
{0x91,1, 0x00},
{0x92,1, 0x09},
{0x93,1, 0x02},
{0x94,1, 0xE1},
{0x95,1, 0x00},
{0x96,1, 0x00},
{0x97,1, 0x00},
{0x98,1, 0x48},
{0x99,1, 0x00},
{0x9A,1, 0x0B},
{0x9B,1, 0x02},
{0x9C,1, 0xE3},
{0x9D,1, 0x00},
{0x9E,1, 0x00},
{0x9F,1, 0x00},
{0xA0,1, 0x48},
{0xA1,1, 0x00},
{0xA2,1, 0x04},
{0xA3,1, 0x02},
{0xA4,1, 0xDC},
{0xA5,1, 0x00},
{0xA6,1, 0x00},
{0xA7,1, 0x00},
{0xA8,1, 0x48},
{0xA9,1, 0x00},
{0xAA,1, 0x06},
{0xAB,1, 0x02},
{0xAC,1, 0xDE},
{0xAD,1, 0x00},
{0xAE,1, 0x00},
{0xAF,1, 0x00},
{0xB0,1, 0x48},
{0xB1,1, 0x00},
{0xB2,1, 0x08},
{0xB3,1, 0x02},
{0xB4,1, 0xE0},
{0xB5,1, 0x00},
{0xB6,1, 0x00},
{0xB7,1, 0x00},
{0xB8,1, 0x48},
{0xB9,1, 0x00},
{0xBA,1, 0x0A},
{0xBB,1, 0x02},
{0xBC,1, 0xE2},
{0xBD,1, 0x00},
{0xBE,1, 0x00},
{0xBF,1, 0x00},
{0xC0,1, 0x22},
{0xC1,1, 0x98},
{0xC2,1, 0x65},
{0xC3,1, 0x74},
{0xC4,1, 0x47},
{0xC5,1, 0x56},
{0xC6,1, 0x00},
{0xC7,1, 0xBA},
{0xC8,1, 0xAB},
{0xC9,1, 0x33},
{0xD0,1, 0x11},
{0xD1,1, 0x98},
{0xD2,1, 0x65},
{0xD3,1, 0x74},
{0xD4,1, 0x47},
{0xD5,1, 0x56},
{0xD6,1, 0x00},
{0xD7,1, 0xBA},
{0xD8,1, 0xAB},
{0xD9,1, 0x33},
{0xF3,1, 0x01},
{0xF0,1, 0x00},
{0x21,1, 0x00},
{0x3A,1, 0x55},
{0x11,1, 0x00},
};
//Display 1, color bar to check LCD ok.
static const uint8_t bist_cmds[][MAX_CMD_LEN] =
{
{0xf0, 1, 0xa5},
{0xb0, 1, 0xa5},
{0xcc, 9, 0x40, 0x00, 0x3f, 0x01, 0x06, 0x06, 0x55, 0x55, 0x00},
};
#else
static const uint8_t lcd_init_cmds[][MAX_CMD_LEN] =
{
{ 0xf0, 1, 0xc3},
{ 0xf0, 1, 0x96},
{ 0xf0, 1, 0xa5},
{ 0xe9, 1, 0x20},
{ 0xe7, 4, 0x80, 0x77, 0x1f, 0xcc},
{ 0xc1, 4, 0x77, 0x07, 0xcf, 0x16},
{ 0xc2, 4, 0x77, 0x07, 0xcf, 0x16},
{ 0xc3, 4, 0x22, 0x02, 0x22, 0x04},
{ 0xc4, 4, 0x22, 0x02, 0x22, 0x04},
{ 0xc5, 1, 0xed},
{ 0xe0, 14, 0x87, 0x09, 0x0c, 0x06, 0x05, 0x03, 0x29, 0x32, 0x49, 0x0f, 0x1b, 0x17, 0x2a, 0x2f},
{ 0xe1, 14, 0x87, 0x09, 0x0c, 0x06, 0x05, 0x03, 0x29, 0x32, 0x49, 0x0f, 0x1b, 0x17, 0x2a, 0x2f},
{ 0xe5, 14, 0xbe, 0xf5, 0xb1, 0x22, 0x22, 0x25, 0x10, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22},
{ 0xe6, 14, 0xbe, 0xf5, 0xb1, 0x22, 0x22, 0x25, 0x10, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22},
{ 0xec, 2, 0x40, 0x03},
{ 0x36, 1, 0x0c},
{ 0x3a, 1, 0x05}, //0x07-rgb888 05-rgb565
{ 0xb2, 1, 0x00},
{ 0xb3, 1, 0x01},
{ 0xb4, 1, 0x00},
{ 0xb5, 4, 0x00, 0x08, 0x00, 0x08},
{ 0xa5, 9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x2a, 0x8a, 0x02},
{ 0xa6, 9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x2a, 0x8a, 0x02},
{ 0xba, 7, 0x0a, 0x5a, 0x23, 0x10, 0x25, 0x02, 0x00},
{ 0xbb, 8, 0x00, 0x30, 0x00, 0x2c, 0x82, 0x87, 0x18, 0x00},
{ 0xbc, 8, 0x00, 0x30, 0x00, 0x2c, 0x82, 0x87, 0x18, 0x00},
{ 0xbd, 11, 0xa1, 0xb2, 0x2b, 0x1a, 0x56, 0x43, 0x34, 0x65, 0xff, 0xff, 0x0f}
};
//Display color bar to check LCD ok.
static const uint8_t bist_cmds[][MAX_CMD_LEN] =
{
{0xb0, 1, 0xa5},
{0xcc, 9, 0x40, 0x00, 0x3f, 0x00, 0x14, 0x14, 0x20, 0x20, 0x03},
};
#endif
/**
* @brief spi read/write mode
* @param enable: false - write spi mode | true - read spi mode
* @retval None
*/
static void LCD_ReadMode(LCDC_HandleTypeDef *hlcdc, bool enable)
{
if (HAL_LCDC_IS_SPI_IF(lcdc_int_cfg.lcd_itf))
{
if (enable)
{
HAL_LCDC_SetFreq(hlcdc, 4000000); //read mode min cycle 300ns
}
else
{
HAL_LCDC_SetFreq(hlcdc, lcdc_int_cfg.freq); //Restore normal frequency
}
}
}
/**
* @brief Power on the LCD.
* @param None
* @retval None
*/
static void LCD_Init(LCDC_HandleTypeDef *hlcdc)
{
uint8_t parameter[14];
memcpy(&hlcdc->Init, &lcdc_int_cfg, sizeof(LCDC_InitTypeDef));
HAL_LCDC_Init(hlcdc);
#if 1
BSP_LCD_Reset(1);//Reset LCD
LCD_DRIVER_DELAY_MS(100);
BSP_LCD_Reset(0);
LCD_DRIVER_DELAY_MS(120);
BSP_LCD_Reset(1);
LCD_DRIVER_DELAY_MS(120);
#else
// software_reset
LCD_WriteReg(hlcdc, REG_SWRESET, (uint8_t *)NULL, 0);
LCD_DRIVER_DELAY_MS(120);
#endif
for (int i = 0; i < sizeof(lcd_init_cmds) / MAX_CMD_LEN; i++)
{
//rt_kprintf("write %d,cmd=0x%x,len=%d\n",i,(int)lcd_init_cmds[i][0], (int)lcd_init_cmds[i][1]);
//HAL_DBG_print_data((char*)&(lcd_init_cmds[i][2]),0,(int)lcd_init_cmds[i][1]);
LCD_WriteReg(hlcdc, lcd_init_cmds[i][0], (uint8_t *)&lcd_init_cmds[i][2], lcd_init_cmds[i][1]);
}
#ifdef LCD_ST77916_VSYNC_ENABLE
LCD_DRIVER_DELAY_MS(80);
rt_kprintf("Enable V-Blanking TE signal\n");
// 启用 TE 指令
parameter[0] = 0x01; // 00h: VSYNC Only , 01h:VSYNC&HSYNC
LCD_WriteReg(hlcdc, REG_TEARING_EFFECT, parameter, 1);
#endif
LCD_DRIVER_DELAY_MS(100);
// tag:...................
parameter[0] = 0x00;
LCD_WriteReg(hlcdc, REG_DISPLAY_ON, parameter, 1); /* Display On */
//tag:............
#if 0
HAL_LCDC_SetROIArea(hlcdc, 0, 0, LCD_HOR_RES_MAX - 1, LCD_VER_RES_MAX - 1);
{
uint32_t data;
data = LCD_ReadData(hlcdc, REG_LCD_ID, 4);
DEBUG_PRINTF("ST77916_ReadID 0x%x \n", data);
data = LCD_ReadData(hlcdc, REG_POWER_MODE, 4);
DEBUG_PRINTF("ST77916_ReadPowerMode 0x%x \n", data);
}
#endif
}
/**
* @brief Disables the Display.
* @param None
* @retval LCD Register Value.
*/
static uint32_t LCD_ReadID(LCDC_HandleTypeDef *hlcdc)
{
uint32_t data;
data = LCD_ReadData(hlcdc, REG_LCD_ID, 4);
DEBUG_PRINTF("ST77916_ReadID 0x%x \n", data);
// data = ((data << 1) >> 8) & 0xFFFFFF;
if (data)
{
DEBUG_PRINTF("LCD module use ST77916 IC \n");
data = THE_LCD_ID;
}
return THE_LCD_ID;
}
/**
* @brief Enables the Display.
* @param None
* @retval None
*/
static void LCD_DisplayOn(LCDC_HandleTypeDef *hlcdc)
{
/* Display On */
LCD_WriteReg(hlcdc, REG_SLEEP_OUT, (uint8_t *)NULL, 0);
/* Wait for 120ms */
LCD_DRIVER_DELAY_MS(100);
}
/**
* @brief Disables the Display.
* @param None
* @retval None
*/
static void LCD_DisplayOff(LCDC_HandleTypeDef *hlcdc)
{
/* Display Off */
LCD_WriteReg(hlcdc, REG_SLEEP_IN, (uint8_t *)NULL, 0);
/* Wait for 120ms */
LCD_DRIVER_DELAY_MS(100);
}
/**
* @brief set display windown
*
*/
static void LCD_SetRegion(LCDC_HandleTypeDef *hlcdc, uint16_t Xpos0, uint16_t Ypos0, uint16_t Xpos1, uint16_t Ypos1)
{
/*
0x2A & 0X2B is invalid for ST77916
*/
uint8_t parameter[4];
//Set LCDC clip area
HAL_LCDC_SetROIArea(hlcdc, Xpos0, Ypos0, Xpos1, Ypos1);
Xpos0 += COL_OFFSET;
Xpos1 += COL_OFFSET;
Ypos0 += ROW_OFFSET;
Ypos1 += ROW_OFFSET;
parameter[0] = (Xpos0) >> 8;
parameter[1] = (Xpos0) & 0xFF;
parameter[2] = (Xpos1) >> 8;
parameter[3] = (Xpos1) & 0xFF;
LCD_WriteReg(hlcdc, REG_CASET, parameter, 4);
parameter[0] = (Ypos0) >> 8;
parameter[1] = (Ypos0) & 0xFF;
parameter[2] = (Ypos1) >> 8;
parameter[3] = (Ypos1) & 0xFF;
LCD_WriteReg(hlcdc, REG_RASET, parameter, 4);
}
/**
* @brief Writes pixel.
* @param Xpos: specifies the X position.
* @param Ypos: specifies the Y position.
* @param RGBCode: the RGB pixel color
* @retval None
*/
static void LCD_WritePixel(LCDC_HandleTypeDef *hlcdc, uint16_t Xpos, uint16_t Ypos, const uint8_t *RGBCode)
{
uint8_t data = 0;
rt_kprintf("\n ST77916_WritePixel xpos=%d, ypos=%d\n", Xpos, Ypos);
if ((Xpos >= THE_LCD_PIXEL_WIDTH) || (Ypos >= THE_LCD_PIXEL_HEIGHT))
{
return;
}
/* Set Cursor */
LCD_SetRegion(hlcdc, Xpos, Ypos, Xpos, Ypos);
LCD_WriteReg(hlcdc, REG_WRITE_RAM, (uint8_t *)RGBCode, 2);
}
#if 0
void ST77916_WriteMultiplePixels_mcu(LCDC_HandleTypeDef *hlcdc, const uint8_t *RGBCode, uint16_t Xpos0, uint16_t Ypos0, uint16_t Xpos1, uint16_t Ypos1)
{
uint32_t size;
if ((Xpos0 >= THE_LCD_PIXEL_WIDTH) || (Ypos0 >= THE_LCD_PIXEL_HEIGHT)
|| (Xpos1 >= THE_LCD_PIXEL_WIDTH) || (Ypos1 >= THE_LCD_PIXEL_HEIGHT))
{
return;
}
if ((Xpos0 > Xpos1) || (Ypos0 > Ypos1))
{
return;
}
if (LCDC_INTF_SPI_DCX_4DATA_AUX == lcdc_int_cfg.lcd_itf)
{
HAL_LCDC_LayerSetData(hlcdc, HAL_LCDC_LAYER_DEFAULT, (uint8_t *)RGBCode, Xpos0, Ypos0, Xpos1, Ypos1);
while (1)
{
/*
1line data ----(must > 40us, include Vporch line)------> 1line data
1 frame ------(must > 1ms)---------------> 1 frame
*/
HAL_LCDC_WriteU32Reg(hlcdc, 0xDE006100, 0, 0);
HAL_Delay_us(40); //Must delay 40us
for (uint32_t back_porch = 7; back_porch > 0; back_porch--)
{
HAL_LCDC_WriteU32Reg(hlcdc, 0xDE006000, 0, 0);
HAL_Delay_us(40);//Must delay 40us
}
for (uint16_t row = Ypos0; row < Ypos1; row++)
{
HAL_LCDC_SetROIArea(hlcdc, Xpos0, row, Xpos1, row);
HAL_LCDC_SendLayerData2Reg_IT(hlcdc, 0xDE006000, 4);
//Must delay 40us
}
for (uint32_t front_porch = 8; front_porch > 0; front_porch--)
{
HAL_LCDC_WriteU32Reg(hlcdc, 0xDE006000, 0, 0);
HAL_Delay_us(40); //Must delay 40us
}
LCD_DRIVER_DELAY_MS(1); //Must delay 1ms
}
}
else
{
HAL_LCDC_LayerSetData(hlcdc, HAL_LCDC_LAYER_DEFAULT, (uint8_t *)RGBCode, Xpos0, Ypos0, Xpos1, Ypos1);
HAL_LCDC_SendLayerData2Reg_IT(hlcdc, REG_WRITE_RAM, 1);
}
}
#endif
//tag: 02-20 20:07:11:930 [101034] E/drv.lcd lcd_task: draw_core timeout
static void LCD_WriteMultiplePixels(LCDC_HandleTypeDef *hlcdc, const uint8_t *RGBCode, uint16_t Xpos0, uint16_t Ypos0, uint16_t Xpos1, uint16_t Ypos1)
{
uint32_t size;
HAL_LCDC_LayerSetData(hlcdc, HAL_LCDC_LAYER_DEFAULT, (uint8_t *)RGBCode, Xpos0, Ypos0, Xpos1, Ypos1);
if (QAD_SPI_ITF == lcdc_int_cfg.lcd_itf)
{
HAL_LCDC_SendLayerData2Reg_IT(hlcdc, ((0x32 << 24) | (REG_WRITE_RAM << 8)), 4);
}
else
{
HAL_LCDC_SendLayerData2Reg_IT(hlcdc, REG_WRITE_RAM, 1);
}
}
// fixme :ZhouMo Modify 2025-02-25
/**
* @brief Writes to the selected LCD register.
* @param LCD_Reg: address of the selected register.
* @retval None
*/
static void LCD_WriteReg(LCDC_HandleTypeDef *hlcdc, uint16_t LCD_Reg, uint8_t *Parameters, uint32_t NbParameters)
{
if (QAD_SPI_ITF == lcdc_int_cfg.lcd_itf)
{
uint32_t cmd;
cmd = (0x02 << 24) | (LCD_Reg << 8);
if (0 != NbParameters)
{
/* Send command's parameters if any */
HAL_LCDC_WriteU32Reg(hlcdc, cmd, Parameters, NbParameters);
}
else
{
uint32_t v = 0;
HAL_LCDC_WriteU32Reg(hlcdc, cmd, (uint8_t *)&v, 1);
}
}
else
{
HAL_LCDC_WriteU8Reg(hlcdc, LCD_Reg, Parameters, NbParameters);
}
}
/**
* @brief Reads the selected LCD Register.
* @param RegValue: Address of the register to read
* @param ReadSize: Number of bytes to read
* @retval LCD Register Value.
*/
static uint32_t LCD_ReadData(LCDC_HandleTypeDef *hlcdc, uint16_t RegValue, uint8_t ReadSize)
{
uint32_t rd_data = 0;
LCD_ReadMode(hlcdc, true);
if (0)
{
}
else if (QAD_SPI_ITF == lcdc_int_cfg.lcd_itf)
{
HAL_LCDC_ReadU32Reg(hlcdc, ((0x03 << 24) | (RegValue << 8)), (uint8_t *)&rd_data, ReadSize);
}
else
{
HAL_LCDC_ReadU8Reg(hlcdc, RegValue, (uint8_t *)&rd_data, ReadSize);
}
LCD_ReadMode(hlcdc, false);
return rd_data;
}
// or
static uint32_t LCD_ReadPixel(LCDC_HandleTypeDef *hlcdc, uint16_t Xpos, uint16_t Ypos)
{
return 0;
}
static void LCD_SetColorMode(LCDC_HandleTypeDef *hlcdc, uint16_t color_mode)
{
uint8_t parameter[2];
switch (color_mode)
{
case RTGRAPHIC_PIXEL_FORMAT_RGB565:
/* Color mode 16bits/pixel */
parameter[0] = 0x55;
lcdc_int_cfg.color_mode = LCDC_PIXEL_FORMAT_RGB565;
break;
case RTGRAPHIC_PIXEL_FORMAT_RGB888:
parameter[0] = 0x66;
lcdc_int_cfg.color_mode = LCDC_PIXEL_FORMAT_RGB888;
break;
default:
return; // unsupport
break;
}
LCD_WriteReg(hlcdc, REG_COLOR_MODE, parameter, 1);
uint32_t data = LCD_ReadData(hlcdc, 0xc, 1);
DEBUG_PRINTF("\nST77916color_format 0x%x \n", data);
HAL_LCDC_SetOutFormat(hlcdc, lcdc_int_cfg.color_mode);
}
/**
* @brief
*
* @param hlcdc
* @param br
*/
static void LCD_SetBrightness(LCDC_HandleTypeDef *hlcdc, uint8_t br)
{
LOG_I("Set lcdlight %d", br);
uint8_t bright = (uint8_t)((uint16_t)UINT8_MAX * br / 100);
//LCD_WriteReg(hlcdc, REG_WBRIGHT, &br, 1);
rt_device_t device = rt_device_find("lcdlight");
if (device)
{
rt_err_t err = rt_device_open(device, RT_DEVICE_OFLAG_RDWR);
uint8_t val = br;
rt_device_write(device, 0, &val, 1);
rt_device_close(device);
}
else
{
LOG_E("Can't find device lcdlight!");
}
}
static void LCD_Rotate(LCDC_HandleTypeDef *hlcdc, LCD_DrvRotateTypeDef degree)
{
uint8_t parameter;
#if defined(LCDC_SUPPORT_V_MIRROR)&&!defined(LCDC_SUPPORT_H_MIRROR)
if (LCD_ROTATE_180_DEGREE == degree)
{
parameter = 0 << 7; //MY
parameter = 0 << 6; //MX
LCD_WriteReg(hlcdc, REG_MACTL, ¶meter, 1);
}
else
{
parameter = 0 << 7; //MY
parameter = 1 << 6; //MX
LCD_WriteReg(hlcdc, REG_MACTL, ¶meter, 1);
}
#endif /* LCDC_SUPPORT_H_MIRROR */
}
static const LCD_DrvOpsDef ST77916_drv =
{
LCD_Init,
LCD_ReadID,
LCD_DisplayOn,
LCD_DisplayOff,
LCD_SetRegion,
LCD_WritePixel,
LCD_WriteMultiplePixels,
LCD_ReadPixel,
LCD_SetColorMode,
LCD_SetBrightness,
NULL,
NULL,
LCD_Rotate,
};
LCD_DRIVER_EXPORT2(ST77916, THE_LCD_ID, &lcdc_int_cfg,
&ST77916_drv, 1);
/************************ (C) COPYRIGHT Sifli Technology *******END OF FILE****/
自行添加宏