Merge pull request #2717 from willianchanlovegithub/469
[bsp][stm32][f469-disco]Separation of MIPI-LTCDC and LCD Configuration
This commit is contained in:
commit
7ca0ce2627
|
@ -49,6 +49,9 @@ if GetDepend('BSP_USING_SDRAM'):
|
||||||
if GetDepend('BSP_USING_LCD'):
|
if GetDepend('BSP_USING_LCD'):
|
||||||
src += ['drv_lcd.c']
|
src += ['drv_lcd.c']
|
||||||
|
|
||||||
|
if GetDepend('BSP_USING_LCD_MIPI'):
|
||||||
|
src += ['drv_lcd_mipi.c']
|
||||||
|
|
||||||
if GetDepend('BSP_USING_ONCHIP_RTC'):
|
if GetDepend('BSP_USING_ONCHIP_RTC'):
|
||||||
src += ['drv_rtc.c']
|
src += ['drv_rtc.c']
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,254 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Change Logs:
|
||||||
|
* Date Author Notes
|
||||||
|
* 2019-05-23 WillianChan first version
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <board.h>
|
||||||
|
|
||||||
|
#ifdef BSP_USING_LCD_MIPI
|
||||||
|
#include <lcd_port.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
DSI_HandleTypeDef hdsi;
|
||||||
|
DSI_VidCfgTypeDef hdsi_video;
|
||||||
|
LTDC_HandleTypeDef hltdc;
|
||||||
|
|
||||||
|
struct stm32_lcd
|
||||||
|
{
|
||||||
|
struct rt_device parent;
|
||||||
|
struct rt_device_graphic_info info;
|
||||||
|
};
|
||||||
|
static struct stm32_lcd lcd;
|
||||||
|
|
||||||
|
extern void stm32_mipi_lcd_init(void);
|
||||||
|
extern void stm32_mipi_lcd_config(rt_uint32_t pixel_format);
|
||||||
|
extern void stm32_mipi_display_on(void);
|
||||||
|
extern void stm32_mipi_display_off(void);
|
||||||
|
|
||||||
|
rt_err_t ltdc_init(void)
|
||||||
|
{
|
||||||
|
uint32_t lcd_clock = 27429;
|
||||||
|
uint32_t lanebyte_clock = 62500;
|
||||||
|
|
||||||
|
uint32_t HSA = LCD_HSYNC, HFP = LCD_HFP, HBP = LCD_HBP, HACT = LCD_WIDTH;
|
||||||
|
uint32_t VSA = LCD_VSYNC, VFP = LCD_VFP, VBP = LCD_VBP, VACT = LCD_HEIGHT;
|
||||||
|
|
||||||
|
stm32_mipi_lcd_init();
|
||||||
|
|
||||||
|
__HAL_RCC_LTDC_CLK_ENABLE();
|
||||||
|
__HAL_RCC_LTDC_FORCE_RESET();
|
||||||
|
__HAL_RCC_LTDC_RELEASE_RESET();
|
||||||
|
|
||||||
|
__HAL_RCC_DSI_CLK_ENABLE();
|
||||||
|
__HAL_RCC_DSI_FORCE_RESET();
|
||||||
|
__HAL_RCC_DSI_RELEASE_RESET();
|
||||||
|
|
||||||
|
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
|
||||||
|
|
||||||
|
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
|
||||||
|
PeriphClkInitStruct.PLLSAI.PLLSAIN = 384;
|
||||||
|
PeriphClkInitStruct.PLLSAI.PLLSAIR = 7;
|
||||||
|
PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_2;
|
||||||
|
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
|
||||||
|
|
||||||
|
HAL_NVIC_SetPriority(LTDC_IRQn, 3, 0);
|
||||||
|
HAL_NVIC_SetPriority(DSI_IRQn, 3, 0);
|
||||||
|
|
||||||
|
HAL_NVIC_EnableIRQ(LTDC_IRQn);
|
||||||
|
HAL_NVIC_EnableIRQ(DSI_IRQn);
|
||||||
|
|
||||||
|
DSI_PLLInitTypeDef dsi_pll;
|
||||||
|
|
||||||
|
hdsi.Instance = DSI;
|
||||||
|
hdsi.Init.NumberOfLanes = DSI_TWO_DATA_LANES;
|
||||||
|
hdsi.Init.TXEscapeCkdiv = lanebyte_clock / 15620;
|
||||||
|
|
||||||
|
dsi_pll.PLLNDIV = 125;
|
||||||
|
dsi_pll.PLLIDF = DSI_PLL_IN_DIV2;
|
||||||
|
dsi_pll.PLLODF = DSI_PLL_OUT_DIV1;
|
||||||
|
|
||||||
|
HAL_DSI_DeInit(&hdsi);
|
||||||
|
HAL_DSI_Init(&hdsi, &dsi_pll);
|
||||||
|
|
||||||
|
hdsi_video.VirtualChannelID = 0;
|
||||||
|
hdsi_video.ColorCoding = DSI_RGB888;
|
||||||
|
hdsi_video.VSPolarity = DSI_VSYNC_ACTIVE_HIGH;
|
||||||
|
hdsi_video.HSPolarity = DSI_HSYNC_ACTIVE_HIGH;
|
||||||
|
hdsi_video.DEPolarity = DSI_DATA_ENABLE_ACTIVE_HIGH;
|
||||||
|
hdsi_video.Mode = DSI_VID_MODE_BURST;
|
||||||
|
hdsi_video.NullPacketSize = 0xFFF;
|
||||||
|
hdsi_video.NumberOfChunks = 0;
|
||||||
|
hdsi_video.PacketSize = HACT;
|
||||||
|
hdsi_video.HorizontalSyncActive = (HSA * lanebyte_clock) / lcd_clock;
|
||||||
|
hdsi_video.HorizontalBackPorch = (HBP * lanebyte_clock) / lcd_clock;
|
||||||
|
hdsi_video.HorizontalLine = ((HACT + HSA + HBP + HFP) * lanebyte_clock) / lcd_clock;
|
||||||
|
hdsi_video.VerticalSyncActive = VSA;
|
||||||
|
hdsi_video.VerticalBackPorch = VBP;
|
||||||
|
hdsi_video.VerticalFrontPorch = VFP;
|
||||||
|
hdsi_video.VerticalActive = VACT;
|
||||||
|
hdsi_video.LPCommandEnable = DSI_LP_COMMAND_ENABLE;
|
||||||
|
hdsi_video.LPLargestPacketSize = 16;
|
||||||
|
hdsi_video.LPVACTLargestPacketSize = 0;
|
||||||
|
hdsi_video.LPHorizontalFrontPorchEnable = DSI_LP_HFP_ENABLE;
|
||||||
|
hdsi_video.LPHorizontalBackPorchEnable = DSI_LP_HBP_ENABLE;
|
||||||
|
hdsi_video.LPVerticalActiveEnable = DSI_LP_VACT_ENABLE;
|
||||||
|
hdsi_video.LPVerticalFrontPorchEnable = DSI_LP_VFP_ENABLE;
|
||||||
|
hdsi_video.LPVerticalBackPorchEnable = DSI_LP_VBP_ENABLE;
|
||||||
|
hdsi_video.LPVerticalSyncActiveEnable = DSI_LP_VSYNC_ENABLE;
|
||||||
|
HAL_DSI_ConfigVideoMode(&hdsi, &hdsi_video);
|
||||||
|
|
||||||
|
DSI_PHY_TimerTypeDef dsi_phy;
|
||||||
|
|
||||||
|
dsi_phy.ClockLaneHS2LPTime = 35;
|
||||||
|
dsi_phy.ClockLaneLP2HSTime = 35;
|
||||||
|
dsi_phy.DataLaneHS2LPTime = 35;
|
||||||
|
dsi_phy.DataLaneLP2HSTime = 35;
|
||||||
|
dsi_phy.DataLaneMaxReadTime = 0;
|
||||||
|
dsi_phy.StopWaitTime = 10;
|
||||||
|
HAL_DSI_ConfigPhyTimer(&hdsi, &dsi_phy);
|
||||||
|
|
||||||
|
hltdc.Instance = LTDC;
|
||||||
|
|
||||||
|
hltdc.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
|
||||||
|
hltdc.Init.HorizontalSync = (HSA - 1);
|
||||||
|
hltdc.Init.AccumulatedHBP = (HSA + HBP - 1);
|
||||||
|
hltdc.Init.AccumulatedActiveW = (LCD_WIDTH + HSA + HBP - 1);
|
||||||
|
hltdc.Init.TotalWidth = (LCD_WIDTH + HSA + HBP + HFP - 1);
|
||||||
|
|
||||||
|
hltdc.LayerCfg->ImageWidth = LCD_WIDTH;
|
||||||
|
hltdc.LayerCfg->ImageHeight = LCD_HEIGHT;
|
||||||
|
hltdc.Init.Backcolor.Blue = 0x00;
|
||||||
|
hltdc.Init.Backcolor.Green = 0x00;
|
||||||
|
hltdc.Init.Backcolor.Red = 0x00;
|
||||||
|
HAL_LTDCEx_StructInitFromVideoConfig(&hltdc, &(hdsi_video));
|
||||||
|
HAL_LTDC_Init(&(hltdc));
|
||||||
|
|
||||||
|
HAL_DSI_Start(&(hdsi));
|
||||||
|
|
||||||
|
stm32_mipi_lcd_config(RTGRAPHIC_PIXEL_FORMAT_ARGB888);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ltdc_layer_init(uint16_t index, uint32_t framebuffer)
|
||||||
|
{
|
||||||
|
LTDC_LayerCfgTypeDef layer_cfg;
|
||||||
|
|
||||||
|
layer_cfg.WindowX0 = 0;
|
||||||
|
layer_cfg.WindowX1 = LCD_WIDTH;
|
||||||
|
layer_cfg.WindowY0 = 0;
|
||||||
|
layer_cfg.WindowY1 = LCD_HEIGHT;
|
||||||
|
layer_cfg.PixelFormat = LTDC_PIXEL_FORMAT_ARGB8888;
|
||||||
|
layer_cfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
|
||||||
|
layer_cfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
|
||||||
|
layer_cfg.Alpha = 255;
|
||||||
|
layer_cfg.Alpha0 = 0;
|
||||||
|
layer_cfg.ImageWidth = LCD_WIDTH;
|
||||||
|
layer_cfg.ImageHeight = LCD_HEIGHT;
|
||||||
|
layer_cfg.Backcolor.Blue = 0;
|
||||||
|
layer_cfg.Backcolor.Green = 0;
|
||||||
|
layer_cfg.Backcolor.Red = 0;
|
||||||
|
layer_cfg.FBStartAdress = framebuffer;
|
||||||
|
|
||||||
|
HAL_LTDC_ConfigLayer(&hltdc, &layer_cfg, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LTDC_IRQHandler(void)
|
||||||
|
{
|
||||||
|
rt_interrupt_enter();
|
||||||
|
HAL_LTDC_IRQHandler(&hltdc);
|
||||||
|
rt_interrupt_leave();
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t stm32_lcd_init(rt_device_t device)
|
||||||
|
{
|
||||||
|
lcd.info.width = LCD_WIDTH;
|
||||||
|
lcd.info.height = LCD_HEIGHT;
|
||||||
|
lcd.info.pixel_format = RTGRAPHIC_PIXEL_FORMAT_ARGB888;
|
||||||
|
lcd.info.bits_per_pixel = 32;
|
||||||
|
lcd.info.framebuffer = (void *)rt_malloc_align(LCD_WIDTH * LCD_HEIGHT * (lcd.info.bits_per_pixel / 8), 32);
|
||||||
|
memset(lcd.info.framebuffer, 0, LCD_WIDTH * LCD_HEIGHT * (lcd.info.bits_per_pixel / 8));
|
||||||
|
ltdc_init();
|
||||||
|
ltdc_layer_init(0, (uint32_t)lcd.info.framebuffer);
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rt_err_t stm32_lcd_control(rt_device_t device, int cmd, void *args)
|
||||||
|
{
|
||||||
|
switch(cmd)
|
||||||
|
{
|
||||||
|
case RTGRAPHIC_CTRL_RECT_UPDATE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RTGRAPHIC_CTRL_POWERON:
|
||||||
|
stm32_mipi_display_on();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RTGRAPHIC_CTRL_POWEROFF:
|
||||||
|
stm32_mipi_display_off();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RTGRAPHIC_CTRL_GET_INFO:
|
||||||
|
rt_memcpy(args, &lcd.info, sizeof(lcd.info));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RTGRAPHIC_CTRL_SET_MODE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RTGRAPHIC_CTRL_GET_EXT:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rt_hw_lcd_init(void)
|
||||||
|
{
|
||||||
|
rt_err_t ret;
|
||||||
|
|
||||||
|
rt_memset(&lcd, 0x00, sizeof(lcd));
|
||||||
|
|
||||||
|
lcd.parent.type = RT_Device_Class_Graphic;
|
||||||
|
lcd.parent.init = stm32_lcd_init;
|
||||||
|
lcd.parent.open = RT_NULL;
|
||||||
|
lcd.parent.close = RT_NULL;
|
||||||
|
lcd.parent.read = RT_NULL;
|
||||||
|
lcd.parent.write = RT_NULL;
|
||||||
|
lcd.parent.control = stm32_lcd_control;
|
||||||
|
|
||||||
|
lcd.parent.user_data = (void *)&lcd.info;
|
||||||
|
|
||||||
|
ret = rt_device_register(&lcd.parent, "lcd", RT_DEVICE_FLAG_RDWR);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
INIT_DEVICE_EXPORT(rt_hw_lcd_init);
|
||||||
|
|
||||||
|
|
||||||
|
RT_WEAK void stm32_mipi_lcd_init(void)
|
||||||
|
{
|
||||||
|
rt_kprintf("please Implementation function %s\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
RT_WEAK void stm32_mipi_lcd_config(rt_uint32_t pixel_format)
|
||||||
|
{
|
||||||
|
rt_kprintf("please Implementation function %s\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
RT_WEAK void stm32_mipi_display_on(void)
|
||||||
|
{
|
||||||
|
rt_kprintf("please Implementation function %s\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
RT_WEAK void stm32_mipi_display_off(void)
|
||||||
|
{
|
||||||
|
rt_kprintf("please Implementation function %s\n", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* BSP_USING_LCD_MIPI */
|
|
@ -11,10 +11,15 @@ menu "Onboard Peripheral Drivers"
|
||||||
select BSP_USING_FMC
|
select BSP_USING_FMC
|
||||||
default n
|
default n
|
||||||
|
|
||||||
|
config BSP_USING_LCD_MIPI
|
||||||
|
bool
|
||||||
|
default n
|
||||||
|
|
||||||
config BSP_USING_LCD_OTM8009A
|
config BSP_USING_LCD_OTM8009A
|
||||||
bool "Enable LCD OTM8009A"
|
bool "Enable LCD OTM8009A"
|
||||||
select BSP_USING_SDRAM
|
select BSP_USING_SDRAM
|
||||||
select BSP_USING_LTDC
|
select BSP_USING_LTDC
|
||||||
|
select BSP_USING_LCD_MIPI
|
||||||
default n
|
default n
|
||||||
|
|
||||||
config BSP_USING_QSPI_FLASH
|
config BSP_USING_QSPI_FLASH
|
||||||
|
|
|
@ -13,22 +13,22 @@ CubeMX_Config/Src/stm32f4xx_hal_msp.c
|
||||||
''')
|
''')
|
||||||
|
|
||||||
if GetDepend(['BSP_USING_QSPI_FLASH']):
|
if GetDepend(['BSP_USING_QSPI_FLASH']):
|
||||||
src += Glob('ports/drv_qspi_flash.c')
|
src += ['ports/drv_qspi_flash.c']
|
||||||
|
|
||||||
if GetDepend(['PKG_USING_FAL']):
|
if GetDepend(['PKG_USING_FAL']):
|
||||||
src += Glob('ports/qspi_mnt.c')
|
src += ['ports/qspi_mnt.c']
|
||||||
|
|
||||||
if GetDepend(['BSP_USING_LCD_OTM8009A']):
|
if GetDepend(['BSP_USING_LCD_OTM8009A']):
|
||||||
src += Glob('ports/drv_lcd_otm8009a.c')
|
src += ['ports/drv_otm8009a.c']
|
||||||
|
|
||||||
if GetDepend(['BSP_USING_TOUCH']):
|
if GetDepend(['BSP_USING_TOUCH']):
|
||||||
src += Glob('ports/touch/*.c')
|
src += Glob('ports/touch/*.c')
|
||||||
|
|
||||||
if GetDepend(['BSP_USING_SDCARD']):
|
if GetDepend(['BSP_USING_SDCARD']):
|
||||||
src += Glob('ports/drv_sdcard.c')
|
src += ['ports/drv_sdcard.c']
|
||||||
|
|
||||||
if GetDepend(['BSP_USING_QSPI']):
|
if GetDepend(['BSP_USING_QSPI']):
|
||||||
src += Glob('ports/drv_qspi_flash.c')
|
src += ['ports/drv_qspi_flash.c']
|
||||||
|
|
||||||
path = [cwd]
|
path = [cwd]
|
||||||
path += [cwd + '/CubeMX_Config/Inc']
|
path += [cwd + '/CubeMX_Config/Inc']
|
||||||
|
|
|
@ -5,37 +5,13 @@
|
||||||
*
|
*
|
||||||
* Change Logs:
|
* Change Logs:
|
||||||
* Date Author Notes
|
* Date Author Notes
|
||||||
* 2018-07-28 liu2guang the first version for STM32F469NI-Discovery.
|
* 2019-05-23 WillianChan first version
|
||||||
* 2019-04-19 WillianChan porting STM32F469NI-Discovery lcd driver to
|
|
||||||
* the new STM32 BSP framework.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <board.h>
|
#include <board.h>
|
||||||
|
|
||||||
#ifdef BSP_USING_LCD_OTM8009A
|
#ifdef BSP_USING_LCD_OTM8009A
|
||||||
#include <lcd_port.h>
|
extern DSI_HandleTypeDef hdsi;
|
||||||
|
extern DSI_VidCfgTypeDef hdsi_video;
|
||||||
struct stm32_lcd
|
|
||||||
{
|
|
||||||
struct rt_device device;
|
|
||||||
struct rt_device_graphic_info info;
|
|
||||||
|
|
||||||
LTDC_HandleTypeDef ltdc;
|
|
||||||
DSI_HandleTypeDef dsi;
|
|
||||||
DSI_VidCfgTypeDef dsi_video;
|
|
||||||
DMA2D_HandleTypeDef dma2d;
|
|
||||||
};
|
|
||||||
static struct stm32_lcd lcd;
|
|
||||||
|
|
||||||
#define LCD_WIDTH ((uint16_t)800)
|
|
||||||
#define LCD_HEIGHT ((uint16_t)480)
|
|
||||||
|
|
||||||
#define LCD_HSYNC ((uint16_t)1)
|
|
||||||
#define LCD_HBP ((uint16_t)15)
|
|
||||||
#define LCD_HFP ((uint16_t)16)
|
|
||||||
#define LCD_VSYNC ((uint16_t)2)
|
|
||||||
#define LCD_VBP ((uint16_t)34)
|
|
||||||
#define LCD_VFP ((uint16_t)34)
|
|
||||||
|
|
||||||
const rt_uint8_t RDL01[] = {0x80, 0x09, 0x01, 0xFF};
|
const rt_uint8_t RDL01[] = {0x80, 0x09, 0x01, 0xFF};
|
||||||
const rt_uint8_t RDL02[] = {0x80, 0x09, 0xFF};
|
const rt_uint8_t RDL02[] = {0x80, 0x09, 0xFF};
|
||||||
|
@ -117,7 +93,7 @@ const rt_uint8_t RDS49[] = {0xF5, 0x06};
|
||||||
const rt_uint8_t RDS50[] = {0x00, 0xB1};
|
const rt_uint8_t RDS50[] = {0x00, 0xB1};
|
||||||
const rt_uint8_t RDS51[] = {0xC6, 0x06};
|
const rt_uint8_t RDS51[] = {0xC6, 0x06};
|
||||||
|
|
||||||
static void otm8009a_reset(void)
|
void otm8009a_reset(void)
|
||||||
{
|
{
|
||||||
rt_pin_mode (GET_PIN(H, 7), PIN_MODE_OUTPUT);
|
rt_pin_mode (GET_PIN(H, 7), PIN_MODE_OUTPUT);
|
||||||
rt_pin_write(GET_PIN(H, 7), PIN_LOW);
|
rt_pin_write(GET_PIN(H, 7), PIN_LOW);
|
||||||
|
@ -126,19 +102,19 @@ static void otm8009a_reset(void)
|
||||||
rt_thread_delay(rt_tick_from_millisecond(20));
|
rt_thread_delay(rt_tick_from_millisecond(20));
|
||||||
}
|
}
|
||||||
|
|
||||||
void otm8009a_write_cmd(uint8_t *p, uint32_t num)
|
static void otm8009a_write_cmd(uint8_t *p, uint32_t num)
|
||||||
{
|
{
|
||||||
if (num <= 1)
|
if (num <= 1)
|
||||||
{
|
{
|
||||||
HAL_DSI_ShortWrite(&(lcd.dsi), lcd.dsi_video.VirtualChannelID, DSI_DCS_SHORT_PKT_WRITE_P1, p[0], p[1]);
|
HAL_DSI_ShortWrite(&hdsi, hdsi_video.VirtualChannelID, DSI_DCS_SHORT_PKT_WRITE_P1, p[0], p[1]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HAL_DSI_LongWrite(&(lcd.dsi), lcd.dsi_video.VirtualChannelID, DSI_DCS_LONG_PKT_WRITE, num, p[num], p);
|
HAL_DSI_LongWrite(&hdsi, hdsi_video.VirtualChannelID, DSI_DCS_LONG_PKT_WRITE, num, p[num], p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void otm8009a_delay(uint32_t d)
|
static void otm8009a_delay(uint32_t d)
|
||||||
{
|
{
|
||||||
rt_thread_delay(rt_tick_from_millisecond(d));
|
rt_thread_delay(rt_tick_from_millisecond(d));
|
||||||
}
|
}
|
||||||
|
@ -264,262 +240,24 @@ static void otm8009a_config(rt_uint32_t pixel_format)
|
||||||
otm8009a_write_cmd((rt_uint8_t *)RDS45, 0);
|
otm8009a_write_cmd((rt_uint8_t *)RDS45, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
rt_err_t otm8009a_init(void)
|
|
||||||
|
void stm32_mipi_lcd_init(void)
|
||||||
{
|
{
|
||||||
uint32_t lcd_clock = 27429;
|
|
||||||
uint32_t lanebyte_clock = 62500;
|
|
||||||
|
|
||||||
uint32_t HSA = LCD_HSYNC, HFP = LCD_HFP, HBP = LCD_HBP, HACT = LCD_WIDTH;
|
|
||||||
uint32_t VSA = LCD_VSYNC, VFP = LCD_VFP, VBP = LCD_VBP, VACT = LCD_HEIGHT;
|
|
||||||
|
|
||||||
/* <20><>λOTM8009A<39><41>ʾ<EFBFBD><CABE> */
|
|
||||||
otm8009a_reset();
|
otm8009a_reset();
|
||||||
|
|
||||||
/* <20><>ʼ<EFBFBD><CABC>STM32<33><32>ʾ<EFBFBD><CABE>ʱ<EFBFBD><CAB1> */
|
|
||||||
__HAL_RCC_LTDC_CLK_ENABLE();
|
|
||||||
__HAL_RCC_LTDC_FORCE_RESET();
|
|
||||||
__HAL_RCC_LTDC_RELEASE_RESET();
|
|
||||||
|
|
||||||
__HAL_RCC_DMA2D_CLK_ENABLE();
|
|
||||||
__HAL_RCC_DMA2D_FORCE_RESET();
|
|
||||||
__HAL_RCC_DMA2D_RELEASE_RESET();
|
|
||||||
|
|
||||||
__HAL_RCC_DSI_CLK_ENABLE();
|
|
||||||
__HAL_RCC_DSI_FORCE_RESET();
|
|
||||||
__HAL_RCC_DSI_RELEASE_RESET();
|
|
||||||
|
|
||||||
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
|
|
||||||
|
|
||||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
|
|
||||||
PeriphClkInitStruct.PLLSAI.PLLSAIN = 384;
|
|
||||||
PeriphClkInitStruct.PLLSAI.PLLSAIR = 7;
|
|
||||||
PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_2;
|
|
||||||
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
|
|
||||||
|
|
||||||
/* <20><><EFBFBD><EFBFBD>NVIC */
|
|
||||||
HAL_NVIC_SetPriority(LTDC_IRQn, 3, 0);
|
|
||||||
HAL_NVIC_SetPriority(DMA2D_IRQn, 3, 0);
|
|
||||||
HAL_NVIC_SetPriority(DSI_IRQn, 3, 0);
|
|
||||||
|
|
||||||
HAL_NVIC_EnableIRQ(LTDC_IRQn);
|
|
||||||
HAL_NVIC_EnableIRQ(DMA2D_IRQn);
|
|
||||||
HAL_NVIC_EnableIRQ(DSI_IRQn);
|
|
||||||
|
|
||||||
/* <20><><EFBFBD><EFBFBD>DSI */
|
|
||||||
DSI_PLLInitTypeDef dsi_pll;
|
|
||||||
|
|
||||||
lcd.dsi.Instance = DSI;
|
|
||||||
lcd.dsi.Init.NumberOfLanes = DSI_TWO_DATA_LANES;
|
|
||||||
lcd.dsi.Init.TXEscapeCkdiv = lanebyte_clock / 15620;
|
|
||||||
|
|
||||||
dsi_pll.PLLNDIV = 125;
|
|
||||||
dsi_pll.PLLIDF = DSI_PLL_IN_DIV2;
|
|
||||||
dsi_pll.PLLODF = DSI_PLL_OUT_DIV1;
|
|
||||||
|
|
||||||
HAL_DSI_DeInit(&(lcd.dsi));
|
|
||||||
HAL_DSI_Init(&(lcd.dsi), &(dsi_pll));
|
|
||||||
|
|
||||||
/* <20><><EFBFBD><EFBFBD>DSI Video */
|
|
||||||
lcd.dsi_video.VirtualChannelID = 0;
|
|
||||||
lcd.dsi_video.ColorCoding = DSI_RGB888;
|
|
||||||
lcd.dsi_video.VSPolarity = DSI_VSYNC_ACTIVE_HIGH;
|
|
||||||
lcd.dsi_video.HSPolarity = DSI_HSYNC_ACTIVE_HIGH;
|
|
||||||
lcd.dsi_video.DEPolarity = DSI_DATA_ENABLE_ACTIVE_HIGH;
|
|
||||||
lcd.dsi_video.Mode = DSI_VID_MODE_BURST;
|
|
||||||
lcd.dsi_video.NullPacketSize = 0xFFF;
|
|
||||||
lcd.dsi_video.NumberOfChunks = 0;
|
|
||||||
lcd.dsi_video.PacketSize = HACT;
|
|
||||||
lcd.dsi_video.HorizontalSyncActive = (HSA * lanebyte_clock) / lcd_clock;
|
|
||||||
lcd.dsi_video.HorizontalBackPorch = (HBP * lanebyte_clock) / lcd_clock;
|
|
||||||
lcd.dsi_video.HorizontalLine = ((HACT + HSA + HBP + HFP) * lanebyte_clock) / lcd_clock;
|
|
||||||
lcd.dsi_video.VerticalSyncActive = VSA;
|
|
||||||
lcd.dsi_video.VerticalBackPorch = VBP;
|
|
||||||
lcd.dsi_video.VerticalFrontPorch = VFP;
|
|
||||||
lcd.dsi_video.VerticalActive = VACT;
|
|
||||||
lcd.dsi_video.LPCommandEnable = DSI_LP_COMMAND_ENABLE;
|
|
||||||
lcd.dsi_video.LPLargestPacketSize = 16;
|
|
||||||
lcd.dsi_video.LPVACTLargestPacketSize = 0;
|
|
||||||
lcd.dsi_video.LPHorizontalFrontPorchEnable = DSI_LP_HFP_ENABLE;
|
|
||||||
lcd.dsi_video.LPHorizontalBackPorchEnable = DSI_LP_HBP_ENABLE;
|
|
||||||
lcd.dsi_video.LPVerticalActiveEnable = DSI_LP_VACT_ENABLE;
|
|
||||||
lcd.dsi_video.LPVerticalFrontPorchEnable = DSI_LP_VFP_ENABLE;
|
|
||||||
lcd.dsi_video.LPVerticalBackPorchEnable = DSI_LP_VBP_ENABLE;
|
|
||||||
lcd.dsi_video.LPVerticalSyncActiveEnable = DSI_LP_VSYNC_ENABLE;
|
|
||||||
HAL_DSI_ConfigVideoMode(&(lcd.dsi), &(lcd.dsi_video));
|
|
||||||
|
|
||||||
/* <20><><EFBFBD><EFBFBD>DSI PHY */
|
|
||||||
DSI_PHY_TimerTypeDef dsi_phy;
|
|
||||||
|
|
||||||
dsi_phy.ClockLaneHS2LPTime = 35;
|
|
||||||
dsi_phy.ClockLaneLP2HSTime = 35;
|
|
||||||
dsi_phy.DataLaneHS2LPTime = 35;
|
|
||||||
dsi_phy.DataLaneLP2HSTime = 35;
|
|
||||||
dsi_phy.DataLaneMaxReadTime = 0;
|
|
||||||
dsi_phy.StopWaitTime = 10;
|
|
||||||
HAL_DSI_ConfigPhyTimer(&(lcd.dsi), &dsi_phy);
|
|
||||||
|
|
||||||
/* <20><><EFBFBD><EFBFBD>LTDC */
|
|
||||||
lcd.ltdc.Instance = LTDC;
|
|
||||||
|
|
||||||
lcd.ltdc.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
|
|
||||||
lcd.ltdc.Init.HorizontalSync = (HSA - 1);
|
|
||||||
lcd.ltdc.Init.AccumulatedHBP = (HSA + HBP - 1);
|
|
||||||
lcd.ltdc.Init.AccumulatedActiveW = (LCD_WIDTH + HSA + HBP - 1);
|
|
||||||
lcd.ltdc.Init.TotalWidth = (LCD_WIDTH + HSA + HBP + HFP - 1);
|
|
||||||
|
|
||||||
lcd.ltdc.LayerCfg->ImageWidth = LCD_WIDTH;
|
|
||||||
lcd.ltdc.LayerCfg->ImageHeight = LCD_HEIGHT;
|
|
||||||
lcd.ltdc.Init.Backcolor.Blue = 0x00;
|
|
||||||
lcd.ltdc.Init.Backcolor.Green = 0x00;
|
|
||||||
lcd.ltdc.Init.Backcolor.Red = 0x00;
|
|
||||||
HAL_LTDCEx_StructInitFromVideoConfig(&(lcd.ltdc), &(lcd.dsi_video));
|
|
||||||
HAL_LTDC_Init(&(lcd.ltdc));
|
|
||||||
|
|
||||||
HAL_DSI_Start(&(lcd.dsi));
|
|
||||||
|
|
||||||
otm8009a_config(RTGRAPHIC_PIXEL_FORMAT_ARGB888);
|
|
||||||
|
|
||||||
return RT_EOK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void otm8009a_layer_init(uint16_t index, uint32_t framebuffer)
|
void stm32_mipi_lcd_config(rt_uint32_t pixel_format)
|
||||||
{
|
{
|
||||||
LTDC_LayerCfgTypeDef layer_cfg;
|
otm8009a_config(pixel_format);
|
||||||
|
|
||||||
layer_cfg.WindowX0 = 0;
|
|
||||||
layer_cfg.WindowX1 = LCD_WIDTH;
|
|
||||||
layer_cfg.WindowY0 = 0;
|
|
||||||
layer_cfg.WindowY1 = LCD_HEIGHT;
|
|
||||||
layer_cfg.PixelFormat = LTDC_PIXEL_FORMAT_ARGB8888;
|
|
||||||
layer_cfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
|
|
||||||
layer_cfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
|
|
||||||
layer_cfg.Alpha = 255;
|
|
||||||
layer_cfg.Alpha0 = 0;
|
|
||||||
layer_cfg.ImageWidth = LCD_WIDTH;
|
|
||||||
layer_cfg.ImageHeight = LCD_HEIGHT;
|
|
||||||
layer_cfg.Backcolor.Blue = 0;
|
|
||||||
layer_cfg.Backcolor.Green = 0;
|
|
||||||
layer_cfg.Backcolor.Red = 0;
|
|
||||||
layer_cfg.FBStartAdress = framebuffer;
|
|
||||||
|
|
||||||
HAL_LTDC_ConfigLayer(&(lcd.ltdc), &layer_cfg, index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void otm8009a_display_on(void)
|
void stm32_mipi_display_on(void)
|
||||||
{
|
{
|
||||||
HAL_DSI_ShortWrite(&(lcd.dsi), lcd.dsi_video.VirtualChannelID, DSI_DCS_SHORT_PKT_WRITE_P1, 0x29, 0x00);
|
HAL_DSI_ShortWrite(&hdsi, hdsi_video.VirtualChannelID, DSI_DCS_SHORT_PKT_WRITE_P1, 0x29, 0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void otm8009a_display_off(void)
|
void stm32_mipi_display_off(void)
|
||||||
{
|
{
|
||||||
HAL_DSI_ShortWrite(&(lcd.dsi), lcd.dsi_video.VirtualChannelID, DSI_DCS_SHORT_PKT_WRITE_P1, 0x28, 0x00);
|
HAL_DSI_ShortWrite(&hdsi, hdsi_video.VirtualChannelID, DSI_DCS_SHORT_PKT_WRITE_P1, 0x28, 0x00);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
void LTDC_IRQHandler(void)
|
|
||||||
{
|
|
||||||
rt_interrupt_enter();
|
|
||||||
HAL_LTDC_IRQHandler(&(lcd.ltdc));
|
|
||||||
rt_interrupt_leave();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* <20><><EFBFBD>Դ<EFBFBD><D4B4><EFBFBD>: ---------------------------------------- */
|
|
||||||
static void lcd_fill_buffer(void *addr, uint32_t x_size, uint32_t y_size, uint32_t offset, uint32_t color)
|
|
||||||
{
|
|
||||||
lcd.dma2d.Instance = DMA2D;
|
|
||||||
|
|
||||||
lcd.dma2d.Init.Mode = DMA2D_R2M;
|
|
||||||
lcd.dma2d.Init.ColorMode = DMA2D_ARGB8888;
|
|
||||||
lcd.dma2d.Init.OutputOffset = offset;
|
|
||||||
|
|
||||||
if (HAL_DMA2D_Init(&lcd.dma2d) == HAL_OK)
|
|
||||||
{
|
|
||||||
if (HAL_DMA2D_ConfigLayer(&lcd.dma2d, 0) == HAL_OK)
|
|
||||||
{
|
|
||||||
if (HAL_DMA2D_Start(&lcd.dma2d, color, (uint32_t)addr, x_size, y_size) == HAL_OK)
|
|
||||||
{
|
|
||||||
HAL_DMA2D_PollForTransfer(&lcd.dma2d, 10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void lcd_clear(uint32_t color)
|
|
||||||
{
|
|
||||||
/* Clear the LCD */
|
|
||||||
lcd_fill_buffer((uint32_t *)(lcd.ltdc.LayerCfg[0].FBStartAdress), LCD_WIDTH, LCD_HEIGHT, 0, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lcd_fill_rect(uint16_t x_pos, uint16_t y_pos, uint16_t width, uint16_t height)
|
|
||||||
{
|
|
||||||
uint32_t Xaddress = (lcd.ltdc.LayerCfg[0].FBStartAdress) + 4 * (LCD_WIDTH * x_pos + y_pos);
|
|
||||||
lcd_fill_buffer((uint32_t *)Xaddress, width, height, (LCD_WIDTH - width), 0xFF00FF00);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* <20><><EFBFBD>Դ<EFBFBD><D4B4><EFBFBD> ----------------------------------------- */
|
|
||||||
|
|
||||||
static rt_err_t stm32_lcd_init(rt_device_t device)
|
|
||||||
{
|
|
||||||
lcd.info.width = LCD_WIDTH;
|
|
||||||
lcd.info.height = LCD_HEIGHT;
|
|
||||||
lcd.info.pixel_format = RTGRAPHIC_PIXEL_FORMAT_ARGB888;
|
|
||||||
lcd.info.bits_per_pixel = 32;
|
|
||||||
lcd.info.framebuffer = (void *)rt_malloc_align(LCD_WIDTH * LCD_HEIGHT * (lcd.info.bits_per_pixel / 8), 32);
|
|
||||||
otm8009a_init();
|
|
||||||
otm8009a_layer_init(0, (uint32_t)lcd.info.framebuffer);
|
|
||||||
lcd_clear(0xFF000000);
|
|
||||||
|
|
||||||
return RT_EOK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static rt_err_t stm32_lcd_control(rt_device_t device, int cmd, void *args)
|
|
||||||
{
|
|
||||||
switch(cmd)
|
|
||||||
{
|
|
||||||
case RTGRAPHIC_CTRL_RECT_UPDATE:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RTGRAPHIC_CTRL_POWERON:
|
|
||||||
otm8009a_display_on();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RTGRAPHIC_CTRL_POWEROFF:
|
|
||||||
otm8009a_display_off();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RTGRAPHIC_CTRL_GET_INFO:
|
|
||||||
rt_memcpy(args, &lcd.info, sizeof(lcd.info));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RTGRAPHIC_CTRL_SET_MODE:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RTGRAPHIC_CTRL_GET_EXT:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RT_EOK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int rt_hw_lcd_init(void)
|
|
||||||
{
|
|
||||||
rt_err_t ret;
|
|
||||||
|
|
||||||
rt_memset(&lcd, 0x00, sizeof(lcd));
|
|
||||||
|
|
||||||
lcd.device.type = RT_Device_Class_Graphic;
|
|
||||||
lcd.device.init = stm32_lcd_init;
|
|
||||||
lcd.device.open = RT_NULL;
|
|
||||||
lcd.device.close = RT_NULL;
|
|
||||||
lcd.device.read = RT_NULL;
|
|
||||||
lcd.device.write = RT_NULL;
|
|
||||||
lcd.device.control = stm32_lcd_control;
|
|
||||||
|
|
||||||
lcd.device.user_data = (void *)&lcd.info;
|
|
||||||
|
|
||||||
ret = rt_device_register(&lcd.device, "lcd", RT_DEVICE_FLAG_RDWR);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
INIT_DEVICE_EXPORT(rt_hw_lcd_init);
|
|
||||||
|
|
||||||
#endif /* BSP_USING_LCD_OTM8009A */
|
|
|
@ -15,9 +15,14 @@
|
||||||
#include <rtdevice.h>
|
#include <rtdevice.h>
|
||||||
#include <board.h>
|
#include <board.h>
|
||||||
|
|
||||||
rt_err_t otm8009a_init(void);
|
#define LCD_WIDTH (800U)
|
||||||
void otm8009a_layer_init(uint16_t index, uint32_t framebuffer);
|
#define LCD_HEIGHT (480U)
|
||||||
void lcd_clear(uint32_t color);
|
|
||||||
void lcd_fill_rect(uint16_t x_pos, uint16_t y_pos, uint16_t width, uint16_t height);
|
#define LCD_HSYNC (1U)
|
||||||
|
#define LCD_HBP (15U)
|
||||||
|
#define LCD_HFP (16U)
|
||||||
|
#define LCD_VSYNC (2U)
|
||||||
|
#define LCD_VBP (34U)
|
||||||
|
#define LCD_VFP (34U)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue