From a9a743f191104e30355a707dee33e1135da9d777 Mon Sep 17 00:00:00 2001 From: Laurent Ellerbach Date: Wed, 15 Feb 2023 15:48:57 +0100 Subject: [PATCH] Add touch pad support for ESP32 and ESP32-S2/3 (#2536) ***NO_CI*** --- .gitignore | 2 +- CMake/Modules/FindESP32_IDF.cmake | 1 + .../FindnanoFramework.Hardware.Esp32.cmake | 1 + targets/ESP32/_include/esp32_idf.h | 6 + .../nanoFramework_hardware_esp32_native.cpp | 113 +- .../nanoFramework_hardware_esp32_native.h | 311 ++++- ...ware_esp32_native_Hardware_Esp32_Sleep.cpp | 163 ++- ...ramework_Hardware_Esp32_Touch_TouchPad.cpp | 1149 +++++++++++++++++ 8 files changed, 1728 insertions(+), 18 deletions(-) create mode 100644 targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad.cpp diff --git a/.gitignore b/.gitignore index 68b0f5f694..9727ed1dc9 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,7 @@ /zips/ # ignore build folder -/build/ +/build**/ /out/ /build/.gitkeep diff --git a/CMake/Modules/FindESP32_IDF.cmake b/CMake/Modules/FindESP32_IDF.cmake index d07fba87cb..34d9f4a9fd 100644 --- a/CMake/Modules/FindESP32_IDF.cmake +++ b/CMake/Modules/FindESP32_IDF.cmake @@ -16,6 +16,7 @@ list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/${ESP32_CP list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/${ESP32_CPU_TYPE}/${TARGET_SERIES_SHORT}/include) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/driver/${TARGET_SERIES_SHORT}/include/driver) +list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/driver/${TARGET_SERIES_SHORT}/include) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/hal/include) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/hal/${TARGET_SERIES_SHORT}/include) list(APPEND ESP32_IDF_INCLUDE_DIRS ${esp32_idf_SOURCE_DIR}/components/soc/${TARGET_SERIES_SHORT}/include) diff --git a/CMake/Modules/FindnanoFramework.Hardware.Esp32.cmake b/CMake/Modules/FindnanoFramework.Hardware.Esp32.cmake index b99e6056c9..4f44319cf7 100644 --- a/CMake/Modules/FindnanoFramework.Hardware.Esp32.cmake +++ b/CMake/Modules/FindnanoFramework.Hardware.Esp32.cmake @@ -23,6 +23,7 @@ set(nanoFramework.Hardware.Esp32_SRCS nanoFramework_hardware_esp32_native_Hardware_Esp32_HighResTimer.cpp nanoFramework_hardware_esp32_native_Hardware_Esp32_Configuration.cpp nanoFramework_hardware_esp32_native_Hardware_Esp32_NativeMemory.cpp + nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad.cpp ) foreach(SRC_FILE ${nanoFramework.Hardware.Esp32_SRCS}) diff --git a/targets/ESP32/_include/esp32_idf.h b/targets/ESP32/_include/esp32_idf.h index faf9f9ae38..4f30d9d30b 100644 --- a/targets/ESP32/_include/esp32_idf.h +++ b/targets/ESP32/_include/esp32_idf.h @@ -70,6 +70,12 @@ #include #include +// Touch pad supported only on those platforms +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) +#include +#include +#endif + // includes specific for TinyUSB and CDC #if CONFIG_USB_CDC_ENABLED #include diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native.cpp b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native.cpp index 219a66e9e4..9562855ea6 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native.cpp +++ b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native.cpp @@ -1,4 +1,4 @@ -// +// // Copyright (c) .NET Foundation and Contributors // Portions Copyright (c) Microsoft Corporation. All rights reserved. // See LICENSE file in the project root for full license information. @@ -13,6 +13,7 @@ static const CLR_RT_MethodHandler method_lookup[] = NULL, NULL, NULL, + NULL, Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Configuration::NativeSetPinFunction___STATIC__VOID__I4__I4, Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Configuration::NativeGetPinFunction___STATIC__I4__I4, NULL, @@ -66,20 +67,122 @@ static const CLR_RT_MethodHandler method_lookup[] = Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByTimer___STATIC__nanoFrameworkHardwareEsp32EspNativeError__U8, Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByPin___STATIC__nanoFrameworkHardwareEsp32EspNativeError__nanoFrameworkHardwareEsp32SleepWakeupGpioPin__I4, Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByMultiPins___STATIC__nanoFrameworkHardwareEsp32EspNativeError__nanoFrameworkHardwareEsp32SleepWakeupGpioPin__nanoFrameworkHardwareEsp32SleepWakeupMode, - Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByTouchPad___STATIC__nanoFrameworkHardwareEsp32EspNativeError, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByTouchPad___STATIC__nanoFrameworkHardwareEsp32EspNativeError__I4__I4__U1, Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeStartLightSleep___STATIC__nanoFrameworkHardwareEsp32EspNativeError, Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeStartDeepSleep___STATIC__nanoFrameworkHardwareEsp32EspNativeError, Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeGetWakeupCause___STATIC__nanoFrameworkHardwareEsp32SleepWakeupCause, Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeGetWakeupGpioPin___STATIC__nanoFrameworkHardwareEsp32SleepWakeupGpioPin, - Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeGetWakeupTouchpad___STATIC__nanoFrameworkHardwareEsp32SleepTouchPad, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeGetWakeupTouchpad___STATIC__I4, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeInit___VOID, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeDeinit___VOID, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeRead___U4, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeGetThreshold___U4, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeSetThreshold___VOID__U4, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeGetTouchSpeed___VOID__BYREF_I4__BYREF_I4, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeSetChargeSpeed___VOID__I4__I4, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeCalibrate___I4__I4, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeGetGpioNumberFromTouchNumber___STATIC__I4__I4, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeGetTriggerMode___STATIC__nanoFrameworkHardwareEsp32TouchTouchTriggerMode, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeSetTriggerMode___STATIC__VOID__nanoFrameworkHardwareEsp32TouchTouchTriggerMode, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeGetTriggerSource___STATIC__nanoFrameworkHardwareEsp32TouchWakeUpSource, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeSetTriggerSource___STATIC__VOID__nanoFrameworkHardwareEsp32TouchWakeUpSource, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeGetMeasurementMode___STATIC__nanoFrameworkHardwareEsp32TouchMeasurementMode, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeSetMeasurementMode___STATIC__VOID__nanoFrameworkHardwareEsp32TouchMeasurementMode, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeSetVoltage___STATIC__VOID__nanoFrameworkHardwareEsp32TouchTouchHighVoltage__nanoFrameworkHardwareEsp32TouchTouchLowVoltage__nanoFrameworkHardwareEsp32TouchTouchHighVoltageAttenuation, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeGetVoltage___STATIC__VOID__BYREF_nanoFrameworkHardwareEsp32TouchTouchHighVoltage__BYREF_nanoFrameworkHardwareEsp32TouchTouchLowVoltage__BYREF_nanoFrameworkHardwareEsp32TouchTouchHighVoltageAttenuation, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeStartFilter___STATIC__VOID__nanoFrameworkHardwareEsp32TouchIFilterSetting, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeStopFilter___STATIC__VOID, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeSetMeasurementTime___STATIC__VOID__U2__U2, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeGetMeasurementTime___STATIC__VOID__BYREF_U2__BYREF_U2, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeGetDenoise___STATIC__VOID__nanoFrameworkHardwareEsp32TouchDenoiseSetting, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeSetDenoise___STATIC__VOID__nanoFrameworkHardwareEsp32TouchDenoiseSetting, + Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeDenoiseEnabled___STATIC__VOID__BOOLEAN, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, }; const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Esp32 = { "nanoFramework.Hardware.Esp32", - 0xBE7FF253, + 0x573559C0, method_lookup, - { 100, 0, 7, 3 } + { 100, 0, 8, 0 } }; // clang-format on diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native.h b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native.h index 3a804f92d9..757b5e36f4 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native.h +++ b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native.h @@ -9,15 +9,42 @@ #include #include -#include +#include #include +typedef enum __nfpack EspNativeError +{ + EspNativeError_OK = 0, + EspNativeError_FAIL = -1, + EspNativeError_NO_MEM = 257, + EspNativeError_INVALID_ARG = 258, + EspNativeError_INVALID_STATE = 259, + EspNativeError_INVALID_SIZE = 260, + EspNativeError_NOT_FOUND = 261, + EspNativeError_NOT_SUPPORTED = 262, + EspNativeError_TIMEOUT = 263, + EspNativeError_INVALID_RESPONSE = 264, + EspNativeError_INVALID_CRC = 265, + EspNativeError_INVALID_VERSION = 266, + EspNativeError_INVALID_MAC = 267, + EspNativeError_WIFI_BASE = 12288, +} EspNativeError; typedef enum __nfpack HighResTimerEventType { HighResTimerEventType_TimerExpired = 101, } HighResTimerEventType; +typedef enum __nfpack Logging_LogLevel +{ + Logging_LogLevel_LOG_LEVEL_NONE = 0, + Logging_LogLevel_LOG_LEVEL_ERROR = 1, + Logging_LogLevel_LOG_LEVEL_WARN = 2, + Logging_LogLevel_LOG_LEVEL_INFO = 3, + Logging_LogLevel_LOG_LEVEL_DEBUG = 4, + Logging_LogLevel_LOG_LEVEL_VERBOSE = 5, +} Logging_LogLevel; + typedef enum __nfpack NativeMemory_MemoryType { NativeMemory_MemoryType_All = 0, @@ -25,6 +52,174 @@ typedef enum __nfpack NativeMemory_MemoryType NativeMemory_MemoryType_SpiRam = 2, } NativeMemory_MemoryType; +typedef enum __nfpack Sleep_WakeupCause +{ + Sleep_WakeupCause_Undefined = 0, + Sleep_WakeupCause_Ext0 = 2, + Sleep_WakeupCause_Ext1 = 3, + Sleep_WakeupCause_Timer = 4, + Sleep_WakeupCause_TouchPad = 5, + Sleep_WakeupCause_Ulp = 6, + Sleep_WakeupCause_Gpio = 7, + Sleep_WakeupCause_Uart = 8, +} Sleep_WakeupCause; + +typedef enum __nfpack Sleep_WakeupGpioPin +{ + Sleep_WakeupGpioPin_None = 0, + Sleep_WakeupGpioPin_Pin0 = 1, + Sleep_WakeupGpioPin_Pin2 = 4, + Sleep_WakeupGpioPin_Pin4 = 16, + Sleep_WakeupGpioPin_Pin12 = 4096, + Sleep_WakeupGpioPin_Pin13 = 8192, + Sleep_WakeupGpioPin_Pin14 = 16384, + Sleep_WakeupGpioPin_Pin15 = 32768, + Sleep_WakeupGpioPin_Pin25 = 33554432, + Sleep_WakeupGpioPin_Pin26 = 67108864, + Sleep_WakeupGpioPin_Pin27 = 134217728, + Sleep_WakeupGpioPin_Pin32 = 4294967296, + Sleep_WakeupGpioPin_Pin33 = 8589934592, + Sleep_WakeupGpioPin_Pin34 = 17179869184, + Sleep_WakeupGpioPin_Pin35 = 34359738368, + Sleep_WakeupGpioPin_Pin36 = 68719476736, + Sleep_WakeupGpioPin_Pin37 = 137438953472, + Sleep_WakeupGpioPin_Pin38 = 274877906944, + Sleep_WakeupGpioPin_Pin39 = 549755813888, +} Sleep_WakeupGpioPin; + +typedef enum __nfpack Sleep_WakeupMode +{ + Sleep_WakeupMode_AllLow = 0, + Sleep_WakeupMode_AnyHigh = 1, +} Sleep_WakeupMode; + +typedef enum __nfpack DenoiseCapacitance +{ + DenoiseCapacitance_Cap5pf = 0, + DenoiseCapacitance_Cap6pf4 = 1, + DenoiseCapacitance_Cap7pf8 = 2, + DenoiseCapacitance_Cap9pf2 = 3, + DenoiseCapacitance_Cap10pf6 = 4, + DenoiseCapacitance_Cap12pf0 = 5, + DenoiseCapacitance_Cap13pf4 = 6, + DenoiseCapacitance_Cap14pf8 = 7, +} DenoiseCapacitance; + +typedef enum __nfpack DenoiseRange +{ + DenoiseRange_Bit12 = 0, + DenoiseRange_Bit10 = 1, + DenoiseRange_Bit8 = 2, + DenoiseRange_Bit4 = 3, +} DenoiseRange; + +typedef enum __nfpack FilterSettingDebounce +{ + FilterSettingDebounce_NoDebounce = 0, + FilterSettingDebounce_One = 1, + FilterSettingDebounce_Two = 2, + FilterSettingDebounce_Three = 3, + FilterSettingDebounce_Four = 4, + FilterSettingDebounce_Five = 5, + FilterSettingDebounce_Six = 6, + FilterSettingDebounce_Seven = 7, +} FilterSettingDebounce; + +typedef enum __nfpack FilterSettingMode +{ + FilterSettingMode_Iir4 = 0, + FilterSettingMode_Iir8 = 1, + FilterSettingMode_Iir16 = 2, + FilterSettingMode_Iir32 = 3, + FilterSettingMode_Iir64 = 4, + FilterSettingMode_Iir128 = 5, + FilterSettingMode_Iir256 = 6, + FilterSettingMode_IirJitter = 7, +} FilterSettingMode; + +typedef enum __nfpack FilterSettingNoiseThreshold +{ + FilterSettingNoiseThreshold_Low = 0, + FilterSettingNoiseThreshold_Mediumlow = 1, + FilterSettingNoiseThreshold_MediumHigh = 2, + FilterSettingNoiseThreshold_High = 3, +} FilterSettingNoiseThreshold; + +typedef enum __nfpack FilterSettingSmoothMode +{ + FilterSettingSmoothMode_Off = 0, + FilterSettingSmoothMode_Iir2 = 1, + FilterSettingSmoothMode_Iir4 = 2, + FilterSettingSmoothMode_Iir8 = 3, +} FilterSettingSmoothMode; + +typedef enum __nfpack MeasurementMode +{ + MeasurementMode_Timer = 0, + MeasurementMode_Software = 1, +} MeasurementMode; + +typedef enum __nfpack TouchChargeSpeed_ChargeSpeed +{ + TouchChargeSpeed_ChargeSpeed_Zero = 0, + TouchChargeSpeed_ChargeSpeed_Slowest = 1, + TouchChargeSpeed_ChargeSpeed_Speed2 = 2, + TouchChargeSpeed_ChargeSpeed_Speed3 = 3, + TouchChargeSpeed_ChargeSpeed_Speed4 = 4, + TouchChargeSpeed_ChargeSpeed_Speed5 = 5, + TouchChargeSpeed_ChargeSpeed_Speed6 = 6, + TouchChargeSpeed_ChargeSpeed_Fastest = 7, +} TouchChargeSpeed_ChargeSpeed; + +typedef enum __nfpack TouchChargeSpeed_InitialCharge +{ + TouchChargeSpeed_InitialCharge_Low = 0, + TouchChargeSpeed_InitialCharge_High = 1, +} TouchChargeSpeed_InitialCharge; + +typedef enum __nfpack TouchHighVoltage +{ + TouchHighVoltage_Volt2V4 = 0, + TouchHighVoltage_Volt2V5 = 1, + TouchHighVoltage_Volt2V6 = 2, + TouchHighVoltage_Volt2V7 = 3, +} TouchHighVoltage; + +typedef enum __nfpack TouchHighVoltageAttenuation +{ + TouchHighVoltageAttenuation_Volt1V5 = 0, + TouchHighVoltageAttenuation_Volt1V0 = 1, + TouchHighVoltageAttenuation_Volt0V5 = 2, + TouchHighVoltageAttenuation_Volt0V0 = 3, +} TouchHighVoltageAttenuation; + +typedef enum __nfpack TouchLowVoltage +{ + TouchLowVoltage_Volt0V5 = 0, + TouchLowVoltage_Volt0V6 = 1, + TouchLowVoltage_Volt0V7 = 2, + TouchLowVoltage_Volt0V8 = 3, +} TouchLowVoltage; + +typedef enum __nfpack TouchTriggerMode +{ + TouchTriggerMode_BellowThreshold = 0, + TouchTriggerMode_AboveThreshold = 1, +} TouchTriggerMode; + +typedef enum __nfpack WakeUpSource +{ + WakeUpSource_BothSet1AndSet2 = 0, + WakeUpSource_OnlySet1 = 1, +} WakeUpSource; + +typedef enum __nfpack ValueTypes +{ + ValueTypes_Index = 0, + ValueTypes_DeviceIndex = 256, + ValueTypes_DeviceType = 65536, +} ValueTypes; + struct Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Configuration { NANOCLR_NATIVE_DECLARE(NativeSetPinFunction___STATIC__VOID__I4__I4); @@ -90,12 +285,122 @@ struct Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_ NativeEnableWakeupByPin___STATIC__nanoFrameworkHardwareEsp32EspNativeError__nanoFrameworkHardwareEsp32SleepWakeupGpioPin__I4); NANOCLR_NATIVE_DECLARE( NativeEnableWakeupByMultiPins___STATIC__nanoFrameworkHardwareEsp32EspNativeError__nanoFrameworkHardwareEsp32SleepWakeupGpioPin__nanoFrameworkHardwareEsp32SleepWakeupMode); - NANOCLR_NATIVE_DECLARE(NativeEnableWakeupByTouchPad___STATIC__nanoFrameworkHardwareEsp32EspNativeError); + NANOCLR_NATIVE_DECLARE(NativeEnableWakeupByTouchPad___STATIC__nanoFrameworkHardwareEsp32EspNativeError__I4__I4__U1); NANOCLR_NATIVE_DECLARE(NativeStartLightSleep___STATIC__nanoFrameworkHardwareEsp32EspNativeError); NANOCLR_NATIVE_DECLARE(NativeStartDeepSleep___STATIC__nanoFrameworkHardwareEsp32EspNativeError); NANOCLR_NATIVE_DECLARE(NativeGetWakeupCause___STATIC__nanoFrameworkHardwareEsp32SleepWakeupCause); NANOCLR_NATIVE_DECLARE(NativeGetWakeupGpioPin___STATIC__nanoFrameworkHardwareEsp32SleepWakeupGpioPin); - NANOCLR_NATIVE_DECLARE(NativeGetWakeupTouchpad___STATIC__nanoFrameworkHardwareEsp32SleepTouchPad); + NANOCLR_NATIVE_DECLARE(NativeGetWakeupTouchpad___STATIC__I4); + + //--// +}; + +struct Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_DenoiseSetting +{ + static const int FIELD___denoiseCapacitance = 1; + static const int FIELD___denoiseRange = 2; + + //--// +}; + +struct Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_Esp32FilterSetting +{ + static const int FIELD___period = 1; + + //--// +}; +/* +struct Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_MeasurementTime +{ + static const int FIELD__k__BackingField = 1; + static const int FIELD__k__BackingField = 2; + + //--// +}; +*/ +struct Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_S2S3FilterSetting +{ + static const int FIELD___periodeSettingMode = 1; + static const int FIELD___filterSettingDebounce = 2; + static const int FIELD___filterSettingNoiseThreshold = 3; + static const int FIELD___jitterSize = 4; + static const int FIELD___filterSettingSmoothMode = 5; + + //--// +}; +/* +struct Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchChargeSpeed +{ + static const int FIELD__k__BackingField = 1; + static const int FIELD__k__BackingField = 2; + + //--// +}; + +struct Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPadEventArgs +{ + static const int FIELD__k__BackingField = 3; + static const int FIELD__k__BackingField = 4; + + //--// +}; +*/ +struct Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad +{ + static const int FIELD_STATIC___touchHighVoltage = 1; + static const int FIELD_STATIC___touchLowVoltage = 2; + static const int FIELD_STATIC___touchHighVoltageAttenuation = 3; + static const int FIELD_STATIC___isFilterOn = 4; + static const int FIELD_STATIC___denoiseEnabled = 5; + static const int FIELD_STATIC___touchPadEventHandler = 6; + + static const int FIELD___calibrationData = 1; + static const int FIELD___callbacks = 2; + static const int FIELD___syncLock = 3; + static const int FIELD___disposedValue = 4; + static const int FIELD___touchPadNumber = 5; + + NANOCLR_NATIVE_DECLARE(NativeInit___VOID); + NANOCLR_NATIVE_DECLARE(NativeDeinit___VOID); + NANOCLR_NATIVE_DECLARE(NativeRead___U4); + NANOCLR_NATIVE_DECLARE(NativeGetThreshold___U4); + NANOCLR_NATIVE_DECLARE(NativeSetThreshold___VOID__U4); + NANOCLR_NATIVE_DECLARE(NativeGetTouchSpeed___VOID__BYREF_I4__BYREF_I4); + NANOCLR_NATIVE_DECLARE(NativeSetChargeSpeed___VOID__I4__I4); + NANOCLR_NATIVE_DECLARE(NativeCalibrate___I4__I4); + NANOCLR_NATIVE_DECLARE(NativeGetGpioNumberFromTouchNumber___STATIC__I4__I4); + NANOCLR_NATIVE_DECLARE(NativeGetTriggerMode___STATIC__nanoFrameworkHardwareEsp32TouchTouchTriggerMode); + NANOCLR_NATIVE_DECLARE(NativeSetTriggerMode___STATIC__VOID__nanoFrameworkHardwareEsp32TouchTouchTriggerMode); + NANOCLR_NATIVE_DECLARE(NativeGetTriggerSource___STATIC__nanoFrameworkHardwareEsp32TouchWakeUpSource); + NANOCLR_NATIVE_DECLARE(NativeSetTriggerSource___STATIC__VOID__nanoFrameworkHardwareEsp32TouchWakeUpSource); + NANOCLR_NATIVE_DECLARE(NativeGetMeasurementMode___STATIC__nanoFrameworkHardwareEsp32TouchMeasurementMode); + NANOCLR_NATIVE_DECLARE(NativeSetMeasurementMode___STATIC__VOID__nanoFrameworkHardwareEsp32TouchMeasurementMode); + NANOCLR_NATIVE_DECLARE( + NativeSetVoltage___STATIC__VOID__nanoFrameworkHardwareEsp32TouchTouchHighVoltage__nanoFrameworkHardwareEsp32TouchTouchLowVoltage__nanoFrameworkHardwareEsp32TouchTouchHighVoltageAttenuation); + NANOCLR_NATIVE_DECLARE( + NativeGetVoltage___STATIC__VOID__BYREF_nanoFrameworkHardwareEsp32TouchTouchHighVoltage__BYREF_nanoFrameworkHardwareEsp32TouchTouchLowVoltage__BYREF_nanoFrameworkHardwareEsp32TouchTouchHighVoltageAttenuation); + NANOCLR_NATIVE_DECLARE(NativeStartFilter___STATIC__VOID__nanoFrameworkHardwareEsp32TouchIFilterSetting); + NANOCLR_NATIVE_DECLARE(NativeStopFilter___STATIC__VOID); + NANOCLR_NATIVE_DECLARE(NativeSetMeasurementTime___STATIC__VOID__U2__U2); + NANOCLR_NATIVE_DECLARE(NativeGetMeasurementTime___STATIC__VOID__BYREF_U2__BYREF_U2); + NANOCLR_NATIVE_DECLARE(NativeGetDenoise___STATIC__VOID__nanoFrameworkHardwareEsp32TouchDenoiseSetting); + NANOCLR_NATIVE_DECLARE(NativeSetDenoise___STATIC__VOID__nanoFrameworkHardwareEsp32TouchDenoiseSetting); + NANOCLR_NATIVE_DECLARE(NativeDenoiseEnabled___STATIC__VOID__BOOLEAN); + + //--// +}; + +struct Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPadEvent +{ + static const int FIELD__TouchPadNumber = 3; + static const int FIELD__Touched = 4; + + //--// +}; + +struct Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPadEventHandler +{ + static const int FIELD___pinMap = 1; //--// }; diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_Hardware_Esp32_Sleep.cpp b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_Hardware_Esp32_Sleep.cpp index dec5882ac7..b88622d17e 100644 --- a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_Hardware_Esp32_Sleep.cpp +++ b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_Hardware_Esp32_Sleep.cpp @@ -10,6 +10,10 @@ #include "nanoFramework_hardware_esp32_native.h" +#if defined(CONFIG_IDF_TARGET_ESP32) +static bool CalibrateEspTouchPad(touch_pad_t pad, int calibrationCount, int coefficient); +#endif + HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep:: NativeEnableWakeupByTimer___STATIC__nanoFrameworkHardwareEsp32EspNativeError__U8(CLR_RT_StackFrame &stack) { @@ -98,26 +102,134 @@ HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32 } HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep:: - NativeEnableWakeupByTouchPad___STATIC__nanoFrameworkHardwareEsp32EspNativeError(CLR_RT_StackFrame &stack) + NativeEnableWakeupByTouchPad___STATIC__nanoFrameworkHardwareEsp32EspNativeError__I4__I4__U1( + CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); #if SOC_PM_SUPPORT_EXT_WAKEUP + esp_err_t err; + int pad1; + int coefficient; - esp_err_t err = esp_sleep_enable_touchpad_wakeup(); +#if defined(CONFIG_IDF_TARGET_ESP32) + int pad2; + // Setup the sleep mode + touch_pad_init(); + touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); - // Return err to the managed application - stack.SetResult_I4((int)err); + pad1 = stack.Arg0().NumericByRef().s4; + pad2 = stack.Arg1().NumericByRef().s4; + coefficient = stack.Arg2().NumericByRef().u1; - NANOCLR_NOCLEANUP_NOLABEL(); + // Check that the configuration is correct + if ((pad1 < 0) && (pad2 < 0)) + { + // We can't have both pads negative + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + else if ((pad1 >= TOUCH_PAD_MAX) || (pad2 >= TOUCH_PAD_MAX)) + { + // We can't have any pad more than the maximum pad number + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + else if (pad1 < 0) + { + // If we have pad1 negative but pad 2 positive, swap them + int padTmp = pad2; + pad2 = pad1; + pad1 = padTmp; + // Set the source on 1 pad only + touch_pad_set_trigger_source(TOUCH_TRIGGER_SOURCE_SET1); + } + else + { + // Both positives, both in the norm, then both sources + touch_pad_set_trigger_source(TOUCH_TRIGGER_SOURCE_BOTH); + } + + // Set pad 1 and calibrate it + touch_pad_config((touch_pad_t)pad1, 0); + if (!CalibrateEspTouchPad((touch_pad_t)pad1, 20, coefficient)) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + if (pad2 >= 0) + { + // Set pad 2 and calibrate it if it's a valid one + touch_pad_config((touch_pad_t)pad2, 0); + if (!CalibrateEspTouchPad((touch_pad_t)pad2, 20, coefficient)) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + } #else + touch_pad_denoise_t denoise; + touch_filter_config_t filterInfo; + uint32_t touchValue; + uint32_t wakeThreshold; + + touch_pad_init(); + pad1 = stack.Arg0().NumericByRef().s4; + if (pad1 <= 0) + { + // We can't have both pads negative + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } - NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); + touch_pad_config((touch_pad_t)pad1); + // Denoise setting at TouchSensor 0. + denoise = { + // The bits to be cancelled are determined according to the noise level. + .grade = TOUCH_PAD_DENOISE_BIT4, + .cap_level = TOUCH_PAD_DENOISE_CAP_L4, + }; + touch_pad_denoise_set_config(&denoise); + touch_pad_denoise_enable(); + + // Filter setting + filterInfo = { + .mode = TOUCH_PAD_FILTER_IIR_16, + .debounce_cnt = 1, // 1 time count. + .noise_thr = 0, // 50% + .jitter_step = 4, // use for jitter mode. + .smh_lvl = TOUCH_PAD_SMOOTH_IIR_2, + }; + touch_pad_filter_set_config(&filterInfo); + touch_pad_filter_enable(); + + // Set sleep touch pad. No proximity + touch_pad_sleep_channel_enable((touch_pad_t)pad1, true); + touch_pad_sleep_channel_enable_proximity((touch_pad_t)pad1, false); + // Reducing the operating frequency can effectively reduce power consumption. + touch_pad_sleep_channel_set_work_time(1000, TOUCH_PAD_MEASURE_CYCLE_DEFAULT); + // Enable touch sensor clock. Work mode is "timer trigger". + touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); + touch_pad_fsm_start(); + // Giving time for measurements + vTaskDelay(100 / portTICK_RATE_MS); + + coefficient = stack.Arg2().NumericByRef().u1; + + touch_pad_sleep_channel_read_smooth((touch_pad_t)pad1, &touchValue); + // wakeup when touch sensor crosses % of background level + wakeThreshold = touchValue * (100 - coefficient) / 100.0; + touch_pad_sleep_set_threshold((touch_pad_t)pad1, wakeThreshold); +#endif - NANOCLR_NOCLEANUP(); + err = esp_sleep_enable_touchpad_wakeup(); + esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); + + // Return err to the managed application + stack.SetResult_I4((int)err); +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); #endif + + NANOCLR_NOCLEANUP(); } HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep:: @@ -208,16 +320,22 @@ HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32 } HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep:: - NativeGetWakeupTouchpad___STATIC__nanoFrameworkHardwareEsp32SleepTouchPad(CLR_RT_StackFrame &stack) + NativeGetWakeupTouchpad___STATIC__I4(CLR_RT_StackFrame &stack) { NANOCLR_HEADER(); #if SOC_PM_SUPPORT_EXT_WAKEUP touch_pad_t touch_pad = esp_sleep_get_touchpad_wakeup_status(); + int retValue = (int)touch_pad; + // We have to remap this enum. + if (touch_pad == TOUCH_PAD_MAX) + { + retValue = -1; + } // Return value to the managed application - stack.SetResult_I4((int)touch_pad); + stack.SetResult_I4(retValue); NANOCLR_NOCLEANUP_NOLABEL(); @@ -229,3 +347,30 @@ HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32 #endif } + +#if defined(CONFIG_IDF_TARGET_ESP32) +static bool CalibrateEspTouchPad(touch_pad_t pad, int calibrationCount, int coefficient) +{ + double avg = 0; + const int minReading = 300; + uint16_t val; + for (int i = 0; i < calibrationCount; i++) + { + touch_pad_read(pad, &val); + avg = (avg * i + val) / (i + 1); + } + + if (avg < minReading) + { + touch_pad_config(pad, 0); + return false; + } + else + { + int threshold = avg * coefficient / 100; + touch_pad_config(pad, threshold); + } + + return true; +} +#endif \ No newline at end of file diff --git a/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad.cpp b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad.cpp new file mode 100644 index 0000000000..8496ad381b --- /dev/null +++ b/targets/ESP32/_nanoCLR/nanoFramework.Hardware.ESP32/nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad.cpp @@ -0,0 +1,1149 @@ +// +// Copyright (c) .NET Foundation and Contributors +// Portions Copyright (c) Microsoft Corporation. All rights reserved. +// See LICENSE file in the project root for full license information. +// + +#include "nanoFramework_hardware_esp32_native.h" +#include +#include + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + +static int numberInitialzed = 0; +static bool isTouchInitialized = false; +static bool isTouchPadUsed[TOUCH_PAD_MAX]; +static bool isFilterOn = false; +static TaskHandle_t handleReadTask = NULL; +static bool isTouched[TOUCH_PAD_MAX]; +static uint32_t thresholds[TOUCH_PAD_MAX]; +static bool isTimeModeOn = false; +static uint32_t lastTouchValues[TOUCH_PAD_MAX]; +static touch_fsm_mode_t measurementMode; +static touch_trigger_mode_t triggerMode; + +/* + * + * Shared functions between ESP32 and ESP32S2 and for all the functions. + * + */ + +/* +Function used for all the interruption in the touch pad. +*/ +static void IsrCallBack(void *arg) +{ + bool val; + uint32_t padIntr = touch_pad_get_status(); +#if defined(CONFIG_IDF_TARGET_ESP32) + touch_pad_intr_clear(); +#else + touch_pad_intr_clear(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE | TOUCH_PAD_INTR_MASK_TIMEOUT); +#endif + for (int i = 0; i < TOUCH_PAD_MAX; i++) + { + val = (padIntr >> i) & 0x01; + // Check if we have a change and raise an even if yes + if (val != isTouched[i]) + { + PostManagedEvent(EVENT_TOUCH, 0, i, val); + } + + isTouched[i] = val; + } +} + +/* +Resources need to be cleaned and the driver uninstalled in case of a soft reboot. +*/ +static void TouchPad_Uninitialize() +{ + // stop the task + if (handleReadTask != NULL) + { + vTaskDelete(handleReadTask); + } + + handleReadTask = NULL; + isTimeModeOn = false; + + // Clean the isr registration +#if defined(CONFIG_IDF_TARGET_ESP32) + touch_pad_intr_disable(); +#else + touch_pad_intr_disable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE | TOUCH_PAD_INTR_MASK_TIMEOUT); +#endif + touch_pad_isr_deregister(IsrCallBack, NULL); + // Clean filter and uninstall the driver +#if defined(CONFIG_IDF_TARGET_ESP32) + touch_pad_filter_stop(); + touch_pad_filter_delete(); +#else + touch_pad_filter_disable(); +#endif + + // Deinitialize and clean the touch pad driver + touch_pad_deinit(); + + isFilterOn = false; + isTouchInitialized = false; + // Make sure all pins are not reserved + memset(isTouchPadUsed, 0, sizeof(isTouchPadUsed)); + // Clear the pin values + memset(isTouched, 0, sizeof(isTouched)); + memset(thresholds, 0, sizeof(thresholds)); + memset(lastTouchValues, 0, sizeof(lastTouchValues)); +} + +/* +This function ensure that the driver is installed for static functions. +It does initialize as well the pins table and register for the soft reboot call back. +*/ +static void MakeSureTouchIsInitialized() +{ + if (!isTouchInitialized) + { + isTouchInitialized = true; + touch_pad_init(); + + // We setup software trigger mode because the FSM one + // is not properly working on ESP32 and we will manage a read loop + // in a task. + touch_pad_set_fsm_mode(TOUCH_FSM_MODE_SW); + + // Make sure all pins are not reserved + memset(isTouchPadUsed, 0, sizeof(isTouchPadUsed)); + // Clear the pin values + memset(isTouched, 0, sizeof(isTouched)); + memset(thresholds, 0, sizeof(thresholds)); + memset(lastTouchValues, 0, sizeof(lastTouchValues)); + + HAL_AddSoftRebootHandler(TouchPad_Uninitialize); + + // The ISR is not really working properly, leaving this code in case new functions +#if defined(CONFIG_IDF_TARGET_ESP32) + // and features will be added in the future. + // touch_pad_intr_enable(); + // touch_pad_isr_register(IsrCallBack, NULL); +#else + // touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE | + // TOUCH_PAD_INTR_MASK_TIMEOUT); touch_pad_isr_register(IsrCallBack, NULL, TOUCH_PAD_INTR_MASK_ALL); +#endif + } +} + +/* +This function reads the sensor value. It does return the last read if running in timer mode. +Otherwise returns the value read directly on the sensors. +*/ +static uint32_t TouchPadRead(touch_pad_t padNumber) +{ +#if defined(CONFIG_IDF_TARGET_ESP32) + uint16_t touchValue; +#else + uint32_t touchValue; +#endif + // Start a manual measurement if software mode + touch_pad_sw_start(); + + // We're waiting to get the data ready + while (!touch_pad_meas_is_done()) + { + vTaskDelay(1); + } + + // If we are filtering, the function to call to read the data is different + if (isFilterOn) + { +#if defined(CONFIG_IDF_TARGET_ESP32) + touch_pad_read_filtered(padNumber, &touchValue); +#else + touch_pad_filter_read_smooth(padNumber, &touchValue); +#endif + } + else + { +#if defined(CONFIG_IDF_TARGET_ESP32) + touch_pad_read(padNumber, &touchValue); +#else + touch_pad_read_raw_data(padNumber, &touchValue); +#endif + } + + // Do we have an event? + if (triggerMode == TOUCH_TRIGGER_ABOVE) + { + if (touchValue < thresholds[padNumber] && isTouched[padNumber]) + { + // Released + PostManagedEvent(EVENT_TOUCH, 0, padNumber, 0); + isTouched[padNumber] = false; + } + else if (touchValue > thresholds[padNumber] && !isTouched[padNumber]) + { + // Touched + PostManagedEvent(EVENT_TOUCH, 0, padNumber, 1); + isTouched[padNumber] = true; + } + } + else + { + if (touchValue > thresholds[padNumber] && !isTouched[padNumber]) + { + // Touched + PostManagedEvent(EVENT_TOUCH, 0, padNumber, 1); + isTouched[padNumber] = true; + } + else if (touchValue < thresholds[padNumber] && isTouched[padNumber]) + { + // Released + PostManagedEvent(EVENT_TOUCH, 0, padNumber, 0); + isTouched[padNumber] = false; + } + } + + lastTouchValues[padNumber] = touchValue; + + return touchValue; +} + +/* +This task is run when the timer mode is used. +*/ +static void ReadTask(void *pvParameter) +{ + while (isTimeModeOn) + { + for (int i = 0; i < TOUCH_PAD_MAX; i++) + { + if (isTouchPadUsed[i]) + { + TouchPadRead((touch_pad_t)i); + } + } + + // Wait the measurement time, 20 milliseconds + // So we are aligning on the nano Thread + vTaskDelay(20 / portTICK_PERIOD_MS); + } +} + +#endif + +typedef Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad TouchPad; +typedef Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_Esp32FilterSetting + Esp32FilterSetting; +typedef Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_DenoiseSetting DenoiseSetting; + +#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) +typedef Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_S2S3FilterSetting + S2S3FilterSetting; +#endif + +HRESULT GetAndCheckTouchPadNumber(CLR_RT_StackFrame &stack, touch_pad_t *padNumber) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + // Get the stack + CLR_RT_HeapBlock *pThis = stack.This(); + FAULT_ON_NULL(pThis); + *padNumber = (touch_pad_t)(pThis[TouchPad::FIELD___touchPadNumber].NumericByRef().s4); + + // Let's make sure it's a proper pin + if ((*padNumber < 0) || (*padNumber >= TOUCH_PAD_MAX)) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeInit___VOID( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + touch_pad_t padNumber; + NANOCLR_CHECK_HRESULT(GetAndCheckTouchPadNumber(stack, &padNumber)); + + // We make sure the pin is not yet open + if (isTouchPadUsed[padNumber]) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + // We initalize the pin + MakeSureTouchIsInitialized(); + if (touch_pad_io_init(padNumber) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + +#if defined(CONFIG_IDF_TARGET_ESP32) + if (touch_pad_config(padNumber, 0) != ESP_OK) +#else + if (touch_pad_config(padNumber) != ESP_OK) +#endif + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + // And we increase the number and mark the pin as open + numberInitialzed++; + isTouchPadUsed[padNumber] = true; + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeDeinit___VOID( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + if (numberInitialzed == 1) + { + touch_pad_deinit(); + isTouchInitialized = false; + } + + touch_pad_t padNumber; + NANOCLR_CHECK_HRESULT(GetAndCheckTouchPadNumber(stack, &padNumber)); + + // Decrease the counter and make sure we mark this one as not used anymore + numberInitialzed--; + isTouchPadUsed[padNumber] = false; + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad::NativeRead___U4( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + touch_pad_t padNumber; + uint32_t touchValue; + NANOCLR_CHECK_HRESULT(GetAndCheckTouchPadNumber(stack, &padNumber)); + + // If we already have the background task running + if (isTimeModeOn) + { + touchValue = lastTouchValues[padNumber]; + } + else + { + touchValue = TouchPadRead(padNumber); + } + + stack.SetResult_U4(touchValue); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeGetThreshold___U4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + touch_pad_t padNumber; + NANOCLR_CHECK_HRESULT(GetAndCheckTouchPadNumber(stack, &padNumber)); + +#if defined(CONFIG_IDF_TARGET_ESP32) + uint16_t threshold; +#else + uint32_t threshold; +#endif + if (touch_pad_get_thresh(padNumber, &threshold) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + // Make sure we store it for later usage + thresholds[padNumber] = threshold; + stack.SetResult_U4(threshold); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeSetThreshold___VOID__U4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + touch_pad_t padNumber; + NANOCLR_CHECK_HRESULT(GetAndCheckTouchPadNumber(stack, &padNumber)); + +#if defined(CONFIG_IDF_TARGET_ESP32) + uint16_t threshold; + // Non static function, Arg1 is the first argument + threshold = (uint16_t)stack.Arg1().NumericByRef().u4; +#else + uint32_t threshold; + // Non static function, Arg1 is the first argument + threshold = (uint32_t)stack.Arg1().NumericByRef().u4; + +#endif + if (touch_pad_set_thresh(padNumber, threshold) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + // Make sure we store it for later usage + thresholds[padNumber] = threshold; + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeGetTouchSpeed___VOID__BYREF_I4__BYREF_I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + touch_pad_t padNumber; + touch_cnt_slope_t slope; + touch_tie_opt_t opt; + + NANOCLR_CHECK_HRESULT(GetAndCheckTouchPadNumber(stack, &padNumber)); + if (touch_pad_get_cnt_mode(padNumber, &slope, &opt) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + // Arg1 as we are in a non static function. + CLR_RT_HeapBlock bhSlope; + CLR_RT_HeapBlock bhOpt; + bhSlope.SetInteger(slope); + NANOCLR_CHECK_HRESULT(bhSlope.StoreToReference(stack.Arg1(), 0)); + bhOpt.SetInteger(opt); + NANOCLR_CHECK_HRESULT(bhOpt.StoreToReference(stack.Arg2(), 0)); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeSetChargeSpeed___VOID__I4__I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + touch_pad_t padNumber; + touch_cnt_slope_t slope; + touch_tie_opt_t opt; + + NANOCLR_CHECK_HRESULT(GetAndCheckTouchPadNumber(stack, &padNumber)); + // Non static function, Arg1 is the first argument + slope = (touch_cnt_slope_t)stack.Arg1().NumericByRef().u4; + opt = (touch_tie_opt_t)stack.Arg2().NumericByRef().u4; + if (touch_pad_set_cnt_mode(padNumber, slope, opt) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeCalibrate___I4__I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + touch_pad_t padNumber; + uint32_t count; + double average = 0; + + NANOCLR_CHECK_HRESULT(GetAndCheckTouchPadNumber(stack, &padNumber)); + // In theory, this part is for ESP32 because S2/S3 works differently + // #if defined(CONFIG_IDF_TARGET_ESP32) + + // Non static function, Arg1 is the first argument + count = (uint32_t)stack.Arg1().NumericByRef().s4; + + // We will read the values and make an average + for (uint32_t i = 0; i < count; i++) + { + average = (average * i + TouchPadRead(padNumber)) / (i + 1); + } + + // Practically, we will do the same as it's the only way to do have it working + // #else + // touch_pad_reset_benchmark(padNumber); + // vTaskDelay(10 * count / portTICK_PERIOD_MS); + // touch_pad_read_benchmark(padNumber, &count); + // average = count; + // #endif + + // And we return the average + stack.SetResult_I4((int)average); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeGetGpioNumberFromTouchNumber___STATIC__I4__I4(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + int padNumber = (int)(stack.Arg0().NumericByRef().u4); + int gpioNumber = -1; + + // Let's make sure it's a proper pin + if ((padNumber < 0) || (padNumber >= TOUCH_PAD_MAX)) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + /*!< Touch pad channel 0 is GPIO4(ESP32) */ + /*!< Touch pad channel 1 is GPIO0(ESP32) / GPIO1(ESP32-S2) */ + /*!< Touch pad channel 2 is GPIO2(ESP32) / GPIO2(ESP32-S2) */ + /*!< Touch pad channel 3 is GPIO15(ESP32) / GPIO3(ESP32-S2) */ + /*!< Touch pad channel 4 is GPIO13(ESP32) / GPIO4(ESP32-S2) */ + /*!< Touch pad channel 5 is GPIO12(ESP32) / GPIO5(ESP32-S2) */ + /*!< Touch pad channel 6 is GPIO14(ESP32) / GPIO6(ESP32-S2) */ + /*!< Touch pad channel 7 is GPIO27(ESP32) / GPIO7(ESP32-S2) */ + /*!< Touch pad channel 8 is GPIO33(ESP32) / GPIO8(ESP32-S2) */ + /*!< Touch pad channel 9 is GPIO32(ESP32) / GPIO9(ESP32-S2) */ + /*!< Touch channel 10 is GPIO10(ESP32-S2) */ + /*!< Touch channel 11 is GPIO11(ESP32-S2) */ + /*!< Touch channel 12 is GPIO12(ESP32-S2) */ + /*!< Touch channel 13 is GPIO13(ESP32-S2) */ + /*!< Touch channel 14 is GPIO14(ESP32-S2) */ + + // This is the ESP32-S2 series + if (SOC_TOUCH_SENSOR_NUM > 10) + { + // In this case it's simple + if (padNumber > 0) + { + gpioNumber = padNumber; + } + } + else + { + // This is traditional ESP32 + switch (padNumber) + { + case TOUCH_PAD_NUM0: + gpioNumber = 4; + break; + + case TOUCH_PAD_NUM1: + gpioNumber = 0; + break; + + case TOUCH_PAD_NUM2: + gpioNumber = 2; + break; + + case TOUCH_PAD_NUM3: + gpioNumber = 15; + break; + + case TOUCH_PAD_NUM4: + gpioNumber = 13; + break; + + case TOUCH_PAD_NUM5: + gpioNumber = 12; + break; + + case TOUCH_PAD_NUM6: + gpioNumber = 14; + break; + + case TOUCH_PAD_NUM7: + gpioNumber = 27; + break; + + case TOUCH_PAD_NUM8: + gpioNumber = 33; + break; + + case TOUCH_PAD_NUM9: + gpioNumber = 32; + break; + } + } + + stack.SetResult_I4(gpioNumber); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeGetTriggerMode___STATIC__nanoFrameworkHardwareEsp32TouchTouchTriggerMode(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) + + // For static functions, we need to make sure that we have the touch pad initialized + MakeSureTouchIsInitialized(); + + if (touch_pad_get_trigger_mode(&triggerMode) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + stack.SetResult_I4(triggerMode); + NANOCLR_NOCLEANUP(); + +#elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + stack.SetResult_I4(triggerMode); + NANOCLR_NOCLEANUP_NOLABEL(); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); + NANOCLR_NOCLEANUP(); +#endif +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeSetTriggerMode___STATIC__VOID__nanoFrameworkHardwareEsp32TouchTouchTriggerMode(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) + + // For static functions, we need to make sure that we have the touch pad initialized + MakeSureTouchIsInitialized(); + triggerMode = (touch_trigger_mode_t)stack.Arg0().NumericByRef().s4; + if (touch_pad_set_trigger_mode(triggerMode) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + NANOCLR_NOCLEANUP(); + +#elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + triggerMode = (touch_trigger_mode_t)stack.Arg0().NumericByRef().s4; + NANOCLR_NOCLEANUP_NOLABEL(); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); + NANOCLR_NOCLEANUP(); +#endif +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeGetTriggerSource___STATIC__nanoFrameworkHardwareEsp32TouchWakeUpSource(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +// Not implemented in this IDF version on the S2/S3 || +// defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) +#if defined(CONFIG_IDF_TARGET_ESP32) + + // For static functions, we need to make sure that we have the touch pad initialized + MakeSureTouchIsInitialized(); + touch_trigger_src_t triggerSource; + + if (touch_pad_get_trigger_source(&triggerSource) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + stack.SetResult_I4(triggerSource); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeSetTriggerSource___STATIC__VOID__nanoFrameworkHardwareEsp32TouchWakeUpSource(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +// Not implemented in this IDF version on the S2/S3 || +// defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) +#if defined(CONFIG_IDF_TARGET_ESP32) + + // For static functions, we need to make sure that we have the touch pad initialized + MakeSureTouchIsInitialized(); + touch_trigger_src_t triggerSource = (touch_trigger_src_t)stack.Arg0().NumericByRef().s4; + if (touch_pad_set_trigger_source(triggerSource) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeGetMeasurementMode___STATIC__nanoFrameworkHardwareEsp32TouchMeasurementMode(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + // For static functions, we need to make sure that we have the touch pad initialized + MakeSureTouchIsInitialized(); + + stack.SetResult_I4(measurementMode); + + NANOCLR_NOCLEANUP_NOLABEL(); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); + NANOCLR_NOCLEANUP(); +#endif +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeSetMeasurementMode___STATIC__VOID__nanoFrameworkHardwareEsp32TouchMeasurementMode(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + // For static functions, we need to make sure that we have the touch pad initialized + MakeSureTouchIsInitialized(); + measurementMode = (touch_fsm_mode_t)stack.Arg0().NumericByRef().s4; + + // TODO: once we'll use IDF 5.0 or a version where the FSM start is present for ESP32 + // One fixed, you may try: if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + // if (measurementMode == TOUCH_FSM_MODE_TIMER) + // { + // if (touch_pad_fsm_start() != ESP_OK) + // { + // NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + // } + // } + // else + // { + // if (touch_pad_fsm_stop() != ESP_OK) + // { + // NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + // } + // } + // endif + + // Do we need to stop the task? + if (measurementMode == TOUCH_FSM_MODE_SW) + { + isTimeModeOn = false; + // If we just switch mode, we have to wait for the task to exit + // So killing it + if (handleReadTask != NULL) + { + vTaskDelete(handleReadTask); + } + + // Waiting a bit to make sure the task is properly deleted + vTaskDelay(20 / portTICK_PERIOD_MS); + handleReadTask = NULL; + } + + // We are starting a task when on timer mode. + if (measurementMode == TOUCH_FSM_MODE_TIMER) + { + if (!isTimeModeOn) + { + isTimeModeOn = true; + // Start a task to show what pads have been touched + xTaskCreate(&ReadTask, "ReadTask", 4096, NULL, 5, &handleReadTask); + } + } + + NANOCLR_NOCLEANUP_NOLABEL(); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); + NANOCLR_NOCLEANUP(); +#endif +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeSetVoltage___STATIC__VOID__nanoFrameworkHardwareEsp32TouchTouchHighVoltage__nanoFrameworkHardwareEsp32TouchTouchLowVoltage__nanoFrameworkHardwareEsp32TouchTouchHighVoltageAttenuation( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + // For static functions, we need to make sure that we have the touch pad initialized + MakeSureTouchIsInitialized(); + touch_high_volt_t refh = (touch_high_volt_t)stack.Arg0().NumericByRef().s4; + touch_low_volt_t refl = (touch_low_volt_t)stack.Arg1().NumericByRef().s4; + touch_volt_atten_t atten = (touch_volt_atten_t)stack.Arg2().NumericByRef().s4; + + if (touch_pad_set_voltage(refh, refl, atten) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeGetVoltage___STATIC__VOID__BYREF_nanoFrameworkHardwareEsp32TouchTouchHighVoltage__BYREF_nanoFrameworkHardwareEsp32TouchTouchLowVoltage__BYREF_nanoFrameworkHardwareEsp32TouchTouchHighVoltageAttenuation( + CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + touch_high_volt_t refh; + touch_low_volt_t refl; + touch_volt_atten_t atten; + + // Get the voltage + if (touch_pad_get_voltage(&refh, &refl, &atten) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + CLR_RT_HeapBlock bhRefh; + CLR_RT_HeapBlock bhRefl; + CLR_RT_HeapBlock bhAtten; + bhRefh.SetInteger(refh); + NANOCLR_CHECK_HRESULT(bhRefh.StoreToReference(stack.Arg0(), 0)); + bhRefl.SetInteger(refl); + NANOCLR_CHECK_HRESULT(bhRefl.StoreToReference(stack.Arg1(), 0)); + bhAtten.SetInteger(atten); + NANOCLR_CHECK_HRESULT(bhAtten.StoreToReference(stack.Arg2(), 0)); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeStartFilter___STATIC__VOID__nanoFrameworkHardwareEsp32TouchIFilterSetting(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + + CLR_RT_TypeDescriptor typeParamType; + CLR_RT_HeapBlock *bhPeriodeSetting; + + // Static function, argument 0 is the first argument + bhPeriodeSetting = stack.Arg0().Dereference(); + + // get type descriptor for parameter + NANOCLR_CHECK_HRESULT(typeParamType.InitializeFromObject(*bhPeriodeSetting)); + +#if defined(CONFIG_IDF_TARGET_ESP32) + uint32_t period; + esp_err_t err; + CLR_RT_TypeDef_Index esp32FilteringTypeDef; + CLR_RT_TypeDescriptor esp32FilteringType; + + // init types to compare with bhPeriodeSetting parameter + g_CLR_RT_TypeSystem.FindTypeDef("Esp32FilterSetting", "nanoFramework.Hardware.Esp32.Touch", esp32FilteringTypeDef); + esp32FilteringType.InitializeFromType(esp32FilteringTypeDef); + + // sanity check for parameter type + if (!CLR_RT_ExecutionEngine::IsInstanceOf(typeParamType, esp32FilteringType, false)) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + period = (uint32_t)bhPeriodeSetting[Esp32FilterSetting::FIELD___period].NumericByRef().u4; + + err = touch_pad_filter_start(period); + if (err != ESP_OK) + { + if (err == ESP_ERR_INVALID_ARG) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + else + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + } + + isFilterOn = true; + +#elif defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + touch_filter_config_t filterConfig; + esp_err_t err; + CLR_RT_TypeDef_Index s2s3FilteringTypeDef; + CLR_RT_TypeDescriptor s2s3FilteringType; + + // init types to compare with bhPeriodeSetting parameter + g_CLR_RT_TypeSystem.FindTypeDef("S2S3FilterSetting", "nanoFramework.Hardware.Esp32.Touch", s2s3FilteringTypeDef); + s2s3FilteringType.InitializeFromType(s2s3FilteringTypeDef); + + // sanity check for parameter type + if (!CLR_RT_ExecutionEngine::IsInstanceOf(typeParamType, s2s3FilteringType, false)) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + + filterConfig.mode = + (touch_filter_mode_t)bhPeriodeSetting[S2S3FilterSetting::FIELD___periodeSettingMode].NumericByRef().s4; + filterConfig.debounce_cnt = + (uint32_t)bhPeriodeSetting[S2S3FilterSetting::FIELD___filterSettingDebounce].NumericByRef().s4; + filterConfig.noise_thr = + (uint32_t)bhPeriodeSetting[S2S3FilterSetting::FIELD___filterSettingNoiseThreshold].NumericByRef().s4; + filterConfig.jitter_step = (uint32_t)bhPeriodeSetting[S2S3FilterSetting::FIELD___jitterSize].NumericByRef().u1; + filterConfig.smh_lvl = + (touch_smooth_mode_t)bhPeriodeSetting[S2S3FilterSetting::FIELD___filterSettingSmoothMode].NumericByRef().s4; + + err = touch_pad_filter_set_config(&filterConfig); + if (err != ESP_OK) + { + if (err == ESP_ERR_INVALID_ARG) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER); + } + else + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + } + + if (touch_pad_filter_enable() != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + isFilterOn = true; +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeStopFilter___STATIC__VOID(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + +#if defined(CONFIG_IDF_TARGET_ESP32) + touch_pad_filter_stop(); +#else + touch_pad_filter_disable(); +#endif + + isFilterOn = false; + NANOCLR_NOCLEANUP_NOLABEL(); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); + NANOCLR_NOCLEANUP(); +#endif +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeSetMeasurementTime___STATIC__VOID__U2__U2(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + // Static function, argument 0 is the first argument + uint16_t sleep = (uint16_t)stack.Arg0().NumericByRef().u2; + uint16_t meas = (uint16_t)stack.Arg1().NumericByRef().u2; + + if (touch_pad_set_meas_time(sleep, meas) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeGetMeasurementTime___STATIC__VOID__BYREF_U2__BYREF_U2(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + // Static function, argument 0 is the first argument + uint16_t sleep; + uint16_t meas; + + if (touch_pad_get_meas_time(&sleep, &meas) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + // Arg0 as we are in a non static function. + CLR_RT_HeapBlock bhSleep; + CLR_RT_HeapBlock bhMeas; + bhSleep.SetInteger(sleep); + NANOCLR_CHECK_HRESULT(bhSleep.StoreToReference(stack.Arg0(), 0)); + bhMeas.SetInteger(meas); + NANOCLR_CHECK_HRESULT(bhMeas.StoreToReference(stack.Arg1(), 0)); + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeGetDenoise___STATIC__VOID__nanoFrameworkHardwareEsp32TouchDenoiseSetting(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +// Not supported on defined(CONFIG_IDF_TARGET_ESP32) || +#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + CLR_RT_HeapBlock *bhDenoiseSetting; + touch_pad_denoise_t denoise; + bhDenoiseSetting = stack.Arg0().Dereference(); + + if (touch_pad_denoise_get_config(&denoise) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + + bhDenoiseSetting[DenoiseSetting::FIELD___denoiseCapacitance].NumericByRef().s4 = denoise.cap_level; + bhDenoiseSetting[DenoiseSetting::FIELD___denoiseRange].NumericByRef().s4 = denoise.grade; + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeDenoiseEnabled___STATIC__VOID__BOOLEAN(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + // For static functions, first argument is 0 + bool denoiseEnabled = stack.Arg0().NumericByRef().u4; + + if (denoiseEnabled) + { + if (touch_pad_denoise_enable() != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + } + else + { + if (touch_pad_denoise_disable() != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + } + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + NANOCLR_NOCLEANUP(); +} + +HRESULT Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Touch_TouchPad:: + NativeSetDenoise___STATIC__VOID__nanoFrameworkHardwareEsp32TouchDenoiseSetting(CLR_RT_StackFrame &stack) +{ + NANOCLR_HEADER(); + +// Not supported on defined(CONFIG_IDF_TARGET_ESP32) || +#if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) + + CLR_RT_HeapBlock *bhDenoiseSetting; + touch_pad_denoise_t denoise; + touch_pad_denoise_grade_t grade; + touch_pad_denoise_cap_t capLevel; + bhDenoiseSetting = stack.Arg0().Dereference(); + + grade = (touch_pad_denoise_grade_t)bhDenoiseSetting[DenoiseSetting::FIELD___denoiseRange].NumericByRef().s4; + capLevel = (touch_pad_denoise_cap_t)bhDenoiseSetting[DenoiseSetting::FIELD___denoiseCapacitance].NumericByRef().s4; + + denoise = { + /* The bits to be cancelled are determined according to the noise level. */ + .grade = grade, + .cap_level = capLevel, + }; + + if (touch_pad_denoise_set_config(&denoise) != ESP_OK) + { + NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION); + } + +#else + NANOCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED); +#endif + + NANOCLR_NOCLEANUP(); +}