Files
player/Project/Src/Drive/Source/lcd_rgb.c

1060 lines
31 KiB
C
Raw Normal View History

2025-06-27 00:32:57 +08:00
/***
2025-07-10 11:30:57 +08:00
*****************************************************************************************
* @file lcd.c
* @brief ʹ<EFBFBD><EFBFBD>STM32F29<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>´<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֲ<EFBFBD>ڹٷ<EFBFBD>
*STM32F429I_DISCOVERY ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̣<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD>
*****************************************************************************************
*
*
*
*
******************************************************************************************
***/
2025-06-27 00:32:57 +08:00
#include "lcd_rgb.h"
#include "mymem.h"
2025-07-10 11:30:57 +08:00
#define COLOR565TO888(color) \
((((color) & 0xf800) << 8) | ((color) & 0x07e0) << 5 | \
(((color) & 0x001f) << 3))
#define COLOR888TO565(color) \
((((color) >> 8) & 0xf800) | (((color) >> 5) & 0x07e0) | \
(((color) >> 3) & 0x001f))
// <20><>RGBת<42><D7AA>Ϊ565<36><35>ʽ
#define RGB(r, g, b) ((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3))
// RGBת<42>Ҷ<EFBFBD>
#define RGB2GRAY(rgb16) \
(((((rgb16) & 0xf800) >> 8) + (((rgb16) & 0x07e0) >> 3) + \
(((rgb16) & 0x001f) << 3)) / \
3)
// <20>Ҷ<EFBFBD>תRGB
#define GRAY2RGB(gray) \
((((gray) >> 3) << 11) | (((gray) >> 2) << 5) | ((gray) >> 3))
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IO<49>ڳ<EFBFBD>ʼ<EFBFBD><CABC>
void LCD_GPIO_Config(void) {
GPIO_InitTypeDef GPIO_InitStruct;
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
RCC_AHB1PeriphClockCmd(LCD_GPIO_CLK, ENABLE);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_R0_PIN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
// LCD <20><>ɫ R <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
GPIO_PinAFConfig(LTDC_R0_PORT, LTDC_R0_PINSOURCE, GPIO_AF_LTDC);
GPIO_PinAFConfig(LTDC_R1_PORT, LTDC_R1_PINSOURCE, GPIO_AF_LTDC);
GPIO_PinAFConfig(LTDC_R2_PORT, LTDC_R2_PINSOURCE, GPIO_AF_LTDC);
GPIO_PinAFConfig(LTDC_R3_PORT, LTDC_R3_PINSOURCE, GPIO_AF_LTDC);
GPIO_PinAFConfig(LTDC_R4_PORT, LTDC_R4_PINSOURCE, GPIO_AF_LTDC);
GPIO_PinAFConfig(LTDC_R5_PORT, LTDC_R5_PINSOURCE, GPIO_AF_LTDC);
GPIO_PinAFConfig(LTDC_R6_PORT, LTDC_R6_PINSOURCE, GPIO_AF_LTDC);
GPIO_PinAFConfig(LTDC_R7_PORT, LTDC_R7_PINSOURCE, GPIO_AF_LTDC);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_R0_PIN;
GPIO_Init(LTDC_R0_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_R1_PIN;
GPIO_Init(LTDC_R1_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_R2_PIN;
GPIO_Init(LTDC_R2_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_R3_PIN;
GPIO_Init(LTDC_R3_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_R4_PIN;
GPIO_Init(LTDC_R4_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_R5_PIN;
GPIO_Init(LTDC_R5_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_R6_PIN;
GPIO_Init(LTDC_R6_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_R7_PIN;
GPIO_Init(LTDC_R7_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
// LCD <20><>ɫ G <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_PinAFConfig(LTDC_G0_PORT, LTDC_G0_PINSOURCE, GPIO_AF_LTDC);
GPIO_PinAFConfig(LTDC_G1_PORT, LTDC_G1_PINSOURCE, GPIO_AF_LTDC);
GPIO_PinAFConfig(LTDC_G2_PORT, LTDC_G2_PINSOURCE, GPIO_AF_LTDC);
GPIO_PinAFConfig(LTDC_G3_PORT, LTDC_G3_PINSOURCE, GPIO_AF_LTDC);
GPIO_PinAFConfig(LTDC_G4_PORT, LTDC_G4_PINSOURCE, GPIO_AF_LTDC);
GPIO_PinAFConfig(LTDC_G5_PORT, LTDC_G5_PINSOURCE, GPIO_AF_LTDC);
GPIO_PinAFConfig(LTDC_G6_PORT, LTDC_G6_PINSOURCE, GPIO_AF_LTDC);
GPIO_PinAFConfig(LTDC_G7_PORT, LTDC_G7_PINSOURCE, GPIO_AF_LTDC);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_G0_PIN;
GPIO_Init(LTDC_G0_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_G1_PIN;
GPIO_Init(LTDC_G1_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_G2_PIN;
GPIO_Init(LTDC_G2_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_G3_PIN;
GPIO_Init(LTDC_G3_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_G4_PIN;
GPIO_Init(LTDC_G4_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_G5_PIN;
GPIO_Init(LTDC_G5_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_G6_PIN;
GPIO_Init(LTDC_G6_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_G7_PIN;
GPIO_Init(LTDC_G7_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
// LCD <20><>ɫ B <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_PinAFConfig(LTDC_B0_PORT, LTDC_B0_PINSOURCE, GPIO_AF_LTDC);
GPIO_PinAFConfig(LTDC_B1_PORT, LTDC_B1_PINSOURCE, GPIO_AF_LTDC);
GPIO_PinAFConfig(LTDC_B2_PORT, LTDC_B2_PINSOURCE, GPIO_AF_LTDC);
GPIO_PinAFConfig(LTDC_B3_PORT, LTDC_B3_PINSOURCE, GPIO_AF_LTDC);
GPIO_PinAFConfig(LTDC_B4_PORT, LTDC_B4_PINSOURCE, GPIO_AF_LTDC);
GPIO_PinAFConfig(LTDC_B5_PORT, LTDC_B5_PINSOURCE, GPIO_AF_LTDC);
GPIO_PinAFConfig(LTDC_B6_PORT, LTDC_B6_PINSOURCE, GPIO_AF_LTDC);
GPIO_PinAFConfig(LTDC_B7_PORT, LTDC_B7_PINSOURCE, GPIO_AF_LTDC);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_B0_PIN;
GPIO_Init(LTDC_B0_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_B1_PIN;
GPIO_Init(LTDC_B1_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_B2_PIN;
GPIO_Init(LTDC_B2_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_B3_PIN;
GPIO_Init(LTDC_B3_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_B4_PIN;
GPIO_Init(LTDC_B4_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_B5_PIN;
GPIO_Init(LTDC_B5_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_B6_PIN;
GPIO_Init(LTDC_B6_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_B7_PIN;
GPIO_Init(LTDC_B7_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
GPIO_PinAFConfig(LTDC_CLK_PORT, LTDC_CLK_PINSOURCE, GPIO_AF_LTDC);
GPIO_PinAFConfig(LTDC_HSYNC_PORT, LTDC_HSYNC_PINSOURCE, GPIO_AF_LTDC);
GPIO_PinAFConfig(LTDC_VSYNC_PORT, LTDC_VSYNC_PINSOURCE, GPIO_AF_LTDC);
GPIO_PinAFConfig(LTDC_DE_PORT, LTDC_DE_PINSOURCE, GPIO_AF_LTDC);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_CLK_PIN;
GPIO_Init(LTDC_CLK_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_HSYNC_PIN;
GPIO_Init(LTDC_HSYNC_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_VSYNC_PIN;
GPIO_Init(LTDC_VSYNC_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_InitStruct.GPIO_Pin = LTDC_DE_PIN;
GPIO_Init(LTDC_DE_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
// <20><><EFBFBD><EFBFBD>
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_Pin = LTDC_Black_PIN;
GPIO_Init(LTDC_Black_PORT, &GPIO_InitStruct);
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
GPIO_SetBits(LTDC_Black_PORT, LTDC_Black_PIN);
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
void LCD_Backlight(u8 power) {
if (power) {
GPIO_SetBits(LTDC_Black_PORT, LTDC_Black_PIN);
} else {
GPIO_ResetBits(LTDC_Black_PORT, LTDC_Black_PIN);
}
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
static u32 *LCD_ADDR = ((u32 *)(LCD_MemoryAdd + LCD_MemoryAdd_OFFSET * 0));
static u32 *LCD_ADDR1 = ((u32 *)(LCD_MemoryAdd + LCD_MemoryAdd_OFFSET * 1));
#define LCD_ADDR_BUFF0 \
((u32)(LCD_MemoryAdd + (uint32_t)LCD_Width * LCD_Height * 4 * 0))
#define LCD_ADDR_BUFF1 \
((u32)(LCD_MemoryAdd + (uint32_t)LCD_Width * LCD_Height * 4 * 1))
#define LCD_ADDR_BUFF2 \
((u32)(LCD_MemoryAdd + (uint32_t)LCD_Width * LCD_Height * 4 * 2))
const static u32 g_lcdAddrTable[3] = {
(u32)LCD_ADDR_BUFF0,
(u32)LCD_ADDR_BUFF1,
(u32)LCD_ADDR_BUFF2,
};
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
static LCD_Struct g_lcd = {0};
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>LCD<43><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// ˵<><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>emWin<69><6E>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFB1BB><EFBFBD><EFBFBD>
//
void LCD_Init(void) {
u16 LCD_PLLSAIN = 0; // <20><><EFBFBD>ڱ<EFBFBD>Ƶ<EFBFBD><C6B5>PLLSAIN<49><4E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>ΧΪ50~432
u8 LCD_PLLSAIR = 3; // <20><><EFBFBD>ڷ<EFBFBD>Ƶ<EFBFBD><C6B5>PLLSAIR<49><52><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>ΧΪ2~7
u8 LCD_CLKDIV =
8; // LCDʱ<44>ӷ<EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ8<CEAA><38>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD>ֵ<EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD>RCC_PLLSAIDivR_Div8
LTDC_InitTypeDef LTDC_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_LTDC, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2D, ENABLE);
LCD_GPIO_Config(); // <20><>ʼ<EFBFBD><CABC>LCD<43><44><EFBFBD><EFBFBD>
LCD_PLLSAIN =
LCD_CLK * LCD_PLLSAIR *
LCD_CLKDIV; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫʹ<D2AA>õ<EFBFBD>LCDʱ<44>Ӽ<EFBFBD><D3BC><EFBFBD>PLLSAIN<49><4E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>ΧΪ50~432
RCC_PLLSAIConfig(LCD_PLLSAIN, 7, LCD_PLLSAIR); // ʱ<><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
RCC_LTDCCLKDivConfig(
RCC_PLLSAIDivR_Div8); // LCDʱ<44>ӷ<EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD>ã<EFBFBD>Ҫ<EFBFBD><D2AA>LCD_CLKDIV<49><56>Ӧ
RCC_PLLSAICmd(ENABLE); // ʹ<><CAB9>PLLSAIʱ<49><CAB1>
while (RCC_GetFlagStatus(RCC_FLAG_PLLSAIRDY) == RESET)
; // <20>ȴ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
LTDC_InitStruct.LTDC_HSPolarity = LTDC_HSPolarity_AL;
LTDC_InitStruct.LTDC_VSPolarity = LTDC_VSPolarity_AL;
LTDC_InitStruct.LTDC_DEPolarity = LTDC_DEPolarity_AL;
LTDC_InitStruct.LTDC_PCPolarity = LTDC_PCPolarity_IPC;
LTDC_InitStruct.LTDC_BackgroundRedValue = 0;
LTDC_InitStruct.LTDC_BackgroundGreenValue = 0;
LTDC_InitStruct.LTDC_BackgroundBlueValue = 0;
LTDC_InitStruct.LTDC_HorizontalSync = HSW;
LTDC_InitStruct.LTDC_VerticalSync = VSW;
LTDC_InitStruct.LTDC_AccumulatedHBP = HBP;
LTDC_InitStruct.LTDC_AccumulatedVBP = VBP;
LTDC_InitStruct.LTDC_AccumulatedActiveW = LCD_Width + HBP;
LTDC_InitStruct.LTDC_AccumulatedActiveH = LCD_Height + VBP;
LTDC_InitStruct.LTDC_TotalWidth = LCD_Width + HBP + HFP;
LTDC_InitStruct.LTDC_TotalHeigh = LCD_Height + VBP + VFP;
LTDC_Init(&LTDC_InitStruct); // <20><>ʼ<EFBFBD><CABC>LCD<43><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
LTDC_ITConfig(LTDC_IT_LI, ENABLE);
NVIC_SetPriority(LTDC_IRQn, 0);
NVIC_EnableIRQ(LTDC_IRQn);
LTDC_Cmd(ENABLE); // ʹ<><CAB9>LCD<43><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
LCD_LayerInit();
g_lcd.x_size = LCD_Width;
g_lcd.y_size = LCD_Height;
g_lcd.show = (u16 *)g_lcdAddrTable[0];
g_lcd.draw = (u16 *)g_lcdAddrTable[1];
LCD_SetWindow(0, 0, g_lcd.x_size, g_lcd.y_size);
g_lcd.bkColor = 0x0;
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>LCD<43><44><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD>ʼ<EFBFBD><CABC>
//
void LCD_LayerInit(void) {
LTDC_Layer_InitTypeDef LTDC_Layer_InitStruct;
LTDC_Layer_InitStruct.LTDC_HorizontalStart = HBP + 1;
LTDC_Layer_InitStruct.LTDC_HorizontalStop = (LCD_Width + HBP);
LTDC_Layer_InitStruct.LTDC_VerticalStart = VBP + 1;
LTDC_Layer_InitStruct.LTDC_VerticalStop = (LCD_Height + VBP);
// LTDC_Layer_InitStruct.LTDC_PixelFormat = LTDC_Pixelformat_ARGB8888;
// //<2F><><EFBFBD>ظ<EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>
LTDC_Layer_InitStruct.LTDC_PixelFormat =
LTDC_Pixelformat_RGB565; // <20><><EFBFBD>ظ<EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>
LTDC_Layer_InitStruct.LTDC_ConstantAlpha = 255;
LTDC_Layer_InitStruct.LTDC_DefaultColorBlue = 0; // Ĭ<>ϵ<EFBFBD><CFB5><EFBFBD>ɫ
LTDC_Layer_InitStruct.LTDC_DefaultColorGreen = 0;
LTDC_Layer_InitStruct.LTDC_DefaultColorRed = 0;
LTDC_Layer_InitStruct.LTDC_DefaultColorAlpha = 0;
LTDC_Layer_InitStruct.LTDC_BlendingFactor_1 = LTDC_BlendingFactor1_CA;
LTDC_Layer_InitStruct.LTDC_BlendingFactor_2 = LTDC_BlendingFactor2_CA;
LTDC_Layer_InitStruct.LTDC_CFBLineNumber = LCD_Height; // <20><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
LTDC_Layer_InitStruct.LTDC_CFBStartAdress = LCD_MemoryAdd; // <20><>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>ַ
// <20><><EFBFBD><EFBFBD>ARGB8888<38><38>RGB888ʹ<38><CAB9><EFBFBD><EFBFBD>ͬ<EFBFBD>ļ<EFBFBD><C4BC>ʽ
{
LTDC_Layer_InitStruct.LTDC_CFBLineLength =
((LCD_Width * 2) + 3); // ÿ<>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>
LTDC_Layer_InitStruct.LTDC_CFBPitch =
(LCD_Width * 2); // <20>м<EFBFBD><D0BC>࣬ij<E0A3AC><C4B3><EFBFBD>ص<EFBFBD><D8B5><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>е<EFBFBD><D0B5><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
LTDC_LayerInit(LTDC_Layer1, &LTDC_Layer_InitStruct); // <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>1
LTDC_LayerCmd(LTDC_Layer1, ENABLE); // ʹ<>ܲ<EFBFBD>1
#if (LCD_NUM_LAYERS == 2) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˫<EFBFBD><CBAB>ʱ
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
LTDC_Layer_InitStruct.LTDC_PixelFormat = ColorMode_1; // <20><><EFBFBD>ظ<EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>
LTDC_Layer_InitStruct.LTDC_BlendingFactor_1 = LTDC_BlendingFactor1_PAxCA;
LTDC_Layer_InitStruct.LTDC_BlendingFactor_2 = LTDC_BlendingFactor2_PAxCA;
LTDC_Layer_InitStruct.LTDC_CFBStartAdress =
LCD_MemoryAdd + LCD_MemoryAdd_OFFSET; // <20><>2<EFBFBD><32><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>ַ
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
if (ColorMode_1 == LCD_RGB565 || ColorMode_1 == LCD_ARGB1555) // <20>ж<EFBFBD><D0B6><EFBFBD>ɫ<EFBFBD><C9AB>ʽ
{
LTDC_Layer_InitStruct.LTDC_CFBLineLength =
((LCD_Width * 2) + 3); // ÿ<>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>
LTDC_Layer_InitStruct.LTDC_CFBPitch =
(LCD_Width * 2); // <20>м<EFBFBD><D0BC>࣬ij<E0A3AC><C4B3><EFBFBD>ص<EFBFBD><D8B5><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>е<EFBFBD><D0B5><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
} else // <20><><EFBFBD><EFBFBD>ARGB8888<38><38>RGB888ʹ<38><CAB9><EFBFBD><EFBFBD>ͬ<EFBFBD>ļ<EFBFBD><C4BC>ʽ
{
LTDC_Layer_InitStruct.LTDC_CFBLineLength =
((LCD_Width * 4) + 3); // ÿ<>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>
LTDC_Layer_InitStruct.LTDC_CFBPitch =
(LCD_Width * 4); // <20>м<EFBFBD><D0BC>࣬ij<E0A3AC><C4B3><EFBFBD>ص<EFBFBD><D8B5><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>е<EFBFBD><D0B5><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
LTDC_LayerInit(LTDC_Layer2, &LTDC_Layer_InitStruct); // <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>2
LTDC_LayerCmd(LTDC_Layer2, ENABLE); // ʹ<>ܲ<EFBFBD>2
#endif
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
LTDC_ReloadConfig(LTDC_IMReload); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
LTDC_DitherCmd(
ENABLE); // ʹ<><CAB9><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>24λɫ<CEBB><C9AB><EFBFBD><EFBFBD><EFBFBD>򿪣<EFBFBD><F2BFAAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޷<EFBFBD><DEB7>ﵽ24λɫ<CEBB><C9AB>Ч<EFBFBD><D0A7>
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
void LTDC_ISR_Handler(void) {
LTDC_ClearFlag(LTDC_FLAG_LI);
if (g_lcd.LcdSwitchEn == 1) {
g_lcd.LcdSwitchEn = 0;
LTDC_Layer1->CFBAR = (u32)g_lcd.show;
LTDC->SRCR = 1;
}
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
static int LCD_UpDataWindow(void) {
LCD_WindowStruct *win = &g_lcd.win;
LCD_WindowStruct *draw = &g_lcd.realwin;
int real = 1;
if (win->xs >= 0 && win->xs < g_lcd.x_size)
draw->xs = win->xs;
else if (win->xs < 0)
draw->xs = 0;
else if (win->xs >= g_lcd.x_size)
real = 0; // <20><><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (win->ys >= 0 && win->ys < g_lcd.y_size)
draw->ys = win->ys;
else if (win->ys < 0)
draw->ys = 0;
else if (win->ys >= g_lcd.y_size)
real = 0; // <20><><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (win->xe >= 0 && win->xe < g_lcd.x_size)
draw->xe = win->xe;
else if (win->xe < 0)
real = 0; // <20><><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
else if (win->xe >= g_lcd.x_size)
draw->xe = g_lcd.x_size - 1;
if (win->ye >= 0 && win->ye < g_lcd.y_size)
draw->ye = win->ye;
else if (win->ye < 0)
real = 0; // <20><><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
else if (win->ye >= g_lcd.y_size)
draw->ye = g_lcd.y_size - 1;
if ((win->xs > win->xe) || (win->ys > win->ye))
real = 0;
g_lcd.effective = real;
return real;
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// <20><><EFBFBD>û<C3BB><EEB6AF><EFBFBD><EFBFBD>
void LCD_SetWindow(int x_s, int y_s, int x_size, int y_size) {
g_lcd.win.xs = x_s;
g_lcd.win.ys = y_s;
g_lcd.win.xe = x_s + x_size - 1;
g_lcd.win.ye = y_s + y_size - 1;
LCD_UpDataWindow();
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
int LCD_GetLcdSizeX(void) { return LCD_Width; }
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
int LCD_GetLcdSizeY(void) { return LCD_Height; }
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
// <20><>ȡͼ<C8A1><CDBC><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>ַ
u32 *LCD_GetShowAddr(void) {
uint32_t *ret = (u32 *)LTDC_Layer1->CFBAR;
ret = (u32 *)g_lcd.show;
return ret;
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// <20><>ȡͼ<C8A1><CDBC><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>ַ
u32 *LCD_GetDrawAddr(void) {
uint32_t *ret = 0;
ret = (u32 *)g_lcd.draw;
return ret;
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB>ʾ<EFBFBD><CABE>ַ,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱַ<D6B7><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD>ĵ<EFBFBD>ַ
u32 LCD_SetLayer(u32 AddrIndex) {
uint32_t ret = LTDC_Layer1->CFBAR;
if (AddrIndex < 3) {
g_lcd.show = (u16 *)g_lcdAddrTable[AddrIndex];
LTDC_Layer1->CFBAR = g_lcdAddrTable[AddrIndex];
LTDC->SRCR = 1;
}
for (int i = 0; i < 3; i++) {
if (ret == g_lcdAddrTable[i]) {
ret = i;
break;
}
}
if (ret >= 3)
ret = 0;
return ret;
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// <20><><EFBFBD>û<EFBFBD>ͼ<EFBFBD><CDBC>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><D0BB>Ʋ<EFBFBD><C6B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִַ<D6B7><D6B4>
u32 LCD_SetDrawLayer(u32 Index) {
u32 ret = (u32)g_lcd.draw;
if (Index < 3) {
g_lcd.draw = (u16 *)g_lcdAddrTable[Index];
}
for (int i = 0; i < 3; i++) {
if (ret == g_lcdAddrTable[i]) {
ret = i;
break;
}
}
if (ret >= 3)
ret = 0;
return ret;
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
u32 LCD_SetLcdColor(u32 color) {
u32 ret = g_lcd.color;
// g_lcd_struct.Color=color;
g_lcd.color = COLOR888TO565(color);
return ret;
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
u32 LCD_SetLcdBkColor(u32 color) {
u32 ret = g_lcd.bkColor;
// g_lcd_struct.BackColor=color;
ret = g_lcd.bkColor = COLOR888TO565(color);
return ret;
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
u32 LCD_SetLcdColor16(u32 color) {
u32 ret = g_lcd.color;
g_lcd.color = (color);
return ret;
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
u32 LCD_SetLcdBkColor16(u32 color) {
u32 ret = ret = g_lcd.bkColor;
ret = g_lcd.bkColor = (color);
return ret;
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
u32 LCD_GetLcdColor(void) {
u32 ret = g_lcd.color;
return COLOR565TO888(ret);
}
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
u32 LCD_GetLcdBkColor(void) {
u32 ret = g_lcd.bkColor;
return COLOR565TO888(ret);
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
u32 LCD_GetLcdColor16(void) {
u32 ret = g_lcd.color;
return ret;
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
u32 LCD_GetLcdBkColor16(void) {
u32 ret = g_lcd.bkColor;
return ret;
}
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
// <20><><EFBFBD>û<EFBFBD><C3BB><EFBFBD>ģʽ<C4A3><CABD>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʊ<EFBFBD><C6B1><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><30><EFBFBD><EFBFBD><EFBFBD>Ʊ<EFBFBD><C6B1><EFBFBD>
void LCD_SetLcdDrawMode(int mode) {
if (mode) {
// g_lcd.DrawMode=1;//<2F><>ʱ<EFBFBD><CAB1><EFBFBD>û<EFBFBD><C3BB><EFBFBD><E3BAAF>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>Ʊ<EFBFBD><C6B1><EFBFBD>ɫ
} else {
// g_lcd.DrawMode=0;
}
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
static void LCD_DmaCopy(void *pSrc, void *pDst, uint32_t x_size,
uint32_t y_size) {
DMA2D_DeInit();
/* Set up mode */
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
DMA2D->CR =
0x00010000UL | (1 << 9); /* Control Register (Memory to memory with pixel
format conversion and TCIE) */
2025-06-27 00:32:57 +08:00
/* Set up pointers */
2025-07-10 11:30:57 +08:00
DMA2D->FGMAR =
(uint32_t)pSrc; /* Foreground Memory Address Register (Source address) */
DMA2D->OMAR =
(uint32_t)pDst; /* Output Memory Address Register (Destination address) */
2025-06-27 00:32:57 +08:00
/* Set up offsets */
2025-07-10 11:30:57 +08:00
DMA2D->FGOR = 0; /* Foreground Offset Register (Source line offset) */
DMA2D->OOR = 0; /* Output Offset Register (Destination line offset) */
2025-06-27 00:32:57 +08:00
/* Set up pixel format */
2025-07-10 11:30:57 +08:00
DMA2D->FGPFCCR =
LTDC_Pixelformat_RGB565; /* Foreground PFC Control Register (Defines the
input pixel format) */
DMA2D->OPFCCR =
LTDC_Pixelformat_RGB565; /* Output PFC Control Register (Defines the
output pixel format) */
2025-06-27 00:32:57 +08:00
/* Set up size */
2025-07-10 11:30:57 +08:00
DMA2D->NLR = (uint32_t)(x_size << 16) |
y_size; /* Number of Line Register (Size configuration of area to
be transfered) */
2025-06-27 00:32:57 +08:00
/* Execute operation */
2025-07-10 11:30:57 +08:00
DMA2D->CR |= DMA2D_CR_START;
while (DMA2D->CR & DMA2D_CR_START) {
2025-06-27 00:32:57 +08:00
}
}
2025-07-10 11:30:57 +08:00
static void LCD_FillColor(void *pDst, int x, int y, int x_size, int y_size,
u32 color) {
DMA2D_DeInit();
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
DMA2D->OPFCCR = DMA2D_RGB565;
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
DMA2D->CR = DMA2D_R2M;
DMA2D->OCOLR = color;
DMA2D->OMAR = (u32)pDst + (y * LCD_Width + x) * 2;
DMA2D->OOR = LCD_Width - x_size;
DMA2D->NLR = (x_size << 16) | y_size;
2025-06-27 00:32:57 +08:00
/* Execute operation */
2025-07-10 11:30:57 +08:00
DMA2D->CR |= DMA2D_CR_START;
while (DMA2D->CR & DMA2D_CR_START) {
2025-06-27 00:32:57 +08:00
}
}
2025-07-10 11:30:57 +08:00
void LCD_FillImg(const u16 *pSurf, int x, int y, u16 w, u16 h, int width_bytes,
const u8 *bits) {
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
DMA2D_DeInit();
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
DMA2D->OPFCCR = DMA2D_RGB565;
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
DMA2D->CR = DMA2D_M2M;
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
DMA2D->OMAR = (u32)pSurf + (y * LCD_Width + x) * 2;
DMA2D->OOR = LCD_Width - w;
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
DMA2D->NLR = (w << 16) | h;
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
DMA2D->FGPFCCR = CM_RGB565;
DMA2D->FGMAR = (u32)bits;
DMA2D->FGOR = (width_bytes >> 1) - w;
2025-06-27 00:32:57 +08:00
/* Execute operation */
2025-07-10 11:30:57 +08:00
DMA2D->CR |= DMA2D_CR_START;
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
while (DMA2D->CR & DMA2D_CR_START) {
}
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// <20><EFBFBD><E3B8B4>
void LCD_LayerCopy(int dst, int src) {
u32 *p_dst = 0;
u32 *p_src = 0;
if ((dst < 3) && (src < 3)) {
p_dst = (u32 *)g_lcdAddrTable[dst];
p_src = (u32 *)g_lcdAddrTable[src];
LCD_DmaCopy(p_src, p_dst, LCD_Width, LCD_Height);
}
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// <20><>ʼ<EFBFBD>ڻ<EFBFBD><DABB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void LCD_LayerBufferOn(void) {
// Ϊ<>˼<EFBFBD><CBBC><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD>Ĵ<EFBFBD><C4B4>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>պ<EFBFBD><D5BA><EFBFBD><EFBFBD><EFBFBD>2019.12.26
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// <20><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void LCD_LayerBuffShow(void) {
// Ϊ<>˼<EFBFBD><CBBC><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD>Ĵ<EFBFBD><C4B4>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>պ<EFBFBD><D5BA><EFBFBD><EFBFBD><EFBFBD>2019.12.26
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// <20><><EFBFBD><EFBFBD><EBBBBA><EFBFBD><EFBFBD>
void LCD_EnterLayerBuff(void) {
if (g_lcd.LayerBuffEnter != 0)
return;
g_lcd.LayerBuffEnter++;
// while(LCD_GetLayerUpdataStat()==0);
if (g_lcd.LcdSwitchEn == 1) {
// <20><><EFBFBD><EFBFBD><EFBFBD>ϴθ<CFB4><CEB8>Ļ<EFBFBD>û<EFBFBD><C3BB><EFBFBD>ü<EFBFBD>ˢ<EFBFBD>£<EFBFBD><C2A3><EFBFBD>ˢ<EFBFBD><CBA2><EFBFBD>ˣ<EFBFBD><CBA3><EFBFBD><EFBFBD>θ<EFBFBD><CEB8><EFBFBD>֮<EFBFBD><D6AE>һ<EFBFBD><D2BB>ˢ<EFBFBD><CBA2>
// <20><><EFBFBD><EFBFBD>Ӧ<EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļˢ<C4BB><CBA2>̫<EFBFBD><EFBFBD><ECA3AC><EFBFBD><EFBFBD><EFBFBD>ɶ<EFBFBD>֡
g_lcd.LcdSwitchEn = 0;
} else {
// ˢ<><CBA2><EFBFBD><EFBFBD>֮<EFBFBD><D6AE><EFBFBD><EFBFBD>lcd<63><64>ʾ<EFBFBD><CABE><EFBFBD>ͻ<EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD>ͬһ<CDAC><D2BB><EFBFBD>ڴ棬<DAB4><E6A3AC>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>
if ((u32)g_lcd.show == g_lcdAddrTable[0]) {
g_lcd.draw = (u16 *)g_lcdAddrTable[1];
LCD_LayerCopy(1, 0);
} else if ((u32)g_lcd.show == g_lcdAddrTable[1]) {
g_lcd.draw = (u16 *)g_lcdAddrTable[0];
LCD_LayerCopy(0, 1);
}
}
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// <20>л<EFBFBD><D0BB><EFBFBD><E3A3AC><EFBFBD>ø<EFBFBD><C3B8><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶʱ<C6B5><CAB1>
void LCD_SwitchLayerBuff(void) {
if (g_lcd.LayerBuffEnter != 0)
return;
g_lcd.LayerBuffEnter++;
if (g_lcd.LcdSwitchEn == 1) {
// <20><><EFBFBD><EFBFBD><EFBFBD>ϴθ<CFB4><CEB8>Ļ<EFBFBD>û<EFBFBD><C3BB><EFBFBD>ü<EFBFBD>ˢ<EFBFBD>£<EFBFBD><C2A3><EFBFBD>ˢ<EFBFBD><CBA2><EFBFBD>ˣ<EFBFBD><CBA3><EFBFBD><EFBFBD>θ<EFBFBD><CEB8><EFBFBD>֮<EFBFBD><D6AE>һ<EFBFBD><D2BB>ˢ<EFBFBD><CBA2>
// <20><><EFBFBD><EFBFBD>Ӧ<EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļˢ<C4BB><CBA2>̫<EFBFBD><EFBFBD><ECA3AC><EFBFBD><EFBFBD><EFBFBD>ɶ<EFBFBD>֡
g_lcd.LcdSwitchEn = 0;
} else {
// ˢ<><CBA2><EFBFBD><EFBFBD>֮<EFBFBD><D6AE><EFBFBD><EFBFBD>lcd<63><64>ʾ<EFBFBD><CABE><EFBFBD>ͻ<EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD>ͬһ<CDAC><D2BB><EFBFBD>ڴ棬<DAB4><E6A3AC>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>
if ((u32)g_lcd.show == g_lcdAddrTable[0]) {
g_lcd.draw = (u16 *)g_lcdAddrTable[1];
} else if ((u32)g_lcd.show == g_lcdAddrTable[1]) {
g_lcd.draw = (u16 *)g_lcdAddrTable[0];
}
}
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// <20>˳<EFBFBD><CBB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void LCD_ExitLayerBuff(void) {
g_lcd.show = g_lcd.draw;
g_lcd.LcdSwitchEn = 1;
g_lcd.LayerBuffEnter = 0;
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// <20><>ȡ<EFBFBD><C8A1>Ļˢ<C4BB><CBA2>״̬<D7B4><CCAC>1<EFBFBD><31><EFBFBD><EFBFBD>ˢ<EFBFBD><CBA2>
int LCD_GetLayerUpdataStat(void) { return !g_lcd.LcdSwitchEn; }
// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>,<2C>Դ<EFBFBD><D4B4>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><E3A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E4B5BD><EFBFBD>ڵ<EFBFBD><DAB5>յ<EFBFBD>λ<EFBFBD><CEBB>
static void LCD_FillLine16(int x, int y, int xe, u16 *buff, int xsize) {
if (g_lcd.effective == 0)
return;
x += g_lcd.win.xs;
xe += g_lcd.win.xs;
if ((y < g_lcd.realwin.ys) || (y > g_lcd.realwin.ye))
return;
if ((x + xsize - 1 < g_lcd.realwin.xs) || x > g_lcd.realwin.xe)
return;
int mx = x;
if (mx < g_lcd.realwin.xs)
mx = g_lcd.realwin.xs;
buff += mx - x;
xsize -= mx - x;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>Χ
// if (mx + xsize - 1 > xe) xsize=xe - mx + 1;
if (xsize > g_lcd.realwin.xe - mx + 1)
xsize = g_lcd.realwin.xe - mx + 1;
for (int i = 0; i < xsize; i++)
g_lcd.draw[mx + y * g_lcd.x_size + i] = (buff[i]);
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// <20><>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E4B5BD>Ļ<EFBFBD>Ļ<C4BB><EEB6AF><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD>
// <20><><EFBFBD><EFBFBD>xsize,ͼ<><CDBC><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD>
// <20><><EFBFBD><EFBFBD>ysize,ͼ<><CDBC><EFBFBD>ĸ߶<C4B8>
static void LCD_FillRect16(int xs, int ys, int xe, int ye, u16 *buff, int xsize,
int ysize) {
ys += g_lcd.win.ys;
ye += g_lcd.win.ys;
xs += g_lcd.win.xs;
xe += g_lcd.win.xs;
// for (int y = ys; y<=ye; y++)
// {
// LCD_FillLine16( xs,y,xe,buff, xsize);
// buff += xsize;
// }
if (ye < g_lcd.realwin.ys || ys > g_lcd.realwin.ye)
return;
if (xe < g_lcd.realwin.xs || xs > g_lcd.realwin.xe)
return;
if (ys < g_lcd.realwin.ys) {
buff += (g_lcd.realwin.ys - ys) * xsize;
ysize -= g_lcd.realwin.ys - ys;
if (ysize < 0)
return;
ys = g_lcd.realwin.ys;
}
if (xs < g_lcd.realwin.xs) {
buff += (g_lcd.realwin.xs - xs);
xsize -= g_lcd.realwin.xs - xs;
if (xsize < 0)
return;
xs = g_lcd.realwin.xs;
}
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
int lcd_xsize = xe - xs + 1;
if (lcd_xsize > xsize)
lcd_xsize = xsize;
if (ysize > ye - ys + 1)
ysize = ye - ys + 1;
if (lcd_xsize > 0 && ysize > 0)
LCD_FillImg(g_lcd.draw, xs, ys, lcd_xsize, ysize, xsize * 2, (u8 *)buff);
// DMA2D_DrawBitmap_RGB565(LCD_GetDrawAddr(),g_lcd_struct.WindowSrcX,g_lcd_struct.WindowSrcY,lcd_xsize,ysize,xsize*2,(u8*)buff);
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// <20><>ͼ<EFBFBD><CDBC>ƫ<EFBFBD><C6AB>֮<EFBFBD><D6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E4B5BD>Ļ<EFBFBD>Ļ<C4BB><EEB6AF><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD>
// <20><><EFBFBD><EFBFBD>x_s,ͼ<><CDBC>Ҫ<EFBFBD><D2AA>ʾ<EFBFBD>ĺ<EFBFBD><C4BA><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD>y_s<5F><73>ͼ<EFBFBD><CDBC>Ҫ<EFBFBD><D2AA>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD>xsize,ͼ<><CDBC><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD>
// <20><><EFBFBD><EFBFBD>ysize,ͼ<><CDBC><EFBFBD>ĸ߶<C4B8>
static void LCD_FillRectOff16(int xs, int ys, int xe, int ye, u16 *buff,
int x_s, int y_s, int xsize, int ysize) {
// ͼ<><CDBC>ƫ<EFBFBD><C6AB>
int offset = y_s * xsize + x_s;
// ͼ<><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļƫ<C4BB><C6AB>
// offset += xs + ys*xsize;
LCD_FillRect16(xs, ys, xe, ye, buff + offset, xsize, ysize - y_s);
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
void LCD_FillRectOff16At(int lcd_xs, int lcd_ys, int lcd_xsize, int lcd_ysize,
u16 *buff, int xs, int ys, int xsize, int ysize) {
// <20><>ͼ
LCD_FillRectOff16(lcd_xs, lcd_ys, lcd_xs + lcd_xsize - 1,
lcd_ys + lcd_ysize - 1, buff, xs, ys, xsize, ysize);
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
static int LCD_FillImg_ARGB(const void *pSurf, int x, int y, u16 w, u16 h,
int width_bytes, const u8 *bits, u32 color_format);
// <20><>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E4B5BD>Ļ<EFBFBD>Ļ<C4BB><EEB6AF><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD>
// <20><><EFBFBD><EFBFBD>xsize,ͼ<><CDBC><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD>
// <20><><EFBFBD><EFBFBD>ysize,ͼ<><CDBC><EFBFBD>ĸ߶<C4B8>
static void LCD_FillRectAlpha(int xs, int ys, int xe, int ye, u32 *buff,
int xsize, int ysize) {
ys += g_lcd.win.ys;
ye += g_lcd.win.ys;
xs += g_lcd.win.xs;
xe += g_lcd.win.xs;
if (ye < g_lcd.realwin.ys || ys > g_lcd.realwin.ye)
return;
if (xe < g_lcd.realwin.xs || xs > g_lcd.realwin.xe)
return;
if (ys < g_lcd.realwin.ys) {
buff += (g_lcd.realwin.ys - ys) * xsize;
ysize -= g_lcd.realwin.ys - ys;
if (ysize < 0)
return;
ys = g_lcd.realwin.ys;
}
if (xs < g_lcd.realwin.xs) {
buff += (g_lcd.realwin.xs - xs);
xsize -= g_lcd.realwin.xs - xs;
if (xsize < 0)
return;
xs = g_lcd.realwin.xs;
}
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
int lcd_xsize = xe - xs + 1;
if (lcd_xsize > xsize)
lcd_xsize = xsize;
if (ysize > ye - ys + 1)
ysize = ye - ys + 1;
if (lcd_xsize > 0 && ysize > 0)
LCD_FillImg_ARGB(g_lcd.draw, xs, ys, lcd_xsize, ysize, xsize * 4,
(u8 *)buff, CM_ARGB8888);
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
static void LCD_FillRectOffAlpha(int xs, int ys, int xe, int ye, u32 *buff,
int x_s, int y_s, int xsize, int ysize) {
// ͼ<><CDBC>ƫ<EFBFBD><C6AB>
int offset = y_s * xsize + x_s;
// ͼ<><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļƫ<C4BB><C6AB>
// offset += xs + ys*xsize;
LCD_FillRectAlpha(xs, ys, xe, ye, buff + offset, xsize, ysize - y_s);
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
void LCD_FillRectOffAtAlpha(int lcd_xs, int lcd_ys, int lcd_xsize,
int lcd_ysize, void *buff, int xs, int ys,
int xsize, int ysize) {
// <20><>ͼ
LCD_FillRectOffAlpha(lcd_xs, lcd_ys, lcd_xs + lcd_xsize - 1,
lcd_ys + lcd_ysize - 1, buff, xs, ys, xsize, ysize);
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// <20><><EFBFBD><EFBFBD><E3A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>а<EFBFBD>ȫ<EFBFBD>Լ<EFBFBD><D4BC><EFBFBD><E9A3AC><EFBFBD><EFBFBD>ʱҪ<CAB1><D2AA>֤Ҫ<D6A4><D2AA><EFBFBD>ĵ㲻<C4B5><EFBFBD><E1B3AC><EFBFBD><EFBFBD>Ļ
// <20><><EFBFBD><EFBFBD>mode,1<><31><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0>ɫ<EFBFBD><C9AB>0<EFBFBD><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ
void LCD_DrawPoint(int x, int y, u32 mode) {
if (g_lcd.effective == 0)
return;
x += g_lcd.win.xs;
y += g_lcd.win.ys;
if (x < g_lcd.realwin.xs || x > g_lcd.realwin.xe)
return;
if (y < g_lcd.realwin.ys || y > g_lcd.realwin.ye)
return;
if (mode)
g_lcd.draw[x + y * g_lcd.x_size] = g_lcd.color;
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// <20><>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><E3A3AC><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>Ϊԭ<CEAA><EFBFBD><E3A3AC><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><E1B3AC><EFBFBD><EFBFBD><EFBFBD>ڷ<EFBFBD>Χ
void LCD_DrawPointSafe(int x, int y, u32 mode) {
if (g_lcd.effective == 0)
return;
x += g_lcd.win.xs;
y += g_lcd.win.ys;
if (x < g_lcd.realwin.xs || x > g_lcd.realwin.xe)
return;
if (y < g_lcd.realwin.ys || y > g_lcd.realwin.ye)
return;
if (mode)
g_lcd.draw[x + y * g_lcd.x_size] = g_lcd.color;
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// <20><>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><E3A3AC><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>Ϊԭ<CEAA><EFBFBD><E3A3AC><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><E1B3AC><EFBFBD><EFBFBD><EFBFBD>ڷ<EFBFBD>Χ
// <20><>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><E3A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0>ɫ
void LCD_DrawPointSafeColor(int x, int y, u16 color) {
if (g_lcd.effective == 0)
return;
x += g_lcd.win.xs;
y += g_lcd.win.ys;
if (x < g_lcd.realwin.xs || x > g_lcd.realwin.xe)
return;
if (y < g_lcd.realwin.ys || y > g_lcd.realwin.ye)
return;
g_lcd.draw[x + y * g_lcd.x_size] = (color);
}
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
// <20><><EFBFBD><EFBFBD>ALPHA BLENDING<4E>㷨.
// src:Դ<><D4B4>ɫ
// dst:Ŀ<><C4BF><EFBFBD><EFBFBD>ɫ
// alpha:͸<><CDB8><EFBFBD>̶<EFBFBD>(0~32)
// <20><><EFBFBD><EFBFBD>ֵ:<3A><><EFBFBD>Ϻ<EFBFBD><CFBA><EFBFBD><EFBFBD><EFBFBD>ɫ.
static u16 alpha_blend565(u16 src, u16 dst, u8 alpha) {
u32 src2;
u32 dst2;
// Convert to 32bit |-----GGGGGG-----RRRRR------BBBBB|
src2 = ((src << 16) | src) & 0x07E0F81F;
dst2 = ((dst << 16) | dst) & 0x07E0F81F;
// Perform blending R:G:B with alpha in range 0..32
// Note that the reason that alpha may not exceed 32 is that there are only
// 5bits of space between each R:G:B value, any higher value will overflow
// into the next component and deliver ugly result.
dst2 = ((((dst2 - src2) * alpha) >> 5) + src2) & 0x07E0F81F;
return (dst2 >> 16) | dst2;
}
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
// <20><>ָ<EFBFBD><D6B8>ɫ͸<C9AB><CDB8><EFBFBD>Ȼ<EFBFBD><C8BB><EFBFBD>0~32
void LCD_DrawPointSafeColorAlpha(int x, int y, u16 color, u8 alpha) {
if (g_lcd.effective == 0)
return;
if (alpha == 0)
return;
x += g_lcd.win.xs;
y += g_lcd.win.ys;
if (x < g_lcd.realwin.xs || x > g_lcd.realwin.xe)
return;
if (y < g_lcd.realwin.ys || y > g_lcd.realwin.ye)
return;
u32 color_old = g_lcd.draw[x + y * g_lcd.x_size];
color_old = (color_old);
color = alpha_blend565(color_old, color, alpha);
g_lcd.draw[x + y * g_lcd.x_size] = (color);
}
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Σ<EFBFBD><CEA3>Ѵ<EFBFBD><D1B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊԭ<CEAA><D4AD>
void LCD_FillRectByColor(int x, int y, int x_size, int y_size) {
if (g_lcd.effective == 0)
return;
x += g_lcd.win.xs;
y += g_lcd.win.ys;
int xe = x + x_size - 1;
int ye = y + y_size - 1;
if (x < g_lcd.realwin.xs)
x = g_lcd.realwin.xs;
if (y < g_lcd.realwin.ys)
y = g_lcd.realwin.ys;
if (xe > g_lcd.realwin.xe)
xe = g_lcd.realwin.xe;
if (ye > g_lcd.realwin.ye)
ye = g_lcd.realwin.ye;
x_size = xe - x + 1;
y_size = ye - y + 1;
if (x_size < 0 || y_size < 0)
return;
LCD_FillColor(g_lcd.draw, x, y, x_size, y_size, g_lcd.color);
}
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
static int LCD_MemSet(const void *pSurf, u16 w, u16 h, u32 color) {
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
DMA2D_DeInit();
DMA2D->OPFCCR = DMA2D_ARGB8888;
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
DMA2D->CR = DMA2D_R2M;
// DMA2D->OPFCCR = DMA2D_RGB565;
DMA2D->OCOLR = color;
DMA2D->OMAR = (u32)pSurf;
DMA2D->OOR = 0;
DMA2D->NLR = (w << 16) | h;
2025-06-27 00:32:57 +08:00
/* Execute operation */
2025-07-10 11:30:57 +08:00
DMA2D->CR |= DMA2D_CR_START;
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
while (DMA2D->CR & DMA2D_CR_START) {
}
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
return 1;
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
static int LCD_FillImg_ARGB(const void *pSurf, int x, int y, u16 w, u16 h,
int width_bytes, const u8 *bits, u32 color_format) {
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
DMA2D_DeInit();
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
DMA2D->OPFCCR = DMA2D_RGB565;
DMA2D->BGPFCCR = CM_RGB565;
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
DMA2D->CR = DMA2D_M2M_BLEND;
DMA2D->OMAR = (u32)pSurf + (y * LCD_Width + x) * 2;
DMA2D->OOR = LCD_Width - w;
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
DMA2D->NLR = (w << 16) | h;
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
DMA2D->BGMAR = DMA2D->OMAR;
DMA2D->BGOR = DMA2D->OOR;
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
DMA2D->FGPFCCR = NO_MODIF_ALPHA_VALUE | color_format;
DMA2D->FGMAR = (u32)bits;
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
switch (color_format) {
case CM_ARGB4444:
DMA2D->FGOR = (width_bytes >> 1) - w;
break;
case CM_ARGB8888:
DMA2D->FGOR = (width_bytes >> 2) - w;
break;
default:
return 0;
}
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
DMA2D->CR |= DMA2D_CR_START;
2025-06-27 00:32:57 +08:00
2025-07-10 11:30:57 +08:00
while (DMA2D->CR & DMA2D_CR_START) {
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
return 1;
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// <20><>͸<EFBFBD><CDB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Σ<EFBFBD><CEA3>Ѵ<EFBFBD><D1B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊԭ<CEAA><D4AD>
void LCD_FillRectByColorAlpha(int x, int y, int x_size, int y_size, u8 alpha) {
if (g_lcd.effective == 0)
return;
x += g_lcd.win.xs;
y += g_lcd.win.ys;
int xe = x + x_size - 1;
int ye = y + y_size - 1;
if (x < g_lcd.realwin.xs)
x = g_lcd.realwin.xs;
if (y < g_lcd.realwin.ys)
y = g_lcd.realwin.ys;
if (xe > g_lcd.realwin.xe)
xe = g_lcd.realwin.xe;
if (ye > g_lcd.realwin.ye)
ye = g_lcd.realwin.ye;
x_size = xe - x + 1;
y_size = ye - y + 1;
if (x_size < 0 || y_size < 0)
return;
u8 *fb = mymalloc(x_size * y_size * 4);
LCD_MemSet(fb, x_size, y_size,
COLOR565TO888(g_lcd.color) | (alpha << (24 + 3)));
LCD_FillImg_ARGB(LCD_GetDrawAddr(), x, y, x_size, y_size, x_size * 4, fb,
CM_ARGB8888);
myfree(fb);
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD>е<EFBFBD><D0B5><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>
static int LCD_RectIntersection(LCD_WindowStruct *out, int x, int y, int xsize,
int ysize) {
// ȡ<><C8A1><EFBFBD>¾<EFBFBD><C2BE>ε<EFBFBD><CEB5><EFBFBD><EFBFBD>Ͻ<EFBFBD>
int x_s = g_lcd.realwin.xs;
int y_s = g_lcd.realwin.ys;
if (x_s < x)
x_s = x;
if (y_s < y)
y_s = y;
// ȡ<><C8A1><EFBFBD>¾<EFBFBD><C2BE>ε<EFBFBD><CEB5><EFBFBD><EFBFBD>½<EFBFBD>
int x_e = g_lcd.realwin.xe;
int y_e = g_lcd.realwin.ye;
if (x_e > x + xsize - 1)
x_e = x + xsize - 1;
if (y_e > y + ysize - 1)
y_e = y + ysize - 1;
out->xs = x_s;
out->ys = y_s;
out->xe = x_e;
out->ye = y_e;
if ((y_e >= y_s) && (x_e >= x_s)) {
return 1;
} else {
return 0;
}
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD>ʾ
void LCD_ClearRect(int x, int y, int xsize, int ysize) {
if (g_lcd.effective == 0)
return;
x += g_lcd.win.xs;
y += g_lcd.win.ys;
LCD_WindowStruct out = {0};
if (LCD_RectIntersection(&out, x, y, xsize, ysize)) {
LCD_FillColor(g_lcd.draw, out.xs, out.ys, out.xe - out.xs + 1,
out.ye - out.ys + 1, g_lcd.bkColor);
}
2025-06-27 00:32:57 +08:00
}
2025-07-10 11:30:57 +08:00
// <20><>ȡָ<C8A1><D6B8><EFBFBD><EFBFBD><EFBFBD>οռ<CEBF><D5BC><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>Ļ<EFBFBD>ľ<EFBFBD><C4BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void LCD_GetColors(u16 *buff, int x_s, int y_s, int x_size, int y_size) {
u16 *addr = g_lcd.draw;
if (x_s < 0)
x_s = 0;
else if (x_s > LCD_Width - 1)
x_s = LCD_Width - 1;
if (y_s < 0)
y_s = 0;
else if (y_s > LCD_Height - 1)
y_s = LCD_Height - 1;
if (x_size > LCD_Width - x_s)
x_size = LCD_Width - x_s;
else if (x_size < 0)
x_size = 0;
if (y_size > LCD_Height - y_s)
y_size = LCD_Height - y_s;
else if (y_size < 0)
y_size = 0;
for (int y = y_s; y < y_size + y_s; y++) {
for (int x = x_s; x < x_size + x_s; x++) {
u32 temp = addr[(y * LCD_Width + x)];
//*buff=COLOR888TO565(temp);
*buff = temp;
buff++;
}
}
}