adc_common.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <esp_types.h>
  7. #include "sdkconfig.h"
  8. #include "esp_log.h"
  9. #include "esp_check.h"
  10. #include "freertos/FreeRTOS.h"
  11. #include "esp_private/periph_ctrl.h"
  12. #include "esp_private/adc_private.h"
  13. #include "esp_private/adc_share_hw_ctrl.h"
  14. #include "driver/gpio.h"
  15. #include "hal/adc_hal.h"
  16. #include "hal/adc_hal_common.h"
  17. #include "hal/adc_hal_conf.h"
  18. #include "soc/adc_periph.h"
  19. static const char *TAG = "adc_common";
  20. static portMUX_TYPE s_spinlock = portMUX_INITIALIZER_UNLOCKED;
  21. extern portMUX_TYPE rtc_spinlock;
  22. /*------------------------------------------------------------------------------
  23. * For those who use APB_SARADC periph
  24. *----------------------------------------------------------------------------*/
  25. static int s_adc_digi_ctrlr_cnt;
  26. void adc_apb_periph_claim(void)
  27. {
  28. portENTER_CRITICAL(&s_spinlock);
  29. s_adc_digi_ctrlr_cnt++;
  30. if (s_adc_digi_ctrlr_cnt == 1) {
  31. //enable ADC digital part
  32. periph_module_enable(PERIPH_SARADC_MODULE);
  33. //reset ADC digital part
  34. periph_module_reset(PERIPH_SARADC_MODULE);
  35. }
  36. portEXIT_CRITICAL(&s_spinlock);
  37. }
  38. void adc_apb_periph_free(void)
  39. {
  40. portENTER_CRITICAL(&s_spinlock);
  41. s_adc_digi_ctrlr_cnt--;
  42. if (s_adc_digi_ctrlr_cnt == 0) {
  43. periph_module_disable(PERIPH_SARADC_MODULE);
  44. } else if (s_adc_digi_ctrlr_cnt < 0) {
  45. portEXIT_CRITICAL(&s_spinlock);
  46. ESP_LOGE(TAG, "%s called, but `s_adc_digi_ctrlr_cnt == 0`", __func__);
  47. abort();
  48. }
  49. portEXIT_CRITICAL(&s_spinlock);
  50. }
  51. /*---------------------------------------------------------------
  52. ADC IOs
  53. ---------------------------------------------------------------*/
  54. esp_err_t adc_io_to_channel(int io_num, adc_unit_t *unit_id, adc_channel_t *channel)
  55. {
  56. ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(io_num), ESP_ERR_INVALID_ARG, TAG, "invalid gpio number");
  57. ESP_RETURN_ON_FALSE(unit_id && channel, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
  58. bool found = false;
  59. for (int i = 0; i < SOC_ADC_PERIPH_NUM; i++) {
  60. for (int j = 0; j < SOC_ADC_MAX_CHANNEL_NUM; j++) {
  61. if (adc_channel_io_map[i][j] == io_num) {
  62. *channel = j;
  63. *unit_id = i;
  64. found = true;
  65. }
  66. }
  67. }
  68. return (found) ? ESP_OK : ESP_ERR_NOT_FOUND;
  69. }
  70. esp_err_t adc_channel_to_io(adc_unit_t unit_id, adc_channel_t channel, int *io_num)
  71. {
  72. ESP_RETURN_ON_FALSE(unit_id < SOC_ADC_PERIPH_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid unit");
  73. ESP_RETURN_ON_FALSE(channel < SOC_ADC_CHANNEL_NUM(unit_id), ESP_ERR_INVALID_ARG, TAG, "invalid channel");
  74. ESP_RETURN_ON_FALSE(io_num, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
  75. *io_num = adc_channel_io_map[unit_id][channel];
  76. return ESP_OK;
  77. }
  78. #if SOC_ADC_CALIBRATION_V1_SUPPORTED
  79. /*---------------------------------------------------------------
  80. ADC Hardware Calibration
  81. ---------------------------------------------------------------*/
  82. static __attribute__((constructor)) void adc_hw_calibration(void)
  83. {
  84. //Calculate all ICode
  85. for (int i = 0; i < SOC_ADC_PERIPH_NUM; i++) {
  86. adc_hal_calibration_init(i);
  87. for (int j = 0; j < SOC_ADC_ATTEN_NUM; j++) {
  88. /**
  89. * This may get wrong when attenuations are NOT consecutive on some chips,
  90. * update this when bringing up the calibration on that chip
  91. */
  92. adc_calc_hw_calibration_code(i, j);
  93. }
  94. }
  95. }
  96. #endif //#if SOC_ADC_CALIBRATION_V1_SUPPORTED