#include "drivers/Cst816s.h" #include "lv_drv_conf.h" // MONITOR_ZOOM #include #include #include 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! * */ //Cst816S::Cst816S(TwiMaster& twiMaster, uint8_t twiAddress) : twiMaster {twiMaster}, twiAddress {twiAddress} { //} Cst816S::Cst816S() { } bool Cst816S::Init() { return true; } Cst816S::TouchInfos Cst816S::GetTouchInfo() { int x, y; uint32_t buttons = SDL_GetMouseState(&x, &y); // scale down real mouse coordinates to InfiniTime scale to make zoom work // the MONITOR_ZOOM-factor is defined in lv_drv_conf.h x /= MONITOR_ZOOM; y /= MONITOR_ZOOM; Cst816S::TouchInfos info; info.x = x; info.y = y; info.touching = (buttons & SDL_BUTTON_LMASK) != 0; //info.gesture = gesture; info.isValid = x > 0 && x <= maxX && y > 0 && y <= maxY; if(info.isValid) { if(!is_pressed && info.touching) { // start klick pressed_since = std::chrono::steady_clock::now(); is_pressed = true; is_long_press = false; is_swipe = false; is_stationary = true; x_start = info.x; y_start = info.y; } else if(is_pressed && info.touching) { // is it long press? if (is_stationary) { // check if while touching we moved away from the start coordinates double x_diff = static_cast(info.x) - x_start; double y_diff = static_cast(info.y) - y_start; double norm = hypot(x_diff, y_diff); if(norm > 20) { // we moved out of start area is_stationary = false; } } if (!is_long_press && !is_swipe) { // check for long-press only if it's not yet a long-press and didn't move std::chrono::duration press_duration = std::chrono::steady_clock::now() - pressed_since; if(is_stationary && press_duration.count() > 1.0) { // longer than 1 second pressed, then it is long-press is_long_press = true; info.gesture = Gestures::LongPress; } else if(!is_stationary) { // moved mouse fast enough to not be a long-press is_swipe = true; double x_diff = static_cast(info.x) - x_start; double y_diff = static_cast(info.y) - y_start; if (fabs(x_diff) > fabs(y_diff)) { // x-swipe if (x_diff < 0) { info.gesture = Gestures::SlideLeft; } else { info.gesture = Gestures::SlideRight; } } else { // y-swipe if (y_diff < 0) { info.gesture = Gestures::SlideUp; } else { info.gesture = Gestures::SlideDown; } } } } } else if(is_pressed && !info.touching) { // end klick is_pressed = false; double x_diff = static_cast(info.x) - x_start; double y_diff = static_cast(info.y) - y_start; double norm = hypot(x_diff, y_diff); if(norm < 20) { if(is_stationary && !is_long_press && !is_swipe) { // no swipe with less than 5 pixel mouse movement info.gesture = Gestures::SingleTap; } } } } return info; } void Cst816S::Sleep() { NRF_LOG_INFO("[TOUCHPANEL] Sleep"); } void Cst816S::Wakeup() { Init(); NRF_LOG_INFO("[TOUCHPANEL] Wakeup"); } bool Cst816S::CheckDeviceIds() { return chipId == 0xb4 && vendorId == 0 && fwVersion == 1; }