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.

Files at this revision

API Documentation at this revision

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

Registers.txt Show annotated file Show diff for this revision Revisions of this file
TSIHW.cpp Show annotated file Show diff for this revision Revisions of this file
TSIHW.h Show annotated file Show diff for this revision Revisions of this file
--- /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