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.
trezor-firmware/core/embed/trezorhal/stm32f4/display/stm32f429i-disc1/display_ltdc.c

292 lines
9.9 KiB

/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include <string.h>
#include TREZOR_BOARD
#include STM32_HAL_H
#include "display_internal.h"
#include "ili9341_spi.h"
#include "xdisplay.h"
#define MAX_LAYER_NUMBER 2
LTDC_HandleTypeDef LtdcHandler;
static RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
/* Default LCD configuration with LCD Layer 1 */
uint32_t ActiveLayer = 0;
/**
* @brief Initializes the LCD layers.
* @param LayerIndex: the layer foreground or background.
* @param FB_Address: the layer frame buffer.
*/
void BSP_LCD_LayerDefaultInit(uint16_t LayerIndex, uint32_t FB_Address) {
LTDC_LayerCfgTypeDef Layercfg;
/* Layer Init */
Layercfg.WindowX0 = 0;
Layercfg.WindowX1 = DISPLAY_RESX;
Layercfg.WindowY0 = 0;
Layercfg.WindowY1 = DISPLAY_RESY;
Layercfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
Layercfg.FBStartAdress = FB_Address;
Layercfg.Alpha = 255;
Layercfg.Alpha0 = 0;
Layercfg.Backcolor.Blue = 0;
Layercfg.Backcolor.Green = 0;
Layercfg.Backcolor.Red = 0;
Layercfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
Layercfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
Layercfg.ImageWidth = DISPLAY_RESX;
Layercfg.ImageHeight = DISPLAY_RESY;
HAL_LTDC_ConfigLayer(&LtdcHandler, &Layercfg, LayerIndex);
// DrawProp[LayerIndex].BackColor = LCD_COLOR_WHITE;
// DrawProp[LayerIndex].pFont = &Font24;
// DrawProp[LayerIndex].TextColor = LCD_COLOR_BLACK;
/* Dithering activation */
HAL_LTDC_EnableDither(&LtdcHandler);
}
/**
* @brief Selects the LCD Layer.
* @param LayerIndex: the Layer foreground or background.
*/
void BSP_LCD_SelectLayer(uint32_t LayerIndex) { ActiveLayer = LayerIndex; }
/**
* @brief Sets a LCD Layer visible.
* @param LayerIndex: the visible Layer.
* @param state: new state of the specified layer.
* This parameter can be: ENABLE or DISABLE.
*/
void BSP_LCD_SetLayerVisible(uint32_t LayerIndex, FunctionalState state) {
if (state == ENABLE) {
__HAL_LTDC_LAYER_ENABLE(&LtdcHandler, LayerIndex);
} else {
__HAL_LTDC_LAYER_DISABLE(&LtdcHandler, LayerIndex);
}
__HAL_LTDC_RELOAD_CONFIG(&LtdcHandler);
}
/**
* @brief Sets an LCD Layer visible without reloading.
* @param LayerIndex: Visible Layer
* @param State: New state of the specified layer
* This parameter can be one of the following values:
* @arg ENABLE
* @arg DISABLE
* @retval None
*/
void BSP_LCD_SetLayerVisible_NoReload(uint32_t LayerIndex,
FunctionalState State) {
if (State == ENABLE) {
__HAL_LTDC_LAYER_ENABLE(&LtdcHandler, LayerIndex);
} else {
__HAL_LTDC_LAYER_DISABLE(&LtdcHandler, LayerIndex);
}
/* Do not Sets the Reload */
}
/**
* @brief Configures the Transparency.
* @param LayerIndex: the Layer foreground or background.
* @param Transparency: the Transparency,
* This parameter must range from 0x00 to 0xFF.
*/
void BSP_LCD_SetTransparency(uint32_t LayerIndex, uint8_t Transparency) {
HAL_LTDC_SetAlpha(&LtdcHandler, Transparency, LayerIndex);
}
/**
* @brief Configures the transparency without reloading.
* @param LayerIndex: Layer foreground or background.
* @param Transparency: Transparency
* This parameter must be a number between Min_Data = 0x00 and
* Max_Data = 0xFF
* @retval None
*/
void BSP_LCD_SetTransparency_NoReload(uint32_t LayerIndex,
uint8_t Transparency) {
HAL_LTDC_SetAlpha_NoReload(&LtdcHandler, Transparency, LayerIndex);
}
/**
* @brief Sets a LCD layer frame buffer address.
* @param LayerIndex: specifies the Layer foreground or background
* @param Address: new LCD frame buffer value
*/
void BSP_LCD_SetLayerAddress(uint32_t LayerIndex, uint32_t Address) {
HAL_LTDC_SetAddress(&LtdcHandler, Address, LayerIndex);
}
/**
* @brief Sets an LCD layer frame buffer address without reloading.
* @param LayerIndex: Layer foreground or background
* @param Address: New LCD frame buffer value
* @retval None
*/
void BSP_LCD_SetLayerAddress_NoReload(uint32_t LayerIndex, uint32_t Address) {
HAL_LTDC_SetAddress_NoReload(&LtdcHandler, Address, LayerIndex);
}
void BSP_LCD_Init(void) {
GPIO_InitTypeDef GPIO_InitStructure = {0};
/* Enable the LTDC and DMA2D Clock */
__HAL_RCC_LTDC_CLK_ENABLE();
__HAL_RCC_DMA2D_CLK_ENABLE();
/* Enable GPIOs clock */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
/* GPIOs Configuration */
/*
+------------------------+-----------------------+----------------------------+
+ LCD pins assignment +
+------------------------+-----------------------+----------------------------+
| LCD_TFT R2 <-> PC.10 | LCD_TFT G2 <-> PA.06 | LCD_TFT B2 <-> PD.06 | |
LCD_TFT R3 <-> PB.00 | LCD_TFT G3 <-> PG.10 | LCD_TFT B3 <-> PG.11 |
| LCD_TFT R4 <-> PA.11 | LCD_TFT G4 <-> PB.10 | LCD_TFT B4 <-> PG.12 | |
LCD_TFT R5 <-> PA.12 | LCD_TFT G5 <-> PB.11 | LCD_TFT B5 <-> PA.03 |
| LCD_TFT R6 <-> PB.01 | LCD_TFT G6 <-> PC.07 | LCD_TFT B6 <-> PB.08 | |
LCD_TFT R7 <-> PG.06 | LCD_TFT G7 <-> PD.03 | LCD_TFT B7 <-> PB.09 |
-------------------------------------------------------------------------------
| LCD_TFT HSYNC <-> PC.06 | LCDTFT VSYNC <-> PA.04 |
| LCD_TFT CLK <-> PG.07 | LCD_TFT DE <-> PF.10 |
-----------------------------------------------------
*/
/* GPIOA configuration */
GPIO_InitStructure.Pin =
GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_6 | GPIO_PIN_11 | GPIO_PIN_12;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
GPIO_InitStructure.Alternate = GPIO_AF14_LTDC;
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
/* GPIOB configuration */
GPIO_InitStructure.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11;
HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
/* GPIOC configuration */
GPIO_InitStructure.Pin = GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_10;
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
/* GPIOD configuration */
GPIO_InitStructure.Pin = GPIO_PIN_3 | GPIO_PIN_6;
HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
/* GPIOF configuration */
GPIO_InitStructure.Pin = GPIO_PIN_10;
HAL_GPIO_Init(GPIOF, &GPIO_InitStructure);
/* GPIOG configuration */
GPIO_InitStructure.Pin = GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_11;
HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
/* GPIOB configuration */
GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1;
GPIO_InitStructure.Alternate = GPIO_AF9_LTDC;
HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
/* GPIOG configuration */
GPIO_InitStructure.Pin = GPIO_PIN_10 | GPIO_PIN_12;
HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
/* On STM32F429I-DISCO, it is not possible to read ILI9341 ID because */
/* PIN EXTC is not connected to VDD and then LCD_READ_ID4 is not accessible.
*/
/* In this case, ReadID function is bypassed.*/
/*if(ili9341_drv.ReadID() == ILI9341_ID)*/
/* LTDC Configuration ----------------------------------------------------*/
LtdcHandler.Instance = LTDC;
/* Timing configuration (Typical configuration from ILI9341 datasheet)
HSYNC=10 (9+1)
HBP=20 (29-10+1)
ActiveW=240 (269-20-10+1)
HFP=10 (279-240-20-10+1)
VSYNC=2 (1+1)
VBP=2 (3-2+1)
ActiveH=320 (323-2-2+1)
VFP=4 (327-320-2-2+1)
*/
/* Configure horizontal synchronization width */
LtdcHandler.Init.HorizontalSync = ILI9341_HSYNC;
/* Configure vertical synchronization height */
LtdcHandler.Init.VerticalSync = ILI9341_VSYNC;
/* Configure accumulated horizontal back porch */
LtdcHandler.Init.AccumulatedHBP = ILI9341_HBP;
/* Configure accumulated vertical back porch */
LtdcHandler.Init.AccumulatedVBP = ILI9341_VBP;
/* Configure accumulated active width */
LtdcHandler.Init.AccumulatedActiveW = 269;
/* Configure accumulated active height */
LtdcHandler.Init.AccumulatedActiveH = 323;
/* Configure total width */
LtdcHandler.Init.TotalWidth = 279;
/* Configure total height */
LtdcHandler.Init.TotalHeigh = 327;
/* Configure R,G,B component values for LCD background color */
LtdcHandler.Init.Backcolor.Red = 0;
LtdcHandler.Init.Backcolor.Blue = 0;
LtdcHandler.Init.Backcolor.Green = 0;
/* LCD clock configuration */
/* PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */
/* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN = 192 Mhz */
/* PLLLCDCLK = PLLSAI_VCO Output/PLLSAIR = 192/4 = 48 Mhz */
/* LTDC clock frequency = PLLLCDCLK / LTDC_PLLSAI_DIVR_8 = 48/4 = 6Mhz */
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
PeriphClkInitStruct.PLLSAI.PLLSAIN = 192;
PeriphClkInitStruct.PLLSAI.PLLSAIR = 4;
PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_8;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
/* Polarity */
LtdcHandler.Init.HSPolarity = LTDC_HSPOLARITY_AL;
LtdcHandler.Init.VSPolarity = LTDC_VSPOLARITY_AL;
LtdcHandler.Init.DEPolarity = LTDC_DEPOLARITY_AL;
LtdcHandler.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
HAL_LTDC_Init(&LtdcHandler);
/* Initialize the LCD Layers */
BSP_LCD_LayerDefaultInit(1, FRAME_BUFFER_ADDR);
memset((void *)FRAME_BUFFER_ADDR, 0, FRAME_BUFFER_SIZE);
}