diff --git a/README.md b/README.md index a95c22f70..c2cc69e4c 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ These icons will be used in the steps below showing common ESP-IDF use cases: 10. Make sure to configure your drivers as mentioned in ESP-IDF [Configure JTAG Interface](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/jtag-debugging/configure-ft2232h-jtag.html) documentation. -11. Before debugging your device, select the device OpenOCD board configuration files by pressing F1 and typing **ESP-IDF: Select OpenOCD Board Configuration**. You can test the connection by clicking status bar icon ![openocd](./media/readme/openocd.png) or pressing F1 and typing **ESP-IDF: OpenOCD Manager**. The output is shown in the menu `View` -> `Output` and choose `ESP-IDF` from the dropdown list. +11. Before debugging your device, if you are using a connected ESP-IDF development board, the OpenOCD configuration will be automatically selected based on your connected board, including the USB location if available (requires OpenOCD version v0.12.0-esp32-20240821 or higher). Otherwise, you can manually select the device OpenOCD board configuration files by pressing F1 and typing **ESP-IDF: Select OpenOCD Board Configuration**. You can test the connection by clicking status bar icon ![openocd](./media/readme/openocd.png) or pressing F1 and typing **ESP-IDF: OpenOCD Manager**. The output is shown in the menu `View` -> `Output` and choose `ESP-IDF` from the dropdown list. > **NOTE:** You can start or stop the OpenOCD in Visual Studio Code using the **ESP-IDF: OpenOCD Manager** command or by clicking the `OpenOCD Server (Running | Stopped)` button in the status bar. @@ -159,7 +159,7 @@ Press F1 or click menu `View` -> `Command Palette...` to show Visual Pick a Workspace Folder - When using a Visual Studio Code workspace with multiple folders, this command allows you to choose which workspace folder to apply this extension’s commands to. + When using a Visual Studio Code workspace with multiple folders, this command allows you to choose which workspace folder to apply this extension's commands to. More information in working with multiple projects. @@ -203,7 +203,7 @@ Press F1 or click menu `View` -> `Command Palette...` to show Visual Flash Your Project - Write binary data to the ESP’s flash chip from your current ESP-IDF project. This command will use either UART, DFU or JTAG based on idf.flashType. + Write binary data to the ESP's flash chip from your current ESP-IDF project. This command will use either UART, DFU or JTAG based on idf.flashType. I F Ctrl E F @@ -272,25 +272,25 @@ Press F1 or click menu `View` -> `Command Palette...` to show Visual Flash Your Project - Write binary data to the ESP’s flash chip from your current ESP-IDF project. This command will use either UART, DFU or JTAG based on idf.flashType + Write binary data to the ESP's flash chip from your current ESP-IDF project. This command will use either UART, DFU or JTAG based on idf.flashType I F Ctrl E F Flash (DFU) Your Project - Write binary data to the ESP’s flash chip from your current ESP-IDF project using DFU. Only for ESP32-S2 and ESP32-S3. + Write binary data to the ESP's flash chip from your current ESP-IDF project using DFU. Only for ESP32-S2 and ESP32-S3. Flash (UART) Your Project - Write binary data to the ESP’s flash chip from your current ESP-IDF project using esptool.py. + Write binary data to the ESP's flash chip from your current ESP-IDF project using esptool.py. Flash (with JTAG) - Write binary data to the ESP’s flash chip from your current ESP-IDF project using OpenOCD JTAG. + Write binary data to the ESP's flash chip from your current ESP-IDF project using OpenOCD JTAG. diff --git a/docs_espressif/en/configureproject.rst b/docs_espressif/en/configureproject.rst index 2eaf99b55..912f9d2bc 100644 --- a/docs_espressif/en/configureproject.rst +++ b/docs_espressif/en/configureproject.rst @@ -7,7 +7,7 @@ Configure Your Project Select an Espressif target (esp32, esp32s2, etc.) by going to ``View`` > ``Command Palette`` and entering ``ESP-IDF: Set Espressif Device Target`` command. -Go to ``View`` > ``Command Palette`` and enter ``ESP-IDF: Select OpenOCD Board Configuration`` to choose the openOCD configuration files for the extension openOCD server. +If you are using a connected ESP-IDF development board, the OpenOCD configuration will be automatically selected based on your connected board. Otherwise, you can manually select the OpenOCD configuration by going to ``View`` > ``Command Palette`` and entering ``ESP-IDF: Select OpenOCD Board Configuration``. .. note:: diff --git a/l10n/bundle.l10n.es.json b/l10n/bundle.l10n.es.json index a3900c46c..1d809cab6 100644 --- a/l10n/bundle.l10n.es.json +++ b/l10n/bundle.l10n.es.json @@ -233,5 +233,7 @@ "Type 'SWITCH' to confirm switching to Release Mode": "Escriba 'SWITCH' para confirmar el cambio al Modo Release", "Please type 'SWITCH' exactly to confirm": "Por favor escriba 'SWITCH' exactamente para confirmar", "Switching to Release Mode cancelled by user": "Cambio al Modo Release cancelado por el usuario", - "User confirmed switching to Release Mode. Proceeding with flash encryption.": "Usuario confirmó el cambio al Modo Release. Procediendo con el cifrado de flash." + "User confirmed switching to Release Mode. Proceeding with flash encryption.": "Usuario confirmó el cambio al Modo Release. Procediendo con el cifrado de flash.", + "Connected ESP-IDF devkit detection is skipped while debugging. You can still select a target manually.": "La detección de devkit ESP-IDF conectados se omite durante la depuración. Aún puede seleccionar un objetivo manualmente.", + "Connected ESP-IDF devkit detection is not available for your {openOCDVersion} OpenOCD version. Required version is {minRequiredVersion} or higher. You can still select a target manually.": "La detección de devkit ESP-IDF conectados no está disponible para su versión de OpenOCD {openOCDVersion}. Se requiere la versión {minRequiredVersion} o superior. Aún puede seleccionar un objetivo manualmente." } diff --git a/l10n/bundle.l10n.pt.json b/l10n/bundle.l10n.pt.json index 117eac11a..4f99c6852 100644 --- a/l10n/bundle.l10n.pt.json +++ b/l10n/bundle.l10n.pt.json @@ -233,5 +233,7 @@ "Type 'SWITCH' to confirm switching to Release Mode": "Digite 'SWITCH' para confirmar a mudança para o Modo de Release", "Please type 'SWITCH' exactly to confirm": "Por favor, digite 'SWITCH' exatamente para confirmar", "Switching to Release Mode cancelled by user": "Mudança para o Modo de Release cancelada pelo usuário", - "User confirmed switching to Release Mode. Proceeding with flash encryption.": "Usuário confirmou a mudança para o Modo de Release. Prosseguindo com a criptografia flash." + "User confirmed switching to Release Mode. Proceeding with flash encryption.": "Usuário confirmou a mudança para o Modo de Release. Prosseguindo com a criptografia flash.", + "Connected ESP-IDF devkit detection is skipped while debugging. You can still select a target manually.": "A detecção de devkit ESP-IDF conectados é ignorada durante a depuração. Você ainda pode selecionar um alvo manualmente.", + "Connected ESP-IDF devkit detection is not available for your {openOCDVersion} OpenOCD version. Required version is {minRequiredVersion} or higher. You can still select a target manually.": "A detecção de devkit ESP-IDF conectados não está disponível para sua versão do OpenOCD {openOCDVersion}. É necessária a versão {minRequiredVersion} ou superior. Você ainda pode selecionar um alvo manualmente." } diff --git a/l10n/bundle.l10n.ru.json b/l10n/bundle.l10n.ru.json index 5945d0d96..aa0c7fb64 100644 --- a/l10n/bundle.l10n.ru.json +++ b/l10n/bundle.l10n.ru.json @@ -233,5 +233,7 @@ "Type 'SWITCH' to confirm switching to Release Mode": "Введите 'SWITCH' для подтверждения переключения в Режим Релиза", "Please type 'SWITCH' exactly to confirm": "Пожалуйста, введите точно 'SWITCH' для подтверждения", "Switching to Release Mode cancelled by user": "Переключение в Режим Релиза отменено пользователем", - "User confirmed switching to Release Mode. Proceeding with flash encryption.": "Пользователь подтвердил переключение в Режим Релиза. Продолжаем шифрование флеш-памяти." + "User confirmed switching to Release Mode. Proceeding with flash encryption.": "Пользователь подтвердил переключение в Режим Релиза. Продолжаем шифрование флеш-памяти.", + "Connected ESP-IDF devkit detection is skipped while debugging. You can still select a target manually.": "Обнаружение подключенных ESP-IDF devkit пропускается во время отладки. Вы все еще можете выбрать цель вручную.", + "Connected ESP-IDF devkit detection is not available for your {openOCDVersion} OpenOCD version. Required version is {minRequiredVersion} or higher. You can still select a target manually.": "Обнаружение подключенных ESP-IDF devkit недоступно для вашей версии OpenOCD {openOCDVersion}. Требуется версия {minRequiredVersion} или выше. Вы все еще можете выбрать цель вручную." } diff --git a/l10n/bundle.l10n.zh-CN.json b/l10n/bundle.l10n.zh-CN.json index 9a5c29d64..79b79d24b 100644 --- a/l10n/bundle.l10n.zh-CN.json +++ b/l10n/bundle.l10n.zh-CN.json @@ -233,5 +233,7 @@ "Type 'SWITCH' to confirm switching to Release Mode": "输入 'SWITCH' 确认切换到发布模式", "Please type 'SWITCH' exactly to confirm": "请准确输入 'SWITCH' 以确认", "Switching to Release Mode cancelled by user": "用户取消了切换到发布模式", - "User confirmed switching to Release Mode. Proceeding with flash encryption.": "用户确认切换到发布模式。继续进行闪存加密。" + "User confirmed switching to Release Mode. Proceeding with flash encryption.": "用户确认切换到发布模式。继续进行闪存加密。", + "Connected ESP-IDF devkit detection is skipped while debugging. You can still select a target manually.": "调试时跳过已连接的 ESP-IDF 开发板检测。您仍可以手动选择目标。", + "Connected ESP-IDF devkit detection is not available for your {openOCDVersion} OpenOCD version. Required version is {minRequiredVersion} or higher. You can still select a target manually.": "您的 OpenOCD 版本 {openOCDVersion} 不支持已连接的 ESP-IDF 开发板检测功能。需要 {minRequiredVersion} 或更高版本。您仍可以手动选择目标。" } diff --git a/src/espIdf/setTarget/DevkitsCommand.ts b/src/espIdf/setTarget/DevkitsCommand.ts new file mode 100644 index 000000000..fd906de5e --- /dev/null +++ b/src/espIdf/setTarget/DevkitsCommand.ts @@ -0,0 +1,174 @@ +/* + * Project: ESP-IDF VSCode Extension + * File Created: Friday, 8th January 2021 5:34:24 pm + * Copyright 2021 Espressif Systems (Shanghai) CO LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as vscode from "vscode"; +import * as fs from "fs" +import { join } from "path"; +import * as idfConf from "../../idfConfiguration"; +import { Logger } from "../../logger/logger"; +import { getVirtualEnvPythonPath } from "../../pythonManager"; +import { OpenOCDManager } from "../openOcd/openOcdManager"; +import { appendIdfAndToolsToPath, execChildProcess } from "../../utils"; +import { OutputChannel } from "../../logger/outputChannel"; +import { getOpenOcdScripts } from "../openOcd/boardConfiguration"; + +export class DevkitsCommand { + private workspaceRoot: vscode.Uri; + + constructor(workspaceRoot: vscode.Uri) { + this.workspaceRoot = workspaceRoot; + } + + public async runDevkitsScript(): Promise { + try { + const workspaceFolder = vscode.workspace.getWorkspaceFolder( + this.workspaceRoot + ); + if (!workspaceFolder) { + throw new Error("No workspace folder found"); + } + + const toolsPath = idfConf.readParameter( + "idf.toolsPath", + this.workspaceRoot + ) as string; + const openOCDManager = OpenOCDManager.init(); + const openOCDVersion = await openOCDManager.version(); + + if (!toolsPath || !openOCDVersion) { + throw new Error("Could not get toolsPath or OpenOCD version"); + } + + const scriptPath = join( + toolsPath, + "tools", + "openocd-esp32", + openOCDVersion, + "openocd-esp32", + "share", + "openocd", + "espressif", + "tools", + "esp_detect_config.py" + ); + + const openOcdScriptsPath = await getOpenOcdScripts(this.workspaceRoot); + if (!openOcdScriptsPath) { + throw new Error("Could not get OpenOCD scripts path"); + } + + const espConfigPath = join(openOcdScriptsPath, "esp-config.json"); + + const notificationMode = idfConf.readParameter( + "idf.notificationMode", + this.workspaceRoot + ) as string; + + const ProgressLocation = + notificationMode === idfConf.NotificationMode.All || + notificationMode === idfConf.NotificationMode.Notifications + ? vscode.ProgressLocation.Notification + : vscode.ProgressLocation.Window; + + const pythonBinPath = await getVirtualEnvPythonPath(this.workspaceRoot); + const modifiedEnv = await appendIdfAndToolsToPath(this.workspaceRoot); + + OutputChannel.init(); + OutputChannel.appendLine( + "Running ESP Detect Config...", + "ESP Detect Config" + ); + OutputChannel.show(); + + return await vscode.window.withProgress( + { + cancellable: true, + location: ProgressLocation, + title: "ESP-IDF: Running ESP Detect Config", + }, + async ( + progress: vscode.Progress<{ message: string; increment: number }>, + cancelToken: vscode.CancellationToken + ) => { + try { + const result = await execChildProcess( + pythonBinPath, + [scriptPath, "--esp-config", espConfigPath], + this.workspaceRoot.fsPath, + OutputChannel.init(), + { env: modifiedEnv }, + cancelToken + ); + + OutputChannel.appendLine(result, "ESP Detect Config"); + OutputChannel.show(); + vscode.window.showInformationMessage("ESP Detect Config completed"); + return result; + } catch (error) { + const msg = error.message + ? error.message + : "Error running ESP Detect Config"; + Logger.errorNotify(msg, error, "DevkitsCommand"); + OutputChannel.appendLine(msg, "ESP Detect Config"); + OutputChannel.show(); + throw error; + } + } + ); + } catch (error) { + const msg = error.message + ? error.message + : "Error running ESP Detect Config"; + Logger.errorNotify(msg, error, "DevkitsCommand"); + OutputChannel.appendLine(msg, "ESP Detect Config"); + OutputChannel.show(); + } + } + + public async getScriptPath(): Promise { + try { + const toolsPath = idfConf.readParameter( + "idf.toolsPath", + this.workspaceRoot + ) as string; + const openOCDManager = OpenOCDManager.init(); + const openOCDVersion = await openOCDManager.version(); + + if (!toolsPath || !openOCDVersion) { + return null; + } + + const scriptPath = join( + toolsPath, + "tools", + "openocd-esp32", + openOCDVersion, + "openocd-esp32", + "share", + "openocd", + "espressif", + "tools", + "esp_detect_config.py" + ); + + return fs.existsSync(scriptPath) ? scriptPath : null; + } catch (error) { + return null; + } + } +} diff --git a/src/espIdf/setTarget/index.ts b/src/espIdf/setTarget/index.ts index 3a6106d5f..22e6d83bf 100644 --- a/src/espIdf/setTarget/index.ts +++ b/src/espIdf/setTarget/index.ts @@ -23,6 +23,8 @@ import { WorkspaceFolder, window, l10n, + QuickPickItemKind, + debug, } from "vscode"; import { NotificationMode, @@ -35,6 +37,7 @@ import { selectOpenOcdConfigFiles } from "../openOcd/boardConfiguration"; import { getTargetsFromEspIdf } from "./getTargets"; import { setTargetInIDF } from "./setTargetInIdf"; import { updateCurrentProfileIdfTarget } from "../../project-conf"; +import { DevkitsCommand } from "./DevkitsCommand"; export let isSettingIDFTarget = false; @@ -70,14 +73,107 @@ export async function setIdfTarget( async (progress: Progress<{ message: string; increment: number }>) => { try { const targetsFromIdf = await getTargetsFromEspIdf(workspaceFolder.uri); - const selectedTarget = await window.showQuickPick(targetsFromIdf); + let connectedBoards: any[] = []; + + const isDebugging = debug.activeDebugSession !== undefined; + + if (!isDebugging) { + try { + const devkitsCmd = new DevkitsCommand(workspaceFolder.uri); + const scriptPath = await devkitsCmd.getScriptPath(); + + if (scriptPath) { + const devkitsOutput = await devkitsCmd.runDevkitsScript(); + if (devkitsOutput) { + const parsed = JSON.parse(devkitsOutput); + if (parsed && Array.isArray(parsed.boards)) { + connectedBoards = parsed.boards.map((b: any) => ({ + label: b.name, + target: b.target, + description: b.description, + detail: `Status: CONNECTED${ + b.location ? ` Location: ${b.location}` : "" + }`, + isConnected: true, + boardInfo: b, + })); + } + } + } else { + Logger.info( + "Devkit detection script not available. A default list of targets will be displayed instead." + ); + } + } catch (e) { + Logger.info( + "No connected boards detected or error running DevkitsCommand: " + + (e && e.message ? e.message : e) + ); + } + } else { + Logger.info( + "Connected ESP-IDF devkit detection is skipped while debugging. You can still select a target manually." + ); + } + let quickPickItems: any[] = []; + if (connectedBoards.length > 0) { + quickPickItems = [ + ...connectedBoards, + { kind: QuickPickItemKind.Separator, label: "Default Boards" }, + ...targetsFromIdf.map((t) => ({ + label: t.label, + target: t.target, + description: t.isPreview ? "Preview target" : undefined, + isConnected: false, + })), + ]; + } else { + quickPickItems = targetsFromIdf.map((t) => ({ + label: t.label, + target: t.target, + description: t.isPreview ? "Preview target" : undefined, + isConnected: false, + })); + } + const selectedTarget = await window.showQuickPick(quickPickItems, { + placeHolder: placeHolderMsg, + }); if (!selectedTarget) { return; } - await selectOpenOcdConfigFiles( - workspaceFolder.uri, - selectedTarget.target - ); + if (selectedTarget.isConnected && selectedTarget.boardInfo) { + // Directly set OpenOCD configs for connected board + const configFiles = selectedTarget.boardInfo.config_files || []; + await writeParameter( + "idf.openOcdConfigs", + configFiles, + configurationTarget, + workspaceFolder.uri + ); + // Store USB location if available + if (selectedTarget.boardInfo.location) { + const customExtraVars = readParameter( + "idf.customExtraVars", + workspaceFolder + ) as { [key: string]: string }; + const location = selectedTarget.boardInfo.location.replace( + "usb://", + "" + ); + customExtraVars["OPENOCD_USB_ADAPTER_LOCATION"] = location; + await writeParameter( + "idf.customExtraVars", + customExtraVars, + configurationTarget, + workspaceFolder.uri + ); + } + } else { + await selectOpenOcdConfigFiles( + workspaceFolder.uri, + selectedTarget.target + ); + } await setTargetInIDF(workspaceFolder, selectedTarget); const customExtraVars = readParameter( diff --git a/src/espIdf/setTarget/setTargetInIdf.ts b/src/espIdf/setTarget/setTargetInIdf.ts index 603020003..14662d6b0 100644 --- a/src/espIdf/setTarget/setTargetInIdf.ts +++ b/src/espIdf/setTarget/setTargetInIdf.ts @@ -75,6 +75,7 @@ export async function setTargetInIDF( setTargetArgs.push("set-target", selectedTarget.target); const pythonBinPath = await getVirtualEnvPythonPath(workspaceFolder.uri); + OutputChannel.appendLine("Running IDF Set Target action", "Set Target"); const setTargetResult = await spawn(pythonBinPath, setTargetArgs, { cwd: workspaceFolder.uri.fsPath, env: modifiedEnv,