Fork of tsi_sensor library that allows object construction with pin names instead of TSI channels
Fork of tsi_sensor by
tsi_sensor.cpp
- Committer:
- Kojto
- Date:
- 2014-02-22
- Revision:
- 0:9331e373c138
- Child:
- 1:8a2098a10330
File content as of revision 0:9331e373c138:
/* 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); }