1 // Copyright 2016-2020 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #include "driver/touch_sensor.h"
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 
23 /* -------------------------------- General hardware & system default configuration  -------------------------------- */
24 /* Since those are important hardware and algorithm parameters, user should not change them before knowing all details*/
25 /* ------------------------------------------------------------------------------------------------------------------ */
26 #define TOUCH_ELEM_GLOBAL_DEFAULT_CONFIG()                                    \
27 {                                                                             \
28     .hardware = {                                                             \
29         .upper_voltage = TOUCH_HVOLT_2V7,                                     \
30         .voltage_attenuation = TOUCH_HVOLT_ATTEN_0V5,                         \
31         .lower_voltage = TOUCH_LVOLT_0V5,                                     \
32         .suspend_channel_polarity = TOUCH_PAD_CONN_HIGHZ,                     \
33         .denoise_level = TOUCH_PAD_DENOISE_BIT4,                              \
34         .denoise_equivalent_cap = TOUCH_PAD_DENOISE_CAP_L0,                   \
35         .smooth_filter_mode = TOUCH_PAD_SMOOTH_IIR_2,                         \
36         .benchmark_filter_mode = TOUCH_PAD_FILTER_IIR_16,                     \
37         .sample_count = 500,                                                  \
38         .sleep_cycle = 0xf,                                                   \
39         .benchmark_debounce_count = 2,                                        \
40         .benchmark_calibration_threshold = 2,                                 \
41         .benchmark_jitter_step = 5                                            \
42     },                                                                        \
43     .software = {                                                             \
44         .waterproof_threshold_divider = 0.8,                                  \
45         .processing_period = 10,                                              \
46         .intr_message_size = 14,                                              \
47         .event_message_size = 20                                              \
48     }                                                                         \
49 }
50 /* ------------------------------------------------------------------------------------------------------------------ */
51 
52 /* ---------------------------------------------- Event subscription  ----------------------------------------------- */
53 #define TOUCH_ELEM_EVENT_NONE                       BIT(0)      //!< None event
54 #define TOUCH_ELEM_EVENT_ON_PRESS                   BIT(1)      //!< On Press event
55 #define TOUCH_ELEM_EVENT_ON_RELEASE                 BIT(2)      //!< On Release event
56 #define TOUCH_ELEM_EVENT_ON_LONGPRESS               BIT(3)      //!< On LongPress event
57 #define TOUCH_ELEM_EVENT_ON_CALCULATION             BIT(4)      //!< On Calculation event
58 /* ------------------------------------------------------------------------------------------------------------------ */
59 #define TOUCH_WATERPROOF_GUARD_NOUSE       (0)         //!< Waterproof no use guard sensor
60 /* -------------------------------- Global hardware & software configuration struct --------------------------------- */
61 /**
62  * @brief   Touch element software configuration
63  */
64 typedef struct {
65     float waterproof_threshold_divider;        //!< Waterproof guard channel threshold divider
66     uint8_t processing_period;                 //!< Processing period(ms)
67     uint8_t intr_message_size;                 //!< Interrupt message queue size
68     uint8_t event_message_size;                //!< Event message queue size
69 } touch_elem_sw_config_t;
70 
71 /**
72  * @brief   Touch element hardware configuration
73  */
74 typedef struct {
75     touch_high_volt_t upper_voltage;                  //!< Touch sensor channel upper charge voltage
76     touch_volt_atten_t voltage_attenuation;           //!< Touch sensor channel upper charge voltage attenuation (Diff voltage is upper - attenuation - lower)
77     touch_low_volt_t lower_voltage;                   //!< Touch sensor channel lower charge voltage
78     touch_pad_conn_type_t suspend_channel_polarity;   //!< Suspend channel polarity (High Impedance State or GND)
79     touch_pad_denoise_grade_t denoise_level;          //!< Internal de-noise level
80     touch_pad_denoise_cap_t denoise_equivalent_cap;   //!< Internal de-noise channel (Touch channel 0) equivalent capacitance
81     touch_smooth_mode_t smooth_filter_mode;           //!< Smooth value filter mode (This only apply to touch_pad_filter_read_smooth())
82     touch_filter_mode_t benchmark_filter_mode;        //!< Benchmark filter mode
83     uint16_t sample_count;                            //!< The count of sample in each measurement of touch sensor
84     uint16_t sleep_cycle;                             //!< The cycle (RTC slow clock) of sleep
85     uint8_t benchmark_debounce_count;                 //!< Benchmark debounce count
86     uint8_t benchmark_calibration_threshold;          //!< Benchmark calibration threshold
87     uint8_t benchmark_jitter_step;                    //!< Benchmark jitter filter step (This only works at while benchmark filter mode is jitter filter)
88 } touch_elem_hw_config_t;
89 
90 /**
91  * @brief   Touch element global configuration passed to touch_element_install
92  */
93 typedef struct {
94     touch_elem_hw_config_t hardware;         //!< Hardware configuration
95     touch_elem_sw_config_t software;         //!< Software configuration
96 } touch_elem_global_config_t;
97 
98 /**
99  * @brief   Touch element waterproof configuration passed to touch_element_waterproof_install
100  */
101 typedef struct {
102     touch_pad_t guard_channel;     //!< Waterproof Guard-Sensor channel number (index)
103     float guard_sensitivity;       //!< Waterproof Guard-Sensor sensitivity
104 } touch_elem_waterproof_config_t;
105 /* ------------------------------------------------------------------------------------------------------------------ */
106 typedef void *touch_elem_handle_t;        //!< Touch element handle type
107 typedef uint32_t touch_elem_event_t;      //!< Touch element event type
108 
109 /**
110  * @brief   Touch element handle type
111  */
112 typedef enum {
113     TOUCH_ELEM_TYPE_BUTTON,         //!< Touch element button
114     TOUCH_ELEM_TYPE_SLIDER,         //!< Touch element slider
115     TOUCH_ELEM_TYPE_MATRIX,         //!< Touch element matrix button
116 } touch_elem_type_t;
117 
118 /**
119  * @brief   Touch element event dispatch methods (event queue/callback)
120  */
121 typedef enum {
122     TOUCH_ELEM_DISP_EVENT,           //!< Event queue dispatch
123     TOUCH_ELEM_DISP_CALLBACK,        //!< Callback dispatch
124     TOUCH_ELEM_DISP_MAX
125 } touch_elem_dispatch_t;
126 
127 /**
128  * @brief   Touch element event message type from touch_element_message_receive()
129  */
130 typedef struct {
131     touch_elem_handle_t handle;             //!< Touch element handle
132     touch_elem_type_t element_type;         //!< Touch element type
133     void *arg;                              //!< User input argument
134     uint8_t child_msg[8];                   //!< Encoded message
135 } touch_elem_message_t;
136 /* ------------------------------------------------------------------------------------------------------------------ */
137 
138 /**
139  * @brief   Touch element processing initialization
140  *
141  * @param[in]   global_config   Global initialization configuration structure
142  *
143  * @note    To reinitialize the touch element object, call touch_element_uninstall() first
144  *
145  * @return
146  *      - ESP_OK: Successfully initialized
147  *      - ESP_ERR_INVALID_ARG: Invalid argument
148  *      - ESP_ERR_NO_MEM: Insufficient memory
149  *      - ESP_ERR_INVALID_STATE: Touch element is already initialized
150  *      - Others: Unknown touch driver layer or lower layer error
151  */
152 esp_err_t touch_element_install(const touch_elem_global_config_t *global_config);
153 
154 /**
155  * @brief   Touch element processing start
156  *
157  * This function starts the touch element processing system
158  *
159  * @note    This function must only be called after all the touch element instances finished creating
160  *
161  * @return
162  *      - ESP_OK: Successfully started to process
163  *      - Others: Unknown touch driver layer or lower layer error
164  */
165 esp_err_t touch_element_start(void);
166 
167 /**
168  * @brief   Touch element processing stop
169  *
170  * This function stops the touch element processing system
171  *
172  * @note    This function must be called before changing the system (hardware, software) parameters
173  *
174  * @return
175  *      - ESP_OK: Successfully stopped to process
176  *      - Others: Unknown touch driver layer or lower layer error
177  */
178 esp_err_t touch_element_stop(void);
179 
180 /**
181  * @brief   Release resources allocated using touch_element_install
182  *
183  * @return
184  *      - ESP_OK: Successfully released touch element object
185  *      - ESP_ERR_INVALID_STATE: Touch element object is not initialized
186  *      - Others: Unknown touch driver layer or lower layer error
187  */
188 void touch_element_uninstall(void);
189 
190 /**
191  * @brief   Get current event message of touch element instance
192  *
193  * This function will receive the touch element message (handle, event type, etc...)
194  * from te_event_give(). It will block until a touch element event or a timeout occurs.
195  *
196  * @param[out]  element_message          Touch element event message structure
197  * @param[in]   ticks_to_wait   Number of FreeRTOS ticks to block for waiting event
198  * @return
199  *      - ESP_OK: Successfully received touch element event
200  *      - ESP_ERR_INVALID_STATE: Touch element library is not initialized
201  *      - ESP_ERR_INVALID_ARG: element_message is null
202  *      - ESP_ERR_TIMEOUT: Timed out waiting for event
203  */
204 esp_err_t touch_element_message_receive(touch_elem_message_t *element_message, uint32_t ticks_to_wait);
205 
206 /**
207  * @brief   Touch element waterproof initialization
208  *
209  * This function enables the hardware waterproof, then touch element system uses Shield-Sensor
210  * and Guard-Sensor to mitigate the influence of water-drop and water-stream.
211  *
212  * @param[in] waterproof_config     Waterproof configuration
213  *
214  * @note    If the waterproof function is used, Shield-Sensor can not be disabled and it will use channel 14 as
215  *          it's internal channel. Hence, the user can not use channel 14 for another propose. And the Guard-Sensor
216  *          is not necessary since it is optional.
217  *
218  * @note    Shield-Sensor: It always uses channel 14 as the shield channel, so user must connect
219  *          the channel 14 and Shield-Layer in PCB since it will generate a synchronous signal automatically
220  *
221  * @note    Guard-Sensor: This function is optional. If used, the user must connect the guard channel and Guard-Ring
222  *          in PCB. Any channels user wants to protect should be added into Guard-Ring in PCB.
223  *
224  * @return
225  *      - ESP_OK: Successfully initialized
226  *      - ESP_ERR_INVALID_STATE: Touch element library is not initialized
227  *      - ESP_ERR_INVALID_ARG: waterproof_config is null or invalid Guard-Sensor channel
228  *      - ESP_ERR_NO_MEM: Insufficient memory
229  */
230 esp_err_t touch_element_waterproof_install(const touch_elem_waterproof_config_t *waterproof_config);
231 
232 /**
233  * @brief   Release resources allocated using touch_element_waterproof_install()
234  */
235 void touch_element_waterproof_uninstall(void);
236 
237 /**
238  * @brief   Add a masked handle to protect while Guard-Sensor has been triggered
239  *
240  * This function will add an application handle (button, slider, etc...) as a masked handle. While Guard-Sensor
241  * has been triggered, waterproof function will start working and lock the application internal state. While the
242  * influence of water is reduced, the application will be unlock and reset into IDLE state.
243  *
244  * @param[in] element_handle     Touch element instance handle
245  *
246  * @note    The waterproof protection logic must follow the real circuit in PCB, it means that all of the channels
247  *          inside the input handle must be inside the Guard-Ring in real circuit.
248  *
249  * @return
250  *      - ESP_OK: Successfully added a masked handle
251  *      - ESP_ERR_INVALID_STATE: Waterproof is not initialized
252  *      - ESP_ERR_INVALID_ARG: element_handle is null
253  */
254 esp_err_t touch_element_waterproof_add(touch_elem_handle_t element_handle);
255 
256 /**
257  * @brief   Remove a masked handle to protect
258  *
259  * This function will remove an application handle from masked handle table.
260  *
261  * @param[in] element_handle     Touch element instance handle
262  *
263  * @return
264  *      - ESP_OK: Successfully removed a masked handle
265  *      - ESP_ERR_INVALID_STATE: Waterproof is not initialized
266  *      - ESP_ERR_INVALID_ARG: element_handle is null
267  *      - ESP_ERR_NOT_FOUND: Failed to search element_handle from waterproof mask_handle list
268  */
269 esp_err_t touch_element_waterproof_remove(touch_elem_handle_t element_handle);
270 
271 #ifdef __cplusplus
272 }
273 #endif
274