2019-08-05 13:14:59 +01:00

425 lines
14 KiB
C

/**
******************************************************************************
* @file DMA2D/DMA2D_RegToMemWithLCD/Src/main.c
* @author MCD Application Team
* @brief This example provides a description of how to configure DMA2D peripheral
* in Register to Memory transfer mode and display the result on LCD.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/** @addtogroup STM32F7xx_HAL_Examples
* @{
*/
/** @addtogroup DMA2D_RegToMemWithLCD
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
DMA2D_HandleTypeDef Dma2dHandle;
/* DMA2D output address and Input for LCD */
uint32_t aBufferResult[(LAYER_SIZE_X * LAYER_SIZE_Y * LAYER_BYTE_PER_PIXEL) / 4];
/* Private function prototypes -----------------------------------------------*/
static void DMA2D_Config(void);
static void LCD_Config(void);
static void TransferError(DMA2D_HandleTypeDef* Dma2dHandle);
static void TransferComplete(DMA2D_HandleTypeDef* Dma2dHandle);
static void SystemClock_Config(void);
static void Error_Handler(void);
static void CPU_CACHE_Enable(void);
/* Private functions ---------------------------------------------------------*/
/**
* @brief Main program
* @param None
* @retval None
*/
int main(void)
{
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
/* Enable the CPU Cache */
CPU_CACHE_Enable();
/* STM32F7xx HAL library initialization:
- Configure the Flash ART accelerator on ITCM interface
- Systick timer is configured by default as source of time base, but user
can eventually implement his proper time base source (a general purpose
timer for example or other time source), keeping in mind that Time base
duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
handled in milliseconds basis.
- Set NVIC Group Priority to 4
- Low Level Initialization
*/
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/*## LTDC Clock Configuration ###########################################*/
if(stmpe811_ts_drv.ReadID(TS_I2C_ADDRESS) == STMPE811_ID)
{
/* LCD clock configuration */
/* 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/5 = 38.4 Mhz */
/* LTDC clock frequency = PLLLCDCLK / LTDC_PLLSAI_DIVR_4 = 38.4/4 = 9.6Mhz */
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
PeriphClkInitStruct.PLLSAI.PLLSAIN = 192;
PeriphClkInitStruct.PLLSAI.PLLSAIR = 5;
PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_4;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
}
else
{
/* LCD clock configuration */
/* LCD clock configuration */
/* PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */
/* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN = 151 Mhz */
/* PLLLCDCLK = PLLSAI_VCO Output/PLLSAIR = 151/3 = 50.3 Mhz */
/* LTDC clock frequency = PLLLCDCLK / LTDC_PLLSAI_DIVR_2 = 50.3/2 = 25.16Mhz */
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
PeriphClkInitStruct.PLLSAI.PLLSAIN = 151;
PeriphClkInitStruct.PLLSAI.PLLSAIR = 3;
PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_2;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
}
/* Configure LED1, LED2 and LED3 */
BSP_LED_Init(LED1);
BSP_LED_Init(LED2);
BSP_LED_Init(LED3);
/*##-1- DMA2D configuration ################################################*/
DMA2D_Config();
/*##-2- LCD Configuration ##################################################*/
LCD_Config();
/*##-3- Start DMA2D transfer ###############################################*/
if(HAL_DMA2D_Start_IT(&Dma2dHandle,
0xF0FF, /* Color value in Register to Memory DMA2D mode */
(uint32_t)&aBufferResult, /* DMA2D output buffer */
LAYER_SIZE_X, /* width of buffer in pixels */
LAYER_SIZE_Y) /* height of buffer in lines */
!= HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
while (1) { ; }
}
/**
* @brief DMA2D configuration.
* @note This function Configure tha DMA2D peripheral :
* 1) Configure the transfer mode : register to memory
* 2) Configure the color to be used to fill user defined area.
* 3) Configure the output memory address at SRAM memory
* 4) Configure the data size : 100x100 (pixels)
* @retval
* None
*/
static void DMA2D_Config(void)
{
/* Register to memory mode with ARGB4444 as colorMode */
Dma2dHandle.Init.Mode = DMA2D_R2M; /* Mode Register to Mmeory */
Dma2dHandle.Init.ColorMode = DMA2D_OUTPUT_ARGB4444; /* Output color mode */
Dma2dHandle.Init.OutputOffset = 0x0; /* No offset in output */
Dma2dHandle.XferCpltCallback = TransferComplete;
Dma2dHandle.XferErrorCallback = TransferError;
Dma2dHandle.Instance = DMA2D;
/* DMA2D Initialisation */
if(HAL_DMA2D_Init(&Dma2dHandle) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
}
/**
* @brief LCD configuration.
* @note This function Configure tha LTDC peripheral :
* 1) Configure the Pixel Clock for the LCD
* 2) Configure the LTDC Timing and Polarity
* 3) Configure the LTDC Layer 2 :
* - ARGB4444 as pixel format
* - The frame buffer is located at internal RAM : The output of DMA2D transfer
* - The Layer size configuration : 100x100
* @retval
* None
*/
static void LCD_Config(void)
{
static LTDC_HandleTypeDef hltdc_F;
static LTDC_LayerCfgTypeDef pLayerCfg;
/* LTDC Initialization -------------------------------------------------------*/
/* DeInit */
HAL_LTDC_DeInit(&hltdc_F);
/* Polarity configuration */
/* Initialize the horizontal synchronization polarity as active low */
hltdc_F.Init.HSPolarity = LTDC_HSPOLARITY_AL;
/* Initialize the vertical synchronization polarity as active low */
hltdc_F.Init.VSPolarity = LTDC_VSPOLARITY_AL;
/* Initialize the data enable polarity as active low */
hltdc_F.Init.DEPolarity = LTDC_DEPOLARITY_AL;
/* Initialize the pixel clock polarity as input pixel clock */
hltdc_F.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
/* Timing configuration */
if(stmpe811_ts_drv.ReadID(TS_I2C_ADDRESS) == STMPE811_ID)
{
/* The AMPIRE LCD 480x272 is selected */
/* Timing Configuration */
hltdc_F.Init.HorizontalSync = (AMPIRE480272_HSYNC - 1);
hltdc_F.Init.VerticalSync = (AMPIRE480272_VSYNC - 1);
hltdc_F.Init.AccumulatedHBP = (AMPIRE480272_HSYNC + AMPIRE480272_HBP - 1);
hltdc_F.Init.AccumulatedVBP = (AMPIRE480272_VSYNC + AMPIRE480272_VBP - 1);
hltdc_F.Init.AccumulatedActiveH = (AMPIRE480272_HEIGHT + AMPIRE480272_VSYNC + AMPIRE480272_VBP - 1);
hltdc_F.Init.AccumulatedActiveW = (AMPIRE480272_WIDTH + AMPIRE480272_HSYNC + AMPIRE480272_HBP - 1);
hltdc_F.Init.TotalHeigh = (AMPIRE480272_HEIGHT + AMPIRE480272_VSYNC + AMPIRE480272_VBP + AMPIRE480272_VFP - 1);
hltdc_F.Init.TotalWidth = (AMPIRE480272_WIDTH + AMPIRE480272_HSYNC + AMPIRE480272_HBP + AMPIRE480272_HFP - 1);
}
else
{
/* The LCD AMPIRE 640x480 is selected */
/* Timing configuration */
hltdc_F.Init.HorizontalSync = (AMPIRE640480_HSYNC - 1);
hltdc_F.Init.VerticalSync = (AMPIRE640480_VSYNC - 1);
hltdc_F.Init.AccumulatedHBP = (AMPIRE640480_HSYNC + AMPIRE640480_HBP - 1);
hltdc_F.Init.AccumulatedVBP = (AMPIRE640480_VSYNC + AMPIRE640480_VBP - 1);
hltdc_F.Init.AccumulatedActiveH = (AMPIRE640480_HEIGHT + AMPIRE640480_VSYNC + AMPIRE640480_VBP - 1);
hltdc_F.Init.AccumulatedActiveW = (AMPIRE640480_WIDTH + AMPIRE640480_HSYNC + AMPIRE640480_HBP - 1);
hltdc_F.Init.TotalHeigh = (AMPIRE640480_HEIGHT + AMPIRE640480_VSYNC + AMPIRE640480_VBP + AMPIRE640480_VFP - 1);
hltdc_F.Init.TotalWidth = (AMPIRE640480_WIDTH + AMPIRE640480_HSYNC + AMPIRE640480_HBP + AMPIRE640480_HFP - 1);
}
/* Configure R,G,B component values for LCD background color */
hltdc_F.Init.Backcolor.Blue = 0;
hltdc_F.Init.Backcolor.Green = 0;
hltdc_F.Init.Backcolor.Red = 0;
hltdc_F.Instance = LTDC;
/* Layer1 Configuration ------------------------------------------------------*/
/* Windowing configuration */
/*
WindowX0 = Horizontal start
WindowX1 = Horizontal stop
WindowY0 = Vertical start
WindowY1 = Vertical stop
*/
pLayerCfg.WindowX0 = 0;
pLayerCfg.WindowX1 = 100;
pLayerCfg.WindowY0 = 0;
pLayerCfg.WindowY1 = 100;
/* Pixel Format configuration*/
pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_ARGB4444;
/* Start Address configuration : frame buffer is located at FLASH memory */
pLayerCfg.FBStartAdress = (uint32_t)&aBufferResult;
/* Alpha constant (255 totally opaque) */
pLayerCfg.Alpha = 255;
/* Default Color configuration (configure A,R,G,B component values) */
pLayerCfg.Alpha0 = 0;
pLayerCfg.Backcolor.Blue = 0;
pLayerCfg.Backcolor.Green = 0;
pLayerCfg.Backcolor.Red = 0;
/* Configure blending factors */
pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_CA;
pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_CA;
/* Configure the number of lines and number of pixels per line */
pLayerCfg.ImageWidth = LAYER_SIZE_X;
pLayerCfg.ImageHeight = LAYER_SIZE_Y;
/* Configure the LTDC */
HAL_LTDC_Init(&hltdc_F);
/* Configure the Layer 1 */
HAL_LTDC_ConfigLayer(&hltdc_F, &pLayerCfg, 1);
}
/**
* @brief System Clock Configuration
* The system Clock is configured as follow :
* System Clock source = PLL (HSE)
* SYSCLK(Hz) = 216000000
* HCLK(Hz) = 216000000
* AHB Prescaler = 1
* APB1 Prescaler = 4
* APB2 Prescaler = 2
* HSE Frequency(Hz) = 25000000
* PLL_M = 25
* PLL_N = 432
* PLL_P = 2
* PLL_Q = 9
* VDD(V) = 3.3
* Main regulator output voltage = Scale1 mode
* Flash Latency(WS) = 7
* @param None
* @retval None
*/
void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
HAL_StatusTypeDef ret = HAL_OK;
/* Enable HSE Oscillator and activate PLL with HSE as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 25;
RCC_OscInitStruct.PLL.PLLN = 432;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 9;
ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
if(ret != HAL_OK)
{
while(1) { ; }
}
/* Activate the OverDrive to reach the 216 MHz Frequency */
ret = HAL_PWREx_EnableOverDrive();
if(ret != HAL_OK)
{
while(1) { ; }
}
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7);
if(ret != HAL_OK)
{
while(1) { ; }
}
}
/**
* @brief This function is executed in case of error occurrence.
* @param None
* @retval None
*/
static void Error_Handler(void)
{
/* Turn LED3 on */
BSP_LED_On(LED3);
while(1)
{
}
}
/**
* @brief DMA2D Transfer completed callback
* @param hdma2d: DMA2D handle.
* @note This example shows a simple way to report end of DMA2D transfer, and
* you can add your own implementation.
* @retval None
*/
static void TransferComplete(DMA2D_HandleTypeDef *hdma2d)
{
/* Turn LED1 on */
BSP_LED_On(LED1);
}
/**
* @brief DMA2D error callbacks
* @param hdma2d: DMA2D handle
* @note This example shows a simple way to report DMA2D transfer error, and you can
* add your own implementation.
* @retval None
*/
static void TransferError(DMA2D_HandleTypeDef *hdma2d)
{
/* Turn LED2 on */
BSP_LED_On(LED2);
}
/**
* @brief CPU L1-Cache enable.
* @param None
* @retval None
*/
static void CPU_CACHE_Enable(void)
{
/* Enable I-Cache */
SCB_EnableICache();
/* Enable D-Cache */
SCB_EnableDCache();
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/