adc.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. // Copyright 2016-2018 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. #include <esp_types.h>
  15. #include <stdlib.h>
  16. #include <ctype.h>
  17. #include "esp_log.h"
  18. #include "sys/lock.h"
  19. #include "freertos/FreeRTOS.h"
  20. #include "freertos/xtensa_api.h"
  21. #include "freertos/semphr.h"
  22. #include "freertos/timers.h"
  23. #include "esp_pm.h"
  24. #include "esp_intr_alloc.h"
  25. #include "driver/periph_ctrl.h"
  26. #include "driver/rtc_io.h"
  27. #include "driver/rtc_cntl.h"
  28. #include "driver/gpio.h"
  29. #include "driver/adc.h"
  30. #include "sdkconfig.h"
  31. #include "esp32s2/rom/ets_sys.h"
  32. #include "hal/adc_types.h"
  33. #include "hal/adc_hal.h"
  34. #define ADC_CHECK_RET(fun_ret) ({ \
  35. if (fun_ret != ESP_OK) { \
  36. ESP_LOGE(ADC_TAG,"%s:%d\n",__FUNCTION__,__LINE__); \
  37. return ESP_FAIL; \
  38. } \
  39. })
  40. static const char *ADC_TAG = "ADC";
  41. #define ADC_CHECK(a, str, ret_val) ({ \
  42. if (!(a)) { \
  43. ESP_LOGE(ADC_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \
  44. return (ret_val); \
  45. } \
  46. })
  47. #define ADC_GET_IO_NUM(periph, channel) (adc_channel_io_map[periph][channel])
  48. #define ADC_CHANNEL_CHECK(periph, channel) ADC_CHECK(channel < SOC_ADC_CHANNEL_NUM(periph), "ADC"#periph" channel error", ESP_ERR_INVALID_ARG)
  49. extern portMUX_TYPE rtc_spinlock; //TODO: Will be placed in the appropriate position after the rtc module is finished.
  50. #define ADC_ENTER_CRITICAL() portENTER_CRITICAL(&rtc_spinlock)
  51. #define ADC_EXIT_CRITICAL() portEXIT_CRITICAL(&rtc_spinlock)
  52. #ifdef CONFIG_PM_ENABLE
  53. static esp_pm_lock_handle_t s_adc_digi_arbiter_lock = NULL;
  54. #endif //CONFIG_PM_ENABLE
  55. /*---------------------------------------------------------------
  56. Digital controller setting
  57. ---------------------------------------------------------------*/
  58. esp_err_t adc_digi_init(void)
  59. {
  60. adc_arbiter_t config = ADC_ARBITER_CONFIG_DEFAULT();
  61. ADC_ENTER_CRITICAL();
  62. adc_hal_digi_init();
  63. adc_hal_arbiter_config(&config);
  64. ADC_EXIT_CRITICAL();
  65. return ESP_OK;
  66. }
  67. esp_err_t adc_digi_deinit(void)
  68. {
  69. #ifdef CONFIG_PM_ENABLE
  70. if (s_adc_digi_arbiter_lock) {
  71. esp_pm_lock_delete(s_adc_digi_arbiter_lock);
  72. s_adc_digi_arbiter_lock = NULL;
  73. }
  74. #endif
  75. adc_power_release();
  76. ADC_ENTER_CRITICAL();
  77. adc_hal_digi_deinit();
  78. ADC_EXIT_CRITICAL();
  79. return ESP_OK;
  80. }
  81. esp_err_t adc_digi_controller_config(const adc_digi_config_t *config)
  82. {
  83. #ifdef CONFIG_PM_ENABLE
  84. esp_err_t err;
  85. if (s_adc_digi_arbiter_lock == NULL) {
  86. if (config->dig_clk.use_apll) {
  87. err = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "adc_dma", &s_adc_digi_arbiter_lock);
  88. } else {
  89. err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "adc_dma", &s_adc_digi_arbiter_lock);
  90. }
  91. if (err != ESP_OK) {
  92. s_adc_digi_arbiter_lock = NULL;
  93. ESP_LOGE(ADC_TAG, "ADC-DMA pm lock error");
  94. return err;
  95. }
  96. }
  97. #endif //CONFIG_PM_ENABLE
  98. /* If enable digtal controller, adc xpd should always on. */
  99. adc_power_acquire();
  100. ADC_ENTER_CRITICAL();
  101. adc_hal_digi_controller_config(config);
  102. ADC_EXIT_CRITICAL();
  103. return ESP_OK;
  104. }
  105. esp_err_t adc_arbiter_config(adc_unit_t adc_unit, adc_arbiter_t *config)
  106. {
  107. if (adc_unit & ADC_UNIT_1) {
  108. return ESP_ERR_NOT_SUPPORTED;
  109. }
  110. ADC_ENTER_CRITICAL();
  111. adc_hal_arbiter_config(config);
  112. ADC_EXIT_CRITICAL();
  113. return ESP_OK;
  114. }
  115. /**
  116. * @brief Set ADC module controller.
  117. * There are five SAR ADC controllers:
  118. * Two digital controller: Continuous conversion mode (DMA). High performance with multiple channel scan modes;
  119. * Two RTC controller: Single conversion modes (Polling). For low power purpose working during deep sleep;
  120. * the other is dedicated for Power detect (PWDET / PKDET), Only support ADC2.
  121. *
  122. * @note Only ADC2 support arbiter to switch controllers automatically. Access to the ADC is based on the priority of the controller.
  123. * @note For ADC1, Controller access is mutually exclusive.
  124. *
  125. * @param adc_unit ADC unit.
  126. * @param ctrl ADC controller, Refer to `adc_controller_t`.
  127. *
  128. * @return
  129. * - ESP_OK Success
  130. */
  131. esp_err_t adc_set_controller(adc_unit_t adc_unit, adc_controller_t ctrl)
  132. {
  133. adc_arbiter_t config = {0};
  134. adc_arbiter_t cfg = ADC_ARBITER_CONFIG_DEFAULT();
  135. if (adc_unit & ADC_UNIT_1) {
  136. adc_hal_set_controller(ADC_NUM_1, ctrl);
  137. }
  138. if (adc_unit & ADC_UNIT_2) {
  139. adc_hal_set_controller(ADC_NUM_2, ctrl);
  140. switch (ctrl) {
  141. case ADC2_CTRL_FORCE_PWDET:
  142. config.pwdet_pri = 2;
  143. config.mode = ADC_ARB_MODE_SHIELD;
  144. adc_hal_arbiter_config(&config);
  145. adc_hal_set_controller(ADC_NUM_2, ADC2_CTRL_PWDET);
  146. break;
  147. case ADC2_CTRL_FORCE_RTC:
  148. config.rtc_pri = 2;
  149. config.mode = ADC_ARB_MODE_SHIELD;
  150. adc_hal_arbiter_config(&config);
  151. adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_RTC);
  152. break;
  153. case ADC2_CTRL_FORCE_ULP:
  154. config.rtc_pri = 2;
  155. config.mode = ADC_ARB_MODE_SHIELD;
  156. adc_hal_arbiter_config(&config);
  157. adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_ULP);
  158. break;
  159. case ADC2_CTRL_FORCE_DIG:
  160. config.dig_pri = 2;
  161. config.mode = ADC_ARB_MODE_SHIELD;
  162. adc_hal_arbiter_config(&config);
  163. adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_DIG);
  164. break;
  165. default:
  166. adc_hal_arbiter_config(&cfg);
  167. break;
  168. }
  169. }
  170. return ESP_OK;
  171. }
  172. esp_err_t adc_digi_start(void)
  173. {
  174. #ifdef CONFIG_PM_ENABLE
  175. ADC_CHECK((s_adc_digi_arbiter_lock), "Should start after call `adc_digi_controller_config`", ESP_FAIL);
  176. esp_pm_lock_acquire(s_adc_digi_arbiter_lock);
  177. #endif
  178. ADC_ENTER_CRITICAL();
  179. adc_hal_digi_enable();
  180. ADC_EXIT_CRITICAL();
  181. return ESP_OK;
  182. }
  183. esp_err_t adc_digi_stop(void)
  184. {
  185. #ifdef CONFIG_PM_ENABLE
  186. if (s_adc_digi_arbiter_lock) {
  187. esp_pm_lock_release(s_adc_digi_arbiter_lock);
  188. }
  189. #endif
  190. ADC_ENTER_CRITICAL();
  191. adc_hal_digi_disable();
  192. ADC_EXIT_CRITICAL();
  193. return ESP_OK;
  194. }
  195. /**
  196. * @brief Reset FSM of adc digital controller.
  197. *
  198. * @return
  199. * - ESP_OK Success
  200. */
  201. esp_err_t adc_digi_reset(void)
  202. {
  203. ADC_ENTER_CRITICAL();
  204. adc_hal_digi_reset();
  205. adc_hal_digi_clear_pattern_table(ADC_NUM_1);
  206. adc_hal_digi_clear_pattern_table(ADC_NUM_2);
  207. ADC_EXIT_CRITICAL();
  208. return ESP_OK;
  209. }
  210. /*************************************/
  211. /* Digital controller filter setting */
  212. /*************************************/
  213. esp_err_t adc_digi_filter_reset(adc_digi_filter_idx_t idx)
  214. {
  215. ADC_ENTER_CRITICAL();
  216. if (idx == ADC_DIGI_FILTER_IDX0) {
  217. adc_hal_digi_filter_reset(ADC_NUM_1);
  218. } else if (idx == ADC_DIGI_FILTER_IDX1) {
  219. adc_hal_digi_filter_reset(ADC_NUM_2);
  220. }
  221. ADC_EXIT_CRITICAL();
  222. return ESP_OK;
  223. }
  224. esp_err_t adc_digi_filter_set_config(adc_digi_filter_idx_t idx, adc_digi_filter_t *config)
  225. {
  226. ADC_ENTER_CRITICAL();
  227. if (idx == ADC_DIGI_FILTER_IDX0) {
  228. adc_hal_digi_filter_set_factor(ADC_NUM_1, config->mode);
  229. } else if (idx == ADC_DIGI_FILTER_IDX1) {
  230. adc_hal_digi_filter_set_factor(ADC_NUM_2, config->mode);
  231. }
  232. ADC_EXIT_CRITICAL();
  233. return ESP_OK;
  234. }
  235. esp_err_t adc_digi_filter_get_config(adc_digi_filter_idx_t idx, adc_digi_filter_t *config)
  236. {
  237. ADC_ENTER_CRITICAL();
  238. if (idx == ADC_DIGI_FILTER_IDX0) {
  239. config->adc_unit = ADC_UNIT_1;
  240. config->channel = ADC_CHANNEL_MAX;
  241. adc_hal_digi_filter_get_factor(ADC_NUM_1, &config->mode);
  242. } else if (idx == ADC_DIGI_FILTER_IDX1) {
  243. config->adc_unit = ADC_UNIT_2;
  244. config->channel = ADC_CHANNEL_MAX;
  245. adc_hal_digi_filter_get_factor(ADC_NUM_2, &config->mode);
  246. }
  247. ADC_EXIT_CRITICAL();
  248. return ESP_OK;
  249. }
  250. esp_err_t adc_digi_filter_enable(adc_digi_filter_idx_t idx, bool enable)
  251. {
  252. ADC_ENTER_CRITICAL();
  253. if (idx == ADC_DIGI_FILTER_IDX0) {
  254. adc_hal_digi_filter_enable(ADC_NUM_1, enable);
  255. } else if (idx == ADC_DIGI_FILTER_IDX1) {
  256. adc_hal_digi_filter_enable(ADC_NUM_2, enable);
  257. }
  258. ADC_EXIT_CRITICAL();
  259. return ESP_OK;
  260. }
  261. /**
  262. * @brief Get the filtered data of adc digital controller filter. For debug.
  263. * The data after each measurement and filtering is updated to the DMA by the digital controller. But it can also be obtained manually through this API.
  264. *
  265. * @note For ESP32S2, The filter will filter all the enabled channel data of the each ADC unit at the same time.
  266. * @param idx Filter index.
  267. * @return Filtered data. if <0, the read data invalid.
  268. */
  269. int adc_digi_filter_read_data(adc_digi_filter_idx_t idx)
  270. {
  271. if (idx == ADC_DIGI_FILTER_IDX0) {
  272. return adc_hal_digi_filter_read_data(ADC_NUM_1);
  273. } else if (idx == ADC_DIGI_FILTER_IDX1) {
  274. return adc_hal_digi_filter_read_data(ADC_NUM_2);
  275. } else {
  276. return -1;
  277. }
  278. }
  279. /**************************************/
  280. /* Digital controller monitor setting */
  281. /**************************************/
  282. esp_err_t adc_digi_monitor_set_config(adc_digi_monitor_idx_t idx, adc_digi_monitor_t *config)
  283. {
  284. ADC_ENTER_CRITICAL();
  285. if (idx == ADC_DIGI_MONITOR_IDX0) {
  286. adc_hal_digi_monitor_config(ADC_NUM_1, config);
  287. } else if (idx == ADC_DIGI_MONITOR_IDX1) {
  288. adc_hal_digi_monitor_config(ADC_NUM_2, config);
  289. }
  290. ADC_EXIT_CRITICAL();
  291. return ESP_OK;
  292. }
  293. esp_err_t adc_digi_monitor_enable(adc_digi_monitor_idx_t idx, bool enable)
  294. {
  295. ADC_ENTER_CRITICAL();
  296. if (idx == ADC_DIGI_MONITOR_IDX0) {
  297. adc_hal_digi_monitor_enable(ADC_NUM_1, enable);
  298. } else if (idx == ADC_DIGI_MONITOR_IDX1) {
  299. adc_hal_digi_monitor_enable(ADC_NUM_2, enable);
  300. }
  301. ADC_EXIT_CRITICAL();
  302. return ESP_OK;
  303. }
  304. /**************************************/
  305. /* Digital controller intr setting */
  306. /**************************************/
  307. esp_err_t adc_digi_intr_enable(adc_unit_t adc_unit, adc_digi_intr_t intr_mask)
  308. {
  309. ADC_ENTER_CRITICAL();
  310. if (adc_unit & ADC_UNIT_1) {
  311. adc_hal_digi_intr_enable(ADC_NUM_1, intr_mask);
  312. }
  313. if (adc_unit & ADC_UNIT_2) {
  314. adc_hal_digi_intr_enable(ADC_NUM_2, intr_mask);
  315. }
  316. ADC_EXIT_CRITICAL();
  317. return ESP_OK;
  318. }
  319. esp_err_t adc_digi_intr_disable(adc_unit_t adc_unit, adc_digi_intr_t intr_mask)
  320. {
  321. ADC_ENTER_CRITICAL();
  322. if (adc_unit & ADC_UNIT_1) {
  323. adc_hal_digi_intr_disable(ADC_NUM_1, intr_mask);
  324. }
  325. if (adc_unit & ADC_UNIT_2) {
  326. adc_hal_digi_intr_disable(ADC_NUM_2, intr_mask);
  327. }
  328. ADC_EXIT_CRITICAL();
  329. return ESP_OK;
  330. }
  331. esp_err_t adc_digi_intr_clear(adc_unit_t adc_unit, adc_digi_intr_t intr_mask)
  332. {
  333. ADC_ENTER_CRITICAL();
  334. if (adc_unit & ADC_UNIT_1) {
  335. adc_hal_digi_intr_clear(ADC_NUM_1, intr_mask);
  336. }
  337. if (adc_unit & ADC_UNIT_2) {
  338. adc_hal_digi_intr_clear(ADC_NUM_2, intr_mask);
  339. }
  340. ADC_EXIT_CRITICAL();
  341. return ESP_OK;
  342. }
  343. uint32_t adc_digi_intr_get_status(adc_unit_t adc_unit)
  344. {
  345. uint32_t ret = 0;
  346. ADC_ENTER_CRITICAL();
  347. if (adc_unit & ADC_UNIT_1) {
  348. ret = adc_hal_digi_get_intr_status(ADC_NUM_1);
  349. }
  350. if (adc_unit & ADC_UNIT_2) {
  351. ret = adc_hal_digi_get_intr_status(ADC_NUM_2);
  352. }
  353. ADC_EXIT_CRITICAL();
  354. return ret;
  355. }
  356. static uint8_t s_isr_registered = 0;
  357. static intr_handle_t s_adc_isr_handle = NULL;
  358. esp_err_t adc_digi_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags)
  359. {
  360. ADC_CHECK((fn != NULL), "Parameter error", ESP_ERR_INVALID_ARG);
  361. ADC_CHECK(s_isr_registered == 0, "ADC ISR have installed, can not install again", ESP_FAIL);
  362. esp_err_t ret = esp_intr_alloc(ETS_APB_ADC_INTR_SOURCE, intr_alloc_flags, fn, arg, &s_adc_isr_handle);
  363. if (ret == ESP_OK) {
  364. s_isr_registered = 1;
  365. }
  366. return ret;
  367. }
  368. esp_err_t adc_digi_isr_deregister(void)
  369. {
  370. esp_err_t ret = ESP_FAIL;
  371. if (s_isr_registered) {
  372. ret = esp_intr_free(s_adc_isr_handle);
  373. if (ret == ESP_OK) {
  374. s_isr_registered = 0;
  375. }
  376. }
  377. return ret;
  378. }
  379. /*---------------------------------------------------------------
  380. RTC controller setting
  381. ---------------------------------------------------------------*/