SPI Emulated DOGM (like FSMC_GRAPHICAL_TFT, but SPI) (#18817)

This commit is contained in:
Victor Oliveira
2020-07-29 23:25:07 -03:00
committed by GitHub
parent 73ce80af3a
commit 38ce5966e1
15 changed files with 546 additions and 129 deletions

View File

@ -23,10 +23,14 @@
#include "xpt2046.h"
#include "../../inc/MarlinConfig.h"
#if ENABLED(FSMC_GRAPHICAL_TFT)
#if TFT_SCALED_DOGLCD
#include "../../lcd/dogm/ultralcd_DOGM.h" // for LCD_FULL_PIXEL_WIDTH, etc.
#endif
#ifndef XPT2046_Z1_THRESHOLD
#define XPT2046_Z1_THRESHOLD 10
#endif
/*
* Draw and Touch processing
@ -117,10 +121,15 @@ uint8_t XPT2046::read_buttons() {
// We rely on XPT2046 compatible mode to ADS7843, hence no Z1 and Z2 measurements possible.
if (!isTouched()) return 0;
const uint16_t x = uint16_t(((uint32_t(getInTouch(XPT2046_X))) * tsoffsets[0]) >> 16) + tsoffsets[1],
y = uint16_t(((uint32_t(getInTouch(XPT2046_Y))) * tsoffsets[2]) >> 16) + tsoffsets[3];
uint16_t x = uint16_t(((uint32_t(getInTouch(XPT2046_X))) * tsoffsets[0]) >> 16) + tsoffsets[1],
y = uint16_t(((uint32_t(getInTouch(XPT2046_Y))) * tsoffsets[2]) >> 16) + tsoffsets[3];
if (!isTouched()) return 0; // Fingers must still be on the TS for a valid read.
#if ENABLED(GRAPHICAL_TFT_ROTATE_180)
x = TOUCH_SCREEN_WIDTH - x;
y = TOUCH_SCREEN_HEIGHT - y;
#endif
// Touch within the button area simulates an encoder button
if (y > BUTTON_AREA_TOP && y < BUTTON_AREA_BOT)
return WITHIN(x, 14, 77) ? EN_D
@ -151,30 +160,69 @@ bool XPT2046::isTouched() {
);
}
#if ENABLED(TOUCH_BUTTONS_HW_SPI)
#include <SPI.h>
static void touch_spi_init(uint8_t spiRate) {
/**
* STM32F1 APB2 = 72MHz, APB1 = 36MHz, max SPI speed of this MCU if 18Mhz
* STM32F1 has 3 SPI ports, SPI1 in APB2, SPI2/SPI3 in APB1
* so the minimum prescale of SPI1 is DIV4, SPI2/SPI3 is DIV2
*/
uint8_t clock;
switch (spiRate) {
case SPI_FULL_SPEED: clock = SPI_CLOCK_DIV4; break;
case SPI_HALF_SPEED: clock = SPI_CLOCK_DIV4; break;
case SPI_QUARTER_SPEED: clock = SPI_CLOCK_DIV8; break;
case SPI_EIGHTH_SPEED: clock = SPI_CLOCK_DIV16; break;
case SPI_SPEED_5: clock = SPI_CLOCK_DIV32; break;
case SPI_SPEED_6: clock = SPI_CLOCK_DIV64; break;
default: clock = SPI_CLOCK_DIV2; // Default from the SPI library
}
SPI.setModule(TOUCH_BUTTONS_HW_SPI_DEVICE);
SPI.begin();
SPI.setClockDivider(clock);
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE0);
}
#endif // TOUCH_BUTTONS_HW_SPI
uint16_t XPT2046::getInTouch(const XPTCoordinate coordinate) {
uint16_t data[3];
OUT_WRITE(TOUCH_CS_PIN, LOW);
const uint8_t coord = uint8_t(coordinate) | XPT2046_CONTROL | XPT2046_DFR_MODE;
for (uint16_t i = 0; i < 3 ; i++) {
for (uint8_t j = 0x80; j; j >>= 1) {
WRITE(TOUCH_SCK_PIN, LOW);
WRITE(TOUCH_MOSI_PIN, bool(coord & j));
WRITE(TOUCH_SCK_PIN, HIGH);
#if ENABLED(TOUCH_BUTTONS_HW_SPI)
touch_spi_init(SPI_SPEED_6);
for (uint16_t i = 0; i < 3; i++) {
OUT_WRITE(TOUCH_CS_PIN, LOW);
SPI.transfer(coord);
data[i] = (((SPI.transfer(0xFF) << 8) | SPI.transfer(0xFF)) >> 3) & 0x0FFF;
WRITE(TOUCH_CS_PIN, HIGH);
}
data[i] = 0;
for (uint16_t j = 0x8000; j; j >>= 1) {
WRITE(TOUCH_SCK_PIN, LOW);
if (READ(TOUCH_MISO_PIN)) data[i] |= j;
WRITE(TOUCH_SCK_PIN, HIGH);
}
WRITE(TOUCH_SCK_PIN, LOW);
data[i] >>= 4;
}
#else // !TOUCH_BUTTONS_HW_SPI
WRITE(TOUCH_CS_PIN, HIGH);
OUT_WRITE(TOUCH_CS_PIN, LOW);
for (uint16_t i = 0; i < 3; i++) {
for (uint8_t j = 0x80; j; j >>= 1) {
WRITE(TOUCH_SCK_PIN, LOW);
WRITE(TOUCH_MOSI_PIN, bool(coord & j));
WRITE(TOUCH_SCK_PIN, HIGH);
}
data[i] = 0;
for (uint16_t j = 0x8000; j; j >>= 1) {
WRITE(TOUCH_SCK_PIN, LOW);
if (READ(TOUCH_MISO_PIN)) data[i] |= j;
WRITE(TOUCH_SCK_PIN, HIGH);
}
WRITE(TOUCH_SCK_PIN, LOW);
data[i] >>= 4;
}
WRITE(TOUCH_CS_PIN, HIGH);
#endif // !TOUCH_BUTTONS_HW_SPI
uint16_t delta01 = _MAX(data[0], data[1]) - _MIN(data[0], data[1]),
delta02 = _MAX(data[0], data[2]) - _MIN(data[0], data[2]),

View File

@ -34,10 +34,6 @@ enum XPTCoordinate : uint8_t {
XPT2046_Z2 = 0x40
};
#ifndef XPT2046_Z1_THRESHOLD
#define XPT2046_Z1_THRESHOLD 10
#endif
class XPT2046 {
public:
static void init();