1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
| #pragma once
// DEFINE HERE THE PIN USED --------------------------------------------------------------
#if defined(ARDUINO_AVR_UNO)
#define T_IRQ 5 // (PD5)
#define T_CS 2 // (PD2)
#define T_DOUT 7 // (PD7) MISO
#define T_DIN 6 // (PD6) MOSI
#define T_CLK 1 // (PD1)
#else
// ARDUINO MEGA
// FONCTIONNE CORRECTEMENT :
// #define T_IRQ 33 // (PC4)
// #define T_CS 34 // (PC3)
// #define T_DOUT 35 // (PC2) MISO
// #define T_DIN 36 // (PC1) MOSI
// #define T_CLK 37 // (PC0)
// NE FONCTIONNE PAS :
#define T_IRQ 42 // (PL7)
#define T_CS 43 // (PL6)
#define T_DOUT 44 // (PL5) MISO
#define T_DIN 45 // (PL4) MOSI
#define T_CLK 46 // (PL3)
// AVEC L'ECRAN TFT BRANCHE AINSI SUR L'ARDUINO MEGA :
// ILI9341_CS_PIN 49 (PL0)
// ILI9341_DC_PIN 48 (PL1)
// ILI9341_RST_PIN 47 (PL2)
// ILI9341_MISO 50 (PB3) No choice, Mega Hardware SPI MISO
// ILI9341_MOSI 51 (PB2) No choice, Mega Hardware SPI MOSI
// ILI9341_CK 52 (PB1) No choice, Mega Hardware SPI CK
#endif
// ---------------------------------------------------------------------------------------
#if !defined(TFT_SIZE_WIDTH)
#define TFT_SIZE_WIDTH 240
#endif
#if !defined(TFT_SIZE_HEIGHT)
#define TFT_SIZE_HEIGHT 320
#endif
#define PORTRAIT 0
#define LANDSCAPE 1
// Now calibration data is saved on EEPROM, and calibration software is included in the "setup menu" of the interface :-)
// So you don't have to burn a separate calibration sketch and include calibration data in the INO file for each bord and each screen
int touch_x_left, touch_x_right, touch_y_top, touch_y_bottom;
// Hardware specific defines
#define TOUCH_SAVE_PCR 1
#if (TOUCH_SAVE_PCR)
#define cbi(reg, bitmask) oldSREG = SREG; cli(); *reg &= ~bitmask; SREG = oldSREG
#define sbi(reg, bitmask) oldSREG = SREG; cli(); *reg |= bitmask; SREG = oldSREG
#define rbi(reg, bitmask) ((*reg) & bitmask)
#define pulse_high(reg, bitmask) oldSREG = SREG; cli(); *reg |= bitmask; *reg &= ~bitmask; SREG = oldSREG
#define pulse_low(reg, bitmask) oldSREG = SREG; cli(); *reg &= ~bitmask; *reg |= bitmask; SREG = oldSREG
#else
#define cbi(reg, bitmask) *reg &= ~bitmask
#define sbi(reg, bitmask) *reg |= bitmask
#define rbi(reg, bitmask) ((*reg) & bitmask)
#define pulse_high(reg, bitmask) sbi(reg, bitmask); cbi(reg, bitmask)
#define pulse_low(reg, bitmask) cbi(reg, bitmask); sbi(reg, bitmask)
#endif
#define regtype volatile uint8_t
#define regsize uint8_t
#define PREC_LOW 1
#define URTouch_Prec 102
class URTouch {
public:
int16_t TP_X ,TP_Y;
void InitTouch(byte orientation);
bool read();
bool dataAvailable();
int16_t getX();
int16_t getY();
void calibrateRead();
byte FutureOrientation;
void UpdateOrientation();
private:
regtype *P_CLK, *P_CS, *P_DIN, *P_DOUT, *P_IRQ;
regsize B_CLK, B_CS, B_DIN, B_DOUT, B_IRQ;
int disp_x_size, disp_y_size;
void touch_WriteData(byte data);
word touch_ReadData();
byte orient;
};
void URTouch::touch_WriteData(byte data) {
byte temp;
temp=data;
#if TOUCH_SAVE_PCR
byte oldSREG;
#endif
cbi(P_CLK, B_CLK);
for(byte count=0; count<8; count++) {
if(temp & 0x80) {
sbi(P_DIN, B_DIN);
} else {
cbi(P_DIN, B_DIN);
}
temp = temp << 1;
cbi(P_CLK, B_CLK);
sbi(P_CLK, B_CLK);
}
}
word URTouch::touch_ReadData() {
word data = 0;
#if TOUCH_SAVE_PCR
byte oldSREG;
#endif
for(byte count=0; count<12; count++) {
data <<= 1;
sbi(P_CLK, B_CLK);
cbi(P_CLK, B_CLK);
if (rbi(P_DOUT, B_DOUT)) data++;
}
return(data);
}
void URTouch::UpdateOrientation() {
orient = FutureOrientation;
}
void URTouch::InitTouch(byte orientation) {
FutureOrientation = orientation;
orient = orientation;
disp_x_size = TFT_SIZE_WIDTH-1;
disp_y_size = TFT_SIZE_HEIGHT-1;
P_CLK = portOutputRegister(digitalPinToPort(T_CLK));
B_CLK = digitalPinToBitMask(T_CLK);
P_CS = portOutputRegister(digitalPinToPort(T_CS));
B_CS = digitalPinToBitMask(T_CS);
P_DIN = portOutputRegister(digitalPinToPort(T_DIN));
B_DIN = digitalPinToBitMask(T_DIN);
P_DOUT = portInputRegister(digitalPinToPort(T_DOUT));
B_DOUT = digitalPinToBitMask(T_DOUT);
P_IRQ = portInputRegister(digitalPinToPort(T_IRQ));
B_IRQ = digitalPinToBitMask(T_IRQ);
pinMode(T_CLK, OUTPUT);
pinMode(T_CS, OUTPUT);
pinMode(T_DIN, OUTPUT);
pinMode(T_DOUT, INPUT);
pinMode(T_IRQ, OUTPUT);
#if TOUCH_SAVE_PCR
byte oldSREG;
#endif
sbi(P_CS, B_CS);
sbi(P_CLK, B_CLK);
sbi(P_DIN, B_DIN);
sbi(P_IRQ, B_IRQ);
}
bool URTouch::read() {
unsigned long tx=0, temp_x=0;
unsigned long ty=0, temp_y=0;
unsigned long minx=99999, maxx=0;
unsigned long miny=99999, maxy=0;
byte datacount=0;
#if TOUCH_SAVE_PCR
byte oldSREG;
#endif
cbi(P_CS, B_CS);
pinMode(T_IRQ, INPUT);
for (byte i=0; i<URTouch_Prec; i++) {
if (!rbi(P_IRQ, B_IRQ)) {
touch_WriteData(0x90);
pulse_high(P_CLK, B_CLK);
temp_x = touch_ReadData();
if (!rbi(P_IRQ, B_IRQ)) {
touch_WriteData(0xD0);
pulse_high(P_CLK, B_CLK);
temp_y = touch_ReadData();
if ((temp_x>0) and (temp_x<4096) and (temp_y>0) and (temp_y<4096)) {
tx += temp_x;
ty += temp_y;
if (temp_x<minx) minx = temp_x;
if (temp_x>maxx) maxx = temp_x;
if (temp_y<miny) miny = temp_y;
if (temp_y>maxy) maxy = temp_y;
datacount++;
}
}
}
}
pinMode(T_IRQ, OUTPUT);
tx -= minx + maxx;
ty -= miny + maxy;
datacount -= 2;
sbi(P_CS, B_CS);
if ((datacount==(URTouch_Prec-2)) or (datacount==PREC_LOW)) {
if (orient == PORTRAIT) {
TP_X = ty/datacount;
TP_Y = tx/datacount;
} else {
TP_X = tx/datacount;
TP_Y = ty/datacount;
}
return true;
} else {
return false;
}
}
bool URTouch::dataAvailable() {
bool avail;
pinMode(T_IRQ, INPUT);
avail = !(rbi(P_IRQ, B_IRQ));
pinMode(T_IRQ, OUTPUT);
return avail;
}
int16_t URTouch::getX() {
int c;
if (orient == PORTRAIT) {
c = long(long(TP_X - touch_x_left) * (disp_x_size)) / long(touch_x_right - touch_x_left);
} else {
c = long(long(TP_X - touch_y_top) * (-disp_y_size)) / long(touch_y_bottom - touch_y_top) + long(disp_y_size);
}
return c;
}
int16_t URTouch::getY() {
int c;
if (orient == PORTRAIT) {
c = long(long(TP_Y - touch_y_top) * (disp_y_size)) / long(touch_y_bottom - touch_y_top);
} else {
c = long(long(TP_Y - touch_x_left) * (disp_x_size)) / long(touch_x_right - touch_x_left);
}
return c;
}
void URTouch::calibrateRead() {
unsigned long tx=0;
unsigned long ty=0;
#if TOUCH_SAVE_PCR
byte oldSREG;
#endif
cbi(P_CS, B_CS);
touch_WriteData(0x90);
pulse_high(P_CLK, B_CLK);
tx=touch_ReadData();
touch_WriteData(0xD0);
pulse_high(P_CLK, B_CLK);
ty=touch_ReadData();
sbi(P_CS, B_CS);
TP_X=ty;
TP_Y=tx;
} |
Partager