touch_sensor_ll.h 16 KB

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