A library for Freescale MCU which contain TSI peripheral, just for Kinetis L version. Because they use "lighter" version of TSI peripheral.

Dependents:   kl25z-tinyshell-demo tsi_slider_light_senso_LED frdm_tsi_slider_led_blend demo_slider ... more

This library is "fork" of the TSI library created by the mbed team.

Revision:
0:9331e373c138
Child:
1:8a2098a10330
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tsi_sensor.cpp	Sat Feb 22 11:07:29 2014 +0000
@@ -0,0 +1,148 @@
+/* Freescale Semiconductor Inc.
+ * mbed Microcontroller Library
+ * (c) Copyright 2014 ARM Limited.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "mbed.h"
+#include "TSISensor.h"
+
+void tsi_irq(void);
+TSIAnalogSlider *TSIAnalogSlider::_instance;
+
+TSIAnalogSlider::TSIAnalogSlider(TSIElectrode& elec0, TSIElectrode& elec1,
+                                 uint32_t range)
+: _elec0(elec0), _elec1(elec1), _range(range) {
+    _instance = this;
+    _current_elec = &elec0;
+    SIM->SCGC5 |= SIM_SCGC5_TSI_MASK;
+
+    TSI0->GENCS |= (TSI_GENCS_ESOR_MASK | TSI_GENCS_MODE(0) | TSI_GENCS_REFCHRG(4)
+                   | TSI_GENCS_DVOLT(0) | TSI_GENCS_EXTCHRG(7) | TSI_GENCS_PS(4)
+                   | TSI_GENCS_NSCN(11) | TSI_GENCS_TSIIEN_MASK | TSI_GENCS_STPE_MASK);
+    TSI0->GENCS |= TSI_GENCS_TSIEN_MASK;
+
+    NVIC_SetVector(TSI0_IRQn, (uint32_t)&tsi_irq);
+    NVIC_EnableIRQ(TSI0_IRQn);
+
+    selfCalibration();
+}
+
+static void initBaseline(TSIElectrode& elec)
+{
+    uint32_t channel0 = elec.getChannel();
+    TSI0->DATA = ((channel0 << TSI_DATA_TSICH_SHIFT) );
+    TSI0->DATA |= TSI_DATA_SWTS_MASK;
+    while(!(TSI0->GENCS & TSI_GENCS_EOSF_MASK));
+    TSI0->GENCS |= TSI_GENCS_EOSF_MASK;
+    elec.setBaseline(TSI0->DATA & TSI_DATA_TSICNT_MASK);
+}
+
+void TSIAnalogSlider::selfCalibration(void)
+{
+    TSI0->GENCS |= TSI_GENCS_EOSF_MASK;      // Clear End of Scan Flag
+    TSI0->GENCS &= ~TSI_GENCS_TSIEN_MASK;    // Disable TSI module
+
+    uint32_t trigger_backup;
+    if(TSI0->GENCS & TSI_GENCS_STM_MASK) {     // Back-up TSI Trigger mode from Application
+        trigger_backup = 1;
+    } else {
+        trigger_backup = 0;
+    }
+
+    TSI0->GENCS &= ~TSI_GENCS_STM_MASK;    // Use SW trigger
+    TSI0->GENCS &= ~TSI_GENCS_TSIIEN_MASK; // Enable TSI interrupts
+    TSI0->GENCS |= TSI_GENCS_TSIEN_MASK;   // Enable TSI module
+
+    initBaseline(_elec0);
+    initBaseline(_elec1);
+
+    TSI0->DATA = ((_elec0.getChannel() << TSI_DATA_TSICH_SHIFT));
+
+    TSI0->GENCS &= ~TSI_GENCS_TSIEN_MASK;    // Disable TSI module
+    TSI0->GENCS |= TSI_GENCS_TSIIEN_MASK;     // Enale TSI interrupt
+    if (trigger_backup) {                     // Restore trigger mode
+        TSI0->GENCS |= TSI_GENCS_STM_MASK;
+    } else {
+        TSI0->GENCS &= ~TSI_GENCS_STM_MASK;
+    }
+
+    TSI0->GENCS |= TSI_GENCS_TSIEN_MASK;     // Enable TSI module
+    TSI0->DATA |= TSI_DATA_SWTS_MASK;
+}
+
+
+void TSIAnalogSlider::sliderRead(void ) {
+    if (_scan_in_progress) {
+        _scan_in_progress = 0;
+        uint32_t delta0 = _elec0.getDelta();
+        uint32_t delta1 = _elec1.getDelta();
+
+        if ((delta0 > _elec0.getThreshold()) || (delta1 > _elec1.getThreshold())) {
+            uint32_t perc_pos0 = (delta0 * 100) / (delta0 + delta1);
+            uint32_t perc_pos1 = (delta1 * 100) / (delta0 + delta1);
+            setSliderPercPosition(0, perc_pos0);
+            setSliderPercPosition(1, perc_pos1);
+            uint32_t dist_pos0 = (perc_pos0 * _range) / 100;
+            uint32_t dist_pos1 = (perc_pos0 * _range) / 100;
+            setSliderDisPosition(0, dist_pos0);
+            setSliderDisPosition(1, dist_pos1);
+
+            setAbsolutePosition(((100 - perc_pos0) + perc_pos1) / 2);
+            setAbsoluteDistance(((_range - dist_pos0) + dist_pos1) / 2);
+        } else {
+            setSliderPercPosition(0, 0);
+            setSliderPercPosition(1, 0);
+            setSliderDisPosition(0, 0);
+            setSliderDisPosition(1, 0);
+            setAbsolutePosition(0);
+            setAbsoluteDistance(0);
+        }
+    }
+}
+
+float TSIAnalogSlider::readPercentage() {
+    sliderRead();
+    return (float)getAbsolutePosition() / 100.0;
+}
+
+uint32_t TSIAnalogSlider::readDistance() {
+    sliderRead();
+    return getAbsoluteDistance();
+}
+
+static void changeElectrode(TSIAnalogSlider *analog_slider)
+{
+    TSIElectrode* elec = analog_slider->getCurrentElectrode();
+    uint32_t signal = (TSI0->DATA & TSI_DATA_TSICNT_MASK);
+    elec->setSignal(signal);
+
+    TSIElectrode *next_elec =  analog_slider->getNextElectrode(elec);
+
+    analog_slider->setCurrentElectrode(next_elec);
+    TSI0->DATA = ((next_elec->getChannel() << TSI_DATA_TSICH_SHIFT) );
+    TSI0->DATA |= TSI_DATA_SWTS_MASK;
+}
+
+
+void tsi_irq(void)
+{
+    TSIAnalogSlider *analog_slider = TSIAnalogSlider::getInstance();
+    analog_slider->setScan(1);
+    TSI0->GENCS |= TSI_GENCS_EOSF_MASK; // Clear End of Scan Flag
+    changeElectrode(analog_slider);
+}