diff --git a/Documentation/platforms/arm/ht32f491x3/boards/esk32/ht32f491x3-starter-kit.jpg b/Documentation/platforms/arm/ht32f491x3/boards/esk32/ht32f491x3-starter-kit.jpg new file mode 100644 index 00000000000..9422d707cc5 Binary files /dev/null and b/Documentation/platforms/arm/ht32f491x3/boards/esk32/ht32f491x3-starter-kit.jpg differ diff --git a/Documentation/platforms/arm/ht32f491x3/boards/esk32/index.rst b/Documentation/platforms/arm/ht32f491x3/boards/esk32/index.rst new file mode 100644 index 00000000000..fbf7f2fa1f6 --- /dev/null +++ b/Documentation/platforms/arm/ht32f491x3/boards/esk32/index.rst @@ -0,0 +1,177 @@ +================== +ESK32 (HT32F49163) +================== + +.. tags:: arch:arm, chip:ht32f491x3, chip:ht32f49163, vendor:holtek + +The ESK32 is a development board based on the Holtek HT32F49163 MCU. +The current NuttX port targets the HT32F49163 device used on the +HT32F49163 development kit and focuses on a working serial-console NSH +configuration with basic board bring-up. + +For additional hardware details, refer to Holtek's +`HT32F491x3 Starter Kit User Guide `_. + +.. figure:: ht32f491x3-starter-kit.jpg + :align: center + :alt: HT32F491x3 Starter Kit + + HT32F491x3 Starter Kit board photo + +Features +======== + +The current port provides: + +* Holtek HT32F49163 MCU from the HT32F491x3 family +* ARM Cortex-M4 core with FPU support +* Boot and clock initialization for the ESK32 8 MHz external crystal +* System clock configured to 150 MHz +* USART1 serial console at 115200 8N1 +* ``/bin`` mounted through ``binfs`` +* ``/proc`` mounted through ``procfs`` +* User LED registration through ``/dev/userleds`` +* Basic internal GPIO helpers used by the console and LED support + +The default ``esk32:nsh`` configuration also enables these built-in +applications: + +* ``hello`` +* ``ostest`` +* ``dumpstack`` +* ``leds`` + +Buttons and LEDs +================ + +Board LEDs +---------- + +Three user LEDs from the development kit are currently mapped by the board +port. They are active-low and are exposed through the standard NuttX +``USERLED`` interface and the ``/dev/userleds`` device. + +===== =========== ========== +LED Port/Pin Notes +===== =========== ========== +LED2 PD13 Active-low +LED3 PD14 Active-low +LED4 PD15 Active-low +===== =========== ========== + +The generic ``leds`` example from ``nuttx-apps`` can be used to validate the +LED interface. + +Board Buttons +------------- + +No button is currently exposed by the board port. + +Pin Mapping +=========== + +The current port uses the following MCU pins: + +===== ========== ========== +Pin Signal Notes +===== ========== ========== +PA9 USART1_TX Default serial console TX +PA10 USART1_RX Default serial console RX +PD13 LED2 User LED, active-low +PD14 LED3 User LED, active-low +PD15 LED4 User LED, active-low +===== ========== ========== + +Flashing +======== + +The board directory includes a helper script for flashing through Holtek's +Windows OpenOCD package from a WSL-based development environment: + +.. code-block:: console + + $ ./boards/arm/ht32f491x3/esk32/tools/flash.sh + +The script expects: + +* ``nuttx.bin`` already generated in the ``nuttx`` directory +* Holtek xPack OpenOCD installed under + ``C:\Program Files (x86)\Holtek HT32 Series\HT32-IDE\xPack\xpack-openocd-0.11.0-4`` +* an HT32-Link compatible debug connection +* Holtek xPack OpenOCD can be installed together with the HT32 IDE, available + from Holtek's website: `Holtek Downloads `_ + +Useful options: + +.. code-block:: console + + $ ./boards/arm/ht32f491x3/esk32/tools/flash.sh --dry-run + $ ./boards/arm/ht32f491x3/esk32/tools/flash.sh --device HT32F49163_100LQFP + $ ./boards/arm/ht32f491x3/esk32/tools/flash.sh --openocd-root /mnt/c/path/to/openocd + +Testing Notes +============= + +The following commands are useful for validating the current port: + +.. code-block:: console + + nsh> hello + nsh> ostest + nsh> dumpstack + nsh> leds + +When ``leds`` is executed, the example opens ``/dev/userleds`` and cycles +through the LED bitmasks supported by the board. + +Current Limitations +=================== + +The current port is still intentionally small. In particular: + +* only the ``nsh`` board configuration is maintained +* only USART1 routing is described by the board port +* LEDs are supported, but board buttons are not yet implemented +* internal GPIO helpers exist, but there is not yet a board-level ``/dev/gpio`` + test interface in this port + +Configurations +============== + +nsh +--- + +This is the currently maintained configuration for the board. It provides a +serial console with the NuttShell and mounts ``/bin`` and ``/proc`` during +board bring-up. + +Configure and build it from the ``nuttx`` directory: + +.. code-block:: console + + $ ./tools/configure.sh -l esk32:nsh + $ make -j + +After boot, a typical prompt looks like: + +.. code-block:: console + + NuttShell (NSH) NuttX-12.x.x + nsh> ls / + /: + bin/ + dev/ + proc/ + +And the built-in applications can be listed with: + +.. code-block:: console + + nsh> ls /bin + dd + dumpstack + hello + leds + nsh + ostest + sh diff --git a/Documentation/platforms/arm/ht32f491x3/index.rst b/Documentation/platforms/arm/ht32f491x3/index.rst new file mode 100644 index 00000000000..c468b5d7e68 --- /dev/null +++ b/Documentation/platforms/arm/ht32f491x3/index.rst @@ -0,0 +1,14 @@ +=============== +Holtek HT32F491 +=============== + +The HT32F491x3 family is based on the ARM Cortex-M4 core. + +Supported Boards +================ + +.. toctree:: + :glob: + :maxdepth: 1 + + boards/*/* diff --git a/arch/arm/include/ht32f491x3/chip.h b/arch/arm/include/ht32f491x3/chip.h index bc843a01c33..8b3393a1cf7 100644 --- a/arch/arm/include/ht32f491x3/chip.h +++ b/arch/arm/include/ht32f491x3/chip.h @@ -56,10 +56,10 @@ #define HT32_NGPIO 6 #define HT32_HICK_FREQUENCY 8000000 -#define HT32_HICK48_FREQUENCY 48000000 +#define HT32_HICK48_FREQUENCY 48000000 #define HT32_HEXT_MIN_FREQUENCY 4000000 -#define HT32_HEXT_MAX_FREQUENCY 25000000 -#define HT32_PLL_MAX_FREQUENCY 150000000 +#define HT32_HEXT_MAX_FREQUENCY 25000000 +#define HT32_PLL_MAX_FREQUENCY 150000000 #define HT32_SYSCLK_FREQUENCY CONFIG_HT32F491X3_SYSCLK_FREQUENCY #define HT32_HCLK_FREQUENCY HT32_SYSCLK_FREQUENCY diff --git a/boards/arm/ht32f491x3/esk32/tools/flash.ps1 b/boards/arm/ht32f491x3/esk32/tools/flash.ps1 new file mode 100644 index 00000000000..39f15246bfe --- /dev/null +++ b/boards/arm/ht32f491x3/esk32/tools/flash.ps1 @@ -0,0 +1,239 @@ +############################################################################ +# boards/arm/ht32f491x3/esk32/tools/flash.ps1 +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you 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. +# +############################################################################ + +param( + [Parameter(ValueFromRemainingArguments = $true)] + [string[]]$RemainingArgs +) + +$ErrorActionPreference = "Stop" +Set-StrictMode -Version 2 + +$ScriptDir = $PSScriptRoot +$TopDir = [System.IO.Path]::GetFullPath((Join-Path $ScriptDir "..\..\..\..\..")) + +$DefaultBin = Join-Path $TopDir "nuttx.bin" +$WindowsSetup = "Windows 10 Pro" +$PowerShellSetup = "Windows PowerShell 5.1 or newer" +$HT32IDEVersion = "HT32-IDE 1.0.6 (Build Date: 2025/12/04)" +$HT32IDERoot = "C:\Program Files (x86)\Holtek HT32 Series\HT32-IDE" +$OpenOCDPackage = "xPack OpenOCD 0.11.0-4" +$OpenOCDRoot = Join-Path $HT32IDERoot "xPack\xpack-openocd-0.11.0-4" +$OpenOCDExe = Join-Path $OpenOCDRoot "bin\openocd.exe" +$ScriptsDir = Join-Path $OpenOCDRoot "scripts" +$FlashLoader = Join-Path $OpenOCDRoot "FlashLoader\HT32F491x3_256.HLM" +$DeviceName = "HT32F49163_100LQFP" +$FlashBase = "0x08000000" +$FlashEnd = "0x0803FFFF" +$SRAMBase = "0x20000000" +$WorkAreaSize = "0xC000" +$BinPath = $DefaultBin +$DryRun = $false +$ProgName = $MyInvocation.MyCommand.Name + +function Get-AbsolutePath { + param( + [string]$Path + ) + + if ([System.IO.Path]::IsPathRooted($Path)) { + return [System.IO.Path]::GetFullPath($Path) + } + + return [System.IO.Path]::GetFullPath((Join-Path (Get-Location) $Path)) +} + +function Format-CommandArgument { + param( + [string]$Argument + ) + + if ($Argument -match '[\s"]') { + return '"' + ($Argument -replace '"', '\"') + '"' + } + + return $Argument +} + +function Show-Assumptions { + Write-Host "############################################################################" + Write-Host "# Assumptions:" + Write-Host "#" + Write-Host "# - $WindowsSetup" + Write-Host "# - $PowerShellSetup" + Write-Host "# - This is the native Windows backend; use flash.py from the same" + Write-Host "# directory for automatic backend selection, or run this script directly" + Write-Host "# - $HT32IDEVersion installed at:" + Write-Host "# $HT32IDERoot" + Write-Host "# - $OpenOCDPackage available at:" + Write-Host "# $OpenOCDRoot" + Write-Host "# - Holtek HT-Link probe using interface/htlink.cfg" + Write-Host "# - ESK32 board with $DeviceName and FlashLoader\HT32F491x3_256.HLM" + Write-Host "#" + Write-Host "# Update this script if any of the above are not true." + Write-Host "#" + Write-Host "############################################################################" + Write-Host "" +} + +function Show-Usage { + Write-Host "Usage: $ProgName [options]" + Write-Host "" + Write-Host "Options:" + Write-Host " --bin PATH Binary to flash. Default: $DefaultBin" + Write-Host " --device NAME Holtek expected device name. Default: $DeviceName" + Write-Host " --openocd-root DIR Holtek xPack OpenOCD root." + Write-Host " --dry-run Print the OpenOCD command without executing it." + Write-Host " --help Show this help." + Write-Host "" + Write-Host "Examples:" + Write-Host " .\$ProgName" + Write-Host " .\$ProgName --dry-run" + Write-Host " .\$ProgName --device HT32F49163_100LQFP" +} + +function Fail { + param( + [string]$Message, + [switch]$ShowUsage + ) + + [Console]::Error.WriteLine($Message) + + if ($ShowUsage) { + Show-Usage + } + + exit 1 +} + +Show-Assumptions + +for ($i = 0; $i -lt $RemainingArgs.Count; $i++) { + switch ($RemainingArgs[$i]) { + "--bin" { + if ($i + 1 -ge $RemainingArgs.Count) { + Fail "Missing value for --bin" -ShowUsage + } + + $i++ + $BinPath = Get-AbsolutePath $RemainingArgs[$i] + } + "--device" { + if ($i + 1 -ge $RemainingArgs.Count) { + Fail "Missing value for --device" -ShowUsage + } + + $i++ + $DeviceName = $RemainingArgs[$i] + } + "--openocd-root" { + if ($i + 1 -ge $RemainingArgs.Count) { + Fail "Missing value for --openocd-root" -ShowUsage + } + + $i++ + $OpenOCDRoot = Get-AbsolutePath $RemainingArgs[$i] + $OpenOCDExe = Join-Path $OpenOCDRoot "bin\openocd.exe" + $ScriptsDir = Join-Path $OpenOCDRoot "scripts" + $FlashLoader = Join-Path $OpenOCDRoot "FlashLoader\HT32F491x3_256.HLM" + } + "--dry-run" { + $DryRun = $true + } + "--help" { + Show-Usage + exit 0 + } + "-h" { + Show-Usage + exit 0 + } + default { + Fail "Unknown argument: $($RemainingArgs[$i])" -ShowUsage + } + } +} + +if (-not $DryRun) { + if (-not (Test-Path -Path $BinPath -PathType Leaf)) { + Fail "Binary not found: $BinPath" + } + + if (-not (Test-Path -Path $OpenOCDExe -PathType Leaf)) { + Fail "OpenOCD executable not found: $OpenOCDExe" + } + + if (-not (Test-Path -Path $FlashLoader -PathType Leaf)) { + Fail "Flash loader not found: $FlashLoader" + } +} + +$OpenOCDArgs = @( + "-s" + $ScriptsDir + "-c" + "hlm_SRAM $SRAMBase $WorkAreaSize" + "-c" + "hlm_loader {$FlashLoader} $FlashBase $FlashEnd" + "-c" + "ht_flags erase_sector" + "-c" + "set WORKAREASIZE $WorkAreaSize" + "-f" + "interface/htlink.cfg" + "-f" + "target/HLM491x3.cfg" + "-c" + "set_expected_name $DeviceName" + "-c" + "program $BinPath verify reset exit $FlashBase" +) + +$CommandParts = @($OpenOCDExe) + $OpenOCDArgs +$CommandText = ($CommandParts | ForEach-Object { Format-CommandArgument $_ }) -join " " + +Write-Host ("TOPDIR : {0}" -f $TopDir) +Write-Host ("Binary : {0}" -f $BinPath) +Write-Host ("Device : {0}" -f $DeviceName) +Write-Host ("OpenOCD : {0}" -f $OpenOCDExe) +Write-Host ("Flash loader: {0}" -f $FlashLoader) + +if ($DryRun) { + if (-not (Test-Path -Path $BinPath -PathType Leaf)) { + Write-Host "Warning : binary not found yet" + } + + if (-not (Test-Path -Path $OpenOCDExe -PathType Leaf)) { + Write-Host "Warning : OpenOCD executable not found" + } + + if (-not (Test-Path -Path $FlashLoader -PathType Leaf)) { + Write-Host "Warning : flash loader not found" + } + + Write-Host ("Command : {0}" -f $CommandText) + exit 0 +} + +& $OpenOCDExe @OpenOCDArgs +exit $LASTEXITCODE diff --git a/boards/arm/ht32f491x3/esk32/tools/flash.py b/boards/arm/ht32f491x3/esk32/tools/flash.py new file mode 100755 index 00000000000..74ae8a6a462 --- /dev/null +++ b/boards/arm/ht32f491x3/esk32/tools/flash.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python3 +############################################################################ +# boards/arm/ht32f491x3/esk32/tools/flash.py +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you 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. +# +############################################################################ + +# Wrapper that dispatches to flash.sh in WSL and flash.ps1 on Windows. + +import os +import platform +import shutil +import subprocess +import sys +from pathlib import Path + +SCRIPT_DIR = Path(__file__).resolve().parent + + +def is_windows_host(): + system = platform.system().lower() + return os.name == "nt" or system.startswith("msys") or system.startswith("cygwin") + + +def is_wsl(): + if "WSL_INTEROP" in os.environ or "WSL_DISTRO_NAME" in os.environ: + return True + + release = platform.release().lower() + version = platform.version().lower() + return "microsoft" in release or "microsoft" in version + + +def build_command(argv): + if is_windows_host(): + powershell = shutil.which("powershell.exe") or shutil.which("pwsh.exe") + if powershell is None: + raise RuntimeError("Unable to find powershell.exe or pwsh.exe in PATH.") + + backend = SCRIPT_DIR / "flash.ps1" + return [powershell, "-ExecutionPolicy", "Bypass", "-File", str(backend), *argv] + + if sys.platform.startswith("linux"): + if not is_wsl(): + raise RuntimeError( + "Unsupported host: this wrapper supports Windows native and WSL." + ) + + bash = shutil.which("bash") + if bash is None: + raise RuntimeError("Unable to find bash in PATH.") + + backend = SCRIPT_DIR / "flash.sh" + return [bash, str(backend), *argv] + + raise RuntimeError( + "Unsupported host: this wrapper supports Windows native and WSL." + ) + + +def main(argv): + try: + cmd = build_command(argv) + completed = subprocess.run(cmd, check=False) + return completed.returncode + except RuntimeError as err: + print(err, file=sys.stderr) + return 1 + except OSError as err: + print(f"Failed to start backend script: {err}", file=sys.stderr) + return 1 + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) diff --git a/boards/arm/ht32f491x3/esk32/tools/flash.sh b/boards/arm/ht32f491x3/esk32/tools/flash.sh index 25d3635deb1..eeff2de93d8 100755 --- a/boards/arm/ht32f491x3/esk32/tools/flash.sh +++ b/boards/arm/ht32f491x3/esk32/tools/flash.sh @@ -27,7 +27,11 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" TOPDIR="$(cd "${SCRIPT_DIR}/../../../../.." && pwd)" DEFAULT_BIN="${TOPDIR}/nuttx.bin" -OPENOCD_ROOT="/mnt/c/Program Files (x86)/Holtek HT32 Series/HT32-IDE/xPack/xpack-openocd-0.11.0-4" +WINDOWS_SETUP="Windows 10 Pro with WSL2" +HT32_IDE_VERSION="HT32-IDE 1.0.6 (Build Date: 2025/12/04)" +HT32_IDE_ROOT="/mnt/c/Program Files (x86)/Holtek HT32 Series/HT32-IDE" +OPENOCD_PACKAGE="xPack OpenOCD 0.11.0-4" +OPENOCD_ROOT="${HT32_IDE_ROOT}/xPack/xpack-openocd-0.11.0-4" OPENOCD_EXE="${OPENOCD_ROOT}/bin/openocd.exe" SCRIPTS_DIR="${OPENOCD_ROOT}/scripts" FLASH_LOADER="${OPENOCD_ROOT}/FlashLoader/HT32F491x3_256.HLM" @@ -39,6 +43,28 @@ WORKAREA_SIZE="0xC000" BIN_PATH="${DEFAULT_BIN}" DRY_RUN=0 +print_assumptions() { + cat < 0)); do case "$1" in --bin)