secure_boot: Checks secure boot efuses

ESP32 V1 and V2 - protection bits.
ESP32xx V2: revoke bits, protection bits

- refactor efuse component
- adds some APIs for esp32 chips as well as for esp32xx chips
This commit is contained in:
KonstantinKondrashov
2021-01-26 04:27:03 +08:00
parent b92c290e56
commit 90f2d3199a
55 changed files with 877 additions and 767 deletions

View File

@@ -0,0 +1,75 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "esp_efuse.h"
#include "esp_efuse_utility.h"
#include "esp_efuse_table.h"
#include "stdlib.h"
#include "esp_types.h"
#include "assert.h"
#include "esp_err.h"
#include "esp_log.h"
#include "soc/efuse_periph.h"
#include "bootloader_random.h"
#include "sys/param.h"
const static char *TAG = "efuse";
// Contains functions that provide access to efuse fields which are often used in IDF.
// Returns chip version from efuse
uint8_t esp_efuse_get_chip_ver(void)
{
// should return the same value as bootloader_common_get_chip_revision()
uint32_t chip_ver = 0;
// TODO: ESP32S2 does not have this field
return chip_ver;
}
// Returns chip package from efuse
uint32_t esp_efuse_get_pkg_ver(void)
{
uint32_t pkg_ver = 0;
esp_efuse_read_field_blob(ESP_EFUSE_PKG_VERSION, &pkg_ver, 4);
return pkg_ver;
}
void esp_efuse_write_random_key(uint32_t blk_wdata0_reg)
{
uint32_t buf[8];
uint8_t raw[24];
bootloader_fill_random(buf, sizeof(buf));
ESP_LOGV(TAG, "Writing random values to address 0x%08x", blk_wdata0_reg);
for (int i = 0; i < 8; i++) {
ESP_LOGV(TAG, "EFUSE_BLKx_WDATA%d_REG = 0x%08x", i, buf[i]);
REG_WRITE(blk_wdata0_reg + 4*i, buf[i]);
}
bzero(buf, sizeof(buf));
bzero(raw, sizeof(raw));
}
esp_err_t esp_efuse_disable_rom_download_mode(void)
{
return esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MODE);
}
esp_err_t esp_efuse_enable_rom_secure_download_mode(void)
{
if (esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MODE)) {
return ESP_ERR_INVALID_STATE;
}
return esp_efuse_write_field_bit(ESP_EFUSE_ENABLE_SECURITY_DOWNLOAD);
}

View File

@@ -0,0 +1,167 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdbool.h>
#include "esp_efuse_rtc_table.h"
#include "esp_efuse.h"
#include "esp_efuse_table.h"
#include "esp_log.h"
#include "soc/soc_caps.h"
#define RTC_TBL_LOG_TAG "efuse_rtc_table"
/* Note on definition of tags
*
* For adc calibration, value = raw * multiplier + offset, but these values are kind of arbitrary so
* we use a lookup table to do the bookkeeping.
*
* The offset of an item can be calculated as follows:
* PARAM_OFFSET + ADC_NUM(which is the UNIT_COUNT minus 1) * ATTEN_NUM + ATTEN_NUM
* where PARAM_OFFSET is the index of the first item.
*
* ADC, ATTEN form a 2-dim array. For each (version number, extra parameters) tuple we keep a such array,
* and use if-else statements to choose which array we use.
* */
#define RTCCALIB_V1_ADCREADINGLOW_OFFSET RTCCALIB_V1IDX_A10L
#define RTCCALIB_V1_ADCREADINGHIGH_OFFSET RTCCALIB_V1IDX_A10H
#define RTCCALIB_V2_ADCREADINGHIGH_OFFSET RTCCALIB_V2IDX_A10H
#define RTCCALIB_V2_ADCREADINGINIT_OFFSET RTCCALIB_V2IDX_A10I
typedef struct {
const int tag; // should be the same as the index in adc_efuse_raw_map
const int block;
const int begin_bit;
const int length;
const int multiplier;
const int base;
const int depends;
} efuse_map_info_t;
static const efuse_map_info_t adc_efuse_raw_map[] = {
{0},
// INDEXING TAG, BLOCK, BEGIN_BIT, LENGTH, MULTIPLIER, OFFSET BASE, OFFSET DEP
{RTCCALIB_V1IDX_A10L, 2, 208, 6, 4, 2231, 0},
{RTCCALIB_V1IDX_A11L, 2, 214, 6, 4, 1643, 0},
{RTCCALIB_V1IDX_A12L, 2, 220, 6, 4, 1290, 0},
{RTCCALIB_V1IDX_A13L, 2, 226, 6, 4, 701, 0},
{RTCCALIB_V1IDX_A20L, 2, 232, 6, 4, 2305, 0},
{RTCCALIB_V1IDX_A21L, 2, 238, 6, 4, 1693, 0},
{RTCCALIB_V1IDX_A22L, 2, 244, 6, 4, 1343, 0},
{RTCCALIB_V1IDX_A23L, 2, 250, 6, 4, 723, 0},
{RTCCALIB_V1IDX_A10H, 2, 144, 8, 4, 5775, 0},
{RTCCALIB_V1IDX_A11H, 2, 152, 8, 4, 5693, 0},
{RTCCALIB_V1IDX_A12H, 2, 160, 8, 4, 5723, 0},
{RTCCALIB_V1IDX_A13H, 2, 168, 8, 4, 6209, 0},
{RTCCALIB_V1IDX_A20H, 2, 176, 8, 4, 5817, 0},
{RTCCALIB_V1IDX_A21H, 2, 184, 8, 4, 5703, 0},
{RTCCALIB_V1IDX_A22H, 2, 192, 8, 4, 5731, 0},
{RTCCALIB_V1IDX_A23H, 2, 200, 8, 4, 6157, 0},
{RTCCALIB_V2IDX_A10H, 2, 197, 6, 2, 169, RTCCALIB_V2IDX_A12H},
{RTCCALIB_V2IDX_A11H, 2, 203, 6, 2, -26, RTCCALIB_V2IDX_A12H},
{RTCCALIB_V2IDX_A12H, 2, 209, 9, 2, 126, RTCCALIB_V2IDX_A21H},
{RTCCALIB_V2IDX_A13H, 2, 218, 7, 2, 387, RTCCALIB_V2IDX_A12H},
{RTCCALIB_V2IDX_A20H, 2, 225, 7, 2, 177, RTCCALIB_V2IDX_A21H},
{RTCCALIB_V2IDX_A21H, 2, 232, 10, 2, 5815, 0},
{RTCCALIB_V2IDX_A22H, 2, 242, 7, 2, 27, RTCCALIB_V2IDX_A21H},
{RTCCALIB_V2IDX_A23H, 2, 249, 7, 2, 410, RTCCALIB_V2IDX_A21H},
{RTCCALIB_V2IDX_A10I, 2, 147, 8, 2, 1519, 0},
{RTCCALIB_V2IDX_A11I, 2, 155, 6, 2, 88, RTCCALIB_V2IDX_A10I},
{RTCCALIB_V2IDX_A12I, 2, 161, 5, 2, 8, RTCCALIB_V2IDX_A11I},
{RTCCALIB_V2IDX_A13I, 2, 166, 6, 2, 70, RTCCALIB_V2IDX_A12I},
{RTCCALIB_V2IDX_A20I, 2, 172, 8, 2, 1677, 0},
{RTCCALIB_V2IDX_A21I, 2, 180, 6, 2, 23, RTCCALIB_V2IDX_A20I},
{RTCCALIB_V2IDX_A22I, 2, 186, 5, 2, 6, RTCCALIB_V2IDX_A21I},
{RTCCALIB_V2IDX_A23I, 2, 191, 6, 2, 13, RTCCALIB_V2IDX_A22I},
{RTCCALIB_IDX_TMPSENSOR, 2, 135, 9, 1, 0, 0},
};
int esp_efuse_rtc_table_read_calib_version(void)
{
uint32_t result = 0;
esp_efuse_read_field_blob(ESP_EFUSE_BLOCK2_VERSION, &result, 32);
return result;
}
int esp_efuse_rtc_table_get_tag(int version, int adc_num, int atten, int extra_params)
{
int param_offset; // used to index which (adc_num, atten) array to use.
if (version == 1 && extra_params == RTCCALIB_V1_PARAM_VLOW) { // Volage LOW, Version 1
param_offset = RTCCALIB_V1_ADCREADINGLOW_OFFSET;
} else if (version == 1 && extra_params == RTCCALIB_V1_PARAM_VHIGH) {
param_offset = RTCCALIB_V1_ADCREADINGHIGH_OFFSET;
} else if (version == 2 && extra_params == RTCCALIB_V2_PARAM_VHIGH) {
param_offset = RTCCALIB_V2_ADCREADINGHIGH_OFFSET;
} else if (version == 2 && extra_params == RTCCALIB_V2_PARAM_VINIT) {
param_offset = RTCCALIB_V2_ADCREADINGINIT_OFFSET;
} else {
return -1;
}
int result = param_offset + (adc_num - 1) * RTCCALIB_ESP32S2_ATTENCOUNT + atten;
ESP_EARLY_LOGV(RTC_TBL_LOG_TAG, "V%d ADC%d ATTEN%d PARAM%d -> %d", version, adc_num, atten, extra_params, result);
return result;
}
/*
* Converts a signed-bit int to a normal (2-complement) int.
* */
static int signed_bit_to_int(uint32_t number, int len)
{
if (number >> (len - 1)) {
// first bit is set, unset that bit and negate the number.
number = -(number ^ (1 << (len - 1)));
}
return number;
}
int esp_efuse_rtc_table_get_raw_efuse_value(int tag)
{
assert(tag > 0);
if (tag == 0) {
return 0;
}
uint32_t val = 0;
esp_efuse_read_block(adc_efuse_raw_map[tag].block, &val, adc_efuse_raw_map[tag].begin_bit, adc_efuse_raw_map[tag].length);
int result = signed_bit_to_int(val, adc_efuse_raw_map[tag].length);
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,
result);
return result;
}
int esp_efuse_rtc_table_get_parsed_efuse_value(int tag, bool skip_efuse_reading)
{
assert(tag >= 0);
if (tag == 0) {
return 0; // tag 0 is the dummy tag and has no value. (used by depends)
}
int efuse_val = 0;
if (!skip_efuse_reading) {
efuse_val = esp_efuse_rtc_table_get_raw_efuse_value(tag) * adc_efuse_raw_map[tag].multiplier;
}
int result = efuse_val + adc_efuse_raw_map[tag].base +
esp_efuse_rtc_table_get_parsed_efuse_value(adc_efuse_raw_map[tag].depends, skip_efuse_reading);
ESP_EARLY_LOGV(RTC_TBL_LOG_TAG, "Parsed efuse val for tag %d: %d", tag, result);
return result;
}

View File

@@ -0,0 +1,139 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "esp_efuse_utility.h"
#include "soc/efuse_periph.h"
#include "esp32s2/clk.h"
#include "esp_log.h"
#include "assert.h"
#include "sdkconfig.h"
#include <sys/param.h>
#include "esp32s2/rom/efuse.h"
static const char *TAG = "efuse";
#ifdef CONFIG_EFUSE_VIRTUAL
extern uint32_t virt_blocks[EFUSE_BLK_MAX][COUNT_EFUSE_REG_PER_BLOCK];
#endif // CONFIG_EFUSE_VIRTUAL
/*Range addresses to read blocks*/
const esp_efuse_range_addr_t range_read_addr_blocks[] = {
{EFUSE_RD_WR_DIS_REG, EFUSE_RD_REPEAT_DATA4_REG}, // range address of EFUSE_BLK0 REPEAT
{EFUSE_RD_MAC_SPI_SYS_0_REG, EFUSE_RD_MAC_SPI_SYS_5_REG}, // range address of EFUSE_BLK1 MAC_SPI_8M
{EFUSE_RD_SYS_PART1_DATA0_REG, EFUSE_RD_SYS_PART1_DATA7_REG}, // range address of EFUSE_BLK2 SYS_DATA
{EFUSE_RD_USR_DATA0_REG, EFUSE_RD_USR_DATA7_REG}, // range address of EFUSE_BLK3 USR_DATA
{EFUSE_RD_KEY0_DATA0_REG, EFUSE_RD_KEY0_DATA7_REG}, // range address of EFUSE_BLK4 KEY0
{EFUSE_RD_KEY1_DATA0_REG, EFUSE_RD_KEY1_DATA7_REG}, // range address of EFUSE_BLK5 KEY1
{EFUSE_RD_KEY2_DATA0_REG, EFUSE_RD_KEY2_DATA7_REG}, // range address of EFUSE_BLK6 KEY2
{EFUSE_RD_KEY3_DATA0_REG, EFUSE_RD_KEY3_DATA7_REG}, // range address of EFUSE_BLK7 KEY3
{EFUSE_RD_KEY4_DATA0_REG, EFUSE_RD_KEY4_DATA7_REG}, // range address of EFUSE_BLK8 KEY4
{EFUSE_RD_KEY5_DATA0_REG, EFUSE_RD_KEY5_DATA7_REG}, // range address of EFUSE_BLK9 KEY5
{EFUSE_RD_SYS_PART2_DATA0_REG, EFUSE_RD_SYS_PART2_DATA7_REG} // range address of EFUSE_BLK10 KEY6
};
static uint32_t write_mass_blocks[EFUSE_BLK_MAX][COUNT_EFUSE_REG_PER_BLOCK] = { 0 };
/*Range addresses to write blocks (it is not real regs, it is buffer) */
const esp_efuse_range_addr_t range_write_addr_blocks[] = {
{(uint32_t) &write_mass_blocks[EFUSE_BLK0][0], (uint32_t) &write_mass_blocks[EFUSE_BLK0][5]},
{(uint32_t) &write_mass_blocks[EFUSE_BLK1][0], (uint32_t) &write_mass_blocks[EFUSE_BLK1][5]},
{(uint32_t) &write_mass_blocks[EFUSE_BLK2][0], (uint32_t) &write_mass_blocks[EFUSE_BLK2][7]},
{(uint32_t) &write_mass_blocks[EFUSE_BLK3][0], (uint32_t) &write_mass_blocks[EFUSE_BLK3][7]},
{(uint32_t) &write_mass_blocks[EFUSE_BLK4][0], (uint32_t) &write_mass_blocks[EFUSE_BLK4][7]},
{(uint32_t) &write_mass_blocks[EFUSE_BLK5][0], (uint32_t) &write_mass_blocks[EFUSE_BLK5][7]},
{(uint32_t) &write_mass_blocks[EFUSE_BLK6][0], (uint32_t) &write_mass_blocks[EFUSE_BLK6][7]},
{(uint32_t) &write_mass_blocks[EFUSE_BLK7][0], (uint32_t) &write_mass_blocks[EFUSE_BLK7][7]},
{(uint32_t) &write_mass_blocks[EFUSE_BLK8][0], (uint32_t) &write_mass_blocks[EFUSE_BLK8][7]},
{(uint32_t) &write_mass_blocks[EFUSE_BLK9][0], (uint32_t) &write_mass_blocks[EFUSE_BLK9][7]},
{(uint32_t) &write_mass_blocks[EFUSE_BLK10][0], (uint32_t) &write_mass_blocks[EFUSE_BLK10][7]},
};
#ifndef CONFIG_EFUSE_VIRTUAL
// Update Efuse timing configuration
static esp_err_t esp_efuse_set_timing(void)
{
uint32_t clock_hz = esp_clk_apb_freq();
return ets_efuse_set_timing(clock_hz) ? ESP_FAIL : ESP_OK;
}
#endif // ifndef CONFIG_EFUSE_VIRTUAL
// Efuse read operation: copies data from physical efuses to efuse read registers.
void esp_efuse_utility_clear_program_registers(void)
{
ets_efuse_read();
ets_efuse_clear_program_registers();
}
// Burn values written to the efuse write registers
void esp_efuse_utility_burn_efuses(void)
{
#ifdef CONFIG_EFUSE_VIRTUAL
ESP_LOGW(TAG, "Virtual efuses enabled: Not really burning eFuses");
for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) {
int subblock = 0;
for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) {
virt_blocks[num_block][subblock++] |= REG_READ(addr_wr_block);
}
}
#else
if (esp_efuse_set_timing() != ESP_OK) {
ESP_LOGE(TAG, "Efuse fields are not burnt");
} else {
// Permanently update values written to the efuse write registers
// It is necessary to process blocks in the order from MAX-> EFUSE_BLK0, because EFUSE_BLK0 has protection bits for other blocks.
for (int num_block = EFUSE_BLK_MAX - 1; num_block >= EFUSE_BLK0; num_block--) {
for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) {
if (REG_READ(addr_wr_block) != 0) {
if (esp_efuse_get_coding_scheme(num_block) == EFUSE_CODING_SCHEME_RS) {
uint8_t block_rs[12];
ets_efuse_rs_calculate((void *)range_write_addr_blocks[num_block].start, block_rs);
memcpy((void *)EFUSE_PGM_CHECK_VALUE0_REG, block_rs, sizeof(block_rs));
}
int data_len = (range_write_addr_blocks[num_block].end - range_write_addr_blocks[num_block].start) + sizeof(uint32_t);
memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)range_write_addr_blocks[num_block].start, data_len);
ets_efuse_program(num_block);
break;
}
}
}
}
#endif // CONFIG_EFUSE_VIRTUAL
esp_efuse_utility_reset();
}
// After esp_efuse_write.. functions EFUSE_BLKx_WDATAx_REG were filled is not coded values.
// This function reads EFUSE_BLKx_WDATAx_REG registers, and checks possible to write these data with RS coding scheme.
// The RS coding scheme does not require data changes for the encoded data. esp32s2 has special registers for this.
// They will be filled during the burn operation.
esp_err_t esp_efuse_utility_apply_new_coding_scheme()
{
// start with EFUSE_BLK1. EFUSE_BLK0 - always uses EFUSE_CODING_SCHEME_NONE.
for (int num_block = EFUSE_BLK1; num_block < EFUSE_BLK_MAX; num_block++) {
if (esp_efuse_get_coding_scheme(num_block) == EFUSE_CODING_SCHEME_RS) {
for (uint32_t addr_wr_block = range_write_addr_blocks[num_block].start; addr_wr_block <= range_write_addr_blocks[num_block].end; addr_wr_block += 4) {
if (REG_READ(addr_wr_block)) {
int num_reg = 0;
for (uint32_t addr_rd_block = range_read_addr_blocks[num_block].start; addr_rd_block <= range_read_addr_blocks[num_block].end; addr_rd_block += 4, ++num_reg) {
if (esp_efuse_utility_read_reg(num_block, num_reg)) {
ESP_LOGE(TAG, "Bits are not empty. Write operation is forbidden.");
return ESP_ERR_CODING;
}
}
break;
}
}
}
}
return ESP_OK;
}

View File

@@ -0,0 +1,70 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Type of eFuse blocks ESP32S2
*/
typedef enum {
EFUSE_BLK0 = 0, /**< Number of eFuse BLOCK0. REPEAT_DATA */
EFUSE_BLK1 = 1, /**< Number of eFuse BLOCK1. MAC_SPI_8M_SYS */
EFUSE_BLK2 = 2, /**< Number of eFuse BLOCK2. SYS_DATA_PART1 */
EFUSE_BLK_SYS_DATA_PART1 = 2, /**< Number of eFuse BLOCK2. SYS_DATA_PART1 */
EFUSE_BLK3 = 3, /**< Number of eFuse BLOCK3. USER_DATA*/
EFUSE_BLK_USER_DATA = 3, /**< Number of eFuse BLOCK3. USER_DATA*/
EFUSE_BLK4 = 4, /**< Number of eFuse BLOCK4. KEY0 */
EFUSE_BLK_KEY0 = 4, /**< Number of eFuse BLOCK4. KEY0 */
EFUSE_BLK5 = 5, /**< Number of eFuse BLOCK5. KEY1 */
EFUSE_BLK_KEY1 = 5, /**< Number of eFuse BLOCK5. KEY1 */
EFUSE_BLK6 = 6, /**< Number of eFuse BLOCK6. KEY2 */
EFUSE_BLK_KEY2 = 6, /**< Number of eFuse BLOCK6. KEY2 */
EFUSE_BLK7 = 7, /**< Number of eFuse BLOCK7. KEY3 */
EFUSE_BLK_KEY3 = 7, /**< Number of eFuse BLOCK7. KEY3 */
EFUSE_BLK8 = 8, /**< Number of eFuse BLOCK8. KEY4 */
EFUSE_BLK_KEY4 = 8, /**< Number of eFuse BLOCK8. KEY4 */
EFUSE_BLK9 = 9, /**< Number of eFuse BLOCK9. KEY5 */
EFUSE_BLK_KEY5 = 9, /**< Number of eFuse BLOCK9. KEY5 */
EFUSE_BLK_KEY_MAX = 10,
EFUSE_BLK10 = 10, /**< Number of eFuse BLOCK10. SYS_DATA_PART2 */
EFUSE_BLK_SYS_DATA_PART2 = 10, /**< Number of eFuse BLOCK10. SYS_DATA_PART2 */
EFUSE_BLK_MAX
} esp_efuse_block_t;
/**
* @brief Type of coding scheme
*/
typedef enum {
EFUSE_CODING_SCHEME_NONE = 0, /**< None */
EFUSE_CODING_SCHEME_RS = 3, /**< Reed-Solomon coding */
} esp_efuse_coding_scheme_t;
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,108 @@
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <stdint.h>
#include "esp_err.h"
#include "sdkconfig.h"
#define RTCCALIB_ESP32S2_ADCCOUNT 2
#define RTCCALIB_ESP32S2_ATTENCOUNT 4
#define RTCCALIB_V1_PARAM_VLOW 0
#define RTCCALIB_V1_PARAM_VHIGH 1
#define RTCCALIB_V2_PARAM_VHIGH 0
#define RTCCALIB_V2_PARAM_VINIT 1
// these are the tags. Either use them directly or use esp_efuse_rtc_table_get_tag to calculate
// the corresponding tag.
#define RTCCALIB_V1IDX_A10L 1
#define RTCCALIB_V1IDX_A11L 2
#define RTCCALIB_V1IDX_A12L 3
#define RTCCALIB_V1IDX_A13L 4
#define RTCCALIB_V1IDX_A20L 5
#define RTCCALIB_V1IDX_A21L 6
#define RTCCALIB_V1IDX_A22L 7
#define RTCCALIB_V1IDX_A23L 8
#define RTCCALIB_V1IDX_A10H 9
#define RTCCALIB_V1IDX_A11H 10
#define RTCCALIB_V1IDX_A12H 11
#define RTCCALIB_V1IDX_A13H 12
#define RTCCALIB_V1IDX_A20H 13
#define RTCCALIB_V1IDX_A21H 14
#define RTCCALIB_V1IDX_A22H 15
#define RTCCALIB_V1IDX_A23H 16
#define RTCCALIB_V2IDX_A10H 17
#define RTCCALIB_V2IDX_A11H 18
#define RTCCALIB_V2IDX_A12H 19
#define RTCCALIB_V2IDX_A13H 20
#define RTCCALIB_V2IDX_A20H 21
#define RTCCALIB_V2IDX_A21H 22
#define RTCCALIB_V2IDX_A22H 23
#define RTCCALIB_V2IDX_A23H 24
#define RTCCALIB_V2IDX_A10I 25
#define RTCCALIB_V2IDX_A11I 26
#define RTCCALIB_V2IDX_A12I 27
#define RTCCALIB_V2IDX_A13I 28
#define RTCCALIB_V2IDX_A20I 29
#define RTCCALIB_V2IDX_A21I 30
#define RTCCALIB_V2IDX_A22I 31
#define RTCCALIB_V2IDX_A23I 32
#define RTCCALIB_IDX_TMPSENSOR 33
/**
* @brief Get rtc calibration version.
*/
int esp_efuse_rtc_table_read_calib_version(void);
/**
* @brief Helper function to calculate a tag from human-readable parameters.
* Tag is used to index the desired data from the efuse.
* For example, (1, 1, 3, 1) yields the tag RTCCALIB_V1IDX_A13H
* extra params are used for identification when a adc_num-atten combination has
* multiple efuse values.
* @param adc_channel_num verbatim numbering of the ADC channel. For channel 1, use 1 and not 0.
* @param atten attenuation. use the enum value.
* @param version the version of the scheme to index for.
* @param extra_params defined differently for each version.
* */
int esp_efuse_rtc_table_get_tag(int version, int adc_channel_num, int atten, int extra_params);
/**
* @brief Fetches a raw value from efuse and does signed bit parsing
* @param tag tag obtained with esp_efuse_rtc_table_get_tag
*
* */
int esp_efuse_rtc_table_get_raw_efuse_value(int tag);
/**
* @brief Fetches a raw value from efuse and resolve it to get
* the original number that it meant to represent.
*
* @param tag tag obtained with esp_efuse_rtc_table_get_tag
* @param use_zero_inputs Does not perform the raw value fetching before resolving the number,
* but proceed as if all zeros were read from efuse.
*
* */
int esp_efuse_rtc_table_get_parsed_efuse_value(int tag, bool skip_efuse_reading);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,29 @@
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#define COUNT_EFUSE_REG_PER_BLOCK 8 /* The number of registers per block. */
#define ESP_EFUSE_SECURE_VERSION_NUM_BLOCK EFUSE_BLK0
#define ESP_EFUSE_FIELD_CORRESPONDS_CODING_SCHEME(scheme, max_num_bit)
#ifdef __cplusplus
}
#endif

View File

@@ -1 +1,4 @@
set(EFUSE_SOC_SRCS "esp_efuse_table.c")
set(EFUSE_SOC_SRCS "esp_efuse_table.c"
"esp_efuse_fields.c"
"esp_efuse_rtc_table.c"
"esp_efuse_utility.c")