test_efuse.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867
  1. /*
  2. * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. #include <errno.h>
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include "unity.h"
  12. #include "esp_log.h"
  13. #include <string.h>
  14. #include "esp_efuse.h"
  15. #include "esp_efuse_table.h"
  16. #include "esp_efuse_utility.h"
  17. #include "esp_efuse_test_table.h"
  18. #include "esp_timer.h"
  19. #include "bootloader_random.h"
  20. #include "freertos/FreeRTOS.h"
  21. #include "freertos/task.h"
  22. #include "freertos/semphr.h"
  23. #include "test_utils.h"
  24. #include "sdkconfig.h"
  25. #include "esp_rom_efuse.h"
  26. #include "bootloader_common.h"
  27. #ifdef CONFIG_IDF_TARGET_ESP32
  28. #define MAC_FACTORY_HAS_CRC 1
  29. #endif
  30. __attribute__((unused)) static const char* TAG = "efuse_test";
  31. static void test_read_blob(void)
  32. {
  33. esp_efuse_utility_update_virt_blocks();
  34. esp_efuse_utility_debug_dump_blocks();
  35. uint8_t mac[6];
  36. ESP_LOGI(TAG, "1. Read MAC address");
  37. memset(mac, 0, sizeof(mac));
  38. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, sizeof(mac) * 8));
  39. TEST_ASSERT_EQUAL_INT(sizeof(mac) * 8, esp_efuse_get_field_size(ESP_EFUSE_MAC_FACTORY));
  40. ESP_LOGI(TAG, "MAC: %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  41. #ifdef MAC_FACTORY_HAS_CRC
  42. ESP_LOGI(TAG, "2. Check CRC by MAC");
  43. uint8_t crc;
  44. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY_CRC, &crc, 8));
  45. TEST_ASSERT_EQUAL_HEX8(crc, esp_rom_efuse_mac_address_crc8(mac, sizeof(mac)));
  46. #endif
  47. ESP_LOGI(TAG, "3. Test check args");
  48. uint32_t test_var;
  49. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, NULL, 1));
  50. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &test_var, 0));
  51. uint8_t half_byte;
  52. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &half_byte, 4));
  53. TEST_ASSERT_EQUAL_HEX8(mac[0]&0x0F, half_byte);
  54. uint8_t buff[7] = {0x59};
  55. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &buff, sizeof(buff) * 8));
  56. TEST_ASSERT_TRUE_MESSAGE(memcmp(mac, buff, sizeof(mac)) == 0, "Operation read blob is not success");
  57. TEST_ASSERT_EQUAL_HEX8(0, buff[6]);
  58. }
  59. TEST_CASE("efuse test read_field_blob", "[efuse]")
  60. {
  61. test_read_blob();
  62. }
  63. static void test_read_cnt(void)
  64. {
  65. esp_efuse_utility_update_virt_blocks();
  66. esp_efuse_utility_debug_dump_blocks();
  67. ESP_LOGI(TAG, "1. Test check args");
  68. size_t cnt;
  69. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_read_field_cnt(ESP_EFUSE_MAC_FACTORY, NULL));
  70. ESP_LOGI(TAG, "2. Read MAC address");
  71. uint8_t mac[6];
  72. memset(mac, 0, sizeof(mac));
  73. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, 48));
  74. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_MAC_FACTORY, &cnt));
  75. size_t cnt_summ = 0;
  76. for (int i = 0; i < sizeof(mac); ++i) {
  77. cnt_summ += __builtin_popcount(mac[i]);
  78. }
  79. TEST_ASSERT_EQUAL_INT(cnt_summ, cnt);
  80. }
  81. TEST_CASE("efuse test read_field_cnt", "[efuse]")
  82. {
  83. test_read_cnt();
  84. }
  85. // If using efuse is real, then turn off writing tests.
  86. #ifdef CONFIG_EFUSE_VIRTUAL
  87. static void test_write_blob(void)
  88. {
  89. esp_efuse_coding_scheme_t scheme = esp_efuse_get_coding_scheme(EFUSE_BLK1);
  90. esp_efuse_utility_erase_virt_blocks();
  91. esp_efuse_utility_debug_dump_blocks();
  92. ESP_LOGI(TAG, "1. Test check args");
  93. uint16_t test1_len_8 = 0x5FAA;
  94. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_blob(ESP_EFUSE_MAC_FACTORY, &test1_len_8, 0));
  95. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, NULL, 8));
  96. TEST_ASSERT_EQUAL_HEX16(0x5FAA, test1_len_8);
  97. ESP_LOGI(TAG, "2. Test write operation");
  98. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, &test1_len_8, 7));
  99. TEST_ESP_ERR(ESP_ERR_EFUSE_REPEATED_PROG, esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, &test1_len_8, 9));
  100. uint16_t val_read1 = 0;
  101. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST1_LEN_8, &val_read1, 8));
  102. TEST_ASSERT_EQUAL_HEX16(test1_len_8&((1 << 7) - 1), val_read1);
  103. uint16_t test1_len_8_hi = test1_len_8 & ~((1 << 7) - 1);
  104. if (scheme == EFUSE_CODING_SCHEME_NONE) {
  105. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, &test1_len_8_hi, 8));
  106. } else {
  107. TEST_ESP_ERR(ESP_ERR_CODING, esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, &test1_len_8_hi, 8));
  108. }
  109. TEST_ESP_ERR(ESP_ERR_EFUSE_REPEATED_PROG, esp_efuse_write_field_blob(ESP_EFUSE_TEST1_LEN_8, &test1_len_8, 8));
  110. val_read1 = 0;
  111. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST1_LEN_8, &val_read1, 16));
  112. if (scheme == EFUSE_CODING_SCHEME_NONE) {
  113. TEST_ASSERT_EQUAL_HEX16(test1_len_8&0x00FF, val_read1);
  114. } else {
  115. TEST_ASSERT_EQUAL_HEX16(test1_len_8&0x007F, val_read1);
  116. }
  117. if (scheme != EFUSE_CODING_SCHEME_NONE) {
  118. esp_efuse_utility_erase_virt_blocks();
  119. ESP_LOGI(TAG, "erase virt blocks");
  120. }
  121. uint16_t test2_len_16 = 0xAA55;
  122. uint32_t val_32 = test2_len_16;
  123. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST2_LEN_16, &val_32, 17));
  124. TEST_ESP_ERR(ESP_ERR_EFUSE_REPEATED_PROG, esp_efuse_write_field_blob(ESP_EFUSE_TEST2_LEN_16, &test2_len_16, 16));
  125. uint16_t test_16 = 0;
  126. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST2_LEN_16, &test_16, 16));
  127. TEST_ASSERT_EQUAL_HEX16(test2_len_16, test_16);
  128. ESP_LOGI(TAG, "3. Test field with one bit");
  129. uint8_t test5_len_1;
  130. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  131. TEST_ASSERT_EQUAL_HEX8(0, test5_len_1);
  132. test5_len_1 = 0;
  133. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  134. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  135. TEST_ASSERT_EQUAL_HEX8(0, test5_len_1);
  136. test5_len_1 = 1;
  137. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  138. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  139. TEST_ASSERT_EQUAL_HEX8(1, test5_len_1);
  140. test5_len_1 = 1;
  141. TEST_ESP_ERR(ESP_ERR_EFUSE_REPEATED_PROG, esp_efuse_write_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  142. esp_efuse_utility_debug_dump_blocks();
  143. }
  144. TEST_CASE("efuse test write_field_blob", "[efuse]")
  145. {
  146. test_write_blob();
  147. }
  148. static void test_write_cnt(void)
  149. {
  150. esp_efuse_coding_scheme_t scheme = esp_efuse_get_coding_scheme(EFUSE_BLK1);
  151. esp_efuse_utility_erase_virt_blocks();
  152. esp_efuse_utility_debug_dump_blocks();
  153. ESP_LOGI(TAG, "1. Test check args");
  154. size_t test3_len_6 = 5;
  155. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_cnt(ESP_EFUSE_MAC_FACTORY, 0));
  156. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_cnt(NULL, 5));
  157. TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 0));
  158. ESP_LOGI(TAG, "2. Test write operation");
  159. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST3_LEN_6, &test3_len_6));
  160. TEST_ASSERT_EQUAL_INT(0, test3_len_6);
  161. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 1));
  162. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST3_LEN_6, &test3_len_6));
  163. TEST_ASSERT_EQUAL_INT(1, test3_len_6);
  164. if (scheme == EFUSE_CODING_SCHEME_NONE) {
  165. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 1));
  166. } else {
  167. esp_efuse_utility_erase_virt_blocks();
  168. ESP_LOGI(TAG, "erase virt blocks");
  169. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 2));
  170. }
  171. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST3_LEN_6, &test3_len_6));
  172. TEST_ASSERT_EQUAL_INT(2, test3_len_6);
  173. if (scheme == EFUSE_CODING_SCHEME_NONE) {
  174. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 3));
  175. } else {
  176. esp_efuse_utility_erase_virt_blocks();
  177. ESP_LOGI(TAG, "erase virt blocks");
  178. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, 5));
  179. }
  180. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST3_LEN_6, &test3_len_6));
  181. TEST_ASSERT_EQUAL_INT(5, test3_len_6);
  182. esp_efuse_utility_debug_dump_blocks();
  183. ESP_LOGI(TAG, "3. Test field is full set");
  184. int max_bits = esp_efuse_get_field_size(ESP_EFUSE_TEST4_LEN_182);
  185. size_t test4_len_182;
  186. esp_efuse_utility_debug_dump_blocks();
  187. for (int i = 0; i < max_bits / 26; ++i) {
  188. ESP_LOGD(TAG, "# %d", i);
  189. if (scheme == EFUSE_CODING_SCHEME_NONE) {
  190. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST4_LEN_182, 26));
  191. } else {
  192. esp_efuse_utility_erase_virt_blocks();
  193. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST4_LEN_182, (i + 1) * 26));
  194. }
  195. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST4_LEN_182, &test4_len_182));
  196. esp_efuse_utility_debug_dump_blocks();
  197. TEST_ASSERT_EQUAL_INT((i + 1) * 26, test4_len_182);
  198. }
  199. esp_efuse_utility_debug_dump_blocks();
  200. ESP_LOGI(TAG, "4. Test field ESP_EFUSE_TEST4_LEN_182 is full");
  201. TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_write_field_cnt(ESP_EFUSE_TEST4_LEN_182, 1));
  202. ESP_LOGI(TAG, "3. Test field with one bit");
  203. size_t test5_len_1;
  204. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST5_LEN_1, &test5_len_1));
  205. TEST_ASSERT_EQUAL_HEX8(0, test5_len_1);
  206. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  207. TEST_ASSERT_EQUAL_HEX8(0, test5_len_1);
  208. if (scheme != EFUSE_CODING_SCHEME_NONE) {
  209. esp_efuse_utility_erase_virt_blocks();
  210. ESP_LOGI(TAG, "erase virt blocks");
  211. }
  212. test5_len_1 = 1;
  213. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST5_LEN_1, test5_len_1));
  214. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST5_LEN_1, &test5_len_1));
  215. TEST_ASSERT_EQUAL_HEX8(1, test5_len_1);
  216. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test5_len_1, 1));
  217. TEST_ASSERT_EQUAL_HEX8(1, test5_len_1);
  218. test5_len_1 = 1;
  219. TEST_ESP_ERR(ESP_ERR_EFUSE_CNT_IS_FULL, esp_efuse_write_field_cnt(ESP_EFUSE_TEST5_LEN_1, test5_len_1));
  220. esp_efuse_utility_debug_dump_blocks();
  221. ESP_LOGI(TAG, "4. Test field test2_len_16");
  222. size_t test2_len_16 = 11;
  223. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST2_LEN_16, test2_len_16));
  224. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST2_LEN_16, &test2_len_16));
  225. TEST_ASSERT_EQUAL_HEX16(11, test2_len_16);
  226. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST2_LEN_16, &test2_len_16, 16));
  227. TEST_ASSERT_EQUAL_HEX16(0x07FF, test2_len_16);
  228. esp_efuse_utility_debug_dump_blocks();
  229. }
  230. TEST_CASE("efuse test write_field_cnt", "[efuse]")
  231. {
  232. test_write_cnt();
  233. }
  234. TEST_CASE("efuse test single bit functions", "[efuse]")
  235. {
  236. esp_efuse_utility_erase_virt_blocks();
  237. esp_efuse_utility_debug_dump_blocks();
  238. uint8_t test_bit;
  239. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test_bit, 1));
  240. TEST_ASSERT_EQUAL_HEX8(0, test_bit);
  241. test_bit = esp_efuse_read_field_bit(ESP_EFUSE_TEST5_LEN_1);
  242. TEST_ASSERT_EQUAL_HEX8(0, test_bit);
  243. TEST_ESP_OK(esp_efuse_write_field_bit(ESP_EFUSE_TEST5_LEN_1));
  244. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST5_LEN_1, &test_bit, 1));
  245. TEST_ASSERT_EQUAL_HEX8(1, test_bit);
  246. test_bit = esp_efuse_read_field_bit(ESP_EFUSE_TEST5_LEN_1);
  247. TEST_ASSERT_EQUAL_HEX8(1, test_bit);
  248. // Can write the bit again and it's a no-op
  249. TEST_ESP_OK(esp_efuse_write_field_bit(ESP_EFUSE_TEST5_LEN_1));
  250. TEST_ASSERT_EQUAL_HEX8(1, esp_efuse_read_field_bit(ESP_EFUSE_TEST5_LEN_1));
  251. esp_efuse_utility_debug_dump_blocks();
  252. }
  253. void cut_tail_arr(uint8_t *arr, int num_used_bits, size_t count_bits)
  254. {
  255. if ((num_used_bits + count_bits) % 8) {
  256. int start_used_item = (num_used_bits - 1) / 8;
  257. int last_used_item = ((num_used_bits + count_bits) - 1) / 8;
  258. int shift = 0;
  259. int mask = num_used_bits + count_bits;
  260. if (last_used_item == start_used_item) {
  261. shift = (num_used_bits) % 8;
  262. mask = count_bits;
  263. }
  264. arr[last_used_item] &= ((1 << (mask % 8)) - 1) << shift;
  265. }
  266. }
  267. void cut_start_arr(uint8_t *arr, size_t num_used_bits)
  268. {
  269. if (num_used_bits % 8) {
  270. int start_used_item = (num_used_bits - 1) / 8;
  271. arr[start_used_item] &= ~((1 << (num_used_bits % 8)) - 1);
  272. }
  273. }
  274. void get_part_arr(uint8_t *arr_in, uint8_t *arr_out, int num_used_bits, int count_bits)
  275. {
  276. int num_items = esp_efuse_utility_get_number_of_items(num_used_bits + count_bits, 8);
  277. memcpy(arr_out, arr_in, num_items);
  278. memset(arr_out, 0, num_used_bits / 8);
  279. cut_start_arr(arr_out, num_used_bits);
  280. cut_tail_arr(arr_out, num_used_bits, count_bits);
  281. }
  282. void fill_part_arr(uint8_t *arr_in, uint8_t *arr_out, int count_bits)
  283. {
  284. int num_items = esp_efuse_utility_get_number_of_items(count_bits, 8);
  285. memcpy(arr_out, arr_in, num_items);
  286. cut_tail_arr(arr_out, 0, count_bits);
  287. }
  288. // Writes a random array to efuse, then reads and compares it.
  289. void test_blob(const esp_efuse_desc_t* field[], uint8_t *arr_w, uint8_t *arr_r, uint8_t *arr_temp, int arr_size, size_t field_size)
  290. {
  291. ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_w, arr_size, ESP_LOG_INFO);
  292. TEST_ESP_OK(esp_efuse_write_field_blob(field, arr_w, field_size));
  293. memset(arr_r, 0, arr_size);
  294. TEST_ESP_OK(esp_efuse_read_field_blob(field, arr_r, field_size));
  295. ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_r, arr_size, ESP_LOG_INFO);
  296. esp_efuse_utility_debug_dump_blocks();
  297. TEST_ASSERT_TRUE_MESSAGE(memcmp(arr_w, arr_r, arr_size) == 0, "Operation write/read blob is not success");
  298. int count_once = 0;
  299. for (int i = 0; i < arr_size; ++i) {
  300. count_once += __builtin_popcount(arr_w[i]);
  301. }
  302. size_t num_bits_r = 0;
  303. TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
  304. TEST_ASSERT_EQUAL_INT(count_once, num_bits_r);
  305. size_t num_bits_w = field_size - count_once;
  306. if (num_bits_w == 0) {
  307. esp_efuse_utility_erase_virt_blocks();
  308. num_bits_w = field_size;
  309. }
  310. TEST_ESP_OK(esp_efuse_write_field_cnt(field, num_bits_w));
  311. TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
  312. esp_efuse_utility_debug_dump_blocks();
  313. TEST_ASSERT_EQUAL_INT(field_size, num_bits_r);
  314. memset(arr_r, 0, arr_size);
  315. TEST_ESP_OK(esp_efuse_read_field_blob(field, arr_r, field_size));
  316. memset(arr_temp, 0xFF, arr_size);
  317. cut_tail_arr(arr_temp, 0, field_size);
  318. esp_efuse_utility_debug_dump_blocks();
  319. TEST_ASSERT_TRUE_MESSAGE(memcmp(arr_temp, arr_r, arr_size) == 0, "Operation write/read blob is not success");
  320. }
  321. // Records a random number of bits (as "1") in the efuse field, then reads and compares.
  322. void test_cnt_part(const esp_efuse_desc_t* field[], uint8_t *arr_r, int arr_size, size_t field_size)
  323. {
  324. size_t num_bits_r = 0;
  325. TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
  326. TEST_ASSERT_EQUAL_INT(0, num_bits_r);
  327. TEST_ESP_OK(esp_efuse_write_field_cnt(field, field_size));
  328. TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
  329. TEST_ASSERT_EQUAL_INT(field_size, num_bits_r);
  330. esp_efuse_utility_erase_virt_blocks();
  331. int num_bits_summ_r = 0;
  332. int num_bits_w = 0;
  333. while(field_size > num_bits_summ_r) {
  334. num_bits_w = 0;
  335. while(num_bits_w == 0 || (num_bits_summ_r + num_bits_w) > field_size) {
  336. bootloader_random_enable();
  337. bootloader_fill_random(&num_bits_w, 1);
  338. bootloader_random_disable();
  339. num_bits_w = num_bits_w * field_size / 255;
  340. if (num_bits_w != 0 && (num_bits_summ_r + num_bits_w) <= field_size) {
  341. break;
  342. }
  343. }
  344. TEST_ESP_OK(esp_efuse_write_field_cnt(field, num_bits_w));
  345. TEST_ESP_OK(esp_efuse_read_field_cnt(field, &num_bits_r));
  346. num_bits_summ_r += num_bits_w;
  347. TEST_ASSERT_EQUAL_INT(num_bits_summ_r, num_bits_r);
  348. memset(arr_r, 0, arr_size);
  349. TEST_ESP_OK(esp_efuse_read_field_blob(field, arr_r, field_size));
  350. int count_once = 0;
  351. for (int i = 0; i < arr_size; ++i) {
  352. count_once += __builtin_popcount(arr_r[i]);
  353. }
  354. TEST_ASSERT_EQUAL_INT(num_bits_summ_r, count_once);
  355. ESP_LOGI(TAG, "Once bits=%d, step=%d", num_bits_summ_r, num_bits_w);
  356. }
  357. esp_efuse_utility_debug_dump_blocks();
  358. }
  359. // From a random array takes a random number of bits and write to efuse, it repeats until the entire length of the field is written down.
  360. void test_blob_part(const esp_efuse_desc_t* field[], uint8_t *arr_w, uint8_t *arr_r, uint8_t *arr_temp, int arr_size, size_t field_size)
  361. {
  362. esp_efuse_utility_debug_dump_blocks();
  363. int num_bits_summ_r = 0;
  364. int num_bits_w = 0;
  365. memset(arr_w, 0, arr_size);
  366. bootloader_random_enable();
  367. bootloader_fill_random(arr_w, arr_size);
  368. bootloader_random_disable();
  369. ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_w, arr_size, ESP_LOG_INFO);
  370. while(field_size > num_bits_summ_r) {
  371. num_bits_w = 0;
  372. while(num_bits_w == 0 || (num_bits_summ_r + num_bits_w) > field_size) {
  373. bootloader_random_enable();
  374. bootloader_fill_random(&num_bits_w, 1);
  375. bootloader_random_disable();
  376. num_bits_w = num_bits_w * field_size / 255;
  377. if (num_bits_w != 0 && (num_bits_summ_r + num_bits_w) <= field_size) {
  378. break;
  379. }
  380. }
  381. ESP_LOGI(TAG, "Summ bits=%d, step=%d", num_bits_summ_r, num_bits_w);
  382. memset(arr_temp, 0, arr_size);
  383. get_part_arr(arr_w, arr_temp, num_bits_summ_r, num_bits_w);
  384. ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_temp, arr_size, ESP_LOG_INFO);
  385. TEST_ESP_OK(esp_efuse_write_field_blob(field, arr_temp, field_size));
  386. memset(arr_r, 0, arr_size);
  387. TEST_ESP_OK(esp_efuse_read_field_blob(field, arr_r, field_size));
  388. ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_r, arr_size, ESP_LOG_INFO);
  389. esp_efuse_utility_debug_dump_blocks();
  390. num_bits_summ_r += num_bits_w;
  391. memset(arr_temp, 0, arr_size);
  392. fill_part_arr(arr_w, arr_temp, num_bits_summ_r);
  393. ESP_LOG_BUFFER_HEX_LEVEL(TAG, arr_temp, arr_size, ESP_LOG_INFO);
  394. TEST_ASSERT_TRUE_MESSAGE(memcmp(arr_temp, arr_r, arr_size) == 0, "Operation write/read blob is not success");
  395. }
  396. }
  397. void check_efuse_table_test(int cycle)
  398. {
  399. int num_test = 0;
  400. while(1) {
  401. const esp_efuse_desc_t** field;
  402. switch (num_test++) {
  403. case 0: field = ESP_EFUSE_TEST1_LEN_8; break;
  404. case 1: field = ESP_EFUSE_TEST2_LEN_16; break;
  405. case 2: field = ESP_EFUSE_TEST3_LEN_6; break;
  406. case 3: field = ESP_EFUSE_TEST4_LEN_182; break;
  407. case 4: field = ESP_EFUSE_TEST5_LEN_1; break;
  408. case 5: field = ESP_EFUSE_TEST6_LEN_17; break;
  409. default:
  410. return;
  411. break;
  412. }
  413. size_t field_size = esp_efuse_get_field_size(field);
  414. int arr_size = esp_efuse_utility_get_number_of_items(field_size, 8);
  415. uint8_t *arr_w = (uint8_t *) malloc(arr_size);
  416. uint8_t *arr_r = (uint8_t *) malloc(arr_size);
  417. uint8_t *arr_temp = (uint8_t *) malloc(arr_size);
  418. ESP_LOGI(TAG, "Test#%d", num_test);
  419. for (int c = 1; c <= cycle; ++c) {
  420. ESP_LOGI(TAG, "Cycle#%d/%d", c, cycle);
  421. memset(arr_w, 0, arr_size);
  422. bootloader_random_enable();
  423. bootloader_fill_random(arr_w, arr_size);
  424. bootloader_random_disable();
  425. cut_tail_arr(arr_w, 0, field_size);
  426. esp_efuse_utility_erase_virt_blocks();
  427. ESP_LOGI(TAG, "1) blob write/read");
  428. test_blob(field, arr_w, arr_r, arr_temp, arr_size, field_size);
  429. esp_efuse_utility_erase_virt_blocks();
  430. ESP_LOGI(TAG, "2) cnt part write/read");
  431. test_cnt_part(field, arr_r, arr_size, field_size);
  432. esp_efuse_utility_erase_virt_blocks();
  433. ESP_LOGI(TAG, "3) blob part write/read");
  434. test_blob_part(field, arr_w, arr_r, arr_temp, arr_size, field_size);
  435. }
  436. free(arr_temp);
  437. free(arr_r);
  438. free(arr_w);
  439. }
  440. }
  441. TEST_CASE("efuse esp_efuse_table_test", "[efuse]")
  442. {
  443. esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK2);
  444. if (coding_scheme == EFUSE_CODING_SCHEME_NONE) {
  445. check_efuse_table_test(2);
  446. } else {
  447. ESP_LOGI(TAG, "This test is applicable only to the EFUSE_CODING_SCHEME_NONE. Skip this test.");
  448. }
  449. }
  450. TEST_CASE("Test esp_efuse_read_block esp_efuse_write_block functions", "[efuse]")
  451. {
  452. int count_useful_reg = 0;
  453. esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK2);
  454. if (coding_scheme == EFUSE_CODING_SCHEME_NONE) {
  455. printf("EFUSE_CODING_SCHEME_NONE\n");
  456. count_useful_reg = 8;
  457. }
  458. #if CONFIG_IDF_TARGET_ESP32
  459. if (coding_scheme == EFUSE_CODING_SCHEME_3_4) {
  460. printf("EFUSE_CODING_SCHEME_3_4\n");
  461. count_useful_reg = 6;
  462. } else if (coding_scheme == EFUSE_CODING_SCHEME_REPEAT) {
  463. printf("EFUSE_CODING_SCHEME_REPEAT\n");
  464. count_useful_reg = 4;
  465. }
  466. #else
  467. if (coding_scheme == EFUSE_CODING_SCHEME_RS) {
  468. printf("EFUSE_CODING_SCHEME_RS\n");
  469. count_useful_reg = 8;
  470. }
  471. #endif
  472. esp_efuse_utility_reset();
  473. esp_efuse_utility_erase_virt_blocks();
  474. uint8_t src_key[32] = { 0 };
  475. uint8_t dst_key[32] = { 0 };
  476. int offset_in_bits = 0;
  477. for (int i = 0; i < count_useful_reg * 4; ++i) {
  478. src_key[i] = 0xAB + i;
  479. }
  480. TEST_ESP_OK(esp_efuse_write_block(EFUSE_BLK2, src_key, offset_in_bits, count_useful_reg * 32));
  481. TEST_ESP_OK(esp_efuse_read_block(EFUSE_BLK2, dst_key, offset_in_bits, count_useful_reg * 32));
  482. esp_efuse_utility_debug_dump_blocks();
  483. TEST_ASSERT_EQUAL_HEX8_ARRAY(src_key, dst_key, sizeof(src_key));
  484. esp_efuse_utility_erase_virt_blocks();
  485. memset(src_key, 0, sizeof(src_key));
  486. memset(dst_key, 0, sizeof(dst_key));
  487. offset_in_bits = count_useful_reg * 32 / 2;
  488. for (int i = 0; i < count_useful_reg * 4 / 2; ++i) {
  489. src_key[i] = 0xCD + i;
  490. }
  491. TEST_ESP_OK(esp_efuse_write_block(EFUSE_BLK2, src_key, offset_in_bits, count_useful_reg * 32 / 2));
  492. TEST_ESP_OK(esp_efuse_read_block(EFUSE_BLK2, dst_key, offset_in_bits, count_useful_reg * 32 / 2));
  493. esp_efuse_utility_debug_dump_blocks();
  494. TEST_ASSERT_EQUAL_HEX8_ARRAY(src_key, dst_key, count_useful_reg * 4 / 2);
  495. esp_efuse_utility_erase_virt_blocks();
  496. }
  497. TEST_CASE("Test Bits are not empty. Write operation is forbidden", "[efuse]")
  498. {
  499. esp_efuse_utility_update_virt_blocks();
  500. esp_efuse_utility_debug_dump_blocks();
  501. int count_useful_reg = 0;
  502. uint8_t r_buff[32];
  503. int st_offset = -1;
  504. int num_block;
  505. for (num_block = EFUSE_BLK_KEY0; num_block < EFUSE_BLK_KEY_MAX; ++num_block) {
  506. memset(r_buff, 0, sizeof(r_buff));
  507. esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(num_block);
  508. if (coding_scheme == EFUSE_CODING_SCHEME_NONE) {
  509. printf("EFUSE_CODING_SCHEME_NONE. The test is not applicable.\n");
  510. count_useful_reg = 8;
  511. return;
  512. }
  513. #if CONFIG_IDF_TARGET_ESP32
  514. if (coding_scheme == EFUSE_CODING_SCHEME_3_4) {
  515. printf("EFUSE_CODING_SCHEME_3_4\n");
  516. count_useful_reg = 6;
  517. } else if (coding_scheme == EFUSE_CODING_SCHEME_REPEAT) {
  518. printf("EFUSE_CODING_SCHEME_REPEAT\n");
  519. count_useful_reg = 4;
  520. }
  521. #else
  522. if (coding_scheme == EFUSE_CODING_SCHEME_RS) {
  523. printf("EFUSE_CODING_SCHEME_RS\n");
  524. if (num_block == EFUSE_BLK_KEY0) {
  525. count_useful_reg = 6;
  526. } else {
  527. count_useful_reg = 8;
  528. }
  529. }
  530. #endif
  531. TEST_ESP_OK(esp_efuse_read_block(num_block, r_buff, 0, count_useful_reg * 32));
  532. for (int i = 0; i < count_useful_reg * 4; ++i) {
  533. if (r_buff[i] != 0) {
  534. // found used byte
  535. for (int j = 0; j < 8; ++j) {
  536. if ((r_buff[i] & (1 << j)) == 0) {
  537. // found empty bit into this byte
  538. st_offset = i * 8 + j;
  539. printf("Byte = 0x%02x. offset is = %d\n", r_buff[i], st_offset);
  540. break;
  541. }
  542. }
  543. if (st_offset != -1) {
  544. break;
  545. }
  546. }
  547. }
  548. if (st_offset != -1) {
  549. break;
  550. }
  551. }
  552. if (st_offset != -1) {
  553. // write 1 bit to empty place.
  554. uint8_t val = 1;
  555. TEST_ESP_ERR(ESP_ERR_CODING, esp_efuse_write_block(num_block, &val, st_offset, 1));
  556. } else {
  557. printf("Test skipped. It is not applicable, the device has no written bits.\n");
  558. }
  559. }
  560. #ifndef CONFIG_FREERTOS_UNICORE
  561. static const int delay_ms = 2000;
  562. static SemaphoreHandle_t sema;
  563. static void task1(void* arg)
  564. {
  565. TEST_ESP_OK(esp_efuse_batch_write_begin());
  566. ESP_LOGI(TAG, "Start work in batch mode");
  567. xSemaphoreGive(sema);
  568. vTaskDelay((delay_ms + 100) / portTICK_PERIOD_MS);
  569. ESP_LOGI(TAG, "Finish work in batch mode");
  570. TEST_ESP_OK(esp_efuse_batch_write_cancel());
  571. vTaskDelete(NULL);
  572. }
  573. static void task2(void* arg)
  574. {
  575. xSemaphoreTake(sema, portMAX_DELAY);
  576. uint8_t mac[6];
  577. int64_t t1 = esp_timer_get_time();
  578. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, sizeof(mac) * 8));
  579. int64_t t2 = esp_timer_get_time();
  580. int diff_ms = (t2 - t1) / 1000;
  581. TEST_ASSERT_GREATER_THAN(diff_ms, delay_ms);
  582. ESP_LOGI(TAG, "read MAC address: %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  583. xSemaphoreGive(sema);
  584. vTaskDelete(NULL);
  585. }
  586. static void task3(void* arg)
  587. {
  588. xSemaphoreTake(sema, portMAX_DELAY);
  589. size_t test3_len_6 = 2;
  590. int64_t t1 = esp_timer_get_time();
  591. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, test3_len_6));
  592. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_TEST3_LEN_6, &test3_len_6));
  593. int64_t t2 = esp_timer_get_time();
  594. ESP_LOGI(TAG, "write&read test3_len_6: %d", test3_len_6);
  595. int diff_ms = (t2 - t1) / 1000;
  596. TEST_ASSERT_GREATER_THAN(delay_ms, diff_ms);
  597. TEST_ASSERT_EQUAL_INT(2, test3_len_6);
  598. xSemaphoreGive(sema);
  599. vTaskDelete(NULL);
  600. }
  601. TEST_CASE("Batch mode is thread-safe", "[efuse]")
  602. {
  603. // Batch mode blocks work with efuse on other tasks.
  604. esp_efuse_utility_update_virt_blocks();
  605. esp_efuse_utility_debug_dump_blocks();
  606. sema = xSemaphoreCreateBinary();
  607. printf("\n");
  608. xTaskCreatePinnedToCore(task1, "task1", 3072, NULL, UNITY_FREERTOS_PRIORITY - 1, NULL, 0);
  609. xTaskCreatePinnedToCore(task2, "task2", 3072, NULL, UNITY_FREERTOS_PRIORITY - 1, NULL, 1);
  610. vTaskDelay(3000 / portTICK_PERIOD_MS);
  611. xSemaphoreTake(sema, portMAX_DELAY);
  612. esp_efuse_utility_reset();
  613. esp_efuse_utility_erase_virt_blocks();
  614. printf("\n");
  615. xTaskCreatePinnedToCore(task1, "task1", 3072, NULL, UNITY_FREERTOS_PRIORITY - 1, NULL, 0);
  616. xTaskCreatePinnedToCore(task3, "task3", 3072, NULL, UNITY_FREERTOS_PRIORITY - 1, NULL, 1);
  617. vTaskDelay(3000 / portTICK_PERIOD_MS);
  618. xSemaphoreTake(sema, portMAX_DELAY);
  619. printf("\n");
  620. vSemaphoreDelete(sema);
  621. esp_efuse_utility_reset();
  622. esp_efuse_utility_erase_virt_blocks();
  623. }
  624. #endif // #ifndef CONFIG_FREERTOS_UNICORE
  625. static volatile bool cmd_stop_reset_task1;
  626. static void efuse_burn_task(void* arg)
  627. {
  628. SemaphoreHandle_t sema = (SemaphoreHandle_t) arg;
  629. ESP_LOGI(TAG, "Start burn task");
  630. size_t test3_len_6 = 2;
  631. while (!cmd_stop_reset_task1) {
  632. esp_efuse_utility_update_virt_blocks();
  633. esp_efuse_utility_reset();
  634. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_TEST3_LEN_6, test3_len_6));
  635. }
  636. xSemaphoreGive(sema);
  637. ESP_LOGI(TAG, "Stop burn task");
  638. vTaskDelete(NULL);
  639. }
  640. static void efuse_read_task(void* arg)
  641. {
  642. SemaphoreHandle_t sema = (SemaphoreHandle_t) arg;
  643. ESP_LOGI(TAG, "Start read task");
  644. size_t test3_len_6 = 0;
  645. while (!cmd_stop_reset_task1) {
  646. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_TEST3_LEN_6, &test3_len_6, 6));
  647. }
  648. xSemaphoreGive(sema);
  649. ESP_LOGI(TAG, "Stop read task");
  650. vTaskDelete(NULL);
  651. }
  652. TEST_CASE("Check a case when ESP_ERR_DAMAGED_READING occurs and read and burn are not blocked", "[efuse]")
  653. {
  654. cmd_stop_reset_task1 = false;
  655. TaskHandle_t read_task_hdl;
  656. SemaphoreHandle_t sema[2];
  657. sema[0] = xSemaphoreCreateBinary();
  658. sema[1] = xSemaphoreCreateBinary();
  659. esp_efuse_utility_update_virt_blocks();
  660. esp_efuse_utility_debug_dump_blocks();
  661. xTaskCreatePinnedToCore(efuse_burn_task, "efuse_burn_task", 3072, sema[0], 2, NULL, 0);
  662. xTaskCreatePinnedToCore(efuse_read_task, "efuse_read_task", 3072, sema[1], 2, &read_task_hdl, 0);
  663. vTaskDelay(10 / portTICK_PERIOD_MS);
  664. for (unsigned i = 1; i < 30; ++i) {
  665. vTaskPrioritySet(read_task_hdl, 2 + i % 2);
  666. vTaskDelay(10 / portTICK_PERIOD_MS);
  667. }
  668. vTaskDelay(10 / portTICK_PERIOD_MS);
  669. cmd_stop_reset_task1 = true;
  670. vTaskDelay(10 / portTICK_PERIOD_MS);
  671. TEST_ASSERT_EQUAL(pdPASS, xSemaphoreTake(sema[0], 1000 / portTICK_PERIOD_MS));
  672. TEST_ASSERT_EQUAL(pdPASS, xSemaphoreTake(sema[1], 1000 / portTICK_PERIOD_MS));
  673. vSemaphoreDelete(sema[0]);
  674. vSemaphoreDelete(sema[1]);
  675. }
  676. #endif // #ifdef CONFIG_EFUSE_VIRTUAL
  677. #ifndef CONFIG_FREERTOS_UNICORE
  678. static volatile bool cmd_stop_reset_task;
  679. static void reset_task(void* arg)
  680. {
  681. ESP_LOGI(TAG, "Start reset task");
  682. while (!cmd_stop_reset_task) {
  683. esp_efuse_utility_reset();
  684. vTaskDelay(2);
  685. }
  686. vTaskDelete(NULL);
  687. }
  688. TEST_CASE("Check a case when ESP_ERR_DAMAGED_READING occurs during reading efuses", "[efuse]")
  689. {
  690. cmd_stop_reset_task = false;
  691. esp_efuse_utility_update_virt_blocks();
  692. esp_efuse_utility_debug_dump_blocks();
  693. uint8_t mac[6];
  694. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, sizeof(mac) * 8));
  695. ESP_LOGI(TAG, "read MAC address: %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  696. xTaskCreatePinnedToCore(reset_task, "reset_task", 3072, NULL, UNITY_FREERTOS_PRIORITY - 1, NULL, 1);
  697. uint8_t new_mac[6];
  698. for (int i = 0; i < 1000; ++i) {
  699. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &new_mac, sizeof(new_mac) * 8));
  700. TEST_ASSERT_EQUAL_HEX8_ARRAY(mac, new_mac, sizeof(mac));
  701. }
  702. cmd_stop_reset_task = true;
  703. ESP_LOGI(TAG, "read new MAC address: %02x:%02x:%02x:%02x:%02x:%02x", new_mac[0], new_mac[1], new_mac[2], new_mac[3], new_mac[4], new_mac[5]);
  704. vTaskDelay(100 / portTICK_PERIOD_MS);
  705. }
  706. #endif // if not CONFIG_FREERTOS_UNICORE
  707. #ifdef CONFIG_IDF_ENV_FPGA
  708. TEST_CASE("Test a real write (FPGA)", "[efuse]")
  709. {
  710. ESP_LOGI(TAG, "1. Write MAC address");
  711. esp_efuse_utility_debug_dump_blocks();
  712. uint8_t mac[6];
  713. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, sizeof(mac) * 8));
  714. ESP_LOGI(TAG, "MAC: %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  715. uint8_t new_mac[6];
  716. if (mac[0] == 0) {
  717. new_mac[0] = 0x71;
  718. new_mac[1] = 0x62;
  719. new_mac[2] = 0x53;
  720. new_mac[3] = 0x44;
  721. new_mac[4] = 0x35;
  722. new_mac[5] = 0x26;
  723. TEST_ESP_OK(esp_efuse_write_field_blob(ESP_EFUSE_MAC_FACTORY, &new_mac, sizeof(new_mac) * 8));
  724. ESP_LOGI(TAG, "new MAC: %02x:%02x:%02x:%02x:%02x:%02x", new_mac[0], new_mac[1], new_mac[2], new_mac[3], new_mac[4], new_mac[5]);
  725. TEST_ESP_OK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, sizeof(mac) * 8));
  726. TEST_ASSERT_EQUAL_HEX8_ARRAY(new_mac, mac, sizeof(new_mac));
  727. esp_efuse_utility_debug_dump_blocks();
  728. }
  729. ESP_LOGI(TAG, "4. Write SECURE_VERSION");
  730. int max_bits = esp_efuse_get_field_size(ESP_EFUSE_SECURE_VERSION);
  731. size_t read_sec_version;
  732. esp_efuse_utility_debug_dump_blocks();
  733. for (int i = 0; i < max_bits; ++i) {
  734. ESP_LOGI(TAG, "# %d", i);
  735. TEST_ESP_OK(esp_efuse_write_field_cnt(ESP_EFUSE_SECURE_VERSION, 1));
  736. TEST_ESP_OK(esp_efuse_read_field_cnt(ESP_EFUSE_SECURE_VERSION, &read_sec_version));
  737. esp_efuse_utility_debug_dump_blocks();
  738. TEST_ASSERT_EQUAL_INT(i + 1, read_sec_version);
  739. }
  740. }
  741. #endif // CONFIG_IDF_ENV_FPGA
  742. TEST_CASE("Test chip_ver_pkg APIs return the same value", "[efuse]")
  743. {
  744. esp_efuse_utility_update_virt_blocks();
  745. TEST_ASSERT_EQUAL_INT(esp_efuse_get_pkg_ver(), bootloader_common_get_chip_ver_pkg());
  746. }