esp_efuse_rtc_table.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <stdbool.h>
  7. #include "esp_efuse_rtc_table.h"
  8. #include "esp_efuse.h"
  9. #include "esp_efuse_table.h"
  10. #include "esp_log.h"
  11. #include "hal/adc_types.h"
  12. #include "hal/efuse_ll.h"
  13. #include "soc/soc_caps.h"
  14. #define RTC_TBL_LOG_TAG "efuse_rtc_table"
  15. /* Note on definition of tags
  16. *
  17. * For adc calibration, value = raw * multiplier + offset, but these values are kind of arbitrary so
  18. * we use a lookup table to do the bookkeeping.
  19. *
  20. * The offset of an item can be calculated as follows:
  21. * PARAM_OFFSET + ADC_NUM(which is the UNIT_COUNT minus 1) * ATTEN_NUM + ATTEN_NUM
  22. * where PARAM_OFFSET is the index of the first item.
  23. *
  24. * ADC, ATTEN form a 2-dim array. For each (version number, extra parameters) tuple we keep a such array,
  25. * and use if-else statements to choose which array we use.
  26. * */
  27. #define RTCCALIB_V1_ADCREADINGLOW_OFFSET RTCCALIB_V1IDX_A10L
  28. #define RTCCALIB_V1_ADCREADINGHIGH_OFFSET RTCCALIB_V1IDX_A10H
  29. #define RTCCALIB_V2_ADCREADINGHIGH_OFFSET RTCCALIB_V2IDX_A10H
  30. #define RTCCALIB_V2_ADCREADINGINIT_OFFSET RTCCALIB_V2IDX_A10I
  31. typedef struct {
  32. const int tag; // should be the same as the index in adc_efuse_raw_map
  33. const int block;
  34. const int begin_bit;
  35. const int length;
  36. const int multiplier;
  37. const int base;
  38. const int depends;
  39. } efuse_map_info_t;
  40. static const efuse_map_info_t adc_efuse_raw_map[] = {
  41. {0},
  42. // INDEXING TAG, BLOCK, BEGIN_BIT, LENGTH, MULTIPLIER, OFFSET BASE, OFFSET DEP
  43. {RTCCALIB_V1IDX_A10L, 2, 208, 6, 4, 2231, 0},
  44. {RTCCALIB_V1IDX_A11L, 2, 214, 6, 4, 1643, 0},
  45. {RTCCALIB_V1IDX_A12L, 2, 220, 6, 4, 1290, 0},
  46. {RTCCALIB_V1IDX_A13L, 2, 226, 6, 4, 701, 0},
  47. {RTCCALIB_V1IDX_A20L, 2, 232, 6, 4, 2305, 0},
  48. {RTCCALIB_V1IDX_A21L, 2, 238, 6, 4, 1693, 0},
  49. {RTCCALIB_V1IDX_A22L, 2, 244, 6, 4, 1343, 0},
  50. {RTCCALIB_V1IDX_A23L, 2, 250, 6, 4, 723, 0},
  51. {RTCCALIB_V1IDX_A10H, 2, 144, 8, 4, 5775, 0},
  52. {RTCCALIB_V1IDX_A11H, 2, 152, 8, 4, 5693, 0},
  53. {RTCCALIB_V1IDX_A12H, 2, 160, 8, 4, 5723, 0},
  54. {RTCCALIB_V1IDX_A13H, 2, 168, 8, 4, 6209, 0},
  55. {RTCCALIB_V1IDX_A20H, 2, 176, 8, 4, 5817, 0},
  56. {RTCCALIB_V1IDX_A21H, 2, 184, 8, 4, 5703, 0},
  57. {RTCCALIB_V1IDX_A22H, 2, 192, 8, 4, 5731, 0},
  58. {RTCCALIB_V1IDX_A23H, 2, 200, 8, 4, 6157, 0},
  59. {RTCCALIB_V2IDX_A10H, 2, 197, 6, 2, 169, RTCCALIB_V2IDX_A12H},
  60. {RTCCALIB_V2IDX_A11H, 2, 203, 6, 2, -26, RTCCALIB_V2IDX_A12H},
  61. {RTCCALIB_V2IDX_A12H, 2, 209, 9, 2, 126, RTCCALIB_V2IDX_A21H},
  62. {RTCCALIB_V2IDX_A13H, 2, 218, 7, 2, 387, RTCCALIB_V2IDX_A12H},
  63. {RTCCALIB_V2IDX_A20H, 2, 225, 7, 2, 177, RTCCALIB_V2IDX_A21H},
  64. {RTCCALIB_V2IDX_A21H, 2, 232, 10, 2, 5815, 0},
  65. {RTCCALIB_V2IDX_A22H, 2, 242, 7, 2, 27, RTCCALIB_V2IDX_A21H},
  66. {RTCCALIB_V2IDX_A23H, 2, 249, 7, 2, 410, RTCCALIB_V2IDX_A21H},
  67. {RTCCALIB_V2IDX_A10I, 2, 147, 8, 2, 1519, 0},
  68. {RTCCALIB_V2IDX_A11I, 2, 155, 6, 2, 88, RTCCALIB_V2IDX_A10I},
  69. {RTCCALIB_V2IDX_A12I, 2, 161, 5, 2, 8, RTCCALIB_V2IDX_A11I},
  70. {RTCCALIB_V2IDX_A13I, 2, 166, 6, 2, 70, RTCCALIB_V2IDX_A12I},
  71. {RTCCALIB_V2IDX_A20I, 2, 172, 8, 2, 1677, 0},
  72. {RTCCALIB_V2IDX_A21I, 2, 180, 6, 2, 23, RTCCALIB_V2IDX_A20I},
  73. {RTCCALIB_V2IDX_A22I, 2, 186, 5, 2, 6, RTCCALIB_V2IDX_A21I},
  74. {RTCCALIB_V2IDX_A23I, 2, 191, 6, 2, 13, RTCCALIB_V2IDX_A22I},
  75. {RTCCALIB_IDX_TMPSENSOR, 2, 135, 9, 1, 0, 0},
  76. };
  77. int esp_efuse_rtc_table_read_calib_version(void)
  78. {
  79. return efuse_ll_get_blk_version_minor();
  80. }
  81. int esp_efuse_rtc_table_get_tag(int version, int adc_num, int atten, int extra_params)
  82. {
  83. assert(adc_num <= ADC_UNIT_2);
  84. int index = (adc_num == ADC_UNIT_1) ? 0 : 1;
  85. int param_offset; // used to index which (adc_num, atten) array to use.
  86. if (version == 1 && extra_params == RTCCALIB_V1_PARAM_VLOW) { // Volage LOW, Version 1
  87. param_offset = RTCCALIB_V1_ADCREADINGLOW_OFFSET;
  88. } else if (version == 1 && extra_params == RTCCALIB_V1_PARAM_VHIGH) {
  89. param_offset = RTCCALIB_V1_ADCREADINGHIGH_OFFSET;
  90. } else if (version == 2 && extra_params == RTCCALIB_V2_PARAM_VHIGH) {
  91. param_offset = RTCCALIB_V2_ADCREADINGHIGH_OFFSET;
  92. } else if (version == 2 && extra_params == RTCCALIB_V2_PARAM_VINIT) {
  93. param_offset = RTCCALIB_V2_ADCREADINGINIT_OFFSET;
  94. } else {
  95. return -1;
  96. }
  97. int result = param_offset + index * RTCCALIB_ESP32S2_ATTENCOUNT + atten;
  98. ESP_EARLY_LOGV(RTC_TBL_LOG_TAG, "V%d ADC%d ATTEN%d PARAM%d -> %d", version, adc_num + 1, atten, extra_params, result);
  99. return result;
  100. }
  101. /*
  102. * Converts a signed-bit int to a normal (2-complement) int.
  103. * */
  104. static int signed_bit_to_int(uint32_t number, int len)
  105. {
  106. if (number >> (len - 1)) {
  107. // first bit is set, unset that bit and negate the number.
  108. number = -(number ^ (1 << (len - 1)));
  109. }
  110. return number;
  111. }
  112. int esp_efuse_rtc_table_get_raw_efuse_value(int tag)
  113. {
  114. assert(tag > 0);
  115. if (tag == 0) {
  116. return 0;
  117. }
  118. uint32_t val = 0;
  119. esp_efuse_read_block(adc_efuse_raw_map[tag].block, &val, adc_efuse_raw_map[tag].begin_bit, adc_efuse_raw_map[tag].length);
  120. int result = signed_bit_to_int(val, adc_efuse_raw_map[tag].length);
  121. ESP_EARLY_LOGV(RTC_TBL_LOG_TAG, "Fetching raw for tag %d @blk%d bit%d len%d: %d", tag, adc_efuse_raw_map[tag].block, adc_efuse_raw_map[tag].begin_bit, adc_efuse_raw_map[tag].length,
  122. result);
  123. return result;
  124. }
  125. int esp_efuse_rtc_table_get_parsed_efuse_value(int tag, bool skip_efuse_reading)
  126. {
  127. assert(tag >= 0);
  128. if (tag == 0) {
  129. return 0; // tag 0 is the dummy tag and has no value. (used by depends)
  130. }
  131. int efuse_val = 0;
  132. if (!skip_efuse_reading) {
  133. efuse_val = esp_efuse_rtc_table_get_raw_efuse_value(tag) * adc_efuse_raw_map[tag].multiplier;
  134. }
  135. int result = efuse_val + adc_efuse_raw_map[tag].base +
  136. esp_efuse_rtc_table_get_parsed_efuse_value(adc_efuse_raw_map[tag].depends, skip_efuse_reading);
  137. ESP_EARLY_LOGV(RTC_TBL_LOG_TAG, "Parsed efuse val for tag %d: %d", tag, result);
  138. return result;
  139. }