Exemplo n.º 1
0
tsTouchError_t tsRead(tsTouchData_t* data) {
  uint32_t x1, y1;

  // Assign pressure levels regardless of touch state
  tsReadZ(&data->z1, &data->z2);

  data->xraw = 0;
  data->yraw = 0;
  data->xlcd = 0;
  data->ylcd = 0;

  // Abort if the screen is not being touched (0 levels reported)
  if (data->z1 < _tsThreshhold) {
    data->valid = false;
    return TS_ERROR_NONE;
  }

  nopDelay(CFG_TFTLCD_TS_DELAYBETWEENSAMPLES);

  // Get two X/Y readings and compare results
  x1 = tsReadX();
  y1 = tsReadY();

  // X/Y seems to be valid and reading has been confirmed twice
  data->xraw = x1;
  data->yraw = y1;

  // Convert x/y values to pixel location with matrix multiply
  tsPoint_t location, touch;
  touch.x = x1;
  touch.y = y1;

  getDisplayPoint(&location, &touch, &_tsMatrix);
  data->xlcd = location.x;
  data->ylcd = location.y;
  data->valid = true;

  return TS_ERROR_NONE;
}
Exemplo n.º 2
0
void tsCalibrate(void)
{
  lcdOrientation_t orientation;
  uint16_t right2, top2, left2, bottom2;
  bool passed = false;

  // Determine screen orientation before starting calibration
  orientation = lcdGetOrientation();

  /* -------------- Welcome Screen --------------- */
  tsRenderCalibrationScreen(lcdGetWidth() / 2, lcdGetHeight() / 2, 5);

  // Delay to avoid multiple touch events
  systickDelay(250);

  /* -------------- CALIBRATE TOP-LEFT --------------- */
  passed = false;
  while (!passed)
  {
    // Read X/Y depending on screen orientation
    tsRenderCalibrationScreen(3, 3, 5);
    _calibration.offsetLeft = orientation == LCD_ORIENTATION_LANDSCAPE ? tsReadY() : tsReadX();
    _calibration.offsetTop = orientation == LCD_ORIENTATION_LANDSCAPE ? tsReadX() : tsReadY();
  
    // Make sure values are in range
    if (_calibration.offsetLeft < TS_CALIBRATION_OUTOFRANGE && _calibration.offsetTop < TS_CALIBRATION_OUTOFRANGE)
      passed = true;
  }

  // Delay to avoid multiple touch events
  systickDelay(250);

  /* -------------- CALIBRATE BOTTOM-RIGHT  --------------- */
  passed = false;
  while (!passed)
  {
    tsRenderCalibrationScreen(lcdGetWidth() - 4, lcdGetHeight() - 4, 5);
  
    // Read X/Y depending on screen orientation
    _calibration.offsetRight = orientation == LCD_ORIENTATION_LANDSCAPE ? TS_ADC_LIMIT - tsReadY() : TS_ADC_LIMIT - tsReadX();
    _calibration.offsetBottom = orientation == LCD_ORIENTATION_LANDSCAPE ? TS_ADC_LIMIT - tsReadX() : TS_ADC_LIMIT - tsReadY();
  
    // Redo test if value is out of range
    if (_calibration.offsetRight < TS_CALIBRATION_OUTOFRANGE && _calibration.offsetBottom < TS_CALIBRATION_OUTOFRANGE)
      passed = true;
  }

  // Delay to avoid multiple touch events
  systickDelay(250);

  /* -------------- CALIBRATE TOP-RIGHT  --------------- */
  passed = false;
  while (!passed)
  {
    tsRenderCalibrationScreen(lcdGetWidth() - 4, 3, 5);
  
    if (orientation == LCD_ORIENTATION_LANDSCAPE)
    {
      right2 = TS_ADC_LIMIT - tsReadY();
      top2 = tsReadX();
    }
    else
    {
      right2 = tsReadX();
      top2 = TS_ADC_LIMIT - tsReadY();
    }
  
    // Redo test if value is out of range
    if (right2 < TS_CALIBRATION_OUTOFRANGE && top2 < TS_CALIBRATION_OUTOFRANGE)
      passed = true;  
  }

  // Average readings
  _calibration.offsetRight = (_calibration.offsetRight + right2) / 2;
  _calibration.offsetTop = (_calibration.offsetTop + top2) / 2;

  // Delay to avoid multiple touch events
  systickDelay(250);

  /* -------------- CALIBRATE BOTTOM-LEFT --------------- */
  passed = false;
  while (!passed)
  {
    tsRenderCalibrationScreen(3, lcdGetHeight() - 4, 5);
  
    if (orientation == LCD_ORIENTATION_LANDSCAPE)
    {
      left2 = tsReadY();
      bottom2 = TS_ADC_LIMIT - tsReadX();
    }
    else
    {
      left2 = TS_ADC_LIMIT - tsReadX();
      bottom2 = tsReadY();
    }
  
    // Redo test if value is out of range
    if (left2 < TS_CALIBRATION_OUTOFRANGE && bottom2 < TS_CALIBRATION_OUTOFRANGE)
      passed = true;
  }

  // Average readings
  _calibration.offsetLeft = (_calibration.offsetLeft + left2) / 2;
  _calibration.offsetBottom = (_calibration.offsetBottom + bottom2) / 2;

  // Delay to avoid multiple touch events
  systickDelay(250);

  _calibration.divisorX = ((TS_ADC_LIMIT - (_calibration.offsetLeft + _calibration.offsetRight)) * 100) / lcdGetWidth();
  _calibration.divisorY = ((TS_ADC_LIMIT - (_calibration.offsetTop + _calibration.offsetBottom)) * 100) / lcdGetHeight();

  /* -------------- Persist Data --------------- */
  // Persist data to EEPROM
  eepromWriteU16(CFG_EEPROM_TOUCHSCREEN_OFFSET_LEFT, _calibration.offsetLeft);
  eepromWriteU16(CFG_EEPROM_TOUCHSCREEN_OFFSET_RIGHT, _calibration.offsetRight);
  eepromWriteU16(CFG_EEPROM_TOUCHSCREEN_OFFSET_TOP, _calibration.offsetTop);
  eepromWriteU16(CFG_EEPROM_TOUCHSCREEN_OFFSET_BOT, _calibration.offsetBottom);
  eepromWriteU16(CFG_EEPROM_TOUCHSCREEN_OFFSET_DIVX, _calibration.divisorX);
  eepromWriteU16(CFG_EEPROM_TOUCHSCREEN_OFFSET_DIVY, _calibration.divisorY);
  eepromWriteU8(CFG_EEPROM_TOUCHSCREEN_CALIBRATED, 1);

  // Clear the screen
  drawFill(COLOR_BLACK);
}
Exemplo n.º 3
0
tsTouchError_t tsWaitForEvent(tsTouchData_t* data, uint32_t timeoutMS)
{
  if (!_tsInitialised) tsInit();

  uint32_t z1, z2;
  uint32_t xRaw1, xRaw2, yRaw1, yRaw2;
  z1 = z2 = 0;

  // Handle timeout if delay > 0 milliseconds
  if (timeoutMS)
  {
    uint32_t startTick = systickGetTicks();
    // Systick rollover may occur while waiting for timeout
    if (startTick > 0xFFFFFFFF - timeoutMS)
    {
      // Wait for timeout or touch event
      while (z2 < CFG_TFTLCD_TS_THRESHOLD)
      {
        // Throw alert if timeout delay has been passed
        if ((systickGetTicks() < startTick) && (systickGetTicks() >= (timeoutMS - (0xFFFFFFFF - startTick))))
        {
          return TS_ERROR_TIMEOUT;
        }      
        tsReadZ(&z1, &z2);
      }
    }
    // No systick rollover will occur ... calculate timeout the simple way
    else
    {
      // Wait in infinite loop
      while (z2 < CFG_TFTLCD_TS_THRESHOLD)
      {
        // Throw timeout if delay has been passed
        if ((systickGetTicks() - startTick) > timeoutMS)
        {
          return TS_ERROR_TIMEOUT;
        }
        tsReadZ(&z1, &z2);
      }
    }
  }
  // No timeout requested ... wait forever
  else
  {
    while (z2 < CFG_TFTLCD_TS_THRESHOLD)
    {
      tsReadZ(&z1, &z2);
    }
  }

  // Get raw conversion results
  // Each value is read twice and compared to avoid erroneous readings
  xRaw1 = tsReadY();    // X and Y are reversed
  xRaw2 = tsReadY();    // X and Y are reversed
  yRaw1 = tsReadX();    // X and Y are reverse
  yRaw2 = tsReadX();    // X and Y are reverse

  // If both read attempts aren't identical, return mismatch error
  if ((xRaw1 != xRaw2) || (yRaw1 != yRaw2))
  {
    return TS_ERROR_XYMISMATCH;
  }

  // Normalise X
  data->x = ((xRaw1 - _calibration.offsetLeft > TS_ADC_LIMIT ? 0 : xRaw1 - _calibration.offsetLeft) * 100) / _calibration.divisorX;
  if (data->x > lcdGetWidth() - 1) data->x = lcdGetWidth() - 1;

  // Normalise Y
  data->y = ((yRaw1 - _calibration.offsetTop > TS_ADC_LIMIT ? 0 : yRaw1 - _calibration.offsetTop) * 100) / _calibration.divisorY;
  if (data->y > lcdGetHeight() - 1) data->y = lcdGetHeight() - 1;

  // Indicate correct reading
  return TS_ERROR_NONE;
}
Exemplo n.º 4
0
tsTouchError_t tsRead(tsTouchData_t* data, uint8_t calibrating)
{
  uint32_t x1, x2, y1, y2, z1, z2;

  // Assign pressure levels regardless of touch state
  tsReadZ(&z1, &z2);
  data->z1 = z1;
  data->z2 = z2;
  data->xraw = 0;
  data->yraw = 0;
  data->xlcd = 0;
  data->ylcd = 0;

  // Abort if the screen is not being touched (0 levels reported)
  if (z1 < _tsThreshhold)
  {
    data->valid = false;
    return TS_ERROR_NONE;
  }

  // Get two X/Y readings and compare results
  x1 = tsReadX();
  x2 = tsReadX();
  y1 = tsReadY();
  y2 = tsReadY();

  // Throw an error if both readings aren't identical
  if (x1 != x2 || y1 != y2)
  {
    data->valid = false;
    data->xraw = x1;
    data->yraw = y1;
    return TS_ERROR_XYMISMATCH;
  }

  // X/Y seems to be valid and reading has been confirmed twice
  data->xraw = x1;
  data->yraw = y1;

  // Convert x/y values to pixel location with matrix multiply
  tsPoint_t location, touch;
  touch.x = x1;
  touch.y = y1;
  // Only calculate the relative LCD value if this isn't for calibration
  if (!calibrating)
  {
    getDisplayPoint( &location, &touch, &_tsMatrix) ;
    data->xlcd = location.x;
    data->ylcd = location.y;
  }
  else
  {
    // Assign some false values, but only xraw and yraw are
    // used for calibration
    data->xlcd = 0;
    data->ylcd = 0;
  }
  data->valid = true;

  return TS_ERROR_NONE;
}