/**
  * @brief  Performs the TS calibration
  * @param  None
  * @retval None
  */
void Touchscreen_Calibration (void)
{ 
  uint8_t status = 0;
  uint8_t i = 0;

  TouchscreenCalibration_SetHint();
  
  status = BSP_TS_Init(BSP_LCD_GetXSize(), BSP_LCD_GetYSize());
  
  if (status != TS_OK)
  {
    BSP_LCD_SetBackColor(LCD_COLOR_WHITE); 
    BSP_LCD_SetTextColor(LCD_COLOR_RED);
    BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize()- 95, (uint8_t *)"ERROR", CENTER_MODE);
    BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize()- 80, (uint8_t *)"Touchscreen cannot be initialized", CENTER_MODE);
  }
  
  while (1)
  {
    if (status == TS_OK)
    {
      aLogX[0] = 15;
      aLogY[0] = 15;
      aLogX[1] = BSP_LCD_GetXSize() - 15;
      aLogY[1] = BSP_LCD_GetYSize() - 15;
      
      for (i = 0; i < 2; i++) 
      {
        GetPhysValues(aLogX[i], aLogY[i], &aPhysX[i], &aPhysY[i]);
      }
      A1 = (TUNE_FACTOR_X * ( aLogX[1] - aLogX[0]))/ ( aPhysX[1] - aPhysX[0]); 
      B1 = (TUNE_FACTOR_X * aLogX[0]) - A1 * aPhysX[0]; 
      
      A2 = (TUNE_FACTOR_Y * ( aLogY[1] - aLogY[0]))/ ( aPhysY[1] - aPhysY[0]); 
      B2 = (TUNE_FACTOR_Y * aLogY[0]) - A2 * aPhysY[0]; 
      if (B2 > 0)
        B2 = 0;
      
      Calibration_Done = 1;
      return;
    }
   
    HAL_Delay(5);
  }
}
/**
  * @brief  Performs the TS calibration
  * @param  None
  * @retval Status (TS_OK = 0/ TS_ERROR = 1 / TS_TIMEOUT = 1 / TS_DEVICE_NOT_FOUND = 3)
  */
uint8_t Touchscreen_Calibration(void)
{
  uint8_t ts_status = TS_OK;
  uint8_t i;
  uint16_t ts_SizeX;
  uint16_t ts_SizeY;

  ts_SizeX = BSP_LCD_GetXSize();
  ts_SizeY = BSP_LCD_GetYSize();

  TouchscreenCalibration_SetHint();

  /* Start touchscreen internal calibration and configuration + start */
  ts_status = BSP_TS_Init(ts_SizeX, ts_SizeY);
  if (ts_status != TS_OK)
  {
    BSP_LCD_SetBackColor(LCD_COLOR_WHITE);
    BSP_LCD_SetTextColor(LCD_COLOR_RED);
    BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 95, (uint8_t *)"ERROR", CENTER_MODE);
    BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 80, (uint8_t *)"Touchscreen cannot be calibrated", CENTER_MODE);
    if(ts_status == TS_ERROR)
    {
      BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 65, (uint8_t *)"Touchscreen undefined error", CENTER_MODE);
    }
    else if(ts_status == TS_TIMEOUT)
    {
      BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 65, (uint8_t *)"Touchscreen Timeout", CENTER_MODE);
    }
    else
    {
      /* TS_DEVICE_NOT_FOUND */
      BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 65, (uint8_t *)"Touchscreen Not Found", CENTER_MODE);
    }
  }
  else
  {
    /* status == TS_OK */
    BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 65, (uint8_t *)"FT6x06 internal calibration passed", CENTER_MODE);

    /* Get touch points for SW calibration processing */
    aLogX[0] = 40;
    aLogY[0] = 40;
    aLogX[1] = BSP_LCD_GetXSize() - 40;
    aLogY[1] = BSP_LCD_GetYSize() - 40;

    for (i = 0; i < 2; i++)
    {
      TouchScreen_Calibration_GetPhysValues(aLogX[i], aLogY[i], &aPhysX[i], &aPhysY[i]);
    }

    /* Compute calibration coefficients */
    A1 = (1000 * ( aLogX[1] - aLogX[0])) / ( aPhysX[1] - aPhysX[0]);
    B1 = (1000 * aLogX[0]) - A1 * aPhysX[0];

    A2 = (1000 * ( aLogY[1] - aLogY[0])) / ( aPhysY[1] - aPhysY[0]);
    B2 = (1000 * aLogY[0]) - A2 * aPhysY[0];

    ts_calibration_done = 1;
  }

  return (ts_status);
}