esp_efuse_rtc_calib.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*
  2. * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <esp_bit_defs.h>
  7. #include "esp_efuse.h"
  8. #include "esp_efuse_table.h"
  9. #include "esp_efuse_rtc_calib.h"
  10. #include "hal/efuse_hal.h"
  11. /**
  12. * @brief Get the signed value by the raw data that read from eFuse
  13. * @param data The raw data that read from eFuse
  14. * @param sign_bit The index of the sign bit, start from 0
  15. */
  16. #define RTC_CALIB_GET_SIGNED_VAL(data, sign_bit) ((data & BIT##sign_bit) ? -(int)(data & ~BIT##sign_bit) : (int)data)
  17. int esp_efuse_rtc_calib_get_ver(void)
  18. {
  19. uint32_t cali_version = 0;
  20. uint32_t blk_ver = efuse_hal_blk_version();
  21. if (blk_ver == 1) {
  22. cali_version = ESP_EFUSE_ADC_CALIB_VER1;
  23. } else if (blk_ver >= 2) {
  24. cali_version = ESP_EFUSE_ADC_CALIB_VER2;
  25. } else {
  26. ESP_LOGW("eFuse", "calibration efuse version does not match, set default version to 0");
  27. }
  28. return cali_version;
  29. }
  30. uint32_t esp_efuse_rtc_calib_get_init_code(int version, uint32_t adc_unit, int atten)
  31. {
  32. /* Version validation should be guaranteed in the caller */
  33. assert(atten >=0 && atten < 4);
  34. (void) adc_unit;
  35. const esp_efuse_desc_t** init_code_efuse;
  36. if (atten == 0) {
  37. init_code_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0;
  38. } else if (atten == 1) {
  39. init_code_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN1;
  40. } else if (atten == 2) {
  41. init_code_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN2;
  42. } else {
  43. init_code_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN3;
  44. }
  45. int init_code_size = esp_efuse_get_field_size(init_code_efuse);
  46. assert(init_code_size == 10);
  47. uint32_t init_code = 0;
  48. ESP_ERROR_CHECK(esp_efuse_read_field_blob(init_code_efuse, &init_code, init_code_size));
  49. return init_code + 1600; // version 1 logic
  50. }
  51. int esp_efuse_rtc_calib_get_chan_compens(int version, uint32_t adc_unit, uint32_t adc_channel, int atten)
  52. {
  53. /* Version validation should be guaranteed in the caller */
  54. assert(atten < 4);
  55. assert(adc_channel < SOC_ADC_CHANNEL_NUM(adc_unit));
  56. const esp_efuse_desc_t** chan_diff_efuse = NULL;
  57. switch (adc_channel) {
  58. case 0:
  59. chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH0;
  60. break;
  61. case 1:
  62. chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH1;
  63. break;
  64. case 2:
  65. chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH2;
  66. break;
  67. case 3:
  68. chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH3;
  69. break;
  70. case 4:
  71. chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH4;
  72. break;
  73. case 5:
  74. chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH5;
  75. break;
  76. default:
  77. chan_diff_efuse = ESP_EFUSE_ADC1_INIT_CODE_ATTEN0_CH6;
  78. break;
  79. }
  80. int chan_diff_size = esp_efuse_get_field_size(chan_diff_efuse);
  81. assert(chan_diff_size == 4);
  82. uint32_t chan_diff = 0;
  83. ESP_ERROR_CHECK(esp_efuse_read_field_blob(chan_diff_efuse, &chan_diff, chan_diff_size));
  84. return RTC_CALIB_GET_SIGNED_VAL(chan_diff, 3) * (4 - atten);
  85. }
  86. esp_err_t esp_efuse_rtc_calib_get_cal_voltage(int version, uint32_t adc_unit, int atten, uint32_t* out_digi, uint32_t* out_vol_mv)
  87. {
  88. (void) adc_unit;
  89. const esp_efuse_desc_t** cal_vol_efuse[4] = {
  90. ESP_EFUSE_ADC1_CAL_VOL_ATTEN0,
  91. ESP_EFUSE_ADC1_CAL_VOL_ATTEN1,
  92. ESP_EFUSE_ADC1_CAL_VOL_ATTEN2,
  93. ESP_EFUSE_ADC1_CAL_VOL_ATTEN3,
  94. };
  95. const uint32_t input_vout_mv[2][4] = {
  96. {400, 550, 750, 1370}, // Calibration V1 coefficients
  97. {750, 1000, 1500, 2800}, // Calibration V2 coefficients
  98. };
  99. if ((version < ESP_EFUSE_ADC_CALIB_VER_MIN) ||
  100. (version > ESP_EFUSE_ADC_CALIB_VER_MAX)) {
  101. return ESP_ERR_INVALID_ARG;
  102. }
  103. if (atten >= 4 || atten < 0) {
  104. return ESP_ERR_INVALID_ARG;
  105. }
  106. assert(cal_vol_efuse[atten][0]->bit_count == 10);
  107. uint32_t cal_vol = 0;
  108. esp_err_t ret = esp_efuse_read_field_blob(cal_vol_efuse[atten], &cal_vol, cal_vol_efuse[atten][0]->bit_count);
  109. if (ret != ESP_OK) {
  110. return ret;
  111. }
  112. uint32_t chk_offset = (version == ESP_EFUSE_ADC_CALIB_VER1) ? 1500 : (atten == 2) ? 2900 : 2850;
  113. *out_digi = chk_offset + RTC_CALIB_GET_SIGNED_VAL(cal_vol, 9);
  114. *out_vol_mv = input_vout_mv[VER2IDX(version)][atten];
  115. return ESP_OK;
  116. }
  117. esp_err_t esp_efuse_rtc_calib_get_tsens_val(float* tsens_cal)
  118. {
  119. // Currently calibration is not supported on ESP32-C6, IDF-5236
  120. *tsens_cal = 0;
  121. return ESP_OK;
  122. }