DBI-C
该示例演示LCDC外设中DBI-C接口的应用。DBI-C也普遍被称为QSPI。
环境需求
该示例支持以下开发套件:
硬件平台 |
设备名称 |
---|---|
RTL87x2G HDK |
RTL87x2G EVB |
更多信息请参考快速入门。
硬件连线
需要任意QSPI屏幕或逻辑分析仪。
P3_6接到屏幕Reset。
P4_2接到屏幕D0。
P4_1接到屏幕D1。
P3_2接到屏幕D2。
P3_3接到屏幕D3。
P4_3接到屏幕CS。
P4_0接到屏幕CLK。
P0_5接到屏幕TE。
或以上所有引脚连接至逻辑分析仪。
配置选项
无
编译和下载
该示例的工程路径如下:
Project file: samples\peripheral\lcdc\lcdc_qspi\proj\rtl87x2g\mdk
Project file: samples\peripheral\lcdc\lcdc_qspi\proj\rtl87x2g\gcc
请按照以下步骤操作构建并运行该示例:
打开工程文件。
按照 快速入门 中 编译APP Image 给出的步骤构建目标文件。
编译成功后,在路径
mdk\bin
下会生成 app binapp_MP_xxx.bin
文件。按下复位按键,开始运行。
测试验证
观察到屏幕点亮为绿色,或逻辑分析仪观察到正确波形。
代码介绍
该章节分为以下几个部分:
源码路径
工程路径:
sdk\samples\peripheral\lcdc\lcdc_qspi\proj
源码路径:
sdk\samples\peripheral\lcdc\lcdc_qspi\src
该工程的工程文件代码结构如下:
└── Project: qspi
└── lcdc
├── config includes project construct configuration
├── display includes the peripheral drivers related with display
└── Device includes startup code
├── startup_rtl.c
└── system_rtl.c
├── CMSIS includes CMSIS header files
├── CMSE Library non-secure callable lib
├── lib includes all binary symbol files that user application is built on
├── peripheral includes all peripheral drivers and module code used by the application
└── APP source code of LCDC qspi sample
├── main_ns.c
└── icna3311_280x456_qspi.c driver of LCD screen
初始化
初始化流程包含在 rtk_lcd_hal_init()
中。
使能LCDC时钟,并选择合适的时钟源。
/* config LCD dev info */
RCC_PeriphClockCmd(APBPeriph_DISP, APBPeriph_DISP_CLOCK, ENABLE);
//from XTAL SOURCE = 40M
PERIBLKCTRL_PERI_CLK->u_324.BITS_324.disp_ck_en = 1;
PERIBLKCTRL_PERI_CLK->u_324.BITS_324.disp_func_en = 1;
PERIBLKCTRL_PERI_CLK->u_324.BITS_324.r_disp_mux_clk_cg_en = 1;
//From PLL1, SOURCE = 100M
PERIBLKCTRL_PERI_CLK->u_324.BITS_324.r_disp_div_en = 1;
PERIBLKCTRL_PERI_CLK->u_324.BITS_324.r_disp_clk_src_sel0 = 0; //pll1_peri(0) or pll2(1, pll2 = 160M)
PERIBLKCTRL_PERI_CLK->u_324.BITS_324.r_disp_clk_src_sel1 = 1; //pll(1) or xtal(0)
PERIBLKCTRL_PERI_CLK->u_324.BITS_324.r_disp_div_sel = 1; //div
初始化需要使用的引脚。
Pad_Config(LCD_QSPI_RST, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
Pad_Config(LCD_QSPI_D0, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
Pad_Config(LCD_QSPI_D1, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
Pad_Config(LCD_QSPI_D2, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
Pad_Config(LCD_QSPI_D3, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
Pad_Config(LCD_QSPI_CS, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
Pad_Config(LCD_QSPI_CLK, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
Pad_Config(LCD_QSPI_TE, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_UP, PAD_OUT_DISABLE, PAD_OUT_HIGH);
Pad_Dedicated_Config(LCD_QSPI_RST, ENABLE);
Pad_Dedicated_Config(LCD_QSPI_D0, ENABLE);
Pad_Dedicated_Config(LCD_QSPI_D1, ENABLE);
Pad_Dedicated_Config(LCD_QSPI_D2, ENABLE);
Pad_Dedicated_Config(LCD_QSPI_D3, ENABLE);
Pad_Dedicated_Config(LCD_QSPI_CS, ENABLE);
Pad_Dedicated_Config(LCD_QSPI_CLK, ENABLE);
Pad_Dedicated_Config(LCD_QSPI_TE, ENABLE);
选择需要的颜色格式,指定使用DBI-C接口。
LCDC_InitTypeDef lcdc_init = {0};
lcdc_init.LCDC_Interface = LCDC_IF_DBIC;
lcdc_init.LCDC_GroupSel = 1;
lcdc_init.LCDC_PixelInputFormat = LCDC_INPUT_RGB565;
lcdc_init.LCDC_PixelOutputFormat = LCDC_OUTPUT_RGB565;
lcdc_init.LCDC_PixelBitSwap = LCDC_SWAP_BYPASS;
lcdc_init.LCDC_TeEn = ENABLE;
lcdc_init.LCDC_TePolarity = LCDC_TE_EDGE_FALLING;
lcdc_init.LCDC_TeInputMux = LCDC_TE_LCD_INPUT;
lcdc_init.LCDC_DmaThreshold = 112;
LCDC_Init(&lcdc_init);
初始化DBI-C接口,指定分频系数与极性。
LCDC_DBICCfgTypeDef dbic_init = {0};
dbic_init.DBIC_SPEED_SEL = 1;
dbic_init.DBIC_TxThr = 0;
dbic_init.DBIC_RxThr = 0;
dbic_init.SCPOL = DBIC_SCPOL_LOW;
dbic_init.SCPH = DBIC_SCPH_1Edge;
DBIC_Init(&dbic_init);
通过控制Reset引脚使屏幕完成Reset。
LCDC_LCD_SET_RST(false);
platform_delay_ms(100);
LCDC_LCD_SET_RST(true);
platform_delay_ms(120);
LCDC_LCD_SET_RST(false);
platform_delay_ms(50);
如果使用的屏幕需要初始化,通过DBI-C接口向屏幕发送初始化命令和数据。
小技巧
通过DBIC向外发送命令的方式,详见 常见问题。
功能实现
通过函数
rtk_lcd_hal_set_window()
指定更新屏幕RAM的区域,如下所示,将窗口设为起始点为(0,0), 宽度为280, 高度为456:
rtk_lcd_hal_set_window(0, 0, 280, 456);
通过函数
rtk_lcd_hal_start_transfer()
将指定长度的数据向屏幕发送。该函数中,首先初始化了DMA的配置。
LCDC_DMA_InitTypeDef LCDC_DMA_InitStruct = {0};
LCDC_DMA_StructInit(&LCDC_DMA_InitStruct);
LCDC_DMA_InitStruct.LCDC_DMA_ChannelNum = LCDC_DMA_CHANNEL_NUM;
LCDC_DMA_InitStruct.LCDC_DMA_DIR = 4;
LCDC_DMA_InitStruct.LCDC_DMA_SourceInc = LCDC_DMA_SourceInc_Inc;
LCDC_DMA_InitStruct.LCDC_DMA_DestinationInc = LCDC_DMA_DestinationInc_Fix;
LCDC_DMA_InitStruct.LCDC_DMA_SourceDataSize = LCDC_DMA_DataSize_Word;
LCDC_DMA_InitStruct.LCDC_DMA_DestinationDataSize = LCDC_DMA_DataSize_Word;
LCDC_DMA_InitStruct.LCDC_DMA_SourceMsize = LCDC_DMA_Msize_8;
LCDC_DMA_InitStruct.LCDC_DMA_DestinationMsize = LCDC_DMA_Msize_8;
LCDC_DMA_InitStruct.LCDC_DMA_SourceAddr = (uint32_t)buf;
LCDC_DMA_InitStruct.LCDC_DMA_Multi_Block_En = 0;
LCDC_DMA_Init(LCDC_DMA_CHANNEL_INDEX, &LCDC_DMA_InitStruct);
重置DMA寄存器,并设置当前需要的参数。
LCDC_ClearDmaFifo();
LCDC_ClearTxPixelCnt();
LCDC_SwitchMode(LCDC_AUTO_MODE);
LCDC_SwitchDirect(LCDC_TX_MODE);
LCDC_SetTxPixelLen(len);
使能DMA,若有TE信号,则通过TE信号开始DMA传输数据。
LCDC_Cmd(ENABLE);
LCDC_DMAChannelCmd(LCDC_DMA_CHANNEL_NUM, ENABLE);
LCDC_DmaCmd(ENABLE);
#if (TE_VALID == 1)
LCDC_TeCmd(ENABLE);
#endif
#if (TE_VALID == 0)
LCDC_AutoWriteCmd(ENABLE);
#endif
通过
rtk_lcd_hal_transfer_done()
等待DMA传输完成。
常见问题
通过DBIC发送数据
可以参考函数
qspi_write()
设定使用的数据线数量,以及数据的传输方向。
DBIC_Cmd(DISABLE);//disable DBIC
DBIC->CTRLR0 &= ~(BIT_CMD_CH(3) | BIT_ADDR_CH(3) | BIT_DATA_CH(3));//SET CHANNEL NUM
DBIC->CTRLR0 &= ~(BIT_TMOD(3)); //tx mode
设定向外发送的命令与地址的长度。
DBIC_CmdLength(1);
DBIC_AddrLength(3);
DBIC_TX_NDF(len - 4);
DBIC_Cmd(ENABLE);
向DR寄存器写书需要发送的数据,并等待其发送结束。
for (uint32_t i = 0; i < len; i++)
{
DBIC->DR[0].byte = buf[i];
}
while (DBIC->SR & BIT0); // wait bus busy
DBIC_Cmd(DISABLE);//disable DBIC