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
#define SECOND_TSI_INPUT TSI0_DATA_TSICH_10
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);
}
static unsigned long fnReadTouchSensorInputs(void)
{
#define CALIBRATE_CYCLES (8 * KEY_ROWS)
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) {
case FIRST_TSI_INPUT:
ulKeys[0] = (TSI0_DATA & TSI0_DATA_TSICNT);
TSI0_GENCS = TSI0_GENCS;
TSI0_DATA = (TSI0_DATA_SWTS | SECOND_TSI_INPUT);
ulCols = (ulLastCols & ~0x01);
slLast[0] = (signed long)(ulKeys[0] - ulCalibrationValue[0]);
break;
case SECOND_TSI_INPUT:
ulKeys[1] = (TSI0_DATA & TSI0_DATA_TSICNT);
TSI0_GENCS = TSI0_GENCS;
#if VIRTUAL_KEY_ROWS > 2
TSI0_DATA = (TSI0_DATA_SWTS | THIRD_TSI_INPUT);
#else
TSI0_DATA = (TSI0_DATA_SWTS | FIRST_TSI_INPUT);
#endif
ulCols = (ulLastCols & ~0x02);
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);
TSI0_GENCS = TSI0_GENCS;
TSI0_DATA = (TSI0_DATA_SWTS | FIRST_TSI_INPUT);
ulCols = (ulLastCols & ~0x04);
break;
#endif
}
if (iCalibrate < CALIBRATE_CYCLES) {
ulCalibrationValue[0] += ulKeys[0];
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) {
ulCalibrationValue[0] /= (CALIBRATE_CYCLES/KEY_ROWS);
ulCalibrationValue[0] += 0x15;
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;
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];
#endif
#if VIRTUAL_KEY_ROWS > 2
ulCalibrationValue[2] /= (CALIBRATE_CYCLES/KEY_ROWS);
ulCalibrationValue[2] += 0x15;
fnDebugMsg(", ");
fnDebugHex(ulCalibrationValue[2], WITH_LEADIN | WITH_CR_LF | sizeof(ulCalibrationValue[2]));
#if KINETIS_MAX_SPEED == 100000000
TSI0_THRESHLD7 = (unsigned short)ulCalibrationValue[2];
#endif
#endif
#if VIRTUAL_KEY_ROWS > 3
ulCalibrationValue[3] /= CALIBRATE_CYCLES;
ulCalibrationValue[3] += 0x15;
#if KINETIS_MAX_SPEED == 100000000
TSI0_THRESHLD9 = (unsigned short)ulCalibrationValue[3];
#endif
#endif
}
}
else {
ulCols = 0;
if ((slLast[1] > 10) || (slLast[0] > 10)) {
PWM_INTERRUPT_SETUP pwm_setup;
pwm_setup.int_type = PWM_INTERRUPT;
pwm_setup.pwm_mode = (PWM_SYS_CLK | PWM_PRESCALER_16);
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);
pwm_setup.pwm_frequency = PWM_TIMER_US_DELAY(TIMER_FREQUENCY_VALUE(1000), 16);
pwm_setup.pwm_value = _PWM_PERCENT((100 - (unsigned char)sSlider), pwm_setup.pwm_frequency);
fnConfigureInterrupt((void *)&pwm_setup);
pwm_setup.pwm_value = _PWM_PERCENT((unsigned char)sSlider, pwm_setup.pwm_frequency);
pwm_setup.pwm_reference = (_TIMER_0 | 1);
fnConfigureInterrupt((void *)&pwm_setup);
fnDebugMsg("Slider = ");
fnDebugDec(sSlider, (DISPLAY_NEGATIVE | WITH_CR_LF));
}
else {
if (iSliderDown != 0) {
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;
}