RA8875 from Buydisplay

Status
Not open for further replies.
If i remember right I did try touch on the adafruit display using the RA8875 library and it did work.

Ok - just tried it using sumotoys library and it doesn't seem to work with the Adafruit board didn't try the buydisplay one

EDIT: Tried it with the ISR commented out it works sort of - even did the calibration which seemed to work and was close to what was already in the setting file
 
Last edited:
Dumb question time. If you buy the 5 v powered versions do you need a level shifter for the 4? I'm not sure if the logic is 3.3 v and just the main power is 5 v or both. It would be easier to just power the thing 3.3 than use a level shifter but I wouldn't want to use the Teensy to power it. Also would you pro's recommend I2C, 3 w SPI, or 4 wire SPI?
 
Dumb question time. If you buy the 5 v powered versions do you need a level shifter for the 4? I'm not sure if the logic is 3.3 v and just the main power is 5 v or both. It would be easier to just power the thing 3.3 than use a level shifter but I wouldn't want to use the Teensy to power it. Also would you pro's recommend I2C, 3 w SPI, or 4 wire SPI?

No. The logic level is set at 3.3v even though you are powering at 5v. Right now testing on T4 with5v to power.

Think all the libs are set up for 4-wire SPI. I ordered the display with 5v. There was a discussion about that like on page 3?
 
If i remember right I did try touch on the adafruit display using the RA8875 library and it did work.

Ok - just tried it using sumotoys library and it doesn't seem to work with the Adafruit board didn't try the buydisplay one

EDIT: Tried it with the ISR commented out it works sort of - even did the calibration which seemed to work and was close to what was already in the setting file

Assuming some one does not beat me to it, I did my testing on T4, with the ISR, maybe should try with 3.x to make sure it is not some T4 specific thing, like maybe how T4 works with attachInterrupt on FALLING...

Also I want to check to see what exactly is different between the Adafruit library one which is doing roughly the same thing, other than when things get set/cleared, how sampled and how it is scaled to the display, but other than that pretty much the same 8)
 
@KurtE

Just tried SPI on the T3.6 with the easypaint sketch. It draws the boxes but the touch doesn't work at all.
 
@mjs513 - I was noticing mostly not working either, using the Buydisplay 5" one that has resistive touch...

I was getting some results from the Adafruit library with touch on both displays.

So looking at differences between the two libraries.

a) Adafruit does not setup to do interrupts on touch, only polling.

b) Timing setups - The RA8875 sets up a different clock setup for teensy/due then it does for others. Adafruit also adjusts it depending on size of display.


Code:
void Adafruit_RA8875::touchEnable(boolean on) 
{
  uint8_t   adcClk = (uint8_t) [COLOR="#FF0000"]RA8875_TPCR0_ADCCLK_DIV4[/COLOR];

  if ( _size == RA8875_800x480 ) //match up touch size with LCD size
    adcClk = (uint8_t) [COLOR="#FF0000"]RA8875_TPCR0_ADCCLK_DIV16[/COLOR];

  if (on)
  {
    /* Enable Touch Panel (Reg 0x70) */
    writeReg(RA8875_TPCR0, RA8875_TPCR0_ENABLE        |
                           [COLOR="#FF0000"]RA8875_TPCR0_WAIT_4096CLK  [/COLOR]|
                           RA8875_TPCR0_WAKEENABLE   |
                           adcClk); // 10mhz max!
    /* Set Auto Mode      (Reg 0x71) */
    writeReg(RA8875_TPCR1, RA8875_TPCR1_AUTO    |
                           // RA8875_TPCR1_VREFEXT |
                           RA8875_TPCR1_DEBOUNCE);
    /* Enable TP INT */
    writeReg(RA8875_INTC1, readReg(RA8875_INTC1) | RA8875_INTC1_TP);
  }
  else
  {
    /* Disable TP INT */
    writeReg(RA8875_INTC1, readReg(RA8875_INTC1) & ~RA8875_INTC1_TP);
    /* Disable Touch Panel (Reg 0x70) */
    writeReg(RA8875_TPCR0, RA8875_TPCR0_DISABLE);
  }
}
Code:
void RA8875::touchBegin(void) 
{
	if (_intPin < 255){
/*		Touch Panel Control Register 0  TPCR0  [0x70]
		7: 0(disable, 1:(enable)
		6,5,4:TP Sample Time Adjusting (000...111)
		3:Touch Panel Wakeup Enable 0(disable),1(enable)
		2,1,0:ADC Clock Setting (000...111) set fixed to 010: (System CLK) / 4, 10Mhz Max! */
		#if defined(___TEENSYES) ||  defined(___DUESTUFF)//fast 32 bit processors
			_writeRegister(RA8875_TPCR0, TP_ENABLE | [COLOR="#FF0000"]TP_ADC_SAMPLE_16384_CLKS | TP_ADC_CLKDIV_32)[/COLOR];
		#else
			_writeRegister(RA8875_TPCR0, TP_ENABLE | TP_ADC_SAMPLE_4096_CLKS | TP_ADC_CLKDIV_16);
		#endif
		_writeRegister(RA8875_TPCR1, TP_MODE_AUTO | TP_DEBOUNCE_ON);
		setInternalInt(TOUCH);
		_INTC1_Reg |= (1 << 2);//set
		_writeRegister(RA8875_INTC1, _INTC1_Reg);
		_touchEnabled = true;
	} else {
		_touchEnabled = false;
	}
}

c) Adafruit clears the flag about touched when you read int coordinates in whereas RA8875 does it on the touched call (maybe)

d) Magic numbers and the like: That is
Adafruit does things with symbols:
Code:
/* Clear TP INT Status */
  writeReg(RA8875_INTC2, RA8875_INTC2_TP);


RA8875 does some with magic numbers:
Code:
 _checkInterrupt(2);//clear internal RA int to re-engage
...
bool RA8875::_checkInterrupt(uint8_t _bit,bool _clear) 
{
	if (_bit > 4) _bit = 4;
	uint8_t temp = _readRegister(RA8875_INTC2);
	if (bitRead(temp,_bit) == 1){
		if (_clear){
			temp |= (1 << _bit);//bitSet(temp,_bit);
			//if (bitRead(temp,0)) bitSet(temp,0);//Mmmmm...
			Serial.println("_checkInterrupt clear");
			_writeRegister(RA8875_INTC2, temp);//clear int
		}
		return true;
	}
	return false;
}
(includes some debug code to see if happens...)
 
@KurtE

Was playing around with that this morning believe it or not over coffee - since I am still half asleep.

I commented out the Teensy stuff in the RA8875 library so that I would only use:
Code:
_writeRegister(RA8875_TPCR0, TP_ENABLE | TP_ADC_SAMPLE_4096_CLKS | TP_ADC_CLKDIV_16);
even changed clkdiv to 4 to see what would happen. Didn't help much.
Adafruit clears the flag about touched when you read int coordinates in whereas RA8875 does it on the touched call (maybe)
This might help more when I printed out the touch points without mods it would vary dramatically so dots were all over the screen except where you touched.

I did play with the magic numbers though.

EDIT: The one note that peaked my interest was that there was a 10mhz max limit for touch:
Code:
2,1,0:ADC Clock Setting (000...111) set fixed to 010: (System CLK) / 4, 10Mhz Max! */

for T4 have to try "#define TP_ADC_CLKDIV_64"
 
@KurtE

I redid the calibration using Sumotoy's lib and getting really strange results for rotation 0:
Code:
#define TOUCSRCAL_XLOW  655
#define TOUCSRCAL_YLOW  697
#define TOUCSRCAL_XHIGH 80
#define TOUCSRCAL_YHIGH 83
While the numbers look reasonable high and low are reversed. If I setRotation(2)
Code:
#define TOUCSRCAL_XLOW  36
#define TOUCSRCAL_YLOW  66
#define TOUCSRCAL_XHIGH 636
#define TOUCSRCAL_YHIGH 565
Still get the same behavior though with their touch example.

Wondering if the problem is with the ADC and mapping of the values.

This is the Mbed version for the RA8875 touch - they seem to be doing a bunch of filtering on the ADC and recommend keeping it at 4096.
https://os.mbed.com/users/WiredHome/code/RA8875/file/224e03d5c31f/RA8875_Touch.cpp/

EDIT: Found this from Sumotoy:
One common mistake it's the releationship between INT pin and INT number, most arm can attach any int to any pin but AVR and some other CPU has a precise relation, for example using pin 2 in uno will result INT 0 but Teensy 3 can use any number.
Changing pin can break this relation so if it's your case, check RA8875UserSettings file for:
#if !defined(_AVOID_TOUCHSCREEN)
#define __RA8875ISRINT 0 //// [default 0, pin 2 on Arduino UNO]
#endif
Accordly your processor (and pin used) you should put the right value of __RA8875ISRINT
I'm not a CPU enciclopedia so I don't know exact this relation for every CPU, check your board documents.
 
@mjs513 - Yes I do believe that there are probably lots of issues in this code.

Both the ordering and when things are called, to configured.

Also the setRotation stuff looks wrong for which value is which for the mappings....

I was/am thinking of hacking up some of this, and try to print out some of the raw data, to get an idea of what the mappings are doing and which limit is valid for what...
 
@mjs513 - A couple of things so far...

I have hacked up the library a little, and added a function to allow me to currently turn off the calibration, and later should be good to allow you to
set one per display...

tft.setTouchCalibrationData(0,0,0,0);

Code:
/**************************************************************************/
/*!   A way to have different calibrations for different displays and
	  a way to force the system to act like uncalibrated, so you don't have
	  to edit header file, rebuild, edit header again ...
*/
/**************************************************************************/
void RA8875::setTouchCalibrationData(uint16_t minX, uint16_t maxX, uint16_t minY, uint16_t maxY) 
{
	_tsAdcMinX = minX; 
	_tsAdcMaxX = maxX;
	_tsAdcMinY = minY;
	_tsAdcMaxY = maxY;

	// Lets guess at setting is calibrated. 
	_calibrated = ((minX >= maxX) || (minY >= maxY)) ? false : true;
}

I have that one in place to clear out the values and you can also do by simply deleting the calibration information and rebuilding...

I then changed the touchReadAdc and touchReadPixel to just give me the raw data if not calibrated:
Code:
void RA8875::touchReadAdc(uint16_t *x, uint16_t *y) 
{
	uint16_t tx,ty;
	readTouchADC(&tx,&ty);
	if (_calibrated) {
	#if (defined(TOUCSRCAL_XLOW) && (TOUCSRCAL_XLOW != 0)) || (defined(TOUCSRCAL_XHIGH) && (TOUCSRCAL_XHIGH != 0))
		*x = map(tx,_tsAdcMinX,_tsAdcMaxX,0,1024);
	#else
		*x = tx;
	#endif
	#if (defined(TOUCSRCAL_YLOW) && (TOUCSRCAL_YLOW != 0)) || (defined(TOUCSRCAL_YHIGH) && (TOUCSRCAL_YHIGH != 0))
		*y = map(ty,_tsAdcMinY,_tsAdcMaxY,0,1024);
	#else
		*y = ty;
	#endif		
	} else {
		*x = tx;
		*y = ty;
	}
	_checkInterrupt(2);
}

/**************************************************************************/
/*!   
	  Returns pixel x,y data with SCREEN scale (screen width, screen Height)
	  Parameters:
	  x: out 0...screen width  (pixels)
	  Y: out 0...screen Height (pixels)
	  Check for out-of-bounds here as touches near the edge of the screen
	  can be safely mapped to the nearest point of the screen.
	  If the screen is rotated, then the min and max will be modified elsewhere
	  so that this always corresponds to screen pixel coordinates.
	  /M.SANDERSCROCK added constrain
*/
/**************************************************************************/
void RA8875::touchReadPixel(uint16_t *x, uint16_t *y) 
{
	uint16_t tx,ty;
	readTouchADC(&tx,&ty);

	if (_calibrated) {
		*x = constrain(map(tx,_tsAdcMinX,_tsAdcMaxX,0,_width-1),0,_width-1);
		//*y = map(ty,_tsAdcMinY,_tsAdcMaxY,0,_height-1);
		*y = constrain(map(ty,_tsAdcMinY,_tsAdcMaxY,0,_height-1),0,_height-1);		
		//*x = map(tx,_tsAdcMinX,_tsAdcMaxX,0,_width-1);
	} else {		
		*x = tx;
		//*y = map(ty,_tsAdcMinY,_tsAdcMaxY,0,_height-1);
		*y = ty;		
	}

	_checkInterrupt(2);
}

Also I know that telling the display at 12mhz instead of 22mhz helps...


Also I am getting better results now when I don't have touched call the
Code:
						#elif defined(USE_RA8875_TOUCH)
							_RA8875_INTS &= ~(1 << 0);//clear
							//_checkInterrupt(2);//clear internal RA int to re-engage
						#endif

I also have a complete mucked up version of touch test, which prints out data:
Like tx, ty to terminal and tries to keep a min max values for these,

if you type in anything in terminal window it will print out min/max values.

if you enter 0-3 it will change rotation, and screen color and reset mins/maxs...

Code:
/* Testing Resistive Touch Screen
*/

#include <SPI.h>
#include <RA8875.h>

/*
Teensy3.x
You are using 4 wire SPI here, so:
 MOSI:  11//Teensy3.x
 MISO:  12//Teensy3.x
 SCK:   13//Teensy3.x
 the rest of pin below:
 */

#define RA8875_INT 3 //any pin that have an INT
#define RA8875_CS 10 //see below...
/*Teensy 3.x can use: 2,6,9,10,15,20,21,22,23 */
#define RA8875_RESET 23//any pin or nothing!


static uint16_t tx, ty;//used as temp
uint16_t  txPrev = 0xffff;
uint16_t  tyPrev = 0xffff;
uint16_t  minX = 0xffff;
uint16_t  maxX = 0;
uint16_t  minY = 0xffff;
uint16_t  maxY = 0;

uint16_t rotation_colors[4] = {RA8875_RED, RA8875_GREEN, RA8875_BLUE, RA8875_YELLOW};

RA8875 tft = RA8875(RA8875_CS, RA8875_RESET);//Teensy3/arduino's

void setup() {
  Serial.begin(38400);
  long unsigned debug_start = millis ();
  while (!Serial && ((millis () - debug_start) <= 5000)) ;
  //  begin display: Choose from: RA8875_480x272, RA8875_800x480, RA8875_800x480ALT, Adafruit_480x272, Adafruit_800x480
  tft.begin(RA8875_480x272, 16, 10000000);//initialize RA8875
  /* Adafruit_480x272 Adafruit_800x480 RA8875_480x272 RA8875_800x480 */
  tft.useINT(RA8875_INT);//We use generic int helper for Internal Resistive Touch
  tft.touchBegin();//enable touch support for RA8875
  if (!tft.touchCalibrated()) {//already calibrated?
    Serial.println("Maybe better you calibrate first!");
    Serial.println("Clearing it out");
    tft.setTouchCalibrationData(0,0,0,0);
  }
  //this enable an ISR on CPU and RA8875 INT
  tft.enableISR(true);
  //You can avoid ISR by simple ignore the line above
  //it will use the slower digitalRead(pin) alternative internally
  tft.fillWindow(rotation_colors[0]);

}

void loop() {
  if (tft.touched()) {
    //if you are here means that you touched screen
    tft.touchReadPixel(&tx,&ty);//read directly in pixel
    if ((tx != txPrev) || (ty != tyPrev)) {
      tft.fillCircle(tx,ty,5,0xFFFF);
      Serial.printf("TX: %u TY: %u\n", tx, ty);     
      if (tx < minX) minX = tx;
      if (tx > maxX) maxX = tx;
      if (ty < minY) minY = ty;
      if (ty > minY) maxY = ty;
    }
  }
  if (Serial.available()) {
    Serial.printf("X Range: %u %u Y Range: %u %u\n", minX, maxX, minY, maxY);
    uint8_t rot = Serial.read(); 
    if ((rot >= '0') && (rot <= '3')) {
      rot -= '0';
      tft.setRotation(rot);
      tft.fillWindow(0);
      Serial.printf("\n\n*** Set Rotation(%d) ***\n", rot);
      tft.setTouchCalibrationData(0,0,0,0);
      tft.fillWindow(rotation_colors[rot]);
      minX = 0xffff;
      maxX = 0;
      minY = 0xffff;
      maxY = 0;
    }
    while (Serial.read() != -1) ; // clear out rest of data
  }
}
Again nothing special, but at least you can start to see how the numbers change...

Edit: with running at 12mhz and remove that call to clear out stuff in the touched member, The easyPaint program sort of works. There looks like some of the data is sort of non-consistent. Probably would need/want some of the filtering stuff, but probably good enough for now... I might even be able to hack in the stuff to try out to the two resistive displays I have (one BuyDisplay one Adafruit).
 
Last edited:
@KurtE

I went ahead and implemented those changes you recommended above and this is what I am seeing:

1. Yeah works fairly good up to about 14Mhz then will just die. At least its not all over the screen anymore.
2. Using setCalibration(0,0,0,0) I get a min max ranges that I used to update the calibration, so:
Code:
    tft.setTouchCalibrationData(40,996,68,890);  //rot(2)
Now the fun begins.
3. If I use setRotation(0) if I draw a diagonal from the upper right to the lower left the circles are drawn the opposite way (lower left to top right). Basically its diagonally mirrored
4. If I do a setRotation(2) it works perfectly. Dots go where the belong.
5. Rotations 1 and 3 are even more fun to watch, horizontally and vertically mirrored depending the quadrant you are putting the pen in :)

Probably could use a little filtering on the ADC.
 
Yep - Not sure if we should just limit the user to 12mhz if they turn on using the touch stuff or fix it to max in touch stuf...

Now currently the tft.setTouchCalibrationData(40,996,68,890);
Is real stupid. That is it will simply do:
Code:
_tsAdcMinX = 40; 
_tsAdcMaxX = 996;
_tsAdcMinY = 68;
_tsAdcMaxY = 890;
And currently these values will be overwritten by the values in the configuration header file if you call setRotation.

I can see three possible ways to go:
a) Punt, If you call setRotation, you need to setTouchCalibrationData with the parameters in the right order for processing that orientation. (easy for library, but messy)

b) Waste 4 uint16_t values in the class to store these value:
Currently the code will use the files out of header like in case0 - _tsAdcMinX = TOUCSRCAL_XLOW; _tsAdcMinY = TOUCSRCAL_YLOW; _tsAdcMaxX = TOUCSRCAL_XHIGH; _tsAdcMaxY = TOUCSRCAL_YHIGH;
So instead at init time we set the member variables to values like: TOUCSRCAL_XLOW
And if you call this function, we update those values, such that assuming the current setRotation stuff is setup correctly, it should just work (I have doubts)...

Code:
void RA8875::setRotation(uint8_t rotation)//0.69b32 - less code
{
	_rotation = rotation % 4; //limit to the range 0-3
	switch (_rotation) {
	case 0:
		//default, connector to bottom
		_portrait = false;
		_scanDirection(0,0);
		#if defined(USE_RA8875_TOUCH)
			if (!_calibrated) {
				_tsAdcMinX = 0;  _tsAdcMinY = 0; _tsAdcMaxX = 1023;  _tsAdcMaxY = 1023;
			} else {
				_tsAdcMinX = TOUCSRCAL_XLOW; _tsAdcMinY = TOUCSRCAL_YLOW; _tsAdcMaxX = TOUCSRCAL_XHIGH; _tsAdcMaxY = TOUCSRCAL_YHIGH;
			}
		#endif
    break;
	case 1:
		//90
		_portrait = true;
		_scanDirection(1,0);
		#if defined(USE_RA8875_TOUCH)
			if (!_calibrated) {
				_tsAdcMinX = 1023; _tsAdcMinY = 0; _tsAdcMaxX = 0; _tsAdcMaxY = 1023;
			} else {
				_tsAdcMinX = TOUCSRCAL_XHIGH; _tsAdcMinY = TOUCSRCAL_YLOW; _tsAdcMaxX = TOUCSRCAL_XLOW; _tsAdcMaxY = TOUCSRCAL_YHIGH;
			}
		#endif
    break;
	case 2:
		//180
		_portrait = false;
		_scanDirection(1,1);
		#if defined(USE_RA8875_TOUCH)
			if (!_calibrated) {
				_tsAdcMinX = 1023; _tsAdcMinY = 1023; _tsAdcMaxX = 0; _tsAdcMaxY = 0;
			} else {
				_tsAdcMinX = TOUCSRCAL_XHIGH; _tsAdcMinY = TOUCSRCAL_YHIGH; _tsAdcMaxX = TOUCSRCAL_XLOW; _tsAdcMaxY = TOUCSRCAL_YLOW;
			}
		#endif
    break;
	case 3:
		//270
		_portrait = true;
		_scanDirection(0,1);
		#if defined(USE_RA8875_TOUCH)
			if (!_calibrated) {
				_tsAdcMinX = 0; _tsAdcMinY = 1023; _tsAdcMaxX = 1023; _tsAdcMaxY = 0;
			} else {
				_tsAdcMinX = TOUCSRCAL_XLOW; _tsAdcMinY = TOUCSRCAL_YHIGH; _tsAdcMaxX = TOUCSRCAL_XHIGH; _tsAdcMaxY = TOUCSRCAL_YLOW;
			}
		#endif
    break;
	}
	if (_portrait){
		_width = RA8875_HEIGHT;
		_height = RA8875_WIDTH;
		_FNCR1_Reg |= (1 << 4);
	} else {
		_width = RA8875_WIDTH;
		_height = RA8875_HEIGHT;
		_FNCR1_Reg &= ~(1 << 4);
	}
	_writeRegister(RA8875_FNCR1,_FNCR1_Reg);//0.69b21
	setActiveWindow();
}

c) Or we update setRotoation, that before you update the rotation to be the new rotation value, you use the old ration value to extract the current Min/MAX values into some local variables, and then use thos values to update for the new rotation. (not sure if I explained that very well).
 
@KurtE

Or leave it the way it is for calibration and change to the following:
Code:
void RA8875::readTouchADC(uint16_t *x, uint16_t *y) 
{
	#if defined(_FASTCPU)
		_slowDownSPI(true);
	#endif
	uint16_t tx =  _readRegister(RA8875_TPXH);
	uint16_t ty =  _readRegister(RA8875_TPYH);
	uint8_t remain = _readRegister(RA8875_TPXYL);
	#if defined(_FASTCPU)
		_slowDownSPI(false);
	#endif
	tx <<= 2;
	ty <<= 2;
	tx |= remain & 0x03;        // get the bottom x bits
	ty |= (remain >> 2) & 0x03; // get the bottom y bits
	if (_rotation == 1){
		tx = 1024 - tx;
		*x = ty;
		*y = tx;
	} else if(_rotation == 3){
		ty = 1024 - ty;
		*x = ty;
		*y = tx;
	}
	
	if(_rotation == 0){
		*x = tx;   //this works for rotation(0)
		*y = ty;
	} else if(_rotation == 2){
		tx = 1024 - tx;  //needed for rotation 2 + next 2
		ty = 1024 - ty;
		*x = tx;   //this works for rotation(0)
		*y = ty;
	}
}

EDIT: Not the most elegant and probably wastes cycles but just another approach.
 
@KurtE

My method seems to just work if you do setCalibration for each rotation. If you put it in the header it works for rotation 0 only. Not sure if that would be any indication of what would happen with any of your methods.
 
@mjs513 - So what are your 4 sets of values for setCalibration?

Is there a reasonable mapping for what each of them are? i.e. could there simply be bugs in the setRotation code for which values are initialized to what?
 
@KurtE

Ok here goes. Calibrated at rotation 0 and got the following calibration using you min-max ranges from your sketch:
Code:
      tft.setTouchCalibrationData(40,996,68,890);

All I did in your sketch was to call setTouchCalibration with those values every time it did a set rotation. Haven't tried it with just calling it once though. the calibration just has all the values set to 0.

EDIT: nope have to call it each time unless you just set it and be done with the extra header file.

EDIT2: Probably could make it work from the header file as well
 
@KurtE

If you put the calibration values in the header file your rotation transform is simpler for some reason:
Code:
	if (_rotation == 1 || _rotation == 3){
		tx = 1024 - tx;
		ty = 1024 - ty;
		*x = ty;
		*y = tx;
	} 

	if(_rotation == 0 || _rotation == 2){
		*x = tx;   //this works for rotation(0)
		*y = ty;
	}
 
@mjs513 - My head hurts ;) Or maybe my eyes are crossed, but some of this stuff just does not feel right to me...

That is lets say we are in rotation 1 and you set your call above: setTouchCalibrationData(40,996,68,890)
So we have:
Code:
_tsAdcMinX = 40; 
_tsAdcMaxX = 996;
_tsAdcMinY = 68;
_tsAdcMaxY = 890;

So if we cal touchReadPixel and the user clicked at tx= 950 ty= 70 Lets see what happens to the values.

TouchReadPixel calls readTouchADC(&tx, &ty)

So with your code, we see:
Code:
	tx = 1024 - tx;
		*x = ty;
		*y = tx;
Or in our case: returns x=70, y= 1024-950= 74

So now in touchReadPixel we do:
Code:
	*x = constrain(map(tx,_tsAdcMinX,_tsAdcMaxX,0,_width-1),0,_width-1);
		//*y = map(ty,_tsAdcMinY,_tsAdcMaxY,0,_height-1);
		*y = constrain(map(ty,_tsAdcMinY,_tsAdcMaxY,0,_height-1),0,_height-1);
So we are constraining the X value to the Y value mins/maxs and likewise Ys with x touch value calibrations, which feels wrong...
Unless somehow the hardware has already translated that value earlier?

Personally I think this should instead be more something like:
Code:
void RA8875::readTouchADC(uint16_t *x, uint16_t *y)
{
	#if defined(_FASTCPU)
		_slowDownSPI(true);
	#endif
	uint16_t tx =  _readRegister(RA8875_TPXH);
	uint16_t ty =  _readRegister(RA8875_TPYH);
	uint8_t remain = _readRegister(RA8875_TPXYL);
	#if defined(_FASTCPU)
		_slowDownSPI(false);
	#endif
	tx <<= 2;
	ty <<= 2;
	tx |= remain & 0x03;        // get the bottom x bits
	ty |= (remain >> 2) & 0x03; // get the bottom y bits

	// map the constrained values back to normal range 0,1023
	tx = constrain(map, tx, _tsAdcMinX,_tsAdcMaxX,0,1023), 0, 1023);
	ty = constrain(map, ty, _tsAdcMinY,_tsAdcMaxY,0,1023), 0, 1023);
  
	switch(rotation) {
	case 1:
		tx = 1023 - tx;
		*x = ty;
		*y = tx;
		break;
	case 3:
		ty = 1023 - ty;
		*x = ty;
		*y = tx;
		break;
	case 0:
		*x = tx;   //this works for rotation(0)
		*y = ty;
		break;
	case 2:
		tx = 102 - tx;  //needed for rotation 2 + next 2
		ty = 1024 - ty;
		*x = tx;   //this works for rotation(0)
		*y = ty;
	  }
}
And then the touchReadPixel maybe something like:
Code:
void RA8875::touchReadPixel(uint16_t *x, uint16_t *y) 
{
	uint16_t tx,ty;
	readTouchADC(&tx,&ty);

	if (_calibrated) {
		*x = map(tx, 0, 1023,0,_width-1);
		*y = map(ty, 0, 1023,0,_height-1);		
	} else {		
		*x = tx;
		*y = ty;		
	}

	_checkInterrupt(2);
}
Then toss away all of the constraint setting stuff in setRotation, just use the values setup at Init or the values we pass in?

Am I missing something?
 
KurtE said:
@mjs513 - My head hurts Or maybe my eyes are crossed, but some of this stuff just does not feel right to me...

I'll second that. What I did was just to see what it would take to get the rotations right with the current context and from what I am seeing it just doesn't make sense, just like you said. Was playing around with the contraints and mapping that was giving me a bigger headache :)

Think what you are doing is basically revamping the way touch points work which feels a lot better. Something is just wrong with the way its is now.
 
When I did the touch_MAP[] for ili9341 the other year - it was working with my 5 set array of x,y as I had it to work in all 4 rotations.

TS_MAP tsMap[5] = { {200, 3700, 325, 3670 }, { 0, 319, 0, 239 }, { 319, 0, 0, 239 }, { 319, 0, 239, 0 }, { 0, 319, 239, 0 } }; //github link

Revisiting it the other week I got a hurting head and crossed eyes as the old code worked - but trying a new treatment was failing so that got aborted when @mjs513 said it was working in the 9488/9341 timeframe?

The 9341 and XPT posted sample code still up there where I did alternate screens of a button array drawing with hit test on the button returns - and one button was 'Rotate' - other buttons drew a fresh screen of button with colors/labels - and working around all 4 rotations it would redraw and the button hits worked.

>> GitHub … ColorButtonsMark3 Current Version Support in Teensy 1.27b2
TS_BUTTON mybuttons2[] = { {(char *)"Rot", 5, 5, 50, 50, 65535, 15, TS_FBUTN, 0, 0, 2, 1, 0} , … //github link

Christmas 2015 :: youtube.com … Touch buttons
 
@mjs513 and @defragster - I backed off (and enhanced) my changes and I believe all 4 rotations are working now, and you only need to set the rotation data once, as I
changed the code to my option b) above.

In particular, I have 4 new bounds values defined in the instance, which gets initialized to what the values are in your RA8875Calibration.h at begin time. The call to
setCalibrationData will update these values.

setRotation: was updated to use these values instead of the header file values.

I believe I then fixed the code in setRotation: to use the correct bounds for the values in the different rotations. In particular if you rotate the screen to portrait mode, the values returned from the read ADC call, the X, Y values are swapped. So when you do the mapping, you should also swap the touch screen ranges for X and Y as well...

Again appears to work.

I pushed up the changes up to my fork/branch: https://github.com/KurtE/RA8875/tree/RA8875_t4_settings

I also updated the touchtest sketch, to be my version, where you can change the orientations.

I also pushed up some gratuitous updates to most of the examples under Teensy, to update the comments about CS pins needing to be one of the hardware CS pins, as the code simply uses digitalWrite (or digitalWriteFast)

I think I am pretty close to doing a PR back to you. Although might do quick and dirty update to allow multiple screens...
 
@pdolew - yes.

I have 1 from Adafruit, with the 4.3" 480x272 resistive touch (currently on T4) - Will next check to see how these changes work.

The one I have been testing the touch on is a BuyDisplay 5" 480x272 resistive touch (currently on T3.6)

Also have Buydisplay 5" 800x480 capacitive touch external connector which I don't member where I put that connector...

And now I have Buydisplay 4.3" 800x480 capacitive touch (on main connector) that uses I2C to talk to this part. Screen works, I have not tried touch yet...

Note: The last two displays I did the testing to run both on single T3.6 one on SPI the other on SPI1. Required external power
 
@Kurt, @mjs513

My newest board ..... not ready but the begin is there .... use here two AD7991...
DeepinScreenshot_select-area_20190908171232.png
 
Status
Not open for further replies.
Back
Top