打印
[STM32N6]

运行STM32N6 的BSP外设综合测试

[复制链接]
554|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 一路向北lm 于 2025-3-15 19:35 编辑

Demo:按键触摸




DemoSD卡实验

Demo:摄像头实验

视频动图展示







使用特权

评论回复
沙发
一路向北lm|  楼主 | 2025-3-15 19:29 | 只看该作者

摄像头camera代码部分

/**
  ******************************************************************************
  * [url=home.php?mod=space&uid=288409]@file[/url]    camera.c
  * [url=home.php?mod=space&uid=187600]@author[/url]  MCD Application Team
  * [url=home.php?mod=space&uid=247401]@brief[/url]   This example code shows how to use the camera features of the
  *          stm32h7b3i_eval_camera driver
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 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"
/** @addtogroup STM32N6xx_HAL_Examples
  * @{
  */

/** @addtogroup BSP
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define WVGA_RES_X      800
#define WVGA_RES_Y      480
#define CAMERA_FRAME_BUFFER LCD_LAYER_1_ADDRESS
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static uint8_t MirrorFlipIndex = 0;
/* Camera resolutions */

uint8_t  CameraMirrorFlip[4] =
{
  CAMERA_MIRRORFLIP_NONE,
  CAMERA_MIRRORFLIP_FLIP,
  CAMERA_MIRRORFLIP_MIRROR,
  CAMERA_MIRRORFLIP_FLIP | CAMERA_MIRRORFLIP_MIRROR,
};

CAMERA_Capabilities_t Cap;

/* Private function prototypes -----------------------------------------------*/
static void Camera_SetHint(void);
static uint32_t Camera_ISP_IdleWait(uint32_t delay);

/* Private functions ---------------------------------------------------------*/
/**
  * @brief  Camera demo
  * @param  None
  * @retval None
  */
void Camera_Demo (void)
{
  Camera_SetHint();

  UTIL_LCD_Clear(UTIL_LCD_COLOR_WHITE);
  /* Display USB initialization message */
  UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_WHITE);
  UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_DARKBLUE);

  UTIL_LCD_SetFont(&Font24);
  BSP_LCD_LayerConfig_t cam_layer;
  cam_layer.Address = LCD_LAYER_1_ADDRESS;
  cam_layer.PixelFormat = LCD_PIXEL_FORMAT_RGB565;
  cam_layer.X0 = 0;
  cam_layer.X1 = 800;
  cam_layer.Y0 = 0;
  cam_layer.Y1 = 480;
  BSP_LCD_ConfigLayer(0, 1, &cam_layer);
  BSP_LCD_SetColorKeying(0, 1, UTIL_LCD_COLOR_WHITE);
  BSP_LCD_SetActiveLayer(0,1);
  BSP_LCD_SetLayerAddress(0, 0, LCD_LAYER_1_ADDRESS);
  BSP_LCD_SetLayerAddress(0, 1, LCD_LAYER_0_ADDRESS);
  /* Initialize the Camera */
  if(BSP_CAMERA_Init(0, CAMERA_R2592x1944, CAMERA_PF_RAW_RGGB10) != BSP_ERROR_NONE)
  {
    UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_RED);
    UTIL_LCD_DisplayStringAt(20, 0, (uint8_t *)" NO CAMERA CONNECTED", CENTER_MODE);
  }
  else
  {
    UTIL_LCD_DisplayStringAt(20, 35, (uint8_t *)"CAMERA CONTINUOUS MODE", CENTER_MODE);
    /* Wait for the camera initialization after HW reset*/
    HAL_Delay(100);

    BSP_CAMERA_GetCapabilities(0, &Cap);

    /* Start the Camera Capture */
    BSP_CAMERA_Start(0, (uint8_t *)CAMERA_FRAME_BUFFER, CAMERA_MODE_CONTINUOUS);

    UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_RED);
    Camera_ISP_IdleWait(5000);
    /* Start the Camera Capture */
    UTIL_LCD_Clear(UTIL_LCD_COLOR_WHITE);
    if(Cap.MirrorFlip != 1)
    {
      UTIL_LCD_DisplayStringAt(0, 35, (uint8_t *)"Camera MirrorFlip feature not supported", CENTER_MODE);
      Camera_ISP_IdleWait(2000);
    }
    else
    {
      UTIL_LCD_DisplayStringAt(0, 35, (uint8_t *)"                                               ", CENTER_MODE);
      UTIL_LCD_DisplayStringAt(0, 70, (uint8_t *)"Camera Mirror/Flip", CENTER_MODE);
      /* Test Camera Mirror/Flip */
      while(MirrorFlipIndex < 4)
      {
        Camera_ISP_IdleWait(2000);
        BSP_CAMERA_SetMirrorFlip(0, CameraMirrorFlip[MirrorFlipIndex]);
        MirrorFlipIndex++;
      }
      Camera_ISP_IdleWait(2000);
      MirrorFlipIndex = 1;
      BSP_CAMERA_SetMirrorFlip(0, CameraMirrorFlip[MirrorFlipIndex]);
    }
    BSP_CAMERA_SetMirrorFlip(0, CAMERA_MIRRORFLIP_NONE);

    Camera_ISP_IdleWait(2000);
  }
  BSP_CAMERA_Stop(0);
  UTIL_LCD_FillRect(0, 0, 800, 480, UTIL_LCD_COLOR_WHITE);
  BSP_LCD_ResetColorKeying(0, 1);
  BSP_LCD_SetLayerAddress(0, 0, LCD_LAYER_0_ADDRESS);
  BSP_LCD_SetLayerAddress(0, 1, LCD_LAYER_1_ADDRESS);
  BSP_LCD_SetLayerVisible(0, 1, DISABLE);
  BSP_LCD_SetActiveLayer(0,0);
  UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_WHITE);
  UTIL_LCD_DisplayStringAt(20, 35, (uint8_t *)"CAMERA Demo done. press USR1 to continue", CENTER_MODE);



  while (1)
  {
    if(CheckForUserInput() > 0)
    {
      ClearUserInput();
      BSP_CAMERA_DeInit(0);
      return;
    }
  }
}

/**
  * @brief  Display Camera demo hint
  * @param  None
  * @retval None
  */
static void Camera_SetHint(void)
{
  uint32_t x_size, y_size;

  BSP_LCD_GetXSize(0, &x_size);
  BSP_LCD_GetYSize(0, &y_size);

  /* Clear the LCD */
  UTIL_LCD_Clear(UTIL_LCD_COLOR_WHITE);

  /* Set Camera Demo description */
  UTIL_LCD_FillRect(0, 0, x_size, 120, UTIL_LCD_COLOR_BLUE);
  UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_WHITE);
  UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_BLUE);
  UTIL_LCD_SetFont(&Font24);
  UTIL_LCD_DisplayStringAt(0, 0, (uint8_t *)"CAMERA EXAMPLE", CENTER_MODE);
  UTIL_LCD_SetFont(&Font12);
  UTIL_LCD_DisplayStringAt(0, 30, (uint8_t *)"     Press User button for next menu     ", CENTER_MODE);

  /* Set the LCD Text Color */
  UTIL_LCD_DrawRect(10, 130, x_size - 20, y_size - 130, UTIL_LCD_COLOR_BLUE);
  UTIL_LCD_DrawRect(11, 131, x_size - 22, y_size - 132, UTIL_LCD_COLOR_BLUE);
}

/**
  * @brief  Camera demo idle loop
  * @param  None
  * @retval None
  */
static uint32_t Camera_ISP_IdleWait(uint32_t delay){
  uint32_t initial_tick =  HAL_GetTick();
  while((HAL_GetTick() - initial_tick) < delay){
    int err = BSP_CAMERA_BackgroundProcess();
    if(err != BSP_ERROR_NONE){
      return err;
    }
  }
  return 0;
}
/**
  * @}
  */

/**
  * @}
  */





使用特权

评论回复
板凳
一路向北lm|  楼主 | 2025-3-15 19:30 | 只看该作者
LCD 部分代码:
/**
  ******************************************************************************
  * @file    lcd.c
  * @author  MCD Application Team
  * @brief   This example code shows how to use the LCD display feature in the
  *          STM32H573I-DK driver
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 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"

/** @addtogroup STM32H5xx_HAL_Examples
  * @{
  */

/** @addtogroup BSP
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint32_t  colors[24] = {UTIL_LCD_COLOR_BLUE , UTIL_LCD_COLOR_GREEN, UTIL_LCD_COLOR_RED, UTIL_LCD_COLOR_CYAN,
                        UTIL_LCD_COLOR_MAGENTA, UTIL_LCD_COLOR_YELLOW,UTIL_LCD_COLOR_LIGHTBLUE, UTIL_LCD_COLOR_LIGHTGREEN,
                        UTIL_LCD_COLOR_LIGHTRED, UTIL_LCD_COLOR_WHITE, UTIL_LCD_COLOR_LIGHTMAGENTA, UTIL_LCD_COLOR_LIGHTYELLOW,
                        UTIL_LCD_COLOR_DARKGREEN, UTIL_LCD_COLOR_DARKRED, UTIL_LCD_COLOR_DARKCYAN,UTIL_LCD_COLOR_DARKMAGENTA,
                        UTIL_LCD_COLOR_LIGHTGRAY, UTIL_LCD_COLOR_GRAY, UTIL_LCD_COLOR_DARKGRAY, UTIL_LCD_COLOR_DARKYELLOW,
                        UTIL_LCD_COLOR_BLACK, UTIL_LCD_COLOR_BROWN, UTIL_LCD_COLOR_ORANGE, UTIL_LCD_COLOR_DARKBLUE};
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/**
  * @brief  LCD demo
  * @param  None
  * @retval None
  */
void Lcd_Demo(void)
{
  Point    triangle[3] = {{0, 0}, {0, 0}, {0, 0}};
  uint32_t colorIndex = 0;
  uint32_t x;
  uint32_t y;
  uint32_t  i, color_index;

  UTIL_LCD_Clear(UTIL_LCD_COLOR_WHITE);
  UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_ST_BLUE_DARK);
  UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_WHITE);
  UTIL_LCD_FillRect(0, 0, 800, 40, UTIL_LCD_COLOR_ST_BLUE_DARK);
  UTIL_LCD_DisplayStringAt(0, 15, (uint8_t *)" Test LCD  ", CENTER_MODE);

  /* Display a grid of colored rectangles with each rectangle being 80x80 pixels in size.
     There are 8 rectangles per row and 3 rows, each with a color from the colors array */
  for (color_index = 0; color_index < 24; color_index++)
  {
    int x = 80 * ((color_index % 8) + 1);
    int y = 80 * (color_index / 8 + 2);

    UTIL_LCD_FillRect(x, y, 80, 80, colors[color_index]);
  }

  HAL_Delay(1000);

  UTIL_LCD_FillRect(0, 40, 800, 440, UTIL_LCD_COLOR_WHITE);

  /* Display a grid of circles on an LCD screen */
  for(color_index = 0; color_index < 4; color_index++)
  {
    for(i = 0; i < 6; i++)
    {
      UTIL_LCD_DrawCircle(150 + (100*i), 100*(color_index+1), 40, UTIL_LCD_COLOR_BLACK);
    }
  }

  HAL_Delay(1000);

  /* Display a grid of colored circles */
  for(color_index = 0; color_index < 4; color_index++)
  {
    for(i = 0; i < 6; i++)
    {
      UTIL_LCD_FillCircle(150 + (100*i), 100*(color_index+1), 40, colors[colorIndex]);
      colorIndex++;
      HAL_Delay(50);
    }
  }

  HAL_Delay(1000);
  UTIL_LCD_FillRect(0, 40, 800, 440, UTIL_LCD_COLOR_WHITE);

  colorIndex = 0;
  /* Display a grid of colored triangles */
  for(color_index = 0; color_index < 6; color_index++)
  {
    for(i = 0; i < 4; i++)
    {
      triangle[0].X = 40*color_index;
      triangle[0].Y = 40 + 50*(i);
      triangle[1].X = 40*(color_index+1);
      triangle[1].Y = 65 + 50*(i);
      triangle[2].X = 40*color_index;
      triangle[2].Y = 40 + 50*(1+i);
      UTIL_LCD_FillPolygon(triangle, 3, colors[colorIndex]);
      if(colors[colorIndex] == UTIL_LCD_COLOR_WHITE)
      {
        UTIL_LCD_DrawPolygon(triangle, 3, UTIL_LCD_COLOR_BLACK);
      }
      colorIndex++;
    }
  }
  HAL_Delay(1000);

  UTIL_LCD_FillRect(0, 40, 800, 440, UTIL_LCD_COLOR_WHITE);

  /* Draw bitmap */
  UTIL_LCD_DrawBitmap(80, 130, (uint8_t *)st**);
  HAL_Delay(500);

  UTIL_LCD_DrawBitmap(240, 130, (uint8_t *)st**);

  HAL_Delay(500);

  UTIL_LCD_DrawBitmap(400, 130, (uint8_t *)st**);

  HAL_Delay(500);

  UTIL_LCD_DrawBitmap(560, 130, (uint8_t *)st**);

  HAL_Delay(1000);
  UTIL_LCD_FillRect(0, 40, 800, 440, UTIL_LCD_COLOR_WHITE);

  BSP_LCD_DisplayOff(0);

  if (BSP_LCD_DeInit(0) != BSP_ERROR_NONE)
  {
    Error_Handler();
  }

  BSP_LCD_InitEx(0, LCD_ORIENTATION_LANDSCAPE, LCD_PIXEL_FORMAT_RGB888, LCD_DEFAULT_WIDTH, LCD_DEFAULT_HEIGHT);
  UTIL_LCD_SetFuncDriver(&LCD_Driver);
  BSP_LCD_DisplayOn(0);


  UTIL_LCD_FillRect(0, 40, 800, 440, UTIL_LCD_COLOR_WHITE);
  UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_ST_BLUE_DARK);
  UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_WHITE);
  UTIL_LCD_FillRect(0, 0, 800, 40, UTIL_LCD_COLOR_ST_BLUE_DARK);
  UTIL_LCD_DisplayStringAt(0, 15, (uint8_t *)" Test LCD  ", CENTER_MODE);
  UTIL_LCD_DisplayStringAt(0, 100, (uint8_t *)"LCD RGB888", CENTER_MODE);

  for (color_index = 0; color_index < 16; color_index++)
  {
     x = 40 * ((color_index % 4) + 8) ;
     y = (40 * (color_index / 4 + 4));

    UTIL_LCD_FillRect(x, y, 40, 40, colors[color_index]);
  }

  HAL_Delay(1000);
  if (BSP_LCD_DeInit(0) != BSP_ERROR_NONE)
  {
    Error_Handler();
  }

  BSP_LCD_DisplayOff(0);

  BSP_LCD_InitEx(0, LCD_ORIENTATION_LANDSCAPE, LCD_PIXEL_FORMAT_ARGB4444, LCD_DEFAULT_WIDTH, LCD_DEFAULT_HEIGHT);
  UTIL_LCD_SetFuncDriver(&LCD_Driver);
  BSP_LCD_DisplayOn(0);

  UTIL_LCD_FillRect(0, 40, 800, 440, UTIL_LCD_COLOR_WHITE);
  UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_ST_BLUE_DARK);
  UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_WHITE);
  UTIL_LCD_FillRect(0, 0, 800, 40, UTIL_LCD_COLOR_ST_BLUE_DARK);
  UTIL_LCD_DisplayStringAt(0, 15, (uint8_t *)" Test LCD  ", CENTER_MODE);
  UTIL_LCD_DisplayStringAt(0, 100, (uint8_t *)"LCD ARGB4444", CENTER_MODE);

  for (color_index = 8; color_index < 24; color_index++)
  {
     x = 40 * ((color_index % 4) + 8) ;
     y = (40 * (color_index / 4 + 4));

    UTIL_LCD_FillRect(x, y, 40, 40, colors[color_index]);
  }

  HAL_Delay(1000);
  UTIL_LCD_Clear(UTIL_LCD_COLOR_WHITE);

  if (BSP_LCD_DeInit(0) != BSP_ERROR_NONE)
  {
    Error_Handler();
  }

  if(BSP_LCD_Init(0, LCD_ORIENTATION_LANDSCAPE) != BSP_ERROR_NONE)
  {
    Error_Handler();
  }

  UTIL_LCD_SetFuncDriver(&LCD_Driver);

  UTIL_LCD_FillRect(0, 0, 800, 40, UTIL_LCD_COLOR_ST_BLUE_DARK);
  UTIL_LCD_DisplayStringAt(0, 15, (uint8_t *)" Test LCD  ", CENTER_MODE);
}


/**
  * @}
  */

/**
  * @}
  */



使用特权

评论回复
地板
一路向北lm|  楼主 | 2025-3-15 19:31 | 只看该作者
触摸演示相关函数

/**
  ******************************************************************************
  * @file    touchscreen.c
  * @author  MCD Application Team
  * @brief   This example code shows how to use the touchscreen driver.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 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"

/** @addtogroup STM32H7RSxx_HAL_Examples
  * @{
  */

/** @addtogroup BSP
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define  CIRCLE_RADIUS        40
#define  LINE_LENGHT          30
/* Private macro -------------------------------------------------------------*/
#define  CIRCLE_XPOS(i)       ((i * 480) / 5)
#define  CIRCLE_YPOS(i)       (272 - CIRCLE_RADIUS - 60)

/* Private Structures and Enumerations ------------------------------------------------------------*/
/* Possible allowed indexes of touchscreen demo */
typedef enum
{
  TOUCHSCREEN_DEMO_1 = 1,
#if (USE_TS_MULTI_TOUCH == 1)
  TOUCHSCREEN_DEMO_2 = 2,
  TOUCHSCREEN_DEMO_3 = 3,
  TOUCHSCREEN_DEMO_MAX = TOUCHSCREEN_DEMO_3,
#else
  TOUCHSCREEN_DEMO_MAX = TOUCHSCREEN_DEMO_1,
#endif /* USE_TS_MULTI_TOUCH == 1 */
} TouchScreenDemoTypeDef;

/* Table for touchscreen event information display on LCD : table indexed on enum [url=home.php?mod=space&uid=144993]@ref[/url] TS_TouchEventTypeDef information */
char * ts_event_string_tab[4] = { "None",
                                  "Press down",
                                  "Lift up",
                                  "Contact"};

/* Global variables ---------------------------------------------------------*/
uint16_t x_new_pos = 0, x_previous_pos = 0;
uint16_t y_new_pos = 0, y_previous_pos = 0;
TS_State_t  TS_State;
TS_MultiTouch_State_t  TS_MTState = {0};

extern uint32_t colors[];

/* Private variables ---------------------------------------------------------*/
/* Static variable holding the current touch color index : used to change color at each touch */
#if (USE_TS_MULTI_TOUCH == 1)
static uint32_t touchscreen_color_idx = 0;
#endif /* USE_TS_MULTI_TOUCH == 1 */
TS_Init_t hTS;
/* Private function prototypes -----------------------------------------------*/
static void     Touchscreen_SetHint_Demo(TouchScreenDemoTypeDef demoIndex);
#if (USE_TS_MULTI_TOUCH == 1)
static uint32_t Touchscreen_Handle_NewTouch(void);
static void TS_Update(void);
#endif /* USE_TS_MULTI_TOUCH == 1 */

/* Private functions ---------------------------------------------------------*/
/**
  * @brief  Touchscreen Demo1 : test touchscreen calibration and single touch in polling mode
  * @param  None
  * @retval None
  */
void Touchscreen_demo1(void)
{
  uint16_t x1, y1;
  uint8_t state = 0;
  uint32_t ts_status = BSP_ERROR_NONE;
  uint32_t x_size, y_size;

  BSP_LCD_GetXSize(0, &x_size);
  BSP_LCD_GetYSize(0, &y_size);
  UserButtonPressed = 0;

  hTS.Width = x_size;
  hTS.Height = y_size;
  hTS.Orientation = TS_SWAP_NONE;
  hTS.Accuracy = 5;

  /* Touchscreen initialization */
  ts_status = BSP_TS_Init(0, &hTS);

  if(ts_status == BSP_ERROR_NONE)
  {
    /* Display touch screen demo description */
    Touchscreen_SetHint_Demo(TOUCHSCREEN_DEMO_1);
    Touchscreen_DrawBackground_Circles(state);

    while (1)
    {
      /* Check in polling mode in touch screen the touch status and coordinates */
      /* of touches if touch occurred                                           */
      ts_status = BSP_TS_GetState(0, &TS_State);
      if(TS_State.TouchDetected)
      {
        /* One or dual touch have been detected          */
        /* Only take into account the first touch so far */

        /* Get X and Y position of the first touch post calibrated */
        x1 = TS_State.TouchX;
        y1 = TS_State.TouchY;

        if ((y1 > (CIRCLE_YPOS(1) - CIRCLE_RADIUS)) &&
            (y1 < (CIRCLE_YPOS(1) + CIRCLE_RADIUS)))
        {
          if ((x1 > (CIRCLE_XPOS(1) - CIRCLE_RADIUS)) &&
              (x1 < (CIRCLE_XPOS(1) + CIRCLE_RADIUS)))
          {
            if ((state & 1) == 0)
            {
              Touchscreen_DrawBackground_Circles(state);
              UTIL_LCD_FillCircle(CIRCLE_XPOS(1), CIRCLE_YPOS(1), CIRCLE_RADIUS, UTIL_LCD_COLOR_BLUE);
              HAL_Delay(1);
              state = 1;
            }
          }
          if ((x1 > (CIRCLE_XPOS(2) - CIRCLE_RADIUS)) &&
              (x1 < (CIRCLE_XPOS(2) + CIRCLE_RADIUS)))
          {
            if ((state & 2) == 0)
            {
              Touchscreen_DrawBackground_Circles(state);
              UTIL_LCD_FillCircle(CIRCLE_XPOS(2), CIRCLE_YPOS(2), CIRCLE_RADIUS, UTIL_LCD_COLOR_RED);
              HAL_Delay(1);
              state = 2;
            }
          }

          if ((x1 > (CIRCLE_XPOS(3) - CIRCLE_RADIUS)) &&
              (x1 < (CIRCLE_XPOS(3) + CIRCLE_RADIUS)))
          {
            if ((state & 4) == 0)
            {
              Touchscreen_DrawBackground_Circles(state);
              UTIL_LCD_FillCircle(CIRCLE_XPOS(3), CIRCLE_YPOS(3), CIRCLE_RADIUS, UTIL_LCD_COLOR_YELLOW);
              state = 4;
            }
          }

          if ((x1 > (CIRCLE_XPOS(4) - CIRCLE_RADIUS)) &&
              (x1 < (CIRCLE_XPOS(4) + CIRCLE_RADIUS)))
          {
            if ((state & 8) == 0)
            {
              Touchscreen_DrawBackground_Circles(state);
              UTIL_LCD_FillCircle(CIRCLE_XPOS(4), CIRCLE_YPOS(3), CIRCLE_RADIUS, UTIL_LCD_COLOR_GREEN);
              state = 8;
            }
          }
        }

      } /* of if(TS_State.TouchDetected) */

      if(CheckForUserInput() > 0)
      {
        ClearUserInput();
        BSP_TS_DeInit(0);
        return;
      }

      HAL_Delay(20);
    }
  } /* of if(status == BSP_ERROR_NONE) */
}

#if (USE_TS_MULTI_TOUCH == 1)
/**
  * @brief  Touchscreen Demo2 : test touchscreen single and dual touch in polling mode
  * @param  None
  * @retval None
  */
void Touchscreen_demo2(void)
{
  uint32_t ts_status = BSP_ERROR_NONE;
  uint32_t x_size, y_size;
  UserButtonPressed = 0;
  BSP_LCD_GetXSize(0, &x_size);
  BSP_LCD_GetYSize(0, &y_size);

  hTS.Width = x_size;
  hTS.Height = y_size;
  hTS.Orientation = TS_SWAP_NONE;
  hTS.Accuracy = 0;

  /* Touchscreen initialization */
  ts_status = BSP_TS_Init(0, &hTS);

  if(ts_status == BSP_ERROR_NONE)
  {
    /* Display touch screen demo2 description */
    Touchscreen_SetHint_Demo(TOUCHSCREEN_DEMO_2);
  } /* of if(status == BSP_ERROR_NONE) */

  while (1)
  {
    Touchscreen_Handle_NewTouch();
    if(CheckForUserInput() > 0)
    {
      ClearUserInput();
      BSP_TS_DeInit(0);
      return;
    }
    HAL_Delay(100);
  }
}

/**
  * @brief  Touchscreen Demo3 : test touchscreen single touch in interrupt mode
  * @param  None
  * @retval None
  */
void Touchscreen_demo3(void)
{
  uint16_t k, l;
  uint32_t x_size, y_size;

  BSP_LCD_GetXSize(0, &x_size);
  BSP_LCD_GetYSize(0, &y_size);

  hTS.Width = x_size;
  hTS.Height = y_size;
  hTS.Orientation = TS_SWAP_NONE;
  hTS.Accuracy = 0;

  /* Touchscreen initialization */
  BSP_TS_Init(0, &hTS);

  BSP_TS_EnableIT(0);

  UTIL_LCD_Clear(UTIL_LCD_COLOR_WHITE);
  for(k = 0; k < hTS.Width/40; k++)
  {
    for(l = 0; l < hTS.Height/40; l++)
    {
      UTIL_LCD_DrawRect(40*k, 40*l,40,40, UTIL_LCD_COLOR_BLACK);
    }
  }

  while (1)
  {
    if(CheckForUserInput() > 0)
    {
      ClearUserInput();
      BSP_TS_DisableIT(0);
      BSP_TS_DeInit(0);
      return;
    }
  }
}

void BSP_TS_Callback(uint32_t Instance)
{
  TS_Update();
}

static void TS_Update(void)
{
  uint16_t i, j;

  BSP_TS_GetState(0, &TS_State);
  if(TS_State.TouchDetected)
  {
    /* One or dual touch have been detected          */
    /* Only take into account the first touch so far */
    /* Get X and Y position of the first touch post calibrated */
    x_new_pos = TS_State.TouchX;
    y_new_pos = TS_State.TouchY;

    for(i = 0; i < hTS.Width/40; i++)
    {
      for(j = 0; j < hTS.Height/40; j++)
      {
        if(((x_new_pos > 40*i) && (x_new_pos < 40*(i+1))) && ((y_new_pos > 40*j) && (y_new_pos < 40*(j+1))))
        {
          UTIL_LCD_FillRect(x_previous_pos, y_previous_pos,40,40, UTIL_LCD_COLOR_WHITE);
          UTIL_LCD_DrawRect(x_previous_pos, y_previous_pos,40,40, UTIL_LCD_COLOR_BLACK);

          UTIL_LCD_FillRect(40*i, 40*j,40,40, colors[(touchscreen_color_idx++ % 24)]);

          x_previous_pos = 40*i;
          y_previous_pos = 40*j;
          break;
        }
      }
    }
    x_new_pos = TS_State.TouchX;
    y_new_pos = TS_State.TouchY;
  }
}

/**
  * @brief  Touchscreen_Handle_NewTouch: factorization of touch management
  * @param  None
  * @retval BSP_ERROR_NONE
  */
static uint32_t Touchscreen_Handle_NewTouch(void)
{
#define TS_MULTITOUCH_FOOTPRINT_CIRCLE_RADIUS 15
#define TOUCH_INFO_STRING_SIZE                70
  uint16_t x1 = 0;
  uint16_t y1 = 0;
  uint16_t x2 = 0;
  uint16_t y2 = 0;
  uint32_t drawTouch1 = 0; /* activate/deactivate draw of footprint of touch 1 */
  uint32_t drawTouch2 = 0; /* activate/deactivate draw of footprint of touch 2 */
  uint32_t colors[24] = {UTIL_LCD_COLOR_BLUE, UTIL_LCD_COLOR_GREEN, UTIL_LCD_COLOR_RED, UTIL_LCD_COLOR_CYAN, UTIL_LCD_COLOR_MAGENTA, UTIL_LCD_COLOR_YELLOW,
                         UTIL_LCD_COLOR_LIGHTBLUE, UTIL_LCD_COLOR_LIGHTGREEN, UTIL_LCD_COLOR_LIGHTRED, UTIL_LCD_COLOR_LIGHTCYAN, UTIL_LCD_COLOR_LIGHTMAGENTA,
                         UTIL_LCD_COLOR_LIGHTYELLOW, UTIL_LCD_COLOR_DARKBLUE, UTIL_LCD_COLOR_DARKGREEN, UTIL_LCD_COLOR_DARKRED, UTIL_LCD_COLOR_DARKCYAN,
                         UTIL_LCD_COLOR_DARKMAGENTA, UTIL_LCD_COLOR_DARKYELLOW, UTIL_LCD_COLOR_LIGHTGRAY, UTIL_LCD_COLOR_GRAY, UTIL_LCD_COLOR_DARKGRAY,
                         UTIL_LCD_COLOR_BLACK, UTIL_LCD_COLOR_BROWN, UTIL_LCD_COLOR_ORANGE };
  uint32_t ts_status = BSP_ERROR_NONE;
  uint8_t lcd_string[TOUCH_INFO_STRING_SIZE] = "";
  uint32_t x_size, y_size;

  BSP_LCD_GetXSize(0, &x_size);
  BSP_LCD_GetYSize(0, &y_size);

  /* Check in polling mode in touch screen the touch status and coordinates */
  /* of touches if touch occurred                                           */
  ts_status = BSP_TS_Get_MultiTouchState(0, &TS_MTState);
  if(TS_MTState.TouchDetected)
  {
    /* One or dual touch have been detected  */
    /* Erase previous information on touchscreen play pad area */
    UTIL_LCD_FillRect(0, 80, x_size, y_size - 160, UTIL_LCD_COLOR_WHITE);

    /* Re-Draw touch screen play area on LCD */
    UTIL_LCD_DrawRect(10, 90, x_size - 20, y_size - 180, UTIL_LCD_COLOR_BLUE);
    UTIL_LCD_DrawRect(11, 91, x_size - 22, y_size - 182, UTIL_LCD_COLOR_BLUE);

    /* Erase previous information on bottom text bar */
    UTIL_LCD_FillRect(0, y_size - 80, x_size, 80, UTIL_LCD_COLOR_BLUE);

    /* Deactivate drawing footprint of touch 1 and touch 2 until validated against boundaries of touch pad values */
    drawTouch1 = drawTouch2 = 0;

    /* Get X and Y position of the first touch post calibrated */
    x1 = TS_MTState.TouchX[0];
    y1 = TS_MTState.TouchY[0];

    if((y1 > (90 + TS_MULTITOUCH_FOOTPRINT_CIRCLE_RADIUS)) &&
       (y1 < (y_size - 90 - TS_MULTITOUCH_FOOTPRINT_CIRCLE_RADIUS)))
    {
      drawTouch1 = 1;
    }

    /* If valid touch 1 position : inside the reserved area for the use case : draw the touch */
    if(drawTouch1 == 1)
    {
      /* Draw circle of first touch : turn on colors[] table */
      UTIL_LCD_FillCircle(x1, y1, TS_MULTITOUCH_FOOTPRINT_CIRCLE_RADIUS, colors[(touchscreen_color_idx++ % 24)]);

      UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_WHITE);
      UTIL_LCD_SetFont(&Font16);
      UTIL_LCD_DisplayStringAt(0, y_size - 70, (uint8_t *)"TOUCH INFO : ", CENTER_MODE);

      UTIL_LCD_SetFont(&Font12);
      sprintf((char*)lcd_string, "x1 = %u, y1 = %u",  x1, y1);
      UTIL_LCD_DisplayStringAt(0, y_size - 45, lcd_string, CENTER_MODE);
    } /* of if(drawTouch1 == 1) */

    if(TS_MTState.TouchDetected > 1)
    {
      /* Get X and Y position of the second touch post calibrated */
      x2 = TS_MTState.TouchX[1];
      y2 = TS_MTState.TouchY[1];

      if((y2 > (90 + TS_MULTITOUCH_FOOTPRINT_CIRCLE_RADIUS)) &&
         (y2 < (y_size - 90 - TS_MULTITOUCH_FOOTPRINT_CIRCLE_RADIUS)))
      {
        drawTouch2 = 1;
      }

      /* If valid touch 2 position : inside the reserved area for the use case : draw the touch */
      if(drawTouch2 == 1)
      {
        sprintf((char*)lcd_string, "x2 = %u, y2 = %u",  x2, y2);
        UTIL_LCD_DisplayStringAt(0, y_size - 35, lcd_string, CENTER_MODE);

        /* Draw circle of second touch : turn on color[] table */
        UTIL_LCD_FillCircle(x2, y2, TS_MULTITOUCH_FOOTPRINT_CIRCLE_RADIUS, colors[(touchscreen_color_idx++ % 24)]);
      } /* of if(drawTouch2 == 1) */
    } /* of if(TS_MTState.TouchDetected > 1) */
  } /* of if(TS_MTState.TouchDetected) */
  return(ts_status);
}
#endif /* USE_TS_MULTI_TOUCH == 1 */

/**
  * @brief  Display TS Demo Hint for all touchscreen demos depending on passed
  *         demoIndex in parameter.
  * @param  demoIndex : parameter of type @ref TouchScreenDemoTypeDef
  * @retval None
  */
static void Touchscreen_SetHint_Demo(TouchScreenDemoTypeDef demoIndex)
{
  uint32_t x_size, y_size;

  BSP_LCD_GetXSize(0, &x_size);
  BSP_LCD_GetYSize(0, &y_size);

  BSP_LCD_SetLayerVisible(0,0, DISABLE);

  if(demoIndex <= TOUCHSCREEN_DEMO_MAX)
  {
    /* Clear the LCD */
    UTIL_LCD_Clear(UTIL_LCD_COLOR_WHITE);

    /* Set Touchscreen Demo1 description */
    UTIL_LCD_FillRect(0, 0, x_size, 80, UTIL_LCD_COLOR_BLUE);
    UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_WHITE);
    UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_BLUE);
    UTIL_LCD_SetFont(&Font24);

    if(demoIndex == TOUCHSCREEN_DEMO_1)
    {
      UTIL_LCD_DisplayStringAt(0, 0, (uint8_t *)"Touchscreen basic polling", CENTER_MODE);
      UTIL_LCD_SetFont(&Font16);
      UTIL_LCD_DisplayStringAt(0, 45, (uint8_t *)"Please use the Touchscreen to activate the colored circle", CENTER_MODE);
      UTIL_LCD_DisplayStringAt(0, 60, (uint8_t *)"inside the rectangle, then press USER button", CENTER_MODE);
    }
#if (USE_TS_MULTI_TOUCH == 1)
    else if (demoIndex == TOUCHSCREEN_DEMO_2)
    {
      UTIL_LCD_DisplayStringAt(0, 0, (uint8_t *)"Touchscreen dual touch polling", CENTER_MODE);
      UTIL_LCD_SetFont(&Font16);
      UTIL_LCD_DisplayStringAt(0, 45, (uint8_t *)"Please press the Touchscreen to activate", CENTER_MODE);
      UTIL_LCD_DisplayStringAt(0, 60, (uint8_t *)"single and dual touch, then press USER button", CENTER_MODE);

    }
    else /* demoIndex == TOUCHSCREEN_DEMO_3 */
    {
      UTIL_LCD_DisplayStringAt(0, 0, (uint8_t *)"Touchscreen dual touch interrupt", CENTER_MODE);
      UTIL_LCD_SetFont(&Font16);
      UTIL_LCD_DisplayStringAt(0, 45, (uint8_t *)"Please press the Touchscreen to activate", CENTER_MODE);
      UTIL_LCD_DisplayStringAt(0, 60, (uint8_t *)"single and dual touch, then press USER button", CENTER_MODE);
    }
#endif /* USE_TS_MULTI_TOUCH == 1 */

    UTIL_LCD_DrawRect(10, 90, x_size - 20, y_size - 100, UTIL_LCD_COLOR_BLUE);
    UTIL_LCD_DrawRect(11, 91, x_size - 22, y_size - 102, UTIL_LCD_COLOR_BLUE);

  } /* of if(demoIndex <= TOUCHSCREEN_DEMO_MAX) */

  BSP_LCD_SetLayerVisible(0,0, ENABLE);
}

/**
  * @brief  Draw Touchscreen Background
  * @param  state : touch zone state
  * @retval None
  */
void Touchscreen_DrawBackground_Circles(uint8_t state)
{
  uint16_t x, y;
  switch (state)
  {
    case 0:
      UTIL_LCD_FillCircle(CIRCLE_XPOS(1), CIRCLE_YPOS(1), CIRCLE_RADIUS, UTIL_LCD_COLOR_BLUE);

      UTIL_LCD_FillCircle(CIRCLE_XPOS(2), CIRCLE_YPOS(2), CIRCLE_RADIUS, UTIL_LCD_COLOR_RED);

      UTIL_LCD_FillCircle(CIRCLE_XPOS(3), CIRCLE_YPOS(3), CIRCLE_RADIUS, UTIL_LCD_COLOR_YELLOW);


      UTIL_LCD_FillCircle(CIRCLE_XPOS(4), CIRCLE_YPOS(3), CIRCLE_RADIUS, UTIL_LCD_COLOR_GREEN);

      UTIL_LCD_FillCircle(CIRCLE_XPOS(1), CIRCLE_YPOS(1), CIRCLE_RADIUS - 2, UTIL_LCD_COLOR_WHITE);
      UTIL_LCD_FillCircle(CIRCLE_XPOS(2), CIRCLE_YPOS(2), CIRCLE_RADIUS - 2, UTIL_LCD_COLOR_WHITE);
      UTIL_LCD_FillCircle(CIRCLE_XPOS(3), CIRCLE_YPOS(3), CIRCLE_RADIUS - 2, UTIL_LCD_COLOR_WHITE);
      UTIL_LCD_FillCircle(CIRCLE_XPOS(4), CIRCLE_YPOS(3), CIRCLE_RADIUS - 2, UTIL_LCD_COLOR_WHITE);
      break;

    case 1:
      UTIL_LCD_FillCircle(CIRCLE_XPOS(1), CIRCLE_YPOS(1), CIRCLE_RADIUS, UTIL_LCD_COLOR_BLUE);
      UTIL_LCD_FillCircle(CIRCLE_XPOS(1), CIRCLE_YPOS(1), CIRCLE_RADIUS - 2, UTIL_LCD_COLOR_WHITE);
      break;

    case 2:
      UTIL_LCD_FillCircle(CIRCLE_XPOS(2), CIRCLE_YPOS(2), CIRCLE_RADIUS, UTIL_LCD_COLOR_RED);
      UTIL_LCD_FillCircle(CIRCLE_XPOS(2), CIRCLE_YPOS(2), CIRCLE_RADIUS - 2, UTIL_LCD_COLOR_WHITE);
      break;

    case 4:
      UTIL_LCD_FillCircle(CIRCLE_XPOS(3), CIRCLE_YPOS(3), CIRCLE_RADIUS, UTIL_LCD_COLOR_YELLOW);
      UTIL_LCD_FillCircle(CIRCLE_XPOS(3), CIRCLE_YPOS(3), CIRCLE_RADIUS - 2, UTIL_LCD_COLOR_WHITE);
      break;

    case 8:
      UTIL_LCD_FillCircle(CIRCLE_XPOS(4), CIRCLE_YPOS(4), CIRCLE_RADIUS, UTIL_LCD_COLOR_GREEN);
      UTIL_LCD_FillCircle(CIRCLE_XPOS(4), CIRCLE_YPOS(4), CIRCLE_RADIUS - 2, UTIL_LCD_COLOR_WHITE);
      break;

    case 16:
      UTIL_LCD_FillCircle(CIRCLE_XPOS(1), CIRCLE_YPOS(1), CIRCLE_RADIUS, UTIL_LCD_COLOR_BLUE);
      UTIL_LCD_FillCircle(CIRCLE_XPOS(2), CIRCLE_YPOS(2), CIRCLE_RADIUS, UTIL_LCD_COLOR_BLUE);
      UTIL_LCD_FillCircle(CIRCLE_XPOS(3), CIRCLE_YPOS(3), CIRCLE_RADIUS, UTIL_LCD_COLOR_BLUE);
      UTIL_LCD_FillCircle(CIRCLE_XPOS(4), CIRCLE_YPOS(3), CIRCLE_RADIUS, UTIL_LCD_COLOR_BLUE);

      UTIL_LCD_FillCircle(CIRCLE_XPOS(1), CIRCLE_YPOS(1), CIRCLE_RADIUS - 2, UTIL_LCD_COLOR_WHITE);
      UTIL_LCD_FillCircle(CIRCLE_XPOS(2), CIRCLE_YPOS(2), CIRCLE_RADIUS - 2, UTIL_LCD_COLOR_WHITE);
      UTIL_LCD_FillCircle(CIRCLE_XPOS(3), CIRCLE_YPOS(3), CIRCLE_RADIUS - 2, UTIL_LCD_COLOR_WHITE);
      UTIL_LCD_FillCircle(CIRCLE_XPOS(4), CIRCLE_YPOS(3), CIRCLE_RADIUS - 2, UTIL_LCD_COLOR_WHITE);

      UTIL_LCD_DrawHLine(CIRCLE_XPOS(1)-LINE_LENGHT, CIRCLE_YPOS(1), 2*LINE_LENGHT, UTIL_LCD_COLOR_BLUE);
      UTIL_LCD_DrawHLine(CIRCLE_XPOS(2)-LINE_LENGHT, CIRCLE_YPOS(2), 2*LINE_LENGHT, UTIL_LCD_COLOR_BLUE);
      UTIL_LCD_DrawVLine(CIRCLE_XPOS(2), CIRCLE_YPOS(2)-LINE_LENGHT, 2*LINE_LENGHT, UTIL_LCD_COLOR_BLUE);
      UTIL_LCD_DrawHLine(CIRCLE_XPOS(3)-LINE_LENGHT, CIRCLE_YPOS(3), 2*LINE_LENGHT, UTIL_LCD_COLOR_BLUE);
      UTIL_LCD_DrawHLine(CIRCLE_XPOS(4)-LINE_LENGHT, CIRCLE_YPOS(4), 2*LINE_LENGHT, UTIL_LCD_COLOR_BLUE);
      UTIL_LCD_DrawVLine(CIRCLE_XPOS(4), CIRCLE_YPOS(4)-LINE_LENGHT, 2*LINE_LENGHT, UTIL_LCD_COLOR_BLUE);

      UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_BLUE);
      UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_WHITE);
      UTIL_LCD_SetFont(&Font24);
      x = CIRCLE_XPOS(1);
      y = CIRCLE_YPOS(1) - CIRCLE_RADIUS - UTIL_LCD_GetFont()->Height;
      UTIL_LCD_DisplayStringAt(x, y, (uint8_t *)"Volume", CENTER_MODE);
      x = CIRCLE_XPOS(4);
      y = CIRCLE_YPOS(4) - CIRCLE_RADIUS - UTIL_LCD_GetFont()->Height;
      UTIL_LCD_DisplayStringAt(x, y, (uint8_t *)"Frequency", CENTER_MODE);

      break;

    case 32:
      UTIL_LCD_FillCircle(CIRCLE_XPOS(1), CIRCLE_YPOS(1), CIRCLE_RADIUS, UTIL_LCD_COLOR_BLACK);
      UTIL_LCD_FillCircle(CIRCLE_XPOS(2), CIRCLE_YPOS(2), CIRCLE_RADIUS, UTIL_LCD_COLOR_BLACK);

      UTIL_LCD_FillCircle(CIRCLE_XPOS(1), CIRCLE_YPOS(1), CIRCLE_RADIUS - 2, UTIL_LCD_COLOR_WHITE);
      UTIL_LCD_FillCircle(CIRCLE_XPOS(2), CIRCLE_YPOS(2), CIRCLE_RADIUS - 2, UTIL_LCD_COLOR_WHITE);


      UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_BLACK);
      UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_WHITE);
      UTIL_LCD_SetFont(&Font20);
      x = CIRCLE_XPOS(1) - 10;
      y = CIRCLE_YPOS(1) - (UTIL_LCD_GetFont()->Height)/2;
      UTIL_LCD_DisplayStringAt(x, y, (uint8_t *)"Up", LEFT_MODE);
      x = CIRCLE_XPOS(2) - 10;
      y = CIRCLE_YPOS(3)  - (UTIL_LCD_GetFont()->Height)/2;
      UTIL_LCD_DisplayStringAt(x, y, (uint8_t *)"Dw", LEFT_MODE);
      UTIL_LCD_SetFont(&Font12);

      break;

    case 64:
      UTIL_LCD_FillCircle(CIRCLE_XPOS(2), CIRCLE_YPOS(2), CIRCLE_RADIUS, UTIL_LCD_COLOR_BLUE);
      UTIL_LCD_FillCircle(CIRCLE_XPOS(3), CIRCLE_YPOS(3), CIRCLE_RADIUS, UTIL_LCD_COLOR_BLUE);

      UTIL_LCD_FillCircle(CIRCLE_XPOS(2), CIRCLE_YPOS(2), CIRCLE_RADIUS - 2, UTIL_LCD_COLOR_WHITE);
      UTIL_LCD_FillCircle(CIRCLE_XPOS(3), CIRCLE_YPOS(3), CIRCLE_RADIUS - 2, UTIL_LCD_COLOR_WHITE);

      UTIL_LCD_DrawHLine(CIRCLE_XPOS(2)-LINE_LENGHT, CIRCLE_YPOS(2), 2*LINE_LENGHT, UTIL_LCD_COLOR_BLUE);
      UTIL_LCD_DrawHLine(CIRCLE_XPOS(3)-LINE_LENGHT, CIRCLE_YPOS(3), 2*LINE_LENGHT, UTIL_LCD_COLOR_BLUE);
      UTIL_LCD_DrawVLine(CIRCLE_XPOS(3), CIRCLE_YPOS(3)-LINE_LENGHT, 2*LINE_LENGHT, UTIL_LCD_COLOR_BLUE);

      UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_BLUE);
      UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_WHITE);
      UTIL_LCD_SetFont(&Font24);
      x = CIRCLE_XPOS(2);
      y = CIRCLE_YPOS(1) - CIRCLE_RADIUS - UTIL_LCD_GetFont()->Height;
      UTIL_LCD_DisplayStringAt(x, y, (uint8_t *)"Frequency", LEFT_MODE);
      break;
  }
}

/**
  * @brief  TouchScreen get touch position
  * @param  None
  * @retval None
  */
uint8_t TouchScreen_GetTouchPosition(void)
{
  uint16_t x1, y1;
  uint8_t circleNr = 0;

  /* Check in polling mode in touch screen the touch status and coordinates */
  /* of touches if touch occurred                                           */
  BSP_TS_GetState(0, &TS_State);
  if(TS_State.TouchDetected)
  {
    /* One or dual touch have been detected          */
    /* Only take into account the first touch so far */

    /* Get X and Y position of the first */
    x1 = TS_State.TouchX;
    y1 = TS_State.TouchY;

    if ((y1 > (CIRCLE_YPOS(1) - CIRCLE_RADIUS)) &&
        (y1 < (CIRCLE_YPOS(1) + CIRCLE_RADIUS)))
    {
      if ((x1 > (CIRCLE_XPOS(1) - CIRCLE_RADIUS)) &&
          (x1 < (CIRCLE_XPOS(1) + CIRCLE_RADIUS)))
      {
        circleNr = 1;
      }
      if ((x1 > (CIRCLE_XPOS(2) - CIRCLE_RADIUS)) &&
          (x1 < (CIRCLE_XPOS(2) + CIRCLE_RADIUS)))
      {
        circleNr = 2;
      }

      if ((x1 > (CIRCLE_XPOS(3) - CIRCLE_RADIUS)) &&
          (x1 < (CIRCLE_XPOS(3) + CIRCLE_RADIUS)))
      {
        circleNr = 3;
      }

      if ((x1 > (CIRCLE_XPOS(4) - CIRCLE_RADIUS)) &&
          (x1 < (CIRCLE_XPOS(4) + CIRCLE_RADIUS)))
      {
        circleNr = 4;
      }
    }
    else
    {
      if (((y1 < 220) && (y1 > 140)) &&
          ((x1 < 160) && (x1 > 100)))
      {
        circleNr = 0xFE;   /* top part of the screen */
      }
      else
      {
        circleNr = 0xFF;
      }
    }
  } /* of if(TS_State.TouchDetected) */
  return circleNr;
}

/**
  * @}
  */

/**
  * @}
  */


使用特权

评论回复
5
一路向北lm|  楼主 | 2025-3-15 19:32 | 只看该作者
SD卡相关操作:
/**
  ******************************************************************************
  * @file    sd.c
  * @author  MCD Application Team
  * @brief   This example code shows how to use the BSP SD Driver
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 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"

/** @addtogroup STM32N6xx_HAL_Examples
  * @{
  */

/** @addtogroup BSP
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define SD_START_ADDRESS       ((uint32_t)0x00000400U)     /* SD Address to write/read data */
#define NB_BLOCK_BUFFER        (BUFFER_SIZE*4) / BLOCKSIZE /* Number of Block (512b) by Buffer */
#define BUFFER_SIZE            ((uint32_t)1024)            /* 16Ko */

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint32_t aTxBuffer[BUFFER_SIZE];
uint32_t aRxBuffer[BUFFER_SIZE];
__IO uint32_t SDWriteStatus = 0, SDReadStatus = 0, SDDetectStatus = 0;

/* Private function prototypes -----------------------------------------------*/
static void SD_SetHint(void);
static void Fill_Buffer(uint32_t *pBuffer, uint32_t uwBufferLenght, uint32_t uwOffset);
static uint8_t Buffercmp(uint32_t* pBuffer1, uint32_t* pBuffer2, uint32_t BufferLength);
/* Private functions ---------------------------------------------------------*/

/**
  * @brief  SD Demo
  * @param  None
  * @retval None
  */
void SD_Demo (void)
{
  int32_t SD_state;
  uint32_t prev_status = 2;  /* Undefined state */

  SD_SetHint();

  SD_state = BSP_SD_Init(0);
  BSP_SD_DetectITConfig(0);

  UTIL_LCD_SetFont(&Font20);

  if(SD_state != BSP_ERROR_NONE)
  {
    UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_RED);
    if (SDDetectStatus == SD_NOT_PRESENT)
    {
      UTIL_LCD_DisplayStringAt(20, 100, (uint8_t *)"SD CARD NOT DETECTED", LEFT_MODE);
      UTIL_LCD_DisplayStringAt(20, 115, (uint8_t *)"SD shall be inserted before running test", LEFT_MODE);
      UTIL_LCD_DisplayStringAt(20, 130, (uint8_t *)"SD Test Aborted", LEFT_MODE);
    }
    else
    {
      UTIL_LCD_DisplayStringAt(20, 100, (uint8_t *)"SD INITIALIZATION : FAIL", LEFT_MODE);
      UTIL_LCD_DisplayStringAt(20, 115, (uint8_t *)"SD Test Aborted", LEFT_MODE);
    }
  }
  else
  {
    UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_GREEN);
    UTIL_LCD_DisplayStringAt(20, 100, (uint8_t *)"SD Initialization : OK", LEFT_MODE);
    UTIL_LCD_DisplayStringAt(20, 300, (uint8_t *)"     SD Connected", RIGHT_MODE);
    SDDetectStatus = SD_PRESENT;
    prev_status = SD_PRESENT;

    SD_state = BSP_SD_Erase(0,SD_START_ADDRESS, (SD_START_ADDRESS+BUFFER_SIZE));
    while(BSP_SD_GetCardState(0) != SD_TRANSFER_OK)
    {
    }

    if(SD_state != BSP_ERROR_NONE)
    {
      UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_RED);
      UTIL_LCD_DisplayStringAt(20, 115, (uint8_t *)"SD ERASE : FAILED", LEFT_MODE);
      UTIL_LCD_DisplayStringAt(20, 130, (uint8_t *)"SD Test Aborted", LEFT_MODE);
    }
    else
    {
      UTIL_LCD_DisplayStringAt(20, 115, (uint8_t *)"SD ERASE : OK", LEFT_MODE);

      /* Fill the buffer to write */
      Fill_Buffer(aTxBuffer, BUFFER_SIZE, 0x22FF);
      SD_state = BSP_SD_WriteBlocks(0,(uint32_t *)aTxBuffer, SD_START_ADDRESS, NB_BLOCK_BUFFER);

      if(SD_state != BSP_ERROR_NONE)
      {
        UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_RED);
        UTIL_LCD_DisplayStringAt(20, 130, (uint8_t *)"SD WRITE : FAILED", LEFT_MODE);
        UTIL_LCD_DisplayStringAt(20, 145, (uint8_t *)"SD Test Aborted", LEFT_MODE);
      }
      else
      {
        /* Wait until SD cards are ready to use for new operation */
        while(BSP_SD_GetCardState(0) != SD_TRANSFER_OK)
        {
        }
        UTIL_LCD_DisplayStringAt(20, 130, (uint8_t *)"SD WRITE : OK", LEFT_MODE);
        SD_state = BSP_SD_ReadBlocks(0,(uint32_t *)aRxBuffer, SD_START_ADDRESS, NB_BLOCK_BUFFER);

        /* Wait until SD cards are ready to use for new operation */
        while(BSP_SD_GetCardState(0) != SD_TRANSFER_OK)
        {
        }
        if(SD_state != BSP_ERROR_NONE)
        {
          UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_RED);
          UTIL_LCD_DisplayStringAt(20, 145, (uint8_t *)"SD READ : FAILED", LEFT_MODE);
          UTIL_LCD_DisplayStringAt(20, 160, (uint8_t *)"SD Test Aborted", LEFT_MODE);
        }
        else
        {
          UTIL_LCD_DisplayStringAt(20, 145, (uint8_t *)"SD READ : OK", LEFT_MODE);
          if(Buffercmp(aTxBuffer, aRxBuffer, BUFFER_SIZE) > 0)
          {
            UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_RED);
            UTIL_LCD_DisplayStringAt(20, 160, (uint8_t *)"SD COMPARE : FAILED", LEFT_MODE);
            UTIL_LCD_DisplayStringAt(20, 175, (uint8_t *)"SD Test Aborted", LEFT_MODE);
          }
          else
          {
            UTIL_LCD_DisplayStringAt(20, 160, (uint8_t *)"SD TEST : OK", LEFT_MODE);
          }
        }
      }
    }
  }
  UTIL_LCD_DisplayStringAt(20, 200, (uint8_t *)"SD Demo Done. Press the USR1 button to exit", CENTER_MODE);
  while (1)
  {

    /* Check if the SD card is plugged in the slot */
    if (SDDetectStatus != SD_PRESENT)
    {
      if (prev_status != SD_NOT_PRESENT)
      {
        prev_status = SD_NOT_PRESENT;
        UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_RED);
        UTIL_LCD_DisplayStringAt(20, 300, (uint8_t *)"SD NOT Connected", RIGHT_MODE);
      }
    }
    else if (prev_status != SD_PRESENT)
    {
      UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_GREEN);
      UTIL_LCD_DisplayStringAt(20, 300, (uint8_t *)"     SD Connected", RIGHT_MODE);
      prev_status = SD_PRESENT;
    }

    if(CheckForUserInput() > 0)
    {
      ClearUserInput();
      if(SDDetectStatus != SD_NOT_PRESENT)
      {
        BSP_SD_DeInit(0);
      }
      return;
    }
  }
}


/**
  * @brief Tx Transfer completed callback
  * @param  Instance SD Instance
  * @retval None
  */
void BSP_SD_WriteCpltCallback(uint32_t Instance)
{
  SDWriteStatus = 1;

}

/**
  * @brief Rx Transfer completed callback
  * @param  Instance SD Instance
  * @retval None
  */
void BSP_SD_ReadCpltCallback(uint32_t Instance)
{
  SDReadStatus = 1;
}

/**
  * @brief  BSP SD Callback.
  * @param  Instance SD Instance
  * @param  Status   Pin status
  * @retval None
  */
void BSP_SD_DetectCallback(uint32_t Instance, uint32_t Status)
{
  SDDetectStatus = Status;
}

/**
  * @brief  Display SD Demo Hint
  * @param  None
  * @retval None
  */
static void SD_SetHint(void)
{
  uint32_t x_size, y_size;

  BSP_LCD_GetXSize(0, &x_size);
  BSP_LCD_GetYSize(0, &y_size);
  /* Clear the LCD */
  UTIL_LCD_Clear(UTIL_LCD_COLOR_WHITE);

  /* Set LCD Demo description */
  UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_BLUE);
  UTIL_LCD_FillRect(0, 0, x_size, 80, UTIL_LCD_COLOR_BLUE);
  UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_WHITE);
  UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_BLUE);
  UTIL_LCD_SetFont(&Font24);
  UTIL_LCD_DisplayStringAt(0, 0, (uint8_t *)"SD", CENTER_MODE);
  UTIL_LCD_SetFont(&Font16);
  UTIL_LCD_DisplayStringAt(0, 45, (uint8_t *)"This example shows how to detect the presence of the card", CENTER_MODE);
  UTIL_LCD_DisplayStringAt(0, 60, (uint8_t *)"and how to write and read data on the microSD", CENTER_MODE);

  /* Set the LCD Text Color */
  UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_BLUE);
  UTIL_LCD_DrawRect(10, 90, x_size - 20, y_size - 100, UTIL_LCD_COLOR_BLUE);
  UTIL_LCD_DrawRect(11, 91, x_size - 22, y_size - 102, UTIL_LCD_COLOR_BLUE);

  UTIL_LCD_SetTextColor(UTIL_LCD_COLOR_BLACK);
  UTIL_LCD_SetBackColor(UTIL_LCD_COLOR_WHITE);
}

/**
  * @brief  Fills buffer with user predefined data.
  * @param  pBuffer: pointer on the buffer to fill
  * @param  uwBufferLenght: size of the buffer to fill
  * @param  uwOffset: first value to fill on the buffer
  * @retval None
  */
static void Fill_Buffer(uint32_t *pBuffer, uint32_t uwBufferLenght, uint32_t uwOffset)
{
  uint32_t tmpIndex = 0;

  /* Put in global buffer different values */
  for (tmpIndex = 0; tmpIndex < uwBufferLenght; tmpIndex++ )
  {
    pBuffer[tmpIndex] = tmpIndex + uwOffset;
  }
}

/**
  * @brief  Compares two buffers.
  * @param  pBuffer1, pBuffer2: buffers to be compared.
  * @param  BufferLength: buffer's length
  * @retval 1: pBuffer identical to pBuffer1
  *         0: pBuffer differs from pBuffer1
  */
static uint8_t Buffercmp(uint32_t* pBuffer1, uint32_t* pBuffer2, uint32_t BufferLength)
{
  while (BufferLength--)
  {
    if (*pBuffer1 != *pBuffer2)
    {
      return 1;
    }

    pBuffer1++;
    pBuffer2++;
  }

  return 0;
}
/**
  * @}
  */

/**
  * @}
  */



使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

293

主题

3836

帖子

80

粉丝