[P099] Enable support for configurable SPI bus

This commit is contained in:
Ton Huisman
2025-08-13 14:01:25 +02:00
parent b753fea2ba
commit 7e13c7bd0c
5 changed files with 92 additions and 72 deletions
+13 -13
View File
@@ -32,7 +32,7 @@ void isrPin(void);
bool XPT2046_Touchscreen::begin()
{
SPI.begin();
// _spi.begin(); // ESPEasy already does this
pinMode(csPin, OUTPUT);
digitalWrite(csPin, HIGH);
if (255 != tirqPin) {
@@ -105,25 +105,25 @@ void XPT2046_Touchscreen::update()
uint32_t now = millis();
if (now - msraw < MSEC_THRESHOLD) return;
SPI.beginTransaction(SPI_SETTING);
_spi.beginTransaction(SPI_SETTING);
digitalWrite(csPin, LOW);
SPI.transfer(0xB1 /* Z1 */);
int16_t z1 = SPI.transfer16(0xC1 /* Z2 */) >> 3;
_spi.transfer(0xB1 /* Z1 */);
int16_t z1 = _spi.transfer16(0xC1 /* Z2 */) >> 3;
int z = z1 + 4095;
int16_t z2 = SPI.transfer16(0x91 /* X */) >> 3;
int16_t z2 = _spi.transfer16(0x91 /* X */) >> 3;
z -= z2;
if (z >= Z_THRESHOLD) {
SPI.transfer16(0x91 /* X */); // dummy X measure, 1st is always noisy
data[0] = SPI.transfer16(0xD1 /* Y */) >> 3;
data[1] = SPI.transfer16(0x91 /* X */) >> 3; // make 3 x-y measurements
data[2] = SPI.transfer16(0xD1 /* Y */) >> 3;
data[3] = SPI.transfer16(0x91 /* X */) >> 3;
_spi.transfer16(0x91 /* X */); // dummy X measure, 1st is always noisy
data[0] = _spi.transfer16(0xD1 /* Y */) >> 3;
data[1] = _spi.transfer16(0x91 /* X */) >> 3; // make 3 x-y measurements
data[2] = _spi.transfer16(0xD1 /* Y */) >> 3;
data[3] = _spi.transfer16(0x91 /* X */) >> 3;
}
else data[0] = data[1] = data[2] = data[3] = 0; // Compiler warns these values may be used unset on early exit.
data[4] = SPI.transfer16(0xD0 /* Y */) >> 3; // Last Y touch power down
data[5] = SPI.transfer16(0) >> 3;
data[4] = _spi.transfer16(0xD0 /* Y */) >> 3; // Last Y touch power down
data[5] = _spi.transfer16(0) >> 3;
digitalWrite(csPin, HIGH);
SPI.endTransaction();
_spi.endTransaction();
//Serial.printf("z=%d :: z1=%d, z2=%d ", z, z1, z2);
if (z < 0) z = 0;
if (z < Z_THRESHOLD) { // if ( !touched ) {
@@ -41,8 +41,8 @@ public:
class XPT2046_Touchscreen {
public:
constexpr XPT2046_Touchscreen(uint8_t cspin, uint8_t tirq=255)
: csPin(cspin), tirqPin(tirq) { }
constexpr XPT2046_Touchscreen(uint8_t cspin, SPIClass& spi = SPI, uint8_t tirq=255)
: csPin(cspin), _spi(spi), tirqPin(tirq) { }
bool begin();
TS_Point getPoint();
bool tirqTouched();
@@ -57,8 +57,13 @@ public:
private:
void update();
uint8_t csPin, tirqPin, rotation = 1;
int16_t xraw = 0, yraw = 0, zraw = 0;
uint8_t csPin;
SPIClass& _spi = SPI;
uint8_t tirqPin;
uint8_t rotation = 1;
int16_t xraw = 0;
int16_t yraw = 0;
int16_t zraw = 0;
uint32_t msraw = 0x80000000;
bool flipped = false;
};
+11 -7
View File
@@ -6,6 +6,7 @@
/**
* Changelog:
* 2025-08-13 tonhuisman: Enable use of secondary SPI bus
* 2025-01-12 tonhuisman: Add support for MQTT AutoDiscovery (not supported for Touch)
* 2020-11-01 tonhuisman: Solved previous strange rotation settings to be compatible with TFT ILI9341
* 2020-11-01 tonhuisman: Add option to flip rotation by 180 deg, and command touch,flip,<0|1>
@@ -52,10 +53,11 @@ boolean Plugin_099(uint8_t function, struct EventStruct *event, String& string)
case PLUGIN_DEVICE_ADD:
{
auto& dev = Device[++deviceCount];
dev.Number = PLUGIN_ID_099;
dev.Type = DEVICE_TYPE_SPI;
dev.VType = Sensor_VType::SENSOR_TYPE_TRIPLE;
dev.ValueCount = 3;
dev.Number = PLUGIN_ID_099;
dev.Type = DEVICE_TYPE_SPI;
dev.VType = Sensor_VType::SENSOR_TYPE_TRIPLE;
dev.ValueCount = 3;
dev.SpiBusSelect = true;
break;
}
@@ -81,14 +83,14 @@ boolean Plugin_099(uint8_t function, struct EventStruct *event, String& string)
break;
}
# if FEATURE_MQTT_DISCOVER
#if FEATURE_MQTT_DISCOVER
case PLUGIN_GET_DISCOVERY_VTYPES:
{
event->Par1 = static_cast<int>(Sensor_VType::SENSOR_TYPE_NONE); // Not yet supported
success = true;
break;
}
# endif // if FEATURE_MQTT_DISCOVER
#endif // if FEATURE_MQTT_DISCOVER
case PLUGIN_SET_DEFAULTS:
{
@@ -362,6 +364,7 @@ boolean Plugin_099(uint8_t function, struct EventStruct *event, String& string)
case PLUGIN_INIT:
{
const uint8_t spi_bus = Settings.getSPIBusForTask(event->TaskIndex);
initPluginTaskData(event->TaskIndex, new (std::nothrow) P099_data_struct());
P099_data_struct *P099_data = static_cast<P099_data_struct *>(getPluginTaskData(event->TaskIndex));
@@ -374,7 +377,8 @@ boolean Plugin_099(uint8_t function, struct EventStruct *event, String& string)
bitRead(P099_CONFIG_FLAGS, P099_FLAGS_SEND_Z),
bitRead(P099_CONFIG_FLAGS, P099_FLAGS_USE_CALIBRATION),
P099_CONFIG_X_RES,
P099_CONFIG_Y_RES);
P099_CONFIG_Y_RES,
spi_bus);
break;
}
+9 -3
View File
@@ -42,7 +42,8 @@ bool P099_data_struct::init(taskIndex_t taskIndex,
bool send_z,
bool useCalibration,
uint16_t ts_x_res,
uint16_t ts_y_res) {
uint16_t ts_y_res,
uint8_t spi_bus) {
reset();
_address_ts_cs = cs;
@@ -54,8 +55,13 @@ bool P099_data_struct::init(taskIndex_t taskIndex,
_useCalibration = useCalibration;
_ts_x_res = ts_x_res;
_ts_y_res = ts_y_res;
_spi_bus = spi_bus;
touchscreen = new (std::nothrow) XPT2046_Touchscreen(_address_ts_cs);
touchscreen = new (std::nothrow) XPT2046_Touchscreen(_address_ts_cs
# ifdef ESP32
, 0 == _spi_bus ? SPI : SPI1
# endif // ifdef ESP32
);
if (touchscreen != nullptr) {
touchscreen->setRotation(_rotation);
@@ -328,7 +334,7 @@ bool P099_data_struct::plugin_write(struct EventStruct *event, const String& str
subcommand = parseString(string, 2);
if (equals(command, F("touch"))) {
int command_i = GetCommandCode(subcommand.c_str(), p099_subcommands);
int command_i = GetCommandCode(subcommand.c_str(), p099_subcommands);
if (command_i == -1) {
// No matching subcommand found
+50 -45
View File
@@ -8,64 +8,66 @@
# include <XPT2046_Touchscreen.h>
# include "../Globals/SPI1.h"
// #define PLUGIN_099_DEBUG // Additional debugging information
// Define default values for both ESP32/lolin32 and D1 Mini
# ifdef ESP32
# define P099_TS_CS 12
# else // ESP8266/ESP8285
# define P099_TS_CS 0 // D3
# define P099_TS_CS 0 // D3
# endif // ESP32
# define P099_MaxObjectNameLength 15 // 14 character objectnames + terminating 0
# define P099_MaxObjectCount 40 // This count of touchobjects should be enough, because of limited settings storage, 960 bytes + 8
// bytes calibration coordinates
# define P099_MaxObjectNameLength 15 // 14 character objectnames + terminating 0
# define P099_MaxObjectCount 40 // This count of touchobjects should be enough, because of limited settings storage, 960 bytes + 8
// bytes calibration coordinates
# define P099_FLAGS_ON_OFF_BUTTON 0 // TouchObjects.flags On/Off Button function
# define P099_FLAGS_INVERT_BUTTON 1 // TouchObjects.flags Inverted On/Off Button function
# define P099_FLAGS_ON_OFF_BUTTON 0 // TouchObjects.flags On/Off Button function
# define P099_FLAGS_INVERT_BUTTON 1 // TouchObjects.flags Inverted On/Off Button function
#define P099_FLAGS_SEND_XY 0 // Set in P099_CONFIG_FLAGS
#define P099_FLAGS_SEND_Z 1 // Set in P099_CONFIG_FLAGS
#define P099_FLAGS_SEND_OBJECTNAME 2 // Set in P099_CONFIG_FLAGS
#define P099_FLAGS_USE_CALIBRATION 3 // Set in P099_CONFIG_FLAGS
#define P099_FLAGS_LOG_CALIBRATION 4 // Set in P099_CONFIG_FLAGS
#define P099_FLAGS_ROTATION_FLIPPED 5 // Set in P099_CONFIG_FLAGS
# define P099_FLAGS_SEND_XY 0 // Set in P099_CONFIG_FLAGS
# define P099_FLAGS_SEND_Z 1 // Set in P099_CONFIG_FLAGS
# define P099_FLAGS_SEND_OBJECTNAME 2 // Set in P099_CONFIG_FLAGS
# define P099_FLAGS_USE_CALIBRATION 3 // Set in P099_CONFIG_FLAGS
# define P099_FLAGS_LOG_CALIBRATION 4 // Set in P099_CONFIG_FLAGS
# define P099_FLAGS_ROTATION_FLIPPED 5 // Set in P099_CONFIG_FLAGS
#define P099_CONFIG_STATE PCONFIG(0)
#define P099_CONFIG_CS_PIN PIN(0)
#define P099_CONFIG_TRESHOLD PCONFIG(1)
#define P099_CONFIG_ROTATION PCONFIG(2)
#define P099_CONFIG_X_RES PCONFIG(3)
#define P099_CONFIG_Y_RES PCONFIG(4)
#define P099_CONFIG_OBJECTCOUNT PCONFIG(5)
#define P099_CONFIG_DEBOUNCE_MS PCONFIG(6)
#define P099_CONFIG_FLAGS PCONFIG_LONG(0) // 0-31 flags
# define P099_CONFIG_STATE PCONFIG(0)
# define P099_CONFIG_CS_PIN PIN(0)
# define P099_CONFIG_TRESHOLD PCONFIG(1)
# define P099_CONFIG_ROTATION PCONFIG(2)
# define P099_CONFIG_X_RES PCONFIG(3)
# define P099_CONFIG_Y_RES PCONFIG(4)
# define P099_CONFIG_OBJECTCOUNT PCONFIG(5)
# define P099_CONFIG_DEBOUNCE_MS PCONFIG(6)
# define P099_CONFIG_FLAGS PCONFIG_LONG(0) // 0-31 flags
#define P099_VALUE_X UserVar[event->BaseVarIndex + 0]
#define P099_VALUE_Y UserVar[event->BaseVarIndex + 1]
#define P099_VALUE_Z UserVar[event->BaseVarIndex + 2]
# define P099_VALUE_X UserVar[event->BaseVarIndex + 0]
# define P099_VALUE_Y UserVar[event->BaseVarIndex + 1]
# define P099_VALUE_Z UserVar[event->BaseVarIndex + 2]
#define P099_SET_VALUE_X(v) UserVar.setFloat(event->TaskIndex, 0, v)
#define P099_SET_VALUE_Y(v) UserVar.setFloat(event->TaskIndex, 1, v)
#define P099_SET_VALUE_Z(v) UserVar.setFloat(event->TaskIndex, 2, v)
# define P099_SET_VALUE_X(v) UserVar.setFloat(event->TaskIndex, 0, v)
# define P099_SET_VALUE_Y(v) UserVar.setFloat(event->TaskIndex, 1, v)
# define P099_SET_VALUE_Z(v) UserVar.setFloat(event->TaskIndex, 2, v)
#define P099_TS_TRESHOLD 15 // Treshold before the value is registered as a proper touch
#define P099_TS_ROTATION 2 // Rotation 0-3 = 0/90/180/270 degrees, compatible with TFT ILI9341
#define P099_TS_SEND_XY true // Enable X/Y events
#define P099_TS_SEND_Z false // Disable Z events
#define P099_TS_SEND_OBJECTNAME true // Enable objectname events
#define P099_TS_USE_CALIBRATION false // Disable calibration
#define P099_TS_LOG_CALIBRATION true // Enable calibration logging
#define P099_TS_ROTATION_FLIPPED false // Enable rotation flipped 180 deg.
#define P099_TS_X_RES 240 // Pixels, should match with the screen it is mounted on
#define P099_TS_Y_RES 320
#define P099_INIT_OBJECTCOUNT 8 // Initial setting
#define P099_DEBOUNCE_MILLIS 150 // Debounce delay for On/Off button function
# define P099_TS_TRESHOLD 15 // Treshold before the value is registered as a proper touch
# define P099_TS_ROTATION 2 // Rotation 0-3 = 0/90/180/270 degrees, compatible with TFT ILI9341
# define P099_TS_SEND_XY true // Enable X/Y events
# define P099_TS_SEND_Z false // Disable Z events
# define P099_TS_SEND_OBJECTNAME true // Enable objectname events
# define P099_TS_USE_CALIBRATION false // Disable calibration
# define P099_TS_LOG_CALIBRATION true // Enable calibration logging
# define P099_TS_ROTATION_FLIPPED false // Enable rotation flipped 180 deg.
# define P099_TS_X_RES 240 // Pixels, should match with the screen it is mounted on
# define P099_TS_Y_RES 320
# define P099_INIT_OBJECTCOUNT 8 // Initial setting
# define P099_DEBOUNCE_MILLIS 150 // Debounce delay for On/Off button function
#define P099_TOUCH_X_INVALID 4095 // When picking up spurious noise (or an open/not connected TS-CS pin), these are the values that
// turn up
#define P099_TOUCH_Y_INVALID 4095
#define P099_TOUCH_Z_INVALID 255
# define P099_TOUCH_X_INVALID 4095 // When picking up spurious noise (or an open/not connected TS-CS pin), these are the values that
// turn up
# define P099_TOUCH_Y_INVALID 4095
# define P099_TOUCH_Z_INVALID 255
// Data structure
@@ -84,7 +86,8 @@ struct P099_data_struct : public PluginTaskData_base
bool send_z,
bool useCalibration,
uint16_t ts_x_res,
uint16_t ts_y_res);
uint16_t ts_y_res,
uint8_t spi_bus);
bool isInitialized() const;
void loadTouchObjects(taskIndex_t taskIndex);
bool touched();
@@ -105,7 +108,8 @@ struct P099_data_struct : public PluginTaskData_base
void scaleRawToCalibrated(uint16_t& x,
uint16_t& y);
bool plugin_write(struct EventStruct *event,const String& string);
bool plugin_write(struct EventStruct *event,
const String & string);
// This is initialized by calling init()
XPT2046_Touchscreen *touchscreen = nullptr;
@@ -118,6 +122,7 @@ struct P099_data_struct : public PluginTaskData_base
bool _useCalibration = 0;
uint16_t _ts_x_res = 0;
uint16_t _ts_y_res = 0;
uint8_t _spi_bus = 0;
// This is filled during checking of a touchobject
uint32_t SurfaceAreas[P099_MaxObjectCount] = { 0 };