adc_common.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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 "soc/adc_periph.h"
  18. static const char *TAG = "adc_common";
  19. static portMUX_TYPE s_spinlock = portMUX_INITIALIZER_UNLOCKED;
  20. extern portMUX_TYPE rtc_spinlock;
  21. /*------------------------------------------------------------------------------
  22. * For those who use APB_SARADC periph
  23. *----------------------------------------------------------------------------*/
  24. static int s_adc_digi_ctrlr_cnt;
  25. void adc_apb_periph_claim(void)
  26. {
  27. portENTER_CRITICAL(&s_spinlock);
  28. s_adc_digi_ctrlr_cnt++;
  29. if (s_adc_digi_ctrlr_cnt == 1) {
  30. //enable ADC digital part
  31. periph_module_enable(PERIPH_SARADC_MODULE);
  32. //reset ADC digital part
  33. periph_module_reset(PERIPH_SARADC_MODULE);
  34. }
  35. portEXIT_CRITICAL(&s_spinlock);
  36. }
  37. void adc_apb_periph_free(void)
  38. {
  39. portENTER_CRITICAL(&s_spinlock);
  40. s_adc_digi_ctrlr_cnt--;
  41. if (s_adc_digi_ctrlr_cnt == 0) {
  42. periph_module_disable(PERIPH_SARADC_MODULE);
  43. } else if (s_adc_digi_ctrlr_cnt < 0) {
  44. portEXIT_CRITICAL(&s_spinlock);
  45. ESP_LOGE(TAG, "%s called, but `s_adc_digi_ctrlr_cnt == 0`", __func__);
  46. abort();
  47. }
  48. portEXIT_CRITICAL(&s_spinlock);
  49. }
  50. /*---------------------------------------------------------------
  51. ADC IOs
  52. ---------------------------------------------------------------*/
  53. esp_err_t adc_io_to_channel(int io_num, adc_unit_t * const unit_id, adc_channel_t * const channel)
  54. {
  55. ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(io_num), ESP_ERR_INVALID_ARG, TAG, "invalid gpio number");
  56. ESP_RETURN_ON_FALSE(unit_id && channel, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
  57. bool found = false;
  58. for (int i = 0; i < SOC_ADC_PERIPH_NUM; i++) {
  59. for (int j = 0; j < SOC_ADC_MAX_CHANNEL_NUM; j++) {
  60. if (adc_channel_io_map[i][j] == io_num) {
  61. *channel = j;
  62. *unit_id = i;
  63. found = true;
  64. }
  65. }
  66. }
  67. return (found) ? ESP_OK : ESP_ERR_NOT_FOUND;
  68. }
  69. esp_err_t adc_channel_to_io(adc_unit_t unit_id, adc_channel_t channel, int * const io_num)
  70. {
  71. ESP_RETURN_ON_FALSE(unit_id < SOC_ADC_PERIPH_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid unit");
  72. ESP_RETURN_ON_FALSE(channel < SOC_ADC_CHANNEL_NUM(unit_id), ESP_ERR_INVALID_ARG, TAG, "invalid channel");
  73. ESP_RETURN_ON_FALSE(io_num, ESP_ERR_INVALID_ARG, TAG, "invalid argument: null pointer");
  74. *io_num = adc_channel_io_map[unit_id][channel];
  75. return ESP_OK;
  76. }
  77. #if SOC_ADC_CALIBRATION_V1_SUPPORTED
  78. /*---------------------------------------------------------------
  79. ADC Hardware Calibration
  80. ---------------------------------------------------------------*/
  81. static __attribute__((constructor)) void adc_hw_calibration(void)
  82. {
  83. //Calculate all ICode
  84. for (int i = 0; i < SOC_ADC_PERIPH_NUM; i++) {
  85. adc_hal_calibration_init(i);
  86. for (int j = 0; j < SOC_ADC_ATTEN_NUM; j++) {
  87. /**
  88. * This may get wrong when attenuations are NOT consecutive on some chips,
  89. * update this when bringing up the calibration on that chip
  90. */
  91. adc_calc_hw_calibration_code(i, j);
  92. #if SOC_ADC_CALIB_CHAN_COMPENS_SUPPORTED
  93. /* Load the channel compensation from efuse */
  94. for (int k = 0; k < SOC_ADC_CHANNEL_NUM(i); k++) {
  95. adc_load_hw_calibration_chan_compens(i, k, j);
  96. }
  97. #endif
  98. }
  99. }
  100. }
  101. #endif //#if SOC_ADC_CALIBRATION_V1_SUPPORTED