思澈科技软件开发工具包  2.20
LCDC

LCDC(LCD Controller) 是为屏提供一个统一的接口,而不需关心具体物理连接是SPI、并口或者其他物理连接,只需在初始化时配置需要使用的物理接口及参数,后续均使用统一的接口.

另外,它还可以支持图层的alpha混叠, 图层如下(按叠加排列):

  • 单色背景
  • 图层0
  • 图层1 (54x 不支持)

支持的物理接口:

名称 55X 58X 56X 54X
3SPI (1/2 data line) Y Y Y Y
4SPI (1/2 data line) Y Y Y Y
QAD-SPI Y Y Y Y
DSI Command模式 Y Y N N
DSI Video 模式 N Y N N
AHB 输出到SRAM/PSRAM Y Y Y Y
DBI 8080-8bit Y Y Y Y
JDI Y Y Y Y
DPI Y Y Y Y

支持的速度:

  • SPI (包括3SPI、4SPI、QAD-SPI) 速度=HCLK/divider, 其中divider为2~255
  • DSI 只支持DSI_Clock_Freq配置的几种速度
  • DBI 同SPI

支持的颜色输出格式

  • RGB332
  • RGB565
  • RGB888
  • RGB565_SWAP (55x 不支持)

图层支持的颜色格式

  • RGB565
  • RGB888
  • ARGB888
  • ARGB565
  • A8 (55x 不支持)
  • L8 (55x 不支持)
  • RGB565_SWAP (55x 不支持)

其他特性

  • 支持指定绘图区域, 且该区域可以跟给定的输出buffer区域任意交叉
  • 支持帧同步和行同步
  • 支持同步&异步(中断模式)送数接口
Figure 1: Lcd 输出buffer、绘图区域(ROI)在LCD上刷新的区域

使用LCDC示例1

通过4SPI 1data接口驱动ST7789H2的屏幕

static LCDC_InitTypeDef lcdc_int_cfg =
{
.lcd_itf = LCDC_INTF_SPI_DCX_1DATA, //Choose 4SPI 1data interface
.freq = 24000000, //SPI clock 24MHz
.color_mode = LCDC_PIXEL_FORMAT_RGB565, //LCDC output color format RGB565
.cfg = {
.spi = {
.dummy_clock = 1, //Dummy clock between cmd & data in read mode
.syn_mode = HAL_LCDC_SYNC_VER, //TE sychronization mode
.vsyn_polarity = 0, //TE pin polarity
.vsyn_delay_us = 1000, //Delay 1ms to send frame buffer right after received TE signal
.hsyn_num = 0, //Hsyn num if syn_mode is HAL_LCDC_SYNC_VERHOR
},
},
};
LCDC_HandleTypeDef hlcdc_st7789h2;
__ROM_USED void LCDC1_IRQHandler(void)
{
rt_interrupt_enter();
rt_interrupt_leave();
}
{
/*Send layer data completed*/
}
/**
* @brief Power on the LCD.
* @param None
* @retval None
*/
void ST7789H2_Init(LCDC_HandleTypeDef *hlcdc)
{
uint8_t parameter[14];
//Initalize interface
memcpy(&hlcdc->Init, &lcdc_int_cfg, sizeof(LCDC_InitTypeDef));
HAL_LCDC_Init(hlcdc);
//Generate a reset pulse to reset ST7789H2
HAL_LCDC_ResetLCD(hlcdc, LCDC_RESX_NEG_PULSE, 10);
/************* ST7789H2 initialize sequence start ************************/
/*Sleep In Command */
HAL_LCDC_WriteU8Reg(hlcdc, ST7789H2_SLEEP_IN, (uint8_t *)NULL, 0);
/* Wait for 10ms */
HAL_Delay(10);
/* SW Reset Command */
HAL_LCDC_WriteU8Reg(hlcdc, 0x01, (uint8_t *)NULL, 0);
/* Wait for 200ms */
HAL_Delay(200);
/* Sleep Out Command */
HAL_LCDC_WriteU8Reg(hlcdc, ST7789H2_SLEEP_OUT, (uint8_t *)NULL, 0);
/* Wait for 120ms */
HAL_Delay(120);
...
/************* ST7789H2 initialize sequence end ************************/
}
/**
* @brief ST7789H2 read mode should slow down SPI clock to 4MHz
* @param enable: false - write spi mode | true - read spi mode
* @retval None
*/
void ST7789H2_ReadMode(LCDC_HandleTypeDef *hlcdc, bool enable)
{
if (HAL_LCDC_IS_SPI_IF(lcdc_int_cfg.lcd_itf))
{
if (enable)
{
HAL_LCDC_SetFreq(hlcdc, 4000000); //SPI clock is 4MHz on Read mode
}
else
{
HAL_LCDC_SetFreq(hlcdc, lcdc_int_cfg.freq); //Restore normal frequency
}
}
}
/**
* @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.
*/
uint32_t ST7789H2_ReadData(LCDC_HandleTypeDef *hlcdc, uint16_t RegValue, uint8_t ReadSize)
{
uint32_t rd_data = 0;
//Entry read mode
ST7789H2_ReadMode(hlcdc, true);
HAL_LCDC_ReadU8Reg(hlcdc, RegValue, (uint8_t *)&rd_data, ReadSize);
//Recovery to normal mode
ST7789H2_ReadMode(hlcdc, false);
return rd_data;
}
/**
* @brief Set LCD & LCDC clip area
* @param hlcdc LCD controller handle
* @param Xpos0 - Clip area left coordinate, base on LCD top-left, same as below.
* @param Ypos0 - Clip area top coordinate
* @param Xpos1 - Clip area right coordinate
* @param Ypos1 - Clip area bottom coordinate
*/
void ST7789H2_SetRegion(LCDC_HandleTypeDef *hlcdc, uint16_t Xpos0, uint16_t Ypos0, uint16_t Xpos1, uint16_t Ypos1)
{
uint8_t parameter[4];
//Set LCDC clip area
HAL_LCDC_SetROIArea(hlcdc, Xpos0, Ypos0, Xpos1, Ypos1);
//Set LCD clip area
parameter[0] = (Xpos0) >> 8;
parameter[1] = (Xpos0) & 0xFF;
parameter[2] = (Xpos1) >> 8;
parameter[3] = (Xpos1) & 0xFF;
HAL_LCDC_WriteU8Reg(hlcdc, ST7789H2_CASET, parameter, 4);
parameter[0] = (Ypos0) >> 8;
parameter[1] = (Ypos0) & 0xFF;
parameter[2] = (Ypos1) >> 8;
parameter[3] = (Ypos1) & 0xFF;
HAL_LCDC_WriteU8Reg(hlcdc, ST7789H2_RASET, parameter, 4);
}
/**
* @brief Send layer data to LCD
* @param hlcdc LCD controller handle
* @param RGBCode - Pointer to layer data
* @param Xpos0 - Layer data left coordinate, base on LCD top-left, same as below.
* @param Ypos0 - Layer data top coordinate
* @param Xpos1 - Layer data right coordinate
* @param Ypos1 - Layer data bottom coordinate
*/
void ST7789H2_WriteMultiplePixels(LCDC_HandleTypeDef *hlcdc, const uint8_t *RGBCode, uint16_t Xpos0, uint16_t Ypos0, uint16_t Xpos1, uint16_t Ypos1)
{
uint32_t size;
if ((Xpos0 > Xpos1) || (Ypos0 > Ypos1))
{
//Invalid coordinates
return;
}
//Set default layer data
HAL_LCDC_LayerSetData(hlcdc, HAL_LCDC_LAYER_DEFAULT, (uint8_t *)RGBCode, Xpos0, Ypos0, Xpos1, Ypos1);
//Write datas to LCD register
}
HAL_LCDC_IRQHandler
void HAL_LCDC_IRQHandler(LCDC_HandleTypeDef *lcdc)
LCD controller interrupt handler.
HAL_LCDC_SYNC_VER
@ HAL_LCDC_SYNC_VER
Definition: bf0_hal_lcdc.h:176
HAL_LCDC_LayerSetData
HAL_StatusTypeDef HAL_LCDC_LayerSetData(LCDC_HandleTypeDef *lcdc, HAL_LCDC_LayerDef layeridx, uint8_t *pData, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
Set layer buffer data and it's coordinate.
HAL_LCDC_SendLayerDataCpltCbk
void HAL_LCDC_SendLayerDataCpltCbk(LCDC_HandleTypeDef *lcdc)
LCD controller send layer data complete callback.
HAL_LCDC_LAYER_DEFAULT
@ HAL_LCDC_LAYER_DEFAULT
Default layer.
Definition: bf0_hal_lcdc.h:411
LCDC_InitTypeDef::freq
uint32_t freq
Definition: bf0_hal_lcdc.h:312
LCDC_InitTypeDef
Definition: bf0_hal_lcdc.h:310
HAL_LCDC_SetROIArea
HAL_StatusTypeDef HAL_LCDC_SetROIArea(LCDC_HandleTypeDef *lcdc, uint16_t x_0, uint16_t y_0, uint16_t x_1, uint16_t y_1)
Set LCDC output ROI area by coordinate.
HAL_LCDC_SetFreq
HAL_StatusTypeDef HAL_LCDC_SetFreq(LCDC_HandleTypeDef *lcdc, uint32_t freq)
Update LCDC output frequecy.
__LCDC_HandleTypeDef
Definition: bf0_hal_lcdc.h:462
HAL_LCDC_ReadU8Reg
#define HAL_LCDC_ReadU8Reg(lcdc, U8Reg, p_data, data_len)
Read data(s) from LCD register which address length is 8bit.
Definition: bf0_hal_lcdc.h:873
__LCDC_HandleTypeDef::Init
LCDC_InitTypeDef Init
Definition: bf0_hal_lcdc.h:465
LCDC_INTF_SPI_DCX_1DATA
@ LCDC_INTF_SPI_DCX_1DATA
SPI which has DCX pin, output with 1 data line.
Definition: bf0_hal_lcdc.h:125
LCDC_InitTypeDef::lcd_itf
HAL_LCDC_IF_TypeDef lcd_itf
Definition: bf0_hal_lcdc.h:311
HAL_LCDC_SendLayerData2Reg_IT
HAL_StatusTypeDef HAL_LCDC_SendLayerData2Reg_IT(LCDC_HandleTypeDef *lcdc, uint32_t addr, uint32_t addr_len)
Send an address and layer data to LCD in asynchronized mode.
HAL_LCDC_Init
HAL_StatusTypeDef HAL_LCDC_Init(LCDC_HandleTypeDef *lcdc)
Initialize LCD controller hardware.
HAL_LCDC_WriteU8Reg
#define HAL_LCDC_WriteU8Reg(lcdc, U8Reg, p_data, data_len)
Write data(s) to LCD register which address length is 8bit.
Definition: bf0_hal_lcdc.h:915
HAL_Delay
void HAL_Delay(uint32_t Delay)
This function provides minimum delay (in milliseconds) based on variable incremented.