From eefca330a966c6c005c41722c6d4a9bba0a57e11 Mon Sep 17 00:00:00 2001 From: Brett Regnier Date: Wed, 28 Jan 2026 11:49:51 -0700 Subject: [PATCH 1/2] added serial command to burn efuse --- firmware/net/core/CMakeLists.txt | 4 +- firmware/net/core/inc/efuse_burner.hh | 3 ++ firmware/net/core/src/efuse_burner.cc | 44 +++++++++++++++++++ firmware/net/core/src/net.cc | 21 +++++++-- firmware/shared_inc/net_mgmt_link.h | 3 +- software/hactar-cli/monitor/monitor.py | 23 +++++----- .../hactar-cli/utility/hactar_commands.py | 1 + 7 files changed, 83 insertions(+), 16 deletions(-) create mode 100644 firmware/net/core/inc/efuse_burner.hh create mode 100644 firmware/net/core/src/efuse_burner.cc diff --git a/firmware/net/core/CMakeLists.txt b/firmware/net/core/CMakeLists.txt index f660b7bc..71c07586 100644 --- a/firmware/net/core/CMakeLists.txt +++ b/firmware/net/core/CMakeLists.txt @@ -1,4 +1,4 @@ -set(SOURCE ./src/net.cc ./src/peripherals.cc) +set(SOURCE ./src/net.cc ./src/peripherals.cc ./src/efuse_burner.cc) #idf_component_register(SRCS ${SOURCE} # INCLUDE_DIRS inc ../../shared_inc/ @@ -6,4 +6,4 @@ set(SOURCE ./src/net.cc ./src/peripherals.cc) idf_component_register(SRCS ${SOURCE} INCLUDE_DIRS inc ../../shared_inc/ - REQUIRES driver serial logger quicr storage wifi net_manager nlohmann_json pthread) + REQUIRES driver serial logger quicr storage wifi net_manager nlohmann_json pthread efuse) diff --git a/firmware/net/core/inc/efuse_burner.hh b/firmware/net/core/inc/efuse_burner.hh new file mode 100644 index 00000000..578683fe --- /dev/null +++ b/firmware/net/core/inc/efuse_burner.hh @@ -0,0 +1,3 @@ +#pragma once + +bool BurnDisableUSBJTagEFuse(); diff --git a/firmware/net/core/src/efuse_burner.cc b/firmware/net/core/src/efuse_burner.cc new file mode 100644 index 00000000..795b39df --- /dev/null +++ b/firmware/net/core/src/efuse_burner.cc @@ -0,0 +1,44 @@ +#include "efuse_burner.hh" +#include "esp_efuse.h" +#include "esp_efuse_table.h" +#include "esp_err.h" +#include "logger.hh" + +bool BurnDisableUSBJTagEFuse() +{ + const bool is_set = esp_efuse_read_field_bit(ESP_EFUSE_DIS_USB_JTAG); + + if (is_set) + { + NET_LOG_INFO("Efuse for DIS_USB_JTAG is already burned"); + return true; + } + // TODO check efuse and skip if done + NET_LOG_INFO("Starting efuse burning process to disable usb jtag debugger"); + + esp_err_t err = esp_efuse_batch_write_begin(); + if (err != ESP_OK) + { + NET_LOG_ERROR("Failed to start batch write %s", esp_err_to_name(err)); + return false; + } + + err = esp_efuse_write_field_bit(ESP_EFUSE_DIS_USB_JTAG); + if (err != ESP_OK) + { + NET_LOG_ERROR("Failed to write efuse field %s", esp_err_to_name(err)); + esp_efuse_batch_write_cancel(); + return false; + } + + err = esp_efuse_batch_write_commit(); + if (err != ESP_OK) + { + NET_LOG_ERROR("Failed to commit efuse changes %s", esp_err_to_name(err)); + return false; + } + + NET_LOG_INFO("Successfully burned efuse to disable usb jtag and enable extern jtag debugging"); + + return true; +} diff --git a/firmware/net/core/src/net.cc b/firmware/net/core/src/net.cc index 1407b3e0..50d7180e 100644 --- a/firmware/net/core/src/net.cc +++ b/firmware/net/core/src/net.cc @@ -4,12 +4,14 @@ #include "driver/gpio.h" #include "driver/ledc.h" #include "driver/uart.h" +#include "efuse_burner.hh" #include "esp_event.h" #include "esp_heap_caps.h" #include "esp_log.h" #include "esp_mac.h" #include "esp_pthread.h" #include "freertos/FreeRTOS.h" +#include "freertos/projdefs.h" #include "freertos/queue.h" #include "freertos/task.h" #include "logger.hh" @@ -455,6 +457,19 @@ static void MgmtLinkPacketTask(void* args) mgmt_layer.ReplyAck(); break; } + case Configuration::Burn_Disable_USB_JTag_Efuse: + { + const bool res = BurnDisableUSBJTagEFuse(); + if (res) + { + mgmt_layer.ReplyAck(); + } + else + { + mgmt_layer.ReplyNack(); + } + break; + } default: { NET_LOG_ERROR("Unknown packet type from mgmt"); @@ -604,13 +619,13 @@ extern "C" void app_main(void) IntitializeLEDs(); InitializeUIReadyISR(GpioIsrRisingHandler); + NET_LOG_INFO("Starting Net Main"); + CreateMgmtLinkPacketTask(); mgmt_layer.BeginEventTask(); CreateUILinkPacketTask(); - NET_LOG_INFO("Starting Net Main"); - wifi.Begin(); wifi.Connect("quicr.io", "noPassword"); @@ -904,4 +919,4 @@ void RestartMoqSession(std::shared_ptr& session, { StopMoqSession(session, readers, writers); moq_session.reset(new moq::Session(config, readers, writers)); -} \ No newline at end of file +} diff --git a/firmware/shared_inc/net_mgmt_link.h b/firmware/shared_inc/net_mgmt_link.h index d3a0f202..f068cd05 100644 --- a/firmware/shared_inc/net_mgmt_link.h +++ b/firmware/shared_inc/net_mgmt_link.h @@ -16,4 +16,5 @@ enum Configuration Disable_Loopback, Enable_Loopback, Set_Frontline_Config, -}; \ No newline at end of file + Burn_Disable_USB_JTag_Efuse, +}; diff --git a/software/hactar-cli/monitor/monitor.py b/software/hactar-cli/monitor/monitor.py index 1771e22e..5719eec9 100644 --- a/software/hactar-cli/monitor/monitor.py +++ b/software/hactar-cli/monitor/monitor.py @@ -13,14 +13,9 @@ readline = None import serial -from hactar_commands import ( - bypass_map, - command_map, - hactar_command_completer, - hactar_command_print_matches, - net_command_map, - ui_command_map, -) +from hactar_commands import (bypass_map, command_map, hactar_command_completer, + hactar_command_print_matches, net_command_map, + ui_command_map) from hactar_scanning import HactarScanning, ResetDevice, SelectHactarPort @@ -49,6 +44,10 @@ def GetLine(self): while self.uart.in_waiting: char = self.uart.read() if char == b"\x82": + # print("Got an ack!") + return "" + if char == b"\x82": + # print("Got a nack!") return "" data += char @@ -121,11 +120,15 @@ def ProcessBypassCommand(self, split): command_id = chip_commands[command]["id"] if len(split) - 2 < num_params: - print(f"[ERROR] Not enough parameters for command{command} expected {num_params} got {len(split)-2}") + print( + f"[ERROR] Not enough parameters for command{command} expected {num_params} got {len(split)-2}" + ) return if len(split) - 2 > num_params: - print(f"[ERROR] Too many parameters for command {command} expected {num_params} got {len(split)-2}") + print( + f"[ERROR] Too many parameters for command {command} expected {num_params} got {len(split)-2}" + ) return Header_Bytes = 5 # 1 type, 4 length diff --git a/software/hactar-cli/utility/hactar_commands.py b/software/hactar-cli/utility/hactar_commands.py index 0ae82724..56d66dea 100644 --- a/software/hactar-cli/utility/hactar_commands.py +++ b/software/hactar-cli/utility/hactar_commands.py @@ -55,6 +55,7 @@ "disable_loopback": {"id": 11, "num_params": 0}, "enable_loopback": {"id": 12, "num_params": 0}, "set_fl_config": {"id": 13, "num_params": 2}, + "burn_efuse": {"id": 14, "num_params": 0}, } ST_Ack = 0x79 From fcda70c441b9c490008541cce38d095e224812a0 Mon Sep 17 00:00:00 2001 From: Brett Regnier Date: Thu, 29 Jan 2026 09:04:19 -0700 Subject: [PATCH 2/2] address pr review --- firmware/net/core/src/efuse_burner.cc | 6 ++---- software/hactar-cli/monitor/monitor.py | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/firmware/net/core/src/efuse_burner.cc b/firmware/net/core/src/efuse_burner.cc index 795b39df..38148632 100644 --- a/firmware/net/core/src/efuse_burner.cc +++ b/firmware/net/core/src/efuse_burner.cc @@ -6,14 +6,12 @@ bool BurnDisableUSBJTagEFuse() { - const bool is_set = esp_efuse_read_field_bit(ESP_EFUSE_DIS_USB_JTAG); - - if (is_set) + if (esp_efuse_read_field_bit(ESP_EFUSE_DIS_USB_JTAG)) { NET_LOG_INFO("Efuse for DIS_USB_JTAG is already burned"); return true; } - // TODO check efuse and skip if done + NET_LOG_INFO("Starting efuse burning process to disable usb jtag debugger"); esp_err_t err = esp_efuse_batch_write_begin(); diff --git a/software/hactar-cli/monitor/monitor.py b/software/hactar-cli/monitor/monitor.py index 5719eec9..1d10906a 100644 --- a/software/hactar-cli/monitor/monitor.py +++ b/software/hactar-cli/monitor/monitor.py @@ -46,7 +46,7 @@ def GetLine(self): if char == b"\x82": # print("Got an ack!") return "" - if char == b"\x82": + if char == b"\x83": # print("Got a nack!") return ""