// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /******************************************************************************* * NOTICE * The ll is not public api, don't use in application code. * See readme.md in hal/include/hal/readme.md ******************************************************************************/ // The Lowlevel layer for Touch Sensor #pragma once #include #include #include "hal/misc.h" #include "soc/touch_sensor_periph.h" #include "soc/sens_struct.h" #include "soc/rtc_io_struct.h" #include "soc/rtc_cntl_struct.h" #include "hal/touch_sensor_types.h" #ifdef __cplusplus extern "C" { #endif //Some register bits of touch sensor 8 and 9 are mismatched, we need to swap the bits. #define TOUCH_LL_BIT_SWAP(data, n, m) (((data >> n) & 0x1) == ((data >> m) & 0x1) ? (data) : ((data) ^ ((0x1 < BIT(1) * @return * - ESP_OK on success */ static inline void touch_ll_set_channel_mask(uint16_t enable_mask) { SENS.sar_touch_enable.touch_pad_worken |= TOUCH_LL_BITS_SWAP(enable_mask); } /** * Get touch sensor channel mask. * * @param enable_mask bitmask of touch sensor scan group. * e.g. TOUCH_PAD_NUM1 -> BIT(1) */ static inline void touch_ll_get_channel_mask(uint16_t *enable_mask) { *enable_mask = TOUCH_LL_BITS_SWAP(SENS.sar_touch_enable.touch_pad_worken); } /** * Disable touch sensor channel by bitmask. * * @param enable_mask bitmask of touch sensor scan group. * e.g. TOUCH_PAD_NUM1 -> BIT(1) */ static inline void touch_ll_clear_channel_mask(uint16_t disable_mask) { SENS.sar_touch_enable.touch_pad_worken &= TOUCH_LL_BITS_SWAP(~disable_mask); } /** * Set touch sensor group mask. * Touch pad module has two sets of signals, 'Touched' signal is triggered only if * at least one of touch pad in this group is "touched". * This function will set the register bits according to the given bitmask. * * @param set1_mask bitmask of touch sensor signal group1, it's a 10-bit value * @param set2_mask bitmask of touch sensor signal group2, it's a 10-bit value */ static inline void touch_ll_set_group_mask(uint16_t group1_mask, uint16_t group2_mask) { SENS.sar_touch_enable.touch_pad_outen1 |= TOUCH_LL_BITS_SWAP(group1_mask); SENS.sar_touch_enable.touch_pad_outen2 |= TOUCH_LL_BITS_SWAP(group2_mask); } /** * Get touch sensor group mask. * * @param set1_mask pointer to accept bitmask of touch sensor signal group1, it's a 10-bit value * @param set2_mask pointer to accept bitmask of touch sensor signal group2, it's a 10-bit value */ static inline void touch_ll_get_group_mask(uint16_t *group1_mask, uint16_t *group2_mask) { *group1_mask = TOUCH_LL_BITS_SWAP(SENS.sar_touch_enable.touch_pad_outen1); *group2_mask = TOUCH_LL_BITS_SWAP(SENS.sar_touch_enable.touch_pad_outen2); } /** * Clear touch sensor group mask. * * @param set1_mask pointer to accept bitmask of touch sensor signal group1, it's a 10-bit value * @param set2_mask pointer to accept bitmask of touch sensor signal group2, it's a 10-bit value */ static inline void touch_ll_clear_group_mask(uint16_t group1_mask, uint16_t group2_mask) { SENS.sar_touch_enable.touch_pad_outen1 &= TOUCH_LL_BITS_SWAP(~group1_mask); SENS.sar_touch_enable.touch_pad_outen2 &= TOUCH_LL_BITS_SWAP(~group2_mask); } /** * Get the touch sensor status, usually used in ISR to decide which pads are 'touched'. * * @param status_mask The touch sensor status. e.g. Touch1 trigger status is `status_mask & (BIT1)`. */ static inline void touch_ll_read_trigger_status_mask(uint32_t *status_mask) { *status_mask = TOUCH_LL_BITS_SWAP(SENS.sar_touch_ctrl2.touch_meas_en); } /** * Clear all touch sensor status. */ static inline void touch_ll_clear_trigger_status_mask(void) { SENS.sar_touch_ctrl2.touch_meas_en_clr = 1; } /** * To enable touch pad interrupt. */ static inline void touch_ll_intr_enable(void) { RTCCNTL.int_ena.rtc_touch = 1; } /** * To disable touch pad interrupt. */ static inline void touch_ll_intr_disable(void) { RTCCNTL.int_ena.rtc_touch = 0; } /** * To clear touch pad interrupt. */ static inline void touch_ll_intr_clear(void) { RTCCNTL.int_clr.rtc_touch = 1; } /** * Get touch sensor raw data (touch sensor counter value) from register. No block. * * @param touch_num touch pad index. * @return touch_value pointer to accept touch sensor value. */ static inline uint32_t touch_ll_read_raw_data(touch_pad_t touch_num) { touch_pad_t tp_wrap = touch_ll_num_wrap(touch_num); return ((tp_wrap & 0x1) ? HAL_FORCE_READ_U32_REG_FIELD(SENS.touch_meas[tp_wrap / 2], l_val) : HAL_FORCE_READ_U32_REG_FIELD(SENS.touch_meas[tp_wrap / 2], h_val)); } /** * Get touch sensor measure status. No block. * * @return * - If touch sensors measure done. */ static inline bool touch_ll_meas_is_done(void) { return (bool)SENS.sar_touch_ctrl2.touch_meas_done; } #ifdef __cplusplus } #endif