Refactor Rust drivers for strict idiomatic documentation and 8-line enforcement

This commit is contained in:
Kevin Thomas
2023-10-06 14:27:20 -04:00
commit 46e8b76762
1231 changed files with 110385 additions and 0 deletions
+22
View File
@@ -0,0 +1,22 @@
{
"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
}
+15
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}"
}
}
]
+9
View File
@@ -0,0 +1,9 @@
{
"recommendations": [
"marus25.cortex-debug",
"ms-vscode.cpptools",
"ms-vscode.cpptools-extension-pack",
"ms-vscode.vscode-serial-monitor",
"raspberry-pi.raspberry-pi-pico"
]
}
+50
View File
@@ -0,0 +1,50 @@
{
"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}\""
]
},
]
}
+43
View File
@@ -0,0 +1,43 @@
{
"cmake.showSystemKits": false,
"cmake.options.statusBarVisibility": "hidden",
"cmake.options.advanced": {
"build": {
"statusBarVisibility": "hidden"
},
"launch": {
"statusBarVisibility": "hidden"
},
"debug": {
"statusBarVisibility": "hidden"
}
},
"cmake.configureOnEdit": false,
"cmake.automaticReconfigure": false,
"cmake.configureOnOpen": false,
"cmake.generator": "Ninja",
"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",
"files.associations": {
"stdlib.h": "c"
}
}
+125
View File
@@ -0,0 +1,125 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Compile Project",
"type": "process",
"isBuildCommand": true,
"dependsOn": "Configure Project",
"dependsOrder": "sequence",
"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": "Configure Project",
"type": "process",
"command": "${userHome}/.pico-sdk/cmake/v3.31.5/bin/cmake",
"args": [
"-S",
"${workspaceFolder}",
"-B",
"${workspaceFolder}/build",
"-G",
"Ninja"
],
"presentation": {
"reveal": "always",
"panel": "dedicated"
},
"problemMatcher": "$gcc",
"windows": {
"command": "${env:USERPROFILE}/.pico-sdk/cmake/v3.31.5/bin/cmake.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",
}
}
]
}
+22
View File
@@ -0,0 +1,22 @@
{
"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
}
+15
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}"
}
}
]
+9
View File
@@ -0,0 +1,9 @@
{
"recommendations": [
"marus25.cortex-debug",
"ms-vscode.cpptools",
"ms-vscode.cpptools-extension-pack",
"ms-vscode.vscode-serial-monitor",
"raspberry-pi.raspberry-pi-pico"
]
}
+50
View File
@@ -0,0 +1,50 @@
{
"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}\""
]
},
]
}
+43
View File
@@ -0,0 +1,43 @@
{
"cmake.showSystemKits": false,
"cmake.options.statusBarVisibility": "hidden",
"cmake.options.advanced": {
"build": {
"statusBarVisibility": "hidden"
},
"launch": {
"statusBarVisibility": "hidden"
},
"debug": {
"statusBarVisibility": "hidden"
}
},
"cmake.configureOnEdit": false,
"cmake.automaticReconfigure": false,
"cmake.configureOnOpen": false,
"cmake.generator": "Ninja",
"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",
"files.associations": {
"stdlib.h": "c"
}
}
+125
View File
@@ -0,0 +1,125 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Compile Project",
"type": "process",
"isBuildCommand": true,
"dependsOn": "Configure Project",
"dependsOrder": "sequence",
"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": "Configure Project",
"type": "process",
"command": "${userHome}/.pico-sdk/cmake/v3.31.5/bin/cmake",
"args": [
"-S",
"${workspaceFolder}",
"-B",
"${workspaceFolder}/build",
"-G",
"Ninja"
],
"presentation": {
"reveal": "always",
"panel": "dedicated"
},
"problemMatcher": "$gcc",
"windows": {
"command": "${env:USERPROFILE}/.pico-sdk/cmake/v3.31.5/bin/cmake.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",
}
}
]
}
+63
View File
@@ -0,0 +1,63 @@
/**
* @file 0x01_uart.c
* @brief UART demonstration: echo received characters back in uppercase
* @author Kevin Thomas
* @date 2025
*
* MIT License
*
* Copyright (c) 2025 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* -----------------------------------------------------------------------------
*
* Demonstrates hardware UART0 using the uart driver (uart.h / uart.c).
* Characters typed into a terminal via a USB-to-UART adapter are echoed
* back in uppercase, illustrating full-duplex raw UART operation without
* going through the stdio layer.
*
* Wiring:
* GPIO0 (TX) -> USB-to-UART adapter RX
* GPIO1 (RX) -> USB-to-UART adapter TX
* GND -> USB-to-UART adapter GND
*/
#include "pico/stdlib.h"
#include "uart.h"
/** @brief GPIO pin used for UART0 TX */
#define UART_TX_PIN 0
/** @brief GPIO pin used for UART0 RX */
#define UART_RX_PIN 1
/** @brief UART baud rate in bits per second */
#define UART_BAUD 115200
int main(void) {
uart_driver_init(UART_TX_PIN, UART_RX_PIN, UART_BAUD);
uart_driver_puts("UART driver ready (115200 8N1)\r\n");
uart_driver_puts("Type characters to echo them back in UPPERCASE:\r\n");
while (true) {
if (uart_driver_is_readable()) {
char c = uart_driver_getchar();
char upper = uart_driver_to_upper(c);
uart_driver_putchar(upper);
}
}
}
+57
View File
@@ -0,0 +1,57 @@
# Generated Cmake Pico project file
cmake_minimum_required(VERSION 3.13)
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(0x01_uart C CXX ASM)
# Initialise the Raspberry Pi Pico SDK
pico_sdk_init()
# Add executable. Default name is the project name, version 0.1
add_executable(0x01_uart 0x01_uart.c uart.c)
pico_set_program_name(0x01_uart "0x01_uart")
pico_set_program_version(0x01_uart "0.1")
# Disable stdio routing - driver uses hardware UART0 directly (GPIO0/GPIO1)
pico_enable_stdio_uart(0x01_uart 0)
pico_enable_stdio_usb(0x01_uart 0)
# Add the standard library to the build
target_link_libraries(0x01_uart
pico_stdlib
hardware_uart)
# Add the standard include files to the build
target_include_directories(0x01_uart PRIVATE
${CMAKE_CURRENT_LIST_DIR}
)
pico_add_extra_outputs(0x01_uart)
+121
View File
@@ -0,0 +1,121 @@
# This is a copy of <PICO_SDK_PATH>/external/pico_sdk_import.cmake
# 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}')")
endif ()
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT))
set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT})
message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')")
endif ()
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH))
set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH})
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)
include(FetchContent)
set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR})
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 ()
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")
# 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})
else ()
message(FATAL_ERROR
"SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git."
)
endif ()
endif ()
get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
if (NOT EXISTS ${PICO_SDK_PATH})
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found")
endif ()
set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake)
if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE})
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK")
endif ()
set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE)
include(${PICO_SDK_INIT_CMAKE_FILE})
+67
View File
@@ -0,0 +1,67 @@
/**
* @file uart.c
* @brief Implementation of the hardware UART0 driver
* @author Kevin Thomas
* @date 2025
*
* MIT License
*
* Copyright (c) 2025 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "uart.h"
#include "pico/stdlib.h"
#include "hardware/uart.h"
#include "hardware/gpio.h"
/** @brief Hardware UART instance used by this driver */
#define UART_INST uart0
void uart_driver_init(uint32_t tx_pin, uint32_t rx_pin, uint32_t baud_rate) {
uart_init(UART_INST, baud_rate);
gpio_set_function(tx_pin, GPIO_FUNC_UART);
gpio_set_function(rx_pin, GPIO_FUNC_UART);
}
bool uart_driver_is_readable(void) {
return uart_is_readable(UART_INST);
}
char uart_driver_getchar(void) {
return (char)uart_getc(UART_INST);
}
void uart_driver_putchar(char c) {
uart_putc_raw(UART_INST, c);
}
void uart_driver_puts(const char *str) {
while (*str) {
uart_putc_raw(UART_INST, *str++);
}
}
char uart_driver_to_upper(char c) {
if (c >= 'a' && c <= 'z') {
return (char)(c - 32);
}
return c;
}
+100
View File
@@ -0,0 +1,100 @@
/**
* @file uart.h
* @brief Header for hardware UART0 driver (raw TX/RX, GPIO 0/1)
* @author Kevin Thomas
* @date 2025
*
* MIT License
*
* Copyright (c) 2025 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef UART_H
#define UART_H
#include <stdint.h>
#include <stdbool.h>
/**
* @brief Initialize hardware UART0 on the specified TX and RX GPIO pins
*
* Configures UART0 at the requested baud rate, sets the GPIO alternate
* functions for TX and RX, and enables 8N1 framing. Must be called once
* before using any other uart_driver_* functions.
*
* @param tx_pin GPIO pin number to use as UART0 TX (typically 0)
* @param rx_pin GPIO pin number to use as UART0 RX (typically 1)
* @param baud_rate Desired baud rate in bits per second (e.g. 115200)
*/
void uart_driver_init(uint32_t tx_pin, uint32_t rx_pin, uint32_t baud_rate);
/**
* @brief Check whether a received character is waiting in the UART FIFO
*
* Returns immediately without blocking. Use this to poll for incoming
* data before calling uart_driver_getchar().
*
* @return bool true if at least one byte is available to read, false otherwise
*/
bool uart_driver_is_readable(void);
/**
* @brief Read one character from UART0 (blocking)
*
* Blocks until a byte arrives in the receive FIFO, then returns it.
* Prefer pairing with uart_driver_is_readable() to avoid indefinite blocking.
*
* @return char The received character
*/
char uart_driver_getchar(void);
/**
* @brief Transmit one character over UART0 (blocking)
*
* Waits until the transmit FIFO has space, then places the character into the
* FIFO. Returns once the byte has been accepted by the hardware.
*
* @param c Character to transmit
*/
void uart_driver_putchar(char c);
/**
* @brief Transmit a null-terminated string over UART0
*
* Calls uart_driver_putchar() for every character in the string up to and
* not including the null terminator.
*
* @param str Pointer to the null-terminated ASCII string to send
*/
void uart_driver_puts(const char *str);
/**
* @brief Convert a lowercase ASCII character to uppercase
*
* Returns the uppercase equivalent if the character is in 'a'-'z';
* all other characters are passed through unchanged.
*
* @param c Input character
* @return char Uppercase equivalent, or the original character
*/
char uart_driver_to_upper(char c);
#endif // UART_H
+45
View File
@@ -0,0 +1,45 @@
{
"configurations": [
{
"name": "ARM GCC",
"includePath": [
"${workspaceFolder}/Inc/**"
],
"defines": [
"__GNUC__",
"__ARM_ARCH_8M_MAIN__",
"__ARMCC_VERSION"
],
"compilerPath": "${userHome}/.pico-sdk/toolchain/14_2_Rel1/bin/arm-none-eabi-gcc",
"compileCommands": "${workspaceFolder}/compile_commands.json",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "gcc-arm",
"compilerArgs": [
"-mcpu=cortex-m33",
"-mthumb"
]
},
{
"name": "ARM GCC (Windows)",
"includePath": [
"${workspaceFolder}/Inc/**"
],
"defines": [
"__GNUC__",
"__ARM_ARCH_8M_MAIN__",
"__ARMCC_VERSION"
],
"compilerPath": "${env:USERPROFILE}/.pico-sdk/toolchain/14_2_Rel1/bin/arm-none-eabi-gcc.exe",
"compileCommands": "${workspaceFolder}/compile_commands.json",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "gcc-arm",
"compilerArgs": [
"-mcpu=cortex-m33",
"-mthumb"
]
}
],
"version": 4
}
+9
View File
@@ -0,0 +1,9 @@
{
"recommendations": [
"marus25.cortex-debug",
"ms-vscode.cpptools",
"ms-vscode.cpptools-extension-pack",
"ms-vscode.vscode-serial-monitor",
"raspberry-pi.raspberry-pi-pico"
]
}
+47
View File
@@ -0,0 +1,47 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug RP2350 (OpenOCD)",
"cwd": "${workspaceFolder}",
"executable": "${workspaceFolder}/build/uart.elf",
"request": "launch",
"type": "cortex-debug",
"servertype": "openocd",
"serverpath": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd",
"searchDir": [
"${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts"
],
"gdbPath": "${userHome}/.pico-sdk/toolchain/14_2_Rel1/bin/arm-none-eabi-gdb",
"device": "RP2350",
"configFiles": [
"interface/cmsis-dap.cfg",
"target/rp2350.cfg"
],
"svdFile": "${userHome}/.pico-sdk/sdk/2.2.0/src/rp2350/hardware_regs/RP2350.svd",
"overrideLaunchCommands": [
"set arch armv8-m.main",
"set output-radix 16",
"monitor reset init",
"load",
"monitor reset halt"
],
"openOCDPreConfigLaunchCommands": [
"set USE_CORE { cm0 cm1 }"
],
"openOCDLaunchCommands": [
"adapter speed 5000"
],
"preLaunchTask": "Compile Project",
"showDevDebugOutput": "raw",
"windows": {
"serverpath": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
"searchDir": [
"${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/scripts"
],
"gdbPath": "${env:USERPROFILE}/.pico-sdk/toolchain/14_2_Rel1/bin/arm-none-eabi-gdb.exe",
"svdFile": "${env:USERPROFILE}/.pico-sdk/sdk/2.2.0/src/rp2350/hardware_regs/RP2350.svd"
}
}
]
}
+40
View File
@@ -0,0 +1,40 @@
{
"cmake.showSystemKits": false,
"cmake.options.statusBarVisibility": "hidden",
"cmake.options.advanced": {
"build": {
"statusBarVisibility": "hidden"
},
"launch": {
"statusBarVisibility": "hidden"
},
"debug": {
"statusBarVisibility": "hidden"
}
},
"cmake.configureOnEdit": false,
"cmake.automaticReconfigure": false,
"cmake.configureOnOpen": false,
"cmake.generator": "Ninja",
"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-a4/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-a4/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-a4/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"
}
+128
View File
@@ -0,0 +1,128 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Compile Project",
"type": "shell",
"command": "make",
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"reveal": "always",
"panel": "dedicated"
},
"problemMatcher": "$gcc",
"windows": {
"command": ".\\build.bat"
}
},
{
"label": "Clean Project",
"type": "shell",
"command": "make clean",
"group": "build",
"presentation": {
"reveal": "always",
"panel": "dedicated"
},
"problemMatcher": [],
"windows": {
"command": ".\\clean.bat"
}
},
{
"label": "Run Project",
"type": "shell",
"command": "${userHome}/.pico-sdk/picotool/2.2.0-a4/picotool/picotool",
"args": [
"load",
"build/uart.uf2",
"-fx"
],
"presentation": {
"reveal": "always",
"panel": "dedicated"
},
"problemMatcher": [],
"dependsOn": [
"Compile Project"
],
"windows": {
"command": "${env:USERPROFILE}/.pico-sdk/picotool/2.2.0-a4/picotool/picotool.exe"
}
},
{
"label": "Flash",
"type": "shell",
"command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd",
"args": [
"-s",
"${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts",
"-f",
"interface/cmsis-dap.cfg",
"-f",
"target/rp2350.cfg",
"-c",
"adapter speed 5000; program build/uart.elf verify reset exit"
],
"problemMatcher": [],
"dependsOn": [
"Compile Project"
],
"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",
"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",
"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"
}
}
]
}
],
"problemMatcher": []
}
]
}
+203
View File
@@ -0,0 +1,203 @@
/**
* @file rp2350.h
* @brief RP2350 Device Peripheral Access Layer Header File.
* @author Kevin Thomas
* @date 2026
*
* Memory-mapped register structures and peripheral base addresses
* for the RP2350 microcontroller (Cortex-M33 dual-core). All
* register offsets verified against the RP2350 datasheet
* (RP-008373-DS-2).
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RP2350_H
#define __RP2350_H
#include <stdint.h>
#include <stdbool.h>
/*!< Defines 'read / write' permissions */
#define __IO volatile
/*!< Stack addresses */
#define STACK_TOP 0x20082000UL
#define STACK_LIMIT 0x2007A000UL
/*!< Memory map */
#define XIP_BASE 0x10000000UL
#define SRAM_BASE 0x20000000UL
#define SIO_BASE 0xD0000000UL
#define PPB_BASE 0xE0000000UL
/*!< APB peripherals */
#define CLOCKS_BASE 0x40010000UL
#define RESETS_BASE 0x40020000UL
#define IO_BANK0_BASE 0x40028000UL
#define PADS_BANK0_BASE 0x40038000UL
#define XOSC_BASE 0x40048000UL
#define UART0_BASE 0x40070000UL
/**
* @brief XOSC (External Crystal Oscillator)
*/
typedef struct
{
__IO uint32_t CTRL; // Control register Address offset: 0x00
__IO uint32_t STATUS; // Status register Address offset: 0x04
__IO uint32_t DORMANT; // Dormant mode Address offset: 0x08
__IO uint32_t STARTUP; // Startup delay Address offset: 0x0C
__IO uint32_t COUNT; // Frequency count Address offset: 0x10
} XOSC_TypeDef;
/**
* @brief CLOCKS
*/
typedef struct
{
__IO uint32_t RESERVED0[18]; // Other clock registers Address offset: 0x00-0x44
__IO uint32_t CLK_PERI_CTRL; // Peripheral clock control Address offset: 0x48
} CLOCKS_TypeDef;
/**
* @brief RESETS
*/
typedef struct
{
__IO uint32_t RESET; // Reset control Address offset: 0x00
__IO uint32_t WDSEL; // Watchdog select Address offset: 0x04
__IO uint32_t RESET_DONE; // Reset done status Address offset: 0x08
} RESETS_TypeDef;
/**
* @brief IO_BANK0 GPIO Control (one per GPIO)
*/
typedef struct
{
__IO uint32_t STATUS; // GPIO status Address offset: 0x00
__IO uint32_t CTRL; // GPIO control Address offset: 0x04
} IO_BANK0_GPIO_TypeDef;
/**
* @brief IO_BANK0
*/
typedef struct
{
IO_BANK0_GPIO_TypeDef GPIO[30]; // GPIO 0-29 status/ctrl pairs Address offset: 0x000-0x0E8
} IO_BANK0_TypeDef;
/**
* @brief PADS_BANK0
*/
typedef struct
{
__IO uint32_t VOLTAGE_SELECT; // Voltage select Address offset: 0x00
__IO uint32_t GPIO[30]; // GPIO 0-29 pad control Address offset: 0x04-0x78
} PADS_BANK0_TypeDef;
/**
* @brief Peripheral Definitions
*/
#define XOSC ((XOSC_TypeDef *) XOSC_BASE)
#define CLOCKS ((CLOCKS_TypeDef *) CLOCKS_BASE)
#define RESETS ((RESETS_TypeDef *) RESETS_BASE)
#define IO_BANK0 ((IO_BANK0_TypeDef *) IO_BANK0_BASE)
#define PADS_BANK0 ((PADS_BANK0_TypeDef *) PADS_BANK0_BASE)
#define SIO ((volatile uint32_t *) SIO_BASE)
#define CPACR ((volatile uint32_t *) (PPB_BASE + 0x0ED88UL))
/**
* @brief XOSC bit definitions
*/
#define XOSC_STATUS_STABLE_SHIFT 31U
/**
* @brief CPACR bit definitions
*/
#define CPACR_CP0_SHIFT 0U
#define CPACR_CP1_SHIFT 1U
/**
* @brief CLOCKS bit definitions
*/
#define CLK_PERI_CTRL_ENABLE_SHIFT 11U
#define CLK_PERI_CTRL_AUXSRC_SHIFT 5U
#define CLK_PERI_CTRL_AUXSRC_XOSC 4U
/**
* @brief RESETS bit definitions
*/
#define RESETS_RESET_IO_BANK0_SHIFT 6U
#define RESETS_RESET_UART0_SHIFT 26U
/**
* @brief IO_BANK0 bit definitions
*/
#define IO_BANK0_CTRL_FUNCSEL_MASK 0x1FU
#define IO_BANK0_CTRL_FUNCSEL_UART 0x02U
#define IO_BANK0_CTRL_FUNCSEL_SIO 0x05U
/**
* @brief PADS_BANK0 bit definitions
*/
#define PADS_BANK0_OD_SHIFT 7U
#define PADS_BANK0_IE_SHIFT 6U
#define PADS_BANK0_ISO_SHIFT 8U
/**
* @brief UART register offsets (word indices from UART0_BASE)
*/
#define UART_DR_OFFSET (0x000U / 4U)
#define UART_FR_OFFSET (0x018U / 4U)
#define UART_IBRD_OFFSET (0x024U / 4U)
#define UART_FBRD_OFFSET (0x028U / 4U)
#define UART_LCR_H_OFFSET (0x02CU / 4U)
#define UART_CR_OFFSET (0x030U / 4U)
/**
* @brief UART flag register bit definitions
*/
#define UART_FR_TXFF_MASK 32U
#define UART_FR_RXFE_MASK 16U
/**
* @brief UART line control and enable values
*/
#define UART_LCR_H_8N1_FIFO 0x70U
#define UART_CR_ENABLE ((3U << 8) | 1U)
/**
* @brief GPIO pin definitions
*/
#define LED_PIN 25U
/**
* @brief SIO GPIO register offsets (word indices from SIO_BASE)
*/
#define SIO_GPIO_IN_OFFSET (0x004U / 4U)
#define SIO_GPIO_OUT_SET_OFFSET (0x018U / 4U)
#define SIO_GPIO_OUT_CLR_OFFSET (0x020U / 4U)
#define SIO_GPIO_OUT_XOR_OFFSET (0x028U / 4U)
#define SIO_GPIO_OE_SET_OFFSET (0x038U / 4U)
#endif /* __RP2350_H */
+42
View File
@@ -0,0 +1,42 @@
/**
* @file rp2350_reset.h
* @brief Reset controller driver header for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Provides subsystem reset release for IO_BANK0.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RP2350_RESET_H
#define __RP2350_RESET_H
#include "rp2350.h"
/**
* @brief Release IO_BANK0 from reset and wait until ready.
* @retval None
*/
void reset_init_subsystem(void);
#endif /* __RP2350_RESET_H */
@@ -0,0 +1,42 @@
/**
* @file rp2350_reset_handler.h
* @brief Reset handler header for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Entry point after reset. Performs stack initialization, XOSC
* setup, subsystem reset release, UART initialization,
* and branches to main().
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RP2350_RESET_HANDLER_H
#define __RP2350_RESET_HANDLER_H
/**
* @brief Reset handler entry point (naked, noreturn).
* @retval None
*/
void Reset_Handler(void) __attribute__((noreturn));
#endif /* __RP2350_RESET_HANDLER_H */
+43
View File
@@ -0,0 +1,43 @@
/**
* @file rp2350_stack.h
* @brief Stack pointer initialization header for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Sets MSP, PSP, MSPLIM, and PSPLIM from the STACK_TOP and
* STACK_LIMIT values defined in rp2350.h.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RP2350_STACK_H
#define __RP2350_STACK_H
#include "rp2350.h"
/**
* @brief Initialize MSP, PSP, MSPLIM, and PSPLIM stack pointers.
* @retval None
*/
void stack_init(void);
#endif /* __RP2350_STACK_H */
+82
View File
@@ -0,0 +1,82 @@
/**
* @file rp2350_uart.h
* @brief UART0 driver header for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Bare-metal UART0 driver supporting TX/RX on GPIO 0/1 at
* 115200 baud (12 MHz XOSC clock).
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RP2350_UART_H
#define __RP2350_UART_H
#include "rp2350.h"
/**
* @brief Release UART0 from reset and wait until ready.
* @retval None
*/
void uart_release_reset(void);
/**
* @brief Initialize UART0 pins, baud rate, line control, and enable.
* @retval None
*/
void uart_init(void);
/**
* @brief Check whether a received byte is waiting in the UART FIFO.
* @retval bool true if at least one byte is available
*/
bool uart_is_readable(void);
/**
* @brief Read one character from UART0 (blocking).
* @retval char the received character
*/
char uart_getchar(void);
/**
* @brief Transmit one character over UART0 (blocking).
* @param c character to transmit
* @retval None
*/
void uart_putchar(char c);
/**
* @brief Transmit a null-terminated string over UART0.
* @param str pointer to the string to send
* @retval None
*/
void uart_puts(const char *str);
/**
* @brief Convert a lowercase ASCII character to uppercase.
* @param c input character
* @retval char uppercase equivalent or original character
*/
char uart_to_upper(char c);
#endif /* __RP2350_UART_H */
+49
View File
@@ -0,0 +1,49 @@
/**
* @file rp2350_xosc.h
* @brief XOSC driver header for RP2350.
* @author Kevin Thomas
* @date 2026
*
* External crystal oscillator initialization and peripheral
* clock enable using the XOSC registers.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RP2350_XOSC_H
#define __RP2350_XOSC_H
#include "rp2350.h"
/**
* @brief Initialize the external crystal oscillator and wait until stable.
* @retval None
*/
void xosc_init(void);
/**
* @brief Enable the XOSC peripheral clock via CLK_PERI_CTRL.
* @retval None
*/
void xosc_enable_peri_clk(void);
#endif /* __RP2350_XOSC_H */
+83
View File
@@ -0,0 +1,83 @@
# ------------------------------------------------------------------------------
# @file Makefile
# @author Kevin Thomas
# @brief Build script for RP2350 bare-metal C UART driver.
#
# Compiles, links, and generates UF2 firmware for the RP2350.
# ------------------------------------------------------------------------------
# OS detection
ifeq ($(OS),Windows_NT)
MKDIR = if not exist $(subst /,\\,$(BUILD_DIR)) mkdir $(subst /,\\,$(BUILD_DIR))
RM = if exist $(subst /,\\,$(BUILD_DIR)) rmdir /s /q $(subst /,\\,$(BUILD_DIR))
else
MKDIR = mkdir -p $(BUILD_DIR)
RM = rm -rf $(BUILD_DIR)
endif
# Toolchain
CC = arm-none-eabi-gcc
OBJCOPY = arm-none-eabi-objcopy
SIZE = arm-none-eabi-size
# Target
TARGET = uart
# Directories
SRC_DIR = Src
INC_DIR = Inc
BUILD_DIR = build
# CPU flags
CPU_FLAGS = -mcpu=cortex-m33 -mthumb
# Compiler flags
CFLAGS = $(CPU_FLAGS) -Og -g3 -Wall -Wextra \
-ffunction-sections -fdata-sections \
-I$(INC_DIR)
# Linker flags
LDFLAGS = $(CPU_FLAGS) -T linker.ld -nostdlib -Wl,--gc-sections
# Source files
SRCS = $(SRC_DIR)/vector_table.c \
$(SRC_DIR)/rp2350_reset_handler.c \
$(SRC_DIR)/rp2350_stack.c \
$(SRC_DIR)/rp2350_xosc.c \
$(SRC_DIR)/rp2350_reset.c \
$(SRC_DIR)/rp2350_uart.c \
$(SRC_DIR)/main.c \
$(SRC_DIR)/image_def.c
# Object files
OBJS = $(patsubst $(SRC_DIR)/%.c,$(BUILD_DIR)/%.o,$(SRCS))
# Rules
.PHONY: all clean flash
all: $(BUILD_DIR)/$(TARGET).bin
@echo "==================================="
@echo "SUCCESS! Created $(TARGET).elf and $(TARGET).bin"
@echo "==================================="
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c | $(BUILD_DIR)
$(CC) $(CFLAGS) -c $< -o $@
$(BUILD_DIR)/$(TARGET).elf: $(OBJS)
$(CC) $(LDFLAGS) $(OBJS) -o $@
$(SIZE) $@
$(BUILD_DIR)/$(TARGET).bin: $(BUILD_DIR)/$(TARGET).elf
$(OBJCOPY) -O binary $< $@
$(BUILD_DIR):
$(MKDIR)
clean:
$(RM)
flash: $(BUILD_DIR)/$(TARGET).elf
openocd -f interface/cmsis-dap.cfg -f target/rp2350.cfg \
-c "adapter speed 5000" \
-c "program $< verify reset exit"
+41
View File
@@ -0,0 +1,41 @@
/**
* @file image_def.c
* @brief RP2350 IMAGE_DEF block for boot ROM image recognition.
* @author Kevin Thomas
* @date 2026
*
* Must appear within the first 4 KB of flash for the boot ROM
* to accept the image.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <stdint.h>
__attribute__((section(".embedded_block"), used))
const uint8_t picobin_block[] = {
0xD3, 0xDE, 0xFF, 0xFF,
0x42, 0x01, 0x21, 0x10,
0xFF, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x79, 0x35, 0x12, 0xAB
};
+53
View File
@@ -0,0 +1,53 @@
/**
* @file main.c
* @brief UART demonstration: echo received characters in uppercase.
* @author Kevin Thomas
* @date 2026
*
* Demonstrates hardware UART0 using the bare-metal UART driver.
* Characters typed into a terminal via a USB-to-UART adapter
* are echoed back in uppercase.
*
* Wiring:
* GPIO0 (TX) -> USB-to-UART adapter RX
* GPIO1 (RX) -> USB-to-UART adapter TX
* GND -> USB-to-UART adapter GND
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "rp2350_uart.h"
int main(void)
{
uart_puts("UART driver ready (115200 8N1)\r\n");
uart_puts("Type characters to echo them back in UPPERCASE:\r\n");
while (1)
{
if (uart_is_readable())
{
char c = uart_getchar();
char upper = uart_to_upper(c);
uart_putchar(upper);
}
}
}
+41
View File
@@ -0,0 +1,41 @@
/**
* @file rp2350_reset.c
* @brief Reset controller driver implementation for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Releases IO_BANK0 from reset and waits until the subsystem
* is ready.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "rp2350_reset.h"
void reset_init_subsystem(void)
{
uint32_t value;
value = RESETS->RESET;
value &= ~(1U << RESETS_RESET_IO_BANK0_SHIFT);
RESETS->RESET = value;
while ((RESETS->RESET_DONE & (1U << RESETS_RESET_IO_BANK0_SHIFT)) == 0) {}
}
@@ -0,0 +1,80 @@
/**
* @file rp2350_reset_handler.c
* @brief Reset handler implementation for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Entry point after power-on or system reset. Initializes the
* stack, XOSC, subsystem resets, UART, then branches
* to main().
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "rp2350_reset_handler.h"
#include "rp2350_stack.h"
#include "rp2350_xosc.h"
#include "rp2350_reset.h"
#include "rp2350_uart.h"
extern int main(void);
extern uint32_t __data_lma;
extern uint32_t __data_start;
extern uint32_t __data_end;
extern uint32_t __bss_start;
extern uint32_t __bss_end;
static void _data_copy_init(void)
{
uint32_t *src = &__data_lma;
uint32_t *dst = &__data_start;
while (dst < &__data_end)
*dst++ = *src++;
}
static void _bss_zero_init(void)
{
uint32_t *dst = &__bss_start;
while (dst < &__bss_end)
*dst++ = 0U;
}
void _ram_init(void)
{
stack_init();
_data_copy_init();
_bss_zero_init();
}
void __attribute__((naked, noreturn)) Reset_Handler(void)
{
__asm__ volatile (
"bl _ram_init\n\t"
"bl xosc_init\n\t"
"bl xosc_enable_peri_clk\n\t"
"bl reset_init_subsystem\n\t"
"bl uart_release_reset\n\t"
"bl uart_init\n\t"
"b main\n\t"
);
}
+47
View File
@@ -0,0 +1,47 @@
/**
* @file rp2350_stack.c
* @brief Stack pointer initialization for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Sets MSP, PSP, MSPLIM, and PSPLIM using inline assembly.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "rp2350_stack.h"
void stack_init(void)
{
__asm__ volatile (
"ldr r0, =%0\n\t"
"msr PSP, r0\n\t"
"ldr r0, =%1\n\t"
"msr MSPLIM, r0\n\t"
"msr PSPLIM, r0\n\t"
"ldr r0, =%0\n\t"
"msr MSP, r0\n\t"
:
: "i" (STACK_TOP), "i" (STACK_LIMIT)
: "r0"
);
}
+134
View File
@@ -0,0 +1,134 @@
/**
* @file rp2350_uart.c
* @brief UART0 driver implementation for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Configures UART0 on GPIO 0 (TX) and GPIO 1 (RX) at 115200
* baud using the 12 MHz XOSC clock.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "rp2350_uart.h"
/** @brief Base address pointer for UART0 peripheral registers */
#define UART_BASE ((volatile uint32_t *) UART0_BASE)
/**
* @brief Clear the UART0 reset bit in the reset controller.
* @retval None
*/
static void uart_clear_reset_bit(void)
{
uint32_t value;
value = RESETS->RESET;
value &= ~(1U << RESETS_RESET_UART0_SHIFT);
RESETS->RESET = value;
}
/**
* @brief Wait until the UART0 block is out of reset.
* @retval None
*/
static void uart_wait_reset_done(void)
{
while ((RESETS->RESET_DONE & (1U << RESETS_RESET_UART0_SHIFT)) == 0) {}
}
/**
* @brief Configure GPIO pins 0 (TX) and 1 (RX) for UART function.
* @retval None
*/
static void uart_configure_pins(void)
{
IO_BANK0->GPIO[0].CTRL = IO_BANK0_CTRL_FUNCSEL_UART;
IO_BANK0->GPIO[1].CTRL = IO_BANK0_CTRL_FUNCSEL_UART;
PADS_BANK0->GPIO[0] = 0x04;
PADS_BANK0->GPIO[1] = 0x40;
}
/**
* @brief Set UART0 baud rate divisors for 115200 at 12 MHz.
* @retval None
*/
static void uart_set_baud(void)
{
UART_BASE[UART_CR_OFFSET] = 0;
UART_BASE[UART_IBRD_OFFSET] = 6;
UART_BASE[UART_FBRD_OFFSET] = 33;
}
/**
* @brief Configure line control and enable UART0.
* @retval None
*/
static void uart_enable(void)
{
UART_BASE[UART_LCR_H_OFFSET] = UART_LCR_H_8N1_FIFO;
UART_BASE[UART_CR_OFFSET] = UART_CR_ENABLE;
}
void uart_release_reset(void)
{
uart_clear_reset_bit();
uart_wait_reset_done();
}
void uart_init(void)
{
uart_configure_pins();
uart_set_baud();
uart_enable();
}
bool uart_is_readable(void)
{
return (UART_BASE[UART_FR_OFFSET] & UART_FR_RXFE_MASK) == 0;
}
char uart_getchar(void)
{
while (UART_BASE[UART_FR_OFFSET] & UART_FR_RXFE_MASK) {}
return (char)(UART_BASE[UART_DR_OFFSET] & 0xFF);
}
void uart_putchar(char c)
{
while (UART_BASE[UART_FR_OFFSET] & UART_FR_TXFF_MASK) {}
UART_BASE[UART_DR_OFFSET] = (uint32_t)c;
}
void uart_puts(const char *str)
{
while (*str)
{
uart_putchar(*str++);
}
}
char uart_to_upper(char c)
{
if (c >= 'a' && c <= 'z')
return (char)(c - 32);
return c;
}
+48
View File
@@ -0,0 +1,48 @@
/**
* @file rp2350_xosc.c
* @brief XOSC driver implementation for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Configures the external crystal oscillator and enables the
* peripheral clock sourced from XOSC.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "rp2350_xosc.h"
void xosc_init(void)
{
XOSC->STARTUP = 0x00C4U;
XOSC->CTRL = 0x00FABAA0U;
while ((XOSC->STATUS & (1U << XOSC_STATUS_STABLE_SHIFT)) == 0) {}
}
void xosc_enable_peri_clk(void)
{
uint32_t value;
value = CLOCKS->CLK_PERI_CTRL;
value |= (1U << CLK_PERI_CTRL_ENABLE_SHIFT);
value |= (CLK_PERI_CTRL_AUXSRC_XOSC << CLK_PERI_CTRL_AUXSRC_SHIFT);
CLOCKS->CLK_PERI_CTRL = value;
}
+44
View File
@@ -0,0 +1,44 @@
/**
* @file vector_table.c
* @brief Vector table with initial stack pointer and reset handler.
* @author Kevin Thomas
* @date 2026
*
* Placed in the .vectors section at the start of flash.
* The Thumb bit (bit 0 = 1) is automatically set by the
* linker for function pointers in Thumb mode.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <stdint.h>
extern uint32_t _stack_top;
extern void Reset_Handler(void);
typedef void (*vector_func_t)(void);
__attribute__((section(".vectors"), used))
const void *_vectors[2] = {
&_stack_top,
Reset_Handler
};
Binary file not shown.
+144
View File
@@ -0,0 +1,144 @@
/**
******************************************************************************
* @file linker.ld
* @author Kevin Thomas
* @brief Minimal linker script for bare-metal RP2350 development.
*
* Defines FLASH (XIP 32 MB) and RAM (520 kB SRAM) regions.
* The vector table is placed at the start of flash (0x10000000).
*
******************************************************************************
* @attention
*
* Copyright (c) 2026 Kevin Thomas.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/**
* Entry point.
*/
ENTRY(Reset_Handler)
/**
* Define memory regions.
*/
__XIP_BASE = 0x10000000;
__XIP_SIZE = 32M;
__SRAM_BASE = 0x20000000;
__SRAM_SIZE = 520K;
__STACK_SIZE = 32K;
/**
* Memory layout.
*/
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);
data PT_LOAD FLAGS(6);
}
/**
* Section placement.
*/
SECTIONS
{
. = ORIGIN(FLASH);
/**
* Vector table MUST be first at 0x10000000.
*/
.vectors :
{
KEEP(*(.vectors))
} > FLASH :text
/**
* Verify vector table placement.
*/
ASSERT((ADDR(.vectors) == ORIGIN(FLASH)),
"Vector table must be at start of flash (0x10000000)")
/**
* Text and read-only data.
*/
.text :
{
. = ALIGN(4);
*(.text*)
*(.rodata*)
KEEP(*(.init))
KEEP(*(.fini))
KEEP(*(.ARM.attributes))
} > FLASH :text
/**
* IMAGE_DEF block at end of code.
*/
.embedded_block :
{
KEEP(*(.embedded_block))
} > FLASH :text
/**
* Initialized data and RAM-resident code (LMA in flash, VMA in RAM).
* Startup copies from __data_lma to __data_start..__data_end.
*/
.data :
{
. = ALIGN(4);
__data_start = .;
*(.ram_func*)
*(.data*)
. = ALIGN(4);
__data_end = .;
} > RAM AT> FLASH :data
__data_lma = LOADADDR(.data);
/**
* Uninitialized data (BSS) in RAM.
*/
.bss (NOLOAD) :
{
. = ALIGN(4);
__bss_start = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end = .;
} > RAM
/**
* Non-secure stack symbols.
*/
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - __STACK_SIZE;
__stack = __StackTop;
_stack_top = __StackTop;
/**
* Stack section (no load).
*/
.stack (NOLOAD) : { . = ALIGN(8); } > RAM
/**
* Provide vector table symbol to startup code.
*/
PROVIDE(__Vectors = ADDR(.vectors));
}
+102
View File
@@ -0,0 +1,102 @@
# SPDX-License-Identifier: MIT OR Apache-2.0
#
# Copyright (c) 20212024 The rp-rs Developers
# Copyright (c) 2021 rp-rs organization
# Copyright (c) 2025 Raspberry Pi Ltd.
#
# Cargo Configuration for the https://github.com/rp-rs/rp-hal.git repository.
#
# You might want to make a similar file in your own repository if you are
# writing programs for Raspberry Silicon microcontrollers.
#
[build]
target = "thumbv8m.main-none-eabihf"
# Set the default target to match the Cortex-M33 in the RP2350
# target = "thumbv8m.main-none-eabihf"
# target = "thumbv6m-none-eabi"
# target = "riscv32imac-unknown-none-elf"
# Target specific options
[target.thumbv6m-none-eabi]
# Pass some extra options to rustc, some of which get passed on to the linker.
#
# * linker argument --nmagic turns off page alignment of sections (which saves
# flash space)
# * linker argument -Tlink.x tells the linker to use link.x as the linker
# script. This is usually provided by the cortex-m-rt crate, and by default
# the version in that crate will include a file called `memory.x` which
# describes the particular memory layout for your specific chip.
# * no-vectorize-loops turns off the loop vectorizer (seeing as the M0+ doesn't
# have SIMD)
linker = "flip-link"
rustflags = [
"-C", "link-arg=--nmagic",
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=-Tdefmt.x",
"-C", "no-vectorize-loops",
]
# Use picotool for loading.
#
# Load an elf, skipping unchanged flash sectors, verify it, and execute it
runner = "${PICOTOOL_PATH} load -u -v -x -t elf"
#runner = "probe-rs run --chip ${CHIP} --protocol swd"
# This is the hard-float ABI for Arm mode.
#
# The FPU is enabled by default, and float function arguments use FPU
# registers.
[target.thumbv8m.main-none-eabihf]
# Pass some extra options to rustc, some of which get passed on to the linker.
#
# * linker argument --nmagic turns off page alignment of sections (which saves
# flash space)
# * linker argument -Tlink.x tells the linker to use link.x as a linker script.
# This is usually provided by the cortex-m-rt crate, and by default the
# version in that crate will include a file called `memory.x` which describes
# the particular memory layout for your specific chip.
# * linker argument -Tdefmt.x also tells the linker to use `defmt.x` as a
# secondary linker script. This is required to make defmt_rtt work.
rustflags = [
"-C", "link-arg=--nmagic",
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=-Tdefmt.x",
"-C", "target-cpu=cortex-m33",
]
# Use picotool for loading.
#
# Load an elf, skipping unchanged flash sectors, verify it, and execute it
runner = "${PICOTOOL_PATH} load -u -v -x -t elf"
#runner = "probe-rs run --chip ${CHIP} --protocol swd"
# This is the soft-float ABI for RISC-V mode.
#
# Hazard 3 does not have an FPU and so float function arguments use integer
# registers.
[target.riscv32imac-unknown-none-elf]
# Pass some extra options to rustc, some of which get passed on to the linker.
#
# * linker argument --nmagic turns off page alignment of sections (which saves
# flash space)
# * linker argument -Trp235x_riscv.x also tells the linker to use
# `rp235x_riscv.x` as a linker script. This adds in RP2350 RISC-V specific
# things that the riscv-rt crate's `link.x` requires and then includes
# `link.x` automatically. This is the reverse of how we do it on Cortex-M.
# * linker argument -Tdefmt.x also tells the linker to use `defmt.x` as a
# secondary linker script. This is required to make defmt_rtt work.
rustflags = [
"-C", "link-arg=--nmagic",
"-C", "link-arg=-Trp2350_riscv.x",
"-C", "link-arg=-Tdefmt.x",
]
# Use picotool for loading.
#
# Load an elf, skipping unchanged flash sectors, verify it, and execute it
runner = "${PICOTOOL_PATH} load -u -v -x -t elf"
#runner = "probe-rs run --chip ${CHIP} --protocol swd"
[env]
DEFMT_LOG = "debug"
+113
View File
@@ -0,0 +1,113 @@
# Created by https://www.toptal.com/developers/gitignore/api/rust,visualstudiocode,macos,windows,linux
# Edit at https://www.toptal.com/developers/gitignore?templates=rust,visualstudiocode,macos,windows,linux
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### macOS Patch ###
# iCloud generated files
*.icloud
### Rust ###
# Generated by Cargo
# will have compiled files and executables
debug/
target/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk
# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
### VisualStudioCode Patch ###
# Ignore all local history of files
.history
.ionide
### Windows ###
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# End of https://www.toptal.com/developers/gitignore/api/rust,visualstudiocode,macos,windows,linux
+1
View File
@@ -0,0 +1 @@
rp2350
+8
View File
@@ -0,0 +1,8 @@
{
"recommendations": [
"marus25.cortex-debug",
"rust-lang.rust-analyzer",
"probe-rs.probe-rs-debugger",
"raspberry-pi.raspberry-pi-pico"
]
}
+41
View File
@@ -0,0 +1,41 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Pico Debug (probe-rs)",
"cwd": "${workspaceFolder}",
"request": "launch",
"type": "probe-rs-debug",
"connectUnderReset": false,
"speed": 5000,
"runtimeExecutable": "probe-rs",
"chip": "${command:raspberry-pi-pico.getChip}",
"runtimeArgs": [
"dap-server"
],
"flashingConfig": {
"flashingEnabled": true,
"haltAfterReset": false
},
"coreConfigs": [
{
"coreIndex": 0,
"programBinary": "${command:raspberry-pi-pico.launchTargetPath}",
"rttEnabled": true,
"svdFile": "${command:raspberry-pi-pico.getSVDPath}",
"rttChannelFormats": [
{
"channelNumber": 0,
"dataFormat": "Defmt",
"mode": "NoBlockSkip",
"showTimestamps": true
}
]
}
],
"preLaunchTask": "Build + Generate SBOM (debug)",
"consoleLogLevel": "Debug",
"wireProtocol": "Swd"
}
]
}
+8
View File
@@ -0,0 +1,8 @@
{
"rust-analyzer.cargo.target": "thumbv8m.main-none-eabihf",
"rust-analyzer.check.allTargets": false,
"editor.formatOnSave": true,
"files.exclude": {
".pico-rs": true
}
}
+124
View File
@@ -0,0 +1,124 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Compile Project",
"type": "process",
"isBuildCommand": true,
"command": "cargo",
"args": [
"build",
"--release"
],
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"reveal": "always",
"panel": "dedicated"
},
"problemMatcher": "$rustc",
"options": {
"env": {
"PICOTOOL_PATH": "${command:raspberry-pi-pico.getPicotoolPath}",
"CHIP": "${command:raspberry-pi-pico.getChip}"
}
}
},
{
"label": "Build + Generate SBOM (release)",
"type": "shell",
"command": "bash",
"args": [
"-lc",
"cargo sbom > ${command:raspberry-pi-pico.sbomTargetPathRelease}"
],
"windows": {
"command": "powershell",
"args": [
"-NoProfile",
"-ExecutionPolicy",
"Bypass",
"-Command",
"cargo sbom | Set-Content -Encoding utf8 ${command:raspberry-pi-pico.sbomTargetPathRelease}"
]
},
"dependsOn": "Compile Project",
"presentation": {
"reveal": "silent",
"panel": "shared"
},
"problemMatcher": []
},
{
"label": "Compile Project (debug)",
"type": "process",
"isBuildCommand": true,
"command": "cargo",
"args": [
"build"
],
"group": {
"kind": "build",
"isDefault": false
},
"presentation": {
"reveal": "always",
"panel": "dedicated"
},
"problemMatcher": "$rustc",
"options": {
"env": {
"PICOTOOL_PATH": "${command:raspberry-pi-pico.getPicotoolPath}",
"CHIP": "${command:raspberry-pi-pico.getChip}"
}
}
},
{
"label": "Build + Generate SBOM (debug)",
"type": "shell",
"command": "bash",
"args": [
"-lc",
"cargo sbom > ${command:raspberry-pi-pico.sbomTargetPathDebug}"
],
"windows": {
"command": "powershell",
"args": [
"-NoProfile",
"-ExecutionPolicy",
"Bypass",
"-Command",
"cargo sbom | Set-Content -Encoding utf8 ${command:raspberry-pi-pico.sbomTargetPathDebug}"
]
},
"dependsOn": "Compile Project (debug)",
"presentation": {
"reveal": "silent",
"panel": "shared"
},
"problemMatcher": []
},
{
"label": "Run Project",
"type": "shell",
"dependsOn": [
"Build + Generate SBOM (release)"
],
"command": "${command:raspberry-pi-pico.getPicotoolPath}",
"args": [
"load",
"-x",
"${command:raspberry-pi-pico.launchTargetPathRelease}",
"-t",
"elf"
],
"presentation": {
"reveal": "always",
"panel": "dedicated"
},
"problemMatcher": []
}
]
}
+35
View File
@@ -0,0 +1,35 @@
[package]
edition = "2024"
name = "uart"
version = "0.1.0"
license = "MIT or Apache-2.0"
[build-dependencies]
regex = "1.11.0"
[dependencies]
cortex-m = "0.7"
cortex-m-rt = "0.7"
embedded-hal = "1.0.0"
embedded-hal-nb = "1.0.0"
nb = "1.1.0"
fugit = "0.3"
defmt = "1"
defmt-rtt = "1"
[target.'cfg( target_arch = "arm" )'.dependencies]
panic-probe = { version = "1", features = ["print-defmt"] }
[target.'cfg( target_arch = "riscv32" )'.dependencies]
panic-halt = { version = "1.0.0" }
[target.thumbv6m-none-eabi.dependencies]
rp2040-boot2 = "0.3"
rp2040-hal = { version = "0.11", features = ["rt", "critical-section-impl"] }
[target.riscv32imac-unknown-none-elf.dependencies]
rp235x-hal = { version = "0.3", features = ["rt", "critical-section-impl"] }
[target."thumbv8m.main-none-eabihf".dependencies]
rp235x-hal = { version = "0.3", features = ["rt", "critical-section-impl"] }
+204
View File
@@ -0,0 +1,204 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright (c) 20212024 The rp-rs Developers
Copyright (c) 2021 rp-rs organization
Copyright (c) 2025 Raspberry Pi Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+24
View File
@@ -0,0 +1,24 @@
MIT License
Copyright (c) 20212024 The rp-rs Developers
Copyright (c) 2021 rp-rs organization
Copyright (c) 2025 Raspberry Pi Ltd.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+73
View File
@@ -0,0 +1,73 @@
//! Implementation module
//!
//! **File:** `build.rs`
//! **Author:** Kevin Thomas
//! **Date:** 2025
//!
//! MIT License
//!
//! Copyright (c) 2025 Kevin Thomas
//!
//! Permission is hereby granted, free of charge, to any person obtaining a copy
//! of this software and associated documentation files (the "Software"), to deal
//! in the Software without restriction, including without limitation the rights
//! to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//! copies of the Software, and to permit persons to whom the Software is
//! furnished to do so, subject to the following conditions:
//!
//! The above copyright notice and this permission notice shall be included in
//! all copies or substantial portions of the Software.
//!
//! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//! AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//! LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//! SOFTWARE.
use std::fs::{File, read_to_string};
use std::io::Write;
use std::path::PathBuf;
use regex::Regex;
fn main() {
let out = PathBuf::from(std::env::var_os("OUT_DIR").unwrap());
let contents = read_to_string(".pico-rs").unwrap_or_default().trim().to_lowercase();
let target = setup_target(&contents, &out);
update_cargo_config(&target);
write_riscv(&out);
print_cfgs(&out);
}
fn setup_target(c: &str, out: &PathBuf) -> String {
// Setup the correct build target based on pico-rs
if c == "rp2040" { write_rp2040(out); return "thumbv6m-none-eabi".to_string(); }
write_rp2350(out);
if c.contains("riscv") { "riscv32imac-unknown-none-elf".to_string() } else { "thumbv8m.main-none-eabihf".to_string() }
}
fn write_rp2040(out: &PathBuf) {
File::create(out.join("memory.x")).unwrap().write_all(include_bytes!("rp2040.x")).unwrap();
println!("cargo::rustc-cfg=rp2040");
println!("cargo:rerun-if-changed=rp2040.x");
}
fn write_rp2350(out: &PathBuf) {
File::create(out.join("memory.x")).unwrap().write_all(include_bytes!("rp2350.x")).unwrap();
println!("cargo::rustc-cfg=rp2350");
println!("cargo:rerun-if-changed=rp2350.x");
}
fn update_cargo_config(target: &str) {
let re = Regex::new(r"target = .*").unwrap();
let result = re.replace(include_str!(".cargo/config.toml"), format!("target = \"{}\"", target));
File::create(".cargo/config.toml").unwrap().write_all(result.as_bytes()).unwrap();
}
fn write_riscv(out: &PathBuf) {
File::create(out.join("rp2350_riscv.x")).unwrap().write_all(include_bytes!("rp2350_riscv.x")).unwrap();
}
fn print_cfgs(out: &PathBuf) {
println!("cargo::rustc-check-cfg=cfg(rp2040)");
println!("cargo::rustc-check-cfg=cfg(rp2350)");
println!("cargo:rustc-link-search={}", out.display());
println!("cargo:rerun-if-changed=.pico-rs");
println!("cargo:rerun-if-changed=rp2350_riscv.x");
println!("cargo:rerun-if-changed=build.rs");
}
+91
View File
@@ -0,0 +1,91 @@
/*
* SPDX-License-Identifier: MIT OR Apache-2.0
*
* Copyright (c) 20212024 The rp-rs Developers
* Copyright (c) 2021 rp-rs organization
* Copyright (c) 2025 Raspberry Pi Ltd.
*/
MEMORY {
BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100
/*
* Here we assume you have 2048 KiB of Flash. This is what the Pi Pico
* has, but your board may have more or less Flash and you should adjust
* this value to suit.
*/
FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100
/*
* RAM consists of 4 banks, SRAM0-SRAM3, with a striped mapping.
* This is usually good for performance, as it distributes load on
* those banks evenly.
*/
RAM : ORIGIN = 0x20000000, LENGTH = 256K
/*
* RAM banks 4 and 5 use a direct mapping. They can be used to have
* memory areas dedicated for some specific job, improving predictability
* of access times.
* Example: Separate stacks for core0 and core1.
*/
SRAM4 : ORIGIN = 0x20040000, LENGTH = 4k
SRAM5 : ORIGIN = 0x20041000, LENGTH = 4k
/* SRAM banks 0-3 can also be accessed directly. However, those ranges
alias with the RAM mapping, above. So don't use them at the same time!
SRAM0 : ORIGIN = 0x21000000, LENGTH = 64k
SRAM1 : ORIGIN = 0x21010000, LENGTH = 64k
SRAM2 : ORIGIN = 0x21020000, LENGTH = 64k
SRAM3 : ORIGIN = 0x21030000, LENGTH = 64k
*/
}
EXTERN(BOOT2_FIRMWARE)
SECTIONS {
/* ### Boot loader
*
* An executable block of code which sets up the QSPI interface for
* 'Execute-In-Place' (or XIP) mode. Also sends chip-specific commands to
* the external flash chip.
*
* Must go at the start of external flash, where the Boot ROM expects it.
*/
.boot2 ORIGIN(BOOT2) :
{
KEEP(*(.boot2));
} > BOOT2
} INSERT BEFORE .text;
SECTIONS {
/* ### Boot ROM info
*
* Goes after .vector_table, to keep it in the first 512 bytes of flash,
* where picotool can find it
*/
.boot_info : ALIGN(4)
{
KEEP(*(.boot_info));
} > FLASH
} INSERT AFTER .vector_table;
/* move .text to start /after/ the boot info */
_stext = ADDR(.boot_info) + SIZEOF(.boot_info);
SECTIONS {
/* ### Picotool 'Binary Info' Entries
*
* Picotool looks through this block (as we have pointers to it in our
* header) to find interesting information.
*/
.bi_entries : ALIGN(4)
{
/* We put this in the header */
__bi_entries_start = .;
/* Here are the entries */
KEEP(*(.bi_entries));
/* Keep this block a nice round size */
. = ALIGN(4);
/* We put this in the header */
__bi_entries_end = .;
} > FLASH
} INSERT AFTER .text;
+83
View File
@@ -0,0 +1,83 @@
/*
* SPDX-License-Identifier: MIT OR Apache-2.0
*
* Copyright (c) 20212024 The rp-rs Developers
* Copyright (c) 2021 rp-rs organization
* Copyright (c) 2025 Raspberry Pi Ltd.
*/
MEMORY {
/*
* The RP2350 has either external or internal flash.
*
* 2 MiB is a safe default here, although a Pico 2 has 4 MiB.
*/
FLASH : ORIGIN = 0x10000000, LENGTH = 2048K
/*
* RAM consists of 8 banks, SRAM0-SRAM7, with a striped mapping.
* This is usually good for performance, as it distributes load on
* those banks evenly.
*/
RAM : ORIGIN = 0x20000000, LENGTH = 512K
/*
* RAM banks 8 and 9 use a direct mapping. They can be used to have
* memory areas dedicated for some specific job, improving predictability
* of access times.
* Example: Separate stacks for core0 and core1.
*/
SRAM4 : ORIGIN = 0x20080000, LENGTH = 4K
SRAM5 : ORIGIN = 0x20081000, LENGTH = 4K
}
SECTIONS {
/* ### Boot ROM info
*
* Goes after .vector_table, to keep it in the first 4K of flash
* where the Boot ROM (and picotool) can find it
*/
.start_block : ALIGN(4)
{
__start_block_addr = .;
KEEP(*(.start_block));
} > FLASH
} INSERT AFTER .vector_table;
/* move .text to start /after/ the boot info */
_stext = ADDR(.start_block) + SIZEOF(.start_block);
SECTIONS {
/* ### Picotool 'Binary Info' Entries
*
* Picotool looks through this block (as we have pointers to it in our
* header) to find interesting information.
*/
.bi_entries : ALIGN(4)
{
/* We put this in the header */
__bi_entries_start = .;
/* Here are the entries */
KEEP(*(.bi_entries));
/* Keep this block a nice round size */
. = ALIGN(4);
/* We put this in the header */
__bi_entries_end = .;
} > FLASH
} INSERT AFTER .text;
SECTIONS {
/* ### Boot ROM extra info
*
* Goes after everything in our program, so it can contain a signature.
*/
.end_block : ALIGN(4)
{
__end_block_addr = .;
KEEP(*(.end_block));
} > FLASH
} INSERT AFTER .uninit;
PROVIDE(start_to_end = __end_block_addr - __start_block_addr);
PROVIDE(end_to_start = __start_block_addr - __end_block_addr);
+259
View File
@@ -0,0 +1,259 @@
/*
* SPDX-License-Identifier: MIT OR Apache-2.0
*
* Copyright (c) 20212024 The rp-rs Developers
* Copyright (c) 2021 rp-rs organization
* Copyright (c) 2025 Raspberry Pi Ltd.
*/
MEMORY {
/*
* The RP2350 has either external or internal flash.
*
* 2 MiB is a safe default here, although a Pico 2 has 4 MiB.
*/
FLASH : ORIGIN = 0x10000000, LENGTH = 2048K
/*
* RAM consists of 8 banks, SRAM0-SRAM7, with a striped mapping.
* This is usually good for performance, as it distributes load on
* those banks evenly.
*/
RAM : ORIGIN = 0x20000000, LENGTH = 512K
/*
* RAM banks 8 and 9 use a direct mapping. They can be used to have
* memory areas dedicated for some specific job, improving predictability
* of access times.
* Example: Separate stacks for core0 and core1.
*/
SRAM4 : ORIGIN = 0x20080000, LENGTH = 4K
SRAM5 : ORIGIN = 0x20081000, LENGTH = 4K
}
/* # Developer notes
- Symbols that start with a double underscore (__) are considered "private"
- Symbols that start with a single underscore (_) are considered "semi-public"; they can be
overridden in a user linker script, but should not be referred from user code (e.g. `extern "C" {
static mut _heap_size }`).
- `EXTERN` forces the linker to keep a symbol in the final binary. We use this to make sure a
symbol is not dropped if it appears in or near the front of the linker arguments and "it's not
needed" by any of the preceding objects (linker arguments)
- `PROVIDE` is used to provide default values that can be overridden by a user linker script
- On alignment: it's important for correctness that the VMA boundaries of both .bss and .data *and*
the LMA of .data are all `32`-byte aligned. These alignments are assumed by the RAM
initialization routine. There's also a second benefit: `32`-byte aligned boundaries
means that you won't see "Address (..) is out of bounds" in the disassembly produced by `objdump`.
*/
PROVIDE(_stext = ORIGIN(FLASH));
PROVIDE(_stack_start = ORIGIN(RAM) + LENGTH(RAM));
PROVIDE(_max_hart_id = 0);
PROVIDE(_hart_stack_size = 2K);
PROVIDE(_heap_size = 0);
PROVIDE(InstructionMisaligned = ExceptionHandler);
PROVIDE(InstructionFault = ExceptionHandler);
PROVIDE(IllegalInstruction = ExceptionHandler);
PROVIDE(Breakpoint = ExceptionHandler);
PROVIDE(LoadMisaligned = ExceptionHandler);
PROVIDE(LoadFault = ExceptionHandler);
PROVIDE(StoreMisaligned = ExceptionHandler);
PROVIDE(StoreFault = ExceptionHandler);
PROVIDE(UserEnvCall = ExceptionHandler);
PROVIDE(SupervisorEnvCall = ExceptionHandler);
PROVIDE(MachineEnvCall = ExceptionHandler);
PROVIDE(InstructionPageFault = ExceptionHandler);
PROVIDE(LoadPageFault = ExceptionHandler);
PROVIDE(StorePageFault = ExceptionHandler);
PROVIDE(SupervisorSoft = DefaultHandler);
PROVIDE(MachineSoft = DefaultHandler);
PROVIDE(SupervisorTimer = DefaultHandler);
PROVIDE(MachineTimer = DefaultHandler);
PROVIDE(SupervisorExternal = DefaultHandler);
PROVIDE(MachineExternal = DefaultHandler);
PROVIDE(DefaultHandler = DefaultInterruptHandler);
PROVIDE(ExceptionHandler = DefaultExceptionHandler);
/* # Pre-initialization function */
/* If the user overrides this using the `#[pre_init]` attribute or by creating a `__pre_init` function,
then the function this points to will be called before the RAM is initialized. */
PROVIDE(__pre_init = default_pre_init);
/* A PAC/HAL defined routine that should initialize custom interrupt controller if needed. */
PROVIDE(_setup_interrupts = default_setup_interrupts);
/* # Multi-processing hook function
fn _mp_hook() -> bool;
This function is called from all the harts and must return true only for one hart,
which will perform memory initialization. For other harts it must return false
and implement wake-up in platform-dependent way (e.g. after waiting for a user interrupt).
*/
PROVIDE(_mp_hook = default_mp_hook);
/* # Start trap function override
By default uses the riscv crates default trap handler
but by providing the `_start_trap` symbol external crates can override.
*/
PROVIDE(_start_trap = default_start_trap);
SECTIONS
{
.text.dummy (NOLOAD) :
{
/* This section is intended to make _stext address work */
. = ABSOLUTE(_stext);
} > FLASH
.text _stext :
{
/* Put reset handler first in .text section so it ends up as the entry */
/* point of the program. */
KEEP(*(.init));
KEEP(*(.init.rust));
. = ALIGN(4);
__start_block_addr = .;
KEEP(*(.start_block));
. = ALIGN(4);
*(.trap);
*(.trap.rust);
*(.text.abort);
*(.text .text.*);
. = ALIGN(4);
} > FLASH
/* ### Picotool 'Binary Info' Entries
*
* Picotool looks through this block (as we have pointers to it in our
* header) to find interesting information.
*/
.bi_entries : ALIGN(4)
{
/* We put this in the header */
__bi_entries_start = .;
/* Here are the entries */
KEEP(*(.bi_entries));
/* Keep this block a nice round size */
. = ALIGN(4);
/* We put this in the header */
__bi_entries_end = .;
} > FLASH
.rodata : ALIGN(4)
{
*(.srodata .srodata.*);
*(.rodata .rodata.*);
/* 4-byte align the end (VMA) of this section.
This is required by LLD to ensure the LMA of the following .data
section will have the correct alignment. */
. = ALIGN(4);
} > FLASH
.data : ALIGN(32)
{
_sidata = LOADADDR(.data);
__sidata = LOADADDR(.data);
_sdata = .;
__sdata = .;
/* Must be called __global_pointer$ for linker relaxations to work. */
PROVIDE(__global_pointer$ = . + 0x800);
*(.sdata .sdata.* .sdata2 .sdata2.*);
*(.data .data.*);
. = ALIGN(32);
_edata = .;
__edata = .;
} > RAM AT > FLASH
.bss (NOLOAD) : ALIGN(32)
{
_sbss = .;
*(.sbss .sbss.* .bss .bss.*);
. = ALIGN(32);
_ebss = .;
} > RAM
.end_block : ALIGN(4)
{
__end_block_addr = .;
KEEP(*(.end_block));
} > FLASH
/* fictitious region that represents the memory available for the heap */
.heap (NOLOAD) :
{
_sheap = .;
. += _heap_size;
. = ALIGN(4);
_eheap = .;
} > RAM
/* fictitious region that represents the memory available for the stack */
.stack (NOLOAD) :
{
_estack = .;
. = ABSOLUTE(_stack_start);
_sstack = .;
} > RAM
/* fake output .got section */
/* Dynamic relocations are unsupported. This section is only used to detect
relocatable code in the input files and raise an error if relocatable code
is found */
.got (INFO) :
{
KEEP(*(.got .got.*));
}
.eh_frame (INFO) : { KEEP(*(.eh_frame)) }
.eh_frame_hdr (INFO) : { *(.eh_frame_hdr) }
}
PROVIDE(start_to_end = __end_block_addr - __start_block_addr);
PROVIDE(end_to_start = __start_block_addr - __end_block_addr);
/* Do not exceed this mark in the error messages above | */
ASSERT(ORIGIN(FLASH) % 4 == 0, "
ERROR(riscv-rt): the start of the FLASH must be 4-byte aligned");
ASSERT(ORIGIN(RAM) % 32 == 0, "
ERROR(riscv-rt): the start of the RAM must be 32-byte aligned");
ASSERT(_stext % 4 == 0, "
ERROR(riscv-rt): `_stext` must be 4-byte aligned");
ASSERT(_sdata % 32 == 0 && _edata % 32 == 0, "
BUG(riscv-rt): .data is not 32-byte aligned");
ASSERT(_sidata % 32 == 0, "
BUG(riscv-rt): the LMA of .data is not 32-byte aligned");
ASSERT(_sbss % 32 == 0 && _ebss % 32 == 0, "
BUG(riscv-rt): .bss is not 32-byte aligned");
ASSERT(_sheap % 4 == 0, "
BUG(riscv-rt): start of .heap is not 4-byte aligned");
ASSERT(_stext + SIZEOF(.text) < ORIGIN(FLASH) + LENGTH(FLASH), "
ERROR(riscv-rt): The .text section must be placed inside the FLASH region.
Set _stext to an address smaller than 'ORIGIN(FLASH) + LENGTH(FLASH)'");
ASSERT(SIZEOF(.stack) > (_max_hart_id + 1) * _hart_stack_size, "
ERROR(riscv-rt): .stack section is too small for allocating stacks for all the harts.
Consider changing `_max_hart_id` or `_hart_stack_size`.");
ASSERT(SIZEOF(.got) == 0, "
.got section detected in the input files. Dynamic relocations are not
supported. If you are linking to C code compiled using the `gcc` crate
then modify your build script to compile the C code _without_ the
-fPIC flag. See the documentation of the `gcc::Config.fpic` method for
details.");
/* Do not exceed this mark in the error messages above | */
+124
View File
@@ -0,0 +1,124 @@
//! Implementation module
//!
//! **File:** `board.rs`
//! **Author:** Kevin Thomas
//! **Date:** 2025
//!
//! MIT License
//!
//! Copyright (c) 2025 Kevin Thomas
//!
//! Permission is hereby granted, free of charge, to any person obtaining a copy
//! of this software and associated documentation files (the "Software"), to deal
//! in the Software without restriction, including without limitation the rights
//! to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//! copies of the Software, and to permit persons to whom the Software is
//! furnished to do so, subject to the following conditions:
//!
//! The above copyright notice and this permission notice shall be included in
//! all copies or substantial portions of the Software.
//!
//! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//! AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//! LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//! SOFTWARE.
// Alias our HAL crate
#[cfg(rp2350)]
use rp235x_hal as hal;
#[cfg(rp2040)]
use rp2040_hal as hal;
// UART driver for echo demo
use crate::uart;
/// External crystal frequency in Hz (12 MHz).
pub(crate) const XTAL_FREQ_HZ: u32 = 12_000_000u32;
/// UART baud rate in bits per second.
pub(crate) const UART_BAUD: u32 = 115_200;
/// Initialise system clocks and PLLs from the external 12 MHz crystal.
///
/// # Arguments
///
/// * `xosc` - XOSC peripheral singleton.
/// * `clocks` - CLOCKS peripheral singleton.
/// * `pll_sys` - PLL_SYS peripheral singleton.
/// * `pll_usb` - PLL_USB peripheral singleton.
/// * `resets` - Mutable reference to the RESETS peripheral.
/// * `watchdog` - Mutable reference to the watchdog timer.
///
/// # Returns
///
/// Configured clocks manager.
///
/// # Panics
///
/// Panics if clock initialisation fails.
pub(crate) fn init_clocks(
xosc: hal::pac::XOSC,
clocks: hal::pac::CLOCKS,
pll_sys: hal::pac::PLL_SYS,
pll_usb: hal::pac::PLL_USB,
resets: &mut hal::pac::RESETS,
watchdog: &mut hal::Watchdog,
) -> hal::clocks::ClocksManager {
hal::clocks::init_clocks_and_plls(
XTAL_FREQ_HZ, xosc, clocks, pll_sys, pll_usb, resets, watchdog,
)
.unwrap()
}
/// Unlock the GPIO bank and return the pin set.
///
/// # Arguments
///
/// * `io_bank0` - IO_BANK0 peripheral singleton.
/// * `pads_bank0` - PADS_BANK0 peripheral singleton.
/// * `sio` - SIO peripheral singleton.
/// * `resets` - Mutable reference to the RESETS peripheral.
///
/// # Returns
///
/// GPIO pin set for the entire bank.
pub(crate) fn init_pins(
io_bank0: hal::pac::IO_BANK0,
pads_bank0: hal::pac::PADS_BANK0,
sio: hal::pac::SIO,
resets: &mut hal::pac::RESETS,
) -> hal::gpio::Pins {
let sio = hal::Sio::new(sio);
hal::gpio::Pins::new(io_bank0, pads_bank0, sio.gpio_bank0, resets)
}
/// Initialise all peripherals and run the UART echo demo.
///
/// # Arguments
///
/// * `pac` - PAC Peripherals singleton (consumed).
pub(crate) fn run(mut pac: hal::pac::Peripherals) -> ! {
let clocks = init_clocks(pac.XOSC, pac.CLOCKS, pac.PLL_SYS, pac.PLL_USB, &mut pac.RESETS, &mut hal::Watchdog::new(pac.WATCHDOG));
let p = init_pins(pac.IO_BANK0, pac.PADS_BANK0, pac.SIO, &mut pac.RESETS);
let mut drv = uart::UartDriver::init(pac.UART0, p.gpio0, p.gpio1, UART_BAUD, &mut pac.RESETS, &clocks);
drv.puts(b"UART driver ready (115200 8N1)\r\nType characters to echo them back in UPPERCASE:\r\n");
echo_loop(&mut drv)
}
/// Run the uppercase echo loop forever.
///
/// # Arguments
///
/// * `drv` - Mutable reference to the UART driver.
fn echo_loop(drv: &mut uart::UartDriver) -> ! {
loop {
if drv.is_readable() {
let c = drv.getchar();
drv.putchar(uart::UartDriver::to_upper(c));
}
}
}
+83
View File
@@ -0,0 +1,83 @@
//! Implementation module
//!
//! **File:** `main.rs`
//! **Author:** Kevin Thomas
//! **Date:** 2025
//!
//! MIT License
//!
//! Copyright (c) 2025 Kevin Thomas
//!
//! Permission is hereby granted, free of charge, to any person obtaining a copy
//! of this software and associated documentation files (the "Software"), to deal
//! in the Software without restriction, including without limitation the rights
//! to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//! copies of the Software, and to permit persons to whom the Software is
//! furnished to do so, subject to the following conditions:
//!
//! The above copyright notice and this permission notice shall be included in
//! all copies or substantial portions of the Software.
//!
//! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//! AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//! LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//! SOFTWARE.
#![no_std]
#![no_main]
// Board-level helpers: constants, type aliases, and init functions
mod board;
// UART driver module
mod uart;
// Debugging output over RTT
use defmt_rtt as _;
// Panic handler for RISC-V targets
#[cfg(target_arch = "riscv32")]
use panic_halt as _;
// Panic handler for ARM targets
#[cfg(target_arch = "arm")]
use panic_probe as _;
// HAL entry-point macro
use hal::entry;
// Alias our HAL crate
#[cfg(rp2350)]
use rp235x_hal as hal;
#[cfg(rp2040)]
use rp2040_hal as hal;
/// Second-stage boot loader for RP2040
#[unsafe(link_section = ".boot2")]
#[used]
#[cfg(rp2040)]
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080;
/// Boot metadata for the RP2350 Boot ROM
#[unsafe(link_section = ".start_block")]
#[used]
#[cfg(rp2350)]
pub static IMAGE_DEF: hal::block::ImageDef = hal::block::ImageDef::secure_exe();
/// Application entry point for the UART uppercase echo demo.
#[entry]
fn main() -> ! {
board::run(hal::pac::Peripherals::take().unwrap())
}
/// Picotool binary info metadata
#[unsafe(link_section = ".bi_entries")]
#[used]
pub static PICOTOOL_ENTRIES: [hal::binary_info::EntryAddr; 5] = [
hal::binary_info::rp_cargo_bin_name!(),
hal::binary_info::rp_cargo_version!(),
hal::binary_info::rp_program_description!(c"UART Uppercase Echo"),
hal::binary_info::rp_cargo_homepage_url!(),
hal::binary_info::rp_program_build_attribute!(),
];
+216
View File
@@ -0,0 +1,216 @@
//! Implementation module
//!
//! **File:** `uart.rs`
//! **Author:** Kevin Thomas
//! **Date:** 2025
//!
//! MIT License
//!
//! Copyright (c) 2025 Kevin Thomas
//!
//! Permission is hereby granted, free of charge, to any person obtaining a copy
//! of this software and associated documentation files (the "Software"), to deal
//! in the Software without restriction, including without limitation the rights
//! to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//! copies of the Software, and to permit persons to whom the Software is
//! furnished to do so, subject to the following conditions:
//!
//! The above copyright notice and this permission notice shall be included in
//! all copies or substantial portions of the Software.
//!
//! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//! AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//! LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//! SOFTWARE.
// Rate extension trait for .Hz() baud rate construction
use fugit::RateExtU32;
// Non-blocking I/O helper for UART read/write
use nb::block;
// Alias our HAL crate
use rp235x_hal as hal;
// Clock trait for accessing system clock frequency
use hal::Clock;
// UART configuration and peripheral types
use hal::uart::{DataBits, Enabled, StopBits, UartConfig, UartPeripheral};
// GPIO pin types and function selectors
use hal::gpio::{FunctionNull, FunctionUart, Pin, PullDown, PullNone};
// UART0 peripheral singleton type
use hal::pac::UART0;
/// Type alias for the configured TX pin (GPIO 0, UART function, no pull).
type TxPin = Pin<hal::gpio::bank0::Gpio0, FunctionUart, PullNone>;
/// Type alias for the configured RX pin (GPIO 1, UART function, no pull).
type RxPin = Pin<hal::gpio::bank0::Gpio1, FunctionUart, PullNone>;
/// Type alias for the default TX pin state from `Pins::new()`.
type TxPinDefault = Pin<hal::gpio::bank0::Gpio0, FunctionNull, PullDown>;
/// Type alias for the default RX pin state from `Pins::new()`.
type RxPinDefault = Pin<hal::gpio::bank0::Gpio1, FunctionNull, PullDown>;
/// Type alias for the fully-enabled UART0 peripheral with TX/RX pins.
type EnabledUart = UartPeripheral<Enabled, UART0, (TxPin, RxPin)>;
/// Blocking UART0 driver that owns the enabled peripheral and its pins.
pub struct UartDriver {
uart: EnabledUart,
}
/// Reconfigure TX and RX pins from their default state to UART function.
fn reconfigure_pins(tx_pin: TxPinDefault, rx_pin: RxPinDefault) -> (TxPin, RxPin) {
(
tx_pin.reconfigure::<FunctionUart, PullNone>(),
rx_pin.reconfigure::<FunctionUart, PullNone>(),
)
}
impl UartDriver {
/// Initialize hardware UART0 on the specified TX and RX GPIO pins.
///
/// Configures UART0 at the requested baud rate, reconfigures the GPIO
/// pins for UART function, and enables 8N1 framing.
///
/// # Arguments
///
/// * `uart0` - PAC UART0 peripheral singleton.
/// * `tx_pin` - GPIO pin to use as UART0 TX (typically GPIO 0).
/// * `rx_pin` - GPIO pin to use as UART0 RX (typically GPIO 1).
/// * `baud_rate` - Desired baud rate in bits per second (e.g. 115200).
/// * `resets` - Mutable reference to the RESETS peripheral.
/// * `clocks` - Reference to the initialised clock configuration.
///
/// # Panics
///
/// Panics if the HAL cannot achieve the requested baud rate.
pub fn init(
uart0: UART0,
tx_pin: TxPinDefault,
rx_pin: RxPinDefault,
baud_rate: u32,
resets: &mut hal::pac::RESETS,
clocks: &hal::clocks::ClocksManager,
) -> Self {
let pins = reconfigure_pins(tx_pin, rx_pin);
let cfg = UartConfig::new(baud_rate.Hz(), DataBits::Eight, None, StopBits::One);
let uart = UartPeripheral::new(uart0, pins, resets)
.enable(cfg, clocks.peripheral_clock.freq())
.unwrap();
Self { uart }
}
/// Check whether a received character is waiting in the UART FIFO.
///
/// Returns immediately without blocking.
///
/// # Returns
///
/// `true` if at least one byte is available to read, `false` otherwise.
pub fn is_readable(&self) -> bool {
self.uart.uart_is_readable()
}
/// Read one character from UART0 (blocking).
///
/// Blocks until a byte arrives in the receive FIFO, then returns it.
///
/// # Returns
///
/// The received byte.
pub fn getchar(&mut self) -> u8 {
block!(embedded_hal_nb::serial::Read::read(&mut self.uart)).unwrap()
}
/// Transmit one character over UART0 (blocking).
///
/// Waits until the transmit FIFO has space, then places the byte into
/// the FIFO.
///
/// # Arguments
///
/// * `c` - Byte to transmit.
pub fn putchar(&mut self, c: u8) {
block!(embedded_hal_nb::serial::Write::write(&mut self.uart, c)).unwrap();
}
/// Transmit a null-terminated string over UART0.
///
/// Sends every byte in the slice, blocking until all bytes are sent.
///
/// # Arguments
///
/// * `s` - Byte slice to transmit.
pub fn puts(&mut self, s: &[u8]) {
self.uart.write_full_blocking(s);
}
/// Convert a lowercase ASCII character to uppercase.
///
/// Returns the uppercase equivalent if the character is in `b'a'``b'z'`;
/// all other characters are passed through unchanged.
///
/// # Arguments
///
/// * `c` - Input byte.
///
/// # Returns
///
/// Uppercase equivalent, or the original byte.
pub fn to_upper(c: u8) -> u8 {
if c >= b'a' && c <= b'z' {
c - 32
} else {
c
}
}
}
#[cfg(test)]
mod tests {
// Import all parent module items
use super::*;
#[test]
fn to_upper_lowercase_a() {
assert_eq!(UartDriver::to_upper(b'a'), b'A');
}
#[test]
fn to_upper_lowercase_z() {
assert_eq!(UartDriver::to_upper(b'z'), b'Z');
}
#[test]
fn to_upper_lowercase_m() {
assert_eq!(UartDriver::to_upper(b'm'), b'M');
}
#[test]
fn to_upper_already_uppercase() {
assert_eq!(UartDriver::to_upper(b'A'), b'A');
}
#[test]
fn to_upper_digit_unchanged() {
assert_eq!(UartDriver::to_upper(b'5'), b'5');
}
#[test]
fn to_upper_space_unchanged() {
assert_eq!(UartDriver::to_upper(b' '), b' ');
}
#[test]
fn to_upper_newline_unchanged() {
assert_eq!(UartDriver::to_upper(b'\n'), b'\n');
}
#[test]
fn to_upper_null_unchanged() {
assert_eq!(UartDriver::to_upper(0), 0);
}
}
+22
View File
@@ -0,0 +1,22 @@
{
"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
}
+15
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}"
}
}
]
+9
View File
@@ -0,0 +1,9 @@
{
"recommendations": [
"marus25.cortex-debug",
"ms-vscode.cpptools",
"ms-vscode.cpptools-extension-pack",
"ms-vscode.vscode-serial-monitor",
"raspberry-pi.raspberry-pi-pico"
]
}
+50
View File
@@ -0,0 +1,50 @@
{
"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}\""
]
},
]
}
+43
View File
@@ -0,0 +1,43 @@
{
"cmake.showSystemKits": false,
"cmake.options.statusBarVisibility": "hidden",
"cmake.options.advanced": {
"build": {
"statusBarVisibility": "hidden"
},
"launch": {
"statusBarVisibility": "hidden"
},
"debug": {
"statusBarVisibility": "hidden"
}
},
"cmake.configureOnEdit": false,
"cmake.automaticReconfigure": false,
"cmake.configureOnOpen": false,
"cmake.generator": "Ninja",
"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",
"files.associations": {
"stdlib.h": "c"
}
}
+125
View File
@@ -0,0 +1,125 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Compile Project",
"type": "process",
"isBuildCommand": true,
"dependsOn": "Configure Project",
"dependsOrder": "sequence",
"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": "Configure Project",
"type": "process",
"command": "${userHome}/.pico-sdk/cmake/v3.31.5/bin/cmake",
"args": [
"-S",
"${workspaceFolder}",
"-B",
"${workspaceFolder}/build",
"-G",
"Ninja"
],
"presentation": {
"reveal": "always",
"panel": "dedicated"
},
"problemMatcher": "$gcc",
"windows": {
"command": "${env:USERPROFILE}/.pico-sdk/cmake/v3.31.5/bin/cmake.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",
}
}
]
}
+57
View File
@@ -0,0 +1,57 @@
/**
* @file 0x02_blink.c
* @brief Blink demonstration: toggle onboard LED every 500 ms
* @author Kevin Thomas
* @date 2025
*
* MIT License
*
* Copyright (c) 2025 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* -----------------------------------------------------------------------------
*
* Demonstrates GPIO output control using the blink driver (blink.h / blink.c).
* The onboard LED on GPIO 25 is toggled every BLINK_DELAY_MS milliseconds and
* the current state is reported over UART.
*
* Wiring:
* GPIO25 -> Onboard LED (no external wiring needed)
*/
#include <stdio.h>
#include "pico/stdlib.h"
#include "blink.h"
/** @brief GPIO pin for the onboard LED */
#define LED_PIN 25
/** @brief Delay between blink toggles in milliseconds */
#define BLINK_DELAY_MS 500
int main(void) {
stdio_init_all();
blink_init(LED_PIN);
printf("Blink driver initialized on GPIO %d\r\n", LED_PIN);
while (true) {
blink_toggle(LED_PIN);
printf("LED: %s\r\n", blink_get_state(LED_PIN) ? "ON" : "OFF");
sleep_ms(BLINK_DELAY_MS);
}
}
+56
View File
@@ -0,0 +1,56 @@
# Generated Cmake Pico project file
cmake_minimum_required(VERSION 3.13)
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(0x02_blink C CXX ASM)
# Initialise the Raspberry Pi Pico SDK
pico_sdk_init()
# Add executable. Default name is the project name, version 0.1
add_executable(0x02_blink 0x02_blink.c blink.c)
pico_set_program_name(0x02_blink "0x02_blink")
pico_set_program_version(0x02_blink "0.1")
# Modify the below lines to enable/disable output over UART/USB
pico_enable_stdio_uart(0x02_blink 1)
pico_enable_stdio_usb(0x02_blink 0)
# Add the standard library to the build
target_link_libraries(0x02_blink
pico_stdlib)
# Add the standard include files to the build
target_include_directories(0x02_blink PRIVATE
${CMAKE_CURRENT_LIST_DIR}
)
pico_add_extra_outputs(0x02_blink)
+54
View File
@@ -0,0 +1,54 @@
/**
* @file blink.c
* @brief Implementation of the GPIO output / LED blink driver
* @author Kevin Thomas
* @date 2025
*
* MIT License
*
* Copyright (c) 2025 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "blink.h"
#include "pico/stdlib.h"
#include "hardware/gpio.h"
void blink_init(uint32_t pin) {
gpio_init(pin);
gpio_set_dir(pin, GPIO_OUT);
gpio_put(pin, false);
}
void blink_on(uint32_t pin) {
gpio_put(pin, true);
}
void blink_off(uint32_t pin) {
gpio_put(pin, false);
}
void blink_toggle(uint32_t pin) {
gpio_put(pin, !gpio_get(pin));
}
bool blink_get_state(uint32_t pin) {
return (bool)gpio_get(pin);
}
+78
View File
@@ -0,0 +1,78 @@
/**
* @file blink.h
* @brief Header for GPIO output / LED blink driver
* @author Kevin Thomas
* @date 2025
*
* MIT License
*
* Copyright (c) 2025 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef BLINK_H
#define BLINK_H
#include <stdint.h>
#include <stdbool.h>
/**
* @brief Initialize a GPIO pin as a push-pull digital output
*
* Calls gpio_init() and gpio_set_dir() to configure the pin for output.
* The initial drive level is low (LED off).
*
* @param pin GPIO pin number to configure as a digital output
*/
void blink_init(uint32_t pin);
/**
* @brief Drive the output pin high (LED on)
*
* @param pin GPIO pin number previously initialized with blink_init()
*/
void blink_on(uint32_t pin);
/**
* @brief Drive the output pin low (LED off)
*
* @param pin GPIO pin number previously initialized with blink_init()
*/
void blink_off(uint32_t pin);
/**
* @brief Toggle the current state of the output pin
*
* Reads the current GPIO output level and inverts it. If the LED was on
* it is turned off, and vice versa.
*
* @param pin GPIO pin number previously initialized with blink_init()
*/
void blink_toggle(uint32_t pin);
/**
* @brief Query the current drive state of the output pin
*
* @param pin GPIO pin number previously initialized with blink_init()
* @return bool true if the pin is driven high, false if driven low
*/
bool blink_get_state(uint32_t pin);
#endif // BLINK_H
+121
View File
@@ -0,0 +1,121 @@
# This is a copy of <PICO_SDK_PATH>/external/pico_sdk_import.cmake
# 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}')")
endif ()
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT))
set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT})
message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')")
endif ()
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH))
set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH})
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)
include(FetchContent)
set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR})
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 ()
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")
# 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})
else ()
message(FATAL_ERROR
"SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git."
)
endif ()
endif ()
get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
if (NOT EXISTS ${PICO_SDK_PATH})
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found")
endif ()
set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake)
if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE})
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK")
endif ()
set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE)
include(${PICO_SDK_INIT_CMAKE_FILE})
+45
View File
@@ -0,0 +1,45 @@
{
"configurations": [
{
"name": "ARM GCC",
"includePath": [
"${workspaceFolder}/Inc/**"
],
"defines": [
"__GNUC__",
"__ARM_ARCH_8M_MAIN__",
"__ARMCC_VERSION"
],
"compilerPath": "${userHome}/.pico-sdk/toolchain/14_2_Rel1/bin/arm-none-eabi-gcc",
"compileCommands": "${workspaceFolder}/compile_commands.json",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "gcc-arm",
"compilerArgs": [
"-mcpu=cortex-m33",
"-mthumb"
]
},
{
"name": "ARM GCC (Windows)",
"includePath": [
"${workspaceFolder}/Inc/**"
],
"defines": [
"__GNUC__",
"__ARM_ARCH_8M_MAIN__",
"__ARMCC_VERSION"
],
"compilerPath": "${env:USERPROFILE}/.pico-sdk/toolchain/14_2_Rel1/bin/arm-none-eabi-gcc.exe",
"compileCommands": "${workspaceFolder}/compile_commands.json",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "gcc-arm",
"compilerArgs": [
"-mcpu=cortex-m33",
"-mthumb"
]
}
],
"version": 4
}
+9
View File
@@ -0,0 +1,9 @@
{
"recommendations": [
"marus25.cortex-debug",
"ms-vscode.cpptools",
"ms-vscode.cpptools-extension-pack",
"ms-vscode.vscode-serial-monitor",
"raspberry-pi.raspberry-pi-pico"
]
}
+47
View File
@@ -0,0 +1,47 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug RP2350 (OpenOCD)",
"cwd": "${workspaceFolder}",
"executable": "${workspaceFolder}/build/blink.elf",
"request": "launch",
"type": "cortex-debug",
"servertype": "openocd",
"serverpath": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd",
"searchDir": [
"${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts"
],
"gdbPath": "${userHome}/.pico-sdk/toolchain/14_2_Rel1/bin/arm-none-eabi-gdb",
"device": "RP2350",
"configFiles": [
"interface/cmsis-dap.cfg",
"target/rp2350.cfg"
],
"svdFile": "${userHome}/.pico-sdk/sdk/2.2.0/src/rp2350/hardware_regs/RP2350.svd",
"overrideLaunchCommands": [
"set arch armv8-m.main",
"set output-radix 16",
"monitor reset init",
"load",
"monitor reset halt"
],
"openOCDPreConfigLaunchCommands": [
"set USE_CORE { cm0 cm1 }"
],
"openOCDLaunchCommands": [
"adapter speed 5000"
],
"preLaunchTask": "Compile Project",
"showDevDebugOutput": "raw",
"windows": {
"serverpath": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
"searchDir": [
"${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/scripts"
],
"gdbPath": "${env:USERPROFILE}/.pico-sdk/toolchain/14_2_Rel1/bin/arm-none-eabi-gdb.exe",
"svdFile": "${env:USERPROFILE}/.pico-sdk/sdk/2.2.0/src/rp2350/hardware_regs/RP2350.svd"
}
}
]
}
+40
View File
@@ -0,0 +1,40 @@
{
"cmake.showSystemKits": false,
"cmake.options.statusBarVisibility": "hidden",
"cmake.options.advanced": {
"build": {
"statusBarVisibility": "hidden"
},
"launch": {
"statusBarVisibility": "hidden"
},
"debug": {
"statusBarVisibility": "hidden"
}
},
"cmake.configureOnEdit": false,
"cmake.automaticReconfigure": false,
"cmake.configureOnOpen": false,
"cmake.generator": "Ninja",
"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-a4/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-a4/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-a4/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"
}
+128
View File
@@ -0,0 +1,128 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Compile Project",
"type": "shell",
"command": "make",
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"reveal": "always",
"panel": "dedicated"
},
"problemMatcher": "$gcc",
"windows": {
"command": ".\\build.bat"
}
},
{
"label": "Clean Project",
"type": "shell",
"command": "make clean",
"group": "build",
"presentation": {
"reveal": "always",
"panel": "dedicated"
},
"problemMatcher": [],
"windows": {
"command": ".\\clean.bat"
}
},
{
"label": "Run Project",
"type": "shell",
"command": "${userHome}/.pico-sdk/picotool/2.2.0-a4/picotool/picotool",
"args": [
"load",
"build/blink.uf2",
"-fx"
],
"presentation": {
"reveal": "always",
"panel": "dedicated"
},
"problemMatcher": [],
"dependsOn": [
"Compile Project"
],
"windows": {
"command": "${env:USERPROFILE}/.pico-sdk/picotool/2.2.0-a4/picotool/picotool.exe"
}
},
{
"label": "Flash",
"type": "shell",
"command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd",
"args": [
"-s",
"${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts",
"-f",
"interface/cmsis-dap.cfg",
"-f",
"target/rp2350.cfg",
"-c",
"adapter speed 5000; program build/blink.elf verify reset exit"
],
"problemMatcher": [],
"dependsOn": [
"Compile Project"
],
"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",
"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",
"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"
}
}
]
}
],
"problemMatcher": []
}
]
}
+203
View File
@@ -0,0 +1,203 @@
/**
* @file rp2350.h
* @brief RP2350 Device Peripheral Access Layer Header File.
* @author Kevin Thomas
* @date 2026
*
* Memory-mapped register structures and peripheral base addresses
* for the RP2350 microcontroller (Cortex-M33 dual-core). All
* register offsets verified against the RP2350 datasheet
* (RP-008373-DS-2).
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RP2350_H
#define __RP2350_H
#include <stdint.h>
#include <stdbool.h>
/*!< Defines 'read / write' permissions */
#define __IO volatile
/*!< Stack addresses */
#define STACK_TOP 0x20082000UL
#define STACK_LIMIT 0x2007A000UL
/*!< Memory map */
#define XIP_BASE 0x10000000UL
#define SRAM_BASE 0x20000000UL
#define SIO_BASE 0xD0000000UL
#define PPB_BASE 0xE0000000UL
/*!< APB peripherals */
#define CLOCKS_BASE 0x40010000UL
#define RESETS_BASE 0x40020000UL
#define IO_BANK0_BASE 0x40028000UL
#define PADS_BANK0_BASE 0x40038000UL
#define XOSC_BASE 0x40048000UL
#define UART0_BASE 0x40070000UL
/**
* @brief XOSC (External Crystal Oscillator)
*/
typedef struct
{
__IO uint32_t CTRL; // Control register Address offset: 0x00
__IO uint32_t STATUS; // Status register Address offset: 0x04
__IO uint32_t DORMANT; // Dormant mode Address offset: 0x08
__IO uint32_t STARTUP; // Startup delay Address offset: 0x0C
__IO uint32_t COUNT; // Frequency count Address offset: 0x10
} XOSC_TypeDef;
/**
* @brief CLOCKS
*/
typedef struct
{
__IO uint32_t RESERVED0[18]; // Other clock registers Address offset: 0x00-0x44
__IO uint32_t CLK_PERI_CTRL; // Peripheral clock control Address offset: 0x48
} CLOCKS_TypeDef;
/**
* @brief RESETS
*/
typedef struct
{
__IO uint32_t RESET; // Reset control Address offset: 0x00
__IO uint32_t WDSEL; // Watchdog select Address offset: 0x04
__IO uint32_t RESET_DONE; // Reset done status Address offset: 0x08
} RESETS_TypeDef;
/**
* @brief IO_BANK0 GPIO Control (one per GPIO)
*/
typedef struct
{
__IO uint32_t STATUS; // GPIO status Address offset: 0x00
__IO uint32_t CTRL; // GPIO control Address offset: 0x04
} IO_BANK0_GPIO_TypeDef;
/**
* @brief IO_BANK0
*/
typedef struct
{
IO_BANK0_GPIO_TypeDef GPIO[30]; // GPIO 0-29 status/ctrl pairs Address offset: 0x000-0x0E8
} IO_BANK0_TypeDef;
/**
* @brief PADS_BANK0
*/
typedef struct
{
__IO uint32_t VOLTAGE_SELECT; // Voltage select Address offset: 0x00
__IO uint32_t GPIO[30]; // GPIO 0-29 pad control Address offset: 0x04-0x78
} PADS_BANK0_TypeDef;
/**
* @brief Peripheral Definitions
*/
#define XOSC ((XOSC_TypeDef *) XOSC_BASE)
#define CLOCKS ((CLOCKS_TypeDef *) CLOCKS_BASE)
#define RESETS ((RESETS_TypeDef *) RESETS_BASE)
#define IO_BANK0 ((IO_BANK0_TypeDef *) IO_BANK0_BASE)
#define PADS_BANK0 ((PADS_BANK0_TypeDef *) PADS_BANK0_BASE)
#define SIO ((volatile uint32_t *) SIO_BASE)
#define CPACR ((volatile uint32_t *) (PPB_BASE + 0x0ED88UL))
/**
* @brief XOSC bit definitions
*/
#define XOSC_STATUS_STABLE_SHIFT 31U
/**
* @brief CPACR bit definitions
*/
#define CPACR_CP0_SHIFT 0U
#define CPACR_CP1_SHIFT 1U
/**
* @brief CLOCKS bit definitions
*/
#define CLK_PERI_CTRL_ENABLE_SHIFT 11U
#define CLK_PERI_CTRL_AUXSRC_SHIFT 5U
#define CLK_PERI_CTRL_AUXSRC_XOSC 4U
/**
* @brief RESETS bit definitions
*/
#define RESETS_RESET_IO_BANK0_SHIFT 6U
#define RESETS_RESET_UART0_SHIFT 26U
/**
* @brief IO_BANK0 bit definitions
*/
#define IO_BANK0_CTRL_FUNCSEL_MASK 0x1FU
#define IO_BANK0_CTRL_FUNCSEL_UART 0x02U
#define IO_BANK0_CTRL_FUNCSEL_SIO 0x05U
/**
* @brief PADS_BANK0 bit definitions
*/
#define PADS_BANK0_OD_SHIFT 7U
#define PADS_BANK0_IE_SHIFT 6U
#define PADS_BANK0_ISO_SHIFT 8U
/**
* @brief UART register offsets (word indices from UART0_BASE)
*/
#define UART_DR_OFFSET (0x000U / 4U)
#define UART_FR_OFFSET (0x018U / 4U)
#define UART_IBRD_OFFSET (0x024U / 4U)
#define UART_FBRD_OFFSET (0x028U / 4U)
#define UART_LCR_H_OFFSET (0x02CU / 4U)
#define UART_CR_OFFSET (0x030U / 4U)
/**
* @brief UART flag register bit definitions
*/
#define UART_FR_TXFF_MASK 32U
#define UART_FR_RXFE_MASK 16U
/**
* @brief UART line control and enable values
*/
#define UART_LCR_H_8N1_FIFO 0x70U
#define UART_CR_ENABLE ((3U << 8) | 1U)
/**
* @brief GPIO pin definitions
*/
#define LED_PIN 25U
/**
* @brief SIO GPIO register offsets (word indices from SIO_BASE)
*/
#define SIO_GPIO_IN_OFFSET (0x004U / 4U)
#define SIO_GPIO_OUT_SET_OFFSET (0x018U / 4U)
#define SIO_GPIO_OUT_CLR_OFFSET (0x020U / 4U)
#define SIO_GPIO_OUT_XOR_OFFSET (0x028U / 4U)
#define SIO_GPIO_OE_SET_OFFSET (0x038U / 4U)
#endif /* __RP2350_H */
+43
View File
@@ -0,0 +1,43 @@
/**
* @file rp2350_delay.h
* @brief Delay driver header for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Millisecond busy-wait delay calibrated for a 12 MHz clock.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RP2350_DELAY_H
#define __RP2350_DELAY_H
#include "rp2350.h"
/**
* @brief Delay for the specified number of milliseconds.
* @param ms number of milliseconds to delay
* @retval None
*/
void delay_ms(uint32_t ms);
#endif /* __RP2350_DELAY_H */
+72
View File
@@ -0,0 +1,72 @@
/**
* @file rp2350_gpio.h
* @brief GPIO driver header for RP2350.
* @author Kevin Thomas
* @date 2026
*
* SIO-based GPIO configuration, set, clear, toggle, and read
* functions for the RP2350 GPIO pins 0-29.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RP2350_GPIO_H
#define __RP2350_GPIO_H
#include "rp2350.h"
/**
* @brief Configure a GPIO pin as SIO output.
* @param gpio_num GPIO pin number (0-29)
* @retval None
*/
void gpio_config(uint32_t gpio_num);
/**
* @brief Drive a GPIO output high.
* @param gpio_num GPIO pin number (0-29)
* @retval None
*/
void gpio_set(uint32_t gpio_num);
/**
* @brief Drive a GPIO output low.
* @param gpio_num GPIO pin number (0-29)
* @retval None
*/
void gpio_clear(uint32_t gpio_num);
/**
* @brief Toggle a GPIO output.
* @param gpio_num GPIO pin number (0-29)
* @retval None
*/
void gpio_toggle(uint32_t gpio_num);
/**
* @brief Read the current input level of a GPIO pin.
* @param gpio_num GPIO pin number (0-29)
* @retval bool true if pin is high, false if low
*/
bool gpio_get(uint32_t gpio_num);
#endif /* __RP2350_GPIO_H */
+72
View File
@@ -0,0 +1,72 @@
/**
* @file rp2350_led.h
* @brief LED driver header for RP2350.
* @author Kevin Thomas
* @date 2026
*
* High-level GPIO output / LED driver wrapping the
* low-level GPIO functions.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RP2350_LED_H
#define __RP2350_LED_H
#include "rp2350.h"
/**
* @brief Initialize a GPIO pin as a push-pull digital output.
* @param pin GPIO pin number to configure
* @retval None
*/
void led_init(uint32_t pin);
/**
* @brief Drive the output pin high (LED on).
* @param pin GPIO pin number
* @retval None
*/
void led_on(uint32_t pin);
/**
* @brief Drive the output pin low (LED off).
* @param pin GPIO pin number
* @retval None
*/
void led_off(uint32_t pin);
/**
* @brief Toggle the current state of the output pin.
* @param pin GPIO pin number
* @retval None
*/
void led_toggle(uint32_t pin);
/**
* @brief Query the current drive state of the output pin.
* @param pin GPIO pin number
* @retval bool true if the pin is driven high, false if low
*/
bool led_get_state(uint32_t pin);
#endif /* __RP2350_LED_H */
+42
View File
@@ -0,0 +1,42 @@
/**
* @file rp2350_reset.h
* @brief Reset controller driver header for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Provides subsystem reset release for IO_BANK0.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RP2350_RESET_H
#define __RP2350_RESET_H
#include "rp2350.h"
/**
* @brief Release IO_BANK0 from reset and wait until ready.
* @retval None
*/
void reset_init_subsystem(void);
#endif /* __RP2350_RESET_H */
@@ -0,0 +1,42 @@
/**
* @file rp2350_reset_handler.h
* @brief Reset handler header for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Entry point after reset. Performs stack initialization, XOSC
* setup, subsystem reset release, UART initialization,
* and branches to main().
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RP2350_RESET_HANDLER_H
#define __RP2350_RESET_HANDLER_H
/**
* @brief Reset handler entry point (naked, noreturn).
* @retval None
*/
void Reset_Handler(void) __attribute__((noreturn));
#endif /* __RP2350_RESET_HANDLER_H */
+43
View File
@@ -0,0 +1,43 @@
/**
* @file rp2350_stack.h
* @brief Stack pointer initialization header for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Sets MSP, PSP, MSPLIM, and PSPLIM from the STACK_TOP and
* STACK_LIMIT values defined in rp2350.h.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RP2350_STACK_H
#define __RP2350_STACK_H
#include "rp2350.h"
/**
* @brief Initialize MSP, PSP, MSPLIM, and PSPLIM stack pointers.
* @retval None
*/
void stack_init(void);
#endif /* __RP2350_STACK_H */
+82
View File
@@ -0,0 +1,82 @@
/**
* @file rp2350_uart.h
* @brief UART0 driver header for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Bare-metal UART0 driver supporting TX/RX on GPIO 0/1 at
* 115200 baud (12 MHz XOSC clock).
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RP2350_UART_H
#define __RP2350_UART_H
#include "rp2350.h"
/**
* @brief Release UART0 from reset and wait until ready.
* @retval None
*/
void uart_release_reset(void);
/**
* @brief Initialize UART0 pins, baud rate, line control, and enable.
* @retval None
*/
void uart_init(void);
/**
* @brief Check whether a received byte is waiting in the UART FIFO.
* @retval bool true if at least one byte is available
*/
bool uart_is_readable(void);
/**
* @brief Read one character from UART0 (blocking).
* @retval char the received character
*/
char uart_getchar(void);
/**
* @brief Transmit one character over UART0 (blocking).
* @param c character to transmit
* @retval None
*/
void uart_putchar(char c);
/**
* @brief Transmit a null-terminated string over UART0.
* @param str pointer to the string to send
* @retval None
*/
void uart_puts(const char *str);
/**
* @brief Convert a lowercase ASCII character to uppercase.
* @param c input character
* @retval char uppercase equivalent or original character
*/
char uart_to_upper(char c);
#endif /* __RP2350_UART_H */
+49
View File
@@ -0,0 +1,49 @@
/**
* @file rp2350_xosc.h
* @brief XOSC driver header for RP2350.
* @author Kevin Thomas
* @date 2026
*
* External crystal oscillator initialization and peripheral
* clock enable using the XOSC registers.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RP2350_XOSC_H
#define __RP2350_XOSC_H
#include "rp2350.h"
/**
* @brief Initialize the external crystal oscillator and wait until stable.
* @retval None
*/
void xosc_init(void);
/**
* @brief Enable the XOSC peripheral clock via CLK_PERI_CTRL.
* @retval None
*/
void xosc_enable_peri_clk(void);
#endif /* __RP2350_XOSC_H */
+86
View File
@@ -0,0 +1,86 @@
# ------------------------------------------------------------------------------
# @file Makefile
# @author Kevin Thomas
# @brief Build script for RP2350 bare-metal C blink driver.
#
# Compiles, links, and generates UF2 firmware for the RP2350.
# ------------------------------------------------------------------------------
# OS detection
ifeq ($(OS),Windows_NT)
MKDIR = if not exist $(subst /,\\,$(BUILD_DIR)) mkdir $(subst /,\\,$(BUILD_DIR))
RM = if exist $(subst /,\\,$(BUILD_DIR)) rmdir /s /q $(subst /,\\,$(BUILD_DIR))
else
MKDIR = mkdir -p $(BUILD_DIR)
RM = rm -rf $(BUILD_DIR)
endif
# Toolchain
CC = arm-none-eabi-gcc
OBJCOPY = arm-none-eabi-objcopy
SIZE = arm-none-eabi-size
# Target
TARGET = blink
# Directories
SRC_DIR = Src
INC_DIR = Inc
BUILD_DIR = build
# CPU flags
CPU_FLAGS = -mcpu=cortex-m33 -mthumb
# Compiler flags
CFLAGS = $(CPU_FLAGS) -Og -g3 -Wall -Wextra \
-ffunction-sections -fdata-sections \
-I$(INC_DIR)
# Linker flags
LDFLAGS = $(CPU_FLAGS) -T linker.ld -nostdlib -Wl,--gc-sections
# Source files
SRCS = $(SRC_DIR)/vector_table.c \
$(SRC_DIR)/rp2350_reset_handler.c \
$(SRC_DIR)/rp2350_stack.c \
$(SRC_DIR)/rp2350_xosc.c \
$(SRC_DIR)/rp2350_reset.c \
$(SRC_DIR)/rp2350_uart.c \
$(SRC_DIR)/rp2350_gpio.c \
$(SRC_DIR)/rp2350_led.c \
$(SRC_DIR)/rp2350_delay.c \
$(SRC_DIR)/main.c \
$(SRC_DIR)/image_def.c
# Object files
OBJS = $(patsubst $(SRC_DIR)/%.c,$(BUILD_DIR)/%.o,$(SRCS))
# Rules
.PHONY: all clean flash
all: $(BUILD_DIR)/$(TARGET).bin
@echo "==================================="
@echo "SUCCESS! Created $(TARGET).elf and $(TARGET).bin"
@echo "==================================="
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c | $(BUILD_DIR)
$(CC) $(CFLAGS) -c $< -o $@
$(BUILD_DIR)/$(TARGET).elf: $(OBJS)
$(CC) $(LDFLAGS) $(OBJS) -o $@
$(SIZE) $@
$(BUILD_DIR)/$(TARGET).bin: $(BUILD_DIR)/$(TARGET).elf
$(OBJCOPY) -O binary $< $@
$(BUILD_DIR):
$(MKDIR)
clean:
$(RM)
flash: $(BUILD_DIR)/$(TARGET).elf
openocd -f interface/cmsis-dap.cfg -f target/rp2350.cfg \
-c "adapter speed 5000" \
-c "program $< verify reset exit"
+41
View File
@@ -0,0 +1,41 @@
/**
* @file image_def.c
* @brief RP2350 IMAGE_DEF block for boot ROM image recognition.
* @author Kevin Thomas
* @date 2026
*
* Must appear within the first 4 KB of flash for the boot ROM
* to accept the image.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <stdint.h>
__attribute__((section(".embedded_block"), used))
const uint8_t picobin_block[] = {
0xD3, 0xDE, 0xFF, 0xFF,
0x42, 0x01, 0x21, 0x10,
0xFF, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x79, 0x35, 0x12, 0xAB
};
+63
View File
@@ -0,0 +1,63 @@
/**
* @file main.c
* @brief Blink demonstration: toggle onboard LED every 500 ms.
* @author Kevin Thomas
* @date 2026
*
* Demonstrates GPIO output control using the blink driver.
* The onboard LED on GPIO 25 is toggled every 500 ms and the
* current state is reported over UART.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "rp2350_led.h"
#include "rp2350_uart.h"
#include "rp2350_delay.h"
/** @brief Delay between LED state toggles in milliseconds */
#define BLINK_DELAY_MS 500
/**
* @brief Print the current LED state over UART.
* @param pin GPIO pin number to query
* @retval None
*/
static void print_led_state(uint32_t pin)
{
if (led_get_state(pin))
uart_puts("LED: ON\r\n");
else
uart_puts("LED: OFF\r\n");
}
int main(void)
{
led_init(LED_PIN);
uart_puts("LED driver initialized on GPIO 25\r\n");
while (1)
{
led_toggle(LED_PIN);
print_led_state(LED_PIN);
delay_ms(BLINK_DELAY_MS);
}
}
+48
View File
@@ -0,0 +1,48 @@
/**
* @file rp2350_delay.c
* @brief Delay driver implementation for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Busy-wait millisecond delay calibrated for a 12 MHz clock
* (3600 loop iterations per millisecond).
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "rp2350_delay.h"
void delay_ms(uint32_t ms)
{
if (ms == 0)
return;
__asm__ volatile (
"mov r4, #3600\n\t"
"mul r5, %0, r4\n\t"
"1:\n\t"
"subs r5, #1\n\t"
"bne 1b\n\t"
:
: "r" (ms)
: "r4", "r5", "cc"
);
}
+99
View File
@@ -0,0 +1,99 @@
/**
* @file rp2350_gpio.c
* @brief GPIO driver implementation for RP2350.
* @author Kevin Thomas
* @date 2026
*
* SIO-based GPIO configuration using IO_BANK0 and PADS_BANK0
* register structs defined in rp2350.h. All register offsets
* verified against the RP2350 datasheet (RP-008373-DS-2).
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "rp2350_gpio.h"
/**
* @brief Configure pad control for a GPIO pin.
* @param gpio_num GPIO pin number (0-29)
* @retval None
*/
static void gpio_config_pad(uint32_t gpio_num)
{
uint32_t value;
value = PADS_BANK0->GPIO[gpio_num];
value &= ~(1U << PADS_BANK0_OD_SHIFT);
value |= (1U << PADS_BANK0_IE_SHIFT);
value &= ~(1U << PADS_BANK0_ISO_SHIFT);
PADS_BANK0->GPIO[gpio_num] = value;
}
/**
* @brief Set IO_BANK0 FUNCSEL to SIO for a GPIO pin.
* @param gpio_num GPIO pin number (0-29)
* @retval None
*/
static void gpio_config_funcsel(uint32_t gpio_num)
{
uint32_t value;
value = IO_BANK0->GPIO[gpio_num].CTRL;
value &= ~IO_BANK0_CTRL_FUNCSEL_MASK;
value |= IO_BANK0_CTRL_FUNCSEL_SIO;
IO_BANK0->GPIO[gpio_num].CTRL = value;
}
/**
* @brief Enable the output driver for a GPIO pin via SIO.
* @param gpio_num GPIO pin number (0-29)
* @retval None
*/
static void gpio_enable_output(uint32_t gpio_num)
{
SIO[SIO_GPIO_OE_SET_OFFSET] = (1U << gpio_num);
}
void gpio_config(uint32_t gpio_num)
{
gpio_config_pad(gpio_num);
gpio_config_funcsel(gpio_num);
gpio_enable_output(gpio_num);
}
void gpio_set(uint32_t gpio_num)
{
SIO[SIO_GPIO_OUT_SET_OFFSET] = (1U << gpio_num);
}
void gpio_clear(uint32_t gpio_num)
{
SIO[SIO_GPIO_OUT_CLR_OFFSET] = (1U << gpio_num);
}
void gpio_toggle(uint32_t gpio_num)
{
SIO[SIO_GPIO_OUT_XOR_OFFSET] = (1U << gpio_num);
}
bool gpio_get(uint32_t gpio_num)
{
return (SIO[SIO_GPIO_IN_OFFSET] & (1U << gpio_num)) != 0;
}
+58
View File
@@ -0,0 +1,58 @@
/**
* @file rp2350_led.c
* @brief LED driver implementation for RP2350.
* @author Kevin Thomas
* @date 2026
*
* High-level wrapper around the GPIO driver for LED control.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "rp2350_led.h"
#include "rp2350_gpio.h"
void led_init(uint32_t pin)
{
gpio_config(pin);
gpio_clear(pin);
}
void led_on(uint32_t pin)
{
gpio_set(pin);
}
void led_off(uint32_t pin)
{
gpio_clear(pin);
}
void led_toggle(uint32_t pin)
{
gpio_toggle(pin);
}
bool led_get_state(uint32_t pin)
{
return gpio_get(pin);
}
+41
View File
@@ -0,0 +1,41 @@
/**
* @file rp2350_reset.c
* @brief Reset controller driver implementation for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Releases IO_BANK0 from reset and waits until the subsystem
* is ready.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "rp2350_reset.h"
void reset_init_subsystem(void)
{
uint32_t value;
value = RESETS->RESET;
value &= ~(1U << RESETS_RESET_IO_BANK0_SHIFT);
RESETS->RESET = value;
while ((RESETS->RESET_DONE & (1U << RESETS_RESET_IO_BANK0_SHIFT)) == 0) {}
}
@@ -0,0 +1,80 @@
/**
* @file rp2350_reset_handler.c
* @brief Reset handler implementation for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Entry point after power-on or system reset. Initializes the
* stack, XOSC, subsystem resets, UART, then branches
* to main().
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "rp2350_reset_handler.h"
#include "rp2350_stack.h"
#include "rp2350_xosc.h"
#include "rp2350_reset.h"
#include "rp2350_uart.h"
extern int main(void);
extern uint32_t __data_lma;
extern uint32_t __data_start;
extern uint32_t __data_end;
extern uint32_t __bss_start;
extern uint32_t __bss_end;
static void _data_copy_init(void)
{
uint32_t *src = &__data_lma;
uint32_t *dst = &__data_start;
while (dst < &__data_end)
*dst++ = *src++;
}
static void _bss_zero_init(void)
{
uint32_t *dst = &__bss_start;
while (dst < &__bss_end)
*dst++ = 0U;
}
void _ram_init(void)
{
stack_init();
_data_copy_init();
_bss_zero_init();
}
void __attribute__((naked, noreturn)) Reset_Handler(void)
{
__asm__ volatile (
"bl _ram_init\n\t"
"bl xosc_init\n\t"
"bl xosc_enable_peri_clk\n\t"
"bl reset_init_subsystem\n\t"
"bl uart_release_reset\n\t"
"bl uart_init\n\t"
"b main\n\t"
);
}
+47
View File
@@ -0,0 +1,47 @@
/**
* @file rp2350_stack.c
* @brief Stack pointer initialization for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Sets MSP, PSP, MSPLIM, and PSPLIM using inline assembly.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "rp2350_stack.h"
void stack_init(void)
{
__asm__ volatile (
"ldr r0, =%0\n\t"
"msr PSP, r0\n\t"
"ldr r0, =%1\n\t"
"msr MSPLIM, r0\n\t"
"msr PSPLIM, r0\n\t"
"ldr r0, =%0\n\t"
"msr MSP, r0\n\t"
:
: "i" (STACK_TOP), "i" (STACK_LIMIT)
: "r0"
);
}
+134
View File
@@ -0,0 +1,134 @@
/**
* @file rp2350_uart.c
* @brief UART0 driver implementation for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Configures UART0 on GPIO 0 (TX) and GPIO 1 (RX) at 115200
* baud using the 12 MHz XOSC clock.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "rp2350_uart.h"
/** @brief Base address pointer for UART0 peripheral registers */
#define UART_BASE ((volatile uint32_t *) UART0_BASE)
/**
* @brief Clear the UART0 reset bit in the reset controller.
* @retval None
*/
static void uart_clear_reset_bit(void)
{
uint32_t value;
value = RESETS->RESET;
value &= ~(1U << RESETS_RESET_UART0_SHIFT);
RESETS->RESET = value;
}
/**
* @brief Wait until the UART0 block is out of reset.
* @retval None
*/
static void uart_wait_reset_done(void)
{
while ((RESETS->RESET_DONE & (1U << RESETS_RESET_UART0_SHIFT)) == 0) {}
}
/**
* @brief Configure GPIO pins 0 (TX) and 1 (RX) for UART function.
* @retval None
*/
static void uart_configure_pins(void)
{
IO_BANK0->GPIO[0].CTRL = IO_BANK0_CTRL_FUNCSEL_UART;
IO_BANK0->GPIO[1].CTRL = IO_BANK0_CTRL_FUNCSEL_UART;
PADS_BANK0->GPIO[0] = 0x04;
PADS_BANK0->GPIO[1] = 0x40;
}
/**
* @brief Set UART0 baud rate divisors for 115200 at 12 MHz.
* @retval None
*/
static void uart_set_baud(void)
{
UART_BASE[UART_CR_OFFSET] = 0;
UART_BASE[UART_IBRD_OFFSET] = 6;
UART_BASE[UART_FBRD_OFFSET] = 33;
}
/**
* @brief Configure line control and enable UART0.
* @retval None
*/
static void uart_enable(void)
{
UART_BASE[UART_LCR_H_OFFSET] = UART_LCR_H_8N1_FIFO;
UART_BASE[UART_CR_OFFSET] = UART_CR_ENABLE;
}
void uart_release_reset(void)
{
uart_clear_reset_bit();
uart_wait_reset_done();
}
void uart_init(void)
{
uart_configure_pins();
uart_set_baud();
uart_enable();
}
bool uart_is_readable(void)
{
return (UART_BASE[UART_FR_OFFSET] & UART_FR_RXFE_MASK) == 0;
}
char uart_getchar(void)
{
while (UART_BASE[UART_FR_OFFSET] & UART_FR_RXFE_MASK) {}
return (char)(UART_BASE[UART_DR_OFFSET] & 0xFF);
}
void uart_putchar(char c)
{
while (UART_BASE[UART_FR_OFFSET] & UART_FR_TXFF_MASK) {}
UART_BASE[UART_DR_OFFSET] = (uint32_t)c;
}
void uart_puts(const char *str)
{
while (*str)
{
uart_putchar(*str++);
}
}
char uart_to_upper(char c)
{
if (c >= 'a' && c <= 'z')
return (char)(c - 32);
return c;
}
+48
View File
@@ -0,0 +1,48 @@
/**
* @file rp2350_xosc.c
* @brief XOSC driver implementation for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Configures the external crystal oscillator and enables the
* peripheral clock sourced from XOSC.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "rp2350_xosc.h"
void xosc_init(void)
{
XOSC->STARTUP = 0x00C4U;
XOSC->CTRL = 0x00FABAA0U;
while ((XOSC->STATUS & (1U << XOSC_STATUS_STABLE_SHIFT)) == 0) {}
}
void xosc_enable_peri_clk(void)
{
uint32_t value;
value = CLOCKS->CLK_PERI_CTRL;
value |= (1U << CLK_PERI_CTRL_ENABLE_SHIFT);
value |= (CLK_PERI_CTRL_AUXSRC_XOSC << CLK_PERI_CTRL_AUXSRC_SHIFT);
CLOCKS->CLK_PERI_CTRL = value;
}
+44
View File
@@ -0,0 +1,44 @@
/**
* @file vector_table.c
* @brief Vector table with initial stack pointer and reset handler.
* @author Kevin Thomas
* @date 2026
*
* Placed in the .vectors section at the start of flash.
* The Thumb bit (bit 0 = 1) is automatically set by the
* linker for function pointers in Thumb mode.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <stdint.h>
extern uint32_t _stack_top;
extern void Reset_Handler(void);
typedef void (*vector_func_t)(void);
__attribute__((section(".vectors"), used))
const void *_vectors[2] = {
&_stack_top,
Reset_Handler
};
Binary file not shown.
+144
View File
@@ -0,0 +1,144 @@
/**
******************************************************************************
* @file linker.ld
* @author Kevin Thomas
* @brief Minimal linker script for bare-metal RP2350 development.
*
* Defines FLASH (XIP 32 MB) and RAM (520 kB SRAM) regions.
* The vector table is placed at the start of flash (0x10000000).
*
******************************************************************************
* @attention
*
* Copyright (c) 2026 Kevin Thomas.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/**
* Entry point.
*/
ENTRY(Reset_Handler)
/**
* Define memory regions.
*/
__XIP_BASE = 0x10000000;
__XIP_SIZE = 32M;
__SRAM_BASE = 0x20000000;
__SRAM_SIZE = 520K;
__STACK_SIZE = 32K;
/**
* Memory layout.
*/
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);
data PT_LOAD FLAGS(6);
}
/**
* Section placement.
*/
SECTIONS
{
. = ORIGIN(FLASH);
/**
* Vector table MUST be first at 0x10000000.
*/
.vectors :
{
KEEP(*(.vectors))
} > FLASH :text
/**
* Verify vector table placement.
*/
ASSERT((ADDR(.vectors) == ORIGIN(FLASH)),
"Vector table must be at start of flash (0x10000000)")
/**
* Text and read-only data.
*/
.text :
{
. = ALIGN(4);
*(.text*)
*(.rodata*)
KEEP(*(.init))
KEEP(*(.fini))
KEEP(*(.ARM.attributes))
} > FLASH :text
/**
* IMAGE_DEF block at end of code.
*/
.embedded_block :
{
KEEP(*(.embedded_block))
} > FLASH :text
/**
* Initialized data and RAM-resident code (LMA in flash, VMA in RAM).
* Startup copies from __data_lma to __data_start..__data_end.
*/
.data :
{
. = ALIGN(4);
__data_start = .;
*(.ram_func*)
*(.data*)
. = ALIGN(4);
__data_end = .;
} > RAM AT> FLASH :data
__data_lma = LOADADDR(.data);
/**
* Uninitialized data (BSS) in RAM.
*/
.bss (NOLOAD) :
{
. = ALIGN(4);
__bss_start = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end = .;
} > RAM
/**
* Non-secure stack symbols.
*/
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - __STACK_SIZE;
__stack = __StackTop;
_stack_top = __StackTop;
/**
* Stack section (no load).
*/
.stack (NOLOAD) : { . = ALIGN(8); } > RAM
/**
* Provide vector table symbol to startup code.
*/
PROVIDE(__Vectors = ADDR(.vectors));
}
+102
View File
@@ -0,0 +1,102 @@
# SPDX-License-Identifier: MIT OR Apache-2.0
#
# Copyright (c) 20212024 The rp-rs Developers
# Copyright (c) 2021 rp-rs organization
# Copyright (c) 2025 Raspberry Pi Ltd.
#
# Cargo Configuration for the https://github.com/rp-rs/rp-hal.git repository.
#
# You might want to make a similar file in your own repository if you are
# writing programs for Raspberry Silicon microcontrollers.
#
[build]
target = "thumbv8m.main-none-eabihf"
# Set the default target to match the Cortex-M33 in the RP2350
# target = "thumbv8m.main-none-eabihf"
# target = "thumbv6m-none-eabi"
# target = "riscv32imac-unknown-none-elf"
# Target specific options
[target.thumbv6m-none-eabi]
# Pass some extra options to rustc, some of which get passed on to the linker.
#
# * linker argument --nmagic turns off page alignment of sections (which saves
# flash space)
# * linker argument -Tlink.x tells the linker to use link.x as the linker
# script. This is usually provided by the cortex-m-rt crate, and by default
# the version in that crate will include a file called `memory.x` which
# describes the particular memory layout for your specific chip.
# * no-vectorize-loops turns off the loop vectorizer (seeing as the M0+ doesn't
# have SIMD)
linker = "flip-link"
rustflags = [
"-C", "link-arg=--nmagic",
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=-Tdefmt.x",
"-C", "no-vectorize-loops",
]
# Use picotool for loading.
#
# Load an elf, skipping unchanged flash sectors, verify it, and execute it
runner = "${PICOTOOL_PATH} load -u -v -x -t elf"
#runner = "probe-rs run --chip ${CHIP} --protocol swd"
# This is the hard-float ABI for Arm mode.
#
# The FPU is enabled by default, and float function arguments use FPU
# registers.
[target.thumbv8m.main-none-eabihf]
# Pass some extra options to rustc, some of which get passed on to the linker.
#
# * linker argument --nmagic turns off page alignment of sections (which saves
# flash space)
# * linker argument -Tlink.x tells the linker to use link.x as a linker script.
# This is usually provided by the cortex-m-rt crate, and by default the
# version in that crate will include a file called `memory.x` which describes
# the particular memory layout for your specific chip.
# * linker argument -Tdefmt.x also tells the linker to use `defmt.x` as a
# secondary linker script. This is required to make defmt_rtt work.
rustflags = [
"-C", "link-arg=--nmagic",
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=-Tdefmt.x",
"-C", "target-cpu=cortex-m33",
]
# Use picotool for loading.
#
# Load an elf, skipping unchanged flash sectors, verify it, and execute it
runner = "${PICOTOOL_PATH} load -u -v -x -t elf"
#runner = "probe-rs run --chip ${CHIP} --protocol swd"
# This is the soft-float ABI for RISC-V mode.
#
# Hazard 3 does not have an FPU and so float function arguments use integer
# registers.
[target.riscv32imac-unknown-none-elf]
# Pass some extra options to rustc, some of which get passed on to the linker.
#
# * linker argument --nmagic turns off page alignment of sections (which saves
# flash space)
# * linker argument -Trp235x_riscv.x also tells the linker to use
# `rp235x_riscv.x` as a linker script. This adds in RP2350 RISC-V specific
# things that the riscv-rt crate's `link.x` requires and then includes
# `link.x` automatically. This is the reverse of how we do it on Cortex-M.
# * linker argument -Tdefmt.x also tells the linker to use `defmt.x` as a
# secondary linker script. This is required to make defmt_rtt work.
rustflags = [
"-C", "link-arg=--nmagic",
"-C", "link-arg=-Trp2350_riscv.x",
"-C", "link-arg=-Tdefmt.x",
]
# Use picotool for loading.
#
# Load an elf, skipping unchanged flash sectors, verify it, and execute it
runner = "${PICOTOOL_PATH} load -u -v -x -t elf"
#runner = "probe-rs run --chip ${CHIP} --protocol swd"
[env]
DEFMT_LOG = "debug"
+113
View File
@@ -0,0 +1,113 @@
# Created by https://www.toptal.com/developers/gitignore/api/rust,visualstudiocode,macos,windows,linux
# Edit at https://www.toptal.com/developers/gitignore?templates=rust,visualstudiocode,macos,windows,linux
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### macOS Patch ###
# iCloud generated files
*.icloud
### Rust ###
# Generated by Cargo
# will have compiled files and executables
debug/
target/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk
# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
### VisualStudioCode Patch ###
# Ignore all local history of files
.history
.ionide
### Windows ###
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# End of https://www.toptal.com/developers/gitignore/api/rust,visualstudiocode,macos,windows,linux
+1
View File
@@ -0,0 +1 @@
rp2350
+8
View File
@@ -0,0 +1,8 @@
{
"recommendations": [
"marus25.cortex-debug",
"rust-lang.rust-analyzer",
"probe-rs.probe-rs-debugger",
"raspberry-pi.raspberry-pi-pico"
]
}
+41
View File
@@ -0,0 +1,41 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Pico Debug (probe-rs)",
"cwd": "${workspaceFolder}",
"request": "launch",
"type": "probe-rs-debug",
"connectUnderReset": false,
"speed": 5000,
"runtimeExecutable": "probe-rs",
"chip": "${command:raspberry-pi-pico.getChip}",
"runtimeArgs": [
"dap-server"
],
"flashingConfig": {
"flashingEnabled": true,
"haltAfterReset": false
},
"coreConfigs": [
{
"coreIndex": 0,
"programBinary": "${command:raspberry-pi-pico.launchTargetPath}",
"rttEnabled": true,
"svdFile": "${command:raspberry-pi-pico.getSVDPath}",
"rttChannelFormats": [
{
"channelNumber": 0,
"dataFormat": "Defmt",
"mode": "NoBlockSkip",
"showTimestamps": true
}
]
}
],
"preLaunchTask": "Build + Generate SBOM (debug)",
"consoleLogLevel": "Debug",
"wireProtocol": "Swd"
}
]
}

Some files were not shown because too many files have changed in this diff Show More