Hello,
I am working on FRDM-KL25Z EVM. i need sample code for TSI(Touch Sensing Input).
Any help in this will appreciated more.
Thank You
Bhavin
is there any update on this?
its urgent for me.
Any help in this will be appreciated more.
Hi Bhavin Maru,
I'd highly recommend you to refer to the TSI demo which is from the Kinetis KSDK.
And you can follow the thread to install the KSDK v2.0.
How to: install KSDK 2.0
Have a great day,
Ping
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hello jeremyzhou,
Is there any update for TSI sample code?
Any help in this will be appreciated more.
Hi Bhavin Maru,
As I mentioned before, the KSDK has included the TSI demo which reside in ~\boards\frdmkl25z\driver_examples (see Fig 1).
And you can build the KSDK for the FRDM-KL25 board through the How to: install KSDK 2.0 .
Hope this is clear.
Have a great day,
Ping
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hello jeremyzhou,
Thank you for your reply but i need sample code for TSI for FRDM-KL25Z EVM.
i hope you wiil suggest me sample code for TSI for FRDM-KL25Z EVM.its an urgent for me.
Thank You
Hi
See µTasker Kinetis FRDM-KL25Z support "Emulated FAT and TSI Slider"
This allows the TSI on the FRDM-KL25Z to be used as a slider to control the color of the LED.
Below I extracted the code being used to do it but the complete source is available at the link.
Regards
Mark
#define VIRTUAL_KEY_ROWS 2
#define KEY_ROW_IN_1 PORTB_BIT16
#define KEY_ROW_IN_2 PORTB_BIT17
#define KEY_1_PORT_REF _TOUCH_PORTB
#define KEY_1_PORT_PIN KEY_ROW_IN_1
#define KEY_2_PORT_REF _TOUCH_PORTB
#define KEY_2_PORT_PIN KEY_ROW_IN_2
#define KEY_3_PORT_REF _TOUCH_PORTB
#define KEY_3_PORT_PIN 0
#define FIRST_TSI_INPUT TSI0_DATA_TSICH_9 // alternate between channels 9 and 10
#define SECOND_TSI_INPUT TSI0_DATA_TSICH_10
// Power up the touch sense input module - select TSI channels on the ports and prepare operating mode; start first measurement
//
static void fnStartTSI(void)
{
POWER_UP(5, SIM_SCGC5_TSI);
_CONFIG_PERIPHERAL(B, 16, PB_16_TSI_CH9);
_CONFIG_PERIPHERAL(B, 17, PB_17_TSI_CH10);
TSI0_GENCS = (TSI_GENCS_EOSF | TSI_GENCS_STM_SW | TSI_GENCS_NSCN_32 | TSI_GENCS_TSIEN | TSI_GENCS_PS_DIV_1 | TSI_GENCS_EXTCHRG_32uA | TSI_GENCS_DVOLT_1_03 | TSI_GENCS_REFCHRG_32uA | TSI_GENCS_MODE_CAPACITIVE);
TSI0_DATA = (TSI0_DATA_SWTS | TSI0_DATA_TSICH_9);
}
// Scheduled at 50ms rate
//
static unsigned long fnReadTouchSensorInputs(void)
{
#define CALIBRATE_CYCLES (8 * KEY_ROWS) // first 8 scan cycles used for calibration (assumed not pressed)
static int iCalibrate = 0;
static unsigned long ulCalibrationValue[VIRTUAL_KEY_ROWS] = {0};
unsigned long ulCols = 0;
static unsigned long ulLastCols = 0;
unsigned long ulKeys[KEY_ROWS];
static signed long slLast[KEY_ROWS] = {0};
static int iSliderDown = 0;
signed long sSlider;
uMemset(ulKeys, 0, sizeof(ulKeys));
switch (TSI0_DATA & TSI0_DATA_TSICH_15) { // previous input sampled
case FIRST_TSI_INPUT:
ulKeys[0] = (TSI0_DATA & TSI0_DATA_TSICNT); // key 1 measurement ready
TSI0_GENCS = TSI0_GENCS; // needed by KL25 but not KL26
TSI0_DATA = (TSI0_DATA_SWTS | SECOND_TSI_INPUT); // start measurement for following key
ulCols = (ulLastCols & ~0x01); // reset only key 1 state
slLast[0] = (signed long)(ulKeys[0] - ulCalibrationValue[0]);
break;
case SECOND_TSI_INPUT:
ulKeys[1] = (TSI0_DATA & TSI0_DATA_TSICNT); // key 2 measurement ready
TSI0_GENCS = TSI0_GENCS; // needed by KL25 but not KL26
#if VIRTUAL_KEY_ROWS > 2
TSI0_DATA = (TSI0_DATA_SWTS | THIRD_TSI_INPUT); // start next measurement for following key
#else
TSI0_DATA = (TSI0_DATA_SWTS | FIRST_TSI_INPUT); // start next measurement for following key
#endif
ulCols = (ulLastCols & ~0x02); // reset only key 2 state
slLast[1] = (signed long)(ulKeys[1] - ulCalibrationValue[1]);
break;
#if defined THIRD_TSI_INPUT
case THIRD_TSI_INPUT:
ulKeys[2] = (TSI0_DATA & TSI0_DATA_TSICNT); // key 3 measurement ready
TSI0_GENCS = TSI0_GENCS; // needed by KL25 but not KL26
TSI0_DATA = (TSI0_DATA_SWTS | FIRST_TSI_INPUT); // start next measurement for following key
ulCols = (ulLastCols & ~0x04); // reset only key 3 state
break;
#endif
}
if (iCalibrate < CALIBRATE_CYCLES) { // during calibration phase
ulCalibrationValue[0] += ulKeys[0]; // accumulate
ulCalibrationValue[1] += ulKeys[1];
#if VIRTUAL_KEY_ROWS > 2
ulCalibrationValue[2] += ulKeys[2];
#endif
#if VIRTUAL_KEY_ROWS > 3
ulCalibrationValue[3] += ulKeys[3];
#endif
if (++iCalibrate == CALIBRATE_CYCLES) { // has calibration period expired?
ulCalibrationValue[0] /= (CALIBRATE_CYCLES/KEY_ROWS);
ulCalibrationValue[0] += 0x15; // raise reference over calibrated value
fnDebugMsg("Cal = ");
fnDebugHex(ulCalibrationValue[0], WITH_LEADIN | sizeof(ulCalibrationValue[0]));
#if KINETIS_MAX_SPEED == 100000000
TSI0_THRESHLD5 = (unsigned short)ulCalibrationValue[0];
#endif
ulCalibrationValue[1] /= (CALIBRATE_CYCLES/KEY_ROWS);
ulCalibrationValue[1] += 0x15; // raise reference over calibrated value
fnDebugMsg(", ");
#if VIRTUAL_KEY_ROWS <= 2
fnDebugHex(ulCalibrationValue[1], WITH_LEADIN | WITH_CR_LF | sizeof(ulCalibrationValue[1]));
#else
fnDebugHex(ulCalibrationValue[1], WITH_LEADIN | sizeof(ulCalibrationValue[1]));
#endif
#if KINETIS_MAX_SPEED == 100000000
TSI0_THRESHLD8 = (unsigned short)ulCalibrationValue[1]; // enter threshold value
#endif
#if VIRTUAL_KEY_ROWS > 2
ulCalibrationValue[2] /= (CALIBRATE_CYCLES/KEY_ROWS);
ulCalibrationValue[2] += 0x15; // raise reference over calibrated value
fnDebugMsg(", ");
fnDebugHex(ulCalibrationValue[2], WITH_LEADIN | WITH_CR_LF | sizeof(ulCalibrationValue[2]));
#if KINETIS_MAX_SPEED == 100000000
TSI0_THRESHLD7 = (unsigned short)ulCalibrationValue[2]; // enter threshold value
#endif
#endif
#if VIRTUAL_KEY_ROWS > 3
ulCalibrationValue[3] /= CALIBRATE_CYCLES; // average measured value
ulCalibrationValue[3] += 0x15;
#if KINETIS_MAX_SPEED == 100000000
TSI0_THRESHLD9 = (unsigned short)ulCalibrationValue[3]; // enter threshold value
#endif
#endif
}
}
else { // normal key scan operation
ulCols = 0;
if ((slLast[1] > 10) || (slLast[0] > 10)) { // if a touch is detected
PWM_INTERRUPT_SETUP pwm_setup;
pwm_setup.int_type = PWM_INTERRUPT;
pwm_setup.pwm_mode = (PWM_SYS_CLK | PWM_PRESCALER_16); // clock PWM timer from the system clock with /16 pre-scaler
if (iSliderDown == 0) {
_FLOAT_PORT(B, (BLINK_LED));
}
iSliderDown = 20;
sSlider = (slLast[1] - slLast[0]);
sSlider += 400;
sSlider /= 8;
if (sSlider < 0) {
sSlider = 0;
}
else if (sSlider > 100) {
sSlider = 100;
}
pwm_setup.pwm_reference = (_TIMER_2 | 0); // timer module 2, channel 0 (red LED in RGB LED)
pwm_setup.pwm_frequency = PWM_TIMER_US_DELAY(TIMER_FREQUENCY_VALUE(1000), 16); // generate 1000Hz on PWM output
pwm_setup.pwm_value = _PWM_PERCENT((100 - (unsigned char)sSlider), pwm_setup.pwm_frequency); // PWM (high/low)
fnConfigureInterrupt((void *)&pwm_setup); // enter configuration for PWM test
pwm_setup.pwm_value = _PWM_PERCENT((unsigned char)sSlider, pwm_setup.pwm_frequency); // PWM (high/low)
pwm_setup.pwm_reference = (_TIMER_0 | 1); // timer module 0, channel 5 (blue LED in RGB LED)
fnConfigureInterrupt((void *)&pwm_setup);
fnDebugMsg("Slider = ");
fnDebugDec(sSlider, (DISPLAY_NEGATIVE | WITH_CR_LF));
}
else {
if (iSliderDown != 0) { // if a release has been detected
iSliderDown--;
if (iSliderDown == 0) {
_DRIVE_PORT_OUTPUT(B, (BLINK_LED));
_CONFIG_DRIVE_PORT_OUTPUT_VALUE(B, PORTB_BIT18, PORTB_BIT18, (PORT_SRE_SLOW | PORT_DSE_HIGH));
_CONFIG_DRIVE_PORT_OUTPUT_VALUE(D, PORTD_BIT1, PORTD_BIT1, (PORT_SRE_SLOW | PORT_DSE_HIGH));
}
}
}
}
return ulCols;
}