touch_sensor_ll.h 16 KB

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