summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJF <jf@codingfield.com>2020-01-03 16:32:31 +0100
committerJF <jf@codingfield.com>2020-01-03 16:32:31 +0100
commitee530baaa05faeb246392cd2ac0ee66e79af49db (patch)
tree0fa4254e99d33bd065c3dd3a19157f125d053fc5
parent27d0e1e02f97912ae2a18a0254060a546d2fc42b (diff)
Add basic touch panel driver.
Handle touch event in display app : draw a big square at the touch point coordinates.
-rwxr-xr-xcmake-nRF5x/CMake_nRF5x.cmake5
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/DisplayApp/DisplayApp.cpp18
-rw-r--r--src/DisplayApp/DisplayApp.h8
-rw-r--r--src/drivers/Cst816s.cpp77
-rw-r--r--src/drivers/Cst816s.h47
-rw-r--r--src/main.cpp23
-rw-r--r--src/sdk_config.h102
8 files changed, 179 insertions, 103 deletions
diff --git a/cmake-nRF5x/CMake_nRF5x.cmake b/cmake-nRF5x/CMake_nRF5x.cmake
index 9fc97c16..7fd59f81 100755
--- a/cmake-nRF5x/CMake_nRF5x.cmake
+++ b/cmake-nRF5x/CMake_nRF5x.cmake
@@ -197,8 +197,6 @@ macro(nRF5x_setup)
"${NRF5_SDK_PATH}/components/libraries/strerror"
"${NRF5_SDK_PATH}/components/libraries/svc"
"${NRF5_SDK_PATH}/components/libraries/timer"
- "${NRF5_SDK_PATH}/components/libraries/twi_mngr"
- "${NRF5_SDK_PATH}/components/libraries/twi_sensor"
"${NRF5_SDK_PATH}/components/libraries/usbd"
"${NRF5_SDK_PATH}/components/libraries/usbd/class/audio"
"${NRF5_SDK_PATH}/components/libraries/usbd/class/cdc"
@@ -325,6 +323,9 @@ macro(nRF5x_setup)
"${NRF5_SDK_PATH}/components/libraries/hardfault/nrf52/handler/hardfault_handler_gcc.c"
)
+ LIST(APPEND SDK_SOURCE_FILES
+ "${NRF5_SDK_PATH}/modules/nrfx/drivers/src/nrfx_twi.c"
+ )
# adds target for erasing and flashing the board with a softdevice
add_custom_target(FLASH_SOFTDEVICE ALL
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index bd88d063..64014280 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -41,6 +41,7 @@ list(APPEND SOURCE_FILES
Components/Battery/BatteryController.cpp
Components/Ble/BleController.cpp
Components/DateTime/DateTimeController.cpp
+ drivers/Cst816s.cpp
)
set(INCLUDE_FILES
@@ -57,6 +58,7 @@ set(INCLUDE_FILES
Components/Battery/BatteryController.h
Components/Ble/BleController.h
Components/DateTime/DateTimeController.h
+ drivers/Cst816s.h
)
nRF5x_addExecutable(pinetime-app "${SOURCE_FILES}") \ No newline at end of file
diff --git a/src/DisplayApp/DisplayApp.cpp b/src/DisplayApp/DisplayApp.cpp
index 20704c0d..2a26f189 100644
--- a/src/DisplayApp/DisplayApp.cpp
+++ b/src/DisplayApp/DisplayApp.cpp
@@ -8,6 +8,7 @@
#include "Components/Gfx/Gfx.h"
#include <queue.h>
#include <Components/DateTime/DateTimeController.h>
+#include <drivers/Cst816s.h>
using namespace Pinetime::Applications;
@@ -56,7 +57,6 @@ void DisplayApp::Process(void *instance) {
auto *app = static_cast<DisplayApp *>(instance);
NRF_LOG_INFO("DisplayApp task started!");
app->InitHw();
-
while (1) {
app->Refresh();
}
@@ -101,6 +101,8 @@ void DisplayApp::InitHw() {
gfx->DrawString(10, 0, 0x0000, "BLE", &smallFont, false);
gfx->DrawString(20, 180, 0xffff, "", &smallFont, false);
+
+ touchPanel.Init();
}
void DisplayApp::Refresh() {
@@ -148,6 +150,10 @@ void DisplayApp::Refresh() {
case Messages::UpdateBatteryLevel:
batteryLevelUpdated = true;
break;
+ case Messages::TouchEvent:
+ if(state != States::Running) break;
+ OnTouchEvent();
+ break;
}
}
}
@@ -247,3 +253,13 @@ void DisplayApp::PushMessage(DisplayApp::Messages msg) {
// TODO : should I do something here?
}
}
+
+static uint16_t pointColor = 0x07e0;
+void DisplayApp::OnTouchEvent() {
+ auto info = touchPanel.GetTouchInfo();
+
+ if(info.isTouch) {
+ lcd->FillRectangle(info.x-10, info.y-10, 20,20, pointColor);
+ pointColor+=10;
+ }
+}
diff --git a/src/DisplayApp/DisplayApp.h b/src/DisplayApp/DisplayApp.h
index 24b8e45d..75c74227 100644
--- a/src/DisplayApp/DisplayApp.h
+++ b/src/DisplayApp/DisplayApp.h
@@ -10,6 +10,8 @@
#include <Components/Ble/BleController.h>
#include <Components/DateTime/DateTimeController.h>
#include "lcdfont14.h"
+#include "../drivers/Cst816s.h"
+
extern const FONT_INFO lCD_70ptFontInfo;
@@ -18,7 +20,7 @@ namespace Pinetime {
class DisplayApp {
public:
enum class States {Idle, Running};
- enum class Messages : uint8_t {GoToSleep, GoToRunning, UpdateDateTime, UpdateBleConnection, UpdateBatteryLevel} ;
+ enum class Messages : uint8_t {GoToSleep, GoToRunning, UpdateDateTime, UpdateBleConnection, UpdateBatteryLevel, TouchEvent} ;
DisplayApp(Controllers::Battery &batteryController,
Controllers::Ble &bleController,
Controllers::DateTime& dateTimeController);
@@ -59,11 +61,11 @@ namespace Pinetime {
bool batteryLevelUpdated = false;
static char const *DaysString[];
-
static char const *MonthsString[];
-
bool dateUpdated = false;
+ Pinetime::Drivers::Cst816S touchPanel;
+ void OnTouchEvent();
};
}
}
diff --git a/src/drivers/Cst816s.cpp b/src/drivers/Cst816s.cpp
new file mode 100644
index 00000000..8ed65876
--- /dev/null
+++ b/src/drivers/Cst816s.cpp
@@ -0,0 +1,77 @@
+#include <FreeRTOS.h>
+#include <task.h>
+#include <nrfx_log.h>
+#include <legacy/nrf_drv_gpiote.h>
+
+#include "Cst816s.h"
+using namespace Pinetime::Drivers;
+
+/* References :
+ * This implementation is based on this article : https://medium.com/@ly.lee/building-a-rust-driver-for-pinetimes-touch-controller-cbc1a5d5d3e9
+ * Touch panel datasheet (weird chinese translation) : https://wiki.pine64.org/images/5/51/CST816S%E6%95%B0%E6%8D%AE%E6%89%8B%E5%86%8CV1.1.en.pdf
+ *
+ * TODO : we need a complete datasheet and protocol reference!
+ * */
+
+void Pinetime::Drivers::Cst816S::Init() {
+ nrf_gpio_cfg_output(pinReset);
+ nrf_gpio_pin_clear(pinReset);
+ vTaskDelay(20);
+ nrf_gpio_pin_set(pinReset);
+ vTaskDelay(200);
+
+ nrfx_twi_config_t config;
+ config.frequency = NRF_TWI_FREQ_400K;
+ config.scl = 7;
+ config.sda = 6;
+ config.interrupt_priority = NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY;
+ config.hold_bus_uninit = NRFX_TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT;
+
+ // Configure TWI in blocking mode (event_handler = nullptr)
+ auto ret = nrfx_twi_init(&twi, &config, nullptr, this);
+ nrfx_twi_enable(&twi);
+}
+
+
+void Cst816S::Probe() {
+ nrfx_err_t ret;
+ for(int i = 0; i < 127; i++) {
+ uint8_t data;
+ ret = nrfx_twi_rx(&twi, i, &data, 1);
+ if(ret == NRFX_SUCCESS) {
+ NRF_LOG_INFO("I2C device detected at address %d", i);
+ }
+ }
+}
+
+Cst816S::TouchInfos Cst816S::GetTouchInfo() {
+ Cst816S::TouchInfos info;
+
+ nrfx_twi_rx(&twi, address, touchData, 63);
+ auto nbTouchPoints = touchData[2] & 0x0f;
+
+ uint8_t i = 0;
+ uint8_t pointId = (touchData[touchIdIndex + (touchStep * i)]) >> 4;
+ if(nbTouchPoints == 0 && pointId == lastTouchId) return info;
+
+ // We fetch only the first touch point (the controller seems to handle only one anyway...)
+ info.isTouch = true;
+
+ auto xHigh = touchData[touchXHighIndex + (touchStep * i)] & 0x0f;
+ auto xLow = touchData[touchXLowIndex + (touchStep * i)];
+ uint16_t x = (xHigh << 8) | xLow;
+
+ auto yHigh = touchData[touchYHighIndex + (touchStep * i)] & 0x0f;
+ auto yLow = touchData[touchYLowIndex + (touchStep * i)];
+ uint16_t y = (yHigh << 8) | yLow;
+
+ auto action = touchData[touchEventIndex + (touchStep * i)] >> 6; /* 0 = Down, 1 = Up, 2 = contact*/
+ auto finger = touchData[touchIdIndex + (touchStep * i)] >> 4;
+ auto pressure = touchData[touchXYIndex + (touchStep * i)];
+ auto area = touchData[touchMiscIndex + (touchStep * i)] >> 4;
+
+ info.x = x;
+ info.y = y;
+ info.action = action;
+ return info;
+}
diff --git a/src/drivers/Cst816s.h b/src/drivers/Cst816s.h
new file mode 100644
index 00000000..fea33f40
--- /dev/null
+++ b/src/drivers/Cst816s.h
@@ -0,0 +1,47 @@
+#pragma once
+
+#include <nrfx_twi.h>
+
+namespace Pinetime {
+ namespace Drivers {
+ class Cst816S {
+ public :
+ struct TouchInfos {
+ uint16_t x;
+ uint16_t y;
+ uint8_t action;
+ uint8_t finger;
+ uint8_t pressure;
+ uint8_t area;
+ bool isTouch = false;
+ };
+
+ void Init();
+ void Probe();
+ TouchInfos GetTouchInfo();
+ private:
+ static constexpr uint8_t pinIrq = 28;
+ static constexpr uint8_t pinReset = 10;
+ static constexpr uint8_t address = 0x15;
+ static constexpr uint8_t lastTouchId = 0x0f;
+ static constexpr uint8_t touchPointNumIndex = 2;
+ static constexpr uint8_t touchMiscIndex = 8;
+ static constexpr uint8_t touchXYIndex = 7;
+ static constexpr uint8_t touchEventIndex = 3;
+ static constexpr uint8_t touchXHighIndex = 3;
+ static constexpr uint8_t touchXLowIndex = 4;
+ static constexpr uint8_t touchYHighIndex = 5;
+ static constexpr uint8_t touchYLowIndex = 6;
+ static constexpr uint8_t touchIdIndex = 5;
+ static constexpr uint8_t touchStep = 6;
+
+ uint8_t touchData[63];
+
+ // TODO TWI (i²C) should be created outside and injected into this class
+ // It will be needed when implementing other I²C devices
+ // (0x15 = touch, 0x18 = accelerometer, 0x44 = HR sensor)
+ nrfx_twi_t twi = NRFX_TWI_INSTANCE(1); // Use instance 1, because instance 0 is already used by SPI
+ };
+
+ }
+}
diff --git a/src/main.cpp b/src/main.cpp
index 6463415a..b05c924a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -32,6 +32,10 @@ Pinetime::Controllers::Battery batteryController;
Pinetime::Controllers::Ble bleController;
Pinetime::Controllers::DateTime dateTimeController;
+
+static constexpr uint8_t pinButton = 13;
+static constexpr uint8_t pinTouchIrq = 28;
+
extern "C" {
void vApplicationIdleHook() {
logger.Resume();
@@ -43,6 +47,11 @@ extern "C" {
}
void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
+ if(pin == pinTouchIrq) {
+ displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::TouchEvent);
+ if(!isSleeping) return;
+ }
+
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xTimerStartFromISR(debounceTimer, &xHigherPriorityTaskWoken);
// TODO should I do something if xHigherPriorityTaskWoken == pdTRUE?
@@ -74,7 +83,7 @@ void SystemTask(void *) {
debounceTimer = xTimerCreate ("debounceTimer", 200, pdFALSE, (void *) 0, DebounceTimerCallback);
- nrf_gpio_cfg_sense_input(13, (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pulldown, (nrf_gpio_pin_sense_t)GPIO_PIN_CNF_SENSE_High);
+ nrf_gpio_cfg_sense_input(pinButton, (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pulldown, (nrf_gpio_pin_sense_t)GPIO_PIN_CNF_SENSE_High);
nrf_gpio_cfg_output(15);
nrf_gpio_pin_set(15);
@@ -85,7 +94,17 @@ void SystemTask(void *) {
pinConfig.sense = (nrf_gpiote_polarity_t)NRF_GPIOTE_POLARITY_HITOLO;
pinConfig.pull = (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pulldown;
- nrfx_gpiote_in_init(13, &pinConfig, nrfx_gpiote_evt_handler);
+ nrfx_gpiote_in_init(pinButton, &pinConfig, nrfx_gpiote_evt_handler);
+
+ nrf_gpio_cfg_sense_input(pinTouchIrq, (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pullup, (nrf_gpio_pin_sense_t)GPIO_PIN_CNF_SENSE_Low);
+
+ pinConfig.skip_gpio_setup = true;
+ pinConfig.hi_accuracy = false;
+ pinConfig.is_watcher = false;
+ pinConfig.sense = (nrf_gpiote_polarity_t)NRF_GPIOTE_POLARITY_HITOLO;
+ pinConfig.pull = (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pullup;
+
+ nrfx_gpiote_in_init(pinTouchIrq, &pinConfig, nrfx_gpiote_evt_handler);
vTaskSuspend(nullptr);
}
diff --git a/src/sdk_config.h b/src/sdk_config.h
index 0586c662..e74751ef 100644
--- a/src/sdk_config.h
+++ b/src/sdk_config.h
@@ -3644,7 +3644,7 @@
// <e> NRFX_PRS_ENABLED - nrfx_prs - Peripheral Resource Sharing module
//==========================================================
#ifndef NRFX_PRS_ENABLED
-#define NRFX_PRS_ENABLED 1
+#define NRFX_PRS_ENABLED 0
#endif
// <q> NRFX_PRS_BOX_0_ENABLED - Enables box 0 in the module.
@@ -4281,7 +4281,7 @@
// <e> NRFX_SAADC_ENABLED - nrfx_saadc - SAADC peripheral driver
//==========================================================
#ifndef NRFX_SAADC_ENABLED
-#define NRFX_SAADC_ENABLED 0
+#define NRFX_SAADC_ENABLED 1
#endif
// <o> NRFX_SAADC_CONFIG_RESOLUTION - Resolution
@@ -5236,7 +5236,7 @@
// <e> NRFX_TWI_ENABLED - nrfx_twi - TWI peripheral driver
//==========================================================
#ifndef NRFX_TWI_ENABLED
-#define NRFX_TWI_ENABLED 0
+#define NRFX_TWI_ENABLED 1
#endif
// <q> NRFX_TWI0_ENABLED - Enable TWI0 instance
@@ -5249,7 +5249,7 @@
#ifndef NRFX_TWI1_ENABLED
-#define NRFX_TWI1_ENABLED 0
+#define NRFX_TWI1_ENABLED 1
#endif
// <o> NRFX_TWI_DEFAULT_CONFIG_FREQUENCY - Frequency
@@ -6729,94 +6729,6 @@
// </e>
-// <e> TWI_ENABLED - nrf_drv_twi - TWI/TWIM peripheral driver - legacy layer
-//==========================================================
-#ifndef TWI_ENABLED
-#define TWI_ENABLED 0
-#endif
-// <o> TWI_DEFAULT_CONFIG_FREQUENCY - Frequency
-
-// <26738688=> 100k
-// <67108864=> 250k
-// <104857600=> 400k
-
-#ifndef TWI_DEFAULT_CONFIG_FREQUENCY
-#define TWI_DEFAULT_CONFIG_FREQUENCY 26738688
-#endif
-
-// <q> TWI_DEFAULT_CONFIG_CLR_BUS_INIT - Enables bus clearing procedure during init
-
-
-#ifndef TWI_DEFAULT_CONFIG_CLR_BUS_INIT
-#define TWI_DEFAULT_CONFIG_CLR_BUS_INIT 0
-#endif
-
-// <q> TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT - Enables bus holding after uninit
-
-
-#ifndef TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT
-#define TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT 0
-#endif
-
-// <o> TWI_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority
-
-
-// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
-// <0=> 0 (highest)
-// <1=> 1
-// <2=> 2
-// <3=> 3
-// <4=> 4
-// <5=> 5
-// <6=> 6
-// <7=> 7
-
-#ifndef TWI_DEFAULT_CONFIG_IRQ_PRIORITY
-#define TWI_DEFAULT_CONFIG_IRQ_PRIORITY 6
-#endif
-
-// <e> TWI0_ENABLED - Enable TWI0 instance
-//==========================================================
-#ifndef TWI0_ENABLED
-#define TWI0_ENABLED 0
-#endif
-// <q> TWI0_USE_EASY_DMA - Use EasyDMA (if present)
-
-
-#ifndef TWI0_USE_EASY_DMA
-#define TWI0_USE_EASY_DMA 0
-#endif
-
-// </e>
-
-// <e> TWI1_ENABLED - Enable TWI1 instance
-//==========================================================
-#ifndef TWI1_ENABLED
-#define TWI1_ENABLED 0
-#endif
-// <q> TWI1_USE_EASY_DMA - Use EasyDMA (if present)
-
-
-#ifndef TWI1_USE_EASY_DMA
-#define TWI1_USE_EASY_DMA 0
-#endif
-
-// </e>
-
-// <q> TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED - Enables nRF52 anomaly 109 workaround for TWIM.
-
-
-// <i> The workaround uses interrupts to wake up the CPU by catching
-// <i> the start event of zero-frequency transmission, clear the
-// <i> peripheral, set desired frequency, start the peripheral, and
-// <i> the proper transmission. See more in the Errata document or
-// <i> Anomaly 109 Addendum located at https://infocenter.nordicsemi.com/
-
-#ifndef TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED
-#define TWIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED 0
-#endif
-
-// </e>
// <e> UART_ENABLED - nrf_drv_uart - UART/UARTE peripheral driver - legacy layer
//==========================================================
@@ -8540,15 +8452,15 @@
// <e> NRF_LOG_ENABLED - nrf_log - Logger
//==========================================================
#ifndef NRF_LOG_ENABLED
-#define NRF_LOG_ENABLED 0
+#define NRF_LOG_ENABLED 1
#endif
#ifndef NRF_LOG_BACKEND_RTT_ENABLED
-#define NRF_LOG_BACKEND_RTT_ENABLED 0
+#define NRF_LOG_BACKEND_RTT_ENABLED 1
#endif
#ifndef NRF_LOG_BACKEND_SERIAL_USES_RTT
-#define NRF_LOG_BACKEND_SERIAL_USES_RTT 0
+#define NRF_LOG_BACKEND_SERIAL_USES_RTT 1
#endif
// <h> Log message pool - Configuration of log message pool