text: /**
    ******************************************************************************
    * @file    main.c
    * @author  MCD Application Team
    * @brief   This file provides main program functions
    ******************************************************************************
    * @attention
    *
    * Copyright (c) 2017 STMicroelectronics.
    * All rights reserved.
    *
    * This software is licensed under terms that can be found in the LICENSE file
    * in the root directory of this software component.
    * If no LICENSE file comes with this software, it is provided AS-IS.
    *
    ******************************************************************************
    */
  
  /* Includes ------------------------------------------------------------------*/
  #include "main.h"
  #include "WM.h"
  
  /* Private typedef -----------------------------------------------------------*/
  /* Private define ------------------------------------------------------------*/
  /* Private macro -------------------------------------------------------------*/
  /* Private variables ---------------------------------------------------------*/
  uint8_t GUI_Initialized = 0;
  TIM_HandleTypeDef TimHandle;
  uint32_t uwPrescalerValue = 0;
  
  /* Private function prototypes -----------------------------------------------*/
  static void SystemClock_Config(void);
  void BSP_Background(void);
  static void BSP_Config(void);
  void BSP_Pointer_Update(void);
  
  extern void MainTask(void);
  static void CPU_CACHE_Enable(void);
  static void MPU_Config(void);
  
  /* Private functions ---------------------------------------------------------*/
  
  /**
    * @brief  Main program
    * @param  None
    * @retval None
    */ 
  int main(void)
  {
    MPU_Config();
    
    /* Enable the CPU Cache */
    CPU_CACHE_Enable();
  
    /* STM32F7xx HAL library initialization:
         - Configure the Flash ART accelerator on ITCM interface
         - Configure the Systick to generate an interrupt each 1 msec
         - Set NVIC Group Priority to 4
         - Global MSP (MCU Support Package) initialization
       */
    HAL_Init();  
    
    /* Configure the system clock to 200 MHz */
    SystemClock_Config(); 
    
    /* Configure LED1 */
    BSP_LED_Init(LED1);
  
    /***********************************************************/
    
    /* Compute the prescaler value to have TIM3 counter clock equal to 10 KHz */
    uwPrescalerValue = (uint32_t) ((SystemCoreClock /2) / 10000) - 1;
    
    /* Set TIMx instance */
    TimHandle.Instance = TIM3;
     
    /* Initialize TIM3 peripheral as follows:
         + Period = 500 - 1
         + Prescaler = ((SystemCoreClock/2)/10000) - 1
         + ClockDivision = 0
         + Counter direction = Up
    */
    TimHandle.Init.Period = 500 - 1;
    TimHandle.Init.Prescaler = uwPrescalerValue;
    TimHandle.Init.ClockDivision = 0;
    TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
    if(HAL_TIM_Base_Init(&TimHandle) != HAL_OK)
    {
      while(1) 
      {
      }
    }
    
    /*##-2- Start the TIM Base generation in interrupt mode ####################*/
    /* Start Channel1 */
    if(HAL_TIM_Base_Start_IT(&TimHandle) != HAL_OK)
    {
      while(1) 
      {
      }
    }
    
    /***********************************************************/
    
    BSP_Config();
    
    /* Init the STemWin GUI Library */
    BSP_SDRAM_Init(); /* Initializes the SDRAM device */
    __HAL_RCC_CRC_CLK_ENABLE(); /* Enable the CRC Module */
    GUI_Init();
    
    GUI_DispStringAt("Starting...", 0, 0);
  
    /* Multi buffering enable */
    WM_MULTIBUF_Enable(1); 
    
    GUI_Initialized = 1;
    
    /* Activate the use of memory device feature */
    WM_SetCreateFlags(WM_CF_MEMDEV);
      
    MainTask();
    
    /* Infinite loop */
    for(;;);
  }
  
  /**
    * @brief  Initializes the STM324x9I-EVAL's LCD and LEDs resources.
    * @param  None
    * @retval None
    */
  static void BSP_Config(void)
  {
    BSP_TS_Init(480, 272);
  }
  
  /**
    * @brief  Period elapsed callback in non blocking mode
    * @param  htim: TIM handle
    * @retval None
    */
  void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  {
    BSP_Background();
  }
  
  /**
    * @brief TIM MSP Initialization 
    *        This function configures the hardware resources used in this application: 
    *           - Peripheral's clock enable
    *           - Peripheral's GPIO Configuration  
    * @param htim: TIM handle pointer
    * @retval None
    */
  void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
  {
    /*##-1- Enable peripherals and GPIO Clocks #################################*/
    /* TIMx Peripheral clock enable */
    __HAL_RCC_TIM3_CLK_ENABLE();
  
    /*##-2- Configure the NVIC for TIMx ########################################*/
    /* Set the TIMx priority */
    HAL_NVIC_SetPriority(TIM3_IRQn, 0, 1);
    
    /* Enable the TIMx global Interrupt */
    HAL_NVIC_EnableIRQ(TIM3_IRQn);
  }
  
  /**
  * @brief  BSP_Background.
  * @param  None
  * @retval None
  */ 
  void BSP_Background(void)
  {
    /* Capture input event and updade cursor */
    if(GUI_Initialized == 1)
    {
      BSP_Pointer_Update();
    }
  }
  
  /**
    * @brief  System Clock Configuration
    *         The system Clock is configured as follow : 
    *            System Clock source            = PLL (HSE)
    *            SYSCLK(Hz)                     = 200000000
    *            HCLK(Hz)                       = 200000000
    *            AHB Prescaler                  = 1
    *            APB1 Prescaler                 = 4
    *            APB2 Prescaler                 = 2
    *            HSE Frequency(Hz)              = 25000000
    *            PLL_M                          = 25
    *            PLL_N                          = 400
    *            PLL_P                          = 2
    *            PLL_Q                          = 8
    *            VDD(V)                         = 3.3
    *            Main regulator output voltage  = Scale1 mode
    *            Flash Latency(WS)              = 6
    * @param  None
    * @retval None
    */
  static 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 = 400;  
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
    RCC_OscInitStruct.PLL.PLLQ = 8;
  
    ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
    if(ret != HAL_OK)
    {
      while(1) { ; }
    }
  
    /* Activate the OverDrive to reach the 200 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_6);
    if(ret != HAL_OK)
    {
      while(1) { ; }
    }
  }
  
  /**
    * @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();
  }
  /** ECO added
    * @brief  Configure the MPU attributes as Normal Non Cacheable for SRAM1/2.
    * @note   The Base Address is 0x20010000 since this memory interface is the AXI.
    *         The Region Size is 256KB, it is related to SRAM1 and SRAM2  memory size.
    * @param  None
    * @retval None
    */
  static void MPU_Config(void)
  {
    MPU_Region_InitTypeDef MPU_InitStruct;
    
    /* Disable the MPU */
    HAL_MPU_Disable();
    
    /* Configure the MPU as Strongly ordered for not defined regions */
    MPU_InitStruct.Enable = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress = 0x00;
    MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
    MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
    MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
    MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
    MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
    MPU_InitStruct.Number = MPU_REGION_NUMBER0;
    MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
    MPU_InitStruct.SubRegionDisable = 0x87;
    MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
  
    HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    /* Configure the MPU as Normal Non Cacheable for the SRAM1 and SRAM2 */
    MPU_InitStruct.Enable = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress = 0x20010000;
    MPU_InitStruct.Size = MPU_REGION_SIZE_256KB;
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
    MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
    MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
    MPU_InitStruct.Number = MPU_REGION_NUMBER1;
    MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
  
    HAL_MPU_ConfigRegion(&MPU_InitStruct);
  
    /* Configure the MPU attributes as WT for SDRAM */
    MPU_InitStruct.Enable = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress = 0xC0000000;
    MPU_InitStruct.Size = MPU_REGION_SIZE_32MB;
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
    MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
    MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.Number = MPU_REGION_NUMBER2;
    MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
  
    HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    /* Configure the MPU attributes FMC control registers */
    MPU_InitStruct.Enable = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress = 0xA0000000;
    MPU_InitStruct.Size = MPU_REGION_SIZE_8KB;
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
    MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
    MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
    MPU_InitStruct.Number = MPU_REGION_NUMBER3;
    MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
    MPU_InitStruct.SubRegionDisable = 0x0;
    MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
    
    HAL_MPU_ConfigRegion(&MPU_InitStruct);
  
    /* Enable the MPU */
    HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
  }
  
  /**
    * @brief  Provide the GUI with current state of the touch screen
    * @param  None
    * @retval None
    */
  void BSP_Pointer_Update(void)
  {
    static GUI_PID_STATE TS_State = {0, 0, 0, 0};
    __IO TS_StateTypeDef  ts;
    uint16_t xDiff, yDiff;  
  
    BSP_TS_GetState((TS_StateTypeDef *)&ts);
  
    if((ts.touchX[0] >= LCD_GetXSize()) ||(ts.touchY[0] >= LCD_GetYSize()) ) 
    {
      ts.touchX[0] = 0;
      ts.touchY[0] = 0;
      ts.touchDetected =0;
    }
  
    xDiff = (TS_State.x > ts.touchX[0]) ? (TS_State.x - ts.touchX[0]) : (ts.touchX[0] - TS_State.x);
    yDiff = (TS_State.y > ts.touchY[0]) ? (TS_State.y - ts.touchY[0]) : (ts.touchY[0] - TS_State.y);
    
    
    if((TS_State.Pressed != ts.touchDetected ) ||
       (xDiff > 30 )||
        (yDiff > 30))
    {
      TS_State.Pressed = ts.touchDetected;
      TS_State.Layer = 0;
      if(ts.touchDetected) 
      {
        TS_State.x = ts.touchX[0];
        TS_State.y = ts.touchY[0];
        GUI_TOUCH_StoreStateEx(&TS_State);
      }
      else
      {
        GUI_TOUCH_StoreStateEx(&TS_State);
        TS_State.x = 0;
        TS_State.y = 0;
      }
    }
  }
  
  #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
  
  