PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

355 line
9.0KB

  1. /***************************************************
  2. This is a library for the Adafruit STMPE610 Resistive
  3. touch screen controller breakout
  4. ----> http://www.adafruit.com/products/1571
  5. Check out the links above for our tutorials and wiring diagrams
  6. These breakouts use SPI or I2C to communicate
  7. Adafruit invests time and resources providing this open source code,
  8. please support Adafruit and open-source hardware by purchasing
  9. products from Adafruit!
  10. Written by Limor Fried/Ladyada for Adafruit Industries.
  11. MIT license, all text above must be included in any redistribution
  12. ****************************************************/
  13. #if ARDUINO >= 100
  14. #include "Arduino.h"
  15. #else
  16. #include "WProgram.h"
  17. #endif
  18. #include <Wire.h>
  19. #include <SPI.h>
  20. #include "Adafruit_STMPE610.h"
  21. #if defined (SPI_HAS_TRANSACTION)
  22. // SPI transaction support allows managing SPI settings and prevents
  23. // conflicts between libraries, with a hardware-neutral interface
  24. static SPISettings mySPISettings;
  25. #elif defined (__AVR__)
  26. static uint8_t SPCRbackup;
  27. static uint8_t mySPCR;
  28. #endif
  29. /**************************************************************************/
  30. /*!
  31. @brief Instantiates a new STMPE610 class
  32. */
  33. /**************************************************************************/
  34. // software SPI
  35. Adafruit_STMPE610::Adafruit_STMPE610(uint8_t cspin, uint8_t mosipin, uint8_t misopin, uint8_t clkpin) {
  36. _CS = cspin;
  37. _MOSI = mosipin;
  38. _MISO = misopin;
  39. _CLK = clkpin;
  40. }
  41. // hardware SPI
  42. Adafruit_STMPE610::Adafruit_STMPE610(uint8_t cspin) {
  43. _CS = cspin;
  44. _MOSI = _MISO = _CLK = -1;
  45. }
  46. // I2C
  47. Adafruit_STMPE610::Adafruit_STMPE610() {
  48. // use i2c
  49. _CS = -1;
  50. }
  51. /**************************************************************************/
  52. /*!
  53. @brief Setups the HW
  54. */
  55. /**************************************************************************/
  56. boolean Adafruit_STMPE610::begin(uint8_t i2caddr) {
  57. if (_CS != -1 && _CLK == -1) {
  58. // hardware SPI
  59. pinMode(_CS, OUTPUT);
  60. digitalWrite(_CS, HIGH);
  61. #if defined (SPI_HAS_TRANSACTION)
  62. SPI.begin();
  63. mySPISettings = SPISettings(1000000, MSBFIRST, SPI_MODE0);
  64. #elif defined (__AVR__)
  65. SPCRbackup = SPCR;
  66. SPI.begin();
  67. SPI.setClockDivider(SPI_CLOCK_DIV16);
  68. SPI.setDataMode(SPI_MODE0);
  69. mySPCR = SPCR; // save our preferred state
  70. //Serial.print("mySPCR = 0x"); Serial.println(SPCR, HEX);
  71. SPCR = SPCRbackup; // then restore
  72. #elif defined (__arm__)
  73. SPI.begin();
  74. SPI.setClockDivider(84);
  75. SPI.setDataMode(SPI_MODE0);
  76. #endif
  77. m_spiMode = SPI_MODE0;
  78. } else if (_CS != -1) {
  79. // software SPI
  80. pinMode(_CLK, OUTPUT);
  81. pinMode(_CS, OUTPUT);
  82. pinMode(_MOSI, OUTPUT);
  83. pinMode(_MISO, INPUT);
  84. } else {
  85. Wire.begin();
  86. _i2caddr = i2caddr;
  87. }
  88. // try mode0
  89. if (getVersion() != 0x811) {
  90. if (_CS != -1 && _CLK == -1) {
  91. //Serial.println("try MODE1");
  92. #if defined (SPI_HAS_TRANSACTION)
  93. mySPISettings = SPISettings(1000000, MSBFIRST, SPI_MODE1);
  94. #elif defined (__AVR__)
  95. SPCRbackup = SPCR;
  96. SPI.begin();
  97. SPI.setDataMode(SPI_MODE1);
  98. SPI.setClockDivider(SPI_CLOCK_DIV16);
  99. mySPCR = SPCR; // save our new preferred state
  100. //Serial.print("mySPCR = 0x"); Serial.println(SPCR, HEX);
  101. SPCR = SPCRbackup; // then restore
  102. #elif defined (__arm__)
  103. SPI.setClockDivider(84);
  104. SPI.setDataMode(SPI_MODE1);
  105. #endif
  106. m_spiMode = SPI_MODE1;
  107. if (getVersion() != 0x811) {
  108. return false;
  109. }
  110. } else {
  111. return false;
  112. }
  113. }
  114. writeRegister8(STMPE_SYS_CTRL1, STMPE_SYS_CTRL1_RESET);
  115. delay(10);
  116. for (uint8_t i=0; i<65; i++) {
  117. readRegister8(i);
  118. }
  119. writeRegister8(STMPE_SYS_CTRL2, 0x0); // turn on clocks!
  120. writeRegister8(STMPE_TSC_CTRL, STMPE_TSC_CTRL_XYZ | STMPE_TSC_CTRL_EN); // XYZ and enable!
  121. //Serial.println(readRegister8(STMPE_TSC_CTRL), HEX);
  122. writeRegister8(STMPE_INT_EN, STMPE_INT_EN_TOUCHDET);
  123. writeRegister8(STMPE_ADC_CTRL1, STMPE_ADC_CTRL1_10BIT | (0x6 << 4)); // 96 clocks per conversion
  124. writeRegister8(STMPE_ADC_CTRL2, STMPE_ADC_CTRL2_6_5MHZ);
  125. writeRegister8(STMPE_TSC_CFG, STMPE_TSC_CFG_4SAMPLE | STMPE_TSC_CFG_DELAY_1MS | STMPE_TSC_CFG_SETTLE_5MS);
  126. writeRegister8(STMPE_TSC_FRACTION_Z, 0x6);
  127. writeRegister8(STMPE_FIFO_TH, 1);
  128. writeRegister8(STMPE_FIFO_STA, STMPE_FIFO_STA_RESET);
  129. writeRegister8(STMPE_FIFO_STA, 0); // unreset
  130. writeRegister8(STMPE_TSC_I_DRIVE, STMPE_TSC_I_DRIVE_50MA);
  131. writeRegister8(STMPE_INT_STA, 0xFF); // reset all ints
  132. writeRegister8(STMPE_INT_CTRL, STMPE_INT_CTRL_POL_HIGH | STMPE_INT_CTRL_ENABLE);
  133. #if defined (__AVR__) && !defined (SPI_HAS_TRANSACTION)
  134. if (_CS != -1 && _CLK == -1)
  135. SPCR = SPCRbackup; // restore SPI state
  136. #endif
  137. return true;
  138. }
  139. boolean Adafruit_STMPE610::touched(void) {
  140. return (readRegister8(STMPE_TSC_CTRL) & 0x80);
  141. }
  142. boolean Adafruit_STMPE610::bufferEmpty(void) {
  143. return (readRegister8(STMPE_FIFO_STA) & STMPE_FIFO_STA_EMPTY);
  144. }
  145. uint8_t Adafruit_STMPE610::bufferSize(void) {
  146. return readRegister8(STMPE_FIFO_SIZE);
  147. }
  148. uint16_t Adafruit_STMPE610::getVersion() {
  149. uint16_t v;
  150. //Serial.print("get version");
  151. v = readRegister8(0);
  152. v <<= 8;
  153. v |= readRegister8(1);
  154. //Serial.print("Version: 0x"); Serial.println(v, HEX);
  155. return v;
  156. }
  157. /*****************************/
  158. void Adafruit_STMPE610::readData(uint16_t *x, uint16_t *y, uint8_t *z) {
  159. uint8_t data[4];
  160. for (uint8_t i=0; i<4; i++) {
  161. data[i] = readRegister8(0xD7); //SPI.transfer(0x00);
  162. // Serial.print("0x"); Serial.print(data[i], HEX); Serial.print(" / ");
  163. }
  164. *x = data[0];
  165. *x <<= 4;
  166. *x |= (data[1] >> 4);
  167. *y = data[1] & 0x0F;
  168. *y <<= 8;
  169. *y |= data[2];
  170. *z = data[3];
  171. if (bufferEmpty())
  172. writeRegister8(STMPE_INT_STA, 0xFF); // reset all ints
  173. }
  174. TS_Point Adafruit_STMPE610::getPoint(void) {
  175. uint16_t x, y;
  176. uint8_t z;
  177. readData(&x, &y, &z);
  178. return TS_Point(x, y, z);
  179. }
  180. uint8_t Adafruit_STMPE610::spiIn() {
  181. if (_CLK == -1) {
  182. #if defined (SPI_HAS_TRANSACTION)
  183. uint8_t d = SPI.transfer(0);
  184. return d;
  185. #elif defined (__AVR__)
  186. SPCRbackup = SPCR;
  187. SPCR = mySPCR;
  188. uint8_t d = SPI.transfer(0);
  189. SPCR = SPCRbackup;
  190. return d;
  191. #elif defined (__arm__)
  192. SPI.setClockDivider(84);
  193. SPI.setDataMode(m_spiMode);
  194. uint8_t d = SPI.transfer(0);
  195. return d;
  196. #endif
  197. }
  198. else
  199. return shiftIn(_MISO, _CLK, MSBFIRST);
  200. }
  201. void Adafruit_STMPE610::spiOut(uint8_t x) {
  202. if (_CLK == -1) {
  203. #if defined (SPI_HAS_TRANSACTION)
  204. SPI.transfer(x);
  205. #elif defined (__AVR__)
  206. SPCRbackup = SPCR;
  207. SPCR = mySPCR;
  208. SPI.transfer(x);
  209. SPCR = SPCRbackup;
  210. #elif defined (__arm__)
  211. SPI.setClockDivider(84);
  212. SPI.setDataMode(m_spiMode);
  213. SPI.transfer(x);
  214. #endif
  215. }
  216. else
  217. shiftOut(_MOSI, _CLK, MSBFIRST, x);
  218. }
  219. uint8_t Adafruit_STMPE610::readRegister8(uint8_t reg) {
  220. uint8_t x ;
  221. if (_CS == -1) {
  222. // use i2c
  223. Wire.beginTransmission(_i2caddr);
  224. Wire.write((byte)reg);
  225. Wire.endTransmission();
  226. Wire.beginTransmission(_i2caddr);
  227. Wire.requestFrom(_i2caddr, (byte)1);
  228. x = Wire.read();
  229. Wire.endTransmission();
  230. //Serial.print("$"); Serial.print(reg, HEX);
  231. //Serial.print(": 0x"); Serial.println(x, HEX);
  232. } else {
  233. #if defined (SPI_HAS_TRANSACTION)
  234. if (_CLK == -1) SPI.beginTransaction(mySPISettings);
  235. #endif
  236. digitalWrite(_CS, LOW);
  237. spiOut(0x80 | reg);
  238. spiOut(0x00);
  239. x = spiIn();
  240. digitalWrite(_CS, HIGH);
  241. #if defined (SPI_HAS_TRANSACTION)
  242. if (_CLK == -1) SPI.endTransaction();
  243. #endif
  244. }
  245. return x;
  246. }
  247. uint16_t Adafruit_STMPE610::readRegister16(uint8_t reg) {
  248. uint16_t x = 0;
  249. if (_CS == -1) {
  250. // use i2c
  251. Wire.beginTransmission(_i2caddr);
  252. Wire.write((byte)reg);
  253. Wire.endTransmission();
  254. Wire.requestFrom(_i2caddr, (byte)2);
  255. x = Wire.read();
  256. x<<=8;
  257. x |= Wire.read();
  258. Wire.endTransmission();
  259. } if (_CLK == -1) {
  260. // hardware SPI
  261. #if defined (SPI_HAS_TRANSACTION)
  262. if (_CLK == -1) SPI.beginTransaction(mySPISettings);
  263. #endif
  264. digitalWrite(_CS, LOW);
  265. spiOut(0x80 | reg);
  266. spiOut(0x00);
  267. x = spiIn();
  268. x<<=8;
  269. x |= spiIn();
  270. digitalWrite(_CS, HIGH);
  271. #if defined (SPI_HAS_TRANSACTION)
  272. if (_CLK == -1) SPI.endTransaction();
  273. #endif
  274. }
  275. //Serial.print("$"); Serial.print(reg, HEX);
  276. //Serial.print(": 0x"); Serial.println(x, HEX);
  277. return x;
  278. }
  279. void Adafruit_STMPE610::writeRegister8(uint8_t reg, uint8_t val) {
  280. if (_CS == -1) {
  281. // use i2c
  282. Wire.beginTransmission(_i2caddr);
  283. Wire.write((byte)reg);
  284. Wire.write(val);
  285. Wire.endTransmission();
  286. } else {
  287. #if defined (SPI_HAS_TRANSACTION)
  288. if (_CLK == -1) SPI.beginTransaction(mySPISettings);
  289. #endif
  290. digitalWrite(_CS, LOW);
  291. spiOut(reg);
  292. spiOut(val);
  293. digitalWrite(_CS, HIGH);
  294. #if defined (SPI_HAS_TRANSACTION)
  295. if (_CLK == -1) SPI.endTransaction();
  296. #endif
  297. }
  298. }
  299. /****************/
  300. TS_Point::TS_Point(void) {
  301. x = y = 0;
  302. }
  303. TS_Point::TS_Point(int16_t x0, int16_t y0, int16_t z0) {
  304. x = x0;
  305. y = y0;
  306. z = z0;
  307. }
  308. bool TS_Point::operator==(TS_Point p1) {
  309. return ((p1.x == x) && (p1.y == y) && (p1.z == z));
  310. }
  311. bool TS_Point::operator!=(TS_Point p1) {
  312. return ((p1.x != x) || (p1.y != y) || (p1.z != z));
  313. }