efuse_main.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /* efuse example
  2. This example code is in the Public Domain (or CC0 licensed, at your option.)
  3. Unless required by applicable law or agreed to in writing, this
  4. software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  5. CONDITIONS OF ANY KIND, either express or implied.
  6. */
  7. #include <stdio.h>
  8. #include "freertos/FreeRTOS.h"
  9. #include "freertos/task.h"
  10. #include "esp_err.h"
  11. #include "esp_log.h"
  12. #include "esp_efuse.h"
  13. #include "esp_efuse_table.h"
  14. #include "esp_efuse_custom_table.h"
  15. #include "sdkconfig.h"
  16. static const char* TAG = "example";
  17. typedef struct {
  18. uint8_t module_version; /*!< Module version: length 8 bits */
  19. uint8_t device_role; /*!< Device role: length 3 bits */
  20. uint8_t setting_1; /*!< Setting 1: length 6 bits */
  21. uint8_t setting_2; /*!< Setting 2: length 5 bits */
  22. size_t custom_secure_version; /*!< Custom secure version: length 16 bits */
  23. uint16_t reserv; /*!< Reserv */
  24. } device_desc_t;
  25. static void print_device_desc(device_desc_t *desc)
  26. {
  27. ESP_LOGI(TAG, "module_version = %d", desc->module_version);
  28. if (desc->device_role == 0) {
  29. ESP_LOGI(TAG, "device_role = None");
  30. } else if (desc->device_role == 1) {
  31. ESP_LOGI(TAG, "device_role = Master");
  32. } else if (desc->device_role == 2) {
  33. ESP_LOGI(TAG, "device_role = Slave");
  34. } else {
  35. ESP_LOGI(TAG, "device_role = Not supported");
  36. }
  37. ESP_LOGI(TAG, "setting_1 = %d", desc->setting_1);
  38. ESP_LOGI(TAG, "setting_2 = %d", desc->setting_2);
  39. ESP_LOGI(TAG, "custom_secure_version = %d", desc->custom_secure_version);
  40. }
  41. static void read_device_desc_efuse_fields(device_desc_t *desc)
  42. {
  43. ESP_ERROR_CHECK(esp_efuse_read_field_blob(ESP_EFUSE_MODULE_VERSION, &desc->module_version, 8));
  44. ESP_ERROR_CHECK(esp_efuse_read_field_blob(ESP_EFUSE_DEVICE_ROLE, &desc->device_role, 3));
  45. ESP_ERROR_CHECK(esp_efuse_read_field_blob(ESP_EFUSE_SETTING_1, &desc->setting_1, 6));
  46. ESP_ERROR_CHECK(esp_efuse_read_field_blob(ESP_EFUSE_SETTING_2, &desc->setting_2, 5));
  47. ESP_ERROR_CHECK(esp_efuse_read_field_cnt(ESP_EFUSE_CUSTOM_SECURE_VERSION, &desc->custom_secure_version));
  48. print_device_desc(desc);
  49. }
  50. static void read_efuse_fields(device_desc_t *desc)
  51. {
  52. ESP_LOGI(TAG, "read efuse fields");
  53. uint8_t mac[6];
  54. ESP_ERROR_CHECK(esp_efuse_read_field_blob(ESP_EFUSE_MAC_FACTORY, &mac, sizeof(mac) * 8));
  55. ESP_LOGI(TAG, "1. read MAC address: %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  56. size_t secure_version = 0;
  57. ESP_ERROR_CHECK(esp_efuse_read_field_cnt(ESP_EFUSE_SECURE_VERSION, &secure_version));
  58. ESP_LOGI(TAG, "2. read secure_version: %d", secure_version);
  59. ESP_LOGI(TAG, "3. read custom fields");
  60. read_device_desc_efuse_fields(desc);
  61. }
  62. static void write_efuse_fields(device_desc_t *desc, esp_efuse_coding_scheme_t coding_scheme)
  63. {
  64. #ifdef CONFIG_EFUSE_VIRTUAL
  65. #if CONFIG_IDF_TARGET_ESP32
  66. const esp_efuse_coding_scheme_t coding_scheme_for_batch_mode = EFUSE_CODING_SCHEME_3_4;
  67. #else
  68. const esp_efuse_coding_scheme_t coding_scheme_for_batch_mode = EFUSE_CODING_SCHEME_RS;
  69. #endif
  70. ESP_LOGI(TAG, "write custom efuse fields");
  71. if (coding_scheme == coding_scheme_for_batch_mode) {
  72. ESP_LOGI(TAG, "In the case of 3/4 or RS coding scheme, you cannot write efuse fields separately");
  73. ESP_LOGI(TAG, "You should use the batch mode of writing fields for this");
  74. ESP_ERROR_CHECK(esp_efuse_batch_write_begin());
  75. }
  76. ESP_ERROR_CHECK(esp_efuse_write_field_blob(ESP_EFUSE_MODULE_VERSION, &desc->module_version, 8));
  77. ESP_ERROR_CHECK(esp_efuse_write_field_blob(ESP_EFUSE_DEVICE_ROLE, &desc->device_role, 3));
  78. ESP_ERROR_CHECK(esp_efuse_write_field_blob(ESP_EFUSE_SETTING_1, &desc->setting_1, 6));
  79. ESP_ERROR_CHECK(esp_efuse_write_field_blob(ESP_EFUSE_SETTING_2, &desc->setting_2, 5));
  80. ESP_ERROR_CHECK(esp_efuse_write_field_cnt(ESP_EFUSE_CUSTOM_SECURE_VERSION, desc->custom_secure_version));
  81. if (coding_scheme == coding_scheme_for_batch_mode) {
  82. ESP_ERROR_CHECK(esp_efuse_batch_write_commit());
  83. }
  84. #endif // CONFIG_EFUSE_VIRTUAL
  85. }
  86. static esp_efuse_coding_scheme_t get_coding_scheme(void)
  87. {
  88. // The coding scheme is used for EFUSE_BLK1, EFUSE_BLK2 and EFUSE_BLK3.
  89. // We use EFUSE_BLK3 (custom block) to verify it.
  90. esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK3);
  91. if (coding_scheme == EFUSE_CODING_SCHEME_NONE) {
  92. ESP_LOGI(TAG, "Coding Scheme NONE");
  93. #if CONFIG_IDF_TARGET_ESP32
  94. } else if (coding_scheme == EFUSE_CODING_SCHEME_3_4) {
  95. ESP_LOGI(TAG, "Coding Scheme 3/4");
  96. } else {
  97. ESP_LOGI(TAG, "Coding Scheme REPEAT");
  98. }
  99. #else
  100. } else if (coding_scheme == EFUSE_CODING_SCHEME_RS) {
  101. ESP_LOGI(TAG, "Coding Scheme RS (Reed-Solomon coding)");
  102. }
  103. #endif
  104. return coding_scheme;
  105. }
  106. void app_main(void)
  107. {
  108. esp_efuse_coding_scheme_t coding_scheme = get_coding_scheme();
  109. device_desc_t device_desc = { 0 };
  110. read_efuse_fields(&device_desc);
  111. ESP_LOGW(TAG, "This example does not burn any efuse in reality only virtually");
  112. #ifdef CONFIG_EFUSE_VIRTUAL
  113. ESP_LOGW(TAG, "Write operations in efuse fields are performed virtually");
  114. if (device_desc.device_role == 0) {
  115. device_desc.module_version = 1;
  116. device_desc.device_role = 2;
  117. device_desc.setting_1 = 3;
  118. device_desc.setting_2 = 4;
  119. device_desc.custom_secure_version = 5;
  120. write_efuse_fields(&device_desc, coding_scheme);
  121. read_device_desc_efuse_fields(&device_desc);
  122. }
  123. #else
  124. ESP_LOGW(TAG, "The part of the code that writes efuse fields is disabled");
  125. #endif
  126. ESP_LOGI(TAG, "Done");
  127. }