TEENSY 3.6 / ADAFRUIT 3.5" TFT touch controller issue

Status
Not open for further replies.

Rjp663

New member
Gents,

I'm having a problem getting the STMPE610 touch controller of the ADAFRUIT 3.5" TFT Feather wing to work with the Teensy 3.6. The TFT HX8357 display is working properly.

The sketch uploads with no error messages. With the program running the serial monitor reports the STMPE610 on-line, however a touch is never sensed and reported (x, y and z data). I've looked at all SPI signals, TFT CS, TFT DC and STMPE CS with my o'scope. All signals change state and voltage levels seem appropriate for 3v logic.

Any ideas would be appreciated.

Rick

Here are the particulars:
Arduino IDE 1.8.8 / Teensyduino 1.45
iMac running Mojave, 10.14.2

Code

PINOUT
TEENSY TFT COMMENT
GND GND GROUND
3.3V 3.3V 3.3VDC
11 MOSI MOSI SPI Interface
12 MISO MISO SPI Interface
13 SCK SCK SPI Interface
15 CS TFT Chip Select
14 DC TFT Data/ Command
16 RT STMPE610 Touch Screen controller
****************************************************/

Code:
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_HX8357.h>
#include <Adafruit_GFX.h>
#include <Adafruit_STMPE610.h>

#define TFT_DC   14 //TFT Data/Command
#define TFT_CS   15 //TFT chip select
#define STMPE_CS 16 //Touch screen chip select
#define TFT_RST -1  //TFT reset

Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC);
Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS);

// This is calibration data for the raw touch data to the screen coordinates
#define TS_MINX 3800
#define TS_MAXX 100
#define TS_MINY 100
#define TS_MAXY 3750

void setup() {
  Serial.begin(9600);
  Serial.println("STMPE610 Test");

  tft.begin();
  tft.fillScreen(HX8357_BLACK);
  tft.setTextColor(HX8357_YELLOW);
  tft.setTextSize(3);
  tft.setRotation(3);
  tft.setCursor(5, 5);
  tft.print("HX8357 Display Test");

  if (!ts.begin()) {
    Serial.println("STMPE610 not found!");
    while (1);
  }
  Serial.println("STMPE610 On-line. Touch the screen....");
}

void loop() {
  uint16_t x, y;
  uint8_t z;
  if (ts.touched()) {
    // read x & y & z;
    while (!ts.bufferEmpty()) {
      Serial.print(ts.bufferSize());
      ts.readData(&x, &y, &z);
      Serial.print("->(");
      Serial.print(x); Serial.print(", ");
      Serial.print(y); Serial.print(", ");
      Serial.print(z);
      Serial.println(")");
    }
    ts.writeRegister8(STMPE_INT_STA, 0xFF); // reset all ints
  }
  delay(10);
}

Pics of the Teensy/TFT wiring refer below

IMG_4048.jpg
IMG_1083.jpg
IMG_2147.jpg

The pinout for the ADAFRUIT TFT Feather wing is a bit tricky, the link refers https://www.adafruit.com/product/3651

Basically in this application only the MISO, MOSI, SCK, GND, 3v, RT, CS, DC, USB are utilized. The below pic refers.
TFT.jpg
 
Last edited by a moderator:
All,
After reading many posts I believe the issue is the teensy SPI timing is too fast for the touch processor.

Any input on how to modify the SPI library?

Rick
 
You will likely need to edit the Adafruit_STMPE610 library. In it, look for the call to 'SPISettings', and change the first argument from '1000000' to something slower. Typically it is best practice to copy the library to another folder in your libraries directory with a different name (renaming the .h and .cpp files in the directory to the new name), and change your code to use the new file instead of the standard include.
 
Fix for Adafruit_STMPE610 library

Hi,

I had exactly the same problem with the touch controller of this display.

It turned out that the Adafruit_STMPE610 library doesn't respect the required SPI timing for CS as given in the STMPE610 data sheet (5.2.1 SPI timing definition, page 14).
As a quick fix I changed the methods Adafruit_STMPE610::readRegister8() and Adafruit_STMPE610::writeRegister8() in Adafruit_STMPE610.cpp as follows to get the touch controller working with a Teensy 3.6:

Code:
uint8_t Adafruit_STMPE610::readRegister8(uint8_t reg) {
    uint8_t x;
    if (_CS == -1) {
        // use i2c
        _wire->beginTransmission(_i2caddr);
        _wire->write((byte) reg);
        _wire->endTransmission();
        _wire->requestFrom(_i2caddr, (byte) 1);
        x = _wire->read();

        // Serial.print("$"); Serial.print(reg, HEX);
        // Serial.print(": 0x"); Serial.println(x, HEX);
    } else {
        if (_CLK == -1) {
            _spi->beginTransaction(mySPISettings);
        }
        digitalWriteFast(_CS, LOW);
        delayMicroseconds(1); // CS_n falling to first capture clock: >= 1 us
        spiOut(0x80 | reg);
        spiOut(0x00);
        x = spiIn();
        delayMicroseconds(1); // Last clock edge to CS_n high: >= 1 us

        digitalWriteFast(_CS, HIGH);
        delayMicroseconds(1); // CS_n high to first clock edge: >= 300 ns
        if (_CLK == -1) {
            SPI.endTransaction();
        }
    }

    return x;
}

void Adafruit_STMPE610::writeRegister8(uint8_t reg, uint8_t val) {
    if (_CS == -1) {
        // use i2c
        _wire->beginTransmission(_i2caddr);
        _wire->write((byte) reg);
        _wire->write(val);
        _wire->endTransmission();
    } else {
        if (_CLK == -1) {
            _spi->beginTransaction(mySPISettings);
        }
        digitalWriteFast(_CS, LOW);
        delayMicroseconds(1); // CS_n falling to first capture clock: >= 1 us
        spiOut(reg);
        spiOut(val);
        delayMicroseconds(1); // Last clock edge to CS_n high: >= 1 us
        digitalWriteFast(_CS, HIGH);
        delayMicroseconds(1); // CS_n high to first clock edge: >= 300 ns
        if (_CLK == -1) {
            _spi->endTransaction();
        }
    }
}

I didn't change Adafruit_STMPE610::readRegister16() as this method is never used by the library.

Timo
 
Hi,
having the same problems, I just wanted to thank timo42 for the input:
The delays solved the problem!
"delayMicroseconds(1); // CS_n falling to first capture clock: >= 1 us"

:) Christof
 
Status
Not open for further replies.
Back
Top