• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015-2019 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 /*******************************************************************************
16  * NOTICE
17  * The ll is not public api, don't use in application code.
18  * See readme.md in hal/include/hal/readme.md
19  ******************************************************************************/
20 
21 // The Lowlevel layer for Touch Sensor
22 
23 #pragma once
24 
25 #include <stdlib.h>
26 #include <stdbool.h>
27 #include "soc/touch_sensor_periph.h"
28 #include "hal/touch_sensor_types.h"
29 
30 
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34 
35 //Some register bits of touch sensor 8 and 9 are mismatched, we need to swap the bits.
36 #define TOUCH_LL_BIT_SWAP(data, n, m)   (((data >> n) &  0x1)  == ((data >> m) & 0x1) ? (data) : ((data) ^ ((0x1 <<n) | (0x1 << m))))
37 #define TOUCH_LL_BITS_SWAP(v)  TOUCH_LL_BIT_SWAP(v, TOUCH_PAD_NUM8, TOUCH_PAD_NUM9)
38 
39 /**
40  * Swap the number of touch8 and touch9.
41  *
42  * @touch_num Touch channel num.
43  */
touch_ll_num_wrap(touch_pad_t touch_num)44 static inline touch_pad_t touch_ll_num_wrap(touch_pad_t touch_num)
45 {
46     if (touch_num == TOUCH_PAD_NUM8) {
47         return TOUCH_PAD_NUM9;
48     } else if (touch_num == TOUCH_PAD_NUM9) {
49         return TOUCH_PAD_NUM8;
50     }
51     return touch_num;
52 }
53 
54 /**
55  * Set touch sensor measurement time.
56  *
57  * @param meas_time The duration of the touch sensor measurement.
58  *                  t_meas = meas_time / (8MHz), the maximum measure time is 0xffff / 8M = 8.19 ms.
59  */
touch_ll_set_meas_time(uint16_t meas_time)60 static inline void touch_ll_set_meas_time(uint16_t meas_time)
61 {
62     //touch sensor measure time= meas_cycle / 8Mhz
63     SENS.sar_touch_ctrl1.touch_meas_delay = meas_time;
64     //the waiting cycles (in 8MHz) between TOUCH_START and TOUCH_XPD
65     SENS.sar_touch_ctrl1.touch_xpd_wait = SOC_TOUCH_PAD_MEASURE_WAIT_MAX;
66 }
67 
68 /**
69  * Get touch sensor measurement time.
70  *
71  * @param meas_time Pointer to accept measurement cycle count.
72  */
touch_ll_get_meas_time(uint16_t * meas_time)73 static inline void touch_ll_get_meas_time(uint16_t *meas_time)
74 {
75     *meas_time = SENS.sar_touch_ctrl1.touch_meas_delay;
76 }
77 
78 /**
79  * Set touch sensor sleep time (interval of measurement).
80  *
81  * @param sleep_time  The touch sensor will sleep after each measurement.
82  *                    sleep_cycle decide the interval between each measurement.
83  *                    t_sleep = sleep_cycle / (RTC_SLOW_CLK frequency).
84  *                    The approximate frequency value of RTC_SLOW_CLK can be obtained using `rtc_clk_slow_freq_get_hz` function.
85  */
touch_ll_set_sleep_time(uint16_t sleep_time)86 static inline void touch_ll_set_sleep_time(uint16_t sleep_time)
87 {
88     //touch sensor sleep cycle Time = sleep_cycle / RTC_SLOW_CLK( can be 150k or 32k depending on the options)
89     SENS.sar_touch_ctrl2.touch_sleep_cycles = sleep_time;
90 }
91 
92 /**
93  * Get touch sensor sleep time.
94  *
95  * @param sleep_time Pointer to accept sleep cycle count.
96  */
touch_ll_get_sleep_time(uint16_t * sleep_time)97 static inline void touch_ll_get_sleep_time(uint16_t *sleep_time)
98 {
99     *sleep_time = SENS.sar_touch_ctrl1.touch_meas_delay;
100 }
101 
102 /**
103  * Set touch sensor high voltage threshold of chanrge.
104  * The touch sensor measures the channel capacitance value by charging and discharging the channel.
105  * So the high threshold should be less than the supply voltage.
106  *
107  * @param refh The high voltage threshold of chanrge.
108  */
touch_ll_set_voltage_high(touch_high_volt_t refh)109 static inline void touch_ll_set_voltage_high(touch_high_volt_t refh)
110 {
111     RTCIO.touch_cfg.drefh = refh;
112 }
113 
114 /**
115  * Get touch sensor high voltage threshold of chanrge.
116  * The touch sensor measures the channel capacitance value by charging and discharging the channel.
117  * So the high threshold should be less than the supply voltage.
118  *
119  * @param refh The high voltage threshold of chanrge.
120  */
touch_ll_get_voltage_high(touch_high_volt_t * refh)121 static inline void touch_ll_get_voltage_high(touch_high_volt_t *refh)
122 {
123     *refh = (touch_high_volt_t)RTCIO.touch_cfg.drefh;
124 }
125 
126 /**
127  * Set touch sensor low voltage threshold of discharge.
128  * The touch sensor measures the channel capacitance value by charging and discharging the channel.
129  *
130  * @param refl The low voltage threshold of discharge.
131  */
touch_ll_set_voltage_low(touch_low_volt_t refl)132 static inline void touch_ll_set_voltage_low(touch_low_volt_t refl)
133 {
134     RTCIO.touch_cfg.drefl = refl;
135 }
136 
137 /**
138  * Get touch sensor low voltage threshold of discharge.
139  * The touch sensor measures the channel capacitance value by charging and discharging the channel.
140  *
141  * @param refl The low voltage threshold of discharge.
142  */
touch_ll_get_voltage_low(touch_low_volt_t * refl)143 static inline void touch_ll_get_voltage_low(touch_low_volt_t *refl)
144 {
145     *refl = (touch_low_volt_t)RTCIO.touch_cfg.drefl;
146 }
147 
148 /**
149  * Set touch sensor high voltage attenuation of chanrge. The actual charge threshold is high voltage threshold minus attenuation value.
150  * The touch sensor measures the channel capacitance value by charging and discharging the channel.
151  * So the high threshold should be less than the supply voltage.
152  *
153  * @param refh The high voltage threshold of chanrge.
154  */
touch_ll_set_voltage_attenuation(touch_volt_atten_t atten)155 static inline void touch_ll_set_voltage_attenuation(touch_volt_atten_t atten)
156 {
157     RTCIO.touch_cfg.drange = atten;
158 }
159 
160 /**
161  * Get touch sensor high voltage attenuation of chanrge. The actual charge threshold is high voltage threshold minus attenuation value.
162  * The touch sensor measures the channel capacitance value by charging and discharging the channel.
163  * So the high threshold should be less than the supply voltage.
164  *
165  * @param refh The high voltage threshold of chanrge.
166  */
touch_ll_get_voltage_attenuation(touch_volt_atten_t * atten)167 static inline void touch_ll_get_voltage_attenuation(touch_volt_atten_t *atten)
168 {
169     *atten = (touch_volt_atten_t)RTCIO.touch_cfg.drange;
170 }
171 
172 /**
173  * Set touch sensor charge/discharge speed(currents) for each pad.
174  *        If the slope is 0, the counter would always be zero.
175  *        If the slope is 1, the charging and discharging would be slow. The measurement time becomes longer.
176  *        If the slope is set 7, which is the maximum value, the charging and discharging would be fast.
177  *        The measurement time becomes shorter.
178  *
179  * @note The higher the charge and discharge current, the greater the immunity of the touch channel,
180  *       but it will increase the system power consumption.
181  * @param touch_num Touch pad index.
182  * @param slope touch pad charge/discharge speed(currents).
183  */
touch_ll_set_slope(touch_pad_t touch_num,touch_cnt_slope_t slope)184 static inline void touch_ll_set_slope(touch_pad_t touch_num, touch_cnt_slope_t slope)
185 {
186     RTCIO.touch_pad[touch_num].dac = slope;
187 }
188 
189 /**
190  * Get touch sensor charge/discharge speed(currents) for each pad.
191  *        If the slope is 0, the counter would always be zero.
192  *        If the slope is 1, the charging and discharging would be slow. The measurement time becomes longer.
193  *        If the slope is set 7, which is the maximum value, the charging and discharging would be fast.
194  *        The measurement time becomes shorter.
195  *
196  * @param touch_num Touch pad index.
197  * @param slope touch pad charge/discharge speed(currents).
198  */
touch_ll_get_slope(touch_pad_t touch_num,touch_cnt_slope_t * slope)199 static inline void touch_ll_get_slope(touch_pad_t touch_num, touch_cnt_slope_t *slope)
200 {
201     *slope = (touch_cnt_slope_t)RTCIO.touch_pad[touch_num].dac;
202 }
203 
204 /**
205  * Set initial voltage state of touch channel for each measurement.
206  *
207  * @param touch_num Touch pad index.
208  * @param opt Initial voltage state.
209  */
touch_ll_set_tie_option(touch_pad_t touch_num,touch_tie_opt_t opt)210 static inline void touch_ll_set_tie_option(touch_pad_t touch_num, touch_tie_opt_t opt)
211 {
212     touch_pad_t touch_pad_wrap = touch_ll_num_wrap(touch_num);
213     RTCIO.touch_pad[touch_pad_wrap].tie_opt = opt;
214 }
215 
216 /**
217  * Get initial voltage state of touch channel for each measurement.
218  *
219  * @param touch_num Touch pad index.
220  * @param opt Initial voltage state.
221  */
touch_ll_get_tie_option(touch_pad_t touch_num,touch_tie_opt_t * opt)222 static inline void touch_ll_get_tie_option(touch_pad_t touch_num, touch_tie_opt_t *opt)
223 {
224     touch_pad_t touch_pad_wrap = touch_ll_num_wrap(touch_num);
225     *opt = (touch_tie_opt_t)RTCIO.touch_pad[touch_pad_wrap].tie_opt;
226 }
227 
228 /**
229  * Set touch sensor FSM mode.
230  *        The measurement action can be triggered by the hardware timer, as well as by the software instruction.
231  *
232  * @param mode FSM mode.
233  */
touch_ll_set_fsm_mode(touch_fsm_mode_t mode)234 static inline void touch_ll_set_fsm_mode(touch_fsm_mode_t mode)
235 {
236     SENS.sar_touch_ctrl2.touch_start_fsm_en = 1;
237     SENS.sar_touch_ctrl2.touch_start_en = 0;
238     SENS.sar_touch_ctrl2.touch_start_force = mode;
239 }
240 
241 /**
242  * Get touch sensor FSM mode.
243  *        The measurement action can be triggered by the hardware timer, as well as by the software instruction.
244  *
245  * @param mode FSM mode.
246  */
touch_ll_get_fsm_mode(touch_fsm_mode_t * mode)247 static inline void touch_ll_get_fsm_mode(touch_fsm_mode_t *mode)
248 {
249     *mode = (touch_fsm_mode_t)SENS.sar_touch_ctrl2.touch_start_force;
250 }
251 
252 /**
253  * Start touch sensor FSM timer.
254  *        The measurement action can be triggered by the hardware timer, as well as by the software instruction.
255  *
256  * @param mode FSM mode.
257  */
touch_ll_start_fsm(void)258 static inline void touch_ll_start_fsm(void)
259 {
260     RTCCNTL.state0.touch_slp_timer_en = 1;
261 }
262 
263 /**
264  * Stop touch sensor FSM timer.
265  *        The measurement action can be triggered by the hardware timer, as well as by the software instruction.
266  *
267  * @param mode FSM mode.
268  */
touch_ll_stop_fsm(void)269 static inline void touch_ll_stop_fsm(void)
270 {
271     RTCCNTL.state0.touch_slp_timer_en = 0;
272 }
273 
274 /**
275  * Trigger a touch sensor measurement, only support in SW mode of FSM.
276  */
touch_ll_start_sw_meas(void)277 static inline void touch_ll_start_sw_meas(void)
278 {
279     SENS.sar_touch_ctrl2.touch_start_en = 0;
280     SENS.sar_touch_ctrl2.touch_start_en = 1;
281 }
282 
283 /**
284  * Set touch sensor interrupt threshold.
285  *
286  * @note Refer to `touch_pad_set_trigger_mode` to see how to set trigger mode.
287  * @param touch_num touch pad index.
288  * @param threshold threshold of touchpad count.
289  */
touch_ll_set_threshold(touch_pad_t touch_num,uint16_t threshold)290 static inline void touch_ll_set_threshold(touch_pad_t touch_num, uint16_t threshold)
291 {
292     touch_pad_t tp_wrap = touch_ll_num_wrap(touch_num);
293     if (tp_wrap & 0x1) {
294         SENS.touch_thresh[tp_wrap / 2].l_thresh = threshold;
295     } else {
296         SENS.touch_thresh[tp_wrap / 2].h_thresh = threshold;
297     }
298 }
299 
300 /**
301  * Get touch sensor interrupt threshold.
302  *
303  * @param touch_num touch pad index.
304  * @param threshold pointer to accept threshold.
305  */
touch_ll_get_threshold(touch_pad_t touch_num,uint16_t * threshold)306 static inline void touch_ll_get_threshold(touch_pad_t touch_num, uint16_t *threshold)
307 {
308     touch_pad_t tp_wrap = touch_ll_num_wrap(touch_num);
309     if (threshold) {
310         *threshold = (tp_wrap & 0x1 ) ?
311                      SENS.touch_thresh[tp_wrap / 2].l_thresh :
312                      SENS.touch_thresh[tp_wrap / 2].h_thresh;
313     }
314 }
315 
316 /**
317  * Set touch sensor interrupt trigger mode.
318  * Interrupt can be triggered either when touch value is less than
319  * threshold or when touch value is more than threshold.
320  *
321  * @param mode Touch sensor interrupt trigger mode.
322  */
touch_ll_set_trigger_mode(touch_trigger_mode_t mode)323 static inline void touch_ll_set_trigger_mode(touch_trigger_mode_t mode)
324 {
325     SENS.sar_touch_ctrl1.touch_out_sel = mode;
326 }
327 
328 /**
329  * Get touch sensor interrupt trigger mode.
330  * Interrupt can be triggered either when touch value is less than
331  * threshold or when touch value is more than threshold.
332  *
333  * @param mode Touch sensor interrupt trigger mode.
334  */
touch_ll_get_trigger_mode(touch_trigger_mode_t * mode)335 static inline void touch_ll_get_trigger_mode(touch_trigger_mode_t *mode)
336 {
337     *mode = (touch_trigger_mode_t)SENS.sar_touch_ctrl1.touch_out_sel;
338 }
339 
340 /**
341  * Set touch sensor interrupt trigger source. There are two sets of touch signals.
342  * Set1 and set2 can be mapped to several touch signals. Either set will be triggered
343  * if at least one of its touch signal is 'touched'. The interrupt can be configured to be generated
344  * if set1 is triggered, or only if both sets are triggered.
345  *
346  * @param src Touch sensor interrupt trigger source.
347  */
touch_ll_set_trigger_source(touch_trigger_src_t src)348 static inline void touch_ll_set_trigger_source(touch_trigger_src_t src)
349 {
350     SENS.sar_touch_ctrl1.touch_out_1en = src;
351 }
352 
353 /**
354  * Get touch sensor interrupt trigger source.
355  *
356  * @param src Pointer to accept touch sensor interrupt trigger source.
357  */
touch_ll_get_trigger_source(touch_trigger_src_t * src)358 static inline void touch_ll_get_trigger_source(touch_trigger_src_t *src)
359 {
360     *src = (touch_trigger_src_t)SENS.sar_touch_ctrl1.touch_out_1en;
361 }
362 
363 /**
364  * Enable touch sensor channel. Register touch channel into touch sensor measurement group.
365  * The working mode of the touch sensor is simultaneous measurement.
366  * This function will set the measure bits according to the given bitmask.
367  *
368  * @note  If set this mask, the FSM timer should be stop firsty.
369  * @note  The touch sensor that in scan map, should be deinit GPIO function firstly.
370  * @param enable_mask bitmask of touch sensor scan group.
371  *        e.g. TOUCH_PAD_NUM1 -> BIT(1)
372  * @return
373  *      - ESP_OK on success
374  */
touch_ll_set_channel_mask(uint16_t enable_mask)375 static inline void touch_ll_set_channel_mask(uint16_t enable_mask)
376 {
377     SENS.sar_touch_enable.touch_pad_worken |= TOUCH_LL_BITS_SWAP(enable_mask);
378 }
379 
380 /**
381  * Get touch sensor channel mask.
382  *
383  * @param enable_mask bitmask of touch sensor scan group.
384  *        e.g. TOUCH_PAD_NUM1 -> BIT(1)
385  */
touch_ll_get_channel_mask(uint16_t * enable_mask)386 static inline void touch_ll_get_channel_mask(uint16_t *enable_mask)
387 {
388     *enable_mask = TOUCH_LL_BITS_SWAP(SENS.sar_touch_enable.touch_pad_worken);
389 }
390 
391 /**
392  * Disable touch sensor channel by bitmask.
393  *
394  * @param enable_mask bitmask of touch sensor scan group.
395  *        e.g. TOUCH_PAD_NUM1 -> BIT(1)
396  */
touch_ll_clear_channel_mask(uint16_t disable_mask)397 static inline void touch_ll_clear_channel_mask(uint16_t disable_mask)
398 {
399     SENS.sar_touch_enable.touch_pad_worken &= TOUCH_LL_BITS_SWAP(~disable_mask);
400 }
401 
402 /**
403  * Set touch sensor group mask.
404  * Touch pad module has two sets of signals, 'Touched' signal is triggered only if
405  * at least one of touch pad in this group is "touched".
406  * This function will set the register bits according to the given bitmask.
407  *
408  * @param set1_mask bitmask of touch sensor signal group1, it's a 10-bit value
409  * @param set2_mask bitmask of touch sensor signal group2, it's a 10-bit value
410  */
touch_ll_set_group_mask(uint16_t group1_mask,uint16_t group2_mask)411 static inline void touch_ll_set_group_mask(uint16_t group1_mask, uint16_t group2_mask)
412 {
413     SENS.sar_touch_enable.touch_pad_outen1 |= TOUCH_LL_BITS_SWAP(group1_mask);
414     SENS.sar_touch_enable.touch_pad_outen2 |= TOUCH_LL_BITS_SWAP(group2_mask);
415 }
416 
417 /**
418  * Get touch sensor group mask.
419  *
420  * @param set1_mask pointer to accept bitmask of touch sensor signal group1, it's a 10-bit value
421  * @param set2_mask pointer to accept bitmask of touch sensor signal group2, it's a 10-bit value
422  */
touch_ll_get_group_mask(uint16_t * group1_mask,uint16_t * group2_mask)423 static inline void touch_ll_get_group_mask(uint16_t *group1_mask, uint16_t *group2_mask)
424 {
425     *group1_mask = TOUCH_LL_BITS_SWAP(SENS.sar_touch_enable.touch_pad_outen1);
426     *group2_mask = TOUCH_LL_BITS_SWAP(SENS.sar_touch_enable.touch_pad_outen2);
427 }
428 
429 /**
430  * Clear touch sensor group mask.
431  *
432  * @param set1_mask pointer to accept bitmask of touch sensor signal group1, it's a 10-bit value
433  * @param set2_mask pointer to accept bitmask of touch sensor signal group2, it's a 10-bit value
434  */
touch_ll_clear_group_mask(uint16_t group1_mask,uint16_t group2_mask)435 static inline void touch_ll_clear_group_mask(uint16_t group1_mask, uint16_t group2_mask)
436 {
437     SENS.sar_touch_enable.touch_pad_outen1 &= TOUCH_LL_BITS_SWAP(~group1_mask);
438     SENS.sar_touch_enable.touch_pad_outen2 &= TOUCH_LL_BITS_SWAP(~group2_mask);
439 }
440 
441 /**
442  * Get the touch sensor status, usually used in ISR to decide which pads are 'touched'.
443  *
444  * @param status_mask The touch sensor status. e.g. Touch1 trigger status is `status_mask & (BIT1)`.
445  */
touch_ll_read_trigger_status_mask(uint32_t * status_mask)446 static inline void touch_ll_read_trigger_status_mask(uint32_t *status_mask)
447 {
448     *status_mask = TOUCH_LL_BITS_SWAP(SENS.sar_touch_ctrl2.touch_meas_en);
449 }
450 
451 /**
452  * Clear all touch sensor status.
453  */
touch_ll_clear_trigger_status_mask(void)454 static inline void touch_ll_clear_trigger_status_mask(void)
455 {
456     SENS.sar_touch_ctrl2.touch_meas_en_clr = 1;
457 }
458 
459 /**
460  * To enable touch pad interrupt.
461  */
touch_ll_intr_enable(void)462 static inline void touch_ll_intr_enable(void)
463 {
464     RTCCNTL.int_ena.rtc_touch = 1;
465 }
466 
467 /**
468  * To disable touch pad interrupt.
469  */
touch_ll_intr_disable(void)470 static inline void touch_ll_intr_disable(void)
471 {
472     RTCCNTL.int_ena.rtc_touch = 0;
473 }
474 
475 /**
476  * To clear touch pad interrupt.
477  */
touch_ll_intr_clear(void)478 static inline void touch_ll_intr_clear(void)
479 {
480     RTCCNTL.int_clr.rtc_touch = 1;
481 }
482 
483 /**
484  * Get touch sensor raw data (touch sensor counter value) from register. No block.
485  *
486  * @param touch_num touch pad index.
487  * @return touch_value pointer to accept touch sensor value.
488  */
touch_ll_read_raw_data(touch_pad_t touch_num)489 static inline uint32_t touch_ll_read_raw_data(touch_pad_t touch_num)
490 {
491     touch_pad_t tp_wrap = touch_ll_num_wrap(touch_num);
492     return ((tp_wrap & 0x1) ? SENS.touch_meas[tp_wrap / 2].l_val : SENS.touch_meas[tp_wrap / 2].h_val);
493 }
494 
495 /**
496  * Get touch sensor measure status. No block.
497  *
498  * @return
499  *      - If touch sensors measure done.
500  */
touch_ll_meas_is_done(void)501 static inline bool touch_ll_meas_is_done(void)
502 {
503     return (bool)SENS.sar_touch_ctrl2.touch_meas_done;
504 }
505 
506 #ifdef __cplusplus
507 }
508 #endif
509