cmcu为stm32h743IIt6
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

655 lines
19 KiB

/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2025-12-06 Administrator the first version
* 2025-12-07 Qwen 使用 RT-Thread 内存池替代静态帧缓存,修复 rt_mp_create 参数错误
*/
/* ltdc.c */
#include "ltdc.h"
#include "lcd.h"
#include <string.h>
#include <rtthread.h>
#include <rthw.h>
LTDC_HandleTypeDef g_ltdc_handle; /* LTDC句柄 */
DMA2D_HandleTypeDef g_dma2d_handle; /* DMA2D句柄 */
/* 移除原始静态帧缓存数组定义 */
#define MAX_FRAME_WIDTH 1280
#define MAX_FRAME_HEIGHT 800
#if LTDC_PIXFORMAT == LTDC_PIXFORMAT_ARGB8888 || LTDC_PIXFORMAT == LTDC_PIXFORMAT_RGB888
#define BYTES_PER_PIXEL 4
#else
#define BYTES_PER_PIXEL 2
#endif
#define FRAME_BUF_SIZE (MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * BYTES_PER_PIXEL)
#define FRAME_ALIGN 64 /* LTDC 推荐对齐到 64 字节 */
static rt_mp_t frame_mp = RT_NULL;
uint32_t *g_ltdc_framebuf[2] = {RT_NULL, RT_NULL}; /* 初始化为 NULL */
_ltdc_dev lcdltdc; /* 管理LCD LTDC的重要参数 */
/**
* @brief 从内存池分配对齐内存
*/
static void* alloc_aligned_frame_buffer(rt_mp_t mp, rt_size_t size, rt_size_t align)
{
void *raw, *aligned;
rt_size_t offset;
/* 分配足够空间以保证能对齐 */
raw = rt_mp_alloc(mp, size + align - 1);
if (raw == RT_NULL) return RT_NULL;
offset = (rt_ubase_t)raw & (align - 1);
if (offset != 0)
aligned = (void *)((rt_ubase_t)raw + align - offset);
else
aligned = raw;
return aligned;
}
/**
* @brief LTDC开关
* @param sw : 1,打开; 0,关闭;
* @retval 无
*/
void ltdc_switch(uint8_t sw)
{
if (sw)
{
__HAL_LTDC_ENABLE(&g_ltdc_handle); /* 打开LTDC */
}
else
{
__HAL_LTDC_DISABLE(&g_ltdc_handle); /* 关闭LTDC */
}
}
/**
* @brief LTDC开关指定层
* @param layerx : 0,第一层; 1,第二层;
* @param sw : 1,打开; 0,关闭;
* @retval 无
*/
void ltdc_layer_switch(uint8_t layerx, uint8_t sw)
{
if (sw)
{
__HAL_LTDC_LAYER_ENABLE(&g_ltdc_handle, layerx); /* 开启layerx */
}
else
{
__HAL_LTDC_LAYER_DISABLE(&g_ltdc_handle, layerx); /* 关闭layerx */
}
__HAL_LTDC_RELOAD_CONFIG(&g_ltdc_handle); /* 立即重新加载配置 */
}
/**
* @brief LTDC选择层
* @param layerx : 层号:0,第一层; 1,第二层;
* @retval 无
*/
void ltdc_select_layer(uint8_t layerx)
{
lcdltdc.activelayer = layerx;
}
/**
* @brief LTDC显示方向设置
* @param dir : 0,竖屏; 1,横屏;
* @retval 无
*/
void ltdc_display_dir(uint8_t dir)
{
lcdltdc.dir = dir; /* 显示方向 */
if (dir == 0) /* 竖屏 */
{
lcdltdc.width = lcdltdc.pheight;
lcdltdc.height = lcdltdc.pwidth;
}
else if (dir == 1) /* 横屏 */
{
lcdltdc.width = lcdltdc.pwidth;
lcdltdc.height = lcdltdc.pheight;
}
}
/**
* @brief LTDC画点函数
* @param x,y : 写入坐标
* @param color : 颜色值
* @retval 无
*/
void ltdc_draw_point(uint16_t x, uint16_t y, uint32_t color)
{
#if LTDC_PIXFORMAT == LTDC_PIXFORMAT_ARGB8888
if (lcdltdc.dir) /* 横屏 */
{
*(uint32_t *)((uint32_t)g_ltdc_framebuf[lcdltdc.activelayer] + lcdltdc.pixsize * (lcdltdc.pwidth * y + x)) = color;
}
else /* 竖屏 */
{
*(uint32_t *)((uint32_t)g_ltdc_framebuf[lcdltdc.activelayer] + lcdltdc.pixsize * (lcdltdc.pwidth * (lcdltdc.pheight - x - 1) + y)) = color;
}
#elif LTDC_PIXFORMAT == LTDC_PIXFORMAT_RGB888
if (lcdltdc.dir) /* 横屏 */
{
*(uint16_t *)((uint32_t)g_ltdc_framebuf[lcdltdc.activelayer] + lcdltdc.pixsize * (lcdltdc.pwidth * y + x)) = color;
*(uint8_t *)((uint32_t)g_ltdc_framebuf[lcdltdc.activelayer] + lcdltdc.pixsize * (lcdltdc.pwidth * y + x) + 2) = color >> 16;
}
else /* 竖屏 */
{
*(uint16_t *)((uint32_t)g_ltdc_framebuf[lcdltdc.activelayer] + lcdltdc.pixsize * (lcdltdc.pwidth * (lcdltdc.pheight - x - 1) + y)) = color;
*(uint8_t *)((uint32_t)g_ltdc_framebuf[lcdltdc.activelayer] + lcdltdc.pixsize * (lcdltdc.pwidth * (lcdltdc.pheight - x - 1) + y) + 2) = color >> 16;
}
#else
if (lcdltdc.dir) /* 横屏 */
{
*(uint16_t *)((uint32_t)g_ltdc_framebuf[lcdltdc.activelayer] + lcdltdc.pixsize * (lcdltdc.pwidth * y + x)) = color;
}
else /* 竖屏 */
{
*(uint16_t *)((uint32_t)g_ltdc_framebuf[lcdltdc.activelayer] + lcdltdc.pixsize * (lcdltdc.pwidth * (lcdltdc.pheight - x - 1) + y)) = color;
}
#endif
}
/**
* @brief LTDC读点函数
* @param x,y : 读取点的坐标
* @retval 颜色值
*/
uint32_t ltdc_read_point(uint16_t x, uint16_t y)
{
#if LTDC_PIXFORMAT == LTDC_PIXFORMAT_ARGB8888
if (lcdltdc.dir) /* 横屏 */
{
return *(uint32_t *)((uint32_t)g_ltdc_framebuf[lcdltdc.activelayer] + lcdltdc.pixsize * (lcdltdc.pwidth * y + x));
}
else /* 竖屏 */
{
return *(uint32_t *)((uint32_t)g_ltdc_framebuf[lcdltdc.activelayer] + lcdltdc.pixsize * (lcdltdc.pwidth * (lcdltdc.pheight - x - 1) + y));
}
#elif LTDC_PIXFORMAT == LTDC_PIXFORMAT_RGB888
if (lcdltdc.dir) /* 横屏 */
{
return *(uint32_t *)((uint32_t)g_ltdc_framebuf[lcdltdc.activelayer] + lcdltdc.pixsize * (lcdltdc.pwidth * y + x)) & 0XFFFFFF;
}
else /* 竖屏 */
{
return *(uint32_t *)((uint32_t)g_ltdc_framebuf[lcdltdc.activelayer] + lcdltdc.pixsize * (lcdltdc.pwidth * (lcdltdc.pheight - x - 1) + y)) & 0XFFFFFF;
}
#else
if (lcdltdc.dir) /* 横屏 */
{
return *(uint16_t *)((uint32_t)g_ltdc_framebuf[lcdltdc.activelayer] + lcdltdc.pixsize * (lcdltdc.pwidth * y + x));
}
else /* 竖屏 */
{
return *(uint16_t *)((uint32_t)g_ltdc_framebuf[lcdltdc.activelayer] + lcdltdc.pixsize * (lcdltdc.pwidth * (lcdltdc.pheight - x - 1) + y));
}
#endif
}
/**
* @brief LTDC填充矩形, DMA2D填充
*/
void ltdc_fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint32_t color)
{
uint32_t psx, psy, pex, pey;
uint32_t timeout = 0;
uint16_t offline;
uint32_t addr;
if (lcdltdc.dir)
{
psx = sx;
psy = sy;
pex = ex;
pey = ey;
}
else
{
if (ex >= lcdltdc.pheight) ex = lcdltdc.pheight - 1;
if (sx >= lcdltdc.pheight) sx = lcdltdc.pheight - 1;
psx = sy;
psy = lcdltdc.pheight - ex - 1;
pex = ey;
pey = lcdltdc.pheight - sx - 1;
}
offline = lcdltdc.pwidth - (pex - psx + 1);
addr = ((uint32_t)g_ltdc_framebuf[lcdltdc.activelayer] + lcdltdc.pixsize * (lcdltdc.pwidth * psy + psx));
__HAL_RCC_DMA2D_CLK_ENABLE();
DMA2D->CR &= ~(DMA2D_CR_START);
DMA2D->CR = DMA2D_R2M;
DMA2D->OPFCCR = LTDC_PIXFORMAT;
DMA2D->OOR = offline;
DMA2D->OMAR = addr;
DMA2D->NLR = (pey - psy + 1) | ((pex - psx + 1) << 16);
DMA2D->OCOLR = color;
DMA2D->CR |= DMA2D_CR_START;
while ((DMA2D->ISR & (DMA2D_FLAG_TC)) == 0)
{
timeout++;
if (timeout > 0X1FFFFF) break;
}
DMA2D->IFCR |= DMA2D_FLAG_TC;
}
/**
* @brief 在指定区域内填充指定颜色块, DMA2D填充
*/
void ltdc_color_fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t *color)
{
uint32_t psx, psy, pex, pey;
uint32_t timeout = 0;
uint16_t offline;
uint32_t addr;
if (lcdltdc.dir)
{
psx = sx;
psy = sy;
pex = ex;
pey = ey;
}
else
{
psx = sy;
psy = lcdltdc.pheight - ex - 1;
pex = ey;
pey = lcdltdc.pheight - sx - 1;
}
offline = lcdltdc.pwidth - (pex - psx + 1);
addr = ((uint32_t)g_ltdc_framebuf[lcdltdc.activelayer] + lcdltdc.pixsize * (lcdltdc.pwidth * psy + psx));
__HAL_RCC_DMA2D_CLK_ENABLE();
DMA2D->CR &= ~(DMA2D_CR_START);
DMA2D->CR = DMA2D_M2M;
DMA2D->FGPFCCR = LTDC_PIXFORMAT;
DMA2D->FGOR = 0;
DMA2D->OOR = offline;
DMA2D->FGMAR = (uint32_t)color;
DMA2D->OMAR = addr;
DMA2D->NLR = (pey - psy + 1) | ((pex - psx + 1) << 16);
DMA2D->CR |= DMA2D_CR_START;
while((DMA2D->ISR & (DMA2D_FLAG_TC)) == 0)
{
timeout++;
if (timeout > 0X1FFFFF) break;
}
DMA2D->IFCR |= DMA2D_FLAG_TC;
}
/**
* @brief LTDC清屏
*/
void ltdc_clear(uint32_t color)
{
ltdc_fill(0, 0, lcdltdc.width - 1, lcdltdc.height - 1, color);
}
/**
* @brief LTDC时钟(Fdclk)设置函数
*/
uint8_t ltdc_clk_set(uint32_t pll3n, uint32_t pll3m, uint32_t pll3r)
{
RCC_PeriphCLKInitTypeDef periphclk_initure;
periphclk_initure.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
periphclk_initure.PLL3.PLL3M = pll3m;
periphclk_initure.PLL3.PLL3N = pll3n;
periphclk_initure.PLL3.PLL3P = 2;
periphclk_initure.PLL3.PLL3Q = 2;
periphclk_initure.PLL3.PLL3R = pll3r;
if (HAL_RCCEx_PeriphCLKConfig(&periphclk_initure) == HAL_OK)
{
return 0;
}
else
{
return 1;
}
}
/**
* @brief LTDC层窗口设置
*/
void ltdc_layer_window_config(uint8_t layerx, uint16_t sx, uint16_t sy, uint16_t width, uint16_t height)
{
HAL_LTDC_SetWindowPosition(&g_ltdc_handle, sx, sy, layerx);
HAL_LTDC_SetWindowSize(&g_ltdc_handle, width, height, layerx);
if (lcdltdc.pheight == 1280 && layerx == 0)
{
LTDC_Layer1->CFBLR = (width * 4 << 16) | (width * 4 + 7);
}
}
/**
* @brief LTDC层基本参数设置
*/
void ltdc_layer_parameter_config(uint8_t layerx, uint32_t bufaddr, uint8_t pixformat, uint8_t alpha, uint8_t alpha0, uint8_t bfac1, uint8_t bfac2, uint32_t bkcolor)
{
LTDC_LayerCfgTypeDef playercfg;
playercfg.WindowX0 = 0;
playercfg.WindowY0 = 0;
playercfg.WindowX1 = lcdltdc.pwidth;
playercfg.WindowY1 = lcdltdc.pheight;
playercfg.PixelFormat = pixformat;
playercfg.Alpha = alpha;
playercfg.Alpha0 = alpha0;
playercfg.BlendingFactor1 = (uint32_t)bfac1 << 8;
playercfg.BlendingFactor2 = (uint32_t)bfac2;
playercfg.FBStartAdress = bufaddr;
playercfg.ImageWidth = lcdltdc.pwidth;
playercfg.ImageHeight = lcdltdc.pheight;
playercfg.Backcolor.Red = (uint8_t)(bkcolor & 0X00FF0000) >> 16;
playercfg.Backcolor.Green = (uint8_t)(bkcolor & 0X0000FF00) >> 8;
playercfg.Backcolor.Blue = (uint8_t)bkcolor & 0X000000FF;
HAL_LTDC_ConfigLayer(&g_ltdc_handle, &playercfg, layerx);
}
/**
* @brief LTDC读取面板ID
*/
uint16_t ltdc_panelid_read(void)
{
uint8_t idx = 0;
GPIO_InitTypeDef gpio_init_struct;
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOI_CLK_ENABLE();
gpio_init_struct.Pin = GPIO_PIN_6;
gpio_init_struct.Mode = GPIO_MODE_INPUT;
gpio_init_struct.Pull = GPIO_PULLUP;
gpio_init_struct.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(GPIOG, &gpio_init_struct);
gpio_init_struct.Pin = GPIO_PIN_2 | GPIO_PIN_7;
HAL_GPIO_Init(GPIOI, &gpio_init_struct);
rt_thread_mdelay(1);
idx = (uint8_t)HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_6);
idx |= (uint8_t)HAL_GPIO_ReadPin(GPIOI, GPIO_PIN_2) << 1;
idx |= (uint8_t)HAL_GPIO_ReadPin(GPIOI, GPIO_PIN_7) << 2;
switch (idx)
{
case 0: return 0X4342;
case 1: return 0X7084;
case 2: return 0X7016;
case 3: return 0X7018;
case 4: return 0X4384;
case 5: return 0X1018;
default: return 0;
}
}
/**
* @brief LTDC初始化函数
*/
int ltdc_init(void)
{
uint16_t lcdid = 0;
lcdid = ltdc_panelid_read();
#if RGB_80_8001280
lcdid = 0X8081;
#endif
if (lcdid == 0X4342)
{
lcdltdc.pwidth = 480; lcdltdc.pheight = 272;
lcdltdc.hsw = 1; lcdltdc.hbp = 40; lcdltdc.hfp = 5;
lcdltdc.vsw = 1; lcdltdc.vbp = 8; lcdltdc.vfp = 8;
ltdc_clk_set(300, 25, 33);
}
else if (lcdid == 0X7084)
{
lcdltdc.pwidth = 800; lcdltdc.pheight = 480;
lcdltdc.hsw = 1; lcdltdc.hbp = 46; lcdltdc.hfp = 210;
lcdltdc.vsw = 1; lcdltdc.vbp = 23; lcdltdc.vfp = 22;
ltdc_clk_set(300, 25, 9);
}
else if (lcdid == 0X7016)
{
lcdltdc.pwidth = 1024; lcdltdc.pheight = 600;
lcdltdc.hsw = 20; lcdltdc.hbp = 140; lcdltdc.hfp = 160;
lcdltdc.vsw = 3; lcdltdc.vbp = 20; lcdltdc.vfp = 12;
ltdc_clk_set(300, 25, 6);
}
else if (lcdid == 0X7018)
{
lcdltdc.pwidth = 1280; lcdltdc.pheight = 800;
}
else if (lcdid == 0X4384)
{
lcdltdc.pwidth = 800; lcdltdc.pheight = 480;
lcdltdc.hsw = 48; lcdltdc.hbp = 88; lcdltdc.hfp = 40;
lcdltdc.vsw = 3; lcdltdc.vbp = 32; lcdltdc.vfp = 13;
ltdc_clk_set(300, 25, 9);
}
else if (lcdid == 0X8081)
{
lcdltdc.pwidth = 800; lcdltdc.pheight = 1280;
lcdltdc.hsw = 5; lcdltdc.hbp = 20; lcdltdc.hfp = 40;
lcdltdc.vsw = 3; lcdltdc.vbp = 20; lcdltdc.vfp = 30;
ltdc_clk_set(300, 25, 5);
}
else if (lcdid == 0X1018)
{
lcdltdc.pwidth = 1280; lcdltdc.pheight = 800;
lcdltdc.hsw = 10; lcdltdc.hbp = 140; lcdltdc.hfp = 10;
lcdltdc.vsw = 3; lcdltdc.vbp = 10; lcdltdc.vfp = 10;
ltdc_clk_set(300, 25, 5);
}
lcddev.width = lcdltdc.pwidth;
lcddev.height = lcdltdc.pheight;
lcdltdc.pixformat = LTDC_PIXFORMAT;
lcdltdc.pixsize = BYTES_PER_PIXEL;
/* === 使用 RT-Thread 内存池分配帧缓存(双缓冲)=== */
if (frame_mp == RT_NULL)
{
rt_size_t block_size = FRAME_BUF_SIZE + FRAME_ALIGN; /* 每块大小 */
rt_size_t block_count = 2; /* 双缓冲 */
frame_mp = rt_mp_create("ltdc_mp", block_count, block_size);
if (frame_mp == RT_NULL)
{
rt_kprintf("LTDC: Failed to create memory pool!\n");
return -1;
}
rt_kprintf("LTDC: Memory pool created (%d blocks, %d bytes each)\n",
block_count, block_size);
}
/* 分配帧缓冲 0 */
if (g_ltdc_framebuf[0] == RT_NULL)
{
void *aligned_buf = alloc_aligned_frame_buffer(frame_mp, FRAME_BUF_SIZE, FRAME_ALIGN);
if (aligned_buf == RT_NULL)
{
rt_kprintf("LTDC: Failed to allocate frame buffer 0!\n");
return -1;
}
g_ltdc_framebuf[0] = (uint32_t *)aligned_buf;
}
/* 分配帧缓冲 1(双缓冲) */
if (g_ltdc_framebuf[1] == RT_NULL)
{
void *aligned_buf = alloc_aligned_frame_buffer(frame_mp, FRAME_BUF_SIZE, FRAME_ALIGN);
if (aligned_buf == RT_NULL)
{
rt_kprintf("LTDC: Warning: only single buffer available.\n");
// 可选:回退到单缓冲
g_ltdc_framebuf[1] = g_ltdc_framebuf[0];
}
else
{
g_ltdc_framebuf[1] = (uint32_t *)aligned_buf;
}
}
/* LTDC配置 */
g_ltdc_handle.Instance = LTDC;
if (lcdid == 0X8081)
g_ltdc_handle.Init.HSPolarity = LTDC_HSPOLARITY_AH;
else
g_ltdc_handle.Init.HSPolarity = LTDC_HSPOLARITY_AL;
g_ltdc_handle.Init.VSPolarity = LTDC_VSPOLARITY_AL;
g_ltdc_handle.Init.DEPolarity = LTDC_DEPOLARITY_AL;
g_ltdc_handle.State = HAL_LTDC_STATE_RESET;
if (lcdid == 0X1018 || lcdid == 0X8081)
g_ltdc_handle.Init.PCPolarity = LTDC_PCPOLARITY_IIPC;
else
g_ltdc_handle.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
g_ltdc_handle.Init.HorizontalSync = lcdltdc.hsw - 1;
g_ltdc_handle.Init.VerticalSync = lcdltdc.vsw - 1;
g_ltdc_handle.Init.AccumulatedHBP = lcdltdc.hsw + lcdltdc.hbp - 1;
g_ltdc_handle.Init.AccumulatedVBP = lcdltdc.vsw + lcdltdc.vbp - 1;
g_ltdc_handle.Init.AccumulatedActiveW = lcdltdc.hsw + lcdltdc.hbp + lcdltdc.pwidth - 1;
g_ltdc_handle.Init.AccumulatedActiveH = lcdltdc.vsw + lcdltdc.vbp + lcdltdc.pheight - 1;
g_ltdc_handle.Init.TotalWidth = lcdltdc.hsw + lcdltdc.hbp + lcdltdc.pwidth + lcdltdc.hfp - 1;
g_ltdc_handle.Init.TotalHeigh = lcdltdc.vsw + lcdltdc.vbp + lcdltdc.pheight + lcdltdc.vfp - 1;
g_ltdc_handle.Init.Backcolor.Red = 0;
g_ltdc_handle.Init.Backcolor.Green = 0;
g_ltdc_handle.Init.Backcolor.Blue = 0;
HAL_LTDC_Init(&g_ltdc_handle);
/* 层配置 */
ltdc_layer_parameter_config(0, (uint32_t)g_ltdc_framebuf[0], LTDC_PIXFORMAT, 255, 0, 6, 7, 0X000000);
ltdc_layer_window_config(0, 0, 0, lcdltdc.pwidth, lcdltdc.pheight);
ltdc_select_layer(0);
/* LTDC LCD复位 */
LTDC_RST(1);
rt_thread_mdelay(10);
LTDC_RST(0);
rt_thread_mdelay(50);
LTDC_RST(1);
rt_thread_mdelay(200);
LTDC_BL(1);
ltdc_clear(0XFFFFFFFF);
return 0;
}
/**
* @brief LTDC底层IO初始化和时钟使能
*/
void HAL_LTDC_MspInit(LTDC_HandleTypeDef *hltdc)
{
GPIO_InitTypeDef gpio_init_struct;
__HAL_RCC_LTDC_CLK_ENABLE();
__HAL_RCC_DMA2D_CLK_ENABLE();
/* 控制引脚 */
LTDC_BL_GPIO_CLK_ENABLE();
LTDC_RST_GPIO_CLK_ENABLE();
LTDC_DE_GPIO_CLK_ENABLE();
LTDC_VSYNC_GPIO_CLK_ENABLE();
LTDC_HSYNC_GPIO_CLK_ENABLE();
LTDC_CLK_GPIO_CLK_ENABLE();
gpio_init_struct.Pin = LTDC_BL_GPIO_PIN;
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;
gpio_init_struct.Pull = GPIO_PULLUP;
gpio_init_struct.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(LTDC_BL_GPIO_PORT, &gpio_init_struct);
gpio_init_struct.Pin = LTDC_RST_GPIO_PIN;
HAL_GPIO_Init(LTDC_RST_GPIO_PORT, &gpio_init_struct);
gpio_init_struct.Pin = LTDC_DE_GPIO_PIN;
gpio_init_struct.Mode = GPIO_MODE_AF_PP;
gpio_init_struct.Pull = GPIO_NOPULL;
gpio_init_struct.Speed = GPIO_SPEED_HIGH;
gpio_init_struct.Alternate = GPIO_AF14_LTDC;
HAL_GPIO_Init(LTDC_DE_GPIO_PORT, &gpio_init_struct);
gpio_init_struct.Pin = LTDC_VSYNC_GPIO_PIN;
HAL_GPIO_Init(LTDC_VSYNC_GPIO_PORT, &gpio_init_struct);
gpio_init_struct.Pin = LTDC_HSYNC_GPIO_PIN;
HAL_GPIO_Init(LTDC_HSYNC_GPIO_PORT, &gpio_init_struct);
gpio_init_struct.Pin = LTDC_CLK_GPIO_PIN;
HAL_GPIO_Init(LTDC_CLK_GPIO_PORT, &gpio_init_struct);
/* 数据引脚 */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOI_CLK_ENABLE();
gpio_init_struct.Pin = GPIO_PIN_8;
gpio_init_struct.Alternate = GPIO_AF13_LTDC;
HAL_GPIO_Init(GPIOA, &gpio_init_struct);
gpio_init_struct.Pin = GPIO_PIN_2;
gpio_init_struct.Alternate = GPIO_AF14_LTDC;
HAL_GPIO_Init(GPIOA, &gpio_init_struct);
gpio_init_struct.Pin = GPIO_PIN_6;
HAL_GPIO_Init(GPIOD, &gpio_init_struct);
gpio_init_struct.Pin = GPIO_PIN_5 | GPIO_PIN_6;
HAL_GPIO_Init(GPIOE, &gpio_init_struct);
gpio_init_struct.Pin = GPIO_PIN_6 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14;
HAL_GPIO_Init(GPIOG, &gpio_init_struct);
gpio_init_struct.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 |
GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
HAL_GPIO_Init(GPIOH, &gpio_init_struct);
gpio_init_struct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_4 |
GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
HAL_GPIO_Init(GPIOI, &gpio_init_struct);
}
INIT_DEVICE_EXPORT(ltdc_init);