diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index a39451f..c9ac3b3 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -269,6 +269,33 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { }); addItem(deleteFootageBtn); + // Panda flashing button + auto flashPandaBtn = new ButtonControl(tr("Flash Panda"), tr("FLASH"), "Use this button to troubleshoot and update the Panda device's firmware."); + connect(flashPandaBtn, &ButtonControl::clicked, [this]() { + if (!ConfirmationDialog::confirm(tr("Are you sure you want to flash the Panda?"), tr("Flash"), this)) return; + QProcess process; + // Get Panda type + SubMaster &sm = *(uiState()->sm); + auto pandaStates = sm["pandaStates"].getPandaStates(); + // Choose recovery script based on Panda type + if (pandaStates.size() != 0) { + auto pandaType = pandaStates[0].getPandaType(); + bool isRedPanda = (pandaType == cereal::PandaState::PandaType::RED_PANDA || + pandaType == cereal::PandaState::PandaType::RED_PANDA_V2); + QString recoveryScript = isRedPanda ? "./recover.sh" : "./recover.py"; + // Run recovery script and flash Panda + process.setWorkingDirectory("/data/openpilot/panda/board"); + process.start("/bin/sh", QStringList{"-c", recoveryScript}); + process.waitForFinished(); + } + // Run the killall script as a redundancy + process.setWorkingDirectory("/data/openpilot/panda"); + process.start("/bin/sh", QStringList{"-c", "pkill -f boardd; PYTHONPATH=.. python -c \"from panda import Panda; Panda().flash()\""}); + process.waitForFinished(); + Hardware::reboot(); + }); + addItem(flashPandaBtn); + QObject::connect(uiState(), &UIState::offroadTransition, [=](bool offroad) { for (auto btn : findChildren()) { btn->setEnabled(offroad);