This is a VERY low-level library for controlling the TSI hardware module in a KL25 microcontroller. The programmer creates the TSI object passing basic parameters, and selects the active channels. Then, a scan on a given channel can be started, and the raw result can be read.
Revision 0:b39f4f954a9b, committed 2014-09-24
- Comitter:
- quevedo
- Date:
- Wed Sep 24 18:48:10 2014 +0000
- Child:
- 1:532aa572220b
- Commit message:
- First version of the low-level library; interrupts not active, does not run in STOP modes
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Registers.txt Wed Sep 24 18:48:10 2014 +0000 @@ -0,0 +1,51 @@ +/* +TSI REGISTERS +------------------------------------------ + +TSI0_GENCS: +Bit 31: OUTRGF; Out-of-range flag; set if result register is out of the range given by TSI_THRESHOLD; write 1 to clear +Bit 28: ESOR; Selector for End-of-scan (set) or out-of-range (clear) interrupt source +Bits 27-24: MODE; defines analog mode; keep bits 25-24 to 00 + 0000: capacitive sensing (non-noise detection) + 0100: Single threshold noise detection mode; frequency limitation disabled + 1000: Single threshold noise detection mode; frequency limitation enabled + 1100: Automatic noise detection mode +Bits 23-21: REFCHRG; current value for charging the reference oscillator + 000: 500nA + 001: 1uA + 010: 2uA + 011: 4uA + 100: 8uA + 101: 16uA + 110: 32uA + 111: 64uA +Bits 20-19: DVOLT; oscillator's voltage rails + 00: DV = 1.03V; Vp = 1.33V; Vm = 0.30V + 01: DV = 0.73V; Vp = 1.18V; Vm = 0.45V + 10: DV = 0.43V; Vp = 1.03V; Vm = 0.60V + 11: DV = 0.29V; Vp = 0.95V; Vm = 0.67V +Bits 18-16: EXTCHRG; current value for charging the electrode oscillator + Same values as for REFCHRG +Bits 15-13: PS; electrode oscillator prescaler + Value is 2 to the power of the number given by the three bits (0-7) +Bits 12-8: NSCN; Number of scans for each electrode + Value is the number given by the five bits (0-31) plus 1. +Bit 7: TSIEN; TSI enable; set to enable +Bit 6: TSIIEN; TSI interrupt enable; set to enable +Bit 5: STPE; STOP enable; set to allow TSI to run in low-power modes +Bit 4: STM; Scan Trigger Mode; clear to software and set to hardware +Bit 3: SCNIP; Scan In Progress status; set if there is a scan in progress +Bit 2: EOSF; End of Scan Flag; set if scan complete +Bit 1: CURSW; Current sources swapped; set if swapped + +TSI0_DATA: +Bits 31-28: TSICH; current channel to be measured (4 bits, values 0 to 15) +Bit 23: DMAEN; DMA enabled; set for DMA transfer instead of interrupt +Bit 22: SWTS; Software Trigger Start; write 1 to start scan if software trigger was selected +Bit 15-0: TSICNT; TSI Conversion Counter; record the accumulated scan counter value ticked by the reference oscillator + +TSI0_TSHD: +Threshold value +---------------------------------------------------- + +*/ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TSIHW.cpp Wed Sep 24 18:48:10 2014 +0000 @@ -0,0 +1,59 @@ +#include "mbed.h" +#include "TSIHW.h" + +/* TSI constructor +Parameters: the values of the fields REFCHRG, EXTCHRG, DVOLT, PS, and NSCN from TSI0_GENCS register +Not using interrupts, capacitive sensing (non-noise detection), not configured to work in STOP modes +*/ +TSI::TSI(char rchg, char echg, char dvolt, char ps, char nscn) { + // The first version is preconfigured for non-noise detection, no interrupts, not running on stop modes, software trigger + SIM->SCGC5 |= 0x00000020; // clock gate for TSI + TSI0->GENCS = 0xC0000080 | ((rchg & 0x07) << 21) | ((echg & 0x07) << 16) | ((dvolt & 0x03) << 19) | ((ps & 0x07) << 13) | ((nscn & 0x1F) << 8); +} + +/* TSI destructor */ +TSI::~TSI() { } + +/* Function to configure a pin to work with the corresponding channel (passed as the single parameter) */ +void TSI::ActivateChannel(char ch) { + // reads channel number and sets the MUX of the corresponding pin to ALT0 function + switch(ch) { + case 0: PORTB->PCR[0] &= 0xFFFFF8FF; break; + case 1: PORTA->PCR[0] &= 0xFFFFF8FF; break; + case 2: PORTA->PCR[1] &= 0xFFFFF8FF; break; + case 3: PORTA->PCR[2] &= 0xFFFFF8FF; break; + case 4: PORTA->PCR[3] &= 0xFFFFF8FF; break; + case 5: PORTA->PCR[4] &= 0xFFFFF8FF; break; + case 6: PORTB->PCR[1] &= 0xFFFFF8FF; break; + case 7: PORTB->PCR[2] &= 0xFFFFF8FF; break; + case 8: PORTB->PCR[3] &= 0xFFFFF8FF; break; + case 9: PORTB->PCR[16] &= 0xFFFFF8FF; break; + case 10: PORTB->PCR[17] &= 0xFFFFF8FF; break; + case 11: PORTB->PCR[18] &= 0xFFFFF8FF; break; + case 12: PORTB->PCR[19] &= 0xFFFFF8FF; break; + case 13: PORTC->PCR[0] &= 0xFFFFF8FF; break; + case 14: PORTC->PCR[1] &= 0xFFFFF8FF; break; + case 15: PORTC->PCR[2] &= 0xFFFFF8FF; break; + default: error("PinName provided to TSI::ActivateChannel() does not correspond to any known TSI channel."); + } +} + +// Function to trigger the reading of a given channel +void TSI::Start(char ch) { + //writes 1 to the software trigger bit, defining the channel number in the respective bits + TSI0->GENCS |= 0x00000004; // clears EOSF + TSI0->DATA = 0x00400000 | (ch << 28); +} + +// Function to read scan result; returns zero if not finished +uint16_t TSI::Read() { + uint16_t aux; + + if(!(TSI0->GENCS & 0x00000004)) { + return 0; + } else { + aux = TSI0->DATA & 0x0000FFFF; + TSI0->GENCS |= 0x00000004; // clears EOSF + return aux; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TSIHW.h Wed Sep 24 18:48:10 2014 +0000 @@ -0,0 +1,50 @@ +#ifndef TSIHW_H +#define TSIHW_H + +#include "mbed.h" +/** +* KL25 TSI low-level library with very basic functions +* +* @code +* #include "mbed.h" +* #include "TSIHW.h" +* +* TSI touch(0,0,0,2,2); +* Serial pc(USBTX, USBRX); +* +* int main() { +* uint16_t s; +* +* pc.printf("BEGIN\r\n"); +* touch.ActivateChannel(5); // Electrode connected to PTA4 +* pc.printf("ACTIVATE\r\n"); +* while(1) { +* s = 0; +* touch.Start(5); +* pc.printf("START\r\n"); +* while(!s) { +* s = touch.Read(); +* } +* pc.printf("TOUCH: %d\r\n", s); +* wait(1); +* } +* } +* @endcode +*/ + + +class TSI +{ +public: + TSI(char rchg, char echg, char dvolt, char ps, char nscn); + + ~TSI(); + + void ActivateChannel(char ch); + + void Start(char ch); + + uint16_t Read(void); + +}; +#endif