Source file: /~heha/Mikrocontroller/Displays/utft/Kalender.zip/ILI9341/TouchScreen1.cpp

#include "TouchScreen.h"

#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>

#define NUMSAMPLES 2

// Interruptbedienroutine für Pin-Change (Touchscreen)
// Tut nichts als den Prozessor aufzuwecken

EMPTY_INTERRUPT(PCINT2_vect);
EMPTY_INTERRUPT(ADC_vect);

void TouchScreen::Init() {	// nichts tun!
// Vorausgesetzt sei, dass die beteiligten Pins für das Display
// bereits initialisiert (für Ausgabe) sind
 PCMSK2|=0x80;	// PCINT23 heißmachen
}

// "Ruhezustand" aktivieren
// TODO: Input Disable Register setzen (spart paar µA)
static void setIdling() {
 DDRD&=~0x80;	// Y- = Z
 PORTD=0x80;	// Y- = HiZ, Y+ = L
 DDRC&=~0x02;
 PORTC&=~0x02;	// Y+ = Z
 PORTC&=~0x04;	// X+ = L
 _delay_us(0.5);
}

// Ausgangszustand wiederherstellen
static void restorePorts() {
 DDRD|=0xC0;	// Ausgang
 PORTC|=0x06;	// HIGH
 DDRC|=0x06;	// Ausgang
}

bool TouchScreen::isTouching() {
 setIdling();
 bool ret=!(PIND&0x80);	// Drück-Zustand einlesen (TRUE wenn LOW)
 restorePorts();
 return ret;
}

uint16_t TouchScreen::readTouch(uint8_t b) {
 ADCSRA=0x9F;	// A/D-Wandler aktivieren mit Teiler 128 -> Taktfrequenz 125 kHz
 if (b) {	// Y messen
  DDRC&=~0x02;	PORTC&=~0x02;	// X- = Z
		PORTC&=~0x04;	// Y- = L
  DDRD&=~0x80;	PORTD&=~0x80;	// X+ = Z
		PORTD|= 0x40;	// Y+ = H
  ADMUX=0x41;	// ADC1, sonst wie unten
 }else{		// X messen
		PORTC&=~0x02;	// X- = L
  DDRC&=~0x04;	PORTC&=~0x04;	// Y- = Z
		PORTD|= 0x80;	// X+ = H
  DDRD&=~0x40;	PORTD&=~0x40;	// Y+ = Z
  ADMUX=0x42;	// ADC2, Referenz 5 V, rechts ausgerichtet
 }
 _delay_us(0.5);
 ADCSRA=0xDF;	// A/D-Wandler starten mit Interrupt
 do sleep_cpu();
 while (ADCSRA&0x40);	// warten bis fertig
 uint16_t ret=ADC;
 ADCSRA=0;
 restorePorts();
 return ret;
}

// Hier: Nur für Argument -2: Sleep
bool TouchScreen::wait(int ms) {
 setIdling();
 if (PIND&0x80) {	// Finger nicht drauf?
  PCIFR=0x04;	// Evtl. vorhandenen anhängigen Interrupt löschen
  uint8_t o=PCICR;
  PCICR|=0x04;	// Pegelwechselinterrupt für Touchscreen aktivieren
  sleep_cpu();
  PCICR=o;
 }
 restorePorts();
 return false;
}
Detected encoding: UTF-80