Why the delay in touchRead()?

Bryan42

Active member
Was wondering: Why is a 10 microsecond delay used in the function touchRead() in the touch.c file of the Teensy library?

The code snippet below from touch.c shows what I'm talking about:

Code:
int touchRead(uint8_t pin)
{
	uint32_t ch;

	if (pin >= NUM_DIGITAL_PINS) return 0;
	ch = pin2tsi[pin];
	if (ch == 255) return 0;

	*portConfigRegister(pin) = PORT_PCR_MUX(0);
	SIM_SCGC5 |= SIM_SCGC5_TSI;
#if defined(HAS_KINETIS_TSI)
	TSI0_GENCS = 0;
	TSI0_PEN = (1 << ch);
	TSI0_SCANC = TSI_SCANC_REFCHRG(3) | TSI_SCANC_EXTCHRG(CURRENT);
	TSI0_GENCS = TSI_GENCS_NSCN(NSCAN) | TSI_GENCS_PS(PRESCALE) | TSI_GENCS_TSIEN | TSI_GENCS_SWTS;
	delayMicroseconds(10);  // <<<< WHY THIS DELAY?
	while (TSI0_GENCS & TSI_GENCS_SCNIP) ; // wait
	delayMicroseconds(1);   // <<<< AND THIS ONE FOR THAT MATTER
	return *((volatile uint16_t *)(&TSI0_CNTR1) + ch);
#elif defined(HAS_KINETIS_TSI_LITE)
	TSI0_GENCS = TSI_GENCS_REFCHRG(4) | TSI_GENCS_EXTCHRG(3) | TSI_GENCS_PS(PRESCALE)
		| TSI_GENCS_NSCN(NSCAN) | TSI_GENCS_TSIEN | TSI_GENCS_EOSF;
	TSI0_DATA = TSI_DATA_TSICH(ch) | TSI_DATA_SWTS;
	delayMicroseconds(10); // <<<< WHY THIS DELAY?
	while (TSI0_GENCS & TSI_GENCS_SCNIP) ; // wait
	delayMicroseconds(1);  // <<<< AND THIS ONE FOR THAT MATTER
	return TSI0_DATA & 0xFFFF;
#endif
}

The delay occurs just after starting the touch scan. There's also a 1 microsecond delay after waiting for the scan to complete. I'm sure these weren't just put in willy nilly. But I can find nothing in the NXP documentation that suggests they are needed.

Why this matters: In one of my projects, I have a 100 microsecond main loop, strictly timed. I've successfully rearranged the touch code to read asynchronously, (see my posts in the general discussion threads), so once a scan is started, it's not costing me any time in the main loop. All I have to do is check every so often for completion. However, the 10 microsecond delay at the *start* of a scan *is* costing me -- 10% of the time I've allocated for my main loop. Now, I only sample the touch pads every so often, not every loop, but still, I have to allocate for the maximum possible time required.

I have commented out those delays in my rearranged code, just to see if that made any difference in reading the pins. There was none I could detect, but would like to know what if any consequences there are of doing this.
 
I think I found a solution, if not answer. It was actually mentioned in these forums (I never seem to find stuff using the searching mechanism. Old-fashioned, pains-taking manual browsing the only sure fire way.) This post was the key: https://forum.pjrc.com/threads/26837-minor-fixup-to-touchRead()-function-in-teensy-core-lib

In this post the writer uses the EOSF flag (end of scan flag) rather than the SCNIP (scan in progress) flag, and mentioned that if you do so, you don't need any delays. I tried that method and it indeed seems to work. (I tested it with the Teensy 3.2. I'll try the Teensy 3.6 later).

I had seen the EOSF flag in the NXP documentation and wondered why it wasn't being used in touchRead(). I remember thinking when I saw it that I should try using it, but forgot about it until I saw the aforementioned post.
 
Interesting - Paul might consider changing that SCNIP to EOSF in the core for touchRead() if it tests out on all.
 
I've seen that the library has not changed. Is there a problem with this method?

aka using EOSF versus SCNIP
 
Interesting - Paul might consider changing that SCNIP to EOSF in the core for touchRead() if it tests out on all.
Wonder if there was any follow through on checking it out on the other boards?

I've seen that the library has not changed. Is there a problem with this method?

aka using EOSF versus SCNIP
Maybe there were issues, or it was never tried out on the other platforms?

I don't see any pending Pull Requests in core, that have the word touch in them.

So, if it does work on the different chips, maybe someone should issue a new PR for it.
 
Back
Top