adc.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  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_ENTER_CRITICAL();
  76. adc_hal_digi_deinit();
  77. ADC_EXIT_CRITICAL();
  78. return ESP_OK;
  79. }
  80. esp_err_t adc_digi_controller_config(const adc_digi_config_t *config)
  81. {
  82. #ifdef CONFIG_PM_ENABLE
  83. esp_err_t err;
  84. if (s_adc_digi_arbiter_lock == NULL) {
  85. if (config->dig_clk.use_apll) {
  86. err = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "adc_dma", &s_adc_digi_arbiter_lock);
  87. } else {
  88. err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "adc_dma", &s_adc_digi_arbiter_lock);
  89. }
  90. if (err != ESP_OK) {
  91. s_adc_digi_arbiter_lock = NULL;
  92. ESP_LOGE(ADC_TAG, "ADC-DMA pm lock error");
  93. return err;
  94. }
  95. }
  96. #endif //CONFIG_PM_ENABLE
  97. ADC_ENTER_CRITICAL();
  98. adc_hal_digi_controller_config(config);
  99. ADC_EXIT_CRITICAL();
  100. return ESP_OK;
  101. }
  102. esp_err_t adc_arbiter_config(adc_unit_t adc_unit, adc_arbiter_t *config)
  103. {
  104. if (adc_unit & ADC_UNIT_1) {
  105. return ESP_ERR_NOT_SUPPORTED;
  106. }
  107. ADC_ENTER_CRITICAL();
  108. adc_hal_arbiter_config(config);
  109. ADC_EXIT_CRITICAL();
  110. return ESP_OK;
  111. }
  112. /**
  113. * @brief Set ADC module controller.
  114. * There are five SAR ADC controllers:
  115. * Two digital controller: Continuous conversion mode (DMA). High performance with multiple channel scan modes;
  116. * Two RTC controller: Single conversion modes (Polling). For low power purpose working during deep sleep;
  117. * the other is dedicated for Power detect (PWDET / PKDET), Only support ADC2.
  118. *
  119. * @note Only ADC2 support arbiter to switch controllers automatically. Access to the ADC is based on the priority of the controller.
  120. * @note For ADC1, Controller access is mutually exclusive.
  121. *
  122. * @param adc_unit ADC unit.
  123. * @param ctrl ADC controller, Refer to `adc_controller_t`.
  124. *
  125. * @return
  126. * - ESP_OK Success
  127. */
  128. esp_err_t adc_set_controller(adc_unit_t adc_unit, adc_controller_t ctrl)
  129. {
  130. adc_arbiter_t config = {0};
  131. adc_arbiter_t cfg = ADC_ARBITER_CONFIG_DEFAULT();
  132. if (adc_unit & ADC_UNIT_1) {
  133. adc_hal_set_controller(ADC_NUM_1, ctrl);
  134. }
  135. if (adc_unit & ADC_UNIT_2) {
  136. adc_hal_set_controller(ADC_NUM_2, ctrl);
  137. switch (ctrl) {
  138. case ADC2_CTRL_FORCE_PWDET:
  139. config.pwdet_pri = 2;
  140. config.mode = ADC_ARB_MODE_SHIELD;
  141. adc_hal_arbiter_config(&config);
  142. adc_hal_set_controller(ADC_NUM_2, ADC2_CTRL_PWDET);
  143. break;
  144. case ADC2_CTRL_FORCE_RTC:
  145. config.rtc_pri = 2;
  146. config.mode = ADC_ARB_MODE_SHIELD;
  147. adc_hal_arbiter_config(&config);
  148. adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_RTC);
  149. break;
  150. case ADC2_CTRL_FORCE_ULP:
  151. config.rtc_pri = 2;
  152. config.mode = ADC_ARB_MODE_SHIELD;
  153. adc_hal_arbiter_config(&config);
  154. adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_ULP);
  155. break;
  156. case ADC2_CTRL_FORCE_DIG:
  157. config.dig_pri = 2;
  158. config.mode = ADC_ARB_MODE_SHIELD;
  159. adc_hal_arbiter_config(&config);
  160. adc_hal_set_controller(ADC_NUM_2, ADC_CTRL_DIG);
  161. break;
  162. default:
  163. adc_hal_arbiter_config(&cfg);
  164. break;
  165. }
  166. }
  167. return ESP_OK;
  168. }
  169. esp_err_t adc_digi_start(void)
  170. {
  171. #ifdef CONFIG_PM_ENABLE
  172. ADC_CHECK((s_adc_digi_arbiter_lock), "Should start after call `adc_digi_controller_config`", ESP_FAIL);
  173. esp_pm_lock_acquire(s_adc_digi_arbiter_lock);
  174. #endif
  175. ADC_ENTER_CRITICAL();
  176. adc_hal_digi_enable();
  177. ADC_EXIT_CRITICAL();
  178. return ESP_OK;
  179. }
  180. esp_err_t adc_digi_stop(void)
  181. {
  182. #ifdef CONFIG_PM_ENABLE
  183. if (s_adc_digi_arbiter_lock) {
  184. esp_pm_lock_release(s_adc_digi_arbiter_lock);
  185. }
  186. #endif
  187. ADC_ENTER_CRITICAL();
  188. adc_hal_digi_disable();
  189. ADC_EXIT_CRITICAL();
  190. return ESP_OK;
  191. }
  192. /**
  193. * @brief Reset FSM of adc digital controller.
  194. *
  195. * @return
  196. * - ESP_OK Success
  197. */
  198. esp_err_t adc_digi_reset(void)
  199. {
  200. ADC_ENTER_CRITICAL();
  201. adc_hal_digi_reset();
  202. adc_hal_digi_clear_pattern_table(ADC_NUM_1);
  203. adc_hal_digi_clear_pattern_table(ADC_NUM_2);
  204. ADC_EXIT_CRITICAL();
  205. return ESP_OK;
  206. }
  207. /*************************************/
  208. /* Digital controller filter setting */
  209. /*************************************/
  210. esp_err_t adc_digi_filter_reset(adc_digi_filter_idx_t idx)
  211. {
  212. ADC_ENTER_CRITICAL();
  213. if (idx == ADC_DIGI_FILTER_IDX0) {
  214. adc_hal_digi_filter_reset(ADC_NUM_1);
  215. } else if (idx == ADC_DIGI_FILTER_IDX1) {
  216. adc_hal_digi_filter_reset(ADC_NUM_2);
  217. }
  218. ADC_EXIT_CRITICAL();
  219. return ESP_OK;
  220. }
  221. esp_err_t adc_digi_filter_set_config(adc_digi_filter_idx_t idx, adc_digi_filter_t *config)
  222. {
  223. ADC_ENTER_CRITICAL();
  224. if (idx == ADC_DIGI_FILTER_IDX0) {
  225. adc_hal_digi_filter_set_factor(ADC_NUM_1, config->mode);
  226. } else if (idx == ADC_DIGI_FILTER_IDX1) {
  227. adc_hal_digi_filter_set_factor(ADC_NUM_2, config->mode);
  228. }
  229. ADC_EXIT_CRITICAL();
  230. return ESP_OK;
  231. }
  232. esp_err_t adc_digi_filter_get_config(adc_digi_filter_idx_t idx, adc_digi_filter_t *config)
  233. {
  234. ADC_ENTER_CRITICAL();
  235. if (idx == ADC_DIGI_FILTER_IDX0) {
  236. config->adc_unit = ADC_UNIT_1;
  237. config->channel = ADC_CHANNEL_MAX;
  238. adc_hal_digi_filter_get_factor(ADC_NUM_1, &config->mode);
  239. } else if (idx == ADC_DIGI_FILTER_IDX1) {
  240. config->adc_unit = ADC_UNIT_2;
  241. config->channel = ADC_CHANNEL_MAX;
  242. adc_hal_digi_filter_get_factor(ADC_NUM_2, &config->mode);
  243. }
  244. ADC_EXIT_CRITICAL();
  245. return ESP_OK;
  246. }
  247. esp_err_t adc_digi_filter_enable(adc_digi_filter_idx_t idx, bool enable)
  248. {
  249. ADC_ENTER_CRITICAL();
  250. if (idx == ADC_DIGI_FILTER_IDX0) {
  251. adc_hal_digi_filter_enable(ADC_NUM_1, enable);
  252. } else if (idx == ADC_DIGI_FILTER_IDX1) {
  253. adc_hal_digi_filter_enable(ADC_NUM_2, enable);
  254. }
  255. ADC_EXIT_CRITICAL();
  256. return ESP_OK;
  257. }
  258. /**
  259. * @brief Get the filtered data of adc digital controller filter. For debug.
  260. * 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.
  261. *
  262. * @note For ESP32S2, The filter will filter all the enabled channel data of the each ADC unit at the same time.
  263. * @param idx Filter index.
  264. * @return Filtered data. if <0, the read data invalid.
  265. */
  266. int adc_digi_filter_read_data(adc_digi_filter_idx_t idx)
  267. {
  268. if (idx == ADC_DIGI_FILTER_IDX0) {
  269. return adc_hal_digi_filter_read_data(ADC_NUM_1);
  270. } else if (idx == ADC_DIGI_FILTER_IDX1) {
  271. return adc_hal_digi_filter_read_data(ADC_NUM_2);
  272. } else {
  273. return -1;
  274. }
  275. }
  276. /**************************************/
  277. /* Digital controller monitor setting */
  278. /**************************************/
  279. esp_err_t adc_digi_monitor_set_config(adc_digi_monitor_idx_t idx, adc_digi_monitor_t *config)
  280. {
  281. ADC_ENTER_CRITICAL();
  282. if (idx == ADC_DIGI_MONITOR_IDX0) {
  283. adc_hal_digi_monitor_config(ADC_NUM_1, config);
  284. } else if (idx == ADC_DIGI_MONITOR_IDX1) {
  285. adc_hal_digi_monitor_config(ADC_NUM_2, config);
  286. }
  287. ADC_EXIT_CRITICAL();
  288. return ESP_OK;
  289. }
  290. esp_err_t adc_digi_monitor_enable(adc_digi_monitor_idx_t idx, bool enable)
  291. {
  292. ADC_ENTER_CRITICAL();
  293. if (idx == ADC_DIGI_MONITOR_IDX0) {
  294. adc_hal_digi_monitor_enable(ADC_NUM_1, enable);
  295. } else if (idx == ADC_DIGI_MONITOR_IDX1) {
  296. adc_hal_digi_monitor_enable(ADC_NUM_2, enable);
  297. }
  298. ADC_EXIT_CRITICAL();
  299. return ESP_OK;
  300. }
  301. /**************************************/
  302. /* Digital controller intr setting */
  303. /**************************************/
  304. esp_err_t adc_digi_intr_enable(adc_unit_t adc_unit, adc_digi_intr_t intr_mask)
  305. {
  306. ADC_ENTER_CRITICAL();
  307. if (adc_unit & ADC_UNIT_1) {
  308. adc_hal_digi_intr_enable(ADC_NUM_1, intr_mask);
  309. }
  310. if (adc_unit & ADC_UNIT_2) {
  311. adc_hal_digi_intr_enable(ADC_NUM_2, intr_mask);
  312. }
  313. ADC_EXIT_CRITICAL();
  314. return ESP_OK;
  315. }
  316. esp_err_t adc_digi_intr_disable(adc_unit_t adc_unit, adc_digi_intr_t intr_mask)
  317. {
  318. ADC_ENTER_CRITICAL();
  319. if (adc_unit & ADC_UNIT_1) {
  320. adc_hal_digi_intr_disable(ADC_NUM_1, intr_mask);
  321. }
  322. if (adc_unit & ADC_UNIT_2) {
  323. adc_hal_digi_intr_disable(ADC_NUM_2, intr_mask);
  324. }
  325. ADC_EXIT_CRITICAL();
  326. return ESP_OK;
  327. }
  328. esp_err_t adc_digi_intr_clear(adc_unit_t adc_unit, adc_digi_intr_t intr_mask)
  329. {
  330. ADC_ENTER_CRITICAL();
  331. if (adc_unit & ADC_UNIT_1) {
  332. adc_hal_digi_intr_clear(ADC_NUM_1, intr_mask);
  333. }
  334. if (adc_unit & ADC_UNIT_2) {
  335. adc_hal_digi_intr_clear(ADC_NUM_2, intr_mask);
  336. }
  337. ADC_EXIT_CRITICAL();
  338. return ESP_OK;
  339. }
  340. uint32_t adc_digi_intr_get_status(adc_unit_t adc_unit)
  341. {
  342. uint32_t ret = 0;
  343. ADC_ENTER_CRITICAL();
  344. if (adc_unit & ADC_UNIT_1) {
  345. ret = adc_hal_digi_get_intr_status(ADC_NUM_1);
  346. }
  347. if (adc_unit & ADC_UNIT_2) {
  348. ret = adc_hal_digi_get_intr_status(ADC_NUM_2);
  349. }
  350. ADC_EXIT_CRITICAL();
  351. return ret;
  352. }
  353. static uint8_t s_isr_registered = 0;
  354. static intr_handle_t s_adc_isr_handle = NULL;
  355. esp_err_t adc_digi_isr_register(void (*fn)(void *), void *arg, int intr_alloc_flags)
  356. {
  357. ADC_CHECK((fn != NULL), "Parameter error", ESP_ERR_INVALID_ARG);
  358. ADC_CHECK(s_isr_registered == 0, "ADC ISR have installed, can not install again", ESP_FAIL);
  359. esp_err_t ret = esp_intr_alloc(ETS_APB_ADC_INTR_SOURCE, intr_alloc_flags, fn, arg, &s_adc_isr_handle);
  360. if (ret == ESP_OK) {
  361. s_isr_registered = 1;
  362. }
  363. return ret;
  364. }
  365. esp_err_t adc_digi_isr_deregister(void)
  366. {
  367. esp_err_t ret = ESP_FAIL;
  368. if (s_isr_registered) {
  369. ret = esp_intr_free(s_adc_isr_handle);
  370. if (ret == ESP_OK) {
  371. s_isr_registered = 0;
  372. }
  373. }
  374. return ret;
  375. }
  376. /*---------------------------------------------------------------
  377. RTC controller setting
  378. ---------------------------------------------------------------*/