11#ifdef TOUCH_SELFTEST_ENABLE
21extern SPI_HandleTypeDef hspi1;
24static const uint8_t kControl[4] = { 0xD0, 0x90, 0xB0, 0xC0 };
25static const char *kControlName[4] = {
"X",
"Y",
"Z1",
"Z2" };
28#define SELFTEST_IDLE_SAMPLES 25
29#define SELFTEST_IDLE_SPACING_MS 10
32#define SELFTEST_PRESSURE_MIN 40.0f
33#define SELFTEST_PRESSURE_MAX 1500.0f
37static void resetReport(
void) {
38 memset(&report, 0,
sizeof(report));
51 vsnprintf(report.
detail,
sizeof(report.
detail), fmt, args);
57static HAL_StatusTypeDef rawConversion(uint8_t cmd, uint8_t rx[3]) {
58 uint8_t tx[3] = { cmd, 0x00, 0x00 };
59 rx[0] = rx[1] = rx[2] = 0xAA;
60 HAL_GPIO_WritePin(TSC2046_CS_GPIO_Port, TSC2046_CS_Pin, GPIO_PIN_RESET);
61 HAL_StatusTypeDef st = HAL_SPI_TransmitReceive(&hspi1, tx, rx, 3, 100);
62 HAL_GPIO_WritePin(TSC2046_CS_GPIO_Port, TSC2046_CS_Pin, GPIO_PIN_SET);
67static bool testSpiTransfer(
void) {
69 HAL_StatusTypeDef st = rawConversion(kControl[0], rx);
71 return fail(TOUCH_SELFTEST_SPI_TRANSFER,
72 "HAL SPI transfer failed (status %d, SPI error 0x%lX): check SPI1 setup and wiring",
73 (
int)st, (
unsigned long)HAL_SPI_GetError(&hspi1));
79static bool testFraming(
void) {
81 bool allIdentical =
true;
83 for (
int i = 0; i < 4; i++) {
85 if (rawConversion(kControl[i], rx) != HAL_OK) {
86 return fail(TOUCH_SELFTEST_FRAMING,
"SPI transfer failed reading %s", kControlName[i]);
90 if ((rx[1] & 0x80) != 0 || (rx[2] & 0x07) != 0) {
91 return fail(TOUCH_SELFTEST_FRAMING,
92 "%s response %02X %02X %02X is not a valid frame: MISO stuck or floating, check VCC and wiring",
93 kControlName[i], rx[0], rx[1], rx[2]);
95 value[i] = (uint16_t)((((uint16_t)rx[1] << 8) | rx[2]) >> 3) & 0xFFF;
96 if (i > 0 && value[i] != value[0]) {
101 return fail(TOUCH_SELFTEST_FRAMING,
102 "all four channels returned the same value (%u): MISO stuck low, chip not answering", value[0]);
115static bool testIdle(
void) {
116 uint32_t phantom = 0;
118 for (
int i = 0; i < SELFTEST_IDLE_SAMPLES; i++) {
119 int16_t x = 0, y = 0;
120 float pressure = 0.0f;
122 bool looksTouched = isfinite(pressure) && pressure >= SELFTEST_PRESSURE_MIN &&
128 HAL_Delay(SELFTEST_IDLE_SPACING_MS);
132 return fail(TOUCH_SELFTEST_IDLE,
133 "%lu of %d idle samples looked like touches: hands on the panel, panel pressed or shorted, or flex cable mis-seated",
134 (
unsigned long)phantom, SELFTEST_IDLE_SAMPLES);
142 printf(
"Touch self-test (keep hands off the panel)...\r\n");
145 fail(TOUCH_SELFTEST_SPI_TRANSFER,
"driver not ready: call initTSC2046() first");
146 printf(
" FAIL: %s\r\n", report.
detail);
151 if (!testSpiTransfer()) { printf(
" [1/3] SPI transfer ........ FAIL: %s\r\n", report.
detail);
goto done; }
152 printf(
" [1/3] SPI transfer ........ ok\r\n");
155 if (!testFraming()) { printf(
" [2/3] Response framing .... FAIL: %s\r\n", report.
detail);
goto done; }
156 printf(
" [2/3] Response framing .... ok\r\n");
159 if (!testIdle()) { printf(
" [3/3] Idle, no touches .... FAIL: %s\r\n", report.
detail);
goto done; }
160 printf(
" [3/3] Idle, no touches .... ok (%d samples)\r\n", SELFTEST_IDLE_SAMPLES);
163 printf(
"Self-test %s\r\n", report.
passed ?
"PASSED" :
"FAILED (touch may not work; see above)");
C-callable entry points bridging CubeMX-generated main.c into the C++ TSC2046 driver.
bool tsc2046IsReady(void)
Reports whether initTSC2046() has run. Every other tsc2046* function below returns false without touc...
bool tsc2046GetPoint(int16_t *x, int16_t *y, float *pressure)
Reads the current touch position and pressure.
: Header for main.c file. This file contains the common defines of the application.
Result of the most recent touchSelfTestRunAll().
touchSelfTestId_t failedTest
First failing test, or NONE if passed.
char detail[96]
Human-readable reason for a failure.
bool passed
true if every test passed.
uint32_t idlePhantomTouches
Idle samples that looked like touches.
uint32_t testsRun
Tests that started running (pass or fail).
Startup self-test for the TSC2046 touch controller.
touchSelfTestId_t
Self-test identifiers.
const touchSelfTestReport_t * touchSelfTestRunAll(void)
Runs every self-test in order, stopping at the first failure, and prints progress and a PASS/FAIL ver...
const touchSelfTestReport_t * touchSelfTestGetReport(void)
Maps raw TSC2046 X/Y readings to the printed button zones on the panel overlay.
touchZone_t touchZoneFromPoint(int16_t x, int16_t y)
Classifies a raw touch position into a button zone.