Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: kl25z-tinyshell-demo tsi_slider_light_senso_LED frdm_tsi_slider_led_blend demo_slider ... more
Revision 0:9331e373c138, committed 2014-02-22
- Comitter:
- Kojto
- Date:
- Sat Feb 22 11:07:29 2014 +0000
- Child:
- 1:8a2098a10330
- Commit message:
- the initial version of TSI sensor library. It contains TSI electrode and TSI Analog slider objects.
Changed in this revision
| tsi_sensor.cpp | Show annotated file Show diff for this revision Revisions of this file |
| tsi_sensor.h | Show annotated file Show diff for this revision Revisions of this file |
--- /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);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tsi_sensor.h Sat Feb 22 11:07:29 2014 +0000
@@ -0,0 +1,198 @@
+/* Freescale Semiconductor Inc.
+ *
+ * mbed Microcontroller Library
+ * (c) Copyright 2009-2012 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.
+ */
+
+#ifndef TSISENSOR_H
+#define TSISENSOR_H
+
+/**
+* TSISensor example
+*
+* @code
+* #include "mbed.h"
+* #include "TSISensor.h"
+*
+* int main(void) {
+* DigitalOut led(LED_GREEN);
+* TSIElectrode elec0(9);
+* TSIElectrode elec1(10);
+* TSIAnalogSlider tsi(elec0, elec1, 40);
+*
+* while (true) {
+* printf("slider percentage: %f%\r\n", tsi.readPercentage());
+* printf("slider distance: %dmm\r\n", tsi.readDistance());
+* wait(1);
+* led = !led;
+* }
+* }
+* @endcode
+*/
+#define NO_TOUCH 0
+
+/** TSI Electrode with simple data required for touch detection.
+ */
+class TSIElectrode {
+public:
+ /** Initialize electrode.
+ */
+ TSIElectrode(uint32_t tsi_channel) : _threshold(100) {
+ _channel = (uint8_t)tsi_channel;
+ }
+ /** Set baseline.
+ */
+ void setBaseline(uint32_t baseline) {
+ _baseline = (uint16_t)baseline;
+ }
+ /** Set threshold.
+ */
+ void setThreshold(uint32_t threshold) {
+ _threshold = (uint16_t)threshold;
+ }
+ /** Set signal.
+ */
+ void setSignal(uint32_t signal) {
+ _signal = (uint16_t)signal;
+ }
+ /** Get baseline.
+ */
+ uint32_t getBaseline() {
+ return _baseline;
+ }
+ /** Get delta.
+ */
+ uint32_t getDelta() {
+ int32_t delta = getSignal() - getBaseline();
+ if (delta < 0) {
+ return 0;
+ } else {
+ return delta;
+ }
+ }
+ /** Get signal.
+ */
+ uint32_t getSignal() {
+ return _signal;
+ }
+ /** Get threshold.
+ */
+ uint32_t getThreshold() {
+ return _threshold;
+ }
+ /** Get channel.
+ */
+ uint32_t getChannel() {
+ return _channel;
+ }
+private:
+ uint8_t _channel;
+ uint16_t _signal;
+ uint16_t _baseline;
+ uint16_t _threshold;
+};
+
+/** Analog slider which consists of two electrodes.
+ */
+class TSIAnalogSlider {
+public:
+ /**
+ * Initialize the TSI Touch Sensor
+ */
+ TSIAnalogSlider(TSIElectrode& elec0, TSIElectrode& elec1, uint32_t range);
+ /**
+ * Read Touch Sensor percentage value
+ *
+ * @returns percentage value between [0 ... 1]
+ */
+ float readPercentage();
+ /**
+ * Read Touch Sensor distance
+ *
+ * @returns distance in mm. The value is between [0 ... _range]
+ */
+ uint32_t readDistance();
+ /** Get current electrode.
+ */
+ TSIElectrode* getCurrentElectrode() {
+ return _current_elec;
+ }
+ /** Set current electrode which is being measured.
+ */
+ void setCurrentElectrode(TSIElectrode *elec){
+ _current_elec = elec;
+ }
+ /** Get next electrode.
+ */
+ TSIElectrode* getNextElectrode(TSIElectrode* electrode) {
+ if (electrode->getChannel() == _elec0.getChannel()) {
+ return &_elec1;
+ } else {
+ return &_elec0;
+ }
+ }
+ /** Return absolute distance position.
+ */
+ uint32_t getAbsoluteDistance() {
+ return _absolute_distance_pos;
+ }
+ /** Return absolute precentage position.
+ */
+ uint32_t getAbsolutePosition() {
+ return _absolute_percentage_pos;
+ }
+ /** Set value to the scan in progress flag.
+ */
+ void setScan(uint32_t scan) {
+ _scan_in_progress = scan;
+ }
+ /** Return instance to Analog slider. Used in tsi irq.
+ */
+ static TSIAnalogSlider *getInstance() {
+ return _instance;
+ }
+private:
+ void sliderRead(void);
+ void selfCalibration(void);
+ void setSliderPercPosition(uint32_t elec_num, uint32_t position) {
+ _percentage_position[elec_num] = position;
+ }
+ void setSliderDisPosition(uint32_t elec_num, uint32_t position) {
+ _distance_position[elec_num] = position;
+ }
+ void setAbsolutePosition(uint32_t position) {
+ _absolute_percentage_pos = position;
+ }
+ void setAbsoluteDistance(uint32_t distance) {
+ _absolute_distance_pos = distance;
+ }
+private:
+ TSIElectrode _elec0;
+ TSIElectrode _elec1;
+ uint8_t _scan_in_progress;
+ TSIElectrode* _current_elec;
+ uint8_t _percentage_position[2];
+ uint8_t _distance_position[2];
+ uint32_t _absolute_percentage_pos;
+ uint32_t _absolute_distance_pos;
+ uint8_t _range;
+protected:
+ static TSIAnalogSlider *_instance;
+};
+
+#endif