1 /*
2  * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #pragma once
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 #include <string.h>
14 #include "esp_types.h"
15 #include "esp_err.h"
16 #include "esp_efuse.h"
17 #include "sdkconfig.h"
18 #include_next "esp_efuse_utility.h"
19 
20 #define ESP_EFUSE_CHK(ret)       \
21     do                           \
22     {                            \
23         if( ( err = (ret) ) != ESP_OK ) \
24             goto err_exit;        \
25     } while( 0 )
26 
27 
28 /**
29  * @brief Structure range address by blocks
30  */
31 typedef struct {
32     uint32_t start;
33     uint32_t end;
34 } esp_efuse_range_addr_t;
35 
36 /**
37  * @brief This is type of function that will handle the efuse field register.
38  *
39  * @param[in] num_reg          The register number in the block.
40  * @param[in] efuse_block      Block number.
41  * @param[in] bit_start        Start bit in the register.
42  * @param[in] bit_count        The number of bits used in the register.
43  * @param[in/out] arr          A pointer to an array or variable.
44  * @param[in/out] bits_counter Counter bits.
45  *
46  * @return
47  *      - ESP_OK: The operation was successfully completed.
48  *      - other efuse component errors.
49  */
50 typedef esp_err_t (*efuse_func_proc_t) (unsigned int num_reg, esp_efuse_block_t efuse_block, int starting_bit_num_in_reg, int num_bits_used_in_reg, void* arr, int* bits_counter);
51 
52 /**
53  * @brief This function processes the field by calling the passed function.
54  *
55  * This function selects the field, checks the length, and calls the register processing function.
56  * @param[in] field           A pointer to the structure describing the fields of efuse.
57  * @param[in/out] ptr         A pointer to an array that is used to read / write from / to the efuse field.
58  * @param[in] ptr_size_bits   The size of the data in bits for the efuse field. if = 0 then read all field bits.
59  * @param[in] func_proc       This is the function that will handle the efuse fields.
60  *
61  * @return
62  *      - ESP_OK: The operation was successfully completed.
63  *      - other efuse component errors.
64  */
65 esp_err_t esp_efuse_utility_process(const esp_efuse_desc_t* field[], void* ptr, size_t ptr_size_bits, efuse_func_proc_t func_proc);
66 
67 /**
68  * @brief Write register with the required number of "1" bits.
69  * @param[in/out] cnt      The number of bits you need to set in the field.
70  */
71 esp_err_t esp_efuse_utility_write_cnt(unsigned int num_reg, esp_efuse_block_t efuse_block, int bit_start, int bit_count, void* cnt, int* bits_counter);
72 
73 /**
74  * @brief Fill registers from array for writing.
75  * @param[in] arr_in       A pointer to an array in which the data for the writing.
76  */
77 esp_err_t esp_efuse_utility_write_blob(unsigned int num_reg, esp_efuse_block_t efuse_block, int bit_start, int bit_count, void* arr_in, int* bits_counter);
78 
79 /**
80  * @brief Count a set bits in register.
81  * @param[in/out] out_cnt  A pointer to size_t variable which will contain the number of "1" bits.
82  */
83 esp_err_t esp_efuse_utility_count_once(unsigned int num_reg, esp_efuse_block_t efuse_block, int bit_start, int bit_count, void* out_cnt, int* bits_counter);
84 
85 /**
86  * @brief Read efuse register and write this value to array.
87  * @param[out] arr_out     A pointer to array that will contain the result of reading.
88  */
89 esp_err_t esp_efuse_utility_fill_buff(unsigned int num_reg, esp_efuse_block_t efuse_block, int bit_start, int bit_count, void* arr_out, int* bits_counter);
90 
91 /**
92  * @brief Burn values written to the efuse write registers.
93  *
94  * If CONFIG_EFUSE_VIRTUAL is set, writing will not be performed.
95  * After the function is completed, the writing registers are cleared.
96  *
97  * @return
98  *      - ESP_OK: The operation was successfully completed.
99  *      - ESP_FAIL: The operation was not successfully completed.
100  */
101 esp_err_t esp_efuse_utility_burn_efuses(void);
102 
103 /**
104  * @brief Chip specific operations to perform the burn of values written to the efuse write registers.
105  *
106  * @note Use esp_efuse_utility_burn_efuses() to burn efuses.
107  *
108  * If CONFIG_EFUSE_VIRTUAL is set, writing will not be performed.
109  * After the function is completed, the writing registers are cleared.
110  *
111  * @return
112  *      - ESP_OK: The operation was successfully completed.
113  *      - ESP_FAIL: The operation was not successfully completed.
114  */
115 esp_err_t esp_efuse_utility_burn_chip(void);
116 
117 /**
118  * @brief Returns the number of array elements for placing these "bits" in an array with the length of each element equal to "size_of_base".
119  */
120 int esp_efuse_utility_get_number_of_items(int bits, int size_of_base);
121 
122 /**
123  * @brief Reading efuse register.
124  */
125 uint32_t esp_efuse_utility_read_reg(esp_efuse_block_t blk, unsigned int num_reg);
126 
127 /**
128  * @brief Writing efuse register with checking of repeated programming of programmed bits.
129  */
130 esp_err_t esp_efuse_utility_write_reg(esp_efuse_block_t efuse_block, unsigned int num_reg, uint32_t reg_to_write);
131 
132 /* @brief Reset efuse write registers
133  *
134  * Efuse write registers are written to zero, to negate
135  * any changes that have been staged here.
136  */
137 void esp_efuse_utility_reset(void);
138 
139 /**
140  * @brief   Fills the virt_blocks array by values from efuse_Rdata.
141  */
142 void esp_efuse_utility_update_virt_blocks(void);
143 
144 /**
145  * @brief   Prints efuse values for all registers.
146  */
147 void esp_efuse_utility_debug_dump_blocks(void);
148 
149 /**
150  * @brief   Prints efuse values for a single block.
151  * @param[in] num_block Index of efuse block.
152  * @param[in] from_read Take data from:
153  *                      true - read area (already burned efuses),
154  *                      false - write area (not yet burned efuses, prepared for burn).
155  */
156 void esp_efuse_utility_debug_dump_single_block(int num_block, bool from_read);
157 
158 /**
159  * @brief   Erase the virt_blocks array.
160  */
161 void esp_efuse_utility_erase_virt_blocks(void);
162 
163 /**
164  * @brief   Apply coding_scheme to write registers.
165  *
166  * @return
167  *         - ESP_OK: The operation was successfully completed.
168  *         - ESP_ERR_CODING: Error range of data does not match the coding scheme.
169  */
170 esp_err_t esp_efuse_utility_apply_new_coding_scheme(void);
171 
172 /**
173  * @brief   Checks eFuse errors in BLOCK0.
174  *
175  * @note Refers to ESP32-C3 only.
176  *
177  * It does a BLOCK0 check if eFuse EFUSE_ERR_RST_ENABLE is set.
178  * If BLOCK0 has an error, it prints the error and returns ESP_FAIL, which should be treated as esp_restart.
179  *
180  * @return
181  *         - ESP_OK: No errors in BLOCK0.
182  *         - ESP_FAIL: Error in BLOCK0 requiring reboot.
183  */
184 esp_err_t esp_efuse_utility_check_errors(void);
185 
186 /**
187  * @brief   Efuse read operation: copies data from physical efuses to efuse read registers.
188  */
189 void esp_efuse_utility_clear_program_registers(void);
190 
191 #ifdef CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH
192 /**
193  * @brief   Writes eFuses to the efuse flash partition.
194  *
195  * Used only when CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH is set.
196  */
197 void esp_efuse_utility_write_efuses_to_flash(void);
198 
199 /**
200  * @brief   Loads efuses from efuse flash partition.
201  *
202  * Used only when CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH is set.
203  */
204 bool esp_efuse_utility_load_efuses_from_flash(void);
205 
206 /**
207  * @brief   Erase efuse flash partition.
208  *
209  * Used only when CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH is set.
210  */
211 void esp_efuse_utility_erase_efuses_in_flash(void);
212 #endif
213 
214 /**
215  * @brief Return the address of a particular efuse block's first read register
216  *
217  * @param[in] block Index of efuse block to look up
218  *
219  * @return a numeric read register address of the first word in the block.
220  */
221 uint32_t esp_efuse_utility_get_read_register_address(esp_efuse_block_t block);
222 
223 /**
224  * @brief Checks the correctness of burned data in the given block.
225  *
226  * @note Internal use. Do not call it.
227  *
228  * @param[in] block Index of efuse block.
229  * @param[in] r_data_len Block length for reading data in bytes (multiple of 4).
230  *
231  * @return True  - written data are correct.
232  *         False - written data are incorrect.
233  */
234 bool esp_efuse_utility_is_correct_written_data(esp_efuse_block_t block, unsigned r_data_len);
235 
236 #ifdef __cplusplus
237 }
238 #endif
239