Added RA GPIO Output

This commit is contained in:
Kevin Thomas
2025-10-05 08:30:01 -07:00
parent 1b05159721
commit 6218389092
35 changed files with 2592 additions and 160 deletions

View File

@@ -1,5 +1,2 @@
.idea
_deps
cmake-*
build
.DS_Store
!.vscode/*

View File

@@ -1,18 +1,22 @@
{
"configurations": [
{
"name": "Pico",
"includePath": [
"${workspaceFolder}/**",
"${env:PICO_SDK_PATH}/**"
],
"defines": [],
"compilerPath": "${env:PICO_INSTALL_PATH}/gcc-arm-none-eabi/bin/arm-none-eabi-gcc.exe",
"cStandard": "c11",
"cppStandard": "c++11",
"intelliSenseMode": "linux-gcc-arm",
"configurationProvider": "ms-vscode.cmake-tools"
}
],
"version": 4
"configurations": [
{
"name": "Pico",
"includePath": [
"${workspaceFolder}/**",
"${userHome}/.pico-sdk/sdk/2.2.0/**"
],
"forcedInclude": [
"${userHome}/.pico-sdk/sdk/2.2.0/src/common/pico_base_headers/include/pico.h",
"${workspaceFolder}/build/generated/pico_base/pico/config_autogen.h"
],
"defines": [],
"compilerPath": "${userHome}/.pico-sdk/toolchain/14_2_Rel1/bin/arm-none-eabi-gcc.exe",
"compileCommands": "${workspaceFolder}/build/compile_commands.json",
"cStandard": "c17",
"cppStandard": "c++14",
"intelliSenseMode": "linux-gcc-arm"
}
],
"version": 4
}

View File

@@ -0,0 +1,15 @@
[
{
"name": "Pico",
"compilers": {
"C": "${command:raspberry-pi-pico.getCompilerPath}",
"CXX": "${command:raspberry-pi-pico.getCxxCompilerPath}"
},
"environmentVariables": {
"PATH": "${command:raspberry-pi-pico.getEnvPath};${env:PATH}"
},
"cmakeSettings": {
"Python3_EXECUTABLE": "${command:raspberry-pi-pico.getPythonPath}"
}
}
]

View File

@@ -1,9 +1,9 @@
{
"recommendations": [
"marus25.cortex-debug",
"ms-vscode.cmake-tools",
"ms-vscode.cpptools",
"ms-vscode.cpptools-extension-pack",
"ms-vscode.vscode-serial-monitor"
]
}
"recommendations": [
"marus25.cortex-debug",
"ms-vscode.cpptools",
"ms-vscode.cpptools-extension-pack",
"ms-vscode.vscode-serial-monitor",
"raspberry-pi.raspberry-pi-pico"
]
}

View File

@@ -1,58 +1,50 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Pico Debug (Cortex-Debug)",
"cwd": "${workspaceFolder}",
"executable": "${command:cmake.launchTargetPath}",
"request": "launch",
"type": "cortex-debug",
"servertype": "openocd",
"gdbPath": "arm-none-eabi-gdb",
"device": "RP2040",
"configFiles": [
"interface/cmsis-dap.cfg",
"target/rp2040.cfg"
],
"svdFile": "${env:PICO_SDK_PATH}/src/rp2040/hardware_regs/rp2040.svd",
"runToEntryPoint": "main",
"openOCDLaunchCommands": [
"adapter speed 1000"
]
},
{
"name": "Pico Debug (Cortex-Debug with external OpenOCD)",
"cwd": "${workspaceFolder}",
"executable": "${command:cmake.launchTargetPath}",
"request": "launch",
"type": "cortex-debug",
"servertype": "external",
"gdbTarget": "localhost:3333",
"gdbPath": "arm-none-eabi-gdb",
"device": "RP2040",
"svdFile": "${env:PICO_SDK_PATH}/src/rp2040/hardware_regs/rp2040.svd",
"runToEntryPoint": "main"
},
{
"name": "Pico Debug (C++ Debugger)",
"type": "cppdbg",
"request": "launch",
"cwd": "${workspaceFolder}",
"program": "${command:cmake.launchTargetPath}",
"MIMode": "gdb",
"miDebuggerPath": "arm-none-eabi-gdb",
"miDebuggerServerAddress": "localhost:3333",
"debugServerPath": "openocd",
"debugServerArgs": "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 1000\"",
"serverStarted": "Listening on port .* for gdb connections",
"filterStderr": true,
"stopAtEntry": true,
"hardwareBreakpoints": {
"require": true,
"limit": 4
},
"preLaunchTask": "Flash",
"svdPath": "${env:PICO_SDK_PATH}/src/rp2040/hardware_regs/rp2040.svd"
}
]
"version": "0.2.0",
"configurations": [
{
"name": "Pico Debug (Cortex-Debug)",
"cwd": "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts",
"executable": "${command:raspberry-pi-pico.launchTargetPath}",
"request": "launch",
"type": "cortex-debug",
"servertype": "openocd",
"serverpath": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
"gdbPath": "${command:raspberry-pi-pico.getGDBPath}",
"device": "${command:raspberry-pi-pico.getChipUppercase}",
"configFiles": [
"interface/cmsis-dap.cfg",
"target/${command:raspberry-pi-pico.getTarget}.cfg"
],
"svdFile": "${userHome}/.pico-sdk/sdk/2.2.0/src/${command:raspberry-pi-pico.getChip}/hardware_regs/${command:raspberry-pi-pico.getChipUppercase}.svd",
"runToEntryPoint": "main",
// Fix for no_flash binaries, where monitor reset halt doesn't do what is expected
// Also works fine for flash binaries
"overrideLaunchCommands": [
"monitor reset init",
"load \"${command:raspberry-pi-pico.launchTargetPath}\""
],
"openOCDLaunchCommands": [
"adapter speed 5000"
]
},
{
"name": "Pico Debug (Cortex-Debug with external OpenOCD)",
"cwd": "${workspaceRoot}",
"executable": "${command:raspberry-pi-pico.launchTargetPath}",
"request": "launch",
"type": "cortex-debug",
"servertype": "external",
"gdbTarget": "localhost:3333",
"gdbPath": "${command:raspberry-pi-pico.getGDBPath}",
"device": "${command:raspberry-pi-pico.getChipUppercase}",
"svdFile": "${userHome}/.pico-sdk/sdk/2.2.0/src/${command:raspberry-pi-pico.getChip}/hardware_regs/${command:raspberry-pi-pico.getChipUppercase}.svd",
"runToEntryPoint": "main",
// Fix for no_flash binaries, where monitor reset halt doesn't do what is expected
// Also works fine for flash binaries
"overrideLaunchCommands": [
"monitor reset init",
"load \"${command:raspberry-pi-pico.launchTargetPath}\""
]
},
]
}

View File

@@ -1,30 +1,40 @@
{
// These settings tweaks to the cmake plugin will ensure
// that you debug using cortex-debug instead of trying to launch
// a Pico binary on the host
"cmake.statusbar.advanced": {
"debug": {
"visibility": "hidden"
"cmake.showSystemKits": false,
"cmake.options.statusBarVisibility": "hidden",
"cmake.options.advanced": {
"build": {
"statusBarVisibility": "hidden"
},
"launch": {
"visibility": "hidden"
"statusBarVisibility": "hidden"
},
"build": {
"visibility": "hidden"
},
"buildTarget": {
"visibility": "hidden"
"debug": {
"statusBarVisibility": "hidden"
}
},
"cmake.buildBeforeRun": true,
"cmake.configureOnOpen": true,
"cmake.configureSettings": {
"CMAKE_MODULE_PATH": "${env:PICO_INSTALL_PATH}/pico-sdk-tools"
},
"cmake.configureOnEdit": false,
"cmake.automaticReconfigure": false,
"cmake.configureOnOpen": false,
"cmake.generator": "Ninja",
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools",
"C_Cpp.errorSquiggles": "enabled",
"files.associations": {
"stdlib.h": "c"
}
"cmake.cmakePath": "${userHome}/.pico-sdk/cmake/v3.31.5/bin/cmake",
"C_Cpp.debugShortcut": false,
"terminal.integrated.env.windows": {
"PICO_SDK_PATH": "${env:USERPROFILE}/.pico-sdk/sdk/2.2.0",
"PICO_TOOLCHAIN_PATH": "${env:USERPROFILE}/.pico-sdk/toolchain/14_2_Rel1",
"Path": "${env:USERPROFILE}/.pico-sdk/toolchain/14_2_Rel1/bin;${env:USERPROFILE}/.pico-sdk/picotool/2.2.0/picotool;${env:USERPROFILE}/.pico-sdk/cmake/v3.31.5/bin;${env:USERPROFILE}/.pico-sdk/ninja/v1.12.1;${env:PATH}"
},
"terminal.integrated.env.osx": {
"PICO_SDK_PATH": "${env:HOME}/.pico-sdk/sdk/2.2.0",
"PICO_TOOLCHAIN_PATH": "${env:HOME}/.pico-sdk/toolchain/14_2_Rel1",
"PATH": "${env:HOME}/.pico-sdk/toolchain/14_2_Rel1/bin:${env:HOME}/.pico-sdk/picotool/2.2.0/picotool:${env:HOME}/.pico-sdk/cmake/v3.31.5/bin:${env:HOME}/.pico-sdk/ninja/v1.12.1:${env:PATH}"
},
"terminal.integrated.env.linux": {
"PICO_SDK_PATH": "${env:HOME}/.pico-sdk/sdk/2.2.0",
"PICO_TOOLCHAIN_PATH": "${env:HOME}/.pico-sdk/toolchain/14_2_Rel1",
"PATH": "${env:HOME}/.pico-sdk/toolchain/14_2_Rel1/bin:${env:HOME}/.pico-sdk/picotool/2.2.0/picotool:${env:HOME}/.pico-sdk/cmake/v3.31.5/bin:${env:HOME}/.pico-sdk/ninja/v1.12.1:${env:PATH}"
},
"raspberry-pi-pico.cmakeAutoConfigure": true,
"raspberry-pi-pico.useCmakeTools": false,
"raspberry-pi-pico.cmakePath": "${HOME}/.pico-sdk/cmake/v3.31.5/bin/cmake",
"raspberry-pi-pico.ninjaPath": "${HOME}/.pico-sdk/ninja/v1.12.1/ninja"
}

View File

@@ -1,29 +1,102 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Flash",
"type": "shell",
"command": "openocd",
"args": [
"-f",
"interface/cmsis-dap.cfg",
"-f",
"target/rp2040.cfg",
"-c",
"adapter speed 1000; program {${command:cmake.launchTargetPath}} verify reset exit"
],
"problemMatcher": []
},
{
"label": "Build",
"type": "cmake",
"command": "build",
"problemMatcher": "$gcc",
"group": {
"kind": "build",
"isDefault": true
}
}
]
"version": "2.0.0",
"tasks": [
{
"label": "Compile Project",
"type": "process",
"isBuildCommand": true,
"command": "${userHome}/.pico-sdk/ninja/v1.12.1/ninja",
"args": ["-C", "${workspaceFolder}/build"],
"group": "build",
"presentation": {
"reveal": "always",
"panel": "dedicated"
},
"problemMatcher": "$gcc",
"windows": {
"command": "${env:USERPROFILE}/.pico-sdk/ninja/v1.12.1/ninja.exe"
}
},
{
"label": "Run Project",
"type": "process",
"command": "${env:HOME}/.pico-sdk/picotool/2.2.0/picotool/picotool",
"args": [
"load",
"${command:raspberry-pi-pico.launchTargetPath}",
"-fx"
],
"presentation": {
"reveal": "always",
"panel": "dedicated"
},
"problemMatcher": [],
"windows": {
"command": "${env:USERPROFILE}/.pico-sdk/picotool/2.2.0/picotool/picotool.exe"
}
},
{
"label": "Flash",
"type": "process",
"command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
"args": [
"-s",
"${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts",
"-f",
"interface/cmsis-dap.cfg",
"-f",
"target/${command:raspberry-pi-pico.getTarget}.cfg",
"-c",
"adapter speed 5000; program \"${command:raspberry-pi-pico.launchTargetPath}\" verify reset exit"
],
"problemMatcher": [],
"windows": {
"command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
}
},
{
"label": "Rescue Reset",
"type": "process",
"command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
"args": [
"-s",
"${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts",
"-f",
"interface/cmsis-dap.cfg",
"-f",
"target/${command:raspberry-pi-pico.getChip}-rescue.cfg",
"-c",
"adapter speed 5000; reset halt; exit"
],
"problemMatcher": [],
"windows": {
"command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
}
},
{
"label": "Risc-V Reset (RP2350)",
"type": "process",
"command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
"args": [
"-s",
"${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts",
"-c",
"set USE_CORE { rv0 rv1 cm0 cm1 }",
"-f",
"interface/cmsis-dap.cfg",
"-f",
"target/rp2350.cfg",
"-c",
"adapter speed 5000; init;",
"-c",
"write_memory 0x40120158 8 { 0x3 }; echo [format \"Info : ARCHSEL 0x%02x\" [read_memory 0x40120158 8 1]];",
"-c",
"reset halt; targets rp2350.rv0; echo [format \"Info : ARCHSEL_STATUS 0x%02x\" [read_memory 0x4012015C 8 1]]; exit"
],
"problemMatcher": [],
"windows": {
"command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
}
}
]
}

View File

@@ -1,21 +1,57 @@
# Generated Cmake Pico project file
cmake_minimum_required(VERSION 3.13)
include(pico_sdk_import.cmake)
project(0x000e_floating-point-data-type C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Initialise pico_sdk from installed location
# (note this can come from environment, CMake cache etc)
# == DO NOT EDIT THE FOLLOWING LINES for the Raspberry Pi Pico VS Code Extension to work ==
if(WIN32)
set(USERHOME $ENV{USERPROFILE})
else()
set(USERHOME $ENV{HOME})
endif()
set(sdkVersion 2.2.0)
set(toolchainVersion 14_2_Rel1)
set(picotoolVersion 2.2.0)
set(picoVscode ${USERHOME}/.pico-sdk/cmake/pico-vscode.cmake)
if (EXISTS ${picoVscode})
include(${picoVscode})
endif()
# ====================================================================================
set(PICO_BOARD pico2 CACHE STRING "Board type")
# Pull in Raspberry Pi Pico SDK (must be before project)
include(pico_sdk_import.cmake)
project(0x000e_floating-point-data-type C CXX ASM)
# Initialise the Raspberry Pi Pico SDK
pico_sdk_init()
add_executable(0x000e_floating-point-data-type
main.c
)
# Add executable. Default name is the project name, version 0.1
pico_enable_stdio_usb(0x000e_floating-point-data-type 1)
add_executable(0x000e_floating-point-data-type 0x000e_floating-point-data-type.c )
pico_set_program_name(0x000e_floating-point-data-type "0x000e_floating-point-data-type")
pico_set_program_version(0x000e_floating-point-data-type "0.1")
# Modify the below lines to enable/disable output over UART/USB
pico_enable_stdio_uart(0x000e_floating-point-data-type 1)
pico_enable_stdio_usb(0x000e_floating-point-data-type 0)
# Add the standard library to the build
target_link_libraries(0x000e_floating-point-data-type
pico_stdlib)
# Add the standard include files to the build
target_include_directories(0x000e_floating-point-data-type PRIVATE
${CMAKE_CURRENT_LIST_DIR}
)
pico_add_extra_outputs(0x000e_floating-point-data-type)
target_link_libraries(0x000e_floating-point-data-type
pico_stdlib
)

View File

@@ -3,6 +3,28 @@
# This can be dropped into an external project to help locate this SDK
# It should be include()ed prior to project()
# Copyright 2020 (c) 2020 Raspberry Pi (Trading) Ltd.
#
# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
# following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
# disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH))
set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})
message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')")
@@ -18,9 +40,20 @@ if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_P
message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')")
endif ()
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_TAG} AND (NOT PICO_SDK_FETCH_FROM_GIT_TAG))
set(PICO_SDK_FETCH_FROM_GIT_TAG $ENV{PICO_SDK_FETCH_FROM_GIT_TAG})
message("Using PICO_SDK_FETCH_FROM_GIT_TAG from environment ('${PICO_SDK_FETCH_FROM_GIT_TAG}')")
endif ()
if (PICO_SDK_FETCH_FROM_GIT AND NOT PICO_SDK_FETCH_FROM_GIT_TAG)
set(PICO_SDK_FETCH_FROM_GIT_TAG "master")
message("Using master as default value for PICO_SDK_FETCH_FROM_GIT_TAG")
endif()
set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK")
set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable")
set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK")
set(PICO_SDK_FETCH_FROM_GIT_TAG "${PICO_SDK_FETCH_FROM_GIT_TAG}" CACHE FILEPATH "release tag for SDK")
if (NOT PICO_SDK_PATH)
if (PICO_SDK_FETCH_FROM_GIT)
@@ -29,25 +62,40 @@ if (NOT PICO_SDK_PATH)
if (PICO_SDK_FETCH_FROM_GIT_PATH)
get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}")
endif ()
# GIT_SUBMODULES_RECURSE was added in 3.17
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0")
FetchContent_Declare(
pico_sdk
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
GIT_TAG master
GIT_SUBMODULES_RECURSE FALSE
)
else ()
FetchContent_Declare(
pico_sdk
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
GIT_TAG master
)
endif ()
FetchContent_Declare(
pico_sdk
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
GIT_TAG ${PICO_SDK_FETCH_FROM_GIT_TAG}
)
if (NOT pico_sdk)
message("Downloading Raspberry Pi Pico SDK")
FetchContent_Populate(pico_sdk)
# GIT_SUBMODULES_RECURSE was added in 3.17
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0")
FetchContent_Populate(
pico_sdk
QUIET
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
GIT_TAG ${PICO_SDK_FETCH_FROM_GIT_TAG}
GIT_SUBMODULES_RECURSE FALSE
SOURCE_DIR ${FETCHCONTENT_BASE_DIR}/pico_sdk-src
BINARY_DIR ${FETCHCONTENT_BASE_DIR}/pico_sdk-build
SUBBUILD_DIR ${FETCHCONTENT_BASE_DIR}/pico_sdk-subbuild
)
else ()
FetchContent_Populate(
pico_sdk
QUIET
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
GIT_TAG ${PICO_SDK_FETCH_FROM_GIT_TAG}
SOURCE_DIR ${FETCHCONTENT_BASE_DIR}/pico_sdk-src
BINARY_DIR ${FETCHCONTENT_BASE_DIR}/pico_sdk-build
SUBBUILD_DIR ${FETCHCONTENT_BASE_DIR}/pico_sdk-subbuild
)
endif ()
set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR})
endif ()
set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE})

View File

@@ -0,0 +1,605 @@
# RP2350 GPIO Coprocessor Blink - Detailed Documentation
## Overview
This is a **bare-metal assembly program** for the **Raspberry Pi RP2350** microcontroller that demonstrates the use of the **ARM Cortex-M33 coprocessor interface** to control GPIO pins. Unlike traditional GPIO control using direct memory-mapped register writes, this version uses the RP2350's **hardware GPIO coprocessor (CP0)** with **MCRR (Move to Coprocessor from two ARM Registers)** instructions.
The program blinks an LED connected to **GPIO16** with a 500ms on/off cycle using the specialized coprocessor instructions for high-performance GPIO operations.
---
## What Makes This Special?
### Traditional GPIO Control vs Coprocessor Control
**Traditional Method (Direct Register Access):**
```assembly
LDR R0, =SIO_BASE ; Load SIO base address
LDR R1, =GPIO16_BIT ; Load GPIO bit mask
STR R1, [R0, #GPIO_OUT_SET] ; Write to memory-mapped register
```
**Coprocessor Method (This Implementation):**
```assembly
MOVS R4, #16 ; GPIO pin number
MOVS R5, #1 ; Value to write
MCRR p0, #4, R4, R5, c0 ; Single coprocessor instruction
```
### Advantages of the Coprocessor Approach:
1. **Faster execution** - Single instruction instead of multiple memory operations
2. **More atomic** - Less chance of race conditions
3. **Hardware-accelerated** - Direct hardware interface
4. **Cleaner code** - No need to manage bit masks and base addresses
5. **RP2350-specific** - Takes advantage of advanced features
---
## Hardware Requirements
- **RP2350-based board** (e.g., Raspberry Pi Pico 2)
- **LED** connected to **GPIO16** (or use built-in LED if available)
- Optional: Current-limiting resistor (typically 330Ω - 1kΩ)
- **USB cable** for programming
### GPIO16 Connection
```
RP2350 GPIO16 ----[330Ω]----[LED]---- GND
(Resistor) (Anode to GPIO, Cathode to GND)
```
---
## Technical Details
### Coprocessor Interface
The RP2350 implements a **custom GPIO coprocessor (CP0)** accessible through the ARM Cortex-M33's coprocessor interface. This is documented in the RP2350 datasheet.
#### MCRR Instruction Format
```
MCRR p0, #opcode, Rt, Rt2, CRm
```
Where:
- `p0` = Coprocessor 0 (GPIO coprocessor)
- `#opcode` = Operation code (4 for GPIO operations)
- `Rt` = First source register (GPIO pin number in R4)
- `Rt2` = Second source register (value in R5)
- `CRm` = Coprocessor register (c0 for OUT, c4 for OE)
### GPIO Coprocessor Operations Used
#### 1. `gpioc_bit_out_put(gpio, value)`
**Purpose:** Set or clear a GPIO output pin
**Encoding:** `MCRR p0, #4, R4, R5, c0`
**Parameters:**
- R4 = GPIO pin number (16 in our case)
- R5 = Output value (0 or 1)
**Example:**
```assembly
MOVS R4, #16 ; GPIO16
MOVS R5, #1 ; Set HIGH
MCRR p0, #4, R4, R5, c0
```
#### 2. `gpioc_bit_oe_put(gpio, enable)`
**Purpose:** Set output enable for a GPIO pin
**Encoding:** `MCRR p0, #4, R4, R5, c4`
**Parameters:**
- R4 = GPIO pin number (16 in our case)
- R5 = Output enable (1 to enable output)
**Example:**
```assembly
MOVS R4, #16 ; GPIO16
MOVS R5, #1 ; Enable output
MCRR p0, #4, R4, R5, c4
```
---
## Memory Map & Register Addresses
### Critical Memory Addresses Used
| Address | Register | Purpose |
|--------------|-----------------------------------|--------------------------------------|
| `0xE000ED88` | CPACR (Coprocessor Access Control)| Enable CP0 access |
| `0x40038044` | PADS_BANK0_GPIO16 | Pad configuration for GPIO16 |
| `0x40028084` | IO_BANK0_GPIO16_CTRL | Function select for GPIO16 |
| `0x20082000` | STACK_TOP | Initial stack pointer |
| `0x2007A000` | STACK_LIMIT | Stack limit for overflow protection |
### Register Details
#### CPACR (Coprocessor Access Control Register) - 0xE000ED88
```
Bits [1:0] - CP0 access privileges
00 = No access
01 = Privileged access only
10 = Reserved
11 = Full access (used in this code)
```
#### PADS_BANK0_GPIO16 - 0x40038044
```
Bit 8 (ISO) - Isolate pad (0 = normal operation)
Bit 7 (OD) - Output disable (0 = output enabled)
Bit 6 (IE) - Input enable (1 = input buffer enabled)
Bits [5:4] - Drive strength
Bits [3:2] - Slew rate
Bit 1 (PDE) - Pull-down enable
Bit 0 (PUE) - Pull-up enable
```
#### IO_BANK0_GPIO16_CTRL - 0x40028084
```
Bits [4:0] (FUNCSEL) - Function select
0 = JTAG (TDI)
1 = SPI
2 = UART
3 = I2C
4 = PWM
5 = SIO (Software controlled I/O) ← Used for GPIO
6-8 = PIO
9 = USB
31 = NULL
```
---
## Code Structure & Execution Flow
### 1. Vector Table (`.vectors` section)
```assembly
.section .vectors, "ax"
.align 2
.global _vectors
_vectors:
.word STACK_TOP /* 0x20082000 - Initial Stack Pointer */
.word Reset_Handler + 1 /* Reset Handler (Thumb bit set) */
```
**Why `+ 1`?**
The Cortex-M33 uses the Thumb instruction set exclusively. The LSB (least significant bit) of function pointers must be set to 1 to indicate Thumb mode. This is automatically handled by the processor.
### 2. Stack Initialization
```assembly
Reset_Handler:
/* Initialize stack pointers for Cortex-M33 */
LDR R0, =STACK_TOP
MSR PSP, R0 /* Process Stack Pointer */
LDR R0, =STACK_LIMIT
MSR MSPLIM, R0 /* Main Stack Pointer Limit */
MSR PSPLIM, R0 /* Process Stack Pointer Limit */
LDR R0, =STACK_TOP
MSR MSP, R0 /* Main Stack Pointer */
```
**Cortex-M33 Stack Features:**
- **Dual stack pointers:** MSP (Main) and PSP (Process)
- **Stack limit registers:** MSPLIM and PSPLIM for overflow detection
- **Security feature:** Prevents stack overflow from corrupting memory
### 3. Coprocessor Access Enablement
```assembly
/* Enable coprocessor access - set CP0 to full access */
LDR R0, =0xE000ED88 /* CPACR address */
LDR R1, [R0] /* Read current value */
ORR R1, R1, #0x3 /* Set CP0 bits [1:0] to 11 (full access) */
STR R1, [R0] /* Write back */
DSB /* Data Synchronization Barrier */
ISB /* Instruction Synchronization Barrier */
```
**Critical Step:** Without this, MCRR instructions will trigger a **UsageFault** exception!
**Memory Barriers:**
- `DSB` - Ensures all memory operations complete before proceeding
- `ISB` - Flushes instruction pipeline to ensure new settings take effect
### 4. GPIO Pad Configuration
```assembly
/* Configure pad for GPIO16 */
LDR R3, =0x40038044 /* &pads_bank0_hw->io[16] */
LDR R2, [R3] /* load current config */
BIC R2, R2, #0x80 /* clear OD (bit 7) - enable output */
ORR R2, R2, #0x40 /* set IE (bit 6) - enable input buffer */
STR R2, [R3] /* store updated config */
```
**What this does:**
- Clears OD (Output Disable) bit → Allows pin to drive output
- Sets IE (Input Enable) bit → Enables input buffer for reading
- Preserves other settings (pull-ups, drive strength, etc.)
### 5. Function Selection
```assembly
/* Set GPIO16 function to SIO (Software I/O) */
LDR R3, =0x40028084 /* &io_bank0_hw->io[16].ctrl */
LDR R2, [R3] /* load current config */
BIC R2, R2, #0x1F /* clear FUNCSEL bits [4:0] */
ORR R2, R2, #5 /* set FUNCSEL = 5 (SIO) */
STR R2, [R3] /* store updated config */
```
**Function 5 (SIO):**
- Routes GPIO to software control
- Required before using coprocessor GPIO operations
- Other functions route to hardware peripherals (UART, SPI, etc.)
### 6. Pad Isolation
```assembly
/* Un-isolate the pad */
LDR R3, =0x40038044 /* &pads_bank0_hw->io[16] */
LDR R2, [R3] /* load current config */
BIC R2, R2, #0x100 /* clear ISO bit (bit 8) */
STR R2, [R3] /* store updated config */
```
**ISO bit:**
- When set (1): Pad is isolated from peripherals
- When clear (0): Pad is connected and functional
- Must be cleared for GPIO to work
### 7. Enable GPIO Output
```assembly
/* Enable output using coprocessor */
MOVS R4, #16 /* GPIO16 */
MOVS R5, #1 /* Enable output */
MCRR p0, #4, R4, R5, c4 /* gpioc_bit_oe_put(16, 1) */
```
**This is the first coprocessor instruction!**
- Sets the Output Enable (OE) bit for GPIO16
- Makes the pin drive its output value
- Uses coprocessor register c4 (OE control)
### 8. Main Blink Loop
```assembly
blink_loop:
/* Turn LED ON */
MOVS R4, #16 /* GPIO16 */
MOVS R5, #1 /* HIGH */
MCRR p0, #4, R4, R5, c0 /* gpioc_bit_out_put(16, 1) */
/* Delay ~500ms */
LDR R2, =2000000 /* 2M cycles */
delay_on:
SUBS R2, R2, #1 /* Decrement */
BNE delay_on /* Loop until zero */
/* Turn LED OFF */
MOVS R4, #16 /* GPIO16 */
MOVS R5, #0 /* LOW */
MCRR p0, #4, R4, R5, c0 /* gpioc_bit_out_put(16, 0) */
/* Delay ~500ms */
LDR R2, =2000000 /* 2M cycles */
delay_off:
SUBS R2, R2, #1 /* Decrement */
BNE delay_off /* Loop until zero */
B blink_loop /* Repeat forever */
```
**Delay Calculation:**
- 2,000,000 cycles at ~4-12 MHz boot clock
- Approximately 500ms per delay
- Total period: ~1 second (1Hz blink rate)
---
## Build Process
### Prerequisites
1. **ARM GNU Toolchain** installed and in PATH:
- `arm-none-eabi-as` (Assembler)
- `arm-none-eabi-ld` (Linker)
- `arm-none-eabi-objcopy` (Object copy utility)
2. **Python** (for UF2 conversion)
3. **uf2conv.py** script (located two directories up: `../../uf2conv.py`)
### Build Script (`build.bat`)
```batch
@echo off
REM Build script for RP2350 GPIO16 blink
echo Building GPIO16 blink...
REM Assemble main code
arm-none-eabi-as -mcpu=cortex-m33 -mthumb gpio16_blink.s -o gpio16_blink.o
REM Assemble image definition
arm-none-eabi-as -mcpu=cortex-m33 -mthumb image_def.s -o image_def.o
REM Link with linker script
arm-none-eabi-ld -T linker.ld gpio16_blink.o image_def.o -o gpio16_blink.elf
REM Create raw binary
arm-none-eabi-objcopy -O binary gpio16_blink.elf gpio16_blink.bin
REM Create UF2 bootloader format
python ..\..\uf2conv.py -b 0x10000000 -f 0xe48bff59 -o gpio16_blink.uf2 gpio16_blink.bin
```
### Build Command
```powershell
.\build.bat
```
### Build Flags Explained
**`-mcpu=cortex-m33`**
- Target the Cortex-M33 processor in RP2350
- Enables M33-specific features (stack limits, DSB/ISB instructions, coprocessor)
**`-mthumb`**
- Generate Thumb-2 instruction set (mandatory for Cortex-M)
- Provides 16-bit and 32-bit instruction mix for code density
**`-T linker.ld`**
- Use custom linker script to define memory layout
- Places code at flash start (0x10000000)
**UF2 Parameters:**
- `-b 0x10000000` - Base address (RP2350 flash start)
- `-f 0xe48bff59` - Family ID for RP2350
- `-o gpio16_blink.uf2` - Output filename
---
## Flashing Instructions
### Method 1: UF2 Bootloader (Easiest)
1. **Disconnect** the RP2350 from USB
2. **Hold the BOOTSEL button** on the board
3. **Connect USB cable** while holding BOOTSEL
4. **Release BOOTSEL** - Board appears as USB mass storage device
5. **Copy** `gpio16_blink.uf2` to the RP2350 drive
6. **Board automatically reboots** and starts running the program
### Method 2: OpenOCD with Debug Probe
If you have a debug probe (e.g., Raspberry Pi Debug Probe, CMSIS-DAP):
```bash
openocd -f interface/cmsis-dap.cfg -f target/rp2350.cfg \
-c "adapter speed 5000" \
-c "program gpio16_blink.elf verify reset exit"
```
---
## Debugging & Troubleshooting
### Problem: LED doesn't blink
**Check 1: Coprocessor Access**
- Ensure CPACR is set correctly
- Without this, MCRR triggers UsageFault
- Verify DSB/ISB barriers are present
**Check 2: GPIO Configuration**
- Verify FUNCSEL is set to 5 (SIO)
- Check OD bit is cleared (output enabled)
- Ensure ISO bit is cleared (pad connected)
**Check 3: Hardware Connections**
- LED polarity (anode to GPIO, cathode to GND)
- Current-limiting resistor present
- GPIO16 physically connected
**Check 4: Clock Speed**
- Boot clock may vary (4-12 MHz typical)
- Delay timing depends on actual clock
- Adjust delay constant if needed
### Problem: Build fails
**Missing toolchain:**
```
'arm-none-eabi-as' is not recognized...
```
Solution: Install ARM GNU Toolchain and add to PATH
**Missing uf2conv.py:**
```
python: can't open file 'uf2conv.py'
```
Solution: Ensure uf2conv.py is in `../../` relative to build directory
**Assembly errors:**
```
Error: bad instruction 'mcrr'
```
Solution: Ensure `-mcpu=cortex-m33` flag is used (M33 supports coprocessor)
### Problem: Board doesn't appear as USB drive
**Solution 1:** Try different USB cable (must support data, not just power)
**Solution 2:** Hold BOOTSEL earlier (before connecting USB)
**Solution 3:** Check USB port functionality
---
## Performance Analysis
### Instruction Cycle Counts (Approximate)
**Traditional GPIO Write (3-4 instructions):**
```assembly
LDR R0, =SIO_BASE ; 2 cycles
LDR R1, =GPIO16_BIT ; 2 cycles
STR R1, [R0, #offset] ; 2 cycles
; Total: ~6 cycles + memory latency
```
**Coprocessor GPIO Write (2 instructions):**
```assembly
MOVS R4, #16 ; 1 cycle
MOVS R5, #1 ; 1 cycle
MCRR p0, #4, R4, R5, c0 ; 1 cycle (hardware accelerated)
; Total: ~3 cycles
```
**Performance Gain: ~50% faster execution**
### Memory Usage
| Section | Size | Location |
|-------------|---------|----------------|
| Vector Table| 8 bytes | 0x10000000 |
| Code (.text)| ~140 bytes | 0x10000008 |
| Total Flash | ~148 bytes | Flash |
| Stack | 32 KB | RAM (0x2007A000-0x20082000) |
**UF2 File Size:** 512 bytes (minimum UF2 block size)
---
## Advanced Topics
### Extending to Multiple GPIOs
To control multiple GPIOs with coprocessor:
```assembly
; Blink GPIO16 and GPIO17 alternately
blink_multi:
; Turn GPIO16 ON, GPIO17 OFF
MOVS R4, #16
MOVS R5, #1
MCRR p0, #4, R4, R5, c0
MOVS R4, #17
MOVS R5, #0
MCRR p0, #4, R4, R5, c0
; Delay...
; Turn GPIO16 OFF, GPIO17 ON
MOVS R4, #16
MOVS R5, #0
MCRR p0, #4, R4, R5, c0
MOVS R4, #17
MOVS R5, #1
MCRR p0, #4, R4, R5, c0
```
### Reading GPIO with Coprocessor
The RP2350 also supports GPIO read operations:
```assembly
; Read GPIO state using MRRC (Move to ARM Registers from Coprocessor)
MOVS R4, #16 ; GPIO to read
MRRC p0, #opcode, R4, R5, c0 ; Result in R5
```
*(Exact opcode may vary - consult RP2350 datasheet)*
### Interrupt-Driven Delays
For production code, replace busy-wait delays with timer interrupts:
```assembly
; Configure SysTick for 1ms interrupts
LDR R0, =0xE000E010 ; SysTick base
LDR R1, =4000 ; Reload value for 1ms at 4MHz
STR R1, [R0, #4] ; SYST_RVR
MOV R1, #7 ; Enable + interrupt + clock
STR R1, [R0, #0] ; SYST_CSR
```
---
## Reference Documentation
### Official Documentation
1. **RP2350 Datasheet** - Complete hardware reference
- Section on GPIO Coprocessor (CP0)
- Register maps and bit definitions
- Electrical characteristics
2. **ARM Cortex-M33 Technical Reference Manual**
- Coprocessor interface specification
- MCRR/MRRC instruction encoding
- Stack limit and security features
3. **ARM Architecture Reference Manual (ARMv8-M)**
- Thumb-2 instruction set
- System control registers (CPACR, etc.)
- Exception handling
### Instruction Reference
**MCRR (Move to Coprocessor from ARM Registers):**
```
MCRR coproc, opc1, Rt, Rt2, CRm
coproc: p0-p15 (coprocessor number)
opc1: 4-bit operation code
Rt: First source register
Rt2: Second source register
CRm: Coprocessor register
```
**DSB (Data Synchronization Barrier):**
- Ensures completion of memory operations
- Required after CPACR modification
**ISB (Instruction Synchronization Barrier):**
- Flushes instruction pipeline
- Required after system control changes
---
## Version History
### Version 1.0 (October 2025)
- Initial release
- Implements GPIO16 blink using coprocessor
- 500ms on/off cycle
- CPACR enablement for CP0 access
- Proper initialization sequence
---
## License & Credits
This code is provided as-is for educational and experimental purposes.
**Created for:** Bare-metal RP2350 development
**Target Board:** Raspberry Pi Pico 2 (RP2350)
**Architecture:** ARM Cortex-M33
**Assembly Syntax:** GNU AS (Unified ARM Syntax)
---
## Future Enhancements
Potential improvements:
1. **Add interrupt-driven timing** instead of busy-wait loops
2. **Implement GPIO read operations** using MRRC
3. **Create PWM effects** using variable duty cycles
4. **Multi-GPIO patterns** (Knight Rider, binary counter, etc.)
5. **Add error handling** for fault exceptions
6. **Clock configuration** for precise timing
7. **Low-power modes** using WFI (Wait For Interrupt)
---
## Contact & Support
For issues, questions, or contributions related to this coprocessor implementation, please refer to:
- RP2350 community forums
- ARM Cortex-M33 documentation
- Raspberry Pi Pico SDK examples
**Happy coding with coprocessors!** 🚀

View File

@@ -0,0 +1,78 @@
@echo off
REM ============================================================================
REM FILE: build.bat
REM
REM DESCRIPTION:
REM Build script for RP2350 GPIO16 Blink (Coprocessor Version).
REM Automates the process of assembling, linking, and generating UF2 firmware.
REM
REM AUTHOR: Kevin Thomas
REM CREATION DATE: October 5, 2025
REM UPDATE DATE: October 5, 2025
REM
REM STEPS:
REM 1. Assemble source files (gpio16_blink.s, image_def.s)
REM 2. Link objects with linker script (linker.ld)
REM 3. Convert ELF to BIN
REM 4. Convert BIN to UF2 with correct family ID (RP2350 = 0xe48bff59)
REM 5. Provide flashing instructions (UF2 draganddrop or OpenOCD)
REM ============================================================================
echo Building GPIO16 blink...
REM ============================================================================
REM Assemble source files
REM ============================================================================
arm-none-eabi-as -mcpu=cortex-m33 -mthumb gpio16_blink.s -o gpio16_blink.o
if errorlevel 1 goto error
arm-none-eabi-as -mcpu=cortex-m33 -mthumb image_def.s -o image_def.o
if errorlevel 1 goto error
REM ============================================================================
REM Link object files into ELF using linker script
REM ============================================================================
arm-none-eabi-ld -T linker.ld gpio16_blink.o image_def.o -o gpio16_blink.elf
if errorlevel 1 goto error
REM ============================================================================
REM Create raw binary from ELF
REM ============================================================================
arm-none-eabi-objcopy -O binary gpio16_blink.elf gpio16_blink.bin
if errorlevel 1 goto error
REM ============================================================================
REM Create UF2 image for RP2350
REM -b 0x10000000 : base address
REM -f 0xe48bff59 : RP2350 family ID
REM ============================================================================
python ..\..\uf2conv.py -b 0x10000000 -f 0xe48bff59 -o gpio16_blink.uf2 gpio16_blink.bin
if errorlevel 1 goto error
REM ============================================================================
REM Success message and flashing instructions
REM ============================================================================
echo.
echo ========================================
echo SUCCESS! Created gpio16_blink.uf2
echo ========================================
echo.
echo To flash via UF2:
echo 1. Hold BOOTSEL button
echo 2. Plug in USB
echo 3. Copy gpio16_blink.uf2 to RP2350 drive
echo.
echo To flash via OpenOCD (debug probe):
echo openocd -f interface/cmsis-dap.cfg -f target/rp2350.cfg -c "adapter speed 5000" -c "program gpio16_blink.elf verify reset exit"
echo.
goto end
REM ============================================================================
REM Error handling
REM ============================================================================
:error
echo.
echo BUILD FAILED!
echo.
:end

Binary file not shown.

View File

@@ -0,0 +1,169 @@
/**
* FILE: main.s
*
* DESCRIPTION:
* RP2350 Bare-Metal GPIO16 Blink, Coprocessor Version.
* Minimal baremetal LED blink on the RP2350 using direct coprocessor
* (MCRR) instructions to manipulate GPIO control registers. This bypasses
* SDK abstractions and demonstrates registerlevel control in assembler.
*
* AUTHOR: Kevin Thomas
* CREATION DATE: October 5, 2025
* UPDATE DATE: October 5, 2025
*/
.syntax unified // use unified assembly syntax
.cpu cortex-m33 // target Cortex-M33 core
.thumb // use Thumb instruction set
/**
* Memory addresses and constants.
*/
.equ IO_BANK0_BASE, 0x40028000 // base address of IO_BANK0
.equ PADS_BANK0_BASE, 0x40038000 // base address of PADS_BANK0
.equ SIO_BASE, 0xD0000000 // base address of SIO block
.equ GPIO16_CTRL, 0x84 // io[16].ctrl offset
.equ GPIO16_PAD, 0x44 // pads io[16] offset
.equ GPIO16_BIT, (1 << 16) // bit mask for GPIO16
.equ GPIO_OUT_SET, 0x18 // SIO->GPIO_OUT_SET offset
.equ GPIO_OUT_XOR, 0x28 // SIO->GPIO_OUT_XOR offset
.equ GPIO_OE_SET, 0x38 // SIO->GPIO_OE_SET offset
.equ STACK_TOP, 0x20082000 // top of non-secure SRAM
.equ STACK_LIMIT, 0x2007A000 // stack limit (32 KB below top)
/**
* Vector table section.
*/
.section .vectors, "ax" // vector table section
.align 2 // align to 4 bytes
.global _vectors // export symbol
_vectors:
.word STACK_TOP // initial stack pointer
.word Reset_Handler + 1 // reset handler (Thumb bit set)
/**
* @brief Reset handler for RP2350.
* @details Entry point after reset. Performs:
* - Stack initialization
* - Coprocessor enable
* - GPIO16 pad/function configuration
* - Infinite blink loop using coprocessor writes
* @param None
* @retval None
*/
.section .text // code section
.align 2 // align functions
.global Reset_Handler // export Reset_Handler
.type Reset_Handler, %function // mark as function
Reset_Handler:
BL init_stack // initialize MSP/PSP and limits
BL enable_coprocessor // enable CP0 in CPACR for MCRR
BL gpio16_config // configure pads and FUNCSEL for GPIO16
blink_loop:
BL gpio16_set // set GPIO16 high
BL delay // delay ~500 ms
BL gpio16_clear // set GPIO16 low
BL delay // delay ~500 ms
B blink_loop // loop forever
.size Reset_Handler, . - Reset_Handler
/**
* @brief Initialize stack pointers.
* @details Sets Main and Process Stack Pointers (MSP/PSP) and their limits.
* @param None
* @retval None
*/
.type init_stack, %function
init_stack:
LDR R0, =STACK_TOP // load stack top
MSR PSP, R0 // set PSP
LDR R0, =STACK_LIMIT // load stack limit
MSR MSPLIM, R0 // set MSP limit
MSR PSPLIM, R0 // set PSP limit
LDR R0, =STACK_TOP // reload stack top
MSR MSP, R0 // set MSP
BX LR // return
/**
* @brief Enable coprocessor access.
* @details Grants full access to coprocessor 0 (CP0) via CPACR.
* @param None
* @retval None
*/
.type enable_coprocessor, %function
enable_coprocessor:
LDR R0, =0xE000ED88 // CPACR address
LDR R1, [R0] // read CPACR
ORR R1, R1, #0x3 // set CP0 full access
STR R1, [R0] // write CPACR
DSB // data sync barrier
ISB // instruction sync barrier
BX LR // return
/**
* @brief Configure GPIO16 for SIO control.
* @details Sets pad control (IE, OD, ISO) and FUNCSEL = 5 (SIO). Enables OE.
* @param None
* @retval None
*/
.type gpio16_config, %function
gpio16_config:
LDR R3, =PADS_BANK0_BASE + GPIO16_PAD // pad control address
LDR R2, [R3] // read pad config
BIC R2, R2, #0x80 // clear OD
ORR R2, R2, #0x40 // set IE
BIC R2, R2, #0x100 // clear ISO
STR R2, [R3] // write pad config
LDR R3, =IO_BANK0_BASE + GPIO16_CTRL // IO control address
LDR R2, [R3] // read IO config
BIC R2, R2, #0x1F // clear FUNCSEL
ORR R2, R2, #5 // set FUNCSEL = 5
STR R2, [R3] // write IO config
MOVS R4, #16 // GPIO number
MOVS R5, #1 // enable output
MCRR p0, #4, R4, R5, c4 // gpioc_bit_oe_put(16, 1)
BX LR // return
/**
* @brief Set GPIO16 high.
* @details Drives GPIO16 output = 1 via coprocessor MCRR.
* @param None
* @retval None
*/
.type gpio16_set, %function
gpio16_set:
MOVS R4, #16 // GPIO number
MOVS R5, #1 // logic high
MCRR p0, #4, R4, R5, c0 // gpioc_bit_out_put(16, 1)
BX LR // return
/**
* @brief Clear GPIO16 (set low).
* @details Drives GPIO16 output = 0 via coprocessor MCRR.
* @param None
* @retval None
*/
.type gpio16_clear, %function
gpio16_clear:
MOVS R4, #16 // GPIO number
MOVS R5, #0 // logic low
MCRR p0, #4, R4, R5, c0 // gpioc_bit_out_put(16, 0)
BX LR // return
/**
* @brief Busywait delay loop.
* @details Consumes ~2,000,000 cycles to approximate ~500 ms at boot clock.
* @param None
* @retval None
*/
.type delay, %function
delay:
LDR R2, =2000000 // loop count
1:SUBS R2, R2, #1 // decrement
BNE 1b // loop until zero
BX LR // return

Binary file not shown.

View File

@@ -0,0 +1,39 @@
/**
* FILE: image_def.s
*
* DESCRIPTION:
* RP2350 IMAGE_DEF Block.
* A minimum amount of metadata (a valid IMAGE_DEF block) must be embedded in any
* binary for the bootrom to recognise it as a valid program image, as opposed to,
* for example, blank flash contents or a disconnected flash device. This must
* appear within the first 4 kB of a flash image, or anywhere in a RAM or OTP image.
*
* Unlike RP2040, there is no requirement for flash binaries to have a checksummed
* "boot2" flash setup function at flash address 0. The RP2350 bootrom performs a
* simple besteffort XIP setup during flash scanning, and a flashresident program
* can continue executing in this state, or can choose to reconfigure the QSPI
* interface at a later time for best performance.
*
* AUTHOR: Kevin Thomas
* CREATION DATE: October 5, 2025
* UPDATE DATE: October 5, 2025
*
* REFERENCE:
* RP2350 Datasheet, Section 5.9.5 Minimum viable image metadata
*
* NOTES:
* In the Pico SDK, this block is generated automatically from
* embedded_start_block.inc.S / embedded_end_block.inc.S.
*/
.section .picobin_block, "a" // place IMAGE_DEF block in flash
.word 0xffffded3 // PICOBIN_BLOCK_MARKER_START
.byte 0x42 // PICOBIN_BLOCK_ITEM_1BS_IMAGE_TYPE
.byte 0x1 // item is 1 word in size
.hword 0b0001000000100001 // SECURE mode (0x1021)
.byte 0xff // PICOBIN_BLOCK_ITEM_2BS_LAST
.hword 0x0001 // item is 1 word in size
.byte 0x0 // pad
.word 0x0 // relative pointer to next block (0 = loop to self)
.word 0xab123579 // PICOBIN_BLOCK_MARKER_END

View File

@@ -0,0 +1,104 @@
/**
* FILE: linker.ld
*
* DESCRIPTION:
* RP2350 Minimal Linker Script for baremetal development.
* Ensures the boot ROM accepts and runs the image by:
* - Placing the IMAGE_DEF block first at 0x10000000
* - Aligning the vector table to a 128byte boundary within the first 4 KB
* - Defining a nonsecure stack region in SRAM
*
* AUTHOR: Kevin Thomas
* CREATION DATE: October 5, 2025
* UPDATE DATE: October 5, 2025
*
* KEY FEATURES:
* - FLASH origin at 0x10000000 (XIP base), 32 MB length
* - RAM origin at 0x20000000, 512 KB nonsecure window
* - IMAGE_DEF block emitted before all other sections
* - Vector table alignment and assertion to satisfy ROM requirements
* - Symbols for __StackTop, __StackLimit, and __Vectors provided
*
* REFERENCE:
* RP2350 Datasheet, Section 5.9.5 Minimum viable image metadata
*
* NOTES:
* This script is intentionally minimal to support reproducible,
* SDKfree baremetal builds. It pairs with a standalone IMAGE_DEF
* assembly file and a vector table defined in your startup code.
*/
ENTRY(Reset_Handler)
/**
* Define memory regions.
*/
__XIP_BASE = 0x10000000;
__XIP_SIZE = 32M;
__SRAM_BASE = 0x20000000;
__SRAM_SIZE = 512K; /* non-secure window */
__STACK_SIZE = 32K;
MEMORY
{
RAM (rwx) : ORIGIN = __SRAM_BASE, LENGTH = __SRAM_SIZE
FLASH (rx) : ORIGIN = __XIP_BASE, LENGTH = __XIP_SIZE
}
/**
* Program headers.
*/
PHDRS
{
text PT_LOAD FLAGS(5); /* RX */
}
/**
* Section placement.
*/
SECTIONS
{
. = ORIGIN(FLASH);
/**
* Minimal IMAGE_DEF must be first.
*/
.embedded_block :
{
KEEP(*(.embedded_block))
} > FLASH :text
/**
* Force the vector table section start to a 128-byte boundary.
*/
.vectors ALIGN(128) :
{
KEEP(*(.vectors))
} > FLASH :text
ASSERT(((ADDR(.vectors) - ORIGIN(FLASH)) < 0x1000),
"Vector table must be in first 4KB of flash")
/**
* Text and read-only data.
*/
.text :
{
. = ALIGN(4);
*(.text*)
*(.rodata*)
KEEP(*(.ARM.attributes))
} > FLASH :text
/**
* Non-secure stack symbols.
*/
__StackTop = ORIGIN(RAM) + LENGTH(RAM); /* 0x20080000 */
__StackLimit = __StackTop - __STACK_SIZE;
__stack = __StackTop;
.stack (NOLOAD) : { . = ALIGN(8); } > RAM
PROVIDE(__Vectors = ADDR(.vectors));
}

View File

@@ -0,0 +1,69 @@
@echo off
REM ============================================================================
REM FILE: review.bat
REM
REM DESCRIPTION:
REM Review script for RP2350 ELF and BIN outputs.
REM Runs a suite of GNU binutils tools to inspect ELF and BIN files.
REM Dumps results into text files for easy review.
REM
REM AUTHOR: Kevin Thomas
REM CREATION DATE: October 5, 2025
REM UPDATE DATE: October 5, 2025
REM ============================================================================
set ELF_FILE=gpio16_blink.elf
set BIN_FILE=gpio16_blink.bin
set OUT_DIR=review_reports
if not exist %OUT_DIR% mkdir %OUT_DIR%
echo Reviewing %ELF_FILE% and %BIN_FILE% ...
REM ============================================================================
REM ELF inspection tools
REM ============================================================================
arm-none-eabi-readelf -a %ELF_FILE% > %OUT_DIR%\readelf_all.txt
arm-none-eabi-readelf -h %ELF_FILE% > %OUT_DIR%\readelf_header.txt
arm-none-eabi-readelf -S %ELF_FILE% > %OUT_DIR%\readelf_sections.txt
arm-none-eabi-readelf -s %ELF_FILE% > %OUT_DIR%\readelf_symbols.txt
arm-none-eabi-readelf -r %ELF_FILE% > %OUT_DIR%\readelf_relocs.txt
arm-none-eabi-objdump -x %ELF_FILE% > %OUT_DIR%\objdump_headers.txt
arm-none-eabi-objdump -d %ELF_FILE% > %OUT_DIR%\objdump_disasm.txt
arm-none-eabi-objdump -s %ELF_FILE% > %OUT_DIR%\objdump_fullhex.txt
arm-none-eabi-objdump -h %ELF_FILE% > %OUT_DIR%\objdump_sections.txt
arm-none-eabi-nm -n %ELF_FILE% > %OUT_DIR%\nm_symbols.txt
arm-none-eabi-size %ELF_FILE% > %OUT_DIR%\size.txt
arm-none-eabi-strings %ELF_FILE% > %OUT_DIR%\strings.txt
REM ============================================================================
REM BIN inspection tools
REM ============================================================================
xxd -g4 -l 256 %BIN_FILE% > %OUT_DIR%\bin_hexdump.txt
REM ============================================================================
REM Summary
REM ============================================================================
echo.
echo ========================================
echo REVIEW COMPLETE
echo Reports written to %OUT_DIR%\
echo ========================================
echo.
echo Key files:
echo - readelf_all.txt (everything about ELF)
echo - objdump_disasm.txt (disassembly)
echo - nm_symbols.txt (symbols)
echo - size.txt (section sizes)
echo - bin_hexdump.txt (first 256 bytes of BIN)
echo.
goto end
:error
echo.
echo REVIEW FAILED!
echo.
:end

View File

@@ -0,0 +1,28 @@
00000018 a GPIO_OUT_SET
00000028 a GPIO_OUT_XOR
00000038 a GPIO_OE_SET
00000044 a GPIO16_PAD
00000084 a GPIO16_CTRL
00008000 A __STACK_SIZE
00010000 a GPIO16_BIT
00080000 A __SRAM_SIZE
02000000 A __XIP_SIZE
10000000 A __XIP_BASE
10000000 T _vectors
10000008 T Reset_Handler
10000014 t blink_loop
10000026 t init_stack
1000003e t enable_coprocessor
10000052 t gpio16_config
1000007c t gpio16_set
10000086 t gpio16_clear
10000090 t delay
20000000 A __SRAM_BASE
20078000 A __StackLimit
2007a000 a STACK_LIMIT
20080000 A __stack
20080000 T __StackTop
20082000 a STACK_TOP
40028000 a IO_BANK0_BASE
40038000 a PADS_BANK0_BASE
d0000000 a SIO_BASE

View File

@@ -0,0 +1,101 @@
gpio16_blink.elf: file format elf32-littlearm
Disassembly of section .vectors:
10000000 <_vectors>:
10000000: 20082000 .word 0x20082000
10000004: 10000009 .word 0x10000009
Disassembly of section .text:
10000008 <Reset_Handler>:
10000008: f000 f80d bl 10000026 <init_stack>
1000000c: f000 f817 bl 1000003e <enable_coprocessor>
10000010: f000 f81f bl 10000052 <gpio16_config>
10000014 <blink_loop>:
10000014: f000 f832 bl 1000007c <gpio16_set>
10000018: f000 f83a bl 10000090 <delay>
1000001c: f000 f833 bl 10000086 <gpio16_clear>
10000020: f000 f836 bl 10000090 <delay>
10000024: e7f6 b.n 10000014 <blink_loop>
10000026 <init_stack>:
10000026: 481c ldr r0, [pc, #112] @ (10000098 <delay+0x8>)
10000028: f380 8809 msr PSP, r0
1000002c: 481b ldr r0, [pc, #108] @ (1000009c <delay+0xc>)
1000002e: f380 880a msr MSPLIM, r0
10000032: f380 880b msr PSPLIM, r0
10000036: 4818 ldr r0, [pc, #96] @ (10000098 <delay+0x8>)
10000038: f380 8808 msr MSP, r0
1000003c: 4770 bx lr
1000003e <enable_coprocessor>:
1000003e: 4818 ldr r0, [pc, #96] @ (100000a0 <delay+0x10>)
10000040: 6801 ldr r1, [r0, #0]
10000042: f041 0103 orr.w r1, r1, #3
10000046: 6001 str r1, [r0, #0]
10000048: f3bf 8f4f dsb sy
1000004c: f3bf 8f6f isb sy
10000050: 4770 bx lr
10000052 <gpio16_config>:
10000052: 4b14 ldr r3, [pc, #80] @ (100000a4 <delay+0x14>)
10000054: 681a ldr r2, [r3, #0]
10000056: f022 0280 bic.w r2, r2, #128 @ 0x80
1000005a: f042 0240 orr.w r2, r2, #64 @ 0x40
1000005e: f422 7280 bic.w r2, r2, #256 @ 0x100
10000062: 601a str r2, [r3, #0]
10000064: 4b10 ldr r3, [pc, #64] @ (100000a8 <delay+0x18>)
10000066: 681a ldr r2, [r3, #0]
10000068: f022 021f bic.w r2, r2, #31
1000006c: f042 0205 orr.w r2, r2, #5
10000070: 601a str r2, [r3, #0]
10000072: 2410 movs r4, #16
10000074: 2501 movs r5, #1
10000076: ec45 4044 stcl 0, cr4, [r5], {68} @ 0x44
1000007a: 4770 bx lr
1000007c <gpio16_set>:
1000007c: 2410 movs r4, #16
1000007e: 2501 movs r5, #1
10000080: ec45 4040 stcl 0, cr4, [r5], {64} @ 0x40
10000084: 4770 bx lr
10000086 <gpio16_clear>:
10000086: 2410 movs r4, #16
10000088: 2500 movs r5, #0
1000008a: ec45 4040 stcl 0, cr4, [r5], {64} @ 0x40
1000008e: 4770 bx lr
10000090 <delay>:
10000090: 4a06 ldr r2, [pc, #24] @ (100000ac <delay+0x1c>)
10000092: 3a01 subs r2, #1
10000094: d1fd bne.n 10000092 <delay+0x2>
10000096: 4770 bx lr
10000098: 20082000 .word 0x20082000
1000009c: 2007a000 .word 0x2007a000
100000a0: e000ed88 .word 0xe000ed88
100000a4: 40038044 .word 0x40038044
100000a8: 40028084 .word 0x40028084
100000ac: 001e8480 .word 0x001e8480
100000b0: 00002341 .word 0x00002341
100000b4: 61656100 .word 0x61656100
100000b8: 01006962 .word 0x01006962
100000bc: 00000019 .word 0x00000019
100000c0: 726f4305 .word 0x726f4305
100000c4: 2d786574 .word 0x2d786574
100000c8: 0033334d .word 0x0033334d
100000cc: 4d071106 .word 0x4d071106
100000d0: 012e0309 .word 0x012e0309
100000d4: 00002341 .word 0x00002341
100000d8: 61656100 .word 0x61656100
100000dc: 01006962 .word 0x01006962
100000e0: 00000019 .word 0x00000019
100000e4: 726f4305 .word 0x726f4305
100000e8: 2d786574 .word 0x2d786574
100000ec: 0033334d .word 0x0033334d
100000f0: 4d071106 .word 0x4d071106
100000f4: 012e0309 .word 0x012e0309

View File

@@ -0,0 +1,24 @@
gpio16_blink.elf: file format elf32-littlearm
Contents of section .vectors:
10000000 00200820 09000010 . . ....
Contents of section .text:
10000008 00f00df8 00f017f8 00f01ff8 00f032f8 ..............2.
10000018 00f03af8 00f033f8 00f036f8 f6e71c48 ..:...3...6....H
10000028 80f30988 1b4880f3 0a8880f3 0b881848 .....H.........H
10000038 80f30888 70471848 016841f0 03010160 ....pG.H.hA....`
10000048 bff34f8f bff36f8f 7047144b 1a6822f0 ..O...o.pG.K.h".
10000058 800242f0 400222f4 80721a60 104b1a68 ..B.@."..r.`.K.h
10000068 22f01f02 42f00502 1a601024 012545ec "...B....`.$.%E.
10000078 44407047 10240125 45ec4040 70471024 D@pG.$.%E.@@pG.$
10000088 002545ec 40407047 064a013a fdd17047 .%E.@@pG.J.:..pG
10000098 00200820 00a00720 88ed00e0 44800340 . . ... ....D..@
100000a8 84800240 80841e00 41230000 00616561 ...@....A#...aea
100000b8 62690001 19000000 05436f72 7465782d bi.......Cortex-
100000c8 4d333300 0611074d 09032e01 41230000 M33....M....A#..
100000d8 00616561 62690001 19000000 05436f72 .aeabi.......Cor
100000e8 7465782d 4d333300 0611074d 09032e01 tex-M33....M....
Contents of section .picobin_block:
100000f8 d3deffff 42012110 ff010000 00000000 ....B.!.........
10000108 793512ab y5..

View File

@@ -0,0 +1,58 @@
gpio16_blink.elf: file format elf32-littlearm
gpio16_blink.elf
architecture: armv3m, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x10000009
Program Header:
LOAD off 0x00001000 vaddr 0x10000000 paddr 0x10000000 align 2**12
filesz 0x0000010c memsz 0x0000010c flags r-x
private flags = 0x5000200: [Version5 EABI] [soft-float ABI]
Sections:
Idx Name Size VMA LMA File off Algn
0 .vectors 00000008 10000000 10000000 00001000 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .text 000000f0 10000008 10000008 00001008 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 .picobin_block 00000014 100000f8 100000f8 000010f8 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .stack 00000000 20000000 20000000 0000110c 2**0
CONTENTS
SYMBOL TABLE:
10000000 l d .vectors 00000000 .vectors
10000008 l d .text 00000000 .text
100000f8 l d .picobin_block 00000000 .picobin_block
20000000 l d .stack 00000000 .stack
00000000 l df *ABS* 00000000 gpio16_blink.o
40028000 l *ABS* 00000000 IO_BANK0_BASE
40038000 l *ABS* 00000000 PADS_BANK0_BASE
d0000000 l *ABS* 00000000 SIO_BASE
00000084 l *ABS* 00000000 GPIO16_CTRL
00000044 l *ABS* 00000000 GPIO16_PAD
00010000 l *ABS* 00000000 GPIO16_BIT
00000018 l *ABS* 00000000 GPIO_OUT_SET
00000028 l *ABS* 00000000 GPIO_OUT_XOR
00000038 l *ABS* 00000000 GPIO_OE_SET
20082000 l *ABS* 00000000 STACK_TOP
2007a000 l *ABS* 00000000 STACK_LIMIT
10000026 l F .text 00000000 init_stack
1000003e l F .text 00000000 enable_coprocessor
10000052 l F .text 00000000 gpio16_config
10000014 l .text 00000000 blink_loop
1000007c l F .text 00000000 gpio16_set
10000090 l F .text 00000000 delay
10000086 l F .text 00000000 gpio16_clear
00080000 g *ABS* 00000000 __SRAM_SIZE
10000000 g .vectors 00000000 _vectors
20000000 g *ABS* 00000000 __SRAM_BASE
10000008 g F .text 0000001e Reset_Handler
00008000 g *ABS* 00000000 __STACK_SIZE
20080000 g .text 00000000 __StackTop
20080000 g *ABS* 00000000 __stack
20078000 g *ABS* 00000000 __StackLimit
02000000 g *ABS* 00000000 __XIP_SIZE
10000000 g *ABS* 00000000 __XIP_BASE

View File

@@ -0,0 +1,13 @@
gpio16_blink.elf: file format elf32-littlearm
Sections:
Idx Name Size VMA LMA File off Algn
0 .vectors 00000008 10000000 10000000 00001000 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .text 000000f0 10000008 10000008 00001008 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 .picobin_block 00000014 100000f8 100000f8 000010f8 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .stack 00000000 20000000 20000000 0000110c 2**0
CONTENTS

View File

@@ -0,0 +1,97 @@
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: ARM
Version: 0x1
Entry point address: 0x10000009
Start of program headers: 52 (bytes into file)
Start of section headers: 5424 (bytes into file)
Flags: 0x5000200, Version5 EABI, soft-float ABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 1
Size of section headers: 40 (bytes)
Number of section headers: 8
Section header string table index: 7
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .vectors PROGBITS 10000000 001000 000008 00 AX 0 0 4
[ 2] .text PROGBITS 10000008 001008 0000f0 00 AX 0 0 4
[ 3] .picobin_block PROGBITS 100000f8 0010f8 000014 00 A 0 0 1
[ 4] .stack PROGBITS 20000000 00110c 000000 00 W 0 0 1
[ 5] .symtab SYMTAB 00000000 00110c 000280 10 6 30 4
[ 6] .strtab STRTAB 00000000 00138c 000162 00 0 0 1
[ 7] .shstrtab STRTAB 00000000 0014ee 000040 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
D (mbind), y (purecode), p (processor specific)
There are no section groups in this file.
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x001000 0x10000000 0x10000000 0x0010c 0x0010c R E 0x1000
Section to Segment mapping:
Segment Sections...
00 .vectors .text .picobin_block
There is no dynamic section in this file.
There are no relocations in this file.
There are no unwind sections in this file.
Symbol table '.symtab' contains 40 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 10000000 0 SECTION LOCAL DEFAULT 1 .vectors
2: 10000008 0 SECTION LOCAL DEFAULT 2 .text
3: 100000f8 0 SECTION LOCAL DEFAULT 3 .picobin_block
4: 20000000 0 SECTION LOCAL DEFAULT 4 .stack
5: 00000000 0 FILE LOCAL DEFAULT ABS gpio16_blink.o
6: 40028000 0 NOTYPE LOCAL DEFAULT ABS IO_BANK0_BASE
7: 40038000 0 NOTYPE LOCAL DEFAULT ABS PADS_BANK0_BASE
8: d0000000 0 NOTYPE LOCAL DEFAULT ABS SIO_BASE
9: 00000084 0 NOTYPE LOCAL DEFAULT ABS GPIO16_CTRL
10: 00000044 0 NOTYPE LOCAL DEFAULT ABS GPIO16_PAD
11: 00010000 0 NOTYPE LOCAL DEFAULT ABS GPIO16_BIT
12: 00000018 0 NOTYPE LOCAL DEFAULT ABS GPIO_OUT_SET
13: 00000028 0 NOTYPE LOCAL DEFAULT ABS GPIO_OUT_XOR
14: 00000038 0 NOTYPE LOCAL DEFAULT ABS GPIO_OE_SET
15: 20082000 0 NOTYPE LOCAL DEFAULT ABS STACK_TOP
16: 2007a000 0 NOTYPE LOCAL DEFAULT ABS STACK_LIMIT
17: 10000000 0 NOTYPE LOCAL DEFAULT 1 $d
18: 10000008 0 NOTYPE LOCAL DEFAULT 2 $t
19: 10000027 0 FUNC LOCAL DEFAULT 2 init_stack
20: 1000003f 0 FUNC LOCAL DEFAULT 2 enable_coprocessor
21: 10000053 0 FUNC LOCAL DEFAULT 2 gpio16_config
22: 10000014 0 NOTYPE LOCAL DEFAULT 2 blink_loop
23: 1000007d 0 FUNC LOCAL DEFAULT 2 gpio16_set
24: 10000091 0 FUNC LOCAL DEFAULT 2 delay
25: 10000087 0 FUNC LOCAL DEFAULT 2 gpio16_clear
26: 10000098 0 NOTYPE LOCAL DEFAULT 2 $d
27: 100000b0 0 NOTYPE LOCAL DEFAULT 2 $d
28: 100000f8 0 NOTYPE LOCAL DEFAULT 3 $d
29: 100000d4 0 NOTYPE LOCAL DEFAULT 2 $d
30: 00080000 0 NOTYPE GLOBAL DEFAULT ABS __SRAM_SIZE
31: 10000000 0 NOTYPE GLOBAL DEFAULT 1 _vectors
32: 20000000 0 NOTYPE GLOBAL DEFAULT ABS __SRAM_BASE
33: 10000009 30 FUNC GLOBAL DEFAULT 2 Reset_Handler
34: 00008000 0 NOTYPE GLOBAL DEFAULT ABS __STACK_SIZE
35: 20080000 0 NOTYPE GLOBAL DEFAULT 2 __StackTop
36: 20080000 0 NOTYPE GLOBAL DEFAULT ABS __stack
37: 20078000 0 NOTYPE GLOBAL DEFAULT ABS __StackLimit
38: 02000000 0 NOTYPE GLOBAL DEFAULT ABS __XIP_SIZE
39: 10000000 0 NOTYPE GLOBAL DEFAULT ABS __XIP_BASE
No version information found in this file.

View File

@@ -0,0 +1,20 @@
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: ARM
Version: 0x1
Entry point address: 0x10000009
Start of program headers: 52 (bytes into file)
Start of section headers: 5424 (bytes into file)
Flags: 0x5000200, Version5 EABI, soft-float ABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 1
Size of section headers: 40 (bytes)
Number of section headers: 8
Section header string table index: 7

View File

@@ -0,0 +1,2 @@
There are no relocations in this file.

View File

@@ -0,0 +1,17 @@
There are 8 section headers, starting at offset 0x1530:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .vectors PROGBITS 10000000 001000 000008 00 AX 0 0 4
[ 2] .text PROGBITS 10000008 001008 0000f0 00 AX 0 0 4
[ 3] .picobin_block PROGBITS 100000f8 0010f8 000014 00 A 0 0 1
[ 4] .stack PROGBITS 20000000 00110c 000000 00 W 0 0 1
[ 5] .symtab SYMTAB 00000000 00110c 000280 10 6 30 4
[ 6] .strtab STRTAB 00000000 00138c 000162 00 0 0 1
[ 7] .shstrtab STRTAB 00000000 0014ee 000040 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
D (mbind), y (purecode), p (processor specific)

View File

@@ -0,0 +1,43 @@
Symbol table '.symtab' contains 40 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 10000000 0 SECTION LOCAL DEFAULT 1 .vectors
2: 10000008 0 SECTION LOCAL DEFAULT 2 .text
3: 100000f8 0 SECTION LOCAL DEFAULT 3 .picobin_block
4: 20000000 0 SECTION LOCAL DEFAULT 4 .stack
5: 00000000 0 FILE LOCAL DEFAULT ABS gpio16_blink.o
6: 40028000 0 NOTYPE LOCAL DEFAULT ABS IO_BANK0_BASE
7: 40038000 0 NOTYPE LOCAL DEFAULT ABS PADS_BANK0_BASE
8: d0000000 0 NOTYPE LOCAL DEFAULT ABS SIO_BASE
9: 00000084 0 NOTYPE LOCAL DEFAULT ABS GPIO16_CTRL
10: 00000044 0 NOTYPE LOCAL DEFAULT ABS GPIO16_PAD
11: 00010000 0 NOTYPE LOCAL DEFAULT ABS GPIO16_BIT
12: 00000018 0 NOTYPE LOCAL DEFAULT ABS GPIO_OUT_SET
13: 00000028 0 NOTYPE LOCAL DEFAULT ABS GPIO_OUT_XOR
14: 00000038 0 NOTYPE LOCAL DEFAULT ABS GPIO_OE_SET
15: 20082000 0 NOTYPE LOCAL DEFAULT ABS STACK_TOP
16: 2007a000 0 NOTYPE LOCAL DEFAULT ABS STACK_LIMIT
17: 10000000 0 NOTYPE LOCAL DEFAULT 1 $d
18: 10000008 0 NOTYPE LOCAL DEFAULT 2 $t
19: 10000027 0 FUNC LOCAL DEFAULT 2 init_stack
20: 1000003f 0 FUNC LOCAL DEFAULT 2 enable_coprocessor
21: 10000053 0 FUNC LOCAL DEFAULT 2 gpio16_config
22: 10000014 0 NOTYPE LOCAL DEFAULT 2 blink_loop
23: 1000007d 0 FUNC LOCAL DEFAULT 2 gpio16_set
24: 10000091 0 FUNC LOCAL DEFAULT 2 delay
25: 10000087 0 FUNC LOCAL DEFAULT 2 gpio16_clear
26: 10000098 0 NOTYPE LOCAL DEFAULT 2 $d
27: 100000b0 0 NOTYPE LOCAL DEFAULT 2 $d
28: 100000f8 0 NOTYPE LOCAL DEFAULT 3 $d
29: 100000d4 0 NOTYPE LOCAL DEFAULT 2 $d
30: 00080000 0 NOTYPE GLOBAL DEFAULT ABS __SRAM_SIZE
31: 10000000 0 NOTYPE GLOBAL DEFAULT 1 _vectors
32: 20000000 0 NOTYPE GLOBAL DEFAULT ABS __SRAM_BASE
33: 10000009 30 FUNC GLOBAL DEFAULT 2 Reset_Handler
34: 00008000 0 NOTYPE GLOBAL DEFAULT ABS __STACK_SIZE
35: 20080000 0 NOTYPE GLOBAL DEFAULT 2 __StackTop
36: 20080000 0 NOTYPE GLOBAL DEFAULT ABS __stack
37: 20078000 0 NOTYPE GLOBAL DEFAULT ABS __StackLimit
38: 02000000 0 NOTYPE GLOBAL DEFAULT ABS __XIP_SIZE
39: 10000000 0 NOTYPE GLOBAL DEFAULT ABS __XIP_BASE

View File

@@ -0,0 +1,2 @@
text data bss dec hex filename
268 0 0 268 10c gpio16_blink.elf

View File

@@ -0,0 +1,43 @@
D@pG
@@pG
@@pG
aeabi
Cortex-M33
aeabi
Cortex-M33
gpio16_blink.o
IO_BANK0_BASE
PADS_BANK0_BASE
SIO_BASE
GPIO16_CTRL
GPIO16_PAD
GPIO16_BIT
GPIO_OUT_SET
GPIO_OUT_XOR
GPIO_OE_SET
STACK_TOP
STACK_LIMIT
init_stack
enable_coprocessor
gpio16_config
blink_loop
gpio16_set
delay
gpio16_clear
__SRAM_SIZE
_vectors
__SRAM_BASE
Reset_Handler
__STACK_SIZE
__StackTop
__stack
__StackLimit
__XIP_SIZE
__XIP_BASE
.symtab
.strtab
.shstrtab
.vectors
.text
.picobin_block
.stack

View File

@@ -0,0 +1,365 @@
#!/usr/bin/env python3
import sys
import struct
import subprocess
import re
import os
import os.path
import argparse
import json
from time import sleep
UF2_MAGIC_START0 = 0x0A324655 # "UF2\n"
UF2_MAGIC_START1 = 0x9E5D5157 # Randomly selected
UF2_MAGIC_END = 0x0AB16F30 # Ditto
INFO_FILE = "/INFO_UF2.TXT"
appstartaddr = 0x2000
familyid = 0x0
def is_uf2(buf):
w = struct.unpack("<II", buf[0:8])
return w[0] == UF2_MAGIC_START0 and w[1] == UF2_MAGIC_START1
def is_hex(buf):
try:
w = buf[0:30].decode("utf-8")
except UnicodeDecodeError:
return False
if w[0] == ':' and re.match(rb"^[:0-9a-fA-F\r\n]+$", buf):
return True
return False
def convert_from_uf2(buf):
global appstartaddr
global familyid
numblocks = len(buf) // 512
curraddr = None
currfamilyid = None
families_found = {}
prev_flag = None
all_flags_same = True
outp = []
for blockno in range(numblocks):
ptr = blockno * 512
block = buf[ptr:ptr + 512]
hd = struct.unpack(b"<IIIIIIII", block[0:32])
if hd[0] != UF2_MAGIC_START0 or hd[1] != UF2_MAGIC_START1:
print("Skipping block at " + ptr + "; bad magic")
continue
if hd[2] & 1:
# NO-flash flag set; skip block
continue
datalen = hd[4]
if datalen > 476:
assert False, "Invalid UF2 data size at " + ptr
newaddr = hd[3]
if (hd[2] & 0x2000) and (currfamilyid == None):
currfamilyid = hd[7]
if curraddr == None or ((hd[2] & 0x2000) and hd[7] != currfamilyid):
currfamilyid = hd[7]
curraddr = newaddr
if familyid == 0x0 or familyid == hd[7]:
appstartaddr = newaddr
padding = newaddr - curraddr
if padding < 0:
assert False, "Block out of order at " + ptr
if padding > 10*1024*1024:
assert False, "More than 10M of padding needed at " + ptr
if padding % 4 != 0:
assert False, "Non-word padding size at " + ptr
while padding > 0:
padding -= 4
outp.append(b"\x00\x00\x00\x00")
if familyid == 0x0 or ((hd[2] & 0x2000) and familyid == hd[7]):
outp.append(block[32 : 32 + datalen])
curraddr = newaddr + datalen
if hd[2] & 0x2000:
if hd[7] in families_found.keys():
if families_found[hd[7]] > newaddr:
families_found[hd[7]] = newaddr
else:
families_found[hd[7]] = newaddr
if prev_flag == None:
prev_flag = hd[2]
if prev_flag != hd[2]:
all_flags_same = False
if blockno == (numblocks - 1):
print("--- UF2 File Header Info ---")
families = load_families()
for family_hex in families_found.keys():
family_short_name = ""
for name, value in families.items():
if value == family_hex:
family_short_name = name
print("Family ID is {:s}, hex value is 0x{:08x}".format(family_short_name,family_hex))
print("Target Address is 0x{:08x}".format(families_found[family_hex]))
if all_flags_same:
print("All block flag values consistent, 0x{:04x}".format(hd[2]))
else:
print("Flags were not all the same")
print("----------------------------")
if len(families_found) > 1 and familyid == 0x0:
outp = []
appstartaddr = 0x0
return b"".join(outp)
def convert_to_carray(file_content):
outp = "const unsigned long bindata_len = %d;\n" % len(file_content)
outp += "const unsigned char bindata[] __attribute__((aligned(16))) = {"
for i in range(len(file_content)):
if i % 16 == 0:
outp += "\n"
outp += "0x%02x, " % file_content[i]
outp += "\n};\n"
return bytes(outp, "utf-8")
def convert_to_uf2(file_content):
global familyid
datapadding = b""
while len(datapadding) < 512 - 256 - 32 - 4:
datapadding += b"\x00\x00\x00\x00"
numblocks = (len(file_content) + 255) // 256
outp = []
for blockno in range(numblocks):
ptr = 256 * blockno
chunk = file_content[ptr:ptr + 256]
flags = 0x0
if familyid:
flags |= 0x2000
hd = struct.pack(b"<IIIIIIII",
UF2_MAGIC_START0, UF2_MAGIC_START1,
flags, ptr + appstartaddr, 256, blockno, numblocks, familyid)
while len(chunk) < 256:
chunk += b"\x00"
block = hd + chunk + datapadding + struct.pack(b"<I", UF2_MAGIC_END)
assert len(block) == 512
outp.append(block)
return b"".join(outp)
class Block:
def __init__(self, addr, default_data=0xFF):
self.addr = addr
self.bytes = bytearray([default_data] * 256)
def encode(self, blockno, numblocks):
global familyid
flags = 0x0
if familyid:
flags |= 0x2000
hd = struct.pack("<IIIIIIII",
UF2_MAGIC_START0, UF2_MAGIC_START1,
flags, self.addr, 256, blockno, numblocks, familyid)
hd += self.bytes[0:256]
while len(hd) < 512 - 4:
hd += b"\x00"
hd += struct.pack("<I", UF2_MAGIC_END)
return hd
def convert_from_hex_to_uf2(buf):
global appstartaddr
appstartaddr = None
upper = 0
currblock = None
blocks = []
for line in buf.split('\n'):
if line[0] != ":":
continue
i = 1
rec = []
while i < len(line) - 1:
rec.append(int(line[i:i+2], 16))
i += 2
tp = rec[3]
if tp == 4:
upper = ((rec[4] << 8) | rec[5]) << 16
elif tp == 2:
upper = ((rec[4] << 8) | rec[5]) << 4
elif tp == 1:
break
elif tp == 0:
addr = upper + ((rec[1] << 8) | rec[2])
if appstartaddr == None:
appstartaddr = addr
i = 4
while i < len(rec) - 1:
if not currblock or currblock.addr & ~0xff != addr & ~0xff:
currblock = Block(addr & ~0xff)
blocks.append(currblock)
currblock.bytes[addr & 0xff] = rec[i]
addr += 1
i += 1
numblocks = len(blocks)
resfile = b""
for i in range(0, numblocks):
resfile += blocks[i].encode(i, numblocks)
return resfile
def to_str(b):
return b.decode("utf-8")
def get_drives():
drives = []
if sys.platform == "win32":
r = subprocess.check_output([
"powershell",
"-Command",
'(Get-WmiObject Win32_LogicalDisk -Filter "VolumeName=\'RPI-RP2\'").DeviceID'
])
drive = to_str(r).strip()
if drive:
drives.append(drive)
else:
searchpaths = ["/mnt", "/media"]
if sys.platform == "darwin":
searchpaths = ["/Volumes"]
elif sys.platform == "linux":
searchpaths += ["/media/" + os.environ["USER"], "/run/media/" + os.environ["USER"]]
if "SUDO_USER" in os.environ.keys():
searchpaths += ["/media/" + os.environ["SUDO_USER"]]
searchpaths += ["/run/media/" + os.environ["SUDO_USER"]]
for rootpath in searchpaths:
if os.path.isdir(rootpath):
for d in os.listdir(rootpath):
if os.path.isdir(os.path.join(rootpath, d)):
drives.append(os.path.join(rootpath, d))
def has_info(d):
try:
return os.path.isfile(d + INFO_FILE)
except:
return False
return list(filter(has_info, drives))
def board_id(path):
with open(path + INFO_FILE, mode='r') as file:
file_content = file.read()
return re.search(r"Board-ID: ([^\r\n]*)", file_content).group(1)
def list_drives():
for d in get_drives():
print(d, board_id(d))
def write_file(name, buf):
with open(name, "wb") as f:
f.write(buf)
print("Wrote %d bytes to %s" % (len(buf), name))
def load_families():
# The expectation is that the `uf2families.json` file is in the same
# directory as this script. Make a path that works using `__file__`
# which contains the full path to this script.
filename = "uf2families.json"
pathname = os.path.join(os.path.dirname(os.path.abspath(__file__)), filename)
with open(pathname) as f:
raw_families = json.load(f)
families = {}
for family in raw_families:
families[family["short_name"]] = int(family["id"], 0)
return families
def main():
global appstartaddr, familyid
def error(msg):
print(msg, file=sys.stderr)
sys.exit(1)
parser = argparse.ArgumentParser(description='Convert to UF2 or flash directly.')
parser.add_argument('input', metavar='INPUT', type=str, nargs='?',
help='input file (HEX, BIN or UF2)')
parser.add_argument('-b', '--base', dest='base', type=str,
default="0x2000",
help='set base address of application for BIN format (default: 0x2000)')
parser.add_argument('-f', '--family', dest='family', type=str,
default="0x0",
help='specify familyID - number or name (default: 0x0)')
parser.add_argument('-o', '--output', metavar="FILE", dest='output', type=str,
help='write output to named file; defaults to "flash.uf2" or "flash.bin" where sensible')
parser.add_argument('-d', '--device', dest="device_path",
help='select a device path to flash')
parser.add_argument('-l', '--list', action='store_true',
help='list connected devices')
parser.add_argument('-c', '--convert', action='store_true',
help='do not flash, just convert')
parser.add_argument('-D', '--deploy', action='store_true',
help='just flash, do not convert')
parser.add_argument('-w', '--wait', action='store_true',
help='wait for device to flash')
parser.add_argument('-C', '--carray', action='store_true',
help='convert binary file to a C array, not UF2')
parser.add_argument('-i', '--info', action='store_true',
help='display header information from UF2, do not convert')
args = parser.parse_args()
appstartaddr = int(args.base, 0)
families = load_families()
if args.family.upper() in families:
familyid = families[args.family.upper()]
else:
try:
familyid = int(args.family, 0)
except ValueError:
error("Family ID needs to be a number or one of: " + ", ".join(families.keys()))
if args.list:
list_drives()
else:
if not args.input:
error("Need input file")
with open(args.input, mode='rb') as f:
inpbuf = f.read()
from_uf2 = is_uf2(inpbuf)
ext = "uf2"
if args.deploy:
outbuf = inpbuf
elif from_uf2 and not args.info:
outbuf = convert_from_uf2(inpbuf)
ext = "bin"
elif from_uf2 and args.info:
outbuf = ""
convert_from_uf2(inpbuf)
elif is_hex(inpbuf):
outbuf = convert_from_hex_to_uf2(inpbuf.decode("utf-8"))
elif args.carray:
outbuf = convert_to_carray(inpbuf)
ext = "h"
else:
outbuf = convert_to_uf2(inpbuf)
if not args.deploy and not args.info:
print("Converted to %s, output size: %d, start address: 0x%x" %
(ext, len(outbuf), appstartaddr))
if args.convert or ext != "uf2":
if args.output == None:
args.output = "flash." + ext
if args.output:
write_file(args.output, outbuf)
if ext == "uf2" and not args.convert and not args.info:
drives = get_drives()
if len(drives) == 0:
if args.wait:
print("Waiting for drive to deploy...")
while len(drives) == 0:
sleep(0.1)
drives = get_drives()
elif not args.output:
error("No drive to deploy.")
for d in drives:
print("Flashing %s (%s)" % (d, board_id(d)))
write_file(d + "/NEW.UF2", outbuf)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,382 @@
[
{
"id": "0x16573617",
"short_name": "ATMEGA32",
"description": "Microchip (Atmel) ATmega32"
},
{
"id": "0x1851780a",
"short_name": "SAML21",
"description": "Microchip (Atmel) SAML21"
},
{
"id": "0x1b57745f",
"short_name": "NRF52",
"description": "Nordic NRF52"
},
{
"id": "0x1c5f21b0",
"short_name": "ESP32",
"description": "ESP32"
},
{
"id": "0x1e1f432d",
"short_name": "STM32L1",
"description": "ST STM32L1xx"
},
{
"id": "0x202e3a91",
"short_name": "STM32L0",
"description": "ST STM32L0xx"
},
{
"id": "0x21460ff0",
"short_name": "STM32WL",
"description": "ST STM32WLxx"
},
{
"id": "0x22e0d6fc",
"short_name": "RTL8710B",
"description": "Realtek AmebaZ RTL8710B"
},
{
"id": "0x2abc77ec",
"short_name": "LPC55",
"description": "NXP LPC55xx"
},
{
"id": "0x300f5633",
"short_name": "STM32G0",
"description": "ST STM32G0xx"
},
{
"id": "0x31d228c6",
"short_name": "GD32F350",
"description": "GD32F350"
},
{
"id": "0x3379CFE2",
"short_name": "RTL8720D",
"description": "Realtek AmebaD RTL8720D"
},
{
"id": "0x04240bdf",
"short_name": "STM32L5",
"description": "ST STM32L5xx"
},
{
"id": "0x4c71240a",
"short_name": "STM32G4",
"description": "ST STM32G4xx"
},
{
"id": "0x4fb2d5bd",
"short_name": "MIMXRT10XX",
"description": "NXP i.MX RT10XX"
},
{
"id": "0x51e903a8",
"short_name": "XR809",
"description": "Xradiotech 809"
},
{
"id": "0x53b80f00",
"short_name": "STM32F7",
"description": "ST STM32F7xx"
},
{
"id": "0x55114460",
"short_name": "SAMD51",
"description": "Microchip (Atmel) SAMD51"
},
{
"id": "0x57755a57",
"short_name": "STM32F4",
"description": "ST STM32F4xx"
},
{
"id": "0x5a18069b",
"short_name": "FX2",
"description": "Cypress FX2"
},
{
"id": "0x5d1a0a2e",
"short_name": "STM32F2",
"description": "ST STM32F2xx"
},
{
"id": "0x5ee21072",
"short_name": "STM32F1",
"description": "ST STM32F103"
},
{
"id": "0x621e937a",
"short_name": "NRF52833",
"description": "Nordic NRF52833"
},
{
"id": "0x647824b6",
"short_name": "STM32F0",
"description": "ST STM32F0xx"
},
{
"id": "0x675a40b0",
"short_name": "BK7231U",
"description": "Beken 7231U/7231T"
},
{
"id": "0x68ed2b88",
"short_name": "SAMD21",
"description": "Microchip (Atmel) SAMD21"
},
{
"id": "0x6a82cc42",
"short_name": "BK7251",
"description": "Beken 7251/7252"
},
{
"id": "0x6b846188",
"short_name": "STM32F3",
"description": "ST STM32F3xx"
},
{
"id": "0x6d0922fa",
"short_name": "STM32F407",
"description": "ST STM32F407"
},
{
"id": "0x4e8f1c5d",
"short_name": "STM32H5",
"description": "ST STM32H5xx"
},
{
"id": "0x6db66082",
"short_name": "STM32H7",
"description": "ST STM32H7xx"
},
{
"id": "0x70d16653",
"short_name": "STM32WB",
"description": "ST STM32WBxx"
},
{
"id": "0x7b3ef230",
"short_name": "BK7231N",
"description": "Beken 7231N"
},
{
"id": "0x7eab61ed",
"short_name": "ESP8266",
"description": "ESP8266"
},
{
"id": "0x7f83e793",
"short_name": "KL32L2",
"description": "NXP KL32L2x"
},
{
"id": "0x8fb060fe",
"short_name": "STM32F407VG",
"description": "ST STM32F407VG"
},
{
"id": "0x9fffd543",
"short_name": "RTL8710A",
"description": "Realtek Ameba1 RTL8710A"
},
{
"id": "0xada52840",
"short_name": "NRF52840",
"description": "Nordic NRF52840"
},
{
"id": "0x820d9a5f",
"short_name": "NRF52820",
"description": "Nordic NRF52820_xxAA"
},
{
"id": "0xbfdd4eee",
"short_name": "ESP32S2",
"description": "ESP32-S2"
},
{
"id": "0xc47e5767",
"short_name": "ESP32S3",
"description": "ESP32-S3"
},
{
"id": "0xd42ba06c",
"short_name": "ESP32C3",
"description": "ESP32-C3"
},
{
"id": "0x2b88d29c",
"short_name": "ESP32C2",
"description": "ESP32-C2"
},
{
"id": "0x332726f6",
"short_name": "ESP32H2",
"description": "ESP32-H2"
},
{
"id": "0x540ddf62",
"short_name": "ESP32C6",
"description": "ESP32-C6"
},
{
"id": "0x3d308e94",
"short_name": "ESP32P4",
"description": "ESP32-P4"
},
{
"id": "0xf71c0343",
"short_name": "ESP32C5",
"description": "ESP32-C5"
},
{
"id": "0x77d850c4",
"short_name": "ESP32C61",
"description": "ESP32-C61"
},
{
"id": "0xb6dd00af",
"short_name": "ESP32H21",
"description": "ESP32-H21"
},
{
"id": "0x9e0baa8a",
"short_name": "ESP32H4",
"description": "ESP32-H4"
},
{
"id": "0xde1270b7",
"short_name": "BL602",
"description": "Boufallo 602"
},
{
"id": "0xe08f7564",
"short_name": "RTL8720C",
"description": "Realtek AmebaZ2 RTL8720C"
},
{
"id": "0xe48bff56",
"short_name": "RP2040",
"description": "Raspberry Pi RP2040"
},
{
"id": "0xe48bff57",
"short_name": "RP2XXX_ABSOLUTE",
"description": "Raspberry Pi Microcontrollers: Absolute (unpartitioned) download"
},
{
"id": "0xe48bff58",
"short_name": "RP2XXX_DATA",
"description": "Raspberry Pi Microcontrollers: Data partition download"
},
{
"id": "0xe48bff59",
"short_name": "RP2350_ARM_S",
"description": "Raspberry Pi RP2350, Secure Arm image"
},
{
"id": "0xe48bff5a",
"short_name": "RP2350_RISCV",
"description": "Raspberry Pi RP2350, RISC-V image"
},
{
"id": "0xe48bff5b",
"short_name": "RP2350_ARM_NS",
"description": "Raspberry Pi RP2350, Non-secure Arm image"
},
{
"id": "0x00ff6919",
"short_name": "STM32L4",
"description": "ST STM32L4xx"
},
{
"id": "0x9af03e33",
"short_name": "GD32VF103",
"description": "GigaDevice GD32VF103"
},
{
"id": "0x4f6ace52",
"short_name": "CSK4",
"description": "LISTENAI CSK300x/400x"
},
{
"id": "0x6e7348a8",
"short_name": "CSK6",
"description": "LISTENAI CSK60xx"
},
{
"id": "0x11de784a",
"short_name": "M0SENSE",
"description": "M0SENSE BL702"
},
{
"id": "0x4b684d71",
"short_name": "MaixPlay-U4",
"description": "Sipeed MaixPlay-U4(BL618)"
},
{
"id": "0x9517422f",
"short_name": "RZA1LU",
"description": "Renesas RZ/A1LU (R7S7210xx)"
},
{
"id": "0x2dc309c5",
"short_name": "STM32F411xE",
"description": "ST STM32F411xE"
},
{
"id": "0x06d1097b",
"short_name": "STM32F411xC",
"description": "ST STM32F411xC"
},
{
"id": "0x72721d4e",
"short_name": "NRF52832xxAA",
"description": "Nordic NRF52832xxAA"
},
{
"id": "0x6f752678",
"short_name": "NRF52832xxAB",
"description": "Nordic NRF52832xxAB"
},
{
"id": "0xa0c97b8e",
"short_name": "AT32F415",
"description": "ArteryTek AT32F415"
},
{
"id": "0x699b62ec",
"short_name": "CH32V",
"description": "WCH CH32V2xx and CH32V3xx"
},
{
"id": "0x7be8976d",
"short_name": "RA4M1",
"description": "Renesas RA4M1"
},
{
"id": "0x7410520a",
"short_name": "MAX32690",
"description": "Analog Devices MAX32690"
},
{
"id": "0xd63f8632",
"short_name": "MAX32650",
"description": "Analog Devices MAX32650/1/2"
},
{
"id": "0xf0c30d71",
"short_name": "MAX32666",
"description": "Analog Devices MAX32665/6"
},
{
"id": "0x91d3fd18",
"short_name": "MAX78002",
"description": "Analog Devices MAX78002"
}
]