From e9c7ab4cfc82172a07c19a0c4877b4afd11412f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Milants?= <jf@codingfield.com>
Date: Sat, 6 Nov 2021 19:01:19 +0100
Subject: [PATCH 1/2] Add data validity check and retries in CST816S driver.
 See
 https://github.com/InfiniTimeOrg/InfiniTime/issues/763#issuecomment-962436976.

---
 src/drivers/Cst816s.cpp | 73 +++++++++++++++++++++++++++++------------
 src/drivers/Cst816s.h   |  7 +++-
 2 files changed, 58 insertions(+), 22 deletions(-)

diff --git a/src/drivers/Cst816s.cpp b/src/drivers/Cst816s.cpp
index 7fc8eca4..46dd96dc 100644
--- a/src/drivers/Cst816s.cpp
+++ b/src/drivers/Cst816s.cpp
@@ -32,6 +32,18 @@ bool Cst816S::Init() {
   twiMaster.Read(twiAddress, 0xa7, &dummy, 1);
   vTaskDelay(5);
 
+  static constexpr uint8_t maxRetries = 3;
+  bool isDeviceOk = false;
+  uint8_t retries = 0;
+  do {
+    isDeviceOk = CheckDeviceIds();
+    retries++;
+  } while(!isDeviceOk && retries < maxRetries);
+
+  if(!isDeviceOk) {
+    return false;
+  }
+
   /*
   [2] EnConLR - Continuous operation can slide around
   [1] EnConUD - Slide up and down to enable continuous operation
@@ -50,21 +62,7 @@ bool Cst816S::Init() {
   static constexpr uint8_t irqCtl = 0b01110000;
   twiMaster.Write(twiAddress, 0xFA, &irqCtl, 1);
 
-  // There's mixed information about which register contains which information
-  if (twiMaster.Read(twiAddress, 0xA7, &chipId, 1) == TwiMaster::ErrorCodes::TransactionFailed) {
-    chipId = 0xFF;
-    return false;
-  }
-  if (twiMaster.Read(twiAddress, 0xA8, &vendorId, 1) == TwiMaster::ErrorCodes::TransactionFailed) {
-    vendorId = 0xFF;
-    return false;
-  }
-  if (twiMaster.Read(twiAddress, 0xA9, &fwVersion, 1) == TwiMaster::ErrorCodes::TransactionFailed) {
-    fwVersion = 0xFF;
-    return false;
-  }
-
-  return chipId == 0xb4 && vendorId == 0 && fwVersion == 1;
+  return true;
 }
 
 Cst816S::TouchInfos Cst816S::GetTouchInfo() {
@@ -79,18 +77,33 @@ Cst816S::TouchInfos Cst816S::GetTouchInfo() {
 
   // This can only be 0 or 1
   uint8_t nbTouchPoints = touchData[touchPointNumIndex] & 0x0f;
-
   uint8_t xHigh = touchData[touchXHighIndex] & 0x0f;
   uint8_t xLow = touchData[touchXLowIndex];
-  info.x = (xHigh << 8) | xLow;
-
+  uint16_t x = (xHigh << 8) | xLow;
   uint8_t yHigh = touchData[touchYHighIndex] & 0x0f;
   uint8_t yLow = touchData[touchYLowIndex];
-  info.y = (yHigh << 8) | yLow;
+  uint16_t y = (yHigh << 8) | yLow;
+  Gestures gesture = static_cast<Gestures>(touchData[gestureIndex]);
 
+  // Validity check
+  if(x >= maxX || y >= maxY ||
+      (gesture != Gestures::None &&
+       gesture != Gestures::SlideDown &&
+       gesture != Gestures::SlideUp &&
+       gesture != Gestures::SlideLeft &&
+       gesture != Gestures::SlideRight &&
+       gesture != Gestures::SingleTap &&
+       gesture != Gestures::DoubleTap &&
+       gesture != Gestures::LongPress)) {
+    info.isValid = false;
+    return info;
+  }
+
+  info.x = x;
+  info.y = y;
   info.touching = (nbTouchPoints > 0);
-  info.gesture = static_cast<Gestures>(touchData[gestureIndex]);
-
+  info.gesture = gesture;
+  info.isValid = true;
   return info;
 }
 
@@ -108,3 +121,21 @@ void Cst816S::Wakeup() {
   Init();
   NRF_LOG_INFO("[TOUCHPANEL] Wakeup");
 }
+
+bool Cst816S::CheckDeviceIds() {
+  // There's mixed information about which register contains which information
+  if (twiMaster.Read(twiAddress, 0xA7, &chipId, 1) == TwiMaster::ErrorCodes::TransactionFailed) {
+    chipId = 0xFF;
+    return false;
+  }
+  if (twiMaster.Read(twiAddress, 0xA8, &vendorId, 1) == TwiMaster::ErrorCodes::TransactionFailed) {
+    vendorId = 0xFF;
+    return false;
+  }
+  if (twiMaster.Read(twiAddress, 0xA9, &fwVersion, 1) == TwiMaster::ErrorCodes::TransactionFailed) {
+    fwVersion = 0xFF;
+    return false;
+  }
+
+  return chipId == 0xb4 && vendorId == 0 && fwVersion == 1;
+}
diff --git a/src/drivers/Cst816s.h b/src/drivers/Cst816s.h
index 0fec8419..507dd4f5 100644
--- a/src/drivers/Cst816s.h
+++ b/src/drivers/Cst816s.h
@@ -21,7 +21,7 @@ namespace Pinetime {
         uint16_t y = 0;
         Gestures gesture = Gestures::None;
         bool touching = false;
-        bool isValid = true;
+        bool isValid = false;
       };
 
       Cst816S(TwiMaster& twiMaster, uint8_t twiAddress);
@@ -45,6 +45,8 @@ namespace Pinetime {
         return fwVersion;
       }
     private:
+      bool CheckDeviceIds();
+
       // Unused/Unavailable commented out
       static constexpr uint8_t gestureIndex = 1;
       static constexpr uint8_t touchPointNumIndex = 2;
@@ -58,6 +60,9 @@ namespace Pinetime {
       //static constexpr uint8_t touchXYIndex = 7;
       //static constexpr uint8_t touchMiscIndex = 8;
 
+      static constexpr uint8_t maxX = 240;
+      static constexpr uint8_t maxY = 240;
+
       TwiMaster& twiMaster;
       uint8_t twiAddress;
 

From 8d61419836bffa7c59cb41c33fe747bafe841af5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Milants?= <jf@codingfield.com>
Date: Sun, 7 Nov 2021 16:19:06 +0100
Subject: [PATCH 2/2] Fix formatting following the code review.

---
 src/drivers/Cst816s.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/drivers/Cst816s.cpp b/src/drivers/Cst816s.cpp
index 46dd96dc..4aac19f9 100644
--- a/src/drivers/Cst816s.cpp
+++ b/src/drivers/Cst816s.cpp
@@ -33,14 +33,14 @@ bool Cst816S::Init() {
   vTaskDelay(5);
 
   static constexpr uint8_t maxRetries = 3;
-  bool isDeviceOk = false;
+  bool isDeviceOk;
   uint8_t retries = 0;
   do {
     isDeviceOk = CheckDeviceIds();
     retries++;
-  } while(!isDeviceOk && retries < maxRetries);
+  } while (!isDeviceOk && retries < maxRetries);
 
-  if(!isDeviceOk) {
+  if (!isDeviceOk) {
     return false;
   }