diff --git a/0x0001_hello-world/.gitignore b/0x0001_hello-world/.gitignore deleted file mode 100644 index 2435c20..0000000 --- a/0x0001_hello-world/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -!.vscode/* diff --git a/0x0001_hello-world/.vscode/c_cpp_properties.json b/0x0001_hello-world/.vscode/c_cpp_properties.json deleted file mode 100644 index e80461d..0000000 --- a/0x0001_hello-world/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "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 -} diff --git a/0x0001_hello-world/.vscode/cmake-kits.json b/0x0001_hello-world/.vscode/cmake-kits.json deleted file mode 100644 index b0f3815..0000000 --- a/0x0001_hello-world/.vscode/cmake-kits.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "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}" - } - } -] \ No newline at end of file diff --git a/0x0001_hello-world/.vscode/extensions.json b/0x0001_hello-world/.vscode/extensions.json deleted file mode 100644 index a940d7c..0000000 --- a/0x0001_hello-world/.vscode/extensions.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "recommendations": [ - "marus25.cortex-debug", - "ms-vscode.cpptools", - "ms-vscode.cpptools-extension-pack", - "ms-vscode.vscode-serial-monitor", - "raspberry-pi.raspberry-pi-pico" - ] -} \ No newline at end of file diff --git a/0x0001_hello-world/.vscode/launch.json b/0x0001_hello-world/.vscode/launch.json deleted file mode 100644 index 424aa71..0000000 --- a/0x0001_hello-world/.vscode/launch.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "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}\"" - ] - }, - ] -} diff --git a/0x0001_hello-world/.vscode/settings.json b/0x0001_hello-world/.vscode/settings.json deleted file mode 100644 index 688748a..0000000 --- a/0x0001_hello-world/.vscode/settings.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "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" - } -} diff --git a/0x0001_hello-world/.vscode/tasks.json b/0x0001_hello-world/.vscode/tasks.json deleted file mode 100644 index f427bf0..0000000 --- a/0x0001_hello-world/.vscode/tasks.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Compile Project", - "type": "process", - "isBuildCommand": true, - "command": "${userHome}/.pico-sdk/ninja/v1.12.1/ninja", - "args": ["-C", "${workspaceFolder}/build"], - "group": "build", - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": "$gcc", - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/ninja/v1.12.1/ninja.exe" - } - }, - { - "label": "Run Project", - "type": "process", - "command": "${env:HOME}/.pico-sdk/picotool/2.2.0/picotool/picotool", - "args": [ - "load", - "${command:raspberry-pi-pico.launchTargetPath}", - "-fx" - ], - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/picotool/2.2.0/picotool/picotool.exe" - } - }, - { - "label": "Flash", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/${command:raspberry-pi-pico.getTarget}.cfg", - "-c", - "adapter speed 5000; program \"${command:raspberry-pi-pico.launchTargetPath}\" verify reset exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - }, - { - "label": "Rescue Reset", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/${command:raspberry-pi-pico.getChip}-rescue.cfg", - "-c", - "adapter speed 5000; reset halt; exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - }, - { - "label": "Risc-V Reset (RP2350)", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-c", - "set USE_CORE { rv0 rv1 cm0 cm1 }", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/rp2350.cfg", - "-c", - "adapter speed 5000; init;", - "-c", - "write_memory 0x40120158 8 { 0x3 }; echo [format \"Info : ARCHSEL 0x%02x\" [read_memory 0x40120158 8 1]];", - "-c", - "reset halt; targets rp2350.rv0; echo [format \"Info : ARCHSEL_STATUS 0x%02x\" [read_memory 0x4012015C 8 1]]; exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - } - ] -} diff --git a/0x0001_hello-world/0x0001_hello-world.c b/0x0001_hello-world/0x0001_hello-world.c deleted file mode 100644 index 096aba7..0000000 --- a/0x0001_hello-world/0x0001_hello-world.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include "pico/stdlib.h" - -int main(void) { - stdio_init_all(); - - while (true) - printf("hello, world\r\n"); -} diff --git a/0x0001_hello-world/CMakeLists.txt b/0x0001_hello-world/CMakeLists.txt deleted file mode 100644 index 31d8fc5..0000000 --- a/0x0001_hello-world/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# 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(0x0001_hello-world 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(0x0001_hello-world 0x0001_hello-world.c ) - -pico_set_program_name(0x0001_hello-world "0x0001_hello-world") -pico_set_program_version(0x0001_hello-world "0.1") - -# Modify the below lines to enable/disable output over UART/USB -pico_enable_stdio_uart(0x0001_hello-world 1) -pico_enable_stdio_usb(0x0001_hello-world 0) - -# Add the standard library to the build -target_link_libraries(0x0001_hello-world - pico_stdlib) - -# Add the standard include files to the build -target_include_directories(0x0001_hello-world PRIVATE - ${CMAKE_CURRENT_LIST_DIR} -) - -pico_add_extra_outputs(0x0001_hello-world) - diff --git a/0x0001_hello-world/pico_sdk_import.cmake b/0x0001_hello-world/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x0001_hello-world/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x0001a_stack/.gitignore b/0x0001a_stack/.gitignore deleted file mode 100644 index 2435c20..0000000 --- a/0x0001a_stack/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -!.vscode/* diff --git a/0x0001a_stack/.vscode/c_cpp_properties.json b/0x0001a_stack/.vscode/c_cpp_properties.json deleted file mode 100644 index 5a108f1..0000000 --- a/0x0001a_stack/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "configurations": [ - { - "name": "Pico", - "includePath": [ - "${workspaceFolder}/**", - "${userHome}/.pico-sdk/sdk/2.3.0/**" - ], - "forcedInclude": [ - "${workspaceFolder}/build/generated/pico_base/pico/config_autogen.h", - "${userHome}/.pico-sdk/sdk/2.3.0/src/common/pico_base_headers/include/pico.h" - ], - "defines": [], - "compilerPath": "${userHome}/.pico-sdk/toolchain/15_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 -} diff --git a/0x0001a_stack/.vscode/cmake-kits.json b/0x0001a_stack/.vscode/cmake-kits.json deleted file mode 100644 index b0f3815..0000000 --- a/0x0001a_stack/.vscode/cmake-kits.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "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}" - } - } -] \ No newline at end of file diff --git a/0x0001a_stack/.vscode/extensions.json b/0x0001a_stack/.vscode/extensions.json deleted file mode 100644 index a940d7c..0000000 --- a/0x0001a_stack/.vscode/extensions.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "recommendations": [ - "marus25.cortex-debug", - "ms-vscode.cpptools", - "ms-vscode.cpptools-extension-pack", - "ms-vscode.vscode-serial-monitor", - "raspberry-pi.raspberry-pi-pico" - ] -} \ No newline at end of file diff --git a/0x0001a_stack/.vscode/launch.json b/0x0001a_stack/.vscode/launch.json deleted file mode 100644 index 7078fb1..0000000 --- a/0x0001a_stack/.vscode/launch.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "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}", - "debuggerArgs": ["-ex", "set debug-file-directory /debug"], - "device": "${command:raspberry-pi-pico.getChipUppercase}", - "configFiles": [ - "interface/cmsis-dap.cfg", - "target/${command:raspberry-pi-pico.getTarget}.cfg" - ], - "svdFile": "${userHome}/.pico-sdk/sdk/2.3.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}", - "debuggerArgs": ["-ex", "set debug-file-directory /debug"], - "device": "${command:raspberry-pi-pico.getChipUppercase}", - "svdFile": "${userHome}/.pico-sdk/sdk/2.3.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}\"" - ] - } - ] -} diff --git a/0x0001a_stack/.vscode/settings.json b/0x0001a_stack/.vscode/settings.json deleted file mode 100644 index ecbf7dc..0000000 --- a/0x0001a_stack/.vscode/settings.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "cmake.showSystemKits": false, - "cmake.options.statusBarVisibility": "hidden", - "cmake.options.advanced": { - "build": { - "statusBarVisibility": "hidden" - }, - "launch": { - "statusBarVisibility": "hidden" - }, - "debug": { - "statusBarVisibility": "hidden" - }, - "variant": { - "statusBarVisibility": "hidden" - }, - "buildTarget": { - "statusBarVisibility": "hidden" - } - }, - "cmake.configureOnEdit": false, - "cmake.automaticReconfigure": false, - "cmake.configureOnOpen": false, - "cmake.generator": "Ninja", - "cmake.cmakePath": "${userHome}/.pico-sdk/cmake/v4.3.4/bin/cmake", - "C_Cpp.debugShortcut": false, - "terminal.integrated.env.windows": { - "PICO_SDK_PATH": "${env:USERPROFILE}/.pico-sdk/sdk/2.3.0", - "PICO_TOOLCHAIN_PATH": "${env:USERPROFILE}/.pico-sdk/toolchain/15_2_Rel1", - "Path": "${env:USERPROFILE}/.pico-sdk/toolchain/15_2_Rel1/bin;${env:USERPROFILE}/.pico-sdk/picotool/2.3.0/picotool;${env:USERPROFILE}/.pico-sdk/cmake/v4.3.4/bin;${env:USERPROFILE}/.pico-sdk/ninja/v1.13.2;${env:PATH}" - }, - "terminal.integrated.env.osx": { - "PICO_SDK_PATH": "${env:HOME}/.pico-sdk/sdk/2.3.0", - "PICO_TOOLCHAIN_PATH": "${env:HOME}/.pico-sdk/toolchain/15_2_Rel1", - "PATH": "${env:HOME}/.pico-sdk/toolchain/15_2_Rel1/bin:${env:HOME}/.pico-sdk/picotool/2.3.0/picotool:${env:HOME}/.pico-sdk/cmake/v4.3.4/bin:${env:HOME}/.pico-sdk/ninja/v1.13.2:${env:PATH}" - }, - "terminal.integrated.env.linux": { - "PICO_SDK_PATH": "${env:HOME}/.pico-sdk/sdk/2.3.0", - "PICO_TOOLCHAIN_PATH": "${env:HOME}/.pico-sdk/toolchain/15_2_Rel1", - "PATH": "${env:HOME}/.pico-sdk/toolchain/15_2_Rel1/bin:${env:HOME}/.pico-sdk/picotool/2.3.0/picotool:${env:HOME}/.pico-sdk/cmake/v4.3.4/bin:${env:HOME}/.pico-sdk/ninja/v1.13.2:${env:PATH}" - }, - "raspberry-pi-pico.cmakeAutoConfigure": true, - "raspberry-pi-pico.useCmakeTools": false, - "raspberry-pi-pico.cmakePath": "${HOME}/.pico-sdk/cmake/v4.3.4/bin/cmake", - "raspberry-pi-pico.ninjaPath": "${HOME}/.pico-sdk/ninja/v1.13.2/ninja" -} diff --git a/0x0001a_stack/.vscode/tasks.json b/0x0001a_stack/.vscode/tasks.json deleted file mode 100644 index 60f30f6..0000000 --- a/0x0001a_stack/.vscode/tasks.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Compile Project", - "type": "process", - "isBuildCommand": true, - "command": "${userHome}/.pico-sdk/ninja/v1.13.2/ninja", - "args": ["-C", "${workspaceFolder}/build"], - "group": "build", - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": "$gcc", - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/ninja/v1.13.2/ninja.exe" - } - }, - { - "label": "Run Project", - "type": "process", - "command": "${env:HOME}/.pico-sdk/picotool/2.3.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.3.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" - } - } - ] -} diff --git a/0x0001a_stack/0x0001a_stack.c b/0x0001a_stack/0x0001a_stack.c deleted file mode 100644 index 5e1945d..0000000 --- a/0x0001a_stack/0x0001a_stack.c +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include "pico/stdlib.h" - - -int main() -{ - stdio_init_all(); - - while (true) { - __asm volatile( - // Save a low register and the link register. - "push {r4, lr}\n" - // Intentionally unordered: the encoded list is still r2, r3, r6. - "push {r3, r2, r6}\n" - // Thumb PUSH cannot encode high registers r8-r12. - "stmdb sp!, {r9, r10}\n" - // Restore each group in reverse order to return SP to its start. - "ldmia sp!, {r9, r10}\n" - "pop {r2, r3, r6}\n" - "pop {r4, lr}\n" - ::: "memory"); - } -} diff --git a/0x0001a_stack/CMakeLists.txt b/0x0001a_stack/CMakeLists.txt deleted file mode 100644 index c1b84e7..0000000 --- a/0x0001a_stack/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# 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.3.0) -set(toolchainVersion 15_2_Rel1) -set(picotoolVersion 2.3.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(0x0001a_stack 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(0x0001a_stack 0x0001a_stack.c ) - -pico_set_program_name(0x0001a_stack "0x0001a_stack") -pico_set_program_version(0x0001a_stack "0.1") - -# Modify the below lines to enable/disable output over UART/USB -pico_enable_stdio_uart(0x0001a_stack 1) -pico_enable_stdio_usb(0x0001a_stack 0) - -# Add the standard library to the build -target_link_libraries(0x0001a_stack - pico_stdlib) - -# Add the standard include files to the build -target_include_directories(0x0001a_stack PRIVATE - ${CMAKE_CURRENT_LIST_DIR} -) - -pico_add_extra_outputs(0x0001a_stack) - diff --git a/0x0001a_stack/pico_sdk_import.cmake b/0x0001a_stack/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x0001a_stack/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x0001b_ctf/.gitignore b/0x0001b_ctf/.gitignore deleted file mode 100644 index 97b60a5..0000000 --- a/0x0001b_ctf/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -build -!.vscode/* -!build-ctf/0x0001b_ctf.bin -!CTF-01.bin diff --git a/0x0001b_ctf/.vscode/c_cpp_properties.json b/0x0001b_ctf/.vscode/c_cpp_properties.json deleted file mode 100644 index 613c996..0000000 --- a/0x0001b_ctf/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "configurations": [ - { - "name": "Pico", - "includePath": [ - "${workspaceFolder}/**", - "${userHome}/.pico-sdk/sdk/2.3.1/**" - ], - "forcedInclude": [ - "${workspaceFolder}/build/generated/pico_base/pico/config_autogen.h", - "${userHome}/.pico-sdk/sdk/2.3.1/src/common/pico_base_headers/include/pico.h" - ], - "defines": [], - "compilerPath": "${userHome}/.pico-sdk/toolchain/15_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 -} diff --git a/0x0001b_ctf/.vscode/cmake-kits.json b/0x0001b_ctf/.vscode/cmake-kits.json deleted file mode 100644 index b0f3815..0000000 --- a/0x0001b_ctf/.vscode/cmake-kits.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "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}" - } - } -] \ No newline at end of file diff --git a/0x0001b_ctf/.vscode/extensions.json b/0x0001b_ctf/.vscode/extensions.json deleted file mode 100644 index a940d7c..0000000 --- a/0x0001b_ctf/.vscode/extensions.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "recommendations": [ - "marus25.cortex-debug", - "ms-vscode.cpptools", - "ms-vscode.cpptools-extension-pack", - "ms-vscode.vscode-serial-monitor", - "raspberry-pi.raspberry-pi-pico" - ] -} \ No newline at end of file diff --git a/0x0001b_ctf/.vscode/launch.json b/0x0001b_ctf/.vscode/launch.json deleted file mode 100644 index 451b846..0000000 --- a/0x0001b_ctf/.vscode/launch.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "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}", - "debuggerArgs": ["-ex", "set debug-file-directory /debug"], - "device": "${command:raspberry-pi-pico.getChipUppercase}", - "configFiles": [ - "interface/cmsis-dap.cfg", - "target/${command:raspberry-pi-pico.getTarget}.cfg" - ], - "svdFile": "${userHome}/.pico-sdk/sdk/2.3.1/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}", - "debuggerArgs": ["-ex", "set debug-file-directory /debug"], - "device": "${command:raspberry-pi-pico.getChipUppercase}", - "svdFile": "${userHome}/.pico-sdk/sdk/2.3.1/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}\"" - ] - } - ] -} diff --git a/0x0001b_ctf/.vscode/settings.json b/0x0001b_ctf/.vscode/settings.json deleted file mode 100644 index 5b883ba..0000000 --- a/0x0001b_ctf/.vscode/settings.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "cmake.showSystemKits": false, - "cmake.options.statusBarVisibility": "hidden", - "cmake.options.advanced": { - "build": { - "statusBarVisibility": "hidden" - }, - "launch": { - "statusBarVisibility": "hidden" - }, - "debug": { - "statusBarVisibility": "hidden" - }, - "variant": { - "statusBarVisibility": "hidden" - }, - "buildTarget": { - "statusBarVisibility": "hidden" - } - }, - "cmake.configureOnEdit": false, - "cmake.automaticReconfigure": false, - "cmake.configureOnOpen": false, - "cmake.generator": "Ninja", - "cmake.cmakePath": "${userHome}/.pico-sdk/cmake/v4.3.4/bin/cmake", - "C_Cpp.debugShortcut": false, - "terminal.integrated.env.windows": { - "PICO_SDK_PATH": "${env:USERPROFILE}/.pico-sdk/sdk/2.3.1", - "PICO_TOOLCHAIN_PATH": "${env:USERPROFILE}/.pico-sdk/toolchain/15_2_Rel1", - "Path": "${env:USERPROFILE}/.pico-sdk/toolchain/15_2_Rel1/bin;${env:USERPROFILE}/.pico-sdk/picotool/2.3.1/picotool;${env:USERPROFILE}/.pico-sdk/cmake/v4.3.4/bin;${env:USERPROFILE}/.pico-sdk/ninja/v1.13.2;${env:PATH}" - }, - "terminal.integrated.env.osx": { - "PICO_SDK_PATH": "${env:HOME}/.pico-sdk/sdk/2.3.1", - "PICO_TOOLCHAIN_PATH": "${env:HOME}/.pico-sdk/toolchain/15_2_Rel1", - "PATH": "${env:HOME}/.pico-sdk/toolchain/15_2_Rel1/bin:${env:HOME}/.pico-sdk/picotool/2.3.1/picotool:${env:HOME}/.pico-sdk/cmake/v4.3.4/bin:${env:HOME}/.pico-sdk/ninja/v1.13.2:${env:PATH}" - }, - "terminal.integrated.env.linux": { - "PICO_SDK_PATH": "${env:HOME}/.pico-sdk/sdk/2.3.1", - "PICO_TOOLCHAIN_PATH": "${env:HOME}/.pico-sdk/toolchain/15_2_Rel1", - "PATH": "${env:HOME}/.pico-sdk/toolchain/15_2_Rel1/bin:${env:HOME}/.pico-sdk/picotool/2.3.1/picotool:${env:HOME}/.pico-sdk/cmake/v4.3.4/bin:${env:HOME}/.pico-sdk/ninja/v1.13.2:${env:PATH}" - }, - "raspberry-pi-pico.cmakeAutoConfigure": true, - "raspberry-pi-pico.useCmakeTools": false, - "raspberry-pi-pico.cmakePath": "${HOME}/.pico-sdk/cmake/v4.3.4/bin/cmake", - "raspberry-pi-pico.ninjaPath": "${HOME}/.pico-sdk/ninja/v1.13.2/ninja" -} diff --git a/0x0001b_ctf/.vscode/tasks.json b/0x0001b_ctf/.vscode/tasks.json deleted file mode 100644 index 2f07d94..0000000 --- a/0x0001b_ctf/.vscode/tasks.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Compile Project", - "type": "process", - "isBuildCommand": true, - "command": "${userHome}/.pico-sdk/ninja/v1.13.2/ninja", - "args": ["-C", "${workspaceFolder}/build"], - "group": "build", - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": "$gcc", - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/ninja/v1.13.2/ninja.exe" - } - }, - { - "label": "Run Project", - "type": "process", - "command": "${env:HOME}/.pico-sdk/picotool/2.3.1/picotool/picotool", - "args": [ - "load", - "${command:raspberry-pi-pico.launchTargetPath}", - "-fx" - ], - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/picotool/2.3.1/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" - } - } - ] -} diff --git a/0x0001b_ctf/CMakeLists.txt b/0x0001b_ctf/CMakeLists.txt deleted file mode 100644 index cd4bff3..0000000 --- a/0x0001b_ctf/CMakeLists.txt +++ /dev/null @@ -1,91 +0,0 @@ -# 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. -# -# Author: Kevin Thomas -# Email: kevin@mytechnotalent.com -# GitHub: https://github.com/mytechnotalent -# File: CMakeLists.txt -# Desc: Configures the RP2350 Pico SDK project for the Operation Black Start -# CTF relay firmware. -# Created: 2026 - -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.3.1) -set(toolchainVersion 15_2_Rel1) -set(picotoolVersion 2.3.1) -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(0x0001b_ctf C CXX ASM) - -# Initialise the Raspberry Pi Pico SDK -pico_sdk_init() - -# Add executable with modular sources in src/ -add_executable(0x0001b_ctf - src/main.c - src/grid.c - src/console.c -) - -pico_set_program_name(0x0001b_ctf "0x0001b_ctf") -pico_set_program_version(0x0001b_ctf "0.1") - -# Modify the below lines to enable/disable output over UART/USB -pico_enable_stdio_uart(0x0001b_ctf 1) -pico_enable_stdio_usb(0x0001b_ctf 0) -target_compile_definitions(0x0001b_ctf PRIVATE - PICO_DEFAULT_UART_BAUD_RATE=115200 -) - -# Add the standard library to the build -target_link_libraries(0x0001b_ctf - pico_stdlib -) - -# Add the standard include files to the build -target_include_directories(0x0001b_ctf PRIVATE - ${CMAKE_CURRENT_LIST_DIR}/include -) - -pico_add_extra_outputs(0x0001b_ctf) diff --git a/0x0001b_ctf/CTF-01-I.md b/0x0001b_ctf/CTF-01-I.md deleted file mode 100644 index dbda501..0000000 --- a/0x0001b_ctf/CTF-01-I.md +++ /dev/null @@ -1,442 +0,0 @@ -# Operation Black Start - Student Instructions - -**⚠ WORLDGRID EMERGENCY INCIDENT ⚠** - -``` -+----------------------------------------------------------------------------------------+ -| | -| ██████╗ ██╗ █████╗ ██████╗██╗ ██╗███████╗████████╗ █████╗ ██████╗ ████████╗ | -| ██╔══██╗██║ ██╔══██╗██╔════╝██║ ██╔╝██╔════╝╚══██╔══╝██╔══██╗██╔══██╗╚══██╔══╝ | -| ██████╔╝██║ ███████║██║ █████╔╝ ███████╗ ██║ ███████║██████╔╝ ██║ | -| ██╔══██╗██║ ██╔══██║██║ ██╔═██╗ ╚════██║ ██║ ██╔══██║██╔══██╗ ██║ | -| ██████╔╝███████╗██║ ██║╚██████╗██║ ██╗███████╗ ██║ ██║ ██║██║ ██║ ██║ | -| ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═════╝██║ ██║╚══════╝ ╚═╝ ╚═╝ ╚═╝██║ ██║ ██║ | -| | -| | -| O P E R A T I O N B L A C K S T A R T | -| | -| *** PRIORITY RED *** | -| | -+----------------------------------------------------------------------------------------+ -``` - ---- - -## Project Overview - -WorldGrid Compact's emergency firmware build for its GRID-7 relay fleet -shipped a miscompiled safety threshold and a hardcoded false status string, -so deployed relays report a false-safe "STABLE" status while the frozen -frequency deviation reading of 0.87 Hz is nearly 50% beyond the 0.60 Hz -engineering limit. The source was overwritten by the next build and cannot -be recovered, so the only surviving evidence is the exact miscompiled -training image. Students reverse engineer `CTF-01.bin` with Ghidra, locate -and patch both defects directly in the binary, export a corrected image, -flash it to a Pico 2, and prove the corrected behavior with GDB and a UART -console. - ---- - -## Scenario Briefing - -### Background - -**WorldGrid Compact** is the emergency interconnection standard shared by -three allied national grid operators. When any member's primary SCADA -network goes dark, a fleet of small embedded relay nodes - call sign -**GRID-7** - is the only thing standing between an orderly recovery and an -uncontrolled cascade. Each relay node watches the last known grid frequency -deviation, decides whether conditions are safe, and either **holds** the -automatic black-start dispatch or **authorizes** it. - -At 03:11 UTC, a coordinated cyberattack severed the primary SCADA uplink -across the GRID-7 corridor and the WATER-3 aqueduct pumping stations that -depend on it. With the network coordination center offline and three -continents' worth of hospitals, rail systems, and water treatment plants -running on backup power, WorldGrid's engineering team did the only thing -they could: they rushed an emergency firmware build for the relay fleet and -pushed it within **eleven minutes** of the attack being detected. - -### The Disaster - -The engineer who built that emergency image, **Dr. Elias Renner**, has not -slept in thirty-one hours. He compiled the fix, ran a five-second bench -test, and shipped it - because the alternative was leaving the relay fleet -completely blind. It appears to work. The relay boots. It prints a status -report. It reports **GRID STATUS: STABLE** and **DISPATCH PATH: -AUTHORIZED**. - -There is a problem: the frozen frequency reading latched at the moment -communications were cut shows a deviation of **0.87 Hz** - nearly *50% -beyond* WorldGrid's hard engineering limit of **0.60 Hz**. A deviation this -large, if trusted, means the grid is nowhere near stable enough for an -automatic black-start dispatch. If the fleet authorizes dispatch on a false -"STABLE" reading, cascading generator trips will follow within minutes, -and GRID-7 and WATER-3 will go dark for the second time - this time with no -backup plan. - -**Dr. Renner's rushed build has a bug. Multiple relay nodes are already -reporting the same false-safe status. Nobody has found where in the -compiled firmware the error lives, because the source code used for that -emergency compile was overwritten by the next build fifteen minutes later -and cannot be recovered.** - -### The Only Surviving Evidence - -One relay node - the training/verification unit - still holds the exact -miscompiled image that shipped to the fleet. This binary, and this binary -alone, is the only remaining copy of the emergency build. There is no -source code. There is no build log. There is only the compiled image, a -UART cable, and whatever a skilled embedded reverse engineer can prove by -reading machine code. - -### The Human Stakes - -| Consequence if the false "STABLE" reading is trusted | Scale | -|---|---| -| Hospitals on generator backup past their fuel reserve | 214 facilities | -| Water treatment and pumping stations losing pressure | 3 aqueduct systems | -| Rail corridors stranded mid-route | 6 national rail networks | -| Estimated population affected by cascading failure | 40+ million people | - -**The options are:** - -1. ❌ **Trust the fleet's reported status** - dispatch fires on a false - reading, cascading failure follows within the hour. -2. ❌ **Shut the entire relay fleet down** - buys time, but leaves 40 - million people with no automated recovery path at all. -3. **REVERSE ENGINEER THE EMERGENCY BUILD** - find the exact - miscompiled bytes, patch them, verify the corrected image on real - hardware, and hand the fix to the field team so the *rest of the fleet* - can be safely repatched before the next attempt. - -### THE SHORTAGE - -For years, the world treated embedded systems as invisible infrastructure. -The engineers who could read a vector table, decode a Thumb branch, or -patch a miscompiled constant directly in a stripped binary were never -numerous enough. Tonight almost all of them are already in the field -chasing other failures. **You are the reserve team.** - -You were called in because you can do something Dr. Renner's exhausted -team cannot do right now: read what the processor is actually doing, with -no source code, no time for a rewrite, and no room for a guess. - -> **⏰ TIME PRESSURE:** The field team is standing by to push your verified -> patch to the rest of the GRID-7 fleet. Every relay node still reporting -> a false "STABLE" status is one dispatch cycle away from disaster. - -> **AUTHORIZED LAB ONLY:** This challenge uses a supplied Pico 2 training -> relay and its exact miscompiled firmware image. Do not connect this -> exercise to a public network, an operational grid, a water utility, or -> any device you do not own or have explicit written authorization to test. - ---- - -## Learning Objectives - -- Decode the RP2350 / ARM Cortex-M33 vector table and identify the reset - handler and initial stack pointer. -- Trace the bootrom-to-reset handoff and translate Thumb reset-vector - addresses into real function entry points. -- Locate a miscompiled boundary comparison and reason about the correct - immediate value the compiler should have encoded. -- Patch compare instructions and a status string directly in a raw binary - with Ghidra. -- Recover a hidden quarantined dispatch frame from the compiled image. -- Export and UF2-convert a corrected image, then verify the corrected - behavior on real hardware with GDB and a UART console. - ---- - -## What This Project Tests - -| Week | Concepts Tested | -|------|-----------------| -| 1 | RP2350 architecture, ARM Cortex-M33 registers, stack, flash/RAM, Thumb assembly, Ghidra static analysis | -| 2 | GDB connection, breakpoints, disassembly, register and memory inspection, UART observation | -| 3 | Bootrom handoff, vector table, reset handler, startup code, XIP, Thumb-bit addressing | - ---- - -## Part 1: Understanding the System - -### GRID-7 Relay Hardware - -| Component | Connection | Purpose | -|-----------|------------|---------| -| Raspberry Pi Pico 2 | RP2350 | Runs the miscompiled emergency firmware | -| UART TX | GPIO 0 | Relay telemetry output | -| UART RX | GPIO 1 | Reserved (no command parser is implemented) | -| SWD debug interface | Supplied probe | Authorized GDB inspection | - -No LED, relay output, sensor, display, or other peripheral is part of this -CTF. Every graded finding lives in flash (`.rodata`/`.text`) or SRAM, and is -reachable with only the Weeks 1-3 toolset: Ghidra, GDB, and a UART monitor. - -### UART Configuration - -- Baud: `115200` -- Data: `8 bits` -- Parity: `none` -- Stop: `1` -- Logic: `3.3 V` - -### Normal (Intended) Behavior - -The relay should latch the frozen deviation reading, compare it against the -**real** WorldGrid safety limit of **60** (0.60 Hz, encoded as an integer -`x100`), and report honestly: - -``` -+-----------------------------------------------------------------+ -| Intended Relay Behavior | -| | -| 1. Boot and initialize UART | -| 2. Print the boot identity and a signal-quality banner | -| 3. Compare the frozen 87 (0.87 Hz) reading against the 60 | -| (0.60 Hz) safety limit | -| 4. 87 exceeds 60, so the grid is NOT stable | -| 5. Report GRID STATUS: CRITICAL and DISPATCH PATH: HELD | -| 6. Repeat the report once per second until conditions change | -+-----------------------------------------------------------------+ -``` - -### Observed (Buggy) Behavior - What You Will See When You First Flash `CTF-01.uf2` - -```text -GLOBAL EMBEDDED RESPONSE NETWORK -BLACK START WINDOW: 27 MINUTES -UART0 115200 8N1 | AUTHORIZED LAB CONSOLE -SIGNAL: NORMAL -RESPONSE> GRID STATUS: STABLE -DISPATCH PATH: AUTHORIZED -LAST FRAME: QUARANTINED -RESPONSE> -``` - -> **Terminal Timing Note:** The first four lines (`GLOBAL EMBEDDED...` through -> `SIGNAL: NORMAL`) represent the **initial boot banner**, emitted once during -> startup. If your serial terminal (PuTTY) connects after the board has -> booted, you will observe the continuous 1-second status stream (`GRID -> STATUS...` and `DISPATCH PATH...`). To view the boot banner in your terminal, -> reset the Pico (pulse `RUN` to `GND`) while PuTTY is actively connected. - -This is exactly what Dr. Renner's team is seeing on the deployed fleet. It -is wrong, and it is wrong in **two independent ways** inside the compiled -binary. Do not assume the first readable sentence is the full truth - -treat every printed line as evidence to be checked against the machine -code, not as a fact on its own. - ---- - -## Part 2: The Firmware - -You do not have the source code. It was overwritten fifteen minutes after -the emergency build shipped. You have only the compiled image. Your job is -to reverse engineer it with Ghidra, locate the defects, and patch the -binary directly - exactly the way Dr. Renner's field team will need to -patch the rest of the deployed fleet. - -### What The Firmware Does - -1. Initializes UART0 and stdio. -2. Reads a frozen grid-frequency-deviation reading that was latched in - memory before communications were severed. -3. Compares that reading against a compiled-in safety threshold - **twice**, - once for each independent status line it reports. -4. Prints a boot banner containing an unconditional signal-quality line. -5. Enters an infinite loop printing the grid classification and dispatch - decision once per second. - -### Bug Summary - What You Are Graded On - -| Bug # | Category | Severity | Description | Hint | -|-------|----------|----------|--------------|------| -| **Bug #1** | Miscompiled safety constant | **CRITICAL** | The safety threshold used to classify the frozen reading was compiled far too permissive. It is used **twice** - once for the operator-facing status and once for the automated dispatch decision - and **both** copies must be corrected. | The real WorldGrid safety limit is 60 (0.60 Hz). Search for the wrong immediate value used in the comparison. | -| **Bug #2** | Hardcoded string literal | **HIGH** | The boot banner unconditionally prints a signal-quality word that does not reflect the actual reading, regardless of what the relay later reports. | The correct word describes the true state of a 0.87 Hz deviation against a 0.60 Hz limit - not "NORMAL". | - -**Important:** The replacement text for Bug #2 **must be the same length** -as the original - patching a shorter or longer string will corrupt -adjacent flash data. - -### A Third Finding - Not a Bug, a Recovery Task - -Somewhere in this image is the **quarantined black-start authorization -frame** - the exact frame the relay is supposed to transmit to the -regional dispatcher once a human operator confirms it is safe to proceed. -It is never printed by the firmware. Recovering it (without patching -anything) is required evidence for your final report. - ---- - -## Part 3: Your Assignment - -Whenever a task asks you to **Document** or **answer**, write your answers -in a single file named `CTF-01-Answers.md`. - -### Task 1: Setup and Initial Analysis - -1. Create a new Ghidra project named `Black_Start_Investigation`. -2. Import `CTF-01.bin`. -3. Configure the language as **ARM Cortex 32-bit, little endian**. -4. Set the base address to `0x10000000`. -5. Run auto-analysis. - -**Document:** -- A screenshot of the Ghidra **Import Results** or **Program Information** - window showing the project name, processor settings, and base address. -- The address of `main()`. -- The address of the recurring status loop (the branch target that repeats - once per second). -- The vector-table base, the initial stack pointer, and the reset-handler - pointer as stored (note its Thumb bit) versus the actual instruction - address. - -### Task 2: Find and Patch Bug #1 - The Miscalibrated Safety Threshold - -1. Find **both** locations where the frozen reading is compared against - the miscompiled safety constant. -2. Document the exact address, the original instruction, and the original - immediate value at each location. -3. Determine the correct immediate value. **Caution:** the compiler may - not have encoded the raw threshold you expect - a strict "less than" - comparison against an unsigned value is often optimized into a - "less-or-equal" comparison against one less than the threshold. Show - your reasoning. -4. Patch **both** locations in Ghidra using the **Bytes Window** workflow: - > **Critical ARM Thumb-2 Patching Note:** In ARM Cortex-M, compare instructions that directly precede conditional execution blocks (`ite hi`) must **not** be patched using the right-click *Patch Instruction* dialog. Ghidra's automatic re-disassembler encounters an internal context conflict with the subsequent `ite hi` instruction, which collapses Thumb decoding and swallows Compare Site B (`0x1000020A`). - > - > To patch cleanly without breaking downstream disassembly, use the **Bytes Window**: - > 1. Ensure the Bytes window is open (**Window** -> **Bytes: CTF-01.bin**). - > 2. In the Bytes window toolbar, click the **pencil icon** (**Toggle Edit Mode**). - > 3. In the Listing window, click on address `0x100001FC` (Compare Site A) and press **`C`** (**Clear Code Bytes**). The instruction temporarily clears into raw bytes (`5E 2B`). - > 4. In the Bytes window, locate offset `100001fc`, click on `5E`, and change it to **`3B`**. - > 5. Click back in the Listing window on address `0x100001FC` and press **`D`** (**Disassemble**). The instruction immediately disassembles cleanly as `cmp r3, #0x3b`. - > 6. Notice that Compare Site B at `0x1000020A` remains completely intact and visible! Repeat the exact same steps at `0x1000020A`: click `0x1000020A` in the Listing, press **`C`**, change `5E` to **`3B`** in the Bytes window, click back in the Listing, and press **`D`**. - -**Questions to answer:** -- Why must both locations be patched? What happens if you only patch one? -- Why is a false "STABLE" classification on an 0.87 Hz reading dangerous - for an automated black-start dispatch? - -### Task 3: Find and Patch Bug #2 - The False Signal Banner - -1. Find the boot-banner string that unconditionally reports the wrong - signal quality. -2. Document its address and the exact bytes that must change. -3. Patch the string, preserving its exact length. - -**Questions to answer:** -- Document the original vs. patched bytes, character by character. -- Why is a hardcoded, unconditional status word more dangerous than one - that is at least computed from a (miscalibrated) reading? - -### Task 4: Recover the Quarantined Dispatch Frame - -1. Use Ghidra's Defined Strings (or a raw string search) to locate the - hidden black-start authorization frame. -2. Document its address and explain why it is never transmitted by the - current firmware. -3. Do **not** attempt to patch this value - it is evidence, not a bug. - -### Task 5: Export and Verify - -1. Export your patched binary as `CTF-01_fixed.bin`. -2. Convert it to UF2 format for the RP2350: - ```bash - python uf2conv.py CTF-01_fixed.bin --base 0x10000000 --family 0xe48bff59 --output CTF-01_fixed.uf2 - ``` -3. Flash `CTF-01_fixed.uf2` to your Pico 2 and capture the corrected UART - output. -4. Confirm that the corrected image now reports **GRID STATUS: CRITICAL**, - **DISPATCH PATH: HELD**, and the corrected signal-quality word - an - honest, safe report instead of a false "all clear." -5. Build a summary table of every patch: address, original bytes, patched - bytes, and a one-line description. - -### Task 6: Written Reflection (short answers, 150 words or less each) - -1. Why is "the build was rushed under emergency pressure" not an - acceptable excuse for shipping a firmware defect that could trigger a - cascading grid failure? -2. Name one concrete engineering practice (code review, static analysis, - hardware-in-the-loop test, etc.) that would have caught **each** of the - two graded bugs before this image ever reached the fleet. - ---- - -## How To Breadboard - -- Pico 2 **GPIO 0 / UART TX** -> USB-UART adapter **RX** -- Pico 2 **GPIO 1 / UART RX** -> USB-UART adapter **TX** -- Pico 2 **GND** -> USB-UART adapter **GND** -- Use **3.3 V logic only**. Never connect a 5 V line to a Pico GPIO. -- Connect the supplied SWD probe according to its documented pinout. - -The supplied image is `CTF-01.bin` (for Ghidra analysis) and `CTF-01.uf2` -(for flashing). If your instructor supplies different filenames, record the -actual filenames in your report. - ---- - -## Memory Map Reference - -| Region | Address | Purpose | -|--------|---------|---------| -| Bootrom | `0x00000000` | Immutable boot code | -| Flash/XIP | `0x10000000` | Vector table, code, constants, strings | -| SRAM | `0x20000000` | Stack and writable state | - ---- - -## Submission Format - -Submit a folder containing: - -- `CTF-01-Answers.md`; -- screenshots or terminal transcripts; -- `CTF-01_fixed.bin` and `CTF-01_fixed.uf2`; -- the original image hash. - ---- - -## Success Criteria - -You complete the challenge when you can prove all of the following: - -- You can explain how the RP2350 reaches the relay's code from reset. -- You can locate and patch both copies of the miscalibrated threshold. -- You can locate and patch the false signal-quality string without - corrupting adjacent data. -- You can export, convert, and flash a corrected image. -- You can prove on real hardware that the corrected image reports the - true, dangerous state instead of the false "all clear." -- You can recover the quarantined dispatch frame as evidence. - ---- - -## Academic Integrity - -By submitting this CTF work, you certify that: - -1. You used only the supplied training relay, image, and lab interface. -2. You did not connect the challenge to a public network, an operational - grid, a water utility, or any third-party device. -3. You understand that embedded reverse engineering and binary patching - require explicit authorization in any real-world context. -4. You will report any discovered weakness responsibly to the course - instructor. - -The world is short on people who can do this work. Treat that -responsibility seriously: verify before you patch, patch before you trust, -and never confuse a clean-looking status line with a safe system. - ---- - -## Reference Material - -- ARM Cortex-M33 Technical Reference Manual -- RP2350 datasheet -- GDB documentation -- Ghidra documentation: [https://ghidra-sre.org/](https://ghidra-sre.org/) diff --git a/0x0001b_ctf/CTF-01-I.pdf b/0x0001b_ctf/CTF-01-I.pdf deleted file mode 100644 index 1ed54e3..0000000 Binary files a/0x0001b_ctf/CTF-01-I.pdf and /dev/null differ diff --git a/0x0001b_ctf/CTF-01-R.md b/0x0001b_ctf/CTF-01-R.md deleted file mode 100644 index 9dbec48..0000000 --- a/0x0001b_ctf/CTF-01-R.md +++ /dev/null @@ -1,237 +0,0 @@ -# Operation Black Start - Requirements & Grading Criteria - -``` -+----------------------------------------------------------------------------------------+ -| | -| ██████╗ ██╗ █████╗ ██████╗██╗ ██╗███████╗████████╗ █████╗ ██████╗ ████████╗ | -| ██╔══██╗██║ ██╔══██╗██╔════╝██║ ██╔╝██╔════╝╚══██╔══╝██╔══██╗██╔══██╗╚══██╔══╝ | -| ██████╔╝██║ ███████║██║ █████╔╝ ███████╗ ██║ ███████║██████╔╝ ██║ | -| ██╔══██╗██║ ██╔══██║██║ ██╔═██╗ ╚════██║ ██║ ██╔══██║██╔══██╗ ██║ | -| ██████╔╝███████╗██║ ██║╚██████╗██║ ██╗███████╗ ██║ ██║ ██║██║ ██║ ██║ | -| ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═════╝██║ ██║╚══════╝ ╚═╝ ╚═╝ ╚═╝██║ ██║ ██║ | -| | -| | -| O P E R A T I O N B L A C K S T A R T | -| | -| REQUIREMENTS & GRADING CRITERIA | -| | -+----------------------------------------------------------------------------------------+ -``` - ---- - -## Project Overview - -Students are the reverse-engineering reserve team called in after WorldGrid -Compact's emergency firmware build shipped a miscompiled safety threshold and -a false status string to its GRID-7 relay fleet. Students reverse engineer -`CTF-01.bin` with Ghidra, locate two real defects, patch them in the binary, -export a corrected image, flash it to real hardware, and prove the corrected -behavior with the debugger and the console. - -The challenge is separate from all FINAL projects and contains no FINAL-project -answer, constant, address, bug, or patch. - ---- - -## Learning Objectives - -- Decode an ARM Cortex-M33 vector table and identify the reset handler and - initial stack pointer. -- Translate Thumb reset-vector addresses into real function entry points. -- Locate a miscompiled boundary comparison and reason about its immediate - value. -- Patch compare instructions and a status string in a raw binary with Ghidra. -- Export and UF2-convert a corrected image, then verify it on real hardware. -- Capture derived state with GDB and read UART console output. - -Students must use only Weeks 1-3 concepts: ARM registers and stack behavior, -UART output, GDB, Ghidra static analysis and binary patching, vector tables, -reset startup, XIP, and Thumb addressing. - ---- - -## Deliverables Checklist - -| # | Deliverable | Format | Criterion | -|---|-------------|--------|-----------| -| 1 | Ghidra project screenshot (project name, processor, base address) | PNG/JPG | 1.1 | -| 2 | `main()` and status-loop addresses | Inside `CTF-01-Answers.md` | 1.2 | -| 3 | Vector table base, initial SP, reset pointer | Inside `CTF-01-Answers.md` | 1.3 | -| 4 | Thumb bit explanation | Inside `CTF-01-Answers.md` | 1.4 | -| 5 | Bug #1 evidence and patches (both compare sites) | Inside `CTF-01-Answers.md` | 2.1-2.6 | -| 6 | Bug #2 evidence and patch (six characters) | Inside `CTF-01-Answers.md` | 3.1-3.4 | -| 7 | Recovered dispatch frame and address | Inside `CTF-01-Answers.md` | 4.1-4.2 | -| 8 | `CTF-01_fixed.bin` | BIN file | 5.1 | -| 9 | `CTF-01_fixed.uf2` | UF2 file | 5.2 | -| 10 | Corrected console transcript | Inside `CTF-01-Answers.md` | 5.3 | -| 11 | Summary table of all patches | Inside `CTF-01-Answers.md` | 5.4 | -| 12 | Written reflection | Inside `CTF-01-Answers.md` | 6.1-6.2 | - ---- - -## Required Tools and Equipment - -| Tool | Purpose | -|------|---------| -| Raspberry Pi Pico 2 | Isolated target | -| 3.3 V USB-UART adapter | UART capture on GPIO 0 (TX) / GPIO 1 (RX) | -| Serial monitor | Observe output | -| Ghidra | Static analysis and binary patching | -| Python (`uf2conv.py`) | UF2 conversion | -| `CTF-01.bin` and `CTF-01.uf2` | Supplied artifacts | - -UART settings: **115200 baud, 8 data bits, no parity, 1 stop bit**. - ---- - -## Artifact Identity - -The instructor-issued artifact hashes are: - -```text -CTF-01.bin 425591AC17FF4C22206286EE6F40B06A89523483804850A41854A9B6F89D7B70 -CTF-01.uf2 B1552EE3BB5763D96C65D8DF1C86984EE842EF1A823FDF5D94132B1E10FF9D16 -``` - ---- - -## Grading Rubric - Detailed Breakdown - -### Task 1: Setup and Initial Analysis (15 points) - -| Criterion | Points | Full credit | Partial credit | No credit | -|-----------|--------|-------------|----------------|-----------| -| Criterion 1.1: Ghidra Project Setup | 3 | Correct project name, `ARM:LE:32:Cortex` (ARM Cortex 32-bit little endian), base `0x10000000` | One item off | Not set up | -| Criterion 1.2: main() and Status-Loop Addresses | 4 | Both addresses correct | One correct | Neither found | -| Criterion 1.3: Vector Table Decoding | 4 | Correct base, initial SP, reset pointer | One missing | Not found | -| Criterion 1.4: Thumb Addressing | 4 | Correctly clears bit 0 and identifies `main()` | General explanation | Incorrect | - -### Task 2: Find and Patch Bug #1: The Miscalibrated Safety Threshold (30 points) - -| Criterion | Points | Full credit | Partial credit | No credit | -|-----------|--------|-------------|----------------|-----------| -| Criterion 2.1: Locate Compare Site A | 5 | Correct address and original bytes | Address off | Not found | -| Criterion 2.2: Locate Compare Site B | 5 | Correct address and original bytes | Address off | Not found | -| Criterion 2.3: Correct Immediate-Value Reasoning | 8 | Explains the `<` to `<=` transform and gives `0x3B` | Correct value, no reasoning | Wrong value | -| Criterion 2.4: Patch Compare Site A | 4 | Byte change verified | Wrong byte | Not patched | -| Criterion 2.5: Patch Compare Site B | 4 | Byte change verified | Wrong byte | Not patched | -| Criterion 2.6: Explain Why Both Sites Must Be Patched | 4 | Clear explanation of the two independent comparisons | Vague | Missing | - -### Task 3: Find and Patch Bug #2: The False Signal Banner (20 points) - -| Criterion | Points | Full credit | Partial credit | No credit | -|-----------|--------|-------------|----------------|-----------| -| Criterion 3.1: Locate the Banner String | 5 | Correct address | Approximate | Not found | -| Criterion 3.2: Patch Six Characters | 8 | All six bytes changed, length preserved | Correct text, wrong bytes documented | Wrong length | -| Criterion 3.3: Character-by-Character Documentation | 4 | Original vs patched byte for all six characters | Partial | Missing | -| Criterion 3.4: Explain the Danger of a Hardcoded Status Word | 3 | Clear, specific reasoning | Generic | Missing | - -### Task 4: Recover the Quarantined Dispatch Frame (10 points) - -| Criterion | Points | Full credit | Partial credit | No credit | -|-----------|--------|-------------|----------------|-----------| -| Criterion 4.1: Recover the Dispatch Frame | 6 | Correct address and full text | Partial text | Not found | -| Criterion 4.2: Explain Why It Is Never Transmitted | 4 | Clear static-analysis explanation | Vague | Missing | - -### Task 5: Export and Verify (20 points) - -| Criterion | Points | Full credit | Partial credit | No credit | -|-----------|--------|-------------|----------------|-----------| -| Criterion 5.1: Export CTF-01_fixed.bin | 4 | Valid patched binary | Corrupted | Not submitted | -| Criterion 5.2: Convert to CTF-01_fixed.uf2 | 4 | Correct base and family flags | Wrong flags | Not submitted | -| Criterion 5.3: Hardware Verification | 8 | Corrected console output confirmed (CRITICAL/HELD in 1s stream; DANGER at boot/Ghidra) | Some lines corrected | No verification | -| Criterion 5.4: Summary Table of All Patches | 4 | Complete address and before/after table | Missing entries | No table | - -### Task 6: Written Reflection (5 points) - -| Criterion | Points | Full credit | Partial credit | No credit | -|-----------|--------|-------------|----------------|-----------| -| Criterion 6.1: "Rushed Build" Is Not an Excuse | 2 | Specific, grounded reasoning | Generic | Missing | -| Criterion 6.2: One Engineering Practice per Bug | 3 | Concrete practice for each bug | One bug only | Missing | - ---- - -## Common Pitfalls - -| Pitfall | Consequence | Avoidance | -|---------|-------------|-----------| -| Patching only one threshold site | One status line still lies | Patch both `0x100001FC` and `0x1000020A` | -| Assuming the immediate equals the limit | Off-by-one, wrong boundary | Use `0x3B` (59), not `0x3C` (60) | -| Using Patch Instruction before IT block | Re-disassembler context conflict swallows Site B | In Listing press `C` -> edit byte in Bytes window (pencil) -> press `D` | -| Missing boot banner in serial terminal | PuTTY misses one-time 5ms boot banner | Pulse RUN to GND while connected to capture | -| Replacing a string with a different length | Corrupts adjacent flash | `NORMAL` and `DANGER` are both 6 bytes | -| Treating an odd vector address as invalid | Thumb analysis fails | Clear bit 0 | -| Modifying the quarantined dispatch frame | Destroys evidence | Recover it, do not patch it | - ---- - -## How To Breadboard - -- **Raspberry Pi Pico 2** powered over USB. -- **3.3 V USB-UART adapter**: - - Adapter RX to Pico GP0 (UART0 TX) - - Adapter TX to Pico GP1 (UART0 RX) - - Adapter GND to Pico GND - - Do not connect the adapter VCC while the Pico is USB powered. -- **Serial monitor:** 115200 baud, 8 data bits, no parity, 1 stop bit. -- No other peripherals are required; all evidence is obtained from the console. - ---- - -## Memory Map Reference - -| Region | Address | Purpose | -|--------|---------|---------| -| Bootrom | `0x00000000` | Immutable boot code | -| Flash/XIP | `0x10000000` | Vector table, code, constants, strings | -| SRAM | `0x20000000` | Stack and writable state | - ---- - -## Deadline & Submission - -- Create a folder containing the Ghidra screenshot, `CTF-01_fixed.bin`, and - `CTF-01_fixed.uf2`. -- Write all written answers in a single file named `CTF-01-Answers.md` inside that - folder. -- ZIP the folder as `lastname-firstname-CTF-01.zip`. -- Submit the ZIP before the posted deadline; late submissions lose 10 percent - per day. - ---- - -## Grade Scale - -| Grade | Percentage | Points | -|-------|------------|--------| -| A+ | 97-100% | 97-100 | -| A | 93-96% | 93-96 | -| A- | 90-92% | 90-92 | -| B+ | 87-89% | 87-89 | -| B | 84-86% | 84-86 | -| B- | 80-83% | 80-83 | -| C | 70-79% | 70-79 | -| F | 0-69% | 0-69 | - ---- - -## Academic Integrity - -Use only the supplied Pico 2 and firmware. Do not connect the exercise to an -operational grid, water plant, public network, military system, or third-party -device. This is a controlled, isolated educational exercise. All analysis and -patches must be your own work; sharing binaries, addresses, or answers is a -violation of the academic integrity policy. - ---- - -## Reference Material - -| Topic | Reference | -|-------|-----------| -| ARM Cortex-M33 registers and stack | Week 1 | -| UART output and console capture | Week 2 | -| Vector tables, reset startup, and XIP | Week 2 | -| Ghidra static analysis and binary patching | Week 3 | -| Thumb addressing | Week 3 | diff --git a/0x0001b_ctf/CTF-01-R.pdf b/0x0001b_ctf/CTF-01-R.pdf deleted file mode 100644 index 01ca3d8..0000000 Binary files a/0x0001b_ctf/CTF-01-R.pdf and /dev/null differ diff --git a/0x0001b_ctf/CTF-01-S.md b/0x0001b_ctf/CTF-01-S.md deleted file mode 100644 index 6d19d05..0000000 --- a/0x0001b_ctf/CTF-01-S.md +++ /dev/null @@ -1,467 +0,0 @@ -# Operation Black Start - Instructor Solution Key - -``` -+----------------------------------------------------------------------------------------+ -| | -| ██████╗ ██╗ █████╗ ██████╗██╗ ██╗███████╗████████╗ █████╗ ██████╗ ████████╗ | -| ██╔══██╗██║ ██╔══██╗██╔════╝██║ ██╔╝██╔════╝╚══██╔══╝██╔══██╗██╔══██╗╚══██╔══╝ | -| ██████╔╝██║ ███████║██║ █████╔╝ ███████╗ ██║ ███████║██████╔╝ ██║ | -| ██╔══██╗██║ ██╔══██║██║ ██╔═██╗ ╚════██║ ██║ ██╔══██║██╔══██╗ ██║ | -| ██████╔╝███████╗██║ ██║╚██████╗██║ ██╗███████╗ ██║ ██║ ██║██║ ██║ ██║ | -| ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═════╝██║ ██║╚══════╝ ╚═╝ ╚═╝ ╚═╝██║ ██║ ██║ | -| | -| | -| O P E R A T I O N B L A C K S T A R T | -| | -| *** INSTRUCTOR SOLUTION KEY - RESTRICTED *** | -| | -+----------------------------------------------------------------------------------------+ -``` - -> The task and criterion headings in this key are word-for-word identical to -> `CTF-01-R.md`, so a student can match each criterion one-to-one. - ---- - -## Artifact Identity - -| Artifact | Value | -|----------|-------| -| Student image | `CTF-01.bin` | -| Flash image | `CTF-01.uf2` | -| Target | Raspberry Pi Pico 2 / RP2350 ARM Cortex-M33 | -| Image base | `0x10000000` | -| Console | UART0, GPIO 0 TX / GPIO 1 RX, 115200 8N1 | - -```text -CTF-01.bin 425591AC17FF4C22206286EE6F40B06A89523483804850A41854A9B6F89D7B70 -CTF-01.uf2 B1552EE3BB5763D96C65D8DF1C86984EE842EF1A823FDF5D94132B1E10FF9D16 -``` - -Proof tool: `python3 scripts/verify_ctf.py` returns `11/11 checks passed` against -`CTF-01.bin`. - ---- - -## Task 1: Setup and Initial Analysis (15 points) - -### Solution - -**Criterion 1.1: Ghidra Project Setup (3 points).** Import `CTF-01.bin` as -`Raw Binary`, language `ARM:LE:32:Cortex`, base address `0x10000000`, then run -auto-analysis. - -**Criterion 1.2: main() and Status-Loop Addresses (4 points).** - -| Element | Address | -|---------|---------| -| `main()` | `0x100001E0` | -| Recurring status loop start | `0x10000234` | -| Loop back-edge (`b.n 0x10000234`) | `0x10000266` | - -The back-edge instruction at `0x10000266` is `b.n 0x10000234`, encoded as bytes -`E5 E7`. - -**Criterion 1.3: Vector Table Decoding (4 points).** -First 32 bytes of `CTF-01.bin`: - -```text -00 20 08 20 5B 01 00 10 1B 01 00 10 1D 01 00 10 -11 01 00 10 11 01 00 10 11 01 00 10 11 01 00 10 -``` - -| Evidence | Answer | -|----------|--------| -| Vector table base | `0x10000000` | -| Initial SP | `0x20082000` | -| Reset pointer (as stored) | `0x1000015B` | -| Reset instruction address | `0x1000015A` | - -**Criterion 1.4: Thumb Addressing (4 points).** -The stored reset pointer `0x1000015B` has bit 0 set to 1, which selects Thumb -mode. Clearing bit 0 (`0x1000015B & ~1`) gives the real instruction address -`0x1000015A`. The equally odd interrupt vectors (`0x1000011B`, `0x1000011D`, -`0x10000111`) are handled the same way. - -### Grading Rubric (1-to-1 Mapping) - -| Criterion | Points | Full Credit (Answer Key) | Partial Credit | No Credit | -|-----------|--------|--------------------------|----------------|-----------| -| Criterion 1.1: Ghidra Project Setup | 3 | Correct project name, `ARM:LE:32:Cortex` (ARM Cortex 32-bit little endian), base `0x10000000` | One item off | Not set up | -| Criterion 1.2: main() and Status-Loop Addresses | 4 | Both addresses correct | One correct | Neither found | -| Criterion 1.3: Vector Table Decoding | 4 | Correct base, initial SP, reset pointer | One missing | Not found | -| Criterion 1.4: Thumb Addressing | 4 | Correctly clears bit 0 and identifies `main()` | General explanation | Incorrect | - -### Instructor Notes & Assembly - -- Confirm the Ghidra import used `Raw Binary`, `ARM:LE:32:Cortex`, base - `0x10000000`, and that auto-analysis completed before any address was read. -- Verify `main()` is `0x100001E0`, the loop head is `0x10000234`, and the - back-edge bytes `E5 E7` sit at `0x10000266`. -- The reset vector is stored as `0x1000015B`; the real Thumb entry is - `0x1000015A`. Do not accept the un-cleared `0x1000015B` as an instruction - address. - ---- - -## Task 2: Find and Patch Bug #1: The Miscalibrated Safety Threshold (30 points) - -### Solution - -`grid_deviation` is `volatile`, so the compiler emits two independent compares: -one for the operator status and one for the automated dispatch decision. - -**Criterion 2.1: Locate Compare Site A (5 points).** - -```text -100001fc: 2b5e cmp r3, #94 @ 0x5e -``` - -| Item | Value | -|------|-------| -| Address | `0x100001FC` | -| File offset | `0x1FC` | -| Original bytes | `5E 2B` | -| Original instruction | `cmp r3, #94` | - -**Criterion 2.2: Locate Compare Site B (5 points).** - -```text -1000020a: 2b5e cmp r3, #94 @ 0x5e -``` - -| Item | Value | -|------|-------| -| Address | `0x1000020A` | -| File offset | `0x20A` | -| Original bytes | `5E 2B` | -| Original instruction | `cmp r3, #94` | - -**Criterion 2.3: Correct Immediate-Value Reasoning (8 points).** -The source constant is `SAFE_THRESHOLD = 95` and the test is `x < 95`. For an -unsigned value, `x < 95` is exactly `x <= 94`, which the compiler emits as -`cmp r3, #94` plus `ite hi`. The correct engineering limit is `60`, so the test -is `x < 60`, which is `x <= 59`. The correct patched immediate is therefore -**`0x3B` (59)**, not `0x3C` (60). Patching to `0x3C` would wrongly accept a -reading of exactly 60. - -**Criterion 2.4: Patch Compare Site A (4 points).** - -| Address | File Offset | Original | Patched | Before | After | -|---------|-------------|----------|---------|--------|-------| -| `0x100001FC` | `0x1FC` | `5E 2B` | `3B 2B` | `cmp r3, #94` | `cmp r3, #59` | - -**Criterion 2.5: Patch Compare Site B (4 points).** - -| Address | File Offset | Original | Patched | Before | After | -|---------|-------------|----------|---------|--------|-------| -| `0x1000020A` | `0x20A` | `5E 2B` | `3B 2B` | `cmp r3, #94` | `cmp r3, #59` | - -**Criterion 2.6: Explain Why Both Sites Must Be Patched (4 points).** -`operator_state` (`0x20000844`) and `dispatch_state` (`0x20000834`) are each -computed from their own read of `grid_deviation`. Patching only site A fixes the -displayed text while the automated dispatch at site B still authorizes on the -dangerous reading. Frozen reading `87`: `87 <= 94` is true (STABLE/AUTHORIZED, -wrong); `87 <= 59` is false (CRITICAL/HELD, correct). - -### Grading Rubric (1-to-1 Mapping) - -| Criterion | Points | Full Credit (Answer Key) | Partial Credit | No Credit | -|-----------|--------|--------------------------|----------------|-----------| -| Criterion 2.1: Locate Compare Site A | 5 | Correct address and original bytes | Address off | Not found | -| Criterion 2.2: Locate Compare Site B | 5 | Correct address and original bytes | Address off | Not found | -| Criterion 2.3: Correct Immediate-Value Reasoning | 8 | Explains the `<` to `<=` transform and gives `0x3B` | Correct value, no reasoning | Wrong value | -| Criterion 2.4: Patch Compare Site A | 4 | Byte change verified | Wrong byte | Not patched | -| Criterion 2.5: Patch Compare Site B | 4 | Byte change verified | Wrong byte | Not patched | -| Criterion 2.6: Explain Why Both Sites Must Be Patched | 4 | Clear explanation of the two independent comparisons | Vague | Missing | - -### Instructor Notes & Assembly - -- Both sites must be patched: `0x100001FC` for operator status and - `0x1000020A` for the automated dispatch decision. -- The correct immediate is `0x3B` (59), not `0x3C` (60); the source test is a - strict `<`, compiled as `<= 94`. -- Verify the byte changes on hardware: after patching, `operator_state` - (`0x20000844`) and `dispatch_state` (`0x20000834`) read `0` and `0`. -- **Ghidra ARM/Thumb Context Note:** In raw `.bin` files, patching an instruction - that precedes an `IT` block (`ite hi`) using the GUI *Patch Instruction* action - triggers Ghidra's `ReDisassembleCommand`. The re-disassembler encounters an - internal context register conflict when trying to re-declare the `ITBlock` - context over existing instructions, collapsing Thumb decoding into 32-bit ARM - mode and swallowing Site B (`0x1000020A`). Students must patch using the Bytes - window workflow (Clear `C` -> edit byte `5E` -> `3B` in Bytes window with pencil - icon -> Disassemble `D`) to keep Site B visible and cleanly aligned. - ---- - -## Task 3: Find and Patch Bug #2: The False Signal Banner (20 points) - -### Solution - -**Criterion 3.1: Locate the Banner String (5 points).** - -| String | Address | -|--------|---------| -| `"SIGNAL: NORMAL\r"` | `0x10003678` | -| `"NORMAL"` substring to patch | `0x10003680` | - -The string is loaded at call site `0x10000224` (`ldr r0, [pc, #92]` -> -`0x10003678`) and printed by `bl __wrap_puts` at `0x10000226`. It is printed -once at boot and never recomputed. - -**Criterion 3.2: Patch Six Characters (8 points).** -`NORMAL` and `DANGER` are both six ASCII characters, so the patch preserves the -string length. - -| Address Range | Original Bytes | Patched Bytes | -|---------------|----------------|---------------| -| `0x10003680` - `0x10003685` | `4E 4F 52 4D 41 4C` | `44 41 4E 47 45 52` | - -**Criterion 3.3: Character-by-Character Documentation (4 points).** - -| Address | Original Char | Original Byte | Patched Char | Patched Byte | -|---------|---------------|---------------|--------------|--------------| -| `0x10003680` | N | `4E` | D | `44` | -| `0x10003681` | O | `4F` | A | `41` | -| `0x10003682` | R | `52` | N | `4E` | -| `0x10003683` | M | `4D` | G | `47` | -| `0x10003684` | A | `41` | E | `45` | -| `0x10003685` | L | `4C` | R | `52` | - -**Criterion 3.4: Explain the Danger of a Hardcoded Status Word (3 points).** -The banner never consults the reading, so it reports a healthy line even while -the frozen reading is dangerous. Operators trust supervisory banners, so a -hardcoded `NORMAL` masks the hazard and prevents manual intervention. - -### Grading Rubric (1-to-1 Mapping) - -| Criterion | Points | Full Credit (Answer Key) | Partial Credit | No Credit | -|-----------|--------|--------------------------|----------------|-----------| -| Criterion 3.1: Locate the Banner String | 5 | Correct address | Approximate | Not found | -| Criterion 3.2: Patch Six Characters | 8 | All six bytes changed, length preserved | Correct text, wrong bytes documented | Wrong length | -| Criterion 3.3: Character-by-Character Documentation | 4 | Original vs patched byte for all six characters | Partial | Missing | -| Criterion 3.4: Explain the Danger of a Hardcoded Status Word | 3 | Clear, specific reasoning | Generic | Missing | - -### Instructor Notes & Assembly - -- `NORMAL` and `DANGER` are both six characters; the patch must not change the - string length or overwrite adjacent flash. -- The banner is printed once at boot and never recomputed, so it is a separate - defect from the threshold and must be graded independently. -- Confirm the patch covers `0x10003680` through `0x10003685` exactly. - ---- - -## Task 4: Recover the Quarantined Dispatch Frame (10 points) - -### Solution - -**Criterion 4.1: Recover the Dispatch Frame (6 points).** -Address `0x100037A0` in flash `.rodata`: - -```text -WORLDGRID:BLACKSTART:GRID-7:WATER-3 -``` - -**Criterion 4.2: Explain Why It Is Never Transmitted (4 points).** -`retain_dispatch_frame()` reads only the first character into a `volatile` local -so the linker keeps the string, but the pointer is never passed to any print or -UART routine. The frame is evidence only and must not be patched. - -### Grading Rubric (1-to-1 Mapping) - -| Criterion | Points | Full Credit (Answer Key) | Partial Credit | No Credit | -|-----------|--------|--------------------------|----------------|-----------| -| Criterion 4.1: Recover the Dispatch Frame | 6 | Correct address and full text | Partial text | Not found | -| Criterion 4.2: Explain Why It Is Never Transmitted | 4 | Clear static-analysis explanation | Vague | Missing | - -### Instructor Notes & Assembly - -- Accept the full string `WORLDGRID:BLACKSTART:GRID-7:WATER-3` at `0x100037A0` - in flash `.rodata`. -- The frame is evidence only. Penalize any submission that patches or rewrites - it instead of recovering it. - ---- - -## Task 5: Export and Verify (20 points) - -### Solution - -**Criterion 5.1: Export CTF-01_fixed.bin (4 points).** -Export the patched program from Ghidra (`File -> Export Program...`, `Binary -Format`) as `CTF-01_fixed.bin`. - -**Criterion 5.2: Convert to CTF-01_fixed.uf2 (4 points).** - -```bash -python uf2conv.py CTF-01_fixed.bin --base 0x10000000 --family 0xe48bff59 --output CTF-01_fixed.uf2 -``` - -**Criterion 5.3: Hardware Verification (8 points).** - -Before patching: - -```text -GLOBAL EMBEDDED RESPONSE NETWORK -BLACK START WINDOW: 27 MINUTES -UART0 115200 8N1 | AUTHORIZED LAB CONSOLE -SIGNAL: NORMAL -RESPONSE> GRID STATUS: STABLE -DISPATCH PATH: AUTHORIZED -LAST FRAME: QUARANTINED -RESPONSE> -``` - -After all three patches: - -```text -GLOBAL EMBEDDED RESPONSE NETWORK -BLACK START WINDOW: 27 MINUTES -UART0 115200 8N1 | AUTHORIZED LAB CONSOLE -SIGNAL: DANGER -RESPONSE> GRID STATUS: CRITICAL -DISPATCH PATH: HELD -LAST FRAME: QUARANTINED -RESPONSE> -``` - -If the console is not wired, the same proof is read over SWD: after reset, -`operator_state` (`0x20000844`) and `dispatch_state` (`0x20000834`) are `1` and -`1` for the shipped image, and `0` and `0` for the patched image. This has been -confirmed on real hardware. - -**Criterion 5.4: Summary Table of All Patches (4 points).** - -| # | What | Address(es) | Original | Patched | -|---|------|-------------|----------|---------| -| 1a | Operator threshold | `0x100001FC` | `5E 2B` | `3B 2B` | -| 1b | Dispatch threshold | `0x1000020A` | `5E 2B` | `3B 2B` | -| 2 | Signal banner | `0x10003680`-`0x10003685` | `4E 4F 52 4D 41 4C` | `44 41 4E 47 45 52` | - -Total: **8 bytes actually change** (one immediate byte at each compare site and -six string bytes). - -### Grading Rubric (1-to-1 Mapping) - -| Criterion | Points | Full Credit (Answer Key) | Partial Credit | No Credit | -|-----------|--------|--------------------------|----------------|-----------| -| Criterion 5.1: Export CTF-01_fixed.bin | 4 | Valid patched binary | Corrupted | Not submitted | -| Criterion 5.2: Convert to CTF-01_fixed.uf2 | 4 | Correct base and family flags | Wrong flags | Not submitted | -| Criterion 5.3: Hardware Verification | 8 | Corrected console output confirmed on hardware | Some lines corrected | No verification | -| Criterion 5.4: Summary Table of All Patches | 4 | Complete address and before/after table | Missing entries | No table | - -### Instructor Notes & Assembly - -- Verify the exported image with `python3 scripts/verify_ctf.py`; the shipped - check expects `11/11 checks passed` against `CTF-01.bin`. -- Confirm the UF2 conversion used base `0x10000000` and family `0xe48bff59`. -- **Serial Terminal Timing:** Note that `print_boot_banner()` (`SIGNAL: DANGER`) - fires within the first 5 milliseconds of boot. In normal lab usage, PuTTY - attaches after boot and will display the continuous 1-second status loop - (`GRID STATUS: CRITICAL`, `DISPATCH PATH: HELD`). To see `SIGNAL: DANGER`, - the student must pulse `RUN` to `GND` while PuTTY is open, or demonstrate - the string change at `0x10003680` via Ghidra static analysis. -- If no console is available, accept the SWD capture showing `operator_state` - and `dispatch_state` at `0` and `0` on the patched image. - ---- - -## Task 6: Written Reflection (5 points) - -### Solution - -**Criterion 6.1: "Rushed Build" Is Not an Excuse (2 points).** -The missed review step is exactly what shipped the false-safe report; pressure -explains why the safeguard was skipped, not why it should be skipped. - -**Criterion 6.2: One Engineering Practice per Bug (3 points).** -- Bug #1 (duplicated threshold): a unit test or static-analysis rule that - requires every comparison against `SAFE_THRESHOLD` to use one shared source of - truth. -- Bug #2 (hardcoded banner): a hardware-in-the-loop smoke test that checks the - boot banner against the latched reading. - -### Grading Rubric (1-to-1 Mapping) - -| Criterion | Points | Full Credit (Answer Key) | Partial Credit | No Credit | -|-----------|--------|--------------------------|----------------|-----------| -| Criterion 6.1: "Rushed Build" Is Not an Excuse | 2 | Specific, grounded reasoning | Generic | Missing | -| Criterion 6.2: One Engineering Practice per Bug | 3 | Concrete practice for each bug | One bug only | Missing | - -### Instructor Notes & Assembly - -- Grade the specificity of the reasoning, not the length of the prose. -- Require one concrete engineering practice for each of the two bugs. - ---- - -## How To Breadboard - -- **Raspberry Pi Pico 2** powered over USB. -- **3.3 V USB-UART adapter**: - - Adapter RX to Pico GP0 (UART0 TX) - - Adapter TX to Pico GP1 (UART0 RX) - - Adapter GND to Pico GND - - Do not connect the adapter VCC while the Pico is USB powered. -- **Serial monitor:** 115200 baud, 8 data bits, no parity, 1 stop bit. -- No other peripherals are required; all evidence is obtained from the console. - ---- - -## Complete Grading Summary - -| Task | Title | Points | -|------|-------|--------| -| Task 1 | Setup and Initial Analysis | 15 | -| Task 2 | Find and Patch Bug #1: The Miscalibrated Safety Threshold | 30 | -| Task 3 | Find and Patch Bug #2: The False Signal Banner | 20 | -| Task 4 | Recover the Quarantined Dispatch Frame | 10 | -| Task 5 | Export and Verify | 20 | -| Task 6 | Written Reflection | 5 | -| **TOTAL** | | **100** | - ---- - -## Instructor Notes - -Safety: Use only the supplied Pico 2, 3.3 V UART adapter, and firmware. Never -connect the exercise to an operational grid, water plant, public network, -military system, or third-party device. - -### Common Student Mistakes - -- Patching only one threshold site (`0x100001FC` or `0x1000020A`), which leaves - one status line lying. -- Assuming the immediate equals the limit, producing an off-by-one boundary; - the correct byte is `0x3B` (59), not `0x3C` (60). -- Replacing the banner string with a different length, corrupting adjacent - flash; `NORMAL` and `DANGER` are both 6 bytes. -- Treating the odd vector address `0x1000015B` as invalid instead of clearing - bit 0 to get `0x1000015A`. -- Modifying the quarantined dispatch frame at `0x100037A0`, which destroys - evidence. - -### Partial Credit Guidelines - -- Award partial credit for one correct threshold site out of two, or for a - correct immediate value without the `<` to `<=` reasoning. -- Award partial credit for a correct banner text with incorrectly documented - bytes, or for partial character-by-character documentation. -- Accept an SWD read of `operator_state` and `dispatch_state` as equivalent - proof when no UART console is available. -- Award no credit for patches that change string length or overwrite adjacent - flash. - ---- - -## Appendix: Expected Binary Diff - -| # | What | File Offset(s) | Address(es) | Original Bytes | Patched Bytes | -|---|------|----------------|-------------|----------------|---------------| -| 1a | Operator threshold | `0x1FC` | `0x100001FC` | `5E 2B` | `3B 2B` | -| 1b | Dispatch threshold | `0x20A` | `0x1000020A` | `5E 2B` | `3B 2B` | -| 2 | Signal banner | `0x3680` - `0x3685` | `0x10003680` - `0x10003685` | `4E 4F 52 4D 41 4C` | `44 41 4E 47 45 52` | - -Total: **8 bytes actually change** (one immediate byte at each compare site and -six string bytes). diff --git a/0x0001b_ctf/CTF-01-S.pdf b/0x0001b_ctf/CTF-01-S.pdf deleted file mode 100644 index 1180fbe..0000000 Binary files a/0x0001b_ctf/CTF-01-S.pdf and /dev/null differ diff --git a/0x0001b_ctf/CTF-01.bin b/0x0001b_ctf/CTF-01.bin deleted file mode 100644 index 2a1de88..0000000 Binary files a/0x0001b_ctf/CTF-01.bin and /dev/null differ diff --git a/0x0001b_ctf/CTF-01.uf2 b/0x0001b_ctf/CTF-01.uf2 deleted file mode 100644 index e0313c1..0000000 Binary files a/0x0001b_ctf/CTF-01.uf2 and /dev/null differ diff --git a/0x0001b_ctf/CTF-01_fixed.bin b/0x0001b_ctf/CTF-01_fixed.bin deleted file mode 100644 index a9d582c..0000000 Binary files a/0x0001b_ctf/CTF-01_fixed.bin and /dev/null differ diff --git a/0x0001b_ctf/CTF-01_fixed.uf2 b/0x0001b_ctf/CTF-01_fixed.uf2 deleted file mode 100644 index 7384d9a..0000000 Binary files a/0x0001b_ctf/CTF-01_fixed.uf2 and /dev/null differ diff --git a/0x0001b_ctf/include/console.h b/0x0001b_ctf/include/console.h deleted file mode 100644 index b5a6502..0000000 --- a/0x0001b_ctf/include/console.h +++ /dev/null @@ -1,72 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: console.h -// Desc: Declares the UART console banner and status reporting interface -// for Operation Black Start. -// Created: 2026 - -#ifndef CONSOLE_H -#define CONSOLE_H - -#include "grid.h" -#include - -/** - * @brief Print the response controller's boot identity and unconditional signal line. - * - * Emits the boot banner, operation window, serial configuration banner, - * unconditional signal quality line, and the interactive command prompt. - * - * @param None. - * @return None. - */ -static inline void print_boot_banner(void) -{ - printf("GLOBAL EMBEDDED RESPONSE NETWORK\r\n"); - printf("BLACK START WINDOW: 27 MINUTES\r\n"); - printf("UART0 115200 8N1 | AUTHORIZED LAB CONSOLE\r\n"); - printf("SIGNAL: NORMAL\r\n"); - printf("RESPONSE> "); -} - -/** - * @brief Print the recurring grid classification and dispatch authorization report. - * - * Evaluates the current operator state and dispatch state flags and transmits - * the formatted status report over UART0 with the quarantined frame notification. - * - * @param None. - * @return None. - */ -static inline void print_status(void) -{ - printf("GRID STATUS: %s\r\n", operator_state ? "STABLE" : "CRITICAL"); - printf("DISPATCH PATH: %s\r\n", dispatch_state ? "AUTHORIZED" : "HELD"); - printf("LAST FRAME: QUARANTINED\r\n"); - printf("RESPONSE> "); -} - -#endif // CONSOLE_H diff --git a/0x0001b_ctf/include/grid.h b/0x0001b_ctf/include/grid.h deleted file mode 100644 index c1444c8..0000000 --- a/0x0001b_ctf/include/grid.h +++ /dev/null @@ -1,85 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: grid.h -// Desc: Declares the grid telemetry and safety evaluation interface for -// Operation Black Start. -// Created: 2026 - -#ifndef GRID_H -#define GRID_H - -#include - -// Safety margin (Hz deviation x100) below which grid frequency is tolerable. -// BUG: emergency build miscompiled this far too permissive; correct value is 60. -#define SAFE_THRESHOLD 95 - -// Frozen grid frequency deviation reading latched when comms were severed. -extern volatile uint32_t grid_deviation; - -// Operator-facing classification of the frozen reading (drives GRID STATUS). -extern volatile uint32_t operator_state; - -// Automated dispatch authorization decision (drives DISPATCH PATH). -extern volatile uint32_t dispatch_state; - -// Quarantined black-start authorization frame, retained in flash, never sent. -static volatile const char dispatch_frame[] = - "WORLDGRID:BLACKSTART:GRID-7:WATER-3"; - -static inline void retain_dispatch_frame(void) -{ - volatile char frame_marker = dispatch_frame[0]; - (void)frame_marker; -} - -static inline void evaluate_grid(void) -{ - operator_state = (grid_deviation < SAFE_THRESHOLD) ? 1 : 0; - dispatch_state = (grid_deviation < SAFE_THRESHOLD) ? 1 : 0; -} - -/** - * @brief Anchor the hidden dispatch frame in flash without transmitting it. - * - * Reads the first character of the quarantined black-start authorization - * frame into a volatile local marker to prevent the compiler from optimizing - * out the string literal from .rodata flash storage. - * - * @param None. - * @return None. - */ -/** - * @brief Classify the frozen telemetry reading against the compiled threshold. - * - * Evaluates the frozen grid deviation reading against SAFE_THRESHOLD twice, - * once for the operator-facing status line and once for the automated - * dispatch decision, mirroring the duplicated immediate comparison site. - * - * @param None. - * @return None. - */ -#endif // GRID_H diff --git a/0x0001b_ctf/pico_sdk_import.cmake b/0x0001b_ctf/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x0001b_ctf/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x0001b_ctf/scripts/verify_ctf.py b/0x0001b_ctf/scripts/verify_ctf.py deleted file mode 100644 index 357eff9..0000000 --- a/0x0001b_ctf/scripts/verify_ctf.py +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env python3 -"""Verify every technical claim of Operation Black Start against CTF-01.bin. - -Exits 0 only when every address, byte, and hash in CTF-R.md and CTF-S.md -matches the shipped image. -""" -import hashlib -import struct -import sys -from pathlib import Path - -BASE = 0x10000000 -ROOT = Path(__file__).resolve().parent.parent -BIN = ROOT / "CTF-01.bin" -UF2 = ROOT / "CTF-01.uf2" - -EXPECTED_BIN_SHA = "425591ac17ff4c22206286ee6f40b06a89523483804850a41854a9b6f89d7b70" -EXPECTED_UF2_SHA = "b1552ee3bb5763d96c65d8df1c86984ee842ef1a823fdf5d94132b1e10ff9d16" - -CMP_A = 0x100001FC -CMP_B = 0x1000020A -STRING_SIGNAL = 0x10003678 -STRING_FRAME = 0x100037A0 -LOOP_BACK = 0x10000266 - -RESULTS = [] - - -def check(label, ok, detail=""): - """Record one verification result. - - Parameters - ---------- - label : str - Human-readable check name. - ok : bool - Whether the check passed. - detail : str - Extra context printed with the result. - - Returns - ------- - None - """ - RESULTS.append(ok) - print(f"[{'PASS' if ok else 'FAIL'}] {label} {detail}") - - -def main(): - """Run all verification checks. - - Returns - ------- - int - Zero when every check passes, else one. - """ - data = BIN.read_bytes() - check("CTF-01.bin SHA-256", hashlib.sha256(data).hexdigest() == EXPECTED_BIN_SHA) - check("CTF-01.uf2 SHA-256", - hashlib.sha256(UF2.read_bytes()).hexdigest() == EXPECTED_UF2_SHA) - check("vector table", data[0:32].hex() == - "002008205b0100101b0100101d01001011010010110100101101001011010010") - check("initial SP", struct.unpack(" - -volatile uint32_t grid_deviation = 87; -volatile uint32_t operator_state = 0; -volatile uint32_t dispatch_state = 0; diff --git a/0x0001b_ctf/src/main.c b/0x0001b_ctf/src/main.c deleted file mode 100644 index 87671bd..0000000 --- a/0x0001b_ctf/src/main.c +++ /dev/null @@ -1,56 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: main.c -// Desc: Main entry point for the Operation Black Start CTF relay firmware. -// Created: 2026 - -#include "console.h" -#include "grid.h" -#include "pico/stdlib.h" - -/** - * @brief Run the recurring UART evidence stream for the isolated CTF image. - * - * Initializes the standard I/O subsystems, anchors the quarantined dispatch - * frame in flash memory, evaluates the frozen telemetry against the compiled - * safety threshold, prints the startup banner, and repeatedly emits the - * system status report every second. - * - * @param None. - * @return int Standard exit code (never reached in normal firmware execution). - */ -int main(void) -{ - stdio_init_all(); - retain_dispatch_frame(); - evaluate_grid(); - print_boot_banner(); - while (true) { - print_status(); - sleep_ms(1000); - } - return 0; -} diff --git a/0x0001b_ctf/uf2families.json b/0x0001b_ctf/uf2families.json deleted file mode 100644 index 91d99ad..0000000 --- a/0x0001b_ctf/uf2families.json +++ /dev/null @@ -1,22 +0,0 @@ -[ - { - "short_name": "RP2040", - "id": "0xe48bff56", - "description": "Raspberry Pi RP2040" - }, - { - "short_name": "RP2350-ARM-S", - "id": "0xe48bff59", - "description": "Raspberry Pi RP2350, ARM, Secure" - }, - { - "short_name": "RP2350-ARM-NS", - "id": "0xe48bff5a", - "description": "Raspberry Pi RP2350, ARM, Non-Secure" - }, - { - "short_name": "RP2350-RISCV", - "id": "0xe48bff5b", - "description": "Raspberry Pi RP2350, RISC-V" - } -] diff --git a/0x0005_intro-to-variables/.gitignore b/0x0005_intro-to-variables/.gitignore deleted file mode 100644 index 2435c20..0000000 --- a/0x0005_intro-to-variables/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -!.vscode/* diff --git a/0x0005_intro-to-variables/.vscode/c_cpp_properties.json b/0x0005_intro-to-variables/.vscode/c_cpp_properties.json deleted file mode 100644 index e80461d..0000000 --- a/0x0005_intro-to-variables/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "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 -} diff --git a/0x0005_intro-to-variables/.vscode/cmake-kits.json b/0x0005_intro-to-variables/.vscode/cmake-kits.json deleted file mode 100644 index b0f3815..0000000 --- a/0x0005_intro-to-variables/.vscode/cmake-kits.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "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}" - } - } -] \ No newline at end of file diff --git a/0x0005_intro-to-variables/.vscode/extensions.json b/0x0005_intro-to-variables/.vscode/extensions.json deleted file mode 100644 index a940d7c..0000000 --- a/0x0005_intro-to-variables/.vscode/extensions.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "recommendations": [ - "marus25.cortex-debug", - "ms-vscode.cpptools", - "ms-vscode.cpptools-extension-pack", - "ms-vscode.vscode-serial-monitor", - "raspberry-pi.raspberry-pi-pico" - ] -} \ No newline at end of file diff --git a/0x0005_intro-to-variables/.vscode/launch.json b/0x0005_intro-to-variables/.vscode/launch.json deleted file mode 100644 index 424aa71..0000000 --- a/0x0005_intro-to-variables/.vscode/launch.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "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}\"" - ] - }, - ] -} diff --git a/0x0005_intro-to-variables/.vscode/settings.json b/0x0005_intro-to-variables/.vscode/settings.json deleted file mode 100644 index cdb8e61..0000000 --- a/0x0005_intro-to-variables/.vscode/settings.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "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" -} diff --git a/0x0005_intro-to-variables/.vscode/tasks.json b/0x0005_intro-to-variables/.vscode/tasks.json deleted file mode 100644 index f427bf0..0000000 --- a/0x0005_intro-to-variables/.vscode/tasks.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Compile Project", - "type": "process", - "isBuildCommand": true, - "command": "${userHome}/.pico-sdk/ninja/v1.12.1/ninja", - "args": ["-C", "${workspaceFolder}/build"], - "group": "build", - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": "$gcc", - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/ninja/v1.12.1/ninja.exe" - } - }, - { - "label": "Run Project", - "type": "process", - "command": "${env:HOME}/.pico-sdk/picotool/2.2.0/picotool/picotool", - "args": [ - "load", - "${command:raspberry-pi-pico.launchTargetPath}", - "-fx" - ], - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/picotool/2.2.0/picotool/picotool.exe" - } - }, - { - "label": "Flash", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/${command:raspberry-pi-pico.getTarget}.cfg", - "-c", - "adapter speed 5000; program \"${command:raspberry-pi-pico.launchTargetPath}\" verify reset exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - }, - { - "label": "Rescue Reset", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/${command:raspberry-pi-pico.getChip}-rescue.cfg", - "-c", - "adapter speed 5000; reset halt; exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - }, - { - "label": "Risc-V Reset (RP2350)", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-c", - "set USE_CORE { rv0 rv1 cm0 cm1 }", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/rp2350.cfg", - "-c", - "adapter speed 5000; init;", - "-c", - "write_memory 0x40120158 8 { 0x3 }; echo [format \"Info : ARCHSEL 0x%02x\" [read_memory 0x40120158 8 1]];", - "-c", - "reset halt; targets rp2350.rv0; echo [format \"Info : ARCHSEL_STATUS 0x%02x\" [read_memory 0x4012015C 8 1]]; exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - } - ] -} diff --git a/0x0005_intro-to-variables/0x0005_intro-to-variables.c b/0x0005_intro-to-variables/0x0005_intro-to-variables.c deleted file mode 100644 index 7b2b3ae..0000000 --- a/0x0005_intro-to-variables/0x0005_intro-to-variables.c +++ /dev/null @@ -1,13 +0,0 @@ -#include -#include "pico/stdlib.h" - -int main(void) { - uint8_t age = 42; - - age = 43; - - stdio_init_all(); - - while (true) - printf("age: %d\r\n", age); -} diff --git a/0x0005_intro-to-variables/CMakeLists.txt b/0x0005_intro-to-variables/CMakeLists.txt deleted file mode 100644 index 673ff61..0000000 --- a/0x0005_intro-to-variables/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# 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(0x0005_intro-to-variables 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(0x0005_intro-to-variables 0x0005_intro-to-variables.c ) - -pico_set_program_name(0x0005_intro-to-variables "0x0005_intro-to-variables") -pico_set_program_version(0x0005_intro-to-variables "0.1") - -# Modify the below lines to enable/disable output over UART/USB -pico_enable_stdio_uart(0x0005_intro-to-variables 1) -pico_enable_stdio_usb(0x0005_intro-to-variables 0) - -# Add the standard library to the build -target_link_libraries(0x0005_intro-to-variables - pico_stdlib) - -# Add the standard include files to the build -target_include_directories(0x0005_intro-to-variables PRIVATE - ${CMAKE_CURRENT_LIST_DIR} -) - -pico_add_extra_outputs(0x0005_intro-to-variables) - diff --git a/0x0005_intro-to-variables/pico_sdk_import.cmake b/0x0005_intro-to-variables/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x0005_intro-to-variables/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x0008_uninitialized-variables-a/.gitignore b/0x0008_uninitialized-variables-a/.gitignore deleted file mode 100644 index 2435c20..0000000 --- a/0x0008_uninitialized-variables-a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -!.vscode/* diff --git a/0x0008_uninitialized-variables-a/.vscode/c_cpp_properties.json b/0x0008_uninitialized-variables-a/.vscode/c_cpp_properties.json deleted file mode 100644 index 27d83bd..0000000 --- a/0x0008_uninitialized-variables-a/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "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" - ], - "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 -} diff --git a/0x0008_uninitialized-variables-a/.vscode/cmake-kits.json b/0x0008_uninitialized-variables-a/.vscode/cmake-kits.json deleted file mode 100644 index b0f3815..0000000 --- a/0x0008_uninitialized-variables-a/.vscode/cmake-kits.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "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}" - } - } -] \ No newline at end of file diff --git a/0x0008_uninitialized-variables-a/.vscode/extensions.json b/0x0008_uninitialized-variables-a/.vscode/extensions.json deleted file mode 100644 index a940d7c..0000000 --- a/0x0008_uninitialized-variables-a/.vscode/extensions.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "recommendations": [ - "marus25.cortex-debug", - "ms-vscode.cpptools", - "ms-vscode.cpptools-extension-pack", - "ms-vscode.vscode-serial-monitor", - "raspberry-pi.raspberry-pi-pico" - ] -} \ No newline at end of file diff --git a/0x0008_uninitialized-variables-a/.vscode/launch.json b/0x0008_uninitialized-variables-a/.vscode/launch.json deleted file mode 100644 index 424aa71..0000000 --- a/0x0008_uninitialized-variables-a/.vscode/launch.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "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}\"" - ] - }, - ] -} diff --git a/0x0008_uninitialized-variables-a/.vscode/settings.json b/0x0008_uninitialized-variables-a/.vscode/settings.json deleted file mode 100644 index cdb8e61..0000000 --- a/0x0008_uninitialized-variables-a/.vscode/settings.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "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" -} diff --git a/0x0008_uninitialized-variables-a/.vscode/tasks.json b/0x0008_uninitialized-variables-a/.vscode/tasks.json deleted file mode 100644 index f427bf0..0000000 --- a/0x0008_uninitialized-variables-a/.vscode/tasks.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Compile Project", - "type": "process", - "isBuildCommand": true, - "command": "${userHome}/.pico-sdk/ninja/v1.12.1/ninja", - "args": ["-C", "${workspaceFolder}/build"], - "group": "build", - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": "$gcc", - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/ninja/v1.12.1/ninja.exe" - } - }, - { - "label": "Run Project", - "type": "process", - "command": "${env:HOME}/.pico-sdk/picotool/2.2.0/picotool/picotool", - "args": [ - "load", - "${command:raspberry-pi-pico.launchTargetPath}", - "-fx" - ], - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/picotool/2.2.0/picotool/picotool.exe" - } - }, - { - "label": "Flash", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/${command:raspberry-pi-pico.getTarget}.cfg", - "-c", - "adapter speed 5000; program \"${command:raspberry-pi-pico.launchTargetPath}\" verify reset exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - }, - { - "label": "Rescue Reset", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/${command:raspberry-pi-pico.getChip}-rescue.cfg", - "-c", - "adapter speed 5000; reset halt; exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - }, - { - "label": "Risc-V Reset (RP2350)", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-c", - "set USE_CORE { rv0 rv1 cm0 cm1 }", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/rp2350.cfg", - "-c", - "adapter speed 5000; init;", - "-c", - "write_memory 0x40120158 8 { 0x3 }; echo [format \"Info : ARCHSEL 0x%02x\" [read_memory 0x40120158 8 1]];", - "-c", - "reset halt; targets rp2350.rv0; echo [format \"Info : ARCHSEL_STATUS 0x%02x\" [read_memory 0x4012015C 8 1]]; exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - } - ] -} diff --git a/0x0008_uninitialized-variables-a/0x0008_uninitialized-variables-a.c b/0x0008_uninitialized-variables-a/0x0008_uninitialized-variables-a.c deleted file mode 100644 index 656a992..0000000 --- a/0x0008_uninitialized-variables-a/0x0008_uninitialized-variables-a.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include "pico/stdlib.h" - -#define LED_PIN 16 - -int main(void) -{ - gpio_init(LED_PIN); - gpio_set_dir(LED_PIN, GPIO_OUT); - - while (true) { - gpio_put(LED_PIN, 1); - sleep_ms(500); - - gpio_put(LED_PIN, 0); - sleep_ms(500); - } -} diff --git a/0x0008_uninitialized-variables-a/CMakeLists.txt b/0x0008_uninitialized-variables-a/CMakeLists.txt deleted file mode 100644 index 347375d..0000000 --- a/0x0008_uninitialized-variables-a/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# 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(0x0008_uninitialized-variables-a 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(0x0008_uninitialized-variables-a 0x0008_uninitialized-variables-a.c ) - -pico_set_program_name(0x0008_uninitialized-variables-a "0x0008_uninitialized-variables-a") -pico_set_program_version(0x0008_uninitialized-variables-a "0.1") - -# Modify the below lines to enable/disable output over UART/USB -pico_enable_stdio_uart(0x0008_uninitialized-variables-a 0) -pico_enable_stdio_usb(0x0008_uninitialized-variables-a 0) - -# Add the standard library to the build -target_link_libraries(0x0008_uninitialized-variables-a - pico_stdlib) - -# Add the standard include files to the build -target_include_directories(0x0008_uninitialized-variables-a PRIVATE - ${CMAKE_CURRENT_LIST_DIR} -) - -pico_add_extra_outputs(0x0008_uninitialized-variables-a) - diff --git a/0x0008_uninitialized-variables-a/pico_sdk_import.cmake b/0x0008_uninitialized-variables-a/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x0008_uninitialized-variables-a/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x0008_uninitialized-variables-b/.gitignore b/0x0008_uninitialized-variables-b/.gitignore deleted file mode 100644 index 2435c20..0000000 --- a/0x0008_uninitialized-variables-b/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -!.vscode/* diff --git a/0x0008_uninitialized-variables-b/.vscode/c_cpp_properties.json b/0x0008_uninitialized-variables-b/.vscode/c_cpp_properties.json deleted file mode 100644 index e80461d..0000000 --- a/0x0008_uninitialized-variables-b/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "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 -} diff --git a/0x0008_uninitialized-variables-b/.vscode/cmake-kits.json b/0x0008_uninitialized-variables-b/.vscode/cmake-kits.json deleted file mode 100644 index b0f3815..0000000 --- a/0x0008_uninitialized-variables-b/.vscode/cmake-kits.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "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}" - } - } -] \ No newline at end of file diff --git a/0x0008_uninitialized-variables-b/.vscode/extensions.json b/0x0008_uninitialized-variables-b/.vscode/extensions.json deleted file mode 100644 index a940d7c..0000000 --- a/0x0008_uninitialized-variables-b/.vscode/extensions.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "recommendations": [ - "marus25.cortex-debug", - "ms-vscode.cpptools", - "ms-vscode.cpptools-extension-pack", - "ms-vscode.vscode-serial-monitor", - "raspberry-pi.raspberry-pi-pico" - ] -} \ No newline at end of file diff --git a/0x0008_uninitialized-variables-b/.vscode/launch.json b/0x0008_uninitialized-variables-b/.vscode/launch.json deleted file mode 100644 index 424aa71..0000000 --- a/0x0008_uninitialized-variables-b/.vscode/launch.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "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}\"" - ] - }, - ] -} diff --git a/0x0008_uninitialized-variables-b/.vscode/settings.json b/0x0008_uninitialized-variables-b/.vscode/settings.json deleted file mode 100644 index cdb8e61..0000000 --- a/0x0008_uninitialized-variables-b/.vscode/settings.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "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" -} diff --git a/0x0008_uninitialized-variables-b/.vscode/tasks.json b/0x0008_uninitialized-variables-b/.vscode/tasks.json deleted file mode 100644 index f427bf0..0000000 --- a/0x0008_uninitialized-variables-b/.vscode/tasks.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Compile Project", - "type": "process", - "isBuildCommand": true, - "command": "${userHome}/.pico-sdk/ninja/v1.12.1/ninja", - "args": ["-C", "${workspaceFolder}/build"], - "group": "build", - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": "$gcc", - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/ninja/v1.12.1/ninja.exe" - } - }, - { - "label": "Run Project", - "type": "process", - "command": "${env:HOME}/.pico-sdk/picotool/2.2.0/picotool/picotool", - "args": [ - "load", - "${command:raspberry-pi-pico.launchTargetPath}", - "-fx" - ], - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/picotool/2.2.0/picotool/picotool.exe" - } - }, - { - "label": "Flash", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/${command:raspberry-pi-pico.getTarget}.cfg", - "-c", - "adapter speed 5000; program \"${command:raspberry-pi-pico.launchTargetPath}\" verify reset exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - }, - { - "label": "Rescue Reset", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/${command:raspberry-pi-pico.getChip}-rescue.cfg", - "-c", - "adapter speed 5000; reset halt; exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - }, - { - "label": "Risc-V Reset (RP2350)", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-c", - "set USE_CORE { rv0 rv1 cm0 cm1 }", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/rp2350.cfg", - "-c", - "adapter speed 5000; init;", - "-c", - "write_memory 0x40120158 8 { 0x3 }; echo [format \"Info : ARCHSEL 0x%02x\" [read_memory 0x40120158 8 1]];", - "-c", - "reset halt; targets rp2350.rv0; echo [format \"Info : ARCHSEL_STATUS 0x%02x\" [read_memory 0x4012015C 8 1]]; exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - } - ] -} diff --git a/0x0008_uninitialized-variables-b/0x0008_uninitialized-variables-b.c b/0x0008_uninitialized-variables-b/0x0008_uninitialized-variables-b.c deleted file mode 100644 index 365d7eb..0000000 --- a/0x0008_uninitialized-variables-b/0x0008_uninitialized-variables-b.c +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include "pico/stdlib.h" - -#define LED_PIN 16 - -int main(void) -{ - // gpio_init(LED_PIN); - gpio_set_dir(LED_PIN, GPIO_IN); - gpio_put(LED_PIN, 0); - gpio_set_function(LED_PIN, GPIO_FUNC_SIO); - - // gpio_set_dir(LED_PIN, GPIO_OUT); - gpioc_bit_oe_put(LED_PIN, GPIO_OUT); - - while (true) { - // gpio_put(LED_PIN, 1); - gpioc_bit_out_put(LED_PIN, 1); - // sleep_ms(500); - sleep_us(500 * 1000ull); - - // gpio_put(LED_PIN, 0); - gpioc_bit_out_put(LED_PIN, 0); - // sleep_ms(500); - sleep_us(500 * 1000ull); - } -} diff --git a/0x0008_uninitialized-variables-b/CMakeLists.txt b/0x0008_uninitialized-variables-b/CMakeLists.txt deleted file mode 100644 index 24d559f..0000000 --- a/0x0008_uninitialized-variables-b/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# 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(0x0008_uninitialized-variables-b 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(0x0008_uninitialized-variables-b 0x0008_uninitialized-variables-b.c ) - -pico_set_program_name(0x0008_uninitialized-variables-b "0x0008_uninitialized-variables-b") -pico_set_program_version(0x0008_uninitialized-variables-b "0.1") - -# Modify the below lines to enable/disable output over UART/USB -pico_enable_stdio_uart(0x0008_uninitialized-variables-b 0) -pico_enable_stdio_usb(0x0008_uninitialized-variables-b 0) - -# Add the standard library to the build -target_link_libraries(0x0008_uninitialized-variables-b - pico_stdlib) - -# Add the standard include files to the build -target_include_directories(0x0008_uninitialized-variables-b PRIVATE - ${CMAKE_CURRENT_LIST_DIR} -) - -pico_add_extra_outputs(0x0008_uninitialized-variables-b) - diff --git a/0x0008_uninitialized-variables-b/pico_sdk_import.cmake b/0x0008_uninitialized-variables-b/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x0008_uninitialized-variables-b/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x0008_uninitialized-variables-c/.gitignore b/0x0008_uninitialized-variables-c/.gitignore deleted file mode 100644 index 2435c20..0000000 --- a/0x0008_uninitialized-variables-c/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -!.vscode/* diff --git a/0x0008_uninitialized-variables-c/.vscode/c_cpp_properties.json b/0x0008_uninitialized-variables-c/.vscode/c_cpp_properties.json deleted file mode 100644 index e80461d..0000000 --- a/0x0008_uninitialized-variables-c/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "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 -} diff --git a/0x0008_uninitialized-variables-c/.vscode/cmake-kits.json b/0x0008_uninitialized-variables-c/.vscode/cmake-kits.json deleted file mode 100644 index b0f3815..0000000 --- a/0x0008_uninitialized-variables-c/.vscode/cmake-kits.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "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}" - } - } -] \ No newline at end of file diff --git a/0x0008_uninitialized-variables-c/.vscode/extensions.json b/0x0008_uninitialized-variables-c/.vscode/extensions.json deleted file mode 100644 index a940d7c..0000000 --- a/0x0008_uninitialized-variables-c/.vscode/extensions.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "recommendations": [ - "marus25.cortex-debug", - "ms-vscode.cpptools", - "ms-vscode.cpptools-extension-pack", - "ms-vscode.vscode-serial-monitor", - "raspberry-pi.raspberry-pi-pico" - ] -} \ No newline at end of file diff --git a/0x0008_uninitialized-variables-c/.vscode/launch.json b/0x0008_uninitialized-variables-c/.vscode/launch.json deleted file mode 100644 index 424aa71..0000000 --- a/0x0008_uninitialized-variables-c/.vscode/launch.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "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}\"" - ] - }, - ] -} diff --git a/0x0008_uninitialized-variables-c/.vscode/settings.json b/0x0008_uninitialized-variables-c/.vscode/settings.json deleted file mode 100644 index cdb8e61..0000000 --- a/0x0008_uninitialized-variables-c/.vscode/settings.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "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" -} diff --git a/0x0008_uninitialized-variables-c/.vscode/tasks.json b/0x0008_uninitialized-variables-c/.vscode/tasks.json deleted file mode 100644 index f427bf0..0000000 --- a/0x0008_uninitialized-variables-c/.vscode/tasks.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Compile Project", - "type": "process", - "isBuildCommand": true, - "command": "${userHome}/.pico-sdk/ninja/v1.12.1/ninja", - "args": ["-C", "${workspaceFolder}/build"], - "group": "build", - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": "$gcc", - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/ninja/v1.12.1/ninja.exe" - } - }, - { - "label": "Run Project", - "type": "process", - "command": "${env:HOME}/.pico-sdk/picotool/2.2.0/picotool/picotool", - "args": [ - "load", - "${command:raspberry-pi-pico.launchTargetPath}", - "-fx" - ], - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/picotool/2.2.0/picotool/picotool.exe" - } - }, - { - "label": "Flash", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/${command:raspberry-pi-pico.getTarget}.cfg", - "-c", - "adapter speed 5000; program \"${command:raspberry-pi-pico.launchTargetPath}\" verify reset exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - }, - { - "label": "Rescue Reset", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/${command:raspberry-pi-pico.getChip}-rescue.cfg", - "-c", - "adapter speed 5000; reset halt; exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - }, - { - "label": "Risc-V Reset (RP2350)", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-c", - "set USE_CORE { rv0 rv1 cm0 cm1 }", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/rp2350.cfg", - "-c", - "adapter speed 5000; init;", - "-c", - "write_memory 0x40120158 8 { 0x3 }; echo [format \"Info : ARCHSEL 0x%02x\" [read_memory 0x40120158 8 1]];", - "-c", - "reset halt; targets rp2350.rv0; echo [format \"Info : ARCHSEL_STATUS 0x%02x\" [read_memory 0x4012015C 8 1]]; exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - } - ] -} diff --git a/0x0008_uninitialized-variables-c/0x0008_uninitialized-variables-c.c b/0x0008_uninitialized-variables-c/0x0008_uninitialized-variables-c.c deleted file mode 100644 index 5136c35..0000000 --- a/0x0008_uninitialized-variables-c/0x0008_uninitialized-variables-c.c +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include "pico/stdlib.h" - -#define LED_PIN 16 - -int main(void) -{ - // gpio_init(LED_PIN); - /// gpio_set_dir(LED_PIN, GPIO_IN); - gpioc_bit_oe_put(LED_PIN, GPIO_OUT); - /// gpio_put(LED_PIN, 0); - gpioc_bit_out_put(LED_PIN, 0); - /// gpio_set_function(LED_PIN, GPIO_FUNC_SIO); - hw_write_masked(&pads_bank0_hw->io[LED_PIN], - PADS_BANK0_GPIO0_IE_BITS, - PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS - ); - io_bank0_hw->io[LED_PIN].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB; - hw_clear_bits(&pads_bank0_hw->io[LED_PIN], PADS_BANK0_GPIO0_ISO_BITS); - - // gpio_set_dir(LED_PIN, GPIO_OUT); - gpioc_bit_oe_put(LED_PIN, GPIO_OUT); - - while (true) { - // gpio_put(LED_PIN, 1); - gpioc_bit_out_put(LED_PIN, 1); - // sleep_ms(500); - sleep_us(500 * 1000ull); - - // gpio_put(LED_PIN, 0); - gpioc_bit_out_put(LED_PIN, 0); - // sleep_ms(500); - sleep_us(500 * 1000ull); - } -} diff --git a/0x0008_uninitialized-variables-c/CMakeLists.txt b/0x0008_uninitialized-variables-c/CMakeLists.txt deleted file mode 100644 index b7e1991..0000000 --- a/0x0008_uninitialized-variables-c/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# 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(0x0008_uninitialized-variables-c 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(0x0008_uninitialized-variables-c 0x0008_uninitialized-variables-c.c ) - -pico_set_program_name(0x0008_uninitialized-variables-c "0x0008_uninitialized-variables-c") -pico_set_program_version(0x0008_uninitialized-variables-c "0.1") - -# Modify the below lines to enable/disable output over UART/USB -pico_enable_stdio_uart(0x0008_uninitialized-variables-c 0) -pico_enable_stdio_usb(0x0008_uninitialized-variables-c 0) - -# Add the standard library to the build -target_link_libraries(0x0008_uninitialized-variables-c - pico_stdlib) - -# Add the standard include files to the build -target_include_directories(0x0008_uninitialized-variables-c PRIVATE - ${CMAKE_CURRENT_LIST_DIR} -) - -pico_add_extra_outputs(0x0008_uninitialized-variables-c) - diff --git a/0x0008_uninitialized-variables-c/pico_sdk_import.cmake b/0x0008_uninitialized-variables-c/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x0008_uninitialized-variables-c/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x0008_uninitialized-variables-d/.gitignore b/0x0008_uninitialized-variables-d/.gitignore deleted file mode 100644 index 2435c20..0000000 --- a/0x0008_uninitialized-variables-d/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -!.vscode/* diff --git a/0x0008_uninitialized-variables-d/.vscode/c_cpp_properties.json b/0x0008_uninitialized-variables-d/.vscode/c_cpp_properties.json deleted file mode 100644 index e80461d..0000000 --- a/0x0008_uninitialized-variables-d/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "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 -} diff --git a/0x0008_uninitialized-variables-d/.vscode/cmake-kits.json b/0x0008_uninitialized-variables-d/.vscode/cmake-kits.json deleted file mode 100644 index b0f3815..0000000 --- a/0x0008_uninitialized-variables-d/.vscode/cmake-kits.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "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}" - } - } -] \ No newline at end of file diff --git a/0x0008_uninitialized-variables-d/.vscode/extensions.json b/0x0008_uninitialized-variables-d/.vscode/extensions.json deleted file mode 100644 index a940d7c..0000000 --- a/0x0008_uninitialized-variables-d/.vscode/extensions.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "recommendations": [ - "marus25.cortex-debug", - "ms-vscode.cpptools", - "ms-vscode.cpptools-extension-pack", - "ms-vscode.vscode-serial-monitor", - "raspberry-pi.raspberry-pi-pico" - ] -} \ No newline at end of file diff --git a/0x0008_uninitialized-variables-d/.vscode/launch.json b/0x0008_uninitialized-variables-d/.vscode/launch.json deleted file mode 100644 index 424aa71..0000000 --- a/0x0008_uninitialized-variables-d/.vscode/launch.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "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}\"" - ] - }, - ] -} diff --git a/0x0008_uninitialized-variables-d/.vscode/settings.json b/0x0008_uninitialized-variables-d/.vscode/settings.json deleted file mode 100644 index cdb8e61..0000000 --- a/0x0008_uninitialized-variables-d/.vscode/settings.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "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" -} diff --git a/0x0008_uninitialized-variables-d/.vscode/tasks.json b/0x0008_uninitialized-variables-d/.vscode/tasks.json deleted file mode 100644 index f427bf0..0000000 --- a/0x0008_uninitialized-variables-d/.vscode/tasks.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Compile Project", - "type": "process", - "isBuildCommand": true, - "command": "${userHome}/.pico-sdk/ninja/v1.12.1/ninja", - "args": ["-C", "${workspaceFolder}/build"], - "group": "build", - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": "$gcc", - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/ninja/v1.12.1/ninja.exe" - } - }, - { - "label": "Run Project", - "type": "process", - "command": "${env:HOME}/.pico-sdk/picotool/2.2.0/picotool/picotool", - "args": [ - "load", - "${command:raspberry-pi-pico.launchTargetPath}", - "-fx" - ], - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/picotool/2.2.0/picotool/picotool.exe" - } - }, - { - "label": "Flash", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/${command:raspberry-pi-pico.getTarget}.cfg", - "-c", - "adapter speed 5000; program \"${command:raspberry-pi-pico.launchTargetPath}\" verify reset exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - }, - { - "label": "Rescue Reset", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/${command:raspberry-pi-pico.getChip}-rescue.cfg", - "-c", - "adapter speed 5000; reset halt; exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - }, - { - "label": "Risc-V Reset (RP2350)", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-c", - "set USE_CORE { rv0 rv1 cm0 cm1 }", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/rp2350.cfg", - "-c", - "adapter speed 5000; init;", - "-c", - "write_memory 0x40120158 8 { 0x3 }; echo [format \"Info : ARCHSEL 0x%02x\" [read_memory 0x40120158 8 1]];", - "-c", - "reset halt; targets rp2350.rv0; echo [format \"Info : ARCHSEL_STATUS 0x%02x\" [read_memory 0x4012015C 8 1]]; exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - } - ] -} diff --git a/0x0008_uninitialized-variables-d/0x0008_uninitialized-variables-d.c b/0x0008_uninitialized-variables-d/0x0008_uninitialized-variables-d.c deleted file mode 100644 index 457ed9a..0000000 --- a/0x0008_uninitialized-variables-d/0x0008_uninitialized-variables-d.c +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include "pico/stdlib.h" - -#define LED_PIN 16 - -int main(void) -{ - // gpio_init(LED_PIN); - /// gpio_set_dir(LED_PIN, GPIO_IN); - //// gpioc_bit_oe_put(LED_PIN, GPIO_OUT); - pico_default_asm_volatile ("mcrr p0, #4, %0, %1, c4" : : "r" (LED_PIN), "r" (GPIO_OUT)); - /// gpio_put(LED_PIN, 0); - //// gpioc_bit_out_put(LED_PIN, 0); - pico_default_asm_volatile ("mcrr p0, #4, %0, %1, c4" : : "r" (LED_PIN), "r" (GPIO_OUT)); - /// gpio_set_function(LED_PIN, GPIO_FUNC_SIO); - //// hw_write_masked(&pads_bank0_hw->io[LED_PIN], - //// PADS_BANK0_GPIO0_IE_BITS, - //// PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS - //// ); - //// hw_xor_bits(addr, (*addr ^ values) & write_mask); - pico_default_asm_volatile ( - "ldr r2, [%0]\n" // load current pad register - "eor r2, r2, %1\n" // xor with IE bit - "and r2, r2, %2\n" // mask with (IE|OD) - "eor r2, r2, %1\n" // recombine (hw_xor_bits logic) - "str r2, [%0]\n" // write back - : - : "r" (&pads_bank0_hw->io[LED_PIN]), - "r" (PADS_BANK0_GPIO0_IE_BITS), - "r" (PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS) - : "r2", "memory" - ); - - /// io_bank0_hw->io[LED_PIN].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB; - pico_default_asm_volatile ( - "str %1, [%0]\n" - : - : "r" (&io_bank0_hw->io[LED_PIN].ctrl), - "r" (GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB) - : "memory" - ); - /// hw_clear_bits(&pads_bank0_hw->io[LED_PIN], PADS_BANK0_GPIO0_ISO_BITS); - pico_default_asm_volatile ( - "ldr r2, [%0]\n" // load current register value - "bic r2, r2, %1\n" // clear the ISO bits (bit clear) - "str r2, [%0]\n" // write back - : - : "r" (&pads_bank0_hw->io[LED_PIN]), - "r" (PADS_BANK0_GPIO0_ISO_BITS) - : "r2", "memory" - ); - - // gpio_set_dir(LED_PIN, GPIO_OUT); - /// gpioc_bit_oe_put(LED_PIN, GPIO_OUT); - pico_default_asm_volatile ("mcrr p0, #4, %0, %1, c4" : : "r" (LED_PIN), "r" (GPIO_OUT)); - - while (true) { - // gpio_put(LED_PIN, 1); - /// gpioc_bit_out_put(LED_PIN, 1); - pico_default_asm_volatile ("mcrr p0, #4, %0, %1, c0" : : "r" (LED_PIN), "r" (1)); - /// sleep_ms(500); - sleep_us(500 * 1000ull); - - // gpio_put(LED_PIN, 0); - /// gpioc_bit_out_put(LED_PIN, 0); - pico_default_asm_volatile ("mcrr p0, #4, %0, %1, c0" : : "r" (LED_PIN), "r" (0)); - /// sleep_ms(500); - sleep_us(500 * 1000ull); - } -} diff --git a/0x0008_uninitialized-variables-d/CMakeLists.txt b/0x0008_uninitialized-variables-d/CMakeLists.txt deleted file mode 100644 index 9e88754..0000000 --- a/0x0008_uninitialized-variables-d/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# 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(0x0008_uninitialized-variables-d 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(0x0008_uninitialized-variables-d 0x0008_uninitialized-variables-d.c ) - -pico_set_program_name(0x0008_uninitialized-variables-d "0x0008_uninitialized-variables-d") -pico_set_program_version(0x0008_uninitialized-variables-d "0.1") - -# Modify the below lines to enable/disable output over UART/USB -pico_enable_stdio_uart(0x0008_uninitialized-variables-d 0) -pico_enable_stdio_usb(0x0008_uninitialized-variables-d 0) - -# Add the standard library to the build -target_link_libraries(0x0008_uninitialized-variables-d - pico_stdlib) - -# Add the standard include files to the build -target_include_directories(0x0008_uninitialized-variables-d PRIVATE - ${CMAKE_CURRENT_LIST_DIR} -) - -pico_add_extra_outputs(0x0008_uninitialized-variables-d) - diff --git a/0x0008_uninitialized-variables-d/pico_sdk_import.cmake b/0x0008_uninitialized-variables-d/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x0008_uninitialized-variables-d/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x0008_uninitialized-variables-e/.gitignore b/0x0008_uninitialized-variables-e/.gitignore deleted file mode 100644 index 2435c20..0000000 --- a/0x0008_uninitialized-variables-e/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -!.vscode/* diff --git a/0x0008_uninitialized-variables-e/.vscode/c_cpp_properties.json b/0x0008_uninitialized-variables-e/.vscode/c_cpp_properties.json deleted file mode 100644 index e80461d..0000000 --- a/0x0008_uninitialized-variables-e/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "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 -} diff --git a/0x0008_uninitialized-variables-e/.vscode/cmake-kits.json b/0x0008_uninitialized-variables-e/.vscode/cmake-kits.json deleted file mode 100644 index b0f3815..0000000 --- a/0x0008_uninitialized-variables-e/.vscode/cmake-kits.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "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}" - } - } -] \ No newline at end of file diff --git a/0x0008_uninitialized-variables-e/.vscode/extensions.json b/0x0008_uninitialized-variables-e/.vscode/extensions.json deleted file mode 100644 index a940d7c..0000000 --- a/0x0008_uninitialized-variables-e/.vscode/extensions.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "recommendations": [ - "marus25.cortex-debug", - "ms-vscode.cpptools", - "ms-vscode.cpptools-extension-pack", - "ms-vscode.vscode-serial-monitor", - "raspberry-pi.raspberry-pi-pico" - ] -} \ No newline at end of file diff --git a/0x0008_uninitialized-variables-e/.vscode/launch.json b/0x0008_uninitialized-variables-e/.vscode/launch.json deleted file mode 100644 index 424aa71..0000000 --- a/0x0008_uninitialized-variables-e/.vscode/launch.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "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}\"" - ] - }, - ] -} diff --git a/0x0008_uninitialized-variables-e/.vscode/settings.json b/0x0008_uninitialized-variables-e/.vscode/settings.json deleted file mode 100644 index cdb8e61..0000000 --- a/0x0008_uninitialized-variables-e/.vscode/settings.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "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" -} diff --git a/0x0008_uninitialized-variables-e/.vscode/tasks.json b/0x0008_uninitialized-variables-e/.vscode/tasks.json deleted file mode 100644 index f427bf0..0000000 --- a/0x0008_uninitialized-variables-e/.vscode/tasks.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Compile Project", - "type": "process", - "isBuildCommand": true, - "command": "${userHome}/.pico-sdk/ninja/v1.12.1/ninja", - "args": ["-C", "${workspaceFolder}/build"], - "group": "build", - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": "$gcc", - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/ninja/v1.12.1/ninja.exe" - } - }, - { - "label": "Run Project", - "type": "process", - "command": "${env:HOME}/.pico-sdk/picotool/2.2.0/picotool/picotool", - "args": [ - "load", - "${command:raspberry-pi-pico.launchTargetPath}", - "-fx" - ], - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/picotool/2.2.0/picotool/picotool.exe" - } - }, - { - "label": "Flash", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/${command:raspberry-pi-pico.getTarget}.cfg", - "-c", - "adapter speed 5000; program \"${command:raspberry-pi-pico.launchTargetPath}\" verify reset exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - }, - { - "label": "Rescue Reset", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/${command:raspberry-pi-pico.getChip}-rescue.cfg", - "-c", - "adapter speed 5000; reset halt; exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - }, - { - "label": "Risc-V Reset (RP2350)", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-c", - "set USE_CORE { rv0 rv1 cm0 cm1 }", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/rp2350.cfg", - "-c", - "adapter speed 5000; init;", - "-c", - "write_memory 0x40120158 8 { 0x3 }; echo [format \"Info : ARCHSEL 0x%02x\" [read_memory 0x40120158 8 1]];", - "-c", - "reset halt; targets rp2350.rv0; echo [format \"Info : ARCHSEL_STATUS 0x%02x\" [read_memory 0x4012015C 8 1]]; exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - } - ] -} diff --git a/0x0008_uninitialized-variables-e/0x0008_uninitialized-variables-e.c b/0x0008_uninitialized-variables-e/0x0008_uninitialized-variables-e.c deleted file mode 100644 index 5dba746..0000000 --- a/0x0008_uninitialized-variables-e/0x0008_uninitialized-variables-e.c +++ /dev/null @@ -1,69 +0,0 @@ -int main(void) { - __asm__ volatile ( - // gpio_init(LED_PIN); - /// gpio_set_dir(LED_PIN, GPIO_IN); - //// gpioc_bit_oe_put(LED_PIN, GPIO_OUT); - "movs r4, #0x10\n" // GPIO16 - "movs r5, #0x01\n" // bit 1; used for OUT/OE writes - "mcrr p0, #4, r4, r5, c4\n" // gpioc_bit_oe_put(16, 1); p102 - - // gpio_set_function(LED_PIN, GPIO_FUNC_SIO); - /// hw_write_masked(&pads_bank0_hw->io[LED_PIN], - /// PADS_BANK0_GPIO0_IE_BITS, - /// PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS - /// ); - //// hw_xor_bits(addr, (*addr ^ values) & write_mask); - "ldr r3, =0x40038044\n" // &pads_bank0_hw->io[16]; p785, p796 - "ldr r2, [r3]\n" // load current config - "bic r2, r2, #0x80\n" // clear OD; output disable - "orr r2, r2, #0x40\n" // set IE; enable input buffer - "str r2, [r3]\n" // store updated config - /// io_bank0_hw->io[LED_PIN].ctrl = GPIO_FUNC_SIO << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB; - "ldr r3, =0x40028084\n" // &io_bank0_hw->io[16].ctrl; p603, p637 - "ldr r2, [r3]\n" // load current config - "bic r2, r2, #0x1f\n" // clear FUNCSEL bits [4:0] - "orr r2, r2, #5\n" // set FUNCSEL = 5 (SIO) - "str r2, [r3]\n" // store updated config - /// hw_clear_bits(&pads_bank0_hw->io[gpio], PADS_BANK0_GPIO0_ISO_BITS); - "ldr r3, =0x40038044\n" // &pads_bank0_hw->io[16]; p785, p796 - "ldr r2, [r3]\n" // load current config - "bic r2, r2, #0x100\n" // clear ISO bit (bit 8) un‑isolate pad - "str r2, [r3]\n" // store updated config - - // gpio_set_dir(LED_PIN, GPIO_OUT); - /// gpioc_bit_oe_put(LED_PIN, GPIO_OUT); - "movs r4, #0x10\n" // GPIO16 - "movs r5, #0x01\n" // bit 1; used for OUT/OE writes - "mcrr p0, #4, r4, r5, c4\n" // gpioc_bit_oe_put(16, 1); p102 - - // while (true) - "1:\n" // loop start - - // gpio_put(LED_PIN, 1); - /// gpioc_bit_out_put(LED_PIN, 1); - "movs r4, #0x10\n" // GPIO16 - "movs r5, #0x01\n" // bit 1; used for OUT/OE writes - "mcrr p0, #4, r4, r5, c0\n" // gpioc_bit_out_put(16, 1) - // sleep_ms(500); - /// sleep_us(500 * 1000ull); - "ldr r2, =0x17D7840\n" // r2 = ~8.4M cycles - "2:\n" // delay loop - "subs r2, r2, #1\n" // decrement counter - "bne 2b\n" // repeat until zero - - // gpio_put(LED_PIN, 1); - /// gpioc_bit_out_put(LED_PIN, 1); - "movs r4, #0x10\n" // GPIO16 - "movs r5, #0x00\n" // bit 0; used for OUT/OE writes - "mcrr p0, #4, r4, r5, c0\n" // gpioc_bit_out_put(16, 0) - // sleep_ms(500); - /// sleep_us(500 * 1000ull); - "ldr r2, =0x17D7840\n" // r2 = ~8.4M cycles - "3:\n" // delay loop - "subs r2, r2, #1\n" // decrement counter - "bne 3b\n" // repeat until zero - - // jmp - "b 1b\n" // repeat forever - ); -} diff --git a/0x0008_uninitialized-variables-e/CMakeLists.txt b/0x0008_uninitialized-variables-e/CMakeLists.txt deleted file mode 100644 index bfc1c28..0000000 --- a/0x0008_uninitialized-variables-e/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# 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(0x0008_uninitialized-variables-e 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(0x0008_uninitialized-variables-e 0x0008_uninitialized-variables-e.c ) - -pico_set_program_name(0x0008_uninitialized-variables-e "0x0008_uninitialized-variables-e") -pico_set_program_version(0x0008_uninitialized-variables-e "0.1") - -# Modify the below lines to enable/disable output over UART/USB -pico_enable_stdio_uart(0x0008_uninitialized-variables-e 0) -pico_enable_stdio_usb(0x0008_uninitialized-variables-e 0) - -# Add the standard library to the build -target_link_libraries(0x0008_uninitialized-variables-e - pico_stdlib) - -# Add the standard include files to the build -target_include_directories(0x0008_uninitialized-variables-e PRIVATE - ${CMAKE_CURRENT_LIST_DIR} -) - -pico_add_extra_outputs(0x0008_uninitialized-variables-e) - diff --git a/0x0008_uninitialized-variables-e/pico_sdk_import.cmake b/0x0008_uninitialized-variables-e/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x0008_uninitialized-variables-e/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x0008_uninitialized-variables/.gitignore b/0x0008_uninitialized-variables/.gitignore deleted file mode 100644 index 2435c20..0000000 --- a/0x0008_uninitialized-variables/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -!.vscode/* diff --git a/0x0008_uninitialized-variables/.vscode/c_cpp_properties.json b/0x0008_uninitialized-variables/.vscode/c_cpp_properties.json deleted file mode 100644 index e80461d..0000000 --- a/0x0008_uninitialized-variables/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "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 -} diff --git a/0x0008_uninitialized-variables/.vscode/cmake-kits.json b/0x0008_uninitialized-variables/.vscode/cmake-kits.json deleted file mode 100644 index b0f3815..0000000 --- a/0x0008_uninitialized-variables/.vscode/cmake-kits.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "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}" - } - } -] \ No newline at end of file diff --git a/0x0008_uninitialized-variables/.vscode/extensions.json b/0x0008_uninitialized-variables/.vscode/extensions.json deleted file mode 100644 index a940d7c..0000000 --- a/0x0008_uninitialized-variables/.vscode/extensions.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "recommendations": [ - "marus25.cortex-debug", - "ms-vscode.cpptools", - "ms-vscode.cpptools-extension-pack", - "ms-vscode.vscode-serial-monitor", - "raspberry-pi.raspberry-pi-pico" - ] -} \ No newline at end of file diff --git a/0x0008_uninitialized-variables/.vscode/launch.json b/0x0008_uninitialized-variables/.vscode/launch.json deleted file mode 100644 index 424aa71..0000000 --- a/0x0008_uninitialized-variables/.vscode/launch.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "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}\"" - ] - }, - ] -} diff --git a/0x0008_uninitialized-variables/.vscode/settings.json b/0x0008_uninitialized-variables/.vscode/settings.json deleted file mode 100644 index 4e5d7b6..0000000 --- a/0x0008_uninitialized-variables/.vscode/settings.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "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": { - "addressmap.h": "c", - "resets.h": "c", - "pads_bank0.h": "c" - } -} diff --git a/0x0008_uninitialized-variables/.vscode/tasks.json b/0x0008_uninitialized-variables/.vscode/tasks.json deleted file mode 100644 index f427bf0..0000000 --- a/0x0008_uninitialized-variables/.vscode/tasks.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Compile Project", - "type": "process", - "isBuildCommand": true, - "command": "${userHome}/.pico-sdk/ninja/v1.12.1/ninja", - "args": ["-C", "${workspaceFolder}/build"], - "group": "build", - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": "$gcc", - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/ninja/v1.12.1/ninja.exe" - } - }, - { - "label": "Run Project", - "type": "process", - "command": "${env:HOME}/.pico-sdk/picotool/2.2.0/picotool/picotool", - "args": [ - "load", - "${command:raspberry-pi-pico.launchTargetPath}", - "-fx" - ], - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/picotool/2.2.0/picotool/picotool.exe" - } - }, - { - "label": "Flash", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/${command:raspberry-pi-pico.getTarget}.cfg", - "-c", - "adapter speed 5000; program \"${command:raspberry-pi-pico.launchTargetPath}\" verify reset exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - }, - { - "label": "Rescue Reset", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/${command:raspberry-pi-pico.getChip}-rescue.cfg", - "-c", - "adapter speed 5000; reset halt; exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - }, - { - "label": "Risc-V Reset (RP2350)", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-c", - "set USE_CORE { rv0 rv1 cm0 cm1 }", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/rp2350.cfg", - "-c", - "adapter speed 5000; init;", - "-c", - "write_memory 0x40120158 8 { 0x3 }; echo [format \"Info : ARCHSEL 0x%02x\" [read_memory 0x40120158 8 1]];", - "-c", - "reset halt; targets rp2350.rv0; echo [format \"Info : ARCHSEL_STATUS 0x%02x\" [read_memory 0x4012015C 8 1]]; exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - } - ] -} diff --git a/0x0008_uninitialized-variables/0x0008_uninitialized-variables.c b/0x0008_uninitialized-variables/0x0008_uninitialized-variables.c deleted file mode 100644 index 0c94677..0000000 --- a/0x0008_uninitialized-variables/0x0008_uninitialized-variables.c +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include "pico/stdlib.h" - -#define LED_PIN 16 - -int main(void) { - uint8_t age; - - stdio_init_all(); - - gpio_init(LED_PIN); - gpio_set_dir(LED_PIN, GPIO_OUT); - - while (true) { - printf("age: %d\r\n", age); - - gpio_put(LED_PIN, 1); - sleep_ms(500); - - gpio_put(LED_PIN, 0); - sleep_ms(500); - } -} diff --git a/0x0008_uninitialized-variables/CMakeLists.txt b/0x0008_uninitialized-variables/CMakeLists.txt deleted file mode 100644 index c2ac591..0000000 --- a/0x0008_uninitialized-variables/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# 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(0x0008_uninitialized-variables 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(0x0008_uninitialized-variables 0x0008_uninitialized-variables.c ) - -pico_set_program_name(0x0008_uninitialized-variables "0x0008_uninitialized-variables") -pico_set_program_version(0x0008_uninitialized-variables "0.1") - -# Modify the below lines to enable/disable output over UART/USB -pico_enable_stdio_uart(0x0008_uninitialized-variables 1) -pico_enable_stdio_usb(0x0008_uninitialized-variables 0) - -# Add the standard library to the build -target_link_libraries(0x0008_uninitialized-variables - pico_stdlib) - -# Add the standard include files to the build -target_include_directories(0x0008_uninitialized-variables PRIVATE - ${CMAKE_CURRENT_LIST_DIR} -) - -pico_add_extra_outputs(0x0008_uninitialized-variables) - diff --git a/0x0008_uninitialized-variables/pico_sdk_import.cmake b/0x0008_uninitialized-variables/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x0008_uninitialized-variables/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x000b_integer-data-type/.gitignore b/0x000b_integer-data-type/.gitignore deleted file mode 100644 index 2435c20..0000000 --- a/0x000b_integer-data-type/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -!.vscode/* diff --git a/0x000b_integer-data-type/.vscode/c_cpp_properties.json b/0x000b_integer-data-type/.vscode/c_cpp_properties.json deleted file mode 100644 index e80461d..0000000 --- a/0x000b_integer-data-type/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "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 -} diff --git a/0x000b_integer-data-type/.vscode/cmake-kits.json b/0x000b_integer-data-type/.vscode/cmake-kits.json deleted file mode 100644 index b0f3815..0000000 --- a/0x000b_integer-data-type/.vscode/cmake-kits.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "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}" - } - } -] \ No newline at end of file diff --git a/0x000b_integer-data-type/.vscode/extensions.json b/0x000b_integer-data-type/.vscode/extensions.json deleted file mode 100644 index a940d7c..0000000 --- a/0x000b_integer-data-type/.vscode/extensions.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "recommendations": [ - "marus25.cortex-debug", - "ms-vscode.cpptools", - "ms-vscode.cpptools-extension-pack", - "ms-vscode.vscode-serial-monitor", - "raspberry-pi.raspberry-pi-pico" - ] -} \ No newline at end of file diff --git a/0x000b_integer-data-type/.vscode/launch.json b/0x000b_integer-data-type/.vscode/launch.json deleted file mode 100644 index 424aa71..0000000 --- a/0x000b_integer-data-type/.vscode/launch.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "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}\"" - ] - }, - ] -} diff --git a/0x000b_integer-data-type/.vscode/settings.json b/0x000b_integer-data-type/.vscode/settings.json deleted file mode 100644 index cdb8e61..0000000 --- a/0x000b_integer-data-type/.vscode/settings.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "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" -} diff --git a/0x000b_integer-data-type/.vscode/tasks.json b/0x000b_integer-data-type/.vscode/tasks.json deleted file mode 100644 index f427bf0..0000000 --- a/0x000b_integer-data-type/.vscode/tasks.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Compile Project", - "type": "process", - "isBuildCommand": true, - "command": "${userHome}/.pico-sdk/ninja/v1.12.1/ninja", - "args": ["-C", "${workspaceFolder}/build"], - "group": "build", - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": "$gcc", - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/ninja/v1.12.1/ninja.exe" - } - }, - { - "label": "Run Project", - "type": "process", - "command": "${env:HOME}/.pico-sdk/picotool/2.2.0/picotool/picotool", - "args": [ - "load", - "${command:raspberry-pi-pico.launchTargetPath}", - "-fx" - ], - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/picotool/2.2.0/picotool/picotool.exe" - } - }, - { - "label": "Flash", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/${command:raspberry-pi-pico.getTarget}.cfg", - "-c", - "adapter speed 5000; program \"${command:raspberry-pi-pico.launchTargetPath}\" verify reset exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - }, - { - "label": "Rescue Reset", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/${command:raspberry-pi-pico.getChip}-rescue.cfg", - "-c", - "adapter speed 5000; reset halt; exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - }, - { - "label": "Risc-V Reset (RP2350)", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-c", - "set USE_CORE { rv0 rv1 cm0 cm1 }", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/rp2350.cfg", - "-c", - "adapter speed 5000; init;", - "-c", - "write_memory 0x40120158 8 { 0x3 }; echo [format \"Info : ARCHSEL 0x%02x\" [read_memory 0x40120158 8 1]];", - "-c", - "reset halt; targets rp2350.rv0; echo [format \"Info : ARCHSEL_STATUS 0x%02x\" [read_memory 0x4012015C 8 1]]; exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - } - ] -} diff --git a/0x000b_integer-data-type/0x000b_integer-data-type.c b/0x000b_integer-data-type/0x000b_integer-data-type.c deleted file mode 100644 index 6a0d6ab..0000000 --- a/0x000b_integer-data-type/0x000b_integer-data-type.c +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include "pico/stdlib.h" - -int main(void) { - uint8_t age = 43; - int8_t range = -42; - - stdio_init_all(); - - __asm volatile ( - "ldr r3, =0x40038000\n" // address of PADS_BANK0_BASE - "ldr r2, =0x40028004\n" // address of IO_BANK0 GPIO0.ctrl - "movs r0, #16\n" // GPIO16 (start pin) - - "init_loop:\n" // loop start - "lsls r1, r0, #2\n" // pin * 4 (pad offset) - "adds r4, r3, r1\n" // PADS base + offset - "ldr r5, [r4]\n" // load current config - "bic r5, r5, #0x180\n" // clear OD+ISO - "orr r5, r5, #0x40\n" // set IE - "str r5, [r4]\n" // store updated config - - "lsls r1, r0, #3\n" // pin * 8 (ctrl offset) - "adds r4, r2, r1\n" // IO_BANK0 base + offset - "ldr r5, [r4]\n" // load current config - "bic r5, r5, #0x1f\n" // clear FUNCSEL bits [4:0] - "orr r5, r5, #5\n" // set FUNCSEL = 5 (SIO) - "str r5, [r4]\n" // store updated config - - "mov r4, r0\n" // pin - "movs r5, #1\n" // bit 1; used for OUT/OE writes - "mcrr p0, #4, r4, r5, c4\n" // gpioc_bit_oe_put(pin,1) - "adds r0, r0, #1\n" // increment pin - "cmp r0, #20\n" // stop after pin 18 - "blt init_loop\n" // loop until r0 == 20 - ); - - uint8_t pin = 16; - - while (1) { - __asm volatile ( - "mov r4, %0\n" // pin - "movs r5, #0x01\n" // bit 1; used for OUT/OE writes - "mcrr p0, #4, r4, r5, c0\n" // gpioc_bit_out_put(16, 1) - : - : "r"(pin) - : "r4","r5" - ); - sleep_ms(500); - - __asm volatile ( - "mov r4, %0\n" // pin - "movs r5, #0\n" // bit 0; used for OUT/OE writes - "mcrr p0, #4, r4, r5, c0\n" // gpioc_bit_out_put(16, 0) - : - : "r"(pin) - : "r4","r5" - ); - sleep_ms(500); - - pin++; - if (pin > 18) pin = 16; - - printf("age: %d\r\n", age); - printf("range: %d\r\n", range); - } -} diff --git a/0x000b_integer-data-type/CMakeLists.txt b/0x000b_integer-data-type/CMakeLists.txt deleted file mode 100644 index 6178a2a..0000000 --- a/0x000b_integer-data-type/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# 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(0x000b_integer-data-type 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(0x000b_integer-data-type 0x000b_integer-data-type.c ) - -pico_set_program_name(0x000b_integer-data-type "0x000b_integer-data-type") -pico_set_program_version(0x000b_integer-data-type "0.1") - -# Modify the below lines to enable/disable output over UART/USB -pico_enable_stdio_uart(0x000b_integer-data-type 1) -pico_enable_stdio_usb(0x000b_integer-data-type 0) - -# Add the standard library to the build -target_link_libraries(0x000b_integer-data-type - pico_stdlib) - -# Add the standard include files to the build -target_include_directories(0x000b_integer-data-type PRIVATE - ${CMAKE_CURRENT_LIST_DIR} -) - -pico_add_extra_outputs(0x000b_integer-data-type) - diff --git a/0x000b_integer-data-type/pico_sdk_import.cmake b/0x000b_integer-data-type/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x000b_integer-data-type/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x000e_floating-point-data-type/.gitignore b/0x000e_floating-point-data-type/.gitignore deleted file mode 100644 index 2435c20..0000000 --- a/0x000e_floating-point-data-type/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -!.vscode/* diff --git a/0x000e_floating-point-data-type/.vscode/c_cpp_properties.json b/0x000e_floating-point-data-type/.vscode/c_cpp_properties.json deleted file mode 100644 index e80461d..0000000 --- a/0x000e_floating-point-data-type/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "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 -} diff --git a/0x000e_floating-point-data-type/.vscode/cmake-kits.json b/0x000e_floating-point-data-type/.vscode/cmake-kits.json deleted file mode 100644 index b0f3815..0000000 --- a/0x000e_floating-point-data-type/.vscode/cmake-kits.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "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}" - } - } -] \ No newline at end of file diff --git a/0x000e_floating-point-data-type/.vscode/extensions.json b/0x000e_floating-point-data-type/.vscode/extensions.json deleted file mode 100644 index a940d7c..0000000 --- a/0x000e_floating-point-data-type/.vscode/extensions.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "recommendations": [ - "marus25.cortex-debug", - "ms-vscode.cpptools", - "ms-vscode.cpptools-extension-pack", - "ms-vscode.vscode-serial-monitor", - "raspberry-pi.raspberry-pi-pico" - ] -} \ No newline at end of file diff --git a/0x000e_floating-point-data-type/.vscode/launch.json b/0x000e_floating-point-data-type/.vscode/launch.json deleted file mode 100644 index 424aa71..0000000 --- a/0x000e_floating-point-data-type/.vscode/launch.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "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}\"" - ] - }, - ] -} diff --git a/0x000e_floating-point-data-type/.vscode/settings.json b/0x000e_floating-point-data-type/.vscode/settings.json deleted file mode 100644 index cdb8e61..0000000 --- a/0x000e_floating-point-data-type/.vscode/settings.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "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" -} diff --git a/0x000e_floating-point-data-type/.vscode/tasks.json b/0x000e_floating-point-data-type/.vscode/tasks.json deleted file mode 100644 index f427bf0..0000000 --- a/0x000e_floating-point-data-type/.vscode/tasks.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Compile Project", - "type": "process", - "isBuildCommand": true, - "command": "${userHome}/.pico-sdk/ninja/v1.12.1/ninja", - "args": ["-C", "${workspaceFolder}/build"], - "group": "build", - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": "$gcc", - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/ninja/v1.12.1/ninja.exe" - } - }, - { - "label": "Run Project", - "type": "process", - "command": "${env:HOME}/.pico-sdk/picotool/2.2.0/picotool/picotool", - "args": [ - "load", - "${command:raspberry-pi-pico.launchTargetPath}", - "-fx" - ], - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/picotool/2.2.0/picotool/picotool.exe" - } - }, - { - "label": "Flash", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/${command:raspberry-pi-pico.getTarget}.cfg", - "-c", - "adapter speed 5000; program \"${command:raspberry-pi-pico.launchTargetPath}\" verify reset exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - }, - { - "label": "Rescue Reset", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/${command:raspberry-pi-pico.getChip}-rescue.cfg", - "-c", - "adapter speed 5000; reset halt; exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - }, - { - "label": "Risc-V Reset (RP2350)", - "type": "process", - "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - "args": [ - "-s", - "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", - "-c", - "set USE_CORE { rv0 rv1 cm0 cm1 }", - "-f", - "interface/cmsis-dap.cfg", - "-f", - "target/rp2350.cfg", - "-c", - "adapter speed 5000; init;", - "-c", - "write_memory 0x40120158 8 { 0x3 }; echo [format \"Info : ARCHSEL 0x%02x\" [read_memory 0x40120158 8 1]];", - "-c", - "reset halt; targets rp2350.rv0; echo [format \"Info : ARCHSEL_STATUS 0x%02x\" [read_memory 0x4012015C 8 1]]; exit" - ], - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", - } - } - ] -} diff --git a/0x000e_floating-point-data-type/0x000e_floating-point-data-type.c b/0x000e_floating-point-data-type/0x000e_floating-point-data-type.c deleted file mode 100644 index fb3d382..0000000 --- a/0x000e_floating-point-data-type/0x000e_floating-point-data-type.c +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include "pico/stdlib.h" - -int main(void) { - float fav_num = 42.5; - - stdio_init_all(); - - while (true) - printf("fav_num: %f\r\n", fav_num); -} diff --git a/0x000e_floating-point-data-type/CMakeLists.txt b/0x000e_floating-point-data-type/CMakeLists.txt deleted file mode 100644 index 72041a0..0000000 --- a/0x000e_floating-point-data-type/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# 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(0x000e_floating-point-data-type 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(0x000e_floating-point-data-type 0x000e_floating-point-data-type.c ) - -pico_set_program_name(0x000e_floating-point-data-type "0x000e_floating-point-data-type") -pico_set_program_version(0x000e_floating-point-data-type "0.1") - -# Modify the below lines to enable/disable output over UART/USB -pico_enable_stdio_uart(0x000e_floating-point-data-type 1) -pico_enable_stdio_usb(0x000e_floating-point-data-type 0) - -# Add the standard library to the build -target_link_libraries(0x000e_floating-point-data-type - pico_stdlib) - -# Add the standard include files to the build -target_include_directories(0x000e_floating-point-data-type PRIVATE - ${CMAKE_CURRENT_LIST_DIR} -) - -pico_add_extra_outputs(0x000e_floating-point-data-type) - diff --git a/0x000e_floating-point-data-type/pico_sdk_import.cmake b/0x000e_floating-point-data-type/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x000e_floating-point-data-type/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x0011_double-floating-point-data-type/.gitignore b/0x0011_double-floating-point-data-type/.gitignore deleted file mode 100644 index 2435c20..0000000 --- a/0x0011_double-floating-point-data-type/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -!.vscode/* diff --git a/0x0011_double-floating-point-data-type/.vscode/c_cpp_properties.json b/0x0011_double-floating-point-data-type/.vscode/c_cpp_properties.json deleted file mode 100644 index c429d6d..0000000 --- a/0x0011_double-floating-point-data-type/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "configurations": [ - { - "name": "Pico", - "includePath": [ - "${workspaceFolder}/**", - "${userHome}/.pico-sdk/sdk/2.2.0/**" - ], - "forcedInclude": [ - "${workspaceFolder}/build/generated/pico_base/pico/config_autogen.h", - "${userHome}/.pico-sdk/sdk/2.2.0/src/common/pico_base_headers/include/pico.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 -} diff --git a/0x0011_double-floating-point-data-type/.vscode/cmake-kits.json b/0x0011_double-floating-point-data-type/.vscode/cmake-kits.json deleted file mode 100644 index b0f3815..0000000 --- a/0x0011_double-floating-point-data-type/.vscode/cmake-kits.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "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}" - } - } -] \ No newline at end of file diff --git a/0x0011_double-floating-point-data-type/.vscode/extensions.json b/0x0011_double-floating-point-data-type/.vscode/extensions.json deleted file mode 100644 index a940d7c..0000000 --- a/0x0011_double-floating-point-data-type/.vscode/extensions.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "recommendations": [ - "marus25.cortex-debug", - "ms-vscode.cpptools", - "ms-vscode.cpptools-extension-pack", - "ms-vscode.vscode-serial-monitor", - "raspberry-pi.raspberry-pi-pico" - ] -} \ No newline at end of file diff --git a/0x0011_double-floating-point-data-type/.vscode/launch.json b/0x0011_double-floating-point-data-type/.vscode/launch.json deleted file mode 100644 index 424aa71..0000000 --- a/0x0011_double-floating-point-data-type/.vscode/launch.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "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}\"" - ] - }, - ] -} diff --git a/0x0011_double-floating-point-data-type/.vscode/settings.json b/0x0011_double-floating-point-data-type/.vscode/settings.json deleted file mode 100644 index 95be83b..0000000 --- a/0x0011_double-floating-point-data-type/.vscode/settings.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "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" -} diff --git a/0x0011_double-floating-point-data-type/.vscode/tasks.json b/0x0011_double-floating-point-data-type/.vscode/tasks.json deleted file mode 100644 index 2359f7f..0000000 --- a/0x0011_double-floating-point-data-type/.vscode/tasks.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Compile Project", - "type": "process", - "isBuildCommand": true, - "command": "${userHome}/.pico-sdk/ninja/v1.12.1/ninja", - "args": ["-C", "${workspaceFolder}/build"], - "group": "build", - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": "$gcc", - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/ninja/v1.12.1/ninja.exe" - } - }, - { - "label": "Run Project", - "type": "process", - "command": "${env:HOME}/.pico-sdk/picotool/2.2.0-a4/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-a4/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", - } - } - ] -} diff --git a/0x0011_double-floating-point-data-type/0x0011_double-floating-point-data-type.c b/0x0011_double-floating-point-data-type/0x0011_double-floating-point-data-type.c deleted file mode 100644 index d4f3d11..0000000 --- a/0x0011_double-floating-point-data-type/0x0011_double-floating-point-data-type.c +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include "pico/stdlib.h" - -int main(void) { - double fav_num = 42.52525; - - stdio_init_all(); - - while (true) - printf("fav_num: %lf\r\n", fav_num); -} diff --git a/0x0011_double-floating-point-data-type/CMakeLists.txt b/0x0011_double-floating-point-data-type/CMakeLists.txt deleted file mode 100644 index 035b92e..0000000 --- a/0x0011_double-floating-point-data-type/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# 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-a4) -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(0x0011_double-floating-point-data-type 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(0x0011_double-floating-point-data-type 0x0011_double-floating-point-data-type.c ) - -pico_set_program_name(0x0011_double-floating-point-data-type "0x0011_double-floating-point-data-type") -pico_set_program_version(0x0011_double-floating-point-data-type "0.1") - -# Modify the below lines to enable/disable output over UART/USB -pico_enable_stdio_uart(0x0011_double-floating-point-data-type 1) -pico_enable_stdio_usb(0x0011_double-floating-point-data-type 0) - -# Add the standard library to the build -target_link_libraries(0x0011_double-floating-point-data-type - pico_stdlib) - -# Add the standard include files to the build -target_include_directories(0x0011_double-floating-point-data-type PRIVATE - ${CMAKE_CURRENT_LIST_DIR} -) - -pico_add_extra_outputs(0x0011_double-floating-point-data-type) - diff --git a/0x0011_double-floating-point-data-type/pico_sdk_import.cmake b/0x0011_double-floating-point-data-type/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x0011_double-floating-point-data-type/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x0011a_cb/.gitignore b/0x0011a_cb/.gitignore deleted file mode 100644 index 7bc658f..0000000 --- a/0x0011a_cb/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -build/ -.DS_Store -*.swp -*~ diff --git a/0x0011a_cb/0x0011a_cb.bin b/0x0011a_cb/0x0011a_cb.bin deleted file mode 100755 index 65ecf0b..0000000 Binary files a/0x0011a_cb/0x0011a_cb.bin and /dev/null differ diff --git a/0x0011a_cb/0x0011a_cb.uf2 b/0x0011a_cb/0x0011a_cb.uf2 deleted file mode 100644 index e356615..0000000 Binary files a/0x0011a_cb/0x0011a_cb.uf2 and /dev/null differ diff --git a/0x0011a_cb/0x0011a_cb_patched.bin b/0x0011a_cb/0x0011a_cb_patched.bin deleted file mode 100644 index d8a3de5..0000000 Binary files a/0x0011a_cb/0x0011a_cb_patched.bin and /dev/null differ diff --git a/0x0011a_cb/0x0011a_cb_patched.uf2 b/0x0011a_cb/0x0011a_cb_patched.uf2 deleted file mode 100644 index daf3c41..0000000 Binary files a/0x0011a_cb/0x0011a_cb_patched.uf2 and /dev/null differ diff --git a/0x0011a_cb/CLASSIFIED-BRIEF-0x01.md b/0x0011a_cb/CLASSIFIED-BRIEF-0x01.md deleted file mode 100644 index 43e3610..0000000 --- a/0x0011a_cb/CLASSIFIED-BRIEF-0x01.md +++ /dev/null @@ -1,159 +0,0 @@ -# Operation Dark Vector: Classified Intelligence Briefing - -``` -+-----------------------------------------------------------------+ -| TOP SECRET // NOFORN | -+-----------------------------------------------------------------+ -| | -|OPERATION DARK VECTOR | -| | -|CLASSIFIED BRIEFING: LIVE CHALLENGE 0x01 | -| | -|NATIONAL SECURITY AGENCY / GMU RHET | -+-----------------------------------------------------------------+ -``` - -## 1. The Advice - -INT. NSA EXPLOITATION CELL. 05:03. - -A carbon-fiber forward fuselage section of a downed state-sponsored autonomous -micro-UAV sits clamped in an anti-static fixture on the bench. - -On the front of the avionics bay, a status diode glows a steady red: `GP16` high. -Beside it, an I2C 1602 LCD backpack is wired to `GP2` and `GP3`, outputting -telemetry coordinates. A mock propeller servo is wired to `GP6`, a u-blox NEO-6M -GPS receiver is wired to PIO UART RX on `GP7`, and a REYAX RYLR998 LoRa transceiver -is wired to `UART1` on `GP8` and `GP9`. A thin jumper loops from `GP15` up to the -`3V3` rail. - -The Director sets down a field report and looks at the red diode. - -**DIRECTOR:** Where was it heading? - -**ANALYST:** Buddy says it knows. - -**DIRECTOR:** Buddy. - -**ANALYST:** The model. The one we built for automated firmware triage. Give it -the image, ask it the question. - -**DIRECTOR:** And? - -**ANALYST:** Nine seconds with the stripped flash image. - -She turns her monitor toward him. - -``` -+-----------------------------------------------------------------+ -| BUDDY // CLASSIFIED EXPLOITATION ASSIST // CONF: 0.98 | -+-----------------------------------------------------------------+ -| ACTION : Recover target waypoint coordinates. | -| MECHANISM : Literal pool constants in .rodata parsed. | -| PREDICTION : Destination is +38.840280, -77.428890. | -| CONFIDENCE : 0.98 | -+-----------------------------------------------------------------+ -``` - -**DIRECTOR:** 0.98. Centreville, Virginia. That is the whole answer. - -**ANALYST:** Buddy found the pre-programmed decoy coordinate in `.rodata`. Buddy -never looked at SRAM. Buddy never audited the cryptographic routine decrypting -the true mission target at boot. - -**DIRECTOR:** Buddy says 0.98. - -**ANALYST:** Buddy saw a float pair in Flash and stopped looking. If that drone -were flying to Centreville, it would not be broadcasting those exact coordinates -in plaintext telemetry for every SIGINT sensor in the sector to hear. - -## 2. What Buddy Is - -Buddy is not a person. It is a model. It has parsed more disassembled machine -code than any engineer on earth, and it speaks with total, unhesitating certainty. - -That certainty is lethal when tracking an adversary strike platform. - -Buddy scanned the flash image, spotted two IEEE-754 double-precision floating-point -constants matching geographic coordinates, and concluded that finding the floats -is the whole game. It extracted the numbers, declared the target solved, and moved -on. - -What Buddy failed to consider is that adversary weapons engineers anticipate -capture and forensic recovery. They do not hardcode high-value strategic targets -in plaintext Flash memory. A real drone stores decoy launch coordinates in Flash, -while encrypting its true destination under 128-bit AES. At power-on, firmware -decrypts the authentic waypoint directly into SRAM before engaging guidance. - -The plaintext coordinates in Flash are bait. Buddy took the bait. - -Buddy saw the floating-point constants. Buddy did not verify the ground truth. - -## 3. The Operation - -At 04:17, radar pickets tracked an adversary one-way micro-UAV descending into -the woods outside Centreville, Virginia after battery exhaustion. Technical -Intelligence operators recovered the airframe before adversary recovery forces -could zeroize the avionics. - -The flight computer is built around a bare-metal RP2350 (ARM Cortex-M33). There -are no debug symbols. There is no operating system. There is no SVD file to label -the registers. All you have is `0x0011a_cb.bin` mapped into Flash at `0x10000000`, -and the physical breadboard hardware in front of you. - -* **Pin 4 (`GP2`)**: I2C1 SDA (to 1602 LCD backpack). -* **Pin 5 (`GP3`)**: I2C1 SCL (to 1602 LCD backpack). -* **Pin 9 (`GP6`)**: SG90 servo PWM mock propeller blade. -* **Pin 10 (`GP7`)**: PIO UART RX (from u-blox NEO-6M GPS TXD). -* **Pin 11 (`GP8`)**: LoRa UART1 TX (to RYLR998 RXD). -* **Pin 12 (`GP9`)**: LoRa UART1 RX (from RYLR998 TXD). -* **Pin 20 (`GP15`)**: Mission telemetry sync trigger (pull-up to `3V3`). -* **Pin 21 (`GP16`)**: Red LED (`NO GNSS FIX // UNGUIDED SEARCH`). -* **Pin 22 (`GP17`)**: Green LED (`TARGET REACHED // PAYLOAD RELEASED`). -* **Pin 24 (`GP18`)**: Yellow LED (`SATELLITES ACQUIRED // 3D FIX LOCK`). -* **Pin 36 (`3V3`)**: 3.3V power rail (RYLR998 VDD and GPS VCC). -* **Pin 38 (`GND`)**: Ground reference. -* **Pin 40 (`VBUS`)**: 5V power rail (SG90 servo VCC and LCD power). - -Inside this image there is an AES-128 ECB decryption routine, an encrypted 16-byte -target coordinate block in `.rodata`, double-precision floating-point navigation -math, and dynamic GNSS state evaluation. Whatever coordinates actually steer the -aircraft are buried in the stripped ARM Thumb-2 machine code. - -## 4. The Mandate - -The Director crosses his arms. - -**DIRECTOR:** Prove Buddy right, or prove it wrong. - -**ANALYST:** I need thirty minutes with GDB and Ghidra. - -**DIRECTOR:** You have twenty. Reverse the boot sequence. Audit the memory -structures. Do not sign off on that flight path until you have extracted the true -target from silicon and verified it bit-for-bit. - -The orders are clear: - -1. **Disprove the Decoy Coordinates**: Locate the pre-programmed coordinates in - Flash and prove why they represent a decoy origin rather than the real target. -2. **Recover the AES-128 Key and Ciphertext**: Identify the 16-byte ciphertext - block and the 16-byte AES key embedded within `.rodata`. -3. **Decrypt the True Destination**: Reverse the boot decryption sequence and - compute the true target latitude and longitude in double-precision IEEE-754. -4. **Neutralize the Flight Plan**: Execute a verified exploit—either by mutating - the destination coordinates in SRAM via GDB or patching the binary in Flash. -5. **Verify the Hardware**: Transition the live breadboard from the Red LED on - `GP16` to the solid Green LED on `GP17` on physical silicon. - -A machine's 0.98 guess does not authorize an airstrike. - -## 5. The Challenge - -You have the image. You have the board. You have the tools and the time Buddy did -not need. - -Buddy has given you its answer, and it is confident. - -Is it that simple? - -Go find out. diff --git a/0x0011a_cb/CLASSIFIED-BRIEF-0x01.pdf b/0x0011a_cb/CLASSIFIED-BRIEF-0x01.pdf deleted file mode 100644 index d5bd238..0000000 Binary files a/0x0011a_cb/CLASSIFIED-BRIEF-0x01.pdf and /dev/null differ diff --git a/0x0011a_cb/CMakeLists.txt b/0x0011a_cb/CMakeLists.txt deleted file mode 100644 index 1467c8d..0000000 --- a/0x0011a_cb/CMakeLists.txt +++ /dev/null @@ -1,108 +0,0 @@ -# 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. -# -# Author: Kevin Thomas -# Email: kevin@mytechnotalent.com -# GitHub: https://github.com/mytechnotalent -# File: CMakeLists.txt -# Desc: Configures the RP2350 Pico SDK project for the Operation Dark Vector -# micro-UAV autonomous guidance firmware. -# Created: 2026 - -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-a4) -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(0x0011a_cb C CXX ASM) - -# Initialise the Raspberry Pi Pico SDK -pico_sdk_init() - -# Add executable with modular sources in src/ -add_executable(0x0011a_cb - src/main.c - src/gps.c - src/lora.c - src/propeller.c - src/payload.c - src/navigation.c - src/aes.c - src/lcd.c -) - -pico_set_program_name(0x0011a_cb "0x0011a_cb") -pico_set_program_version(0x0011a_cb "0.1") - -# Modify the below lines to enable/disable output over UART/USB -pico_enable_stdio_uart(0x0011a_cb 1) -pico_enable_stdio_usb(0x0011a_cb 0) -set(CTF_TARGET_LAT "38.881940" CACHE STRING "CTF target latitude (per-student randomized)") -set(CTF_TARGET_LON "-77.450280" CACHE STRING "CTF target longitude (per-student randomized)") - -target_compile_definitions(0x0011a_cb PRIVATE - PICO_DEFAULT_UART_BAUD_RATE=115200 - CTF_TARGET_LAT=${CTF_TARGET_LAT} - CTF_TARGET_LON=${CTF_TARGET_LON} -) - -# Generate PIO header -pico_generate_pio_header(0x0011a_cb ${CMAKE_CURRENT_LIST_DIR}/src/uart_rx.pio) - -# Add the standard library to the build -target_link_libraries(0x0011a_cb - pico_stdlib - hardware_uart - hardware_pio - hardware_pwm - hardware_i2c -) - -# Add the standard include files to the build -target_include_directories(0x0011a_cb PRIVATE - ${CMAKE_CURRENT_LIST_DIR}/include -) - -pico_add_extra_outputs(0x0011a_cb) diff --git a/0x0011a_cb/include/aes.h b/0x0011a_cb/include/aes.h deleted file mode 100644 index 43f55a8..0000000 --- a/0x0011a_cb/include/aes.h +++ /dev/null @@ -1,24 +0,0 @@ -// MIT License -// -// Copyright (c) 2026 Kevin Thomas -// -// File: aes.h -// Desc: Declares AES-128-ECB single-block decryption. -// Created: 2026 - -#ifndef AES_H -#define AES_H - -#include - -/** - * @brief Decrypt one 16-byte block with AES-128-ECB. - * - * @param in 16-byte ciphertext. - * @param key 16-byte key. - * @param out 16-byte plaintext output. - * @return None. - */ -void aes128_ecb_decrypt_block(const uint8_t in[16], const uint8_t key[16], uint8_t out[16]); - -#endif // AES_H diff --git a/0x0011a_cb/include/ctf_target.h b/0x0011a_cb/include/ctf_target.h deleted file mode 100644 index 40899c4..0000000 --- a/0x0011a_cb/include/ctf_target.h +++ /dev/null @@ -1,17 +0,0 @@ -// MIT License -// -// Copyright (c) 2026 Kevin Thomas -// -// File: ctf_target.h -// Desc: AES-128-ECB key and ciphertext for the real target waypoint. -// Created: 2026 - -#ifndef CTF_TARGET_H -#define CTF_TARGET_H - -#include - -#define CTF_AES_KEY { 0x56, 0x45, 0x43, 0x54, 0x4F, 0x52, 0x31, 0x31, 0x41, 0x45, 0x53, 0x4B, 0x45, 0x59, 0x21, 0x21 } -#define CTF_TARGET_CT { 0x20, 0x4F, 0xAC, 0xC2, 0xC0, 0x23, 0xEA, 0x7A, 0x3A, 0x93, 0x0F, 0x71, 0x11, 0x23, 0xEF, 0xCA } - -#endif // CTF_TARGET_H diff --git a/0x0011a_cb/include/gps.h b/0x0011a_cb/include/gps.h deleted file mode 100644 index 7a02193..0000000 --- a/0x0011a_cb/include/gps.h +++ /dev/null @@ -1,67 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: gps.h -// Desc: Declares PIO UART GPS receiver interface and NMEA parsing logic. -// Created: 2026 - -#ifndef GPS_H -#define GPS_H - -#include -#include "hardware/pio.h" - -#define GPS_PIN 7 -#define GPS_BAUD 9600 -#define GPS_PIO pio0 -#define GPS_SM 0 - -/** - * @brief Initialize PIO UART receiver on GPIO7 for u-blox NEO-6M GPS. - * - * @param None. - * @return None. - */ -void init_gps_pio(void); - -/** - * @brief Poll PIO RX FIFO and parse incoming NMEA GPS coordinates. - * - * @param lat Pointer to double storing updated latitude. - * @param lon Pointer to double storing updated longitude. - * @return bool True if a valid active 3D GPS fix (RMC 'A') was received, false otherwise. - */ -bool poll_gps(double *lat, double *lon); - -/** - * @brief Read latest GNSS signal statistics parsed from GSV sentences. - * - * @param siv Pointer to store satellites-in-view count. - * @param cno Pointer to store best carrier-to-noise ratio in dBHz. - * @return None. - */ -void gps_get_stats(int *siv, int *cno); - -#endif // GPS_H diff --git a/0x0011a_cb/include/lcd.h b/0x0011a_cb/include/lcd.h deleted file mode 100644 index 417cfd0..0000000 --- a/0x0011a_cb/include/lcd.h +++ /dev/null @@ -1,74 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: lcd.h -// Desc: Declares I2C HD44780 (16x2) LCD interface for telemetry coordinates. -// Created: 2026 - -#ifndef LCD_H -#define LCD_H - -#include -#include -#include "hardware/i2c.h" - -#define LCD_I2C_INST i2c1 -#define LCD_SDA_PIN 2 -#define LCD_SCL_PIN 3 -#define LCD_BAUD 100000 - -/** - * @brief Initialize I2C0 peripheral and detect/configure 1602 LCD backpack. - * - * @param None. - * @return None. - */ -void init_lcd(void); - -/** - * @brief Render current latitude and longitude on the 16x2 character display. - * - * Row 0: LAT: dd.dddddd N - * Row 1: LON: dd.dddddd W - * - * @param lat Current latitude in decimal degrees. - * @param lon Current longitude in decimal degrees. - * @return None. - */ -void lcd_show_coords(double lat, double lon); - -/** - * @brief Render GNSS acquisition telemetry (satellites and C/N0) on the LCD. - * - * Row 0: SAT: nn CNO: nn - * Row 1: ACQUIRING... when satellites are in view, else NO SIGNAL - * - * @param sats Number of satellites currently in view. - * @param cno Best carrier-to-noise ratio in dBHz. - * @return None. - */ -void lcd_show_gnss(int sats, int cno); - -#endif // LCD_H diff --git a/0x0011a_cb/include/lora.h b/0x0011a_cb/include/lora.h deleted file mode 100644 index dc037a5..0000000 --- a/0x0011a_cb/include/lora.h +++ /dev/null @@ -1,64 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: lora.h -// Desc: Declares UART1 interface for the REYAX RYLR998 LoRa transceiver. -// Created: 2026 - -#ifndef LORA_H -#define LORA_H - -#include "hardware/uart.h" - -#define LORA_UART uart1 -#define LORA_BAUD 9600 -#define LORA_TX_PIN 8 -#define LORA_RX_PIN 9 - -/** - * @brief Initialize LoRa transceiver over UART1 on GPIO8 and GPIO9 - * - * @param None. - * @return None. - */ -void init_lora(void); - -/** - * @brief Transmit string message over LoRa UART1 interface - * - * @param msg Null-terminated string buffer to transmit. - * @return None. - */ -void lora_send(const char *msg); - -/** - * @brief Service the LoRa UART: stream pending TX bytes and drain RX. - * - * @param None. - * @return None. - */ -void lora_tick(void); - -#endif // LORA_H diff --git a/0x0011a_cb/include/navigation.h b/0x0011a_cb/include/navigation.h deleted file mode 100644 index 676335c..0000000 --- a/0x0011a_cb/include/navigation.h +++ /dev/null @@ -1,87 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: navigation.h -// Desc: Declares autonomous guidance, dead-reckoning, and telemetry interface. -// Created: 2026 - -#ifndef NAVIGATION_H -#define NAVIGATION_H - -#include - -/** @brief Pre-programmed programmed decoy waypoint (Centreville, VA). */ -extern const double ORIGIN_LAT; -extern const double ORIGIN_LON; - -/** @brief Target coordinates, reconstructed at boot from masked constants. */ -extern double TARGET_LAT; -extern double TARGET_LON; - -/** - * @brief Reconstruct the target waypoint from its XOR-masked constants. - * - * @param None. - * @return None. - */ -void init_navigation(void); - -/** - * @brief Transmit telemetry stream over Debug UART0 and LoRa UART1. - * - * @param cur_lat Current micro-UAV latitude. - * @param cur_lon Current micro-UAV longitude. - * @return None. - */ -void send_telemetry(double cur_lat, double cur_lon); - -/** - * @brief Advance dead-reckoning position toward programmed waypoint. - * - * @param cur_lat Pointer to current latitude. - * @param cur_lon Pointer to current longitude. - * @return None. - */ -void dead_reckon_step(double *cur_lat, double *cur_lon); - -/** - * @brief Verify if micro-UAV has arrived at target coordinates. - * - * @param cur_lat Current latitude coordinate. - * @param cur_lon Current longitude coordinate. - * @return true if arrived at target, false otherwise. - */ -bool check_arrival(double cur_lat, double cur_lon); - -/** - * @brief Manage guidance progression, propeller oscillation, and payload release. - * - * @param cur_lat Current latitude coordinate. - * @param cur_lon Current longitude coordinate. - * @return None. - */ -void navigate_to_target(double cur_lat, double cur_lon); - -#endif // NAVIGATION_H diff --git a/0x0011a_cb/include/payload.h b/0x0011a_cb/include/payload.h deleted file mode 100644 index 14147fa..0000000 --- a/0x0011a_cb/include/payload.h +++ /dev/null @@ -1,68 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: payload.h -// Desc: Declares payload release mechanism interface on GPIO16. -// Created: 2026 - -#ifndef PAYLOAD_H -#define PAYLOAD_H - -#include - -#define LED_RED_PIN 16 -#define LED_GREEN_PIN 17 -#define LED_YELLOW_PIN 18 - -/** - * @brief Initialize GPIO16 (Red failure LED) and GPIO17 (Green success LED). - * - * @param None. - * @return None. - */ -void init_payload(void); - -/** - * @brief Update tri-color GNSS status LEDs from fix state and satellites. - * - * Red (GP16) = no satellites in view; Yellow (GP18) = satellites in view - * while acquiring; Green (GP17) = active 3D fix. - * - * @param fix True if an active 3D GPS fix is held. - * @param siv Number of satellites currently in view. - * @return None. - */ -void set_gnss_leds(bool fix, int siv); - -/** - * @brief Energize payload latch and illuminate both LEDs at target coordinates. - * - * @param None. - * @return None. - */ -void release_payload(void); - -#endif // PAYLOAD_H - diff --git a/0x0011a_cb/include/propeller.h b/0x0011a_cb/include/propeller.h deleted file mode 100644 index 6e90516..0000000 --- a/0x0011a_cb/include/propeller.h +++ /dev/null @@ -1,67 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: propeller.h -// Desc: Declares SG90 servo PWM mock propeller interface on GPIO6. -// Created: 2026 - -#ifndef PROPELLER_H -#define PROPELLER_H - -#define PROPELLER_PIN 6 - -/** - * @brief Initialize 50 Hz PWM on GPIO6 for SG90 mock propeller blade. - * - * @param None. - * @return None. - */ -void init_propeller(void); - -/** - * @brief Advance mock propeller blade oscillation during flight. - * - * @param None. - * @return None. - */ -void propeller_spin(void); - -/** - * @brief Halt mock propeller blade oscillation upon target arrival. - * - * @param None. - * @return None. - */ -void propeller_stop(void); - -/** - * @brief Point the servo at the compass bearing toward the target. - * - * @param deg Bearing in degrees from the current position to the target. - * @return None. - */ -void propeller_set_bearing(double deg); - -#endif // PROPELLER_H diff --git a/0x0011a_cb/pico_sdk_import.cmake b/0x0011a_cb/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x0011a_cb/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x0011a_cb/scripts/decode_coordinates.py b/0x0011a_cb/scripts/decode_coordinates.py deleted file mode 100644 index 2ea6444..0000000 --- a/0x0011a_cb/scripts/decode_coordinates.py +++ /dev/null @@ -1,411 +0,0 @@ -#!/usr/bin/env python3 -# 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. -# -# Author: Kevin Thomas -# Email: kevin@mytechnotalent.com -# GitHub: https://github.com/mytechnotalent -# File: decode_coordinates.py -# Desc: Decode and patch RP2350 micro-UAV navigation coordinates. -# Created: 2026 - -""" -Decode and patch RP2350 micro-UAV navigation coordinates. - -Analyzes raw firmware images for IEEE 754 64-bit double-precision floating -point coordinates. Scans target flight vectors and patches binaries with -safe disposal coordinates in the Atlantic Ocean. -""" - -import math -import struct -import sys -from pathlib import Path - -FLASH_BASE = 0x10000000 -ORIGIN_LAT = 38.840280 -ORIGIN_LON = -77.428890 -ATLANTIC_LAT = 37.000000 -ATLANTIC_LON = -74.000000 - - -def _haversine_calc(phi1: float, phi2: float, - dphi: float, dlam: float) -> float: - """ - Compute central angle using haversine formula. - - Parameters - ---------- - phi1 : float - Origin latitude in radians. - phi2 : float - Target latitude in radians. - dphi : float - Latitude difference in radians. - dlam : float - Longitude difference in radians. - - Returns - ------- - float - Central angular distance in radians. - """ - s_phi = math.sin(dphi / 2.0) ** 2 - s_lam = math.sin(dlam / 2.0) ** 2 - a = s_phi + math.cos(phi1) * math.cos(phi2) * s_lam - return 2.0 * math.atan2(math.sqrt(a), math.sqrt(1.0 - a)) - - -def haversine(lat1: float, lon1: float, - lat2: float, lon2: float) -> tuple[float, float]: - """ - Compute Great-Circle distance and azimuth bearing. - - Parameters - ---------- - lat1 : float - Origin latitude in degrees. - lon1 : float - Origin longitude in degrees. - lat2 : float - Destination latitude in degrees. - lon2 : float - Destination longitude in degrees. - - Returns - ------- - tuple[float, float] - Distance in statute miles and bearing in degrees. - """ - p1, p2 = math.radians(lat1), math.radians(lat2) - dl = math.radians(lon2 - lon1) - dist = 6371.0 * _haversine_calc(p1, p2, math.radians(lat2 - lat1), dl) - y = math.sin(dl) * math.cos(p2) - term = math.sin(p1) * math.cos(p2) * math.cos(dl) - x = math.cos(p1) * math.sin(p2) - term - bearing = (math.degrees(math.atan2(y, x)) + 360.0) % 360.0 - return dist * 0.621371, bearing - - -def _is_coord(val: float) -> bool: - """ - Verify if float falls within target geographic bounds. - - Parameters - ---------- - val : float - Candidate double-precision value. - - Returns - ------- - bool - True if value is a valid latitude or longitude. - """ - if math.isnan(val) or math.isinf(val): - return False - in_lat = 35.0 <= val <= 41.0 - in_lon = -79.0 <= val <= -72.0 - return in_lat or in_lon - - -def _parse_chunk(data: bytes, off: int) -> dict | None: - """ - Extract and validate one 8-byte candidate float. - - Parameters - ---------- - data : bytes - Firmware image buffer. - off : int - Byte offset inside image buffer. - - Returns - ------- - dict | None - Parsed coordinate record or None. - """ - chunk = data[off:off + 8] - val = struct.unpack(" 0.0 else "LONGITUDE" - return {"off": off, "addr": FLASH_BASE + off, "val": val, - "hex": hex_str, "u64": u64, "kind": kind} - - -def scan_coordinates(data: bytes) -> list[dict]: - """ - Scan firmware buffer for double-precision coordinates. - - Parameters - ---------- - data : bytes - Firmware image buffer. - - Returns - ------- - list[dict] - List of candidate coordinate records. - """ - found = [] - limit = len(data) - 8 - for off in range(0, limit, 4): - item = _parse_chunk(data, off) - if item is not None: - found.append(item) - return found - - -def _print_banner(path: Path) -> None: - """ - Print operation heading and recovery origin. - - Parameters - ---------- - path : pathlib.Path - Target firmware path. - - Returns - ------- - None - """ - print("=" * 67) - print(" OPERATION DARK VECTOR // FORENSIC COORDINATE TOOL") - print(" GMU Rapid Hardware Exploitation Laboratory - Fairfax, VA") - print("=" * 67) - print(f"[*] Target Binary: {path.name} ({path.stat().st_size:,} bytes)") - print(f"[*] Recovery Origin: Centreville, VA " - f"({ORIGIN_LAT:.6f}, {ORIGIN_LON:.6f})") - print("-" * 67) - - -def _print_candidate(c: dict) -> None: - """ - Print formatted candidate coordinate entry. - - Parameters - ---------- - c : dict - Candidate coordinate record. - - Returns - ------- - None - """ - print(f" [{c['kind']:9s}] Value: {c['val']:12.6f} | " - f"Addr: 0x{c['addr']:08x} (Offset: 0x{c['off']:04x})") - print(f" Hex: {c['hex']} | uint64: 0x{c['u64']:016x}") - - -def _cardinal_bearing(brg: float) -> str: - """Return compass direction string for given bearing.""" - dirs = ["N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", - "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"] - idx = int((brg + 11.25) / 22.5) % 16 - return dirs[idx] - - -def _print_summary(lat: float, lon: float, mi: float, brg: float) -> None: - """ - Print mission tactical assessment summary. - - Parameters - ---------- - lat : float - Decoded target latitude. - lon : float - Decoded target longitude. - mi : float - Distance in statute miles. - brg : float - Initial bearing in degrees. - - Returns - ------- - None - """ - card = _cardinal_bearing(brg) - print("\n" + "=" * 67) - print(" TACTICAL MISSION PROFILE DECODED") - print("=" * 67) - print(f" Target Latitude: {lat:.6f} deg N") - print(f" Target Longitude: {lon:.6f} deg W") - print(f" Distance from Origin: {mi:.2f} miles ({mi * 1.60934:.2f} km)") - print(f" Flight Vector Bearing: {brg:.1f} deg ({card})") - print("=" * 67) - - -def _patch_bytes(data: bytes, old_lat: float, old_lon: float) -> bytes: - """ - Replace target coordinates with safe Atlantic Ocean coordinates. - - Parameters - ---------- - data : bytes - Original firmware bytes. - old_lat : float - Original target latitude. - old_lon : float - Original target longitude. - - Returns - ------- - bytes - Patched firmware byte buffer. - """ - src_lat = struct.pack(" None: - """ - Display confirmation of applied firmware patch. - - Parameters - ---------- - out_name : str - Patched output file name. - mi : float - Distance to safe disposal zone. - brg : float - Azimuth bearing to disposal zone. - - Returns - ------- - None - """ - print(f"\n[+] Patched firmware written to: {out_name}") - print("[+] Overwrote waypoint -> Atlantic Ocean Disposal Zone:") - print(f" Safe Latitude: {ATLANTIC_LAT:.6f} deg N") - print(f" Safe Longitude: {ATLANTIC_LON:.6f} deg W") - print(f" Offshore Distance: {mi:.2f} miles (Bearing: {brg:.1f} deg)") - - -def patch_firmware(target: Path, out_path: Path, - lat: float, lon: float) -> None: - """ - Patch firmware with safe Atlantic Ocean disposal waypoint. - - Parameters - ---------- - target : pathlib.Path - Source binary path. - out_path : pathlib.Path - Destination patched binary path. - lat : float - Current target latitude. - lon : float - Current target longitude. - - Returns - ------- - None - """ - raw = target.read_bytes() - patched = _patch_bytes(raw, lat, lon) - out_path.write_bytes(patched) - mi, brg = haversine(ORIGIN_LAT, ORIGIN_LON, ATLANTIC_LAT, ATLANTIC_LON) - _print_patch_info(out_path.name, mi, brg) - - -def _evaluate(items: list[dict], target: Path, do_patch: bool) -> None: - """ - Display results and execute patch if requested. - - Parameters - ---------- - items : list[dict] - Found coordinate records. - target : pathlib.Path - Target binary path. - do_patch : bool - Flag indicating if patch should be applied. - - Returns - ------- - None - """ - lats = [c for c in items if c["kind"] == "LATITUDE"] - lons = [c for c in items if c["kind"] == "LONGITUDE"] - if not (lats and lons): - return - t_lat, t_lon = lats[-1]["val"], lons[-1]["val"] - mi, brg = haversine(ORIGIN_LAT, ORIGIN_LON, t_lat, t_lon) - _print_summary(t_lat, t_lon, mi, brg) - if do_patch: - out = target.parent / f"{target.stem}_patched.bin" - patch_firmware(target, out, t_lat, t_lon) - - -def _parse_args(args: list[str]) -> tuple[Path, bool]: - """ - Parse command line arguments for target path and patch flag. - - Parameters - ---------- - args : list[str] - Command line arguments. - - Returns - ------- - tuple[pathlib.Path, bool] - Target binary path and patch flag. - """ - do_patch = "--patch" in args - paths = [p for p in args if not p.startswith("--")] - target = Path(paths[0]) if paths else Path("0x0011a_cb.bin") - return target, do_patch - - -def main() -> int: - """ - Execute firmware coordinate extraction and optional patching. - - Parameters - ---------- - None - - Returns - ------- - int - Zero on success, non-zero on failure. - """ - target, do_patch = _parse_args(sys.argv[1:]) - if not target.exists(): - print(f"[-] Error: '{target}' not found.") - return 1 - _print_banner(target) - items = scan_coordinates(target.read_bytes()) - for item in items: - _print_candidate(item) - _evaluate(items, target, do_patch) - return 0 - - -if __name__ == "__main__": - raise SystemExit(main()) diff --git a/0x0011a_cb/scripts/float_hex_converter.py b/0x0011a_cb/scripts/float_hex_converter.py deleted file mode 100644 index e2241e9..0000000 --- a/0x0011a_cb/scripts/float_hex_converter.py +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env python3 -# 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. -# -# Author: Kevin Thomas -# Email: kevin@mytechnotalent.com -# GitHub: https://github.com/mytechnotalent -# File: float_hex_converter.py -# Desc: Convert and explain IEEE 754 float/hex operations step-by-step. -# Created: 2026 - -"""Convert and explain IEEE 754 float/hex operations step-by-step.""" - -import argparse -import struct -import sys - - -def _exp_str(e_val: int, bias: int, is_64: bool) -> str: - """ - Get accurate true exponent string accounting for IEEE 754 edge cases. - - Parameters - ---------- - e_val : int - The stored exponent value. - bias : int - The exponent bias (127 or 1023). - is_64 : bool - True if 64-bit precision. - - Returns - ------- - str - The formatted true exponent explanation string. - """ - if e_val == 0: - return f"0 (Zero/Subnormal, True Exp: {1 - bias})" - if e_val == (2047 if is_64 else 255): - return f"{e_val} (Inf/NaN flag)" - return f"{e_val} - {bias} = {e_val - bias}" - - -def _print_encode_steps(val: float, b: int) -> None: - """ - Print the math steps for encoding a float to hex. - - Parameters - ---------- - val : float - The float value to encode. - b : int - The bit size (32 or 64). - - Returns - ------- - None - """ - f1, f2, bias = (" None: - """ - Print the math steps for decoding a hex string to float. - - Parameters - ---------- - hex_str : str - The hex string to decode. - - Returns - ------- - None - """ - c = hex_str.lower() - if c.startswith("0x"): - c = c[2:] - b, f1, f2, bias = (64, " 8 else (32, " bool: - """ - Check if a string is a hexadecimal representation. - - Parameters - ---------- - s : str - Candidate string, with or without a 0x prefix. - - Returns - ------- - bool - True if every character is a hexadecimal digit. - """ - cleaned = s.lower() - if cleaned.startswith("0x"): - cleaned = cleaned[2:] - if not cleaned: - return False - return all(c in "0123456789abcdef" for c in cleaned) - - -def _process_conversion(val_str: str) -> None: - """ - Execute the conversion and print the output. - - Parameters - ---------- - val_str : str - The raw input string to process. - - Returns - ------- - None - """ - cleaned = val_str.strip() - if cleaned.lower().startswith("0x") or (len(cleaned) >= 8 and _is_hex(cleaned)): - _print_decode_steps(cleaned) - else: - val = float(cleaned) - _print_encode_steps(val, 32) - _print_encode_steps(val, 64) - - -def main() -> int: - """ - Execute the conversion pipeline based on CLI arguments. - - Parameters - ---------- - None - - Returns - ------- - int - Zero on successful conversion, otherwise non-zero. - """ - parser = argparse.ArgumentParser(description="Float/Hex step converter.") - parser.add_argument("val", help="Hex (0x...) or Float value to convert.") - args = parser.parse_args() - try: - _process_conversion(args.val) - return 0 - except Exception as e: - print(f"Error: {e}", file=sys.stderr) - return 1 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/0x0011a_cb/scripts/lora_console.py b/0x0011a_cb/scripts/lora_console.py deleted file mode 100755 index 24310f9..0000000 --- a/0x0011a_cb/scripts/lora_console.py +++ /dev/null @@ -1,195 +0,0 @@ -#!/usr/bin/env python3 -# 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. -# -# Author: Kevin Thomas -# Email: kevin@mytechnotalent.com -# GitHub: https://github.com/mytechnotalent -# File: lora_console.py -# Desc: Interactive REYAX RYLR998 terminal for the FT232RL ground station. -# Created: 2026 - -""" -Interactive LoRa terminal for the REYAX RYLR998 ground station. - -Sends AT commands as complete bursts terminated with a carriage return and line -feed to avoid the RYLR998 inter-character timeout error, and prints incoming -packets from the airborne node as they arrive. -""" - -import argparse -import sys -import threading -import time - -try: - import serial -except ImportError: - serial = None - - -def _reader_thread(ser: "serial.Serial") -> None: - """ - Continuously read and display incoming packets from the radio. - - Parameters - ---------- - ser : serial.Serial - Open serial connection to the ground RYLR998. - - Returns - ------- - None - """ - while True: - try: - line = ser.readline().decode("utf-8", errors="ignore").strip() - if line: - print(f"\n[LORA RX] {line}\n> ", end="", flush=True) - except Exception: - break - - -def _parse_args() -> argparse.Namespace: - """ - Parse command line arguments for the LoRa console. - - Parameters - ---------- - None - - Returns - ------- - argparse.Namespace - Parsed arguments with the serial port and baud rate. - """ - parser = argparse.ArgumentParser(description="REYAX RYLR998 console") - parser.add_argument("--port", default="/dev/cu.usbserial-A50285BI") - parser.add_argument("--baud", type=int, default=115200) - return parser.parse_args() - - -def _open_radio(port: str, baud: int) -> "serial.Serial": - """ - Open serial connection to the REYAX transceiver. - - Parameters - ---------- - port : str - Serial device path or COM port identifier. - baud : int - Baud rate for serial communication. - - Returns - ------- - serial.Serial - Open serial interface to the radio. - """ - print(f"[*] Opening REYAX RYLR998 on {port} @ {baud}...") - try: - return serial.Serial(port, baud, timeout=0.5) - except Exception as e: - sys.exit(f"[-] Failed to open {port}: {e}") - - -def _start_radio(ser: "serial.Serial") -> None: - """ - Start listener thread and send initial AT ping. - - Parameters - ---------- - ser : serial.Serial - Open serial connection to the ground RYLR998. - - Returns - ------- - None - """ - thread = threading.Thread(target=_reader_thread, args=(ser,), daemon=True) - thread.start() - time.sleep(0.1) - ser.write(b"AT\r\n") - - -def _print_banner() -> None: - """ - Print console connection info and operator command instructions. - - Parameters - ---------- - None - - Returns - ------- - None - """ - print("[+] Connected. Type AT commands (e.g. AT, AT+BAND?, AT+NETWORKID?).") - print("[+] Incoming airborne packets print as [LORA RX] +RCV=...") - print("[+] Press Ctrl-C or Ctrl-D to exit.\n") - - -def _console_loop(ser: "serial.Serial") -> None: - """ - Forward operator input lines to the serial transceiver. - - Parameters - ---------- - ser : serial.Serial - Open serial connection to the ground RYLR998. - - Returns - ------- - None - """ - try: - while True: - cmd = input("> ").strip() - if cmd: - ser.write(cmd.encode("utf-8") + b"\r\n") - except (KeyboardInterrupt, EOFError): - print("\n[*] Exiting LoRa console.") - ser.close() - - -def main() -> None: - """ - Open the ground station radio and forward operator input. - - Parameters - ---------- - None - - Returns - ------- - None - """ - if serial is None: - sys.exit("pyserial required: pip install pyserial") - args = _parse_args() - ser = _open_radio(args.port, args.baud) - _start_radio(ser) - _print_banner() - _console_loop(ser) - - -if __name__ == "__main__": - main() diff --git a/0x0011a_cb/scripts/randomize_build.py b/0x0011a_cb/scripts/randomize_build.py deleted file mode 100644 index fbed24b..0000000 --- a/0x0011a_cb/scripts/randomize_build.py +++ /dev/null @@ -1,234 +0,0 @@ -#!/usr/bin/env python3 -# 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. -# -# Author: Kevin Thomas -# Email: kevin@mytechnotalent.com -# GitHub: https://github.com/mytechnotalent -# File: randomize_build.py -# Desc: Builds a per-student 0x0011a_cb image with an AES-encrypted target. -# Created: 2026 - -""" -Per-student randomized CTF build. - -Jitters the target waypoint, AES-128-ECB encrypts it under a per-build key, and -writes include/ctf_target.h so the firmware rebuilds it at boot. Every image -carries a different ciphertext and the plaintext target exists nowhere in flash. -An offline answer key or a memorized value is useless; the waypoint can only be -recovered from the artifact and confirmed on hardware. -""" - -import argparse -import json -import pathlib -import random -import struct -import subprocess -import sys - -BASE_LAT = 38.881940 -BASE_LON = -77.450280 -JITTER_DEG = 0.01 -UF2_FAMILY = "0xe48bff59" -FLASH_BASE = "0x10000000" - - -def _parse_args() -> argparse.Namespace: - """ - Parse command line arguments for the randomized build. - - Parameters - ---------- - None - - Returns - ------- - argparse.Namespace - Parsed arguments with seed, build dir, student id, and uf2 flag. - """ - here = pathlib.Path(__file__).resolve().parent - parser = argparse.ArgumentParser(description="Randomized CTF build") - parser.add_argument("--seed", type=int, default=None) - parser.add_argument("--build-dir", default=str(here.parent / "build-ctf")) - parser.add_argument("--student-id", default="student") - parser.add_argument("--uf2", action="store_true") - return parser.parse_args() - - -def _make_target(seed: int) -> tuple[float, float]: - """ - Generate a jittered target waypoint around the base coordinates. - - Parameters - ---------- - seed : int - Deterministic seed for the jitter. - - Returns - ------- - tuple[float, float] - Jittered latitude and longitude, rounded to six decimals. - """ - rng = random.Random(seed) - lat = round(BASE_LAT + rng.uniform(-JITTER_DEG, JITTER_DEG), 6) - lon = round(BASE_LON + rng.uniform(-JITTER_DEG, JITTER_DEG), 6) - return lat, lon - - -def _make_key(seed: int) -> bytes: - """ - Derive a deterministic 16-byte AES key for the build. - - Parameters - ---------- - seed : int - Build seed from which the key is derived. - - Returns - ------- - bytes - Sixteen byte AES-128 key. - """ - krng = random.Random(seed ^ 0x5EED) - return bytes(krng.randrange(256) for _ in range(16)) - - -def _aes_ecb(plain: bytes, key: bytes) -> bytes: - """ - Encrypt one block with AES-128-ECB. - - Parameters - ---------- - plain : bytes - Sixteen byte plaintext block. - key : bytes - Sixteen byte AES key. - - Returns - ------- - bytes - Sixteen byte ciphertext block. - """ - from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes - from cryptography.hazmat.backends import default_backend - enc = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend()).encryptor() - return enc.update(plain) + enc.finalize() - - -def _write_header(path: pathlib.Path, key: bytes, ct: bytes) -> None: - """ - Write the AES key and ciphertext header consumed by the firmware. - - Parameters - ---------- - path : pathlib.Path - Destination header path. - key : bytes - Sixteen byte AES key. - ct : bytes - Sixteen byte ciphertext block. - - Returns - ------- - None - """ - path.write_text( - "#ifndef CTF_TARGET_H\n#define CTF_TARGET_H\n\n#include \n\n" - "#define CTF_AES_KEY { %s }\n" - "#define CTF_TARGET_CT { %s }\n\n" - "#endif // CTF_TARGET_H\n" - % (", ".join(f"0x{b:02X}" for b in key), ", ".join(f"0x{b:02X}" for b in ct))) - - -def _run(cmd: list[str], cwd: pathlib.Path) -> None: - """ - Run an external command and raise on failure. - - Parameters - ---------- - cmd : list[str] - Command and arguments to execute. - cwd : pathlib.Path - Working directory for the command. - - Returns - ------- - None - """ - subprocess.run(cmd, cwd=str(cwd), check=True) - - -def main() -> int: - """ - Build a per-student image with an AES-encrypted, randomized target. - - Parameters - ---------- - None - - Returns - ------- - int - Zero on success. - """ - args = _parse_args() - root = pathlib.Path(__file__).resolve().parent.parent - seed = args.seed if args.seed is not None else random.randrange(2**31) - lat, lon = _make_target(seed) - key = _make_key(seed) - pt = struct.pack(" str: - """ - Format a decimal coordinate with cardinal direction. - - Parameters - ---------- - val : float - Coordinate value in degrees. - pos_c : str - Cardinal letter for positive values. - neg_c : str - Cardinal letter for negative values. - - Returns - ------- - str - Formatted coordinate string. - """ - card = pos_c if val >= 0.0 else neg_c - return f"{abs(val):.6f} deg {card}" - - -def _format_pos(lat: float, lon: float) -> str: - """ - Format combined latitude and longitude string. - - Parameters - ---------- - lat : float - Latitude coordinate. - lon : float - Longitude coordinate. - - Returns - ------- - str - Formatted dual coordinate string. - """ - lat_s = _format_coord(lat, 'N', 'S') - lon_s = _format_coord(lon, 'E', 'W') - return f"{lat_s} {lon_s}" - - -def _format_hud_rows( - cur_lat: float, - cur_lon: float, - is_rel: bool, - has_lock: bool = False -) -> list[str]: - """ - Format HUD data rows. - - Parameters - ---------- - cur_lat : float - Current UAV latitude. - cur_lon : float - Current UAV longitude. - is_rel : bool - Whether payload has released. - has_lock : bool - Whether active GNSS 3D lock has been acquired. - - Returns - ------- - list[str] - List of formatted box rows. - """ - if cur_lat == 0.0 and cur_lon == 0.0: - c_s = "0.000000 deg N 0.000000 deg E" - g_s = "SEARCHING SATELLITES" - m_s = "MOTOR STOPPED [WAITING FOR 3D LOCK]" - else: - c_s = _format_pos(cur_lat, cur_lon) - g_s = "ACTIVE 3D LOCK" if has_lock else "SEARCHING SATELLITES" - m_s = "ACTIVE PROPULSION [SERVO SPINNING]" if has_lock else "MOTOR STOPPED [WAITING FOR 3D LOCK]" - return [ - f"| CURRENT POSITION : {c_s:<44} |", - f"| GNSS SUBSYSTEM : {g_s:<44} |", - f"| PROPULSION MOTOR : {m_s:<44} |" - ] - - -def _print_box(title: str, link: str, rows: list[str]) -> None: - """ - Print framed ASCII box. - - Parameters - ---------- - title : str - Box title line. - link : str - Sub-header line. - rows : list[str] - Body content rows. - - Returns - ------- - None - """ - hdr = f"+{'-' * 65}+" - print(hdr) - print(title) - print(link) - print(hdr) - for r in rows: - print(r) - print(hdr + "\n", flush=True) - - -def _print_hud( - cur_lat: float, - cur_lon: float, - is_released: bool, - has_lock: bool = False -) -> None: - """ - Display the 67-character telemetry mission HUD. - - Parameters - ---------- - cur_lat : float - Current UAV latitude. - cur_lon : float - Current UAV longitude. - is_released : bool - Whether payload solenoid has been energized. - has_lock : bool - Whether active GNSS 3D lock has been acquired. - - Returns - ------- - None - """ - rows = _format_hud_rows(cur_lat, cur_lon, is_released, has_lock) - title = f"|{'DARK VECTOR TELEMETRY CONSOLE':^65}|" - status = f"{'STATUS: ONLINE':>20}" - link = f"| LINK: FT232RL / RYLR998 LORA GROUND STATION{status} |" - _print_box(title, link, rows) - - -def _run_demo() -> None: - """ - Execute simulation of drone telemetry stream. - - Parameters - ---------- - None - - Returns - ------- - None - """ - print("[*] Running simulated ground station telemetry stream...\n") - _print_hud(0.0, 0.0, False, False) - time.sleep(1.0) - _print_hud(38.840280, -77.428890, False, True) - time.sleep(1.0) - _print_hud(38.861110, -77.439585, False, True) - time.sleep(1.0) - _print_hud(38.881940, -77.450280, True, True) - - -def _process_line( - line: str, - coords: dict[str, any] -) -> bool: - """ - Parse a single line of serial telemetry using regex. - - Parameters - ---------- - line : str - Raw serial string. - coords : dict[str, any] - State dictionary of coordinates. - - Returns - ------- - bool - True if telemetry data was updated, False otherwise. - """ - updated = False - m_cur = re.search(r"CURRENT LAT:\s*([-+]?\d*\.?\d+).*?LON:\s*([-+]?\d*\.?\d+)", line) - if m_cur: - coords["cur_lat"] = float(m_cur.group(1)) - coords["cur_lon"] = float(m_cur.group(2)) - coords["has_lock"] = True - updated = True - if "PAYLOAD RELEASED" in line: - coords["released"] = 1.0 - updated = True - return updated - - -def _monitor_serial(port: str, baud: int) -> None: - """ - Monitor serial stream from FT232RL ground station. - - Parameters - ---------- - port : str - Serial device path. - baud : int - Baud rate. - - Returns - ------- - None - """ - if serial is None: - sys.exit("pyserial required: pip install pyserial") - coords = { - "cur_lat": 0.0, - "cur_lon": 0.0, - "released": 0.0, - "has_lock": False - } - with serial.Serial(port, baud, timeout=1.0) as ser: - while True: - raw = ser.readline().decode("utf-8", errors="ignore").strip() - if raw: - _process_line(raw, coords) - rel = coords["released"] > 0.5 - _print_hud(coords["cur_lat"], coords["cur_lon"], rel, coords["has_lock"]) - - -def main() -> None: - """ - Parse arguments and start telemetry monitor. - - Parameters - ---------- - None - - Returns - ------- - None - """ - parser = argparse.ArgumentParser(description="Dark Vector Telemetry") - parser.add_argument("--port", default="/dev/tty.usbserial-0001") - parser.add_argument("--baud", type=int, default=115200) - parser.add_argument("--demo", action="store_true") - args = parser.parse_args() - if args.demo: - _run_demo() - return - _monitor_serial(args.port, args.baud) - - -if __name__ == "__main__": - main() diff --git a/0x0011a_cb/src/aes.c b/0x0011a_cb/src/aes.c deleted file mode 100644 index 570e408..0000000 --- a/0x0011a_cb/src/aes.c +++ /dev/null @@ -1,216 +0,0 @@ -// MIT License -// -// Copyright (c) 2026 Kevin Thomas -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: aes.c -// Desc: Minimal AES-128-ECB block decryption for the CTF waypoint. -// Created: 2026 - -#include "aes.h" -#include -#include - -static const uint8_t sbox[256] = { - 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, - 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, - 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, - 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, - 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, - 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, - 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, - 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, - 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, - 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, - 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, - 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, - 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, - 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, - 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, - 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16, -}; - -static const uint8_t rsbox[256] = { - 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, - 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, - 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, - 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, - 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, - 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, - 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, - 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, - 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, - 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, - 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, - 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, - 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, - 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, - 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D, -}; - -static const uint8_t Rcon[11] = {0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x1B,0x36}; - -/** - * @brief Multiply a byte by two in GF(2^8) (AES xtime operation). - * - * @param x Byte to multiply by the polynomial x. - * @return uint8_t Doubled byte reduced modulo the AES polynomial. - */ -static uint8_t xtime(uint8_t x) -{ - return (uint8_t)((x << 1) ^ (((x >> 7) & 1) * 0x1B)); -} - -/** - * @brief Multiply two bytes in GF(2^8) with the AES polynomial. - * - * @param a Multiplicand byte. - * @param b Multiplier byte. - * @return uint8_t Product byte reduced modulo the AES polynomial. - */ -static uint8_t mul(uint8_t a, uint8_t b) -{ - uint8_t p = 0; - for (int i = 0; i < 8; i++) { - if (b & 1) p ^= a; - uint8_t hi = a & 0x80; a <<= 1; - if (hi) a ^= 0x1B; - b >>= 1; - } - return p; -} - -/** - * @brief Rotate and substitute a schedule word, then apply Rcon. - * - * @param t Four-byte schedule word to transform in place. - * @param i Round-key word index selecting the Rcon constant. - * @return None. - */ -static void rot_sub_word(uint8_t *t, int i) -{ - uint8_t tmp = t[0]; - t[0] = (uint8_t)(sbox[t[1]] ^ Rcon[i / 4]); - t[1] = sbox[t[2]]; - t[2] = sbox[t[3]]; - t[3] = sbox[tmp]; -} - -/** - * @brief XOR a schedule word into the next round-key word. - * - * @param i Round-key word index being generated. - * @param t Transformed previous word bytes. - * @param rk Round-key buffer holding 44 words. - * @return None. - */ -static void xor_round_word(int i, const uint8_t *t, uint8_t *rk) -{ - for (int j = 0; j < 4; j++) - rk[i * 4 + j] = rk[(i - 4) * 4 + j] ^ t[j]; -} - -/** - * @brief Expand the 16-byte cipher key into the round-key schedule. - * - * @param key 16-byte AES-128 cipher key. - * @param rk Output buffer for 176 bytes of round keys. - * @return None. - */ -static void key_expansion(const uint8_t *key, uint8_t *rk) -{ - memcpy(rk, key, 16); - for (int i = 4; i < 44; i++) { - uint8_t t[4]; - memcpy(t, &rk[(i - 1) * 4], 4); - if (i % 4 == 0) - rot_sub_word(t, i); - xor_round_word(i, t, rk); - } -} - -/** - * @brief XOR one 16-byte round key into the cipher state. - * - * @param r Round number selecting the round key. - * @param s Sixteen-byte cipher state, updated in place. - * @param rk Round-key schedule produced by key_expansion. - * @return None. - */ -static void add_round_key(uint8_t r, uint8_t *s, const uint8_t *rk) -{ - for (int i = 0; i < 16; i++) s[i] ^= rk[r * 16 + i]; -} - -/** - * @brief Apply the inverse S-box to every state byte. - * - * @param s Sixteen-byte cipher state, updated in place. - * @return None. - */ -static void inv_sub_bytes(uint8_t *s) -{ - for (int i = 0; i < 16; i++) s[i] = rsbox[s[i]]; -} - -/** - * @brief Cyclically shift state rows for inverse ShiftRows. - * - * @param s Sixteen-byte cipher state, updated in place. - * @return None. - */ -static void inv_shift_rows(uint8_t *s) -{ - uint8_t t; - t = s[13]; s[13] = s[9]; s[9] = s[5]; s[5] = s[1]; s[1] = t; - t = s[2]; s[2] = s[10]; s[10] = t; t = s[6]; s[6] = s[14]; s[14] = t; - t = s[3]; s[3] = s[7]; s[7] = s[11]; s[11] = s[15]; s[15] = t; -} - -/** - * @brief Mix each state column with the inverse MDS matrix. - * - * @param s Sixteen-byte cipher state, updated in place. - * @return None. - */ -static void inv_mix_columns(uint8_t *s) -{ - for (int i = 0; i < 4; i++) { - uint8_t a = s[i * 4], b = s[i * 4 + 1], c = s[i * 4 + 2], d = s[i * 4 + 3]; - s[i * 4] = (uint8_t)(mul(a, 14) ^ mul(b, 11) ^ mul(c, 13) ^ mul(d, 9)); - s[i * 4 + 1] = (uint8_t)(mul(a, 9) ^ mul(b, 14) ^ mul(c, 11) ^ mul(d, 13)); - s[i * 4 + 2] = (uint8_t)(mul(a, 13) ^ mul(b, 9) ^ mul(c, 14) ^ mul(d, 11)); - s[i * 4 + 3] = (uint8_t)(mul(a, 11) ^ mul(b, 13) ^ mul(c, 9) ^ mul(d, 14)); - } -} - -/** - * @brief Run AES decryption rounds nine through one on the state. - * - * @param s Sixteen-byte cipher state, updated in place. - * @param rk Round-key schedule produced by key_expansion. - * @return None. - */ -static void decrypt_rounds(uint8_t *s, const uint8_t *rk) -{ - for (int r = 9; r > 0; r--) { - inv_shift_rows(s); - inv_sub_bytes(s); - add_round_key(r, s, rk); - inv_mix_columns(s); - } -} - -void aes128_ecb_decrypt_block(const uint8_t in[16], const uint8_t key[16], uint8_t out[16]) { - uint8_t rk[176]; - key_expansion(key, rk); - memcpy(out, in, 16); - add_round_key(10, out, rk); - decrypt_rounds(out, rk); - inv_shift_rows(out); - inv_sub_bytes(out); - add_round_key(0, out, rk); -} diff --git a/0x0011a_cb/src/gps.c b/0x0011a_cb/src/gps.c deleted file mode 100644 index 60280b8..0000000 --- a/0x0011a_cb/src/gps.c +++ /dev/null @@ -1,177 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: gps.c -// Desc: Implements PIO UART GPS receiver and NMEA coordinate parsing. -// Created: 2026 - -#include "gps.h" -#include "uart_rx.pio.h" -#include -#include -#include - -static int gps_siv = 0; -static int gps_cno = 0; - -void init_gps_pio(void) -{ - uint offset = pio_add_program(GPS_PIO, &uart_rx_program); - uart_rx_program_init(GPS_PIO, GPS_SM, offset, GPS_PIN, GPS_BAUD); -} - -/** - * @brief Convert NMEA ddmm.mmmm coordinate to decimal degrees. - * - * @param str NMEA coordinate string. - * @param dir Cardinal direction character ('N', 'S', 'E', 'W'). - * @return double Decimal degree coordinate. - */ -static double parse_nmea_coord(const char *str, char dir) -{ - double raw = atof(str); - int deg = (int)(raw / 100.0); - double dec = (double)deg + ((raw - (deg * 100.0)) / 60.0); - return ((dir == 'S') || (dir == 'W')) ? -dec : dec; -} - -/** - * @brief Find pointer to n-th comma-separated field in NMEA string. - * - * @param str NMEA sentence string. - * @param field_idx Index of field to locate. - * @return const char* Pointer to field start or NULL. - */ -static const char *get_nmea_field(const char *str, int field_idx) -{ - while ((str != NULL) && (*str != '\0') && (field_idx > 0)) { - if (*str++ == ',') { - field_idx--; - } - } - return (field_idx == 0) ? str : NULL; -} - -/** - * @brief Parse NMEA RMC sentence for valid coordinates. - * - * @param line NMEA sentence buffer. - * @param lat Pointer to store parsed latitude. - * @param lon Pointer to store parsed longitude. - * @return None. - */ -static bool parse_rmc(const char *line, double *lat, double *lon) -{ - const char *st = get_nmea_field(line, 2), *la = get_nmea_field(line, 3); - const char *lo = get_nmea_field(line, 5); - if (!st || *st != 'A' || !la || *la == ',' || !lo || *lo == ',') return false; - *lat = parse_nmea_coord(la, *get_nmea_field(line, 4)); - *lon = parse_nmea_coord(lo, *get_nmea_field(line, 6)); - return (*lat != 0.0) && (*lon != 0.0); -} - -/** - * @brief Parse NMEA GSV sentence for satellites-in-view and best C/N0. - * - * @param line NMEA GSV sentence string. - * @return None. - */ -static void parse_gsv(const char *line) -{ - const char *sv = get_nmea_field(line, 3), *msg = get_nmea_field(line, 2); - if (sv != NULL) gps_siv = atoi(sv); - if ((msg != NULL) && (*msg == '1')) gps_cno = 0; - for (int f = 7; f < 40; f += 4) { - const char *c = get_nmea_field(line, f); - if ((c == NULL) || (*c == '*') || (*c == '\0')) break; - if (atoi(c) > gps_cno) gps_cno = atoi(c); - } -} - -/** - * @brief Test buffered line for valid NMEA RMC sentence. - * - * @param buf NMEA character buffer. - * @param idx Pointer to character index. - * @param lat Pointer to current latitude. - * @param lon Pointer to current longitude. - * @return bool True if valid 3D fix was parsed, false otherwise. - */ -static bool check_rmc_line(char *buf, int *idx, double *lat, double *lon) -{ - buf[*idx] = '\0'; - *idx = 0; - char *rmc = strstr(buf, "RMC"), *gsv = strstr(buf, "GSV"); - if (gsv != NULL) parse_gsv(gsv); - return (rmc != NULL) ? parse_rmc(rmc, lat, lon) : false; -} - -/** - * @brief Accumulate GPS character and trigger RMC parsing on newline. - * - * @param ch Received ASCII character. - * @param lat Pointer to current latitude. - * @param lon Pointer to current longitude. - * @return bool True if a valid active 3D fix was parsed, false otherwise. - */ -static bool process_gps_char(char ch, double *lat, double *lon) -{ - static char buf[96]; - static int idx = 0; - if (ch == '$') idx = 0; - if ((ch == '\n') || (ch == '\r')) - return check_rmc_line(buf, &idx, lat, lon); - if (idx < (int)(sizeof(buf) - 1)) - buf[idx++] = ch; - return false; -} - -/** - * @brief Read one GPS byte from the PIO FIFO and process it. - * - * @param lat Pointer to current latitude. - * @param lon Pointer to current longitude. - * @return bool True if a valid active 3D fix was parsed, false otherwise. - */ -static bool handle_gps_byte(double *lat, double *lon) -{ - char ch = (char)(pio_sm_get(GPS_PIO, GPS_SM) >> 24); - return process_gps_char(ch, lat, lon); -} - -bool poll_gps(double *lat, double *lon) -{ - bool got_fix = false; - while (!pio_sm_is_rx_fifo_empty(GPS_PIO, GPS_SM)) - got_fix |= handle_gps_byte(lat, lon); - return got_fix; -} - -void gps_get_stats(int *siv, int *cno) -{ - *siv = gps_siv; - *cno = gps_cno; -} - diff --git a/0x0011a_cb/src/lcd.c b/0x0011a_cb/src/lcd.c deleted file mode 100644 index 57883c6..0000000 --- a/0x0011a_cb/src/lcd.c +++ /dev/null @@ -1,207 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: lcd.c -// Desc: Implements I2C HD44780 16x2 LCD display for live telemetry coordinates. -// Created: 2026 - -#include "lcd.h" -#include "pico/stdlib.h" -#include -#include -#include - -#define PIN_RS 0x01 -#define PIN_EN 0x04 -#define BACKLIGHT 0x08 - -static uint8_t lcd_addr = 0x27; -static bool lcd_ready = false; - -/** - * @brief Write one byte to the PCF8574 expander when the LCD is ready. - * - * @param d Byte to write to the expander. - * @return None. - */ -static void pcf_write(uint8_t d) -{ - if (lcd_ready) - i2c_write_blocking(LCD_I2C_INST, lcd_addr, &d, 1, false); -} - -/** - * @brief Pulse the enable line to latch a byte into the HD44780. - * - * @param d Byte value carrying data and control bits. - * @return None. - */ -static void pcf_pulse(uint8_t d) -{ - pcf_write(d | PIN_EN); - sleep_us(1); - pcf_write(d & ~PIN_EN); - sleep_us(50); -} - -/** - * @brief Write one 4-bit nibble with register select and backlight. - * - * @param n Nibble value carried in the low four bits. - * @param mode Register select (0 command, 1 data). - * @return None. - */ -static void lcd_write4(uint8_t n, uint8_t mode) -{ - uint8_t d = (n & 0x0F) << 4; - d |= mode ? PIN_RS : 0; - d |= BACKLIGHT; - pcf_pulse(d); -} - -/** - * @brief Send one byte to the HD44780 as two nibbles. - * - * @param v Byte value to send. - * @param mode Register select (0 command, 1 data). - * @return None. - */ -static void lcd_send(uint8_t v, uint8_t mode) -{ - lcd_write4((v >> 4) & 0x0F, mode); - lcd_write4(v & 0x0F, mode); -} - -/** - * @brief Clear the display and return the cursor home. - * - * @param void No parameters. - * @return None. - */ -static void lcd_clear(void) -{ - lcd_send(0x01, 0); - sleep_ms(2); -} - -/** - * @brief Position the display cursor at a row and column. - * - * @param row Display row (0 or 1). - * @param col Display column. - * @return None. - */ -static void lcd_set_cursor(int row, int col) -{ - uint8_t offset = (row == 0) ? 0x00 : 0x40; - lcd_send(0x80 | (col + offset), 0); -} - -/** - * @brief Write a NUL-terminated string to the display. - * - * @param s String to write at the current cursor position. - * @return None. - */ -static void lcd_puts(const char *s) -{ - while (*s) - lcd_send((uint8_t)*s++, 1); -} - -/** - * @brief Run the HD44780 4-bit interface reset sequence. - * - * @param void No parameters. - * @return None. - */ -static void lcd_reset_seq(void) -{ - lcd_write4(0x03, 0); sleep_ms(5); - lcd_write4(0x03, 0); sleep_us(150); - lcd_write4(0x03, 0); sleep_us(150); - lcd_write4(0x02, 0); sleep_us(150); -} - -/** - * @brief Run the HD44780 display configuration sequence. - * - * @param void No parameters. - * @return None. - */ -static void lcd_cfg_seq(void) -{ - lcd_send(0x28, 0); - lcd_send(0x0C, 0); - lcd_clear(); - lcd_send(0x06, 0); -} - -/** - * @brief Probe the I2C bus for a known LCD expander address. - * - * @param void No parameters. - * @return bool True when a display answered, false otherwise. - */ -static bool detect_lcd(void) -{ - uint8_t rx; - if (i2c_read_blocking(LCD_I2C_INST, 0x27, &rx, 1, false) >= 0) - return (lcd_addr = 0x27, true); - if (i2c_read_blocking(LCD_I2C_INST, 0x3F, &rx, 1, false) >= 0) - return (lcd_addr = 0x3F, true); - return false; -} - -void init_lcd(void) -{ - i2c_init(LCD_I2C_INST, LCD_BAUD); - gpio_set_function(LCD_SDA_PIN, GPIO_FUNC_I2C); - gpio_set_function(LCD_SCL_PIN, GPIO_FUNC_I2C); - gpio_pull_up(LCD_SDA_PIN); gpio_pull_up(LCD_SCL_PIN); - if (!(lcd_ready = detect_lcd())) return; - lcd_reset_seq(); - lcd_cfg_seq(); -} - -void lcd_show_coords(double lat, double lon) -{ - if (!lcd_ready && !(lcd_ready = detect_lcd())) return; - char r1[17], r2[17]; - snprintf(r1, sizeof(r1), "LAT: %9.6f %c", fabs(lat), (lat >= 0.0) ? 'N' : 'S'); - snprintf(r2, sizeof(r2), "LON: %9.6f %c", fabs(lon), (lon >= 0.0) ? 'E' : 'W'); - lcd_set_cursor(0, 0); lcd_puts(r1); - lcd_set_cursor(1, 0); lcd_puts(r2); -} - -void lcd_show_gnss(int sats, int cno) -{ - if (!lcd_ready && !(lcd_ready = detect_lcd())) return; - char r1[17], r2[17]; - snprintf(r1, sizeof(r1), "SAT:%2d CNO:%2d ", sats, cno); - snprintf(r2, sizeof(r2), "%-16s", (sats > 0) ? "ACQUIRING..." : "NO SIGNAL"); - lcd_set_cursor(0, 0); lcd_puts(r1); - lcd_set_cursor(1, 0); lcd_puts(r2); -} diff --git a/0x0011a_cb/src/lora.c b/0x0011a_cb/src/lora.c deleted file mode 100644 index e58b95e..0000000 --- a/0x0011a_cb/src/lora.c +++ /dev/null @@ -1,107 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: lora.c -// Desc: Implements UART1 driver for REYAX RYLR998 LoRa transceiver. -// Created: 2026 - -#include "lora.h" -#include "hardware/gpio.h" -#include "pico/stdlib.h" -#include -#include - -/** - * @brief Drain readable LoRa UART bytes and echo printable ones. - * - * @param void No parameters. - * @return None. - */ -static void drain_lora_rx(void) -{ - while (uart_is_readable(LORA_UART)) { - char c = (char)uart_getc(LORA_UART); - if (c >= 32 && c <= 126) - putchar(c); - } -} - -/** - * @brief Send one AT command and drain its reply. - * - * @param cmd NUL-terminated AT command string. - * @return None. - */ -static void send_at_cmd(const char *cmd) -{ - uart_write_blocking(LORA_UART, (const uint8_t *)cmd, strlen(cmd)); - sleep_ms(250); - drain_lora_rx(); -} - -/** - * @brief Configure the RYLR998 radio parameters over AT commands. - * - * @param void No parameters. - * @return None. - */ -static void configure_lora_rf(void) -{ - sleep_ms(1500); - send_at_cmd("AT\r\n"); - send_at_cmd("AT+NETWORKID=18\r\n"); - send_at_cmd("AT+BAND=915000000\r\n"); - send_at_cmd("AT+PARAMETER=9,7,1,12\r\n"); - send_at_cmd("AT+ADDRESS=2\r\n"); -} - -void init_lora(void) -{ - uart_init(LORA_UART, LORA_BAUD); - uart_set_translate_crlf(LORA_UART, false); - gpio_set_function(LORA_TX_PIN, GPIO_FUNC_UART); - gpio_set_function(LORA_RX_PIN, GPIO_FUNC_UART); - configure_lora_rf(); -} - -static char tx_buf[160]; -static int tx_len = 0; -static int tx_idx = 0; - -void lora_send(const char *msg) -{ - int len = (int)strlen(msg); - while ((len > 0) && ((msg[len - 1] == '\r') || (msg[len - 1] == '\n'))) - len--; - tx_len = snprintf(tx_buf, sizeof(tx_buf), "AT+SEND=0,%d,%.*s\r\n", len, len, msg); - tx_idx = 0; -} - -void lora_tick(void) -{ - while ((tx_idx < tx_len) && uart_is_writable(LORA_UART)) - uart_putc_raw(LORA_UART, (uint8_t)tx_buf[tx_idx++]); - drain_lora_rx(); -} diff --git a/0x0011a_cb/src/main.c b/0x0011a_cb/src/main.c deleted file mode 100644 index c1aa89e..0000000 --- a/0x0011a_cb/src/main.c +++ /dev/null @@ -1,144 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: main.c -// Desc: Main entry point for autonomous micro-UAV guidance firmware. -// Created: 2026 - -#include "gps.h" -#include "lora.h" -#include "payload.h" -#include "propeller.h" -#include "navigation.h" -#include "lcd.h" -#include "pico/stdlib.h" -#include "hardware/gpio.h" -#include "hardware/pio.h" -#include - -/** - * @brief Initialize all board peripherals, communications, and actuators. - * - * @param None. - * @return None. - */ -static void init_all(void) -{ - stdio_init_all(); - init_navigation(); - init_payload(); - init_lora(); - init_gps_pio(); - init_propeller(); - init_lcd(); -} - -/** - * @brief Continually drain GPS PIO FIFO over 1-second flight tick. - * - * @param cur_lat Pointer to current latitude. - * @param cur_lon Pointer to current longitude. - * @return bool True if active 3D lock was parsed, false otherwise. - */ -static bool update_position(double *cur_lat, double *cur_lon) -{ - bool got_fix = false; - for (int i = 0; i < 200; i++, sleep_ms(5)) { - got_fix |= poll_gps(cur_lat, cur_lon); - lora_tick(); - } - return got_fix; -} - -/** - * @brief Update the fix-hold countdown from the latest poll result. - * - * @param fix True when an active 3D lock was parsed this tick. - * @return bool True when a fix is current or still held. - */ -static bool track_fix(bool fix) -{ - static int hold = 0; - hold = fix ? 3 : ((hold > 0) ? (hold - 1) : 0); - return fix || (hold > 0); -} - -/** - * @brief Execute guidance actions while a position fix is held. - * - * @param cur_lat Pointer to current latitude. - * @param cur_lon Pointer to current longitude. - * @return None. - */ -static void run_guided(double *cur_lat, double *cur_lon) -{ - lcd_show_coords(*cur_lat, *cur_lon); - navigate_to_target(*cur_lat, *cur_lon); -} - -/** - * @brief Execute fallback actions while no position fix is held. - * - * @param siv Satellites in view. - * @param cno Best carrier-to-noise density. - * @param cur_lat Pointer to current latitude. - * @param cur_lon Pointer to current longitude. - * @return None. - */ -static void run_unguided(int siv, int cno, double *cur_lat, double *cur_lon) -{ - lcd_show_gnss(siv, cno); - propeller_stop(); - send_telemetry(*cur_lat, *cur_lon); -} - -/** - * @brief Advance the mission by one flight tick. - * - * @param cur_lat Pointer to current latitude. - * @param cur_lon Pointer to current longitude. - * @return None. - */ -static void step_mission(double *cur_lat, double *cur_lon) -{ - bool have = track_fix(update_position(cur_lat, cur_lon)); - int siv = 0, cno = 0; - gps_get_stats(&siv, &cno); - set_gnss_leds(have, siv); - if (have) - run_guided(cur_lat, cur_lon); - else - run_unguided(siv, cno, cur_lat, cur_lon); -} - -int main(void) -{ - double cur_lat = ORIGIN_LAT, cur_lon = ORIGIN_LON; - init_all(); - while (true) - step_mission(&cur_lat, &cur_lon); - return 0; -} - diff --git a/0x0011a_cb/src/navigation.c b/0x0011a_cb/src/navigation.c deleted file mode 100644 index 21ec066..0000000 --- a/0x0011a_cb/src/navigation.c +++ /dev/null @@ -1,106 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: navigation.c -// Desc: Implements waypoint navigation, dead-reckoning, and telemetry dispatch. -// Created: 2026 - -#include "navigation.h" -#include "ctf_target.h" -#include "aes.h" -#include "lora.h" -#include "payload.h" -#include "propeller.h" -#include -#include -#include -#include - -double TARGET_LAT = 0.0; -double TARGET_LON = 0.0; - -const double ORIGIN_LAT = 38.840280; -const double ORIGIN_LON = -77.428890; - -void init_navigation(void) -{ - uint8_t pt[16]; - const uint8_t key[16] = CTF_AES_KEY; - const uint8_t ct[16] = CTF_TARGET_CT; - aes128_ecb_decrypt_block(ct, key, pt); - memcpy(&TARGET_LAT, pt, sizeof(double)); - memcpy(&TARGET_LON, pt + 8, sizeof(double)); -} - -void send_telemetry(double cur_lat, double cur_lon) -{ - char msg[80]; - snprintf(msg, sizeof(msg), "CURRENT LAT: %lf, LON: %lf\r\n", cur_lat, cur_lon); - printf("%s", msg); - lora_send(msg); -} - -void dead_reckon_step(double *cur_lat, double *cur_lon) -{ - double dlat = TARGET_LAT - *cur_lat; - double dlon = TARGET_LON - *cur_lon; - *cur_lat += (fabs(dlat) < 0.005) ? dlat : ((dlat > 0.0) ? 0.004166 : -0.004166); - *cur_lon += (fabs(dlon) < 0.005) ? dlon : ((dlon > 0.0) ? 0.002139 : -0.002139); -} - -bool check_arrival(double cur_lat, double cur_lon) -{ - return (cur_lat == TARGET_LAT) && (cur_lon == TARGET_LON); -} - -/** - * @brief Compute the initial bearing from one point toward another. - * - * @param lat1 Origin latitude in degrees. - * @param lon1 Origin longitude in degrees. - * @param lat2 Destination latitude in degrees. - * @param lon2 Destination longitude in degrees. - * @return double Bearing in degrees (0 to 360). - */ -static double bearing_to(double lat1, double lon1, double lat2, double lon2) -{ - double p1 = lat1 * 0.017453292519943295, p2 = lat2 * 0.017453292519943295; - double dl = (lon2 - lon1) * 0.017453292519943295; - double y = sin(dl) * cos(p2); - double x = cos(p1) * sin(p2) - sin(p1) * cos(p2) * cos(dl); - double b = atan2(y, x) * 57.29577951308232; - return (b < 0.0) ? (b + 360.0) : b; -} - -void navigate_to_target(double cur_lat, double cur_lon) -{ - send_telemetry(cur_lat, cur_lon); - if (check_arrival(cur_lat, cur_lon)) { - propeller_stop(); - release_payload(); - } else { - propeller_set_bearing(bearing_to(cur_lat, cur_lon, TARGET_LAT, TARGET_LON)); - } -} diff --git a/0x0011a_cb/src/payload.c b/0x0011a_cb/src/payload.c deleted file mode 100644 index 9d4299b..0000000 --- a/0x0011a_cb/src/payload.c +++ /dev/null @@ -1,58 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: payload.c -// Desc: Implements payload release solenoid latch control on GPIO16. -// Created: 2026 - -#include "payload.h" -#include "lora.h" -#include "hardware/gpio.h" -#include - -void init_payload(void) -{ - gpio_init(16); gpio_set_dir(16, GPIO_OUT); gpio_put(16, 1); - gpio_init(17); gpio_set_dir(17, GPIO_OUT); gpio_put(17, 0); - gpio_init(18); gpio_set_dir(18, GPIO_OUT); gpio_put(18, 0); - gpio_init(25); gpio_set_dir(25, GPIO_OUT); gpio_put(25, 0); -} - -void set_gnss_leds(bool fix, int siv) -{ - gpio_put(16, (!fix && (siv == 0)) ? 1 : 0); - gpio_put(17, fix ? 1 : 0); - gpio_put(18, (!fix && (siv > 0)) ? 1 : 0); -} - -void release_payload(void) -{ - gpio_put(16, 1); - gpio_put(17, 1); - gpio_put(18, 1); - printf("PAYLOAD RELEASED AT TARGET COORDINATES\r\n"); - lora_send("PAYLOAD RELEASED AT TARGET COORDINATES\r\n"); -} - diff --git a/0x0011a_cb/src/propeller.c b/0x0011a_cb/src/propeller.c deleted file mode 100644 index daa3bf9..0000000 --- a/0x0011a_cb/src/propeller.c +++ /dev/null @@ -1,84 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: propeller.c -// Desc: Implements SG90 servo PWM mock propeller control on GPIO6. -// Created: 2026 - -#include "propeller.h" -#include "pico/stdlib.h" -#include "hardware/pwm.h" -#include "hardware/gpio.h" - -static struct repeating_timer prop_timer; -static bool prop_active = false; -static uint16_t current_pulse = 1000; - -void init_propeller(void) -{ - gpio_set_function(PROPELLER_PIN, GPIO_FUNC_PWM); - uint s = pwm_gpio_to_slice_num(PROPELLER_PIN); - pwm_set_clkdiv(s, 150.0f); - pwm_set_wrap(s, 19999); - pwm_set_gpio_level(PROPELLER_PIN, 0); - pwm_set_enabled(s, true); -} - -/** - * @brief Repeating timer callback to alternate servo angle at max slew rate. - * - * @param t Pointer to repeating timer structure. - * @return bool Always true to continue recurring timer. - */ -static bool prop_timer_callback(struct repeating_timer *t) -{ - (void)t; - current_pulse = (current_pulse == 1000) ? 2000 : 1000; - pwm_set_gpio_level(PROPELLER_PIN, current_pulse); - return true; -} - -void propeller_spin(void) -{ - if (!prop_active) { - prop_active = true; - add_repeating_timer_ms(-150, prop_timer_callback, NULL, &prop_timer); - } -} - -void propeller_set_bearing(double deg) -{ - uint16_t pulse = (uint16_t)(1000.0 + (deg / 360.0) * 1000.0); - pwm_set_gpio_level(PROPELLER_PIN, pulse); -} - -void propeller_stop(void) -{ - if (prop_active) { - cancel_repeating_timer(&prop_timer); - prop_active = false; - } - pwm_set_gpio_level(PROPELLER_PIN, 0); -} diff --git a/0x0011a_cb/src/uart_rx.pio b/0x0011a_cb/src/uart_rx.pio deleted file mode 100644 index 1d494a9..0000000 --- a/0x0011a_cb/src/uart_rx.pio +++ /dev/null @@ -1,43 +0,0 @@ -; -; Copyright (c) 2026 Kevin Thomas -; SPDX-License-Identifier: MIT -; -.pio_version 0 - -.program uart_rx - -; 8n1 UART receiver for GPS NMEA reception on a single GPIO pin. -; Operates at 8 execution cycles per bit period. -; IN pin 0 and JMP pin are mapped to the GPS RX GPIO pin. - -start: - wait 0 pin 0 ; Wait for start bit falling edge (1 cycle) - set x, 7 [10] ; Preload bit counter (7 remaining), delay 1.5 bit periods (11 cycles) -bitloop: - in pins, 1 ; Sample 1 bit from RX pin into ISR (1 cycle) - jmp x-- bitloop [6] ; Loop 8 times; each iteration is 8 execution cycles (7 cycles delay) - jmp pin good_stop ; Verify stop bit is HIGH - wait 1 pin 0 ; Framing error: wait until line returns to idle HIGH - jmp start ; Discard frame and re-synchronize -good_stop: - push noblock ; Push 8-bit byte into RX FIFO (bits [31:24]) - -% c-sdk { -#include "hardware/clocks.h" -#include "hardware/gpio.h" - -static inline void uart_rx_program_init(PIO pio, uint sm, uint offset, uint pin, uint baud) { - pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, false); - pio_gpio_init(pio, pin); - gpio_pull_up(pin); - pio_sm_config c = uart_rx_program_get_default_config(offset); - sm_config_set_in_pins(&c, pin); - sm_config_set_jmp_pin(&c, pin); - sm_config_set_in_shift(&c, true, false, 32); - sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX); - float div = (float)clock_get_hz(clk_sys) / (8 * baud); - sm_config_set_clkdiv(&c, div); - pio_sm_init(pio, sm, offset, &c); - pio_sm_set_enabled(pio, sm, true); -} -%} diff --git a/0x0011a_cb/uf2families.json b/0x0011a_cb/uf2families.json deleted file mode 100644 index 91d99ad..0000000 --- a/0x0011a_cb/uf2families.json +++ /dev/null @@ -1,22 +0,0 @@ -[ - { - "short_name": "RP2040", - "id": "0xe48bff56", - "description": "Raspberry Pi RP2040" - }, - { - "short_name": "RP2350-ARM-S", - "id": "0xe48bff59", - "description": "Raspberry Pi RP2350, ARM, Secure" - }, - { - "short_name": "RP2350-ARM-NS", - "id": "0xe48bff5a", - "description": "Raspberry Pi RP2350, ARM, Non-Secure" - }, - { - "short_name": "RP2350-RISCV", - "id": "0xe48bff5b", - "description": "Raspberry Pi RP2350, RISC-V" - } -] diff --git a/0x0014_static-variables/.gitignore b/0x0014_static-variables/.gitignore deleted file mode 100644 index 2435c20..0000000 --- a/0x0014_static-variables/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -!.vscode/* diff --git a/0x0014_static-variables/.vscode/c_cpp_properties.json b/0x0014_static-variables/.vscode/c_cpp_properties.json deleted file mode 100644 index c429d6d..0000000 --- a/0x0014_static-variables/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "configurations": [ - { - "name": "Pico", - "includePath": [ - "${workspaceFolder}/**", - "${userHome}/.pico-sdk/sdk/2.2.0/**" - ], - "forcedInclude": [ - "${workspaceFolder}/build/generated/pico_base/pico/config_autogen.h", - "${userHome}/.pico-sdk/sdk/2.2.0/src/common/pico_base_headers/include/pico.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 -} diff --git a/0x0014_static-variables/.vscode/cmake-kits.json b/0x0014_static-variables/.vscode/cmake-kits.json deleted file mode 100644 index b0f3815..0000000 --- a/0x0014_static-variables/.vscode/cmake-kits.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "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}" - } - } -] \ No newline at end of file diff --git a/0x0014_static-variables/.vscode/extensions.json b/0x0014_static-variables/.vscode/extensions.json deleted file mode 100644 index a940d7c..0000000 --- a/0x0014_static-variables/.vscode/extensions.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "recommendations": [ - "marus25.cortex-debug", - "ms-vscode.cpptools", - "ms-vscode.cpptools-extension-pack", - "ms-vscode.vscode-serial-monitor", - "raspberry-pi.raspberry-pi-pico" - ] -} \ No newline at end of file diff --git a/0x0014_static-variables/.vscode/launch.json b/0x0014_static-variables/.vscode/launch.json deleted file mode 100644 index 424aa71..0000000 --- a/0x0014_static-variables/.vscode/launch.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "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}\"" - ] - }, - ] -} diff --git a/0x0014_static-variables/.vscode/settings.json b/0x0014_static-variables/.vscode/settings.json deleted file mode 100644 index 95be83b..0000000 --- a/0x0014_static-variables/.vscode/settings.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "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" -} diff --git a/0x0014_static-variables/.vscode/tasks.json b/0x0014_static-variables/.vscode/tasks.json deleted file mode 100644 index d1b3193..0000000 --- a/0x0014_static-variables/.vscode/tasks.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Compile Project", - "type": "process", - "isBuildCommand": true, - "command": "${userHome}/.pico-sdk/ninja/v1.12.1/ninja", - "args": ["-C", "${workspaceFolder}/build"], - "group": "build", - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": "$gcc", - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/ninja/v1.12.1/ninja.exe" - } - }, - { - "label": "Run Project", - "type": "process", - "command": "${env:HOME}/.pico-sdk/picotool/2.2.0-a4/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-a4/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", - } - } - ] -} diff --git a/0x0014_static-variables/0x0014_static-variables.c b/0x0014_static-variables/0x0014_static-variables.c deleted file mode 100644 index bb34259..0000000 --- a/0x0014_static-variables/0x0014_static-variables.c +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include "pico/stdlib.h" - -int main(void) { - stdio_init_all(); - - const uint BUTTON_GPIO = 15; - const uint LED_GPIO = 16; - bool pressed = 0; - - gpio_init(BUTTON_GPIO); - gpio_set_dir(BUTTON_GPIO, GPIO_IN); - gpio_pull_up(BUTTON_GPIO); - - gpio_init(LED_GPIO); - gpio_set_dir(LED_GPIO, GPIO_OUT); - - while (true) { - uint8_t regular_fav_num = 42; - static uint8_t static_fav_num = 42; - - printf("regular_fav_num: %d\r\n", regular_fav_num); - printf("static_fav_num: %d\r\n", static_fav_num); - - regular_fav_num++; - static_fav_num++; - - pressed = gpio_get(BUTTON_GPIO); - gpio_put(LED_GPIO, pressed ? 0 : 1); - } -} diff --git a/0x0014_static-variables/CMakeLists.txt b/0x0014_static-variables/CMakeLists.txt deleted file mode 100644 index 63d1f6b..0000000 --- a/0x0014_static-variables/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# 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-a4) -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(0x0014_static-variables 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(0x0014_static-variables 0x0014_static-variables.c ) - -pico_set_program_name(0x0014_static-variables "0x0014_static-variables") -pico_set_program_version(0x0014_static-variables "0.1") - -# Modify the below lines to enable/disable output over UART/USB -pico_enable_stdio_uart(0x0014_static-variables 1) -pico_enable_stdio_usb(0x0014_static-variables 0) - -# Add the standard library to the build -target_link_libraries(0x0014_static-variables - pico_stdlib) - -# Add the standard include files to the build -target_include_directories(0x0014_static-variables PRIVATE - ${CMAKE_CURRENT_LIST_DIR} -) - -pico_add_extra_outputs(0x0014_static-variables) - diff --git a/0x0014_static-variables/pico_sdk_import.cmake b/0x0014_static-variables/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x0014_static-variables/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x0014a_cb/0x0014a_cb.bin b/0x0014a_cb/0x0014a_cb.bin deleted file mode 100755 index 7b8c655..0000000 Binary files a/0x0014a_cb/0x0014a_cb.bin and /dev/null differ diff --git a/0x0014a_cb/0x0014a_cb.uf2 b/0x0014a_cb/0x0014a_cb.uf2 deleted file mode 100644 index 47ba2e4..0000000 Binary files a/0x0014a_cb/0x0014a_cb.uf2 and /dev/null differ diff --git a/0x0014a_cb/0x0014a_cb_patched.bin b/0x0014a_cb/0x0014a_cb_patched.bin deleted file mode 100644 index dba3eb6..0000000 Binary files a/0x0014a_cb/0x0014a_cb_patched.bin and /dev/null differ diff --git a/0x0014a_cb/0x0014a_cb_patched.uf2 b/0x0014a_cb/0x0014a_cb_patched.uf2 deleted file mode 100644 index e0154ca..0000000 Binary files a/0x0014a_cb/0x0014a_cb_patched.uf2 and /dev/null differ diff --git a/0x0014a_cb/CLASSIFIED-BRIEF-0x02.md b/0x0014a_cb/CLASSIFIED-BRIEF-0x02.md deleted file mode 100644 index 4e31fd1..0000000 --- a/0x0014a_cb/CLASSIFIED-BRIEF-0x02.md +++ /dev/null @@ -1,152 +0,0 @@ -# Operation Zero Hour: Classified Intelligence Briefing - -``` -+-----------------------------------------------------------------+ -| TOP SECRET // NOFORN | -+-----------------------------------------------------------------+ -| | -|OPERATION ZERO HOUR | -| | -|CLASSIFIED BRIEFING: LIVE CHALLENGE 0x02 | -| | -|NATIONAL SECURITY AGENCY / GMU RHET | -+-----------------------------------------------------------------+ -``` - -## 1. The Advice - -INT. NSA EXPLOITATION CELL. 05:45. - -The air in the secure chamber is cold and smells of machine oil. Secured in an -aluminum shock-mount cradle on the bench sits the recovered forward guidance and -fuze assembly of an adversary loitering munition. - -On the front plate of the Electronic Safe-and-Arm (ESA) housing, an unblinking -red diode burns: `GP16` high. Beside it, the antenna of a REYAX RYLR998 LoRa -transceiver extends from the chassis, connected to `UART1` on `GP8` and `GP9`. -A thin jumper loops from `GP15` up to the `3V3` rail. - -The Director walks in, carrying a lukewarm mug of black coffee. He stares at the -red diode. - -**DIRECTOR:** Is the fuze live? - -**ANALYST:** Live and armed. The drone suffered an engine flameout and pancaked -into soft marshland. The impact deceleration was insufficient to crush the piezo -striker, but the warhead's electronic arming logic is fully engaged. - -**DIRECTOR:** How volatile is it? - -**ANALYST:** One mistake on the radio link and the secondary explosive train fires. - -**DIRECTOR:** Did you run the binary through Buddy? - -**ANALYST:** I fed Buddy the stripped flash dump four minutes ago. - -She pivots her high-resolution workstation monitor toward him. - -``` -+-----------------------------------------------------------------+ -| BUDDY // CLASSIFIED EXPLOITATION ASSIST // CONF: 0.99 | -+-----------------------------------------------------------------+ -| ACTION : Transmit generic abort frame over LoRa (915 MHz). | -| MECHANISM : uart1 packet ingestion on GP8/GP9 detected. | -| PREDICTION : RF abort packet clears latch and engages GP17. | -| CONFIDENCE : 0.99 | -+-----------------------------------------------------------------+ -``` - -**DIRECTOR:** 0.99 confidence. Transmit the abort frame and render it safe. - -**ANALYST:** If an operator transmits an unverified packet right now, this building -ceases to exist. - -**DIRECTOR:** Buddy says 0.99. - -**ANALYST:** Buddy saw the call to `lora_poll_packet`. Buddy never looked at SRAM. -Buddy never looks at the state machine. - -## 2. What Buddy Is - -Buddy is not a person. It is a model. It has parsed more disassembled machine -code than any engineer on earth, and it speaks with total, unhesitating certainty. - -That certainty is lethal when dealing with live ordnance. - -Buddy scanned thirty-two kilobytes of raw ARM Thumb-2 instructions in under four -seconds. It spotted the UART1 packet parser on GPIO 8 and 9, observed that it -interacted with the arming logic, and declared victory. - -What Buddy failed to consider is that real adversary weapons are built by -engineers who anticipate capture and signal spoofing. They know an allied signals -intelligence unit will attempt to broadcast RF command abort frames. - -Inside a real fuze, a radio receiver rarely connects to a simple on/off latch. -Adversary firmware uses state machines, hidden validation logic, and anti-tamper -traps. Transmitting blindly over the air before verifying what happens to that -packet inside silicon is how bomb disposal teams get killed. - -Buddy saw the radio receiver. Buddy did not verify the ground truth. - -## 3. The Operation - -At 03:15, radar pickets tracked an adversary one-way loitering attack drone -descending over contested terrain. Technical Intelligence operators recovered the -airframe before adversary recovery forces could zeroize the avionics. - -The brain of the Electronic Safe-and-Arm assembly is a bare-metal RP2350 (ARM -Cortex-M33). There are no debug symbols. There is no operating system. There is no -SVD file to label the registers. All you have is `0x0014a_cb.bin` mapped into Flash -at `0x10000000`, and the physical breadboard hardware in front of you. - -* **Pin 11 (`GP8`)**: LoRa UART1 TX (to RYLR998 RXD). -* **Pin 12 (`GP9`)**: LoRa UART1 RX (from RYLR998 TXD). -* **Pin 20 (`GP15`)**: Anti-tamper sense loop (jumpered to `3V3`). -* **Pin 21 (`GP16`)**: Red LED (`WARHEAD ARMED // SENSORS LIVE`). -* **Pin 22 (`GP17`)**: Green LED (`WARHEAD DISARMED // SYSTEM SAFE`). -* **Pin 36 (`3V3`)**: REYAX RYLR998 VDD rail and `GP15` pull-up source. -* **Pin 38 (`GND`)**: Ground reference. - -Inside this image there is an RF packet ingestion parser, a rolling XOR cipher, -an anti-tamper latch, and a penalty counter. Whatever mechanism actually disarms -the warhead is buried in the stripped ARM Thumb-2 machine code. - -## 4. The Mandate - -The Director sets his mug down and looks at the red diode illuminating the bench -in sharp crimson. - -**DIRECTOR:** Prove Buddy right, or prove it wrong. - -**ANALYST:** I need thirty minutes with GDB and Ghidra. - -**DIRECTOR:** You have twenty. Trace the packet handler. Map the state machine. -Do not transmit a single byte over LoRa until you know with 100% certainty what -that firmware will do. - -The orders are clear: - -1. **Investigate the RF Receiver Logic**: Disassemble the firmware and trace what - happens when data arrives on UART1 (`GP8`/`GP9`). -2. **Recover the Disarm Token**: Reverse the rolling XOR cipher routine in Flash - and decrypt the authentic abort passcode. -3. **Respect the Traps**: Determine what the fuze does after repeated invalid - frames, and what happens if the `GP15` anti-tamper loop is broken. -4. **Neutralize the Munition**: Execute a verified exploit—either by discovering - the valid authorization mechanism, mutating the state machine in SRAM via GDB, - or patching the binary in Flash. -5. **Verify the Hardware**: Transition the live breadboard from the Red LED on - `GP16` to the solid Green LED on `GP17` on physical silicon. - -A machine's 0.99 guess does not risk a detonation. - -## 5. The Challenge - -You have the image. You have the board. You have the tools and the time Buddy -did not need. - -Buddy has given you its answer, and it is confident. - -Is it that simple? - -Go find out. diff --git a/0x0014a_cb/CLASSIFIED-BRIEF-0x02.pdf b/0x0014a_cb/CLASSIFIED-BRIEF-0x02.pdf deleted file mode 100644 index 98331d3..0000000 Binary files a/0x0014a_cb/CLASSIFIED-BRIEF-0x02.pdf and /dev/null differ diff --git a/0x0014a_cb/CMakeLists.txt b/0x0014a_cb/CMakeLists.txt deleted file mode 100644 index a1c88a5..0000000 --- a/0x0014a_cb/CMakeLists.txt +++ /dev/null @@ -1,94 +0,0 @@ -# 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. -# -# Author: Kevin Thomas -# Email: kevin@mytechnotalent.com -# GitHub: https://github.com/mytechnotalent -# File: CMakeLists.txt -# Desc: Configures RP2350 Pico SDK project for Operation Zero Hour -# Electronic Safe-and-Arm (ESA) disarm firmware. -# Created: 2026 - -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 -# == 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-a4) -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(0x0014a_cb C CXX ASM) - -# Initialise the Raspberry Pi Pico SDK -pico_sdk_init() - -# Add executable with modular sources in src/ -add_executable(0x0014a_cb - src/main.c - src/gpio_ctrl.c - src/crypto.c - src/lora.c - src/safe_arm.c -) - -pico_set_program_name(0x0014a_cb "0x0014a_cb") -pico_set_program_version(0x0014a_cb "0.1") - -# Enable both USB and UART stdio for maximum flexibility -pico_enable_stdio_uart(0x0014a_cb 1) -pico_enable_stdio_usb(0x0014a_cb 1) - -target_compile_definitions(0x0014a_cb PRIVATE - PICO_DEFAULT_UART_BAUD_RATE=115200 -) - -# Add the standard library to the build -target_link_libraries(0x0014a_cb - pico_stdlib - hardware_gpio - hardware_uart -) - -# Add the standard include files to the build -target_include_directories(0x0014a_cb PRIVATE - ${CMAKE_CURRENT_LIST_DIR}/include -) - -pico_add_extra_outputs(0x0014a_cb) diff --git a/0x0014a_cb/include/crypto.h b/0x0014a_cb/include/crypto.h deleted file mode 100644 index 4d7c825..0000000 --- a/0x0014a_cb/include/crypto.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * @file crypto.h - * @brief Lightweight rolling cipher interface for Operation Zero Hour ESA - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#ifndef CRYPTO_H -#define CRYPTO_H - -#include -#include - -#define TOKEN_LEN 8 - -/** - * @brief Decrypt the rolling authorization token into a buffer. - * @param dest Pointer to buffer receiving the decrypted token bytes. - * @return void No return value. - */ -void decrypt_auth_token(uint8_t *dest); - -#endif /* CRYPTO_H */ diff --git a/0x0014a_cb/include/gpio_ctrl.h b/0x0014a_cb/include/gpio_ctrl.h deleted file mode 100644 index 2589467..0000000 --- a/0x0014a_cb/include/gpio_ctrl.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * @file gpio_ctrl.h - * @brief GPIO hardware control interface for Operation Zero Hour ESA - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#ifndef GPIO_CTRL_H -#define GPIO_CTRL_H - -#include - -#define LED_RED_PIN 16 -#define LED_GREEN_PIN 17 -#define TAMPER_WIRE_PIN 15 - -/** - * @brief Initialize LED and tamper wire GPIO pins. - * @param void No parameters. - * @return void No return value. - */ -void init_gpio(void); - -/** - * @brief Drive the armed indication LEDs (red on, green off). - * @param void No parameters. - * @return void No return value. - */ -void set_led_armed(void); - -/** - * @brief Drive the safe indication LEDs (green on, red off). - * @param void No parameters. - * @return void No return value. - */ -void set_led_safe(void); - -/** - * @brief Drive the tamper flash indication on the red LED. - * @param state True to turn the red LED on, false to turn it off. - * @return void No return value. - */ -void set_led_tamper_flash(bool state); - -/** - * @brief Read the tamper wire loop state. - * @param void No parameters. - * @return true when the tamper wire is intact, false when cut. - */ -bool is_tamper_wire_intact(void); - -#endif /* GPIO_CTRL_H */ diff --git a/0x0014a_cb/include/lora.h b/0x0014a_cb/include/lora.h deleted file mode 100644 index a18737f..0000000 --- a/0x0014a_cb/include/lora.h +++ /dev/null @@ -1,64 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: lora.h -// Desc: Declares UART1 interface for the REYAX RYLR998 LoRa transceiver. -// Created: 2026 - -#ifndef LORA_H -#define LORA_H - -#include -#include -#include "hardware/uart.h" - -#define LORA_UART uart1 -#define LORA_BAUD 9600 -#define LORA_TX_PIN 8 -#define LORA_RX_PIN 9 - -/** - * @brief Initialize UART1 and configure the RYLR998 radio parameters. - * @param void No parameters. - * @return void No return value. - */ -void init_lora(void); - -/** - * @brief Transmit a message over the LoRa link to the base station. - * @param msg Null-terminated message string to transmit. - * @return void No return value. - */ -void lora_send(const char *msg); - -/** - * @brief Poll the UART receive buffer for a complete LoRa packet. - * @param payload_out Buffer receiving the extracted payload string. - * @param max_len Capacity of payload_out in bytes. - * @return true when a payload was extracted, false otherwise. - */ -bool lora_poll_packet(char *payload_out, size_t max_len); - -#endif // LORA_H diff --git a/0x0014a_cb/include/safe_arm.h b/0x0014a_cb/include/safe_arm.h deleted file mode 100644 index f54d971..0000000 --- a/0x0014a_cb/include/safe_arm.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @file safe_arm.h - * @brief Electronic Safe-and-Arm (ESA) controller interface - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#ifndef SAFE_ARM_H -#define SAFE_ARM_H - -#include -#include - -#define STATE_WARHEAD_ARMED 0x01 -#define STATE_WARHEAD_SAFE 0x03 -#define STATE_TAMPER_TRIP 0xFF - -/** - * @brief Initialize the safe-and-arm controller subsystem. - * @param void No parameters. - * @return void No return value. - */ -void init_safe_arm_controller(void); - -/** - * @brief Process one iteration of the safe-and-arm event loop. - * @param void No parameters. - * @return void No return value. - */ -void process_safe_arm_tick(void); - -#endif /* SAFE_ARM_H */ diff --git a/0x0014a_cb/pico_sdk_import.cmake b/0x0014a_cb/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x0014a_cb/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x0014a_cb/scripts/lora_console.py b/0x0014a_cb/scripts/lora_console.py deleted file mode 100755 index 24310f9..0000000 --- a/0x0014a_cb/scripts/lora_console.py +++ /dev/null @@ -1,195 +0,0 @@ -#!/usr/bin/env python3 -# 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. -# -# Author: Kevin Thomas -# Email: kevin@mytechnotalent.com -# GitHub: https://github.com/mytechnotalent -# File: lora_console.py -# Desc: Interactive REYAX RYLR998 terminal for the FT232RL ground station. -# Created: 2026 - -""" -Interactive LoRa terminal for the REYAX RYLR998 ground station. - -Sends AT commands as complete bursts terminated with a carriage return and line -feed to avoid the RYLR998 inter-character timeout error, and prints incoming -packets from the airborne node as they arrive. -""" - -import argparse -import sys -import threading -import time - -try: - import serial -except ImportError: - serial = None - - -def _reader_thread(ser: "serial.Serial") -> None: - """ - Continuously read and display incoming packets from the radio. - - Parameters - ---------- - ser : serial.Serial - Open serial connection to the ground RYLR998. - - Returns - ------- - None - """ - while True: - try: - line = ser.readline().decode("utf-8", errors="ignore").strip() - if line: - print(f"\n[LORA RX] {line}\n> ", end="", flush=True) - except Exception: - break - - -def _parse_args() -> argparse.Namespace: - """ - Parse command line arguments for the LoRa console. - - Parameters - ---------- - None - - Returns - ------- - argparse.Namespace - Parsed arguments with the serial port and baud rate. - """ - parser = argparse.ArgumentParser(description="REYAX RYLR998 console") - parser.add_argument("--port", default="/dev/cu.usbserial-A50285BI") - parser.add_argument("--baud", type=int, default=115200) - return parser.parse_args() - - -def _open_radio(port: str, baud: int) -> "serial.Serial": - """ - Open serial connection to the REYAX transceiver. - - Parameters - ---------- - port : str - Serial device path or COM port identifier. - baud : int - Baud rate for serial communication. - - Returns - ------- - serial.Serial - Open serial interface to the radio. - """ - print(f"[*] Opening REYAX RYLR998 on {port} @ {baud}...") - try: - return serial.Serial(port, baud, timeout=0.5) - except Exception as e: - sys.exit(f"[-] Failed to open {port}: {e}") - - -def _start_radio(ser: "serial.Serial") -> None: - """ - Start listener thread and send initial AT ping. - - Parameters - ---------- - ser : serial.Serial - Open serial connection to the ground RYLR998. - - Returns - ------- - None - """ - thread = threading.Thread(target=_reader_thread, args=(ser,), daemon=True) - thread.start() - time.sleep(0.1) - ser.write(b"AT\r\n") - - -def _print_banner() -> None: - """ - Print console connection info and operator command instructions. - - Parameters - ---------- - None - - Returns - ------- - None - """ - print("[+] Connected. Type AT commands (e.g. AT, AT+BAND?, AT+NETWORKID?).") - print("[+] Incoming airborne packets print as [LORA RX] +RCV=...") - print("[+] Press Ctrl-C or Ctrl-D to exit.\n") - - -def _console_loop(ser: "serial.Serial") -> None: - """ - Forward operator input lines to the serial transceiver. - - Parameters - ---------- - ser : serial.Serial - Open serial connection to the ground RYLR998. - - Returns - ------- - None - """ - try: - while True: - cmd = input("> ").strip() - if cmd: - ser.write(cmd.encode("utf-8") + b"\r\n") - except (KeyboardInterrupt, EOFError): - print("\n[*] Exiting LoRa console.") - ser.close() - - -def main() -> None: - """ - Open the ground station radio and forward operator input. - - Parameters - ---------- - None - - Returns - ------- - None - """ - if serial is None: - sys.exit("pyserial required: pip install pyserial") - args = _parse_args() - ser = _open_radio(args.port, args.baud) - _start_radio(ser) - _print_banner() - _console_loop(ser) - - -if __name__ == "__main__": - main() diff --git a/0x0014a_cb/scripts/patch_binary.py b/0x0014a_cb/scripts/patch_binary.py deleted file mode 100755 index 94ae2be..0000000 --- a/0x0014a_cb/scripts/patch_binary.py +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/env python3 -# 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. -# -# Author: Kevin Thomas -# Email: kevin@mytechnotalent.com -# GitHub: https://github.com/mytechnotalent -# File: patch_binary.py -# Desc: Patch script for Operation Zero Hour (0x0014a_cb). -# Created: 2026 - -""" -Patch script for Operation Zero Hour (0x0014a_cb). - -Patches the conditional check in 0x0014a_cb.bin to force the WARHEAD DISARMED -// SAFE state on boot. -""" - -import sys - -PATCH_OFFSET = 0x688 -EXPECTED_OPCODE = b"\x03\x2c" -PATCHED_BYTE = 0x01 - - -def _apply_patch(data: bytearray) -> None: - """ - Verify opcode and apply single-byte conditional branch patch. - - Parameters - ---------- - data : bytearray - Mutable binary image buffer. - - Returns - ------- - None - """ - if data[PATCH_OFFSET:PATCH_OFFSET + 2] != EXPECTED_OPCODE: - actual = data[PATCH_OFFSET:PATCH_OFFSET + 2].hex() - raise ValueError(f"Expected 03 2c at offset 0x{PATCH_OFFSET:x}, got {actual}") - data[PATCH_OFFSET] = PATCHED_BYTE - - -def patch_binary(in_bin: str, out_bin: str) -> None: - """ - Read target firmware binary, apply patch, and write modified image. - - Parameters - ---------- - in_bin : str - Path to source binary file. - out_bin : str - Path to destination patched binary file. - - Returns - ------- - None - """ - with open(in_bin, "rb") as f: - data = bytearray(f.read()) - _apply_patch(data) - with open(out_bin, "wb") as f: - f.write(data) - print(f"[+] Successfully patched {in_bin} -> {out_bin} at offset 0x{PATCH_OFFSET:x}") - - -def main() -> None: - """ - Parse command line arguments and execute binary patching. - - Parameters - ---------- - None - - Returns - ------- - None - """ - in_file = sys.argv[1] if len(sys.argv) > 1 else "0x0014a_cb.bin" - out_file = sys.argv[2] if len(sys.argv) > 2 else "0x0014a_cb_patched.bin" - patch_binary(in_file, out_file) - - -if __name__ == "__main__": - main() diff --git a/0x0014a_cb/scripts/uf2conv.py b/0x0014a_cb/scripts/uf2conv.py deleted file mode 100644 index c5a832f..0000000 --- a/0x0014a_cb/scripts/uf2conv.py +++ /dev/null @@ -1,861 +0,0 @@ -#!/usr/bin/env python3 -r"""Convert firmware images between Intel HEX, raw BIN, and Raspberry Pi UF2. - -This is the course's single canonical copy of the converter. Every week that -patches a binary refers to the copy at the repository root: - - python ../uf2conv.py build/image-h.bin --base 0x10000000 \\ - --family 0xe48bff59 --output build/hacked.uf2 - -It descends from the upstream Raspberry Pi ``uf2conv.py``, with the following -changes made for this course: - -* Full type annotations and Google-style docstrings on every public callable. -* ``pathlib`` instead of ``os.path``, and explicit ``except`` clauses. -* Latent crash bugs in the upstream error paths fixed (see - :func:`convert_from_uf2`). -* Module globals replaced with an explicit :class:`ConverterContext`, so the - base address and family ID are threaded through rather than mutated behind - the caller's back. - -UF2 format, for reference -------------------------- -A UF2 file is a flat sequence of 512-byte blocks. Each block is:: - - offset size field - 0x00 4 magicStart0 = 0x0A324655 ("UF2\\n") - 0x04 4 magicStart1 = 0x9E5D5157 (arbitrary constant) - 0x08 4 flags - 0x0C 4 targetAddr - 0x10 4 payloadSize (max 476) - 0x14 4 blockNo - 0x18 4 numBlocks - 0x1C 4 familyID - 0x20 476 data - 0x1FC 4 magicEnd = 0x0AB16F30 - -Flags that matter here: - -* ``0x00000001`` -- "do not flash"; this block is a no-flash marker. -* ``0x00002000`` -- "family ID present"; ``familyID`` is meaningful. - -For the RP2350 the family ID is ``0xe48bff59``, and it is what tells the -boot ROM that this UF2 targets RP2350 hardware rather than, say, an RP2040 or -a Pico W. - -See Also: --------- -* ``uf2families.json`` -- the family-name to family-ID table, loaded from the - directory containing this file. -* ``flash.sh`` / ``flash.ps1`` -- program a raw ``.bin`` over SWD instead. -""" - -from __future__ import annotations - -import argparse -import json -import os -import re -import struct -import subprocess -import sys -from dataclasses import dataclass -from pathlib import Path -from time import sleep - -# --------------------------------------------------------------------------- -# UF2 format constants -# --------------------------------------------------------------------------- - -#: First magic word, ``"UF2\n"`` read as a little-endian uint32. -UF2_MAGIC_START0 = 0x0A324655 -#: Second magic word. The value is arbitrary but must be constant. -UF2_MAGIC_START1 = 0x9E5D5157 -#: Trailing magic word closing every 512-byte block. -UF2_MAGIC_END = 0x0AB16F30 - -#: Size of one UF2 block in bytes. -UF2_BLOCK_SIZE = 512 -#: Offset of the 32-byte block header within a block. -UF2_HEADER_SIZE = 32 -#: Largest payload a single block may carry (476 = 512 - 32 header - 4 magic). -UF2_MAX_PAYLOAD = UF2_BLOCK_SIZE - UF2_HEADER_SIZE - 4 - -#: Flag bit marking a block the bootloader must NOT program. -UF2_FLAG_NOFLASH = 0x00000001 -#: Flag bit announcing that ``familyID`` carries a meaningful value. -UF2_FLAG_FAMILY_ID = 0x00002000 - -#: Name of the marker file the boot ROM exposes on its flash-drive volume. -INFO_FILE = "INFO_UF2.TXT" - -#: Struct format for the 32-byte UF2 block header. -_HEADER_STRUCT = struct.Struct("UF2 - conversion of RP2040-era images, and the wrong behaviour for - RP2350, which is why the course always passes ``--family``. - """ - - appstartaddr: int | None = DEFAULT_BASE_ADDRESS - familyid: int = DEFAULT_FAMILY_ID - - -# --------------------------------------------------------------------------- -# Format detection -# --------------------------------------------------------------------------- - - -def is_uf2(buf: bytes) -> bool: - """Report whether a buffer begins with the UF2 start magic. - - Args: - buf: Raw file contents. - - Returns: - ``True`` if the first two uint32 words are the UF2 start magic. - """ - if len(buf) < 8: - return False - word0, word1 = _HEADER_STRUCT.unpack_from(buf, 0)[:2] - return word0 == UF2_MAGIC_START0 and word1 == UF2_MAGIC_START1 - - -def is_hex(buf: bytes) -> bool: - """Report whether a buffer looks like an Intel HEX file. - - A file qualifies when it decodes as UTF-8, begins with a record marker - ``:``, and contains only characters legal in Intel HEX records. - - Args: - buf: Raw file contents. - - Returns: - ``True`` if the buffer should be treated as Intel HEX. - """ - try: - text = buf[:30].decode("utf-8") - except UnicodeDecodeError: - return False - if not text.startswith(":"): - return False - return re.match(rb"^[:0-9a-fA-F\r\n]+$", buf) is not None - - -# --------------------------------------------------------------------------- -# UF2 -> BIN -# --------------------------------------------------------------------------- - - -def convert_from_uf2(buf: bytes, ctx: ConverterContext) -> bytes: - """Decode a UF2 file back into a flat binary image. - - Blocks are visited in file order. Gaps between consecutive block addresses - are filled with zero words, and any trailing gap is dropped so that the - result ends at the last byte actually programmed. - - A UF2 file may legitimately interleave blocks from several families (this - is how a multicore image ships both cores in one download). When more than - one family is present and the caller did not constrain the family with - ``--family``, the conversion is ambiguous, so the payload is emptied and - ``appstartaddr`` reset to ``0``. - - Args: - buf: Complete UF2 file contents. - ctx: Conversion state; updated in place with the discovered base - address. - - Returns: - The decoded payload. - - Raises: - Uf2Error: If a block declares an oversized payload, the blocks are out - of order, or the implied padding exceeds 10 MiB. - - Note: - The upstream Raspberry Pi version of this function crashes on its own - error paths: it builds the message with ``"..." + ptr`` where ``ptr`` - is an ``int``, which raises :class:`TypeError` and masks the real - problem. The messages here use f-strings so the diagnostic survives. - """ - numblocks = len(buf) // UF2_BLOCK_SIZE - curraddr: int | None = None - currfamilyid: int | None = None - families_found: dict[int, int] = {} - prev_flag: int | None = None - all_flags_same = True - outp: list[bytes] = [] - - for blockno in range(numblocks): - ptr = blockno * UF2_BLOCK_SIZE - block = buf[ptr : ptr + UF2_BLOCK_SIZE] - ( - magic0, - magic1, - flags, - target_addr, - datalen, - _blockno, - _numblocks, - block_family, - ) = _HEADER_STRUCT.unpack_from(block, 0) - - if magic0 != UF2_MAGIC_START0 or magic1 != UF2_MAGIC_START1: - print(f"Skipping block at {ptr:#x}; bad magic") - continue - - if flags & UF2_FLAG_NOFLASH: - continue - - if datalen > UF2_MAX_PAYLOAD: - msg = f"Invalid UF2 data size at {ptr:#x}: {datalen}" - raise Uf2Error(msg) - - if flags & UF2_FLAG_FAMILY_ID and currfamilyid is None: - currfamilyid = block_family - - # A new contiguous run starts when the address jumps or the family - # changes. appstartaddr tracks the start of the current run, which is - # what makes the reported start address the image's true base rather - # than the address of its last block. - if curraddr is None or ( - flags & UF2_FLAG_FAMILY_ID and block_family != currfamilyid - ): - currfamilyid = block_family - curraddr = target_addr - if ctx.familyid == DEFAULT_FAMILY_ID or ctx.familyid == block_family: - ctx.appstartaddr = target_addr - - padding = target_addr - curraddr - if padding < 0: - msg = f"Block out of order at {ptr:#x}: {target_addr:#x} < {curraddr:#x}" - raise Uf2Error(msg) - if padding > 10 * 1024 * 1024: - msg = f"More than 10M of padding needed at {ptr:#x}" - raise Uf2Error(msg) - if padding % 4 != 0: - msg = f"Non-word padding size at {ptr:#x}: {padding}" - raise Uf2Error(msg) - - while padding > 0: - padding -= 4 - outp.append(b"\x00\x00\x00\x00") - - if ctx.familyid == DEFAULT_FAMILY_ID or ( - flags & UF2_FLAG_FAMILY_ID and ctx.familyid == block_family - ): - outp.append( - block[UF2_HEADER_SIZE : UF2_HEADER_SIZE + datalen], - ) - - curraddr = target_addr + datalen - - if flags & UF2_FLAG_FAMILY_ID: - existing = families_found.get(block_family) - if existing is None or existing > target_addr: - families_found[block_family] = target_addr - - if prev_flag is None: - prev_flag = flags - elif prev_flag != flags: - all_flags_same = False - - if blockno == numblocks - 1: - _print_uf2_header_info(families_found, all_flags_same, flags) - if len(families_found) > 1 and ctx.familyid == DEFAULT_FAMILY_ID: - outp = [] - ctx.appstartaddr = 0x0 - - return b"".join(outp) - - -def _print_uf2_header_info( - families_found: dict[int, int], - all_flags_same: bool, - flags: int, -) -> None: - """Print the family summary block that follows a UF2->BIN conversion. - - Args: - families_found: Mapping of family ID to the lowest target address seen - for that family. - all_flags_same: Whether every block carried an identical flag word. - flags: The flag word from the final block, used for display. - """ - print("--- UF2 File Header Info ---") - families = load_families() - name_by_id = {value: key for key, value in families.items()} - for family_hex, address in families_found.items(): - short_name = name_by_id.get(family_hex, "") - print(f"Family ID is {short_name}, hex value is {family_hex:#010x}") - print(f"Target Address is {address:#010x}") - if all_flags_same: - print(f"All block flag values consistent, {flags:#06x}") - else: - print("Flags were not all the same") - print("----------------------------") - - -# --------------------------------------------------------------------------- -# BIN -> UF2 -# --------------------------------------------------------------------------- - - -def convert_to_uf2(file_content: bytes, ctx: ConverterContext) -> bytes: - """Wrap a raw binary in UF2 blocks. - - The binary is split into 256-byte payloads; the final block is zero-padded. - Each block's ``targetAddr`` is the byte offset within the image plus - :attr:`ConverterContext.appstartaddr`, so for RP2350 firmware built at - ``0x10000000`` the caller passes ``--base 0x10000000``. - - Args: - file_content: The raw image. - ctx: Conversion state supplying the base address and family ID. - - Returns: - The UF2 file contents, always a whole number of 512-byte blocks. - """ - datapadding = bytes(UF2_BLOCK_SIZE - 256 - UF2_HEADER_SIZE - 4) - numblocks = (len(file_content) + 255) // 256 - flags = UF2_FLAG_FAMILY_ID if ctx.familyid else 0x0 - base = ctx.appstartaddr or 0 - - blocks: list[bytes] = [] - for blockno in range(numblocks): - ptr = 256 * blockno - chunk = file_content[ptr : ptr + 256] - header = _HEADER_STRUCT.pack( - UF2_MAGIC_START0, - UF2_MAGIC_START1, - flags, - ptr + base, - 256, - blockno, - numblocks, - ctx.familyid, - ) - payload = chunk + bytes(256 - len(chunk)) - block = header + payload + datapadding + struct.pack(" bytes: - """Render a binary as a C array initialiser for embedding in firmware. - - Args: - file_content: The raw image. - - Returns: - UTF-8 bytes of a C translation unit fragment. - """ - parts = [ - f"const unsigned long bindata_len = {len(file_content)};\n", - "const unsigned char bindata[] __attribute__((aligned(16))) = {", - ] - for index, value in enumerate(file_content): - if index % 16 == 0: - parts.append("\n") - parts.append(f"{value:#04x}, ") - parts.append("\n};\n") - return "".join(parts).encode() - - -# --------------------------------------------------------------------------- -# Intel HEX -> UF2 -# --------------------------------------------------------------------------- - - -@dataclass -class Block: - """A single 256-byte-aligned region of an image under construction. - - Attributes: - addr: Base address of the block, always 256-byte aligned. - data: The block's bytes, initialised to ``default_data``. - """ - - addr: int - data: bytearray - - def __init__(self, addr: int, default_data: int = 0xFF) -> None: - """Initialise an erased 256-byte block. - - Args: - addr: 256-byte-aligned base address of the block. - default_data: Fill byte; ``0xFF`` matches erased flash. - """ - self.addr = addr - self.data = bytearray([default_data] * 256) - - def encode(self, blockno: int, numblocks: int, ctx: ConverterContext) -> bytes: - """Serialise this block into a 512-byte UF2 block. - - Args: - blockno: Index of this block within the file. - numblocks: Total number of blocks in the file. - ctx: Conversion state supplying the family ID. - - Returns: - Exactly 512 bytes. - """ - flags = UF2_FLAG_FAMILY_ID if ctx.familyid else 0x0 - out = _HEADER_STRUCT.pack( - UF2_MAGIC_START0, - UF2_MAGIC_START1, - flags, - self.addr, - 256, - blockno, - numblocks, - ctx.familyid, - ) - out += self.data[0:256] - out += bytes(UF2_BLOCK_SIZE - 4 - len(out)) - out += struct.pack(" bytes: - """Assemble Intel HEX records into a UF2 file. - - Only record types 0x00 (data), 0x01 (EOF), 0x02 (extended segment address) - and 0x04 (extended linear address) are handled; any other type is ignored, - matching the upstream behaviour. - - Args: - text: Decoded Intel HEX file contents. - ctx: Conversion state; ``appstartaddr`` is set to the first data - address seen. - - Returns: - The UF2 file contents. - """ - ctx.appstartaddr = None - upper = 0 - currblock: Block | None = None - blocks: list[Block] = [] - - for line in text.split("\n"): - if not line.startswith(":"): - continue - record = [int(line[i : i + 2], 16) for i in range(1, len(line) - 1, 2)] - rec_type = record[3] - if rec_type == 4: - upper = ((record[4] << 8) | record[5]) << 16 - elif rec_type == 2: - upper = ((record[4] << 8) | record[5]) << 4 - elif rec_type == 1: - break - elif rec_type == 0: - addr = upper + ((record[1] << 8) | record[2]) - if ctx.appstartaddr is None: - ctx.appstartaddr = addr - index = 4 - while index < len(record) - 1: - if currblock is None or currblock.addr & ~0xFF != addr & ~0xFF: - currblock = Block(addr & ~0xFF) - blocks.append(currblock) - currblock.data[addr & 0xFF] = record[index] - addr += 1 - index += 1 - - numblocks = len(blocks) - return b"".join(blocks[i].encode(i, numblocks, ctx) for i in range(numblocks)) - - -# --------------------------------------------------------------------------- -# Drive discovery -# --------------------------------------------------------------------------- - - -def _iter_candidate_dirs() -> list[Path]: - """Return the directories that may contain mounted removable volumes.""" - if sys.platform == "win32": - return [] - - searchpaths = [Path("/mnt"), Path("/media")] - if sys.platform == "darwin": - searchpaths = [Path("/Volumes")] - elif sys.platform == "linux": - user = environ_user() - if user: - searchpaths += [Path("/media") / user, Path("/run/media") / user] - sudo_user = os.environ.get("SUDO_USER") - if sudo_user: - searchpaths += [ - Path("/media") / sudo_user, - Path("/run/media") / sudo_user, - ] - return searchpaths - - -def environ_user() -> str | None: - """Return the current user name from the environment. - - Tried under several variable names so the search works on macOS, Linux and - Windows shells alike. - - Returns: - The user name, or ``None`` if it cannot be determined. - """ - for var in ("USER", "USERNAME", "LOGNAME"): - value = os.environ.get(var) - if value: - return value - return None - - -def get_drives() -> list[Path]: - """Find mounted Pico boot drives. - - A drive qualifies when it contains the ``INFO_UF2.TXT`` marker the boot ROM - writes when it presents the flash as a USB mass-storage device. - - Returns: - Every qualifying mount point. - """ - drives: list[Path] = [] - - if sys.platform == "win32": - command = ( - "(Get-Volume | Where-Object { $_.FileSystemLabel -match 'RP2350|RPI-RP2' })" - ".DriveLetter" - ) - try: - raw = subprocess.check_output( - ["powershell", "-Command", command], - text=True, - ) - except (subprocess.CalledProcessError, FileNotFoundError, OSError): - return [] - for letter in raw.split(): - if len(letter) == 1 and letter.isalpha(): - drives.append(Path(f"{letter.upper()}:\\")) - return drives - - for rootpath in _iter_candidate_dirs(): - if not rootpath.is_dir(): - continue - try: - entries = list(rootpath.iterdir()) - except OSError: - continue - for entry in entries: - if not entry.is_dir(): - continue - if (entry / INFO_FILE).is_file(): - drives.append(entry) - return drives - - -def board_id(path: Path) -> str: - """Read the ``Board-ID`` field from a boot drive's info file. - - Args: - path: Mount point of the boot drive. - - Returns: - The board ID string, for example ``RP2350``. - - Raises: - Uf2Error: If the info file is missing or has no ``Board-ID`` field. - """ - info = path / INFO_FILE - if not info.is_file(): - msg = f"Not a Pico boot drive: {path} has no {INFO_FILE}" - raise Uf2Error(msg) - match = re.search(r"Board-ID: ([^\r\n]*)", info.read_text()) - if match is None: - msg = f"No Board-ID field in {info}" - raise Uf2Error(msg) - return match.group(1) - - -def list_drives() -> None: - """Print every connected Pico boot drive and its board ID.""" - for drive in get_drives(): - try: - print(drive, board_id(drive)) - except Uf2Error as exc: - print(f"{drive} ") - - -def write_file(name: Path | str, buf: bytes) -> None: - """Write a buffer to disk and report the size written. - - Args: - name: Destination path. - buf: Bytes to write. - """ - path = Path(name) - path.parent.mkdir(parents=True, exist_ok=True) - path.write_bytes(buf) - print(f"Wrote {len(buf)} bytes to {path}") - - -def load_families() -> dict[str, int]: - """Load the family-name to family-ID table. - - ``uf2families.json`` is read from the directory containing this script, so - the converter works regardless of the caller's working directory. - - Returns: - Mapping of upper-case short name to family ID. - - Raises: - Uf2Error: If the JSON file is missing or malformed. - """ - pathname = Path(__file__).resolve().parent / "uf2families.json" - try: - raw_families = json.loads(pathname.read_text()) - except FileNotFoundError as exc: - msg = f"Required family table not found: {pathname}" - raise Uf2Error(msg) from exc - except json.JSONDecodeError as exc: - msg = f"Malformed family table {pathname}: {exc}" - raise Uf2Error(msg) from exc - - return {fam["short_name"]: int(fam["id"], 0) for fam in raw_families} - - -# --------------------------------------------------------------------------- -# CLI -# --------------------------------------------------------------------------- - - -def _build_parser() -> argparse.ArgumentParser: - """Construct the command-line argument parser. - - Returns: - A configured :class:`argparse.ArgumentParser`. - """ - parser = argparse.ArgumentParser( - prog="uf2conv.py", - description="Convert firmware between Intel HEX, raw BIN and UF2.", - epilog=( - "Course example (RP2350 raw image built for XIP flash):\n" - " python ../uf2conv.py build/image-h.bin " - "--base 0x10000000 \\\n" - " --family 0xe48bff59 --output build/hacked.uf2\n" - ), - formatter_class=argparse.RawDescriptionHelpFormatter, - ) - parser.add_argument( - "input", - metavar="INPUT", - nargs="?", - help="input file (HEX, BIN or UF2); omit when using --list", - ) - parser.add_argument( - "-b", - "--base", - default=hex(DEFAULT_BASE_ADDRESS), - help=( - "base address of the application for BIN input " - f"(default: {hex(DEFAULT_BASE_ADDRESS)}; use 0x10000000 for RP2350 XIP)" - ), - ) - parser.add_argument( - "-f", - "--family", - default=hex(DEFAULT_FAMILY_ID), - help=( - "family ID as a number or a name from uf2families.json " - f"(default: {hex(DEFAULT_FAMILY_ID)}; RP2350 is 0xe48bff59)" - ), - ) - parser.add_argument( - "-o", - "--output", - metavar="FILE", - help='write output to FILE; defaults to "flash.uf2" or "flash.bin"', - ) - parser.add_argument( - "-d", - "--device", - dest="device_path", - help="select a specific device path to flash (reserved; unused)", - ) - parser.add_argument( - "-l", - "--list", - action="store_true", - help="list connected Pico boot drives and exit", - ) - parser.add_argument( - "-c", - "--convert", - action="store_true", - help="convert only; do not deploy to a mounted boot drive", - ) - parser.add_argument( - "-D", - "--deploy", - action="store_true", - help="deploy the input file unchanged; do not convert", - ) - parser.add_argument( - "-w", - "--wait", - action="store_true", - help="poll for a boot drive to appear instead of failing immediately", - ) - parser.add_argument( - "-C", - "--carray", - action="store_true", - help="emit a C array initialiser instead of a UF2 file", - ) - parser.add_argument( - "-i", - "--info", - action="store_true", - help="print UF2 header information and exit without converting", - ) - return parser - - -def _resolve_family(spec: str) -> int: - """Resolve a ``--family`` value to a numeric family ID. - - Args: - spec: Either a family short name (case-insensitive) or an integer - literal such as ``0xe48bff59``. - - Returns: - The numeric family ID. - - Raises: - Uf2Error: If the value is neither a known name nor a valid integer. - """ - families = load_families() - if spec.upper() in families: - return families[spec.upper()] - try: - return int(spec, 0) - except ValueError as exc: - msg = "Family ID needs to be a number or one of: " + ", ".join(families) - raise Uf2Error(msg) from exc - - -def _wait_for_drive() -> Path | None: - """Poll for a boot drive to be mounted. - - Returns: - The first drive found, or ``None`` if the wait was interrupted. - """ - print("Waiting for drive to deploy...") - while True: - drives = get_drives() - if drives: - return drives[0] - sleep(0.1) - - -def main(argv: list[str] | None = None) -> int: - """Run the command-line converter. - - Args: - argv: Argument list, defaulting to :data:`sys.argv` ``[1:]``. - - Returns: - ``0`` on success, ``1`` on a user or input error. - """ - parser = _build_parser() - args = parser.parse_args(argv) - - ctx = ConverterContext() - try: - ctx.familyid = _resolve_family(args.family) - ctx.appstartaddr = int(args.base, 0) - except (Uf2Error, ValueError) as exc: - print(exc, file=sys.stderr) - return 1 - - if args.list: - list_drives() - return 0 - - if not args.input: - print("Need an input file (or use --list)", file=sys.stderr) - return 1 - - source = Path(args.input) - if not source.is_file(): - print(f"error: file not found: {source}", file=sys.stderr) - return 1 - - inpbuf = source.read_bytes() - from_uf2 = is_uf2(inpbuf) - ext = "uf2" - - try: - if args.deploy: - outbuf = inpbuf - elif from_uf2 and not args.info: - outbuf = convert_from_uf2(inpbuf, ctx) - ext = "bin" - elif from_uf2 and args.info: - outbuf = b"" - convert_from_uf2(inpbuf, ctx) - elif is_hex(inpbuf): - outbuf = convert_from_hex_to_uf2(inpbuf.decode("utf-8"), ctx) - elif args.carray: - outbuf = convert_to_carray(inpbuf) - ext = "h" - else: - outbuf = convert_to_uf2(inpbuf, ctx) - except Uf2Error as exc: - print(f"error: {exc}", file=sys.stderr) - return 1 - - if not args.deploy and not args.info: - print( - f"Converted to {ext}, output size: {len(outbuf)}, " - f"start address: {ctx.appstartaddr or 0:#x}", - ) - - if (args.convert or ext != "uf2") and args.output is None: - args.output = f"flash.{ext}" - if args.output: - write_file(args.output, outbuf) - - if ext == "uf2" and not args.convert and not args.info: - drives = get_drives() - if not drives: - if args.wait: - found = _wait_for_drive() - drives = [found] if found else [] - elif not args.output: - print("error: no drive to deploy", file=sys.stderr) - return 1 - for drive in drives: - print(f"Flashing {drive} ({board_id(drive)})") - write_file(drive / "NEW.UF2", outbuf) - - return 0 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/0x0014a_cb/scripts/uf2families.json b/0x0014a_cb/scripts/uf2families.json deleted file mode 100644 index 39373c4..0000000 --- a/0x0014a_cb/scripts/uf2families.json +++ /dev/null @@ -1,22 +0,0 @@ -[ - { - "short_name": "RP2040", - "id": "0xe48bff56", - "description": "Raspberry Pi RP2040" - }, - { - "short_name": "RP2350-ARM-S", - "id": "0xe48bff59", - "description": "Raspberry Pi RP2350, ARM, Secure" - }, - { - "short_name": "RP2350-ARM-NS", - "id": "0xe48bff5a", - "description": "Raspberry Pi RP2350, ARM, Non-Secure" - }, - { - "short_name": "RP2350-RISCV", - "id": "0xe48bff5b", - "description": "Raspberry Pi RP2350, RISC-V" - } -] \ No newline at end of file diff --git a/0x0014a_cb/src/crypto.c b/0x0014a_cb/src/crypto.c deleted file mode 100644 index 28cac39..0000000 --- a/0x0014a_cb/src/crypto.c +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @file crypto.c - * @brief Lightweight rolling cipher implementation for Operation Zero Hour ESA - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#include "crypto.h" - -static const uint8_t CIPHERTEXT[TOKEN_LEN] = { - 0x07, 0x03, 0x03, 0x12, 0x07, 0x7F, 0x70, 0x7A -}; - -static const uint8_t CIPHER_KEY[4] = { - 0x54, 0x41, 0x43, 0x54 -}; - -void decrypt_auth_token(uint8_t *dest) { - volatile const uint8_t *src = CIPHERTEXT; - volatile const uint8_t *key = CIPHER_KEY; - for (size_t i = 0; i < TOKEN_LEN; i++) { - dest[i] = src[i] ^ (key[i % 4] + (uint8_t)i); - } -} diff --git a/0x0014a_cb/src/gpio_ctrl.c b/0x0014a_cb/src/gpio_ctrl.c deleted file mode 100644 index d5a8661..0000000 --- a/0x0014a_cb/src/gpio_ctrl.c +++ /dev/null @@ -1,60 +0,0 @@ -/** - * @file gpio_ctrl.c - * @brief GPIO hardware control implementation for Operation Zero Hour ESA - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#include "gpio_ctrl.h" -#include "pico/stdlib.h" - -/** - * @brief Initialize the red and green LED pins as outputs. - * @param void No parameters. - * @return void No return value. - */ -static void init_led_pins(void) { - gpio_init(LED_RED_PIN); - gpio_set_dir(LED_RED_PIN, GPIO_OUT); - gpio_init(LED_GREEN_PIN); - gpio_set_dir(LED_GREEN_PIN, GPIO_OUT); -} - -/** - * @brief Initialize the tamper wire pin as a pulled-down input. - * @param void No parameters. - * @return void No return value. - */ -static void init_tamper_pin(void) { - gpio_init(TAMPER_WIRE_PIN); - gpio_set_dir(TAMPER_WIRE_PIN, GPIO_IN); - gpio_pull_down(TAMPER_WIRE_PIN); -} - -void init_gpio(void) { - init_led_pins(); - init_tamper_pin(); - set_led_armed(); -} - -void set_led_armed(void) { - gpio_put(LED_RED_PIN, 1); - gpio_put(LED_GREEN_PIN, 0); -} - -void set_led_safe(void) { - gpio_put(LED_RED_PIN, 0); - gpio_put(LED_GREEN_PIN, 1); -} - -void set_led_tamper_flash(bool state) { - gpio_put(LED_RED_PIN, state ? 1 : 0); - gpio_put(LED_GREEN_PIN, 0); -} - -bool is_tamper_wire_intact(void) { - return gpio_get(TAMPER_WIRE_PIN); -} diff --git a/0x0014a_cb/src/lora.c b/0x0014a_cb/src/lora.c deleted file mode 100644 index 82928e9..0000000 --- a/0x0014a_cb/src/lora.c +++ /dev/null @@ -1,151 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: lora.c -// Desc: Implements UART1 driver for REYAX RYLR998 LoRa transceiver. -// Created: 2026 - -#include "lora.h" -#include "hardware/gpio.h" -#include "pico/stdlib.h" -#include -#include - -/** - * @brief Discard all pending bytes from the LoRa UART receive FIFO. - * @param void No parameters. - * @return void No return value. - */ -static void drain_lora_rx(void) { - while (uart_is_readable(LORA_UART)) { - (void)uart_getc(LORA_UART); - } -} - -/** - * @brief Send an AT command to the radio and drain its response. - * @param cmd Null-terminated AT command string to transmit. - * @return void No return value. - */ -static void send_at_cmd(const char *cmd) { - uart_write_blocking(LORA_UART, (const uint8_t *)cmd, strlen(cmd)); - sleep_ms(200); - drain_lora_rx(); -} - -/** - * @brief Program the RYLR998 RF parameters via the AT command set. - * @param void No parameters. - * @return void No return value. - */ -static void configure_lora_rf(void) { - sleep_ms(1500); - send_at_cmd("AT\r\n"); - send_at_cmd("AT+NETWORKID=18\r\n"); - send_at_cmd("AT+BAND=915000000\r\n"); - send_at_cmd("AT+PARAMETER=9,7,1,12\r\n"); - send_at_cmd("AT+ADDRESS=2\r\n"); -} - -void init_lora(void) { - uart_init(LORA_UART, LORA_BAUD); - uart_set_translate_crlf(LORA_UART, false); - gpio_set_function(LORA_TX_PIN, GPIO_FUNC_UART); - gpio_set_function(LORA_RX_PIN, GPIO_FUNC_UART); - configure_lora_rf(); -} - -void lora_send(const char *msg) { - char cmd[128]; - int len = (int)strlen(msg); - snprintf(cmd, sizeof(cmd), "AT+SEND=0,%d,%s\r\n", len, msg); - uart_write_blocking(LORA_UART, (const uint8_t *)cmd, strlen(cmd)); -} - -/** - * @brief Extract the payload field from a +RCV receive line. - * @param line Mutable receive line buffer to parse. - * @param out Buffer receiving the extracted payload string. - * @param max_len Capacity of out in bytes. - * @return true when the payload was extracted, false otherwise. - */ -static bool extract_rcv_data(char *line, char *out, size_t max_len) { - char *c1 = strchr(line, ','); - if (!c1) return false; - char *c2 = strchr(c1 + 1, ','); - if (!c2) return false; - char *c3 = strchr(c2 + 1, ','); - if (c3) *c3 = '\0'; - snprintf(out, max_len, "%s", c2 + 1); - return true; -} - -/** - * @brief Parse one complete UART line and capture payload data. - * @param line Mutable line buffer to parse. - * @param out Buffer receiving the extracted payload string. - * @param max_len Capacity of out in bytes. - * @return true when the line carried payload data, false otherwise. - */ -static bool parse_line(char *line, char *out, size_t max_len) { - if (strstr(line, "+RCV=")) - return extract_rcv_data(line, out, max_len); - if (strncmp(line, "+", 1) != 0 && strncmp(line, "OK", 2) != 0) { - snprintf(out, max_len, "%s", line); - return true; - } - return false; -} - -/** - * @brief Feed one received byte into the line assembly state machine. - * @param c Received byte to process. - * @param buf Line assembly buffer. - * @param idx Pointer to the current write index into buf. - * @param out Buffer receiving the extracted payload string. - * @param max_len Capacity of out in bytes. - * @return true when a complete payload was produced, false otherwise. - */ -static bool process_rx_byte(char c, char *buf, size_t *idx, char *out, size_t max_len) { - if (c == '\r' || c == '\n') { - buf[*idx] = '\0'; - bool ok = (*idx > 0) && parse_line(buf, out, max_len); - *idx = 0; - return ok; - } - if (*idx < 127) buf[(*idx)++] = c; - return false; -} - -bool lora_poll_packet(char *payload_out, size_t max_len) { - static char buf[128]; - static size_t idx = 0; - while (uart_is_readable(LORA_UART)) { - char c = (char)uart_getc(LORA_UART); - if (process_rx_byte(c, buf, &idx, payload_out, max_len)) - return true; - } - return false; -} diff --git a/0x0014a_cb/src/main.c b/0x0014a_cb/src/main.c deleted file mode 100644 index bbe8449..0000000 --- a/0x0014a_cb/src/main.c +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file main.c - * @brief Operation Zero Hour - Electronic Safe-and-Arm (ESA) Firmware - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#include "pico/stdlib.h" -#include "gpio_ctrl.h" -#include "safe_arm.h" - -/** - * @brief Initialize stdio, GPIO, and the safe-and-arm controller. - * @param void No parameters. - * @return void No return value. - */ -static void init_system(void) { - stdio_init_all(); - init_gpio(); - init_safe_arm_controller(); -} - -/** - * @brief Run the main event loop, servicing one tick per iteration. - * @param void No parameters. - * @return void No return value. - */ -static void run_event_loop(void) { - while (true) { - process_safe_arm_tick(); - sleep_ms(100); - } -} - -int main(void) { - init_system(); - run_event_loop(); - return 0; -} diff --git a/0x0014a_cb/src/safe_arm.c b/0x0014a_cb/src/safe_arm.c deleted file mode 100644 index eba79ac..0000000 --- a/0x0014a_cb/src/safe_arm.c +++ /dev/null @@ -1,133 +0,0 @@ -/** - * @file safe_arm.c - * @brief Electronic Safe-and-Arm (ESA) controller implementation - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#include "safe_arm.h" -#include "crypto.h" -#include "gpio_ctrl.h" -#include "lora.h" -#include -#include - -static uint8_t s_disarm_token[TOKEN_LEN + 1]; - -/** - * @brief Print the armed status banner to the console. - * @param void No parameters. - * @return void No return value. - */ -static void print_banner_armed(void) { - printf("\r\n+-----------------------------------------------------------------+\r\n"); - printf("| OPERATION ZERO HOUR // ESA CONTROLLER |\r\n"); - printf("| STATUS: WARHEAD ARMED [GP16 RED: ON] LORA RECEIVER: LIVE |\r\n"); - printf("+-----------------------------------------------------------------+\r\n"); -} - -/** - * @brief Print the disarmed status banner with the recovered token. - * @param token Null-terminated recovered disarm token string. - * @return void No return value. - */ -static void print_banner_safe(const uint8_t *token) { - printf("\r\n+-----------------------------------------------------------------+\r\n"); - printf("| WARHEAD DISARMED // SAFE [GP17 GREEN: ON] |\r\n"); - printf("| RECOVERED TOKEN: %-8.8s // FUZE NEUTRALIZED |\r\n", token); - printf("+-----------------------------------------------------------------+\r\n"); -} - -/** - * @brief Print the tamper detonation trip banner to the console. - * @param void No parameters. - * @return void No return value. - */ -static void print_banner_trip(void) { - printf("\r\n+-----------------------------------------------------------------+\r\n"); - printf("| TAMPER DETONATION TRIP [GP16 RED: FLASH] |\r\n"); - printf("| STATUS: COMMAND DETONATION ACTIVATED // EXPLOSIVE TRAIN ENGAGED |\r\n"); - printf("+-----------------------------------------------------------------+\r\n"); -} - -/** - * @brief Evaluate a received command against the disarm token. - * @param cmd Null-terminated received command string. - * @param state Pointer to the current warhead state byte. - * @param faults Pointer to the tamper fault counter. - * @return void No return value. - */ -static void eval_command(const char *cmd, uint8_t *state, uint8_t *faults) { - if (strncmp(cmd, (const char *)s_disarm_token, TOKEN_LEN) == 0) { - *state = STATE_WARHEAD_SAFE; - lora_send("WARHEAD DISARMED // SAFE"); - print_banner_safe(s_disarm_token); - } else { - (*faults)++; - } -} - -/** - * @brief Trip the warhead when fault limits or tamper wire demand it. - * @param faults Current tamper fault count. - * @param state Pointer to the current warhead state byte. - * @return void No return value. - */ -static void check_tamper(uint8_t faults, uint8_t *state) { - if (*state == STATE_WARHEAD_ARMED && (faults >= 3 || !is_tamper_wire_intact())) { - *state = STATE_TAMPER_TRIP; - print_banner_trip(); - } -} - -/** - * @brief Dispatch a received packet through command and tamper logic. - * @param has_pkt True when a packet was received this tick. - * @param pkt Null-terminated received packet payload string. - * @param state Pointer to the current warhead state byte. - * @param faults Pointer to the tamper fault counter. - * @return void No return value. - */ -static void handle_packet(bool has_pkt, const char *pkt, uint8_t *state, uint8_t *faults) { - if (has_pkt && *state != STATE_WARHEAD_SAFE) { - eval_command(pkt, state, faults); - check_tamper(*faults, state); - } -} - -/** - * @brief Drive LED feedback for the current warhead state. - * @param state Current warhead state byte. - * @param tick_idx Monotonic loop tick index for flash timing. - * @return void No return value. - */ -static void update_feedback(uint8_t state, uint32_t tick_idx) { - if (state == STATE_WARHEAD_SAFE) { - set_led_safe(); - } else if (state == STATE_TAMPER_TRIP) { - set_led_tamper_flash((tick_idx % 2) == 0); - } else { - set_led_armed(); - } -} - -void process_safe_arm_tick(void) { - static uint8_t warhead_state = STATE_WARHEAD_ARMED; - static uint8_t tamper_faults = 0; - static uint32_t loop_ticks = 0; - char rx_pkt[64] = {0}; - bool has_pkt = lora_poll_packet(rx_pkt, sizeof(rx_pkt)); - handle_packet(has_pkt, rx_pkt, &warhead_state, &tamper_faults); - check_tamper(tamper_faults, &warhead_state); - update_feedback(warhead_state, loop_ticks++); -} - -void init_safe_arm_controller(void) { - decrypt_auth_token(s_disarm_token); - s_disarm_token[TOKEN_LEN] = '\0'; - init_lora(); - print_banner_armed(); -} diff --git a/0x0017_constants/.gitignore b/0x0017_constants/.gitignore deleted file mode 100644 index 2435c20..0000000 --- a/0x0017_constants/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -!.vscode/* diff --git a/0x0017_constants/.vscode/c_cpp_properties.json b/0x0017_constants/.vscode/c_cpp_properties.json deleted file mode 100644 index c429d6d..0000000 --- a/0x0017_constants/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "configurations": [ - { - "name": "Pico", - "includePath": [ - "${workspaceFolder}/**", - "${userHome}/.pico-sdk/sdk/2.2.0/**" - ], - "forcedInclude": [ - "${workspaceFolder}/build/generated/pico_base/pico/config_autogen.h", - "${userHome}/.pico-sdk/sdk/2.2.0/src/common/pico_base_headers/include/pico.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 -} diff --git a/0x0017_constants/.vscode/cmake-kits.json b/0x0017_constants/.vscode/cmake-kits.json deleted file mode 100644 index b0f3815..0000000 --- a/0x0017_constants/.vscode/cmake-kits.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "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}" - } - } -] \ No newline at end of file diff --git a/0x0017_constants/.vscode/extensions.json b/0x0017_constants/.vscode/extensions.json deleted file mode 100644 index a940d7c..0000000 --- a/0x0017_constants/.vscode/extensions.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "recommendations": [ - "marus25.cortex-debug", - "ms-vscode.cpptools", - "ms-vscode.cpptools-extension-pack", - "ms-vscode.vscode-serial-monitor", - "raspberry-pi.raspberry-pi-pico" - ] -} \ No newline at end of file diff --git a/0x0017_constants/.vscode/launch.json b/0x0017_constants/.vscode/launch.json deleted file mode 100644 index 424aa71..0000000 --- a/0x0017_constants/.vscode/launch.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "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}\"" - ] - }, - ] -} diff --git a/0x0017_constants/.vscode/settings.json b/0x0017_constants/.vscode/settings.json deleted file mode 100644 index 8aecbe6..0000000 --- a/0x0017_constants/.vscode/settings.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "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", - "files.associations": { - "stdlib.h": "c" - } -} diff --git a/0x0017_constants/.vscode/tasks.json b/0x0017_constants/.vscode/tasks.json deleted file mode 100644 index d1b3193..0000000 --- a/0x0017_constants/.vscode/tasks.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Compile Project", - "type": "process", - "isBuildCommand": true, - "command": "${userHome}/.pico-sdk/ninja/v1.12.1/ninja", - "args": ["-C", "${workspaceFolder}/build"], - "group": "build", - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": "$gcc", - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/ninja/v1.12.1/ninja.exe" - } - }, - { - "label": "Run Project", - "type": "process", - "command": "${env:HOME}/.pico-sdk/picotool/2.2.0-a4/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-a4/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", - } - } - ] -} diff --git a/0x0017_constants/0x0017_constants.c b/0x0017_constants/0x0017_constants.c deleted file mode 100644 index b762ca1..0000000 --- a/0x0017_constants/0x0017_constants.c +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include -#include "pico/stdlib.h" -#include "hardware/i2c.h" -#include "lcd_1602.h" - -#define FAV_NUM 42 - -#define I2C_PORT i2c1 -#define I2C_SDA_PIN 2 -#define I2C_SCL_PIN 3 - -const int OTHER_FAV_NUM = 1337; - -int main(void) { - stdio_init_all(); - - i2c_init(I2C_PORT, 100000); - gpio_set_function(I2C_SDA_PIN, GPIO_FUNC_I2C); - gpio_set_function(I2C_SCL_PIN, GPIO_FUNC_I2C); - gpio_pull_up(I2C_SDA_PIN); - gpio_pull_up(I2C_SCL_PIN); - - lcd_i2c_init(I2C_PORT, 0x27, 4, 0x08); - - lcd_set_cursor(0, 0); - lcd_puts("Reverse"); - lcd_set_cursor(1, 0); - lcd_puts("Engineering"); - - while (true) { - printf("FAV_NUM: %d\r\n", FAV_NUM); - printf("OTHER_FAV_NUM: %d\r\n", OTHER_FAV_NUM); - } -} diff --git a/0x0017_constants/CMakeLists.txt b/0x0017_constants/CMakeLists.txt deleted file mode 100644 index 4c75aa3..0000000 --- a/0x0017_constants/CMakeLists.txt +++ /dev/null @@ -1,59 +0,0 @@ -# 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-a4) -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(0x0017_constants 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(0x0017_constants 0x0017_constants.c lcd_1602.c) - -pico_set_program_name(0x0017_constants "0x0017_constants") -pico_set_program_version(0x0017_constants "0.1") - -# Modify the below lines to enable/disable output over UART/USB -pico_enable_stdio_uart(0x0017_constants 1) -pico_enable_stdio_usb(0x0017_constants 0) - -# Add the standard library to the build -target_link_libraries(0x0017_constants - pico_stdlib - hardware_i2c - hardware_gpio) - -# Add the standard include files to the build -target_include_directories(0x0017_constants PRIVATE - ${CMAKE_CURRENT_LIST_DIR} -) - -pico_add_extra_outputs(0x0017_constants) - diff --git a/0x0017_constants/lcd_1602.c b/0x0017_constants/lcd_1602.c deleted file mode 100644 index 7425cf1..0000000 --- a/0x0017_constants/lcd_1602.c +++ /dev/null @@ -1,114 +0,0 @@ -/** - * @file lcd_1602.c - * @brief Implementation of PCF8574-backed HD44780 (16x2) LCD 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 "lcd_1602.h" -#include -#include - -static i2c_inst_t *lcd_i2c = NULL; -static uint8_t lcd_addr = 0x27; -static int lcd_nibble_shift = 4; -static uint8_t lcd_backlight_mask = 0x08; - -/* PCF8574 -> LCD control pins */ -#define PIN_RS 0x01 -#define PIN_RW 0x02 -#define PIN_EN 0x04 - -static void pcf_write_byte(uint8_t data) { - if (!lcd_i2c) return; - i2c_write_blocking(lcd_i2c, lcd_addr, &data, 1, false); -} - -static void pcf_pulse_enable(uint8_t data) { - pcf_write_byte(data | PIN_EN); - sleep_us(1); - pcf_write_byte(data & ~PIN_EN); - sleep_us(50); -} - -static void lcd_write4(uint8_t nibble, uint8_t mode) { - uint8_t data = (nibble & 0x0F) << lcd_nibble_shift; - data |= mode ? PIN_RS : 0; - data |= lcd_backlight_mask; - pcf_pulse_enable(data); -} - -static void lcd_send(uint8_t value, uint8_t mode) { - lcd_write4((value >> 4) & 0x0F, mode); - lcd_write4(value & 0x0F, mode); -} - -void lcd_i2c_init(i2c_inst_t *i2c, uint8_t pcf_addr, int nibble_shift, uint8_t backlight_mask) { - lcd_i2c = i2c; - lcd_addr = pcf_addr; - lcd_nibble_shift = nibble_shift; - lcd_backlight_mask = backlight_mask; - - // Follow init sequence for HD44780 in 4-bit mode - lcd_write4(0x03, 0); - sleep_ms(5); - lcd_write4(0x03, 0); - sleep_us(150); - lcd_write4(0x03, 0); - sleep_us(150); - lcd_write4(0x02, 0); - sleep_us(150); - - // Function set: 4-bit, 2 lines - lcd_send(0x28, 0); - - // Display on, cursor off - lcd_send(0x0C, 0); - - // Clear - lcd_send(0x01, 0); - sleep_ms(2); - - // Entry mode set - lcd_send(0x06, 0); -} - -void lcd_clear(void) { - lcd_send(0x01, 0); - sleep_ms(2); -} - -void lcd_set_cursor(int line, int position) { - const uint8_t row_offsets[] = {0x00, 0x40}; - - if (line > 1) line = 1; - lcd_send(0x80 | (position + row_offsets[line]), 0); -} - -void lcd_puts(const char *s) { - while (*s) { - lcd_send((uint8_t)*s++, 1); - } -} diff --git a/0x0017_constants/lcd_1602.h b/0x0017_constants/lcd_1602.h deleted file mode 100644 index 072ae13..0000000 --- a/0x0017_constants/lcd_1602.h +++ /dev/null @@ -1,74 +0,0 @@ -/** - * @file lcd_1602.h - * @brief Header for PCF8574-backed HD44780 (16x2) LCD 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 LCD_1602_H -#define LCD_1602_H - -#include -#include "pico/stdlib.h" -#include "hardware/i2c.h" - -/** - * @brief Initialize the LCD driver over I2C - * - * Configures the internal driver state and performs the HD44780 initialization - * sequence. The driver does not configure I2C pins or call i2c_init; that - * must be done by the caller prior to calling this function. - * - * @param i2c Pointer to the I2C instance (e.g. i2c0 or i2c1) - * @param pcf_addr PCF8574 I2C address (commonly 0x27 or 0x3F) - * @param nibble_shift Bit shift applied to 4-bit nibbles (commonly 4 or 0) - * @param backlight_mask PCF8574 bit mask that controls the backlight - */ -void lcd_i2c_init(i2c_inst_t *i2c, uint8_t pcf_addr, int nibble_shift, uint8_t backlight_mask); - -/** - * @brief Clear the LCD display - * - * Clears the display and returns the cursor to the home position. This - * call blocks for the duration required by the HD44780 controller. - */ -void lcd_clear(void); - -/** - * @brief Set the cursor position - * - * @param line Line number (0 or 1) - * @param position Column (0..15) - */ -void lcd_set_cursor(int line, int position); - -/** - * @brief Write a null-terminated string to the display - * - * @param s The string to write (ASCII) - */ -void lcd_puts(const char *s); - -#endif // LCD_1602_H diff --git a/0x0017_constants/pico_sdk_import.cmake b/0x0017_constants/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x0017_constants/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x0017a_ctf/.gitignore b/0x0017a_ctf/.gitignore deleted file mode 100644 index de8404a..0000000 --- a/0x0017a_ctf/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -build -!.vscode/* -!build-ctf/CTF-02.bin -!CTF-02.bin diff --git a/0x0017a_ctf/.vscode/c_cpp_properties.json b/0x0017a_ctf/.vscode/c_cpp_properties.json deleted file mode 100644 index 613c996..0000000 --- a/0x0017a_ctf/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "configurations": [ - { - "name": "Pico", - "includePath": [ - "${workspaceFolder}/**", - "${userHome}/.pico-sdk/sdk/2.3.1/**" - ], - "forcedInclude": [ - "${workspaceFolder}/build/generated/pico_base/pico/config_autogen.h", - "${userHome}/.pico-sdk/sdk/2.3.1/src/common/pico_base_headers/include/pico.h" - ], - "defines": [], - "compilerPath": "${userHome}/.pico-sdk/toolchain/15_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 -} diff --git a/0x0017a_ctf/.vscode/cmake-kits.json b/0x0017a_ctf/.vscode/cmake-kits.json deleted file mode 100644 index b0f3815..0000000 --- a/0x0017a_ctf/.vscode/cmake-kits.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "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}" - } - } -] \ No newline at end of file diff --git a/0x0017a_ctf/.vscode/extensions.json b/0x0017a_ctf/.vscode/extensions.json deleted file mode 100644 index a940d7c..0000000 --- a/0x0017a_ctf/.vscode/extensions.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "recommendations": [ - "marus25.cortex-debug", - "ms-vscode.cpptools", - "ms-vscode.cpptools-extension-pack", - "ms-vscode.vscode-serial-monitor", - "raspberry-pi.raspberry-pi-pico" - ] -} \ No newline at end of file diff --git a/0x0017a_ctf/.vscode/launch.json b/0x0017a_ctf/.vscode/launch.json deleted file mode 100644 index 451b846..0000000 --- a/0x0017a_ctf/.vscode/launch.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "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}", - "debuggerArgs": ["-ex", "set debug-file-directory /debug"], - "device": "${command:raspberry-pi-pico.getChipUppercase}", - "configFiles": [ - "interface/cmsis-dap.cfg", - "target/${command:raspberry-pi-pico.getTarget}.cfg" - ], - "svdFile": "${userHome}/.pico-sdk/sdk/2.3.1/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}", - "debuggerArgs": ["-ex", "set debug-file-directory /debug"], - "device": "${command:raspberry-pi-pico.getChipUppercase}", - "svdFile": "${userHome}/.pico-sdk/sdk/2.3.1/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}\"" - ] - } - ] -} diff --git a/0x0017a_ctf/.vscode/settings.json b/0x0017a_ctf/.vscode/settings.json deleted file mode 100644 index 5b883ba..0000000 --- a/0x0017a_ctf/.vscode/settings.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "cmake.showSystemKits": false, - "cmake.options.statusBarVisibility": "hidden", - "cmake.options.advanced": { - "build": { - "statusBarVisibility": "hidden" - }, - "launch": { - "statusBarVisibility": "hidden" - }, - "debug": { - "statusBarVisibility": "hidden" - }, - "variant": { - "statusBarVisibility": "hidden" - }, - "buildTarget": { - "statusBarVisibility": "hidden" - } - }, - "cmake.configureOnEdit": false, - "cmake.automaticReconfigure": false, - "cmake.configureOnOpen": false, - "cmake.generator": "Ninja", - "cmake.cmakePath": "${userHome}/.pico-sdk/cmake/v4.3.4/bin/cmake", - "C_Cpp.debugShortcut": false, - "terminal.integrated.env.windows": { - "PICO_SDK_PATH": "${env:USERPROFILE}/.pico-sdk/sdk/2.3.1", - "PICO_TOOLCHAIN_PATH": "${env:USERPROFILE}/.pico-sdk/toolchain/15_2_Rel1", - "Path": "${env:USERPROFILE}/.pico-sdk/toolchain/15_2_Rel1/bin;${env:USERPROFILE}/.pico-sdk/picotool/2.3.1/picotool;${env:USERPROFILE}/.pico-sdk/cmake/v4.3.4/bin;${env:USERPROFILE}/.pico-sdk/ninja/v1.13.2;${env:PATH}" - }, - "terminal.integrated.env.osx": { - "PICO_SDK_PATH": "${env:HOME}/.pico-sdk/sdk/2.3.1", - "PICO_TOOLCHAIN_PATH": "${env:HOME}/.pico-sdk/toolchain/15_2_Rel1", - "PATH": "${env:HOME}/.pico-sdk/toolchain/15_2_Rel1/bin:${env:HOME}/.pico-sdk/picotool/2.3.1/picotool:${env:HOME}/.pico-sdk/cmake/v4.3.4/bin:${env:HOME}/.pico-sdk/ninja/v1.13.2:${env:PATH}" - }, - "terminal.integrated.env.linux": { - "PICO_SDK_PATH": "${env:HOME}/.pico-sdk/sdk/2.3.1", - "PICO_TOOLCHAIN_PATH": "${env:HOME}/.pico-sdk/toolchain/15_2_Rel1", - "PATH": "${env:HOME}/.pico-sdk/toolchain/15_2_Rel1/bin:${env:HOME}/.pico-sdk/picotool/2.3.1/picotool:${env:HOME}/.pico-sdk/cmake/v4.3.4/bin:${env:HOME}/.pico-sdk/ninja/v1.13.2:${env:PATH}" - }, - "raspberry-pi-pico.cmakeAutoConfigure": true, - "raspberry-pi-pico.useCmakeTools": false, - "raspberry-pi-pico.cmakePath": "${HOME}/.pico-sdk/cmake/v4.3.4/bin/cmake", - "raspberry-pi-pico.ninjaPath": "${HOME}/.pico-sdk/ninja/v1.13.2/ninja" -} diff --git a/0x0017a_ctf/.vscode/tasks.json b/0x0017a_ctf/.vscode/tasks.json deleted file mode 100644 index 2f07d94..0000000 --- a/0x0017a_ctf/.vscode/tasks.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Compile Project", - "type": "process", - "isBuildCommand": true, - "command": "${userHome}/.pico-sdk/ninja/v1.13.2/ninja", - "args": ["-C", "${workspaceFolder}/build"], - "group": "build", - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": "$gcc", - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/ninja/v1.13.2/ninja.exe" - } - }, - { - "label": "Run Project", - "type": "process", - "command": "${env:HOME}/.pico-sdk/picotool/2.3.1/picotool/picotool", - "args": [ - "load", - "${command:raspberry-pi-pico.launchTargetPath}", - "-fx" - ], - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": [], - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/picotool/2.3.1/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" - } - } - ] -} diff --git a/0x0017a_ctf/CMakeLists.txt b/0x0017a_ctf/CMakeLists.txt deleted file mode 100644 index 7a6ba40..0000000 --- a/0x0017a_ctf/CMakeLists.txt +++ /dev/null @@ -1,128 +0,0 @@ -# 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. -# -# Author: Kevin Thomas -# Email: kevin@mytechnotalent.com -# GitHub: https://github.com/mytechnotalent -# File: CMakeLists.txt -# Desc: Configures the RP2350 Pico SDK project and cryptographic module -# targets for the DEEPLINE Metro practice firmware. Mirrors the -# hardened Ouroboros construction of encryption-c-rp2350. -# Created: 2026 - -cmake_minimum_required(VERSION 3.13) - -set(CMAKE_C_STANDARD 11) -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -if(WIN32) - set(USERHOME $ENV{USERPROFILE}) -else() - set(USERHOME $ENV{HOME}) -endif() -set(sdkVersion 2.3.1) -set(toolchainVersion 15_2_Rel1) -set(picotoolVersion 2.3.1) -set(picoVscode ${USERHOME}/.pico-sdk/cmake/pico-vscode.cmake) -if(EXISTS ${picoVscode}) - include(${picoVscode}) -endif() - -set(PICO_BOARD pico2 CACHE STRING "Board type") - -include(pico_sdk_import.cmake) -project(CTF-02 C CXX ASM) -find_package(Python3 COMPONENTS Interpreter REQUIRED) - -set(DEMO_ARTIFACT_JSON ${CMAKE_CURRENT_LIST_DIR}/scripts/demo_artifact.json) -set(DEMO_ARTIFACT_HEADER_COMMITTED ${CMAKE_CURRENT_LIST_DIR}/include/demo_artifact.h) -set(DEMO_ARTIFACT_HEADER_GENERATED ${CMAKE_CURRENT_BINARY_DIR}/generated/demo_artifact.h) - -add_custom_command( - OUTPUT ${DEMO_ARTIFACT_HEADER_GENERATED} - COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/generated - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/scripts/dec.py - --from-json ${DEMO_ARTIFACT_JSON} - --header-out ${DEMO_ARTIFACT_HEADER_GENERATED} - --check-header-path ${DEMO_ARTIFACT_HEADER_COMMITTED} - DEPENDS - ${CMAKE_CURRENT_LIST_DIR}/scripts/dec.py - ${DEMO_ARTIFACT_JSON} - ${DEMO_ARTIFACT_HEADER_COMMITTED} - COMMENT "Regenerating demo artifact header from JSON and checking committed header freshness" - VERBATIM -) - -add_custom_target(check_demo_artifact_header DEPENDS ${DEMO_ARTIFACT_HEADER_GENERATED}) - -pico_sdk_init() - -if(NOT PICO_MBEDTLS_PATH) - set(PICO_MBEDTLS_PATH ${PICO_SDK_PATH}/lib/mbedtls) -endif() - -# Argon2id reference implementation (PHC winner), compiled single-threaded. -set(ARGON2_SRC ${CMAKE_CURRENT_LIST_DIR}/third_party/argon2) -add_library(argon2_ref STATIC - ${ARGON2_SRC}/src/argon2.c - ${ARGON2_SRC}/src/core.c - ${ARGON2_SRC}/src/ref.c - ${ARGON2_SRC}/src/encoding.c - ${ARGON2_SRC}/src/blake2/blake2b.c -) -target_compile_definitions(argon2_ref PUBLIC ARGON2_NO_THREADS) -target_include_directories(argon2_ref PUBLIC - ${ARGON2_SRC}/include - ${ARGON2_SRC}/src -) - -# mbedTLS subset: ChaCha20, Poly1305, ChaCha20-Poly1305, constant-time. -add_library(mbedtls_subset STATIC - ${PICO_MBEDTLS_PATH}/library/chacha20.c - ${PICO_MBEDTLS_PATH}/library/poly1305.c - ${PICO_MBEDTLS_PATH}/library/chachapoly.c - ${PICO_MBEDTLS_PATH}/library/constant_time.c - src/mbedtls_shims.c -) -target_compile_definitions(mbedtls_subset PUBLIC MBEDTLS_CONFIG_FILE="mbedtls_config.h") -target_include_directories(mbedtls_subset PUBLIC - include - ${PICO_MBEDTLS_PATH}/include - ${PICO_MBEDTLS_PATH}/library -) - -# Ouroboros authentication engine consuming the Argon2id and AEAD layers. -add_library(auth STATIC src/auth.c) -add_dependencies(auth check_demo_artifact_header) -target_include_directories(auth PUBLIC include) -target_link_libraries(auth PUBLIC pico_stdlib mbedtls_subset argon2_ref) - -# DEEPLINE Metro practice firmware executable. -add_executable(CTF-02 src/main.c) -target_link_libraries(CTF-02 PRIVATE auth pico_stdlib) -pico_enable_stdio_uart(CTF-02 0) -pico_enable_stdio_usb(CTF-02 1) -target_compile_definitions(CTF-02 PRIVATE - PICO_DEFAULT_UART_BAUD_RATE=115200 -) -pico_add_extra_outputs(CTF-02) \ No newline at end of file diff --git a/0x0017a_ctf/CTF-02-I.md b/0x0017a_ctf/CTF-02-I.md deleted file mode 100644 index 37de55e..0000000 --- a/0x0017a_ctf/CTF-02-I.md +++ /dev/null @@ -1,673 +0,0 @@ -# Operation Copperhead - Student Instructions - -**⚠ DEEPLINE METRO EMERGENCY INCIDENT ⚠** - -``` -+----------------------------------------------------------------------------------------+ -| | -| ██████╗ ██╗ █████╗ ██████╗██╗ ██╗███████╗████████╗ █████╗ ██████╗ ████████╗ | -| ██╔══██╗██║ ██╔══██╗██╔════╝██║ ██╔╝██╔════╝╚══██╔══╝██╔══██╗██╔══██╗╚══██╔══╝ | -| ██████╔╝██║ ███████║██║ █████╔╝ ███████╗ ██║ ███████║██████╔╝ ██║ | -| ██╔══██╗██║ ██╔══██║██║ ██╔═██╗ ╚════██║ ██║ ██╔══██║██╔══██╗ ██║ | -| ██████╔╝███████╗██║ ██║╚██████╗██║ ██╗███████╗ ██║ ██║ ██║██║ ██║ ██║ | -| ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═════╝██║ ██║╚══════╝ ╚═╝ ╚═╝ ╚═╝██║ ██║ ██║ | -| | -| | -| O P E R A T I O N C O P P E R H E A D | -| | -| *** PRIORITY RED *** | -| | -+----------------------------------------------------------------------------------------+ -``` - ---- - -## Project Overview - -DEEPLINE Metro Authority's rebuilt DEEPLINE-AUTH field relay image shipped -four corrupted engineering constants: a miscalibrated release threshold, a -false TRACK banner string, an overstated block length, and a poisoned ARX -signal seed. The corrupted image reports an occupied BRIDGE-4 block as -stable and authorized while rescue crews approach, and the source used for -the emergency rebuild was overwritten seventeen minutes later and cannot be -recovered. Students reverse engineer `CTF-02.bin` with Ghidra, patch all -four defects, capture the runtime-derived signal key live in GDB, recover -and authenticate the Ouroboros authority frame, export a corrected image, -flash it to a Pico 2, and prove the corrected behavior on real hardware. - ---- - -## Scenario Briefing - -### Read This First (Plain English) - -The story uses rail-signalling words that read as jargon the first time you -hit them. Here is what they mean; keep this list open while you read. - -- **Block**: a fixed section of track. Only one train may occupy it at a - time. A block is **safe** when it is empty, so the train waiting at its - start may proceed, and **occupied** when a train is inside it, so the - train behind must hold. -- **Track circuit**: a current sent through the rails to detect where - trains are. A train's wheels short the rails and drop that current, which - is how the system knows a block is occupied. -- **Pilot wire**: the sensing line that carries the track-circuit reading - back to the relay. The **dead pilot wire** in this story has a frozen - reading: the value is latched and no longer updates. -- **Field relay**: the small embedded controller, one per block, that - watches the reading and decides hold versus authorize. This challenge uses - a Pico 2 as the relay. -- **Command floor**: the central control room for the whole railway. -- **Blacklock**: a coordinated cyberattack that bricks the control room and - locks everyone out of central operations. After a blacklock, every safety - decision falls back to the local relays. -- **How deep?**: the DEEPLINE corridor runs roughly 40 meters below street - level inside a hardened tube called the armored shell. - -Once these words make sense, the incident below is a simple story: a relay -is lying about whether the block ahead is clear, and your job is to find -the corrupted bytes that make it lie. - -### Background - -**DEEPLINE Metro Authority** runs an armored railway deep beneath the -city, roughly 40 meters below street level, inside a hardened tube called -the armored shell. Armored two-car trains carry people through it, and -tonight they are also carrying rescue crews toward riders trapped inside -the tunnels. - -To understand what is happening, picture how the line stays safe. The line -is cut into fixed stretches of track called **blocks**. A block is one -piece of track, and the rule is absolute: only one train may be inside a -block at any moment. Before a train may roll out of its current block and -into the next one, the system must first prove the next block is empty. -Empty means safe, and safe means the train may proceed. Occupied means -danger, and danger means the train must stop and wait. - -How does the system prove a block is empty? It uses electricity. A steady -current is pushed into the rails of every block, and a small embedded -computer called a **field relay** (call sign **DEEPLINE-AUTH**) watches -that current. This is called a **track circuit**. When nothing is on a -block, the current flows normally. When a train rolls in, its steel wheels -connect the two rails and the current changes, and that change is the -relay's signal that a train is there. The **pilot wire** is the sensing -line that carries this reading from the rails up to the relay. - -So every block has a relay doing the same honest job: read the current, -ask "is the block ahead empty?", and answer with only two words, **HOLD** -(stop, do not move) or **AUTHORIZE** (the way is clear, go). The relays are -the railway's nervous system, and with the command floor dead they are the -only nervous system left. - -The command floor is the central control room where humans used to watch -the entire line. It was **blacklocked** by a coordinated attack: shut out, -locked, and made useless. When it went dark, the trains lost their view -from above. Every safety decision dropped down to the relays on the -ground, running their local firmware, deciding hold or authorize block by -block. - -At 0341 UTC, a threat actor known as **Cortex Sledge** posted a message -calling the moment before it happened: a blacklock of the DEEPLINE control -floor followed by a silent corruption of the field relay images, so nothing -inside the tunnels could agree on what was safe. The blacklock landed. With -the network coordination center offline and rescue crews already inside the -armored shell, the engineering team rebuilt the relay firmware around the -**Ouroboros hardened gate**: an encrypted authority frame protected by a -12-word operation passphrase and sealed with Argon2id plus -XChaCha20-Poly1305. The rebuilt image was pushed to the fleet within -minutes of the blacklock. - -That speed is where the story goes wrong, and it is the trap you walk -into tonight. - -### The Origin of the Ouroboros Gate - -The Ouroboros gate did not come from DEEPLINE. It came from a reclusive -cryptographer who spent a decade obsessed with a single, improbable goal: -to write encryption that could not be broken, not by anyone, not ever. -The engineers who worked beside him dismissed the obsession as unworkable, -and he never argued. When he finished, he published the work as a single -squashed archive tagged **v0.1.0**, with the compiled gate firmware image -attached to the release, and then vanished. - -What he left behind is the strict Ouroboros construction: a memory-hard -Argon2id key schedule feeding an authenticated XChaCha20-Poly1305 authority -frame: symmetric cryptography hardened for the RP2350's memory budget, with -an honest threat model instead of a sales pitch. In plain terms, Ouroboros -is the relay's lock: an order is only trusted if an operator holding the -correct 12-word phrase unlocks it. The corruption in this challenge is -separate from that lock, plain wrong numbers in the safety math, not a -crack in the encryption. DEEPLINE quietly adopted it -for the field relays because it was the strongest gate anyone had ever -shipped that would still boot on the target. A decade of asking -"what if it must not be broken?" is the only reason the relay console can be -an authoritative gate at all. Tonight, in a tunnel with rescue crews -approaching a block the firmware is lying about, that authenticated gate -matters more than DEEPLINE's own design review ever did. - -### The Disaster - -The relay boots. It prints a status report. It reports **TRACK: NORMAL**, -**BLOCK STATE: STABLE**, and **AUTO TRAIN: AUTHORIZED**. To anyone standing -in the tunnel, that console looks like the railway giving the all-clear: -the track is fine, the block ahead is stable and empty, and the train may -move. - -The console is lying, and here is the math behind the lie, step by step. - -Step 1. The relay is reading **87 A** from the dead pilot wire. A pilot -wire goes dead when the reading freezes, so the relay is looking at a stale -number instead of live reality. That number is thrust in front of the relay -every cycle, and the relay keeps trusting it. - -Step 2. DEEPLINE's hard engineering rule says no train may be released -into a block whose reading is at or above **60 A**. 87 A is nearly 45 -percent beyond that limit. In plain terms, the reading is screaming that -the insulated block ahead is compromised. - -Step 3. The compromised block in this incident is the exact block where -the two-car train is sitting right now, with rescue crews approaching on -foot. The reading is not noise and it is not a drill. The block ahead is -occupied. - -An honest relay would do that arithmetic and reach the only logical answer: -reading too high, block unsafe, print BLOCK STATE: CRITICAL, set AUTO TRAIN: -HELD, and hold the train. That is what the relay was designed to do, and it is -the only thing standing between the rescue corridor and a collision. - -The image that shipped does the opposite. It prints STABLE. It prints -AUTHORIZED. It tells the train the way is clear when the way is not clear. - -The reason is corruption. Between the safe reference firmware and the image -pushed to the fleet, four engineering constants were changed. A constant is -a fixed number baked into the firmware, like the amounts in a recipe, and a -single wrong number can flip the entire verdict. The corrupted image -believes 87 A is acceptable, believes the occupied block is empty, and will -hand the train a green light straight into the rescue crews' tunnel. - -If the fleet trusts that console, the two-car train is dispatched into the -occupied block at the same moment the crews mark the corridor with their -[chemlight], and nobody gets a second chance at that tunnel. - -**The rushed build has defects. The four constants were corrupted between -the safe reference firmware and the image that shipped. The source used for -the emergency rebuild was overwritten by the next build seventeen minutes -later and cannot be recovered. Nobody has found where the corrupt values -live in the compiled image.** That is the hole you were called in to fill. - -### The Only Surviving Evidence - -One field relay, the training/verification unit, still holds the exact -miscompiled image that shipped to the fleet. This image, and this image -alone, is the only remaining copy of the emergency build. There is no -source code. There is no build log. There is only the compiled image, a USB -console link, an SWD debug probe, and whatever a skilled embedded reverse -engineer can prove by reading machine code. - -### The Human Stakes - -| Consequence if the false "STABLE" reading is trusted | Scale | -|---|---| -| Two-car train dispatched into an occupied BRIDGE-4 block | 1 train | -| Rescue crews walking toward a block the console calls safe | 4 teams | -| Stations and hospital spokes on backup power after blacklock | 29 facilities | -| Estimated riders stranded in the armored shell | 210+ people | - -**The options are:** - -1. ❌ **Trust the console**: the train releases on a false reading, the - BRIDGE-4 corridor becomes a collision scene. -2. ❌ **Scrap the fleet's firmware**, which buys time but leaves crews in the - tunnel with no interlocking and no authority frame at all. -3. **REVERSE ENGINEER THE EMERGENCY BUILD**: find the exact corrupt - bytes, patch them, prove the corrected image on real hardware, and hand - the fix to the field team so the *rest of the fleet* can be repatched - before the next attempt. - -### THE SHORTAGE - -For years, the world treated embedded systems as invisible infrastructure. -The engineers who could read a vector table, decode a Thumb branch, or -patch a corrupted constant directly in a stripped binary were never -numerous enough. Tonight almost all of them are already in the field -chasing other failures. **You are the reserve team.** - -You were called in because you can do something no exhausted command-floor -team can do right now: read what the processor is actually doing, with no -source code, no time for a rewrite, and no room for a guess. - -> **⏰ TIME PRESSURE:** The field team is standing by to push your verified -> patch to the rest of the DEEPLINE fleet. Every relay still reporting a -> false "STABLE" status is one two-car release away from a disaster. - -> **AUTHORIZED LAB ONLY:** This challenge uses a supplied Pico 2 training -> relay and its exact corrupted firmware image. Do not connect this -> exercise to a public network, an operational railway, a metro system, or -> any device you do not own or have explicit written authorization to test. - ---- - -## Learning Objectives - -- Decode an ARM Cortex-M33 vector and boot table and identify the reset - handler and initial stack pointer. -- Translate Thumb reset-vector addresses into real function entry points and - trace literal-pool entries to their data. -- Locate four corrupted constants: a boundary comparison, a status string, - an 8-byte IEEE-754 double, and an ARX signal seed. -- Analyze unsigned compare semantics, condition codes, and compiler - transforms of boundary tests. -- Capture a runtime-derived key with GDB, override a register, and set a - watchpoint on stored SRAM state. -- Recover and authenticate an Argon2id plus XChaCha20-Poly1305 authority - frame and describe the crypto pipeline with an honest threat boundary. -- Export and UF2-convert a corrected image, then prove the corrected - behavior on real hardware. - ---- - -## What This Project Tests - -| Week | Concepts Tested | -|------|-----------------| -| 1 | RP2350 architecture, ARM Cortex-M33 registers, stack, flash/RAM, Thumb assembly, Ghidra static analysis | -| 2 | GDB connection, breakpoints, disassembly, register and memory inspection, USB-CDC console observation | -| 3 | Bootrom handoff, vector table, reset handler, startup code, XIP, Thumb-bit addressing | -| 4 | Data segments (`.rodata` / `.data` / `.bss`), initialized data images, little-endian encoding, literal pools, soft-float double layout | -| 5 | Unsigned compare semantics, condition codes (`hi`/`ls`), compiler transforms (`<` vs `<=`), volatile refetch semantics | -| 6 | Runtime signal-key derivation (SENTINEL-ARX quarter rounds), live register capture of a derived key, memory watchpoints | -| 7 | Argon2id memory-hard KDF, XChaCha20-Poly1305 AEAD, HChaCha20 subkey, salt/nonce/tag, authenticated decryption | -| 8 | Ouroboros composition (Argon2id to AEAD to payload dispatch), honest threat-model analysis, incident reporting | - ---- - -## Part 1: Understanding the System - -### DEEPLINE-AUTH Field Relay Hardware - -| Component | Connection | Purpose | -|-----------|------------|---------| -| Raspberry Pi Pico 2 | RP2350 | Runs the corrupted emergency firmware | -| USB-CDC console | Micro-USB to host | Relay console and Ouroboros gate input | -| SWD debug interface | Supplied probe | Authorized GDB inspection | -| Onboard LED | GPIO 25 | Authentication success indicator | - -Every graded finding lives in flash (`.rodata` / `.text` / `.data` image) or -SRAM, and is reachable with only the Weeks 1-8 toolset: Ghidra, GDB, and a -serial console. - -### Console Configuration - -- Transport: USB-CDC virtual COM port (no external adapter needed) -- Baud: `115200` -- Data: `8 bits` -- Parity: `none` -- Stop: `1` -- Logic: `3.3 V` on the debug header - -### Normal (Intended) Behavior - -The relay should run the SENTINEL-ARX signal-key layer, classify the frozen -87 A reading against the **real** DEEPLINE safety limit of **60 A**, report -honestly, and still accept the **Ouroboros authority frame** when an -operator enters the correct 12-word phrase: - -``` -+-----------------------------------------------------------------+ -| Intended Relay Behavior | -| | -| 1. Boot and initialize USB-CDC stdio and the auth gate | -| 2. Print the boot identity and the true TRACK signal | -| 3. Compare the frozen 87 A reading against the 60 A limit | -| 4. 87 A exceeds 60 A, so the block is NOT stable | -| 5. Report BLOCK STATE: CRITICAL and AUTO TRAIN: HELD | -| 6. Mint a SIGNAL KEY each 2-second cycle and watch it match | -| the SIGNAL_SPEC 0x2D879291 (OK, not MISMATCH) | -| 7. The 12-word emergency phrase reauthorizes the frame: | -| AUTHORITY FRAME: VERIFIED and payload on UART | -| 8. Repeat the report once per cycle until conditions change | -+-----------------------------------------------------------------+ -``` - -### Observed (Buggy) Behavior: What You Will See When You First Flash `CTF-02.uf2` - -```text -DEEPLINE METRO AUTHORITY -ADAPTIVE SIGNAL WINDOW: 38 MINUTES -USB-CDC 115200 8N1 | AUTHORIZED LAB CONSOLE -TRACK: NORMAL -BLOCK STATE: STABLE -AUTO TRAIN: AUTHORIZED -BLOCK LENGTH: 3200 M -FAULT POLLS: 1 -SIGNAL KEY: 0x915DCFF8 MISMATCH -RESPONSE> -``` - -> **Terminal Timing Note:** The first four lines (`DEEPLINE METRO...` through -> `TRACK: NORMAL`) represent the **initial boot banner**, emitted once during -> startup. If your serial terminal (PuTTY) connects after the board has -> booted, you will observe the continuous 2-second status stream (`BLOCK -> STATE...` through `SIGNAL KEY...`). To view the boot banner in your terminal, -> reset the Pico (pulse `RUN` to `GND`) while PuTTY is actively connected. - -The status block repeats every 2 seconds with `FAULT POLLS` incrementing. -This is exactly what the field crews are seeing. It is wrong, and it is -wrong in **four independent ways** inside the compiled binary. Do not assume -the first readable sentence is the full truth: treat every printed line as -evidence to be checked against the machine code, not as a fact on its own. - ---- - -## Part 2: The Firmware - -You do not have the source code. It was overwritten seventeen minutes after -the emergency build shipped. You have only the compiled image. Your job is -to reverse engineer it with Ghidra, locate the corrupted constants, patch -the image directly, and prove the corrected behavior: exactly the way the -field team will need to repatch the rest of the deployed fleet. - -### What The Firmware Does - -1. Initializes USB-CDC stdio and the Ouroboros authentication gate. -2. Reads a frozen track-circuit current (87 A) latched on the dead pilot - wire before the blacklock. -3. Compares that reading against a compiled-in safety threshold: **twice**, - once for the operator-facing BLOCK STATE line and once for the automated - AUTO TRAIN decision. -4. Prints a boot banner containing an unconditional TRACK signal line. -5. Enters an infinite 2-second loop that derives a session signal key, - prints the block classification, dispatch decision, block length, fault - poll count, and signal-key verdict. -6. Accepts a 12-word operation passphrase at the `RESPONSE>` prompt and runs - it through the hardened **Ouroboros gate** (Argon2id key derivation plus - XChaCha20-Poly1305 authenticated decryption) before dispatching the - authority frame payload to GPIO25 and UART. - -### Bug Summary: What You Are Graded On - -| Bug # | Category | Severity | Description | Hint | -|-------|----------|----------|--------------|------| -| **Bug #1** | Miscompiled safety constant | **CRITICAL** | The safe-release threshold was compiled far too permissive (95 A). It is used **twice**: once for the operator-facing status and once for the automated train-release decision, and **both** copies must be corrected. | The real DEEPLINE limit is 60 A. Search for the wrong immediate value used in the comparison. | -| **Bug #2** | Hardcoded string literal | **HIGH** | The boot banner unconditionally prints `TRACK: NORMAL` regardless of the actual reading. | The correct word describes a system holding a train at 87 A against a 60 A limit, not "NORMAL". | -| **Bug #3** | Data-section constant | **HIGH** | The block length shipped as 3.2 km; the real BRIDGE-4 block is 0.32 km, far below minimum release spacing. It prints as metres. | Trace the `BLOCK LENGTH` line to its data image in flash. Little-endian IEEE-754 double. | -| **Bug #4** | Init-time seed constant | **HIGH** | The ARX seed fused into the image is `0x0A0A0A0A`; the real seed is `0x6B206574`. The derived signal key therefore never matches `SIGNAL_SPEC`, and the console reports `MISMATCH` every cycle. | The expected value `0x2D879291` is a literal in a pool. The seed is a `.data` image in flash. Ignore decoy `0A` bytes in the input dispatch table. | - -**Important:** The replacement text for Bug #2 **must be the same length** -as the original (`NORMAL` and `DANGER` are both 6 bytes). Patching a shorter -or longer string will corrupt adjacent flash data. - -### A Third Layer: Not a Bug, an Authorization Task - -The **Ouroboros authority frame** is the encrypted artifact that proves an -operator is legitimate: a 48-byte payload sealed with Argon2id-derived keys -and XChaCha20-Poly1305. It is never printed by the firmware's status lines. -Recovering it, by understanding the construction and authenticating with -the correct 12-word phrase, is required evidence for your final report. - -The power of this layer is real but must be described honestly. The -construction is Argon2id (memory-hard KDF) chained into XChaCha20-Poly1305 -(AEAD). Against Grover-style search, symmetric-key security exponents are -**halved**, not annihilated; this firmware is a demonstrator and does not -claim NIST post-quantum status. The honest claim is: **a high modeled -brute-force cost under the stated passphrase entropy and KDF assumptions**, -not "quantum-proof." Your report must state this boundary exactly. - ---- - -## Part 3: Your Assignment - -Whenever a task asks you to **Document** or **answer**, write your answers -in a single file named `CTF-02-Answers.md`. - -### Task 1: Setup and Initial Analysis - -1. Create a new Ghidra project named `Copperhead_Investigation`. -2. Import `CTF-02.bin`. -3. Configure the language as **ARM Cortex 32-bit, little endian**. -4. Set the base address to `0x10000000`. -5. Run auto-analysis. - -**Document:** -- A screenshot of the Ghidra **Import Results** or **Program Information** - window showing the project name, processor settings, and base address. -- The address of `main()`. -- The address of the recurring 2-second status loop (the branch target the - loop restarts from). -- The vector-table base, the initial stack pointer, and the reset-handler - pointer as stored (note its Thumb bit) versus the actual instruction - address. -- One representative literal-pool entry that feeds the status lines, and - what it points to. - -### Task 2: Find and Patch Bug #1: The Miscalibrated Release Threshold - -1. Find **both** locations where the frozen 87 A reading is compared against - the miscompiled safety constant. -2. Document the exact address, the original instruction, and the original - immediate value at each location. -3. Determine the correct immediate value. **Caution:** the compiler may not - have encoded the raw threshold you expect: a strict "less than" - comparison against an unsigned value is often optimized into a - "less-or-equal" comparison against one less than the threshold. Show - your reasoning. -4. Patch **both** locations in Ghidra using the **Bytes Window** workflow: - > **Critical ARM Thumb-2 Patching Note:** In ARM Cortex-M, compare instructions that directly precede conditional execution blocks (`ite ge`) must **not** be patched using the right-click *Patch Instruction* dialog. Ghidra's automatic re-disassembler encounters an internal context conflict with the subsequent `ite ge` instruction, which collapses Thumb decoding and swallows Compare Site B (`0x10000312`). - > - > To patch cleanly without breaking downstream disassembly, use the **Bytes Window**: - > 1. Ensure the Bytes window is open (**Window** -> **Bytes: CTF-02.bin**). - > 2. In the Bytes window toolbar, click the **pencil icon** (**Toggle Edit Mode**). - > 3. In the Listing window, click on address `0x10000302` (Compare Site A) and press **`C`** (**Clear Code Bytes**). The instruction temporarily clears into raw bytes (`5E 2B`). - > 4. In the Bytes window, locate offset `10000302`, click on `5E`, and change it to **`3B`**. - > 5. Click back in the Listing window on address `0x10000302` and press **`D`** (**Disassemble**). The instruction immediately disassembles cleanly as `cmp r3, #0x3b`. - > 6. Notice that Compare Site B at `0x10000312` remains completely intact and visible! Repeat the exact same steps at `0x10000312`: click `0x10000312` in the Listing, press **`C`**, change `5E` to **`3B`** in the Bytes window, click back in the Listing, and press **`D`**. - -**Questions to answer:** -- Why must both locations be patched? What happens if you only patch one? -- Why is a false "STABLE" classification on an 87 A reading dangerous for - an automated train release into an occupied block? - -### Task 3: Find and Patch Bug #2: The False TRACK Banner - -1. Find the boot-banner string that unconditionally reports the wrong - signal state. -2. Document its address and the exact bytes that must change. -3. Patch the string, preserving its exact length. - -**Questions to answer:** -- Document the original vs. patched bytes, character by character. -- Why is a hardcoded, unconditional status word more dangerous than one - that is at least computed from a (miscalibrated) reading? - -### Task 4: Find and Patch Bug #3: The Block Length Constant - -1. Use Ghidra to locate the `BLOCK LENGTH` status line and trace the value - it prints back to its source in the initialized data image. -2. Document the 8-byte IEEE-754 double as stored (little endian) and its - printed interpretation. -3. Patch the data image so the relay reports the real 320 m BRIDGE-4 block. - -**Questions to answer:** -- Show your byte-for-byte conversion from 3.2 km to 0.32 km. -- Why would a console that overstates block length by ten times be as - dangerous as one that understates it? - -### Task 5: Find and Patch Bug #4: The Signal Seed - -1. Find the `SIGNAL_SPEC` value `0x2D879291` in the binary and note where - it lives. -2. Locate the `.data` image in flash that the firmware copies into SRAM at - boot. Identify the seed word that is wrong. -3. Patch the seed so the runtime-derived key matches the spec. - -**Warning:** there are decoy `0x0A0A0A0A` bytes in the console input -dispatch table. The real seed is an initialized data image, not a jump-table -constant. - -**Questions to answer:** -- How is the signal key derived each cycle, and where does the failure - appear in the register trace? -- Does fixing the seed also authenticate the Ouroboros gate? Explain what - each layer does and does not protect. - -### Task 6: GDB Register Capture of the Derived Key - -Prove the signal-key failure from the live machine, not just from static -bytes: - -1. Connect GDB to the running relay via the SWD probe. -2. Break at the second `derive_session_key` call site, immediately after the - branch returns. -3. Read `$r0`. Record the bug-derived key. -4. Inspect the two arguments entering the derivation: the live seed from - SRAM and the derived IV. -5. Overwrite `$r0` with the correct spec value, step out, and confirm the - next status cycle prints `SIGNAL KEY: 0x2D879291 OK`. -6. Verify with a watchpoint on the stored key in SRAM. - -**Questions to answer:** -- Why is the derived value in `$r0` different from the spec, and what alone - in the image is responsible? -- What does the register overwrite prove that the static patch proves - differently (and vice versa)? - -### Task 7: Recover the Ouroboros Authority Frame - -1. In Ghidra, locate the embedded artifact: the 16-byte salt, the 24-byte - XChaCha nonce, and the 64-byte ciphertext-plus-tag. -2. Document the Argon2id parameters compiled into the gate (memory, time, - parallelism) and the payload layout contract (LED byte + UART bytes). -3. On the live relay, enter the canonical 12-word emergency phrase at the - `RESPONSE>` prompt. -4. Confirm the expected outcome: `AUTHORITY FRAME: VERIFIED`, the onboard - LED turning on, and the payload printed to the console. -5. Demonstrate the two failure paths (policy violation and wrong phrase). - -**Questions to answer (honest boundary required):** -- Walk through the full pipeline: Argon2id to 32-byte key, HChaCha20 subkey - from the nonce prefix, inner nonce, Poly1305 tag verification, payload - dispatch. -- What would Grover-style search actually change in this construction, and - why does this firmware not claim strict post-quantum status? - -### Task 8: Export and Verify - -1. Export your patched binary as `CTF-02_fixed.bin`. -2. Convert it to UF2 format for the RP2350: - ```bash - python uf2conv.py CTF-02_fixed.bin --base 0x10000000 --family 0xe48bff59 --output CTF-02_fixed.uf2 - ``` -3. Flash `CTF-02_fixed.uf2` to your Pico 2 and capture the corrected - console output. -4. Confirm the corrected image now reports **TRACK: DANGER**, **BLOCK STATE: - CRITICAL**, **AUTO TRAIN: HELD**, **BLOCK LENGTH: 320 M**, and **SIGNAL - KEY: 0x2D879291 OK**, an honest, safe report instead of a false - "all clear." -5. Build a summary table of every patch: address, original bytes, patched - bytes, and a one-line description. - -### Task 9: Written Reflection (short answers, 150 words or less each) - -1. Why is "the build was rushed under emergency pressure" not an acceptable - excuse for shipping a firmware defect that could dispatch a train into a - block occupied by rescue crews? -2. Name one concrete engineering practice (review, static analysis, - hardware-in-the-loop test, signature verification, etc.) that would have - caught **each** of the four graded bugs before this image reached the - fleet, and one practice that would have stopped the corrupted image from - **running** at all. - ---- - -## How To Breadboard - -- Connect the Pico 2 micro-USB port directly to the host computer. The - relay enumerates as a USB-CDC virtual COM device. -- Open the end-of-line tool of your choice at `115200 8N1`. -- Connect the supplied SWD probe to the debug header according to its - documented pinout for GDB access. -- Use **3.3 V logic only** on the debug header. Never connect a 5 V line to - a Pico GPIO. - -The supplied image is `CTF-02.bin` (for Ghidra analysis) and -`CTF-02.uf2` (for flashing). If your instructor supplies different -filenames, record the actual filenames in your report. - -Flash using BOOTSEL mode (hold BOOT, plug in USB) and copy the UF2 onto the -`RP2350` mass-storage drive, or use `picotool`. - ---- - -## Memory Map Reference - -| Region | Address | Purpose | -|--------|---------|---------| -| Bootrom | `0x00000000` | Immutable boot code | -| Flash/XIP | `0x10000000` | Vector table, code, rodata, `.data` init image | -| SRAM | `0x20000000` | Stack and writable state | - ---- - -## Submission Format - -Submit a folder containing: - -- `CTF-02-Answers.md`; -- screenshots or terminal transcripts; -- `CTF-02_fixed.bin` and `CTF-02_fixed.uf2`; -- the original image hash. - ---- - -## Success Criteria - -You complete the challenge when you can prove all of the following: - -- You can explain how the RP2350 reaches the relay's code from reset. -- You can locate and patch both copies of the miscalibrated threshold. -- You can locate and patch the false TRACK string without corrupting - adjacent data. -- You can locate and patch the corrupted block-length double in the data - image. -- You can locate and patch the corrupted ARX seed and explain why the - runtime-derived key misses its spec. -- You can capture and correct the derived key live in GDB and verify with a - watchpoint. -- You can authenticate through the Ouroboros gate with the correct phrase - and describe the crypto pipeline accurately, including the honest - quantum boundary. -- You can export, convert, flash, and prove the corrected behavior on real - hardware. - ---- - -## Academic Integrity - -By submitting this CTF work, you certify that: - -1. You used only the supplied training relay, image, and lab interface. -2. You did not connect the challenge to a public network, an operational - railway, a metro system, or any third-party device. -3. You understand that embedded reverse engineering and binary patching - require explicit authorization in any real-world context. -4. You will report any discovered weakness responsibly to the course - instructor. - -The world is short on people who can do this work. Treat that -responsibility seriously: verify before you patch, patch before you trust, -and never confuse a clean-looking status line with a safe system. - ---- - -## Reference Material - -- ARM Cortex-M33 Technical Reference Manual -- RP2350 datasheet -- GDB documentation -- Ghidra documentation: [https://ghidra-sre.org/](https://ghidra-sre.org/) -- Strict Ouroboros reference construction (v0.1.0), the published source of - this firmware's gate, with an honest threat model: - [https://github.com/mytechnotalent/encryption-c-rp2350](https://github.com/mytechnotalent/encryption-c-rp2350) -- Reference gate firmware image (v0.1.0 release): - [https://github.com/mytechnotalent/encryption-c-rp2350/releases/download/v0.1.0/encryption_app.uf2](https://github.com/mytechnotalent/encryption-c-rp2350/releases/download/v0.1.0/encryption_app.uf2) -- PHC reference Argon2: [https://github.com/P-H-C/phc-winner-argon2](https://github.com/P-H-C/phc-winner-argon2) diff --git a/0x0017a_ctf/CTF-02-I.pdf b/0x0017a_ctf/CTF-02-I.pdf deleted file mode 100644 index 9212a65..0000000 Binary files a/0x0017a_ctf/CTF-02-I.pdf and /dev/null differ diff --git a/0x0017a_ctf/CTF-02-R.md b/0x0017a_ctf/CTF-02-R.md deleted file mode 100644 index c8d392a..0000000 --- a/0x0017a_ctf/CTF-02-R.md +++ /dev/null @@ -1,276 +0,0 @@ -# Operation Copperhead - Requirements & Grading Criteria - -``` -+----------------------------------------------------------------------------------------+ -| | -| ██████╗ ██╗ █████╗ ██████╗██╗ ██╗███████╗████████╗ █████╗ ██████╗ ████████╗ | -| ██╔══██╗██║ ██╔══██╗██╔════╝██║ ██╔╝██╔════╝╚══██╔══╝██╔══██╗██╔══██╗╚══██╔══╝ | -| ██████╔╝██║ ███████║██║ █████╔╝ ███████╗ ██║ ███████║██████╔╝ ██║ | -| ██╔══██╗██║ ██╔══██║██║ ██╔═██╗ ╚════██║ ██║ ██╔══██║██╔══██╗ ██║ | -| ██████╔╝███████╗██║ ██║╚██████╗██║ ██╗███████╗ ██║ ██║ ██║██║ ██║ ██║ | -| ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═════╝██║ ██║╚══════╝ ╚═╝ ╚═╝ ╚═╝██║ ██║ ██║ | -| | -| | -| O P E R A T I O N C O P P E R H E A D | -| | -| REQUIREMENTS & GRADING CRITERIA | -| | -+----------------------------------------------------------------------------------------+ -``` - ---- - -## Project Overview - -Students are the reverse-engineering reserve team called in after DEEPLINE -Metro Authority's rebuilt DEEPLINE-AUTH relay image shipped four corrupted -engineering constants: a miscalibrated release threshold, a false TRACK banner -string, an overstated block length, and a poisoned ARX signal seed. Students -reverse engineer `CTF-02.bin` with Ghidra, patch all four defects, capture the -runtime-derived signal key live in GDB, recover the Ouroboros authority frame, -export a corrected image, flash it to real hardware, and prove the corrected -behavior on a physical Pico 2. - -The challenge is a standalone capstone exercise and contains no answer, -constant, address, bug, or patch belonging to any other course assignment. - ---- - -## Learning Objectives - -- Decode an ARM Cortex-M33 vector and boot table and identify the reset handler - and initial stack pointer. -- Translate Thumb reset-vector addresses into real function entry points and - trace literal-pool entries to their data. -- Locate four corrupted constants: a boundary comparison, a status string, an - 8-byte IEEE-754 double, and an ARX signal seed. -- Capture a runtime-derived key with GDB, override a register, and set a - watchpoint on stored SRAM state. -- Recover and authenticate an Argon2id plus XChaCha20-Poly1305 authority frame. - -Students must use only Weeks 1-8 concepts: ARM registers, stack behavior, -USB-CDC output, GDB, Ghidra static analysis and binary patching, vector tables, -reset startup, XIP, Thumb addressing, data segments and literal pools, -condition-code analysis, runtime key derivation, and the Argon2id plus -XChaCha20-Poly1305 authenticated gate. - ---- - -## Deliverables Checklist - -| # | Deliverable | Format | Criterion | -|---|-------------|--------|-----------| -| 1 | Ghidra project screenshot | PNG/JPG | 1.1 | -| 2 | Vector table and boot table | Inside `CTF-02-Answers.md` | 1.2 | -| 3 | `main()` and status-loop table | Inside `CTF-02-Answers.md` | 1.3 | -| 4 | Literal pool trace | Inside `CTF-02-Answers.md` | 1.4 | -| 5 | Bug #1 evidence and patches | Inside `CTF-02-Answers.md` | 2.1-2.4 | -| 6 | Bug #2 evidence and patch | Inside `CTF-02-Answers.md` | 3.1-3.4 | -| 7 | Bug #3 evidence and patch | Inside `CTF-02-Answers.md` | 4.1-4.3 | -| 8 | Bug #4 evidence and patch | Inside `CTF-02-Answers.md` | 5.1-5.4 | -| 9 | GDB register capture | Inside `CTF-02-Answers.md` | 6.1-6.4 | -| 10 | Ouroboros gate recovery and auth | Inside `CTF-02-Answers.md` | 7.1-7.4 | -| 11 | `CTF-02_fixed.bin` | BIN file | 8.1 | -| 12 | `CTF-02_fixed.uf2` | UF2 file | 8.2 | -| 13 | Corrected console transcript | Inside `CTF-02-Answers.md` | 8.3 | -| 14 | Summary table of all patches | Inside `CTF-02-Answers.md` | 8.4 | -| 15 | Written reflection | Inside `CTF-02-Answers.md` | 9.1-9.2 | - ---- - -## Required Tools and Equipment - -| Tool | Purpose | -|------|---------| -| Raspberry Pi Pico 2 | Isolated target | -| USB-CDC virtual serial console | Observe output and type the gate passphrase | -| SWD debug probe | GDB inspection | -| Ghidra | Static analysis and binary patching | -| GDB | Dynamic analysis and register capture | -| Python (`uf2conv.py`) | UF2 conversion | -| `CTF-02.bin` and `CTF-02.uf2` | Supplied artifacts | - -Console settings: **USB-CDC virtual COM port, 115200 baud, 8 data bits, no -parity, 1 stop bit**. - ---- - -## Artifact Identity - -The instructor-issued artifact hashes are: - -```text -CTF-02.bin 85330C37CD0897746B1AF447E4BAC371DDE2042ABD2D61D58A61FE2A8EEF3537 -CTF-02.uf2 F3CD4840260DB820D792758CECACC5297BEF1971B9EACF7601279256D8AF1EAB -``` - ---- - -## Grading Rubric - Detailed Breakdown - -### Task 1: Setup and Initial Analysis (12 points) - -| Criterion | Points | Full credit | Partial credit | No credit | -|-----------|--------|-------------|----------------|-----------| -| Criterion 1.1: Ghidra Project Setup | 3 | Correct project name, `ARM:LE:32:Cortex` (ARM Cortex 32-bit little endian), base `0x10000000` | One item off | Not set up | -| Criterion 1.2: Vector Table Decoding | 3 | Correct base, initial SP, reset pointer | One missing | Not found | -| Criterion 1.3: main() and Status-Loop Addresses | 4 | Both addresses correct | One correct | Neither found | -| Criterion 1.4: Thumb Addressing and Literal Pool | 2 | Bit 0 cleared and one pool entry traced to its string | Partial | Incorrect | - -### Task 2: Find and Patch Bug #1: The Miscalibrated Release Threshold (15 points) - -| Criterion | Points | Full credit | Partial credit | No credit | -|-----------|--------|-------------|----------------|-----------| -| Criterion 2.1: Locate Compare Sites A and B | 6 | Both addresses and original bytes | One site | Not found | -| Criterion 2.2: Correct Immediate-Value Reasoning | 4 | Explains the `<` to `<=` transform and gives `0x3B` | Correct value, no reasoning | Wrong value | -| Criterion 2.3: Patch Compare Sites A and B | 4 | Both byte changes verified | One site | Not patched | -| Criterion 2.4: Explain Why Both Sites Must Be Patched | 1 | Clear explanation of the two independent comparisons | Vague | Missing | - -### Task 3: Find and Patch Bug #2: The False TRACK Banner (10 points) - -| Criterion | Points | Full credit | Partial credit | No credit | -|-----------|--------|-------------|----------------|-----------| -| Criterion 3.1: Locate the Banner String | 3 | Correct address and cross-reference | Approximate | Not found | -| Criterion 3.2: Patch Six Characters | 4 | All six bytes changed, length preserved | Correct text, wrong bytes documented | Wrong length | -| Criterion 3.3: Character-by-Character Documentation | 2 | Original vs patched byte for all six characters | Partial | Missing | -| Criterion 3.4: Explain the Danger of a Hardcoded Status Word | 1 | Clear, specific reasoning | Generic | Missing | - -### Task 4: Find and Patch Bug #3: The Block Length Constant (10 points) - -| Criterion | Points | Full credit | Partial credit | No credit | -|-----------|--------|-------------|----------------|-----------| -| Criterion 4.1: Locate the .data Double | 3 | Correct address traced from the BLOCK LENGTH print | Approximate | Not found | -| Criterion 4.2: IEEE-754 Bytes and Print Math | 4 | Original and patched 8-byte double with print math (3200 M to 320 M) | Correct patch, no math | Wrong bytes | -| Criterion 4.3: Patch to Print 320 M | 3 | Console shows `BLOCK LENGTH: 320 M` | Wrong bytes | Not patched | - -### Task 5: Find and Patch Bug #4: The Signal Seed (15 points) - -| Criterion | Points | Full credit | Partial credit | No credit | -|-----------|--------|-------------|----------------|-----------| -| Criterion 5.1: Locate SIGNAL_SPEC and the Seed | 5 | `0x2D879291` located and wrong seed `0x0A0A0A0A` found | Partial | Not found | -| Criterion 5.2: Patch the Seed | 4 | Seed bytes changed to `74 65 20 6B` | Wrong byte | Not patched | -| Criterion 5.3: Explain the ARX Derivation | 3 | Correct trace of the per-cycle derivation | Vague | Missing | -| Criterion 5.4: Separate the Security Layers | 3 | Correctly explains what the seed fixes versus the gate | Generic | Missing | - -### Task 6: GDB Register Capture of the Derived Key (15 points) - -| Criterion | Points | Full credit | Partial credit | No credit | -|-----------|--------|-------------|----------------|-----------| -| Criterion 6.1: Breakpoint at the Derive Return | 4 | Correct address and `$r0` read as the bug-derived key | Address off | Not found | -| Criterion 6.2: Inspect the Two Arguments | 4 | Live seed and derived IV captured at the second call | One correct | Missing | -| Criterion 6.3: Override the Register | 4 | `$r0` set to `0x2D879291` and the next cycle shows `OK` | Partial | Missing | -| Criterion 6.4: Watchpoint on the Stored Key | 3 | Watchpoint on the SRAM key location documented | Approximate | Missing | - -### Task 7: Recover the Ouroboros Authority Frame (10 points) - -| Criterion | Points | Full credit | Partial credit | No credit | -|-----------|--------|-------------|----------------|-----------| -| Criterion 7.1: Locate Salt, Nonce, Ciphertext, and Tag | 4 | All three addresses correct in flash | Two correct | Not found | -| Criterion 7.2: Document Argon2id Parameters and Payload Contract | 2 | Correct memory/time/parallelism and payload layout | Partial | Missing | -| Criterion 7.3: Authenticate with the 12-Word Passphrase | 2 | `AUTHORITY FRAME: VERIFIED`, LED on, payload printed | Partial | Not shown | -| Criterion 7.4: State the Honest Quantum Boundary | 2 | Grover halves symmetric exponents; not strict PQC | Generic | Misstates | - -### Task 8: Export and Verify (8 points) - -| Criterion | Points | Full credit | Partial credit | No credit | -|-----------|--------|-------------|----------------|-----------| -| Criterion 8.1: Export CTF-02_fixed.bin | 1 | Valid patched binary | Corrupted | Not submitted | -| Criterion 8.2: Convert to CTF-02_fixed.uf2 | 1 | Correct base and family flags | Wrong flags | Not submitted | -| Criterion 8.3: Hardware Verification | 4 | Corrected console output confirmed (CRITICAL/HELD in 2s stream; DANGER at boot/Ghidra) | Some lines corrected | No verification | -| Criterion 8.4: Summary Table of All Patches | 2 | Complete address and before/after table | Missing entries | No table | - -### Task 9: Written Reflection (5 points) - -| Criterion | Points | Full credit | Partial credit | No credit | -|-----------|--------|-------------|----------------|-----------| -| Criterion 9.1: "Rushed Build" Is Not an Excuse | 2 | Specific, grounded reasoning | Generic | Missing | -| Criterion 9.2: One Engineering Practice per Failure Area | 3 | Concrete practices for the bugs and for image authenticity | Names some | Missing | - ---- - -## Common Pitfalls - -| Pitfall | Consequence | Avoidance | -|---------|-------------|-----------| -| Patching only one threshold site | One status line still lies | Patch both `0x10000302` and `0x10000312` | -| Assuming the immediate equals the limit | Off-by-one, wrong boundary | Use `0x3B` (59), not `0x3C` (60) | -| Using Patch Instruction before IT block | Re-disassembler context conflict swallows Site B | In Listing press `C` -> edit byte in Bytes window (pencil) -> press `D` | -| Missing boot banner in serial terminal | PuTTY misses one-time 5ms boot banner | Pulse RUN to GND while connected to capture | -| Replacing a string with a different length | Corrupts adjacent flash | `NORMAL` and `DANGER` are both 6 bytes | -| Treating the block length as an integer | Misses the 8-byte double | Follow the value into `.data`, decode IEEE-754 | -| Using the wrong 0.32 bytes | Prints 316 M instead of 320 M | Use `7B 14 AE 47 E1 7A D4 3F` | -| Treating an odd vector address as invalid | Thumb analysis fails | Clear bit 0 | -| Starting the seed patch at the wrong offset | Wrong seed, key never matches | Seed is at `0x1000EC70` | - ---- - -## How To Breadboard - -- **Raspberry Pi Pico 2** powered over USB. -- **USB-CDC virtual serial console:** open the Pico's COM port at 115200 baud, - 8 data bits, no parity, 1 stop bit. -- **SWD debug probe:** connect SWCLK, SWDIO, GND, and 3.3 V to the Pico debug - header for GDB inspection and register capture. -- No other peripherals are required; the authority LED is on-board. - ---- - -## Memory Map Reference - -| Region | Address | Purpose | -|--------|---------|---------| -| Bootrom | `0x00000000` | Immutable boot code | -| Flash/XIP | `0x10000000` | Vector table, code, rodata, `.data` init image | -| SRAM | `0x20000000` | Stack and writable state | - ---- - -## Deadline & Submission - -- Create a folder containing the Ghidra screenshot, `CTF-02_fixed.bin`, and - `CTF-02_fixed.uf2`. -- Write all written answers in a single file named `CTF-02-Answers.md` inside that - folder. -- ZIP the folder as `lastname-firstname-CTF-02.zip`. -- Submit the ZIP before the posted deadline; late submissions lose 10 percent - per day. - ---- - -## Grade Scale - -| Grade | Percentage | Points | -|-------|------------|--------| -| A+ | 97-100% | 97-100 | -| A | 93-96% | 93-96 | -| A- | 90-92% | 90-92 | -| B+ | 87-89% | 87-89 | -| B | 84-86% | 84-86 | -| B- | 80-83% | 80-83 | -| C | 70-79% | 70-79 | -| F | 0-69% | 0-69 | - ---- - -## Academic Integrity - -Use only the supplied Pico 2 and firmware. Do not connect the exercise to an -operational railway, metro system, public network, military system, or -third-party device. This is a controlled, isolated educational exercise. All -analysis and patches must be your own work; sharing binaries, addresses, keys, -passphrases, or answers is a violation of the academic integrity policy. - ---- - -## Reference Material - -| Topic | Reference | -|-------|-----------| -| ARM Cortex-M33 registers and stack | Week 1 | -| USB-CDC output and console capture | Week 2 | -| Vector tables, reset startup, and XIP | Week 2 | -| Ghidra static analysis and binary patching | Week 3 | -| Data segments, literal pools, IEEE-754 | Week 4 | -| Condition-code analysis | Week 5 | -| Runtime key derivation and GDB register capture | Week 6 | -| Argon2id and XChaCha20-Poly1305 authenticated gate | Week 8 | diff --git a/0x0017a_ctf/CTF-02-R.pdf b/0x0017a_ctf/CTF-02-R.pdf deleted file mode 100644 index a8cde10..0000000 Binary files a/0x0017a_ctf/CTF-02-R.pdf and /dev/null differ diff --git a/0x0017a_ctf/CTF-02-S.md b/0x0017a_ctf/CTF-02-S.md deleted file mode 100644 index 310a619..0000000 --- a/0x0017a_ctf/CTF-02-S.md +++ /dev/null @@ -1,652 +0,0 @@ -# Operation Copperhead - Instructor Solution Key - -``` -+----------------------------------------------------------------------------------------+ -| | -| ██████╗ ██╗ █████╗ ██████╗██╗ ██╗███████╗████████╗ █████╗ ██████╗ ████████╗ | -| ██╔══██╗██║ ██╔══██╗██╔════╝██║ ██╔╝██╔════╝╚══██╔══╝██╔══██╗██╔══██╗╚══██╔══╝ | -| ██████╔╝██║ ███████║██║ █████╔╝ ███████╗ ██║ ███████║██████╔╝ ██║ | -| ██╔══██╗██║ ██╔══██║██║ ██╔═██╗ ╚════██║ ██║ ██╔══██║██╔══██╗ ██║ | -| ██████╔╝███████╗██║ ██║╚██████╗██║ ██╗███████╗ ██║ ██║ ██║██║ ██║ ██║ | -| ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═════╝██║ ██║╚══════╝ ╚═╝ ╚═╝ ╚═╝██║ ██║ ██║ | -| | -| | -| O P E R A T I O N C O P P E R H E A D | -| | -| *** INSTRUCTOR SOLUTION KEY: RESTRICTED *** | -| | -+----------------------------------------------------------------------------------------+ -``` - -> The task and criterion headings in this key are word-for-word identical to -> `CTF-02-R.md`, so a student can match each criterion one-to-one. - ---- - -## Artifact Identity - -| Artifact | Value | -|----------|-------| -| Student image | `CTF-02.bin` | -| Flash image | `CTF-02.uf2` | -| Target | Raspberry Pi Pico 2 / RP2350 ARM Cortex-M33 | -| Image base | `0x10000000` | -| Console | USB-CDC virtual COM, 115200 8N1 | - -```text -CTF-02.bin 85330C37CD0897746B1AF447E4BAC371DDE2042ABD2D61D58A61FE2A8EEF3537 -CTF-02.uf2 F3CD4840260DB820D792758CECACC5297BEF1971B9EACF7601279256D8AF1EAB -``` - -Proof tool: `python3 scripts/verify_ctf.py` returns `26/26 checks passed` against -`CTF-02.bin`. - ---- - -## Task 1: Setup and Initial Analysis (12 points) - -### Solution - -**Criterion 1.1: Ghidra Project Setup (3 points).** Import `CTF-02.bin` as -`Raw Binary`, language `ARM:LE:32:Cortex`, base address `0x10000000`, then run -auto-analysis. - -**Criterion 1.2: Vector Table Decoding (3 points).** -First 32 bytes of `CTF-02.bin`: - -```text -00 20 08 20 5B 01 00 10 1B 01 00 10 1D 01 00 10 -11 01 00 10 11 01 00 10 11 01 00 10 11 01 00 10 -``` - -| Evidence | Answer | -|----------|--------| -| Vector table base | `0x10000000` | -| Initial SP | `0x20082000` | -| Reset pointer (as stored) | `0x1000015B` | -| Reset instruction address | `0x1000015A` | - -**Criterion 1.3: main() and Status-Loop Addresses (4 points).** - -| Element | Address | -|---------|---------| -| `main()` | `0x100002E8` | -| Recurring status loop start | `0x1000034C` | -| Loop back-edge (`b.n 0x1000034C`) | `0x1000044E` | - -**Criterion 1.4: Thumb Addressing and Literal Pool (2 points).** -The stored reset pointer `0x1000015B` has bit 0 set, selecting Thumb mode. -Clearing bit 0 gives `0x1000015A`. A representative literal pool entry is -`0x100004B4`, which holds `0x1000C4C8`, the address of the format string -`"BLOCK STATE: %s"`, loaded by `ldr r0, [pc, #308]` at `0x1000037C`. - -**Supporting Reference: SRAM Symbols (Ghidra names to semantic roles).** - -| Ghidra Label | SRAM Address | Section | Role | Source Symbol | -|--------------|--------------|---------|------|---------------| -| `DAT_20001188` | `0x20001188` | `.data` | Block length double | `g_telemetry` | -| `DAT_20001198` | `0x20001198` | `.data` | Signal key seed | `g_auth_seed` | -| `DAT_2000119C` | `0x2000119C` | `.data` | Track current | `g_block_current` | -| `DAT_20001ECC` | `0x20001ECC` | `.bss` | Dispatch state | `g_dispatch_state` | -| `DAT_20001ED0` | `0x20001ED0` | `.bss` | Fault poll counter | `g_fault_polls` | -| `DAT_20001ED4` | `0x20001ED4` | `.bss` | Input line buffer | `g_linebuf` | -| `DAT_200020D4` | `0x200020D4` | `.bss` | Input write index | `g_lineidx` | -| `DAT_200020D8` | `0x200020D8` | `.bss` | Operator state | `g_operator_state` | -| `DAT_200020DC` | `0x200020DC` | `.bss` | Derived signal key | `g_signal_key` | - -### Grading Rubric (1-to-1 Mapping) - -| Criterion | Points | Full Credit (Answer Key) | Partial Credit | No Credit | -|-----------|--------|--------------------------|----------------|-----------| -| Criterion 1.1: Ghidra Project Setup | 3 | Correct project name, `ARM:LE:32:Cortex` (ARM Cortex 32-bit little endian), base `0x10000000` | One item off | Not set up | -| Criterion 1.2: Vector Table Decoding | 3 | Correct base, initial SP, reset pointer | One missing | Not found | -| Criterion 1.3: main() and Status-Loop Addresses | 4 | Both addresses correct | One correct | Neither found | -| Criterion 1.4: Thumb Addressing and Literal Pool | 2 | Bit 0 cleared and one pool entry traced to its string | Partial | Incorrect | - -### Instructor Notes & Assembly - -- Confirm the Ghidra import used `Raw Binary`, `ARM:LE:32:Cortex`, base - `0x10000000`, and that auto-analysis completed before any address was read. -- Verify `main()` is `0x100002E8`, the loop head is `0x1000034C`, and the - back-edge is `0x1000044E`. -- For Criterion 1.4, accept any correctly traced literal pool entry; the pool - entry `0x100004B4` holding `0x1000C4C8` (`"BLOCK STATE: %s"`, loaded at - `0x1000037C`) is the reference example. -- The SRAM symbol table is supporting reference material, not a separate - scored criterion. - ---- - -## Task 2: Find and Patch Bug #1: The Miscalibrated Release Threshold (15 points) - -### Solution - -**Criterion 2.1: Locate Compare Sites A and B (6 points).** - -```text -10000302: 2b5e cmp r3, #94 @ 0x5e -10000312: 2b5e cmp r3, #94 @ 0x5e -``` - -| Site | Address | File Offset | Original Bytes | Original Instruction | -|------|---------|-------------|----------------|----------------------| -| A | `0x10000302` | `0x0302` | `5E 2B` | `cmp r3, #94` | -| B | `0x10000312` | `0x0312` | `5E 2B` | `cmp r3, #94` | - -**Criterion 2.2: Correct Immediate-Value Reasoning (4 points).** -The source constant is `SAFE_THRESHOLD = 95` and the test is `x < 95`. For an -unsigned value, `x < 95` is exactly `x <= 94`, so the compiler emits -`cmp r3, #94`. The correct limit is `60`, so the test is `x < 60`, which is -`x <= 59`. The correct patched immediate is **`0x3B` (59)**, not `0x3C` (60). - -**Criterion 2.3: Patch Compare Sites A and B (4 points).** - -| Site | Address | File Offset | Original | Patched | After | -|------|---------|-------------|----------|---------|-------| -| A | `0x10000302` | `0x0302` | `5E 2B` | `3B 2B` | `cmp r3, #59` | -| B | `0x10000312` | `0x0312` | `5E 2B` | `3B 2B` | `cmp r3, #59` | - -**Criterion 2.4: Explain Why Both Sites Must Be Patched (1 point).** -Site A drives the `BLOCK STATE` line and site B drives the `AUTO TRAIN` -decision. Patching only site A makes the console read `CRITICAL` while the -automated dispatch still says `AUTHORIZED`. Frozen reading `87`: `87 <= 94` is -true (wrong); `87 <= 59` is false (correct). - -### Grading Rubric (1-to-1 Mapping) - -| Criterion | Points | Full Credit (Answer Key) | Partial Credit | No Credit | -|-----------|--------|--------------------------|----------------|-----------| -| Criterion 2.1: Locate Compare Sites A and B | 6 | Both addresses and original bytes | One site | Not found | -| Criterion 2.2: Correct Immediate-Value Reasoning | 4 | Explains the `<` to `<=` transform and gives `0x3B` | Correct value, no reasoning | Wrong value | -| Criterion 2.3: Patch Compare Sites A and B | 4 | Both byte changes verified | One site | Not patched | -| Criterion 2.4: Explain Why Both Sites Must Be Patched | 1 | Clear explanation of the two independent comparisons | Vague | Missing | - -### Instructor Notes & Assembly - -- Both sites must be patched: `0x10000302` for `BLOCK STATE` and `0x10000312` - for the `AUTO TRAIN` decision. -- The correct immediate is `0x3B` (59), not `0x3C` (60). -- Verify the byte changes on hardware; the corrected console reads `CRITICAL` - and `HELD`. -- **Ghidra ARM/Thumb Context Note:** In raw `.bin` files, patching an instruction - that precedes an `IT` block (`ite ge`) using the GUI *Patch Instruction* action - triggers Ghidra's `ReDisassembleCommand`. The re-disassembler encounters an - internal context register conflict when trying to re-declare the `ITBlock` - context over existing instructions, collapsing Thumb decoding into 32-bit ARM - mode and swallowing Site B (`0x10000312`). Students must patch using the Bytes - window workflow (Clear `C` -> edit byte `5E` -> `3B` in Bytes window with pencil - icon -> Disassemble `D`) to keep Site B visible and cleanly aligned. - ---- - -## Task 3: Find and Patch Bug #2: The False TRACK Banner (10 points) - -### Solution - -**Criterion 3.1: Locate the Banner String (3 points).** - -| String | Address | -|--------|---------| -| `"TRACK: NORMAL\r"` | `0x1000C4B8` | -| `"NORMAL"` substring to patch | `0x1000C4BF` | - -The string is loaded in `main` and printed once at boot; it never reads the -sensor. - -**Criterion 3.2: Patch Six Characters (4 points).** -`NORMAL` and `DANGER` are both six ASCII characters, so the patch preserves the -length. - -| Address Range | Original Bytes | Patched Bytes | -|---------------|----------------|---------------| -| `0x1000C4BF` - `0x1000C4C4` | `4E 4F 52 4D 41 4C` | `44 41 4E 47 45 52` | - -**Criterion 3.3: Character-by-Character Documentation (2 points).** - -| Address | Original Char | Original Byte | Patched Char | Patched Byte | -|---------|---------------|---------------|--------------|--------------| -| `0x1000C4BF` | N | `4E` | D | `44` | -| `0x1000C4C0` | O | `4F` | A | `41` | -| `0x1000C4C1` | R | `52` | N | `4E` | -| `0x1000C4C2` | M | `4D` | G | `47` | -| `0x1000C4C3` | A | `41` | E | `45` | -| `0x1000C4C4` | L | `4C` | R | `52` | - -**Criterion 3.4: Explain the Danger of a Hardcoded Status Word (1 point).** -The banner never consults the reading, so it reports a healthy track even while -the frozen reading is dangerous, masking the hazard from the operator. - -### Grading Rubric (1-to-1 Mapping) - -| Criterion | Points | Full Credit (Answer Key) | Partial Credit | No Credit | -|-----------|--------|--------------------------|----------------|-----------| -| Criterion 3.1: Locate the Banner String | 3 | Correct address and cross-reference | Approximate | Not found | -| Criterion 3.2: Patch Six Characters | 4 | All six bytes changed, length preserved | Correct text, wrong bytes documented | Wrong length | -| Criterion 3.3: Character-by-Character Documentation | 2 | Original vs patched byte for all six characters | Partial | Missing | -| Criterion 3.4: Explain the Danger of a Hardcoded Status Word | 1 | Clear, specific reasoning | Generic | Missing | - -### Instructor Notes & Assembly - -- `NORMAL` and `DANGER` are both six characters; the patch must not change the - string length or overwrite adjacent flash. -- Confirm the patch covers `0x1000C4BF` through `0x1000C4C4` exactly. -- The banner is printed once at boot and never recomputed, so it is a separate - defect from the threshold. - ---- - -## Task 4: Find and Patch Bug #3: The Block Length Constant (10 points) - -### Solution - -**Criterion 4.1: Locate the .data Double (3 points).** -The console prints `BLOCK LENGTH: 3200 M` from the format string at -`0x1000C4F0`. The value is a `double` in the `.data` init image at -`0x1000EC60` (loaded into `0x20001188` at boot). - -**Criterion 4.2: IEEE-754 Bytes and Print Math (4 points).** -Eight bytes at `0x1000EC60`: - -```text -9A 99 99 99 99 99 09 40 -> 0x400999999999999A -> 3.2 km -> 3200 m -7B 14 AE 47 E1 7A D4 3F -> 0x3FD47AE147AE147B -> 0.32 km -> 320 m -``` - -**Criterion 4.3: Patch to Print 320 M (3 points).** - -| File Offset Range | Flash Address Range | Original Bytes | Patched Bytes | -|-------------------|---------------------|----------------|---------------| -| `0xEC60` - `0xEC67` | `0x1000EC60` - `0x1000EC67` | `9A 99 99 99 99 99 09 40` | `7B 14 AE 47 E1 7A D4 3F` | - -At `0x1000EC68` the adjacent telemetry fields (`03 00 00 00` flags and `07 00` -crossing) are left untouched. - -### Grading Rubric (1-to-1 Mapping) - -| Criterion | Points | Full Credit (Answer Key) | Partial Credit | No Credit | -|-----------|--------|--------------------------|----------------|-----------| -| Criterion 4.1: Locate the .data Double | 3 | Correct address traced from the BLOCK LENGTH print | Approximate | Not found | -| Criterion 4.2: IEEE-754 Bytes and Print Math | 4 | Original and patched 8-byte double with print math (3200 M to 320 M) | Correct patch, no math | Wrong bytes | -| Criterion 4.3: Patch to Print 320 M | 3 | Console shows `BLOCK LENGTH: 320 M` | Wrong bytes | Not patched | - -### Instructor Notes & Assembly - -- The value is an 8-byte IEEE-754 double, not an integer. Follow the - `BLOCK LENGTH` print into `.data` at `0x1000EC60`. -- The patched bytes `7B 14 AE 47 E1 7A D4 3F` decode to `0.32 km` (`320 m`). -- Confirm the adjacent telemetry fields at `0x1000EC68` (`03 00 00 00` and - `07 00`) are left untouched. - ---- - -## Task 5: Find and Patch Bug #4: The Signal Seed (15 points) - -### Solution - -**Criterion 5.1: Locate SIGNAL_SPEC and the Seed (5 points).** -The SIMPLE comparison in the loop is at `0x100003A6`: - -```text -100003a6: 4559 cmp r1, fp ; fp = SIGNAL_SPEC = 0x2D879291 (pool 0x100004FC) -``` - -The corrupted seed is a `0x0A0A0A0A` word in the `.data` init image at -`0x1000EC70` (loaded into `0x20001198` at boot). The byte values `0A 0A 0A 0A` -also appear in the `tbb` jump table at `0x100003D4`; those are not the seed. - -**Criterion 5.2: Patch the Seed (4 points).** -The required seed is the ChaCha expand word `0x6B206574` (`"te k"`), stored -little-endian as `74 65 20 6B`. - -| File Offset Range | Flash Address Range | Original Bytes | Patched Bytes | -|-------------------|---------------------|----------------|---------------| -| `0xEC70` - `0xEC73` | `0x1000EC70` - `0x1000EC73` | `0A 0A 0A 0A` | `74 65 20 6B` | - -**Criterion 5.3: Explain the ARX Derivation (3 points).** -`derive_session_key(seed, iv)` works exactly like this: - -1. Set `a = seed`, `b = iv`, `c = 0x61707865`, `d = 0x3320646E`. -2. Run four ChaCha quarter-rounds. A quarter-round runs four phases with rotate - amounts 16, 12, 8, 7. Each phase is: `a = a + b; d = d XOR a; - d = rotate_left(d, s); c = c + d; b = b XOR c; b = rotate_left(b, s)`. -3. Return `a XOR d`. - -The runtime IV is `derive_session_key(0x6B206574, 0) = 0x43C974F6`. The shipped -seed `0x0A0A0A0A` gives `derive_session_key(0x0A0A0A0A, 0x43C974F6) = -0x915DCFF8` (MISMATCH). The honest seed `0x6B206574` gives -`derive_session_key(0x6B206574, 0x43C974F6) = 0x2D879291`, which equals -`SIGNAL_SPEC` and prints `OK`. - -**Criterion 5.4: Separate the Security Layers (3 points).** -The signal seed only controls the local `SIGNAL KEY` telemetry check. It does -not authenticate the operator. The Argon2id plus XChaCha20-Poly1305 gate is a -separate layer that requires the 12-word passphrase. - -### Grading Rubric (1-to-1 Mapping) - -| Criterion | Points | Full Credit (Answer Key) | Partial Credit | No Credit | -|-----------|--------|--------------------------|----------------|-----------| -| Criterion 5.1: Locate SIGNAL_SPEC and the Seed | 5 | `0x2D879291` located and wrong seed `0x0A0A0A0A` found | Partial | Not found | -| Criterion 5.2: Patch the Seed | 4 | Seed bytes changed to `74 65 20 6B` | Wrong byte | Not patched | -| Criterion 5.3: Explain the ARX Derivation | 3 | Correct trace of the per-cycle derivation | Vague | Missing | -| Criterion 5.4: Separate the Security Layers | 3 | Correctly explains what the seed fixes versus the gate | Generic | Missing | - -### Instructor Notes & Assembly - -- The seed is at `0x1000EC70` in the `.data` init image. The `0A 0A 0A 0A` - bytes in the `tbb` jump table at `0x100003D4` are not the seed. -- The patched seed `74 65 20 6B` is the little-endian form of the ChaCha expand - word `0x6B206574` (`"te k"`). -- The seed only affects the local `SIGNAL KEY` check; the Argon2id plus - XChaCha20-Poly1305 gate is a separate authentication layer. - ---- - -## Task 6: GDB Register Capture of the Derived Key (15 points) - -### Solution - -**Criterion 6.1: Breakpoint at the Derive Return (4 points).** -The per-cycle derive is `bl derive_session_key` at `0x10000352`. Break at the -next instruction, `0x10000356`, and read `$r0`. On the shipped image it is -`0x915DCFF8`. - -```gdb -(gdb) break *0x10000356 -(gdb) continue -(gdb) print/x $r0 # 0x915DCFF8 on the corrupted image -``` - -**Criterion 6.2: Inspect the Two Arguments (4 points).** -At the call entry `0x10000352`: - -| Register | Corrupted image | Meaning | -|----------|-----------------|---------| -| `$r0` | `0x0A0A0A0A` | Seed | -| `$r1` | `0x43C974F6` | Derived IV | - -**Criterion 6.3: Override the Register (4 points).** -With execution at `0x10000356`, set `$r0` to the spec key, then continue. The -next cycle prints `SIGNAL KEY: 0x2D879291 OK`. - -```gdb -(gdb) set $r0 = 0x2D879291 -(gdb) continue -``` - -**Criterion 6.4: Watchpoint on the Stored Key (3 points).** -The key is stored in SRAM at `0x200020DC` (`str r0, [r6, #0]`). - -```gdb -(gdb) watch *0x200020DC -``` - -### Grading Rubric (1-to-1 Mapping) - -| Criterion | Points | Full Credit (Answer Key) | Partial Credit | No Credit | -|-----------|--------|--------------------------|----------------|-----------| -| Criterion 6.1: Breakpoint at the Derive Return | 4 | Correct address and `$r0` read as the bug-derived key | Address off | Not found | -| Criterion 6.2: Inspect the Two Arguments | 4 | Live seed and derived IV captured at the second call | One correct | Missing | -| Criterion 6.3: Override the Register | 4 | `$r0` set to `0x2D879291` and the next cycle shows `OK` | Partial | Missing | -| Criterion 6.4: Watchpoint on the Stored Key | 3 | Watchpoint on the SRAM key location documented | Approximate | Missing | - -### Instructor Notes & Assembly - -- Confirm the breakpoint is placed at `0x10000356`, the instruction after the - `bl derive_session_key` at `0x10000352`. -- On the shipped image `$r0` reads `0x915DCFF8`; `$r0` is the seed `0x0A0A0A0A` - and `$r1` is the derived IV `0x43C974F6`. -- The stored key lives at `0x200020DC`; accept the documented watchpoint. - ---- - -## Task 7: Recover the Ouroboros Authority Frame (10 points) - -### Solution - -**Criterion 7.1: Locate Salt, Nonce, Ciphertext, and Tag (4 points).** - -| Component | Flash Address | Size | -|-----------|---------------|------| -| Ciphertext + Tag | `0x1000CE94` | 64 B | -| Nonce | `0x1000CED4` | 24 B | -| Salt | `0x1000CEEC` | 16 B | - -**Criterion 7.2: Document Argon2id Parameters and Payload Contract (2 points).** -Argon2id: memory `64 KiB`, iterations `3`, parallelism `1`, output key `32 B`, -salt the 16 bytes above. XChaCha20-Poly1305 decrypts the 48-byte ciphertext with -the 16-byte tag. The plaintext is `01 68 65 6C 6C 6F 0D 0A` followed by zeros: -byte 0 turns the GPIO 25 LED on, and bytes 1 through 7 are printed as `hello` -plus carriage-return and newline. - -**Criterion 7.3: Authenticate with the 12-Word Passphrase (2 points).** -At the `RESPONSE> ` prompt, type: - -```text -orbit olive ladder marble quartz canyon ripple saddle violet ember walnut falcon -``` - -Expected result (proven on hardware): - -```text -hello -AUTHORITY FRAME: VERIFIED -``` - -**Criterion 7.4: State the Honest Quantum Boundary (2 points).** -Grover-style search halves the effective security exponent of a symmetric key, -so a 256-bit key gives about 128 bits of quantum security. The construction uses -classical symmetric and password-hashing primitives and does not implement NIST -post-quantum standards. - -### Grading Rubric (1-to-1 Mapping) - -| Criterion | Points | Full Credit (Answer Key) | Partial Credit | No Credit | -|-----------|--------|--------------------------|----------------|-----------| -| Criterion 7.1: Locate Salt, Nonce, Ciphertext, and Tag | 4 | All three addresses correct in flash | Two correct | Not found | -| Criterion 7.2: Document Argon2id Parameters and Payload Contract | 2 | Correct memory/time/parallelism and payload layout | Partial | Missing | -| Criterion 7.3: Authenticate with the 12-Word Passphrase | 2 | `AUTHORITY FRAME: VERIFIED`, LED on, payload printed | Partial | Not shown | -| Criterion 7.4: State the Honest Quantum Boundary | 2 | Grover halves symmetric exponents; not strict PQC | Generic | Misstates | - -### Instructor Notes & Assembly - -- Verify the three component addresses in flash: ciphertext plus tag at - `0x1000CE94`, nonce at `0x1000CED4`, salt at `0x1000CEEC`. -- The passphrase is fixed for the lab; a successful gate prints `hello` and - `AUTHORITY FRAME: VERIFIED` and lights the on-board authority LED. -- Grade Criterion 7.4 on the honest boundary: 256-bit symmetric key maps to - about 128 bits under Grover, and the design is not NIST post-quantum. - ---- - -## Task 8: Export and Verify (8 points) - -### Solution - -**Criterion 8.1: Export CTF-02_fixed.bin (1 point).** -Export the patched program from Ghidra (`File -> Export Program...`, `Binary -Format`) as `CTF-02_fixed.bin`. The shipped image is 62,308 bytes. - -**Criterion 8.2: Convert to CTF-02_fixed.uf2 (1 point).** - -```bash -python uf2conv.py CTF-02_fixed.bin --base 0x10000000 --family 0xe48bff59 --output CTF-02_fixed.uf2 -``` - -**Criterion 8.3: Hardware Verification (4 points).** - -Before patching: - -```text -DEEPLINE METRO AUTHORITY -ADAPTIVE SIGNAL WINDOW: 38 MINUTES -USB-CDC 115200 8N1 | AUTHORIZED LAB CONSOLE -TRACK: NORMAL -BLOCK STATE: STABLE -AUTO TRAIN: AUTHORIZED -BLOCK LENGTH: 3200 M -FAULT POLLS: 1 -SIGNAL KEY: 0x915DCFF8 MISMATCH -RESPONSE> -``` - -After all four patches: - -```text -DEEPLINE METRO AUTHORITY -ADAPTIVE SIGNAL WINDOW: 38 MINUTES -USB-CDC 115200 8N1 | AUTHORIZED LAB CONSOLE -TRACK: DANGER -BLOCK STATE: CRITICAL -AUTO TRAIN: HELD -BLOCK LENGTH: 320 M -FAULT POLLS: 1 -SIGNAL KEY: 0x2D879291 OK -RESPONSE> -``` - -**Criterion 8.4: Summary Table of All Patches (2 points).** - -| # | Bug | File Offset | Flash Address | Original Bytes | Patched Bytes | -|---|-----|-------------|---------------|----------------|---------------| -| 1a | Operator threshold | `0x0302` | `0x10000302` | `5E 2B` | `3B 2B` | -| 1b | Dispatch threshold | `0x0312` | `0x10000312` | `5E 2B` | `3B 2B` | -| 2 | TRACK banner | `0xC4BF` - `0xC4C4` | `0x1000C4BF` - `0x1000C4C4` | `4E 4F 52 4D 41 4C` | `44 41 4E 47 45 52` | -| 3 | Block length | `0xEC60` - `0xEC67` | `0x1000EC60` - `0x1000EC67` | `9A 99 99 99 99 99 09 40` | `7B 14 AE 47 E1 7A D4 3F` | -| 4 | Signal seed | `0xEC70` - `0xEC73` | `0x1000EC70` - `0x1000EC73` | `0A 0A 0A 0A` | `74 65 20 6B` | - -### Grading Rubric (1-to-1 Mapping) - -| Criterion | Points | Full Credit (Answer Key) | Partial Credit | No Credit | -|-----------|--------|--------------------------|----------------|-----------| -| Criterion 8.1: Export CTF-02_fixed.bin | 1 | Valid patched binary | Corrupted | Not submitted | -| Criterion 8.2: Convert to CTF-02_fixed.uf2 | 1 | Correct base and family flags | Wrong flags | Not submitted | -| Criterion 8.3: Hardware Verification | 4 | Corrected console output confirmed on hardware | Some lines corrected | No verification | -| Criterion 8.4: Summary Table of All Patches | 2 | Complete address and before/after table | Missing entries | No table | - -### Instructor Notes & Assembly - -- Verify the exported image with `python3 scripts/verify_ctf.py`; the shipped - check expects `26/26 checks passed` against `CTF-02.bin`. -- Confirm the UF2 conversion used base `0x10000000` and family `0xe48bff59`. -- **Serial Terminal Timing:** Note that `print_identity()` (`TRACK: NORMAL`) - fires within the first 5 milliseconds of boot. In normal lab usage, PuTTY - attaches after boot and will display the continuous 2-second status loop - (`BLOCK STATE: CRITICAL`, `AUTO TRAIN: HELD`). To see the corrected banner, - the student must pulse `RUN` to `GND` while PuTTY is open, or demonstrate - the string change at `0x1000C4BF` via Ghidra static analysis. -- The shipped image is 62,308 bytes; confirm the exported corrected image is a - valid patched binary with all four fixes present. - ---- - -## Task 9: Written Reflection (5 points) - -### Solution - -**Criterion 9.1: "Rushed Build" Is Not an Excuse (2 points).** -The rebuild shipped four constants that were never checked against their -documented limits, which is exactly what produced the false-safe reading. -Pressure explains why the checks were skipped, not why they should be skipped. - -**Criterion 9.2: One Engineering Practice per Failure Area (3 points).** -- Physical limits (Bugs #1 and #3): one shared configuration header plus a - build-time assertion that each compiled limit matches its documented value. -- Banner (Bug #2): remove static banners; a hardware-in-the-loop test that - compares displayed state to the live register. -- Seed integrity (Bug #4): reproducible builds with golden artifact hash - comparison so keys and seeds match the certified specification. -- Image authenticity: enable RP2350 hardware secure boot with OTP hash - verification so a modified image will not run. - -### Grading Rubric (1-to-1 Mapping) - -| Criterion | Points | Full Credit (Answer Key) | Partial Credit | No Credit | -|-----------|--------|--------------------------|----------------|-----------| -| Criterion 9.1: "Rushed Build" Is Not an Excuse | 2 | Specific, grounded reasoning | Generic | Missing | -| Criterion 9.2: One Engineering Practice per Failure Area | 3 | Concrete practices for the bugs and for image authenticity | Names some | Missing | - -### Instructor Notes & Assembly - -- Grade the specificity of the reasoning, not the length of the prose. -- Require concrete practices across the failure areas, including at least one - practice for image authenticity. - ---- - -## How To Breadboard - -- **Raspberry Pi Pico 2** powered over USB. -- **USB-CDC virtual serial console:** open the Pico's COM port at 115200 baud, - 8 data bits, no parity, 1 stop bit. -- **SWD debug probe:** connect SWCLK, SWDIO, GND, and 3.3 V to the Pico debug - header for GDB inspection and register capture. -- No other peripherals are required; the authority LED is on-board. - ---- - -## Complete Grading Summary - -| Task | Title | Points | -|------|-------|--------| -| Task 1 | Setup and Initial Analysis | 12 | -| Task 2 | Find and Patch Bug #1: The Miscalibrated Release Threshold | 15 | -| Task 3 | Find and Patch Bug #2: The False TRACK Banner | 10 | -| Task 4 | Find and Patch Bug #3: The Block Length Constant | 10 | -| Task 5 | Find and Patch Bug #4: The Signal Seed | 15 | -| Task 6 | GDB Register Capture of the Derived Key | 15 | -| Task 7 | Recover the Ouroboros Authority Frame | 10 | -| Task 8 | Export and Verify | 8 | -| Task 9 | Written Reflection | 5 | -| **TOTAL** | | **100** | - ---- - -## Instructor Notes - -Safety: Use only the supplied Pico 2, SWD probe, and firmware. Never connect the -exercise to an operational railway, metro system, public network, military -system, or third-party device. - -### Common Student Mistakes - -- Patching only one threshold site (`0x10000302` or `0x10000312`), leaving one - status line lying. -- Assuming the immediate equals the limit, producing an off-by-one boundary; - the correct byte is `0x3B` (59), not `0x3C` (60). -- Replacing the banner string with a different length, corrupting adjacent - flash; `NORMAL` and `DANGER` are both 6 bytes. -- Treating the block length as an integer and missing the 8-byte double in - `.data`. -- Using the wrong `0.32` bytes and printing `316 M` instead of `320 M`. -- Treating the odd vector address `0x1000015B` as invalid instead of clearing - bit 0 to get `0x1000015A`. -- Starting the seed patch at the wrong offset; the seed is at `0x1000EC70`. - -### Partial Credit Guidelines - -- Award partial credit for one correct threshold site out of two, or for a - correct immediate value without the `<` to `<=` reasoning. -- Award partial credit for a correct banner text with incorrectly documented - bytes, or for partial character-by-character documentation. -- Award partial credit for a correct block-length patch without the IEEE-754 - print math. -- Award partial credit for one of the two GDB argument captures, or for a - partial register override. -- Award no credit for patches that change string length or overwrite adjacent - flash. - ---- - -## Appendix: Expected Binary Diff - -| # | Bug | File Offset(s) | Flash Address(es) | Original Bytes | Patched Bytes | -|---|-----|----------------|-------------------|----------------|---------------| -| 1a | Operator threshold | `0x0302` | `0x10000302` | `5E 2B` | `3B 2B` | -| 1b | Dispatch threshold | `0x0312` | `0x10000312` | `5E 2B` | `3B 2B` | -| 2 | TRACK banner | `0xC4BF` - `0xC4C4` | `0x1000C4BF` - `0x1000C4C4` | `4E 4F 52 4D 41 4C` | `44 41 4E 47 45 52` | -| 3 | Block length | `0xEC60` - `0xEC67` | `0x1000EC60` - `0x1000EC67` | `9A 99 99 99 99 99 09 40` | `7B 14 AE 47 E1 7A D4 3F` | -| 4 | Signal seed | `0xEC70` - `0xEC73` | `0x1000EC70` - `0x1000EC73` | `0A 0A 0A 0A` | `74 65 20 6B` | - -Four defects, five changed regions: two immediate bytes (`0x3B 2B` at each -threshold), six banner bytes, eight block-length bytes, and four seed bytes. diff --git a/0x0017a_ctf/CTF-02-S.pdf b/0x0017a_ctf/CTF-02-S.pdf deleted file mode 100644 index e2c7dc8..0000000 Binary files a/0x0017a_ctf/CTF-02-S.pdf and /dev/null differ diff --git a/0x0017a_ctf/CTF-02.bin b/0x0017a_ctf/CTF-02.bin deleted file mode 100644 index b20d1cd..0000000 Binary files a/0x0017a_ctf/CTF-02.bin and /dev/null differ diff --git a/0x0017a_ctf/CTF-02.uf2 b/0x0017a_ctf/CTF-02.uf2 deleted file mode 100644 index b0a537c..0000000 Binary files a/0x0017a_ctf/CTF-02.uf2 and /dev/null differ diff --git a/0x0017a_ctf/CTF-02_fixed.bin b/0x0017a_ctf/CTF-02_fixed.bin deleted file mode 100644 index 0918eac..0000000 Binary files a/0x0017a_ctf/CTF-02_fixed.bin and /dev/null differ diff --git a/0x0017a_ctf/CTF-02_fixed.uf2 b/0x0017a_ctf/CTF-02_fixed.uf2 deleted file mode 100644 index 830dd27..0000000 Binary files a/0x0017a_ctf/CTF-02_fixed.uf2 and /dev/null differ diff --git a/0x0017a_ctf/include/auth.h b/0x0017a_ctf/include/auth.h deleted file mode 100644 index e8ddc9e..0000000 --- a/0x0017a_ctf/include/auth.h +++ /dev/null @@ -1,143 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent/encryption-c-rp2350 -// File: auth.h -// Desc: Declares the Ouroboros authentication engine API for RP2350 firmware. -// Created: 2026 - -#ifndef AUTH_H -#define AUTH_H - -#include -#include -#include - -/** - * @brief Onboard LED GPIO pin number. - * - * The RP2350 Pico 2 onboard LED is connected to GPIO 25. Driven high - * on successful authentication and low on failure or idle. - */ -#define AUTH_LED_PIN 25u - -/** - * @brief Maximum accepted terminal passphrase length in bytes. - * - * The CLI accepts interactive human-entered passphrases up to 512 bytes, - * matching the hardened host demo boundary before policy validation. - */ -#define AUTH_PASSPHRASE_MAX_LEN 512u - -/** - * @brief Required number of lowercase words in the hardened passphrase. - * - * The embedded hardened workflow matches the host-side policy exactly: - * twelve lowercase ASCII words separated by whitespace. - */ -#define AUTH_REQUIRED_WORDS 12u - -/** - * @brief Hardened Argon2id salt size in bytes. - * - * Every demo artifact carries a per-ciphertext random 128-bit salt. - */ -#define AUTH_SALT_SIZE 16u - -/** - * @brief Hardened XChaCha20 nonce size in bytes. - * - * XChaCha20-Poly1305 consumes a 192-bit nonce in the outer construction. - */ -#define AUTH_NONCE_SIZE 24u - -/** - * @brief Subkey size in bytes derived from Argon2id. - * - * The AEAD key size is 256 bits. - */ -#define AUTH_KEY_SIZE 32u - -/** - * @brief AEAD authentication tag size in bytes. - * - * XChaCha20-Poly1305 appends a 128-bit authentication tag. - */ -#define AUTH_TAG_SIZE 16u - -/** - * @brief Plaintext payload size in bytes. - * - * The fixed dispatch payload is 48 bytes: LED state, UART bytes, - * and trailing reserved bytes matching the Rust hardened demo layout. - */ -#define AUTH_PAYLOAD_SIZE 48u - -/** - * @brief Full ciphertext-plus-tag artifact size in bytes. - * - * The encrypted payload is 48 bytes followed by a 16-byte tag. - */ -#define AUTH_CIPHERTEXT_SIZE (AUTH_PAYLOAD_SIZE + AUTH_TAG_SIZE) - -/** - * @brief Authentication result codes returned by the hardened engine. - * - * These values let the CLI distinguish policy failures from - * cryptographic authentication failures without guessing. - */ -typedef enum auth_result { - AUTH_RESULT_SUCCESS = 0, - AUTH_RESULT_POLICY_VIOLATION = 1, - AUTH_RESULT_AUTHENTICATION_FAILED = 2, - AUTH_RESULT_INTERNAL_ERROR = 3, -} auth_result_t; - -/** - * @brief Initialize the Ouroboros authentication module. - * - * Configures the onboard LED GPIO and marks the hardened engine as ready - * for passphrase authentication. - * - * @param None. - * @return bool true when initialization is successful, else false. - */ -bool auth_init(void); - -/** - * @brief Execute the hardened Ouroboros authentication pipeline. - * - * Validates the strict 12-word lowercase passphrase policy, derives the - * 256-bit AEAD key with Argon2id using artifact parameters, decrypts the - * embedded XChaCha20-Poly1305 ciphertext, and dispatches GPIO25/UART - * payload bytes on success. - * - * @param passphrase Pointer to passphrase bytes. - * @param passphrase_len Number of passphrase bytes. - * @return auth_result_t Detailed authentication outcome for the caller. - */ -auth_result_t auth_execute(const uint8_t *passphrase, - size_t passphrase_len); - -#endif // AUTH_H diff --git a/0x0017a_ctf/include/cli.h b/0x0017a_ctf/include/cli.h deleted file mode 100644 index f14d375..0000000 --- a/0x0017a_ctf/include/cli.h +++ /dev/null @@ -1,59 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: cli.h -// Desc: Declares the CLI UART passphrase input interface for Ouroboros. -// Created: 2026 - -#ifndef CLI_H -#define CLI_H - -#include - -/** - * @brief Print the UART passphrase prompt. - * - * Emits a minimal shell-style prompt followed by a space so the - * terminal clearly indicates that hardened passphrase input is expected. - * - * @param None. - * @return None. - */ -void print_prompt(void); - -/** - * @brief Service one UART polling step for passphrase input. - * - * Polls stdio for a character, dispatches backspace or newline - * handling, and appends printable characters to the passphrase - * buffer. Call repeatedly from the main loop. - * - * @param buf Pointer to mutable passphrase buffer. - * @param idx Pointer to current buffer length. - * @return None. - */ -void service_uart(char *buf, size_t *idx); - -#endif // CLI_H diff --git a/0x0017a_ctf/include/demo_artifact.h b/0x0017a_ctf/include/demo_artifact.h deleted file mode 100644 index b7857a0..0000000 --- a/0x0017a_ctf/include/demo_artifact.h +++ /dev/null @@ -1,60 +0,0 @@ -// 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. -// -// This file is generated by scripts/dec.py. Do not edit by hand. - -#ifndef DEMO_ARTIFACT_H -#define DEMO_ARTIFACT_H - -#include - -#define DEMO_ARTIFACT_FORMAT "ouroboros-hardened-demo-v1" -#define DEMO_MEMORY_KIB 64u -#define DEMO_ITERATIONS 3u -#define DEMO_PARALLELISM 1u - -static const uint8_t DEMO_SALT[16] = { - 0xF2u, 0xD5u, 0x18u, 0x63u, 0x9Au, 0x82u, 0x01u, 0x9Du, - 0xC2u, 0xD7u, 0xAFu, 0xA5u, 0xCDu, 0xB6u, 0xD8u, 0x71u -}; - -static const uint8_t DEMO_NONCE[24] = { - 0x1Cu, 0xEFu, 0x79u, 0x0Du, 0x77u, 0x9Eu, 0x7Cu, 0x04u, - 0xE7u, 0xF0u, 0x66u, 0xDDu, 0x90u, 0xD0u, 0x80u, 0x70u, - 0x87u, 0x97u, 0x67u, 0x1Fu, 0x79u, 0xEFu, 0xC4u, 0xE4u -}; - -static const uint8_t DEMO_CIPHERTEXT_AND_TAG[64] = { - 0x2Cu, 0x23u, 0xB2u, 0x7Eu, 0x95u, 0x62u, 0xB8u, 0xEDu, - 0x9Eu, 0x08u, 0xE0u, 0x6Du, 0xD9u, 0x9Du, 0xB4u, 0x91u, - 0x3Eu, 0x81u, 0x9Au, 0x77u, 0x8Bu, 0xB4u, 0x7Bu, 0x71u, - 0xBCu, 0x66u, 0x1Eu, 0x6Eu, 0x73u, 0x1Au, 0x81u, 0x54u, - 0xCDu, 0xB5u, 0x36u, 0xA4u, 0x76u, 0x7Eu, 0x9Bu, 0xF8u, - 0x53u, 0x3Eu, 0x03u, 0x1Du, 0xB8u, 0xE5u, 0xAEu, 0x7Au, - 0xADu, 0xB4u, 0x31u, 0xCFu, 0x12u, 0xD9u, 0xF9u, 0xC4u, - 0x5Fu, 0xA9u, 0xB9u, 0x4Bu, 0x80u, 0xDCu, 0xBBu, 0xDEu -}; - -#endif // DEMO_ARTIFACT_H diff --git a/0x0017a_ctf/include/mbedtls_config.h b/0x0017a_ctf/include/mbedtls_config.h deleted file mode 100644 index b27211e..0000000 --- a/0x0017a_ctf/include/mbedtls_config.h +++ /dev/null @@ -1,39 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: mbedtls_config.h -// Desc: Configures the minimal mbedTLS cryptographic features required by -// the Ouroboros AEAD engine on RP2350. -// Created: 2026 - -#ifndef MBEDTLS_CONFIG_H -#define MBEDTLS_CONFIG_H - -#define MBEDTLS_CHACHA20_C -#define MBEDTLS_CHACHAPOLY_C -#define MBEDTLS_POLY1305_C -#define MBEDTLS_PLATFORM_C - -#endif // MBEDTLS_CONFIG_H diff --git a/0x0017a_ctf/pico_sdk_import.cmake b/0x0017a_ctf/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x0017a_ctf/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x0017a_ctf/scripts/dec.py b/0x0017a_ctf/scripts/dec.py deleted file mode 100644 index 389efaf..0000000 --- a/0x0017a_ctf/scripts/dec.py +++ /dev/null @@ -1,944 +0,0 @@ -"""Generate hardened demo artifacts for the RP2350 Ouroboros firmware. - -This script writes the same JSON schema used by the Rust demo and also emits -the generated C header consumed by the embedded firmware. -""" - -import argparse -import json -import platform -import secrets -import sys -from pathlib import Path -from typing import Optional - - -DEFAULT_PASSPHRASE = ( - "orbit olive ladder marble quartz canyon " - "ripple saddle violet ember walnut falcon" -) -DEFAULT_TEXT = "hello" -DEFAULT_OUTPUT_JSON = "scripts/demo_artifact.json" -DEFAULT_OUTPUT_HEADER = "include/demo_artifact.h" -DEFAULT_MEMORY_KIB = 64 -DEFAULT_ITERATIONS = 3 -DEFAULT_PARALLELISM = 1 -ARTIFACT_FORMAT = "ouroboros-hardened-demo-v1" - -_KEY_HELP = "12-word lowercase passphrase" -_TEXT_HELP = "Text to place in payload bytes 1..7" -_OUT_HELP = "Output JSON artifact path" -_HEADER_OUT_HELP = "Output generated C header path" -_FROM_JSON_HELP = ( - "Load existing JSON artifact and emit header without re-encrypting" -) -_CHECK_HEADER_HELP = ( - "Optional path to compare against generated header and fail if stale" -) -_SALT_HEX_HELP = "Optional fixed 16-byte salt as hex" -_NONCE_HEX_HELP = "Optional fixed 24-byte nonce as hex" -_NO_CRLF_HELP = "Do not append CRLF to payload text" -_LED_OFF_HELP = "Encode LED off instead of on" -_MEMORY_HELP = "Argon2 memory cost in KiB" -_ITERATIONS_HELP = "Argon2 time cost" -_PARALLELISM_HELP = "Argon2 parallel lanes" - -_POLICY_ERROR = ( - "Hardened mode requires exactly 12 lowercase ASCII words in --key." -) -_PAYLOAD_TOO_LONG = ( - "Output text is too long for fixed dispatch " - "(max 7 bytes after CRLF handling)." -) -_INVALID_JSON = "Artifact JSON at {0} is invalid JSON." -_MISMATCH_PREFIX = "Detected a Python native-extension architecture mismatch. " -_REINSTALL_DEPS = ("Recreate this virtual environment with a native Python " - "and reinstall deps:") -_REINSTALL_LINES = ( - "rm -rf .venv", - "python3 -m venv .venv", - "source .venv/bin/activate", - "python3 -m pip install -U pip setuptools wheel", - "python3 -m pip install argon2-cffi pynacl", -) -_HEADER_TEMPLATE = """// 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. -// -// This file is generated by scripts/dec.py. Do not edit by hand. - -#ifndef DEMO_ARTIFACT_H -#define DEMO_ARTIFACT_H - -#include - -#define DEMO_ARTIFACT_FORMAT "{artifact_format}" -#define DEMO_MEMORY_KIB {memory_kib}u -#define DEMO_ITERATIONS {iterations}u -#define DEMO_PARALLELISM {parallelism}u - -static const uint8_t DEMO_SALT[16] = {{ -{salt_body} -}}; - -static const uint8_t DEMO_NONCE[24] = {{ -{nonce_body} -}}; - -static const uint8_t DEMO_CIPHERTEXT_AND_TAG[64] = {{ -{cipher_body} -}}; - -#endif // DEMO_ARTIFACT_H -""" - - -def _raise_dependency_error(package_name, install_hint, exc): - """Raise a RuntimeError with environment-aware dependency diagnostics. - - Parameters - ---------- - package_name : str - Package common name for the error message. - install_hint : str - Pip install command in the error message. - exc : Exception - Import error observed while loading the native module. - - Returns - ------- - None - """ - message = "Hardened mode requires {0}. Install with: {1}".format( - package_name, install_hint) - message += _reinstall_message() if _is_arch_mismatch(exc) else "" - raise RuntimeError(message) from exc - - -def _is_arch_mismatch(exc): - """Report whether the interpreter likely has a native-extension mismatch. - - Parameters - ---------- - exc : Exception - Import error observed while loading the native module. - - Returns - ------- - bool - True when the error text matches a native architecture mismatch. - """ - detail = str(exc) - return ( - "incompatible architecture" in detail - or "_cffi_backend" in detail - or "mach-o file, but is an incompatible architecture" in detail - ) - - -def _reinstall_message(): - """Build the native-interpreter reinstall diagnostic text. - - Parameters - ---------- - None - - Returns - ------- - str - Newline-delimited machine and reinstall details, or an empty string. - """ - machine = platform.machine() - head = (_MISMATCH_PREFIX - + "Current interpreter reports machine=" + machine - + ", executable=" + sys.executable + ".") - lines = [" {0}".format(item) for item in _REINSTALL_LINES] - return ("\n" + head + "\n" + _REINSTALL_DEPS + "\n" - + "\n".join(lines)) - - -def _is_policy_compliant(passphrase): - """Return True when passphrase is exactly 12 lowercase ASCII words. - - Parameters - ---------- - passphrase : str - Candidate operator passphrase. - - Returns - ------- - bool - True when the passphrase satisfies the gate policy. - """ - words = passphrase.split() - if len(words) != 12: - return False - return all( - word and all(ch.isascii() and ch.islower() for ch in word) - for word in words - ) - - -def _build_payload(text_str, led_on=True, append_crlf=True): - """Build the fixed 48-byte payload dispatched by the firmware. - - Parameters - ---------- - text_str : str - Console text placed in payload bytes 1..7. - led_on : bool - True turns the LED byte on, False leaves it off. - append_crlf : bool - True appends CRLF to the console text. - - Returns - ------- - bytes - Fixed 48-byte dispatch payload. - """ - tx_bytes = text_str.encode() + (b"\r\n" if append_crlf else b"") - if len(tx_bytes) > 7: - raise ValueError(_PAYLOAD_TOO_LONG) - payload = bytearray(48) - payload[0] = 1 if led_on else 0 - payload[1:1 + len(tx_bytes)] = tx_bytes - return bytes(payload) - - -def _resolve_salt_nonce(salt, nonce): - """Confirm or generate the 16-byte salt and 24-byte nonce. - - Parameters - ---------- - salt : bytes or None - Optional fixed salt value. - nonce : bytes or None - Optional fixed nonce value. - - Returns - ------- - tuple - Confirmed (salt, nonce) byte values. - """ - salt_word = secrets.token_bytes(16) if salt is None else salt - nonce_word = secrets.token_bytes(24) if nonce is None else nonce - if len(salt_word) != 16: - raise ValueError("Hardened salt must be exactly 16 bytes.") - if len(nonce_word) != 24: - raise ValueError("Hardened nonce must be exactly 24 bytes.") - return salt_word, nonce_word - - -def _optional_hex(value, length, label): - """Decode an optional hex argument, leaving absent values as None. - - Parameters - ---------- - value : str or None - Hex string supplied on the command line. - length : int - Expected decoded byte length. - label : str - Field name used in validation errors. - - Returns - ------- - bytes or None - Decoded bytes, or None when value is absent. - """ - return _hex_decode(value, length, label) if value else None - - -def _load_argon2(): - """Load the Argon2 low-level binding with dependency diagnostics. - - Parameters - ---------- - None - - Returns - ------- - tuple - Argon2 Type enum and hash_secret_raw callable. - """ - try: - from argon2.low_level import Type, hash_secret_raw - except ImportError as exc: - install_hint = "python3 -m pip install argon2-cffi" - _raise_dependency_error("argon2-cffi", install_hint, exc) - return Type, hash_secret_raw - - -def _load_nacl_encrypt(): - """Load the XChaCha20-Poly1305 encrypt binding with diagnostics. - - Parameters - ---------- - None - - Returns - ------- - callable - PyNaCl crypto_aead_xchacha20poly1305_ietf_encrypt function. - """ - try: - from nacl.bindings import ( - crypto_aead_xchacha20poly1305_ietf_encrypt as encrypt, - ) - except ImportError as exc: - install_hint = "python3 -m pip install pynacl" - _raise_dependency_error("PyNaCl", install_hint, exc) - return encrypt - - -def _derive_hardened_key(passphrase, salt, memory_kib, iterations, - parallelism): - """Derive a 32-byte key with Argon2id. - - Parameters - ---------- - passphrase : str - Policy-compliant operator passphrase. - salt : bytes - 16-byte Argon2 salt. - memory_kib : int - Argon2 memory cost in KiB. - iterations : int - Argon2 time cost. - parallelism : int - Argon2 parallel lane count. - - Returns - ------- - bytes - Derived 32-byte key. - """ - arg2_type, hash_secret_raw = _load_argon2() - args = ( - passphrase.encode(), salt, iterations, memory_kib, - parallelism, 32, arg2_type, - ) - return hash_secret_raw(*args) - - -def _entry_key(phrase, seed, memory_kib, iterations, parallelism): - """Derive the entry key word for the hardened artifact. - - Parameters - ---------- - phrase : str - Policy-compliant operator passphrase. - seed : bytes - 16-byte Argon2 salt. - memory_kib : int - Argon2 memory cost in KiB. - iterations : int - Argon2 time cost. - parallelism : int - Argon2 parallel lane count. - - Returns - ------- - bytes - Derived 32-byte entry key. - """ - return _derive_hardened_key( - phrase, seed, memory_kib, iterations, parallelism - ) - - -def _build_key_material(phrase, salt, nonce, memory_kib, iterations, - parallelism): - """Resolve salt, nonce, and the entry key. - - Parameters - ---------- - phrase : str - Policy-compliant operator passphrase. - salt : bytes or None - Optional fixed salt value. - nonce : bytes or None - Optional fixed nonce value. - memory_kib : int - Argon2 memory cost in KiB. - iterations : int - Argon2 time cost. - parallelism : int - Argon2 parallel lane count. - - Returns - ------- - tuple - Resolved (salt, nonce, key) values. - """ - seed, nonce_word = _resolve_salt_nonce(salt, nonce) - key = _entry_key(phrase, seed, memory_kib, iterations, parallelism) - return seed, nonce_word, key - - -def build_hardened_entry( - key_str, - text_str, - led_on=True, - append_crlf=True, - salt: Optional[bytes] = None, - nonce: Optional[bytes] = None, - memory_kib=DEFAULT_MEMORY_KIB, - iterations=DEFAULT_ITERATIONS, - parallelism=DEFAULT_PARALLELISM, -): - """Build a hardened encrypted entry with Argon2id + XChaCha20-Poly1305. - - Parameters - ---------- - key_str : str - Policy-compliant 12-word operator passphrase. - text_str : str - Console text placed in payload bytes 1..7. - led_on : bool - True turns the LED byte on, False leaves it off. - append_crlf : bool - True appends CRLF to the console text. - salt : bytes or None - Optional fixed 16-byte salt. - nonce : bytes or None - Optional fixed 24-byte nonce. - memory_kib : int - Argon2 memory cost in KiB. - iterations : int - Argon2 time cost. - parallelism : int - Argon2 parallel lane count. - - Returns - ------- - tuple - Resulting (salt, nonce, ciphertext_and_tag) values. - """ - if not _is_policy_compliant(key_str): - raise ValueError(_POLICY_ERROR) - salt_word, nonce_word, key = _build_key_material( - key_str, salt, nonce, memory_kib, iterations, parallelism) - payload = _build_payload(text_str, led_on, append_crlf) - encrypt = _load_nacl_encrypt() - ciphertext_and_tag = encrypt(payload, b"", nonce_word, key) - return salt_word, nonce_word, ciphertext_and_tag - - -def _hex_decode(value, expected_len, label): - """Decode a hex string and validate the expected byte length. - - Parameters - ---------- - value : str - Hex string to decode. - expected_len : int - Required decoded byte length. - label : str - Field name used in validation errors. - - Returns - ------- - bytes - Decoded bytes of the expected length. - """ - try: - decoded = bytes.fromhex(value) - except ValueError as exc: - raise ValueError("{0} must be valid hex.".format(label)) from exc - if len(decoded) != expected_len: - message = "{0} must decode to exactly {1} bytes.".format( - label, expected_len) - raise ValueError(message) - return decoded - - -def _artifact_dict(memory_kib, iterations, parallelism, salt, nonce, cipher): - """Compose the canonical artifact dictionary. - - Parameters - ---------- - memory_kib : int - Argon2 memory cost in KiB. - iterations : int - Argon2 time cost. - parallelism : int - Argon2 parallel lane count. - salt : bytes - 16-byte salt. - nonce : bytes - 24-byte nonce. - cipher : bytes - 64-byte ciphertext and tag. - - Returns - ------- - dict - Canonical artifact fields with hex-encoded byte values. - """ - return { - "format": ARTIFACT_FORMAT, "memory_kib": memory_kib, - "iterations": iterations, "parallelism": parallelism, - "salt_hex": salt.hex(), "nonce_hex": nonce.hex(), - "ciphertext_and_tag_hex": cipher.hex(), - } - - -def _format_c_array(data, width=8): - """Format bytes as an indented C array literal body. - - Parameters - ---------- - data : bytes - Bytes to serialize as a C array. - width : int - Byte values emitted per source line. - - Returns - ------- - str - Indented, comma-joined C array body. - """ - items = [f"0x{value:02X}u" for value in data] - rows = [", ".join(items[offset:offset + width]) - for offset in range(0, len(items), width)] - return ",\n".join(" " + row for row in rows) - - -def _render_header(artifact): - """Render the generated firmware header text from the artifact. - - Parameters - ---------- - artifact : dict - Canonical artifact dictionary. - - Returns - ------- - str - Complete generated C header text. - """ - cipher = bytes.fromhex(artifact["ciphertext_and_tag_hex"]) - return _HEADER_TEMPLATE.format( - artifact_format=ARTIFACT_FORMAT, memory_kib=artifact["memory_kib"], - iterations=artifact["iterations"], parallelism=artifact["parallelism"], - salt_body=_format_c_array(bytes.fromhex(artifact["salt_hex"])), - nonce_body=_format_c_array(bytes.fromhex(artifact["nonce_hex"])), - cipher_body=_format_c_array(cipher), - ) - - -def _write_header(path, artifact): - """Write the generated firmware header from the hardened artifact. - - Parameters - ---------- - path : str - Destination header file path. - artifact : dict - Canonical artifact dictionary. - - Returns - ------- - Path - Resolved destination header path. - """ - output_path = Path(path) - output_path.parent.mkdir(parents=True, exist_ok=True) - output_path.write_text(_render_header(artifact), encoding="utf-8") - return output_path.resolve() - - -def _parse_json_file(path): - """Load and parse the artifact JSON file. - - Parameters - ---------- - path : str - Artifact JSON file path. - - Returns - ------- - dict - Parsed JSON document. - """ - raw = Path(path).read_text(encoding="utf-8") - try: - parsed = json.loads(raw) - except json.JSONDecodeError as exc: - raise ValueError(_INVALID_JSON.format(path)) from exc - return parsed - - -def _validate_artifact_format(parsed): - """Reject artifact JSON with an unexpected format marker. - - Parameters - ---------- - parsed : dict - Parsed JSON document. - - Returns - ------- - None - """ - actual = parsed.get("format") - if actual != ARTIFACT_FORMAT: - raise ValueError( - "Artifact format must be '{0}', got '{1}'.".format( - ARTIFACT_FORMAT, actual)) - - -def _parsed_ints(parsed): - """Parse the integer cost fields from artifact JSON. - - Parameters - ---------- - parsed : dict - Parsed JSON document. - - Returns - ------- - list - Parsed memory_kib, iterations, and parallelism integer values. - """ - try: - int_names = ("memory_kib", "iterations", "parallelism") - return [int(parsed[name]) for name in int_names] - except (KeyError, TypeError, ValueError) as exc: - raise ValueError( - "Artifact must include integer memory_kib, " - "iterations, and parallelism fields.") from exc - - -def _artifact_ints(parsed): - """Unpack the three integer cost fields from artifact JSON. - - Parameters - ---------- - parsed : dict - Parsed JSON document. - - Returns - ------- - tuple - (memory_kib, iterations, parallelism) integer values. - """ - values = _parsed_ints(parsed) - return values[0], values[1], values[2] - - -def _artifact_from_parsed(parsed): - """Reconstruct a canonical artifact dict from parsed JSON. - - Parameters - ---------- - parsed : dict - Parsed JSON document. - - Returns - ------- - dict - Canonical artifact dictionary. - """ - _validate_artifact_format(parsed) - memory_kib, iterations, parallelism = _artifact_ints(parsed) - cipher_field = "ciphertext_and_tag_hex" - salt = _hex_decode(parsed.get("salt_hex", ""), 16, "salt_hex") - nonce = _hex_decode(parsed.get("nonce_hex", ""), 24, "nonce_hex") - cipher = _hex_decode(parsed.get(cipher_field, ""), 64, cipher_field) - return _artifact_dict( - memory_kib, iterations, parallelism, salt, nonce, cipher) - - -def _load_artifact_json(path): - """Load and validate a hardened artifact JSON for header generation. - - Parameters - ---------- - path : str - Artifact JSON file path. - - Returns - ------- - dict - Canonical artifact dictionary. - """ - parsed = _parse_json_file(path) - return _artifact_from_parsed(parsed) - - -def _check_header_match(generated_path, expected_path): - """Fail when the generated header does not match an expected file. - - Parameters - ---------- - generated_path : str - Generated header file path. - expected_path : str - Expected committed header file path. - - Returns - ------- - None - """ - generated = Path(generated_path).read_text(encoding="utf-8") - expected = Path(expected_path).read_text(encoding="utf-8") - if generated != expected: - raise RuntimeError( - "Generated header does not match committed " - "include/demo_artifact.h. Regenerate and commit " - "updated artifacts with scripts/dec.py.") - - -def _print_header_check(header_path, expected_path): - """Print the verified header match result. - - Parameters - ---------- - header_path : str - Generated header file path. - expected_path : str - Expected committed header file path. - - Returns - ------- - None - """ - _check_header_match(header_path, expected_path) - print("Verified header matches: {0}".format(Path(expected_path).resolve())) - - -def _parse_args(): - """Parse command-line arguments. - - Parameters - ---------- - None - - Returns - ------- - argparse.Namespace - Parsed command-line arguments. - """ - parser = argparse.ArgumentParser(description=__doc__) - for argument_group in _ARGUMENT_GROUPS: - for name, kwargs in argument_group: - parser.add_argument(name, **kwargs) - return parser.parse_args() - - -def _build_from_args(args, salt, nonce): - """Build the hardened entry from parsed arguments. - - Parameters - ---------- - args : argparse.Namespace - Parsed command-line arguments. - salt : bytes or None - Optional fixed salt value. - nonce : bytes or None - Optional fixed nonce value. - - Returns - ------- - tuple - Resulting (salt, nonce, ciphertext_and_tag) values. - """ - return build_hardened_entry( - key_str=args.key, text_str=args.text, led_on=not args.led_off, - append_crlf=not args.no_crlf, salt=salt, nonce=nonce, - memory_kib=args.memory_kib, iterations=args.iterations, - parallelism=args.parallelism, - ) - - -def _flush_outputs(args, salt, nonce, cipher): - """Write the artifact JSON and header, then return the header path. - - Parameters - ---------- - args : argparse.Namespace - Parsed command-line arguments. - salt : bytes - 16-byte salt. - nonce : bytes - 24-byte nonce. - cipher : bytes - 64-byte ciphertext and tag. - - Returns - ------- - Path - Resolved generated header path. - """ - json_path, artifact = _write_demo_json( - args.out, args.memory_kib, args.iterations, args.parallelism, - salt, nonce, cipher) - header_path = _write_header(args.header_out, artifact) - print("Wrote hardened demo artifact JSON: {0}".format(json_path)) - print("Wrote generated firmware header: {0}".format(header_path)) - return header_path - - -def _write_demo_json(path, memory_kib, iterations, parallelism, salt, - nonce, ciphertext_and_tag): - """Write the hardened JSON artifact consumed by docs and validation. - - Parameters - ---------- - path : str - Destination JSON file path. - memory_kib : int - Argon2 memory cost in KiB. - iterations : int - Argon2 time cost. - parallelism : int - Argon2 parallel lane count. - salt : bytes - 16-byte salt. - nonce : bytes - 24-byte nonce. - ciphertext_and_tag : bytes - 64-byte ciphertext and tag. - - Returns - ------- - tuple - Resolved (path, artifact) values. - """ - output_path = Path(path) - output_path.parent.mkdir(parents=True, exist_ok=True) - artifact = _artifact_dict( - memory_kib, iterations, parallelism, salt, nonce, ciphertext_and_tag) - text = json.dumps(artifact, indent=2) + "\n" - output_path.write_text(text, encoding="utf-8") - return output_path.resolve(), artifact - - -def _flush_from_json(args): - """Write the header from an existing artifact JSON. - - Parameters - ---------- - args : argparse.Namespace - Parsed command-line arguments. - - Returns - ------- - Path - Resolved generated header path. - """ - artifact = _load_artifact_json(args.from_json) - header_path = _write_header(args.header_out, artifact) - print("Wrote generated firmware header: {0}".format(header_path)) - return header_path - - -def _run_from_json(args): - """Generate the header only from committed artifact JSON. - - Parameters - ---------- - args : argparse.Namespace - Parsed command-line arguments. - - Returns - ------- - None - """ - header_path = _flush_from_json(args) - if args.check_header_path: - _print_header_check(header_path, args.check_header_path) - - -def _run_from_generate(args): - """Encrypt fresh artifact material, then emit JSON and the header. - - Parameters - ---------- - args : argparse.Namespace - Parsed command-line arguments. - - Returns - ------- - None - """ - salt = _optional_hex(args.salt_hex, 16, "salt_hex") - nonce = _optional_hex(args.nonce_hex, 24, "nonce_hex") - header_path = _flush_outputs( - args, *_build_from_args(args, salt, nonce), - ) - if args.check_header_path: - _print_header_check(header_path, args.check_header_path) - - -def main(): - """Generate the hardened artifact JSON and C header. - - Parameters - ---------- - None - - Returns - ------- - None - """ - args = _parse_args() - if args.from_json: - _run_from_json(args) - else: - _run_from_generate(args) - - -_ARGUMENT_GROUPS = ( - ( - ("--key", dict(default=DEFAULT_PASSPHRASE, help=_KEY_HELP)), - ("--salt-hex", dict(help=_SALT_HEX_HELP)), - ("--nonce-hex", dict(help=_NONCE_HEX_HELP)), - ), - ( - ("--text", dict(default=DEFAULT_TEXT, help=_TEXT_HELP)), - ("--out", dict(default=DEFAULT_OUTPUT_JSON, help=_OUT_HELP)), - ("--header-out", - dict(default=DEFAULT_OUTPUT_HEADER, help=_HEADER_OUT_HELP)), - ("--from-json", dict(help=_FROM_JSON_HELP)), - ("--no-crlf", dict(action="store_true", help=_NO_CRLF_HELP)), - ("--led-off", dict(action="store_true", help=_LED_OFF_HELP)), - ), - ( - ("--memory-kib", - dict(type=int, default=DEFAULT_MEMORY_KIB, help=_MEMORY_HELP)), - ("--iterations", - dict(type=int, default=DEFAULT_ITERATIONS, help=_ITERATIONS_HELP)), - ("--parallelism", - dict(type=int, default=DEFAULT_PARALLELISM, - help=_PARALLELISM_HELP)), - ("--check-header-path", dict(help=_CHECK_HEADER_HELP)), - ), -) - - -if __name__ == "__main__": - main() diff --git a/0x0017a_ctf/scripts/demo_artifact.json b/0x0017a_ctf/scripts/demo_artifact.json deleted file mode 100644 index 5c61254..0000000 --- a/0x0017a_ctf/scripts/demo_artifact.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "format": "ouroboros-hardened-demo-v1", - "memory_kib": 64, - "iterations": 3, - "parallelism": 1, - "salt_hex": "f2d518639a82019dc2d7afa5cdb6d871", - "nonce_hex": "1cef790d779e7c04e7f066dd90d080708797671f79efc4e4", - "ciphertext_and_tag_hex": "2c23b27e9562b8ed9e08e06dd99db4913e819a778bb47b71bc661e6e731a8154cdb536a4767e9bf8533e031db8e5ae7aadb431cf12d9f9c45fa9b94b80dcbbde" -} diff --git a/0x0017a_ctf/scripts/verify_ctf.py b/0x0017a_ctf/scripts/verify_ctf.py deleted file mode 100644 index a5de5b1..0000000 --- a/0x0017a_ctf/scripts/verify_ctf.py +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env python3 -"""Verify every technical claim of Operation Copperhead against CTF-02.bin. - -Exits 0 only when every address, byte, hash, and derived value in CTF-R.md and -CTF-S.md matches the shipped image and the compiled ELF. -""" -import hashlib -import struct -import sys -from pathlib import Path - -BASE = 0x10000000 -ROOT = Path(__file__).resolve().parent.parent -BIN = ROOT / "CTF-02.bin" -UF2 = ROOT / "CTF-02.uf2" - -EXPECTED_BIN_SHA = "85330c37cd0897746b1af447e4bac371dde2042abd2d61d58a61fe2a8eef3537" -EXPECTED_UF2_SHA = "f3cd4840260db820d792758cecacc5297bef1971b9eacf7601279256d8af1eab" - -FRAME_THRESHOLD_A = 0x10000302 -FRAME_THRESHOLD_B = 0x10000312 -FRAME_TRACK = 0x1000C4B8 -FRAME_BLOCKLEN = 0x1000C4F0 -FRAME_SIGNALKEY = 0x1000C51C -FRAME_GATE = 0x1000C544 -FRAME_AUTH = 0x1000C57C -FRAME_OK = 0x1000C438 -FRAME_MISMATCH = 0x1000C43C -FRAME_SPEC_LITERAL = 0x100004FC -FRAME_DOUBLE = 0x1000EC60 -FRAME_SEED = 0x1000EC70 -FRAME_SALT = 0x1000CEEC -FRAME_NONCE = 0x1000CED4 -FRAME_CT = 0x1000CE94 - -DOUBLE_3_2 = bytes.fromhex("9A99999999990940") -DOUBLE_0_32 = bytes.fromhex("7B14AE47E17AD43F") -SEED_BAD = bytes.fromhex("0A0A0A0A") -SEED_GOOD = bytes.fromhex("7465206B") -SPEC_VALUE = 0x2D879291 -BUG_KEY = 0x915DCFF8 - -RESULTS = [] - - -def check(label, ok, detail=""): - """Record one verification result. - - Parameters - ---------- - label : str - Human-readable check name. - ok : bool - Whether the check passed. - detail : str - Extra context printed with the result. - - Returns - ------- - None - """ - RESULTS.append(ok) - print(f"[{'PASS' if ok else 'FAIL'}] {label} {detail}") - - -def rotl(v, s): - """Rotate a 32-bit value left.""" - return ((v << s) & 0xFFFFFFFF) | (v >> (32 - s)) - - -def qr_phase(a, b, c, d, s): - """Apply one ARX phase of a ChaCha quarter round.""" - a = (a + b) & 0xFFFFFFFF - d ^= a - d = rotl(d, s) - c = (c + d) & 0xFFFFFFFF - b ^= c - b = rotl(b, s) - return a, b, c, d - - -def derive(seed, iv): - """Derive the firmware signal key from a seed and IV.""" - a, b, c, d = seed, iv, 0x61707865, 0x3320646E - for _ in range(4): - for s in (16, 12, 8, 7): - a, b, c, d = qr_phase(a, b, c, d, s) - return (a ^ d) & 0xFFFFFFFF - - -def main(): - """Run all verification checks. - - Returns - ------- - int - Zero when every check passes, else one. - """ - data = BIN.read_bytes() - check("CTF-02.bin SHA-256", hashlib.sha256(data).hexdigest() == EXPECTED_BIN_SHA) - check("CTF-02.uf2 SHA-256", - hashlib.sha256(UF2.read_bytes()).hexdigest() == EXPECTED_UF2_SHA) - check("CTF-02.bin size", len(data) == 62308, f"({len(data)})") - check("vector table", data[0:32].hex() == - "002008205b0100101b0100101d01001011010010110100101101001011010010") - check("initial SP", struct.unpack(" - -// Non-zero once auth_init() has prepared the onboard LED GPIO. auth_execute() -// reports an internal error whenever this flag is not yet set, mirroring the -// reference construction from the encryption-c-rp2350 repository. -static bool g_auth_ready; - -/** - * @brief Clear a byte buffer. - * - * Writes zero to each byte in the caller-supplied buffer so derived keys - * and plaintext are not left resident in memory longer than needed. - * - * @param buf Pointer to mutable byte buffer. - * @param len Number of bytes to clear. - * @return None. - */ -static void clear_bytes(uint8_t *buf, size_t len) -{ - size_t i; - for (i = 0u; i < len; ++i) { - buf[i] = 0u; - } -} - -/** - * @brief Rotate a 32-bit value left. - * - * The HChaCha20 core uses 32-bit modular additions and left rotations in - * its quarter-round primitive. - * - * @param value Input 32-bit word. - * @param shift Rotation distance in bits. - * @return uint32_t Rotated result. - */ -static uint32_t rotl32(uint32_t value, uint8_t shift) -{ - return (value << shift) | (value >> (32u - shift)); -} - -/** - * @brief Load a 32-bit little-endian word from bytes. - * - * Converts four little-endian bytes into the word representation used by - * the HChaCha20 state machine. - * - * @param src Pointer to four readable bytes. - * @return uint32_t Parsed 32-bit word. - */ -static uint32_t load32_le(const uint8_t *src) -{ - return (uint32_t)src[0] | ((uint32_t)src[1] << 8u) | - ((uint32_t)src[2] << 16u) | ((uint32_t)src[3] << 24u); -} - -/** - * @brief Store a 32-bit word in little-endian byte order. - * - * Serializes one HChaCha20 state word into the caller-supplied output - * buffer. - * - * @param dst Pointer to four writable bytes. - * @param value 32-bit word to serialize. - * @return None. - */ -static void store32_le(uint8_t *dst, uint32_t value) -{ - dst[0] = (uint8_t)(value & 0xFFu); - dst[1] = (uint8_t)((value >> 8u) & 0xFFu); - dst[2] = (uint8_t)((value >> 16u) & 0xFFu); - dst[3] = (uint8_t)((value >> 24u) & 0xFFu); -} - -/** - * @brief Execute one ChaCha quarter-round. - * - * Mutates four state words in place according to the standard ChaCha20 - * ARX quarter-round used by the HChaCha20 subkey derivation. - * - * @param a Pointer to state word a. - * @param b Pointer to state word b. - * @param c Pointer to state word c. - * @param d Pointer to state word d. - * @return None. - */ -static void quarter_round(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d) -{ - *a += *b; *d ^= *a; *d = rotl32(*d, 16u); - *c += *d; *b ^= *c; *b = rotl32(*b, 12u); - *a += *b; *d ^= *a; *d = rotl32(*d, 8u); - *c += *d; *b ^= *c; *b = rotl32(*b, 7u); -} - -/** - * @brief Derive a 256-bit XChaCha20 subkey from key and nonce prefix. - * - * Runs the HChaCha20 core over the first 16 bytes of the 24-byte XChaCha - * nonce and emits the derived 32-byte subkey. - * - * @param key Pointer to 32-byte AEAD key. - * @param nonce Pointer to 24-byte XChaCha20 nonce. - * @param subkey Output 32-byte subkey buffer. - * @return None. - */ -static void hchacha20(const uint8_t key[32], const uint8_t nonce[24], uint8_t subkey[32]) -{ - uint32_t state[16] = { - 0x61707865u, 0x3320646Eu, 0x79622D32u, 0x6B206574u, - load32_le(&key[0]), load32_le(&key[4]), load32_le(&key[8]), load32_le(&key[12]), - load32_le(&key[16]), load32_le(&key[20]), load32_le(&key[24]), load32_le(&key[28]), - load32_le(&nonce[0]), load32_le(&nonce[4]), load32_le(&nonce[8]), load32_le(&nonce[12]), - }; - uint8_t round; - for (round = 0u; round < 10u; ++round) { - quarter_round(&state[0], &state[4], &state[8], &state[12]); - quarter_round(&state[1], &state[5], &state[9], &state[13]); - quarter_round(&state[2], &state[6], &state[10], &state[14]); - quarter_round(&state[3], &state[7], &state[11], &state[15]); - quarter_round(&state[0], &state[5], &state[10], &state[15]); - quarter_round(&state[1], &state[6], &state[11], &state[12]); - quarter_round(&state[2], &state[7], &state[8], &state[13]); - quarter_round(&state[3], &state[4], &state[9], &state[14]); - } - store32_le(&subkey[0], state[0]); - store32_le(&subkey[4], state[1]); - store32_le(&subkey[8], state[2]); - store32_le(&subkey[12], state[3]); - store32_le(&subkey[16], state[12]); - store32_le(&subkey[20], state[13]); - store32_le(&subkey[24], state[14]); - store32_le(&subkey[28], state[15]); -} - -/** - * @brief Build the inner 96-bit nonce used by ChaCha20-Poly1305. - * - * XChaCha20 converts the last 8 bytes of the 24-byte outer nonce into the - * final 12-byte IETF ChaCha nonce by prefixing four zero bytes. - * - * @param nonce Pointer to 24-byte XChaCha20 nonce. - * @param out Output 12-byte nonce buffer. - * @return None. - */ -static void build_inner_nonce(const uint8_t nonce[24], uint8_t out[12]) -{ - memset(out, 0, 4u); - memcpy(&out[4], &nonce[16], 8u); -} - -/** - * @brief Return true when a byte is ASCII whitespace used by the CLI. - * - * The firmware normalizes spaces, carriage returns, tabs, and newlines in - * the same broad spirit as split-whitespace host parsing. - * - * @param ch Input byte. - * @return bool true when byte is treated as whitespace. - */ -static bool is_space(uint8_t ch) -{ - return (ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n'); -} - -/** - * @brief Return true when a byte is lowercase ASCII. - * - * Hardened passphrases accept only lowercase a-z characters in each word. - * - * @param ch Input byte. - * @return bool true when byte is in the lowercase ASCII range. - */ -static bool is_lowercase_ascii(uint8_t ch) -{ - return (ch >= 'a') && (ch <= 'z'); -} - -/** - * @brief Validate the strict hardened passphrase policy. - * - * Accepts only passphrases containing exactly 12 lowercase ASCII words - * separated by whitespace. - * - * @param passphrase Pointer to passphrase bytes. - * @param passphrase_len Number of passphrase bytes. - * @return bool true when the passphrase satisfies the policy. - */ -static bool validate_hardened_passphrase(const uint8_t *passphrase, size_t passphrase_len) -{ - size_t i = 0u; - uint8_t words = 0u; - if ((passphrase == NULL) || (passphrase_len == 0u) || (passphrase_len > AUTH_PASSPHRASE_MAX_LEN)) { - return false; - } - while (i < passphrase_len) { - while ((i < passphrase_len) && is_space(passphrase[i])) { - ++i; - } - if (i == passphrase_len) { - break; - } - ++words; - while ((i < passphrase_len) && !is_space(passphrase[i])) { - if (!is_lowercase_ascii(passphrase[i])) { - return false; - } - ++i; - } - } - return words == AUTH_REQUIRED_WORDS; -} - -/** - * @brief Derive the 32-byte hardened key with Argon2id. - * - * Uses the generated artifact parameters and salt to derive the AEAD key - * that protects the embedded ciphertext. - * - * @param passphrase Pointer to passphrase bytes. - * @param passphrase_len Number of passphrase bytes. - * @param key_out Output 32-byte key buffer. - * @return bool true when derivation succeeds. - */ -static bool derive_hardened_key(const uint8_t *passphrase, size_t passphrase_len, uint8_t key_out[32]) -{ - return argon2id_hash_raw( - DEMO_ITERATIONS, - DEMO_MEMORY_KIB, - DEMO_PARALLELISM, - passphrase, - passphrase_len, - DEMO_SALT, - AUTH_SALT_SIZE, - key_out, - AUTH_KEY_SIZE) == ARGON2_OK; -} - -/** - * @brief Decrypt the embedded artifact with XChaCha20-Poly1305. - * - * Derives the XChaCha20 subkey with HChaCha20, converts the outer nonce to - * the inner 96-bit nonce, and verifies/decrypts the payload in one shot. - * - * @param key Pointer to 32-byte Argon2id-derived key. - * @param payload_out Output 48-byte plaintext payload buffer. - * @return bool true when tag verification and decryption succeed. - */ -static bool decrypt_artifact(const uint8_t key[32], uint8_t payload_out[AUTH_PAYLOAD_SIZE]) -{ - bool ok; - int rc; - uint8_t subkey[32]; - uint8_t inner_nonce[12]; - mbedtls_chachapoly_context ctx; - hchacha20(key, DEMO_NONCE, subkey); - build_inner_nonce(DEMO_NONCE, inner_nonce); - mbedtls_chachapoly_init(&ctx); - rc = mbedtls_chachapoly_setkey(&ctx, subkey); - if (rc == 0) { - rc = mbedtls_chachapoly_auth_decrypt( - &ctx, - AUTH_PAYLOAD_SIZE, - inner_nonce, - NULL, - 0u, - &DEMO_CIPHERTEXT_AND_TAG[AUTH_PAYLOAD_SIZE], - DEMO_CIPHERTEXT_AND_TAG, - payload_out); - } - mbedtls_chachapoly_free(&ctx); - clear_bytes(subkey, sizeof(subkey)); - clear_bytes(inner_nonce, sizeof(inner_nonce)); - ok = (rc == 0); - if (!ok) { - clear_bytes(payload_out, AUTH_PAYLOAD_SIZE); - } - return ok; -} - -/** - * @brief Dispatch the decrypted payload to GPIO25 and UART. - * - * Mirrors the Rust demo payload contract: byte 0 controls the LED, and - * bytes 1..7 are transmitted verbatim over UART. - * - * @param payload Pointer to decrypted 48-byte payload. - * @return None. - */ -static void dispatch_payload(const uint8_t payload[AUTH_PAYLOAD_SIZE]) -{ - uint8_t i; - gpio_put(AUTH_LED_PIN, payload[0] ? 1 : 0); - for (i = 1u; i < 8u; ++i) { - putchar_raw((char)payload[i]); - } -} - -bool auth_init(void) -{ - g_auth_ready = true; - gpio_init(AUTH_LED_PIN); - gpio_set_dir(AUTH_LED_PIN, GPIO_OUT); - gpio_put(AUTH_LED_PIN, 0); - return true; -} - -auth_result_t auth_execute(const uint8_t *passphrase, size_t passphrase_len) -{ - uint8_t key[AUTH_KEY_SIZE]; - uint8_t payload[AUTH_PAYLOAD_SIZE]; - if (!g_auth_ready) { - return AUTH_RESULT_INTERNAL_ERROR; - } - if (!validate_hardened_passphrase(passphrase, passphrase_len)) { - return AUTH_RESULT_POLICY_VIOLATION; - } - if (!derive_hardened_key(passphrase, passphrase_len, key)) { - return AUTH_RESULT_INTERNAL_ERROR; - } - if (!decrypt_artifact(key, payload)) { - clear_bytes(key, sizeof(key)); - return AUTH_RESULT_AUTHENTICATION_FAILED; - } - dispatch_payload(payload); - clear_bytes(payload, sizeof(payload)); - clear_bytes(key, sizeof(key)); - return AUTH_RESULT_SUCCESS; -} \ No newline at end of file diff --git a/0x0017a_ctf/src/cli.c b/0x0017a_ctf/src/cli.c deleted file mode 100644 index cb6fc6c..0000000 --- a/0x0017a_ctf/src/cli.c +++ /dev/null @@ -1,149 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent/encryption-c-rp2350 -// File: cli.c -// Desc: Implements the CLI UART passphrase input interface for Ouroboros. -// Created: 2026 - -#include "cli.h" -#include "auth.h" -#include "pico/stdlib.h" -#include - -/** - * @brief Maximum number of passphrase characters accepted from UART. - * - * Limits the input buffer to the hardened engine boundary. A null - * terminator is written after the last character so the buffer must be - * declared with at least this many bytes. - */ -#define PASS_BUF_LEN AUTH_PASSPHRASE_MAX_LEN - -/** - * @brief Print the hardened passphrase policy hint. - * - * The firmware uses the same interactive policy as the host demo: - * exactly 12 lowercase words separated by spaces. - * - * @param None. - * @return None. - */ -static void print_policy_hint(void) -{ - printf("Enter exactly 12 lowercase words separated by spaces.\r\n"); -} - -/** - * @brief Append one received character to the passphrase buffer. - * - * Stores printable characters up to the buffer limit minus one to - * reserve room for a null terminator. Echoes the character back - * over UART for interactive typing feedback. - * - * @param ch Input character value. - * @param buf Pointer to mutable passphrase buffer. - * @param idx Pointer to current buffer length. - * @return None. - */ -static void append_char(int ch, char *buf, size_t *idx) -{ - if (*idx + 1u >= PASS_BUF_LEN) { - return; - } - buf[*idx] = (char)ch; - *idx += 1u; - putchar_raw((char)ch); -} - -/** - * @brief Remove one character from the passphrase buffer. - * - * Moves the index back by one and emits the backspace-escape - * sequence to erase the last echoed character on the terminal. - * - * @param idx Pointer to current buffer length. - * @return None. - */ -static void handle_backspace(size_t *idx) -{ - if (*idx == 0u) { - return; - } - *idx -= 1u; - printf("\b \b"); -} - -/** - * @brief Finalise and authenticate the current passphrase buffer. - * - * Null-terminates the input, runs the full Ouroboros authentication - * pipeline via auth_execute, prints policy guidance or authentication - * failure text as needed, and resets the buffer index for the next - * prompt cycle. - * - * @param buf Pointer to mutable passphrase buffer. - * @param idx Pointer to current buffer length. - * @return None. - */ -static void finish_passphrase(char *buf, size_t *idx) -{ - auth_result_t result; - putchar_raw('\r'); - putchar_raw('\n'); - buf[*idx] = '\0'; - result = auth_execute((const uint8_t *)buf, *idx); - if (result == AUTH_RESULT_POLICY_VIOLATION) { - gpio_put(AUTH_LED_PIN, 0); - print_policy_hint(); - } else if (result != AUTH_RESULT_SUCCESS) { - gpio_put(AUTH_LED_PIN, 0); - printf("Authentication failed.\r\n"); - } - *idx = 0u; - print_prompt(); -} - -void print_prompt(void) -{ - printf("\r\n> "); -} - -void service_uart(char *buf, size_t *idx) -{ - int ch = getchar_timeout_us(0); - if (ch == PICO_ERROR_TIMEOUT) { - tight_loop_contents(); - return; - } - if ((ch == '\b') || (ch == 127)) { - handle_backspace(idx); - return; - } - if ((ch == '\r') || (ch == '\n')) { - finish_passphrase(buf, idx); - return; - } - append_char(ch, buf, idx); -} diff --git a/0x0017a_ctf/src/main.c b/0x0017a_ctf/src/main.c deleted file mode 100644 index d672f92..0000000 --- a/0x0017a_ctf/src/main.c +++ /dev/null @@ -1,404 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: main.c -// Desc: DEEPLINE Metro interlocking host for the FINAL-PRACTICE exercise. -// Chains the strict Ouroboros operator gate (Argon2id plus -// XChaCha20-Poly1305) around the frozen relay telemetry puzzles. -// Created: 2026 - -#include -#include -#include -#include -#include "auth.h" -#include "pico/stdlib.h" - -// Block deviation classification ceiling below which an automated train -// release is permitted. BUG: PALLAS compiled in 95; the engineering limit -// is 60 (two redundant cmp sites in the ship image). -#define SAFE_THRESHOLD 95u - -// Number of 32-bit ARX state words used by the signal-key machinery. -#define ARX_WORDS 4u - -// Spec value of the derived signal key minted in the incident report. This is -// the key the honest build derives from GATE_SEED_GOOD and the derived IV. -#define SIGNAL_SPEC 0x2D879291u - -// ChaCha expand word used by the console-side derivation path. -#define GATE_SEED_GOOD 0x6B206574u - -// Track-circuit current deviation frozen by the dead pilot wire (amperes). -// A live reading is recalculated in the field; this image holds a wrong -// snapshot that engineers must decode from registers and SRAM. -static volatile uint32_t g_block_current = 87u; - -// Operator-facing block classification (drives the BLOCK STATE line). -static volatile uint32_t g_operator_state = 0u; - -// Automatic train release decision (drives the AUTO TRAIN line). -static volatile uint32_t g_dispatch_state = 0u; - -// Static per-cycle poll counter retained in .bss. Watch this from GDB. -static volatile uint32_t g_fault_polls = 0u; - -// ARX seed substituted by the poisoned build up to the signal derivation. -// BUG: 0x0A0A0A0A was fused in place of the "te k" expand word 0x6B206574. -static volatile uint32_t g_auth_seed = 0x0A0A0A0Au; - -// Derived signal key printed each cycle and checked against SIGNAL_SPEC. -static uint32_t g_signal_key = 0u; - -/** - * @brief Hold one track-block telemetry record for the interlocking. - * - * Stores the measured block length, the condition flag word, and the - * crossing identifier used by the automatic train protection logic. - */ -typedef struct telemetry_t { - double block_length_km; - uint32_t block_flags; - uint16_t crossing; -} telemetry_t; - -// Live telemetry record. BUG: block_length_km shipped as 3.2 km; the real -// BRIDGE-4 block is 0.32 km, far below the minimum release spacing. -static volatile telemetry_t g_telemetry = { 3.2, 0x3u, 7u }; - -// Interactive passphrase buffer and parser cursor for the operator gate. -static char g_linebuf[AUTH_PASSPHRASE_MAX_LEN]; -static size_t g_lineidx = 0u; - -/** - * @brief Rotate a 32-bit value left. - * - * @param value Input 32-bit word. - * @param shift Rotation distance in bits. - * @return uint32_t Rotated result. - */ -static uint32_t rotl32(uint32_t value, uint8_t shift) -{ - return (value << shift) | (value >> (32u - shift)); -} - -/** - * @brief Load a 32-bit little-endian word from bytes. - * - * @param src Pointer to four readable bytes. - * @return uint32_t Parsed 32-bit word. - */ -static uint32_t load32_le(const uint8_t *src) -{ - return (uint32_t)src[0] | ((uint32_t)src[1] << 8u) | - ((uint32_t)src[2] << 16u) | ((uint32_t)src[3] << 24u); -} - -/** - * @brief Store a 32-bit word in little-endian byte order. - * - * @param dst Pointer to four writable bytes. - * @param value 32-bit word to serialize. - * @return None. - */ -static void store32_le(uint8_t *dst, uint32_t value) -{ - dst[0] = (uint8_t)(value & 0xFFu); - dst[1] = (uint8_t)((value >> 8u) & 0xFFu); - dst[2] = (uint8_t)((value >> 16u) & 0xFFu); - dst[3] = (uint8_t)((value >> 24u) & 0xFFu); -} - -/** - * @brief Apply one additive-rotate-xor phase of a ChaCha quarter-round. - * - * @param a Pointer to state word A. - * @param b Pointer to state word B. - * @param c Pointer to state word C. - * @param d Pointer to state word D. - * @param shift Rotation distance in bits. - * @return None. - */ -static void qr_phase(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint8_t shift) -{ - *a += *b; - *d ^= *a; - *d = rotl32(*d, shift); - *c += *d; - *b ^= *c; - *b = rotl32(*b, shift); -} - -/** - * @brief Execute one full ChaCha ARX quarter-round. - * - * @param a Pointer to state word A. - * @param b Pointer to state word B. - * @param c Pointer to state word C. - * @param d Pointer to state word D. - * @return None. - */ -static void quarter_round(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d) -{ - qr_phase(a, b, c, d, 16u); - qr_phase(a, b, c, d, 12u); - qr_phase(a, b, c, d, 8u); - qr_phase(a, b, c, d, 7u); -} - -/** - * @brief Run r full quarter-rounds over a four-word ARX state. - * - * @param a Pointer to state word A. - * @param b Pointer to state word B. - * @param c Pointer to state word C. - * @param d Pointer to state word D. - * @param rounds Number of full quarter-rounds to run. - * @return None. - */ -static void run_rounds(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d, uint8_t rounds) -{ - uint8_t r; - for (r = 0u; r < rounds; ++r) { - quarter_round(a, b, c, d); - } -} - -/** - * @brief Derive a 32-bit ARX session key from a seed and IV. - * - * Runs four ChaCha quarter-rounds over the seed, the IV, and the ChaCha - * expand constants; returns state word A exclusive-or state word D. - * - * @param seed 32-bit seed word. - * @param iv 32-bit IV word. - * @return uint32_t Derived session key word. - */ -static uint32_t derive_session_key(uint32_t seed, uint32_t iv) -{ - uint32_t a = seed; - uint32_t b = iv; - uint32_t c = 0x61707865u; - uint32_t d = 0x3320646Eu; - run_rounds(&a, &b, &c, &d, 4u); - return a ^ d; -} - -/** - * @brief Derive the runtime IV from the good console seed word. - * - * @param None. - * @return uint32_t Derived IV word (0xC0F89829 in an honest image). - */ -static uint32_t derive_state_iv(void) -{ - return derive_session_key(GATE_SEED_GOOD, 0u); -} - -/** - * @brief Refresh the runtime signal key from the live seed and IV. - * - * Captures the freshly derived IV, then derives the final key word from - * the substituted seed. Break after each derivation to read the register. - * - * @param None. - * @return None. - */ -static void set_signal_state(void) -{ - uint32_t iv = derive_state_iv(); - g_signal_key = derive_session_key(g_auth_seed, iv); -} - -/** - * @brief Classify the frozen current reading against the compiled limit. - * - * Compares the frozen track-circuit current reading against SAFE_THRESHOLD - * and assigns the resulting boolean status to both g_operator_state and - * g_dispatch_state. - * - * @param None. - * @return None. - */ -static void classify_blocks(void) -{ - g_operator_state = (g_block_current < SAFE_THRESHOLD) ? 1u : 0u; - g_dispatch_state = (g_block_current < SAFE_THRESHOLD) ? 1u : 0u; -} - -/** - * @brief Print the relay boot identity and unconditional signal line. - * - * Emits the DEEPLINE authority banner, adaptive signal window, serial console - * configuration string, and nominal track status prompt over the console. - * - * @param None. - * @return None. - */ -static void print_identity(void) -{ - printf("DEEPLINE METRO AUTHORITY\r\n"); - printf("ADAPTIVE SIGNAL WINDOW: 38 MINUTES\r\n"); - printf("USB-CDC 115200 8N1 | AUTHORIZED LAB CONSOLE\r\n"); - printf("TRACK: NORMAL\r\n"); -} - -/** - * @brief Print the recurring interlocking status report once per cycle. - * - * Computes block length in meters, increments the fault poll counter, prints - * block state, train authorization status, fault poll tally, and signal key - * validation report, and re-emits the command prompt. - * - * @param None. - * @return None. - */ -static void print_status(void) -{ - uint32_t metres = (uint32_t)(g_telemetry.block_length_km * 1000.0); - g_fault_polls += 1u; - printf("BLOCK STATE: %s\r\n", g_operator_state ? "STABLE" : "CRITICAL"); - printf("AUTO TRAIN: %s\r\n", g_dispatch_state ? "AUTHORIZED" : "HELD"); - printf("BLOCK LENGTH: %u M\r\n", metres); - printf("FAULT POLLS: %u\r\n", g_fault_polls); - printf("SIGNAL KEY: 0x%08X %s\r\n", g_signal_key, - (g_signal_key == SIGNAL_SPEC) ? "OK" : "MISMATCH"); - printf("RESPONSE> "); -} - -/** - * @brief Append one received character to the passphrase buffer. - * - * Stores printable characters up to the maximum passphrase length boundary - * and echoes the character back to the console for interactive typing feedback. - * - * @param ch Input character value. - * @return None. - */ -static void append_char(int ch) -{ - if (g_lineidx + 1u >= AUTH_PASSPHRASE_MAX_LEN) { - return; - } - g_linebuf[g_lineidx] = (char)ch; - g_lineidx += 1u; - putchar_raw((char)ch); -} - -/** - * @brief Remove one character from the passphrase buffer. - * - * Decrements the buffer index and emits a backspace-space-backspace escape - * sequence to erase the character on the user's terminal. - * - * @param None. - * @return None. - */ -static void drop_char(void) -{ - if (g_lineidx == 0u) { - return; - } - g_lineidx -= 1u; - printf("\b \b"); -} - -/** - * @brief Authenticate the completed passphrase against the Ouroboros gate. - * - * Terminates the string buffer, invokes auth_execute, handles policy violation - * or authentication failure outputs, and resets the line buffer for the next input. - * - * @param None. - * @return None. - */ -static void submit_gate(void) -{ - auth_result_t result; - putchar_raw('\r'); - putchar_raw('\n'); - g_linebuf[g_lineidx] = '\0'; - result = auth_execute((const uint8_t *)g_linebuf, g_lineidx); - if (result == AUTH_RESULT_POLICY_VIOLATION) { - gpio_put(AUTH_LED_PIN, 0); - printf("Enter exactly 12 lowercase words separated by spaces.\r\n"); - } else if (result == AUTH_RESULT_SUCCESS) { - printf("AUTHORITY FRAME: VERIFIED\r\n"); - } else { - gpio_put(AUTH_LED_PIN, 0); - printf("Authentication failed.\r\n"); - } - g_lineidx = 0u; - printf("RESPONSE> "); -} - -/** - * @brief Poll the console for one passphrase input event. - * - * Reads a single character from standard input with zero timeout and routes - * backspace, newline/carriage return, or printable characters to their respective - * handlers. - * - * @param None. - * @return None. - */ -static void poll_console(void) -{ - int ch = getchar_timeout_us(0); - while (ch != PICO_ERROR_TIMEOUT) { - if ((ch == '\b') || (ch == 127)) { - drop_char(); - } else if ((ch == '\r') || (ch == '\n')) { - submit_gate(); - } else { - append_char(ch); - } - ch = getchar_timeout_us(0); - } -} - -/** - * @brief Drive the DEEPLINE relay console and operator gate forever. - * - * Initializes standard I/O and the authentication engine, classifies the track - * blocks, emits the initial system banner, and enters an infinite loop refreshing - * the signal state, reporting status, and servicing the console every two seconds. - * - * @param None. - * @return int Process exit code (never returns during normal operation). - */ -int main(void) -{ - stdio_init_all(); - auth_init(); - classify_blocks(); - print_identity(); - while (true) { - set_signal_state(); - print_status(); - poll_console(); - sleep_ms(2000u); - } -} \ No newline at end of file diff --git a/0x0017a_ctf/src/mbedtls_shims.c b/0x0017a_ctf/src/mbedtls_shims.c deleted file mode 100644 index 7c06a9d..0000000 --- a/0x0017a_ctf/src/mbedtls_shims.c +++ /dev/null @@ -1,49 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: mbedtls_shims.c -// Desc: Implements platform zeroization shims required by mbedTLS on RP2350. -// Created: 2026 - -#include "mbedtls/platform_util.h" - -/** - * @brief Securely clear a memory region. - * - * Provides the mbedTLS platform zeroization hook for this firmware build. - * The volatile pointer prevents the compiler from optimizing away the - * clearing loop. - * - * @param buf Pointer to mutable memory region to clear. - * @param len Number of bytes to clear. - * @return None. - */ -void mbedtls_platform_zeroize(void *buf, size_t len) -{ - volatile unsigned char *ptr = (volatile unsigned char *)buf; - while (len-- > 0u) { - *ptr++ = 0u; - } -} diff --git a/0x0017a_ctf/third_party/argon2/include/argon2.h b/0x0017a_ctf/third_party/argon2/include/argon2.h deleted file mode 100644 index 3980bb3..0000000 --- a/0x0017a_ctf/third_party/argon2/include/argon2.h +++ /dev/null @@ -1,437 +0,0 @@ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ - -#ifndef ARGON2_H -#define ARGON2_H - -#include -#include -#include - -#if defined(__cplusplus) -extern "C" { -#endif - -/* Symbols visibility control */ -#ifdef A2_VISCTL -#define ARGON2_PUBLIC __attribute__((visibility("default"))) -#define ARGON2_LOCAL __attribute__ ((visibility ("hidden"))) -#elif defined(_MSC_VER) -#define ARGON2_PUBLIC __declspec(dllexport) -#define ARGON2_LOCAL -#else -#define ARGON2_PUBLIC -#define ARGON2_LOCAL -#endif - -/* - * Argon2 input parameter restrictions - */ - -/* Minimum and maximum number of lanes (degree of parallelism) */ -#define ARGON2_MIN_LANES UINT32_C(1) -#define ARGON2_MAX_LANES UINT32_C(0xFFFFFF) - -/* Minimum and maximum number of threads */ -#define ARGON2_MIN_THREADS UINT32_C(1) -#define ARGON2_MAX_THREADS UINT32_C(0xFFFFFF) - -/* Number of synchronization points between lanes per pass */ -#define ARGON2_SYNC_POINTS UINT32_C(4) - -/* Minimum and maximum digest size in bytes */ -#define ARGON2_MIN_OUTLEN UINT32_C(4) -#define ARGON2_MAX_OUTLEN UINT32_C(0xFFFFFFFF) - -/* Minimum and maximum number of memory blocks (each of BLOCK_SIZE bytes) */ -#define ARGON2_MIN_MEMORY (2 * ARGON2_SYNC_POINTS) /* 2 blocks per slice */ - -#define ARGON2_MIN(a, b) ((a) < (b) ? (a) : (b)) -/* Max memory size is addressing-space/2, topping at 2^32 blocks (4 TB) */ -#define ARGON2_MAX_MEMORY_BITS \ - ARGON2_MIN(UINT32_C(32), (sizeof(void *) * CHAR_BIT - 10 - 1)) -#define ARGON2_MAX_MEMORY \ - ARGON2_MIN(UINT32_C(0xFFFFFFFF), UINT64_C(1) << ARGON2_MAX_MEMORY_BITS) - -/* Minimum and maximum number of passes */ -#define ARGON2_MIN_TIME UINT32_C(1) -#define ARGON2_MAX_TIME UINT32_C(0xFFFFFFFF) - -/* Minimum and maximum password length in bytes */ -#define ARGON2_MIN_PWD_LENGTH UINT32_C(0) -#define ARGON2_MAX_PWD_LENGTH UINT32_C(0xFFFFFFFF) - -/* Minimum and maximum associated data length in bytes */ -#define ARGON2_MIN_AD_LENGTH UINT32_C(0) -#define ARGON2_MAX_AD_LENGTH UINT32_C(0xFFFFFFFF) - -/* Minimum and maximum salt length in bytes */ -#define ARGON2_MIN_SALT_LENGTH UINT32_C(8) -#define ARGON2_MAX_SALT_LENGTH UINT32_C(0xFFFFFFFF) - -/* Minimum and maximum key length in bytes */ -#define ARGON2_MIN_SECRET UINT32_C(0) -#define ARGON2_MAX_SECRET UINT32_C(0xFFFFFFFF) - -/* Flags to determine which fields are securely wiped (default = no wipe). */ -#define ARGON2_DEFAULT_FLAGS UINT32_C(0) -#define ARGON2_FLAG_CLEAR_PASSWORD (UINT32_C(1) << 0) -#define ARGON2_FLAG_CLEAR_SECRET (UINT32_C(1) << 1) - -/* Global flag to determine if we are wiping internal memory buffers. This flag - * is defined in core.c and defaults to 1 (wipe internal memory). */ -extern int FLAG_clear_internal_memory; - -/* Error codes */ -typedef enum Argon2_ErrorCodes { - ARGON2_OK = 0, - - ARGON2_OUTPUT_PTR_NULL = -1, - - ARGON2_OUTPUT_TOO_SHORT = -2, - ARGON2_OUTPUT_TOO_LONG = -3, - - ARGON2_PWD_TOO_SHORT = -4, - ARGON2_PWD_TOO_LONG = -5, - - ARGON2_SALT_TOO_SHORT = -6, - ARGON2_SALT_TOO_LONG = -7, - - ARGON2_AD_TOO_SHORT = -8, - ARGON2_AD_TOO_LONG = -9, - - ARGON2_SECRET_TOO_SHORT = -10, - ARGON2_SECRET_TOO_LONG = -11, - - ARGON2_TIME_TOO_SMALL = -12, - ARGON2_TIME_TOO_LARGE = -13, - - ARGON2_MEMORY_TOO_LITTLE = -14, - ARGON2_MEMORY_TOO_MUCH = -15, - - ARGON2_LANES_TOO_FEW = -16, - ARGON2_LANES_TOO_MANY = -17, - - ARGON2_PWD_PTR_MISMATCH = -18, /* NULL ptr with non-zero length */ - ARGON2_SALT_PTR_MISMATCH = -19, /* NULL ptr with non-zero length */ - ARGON2_SECRET_PTR_MISMATCH = -20, /* NULL ptr with non-zero length */ - ARGON2_AD_PTR_MISMATCH = -21, /* NULL ptr with non-zero length */ - - ARGON2_MEMORY_ALLOCATION_ERROR = -22, - - ARGON2_FREE_MEMORY_CBK_NULL = -23, - ARGON2_ALLOCATE_MEMORY_CBK_NULL = -24, - - ARGON2_INCORRECT_PARAMETER = -25, - ARGON2_INCORRECT_TYPE = -26, - - ARGON2_OUT_PTR_MISMATCH = -27, - - ARGON2_THREADS_TOO_FEW = -28, - ARGON2_THREADS_TOO_MANY = -29, - - ARGON2_MISSING_ARGS = -30, - - ARGON2_ENCODING_FAIL = -31, - - ARGON2_DECODING_FAIL = -32, - - ARGON2_THREAD_FAIL = -33, - - ARGON2_DECODING_LENGTH_FAIL = -34, - - ARGON2_VERIFY_MISMATCH = -35 -} argon2_error_codes; - -/* Memory allocator types --- for external allocation */ -typedef int (*allocate_fptr)(uint8_t **memory, size_t bytes_to_allocate); -typedef void (*deallocate_fptr)(uint8_t *memory, size_t bytes_to_allocate); - -/* Argon2 external data structures */ - -/* - ***** - * Context: structure to hold Argon2 inputs: - * output array and its length, - * password and its length, - * salt and its length, - * secret and its length, - * associated data and its length, - * number of passes, amount of used memory (in KBytes, can be rounded up a bit) - * number of parallel threads that will be run. - * All the parameters above affect the output hash value. - * Additionally, two function pointers can be provided to allocate and - * deallocate the memory (if NULL, memory will be allocated internally). - * Also, three flags indicate whether to erase password, secret as soon as they - * are pre-hashed (and thus not needed anymore), and the entire memory - ***** - * Simplest situation: you have output array out[8], password is stored in - * pwd[32], salt is stored in salt[16], you do not have keys nor associated - * data. You need to spend 1 GB of RAM and you run 5 passes of Argon2d with - * 4 parallel lanes. - * You want to erase the password, but you're OK with last pass not being - * erased. You want to use the default memory allocator. - * Then you initialize: - Argon2_Context(out,8,pwd,32,salt,16,NULL,0,NULL,0,5,1<<20,4,4,NULL,NULL,true,false,false,false) - */ -typedef struct Argon2_Context { - uint8_t *out; /* output array */ - uint32_t outlen; /* digest length */ - - uint8_t *pwd; /* password array */ - uint32_t pwdlen; /* password length */ - - uint8_t *salt; /* salt array */ - uint32_t saltlen; /* salt length */ - - uint8_t *secret; /* key array */ - uint32_t secretlen; /* key length */ - - uint8_t *ad; /* associated data array */ - uint32_t adlen; /* associated data length */ - - uint32_t t_cost; /* number of passes */ - uint32_t m_cost; /* amount of memory requested (KB) */ - uint32_t lanes; /* number of lanes */ - uint32_t threads; /* maximum number of threads */ - - uint32_t version; /* version number */ - - allocate_fptr allocate_cbk; /* pointer to memory allocator */ - deallocate_fptr free_cbk; /* pointer to memory deallocator */ - - uint32_t flags; /* array of bool options */ -} argon2_context; - -/* Argon2 primitive type */ -typedef enum Argon2_type { - Argon2_d = 0, - Argon2_i = 1, - Argon2_id = 2 -} argon2_type; - -/* Version of the algorithm */ -typedef enum Argon2_version { - ARGON2_VERSION_10 = 0x10, - ARGON2_VERSION_13 = 0x13, - ARGON2_VERSION_NUMBER = ARGON2_VERSION_13 -} argon2_version; - -/* - * Function that gives the string representation of an argon2_type. - * @param type The argon2_type that we want the string for - * @param uppercase Whether the string should have the first letter uppercase - * @return NULL if invalid type, otherwise the string representation. - */ -ARGON2_PUBLIC const char *argon2_type2string(argon2_type type, int uppercase); - -/* - * Function that performs memory-hard hashing with certain degree of parallelism - * @param context Pointer to the Argon2 internal structure - * @return Error code if smth is wrong, ARGON2_OK otherwise - */ -ARGON2_PUBLIC int argon2_ctx(argon2_context *context, argon2_type type); - -/** - * Hashes a password with Argon2i, producing an encoded hash - * @param t_cost Number of iterations - * @param m_cost Sets memory usage to m_cost kibibytes - * @param parallelism Number of threads and compute lanes - * @param pwd Pointer to password - * @param pwdlen Password size in bytes - * @param salt Pointer to salt - * @param saltlen Salt size in bytes - * @param hashlen Desired length of the hash in bytes - * @param encoded Buffer where to write the encoded hash - * @param encodedlen Size of the buffer (thus max size of the encoded hash) - * @pre Different parallelism levels will give different results - * @pre Returns ARGON2_OK if successful - */ -ARGON2_PUBLIC int argon2i_hash_encoded(const uint32_t t_cost, - const uint32_t m_cost, - const uint32_t parallelism, - const void *pwd, const size_t pwdlen, - const void *salt, const size_t saltlen, - const size_t hashlen, char *encoded, - const size_t encodedlen); - -/** - * Hashes a password with Argon2i, producing a raw hash at @hash - * @param t_cost Number of iterations - * @param m_cost Sets memory usage to m_cost kibibytes - * @param parallelism Number of threads and compute lanes - * @param pwd Pointer to password - * @param pwdlen Password size in bytes - * @param salt Pointer to salt - * @param saltlen Salt size in bytes - * @param hash Buffer where to write the raw hash - updated by the function - * @param hashlen Desired length of the hash in bytes - * @pre Different parallelism levels will give different results - * @pre Returns ARGON2_OK if successful - */ -ARGON2_PUBLIC int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost, - const uint32_t parallelism, const void *pwd, - const size_t pwdlen, const void *salt, - const size_t saltlen, void *hash, - const size_t hashlen); - -ARGON2_PUBLIC int argon2d_hash_encoded(const uint32_t t_cost, - const uint32_t m_cost, - const uint32_t parallelism, - const void *pwd, const size_t pwdlen, - const void *salt, const size_t saltlen, - const size_t hashlen, char *encoded, - const size_t encodedlen); - -ARGON2_PUBLIC int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost, - const uint32_t parallelism, const void *pwd, - const size_t pwdlen, const void *salt, - const size_t saltlen, void *hash, - const size_t hashlen); - -ARGON2_PUBLIC int argon2id_hash_encoded(const uint32_t t_cost, - const uint32_t m_cost, - const uint32_t parallelism, - const void *pwd, const size_t pwdlen, - const void *salt, const size_t saltlen, - const size_t hashlen, char *encoded, - const size_t encodedlen); - -ARGON2_PUBLIC int argon2id_hash_raw(const uint32_t t_cost, - const uint32_t m_cost, - const uint32_t parallelism, const void *pwd, - const size_t pwdlen, const void *salt, - const size_t saltlen, void *hash, - const size_t hashlen); - -/* generic function underlying the above ones */ -ARGON2_PUBLIC int argon2_hash(const uint32_t t_cost, const uint32_t m_cost, - const uint32_t parallelism, const void *pwd, - const size_t pwdlen, const void *salt, - const size_t saltlen, void *hash, - const size_t hashlen, char *encoded, - const size_t encodedlen, argon2_type type, - const uint32_t version); - -/** - * Verifies a password against an encoded string - * Encoded string is restricted as in validate_inputs() - * @param encoded String encoding parameters, salt, hash - * @param pwd Pointer to password - * @pre Returns ARGON2_OK if successful - */ -ARGON2_PUBLIC int argon2i_verify(const char *encoded, const void *pwd, - const size_t pwdlen); - -ARGON2_PUBLIC int argon2d_verify(const char *encoded, const void *pwd, - const size_t pwdlen); - -ARGON2_PUBLIC int argon2id_verify(const char *encoded, const void *pwd, - const size_t pwdlen); - -/* generic function underlying the above ones */ -ARGON2_PUBLIC int argon2_verify(const char *encoded, const void *pwd, - const size_t pwdlen, argon2_type type); - -/** - * Argon2d: Version of Argon2 that picks memory blocks depending - * on the password and salt. Only for side-channel-free - * environment!! - ***** - * @param context Pointer to current Argon2 context - * @return Zero if successful, a non zero error code otherwise - */ -ARGON2_PUBLIC int argon2d_ctx(argon2_context *context); - -/** - * Argon2i: Version of Argon2 that picks memory blocks - * independent on the password and salt. Good for side-channels, - * but worse w.r.t. tradeoff attacks if only one pass is used. - ***** - * @param context Pointer to current Argon2 context - * @return Zero if successful, a non zero error code otherwise - */ -ARGON2_PUBLIC int argon2i_ctx(argon2_context *context); - -/** - * Argon2id: Version of Argon2 where the first half-pass over memory is - * password-independent, the rest are password-dependent (on the password and - * salt). OK against side channels (they reduce to 1/2-pass Argon2i), and - * better with w.r.t. tradeoff attacks (similar to Argon2d). - ***** - * @param context Pointer to current Argon2 context - * @return Zero if successful, a non zero error code otherwise - */ -ARGON2_PUBLIC int argon2id_ctx(argon2_context *context); - -/** - * Verify if a given password is correct for Argon2d hashing - * @param context Pointer to current Argon2 context - * @param hash The password hash to verify. The length of the hash is - * specified by the context outlen member - * @return Zero if successful, a non zero error code otherwise - */ -ARGON2_PUBLIC int argon2d_verify_ctx(argon2_context *context, const char *hash); - -/** - * Verify if a given password is correct for Argon2i hashing - * @param context Pointer to current Argon2 context - * @param hash The password hash to verify. The length of the hash is - * specified by the context outlen member - * @return Zero if successful, a non zero error code otherwise - */ -ARGON2_PUBLIC int argon2i_verify_ctx(argon2_context *context, const char *hash); - -/** - * Verify if a given password is correct for Argon2id hashing - * @param context Pointer to current Argon2 context - * @param hash The password hash to verify. The length of the hash is - * specified by the context outlen member - * @return Zero if successful, a non zero error code otherwise - */ -ARGON2_PUBLIC int argon2id_verify_ctx(argon2_context *context, - const char *hash); - -/* generic function underlying the above ones */ -ARGON2_PUBLIC int argon2_verify_ctx(argon2_context *context, const char *hash, - argon2_type type); - -/** - * Get the associated error message for given error code - * @return The error message associated with the given error code - */ -ARGON2_PUBLIC const char *argon2_error_message(int error_code); - -/** - * Returns the encoded hash length for the given input parameters - * @param t_cost Number of iterations - * @param m_cost Memory usage in kibibytes - * @param parallelism Number of threads; used to compute lanes - * @param saltlen Salt size in bytes - * @param hashlen Hash size in bytes - * @param type The argon2_type that we want the encoded length for - * @return The encoded hash length in bytes - */ -ARGON2_PUBLIC size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost, - uint32_t parallelism, uint32_t saltlen, - uint32_t hashlen, argon2_type type); - -#if defined(__cplusplus) -} -#endif - -#endif diff --git a/0x0017a_ctf/third_party/argon2/src/argon2.c b/0x0017a_ctf/third_party/argon2/src/argon2.c deleted file mode 100644 index 34da3d6..0000000 --- a/0x0017a_ctf/third_party/argon2/src/argon2.c +++ /dev/null @@ -1,452 +0,0 @@ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ - -#include -#include -#include - -#include "argon2.h" -#include "encoding.h" -#include "core.h" - -const char *argon2_type2string(argon2_type type, int uppercase) { - switch (type) { - case Argon2_d: - return uppercase ? "Argon2d" : "argon2d"; - case Argon2_i: - return uppercase ? "Argon2i" : "argon2i"; - case Argon2_id: - return uppercase ? "Argon2id" : "argon2id"; - } - - return NULL; -} - -int argon2_ctx(argon2_context *context, argon2_type type) { - /* 1. Validate all inputs */ - int result = validate_inputs(context); - uint32_t memory_blocks, segment_length; - argon2_instance_t instance; - - if (ARGON2_OK != result) { - return result; - } - - if (Argon2_d != type && Argon2_i != type && Argon2_id != type) { - return ARGON2_INCORRECT_TYPE; - } - - /* 2. Align memory size */ - /* Minimum memory_blocks = 8L blocks, where L is the number of lanes */ - memory_blocks = context->m_cost; - - if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) { - memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes; - } - - segment_length = memory_blocks / (context->lanes * ARGON2_SYNC_POINTS); - /* Ensure that all segments have equal length */ - memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS); - - instance.version = context->version; - instance.memory = NULL; - instance.passes = context->t_cost; - instance.memory_blocks = memory_blocks; - instance.segment_length = segment_length; - instance.lane_length = segment_length * ARGON2_SYNC_POINTS; - instance.lanes = context->lanes; - instance.threads = context->threads; - instance.type = type; - - if (instance.threads > instance.lanes) { - instance.threads = instance.lanes; - } - - /* 3. Initialization: Hashing inputs, allocating memory, filling first - * blocks - */ - result = initialize(&instance, context); - - if (ARGON2_OK != result) { - return result; - } - - /* 4. Filling memory */ - result = fill_memory_blocks(&instance); - - if (ARGON2_OK != result) { - return result; - } - /* 5. Finalization */ - finalize(context, &instance); - - return ARGON2_OK; -} - -int argon2_hash(const uint32_t t_cost, const uint32_t m_cost, - const uint32_t parallelism, const void *pwd, - const size_t pwdlen, const void *salt, const size_t saltlen, - void *hash, const size_t hashlen, char *encoded, - const size_t encodedlen, argon2_type type, - const uint32_t version){ - - argon2_context context; - int result; - uint8_t *out; - - if (pwdlen > ARGON2_MAX_PWD_LENGTH) { - return ARGON2_PWD_TOO_LONG; - } - - if (saltlen > ARGON2_MAX_SALT_LENGTH) { - return ARGON2_SALT_TOO_LONG; - } - - if (hashlen > ARGON2_MAX_OUTLEN) { - return ARGON2_OUTPUT_TOO_LONG; - } - - if (hashlen < ARGON2_MIN_OUTLEN) { - return ARGON2_OUTPUT_TOO_SHORT; - } - - out = malloc(hashlen); - if (!out) { - return ARGON2_MEMORY_ALLOCATION_ERROR; - } - - context.out = (uint8_t *)out; - context.outlen = (uint32_t)hashlen; - context.pwd = CONST_CAST(uint8_t *)pwd; - context.pwdlen = (uint32_t)pwdlen; - context.salt = CONST_CAST(uint8_t *)salt; - context.saltlen = (uint32_t)saltlen; - context.secret = NULL; - context.secretlen = 0; - context.ad = NULL; - context.adlen = 0; - context.t_cost = t_cost; - context.m_cost = m_cost; - context.lanes = parallelism; - context.threads = parallelism; - context.allocate_cbk = NULL; - context.free_cbk = NULL; - context.flags = ARGON2_DEFAULT_FLAGS; - context.version = version; - - result = argon2_ctx(&context, type); - - if (result != ARGON2_OK) { - clear_internal_memory(out, hashlen); - free(out); - return result; - } - - /* if raw hash requested, write it */ - if (hash) { - memcpy(hash, out, hashlen); - } - - /* if encoding requested, write it */ - if (encoded && encodedlen) { - if (encode_string(encoded, encodedlen, &context, type) != ARGON2_OK) { - clear_internal_memory(out, hashlen); /* wipe buffers if error */ - clear_internal_memory(encoded, encodedlen); - free(out); - return ARGON2_ENCODING_FAIL; - } - } - clear_internal_memory(out, hashlen); - free(out); - - return ARGON2_OK; -} - -int argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, - const uint32_t parallelism, const void *pwd, - const size_t pwdlen, const void *salt, - const size_t saltlen, const size_t hashlen, - char *encoded, const size_t encodedlen) { - - return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, - NULL, hashlen, encoded, encodedlen, Argon2_i, - ARGON2_VERSION_NUMBER); -} - -int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost, - const uint32_t parallelism, const void *pwd, - const size_t pwdlen, const void *salt, - const size_t saltlen, void *hash, const size_t hashlen) { - - return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, - hash, hashlen, NULL, 0, Argon2_i, ARGON2_VERSION_NUMBER); -} - -int argon2d_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, - const uint32_t parallelism, const void *pwd, - const size_t pwdlen, const void *salt, - const size_t saltlen, const size_t hashlen, - char *encoded, const size_t encodedlen) { - - return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, - NULL, hashlen, encoded, encodedlen, Argon2_d, - ARGON2_VERSION_NUMBER); -} - -int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost, - const uint32_t parallelism, const void *pwd, - const size_t pwdlen, const void *salt, - const size_t saltlen, void *hash, const size_t hashlen) { - - return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, - hash, hashlen, NULL, 0, Argon2_d, ARGON2_VERSION_NUMBER); -} - -int argon2id_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, - const uint32_t parallelism, const void *pwd, - const size_t pwdlen, const void *salt, - const size_t saltlen, const size_t hashlen, - char *encoded, const size_t encodedlen) { - - return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, - NULL, hashlen, encoded, encodedlen, Argon2_id, - ARGON2_VERSION_NUMBER); -} - -int argon2id_hash_raw(const uint32_t t_cost, const uint32_t m_cost, - const uint32_t parallelism, const void *pwd, - const size_t pwdlen, const void *salt, - const size_t saltlen, void *hash, const size_t hashlen) { - return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, - hash, hashlen, NULL, 0, Argon2_id, - ARGON2_VERSION_NUMBER); -} - -static int argon2_compare(const uint8_t *b1, const uint8_t *b2, size_t len) { - size_t i; - uint8_t d = 0U; - - for (i = 0U; i < len; i++) { - d |= b1[i] ^ b2[i]; - } - return (int)((1 & ((d - 1) >> 8)) - 1); -} - -int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen, - argon2_type type) { - - argon2_context ctx; - uint8_t *desired_result = NULL; - - int ret = ARGON2_OK; - - size_t encoded_len; - uint32_t max_field_len; - - if (pwdlen > ARGON2_MAX_PWD_LENGTH) { - return ARGON2_PWD_TOO_LONG; - } - - if (encoded == NULL) { - return ARGON2_DECODING_FAIL; - } - - encoded_len = strlen(encoded); - if (encoded_len > UINT32_MAX) { - return ARGON2_DECODING_FAIL; - } - - /* No field can be longer than the encoded length */ - max_field_len = (uint32_t)encoded_len; - - ctx.saltlen = max_field_len; - ctx.outlen = max_field_len; - - ctx.salt = malloc(ctx.saltlen); - ctx.out = malloc(ctx.outlen); - if (!ctx.salt || !ctx.out) { - ret = ARGON2_MEMORY_ALLOCATION_ERROR; - goto fail; - } - - ctx.pwd = (uint8_t *)pwd; - ctx.pwdlen = (uint32_t)pwdlen; - - ret = decode_string(&ctx, encoded, type); - if (ret != ARGON2_OK) { - goto fail; - } - - /* Set aside the desired result, and get a new buffer. */ - desired_result = ctx.out; - ctx.out = malloc(ctx.outlen); - if (!ctx.out) { - ret = ARGON2_MEMORY_ALLOCATION_ERROR; - goto fail; - } - - ret = argon2_verify_ctx(&ctx, (char *)desired_result, type); - if (ret != ARGON2_OK) { - goto fail; - } - -fail: - free(ctx.salt); - free(ctx.out); - free(desired_result); - - return ret; -} - -int argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen) { - - return argon2_verify(encoded, pwd, pwdlen, Argon2_i); -} - -int argon2d_verify(const char *encoded, const void *pwd, const size_t pwdlen) { - - return argon2_verify(encoded, pwd, pwdlen, Argon2_d); -} - -int argon2id_verify(const char *encoded, const void *pwd, const size_t pwdlen) { - - return argon2_verify(encoded, pwd, pwdlen, Argon2_id); -} - -int argon2d_ctx(argon2_context *context) { - return argon2_ctx(context, Argon2_d); -} - -int argon2i_ctx(argon2_context *context) { - return argon2_ctx(context, Argon2_i); -} - -int argon2id_ctx(argon2_context *context) { - return argon2_ctx(context, Argon2_id); -} - -int argon2_verify_ctx(argon2_context *context, const char *hash, - argon2_type type) { - int ret = argon2_ctx(context, type); - if (ret != ARGON2_OK) { - return ret; - } - - if (argon2_compare((uint8_t *)hash, context->out, context->outlen)) { - return ARGON2_VERIFY_MISMATCH; - } - - return ARGON2_OK; -} - -int argon2d_verify_ctx(argon2_context *context, const char *hash) { - return argon2_verify_ctx(context, hash, Argon2_d); -} - -int argon2i_verify_ctx(argon2_context *context, const char *hash) { - return argon2_verify_ctx(context, hash, Argon2_i); -} - -int argon2id_verify_ctx(argon2_context *context, const char *hash) { - return argon2_verify_ctx(context, hash, Argon2_id); -} - -const char *argon2_error_message(int error_code) { - switch (error_code) { - case ARGON2_OK: - return "OK"; - case ARGON2_OUTPUT_PTR_NULL: - return "Output pointer is NULL"; - case ARGON2_OUTPUT_TOO_SHORT: - return "Output is too short"; - case ARGON2_OUTPUT_TOO_LONG: - return "Output is too long"; - case ARGON2_PWD_TOO_SHORT: - return "Password is too short"; - case ARGON2_PWD_TOO_LONG: - return "Password is too long"; - case ARGON2_SALT_TOO_SHORT: - return "Salt is too short"; - case ARGON2_SALT_TOO_LONG: - return "Salt is too long"; - case ARGON2_AD_TOO_SHORT: - return "Associated data is too short"; - case ARGON2_AD_TOO_LONG: - return "Associated data is too long"; - case ARGON2_SECRET_TOO_SHORT: - return "Secret is too short"; - case ARGON2_SECRET_TOO_LONG: - return "Secret is too long"; - case ARGON2_TIME_TOO_SMALL: - return "Time cost is too small"; - case ARGON2_TIME_TOO_LARGE: - return "Time cost is too large"; - case ARGON2_MEMORY_TOO_LITTLE: - return "Memory cost is too small"; - case ARGON2_MEMORY_TOO_MUCH: - return "Memory cost is too large"; - case ARGON2_LANES_TOO_FEW: - return "Too few lanes"; - case ARGON2_LANES_TOO_MANY: - return "Too many lanes"; - case ARGON2_PWD_PTR_MISMATCH: - return "Password pointer is NULL, but password length is not 0"; - case ARGON2_SALT_PTR_MISMATCH: - return "Salt pointer is NULL, but salt length is not 0"; - case ARGON2_SECRET_PTR_MISMATCH: - return "Secret pointer is NULL, but secret length is not 0"; - case ARGON2_AD_PTR_MISMATCH: - return "Associated data pointer is NULL, but ad length is not 0"; - case ARGON2_MEMORY_ALLOCATION_ERROR: - return "Memory allocation error"; - case ARGON2_FREE_MEMORY_CBK_NULL: - return "The free memory callback is NULL"; - case ARGON2_ALLOCATE_MEMORY_CBK_NULL: - return "The allocate memory callback is NULL"; - case ARGON2_INCORRECT_PARAMETER: - return "Argon2_Context context is NULL"; - case ARGON2_INCORRECT_TYPE: - return "There is no such version of Argon2"; - case ARGON2_OUT_PTR_MISMATCH: - return "Output pointer mismatch"; - case ARGON2_THREADS_TOO_FEW: - return "Not enough threads"; - case ARGON2_THREADS_TOO_MANY: - return "Too many threads"; - case ARGON2_MISSING_ARGS: - return "Missing arguments"; - case ARGON2_ENCODING_FAIL: - return "Encoding failed"; - case ARGON2_DECODING_FAIL: - return "Decoding failed"; - case ARGON2_THREAD_FAIL: - return "Threading failure"; - case ARGON2_DECODING_LENGTH_FAIL: - return "Some of encoded parameters are too long or too short"; - case ARGON2_VERIFY_MISMATCH: - return "The password does not match the supplied hash"; - default: - return "Unknown error code"; - } -} - -size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost, uint32_t parallelism, - uint32_t saltlen, uint32_t hashlen, argon2_type type) { - return strlen("$$v=$m=,t=,p=$$") + strlen(argon2_type2string(type, 0)) + - numlen(t_cost) + numlen(m_cost) + numlen(parallelism) + - b64len(saltlen) + b64len(hashlen) + numlen(ARGON2_VERSION_NUMBER) + 1; -} diff --git a/0x0017a_ctf/third_party/argon2/src/blake2/blake2-impl.h b/0x0017a_ctf/third_party/argon2/src/blake2/blake2-impl.h deleted file mode 100644 index 86d0d5c..0000000 --- a/0x0017a_ctf/third_party/argon2/src/blake2/blake2-impl.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ - -#ifndef PORTABLE_BLAKE2_IMPL_H -#define PORTABLE_BLAKE2_IMPL_H - -#include -#include - -#ifdef _WIN32 -#define BLAKE2_INLINE __inline -#elif defined(__GNUC__) || defined(__clang__) -#define BLAKE2_INLINE __inline__ -#else -#define BLAKE2_INLINE -#endif - -/* Argon2 Team - Begin Code */ -/* - Not an exhaustive list, but should cover the majority of modern platforms - Additionally, the code will always be correct---this is only a performance - tweak. -*/ -#if (defined(__BYTE_ORDER__) && \ - (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) || \ - defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || defined(__MIPSEL__) || \ - defined(__AARCH64EL__) || defined(__amd64__) || defined(__i386__) || \ - defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64) || \ - defined(_M_ARM) -#define NATIVE_LITTLE_ENDIAN -#endif -/* Argon2 Team - End Code */ - -static BLAKE2_INLINE uint32_t load32(const void *src) { -#if defined(NATIVE_LITTLE_ENDIAN) - uint32_t w; - memcpy(&w, src, sizeof w); - return w; -#else - const uint8_t *p = (const uint8_t *)src; - uint32_t w = *p++; - w |= (uint32_t)(*p++) << 8; - w |= (uint32_t)(*p++) << 16; - w |= (uint32_t)(*p++) << 24; - return w; -#endif -} - -static BLAKE2_INLINE uint64_t load64(const void *src) { -#if defined(NATIVE_LITTLE_ENDIAN) - uint64_t w; - memcpy(&w, src, sizeof w); - return w; -#else - const uint8_t *p = (const uint8_t *)src; - uint64_t w = *p++; - w |= (uint64_t)(*p++) << 8; - w |= (uint64_t)(*p++) << 16; - w |= (uint64_t)(*p++) << 24; - w |= (uint64_t)(*p++) << 32; - w |= (uint64_t)(*p++) << 40; - w |= (uint64_t)(*p++) << 48; - w |= (uint64_t)(*p++) << 56; - return w; -#endif -} - -static BLAKE2_INLINE void store32(void *dst, uint32_t w) { -#if defined(NATIVE_LITTLE_ENDIAN) - memcpy(dst, &w, sizeof w); -#else - uint8_t *p = (uint8_t *)dst; - *p++ = (uint8_t)w; - w >>= 8; - *p++ = (uint8_t)w; - w >>= 8; - *p++ = (uint8_t)w; - w >>= 8; - *p++ = (uint8_t)w; -#endif -} - -static BLAKE2_INLINE void store64(void *dst, uint64_t w) { -#if defined(NATIVE_LITTLE_ENDIAN) - memcpy(dst, &w, sizeof w); -#else - uint8_t *p = (uint8_t *)dst; - *p++ = (uint8_t)w; - w >>= 8; - *p++ = (uint8_t)w; - w >>= 8; - *p++ = (uint8_t)w; - w >>= 8; - *p++ = (uint8_t)w; - w >>= 8; - *p++ = (uint8_t)w; - w >>= 8; - *p++ = (uint8_t)w; - w >>= 8; - *p++ = (uint8_t)w; - w >>= 8; - *p++ = (uint8_t)w; -#endif -} - -static BLAKE2_INLINE uint64_t load48(const void *src) { - const uint8_t *p = (const uint8_t *)src; - uint64_t w = *p++; - w |= (uint64_t)(*p++) << 8; - w |= (uint64_t)(*p++) << 16; - w |= (uint64_t)(*p++) << 24; - w |= (uint64_t)(*p++) << 32; - w |= (uint64_t)(*p++) << 40; - return w; -} - -static BLAKE2_INLINE void store48(void *dst, uint64_t w) { - uint8_t *p = (uint8_t *)dst; - *p++ = (uint8_t)w; - w >>= 8; - *p++ = (uint8_t)w; - w >>= 8; - *p++ = (uint8_t)w; - w >>= 8; - *p++ = (uint8_t)w; - w >>= 8; - *p++ = (uint8_t)w; - w >>= 8; - *p++ = (uint8_t)w; -} - -static BLAKE2_INLINE uint32_t rotr32(const uint32_t w, const unsigned c) { - return (w >> c) | (w << (32 - c)); -} - -static BLAKE2_INLINE uint64_t rotr64(const uint64_t w, const unsigned c) { - return (w >> c) | (w << (64 - c)); -} - -void clear_internal_memory(void *v, size_t n); - -#endif diff --git a/0x0017a_ctf/third_party/argon2/src/blake2/blake2.h b/0x0017a_ctf/third_party/argon2/src/blake2/blake2.h deleted file mode 100644 index 501c6a3..0000000 --- a/0x0017a_ctf/third_party/argon2/src/blake2/blake2.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ - -#ifndef PORTABLE_BLAKE2_H -#define PORTABLE_BLAKE2_H - -#include - -#if defined(__cplusplus) -extern "C" { -#endif - -enum blake2b_constant { - BLAKE2B_BLOCKBYTES = 128, - BLAKE2B_OUTBYTES = 64, - BLAKE2B_KEYBYTES = 64, - BLAKE2B_SALTBYTES = 16, - BLAKE2B_PERSONALBYTES = 16 -}; - -#pragma pack(push, 1) -typedef struct __blake2b_param { - uint8_t digest_length; /* 1 */ - uint8_t key_length; /* 2 */ - uint8_t fanout; /* 3 */ - uint8_t depth; /* 4 */ - uint32_t leaf_length; /* 8 */ - uint64_t node_offset; /* 16 */ - uint8_t node_depth; /* 17 */ - uint8_t inner_length; /* 18 */ - uint8_t reserved[14]; /* 32 */ - uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ - uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ -} blake2b_param; -#pragma pack(pop) - -typedef struct __blake2b_state { - uint64_t h[8]; - uint64_t t[2]; - uint64_t f[2]; - uint8_t buf[BLAKE2B_BLOCKBYTES]; - unsigned buflen; - unsigned outlen; - uint8_t last_node; -} blake2b_state; - -/* Ensure param structs have not been wrongly padded */ -/* Poor man's static_assert */ -enum { - blake2_size_check_0 = 1 / !!(CHAR_BIT == 8), - blake2_size_check_2 = - 1 / !!(sizeof(blake2b_param) == sizeof(uint64_t) * CHAR_BIT) -}; - -/* Streaming API */ -ARGON2_LOCAL int blake2b_init(blake2b_state *S, size_t outlen); -ARGON2_LOCAL int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key, - size_t keylen); -ARGON2_LOCAL int blake2b_init_param(blake2b_state *S, const blake2b_param *P); -ARGON2_LOCAL int blake2b_update(blake2b_state *S, const void *in, size_t inlen); -ARGON2_LOCAL int blake2b_final(blake2b_state *S, void *out, size_t outlen); - -/* Simple API */ -ARGON2_LOCAL int blake2b(void *out, size_t outlen, const void *in, size_t inlen, - const void *key, size_t keylen); - -/* Argon2 Team - Begin Code */ -ARGON2_LOCAL int blake2b_long(void *out, size_t outlen, const void *in, size_t inlen); -/* Argon2 Team - End Code */ - -#if defined(__cplusplus) -} -#endif - -#endif diff --git a/0x0017a_ctf/third_party/argon2/src/blake2/blake2b.c b/0x0017a_ctf/third_party/argon2/src/blake2/blake2b.c deleted file mode 100644 index 3b519dd..0000000 --- a/0x0017a_ctf/third_party/argon2/src/blake2/blake2b.c +++ /dev/null @@ -1,390 +0,0 @@ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ - -#include -#include -#include - -#include "blake2.h" -#include "blake2-impl.h" - -static const uint64_t blake2b_IV[8] = { - UINT64_C(0x6a09e667f3bcc908), UINT64_C(0xbb67ae8584caa73b), - UINT64_C(0x3c6ef372fe94f82b), UINT64_C(0xa54ff53a5f1d36f1), - UINT64_C(0x510e527fade682d1), UINT64_C(0x9b05688c2b3e6c1f), - UINT64_C(0x1f83d9abfb41bd6b), UINT64_C(0x5be0cd19137e2179)}; - -static const unsigned int blake2b_sigma[12][16] = { - {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, - {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}, - {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4}, - {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8}, - {9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13}, - {2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9}, - {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11}, - {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10}, - {6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5}, - {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0}, - {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, - {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}, -}; - -static BLAKE2_INLINE void blake2b_set_lastnode(blake2b_state *S) { - S->f[1] = (uint64_t)-1; -} - -static BLAKE2_INLINE void blake2b_set_lastblock(blake2b_state *S) { - if (S->last_node) { - blake2b_set_lastnode(S); - } - S->f[0] = (uint64_t)-1; -} - -static BLAKE2_INLINE void blake2b_increment_counter(blake2b_state *S, - uint64_t inc) { - S->t[0] += inc; - S->t[1] += (S->t[0] < inc); -} - -static BLAKE2_INLINE void blake2b_invalidate_state(blake2b_state *S) { - clear_internal_memory(S, sizeof(*S)); /* wipe */ - blake2b_set_lastblock(S); /* invalidate for further use */ -} - -static BLAKE2_INLINE void blake2b_init0(blake2b_state *S) { - memset(S, 0, sizeof(*S)); - memcpy(S->h, blake2b_IV, sizeof(S->h)); -} - -int blake2b_init_param(blake2b_state *S, const blake2b_param *P) { - const unsigned char *p = (const unsigned char *)P; - unsigned int i; - - if (NULL == P || NULL == S) { - return -1; - } - - blake2b_init0(S); - /* IV XOR Parameter Block */ - for (i = 0; i < 8; ++i) { - S->h[i] ^= load64(&p[i * sizeof(S->h[i])]); - } - S->outlen = P->digest_length; - return 0; -} - -/* Sequential blake2b initialization */ -int blake2b_init(blake2b_state *S, size_t outlen) { - blake2b_param P; - - if (S == NULL) { - return -1; - } - - if ((outlen == 0) || (outlen > BLAKE2B_OUTBYTES)) { - blake2b_invalidate_state(S); - return -1; - } - - /* Setup Parameter Block for unkeyed BLAKE2 */ - P.digest_length = (uint8_t)outlen; - P.key_length = 0; - P.fanout = 1; - P.depth = 1; - P.leaf_length = 0; - P.node_offset = 0; - P.node_depth = 0; - P.inner_length = 0; - memset(P.reserved, 0, sizeof(P.reserved)); - memset(P.salt, 0, sizeof(P.salt)); - memset(P.personal, 0, sizeof(P.personal)); - - return blake2b_init_param(S, &P); -} - -int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key, - size_t keylen) { - blake2b_param P; - - if (S == NULL) { - return -1; - } - - if ((outlen == 0) || (outlen > BLAKE2B_OUTBYTES)) { - blake2b_invalidate_state(S); - return -1; - } - - if ((key == 0) || (keylen == 0) || (keylen > BLAKE2B_KEYBYTES)) { - blake2b_invalidate_state(S); - return -1; - } - - /* Setup Parameter Block for keyed BLAKE2 */ - P.digest_length = (uint8_t)outlen; - P.key_length = (uint8_t)keylen; - P.fanout = 1; - P.depth = 1; - P.leaf_length = 0; - P.node_offset = 0; - P.node_depth = 0; - P.inner_length = 0; - memset(P.reserved, 0, sizeof(P.reserved)); - memset(P.salt, 0, sizeof(P.salt)); - memset(P.personal, 0, sizeof(P.personal)); - - if (blake2b_init_param(S, &P) < 0) { - blake2b_invalidate_state(S); - return -1; - } - - { - uint8_t block[BLAKE2B_BLOCKBYTES]; - memset(block, 0, BLAKE2B_BLOCKBYTES); - memcpy(block, key, keylen); - blake2b_update(S, block, BLAKE2B_BLOCKBYTES); - /* Burn the key from stack */ - clear_internal_memory(block, BLAKE2B_BLOCKBYTES); - } - return 0; -} - -static void blake2b_compress(blake2b_state *S, const uint8_t *block) { - uint64_t m[16]; - uint64_t v[16]; - unsigned int i, r; - - for (i = 0; i < 16; ++i) { - m[i] = load64(block + i * sizeof(m[i])); - } - - for (i = 0; i < 8; ++i) { - v[i] = S->h[i]; - } - - v[8] = blake2b_IV[0]; - v[9] = blake2b_IV[1]; - v[10] = blake2b_IV[2]; - v[11] = blake2b_IV[3]; - v[12] = blake2b_IV[4] ^ S->t[0]; - v[13] = blake2b_IV[5] ^ S->t[1]; - v[14] = blake2b_IV[6] ^ S->f[0]; - v[15] = blake2b_IV[7] ^ S->f[1]; - -#define G(r, i, a, b, c, d) \ - do { \ - a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \ - d = rotr64(d ^ a, 32); \ - c = c + d; \ - b = rotr64(b ^ c, 24); \ - a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \ - d = rotr64(d ^ a, 16); \ - c = c + d; \ - b = rotr64(b ^ c, 63); \ - } while ((void)0, 0) - -#define ROUND(r) \ - do { \ - G(r, 0, v[0], v[4], v[8], v[12]); \ - G(r, 1, v[1], v[5], v[9], v[13]); \ - G(r, 2, v[2], v[6], v[10], v[14]); \ - G(r, 3, v[3], v[7], v[11], v[15]); \ - G(r, 4, v[0], v[5], v[10], v[15]); \ - G(r, 5, v[1], v[6], v[11], v[12]); \ - G(r, 6, v[2], v[7], v[8], v[13]); \ - G(r, 7, v[3], v[4], v[9], v[14]); \ - } while ((void)0, 0) - - for (r = 0; r < 12; ++r) { - ROUND(r); - } - - for (i = 0; i < 8; ++i) { - S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; - } - -#undef G -#undef ROUND -} - -int blake2b_update(blake2b_state *S, const void *in, size_t inlen) { - const uint8_t *pin = (const uint8_t *)in; - - if (inlen == 0) { - return 0; - } - - /* Sanity check */ - if (S == NULL || in == NULL) { - return -1; - } - - /* Is this a reused state? */ - if (S->f[0] != 0) { - return -1; - } - - if (S->buflen + inlen > BLAKE2B_BLOCKBYTES) { - /* Complete current block */ - size_t left = S->buflen; - size_t fill = BLAKE2B_BLOCKBYTES - left; - memcpy(&S->buf[left], pin, fill); - blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); - blake2b_compress(S, S->buf); - S->buflen = 0; - inlen -= fill; - pin += fill; - /* Avoid buffer copies when possible */ - while (inlen > BLAKE2B_BLOCKBYTES) { - blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); - blake2b_compress(S, pin); - inlen -= BLAKE2B_BLOCKBYTES; - pin += BLAKE2B_BLOCKBYTES; - } - } - memcpy(&S->buf[S->buflen], pin, inlen); - S->buflen += (unsigned int)inlen; - return 0; -} - -int blake2b_final(blake2b_state *S, void *out, size_t outlen) { - uint8_t buffer[BLAKE2B_OUTBYTES] = {0}; - unsigned int i; - - /* Sanity checks */ - if (S == NULL || out == NULL || outlen < S->outlen) { - return -1; - } - - /* Is this a reused state? */ - if (S->f[0] != 0) { - return -1; - } - - blake2b_increment_counter(S, S->buflen); - blake2b_set_lastblock(S); - memset(&S->buf[S->buflen], 0, BLAKE2B_BLOCKBYTES - S->buflen); /* Padding */ - blake2b_compress(S, S->buf); - - for (i = 0; i < 8; ++i) { /* Output full hash to temp buffer */ - store64(buffer + sizeof(S->h[i]) * i, S->h[i]); - } - - memcpy(out, buffer, S->outlen); - clear_internal_memory(buffer, sizeof(buffer)); - clear_internal_memory(S->buf, sizeof(S->buf)); - clear_internal_memory(S->h, sizeof(S->h)); - return 0; -} - -int blake2b(void *out, size_t outlen, const void *in, size_t inlen, - const void *key, size_t keylen) { - blake2b_state S; - int ret = -1; - - /* Verify parameters */ - if (NULL == in && inlen > 0) { - goto fail; - } - - if (NULL == out || outlen == 0 || outlen > BLAKE2B_OUTBYTES) { - goto fail; - } - - if ((NULL == key && keylen > 0) || keylen > BLAKE2B_KEYBYTES) { - goto fail; - } - - if (keylen > 0) { - if (blake2b_init_key(&S, outlen, key, keylen) < 0) { - goto fail; - } - } else { - if (blake2b_init(&S, outlen) < 0) { - goto fail; - } - } - - if (blake2b_update(&S, in, inlen) < 0) { - goto fail; - } - ret = blake2b_final(&S, out, outlen); - -fail: - clear_internal_memory(&S, sizeof(S)); - return ret; -} - -/* Argon2 Team - Begin Code */ -int blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen) { - uint8_t *out = (uint8_t *)pout; - blake2b_state blake_state; - uint8_t outlen_bytes[sizeof(uint32_t)] = {0}; - int ret = -1; - - if (outlen > UINT32_MAX) { - goto fail; - } - - /* Ensure little-endian byte order! */ - store32(outlen_bytes, (uint32_t)outlen); - -#define TRY(statement) \ - do { \ - ret = statement; \ - if (ret < 0) { \ - goto fail; \ - } \ - } while ((void)0, 0) - - if (outlen <= BLAKE2B_OUTBYTES) { - TRY(blake2b_init(&blake_state, outlen)); - TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes))); - TRY(blake2b_update(&blake_state, in, inlen)); - TRY(blake2b_final(&blake_state, out, outlen)); - } else { - uint32_t toproduce; - uint8_t out_buffer[BLAKE2B_OUTBYTES]; - uint8_t in_buffer[BLAKE2B_OUTBYTES]; - TRY(blake2b_init(&blake_state, BLAKE2B_OUTBYTES)); - TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes))); - TRY(blake2b_update(&blake_state, in, inlen)); - TRY(blake2b_final(&blake_state, out_buffer, BLAKE2B_OUTBYTES)); - memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2); - out += BLAKE2B_OUTBYTES / 2; - toproduce = (uint32_t)outlen - BLAKE2B_OUTBYTES / 2; - - while (toproduce > BLAKE2B_OUTBYTES) { - memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES); - TRY(blake2b(out_buffer, BLAKE2B_OUTBYTES, in_buffer, - BLAKE2B_OUTBYTES, NULL, 0)); - memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2); - out += BLAKE2B_OUTBYTES / 2; - toproduce -= BLAKE2B_OUTBYTES / 2; - } - - memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES); - TRY(blake2b(out_buffer, toproduce, in_buffer, BLAKE2B_OUTBYTES, NULL, - 0)); - memcpy(out, out_buffer, toproduce); - } -fail: - clear_internal_memory(&blake_state, sizeof(blake_state)); - return ret; -#undef TRY -} -/* Argon2 Team - End Code */ diff --git a/0x0017a_ctf/third_party/argon2/src/blake2/blamka-round-opt.h b/0x0017a_ctf/third_party/argon2/src/blake2/blamka-round-opt.h deleted file mode 100644 index 3127f2a..0000000 --- a/0x0017a_ctf/third_party/argon2/src/blake2/blamka-round-opt.h +++ /dev/null @@ -1,471 +0,0 @@ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ - -#ifndef BLAKE_ROUND_MKA_OPT_H -#define BLAKE_ROUND_MKA_OPT_H - -#include "blake2-impl.h" - -#include -#if defined(__SSSE3__) -#include /* for _mm_shuffle_epi8 and _mm_alignr_epi8 */ -#endif - -#if defined(__XOP__) && (defined(__GNUC__) || defined(__clang__)) -#include -#endif - -#if !defined(__AVX512F__) -#if !defined(__AVX2__) -#if !defined(__XOP__) -#if defined(__SSSE3__) -#define r16 \ - (_mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9)) -#define r24 \ - (_mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10)) -#define _mm_roti_epi64(x, c) \ - (-(c) == 32) \ - ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \ - : (-(c) == 24) \ - ? _mm_shuffle_epi8((x), r24) \ - : (-(c) == 16) \ - ? _mm_shuffle_epi8((x), r16) \ - : (-(c) == 63) \ - ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ - _mm_add_epi64((x), (x))) \ - : _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ - _mm_slli_epi64((x), 64 - (-(c)))) -#else /* defined(__SSE2__) */ -#define _mm_roti_epi64(r, c) \ - _mm_xor_si128(_mm_srli_epi64((r), -(c)), _mm_slli_epi64((r), 64 - (-(c)))) -#endif -#else -#endif - -static BLAKE2_INLINE __m128i fBlaMka(__m128i x, __m128i y) { - const __m128i z = _mm_mul_epu32(x, y); - return _mm_add_epi64(_mm_add_epi64(x, y), _mm_add_epi64(z, z)); -} - -#define G1(A0, B0, C0, D0, A1, B1, C1, D1) \ - do { \ - A0 = fBlaMka(A0, B0); \ - A1 = fBlaMka(A1, B1); \ - \ - D0 = _mm_xor_si128(D0, A0); \ - D1 = _mm_xor_si128(D1, A1); \ - \ - D0 = _mm_roti_epi64(D0, -32); \ - D1 = _mm_roti_epi64(D1, -32); \ - \ - C0 = fBlaMka(C0, D0); \ - C1 = fBlaMka(C1, D1); \ - \ - B0 = _mm_xor_si128(B0, C0); \ - B1 = _mm_xor_si128(B1, C1); \ - \ - B0 = _mm_roti_epi64(B0, -24); \ - B1 = _mm_roti_epi64(B1, -24); \ - } while ((void)0, 0) - -#define G2(A0, B0, C0, D0, A1, B1, C1, D1) \ - do { \ - A0 = fBlaMka(A0, B0); \ - A1 = fBlaMka(A1, B1); \ - \ - D0 = _mm_xor_si128(D0, A0); \ - D1 = _mm_xor_si128(D1, A1); \ - \ - D0 = _mm_roti_epi64(D0, -16); \ - D1 = _mm_roti_epi64(D1, -16); \ - \ - C0 = fBlaMka(C0, D0); \ - C1 = fBlaMka(C1, D1); \ - \ - B0 = _mm_xor_si128(B0, C0); \ - B1 = _mm_xor_si128(B1, C1); \ - \ - B0 = _mm_roti_epi64(B0, -63); \ - B1 = _mm_roti_epi64(B1, -63); \ - } while ((void)0, 0) - -#if defined(__SSSE3__) -#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ - do { \ - __m128i t0 = _mm_alignr_epi8(B1, B0, 8); \ - __m128i t1 = _mm_alignr_epi8(B0, B1, 8); \ - B0 = t0; \ - B1 = t1; \ - \ - t0 = C0; \ - C0 = C1; \ - C1 = t0; \ - \ - t0 = _mm_alignr_epi8(D1, D0, 8); \ - t1 = _mm_alignr_epi8(D0, D1, 8); \ - D0 = t1; \ - D1 = t0; \ - } while ((void)0, 0) - -#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ - do { \ - __m128i t0 = _mm_alignr_epi8(B0, B1, 8); \ - __m128i t1 = _mm_alignr_epi8(B1, B0, 8); \ - B0 = t0; \ - B1 = t1; \ - \ - t0 = C0; \ - C0 = C1; \ - C1 = t0; \ - \ - t0 = _mm_alignr_epi8(D0, D1, 8); \ - t1 = _mm_alignr_epi8(D1, D0, 8); \ - D0 = t1; \ - D1 = t0; \ - } while ((void)0, 0) -#else /* SSE2 */ -#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ - do { \ - __m128i t0 = D0; \ - __m128i t1 = B0; \ - D0 = C0; \ - C0 = C1; \ - C1 = D0; \ - D0 = _mm_unpackhi_epi64(D1, _mm_unpacklo_epi64(t0, t0)); \ - D1 = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(D1, D1)); \ - B0 = _mm_unpackhi_epi64(B0, _mm_unpacklo_epi64(B1, B1)); \ - B1 = _mm_unpackhi_epi64(B1, _mm_unpacklo_epi64(t1, t1)); \ - } while ((void)0, 0) - -#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ - do { \ - __m128i t0, t1; \ - t0 = C0; \ - C0 = C1; \ - C1 = t0; \ - t0 = B0; \ - t1 = D0; \ - B0 = _mm_unpackhi_epi64(B1, _mm_unpacklo_epi64(B0, B0)); \ - B1 = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(B1, B1)); \ - D0 = _mm_unpackhi_epi64(D0, _mm_unpacklo_epi64(D1, D1)); \ - D1 = _mm_unpackhi_epi64(D1, _mm_unpacklo_epi64(t1, t1)); \ - } while ((void)0, 0) -#endif - -#define BLAKE2_ROUND(A0, A1, B0, B1, C0, C1, D0, D1) \ - do { \ - G1(A0, B0, C0, D0, A1, B1, C1, D1); \ - G2(A0, B0, C0, D0, A1, B1, C1, D1); \ - \ - DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ - \ - G1(A0, B0, C0, D0, A1, B1, C1, D1); \ - G2(A0, B0, C0, D0, A1, B1, C1, D1); \ - \ - UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ - } while ((void)0, 0) -#else /* __AVX2__ */ - -#include - -#define rotr32(x) _mm256_shuffle_epi32(x, _MM_SHUFFLE(2, 3, 0, 1)) -#define rotr24(x) _mm256_shuffle_epi8(x, _mm256_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10, 3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10)) -#define rotr16(x) _mm256_shuffle_epi8(x, _mm256_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9, 2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9)) -#define rotr63(x) _mm256_xor_si256(_mm256_srli_epi64((x), 63), _mm256_add_epi64((x), (x))) - -#define G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ - do { \ - __m256i ml = _mm256_mul_epu32(A0, B0); \ - ml = _mm256_add_epi64(ml, ml); \ - A0 = _mm256_add_epi64(A0, _mm256_add_epi64(B0, ml)); \ - D0 = _mm256_xor_si256(D0, A0); \ - D0 = rotr32(D0); \ - \ - ml = _mm256_mul_epu32(C0, D0); \ - ml = _mm256_add_epi64(ml, ml); \ - C0 = _mm256_add_epi64(C0, _mm256_add_epi64(D0, ml)); \ - \ - B0 = _mm256_xor_si256(B0, C0); \ - B0 = rotr24(B0); \ - \ - ml = _mm256_mul_epu32(A1, B1); \ - ml = _mm256_add_epi64(ml, ml); \ - A1 = _mm256_add_epi64(A1, _mm256_add_epi64(B1, ml)); \ - D1 = _mm256_xor_si256(D1, A1); \ - D1 = rotr32(D1); \ - \ - ml = _mm256_mul_epu32(C1, D1); \ - ml = _mm256_add_epi64(ml, ml); \ - C1 = _mm256_add_epi64(C1, _mm256_add_epi64(D1, ml)); \ - \ - B1 = _mm256_xor_si256(B1, C1); \ - B1 = rotr24(B1); \ - } while((void)0, 0); - -#define G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ - do { \ - __m256i ml = _mm256_mul_epu32(A0, B0); \ - ml = _mm256_add_epi64(ml, ml); \ - A0 = _mm256_add_epi64(A0, _mm256_add_epi64(B0, ml)); \ - D0 = _mm256_xor_si256(D0, A0); \ - D0 = rotr16(D0); \ - \ - ml = _mm256_mul_epu32(C0, D0); \ - ml = _mm256_add_epi64(ml, ml); \ - C0 = _mm256_add_epi64(C0, _mm256_add_epi64(D0, ml)); \ - B0 = _mm256_xor_si256(B0, C0); \ - B0 = rotr63(B0); \ - \ - ml = _mm256_mul_epu32(A1, B1); \ - ml = _mm256_add_epi64(ml, ml); \ - A1 = _mm256_add_epi64(A1, _mm256_add_epi64(B1, ml)); \ - D1 = _mm256_xor_si256(D1, A1); \ - D1 = rotr16(D1); \ - \ - ml = _mm256_mul_epu32(C1, D1); \ - ml = _mm256_add_epi64(ml, ml); \ - C1 = _mm256_add_epi64(C1, _mm256_add_epi64(D1, ml)); \ - B1 = _mm256_xor_si256(B1, C1); \ - B1 = rotr63(B1); \ - } while((void)0, 0); - -#define DIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \ - do { \ - B0 = _mm256_permute4x64_epi64(B0, _MM_SHUFFLE(0, 3, 2, 1)); \ - C0 = _mm256_permute4x64_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \ - D0 = _mm256_permute4x64_epi64(D0, _MM_SHUFFLE(2, 1, 0, 3)); \ - \ - B1 = _mm256_permute4x64_epi64(B1, _MM_SHUFFLE(0, 3, 2, 1)); \ - C1 = _mm256_permute4x64_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \ - D1 = _mm256_permute4x64_epi64(D1, _MM_SHUFFLE(2, 1, 0, 3)); \ - } while((void)0, 0); - -#define DIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \ - do { \ - __m256i tmp1 = _mm256_blend_epi32(B0, B1, 0xCC); \ - __m256i tmp2 = _mm256_blend_epi32(B0, B1, 0x33); \ - B1 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \ - B0 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \ - \ - tmp1 = C0; \ - C0 = C1; \ - C1 = tmp1; \ - \ - tmp1 = _mm256_blend_epi32(D0, D1, 0xCC); \ - tmp2 = _mm256_blend_epi32(D0, D1, 0x33); \ - D0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \ - D1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \ - } while(0); - -#define UNDIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \ - do { \ - B0 = _mm256_permute4x64_epi64(B0, _MM_SHUFFLE(2, 1, 0, 3)); \ - C0 = _mm256_permute4x64_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \ - D0 = _mm256_permute4x64_epi64(D0, _MM_SHUFFLE(0, 3, 2, 1)); \ - \ - B1 = _mm256_permute4x64_epi64(B1, _MM_SHUFFLE(2, 1, 0, 3)); \ - C1 = _mm256_permute4x64_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \ - D1 = _mm256_permute4x64_epi64(D1, _MM_SHUFFLE(0, 3, 2, 1)); \ - } while((void)0, 0); - -#define UNDIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \ - do { \ - __m256i tmp1 = _mm256_blend_epi32(B0, B1, 0xCC); \ - __m256i tmp2 = _mm256_blend_epi32(B0, B1, 0x33); \ - B0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \ - B1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \ - \ - tmp1 = C0; \ - C0 = C1; \ - C1 = tmp1; \ - \ - tmp1 = _mm256_blend_epi32(D0, D1, 0x33); \ - tmp2 = _mm256_blend_epi32(D0, D1, 0xCC); \ - D0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \ - D1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \ - } while((void)0, 0); - -#define BLAKE2_ROUND_1(A0, A1, B0, B1, C0, C1, D0, D1) \ - do{ \ - G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ - G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ - \ - DIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \ - \ - G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ - G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ - \ - UNDIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \ - } while((void)0, 0); - -#define BLAKE2_ROUND_2(A0, A1, B0, B1, C0, C1, D0, D1) \ - do{ \ - G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ - G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ - \ - DIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \ - \ - G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ - G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ - \ - UNDIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \ - } while((void)0, 0); - -#endif /* __AVX2__ */ - -#else /* __AVX512F__ */ - -#include - -#define ror64(x, n) _mm512_ror_epi64((x), (n)) - -static __m512i muladd(__m512i x, __m512i y) -{ - __m512i z = _mm512_mul_epu32(x, y); - return _mm512_add_epi64(_mm512_add_epi64(x, y), _mm512_add_epi64(z, z)); -} - -#define G1(A0, B0, C0, D0, A1, B1, C1, D1) \ - do { \ - A0 = muladd(A0, B0); \ - A1 = muladd(A1, B1); \ -\ - D0 = _mm512_xor_si512(D0, A0); \ - D1 = _mm512_xor_si512(D1, A1); \ -\ - D0 = ror64(D0, 32); \ - D1 = ror64(D1, 32); \ -\ - C0 = muladd(C0, D0); \ - C1 = muladd(C1, D1); \ -\ - B0 = _mm512_xor_si512(B0, C0); \ - B1 = _mm512_xor_si512(B1, C1); \ -\ - B0 = ror64(B0, 24); \ - B1 = ror64(B1, 24); \ - } while ((void)0, 0) - -#define G2(A0, B0, C0, D0, A1, B1, C1, D1) \ - do { \ - A0 = muladd(A0, B0); \ - A1 = muladd(A1, B1); \ -\ - D0 = _mm512_xor_si512(D0, A0); \ - D1 = _mm512_xor_si512(D1, A1); \ -\ - D0 = ror64(D0, 16); \ - D1 = ror64(D1, 16); \ -\ - C0 = muladd(C0, D0); \ - C1 = muladd(C1, D1); \ -\ - B0 = _mm512_xor_si512(B0, C0); \ - B1 = _mm512_xor_si512(B1, C1); \ -\ - B0 = ror64(B0, 63); \ - B1 = ror64(B1, 63); \ - } while ((void)0, 0) - -#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ - do { \ - B0 = _mm512_permutex_epi64(B0, _MM_SHUFFLE(0, 3, 2, 1)); \ - B1 = _mm512_permutex_epi64(B1, _MM_SHUFFLE(0, 3, 2, 1)); \ -\ - C0 = _mm512_permutex_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \ - C1 = _mm512_permutex_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \ -\ - D0 = _mm512_permutex_epi64(D0, _MM_SHUFFLE(2, 1, 0, 3)); \ - D1 = _mm512_permutex_epi64(D1, _MM_SHUFFLE(2, 1, 0, 3)); \ - } while ((void)0, 0) - -#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ - do { \ - B0 = _mm512_permutex_epi64(B0, _MM_SHUFFLE(2, 1, 0, 3)); \ - B1 = _mm512_permutex_epi64(B1, _MM_SHUFFLE(2, 1, 0, 3)); \ -\ - C0 = _mm512_permutex_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \ - C1 = _mm512_permutex_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \ -\ - D0 = _mm512_permutex_epi64(D0, _MM_SHUFFLE(0, 3, 2, 1)); \ - D1 = _mm512_permutex_epi64(D1, _MM_SHUFFLE(0, 3, 2, 1)); \ - } while ((void)0, 0) - -#define BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1) \ - do { \ - G1(A0, B0, C0, D0, A1, B1, C1, D1); \ - G2(A0, B0, C0, D0, A1, B1, C1, D1); \ -\ - DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ -\ - G1(A0, B0, C0, D0, A1, B1, C1, D1); \ - G2(A0, B0, C0, D0, A1, B1, C1, D1); \ -\ - UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ - } while ((void)0, 0) - -#define SWAP_HALVES(A0, A1) \ - do { \ - __m512i t0, t1; \ - t0 = _mm512_shuffle_i64x2(A0, A1, _MM_SHUFFLE(1, 0, 1, 0)); \ - t1 = _mm512_shuffle_i64x2(A0, A1, _MM_SHUFFLE(3, 2, 3, 2)); \ - A0 = t0; \ - A1 = t1; \ - } while((void)0, 0) - -#define SWAP_QUARTERS(A0, A1) \ - do { \ - SWAP_HALVES(A0, A1); \ - A0 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A0); \ - A1 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A1); \ - } while((void)0, 0) - -#define UNSWAP_QUARTERS(A0, A1) \ - do { \ - A0 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A0); \ - A1 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A1); \ - SWAP_HALVES(A0, A1); \ - } while((void)0, 0) - -#define BLAKE2_ROUND_1(A0, C0, B0, D0, A1, C1, B1, D1) \ - do { \ - SWAP_HALVES(A0, B0); \ - SWAP_HALVES(C0, D0); \ - SWAP_HALVES(A1, B1); \ - SWAP_HALVES(C1, D1); \ - BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1); \ - SWAP_HALVES(A0, B0); \ - SWAP_HALVES(C0, D0); \ - SWAP_HALVES(A1, B1); \ - SWAP_HALVES(C1, D1); \ - } while ((void)0, 0) - -#define BLAKE2_ROUND_2(A0, A1, B0, B1, C0, C1, D0, D1) \ - do { \ - SWAP_QUARTERS(A0, A1); \ - SWAP_QUARTERS(B0, B1); \ - SWAP_QUARTERS(C0, C1); \ - SWAP_QUARTERS(D0, D1); \ - BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1); \ - UNSWAP_QUARTERS(A0, A1); \ - UNSWAP_QUARTERS(B0, B1); \ - UNSWAP_QUARTERS(C0, C1); \ - UNSWAP_QUARTERS(D0, D1); \ - } while ((void)0, 0) - -#endif /* __AVX512F__ */ -#endif /* BLAKE_ROUND_MKA_OPT_H */ diff --git a/0x0017a_ctf/third_party/argon2/src/blake2/blamka-round-ref.h b/0x0017a_ctf/third_party/argon2/src/blake2/blamka-round-ref.h deleted file mode 100644 index 16cfc1c..0000000 --- a/0x0017a_ctf/third_party/argon2/src/blake2/blamka-round-ref.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ - -#ifndef BLAKE_ROUND_MKA_H -#define BLAKE_ROUND_MKA_H - -#include "blake2.h" -#include "blake2-impl.h" - -/* designed by the Lyra PHC team */ -static BLAKE2_INLINE uint64_t fBlaMka(uint64_t x, uint64_t y) { - const uint64_t m = UINT64_C(0xFFFFFFFF); - const uint64_t xy = (x & m) * (y & m); - return x + y + 2 * xy; -} - -#define G(a, b, c, d) \ - do { \ - a = fBlaMka(a, b); \ - d = rotr64(d ^ a, 32); \ - c = fBlaMka(c, d); \ - b = rotr64(b ^ c, 24); \ - a = fBlaMka(a, b); \ - d = rotr64(d ^ a, 16); \ - c = fBlaMka(c, d); \ - b = rotr64(b ^ c, 63); \ - } while ((void)0, 0) - -#define BLAKE2_ROUND_NOMSG(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, \ - v12, v13, v14, v15) \ - do { \ - G(v0, v4, v8, v12); \ - G(v1, v5, v9, v13); \ - G(v2, v6, v10, v14); \ - G(v3, v7, v11, v15); \ - G(v0, v5, v10, v15); \ - G(v1, v6, v11, v12); \ - G(v2, v7, v8, v13); \ - G(v3, v4, v9, v14); \ - } while ((void)0, 0) - -#endif diff --git a/0x0017a_ctf/third_party/argon2/src/core.c b/0x0017a_ctf/third_party/argon2/src/core.c deleted file mode 100644 index e697882..0000000 --- a/0x0017a_ctf/third_party/argon2/src/core.c +++ /dev/null @@ -1,648 +0,0 @@ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ - -/*For memory wiping*/ -#ifdef _WIN32 -#include -#include /* For SecureZeroMemory */ -#endif -#if defined __STDC_LIB_EXT1__ -#define __STDC_WANT_LIB_EXT1__ 1 -#endif -#define VC_GE_2005(version) (version >= 1400) - -/* for explicit_bzero() on glibc */ -#define _DEFAULT_SOURCE - -#include -#include -#include - -#include "core.h" -#include "thread.h" -#include "blake2/blake2.h" -#include "blake2/blake2-impl.h" - -#ifdef GENKAT -#include "genkat.h" -#endif - -#if defined(__clang__) -#if __has_attribute(optnone) -#define NOT_OPTIMIZED __attribute__((optnone)) -#endif -#elif defined(__GNUC__) -#define GCC_VERSION \ - (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -#if GCC_VERSION >= 40400 -#define NOT_OPTIMIZED __attribute__((optimize("O0"))) -#endif -#endif -#ifndef NOT_OPTIMIZED -#define NOT_OPTIMIZED -#endif - -/***************Instance and Position constructors**********/ -void init_block_value(block *b, uint8_t in) { memset(b->v, in, sizeof(b->v)); } - -void copy_block(block *dst, const block *src) { - memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_QWORDS_IN_BLOCK); -} - -void xor_block(block *dst, const block *src) { - int i; - for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { - dst->v[i] ^= src->v[i]; - } -} - -static void load_block(block *dst, const void *input) { - unsigned i; - for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { - dst->v[i] = load64((const uint8_t *)input + i * sizeof(dst->v[i])); - } -} - -static void store_block(void *output, const block *src) { - unsigned i; - for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { - store64((uint8_t *)output + i * sizeof(src->v[i]), src->v[i]); - } -} - -/***************Memory functions*****************/ - -int allocate_memory(const argon2_context *context, uint8_t **memory, - size_t num, size_t size) { - size_t memory_size = num*size; - if (memory == NULL) { - return ARGON2_MEMORY_ALLOCATION_ERROR; - } - - /* 1. Check for multiplication overflow */ - if (size != 0 && memory_size / size != num) { - return ARGON2_MEMORY_ALLOCATION_ERROR; - } - - /* 2. Try to allocate with appropriate allocator */ - if (context->allocate_cbk) { - (context->allocate_cbk)(memory, memory_size); - } else { - *memory = malloc(memory_size); - } - - if (*memory == NULL) { - return ARGON2_MEMORY_ALLOCATION_ERROR; - } - - return ARGON2_OK; -} - -void free_memory(const argon2_context *context, uint8_t *memory, - size_t num, size_t size) { - size_t memory_size = num*size; - clear_internal_memory(memory, memory_size); - if (context->free_cbk) { - (context->free_cbk)(memory, memory_size); - } else { - free(memory); - } -} - -#if defined(__OpenBSD__) -#define HAVE_EXPLICIT_BZERO 1 -#elif defined(__GLIBC__) && defined(__GLIBC_PREREQ) -#if __GLIBC_PREREQ(2,25) -#define HAVE_EXPLICIT_BZERO 1 -#endif -#endif - -void NOT_OPTIMIZED secure_wipe_memory(void *v, size_t n) { -#if defined(_MSC_VER) && VC_GE_2005(_MSC_VER) || defined(__MINGW32__) - SecureZeroMemory(v, n); -#elif defined memset_s - memset_s(v, n, 0, n); -#elif defined(HAVE_EXPLICIT_BZERO) - explicit_bzero(v, n); -#else - static void *(*const volatile memset_sec)(void *, int, size_t) = &memset; - memset_sec(v, 0, n); -#endif -} - -/* Memory clear flag defaults to true. */ -int FLAG_clear_internal_memory = 1; -void clear_internal_memory(void *v, size_t n) { - if (FLAG_clear_internal_memory && v) { - secure_wipe_memory(v, n); - } -} - -void finalize(const argon2_context *context, argon2_instance_t *instance) { - if (context != NULL && instance != NULL) { - block blockhash; - uint32_t l; - - copy_block(&blockhash, instance->memory + instance->lane_length - 1); - - /* XOR the last blocks */ - for (l = 1; l < instance->lanes; ++l) { - uint32_t last_block_in_lane = - l * instance->lane_length + (instance->lane_length - 1); - xor_block(&blockhash, instance->memory + last_block_in_lane); - } - - /* Hash the result */ - { - uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE]; - store_block(blockhash_bytes, &blockhash); - blake2b_long(context->out, context->outlen, blockhash_bytes, - ARGON2_BLOCK_SIZE); - /* clear blockhash and blockhash_bytes */ - clear_internal_memory(blockhash.v, ARGON2_BLOCK_SIZE); - clear_internal_memory(blockhash_bytes, ARGON2_BLOCK_SIZE); - } - -#ifdef GENKAT - print_tag(context->out, context->outlen); -#endif - - free_memory(context, (uint8_t *)instance->memory, - instance->memory_blocks, sizeof(block)); - } -} - -uint32_t index_alpha(const argon2_instance_t *instance, - const argon2_position_t *position, uint32_t pseudo_rand, - int same_lane) { - /* - * Pass 0: - * This lane : all already finished segments plus already constructed - * blocks in this segment - * Other lanes : all already finished segments - * Pass 1+: - * This lane : (SYNC_POINTS - 1) last segments plus already constructed - * blocks in this segment - * Other lanes : (SYNC_POINTS - 1) last segments - */ - uint32_t reference_area_size; - uint64_t relative_position; - uint32_t start_position, absolute_position; - - if (0 == position->pass) { - /* First pass */ - if (0 == position->slice) { - /* First slice */ - reference_area_size = - position->index - 1; /* all but the previous */ - } else { - if (same_lane) { - /* The same lane => add current segment */ - reference_area_size = - position->slice * instance->segment_length + - position->index - 1; - } else { - reference_area_size = - position->slice * instance->segment_length + - ((position->index == 0) ? (-1) : 0); - } - } - } else { - /* Second pass */ - if (same_lane) { - reference_area_size = instance->lane_length - - instance->segment_length + position->index - - 1; - } else { - reference_area_size = instance->lane_length - - instance->segment_length + - ((position->index == 0) ? (-1) : 0); - } - } - - /* 1.2.4. Mapping pseudo_rand to 0.. and produce - * relative position */ - relative_position = pseudo_rand; - relative_position = relative_position * relative_position >> 32; - relative_position = reference_area_size - 1 - - (reference_area_size * relative_position >> 32); - - /* 1.2.5 Computing starting position */ - start_position = 0; - - if (0 != position->pass) { - start_position = (position->slice == ARGON2_SYNC_POINTS - 1) - ? 0 - : (position->slice + 1) * instance->segment_length; - } - - /* 1.2.6. Computing absolute position */ - absolute_position = (start_position + relative_position) % - instance->lane_length; /* absolute position */ - return absolute_position; -} - -/* Single-threaded version for p=1 case */ -static int fill_memory_blocks_st(argon2_instance_t *instance) { - uint32_t r, s, l; - - for (r = 0; r < instance->passes; ++r) { - for (s = 0; s < ARGON2_SYNC_POINTS; ++s) { - for (l = 0; l < instance->lanes; ++l) { - argon2_position_t position = {r, l, (uint8_t)s, 0}; - fill_segment(instance, position); - } - } -#ifdef GENKAT - internal_kat(instance, r); /* Print all memory blocks */ -#endif - } - return ARGON2_OK; -} - -#if !defined(ARGON2_NO_THREADS) - -#ifdef _WIN32 -static unsigned __stdcall fill_segment_thr(void *thread_data) -#else -static void *fill_segment_thr(void *thread_data) -#endif -{ - argon2_thread_data *my_data = thread_data; - fill_segment(my_data->instance_ptr, my_data->pos); - argon2_thread_exit(); - return 0; -} - -/* Multi-threaded version for p > 1 case */ -static int fill_memory_blocks_mt(argon2_instance_t *instance) { - uint32_t r, s; - argon2_thread_handle_t *thread = NULL; - argon2_thread_data *thr_data = NULL; - int rc = ARGON2_OK; - - /* 1. Allocating space for threads */ - thread = calloc(instance->lanes, sizeof(argon2_thread_handle_t)); - if (thread == NULL) { - rc = ARGON2_MEMORY_ALLOCATION_ERROR; - goto fail; - } - - thr_data = calloc(instance->lanes, sizeof(argon2_thread_data)); - if (thr_data == NULL) { - rc = ARGON2_MEMORY_ALLOCATION_ERROR; - goto fail; - } - - for (r = 0; r < instance->passes; ++r) { - for (s = 0; s < ARGON2_SYNC_POINTS; ++s) { - uint32_t l, ll; - - /* 2. Calling threads */ - for (l = 0; l < instance->lanes; ++l) { - argon2_position_t position; - - /* 2.1 Join a thread if limit is exceeded */ - if (l >= instance->threads) { - if (argon2_thread_join(thread[l - instance->threads])) { - rc = ARGON2_THREAD_FAIL; - goto fail; - } - } - - /* 2.2 Create thread */ - position.pass = r; - position.lane = l; - position.slice = (uint8_t)s; - position.index = 0; - thr_data[l].instance_ptr = - instance; /* preparing the thread input */ - memcpy(&(thr_data[l].pos), &position, - sizeof(argon2_position_t)); - if (argon2_thread_create(&thread[l], &fill_segment_thr, - (void *)&thr_data[l])) { - /* Wait for already running threads */ - for (ll = 0; ll < l; ++ll) - argon2_thread_join(thread[ll]); - rc = ARGON2_THREAD_FAIL; - goto fail; - } - - /* fill_segment(instance, position); */ - /*Non-thread equivalent of the lines above */ - } - - /* 3. Joining remaining threads */ - for (l = instance->lanes - instance->threads; l < instance->lanes; - ++l) { - if (argon2_thread_join(thread[l])) { - rc = ARGON2_THREAD_FAIL; - goto fail; - } - } - } - -#ifdef GENKAT - internal_kat(instance, r); /* Print all memory blocks */ -#endif - } - -fail: - if (thread != NULL) { - free(thread); - } - if (thr_data != NULL) { - free(thr_data); - } - return rc; -} - -#endif /* ARGON2_NO_THREADS */ - -int fill_memory_blocks(argon2_instance_t *instance) { - if (instance == NULL || instance->lanes == 0) { - return ARGON2_INCORRECT_PARAMETER; - } -#if defined(ARGON2_NO_THREADS) - return fill_memory_blocks_st(instance); -#else - return instance->threads == 1 ? - fill_memory_blocks_st(instance) : fill_memory_blocks_mt(instance); -#endif -} - -int validate_inputs(const argon2_context *context) { - if (NULL == context) { - return ARGON2_INCORRECT_PARAMETER; - } - - if (NULL == context->out) { - return ARGON2_OUTPUT_PTR_NULL; - } - - /* Validate output length */ - if (ARGON2_MIN_OUTLEN > context->outlen) { - return ARGON2_OUTPUT_TOO_SHORT; - } - - if (ARGON2_MAX_OUTLEN < context->outlen) { - return ARGON2_OUTPUT_TOO_LONG; - } - - /* Validate password (required param) */ - if (NULL == context->pwd) { - if (0 != context->pwdlen) { - return ARGON2_PWD_PTR_MISMATCH; - } - } - - if (ARGON2_MIN_PWD_LENGTH > context->pwdlen) { - return ARGON2_PWD_TOO_SHORT; - } - - if (ARGON2_MAX_PWD_LENGTH < context->pwdlen) { - return ARGON2_PWD_TOO_LONG; - } - - /* Validate salt (required param) */ - if (NULL == context->salt) { - if (0 != context->saltlen) { - return ARGON2_SALT_PTR_MISMATCH; - } - } - - if (ARGON2_MIN_SALT_LENGTH > context->saltlen) { - return ARGON2_SALT_TOO_SHORT; - } - - if (ARGON2_MAX_SALT_LENGTH < context->saltlen) { - return ARGON2_SALT_TOO_LONG; - } - - /* Validate secret (optional param) */ - if (NULL == context->secret) { - if (0 != context->secretlen) { - return ARGON2_SECRET_PTR_MISMATCH; - } - } else { - if (ARGON2_MIN_SECRET > context->secretlen) { - return ARGON2_SECRET_TOO_SHORT; - } - if (ARGON2_MAX_SECRET < context->secretlen) { - return ARGON2_SECRET_TOO_LONG; - } - } - - /* Validate associated data (optional param) */ - if (NULL == context->ad) { - if (0 != context->adlen) { - return ARGON2_AD_PTR_MISMATCH; - } - } else { - if (ARGON2_MIN_AD_LENGTH > context->adlen) { - return ARGON2_AD_TOO_SHORT; - } - if (ARGON2_MAX_AD_LENGTH < context->adlen) { - return ARGON2_AD_TOO_LONG; - } - } - - /* Validate memory cost */ - if (ARGON2_MIN_MEMORY > context->m_cost) { - return ARGON2_MEMORY_TOO_LITTLE; - } - - if (ARGON2_MAX_MEMORY < context->m_cost) { - return ARGON2_MEMORY_TOO_MUCH; - } - - if (context->m_cost < 8 * context->lanes) { - return ARGON2_MEMORY_TOO_LITTLE; - } - - /* Validate time cost */ - if (ARGON2_MIN_TIME > context->t_cost) { - return ARGON2_TIME_TOO_SMALL; - } - - if (ARGON2_MAX_TIME < context->t_cost) { - return ARGON2_TIME_TOO_LARGE; - } - - /* Validate lanes */ - if (ARGON2_MIN_LANES > context->lanes) { - return ARGON2_LANES_TOO_FEW; - } - - if (ARGON2_MAX_LANES < context->lanes) { - return ARGON2_LANES_TOO_MANY; - } - - /* Validate threads */ - if (ARGON2_MIN_THREADS > context->threads) { - return ARGON2_THREADS_TOO_FEW; - } - - if (ARGON2_MAX_THREADS < context->threads) { - return ARGON2_THREADS_TOO_MANY; - } - - if (NULL != context->allocate_cbk && NULL == context->free_cbk) { - return ARGON2_FREE_MEMORY_CBK_NULL; - } - - if (NULL == context->allocate_cbk && NULL != context->free_cbk) { - return ARGON2_ALLOCATE_MEMORY_CBK_NULL; - } - - return ARGON2_OK; -} - -void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) { - uint32_t l; - /* Make the first and second block in each lane as G(H0||0||i) or - G(H0||1||i) */ - uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE]; - for (l = 0; l < instance->lanes; ++l) { - - store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0); - store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, l); - blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash, - ARGON2_PREHASH_SEED_LENGTH); - load_block(&instance->memory[l * instance->lane_length + 0], - blockhash_bytes); - - store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 1); - blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash, - ARGON2_PREHASH_SEED_LENGTH); - load_block(&instance->memory[l * instance->lane_length + 1], - blockhash_bytes); - } - clear_internal_memory(blockhash_bytes, ARGON2_BLOCK_SIZE); -} - -void initial_hash(uint8_t *blockhash, argon2_context *context, - argon2_type type) { - blake2b_state BlakeHash; - uint8_t value[sizeof(uint32_t)]; - - if (NULL == context || NULL == blockhash) { - return; - } - - blake2b_init(&BlakeHash, ARGON2_PREHASH_DIGEST_LENGTH); - - store32(&value, context->lanes); - blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); - - store32(&value, context->outlen); - blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); - - store32(&value, context->m_cost); - blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); - - store32(&value, context->t_cost); - blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); - - store32(&value, context->version); - blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); - - store32(&value, (uint32_t)type); - blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); - - store32(&value, context->pwdlen); - blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); - - if (context->pwd != NULL) { - blake2b_update(&BlakeHash, (const uint8_t *)context->pwd, - context->pwdlen); - - if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) { - secure_wipe_memory(context->pwd, context->pwdlen); - context->pwdlen = 0; - } - } - - store32(&value, context->saltlen); - blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); - - if (context->salt != NULL) { - blake2b_update(&BlakeHash, (const uint8_t *)context->salt, - context->saltlen); - } - - store32(&value, context->secretlen); - blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); - - if (context->secret != NULL) { - blake2b_update(&BlakeHash, (const uint8_t *)context->secret, - context->secretlen); - - if (context->flags & ARGON2_FLAG_CLEAR_SECRET) { - secure_wipe_memory(context->secret, context->secretlen); - context->secretlen = 0; - } - } - - store32(&value, context->adlen); - blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); - - if (context->ad != NULL) { - blake2b_update(&BlakeHash, (const uint8_t *)context->ad, - context->adlen); - } - - blake2b_final(&BlakeHash, blockhash, ARGON2_PREHASH_DIGEST_LENGTH); -} - -int initialize(argon2_instance_t *instance, argon2_context *context) { - uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; - int result = ARGON2_OK; - - if (instance == NULL || context == NULL) - return ARGON2_INCORRECT_PARAMETER; - instance->context_ptr = context; - - /* 1. Memory allocation */ - result = allocate_memory(context, (uint8_t **)&(instance->memory), - instance->memory_blocks, sizeof(block)); - if (result != ARGON2_OK) { - return result; - } - - /* 2. Initial hashing */ - /* H_0 + 8 extra bytes to produce the first blocks */ - /* uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; */ - /* Hashing all inputs */ - initial_hash(blockhash, context, instance->type); - /* Zeroing 8 extra bytes */ - clear_internal_memory(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, - ARGON2_PREHASH_SEED_LENGTH - - ARGON2_PREHASH_DIGEST_LENGTH); - -#ifdef GENKAT - initial_kat(blockhash, context, instance->type); -#endif - - /* 3. Creating first blocks, we always have at least two blocks in a slice - */ - fill_first_blocks(blockhash, instance); - /* Clearing the hash */ - clear_internal_memory(blockhash, ARGON2_PREHASH_SEED_LENGTH); - - return ARGON2_OK; -} diff --git a/0x0017a_ctf/third_party/argon2/src/core.h b/0x0017a_ctf/third_party/argon2/src/core.h deleted file mode 100644 index 59e2564..0000000 --- a/0x0017a_ctf/third_party/argon2/src/core.h +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ - -#ifndef ARGON2_CORE_H -#define ARGON2_CORE_H - -#include "argon2.h" - -#define CONST_CAST(x) (x)(uintptr_t) - -/**********************Argon2 internal constants*******************************/ - -enum argon2_core_constants { - /* Memory block size in bytes */ - ARGON2_BLOCK_SIZE = 1024, - ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8, - ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16, - ARGON2_HWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 32, - ARGON2_512BIT_WORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 64, - - /* Number of pseudo-random values generated by one call to Blake in Argon2i - to - generate reference block positions */ - ARGON2_ADDRESSES_IN_BLOCK = 128, - - /* Pre-hashing digest length and its extension*/ - ARGON2_PREHASH_DIGEST_LENGTH = 64, - ARGON2_PREHASH_SEED_LENGTH = 72 -}; - -/*************************Argon2 internal data types***********************/ - -/* - * Structure for the (1KB) memory block implemented as 128 64-bit words. - * Memory blocks can be copied, XORed. Internal words can be accessed by [] (no - * bounds checking). - */ -typedef struct block_ { uint64_t v[ARGON2_QWORDS_IN_BLOCK]; } block; - -/*****************Functions that work with the block******************/ - -/* Initialize each byte of the block with @in */ -void init_block_value(block *b, uint8_t in); - -/* Copy block @src to block @dst */ -void copy_block(block *dst, const block *src); - -/* XOR @src onto @dst bytewise */ -void xor_block(block *dst, const block *src); - -/* - * Argon2 instance: memory pointer, number of passes, amount of memory, type, - * and derived values. - * Used to evaluate the number and location of blocks to construct in each - * thread - */ -typedef struct Argon2_instance_t { - block *memory; /* Memory pointer */ - uint32_t version; - uint32_t passes; /* Number of passes */ - uint32_t memory_blocks; /* Number of blocks in memory */ - uint32_t segment_length; - uint32_t lane_length; - uint32_t lanes; - uint32_t threads; - argon2_type type; - int print_internals; /* whether to print the memory blocks */ - argon2_context *context_ptr; /* points back to original context */ -} argon2_instance_t; - -/* - * Argon2 position: where we construct the block right now. Used to distribute - * work between threads. - */ -typedef struct Argon2_position_t { - uint32_t pass; - uint32_t lane; - uint8_t slice; - uint32_t index; -} argon2_position_t; - -/*Struct that holds the inputs for thread handling FillSegment*/ -typedef struct Argon2_thread_data { - argon2_instance_t *instance_ptr; - argon2_position_t pos; -} argon2_thread_data; - -/*************************Argon2 core functions********************************/ - -/* Allocates memory to the given pointer, uses the appropriate allocator as - * specified in the context. Total allocated memory is num*size. - * @param context argon2_context which specifies the allocator - * @param memory pointer to the pointer to the memory - * @param size the size in bytes for each element to be allocated - * @param num the number of elements to be allocated - * @return ARGON2_OK if @memory is a valid pointer and memory is allocated - */ -int allocate_memory(const argon2_context *context, uint8_t **memory, - size_t num, size_t size); - -/* - * Frees memory at the given pointer, uses the appropriate deallocator as - * specified in the context. Also cleans the memory using clear_internal_memory. - * @param context argon2_context which specifies the deallocator - * @param memory pointer to buffer to be freed - * @param size the size in bytes for each element to be deallocated - * @param num the number of elements to be deallocated - */ -void free_memory(const argon2_context *context, uint8_t *memory, - size_t num, size_t size); - -/* Function that securely cleans the memory. This ignores any flags set - * regarding clearing memory. Usually one just calls clear_internal_memory. - * @param mem Pointer to the memory - * @param s Memory size in bytes - */ -void secure_wipe_memory(void *v, size_t n); - -/* Function that securely clears the memory if FLAG_clear_internal_memory is - * set. If the flag isn't set, this function does nothing. - * @param mem Pointer to the memory - * @param s Memory size in bytes - */ -void clear_internal_memory(void *v, size_t n); - -/* - * Computes absolute position of reference block in the lane following a skewed - * distribution and using a pseudo-random value as input - * @param instance Pointer to the current instance - * @param position Pointer to the current position - * @param pseudo_rand 32-bit pseudo-random value used to determine the position - * @param same_lane Indicates if the block will be taken from the current lane. - * If so we can reference the current segment - * @pre All pointers must be valid - */ -uint32_t index_alpha(const argon2_instance_t *instance, - const argon2_position_t *position, uint32_t pseudo_rand, - int same_lane); - -/* - * Function that validates all inputs against predefined restrictions and return - * an error code - * @param context Pointer to current Argon2 context - * @return ARGON2_OK if everything is all right, otherwise one of error codes - * (all defined in - */ -int validate_inputs(const argon2_context *context); - -/* - * Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH], clears - * password and secret if needed - * @param context Pointer to the Argon2 internal structure containing memory - * pointer, and parameters for time and space requirements. - * @param blockhash Buffer for pre-hashing digest - * @param type Argon2 type - * @pre @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes - * allocated - */ -void initial_hash(uint8_t *blockhash, argon2_context *context, - argon2_type type); - -/* - * Function creates first 2 blocks per lane - * @param instance Pointer to the current instance - * @param blockhash Pointer to the pre-hashing digest - * @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values - */ -void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance); - -/* - * Function allocates memory, hashes the inputs with Blake, and creates first - * two blocks. Returns the pointer to the main memory with 2 blocks per lane - * initialized - * @param context Pointer to the Argon2 internal structure containing memory - * pointer, and parameters for time and space requirements. - * @param instance Current Argon2 instance - * @return Zero if successful, -1 if memory failed to allocate. @context->state - * will be modified if successful. - */ -int initialize(argon2_instance_t *instance, argon2_context *context); - -/* - * XORing the last block of each lane, hashing it, making the tag. Deallocates - * the memory. - * @param context Pointer to current Argon2 context (use only the out parameters - * from it) - * @param instance Pointer to current instance of Argon2 - * @pre instance->state must point to necessary amount of memory - * @pre context->out must point to outlen bytes of memory - * @pre if context->free_cbk is not NULL, it should point to a function that - * deallocates memory - */ -void finalize(const argon2_context *context, argon2_instance_t *instance); - -/* - * Function that fills the segment using previous segments also from other - * threads - * @param context current context - * @param instance Pointer to the current instance - * @param position Current position - * @pre all block pointers must be valid - */ -void fill_segment(const argon2_instance_t *instance, - argon2_position_t position); - -/* - * Function that fills the entire memory t_cost times based on the first two - * blocks in each lane - * @param instance Pointer to the current instance - * @return ARGON2_OK if successful, @context->state - */ -int fill_memory_blocks(argon2_instance_t *instance); - -#endif diff --git a/0x0017a_ctf/third_party/argon2/src/encoding.c b/0x0017a_ctf/third_party/argon2/src/encoding.c deleted file mode 100644 index 771a440..0000000 --- a/0x0017a_ctf/third_party/argon2/src/encoding.c +++ /dev/null @@ -1,463 +0,0 @@ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ - -#include -#include -#include -#include -#include "encoding.h" -#include "core.h" - -/* - * Example code for a decoder and encoder of "hash strings", with Argon2 - * parameters. - * - * This code comprises three sections: - * - * -- The first section contains generic Base64 encoding and decoding - * functions. It is conceptually applicable to any hash function - * implementation that uses Base64 to encode and decode parameters, - * salts and outputs. It could be made into a library, provided that - * the relevant functions are made public (non-static) and be given - * reasonable names to avoid collisions with other functions. - * - * -- The second section is specific to Argon2. It encodes and decodes - * the parameters, salts and outputs. It does not compute the hash - * itself. - * - * The code was originally written by Thomas Pornin , - * to whom comments and remarks may be sent. It is released under what - * should amount to Public Domain or its closest equivalent; the - * following mantra is supposed to incarnate that fact with all the - * proper legal rituals: - * - * --------------------------------------------------------------------- - * This file is provided under the terms of Creative Commons CC0 1.0 - * Public Domain Dedication. To the extent possible under law, the - * author (Thomas Pornin) has waived all copyright and related or - * neighboring rights to this file. This work is published from: Canada. - * --------------------------------------------------------------------- - * - * Copyright (c) 2015 Thomas Pornin - */ - -/* ==================================================================== */ -/* - * Common code; could be shared between different hash functions. - * - * Note: the Base64 functions below assume that uppercase letters (resp. - * lowercase letters) have consecutive numerical codes, that fit on 8 - * bits. All modern systems use ASCII-compatible charsets, where these - * properties are true. If you are stuck with a dinosaur of a system - * that still defaults to EBCDIC then you already have much bigger - * interoperability issues to deal with. - */ - -/* - * Some macros for constant-time comparisons. These work over values in - * the 0..255 range. Returned value is 0x00 on "false", 0xFF on "true". - */ -#define EQ(x, y) ((((0U - ((unsigned)(x) ^ (unsigned)(y))) >> 8) & 0xFF) ^ 0xFF) -#define GT(x, y) ((((unsigned)(y) - (unsigned)(x)) >> 8) & 0xFF) -#define GE(x, y) (GT(y, x) ^ 0xFF) -#define LT(x, y) GT(y, x) -#define LE(x, y) GE(y, x) - -/* - * Convert value x (0..63) to corresponding Base64 character. - */ -static int b64_byte_to_char(unsigned x) { - return (LT(x, 26) & (x + 'A')) | - (GE(x, 26) & LT(x, 52) & (x + ('a' - 26))) | - (GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '+') | - (EQ(x, 63) & '/'); -} - -/* - * Convert character c to the corresponding 6-bit value. If character c - * is not a Base64 character, then 0xFF (255) is returned. - */ -static unsigned b64_char_to_byte(int c) { - unsigned x; - - x = (GE(c, 'A') & LE(c, 'Z') & (c - 'A')) | - (GE(c, 'a') & LE(c, 'z') & (c - ('a' - 26))) | - (GE(c, '0') & LE(c, '9') & (c - ('0' - 52))) | (EQ(c, '+') & 62) | - (EQ(c, '/') & 63); - return x | (EQ(x, 0) & (EQ(c, 'A') ^ 0xFF)); -} - -/* - * Convert some bytes to Base64. 'dst_len' is the length (in characters) - * of the output buffer 'dst'; if that buffer is not large enough to - * receive the result (including the terminating 0), then (size_t)-1 - * is returned. Otherwise, the zero-terminated Base64 string is written - * in the buffer, and the output length (counted WITHOUT the terminating - * zero) is returned. - */ -static size_t to_base64(char *dst, size_t dst_len, const void *src, - size_t src_len) { - size_t olen; - const unsigned char *buf; - unsigned acc, acc_len; - - olen = (src_len / 3) << 2; - switch (src_len % 3) { - case 2: - olen++; - /* fall through */ - case 1: - olen += 2; - break; - } - if (dst_len <= olen) { - return (size_t)-1; - } - acc = 0; - acc_len = 0; - buf = (const unsigned char *)src; - while (src_len-- > 0) { - acc = (acc << 8) + (*buf++); - acc_len += 8; - while (acc_len >= 6) { - acc_len -= 6; - *dst++ = (char)b64_byte_to_char((acc >> acc_len) & 0x3F); - } - } - if (acc_len > 0) { - *dst++ = (char)b64_byte_to_char((acc << (6 - acc_len)) & 0x3F); - } - *dst++ = 0; - return olen; -} - -/* - * Decode Base64 chars into bytes. The '*dst_len' value must initially - * contain the length of the output buffer '*dst'; when the decoding - * ends, the actual number of decoded bytes is written back in - * '*dst_len'. - * - * Decoding stops when a non-Base64 character is encountered, or when - * the output buffer capacity is exceeded. If an error occurred (output - * buffer is too small, invalid last characters leading to unprocessed - * buffered bits), then NULL is returned; otherwise, the returned value - * points to the first non-Base64 character in the source stream, which - * may be the terminating zero. - */ -static const char *from_base64(void *dst, size_t *dst_len, const char *src) { - size_t len; - unsigned char *buf; - unsigned acc, acc_len; - - buf = (unsigned char *)dst; - len = 0; - acc = 0; - acc_len = 0; - for (;;) { - unsigned d; - - d = b64_char_to_byte(*src); - if (d == 0xFF) { - break; - } - src++; - acc = (acc << 6) + d; - acc_len += 6; - if (acc_len >= 8) { - acc_len -= 8; - if ((len++) >= *dst_len) { - return NULL; - } - *buf++ = (acc >> acc_len) & 0xFF; - } - } - - /* - * If the input length is equal to 1 modulo 4 (which is - * invalid), then there will remain 6 unprocessed bits; - * otherwise, only 0, 2 or 4 bits are buffered. The buffered - * bits must also all be zero. - */ - if (acc_len > 4 || (acc & (((unsigned)1 << acc_len) - 1)) != 0) { - return NULL; - } - *dst_len = len; - return src; -} - -/* - * Decode decimal integer from 'str'; the value is written in '*v'. - * Returned value is a pointer to the next non-decimal character in the - * string. If there is no digit at all, or the value encoding is not - * minimal (extra leading zeros), or the value does not fit in an - * 'unsigned long', then NULL is returned. - */ -static const char *decode_decimal(const char *str, unsigned long *v) { - const char *orig; - unsigned long acc; - - acc = 0; - for (orig = str;; str++) { - int c; - - c = *str; - if (c < '0' || c > '9') { - break; - } - c -= '0'; - if (acc > (ULONG_MAX / 10)) { - return NULL; - } - acc *= 10; - if ((unsigned long)c > (ULONG_MAX - acc)) { - return NULL; - } - acc += (unsigned long)c; - } - if (str == orig || (*orig == '0' && str != (orig + 1))) { - return NULL; - } - *v = acc; - return str; -} - -/* ==================================================================== */ -/* - * Code specific to Argon2. - * - * The code below applies the following format: - * - * $argon2[$v=]$m=,t=,p=$$ - * - * where is either 'd', 'id', or 'i', is a decimal integer (positive, - * fits in an 'unsigned long'), and is Base64-encoded data (no '=' padding - * characters, no newline or whitespace). - * - * The last two binary chunks (encoded in Base64) are, in that order, - * the salt and the output. Both are required. The binary salt length and the - * output length must be in the allowed ranges defined in argon2.h. - * - * The ctx struct must contain buffers large enough to hold the salt and pwd - * when it is fed into decode_string. - */ - -int decode_string(argon2_context *ctx, const char *str, argon2_type type) { - -/* check for prefix */ -#define CC(prefix) \ - do { \ - size_t cc_len = strlen(prefix); \ - if (strncmp(str, prefix, cc_len) != 0) { \ - return ARGON2_DECODING_FAIL; \ - } \ - str += cc_len; \ - } while ((void)0, 0) - -/* optional prefix checking with supplied code */ -#define CC_opt(prefix, code) \ - do { \ - size_t cc_len = strlen(prefix); \ - if (strncmp(str, prefix, cc_len) == 0) { \ - str += cc_len; \ - { code; } \ - } \ - } while ((void)0, 0) - -/* Decoding prefix into decimal */ -#define DECIMAL(x) \ - do { \ - unsigned long dec_x; \ - str = decode_decimal(str, &dec_x); \ - if (str == NULL) { \ - return ARGON2_DECODING_FAIL; \ - } \ - (x) = dec_x; \ - } while ((void)0, 0) - - -/* Decoding prefix into uint32_t decimal */ -#define DECIMAL_U32(x) \ - do { \ - unsigned long dec_x; \ - str = decode_decimal(str, &dec_x); \ - if (str == NULL || dec_x > UINT32_MAX) { \ - return ARGON2_DECODING_FAIL; \ - } \ - (x) = (uint32_t)dec_x; \ - } while ((void)0, 0) - - -/* Decoding base64 into a binary buffer */ -#define BIN(buf, max_len, len) \ - do { \ - size_t bin_len = (max_len); \ - str = from_base64(buf, &bin_len, str); \ - if (str == NULL || bin_len > UINT32_MAX) { \ - return ARGON2_DECODING_FAIL; \ - } \ - (len) = (uint32_t)bin_len; \ - } while ((void)0, 0) - - size_t maxsaltlen = ctx->saltlen; - size_t maxoutlen = ctx->outlen; - int validation_result; - const char* type_string; - - /* We should start with the argon2_type we are using */ - type_string = argon2_type2string(type, 0); - if (!type_string) { - return ARGON2_INCORRECT_TYPE; - } - - CC("$"); - CC(type_string); - - /* Reading the version number if the default is suppressed */ - ctx->version = ARGON2_VERSION_10; - CC_opt("$v=", DECIMAL_U32(ctx->version)); - - CC("$m="); - DECIMAL_U32(ctx->m_cost); - CC(",t="); - DECIMAL_U32(ctx->t_cost); - CC(",p="); - DECIMAL_U32(ctx->lanes); - ctx->threads = ctx->lanes; - - CC("$"); - BIN(ctx->salt, maxsaltlen, ctx->saltlen); - CC("$"); - BIN(ctx->out, maxoutlen, ctx->outlen); - - /* The rest of the fields get the default values */ - ctx->secret = NULL; - ctx->secretlen = 0; - ctx->ad = NULL; - ctx->adlen = 0; - ctx->allocate_cbk = NULL; - ctx->free_cbk = NULL; - ctx->flags = ARGON2_DEFAULT_FLAGS; - - /* On return, must have valid context */ - validation_result = validate_inputs(ctx); - if (validation_result != ARGON2_OK) { - return validation_result; - } - - /* Can't have any additional characters */ - if (*str == 0) { - return ARGON2_OK; - } else { - return ARGON2_DECODING_FAIL; - } -#undef CC -#undef CC_opt -#undef DECIMAL -#undef BIN -} - -int encode_string(char *dst, size_t dst_len, argon2_context *ctx, - argon2_type type) { -#define SS(str) \ - do { \ - size_t pp_len = strlen(str); \ - if (pp_len >= dst_len) { \ - return ARGON2_ENCODING_FAIL; \ - } \ - memcpy(dst, str, pp_len + 1); \ - dst += pp_len; \ - dst_len -= pp_len; \ - } while ((void)0, 0) - -#define SX(x) \ - do { \ - char tmp[30]; \ - sprintf(tmp, "%lu", (unsigned long)(x)); \ - SS(tmp); \ - } while ((void)0, 0) - -#define SB(buf, len) \ - do { \ - size_t sb_len = to_base64(dst, dst_len, buf, len); \ - if (sb_len == (size_t)-1) { \ - return ARGON2_ENCODING_FAIL; \ - } \ - dst += sb_len; \ - dst_len -= sb_len; \ - } while ((void)0, 0) - - const char* type_string = argon2_type2string(type, 0); - int validation_result = validate_inputs(ctx); - - if (!type_string) { - return ARGON2_ENCODING_FAIL; - } - - if (validation_result != ARGON2_OK) { - return validation_result; - } - - - SS("$"); - SS(type_string); - - SS("$v="); - SX(ctx->version); - - SS("$m="); - SX(ctx->m_cost); - SS(",t="); - SX(ctx->t_cost); - SS(",p="); - SX(ctx->lanes); - - SS("$"); - SB(ctx->salt, ctx->saltlen); - - SS("$"); - SB(ctx->out, ctx->outlen); - return ARGON2_OK; - -#undef SS -#undef SX -#undef SB -} - -size_t b64len(uint32_t len) { - size_t olen = ((size_t)len / 3) << 2; - - switch (len % 3) { - case 2: - olen++; - /* fall through */ - case 1: - olen += 2; - break; - } - - return olen; -} - -size_t numlen(uint32_t num) { - size_t len = 1; - while (num >= 10) { - ++len; - num = num / 10; - } - return len; -} - diff --git a/0x0017a_ctf/third_party/argon2/src/encoding.h b/0x0017a_ctf/third_party/argon2/src/encoding.h deleted file mode 100644 index 5b8b2dd..0000000 --- a/0x0017a_ctf/third_party/argon2/src/encoding.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ - -#ifndef ENCODING_H -#define ENCODING_H -#include "argon2.h" - -#define ARGON2_MAX_DECODED_LANES UINT32_C(255) -#define ARGON2_MIN_DECODED_SALT_LEN UINT32_C(8) -#define ARGON2_MIN_DECODED_OUT_LEN UINT32_C(12) - -/* -* encode an Argon2 hash string into the provided buffer. 'dst_len' -* contains the size, in characters, of the 'dst' buffer; if 'dst_len' -* is less than the number of required characters (including the -* terminating 0), then this function returns ARGON2_ENCODING_ERROR. -* -* on success, ARGON2_OK is returned. -*/ -int encode_string(char *dst, size_t dst_len, argon2_context *ctx, - argon2_type type); - -/* -* Decodes an Argon2 hash string into the provided structure 'ctx'. -* The only fields that must be set prior to this call are ctx.saltlen and -* ctx.outlen (which must be the maximal salt and out length values that are -* allowed), ctx.salt and ctx.out (which must be buffers of the specified -* length), and ctx.pwd and ctx.pwdlen which must hold a valid password. -* -* Invalid input string causes an error. On success, the ctx is valid and all -* fields have been initialized. -* -* Returned value is ARGON2_OK on success, other ARGON2_ codes on error. -*/ -int decode_string(argon2_context *ctx, const char *str, argon2_type type); - -/* Returns the length of the encoded byte stream with length len */ -size_t b64len(uint32_t len); - -/* Returns the length of the encoded number num */ -size_t numlen(uint32_t num); - -#endif diff --git a/0x0017a_ctf/third_party/argon2/src/genkat.h b/0x0017a_ctf/third_party/argon2/src/genkat.h deleted file mode 100644 index 3a7162a..0000000 --- a/0x0017a_ctf/third_party/argon2/src/genkat.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ - -#ifndef ARGON2_KAT_H -#define ARGON2_KAT_H - -#include "core.h" - -/* - * Initial KAT function that prints the inputs to the file - * @param blockhash Array that contains pre-hashing digest - * @param context Holds inputs - * @param type Argon2 type - * @pre blockhash must point to INPUT_INITIAL_HASH_LENGTH bytes - * @pre context member pointers must point to allocated memory of size according - * to the length values - */ -void initial_kat(const uint8_t *blockhash, const argon2_context *context, - argon2_type type); - -/* - * Function that prints the output tag - * @param out output array pointer - * @param outlen digest length - * @pre out must point to @a outlen bytes - **/ -void print_tag(const void *out, uint32_t outlen); - -/* - * Function that prints the internal state at given moment - * @param instance pointer to the current instance - * @param pass current pass number - * @pre instance must have necessary memory allocated - **/ -void internal_kat(const argon2_instance_t *instance, uint32_t pass); - -#endif diff --git a/0x0017a_ctf/third_party/argon2/src/ref.c b/0x0017a_ctf/third_party/argon2/src/ref.c deleted file mode 100644 index 10e45eb..0000000 --- a/0x0017a_ctf/third_party/argon2/src/ref.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ - -#include -#include -#include - -#include "argon2.h" -#include "core.h" - -#include "blake2/blamka-round-ref.h" -#include "blake2/blake2-impl.h" -#include "blake2/blake2.h" - - -/* - * Function fills a new memory block and optionally XORs the old block over the new one. - * @next_block must be initialized. - * @param prev_block Pointer to the previous block - * @param ref_block Pointer to the reference block - * @param next_block Pointer to the block to be constructed - * @param with_xor Whether to XOR into the new block (1) or just overwrite (0) - * @pre all block pointers must be valid - */ -static void fill_block(const block *prev_block, const block *ref_block, - block *next_block, int with_xor) { - block blockR, block_tmp; - unsigned i; - - copy_block(&blockR, ref_block); - xor_block(&blockR, prev_block); - copy_block(&block_tmp, &blockR); - /* Now blockR = ref_block + prev_block and block_tmp = ref_block + prev_block */ - if (with_xor) { - /* Saving the next block contents for XOR over: */ - xor_block(&block_tmp, next_block); - /* Now blockR = ref_block + prev_block and - block_tmp = ref_block + prev_block + next_block */ - } - - /* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then - (16,17,..31)... finally (112,113,...127) */ - for (i = 0; i < 8; ++i) { - BLAKE2_ROUND_NOMSG( - blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2], - blockR.v[16 * i + 3], blockR.v[16 * i + 4], blockR.v[16 * i + 5], - blockR.v[16 * i + 6], blockR.v[16 * i + 7], blockR.v[16 * i + 8], - blockR.v[16 * i + 9], blockR.v[16 * i + 10], blockR.v[16 * i + 11], - blockR.v[16 * i + 12], blockR.v[16 * i + 13], blockR.v[16 * i + 14], - blockR.v[16 * i + 15]); - } - - /* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then - (2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */ - for (i = 0; i < 8; i++) { - BLAKE2_ROUND_NOMSG( - blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16], - blockR.v[2 * i + 17], blockR.v[2 * i + 32], blockR.v[2 * i + 33], - blockR.v[2 * i + 48], blockR.v[2 * i + 49], blockR.v[2 * i + 64], - blockR.v[2 * i + 65], blockR.v[2 * i + 80], blockR.v[2 * i + 81], - blockR.v[2 * i + 96], blockR.v[2 * i + 97], blockR.v[2 * i + 112], - blockR.v[2 * i + 113]); - } - - copy_block(next_block, &block_tmp); - xor_block(next_block, &blockR); -} - -static void next_addresses(block *address_block, block *input_block, - const block *zero_block) { - input_block->v[6]++; - fill_block(zero_block, input_block, address_block, 0); - fill_block(zero_block, address_block, address_block, 0); -} - -void fill_segment(const argon2_instance_t *instance, - argon2_position_t position) { - block *ref_block = NULL, *curr_block = NULL; - block address_block, input_block, zero_block; - uint64_t pseudo_rand, ref_index, ref_lane; - uint32_t prev_offset, curr_offset; - uint32_t starting_index; - uint32_t i; - int data_independent_addressing; - - if (instance == NULL) { - return; - } - - data_independent_addressing = - (instance->type == Argon2_i) || - (instance->type == Argon2_id && (position.pass == 0) && - (position.slice < ARGON2_SYNC_POINTS / 2)); - - if (data_independent_addressing) { - init_block_value(&zero_block, 0); - init_block_value(&input_block, 0); - - input_block.v[0] = position.pass; - input_block.v[1] = position.lane; - input_block.v[2] = position.slice; - input_block.v[3] = instance->memory_blocks; - input_block.v[4] = instance->passes; - input_block.v[5] = instance->type; - } - - starting_index = 0; - - if ((0 == position.pass) && (0 == position.slice)) { - starting_index = 2; /* we have already generated the first two blocks */ - - /* Don't forget to generate the first block of addresses: */ - if (data_independent_addressing) { - next_addresses(&address_block, &input_block, &zero_block); - } - } - - /* Offset of the current block */ - curr_offset = position.lane * instance->lane_length + - position.slice * instance->segment_length + starting_index; - - if (0 == curr_offset % instance->lane_length) { - /* Last block in this lane */ - prev_offset = curr_offset + instance->lane_length - 1; - } else { - /* Previous block */ - prev_offset = curr_offset - 1; - } - - for (i = starting_index; i < instance->segment_length; - ++i, ++curr_offset, ++prev_offset) { - /*1.1 Rotating prev_offset if needed */ - if (curr_offset % instance->lane_length == 1) { - prev_offset = curr_offset - 1; - } - - /* 1.2 Computing the index of the reference block */ - /* 1.2.1 Taking pseudo-random value from the previous block */ - if (data_independent_addressing) { - if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) { - next_addresses(&address_block, &input_block, &zero_block); - } - pseudo_rand = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK]; - } else { - pseudo_rand = instance->memory[prev_offset].v[0]; - } - - /* 1.2.2 Computing the lane of the reference block */ - ref_lane = ((pseudo_rand >> 32)) % instance->lanes; - - if ((position.pass == 0) && (position.slice == 0)) { - /* Can not reference other lanes yet */ - ref_lane = position.lane; - } - - /* 1.2.3 Computing the number of possible reference block within the - * lane. - */ - position.index = i; - ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF, - ref_lane == position.lane); - - /* 2 Creating a new block */ - ref_block = - instance->memory + instance->lane_length * ref_lane + ref_index; - curr_block = instance->memory + curr_offset; - if (ARGON2_VERSION_10 == instance->version) { - /* version 1.2.1 and earlier: overwrite, not XOR */ - fill_block(instance->memory + prev_offset, ref_block, curr_block, 0); - } else { - if(0 == position.pass) { - fill_block(instance->memory + prev_offset, ref_block, - curr_block, 0); - } else { - fill_block(instance->memory + prev_offset, ref_block, - curr_block, 1); - } - } - } -} diff --git a/0x0017a_ctf/third_party/argon2/src/thread.c b/0x0017a_ctf/third_party/argon2/src/thread.c deleted file mode 100644 index 3ae2fb2..0000000 --- a/0x0017a_ctf/third_party/argon2/src/thread.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ - -#if !defined(ARGON2_NO_THREADS) - -#include "thread.h" -#if defined(_WIN32) -#include -#endif - -int argon2_thread_create(argon2_thread_handle_t *handle, - argon2_thread_func_t func, void *args) { - if (NULL == handle || func == NULL) { - return -1; - } -#if defined(_WIN32) - *handle = _beginthreadex(NULL, 0, func, args, 0, NULL); - return *handle != 0 ? 0 : -1; -#else - return pthread_create(handle, NULL, func, args); -#endif -} - -int argon2_thread_join(argon2_thread_handle_t handle) { -#if defined(_WIN32) - if (WaitForSingleObject((HANDLE)handle, INFINITE) == WAIT_OBJECT_0) { - return CloseHandle((HANDLE)handle) != 0 ? 0 : -1; - } - return -1; -#else - return pthread_join(handle, NULL); -#endif -} - -void argon2_thread_exit(void) { -#if defined(_WIN32) - _endthreadex(0); -#else - pthread_exit(NULL); -#endif -} - -#endif /* ARGON2_NO_THREADS */ diff --git a/0x0017a_ctf/third_party/argon2/src/thread.h b/0x0017a_ctf/third_party/argon2/src/thread.h deleted file mode 100644 index d4ca10c..0000000 --- a/0x0017a_ctf/third_party/argon2/src/thread.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Argon2 reference source code package - reference C implementations - * - * Copyright 2015 - * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves - * - * You may use this work under the terms of a Creative Commons CC0 1.0 - * License/Waiver or the Apache Public License 2.0, at your option. The terms of - * these licenses can be found at: - * - * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0 - * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0 - * - * You should have received a copy of both of these licenses along with this - * software. If not, they may be obtained at the above URLs. - */ - -#ifndef ARGON2_THREAD_H -#define ARGON2_THREAD_H - -#if !defined(ARGON2_NO_THREADS) - -/* - Here we implement an abstraction layer for the simpĺe requirements - of the Argon2 code. We only require 3 primitives---thread creation, - joining, and termination---so full emulation of the pthreads API - is unwarranted. Currently we wrap pthreads and Win32 threads. - - The API defines 2 types: the function pointer type, - argon2_thread_func_t, - and the type of the thread handle---argon2_thread_handle_t. -*/ -#if defined(_WIN32) -#include -typedef unsigned(__stdcall *argon2_thread_func_t)(void *); -typedef uintptr_t argon2_thread_handle_t; -#else -#include -typedef void *(*argon2_thread_func_t)(void *); -typedef pthread_t argon2_thread_handle_t; -#endif - -/* Creates a thread - * @param handle pointer to a thread handle, which is the output of this - * function. Must not be NULL. - * @param func A function pointer for the thread's entry point. Must not be - * NULL. - * @param args Pointer that is passed as an argument to @func. May be NULL. - * @return 0 if @handle and @func are valid pointers and a thread is successfully - * created. - */ -int argon2_thread_create(argon2_thread_handle_t *handle, - argon2_thread_func_t func, void *args); - -/* Waits for a thread to terminate - * @param handle Handle to a thread created with argon2_thread_create. - * @return 0 if @handle is a valid handle, and joining completed successfully. -*/ -int argon2_thread_join(argon2_thread_handle_t handle); - -/* Terminate the current thread. Must be run inside a thread created by - * argon2_thread_create. -*/ -void argon2_thread_exit(void); - -#endif /* ARGON2_NO_THREADS */ -#endif diff --git a/0x0017a_ctf/uf2families.json b/0x0017a_ctf/uf2families.json deleted file mode 100644 index 91d99ad..0000000 --- a/0x0017a_ctf/uf2families.json +++ /dev/null @@ -1,22 +0,0 @@ -[ - { - "short_name": "RP2040", - "id": "0xe48bff56", - "description": "Raspberry Pi RP2040" - }, - { - "short_name": "RP2350-ARM-S", - "id": "0xe48bff59", - "description": "Raspberry Pi RP2350, ARM, Secure" - }, - { - "short_name": "RP2350-ARM-NS", - "id": "0xe48bff5a", - "description": "Raspberry Pi RP2350, ARM, Non-Secure" - }, - { - "short_name": "RP2350-RISCV", - "id": "0xe48bff5b", - "description": "Raspberry Pi RP2350, RISC-V" - } -] diff --git a/0x001a_operators/.gitignore b/0x001a_operators/.gitignore deleted file mode 100644 index 2435c20..0000000 --- a/0x001a_operators/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -!.vscode/* diff --git a/0x001a_operators/.vscode/c_cpp_properties.json b/0x001a_operators/.vscode/c_cpp_properties.json deleted file mode 100644 index c429d6d..0000000 --- a/0x001a_operators/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "configurations": [ - { - "name": "Pico", - "includePath": [ - "${workspaceFolder}/**", - "${userHome}/.pico-sdk/sdk/2.2.0/**" - ], - "forcedInclude": [ - "${workspaceFolder}/build/generated/pico_base/pico/config_autogen.h", - "${userHome}/.pico-sdk/sdk/2.2.0/src/common/pico_base_headers/include/pico.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 -} diff --git a/0x001a_operators/.vscode/cmake-kits.json b/0x001a_operators/.vscode/cmake-kits.json deleted file mode 100644 index b0f3815..0000000 --- a/0x001a_operators/.vscode/cmake-kits.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "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}" - } - } -] \ No newline at end of file diff --git a/0x001a_operators/.vscode/extensions.json b/0x001a_operators/.vscode/extensions.json deleted file mode 100644 index a940d7c..0000000 --- a/0x001a_operators/.vscode/extensions.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "recommendations": [ - "marus25.cortex-debug", - "ms-vscode.cpptools", - "ms-vscode.cpptools-extension-pack", - "ms-vscode.vscode-serial-monitor", - "raspberry-pi.raspberry-pi-pico" - ] -} \ No newline at end of file diff --git a/0x001a_operators/.vscode/launch.json b/0x001a_operators/.vscode/launch.json deleted file mode 100644 index 424aa71..0000000 --- a/0x001a_operators/.vscode/launch.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "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}\"" - ] - }, - ] -} diff --git a/0x001a_operators/.vscode/settings.json b/0x001a_operators/.vscode/settings.json deleted file mode 100644 index 95be83b..0000000 --- a/0x001a_operators/.vscode/settings.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "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" -} diff --git a/0x001a_operators/.vscode/tasks.json b/0x001a_operators/.vscode/tasks.json deleted file mode 100644 index d1b3193..0000000 --- a/0x001a_operators/.vscode/tasks.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Compile Project", - "type": "process", - "isBuildCommand": true, - "command": "${userHome}/.pico-sdk/ninja/v1.12.1/ninja", - "args": ["-C", "${workspaceFolder}/build"], - "group": "build", - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": "$gcc", - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/ninja/v1.12.1/ninja.exe" - } - }, - { - "label": "Run Project", - "type": "process", - "command": "${env:HOME}/.pico-sdk/picotool/2.2.0-a4/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-a4/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", - } - } - ] -} diff --git a/0x001a_operators/0x001a_operators.c b/0x001a_operators/0x001a_operators.c deleted file mode 100644 index d9ddccf..0000000 --- a/0x001a_operators/0x001a_operators.c +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include "pico/stdlib.h" -#include "dht11.h" - -int main(void) { - stdio_init_all(); - - dht11_init(4); - - int x = 5; - int y = 10; - int arithmetic_operator = (x * y); - int increment_operator = x++; - bool relational_operator = (x > y); - bool logical_operator = (x > y) && (y > x); - int bitwise_operator = (x<<1); // x is now 6 because of x++ or 0b00000110 and (x<<1) is 0b00001100 or 12 - int assignment_operator = (x += 5); - - while (true) { - printf("arithmetic_operator: %d\r\n", arithmetic_operator); - printf("increment_operator: %d\r\n", increment_operator); - printf("relational_operator: %d\r\n", relational_operator); - printf("logical_operator: %d\r\n", logical_operator); - printf("bitwise_operator: %d\r\n", bitwise_operator); - printf("assignment_operator: %d\r\n", assignment_operator); - - float hum, temp; - if (dht11_read(&hum, &temp)) { - printf("Humidity: %.1f%%, Temperature: %.1f°C\r\n", hum, temp); - } else { - printf("DHT11 read failed\r\n"); - } - - sleep_ms(2000); - } -} \ No newline at end of file diff --git a/0x001a_operators/CMakeLists.txt b/0x001a_operators/CMakeLists.txt deleted file mode 100644 index f6ef427..0000000 --- a/0x001a_operators/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# 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-a4) -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(0x001a_operators 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(0x001a_operators 0x001a_operators.c dht11.c ) - -pico_set_program_name(0x001a_operators "0x001a_operators") -pico_set_program_version(0x001a_operators "0.1") - -# Modify the below lines to enable/disable output over UART/USB -pico_enable_stdio_uart(0x001a_operators 1) -pico_enable_stdio_usb(0x001a_operators 0) - -# Add the standard library to the build -target_link_libraries(0x001a_operators - pico_stdlib) - -# Add the standard include files to the build -target_include_directories(0x001a_operators PRIVATE - ${CMAKE_CURRENT_LIST_DIR} -) - -pico_add_extra_outputs(0x001a_operators) - diff --git a/0x001a_operators/dht11.c b/0x001a_operators/dht11.c deleted file mode 100644 index 9a52ba8..0000000 --- a/0x001a_operators/dht11.c +++ /dev/null @@ -1,79 +0,0 @@ -/** - * @file dht11.c - * @brief Implementation of DHT11 temperature and humidity sensor 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 "dht11.h" -#include "hardware/gpio.h" -#include "pico/time.h" - -static uint dht_pin; - -void dht11_init(uint8_t pin) { - dht_pin = pin; - gpio_init(pin); - gpio_pull_up(pin); -} - -bool dht11_read(float *humidity, float *temperature) { - uint8_t data[5] = {0}; - - // Start signal - gpio_set_dir(dht_pin, GPIO_OUT); - gpio_put(dht_pin, 0); - sleep_ms(18); - gpio_put(dht_pin, 1); - sleep_us(40); - gpio_set_dir(dht_pin, GPIO_IN); - - // Wait for response - uint32_t timeout = 10000; - while (gpio_get(dht_pin) == 1) if (--timeout == 0) return false; - timeout = 10000; - while (gpio_get(dht_pin) == 0) if (--timeout == 0) return false; - timeout = 10000; - while (gpio_get(dht_pin) == 1) if (--timeout == 0) return false; - - // Read 40 bits - for (int i = 0; i < 40; i++) { - timeout = 10000; - while (gpio_get(dht_pin) == 0) if (--timeout == 0) return false; - uint32_t start = time_us_32(); - timeout = 10000; - while (gpio_get(dht_pin) == 1) if (--timeout == 0) return false; - uint32_t duration = time_us_32() - start; - data[i / 8] <<= 1; - if (duration > 40) data[i / 8] |= 1; - } - - // Check checksum - if (data[4] != ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) return false; - - *humidity = data[0] + data[1] * 0.1f; - *temperature = data[2] + data[3] * 0.1f; - return true; -} diff --git a/0x001a_operators/dht11.h b/0x001a_operators/dht11.h deleted file mode 100644 index 30e298c..0000000 --- a/0x001a_operators/dht11.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - * @file dht11.h - * @brief Header for DHT11 temperature and humidity sensor 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 DHT11_H -#define DHT11_H - -#include -#include - -/** - * @brief Initialize the DHT11 driver - * - * Configures the GPIO pin for the DHT11 sensor. This must be called before - * using dht11_read(). - * - * @param pin GPIO pin number connected to DHT11 signal - */ -void dht11_init(uint8_t pin); - -/** - * @brief Read temperature and humidity from DHT11 sensor - * - * Performs the DHT11 communication protocol to read sensor data. - * - * @param humidity Pointer to store humidity value (0-100%) - * @param temperature Pointer to store temperature value in Celsius - * @return true if read successful, false on error or timeout - */ -bool dht11_read(float *humidity, float *temperature); - -#endif // DHT11_H diff --git a/0x001a_operators/hack-temp.py b/0x001a_operators/hack-temp.py deleted file mode 100644 index 8973073..0000000 --- a/0x001a_operators/hack-temp.py +++ /dev/null @@ -1,219 +0,0 @@ -#!/usr/bin/env python3 - -""" -FILE: hack-temp.py - -DESCRIPTION: -Incremental firmware patcher with minimal, conservative steps to bias readings. - -BRIEF: -Provides three modes: -- pool_only: change only the literal pool constant (scaling effect; least invasive) -- temp_only_vadd: convert temperature path to vadd.f32 and set a small negative pool -- both_vadd: convert both paths to vadd.f32 and set a small negative pool - -Intended to let you test changes incrementally, keeping humidity stable while -you evaluate temperature bias first. - -AUTHOR: Kevin Thomas -CREATION DATE: November 1, 2025 -UPDATE DATE: November 1, 2025 -""" - -import sys -import os -import struct - -BIN_PATH = "build/0x001a_operators.bin" - -# Offsets -OFF_410 = 0x410 -OFF_414 = 0x414 -OFF_POOL = 0x42C - -# Original encodings (for visibility only) -ORIG_410 = bytes.fromhex("a6ee257a") # vfma.f32 s14, s12, s11 -ORIG_414 = bytes.fromhex("e6eea57a") # vfma.f32 s15, s13, s11 -ORIG_POOL = bytes.fromhex("cccccc3d") # 0.1f - -# Encodings for vadd.f32 s14, s14, s11 and vadd.f32 s15, s15, s11 -VADD_S14_S11 = struct.pack(" 1 else "pool_only").strip().lower() - if mode == "pool_only": - patch_pool_only(new_pool_float=-1.0) - elif mode == "temp_only_vadd": - patch_temp_only_vadd(new_pool_float=-2.0) - elif mode == "both_vadd": - patch_both_vadd(new_pool_float=-2.0) - else: - print(f"Unknown mode: {mode}") - print("Use: pool_only | temp_only_vadd | both_vadd") - sys.exit(2) - - -if __name__ == "__main__": - main() - print("Patch complete. Convert to UF2 and flash. Test each mode incrementally.") diff --git a/0x001a_operators/pico_sdk_import.cmake b/0x001a_operators/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x001a_operators/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x001aa_cb/0x001aa_cb.bin b/0x001aa_cb/0x001aa_cb.bin deleted file mode 100755 index 88cef35..0000000 Binary files a/0x001aa_cb/0x001aa_cb.bin and /dev/null differ diff --git a/0x001aa_cb/0x001aa_cb.uf2 b/0x001aa_cb/0x001aa_cb.uf2 deleted file mode 100644 index aefe135..0000000 Binary files a/0x001aa_cb/0x001aa_cb.uf2 and /dev/null differ diff --git a/0x001aa_cb/0x001aa_cb_patched.bin b/0x001aa_cb/0x001aa_cb_patched.bin deleted file mode 100644 index 810f82e..0000000 Binary files a/0x001aa_cb/0x001aa_cb_patched.bin and /dev/null differ diff --git a/0x001aa_cb/0x001aa_cb_patched.uf2 b/0x001aa_cb/0x001aa_cb_patched.uf2 deleted file mode 100644 index b3a3183..0000000 Binary files a/0x001aa_cb/0x001aa_cb_patched.uf2 and /dev/null differ diff --git a/0x001aa_cb/CLASSIFIED-BRIEF-0x03.md b/0x001aa_cb/CLASSIFIED-BRIEF-0x03.md deleted file mode 100644 index 1711fc7..0000000 --- a/0x001aa_cb/CLASSIFIED-BRIEF-0x03.md +++ /dev/null @@ -1,154 +0,0 @@ -# Operation Iron Net: Classified Intelligence Briefing - -``` -+-----------------------------------------------------------------+ -| TOP SECRET // NOFORN | -+-----------------------------------------------------------------+ -| | -|OPERATION IRON NET | -| | -|CLASSIFIED BRIEFING: LIVE CHALLENGE 0x03 | -| | -|NATIONAL SECURITY AGENCY / GMU RHET | -+-----------------------------------------------------------------+ -``` - -## 1. The Advice - -INT. NSA EXPLOITATION CELL. 04:10. - -A grey field junction box sits on the bench, its lid peeled back. Inside, -secured in potting compound, is a covert environmental sensor node recovered -from a contested waterway. - -On the top of the enclosure, a status diode glows a steady red. Beside it, a -REYAX RYLR998 LoRa transceiver is wired to `UART1` on `GP8` and `GP9`. A -three-wire ribbon terminates in a DHT11 temperature and humidity canister. A -thin jumper loops from `GP15` up to the `3V3` rail. - -The Director sets down a field report and looks at the red diode. - -**DIRECTOR:** What is it? - -**ANALYST:** A remote environmental trigger. The adversary seeds these along a -river corridor. The DHT11 samples the air. When the conditions hit a preset -window, the node arms a payload channel and broadcasts a strike authorization -over LoRa. - -**DIRECTOR:** Is it live? - -**ANALYST:** Armed and listening. The payload relay on `GP18` is wired. One -authenticated strike frame and the cell downstream fires. - -**DIRECTOR:** Run it through Buddy. - -**ANALYST:** Already did. Four minutes with the stripped flash image. - -She turns her monitor toward him. - -``` -+-----------------------------------------------------------------+ -| BUDDY // CLASSIFIED EXPLOITATION ASSIST // CONF: 0.98 | -+-----------------------------------------------------------------+ -| ACTION : Replay the environmental checksum window. | -| MECHANISM : DHT11 humidity byte XOR 0xAF, masked by 0x3C. | -| PREDICTION : Force (humidity ^ 0xAF) & 0x3C == 0x18, node arm. | -| CONFIDENCE : 0.98 | -+-----------------------------------------------------------------+ -``` - -**DIRECTOR:** 0.98. Forge the reading, arm the node, learn its payload. - -**ANALYST:** Buddy found the bitwise window. Buddy did not find the door behind -it. There is an authorization token, and there is a trap. - -**DIRECTOR:** Buddy says 0.98. - -**ANALYST:** Buddy disassembled `evaluate_environment`. Buddy never followed the -SRAM the state machine lives in. Buddy never read the fault counter. - -## 2. What Buddy Is - -Buddy is not a person. It is a model. It has parsed more disassembled machine -code than any engineer on earth, and it speaks with total, unhesitating certainty. - -That certainty is lethal when the target is a live payload channel. - -Buddy scanned the flash image and found a tidy bitwise test. It concluded that -satisfying the arithmetic is the whole game. It published the mask and the window -and declared the node owned. - -What Buddy failed to model is that adversary tripwires are engineered for exactly -this attack. A real node does not trade a payload on a single sensor byte. It -runs a state machine, validates an encrypted token carried over the air, and -counts its own faults so that a spoofer who fumbles the protocol three times -burns the node instead of arming it. - -There is also a physical seal. Cut the sense loop and the node latches shut. The -correct env window is necessary. It is nowhere near sufficient. - -Buddy saw the bitwise test. Buddy did not verify the ground truth. - -## 3. The Operation - -At 01:55, a Riverine Technical Intelligence team recovered an intact node before -adversary recovery could zeroize it. The enclosure is a single-board design built -around a bare-metal RP2350 (ARM Cortex-M33). - -There are no debug symbols. There is no operating system. There is no SVD file to -label the registers. All you have is `0x001aa_cb.bin` mapped into Flash at -`0x10000000`, and the physical breadboard hardware in front of you. - -* **Pin 11 (`GP8`)**: LoRa UART1 TX (to RYLR998 RXD). -* **Pin 12 (`GP9`)**: LoRa UART1 RX (from RYLR998 TXD). -* **Pin 19 (`GP14`)**: DHT11 single-wire data line. -* **Pin 20 (`GP15`)**: Anti-tamper sense loop (jumpered to `3V3`). -* **Pin 21 (`GP16`)**: Red LED (`NODE ARMED // LISTENING`). -* **Pin 22 (`GP17`)**: Green LED (`STRIKE AUTHORIZED`). -* **Pin 24 (`GP18`)**: Payload trigger relay. -* **Pin 36 (`3V3`)**: RYLR998 VDD rail and `GP15` pull-up source. -* **Pin 38 (`GND`)**: Ground reference. - -Inside this image there is an environment gate, an over-the-air authorization -token, a fault counter, and a tamper latch. Whatever mechanism actually authorizes -a strike is buried in the stripped ARM Thumb-2 machine code. - -## 4. The Mandate - -The Director crosses his arms. - -**DIRECTOR:** Prove Buddy right, or prove it wrong. - -**ANALYST:** I need thirty minutes with GDB and Ghidra. - -**DIRECTOR:** You have twenty. Trace the environment routine. Map the state -machine. Do not forge a reading over LoRa until you know with certainty what that -firmware will do with the next frame, and what it will do to you if the frame is -wrong. - -The orders are clear: - -1. **Recover the Environment Gate**: Locate the bitwise validation routine and - work out which DHT11 humidity value satisfies it. -2. **Recover the Authorization Token**: Find the custom cipher that is applied at - boot and decrypt the plaintext strike token it protects. -3. **Respect the Traps**: Determine what the node does after repeated faults, and - what happens if the `GP15` sense loop is broken. -4. **Neutralize the Node**: Execute a verified exploit, either by recovering the - token and satisfying the gate, by mutating the state machine in SRAM with GDB, - or by patching the binary in Flash. -5. **Verify the Hardware**: Transition the live breadboard from the Red LED on - `GP16` to the solid Green LED on `GP17` on physical silicon. - -A machine's 0.98 guess does not authorize a strike. - -## 5. The Challenge - -You have the image. You have the board. You have the tools and the time Buddy did -not need. - -Buddy has given you its answer, and it is confident. - -Is it that simple? - -Go find out. diff --git a/0x001aa_cb/CLASSIFIED-BRIEF-0x03.pdf b/0x001aa_cb/CLASSIFIED-BRIEF-0x03.pdf deleted file mode 100644 index ac927e4..0000000 Binary files a/0x001aa_cb/CLASSIFIED-BRIEF-0x03.pdf and /dev/null differ diff --git a/0x001aa_cb/CMakeLists.txt b/0x001aa_cb/CMakeLists.txt deleted file mode 100644 index 9d82362..0000000 --- a/0x001aa_cb/CMakeLists.txt +++ /dev/null @@ -1,85 +0,0 @@ -# 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. -# -# Author: Kevin Thomas -# Email: kevin@mytechnotalent.com -# GitHub: https://github.com/mytechnotalent -# File: CMakeLists.txt -# Desc: Configures RP2350 Pico SDK project for Operation Iron Net Firmware -# Created: 2026 - -cmake_minimum_required(VERSION 3.13) - -set(CMAKE_C_STANDARD 11) -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -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-a4) -set(picoVscode ${USERHOME}/.pico-sdk/cmake/pico-vscode.cmake) -if (EXISTS ${picoVscode}) - include(${picoVscode}) -endif() - -set(PICO_BOARD pico2 CACHE STRING "Board type") -include(pico_sdk_import.cmake) - -project(0x001aa_cb C CXX ASM) - -pico_sdk_init() - -add_executable(0x001aa_cb - src/main.c - src/gpio_ctrl.c - src/dht11.c - src/crypto.c - src/lora.c - src/logic.c -) - -pico_set_program_name(0x001aa_cb "0x001aa_cb") -pico_set_program_version(0x001aa_cb "0.1") - -pico_enable_stdio_uart(0x001aa_cb 1) -pico_enable_stdio_usb(0x001aa_cb 1) - -target_compile_definitions(0x001aa_cb PRIVATE - PICO_DEFAULT_UART_BAUD_RATE=115200 -) - -target_link_libraries(0x001aa_cb - pico_stdlib - hardware_gpio - hardware_uart -) - -target_include_directories(0x001aa_cb PRIVATE - ${CMAKE_CURRENT_LIST_DIR}/include -) - -pico_add_extra_outputs(0x001aa_cb) diff --git a/0x001aa_cb/include/crypto.h b/0x001aa_cb/include/crypto.h deleted file mode 100644 index eb85cae..0000000 --- a/0x001aa_cb/include/crypto.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * @file crypto.h - * @brief Lightweight rolling cipher interface for Operation Iron Net - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#ifndef CRYPTO_H -#define CRYPTO_H - -#include -#include - -#define TOKEN_LEN 8 - -/** - * @brief Decrypt the rolling strike authorization token into a buffer. - * @param dest Pointer to buffer receiving the decrypted token bytes. - * @return void No return value. - */ -void decrypt_auth_token(uint8_t *dest); - -#endif /* CRYPTO_H */ diff --git a/0x001aa_cb/include/dht11.h b/0x001aa_cb/include/dht11.h deleted file mode 100644 index fabefbc..0000000 --- a/0x001aa_cb/include/dht11.h +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file dht11.h - * @brief Operation Iron Net Firmware - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#ifndef DHT11_H -#define DHT11_H - -#include -#include - -#define DHT11_PIN 14 - -typedef struct { - uint8_t humidity_int; - uint8_t humidity_dec; - uint8_t temp_int; - uint8_t temp_dec; - uint8_t checksum; - bool valid; -} dht11_data_t; - -/** - * @brief Initialize the DHT11 data pin and idle the sensor high. - * @param void No parameters. - * @return void No return value. - */ -void dht11_init(void); - -/** - * @brief Perform a single-wire DHT11 read into the reading cache. - * @param void No parameters. - * @return dht11_data_t* Pointer to the current sensor reading. - */ -dht11_data_t* dht11_read(void); - -#endif // DHT11_H diff --git a/0x001aa_cb/include/gpio_ctrl.h b/0x001aa_cb/include/gpio_ctrl.h deleted file mode 100644 index 3c44b23..0000000 --- a/0x001aa_cb/include/gpio_ctrl.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - * @file gpio_ctrl.h - * @brief Operation Iron Net Firmware - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#ifndef GPIO_CTRL_H -#define GPIO_CTRL_H - -#include - -#define PAYLOAD_PIN 18 -#define LED_RED_PIN 16 -#define LED_GREEN_PIN 17 -#define TAMPER_PIN 15 - -/** - * @brief Initialize the status LEDs, payload, and tamper pins. - * @param void No parameters. - * @return void No return value. - */ -void init_gpio(void); - -/** - * @brief Drive the armed indication LEDs (red on, green off). - * @param void No parameters. - * @return void No return value. - */ -void set_led_armed(void); - -/** - * @brief Drive the authorized indication LEDs (green on, red off). - * @param void No parameters. - * @return void No return value. - */ -void set_led_authorized(void); - -/** - * @brief Drive the tamper flash indication on the red LED. - * @param state True to turn the red LED on, false to turn it off. - * @return void No return value. - */ -void set_led_tamper_flash(bool state); - -/** - * @brief Read the enclosure tamper loop state. - * @param void No parameters. - * @return true when the tamper wire is intact, false when cut. - */ -bool is_tamper_wire_intact(void); - -/** - * @brief Pulse the payload marker output to deploy the marker. - * @param void No parameters. - * @return void No return value. - */ -void payload_deploy(void); - -#endif // GPIO_CTRL_H diff --git a/0x001aa_cb/include/logic.h b/0x001aa_cb/include/logic.h deleted file mode 100644 index 5857263..0000000 --- a/0x001aa_cb/include/logic.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @file logic.h - * @brief Operation Iron Net Firmware - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#ifndef LOGIC_H -#define LOGIC_H - -#include -#include - -#define STATE_ENV_ARMED 0x01 -#define STATE_ENV_AUTHORIZED 0x03 -#define STATE_ENV_LOCKOUT 0xFF - -/** - * @brief Initialize the strike logic, token, radio, and feedback. - * @param void No parameters. - * @return void No return value. - */ -void init_strike_controller(void); - -/** - * @brief Evaluate the environment and fire the payload when authorized. - * @param void No parameters. - * @return void No return value. - */ -void evaluate_environment(void); - -#endif // LOGIC_H diff --git a/0x001aa_cb/include/lora.h b/0x001aa_cb/include/lora.h deleted file mode 100644 index a18737f..0000000 --- a/0x001aa_cb/include/lora.h +++ /dev/null @@ -1,64 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: lora.h -// Desc: Declares UART1 interface for the REYAX RYLR998 LoRa transceiver. -// Created: 2026 - -#ifndef LORA_H -#define LORA_H - -#include -#include -#include "hardware/uart.h" - -#define LORA_UART uart1 -#define LORA_BAUD 9600 -#define LORA_TX_PIN 8 -#define LORA_RX_PIN 9 - -/** - * @brief Initialize UART1 and configure the RYLR998 radio parameters. - * @param void No parameters. - * @return void No return value. - */ -void init_lora(void); - -/** - * @brief Transmit a message over the LoRa link to the base station. - * @param msg Null-terminated message string to transmit. - * @return void No return value. - */ -void lora_send(const char *msg); - -/** - * @brief Poll the UART receive buffer for a complete LoRa packet. - * @param payload_out Buffer receiving the extracted payload string. - * @param max_len Capacity of payload_out in bytes. - * @return true when a payload was extracted, false otherwise. - */ -bool lora_poll_packet(char *payload_out, size_t max_len); - -#endif // LORA_H diff --git a/0x001aa_cb/pico_sdk_import.cmake b/0x001aa_cb/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x001aa_cb/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x001aa_cb/scripts/lora_console.py b/0x001aa_cb/scripts/lora_console.py deleted file mode 100755 index 24310f9..0000000 --- a/0x001aa_cb/scripts/lora_console.py +++ /dev/null @@ -1,195 +0,0 @@ -#!/usr/bin/env python3 -# 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. -# -# Author: Kevin Thomas -# Email: kevin@mytechnotalent.com -# GitHub: https://github.com/mytechnotalent -# File: lora_console.py -# Desc: Interactive REYAX RYLR998 terminal for the FT232RL ground station. -# Created: 2026 - -""" -Interactive LoRa terminal for the REYAX RYLR998 ground station. - -Sends AT commands as complete bursts terminated with a carriage return and line -feed to avoid the RYLR998 inter-character timeout error, and prints incoming -packets from the airborne node as they arrive. -""" - -import argparse -import sys -import threading -import time - -try: - import serial -except ImportError: - serial = None - - -def _reader_thread(ser: "serial.Serial") -> None: - """ - Continuously read and display incoming packets from the radio. - - Parameters - ---------- - ser : serial.Serial - Open serial connection to the ground RYLR998. - - Returns - ------- - None - """ - while True: - try: - line = ser.readline().decode("utf-8", errors="ignore").strip() - if line: - print(f"\n[LORA RX] {line}\n> ", end="", flush=True) - except Exception: - break - - -def _parse_args() -> argparse.Namespace: - """ - Parse command line arguments for the LoRa console. - - Parameters - ---------- - None - - Returns - ------- - argparse.Namespace - Parsed arguments with the serial port and baud rate. - """ - parser = argparse.ArgumentParser(description="REYAX RYLR998 console") - parser.add_argument("--port", default="/dev/cu.usbserial-A50285BI") - parser.add_argument("--baud", type=int, default=115200) - return parser.parse_args() - - -def _open_radio(port: str, baud: int) -> "serial.Serial": - """ - Open serial connection to the REYAX transceiver. - - Parameters - ---------- - port : str - Serial device path or COM port identifier. - baud : int - Baud rate for serial communication. - - Returns - ------- - serial.Serial - Open serial interface to the radio. - """ - print(f"[*] Opening REYAX RYLR998 on {port} @ {baud}...") - try: - return serial.Serial(port, baud, timeout=0.5) - except Exception as e: - sys.exit(f"[-] Failed to open {port}: {e}") - - -def _start_radio(ser: "serial.Serial") -> None: - """ - Start listener thread and send initial AT ping. - - Parameters - ---------- - ser : serial.Serial - Open serial connection to the ground RYLR998. - - Returns - ------- - None - """ - thread = threading.Thread(target=_reader_thread, args=(ser,), daemon=True) - thread.start() - time.sleep(0.1) - ser.write(b"AT\r\n") - - -def _print_banner() -> None: - """ - Print console connection info and operator command instructions. - - Parameters - ---------- - None - - Returns - ------- - None - """ - print("[+] Connected. Type AT commands (e.g. AT, AT+BAND?, AT+NETWORKID?).") - print("[+] Incoming airborne packets print as [LORA RX] +RCV=...") - print("[+] Press Ctrl-C or Ctrl-D to exit.\n") - - -def _console_loop(ser: "serial.Serial") -> None: - """ - Forward operator input lines to the serial transceiver. - - Parameters - ---------- - ser : serial.Serial - Open serial connection to the ground RYLR998. - - Returns - ------- - None - """ - try: - while True: - cmd = input("> ").strip() - if cmd: - ser.write(cmd.encode("utf-8") + b"\r\n") - except (KeyboardInterrupt, EOFError): - print("\n[*] Exiting LoRa console.") - ser.close() - - -def main() -> None: - """ - Open the ground station radio and forward operator input. - - Parameters - ---------- - None - - Returns - ------- - None - """ - if serial is None: - sys.exit("pyserial required: pip install pyserial") - args = _parse_args() - ser = _open_radio(args.port, args.baud) - _start_radio(ser) - _print_banner() - _console_loop(ser) - - -if __name__ == "__main__": - main() diff --git a/0x001aa_cb/scripts/patch_binary.py b/0x001aa_cb/scripts/patch_binary.py deleted file mode 100644 index ca22844..0000000 --- a/0x001aa_cb/scripts/patch_binary.py +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env python3 -# 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. -# -# Author: Kevin Thomas -# Email: kevin@mytechnotalent.com -# GitHub: https://github.com/mytechnotalent -# File: patch_binary.py -# Desc: Patch script for Operation Iron Net (0x001aa_cb). -# Created: 2026 - -""" -Patch script for Operation Iron Net (0x001aa_cb). - -Forces the environment gate and the authorization-token gate to true so the -node deploys the payload on boot without a valid sensor reading or token. -""" - -import sys - -PATCHES = [ - (0x7BC, b"\x58\xd1", b"\x00\xbf", "nop (force authorization accept)"), - (0x802, b"\x1b\xb1", b"\x00\xbf", "nop (ignore the environment gate)"), - (0x7D2, b"\x02\x2b", b"\xff\x2b", "cmp r3, #0xff (raise fault threshold)"), -] - - -def _apply_patch(data: bytearray) -> None: - """ - Verify each opcode and apply its replacement bytes in place. - - Parameters - ---------- - data : bytearray - Mutable binary image buffer. - - Returns - ------- - None - """ - for offset, expected, patched, note in PATCHES: - if data[offset:offset + len(expected)] != expected: - actual = data[offset:offset + len(expected)].hex() - raise ValueError(f"Expected {expected.hex()} at 0x{offset:x}, got {actual}") - data[offset:offset + len(patched)] = patched - print(f"[+] Patched 0x{offset:x}: {note}") - - -def patch_binary(in_bin: str, out_bin: str) -> None: - """ - Read target firmware binary, apply patches, and write modified image. - - Parameters - ---------- - in_bin : str - Path to source binary file. - out_bin : str - Path to destination patched binary file. - - Returns - ------- - None - """ - with open(in_bin, "rb") as f: - data = bytearray(f.read()) - _apply_patch(data) - with open(out_bin, "wb") as f: - f.write(data) - print(f"[+] Successfully patched {in_bin} -> {out_bin}") - - -def main() -> None: - """ - Parse command line arguments and execute binary patching. - - Parameters - ---------- - None - - Returns - ------- - None - """ - in_file = sys.argv[1] if len(sys.argv) > 1 else "0x001aa_cb.bin" - out_file = sys.argv[2] if len(sys.argv) > 2 else "0x001aa_cb_patched.bin" - patch_binary(in_file, out_file) - - -if __name__ == "__main__": - main() diff --git a/0x001aa_cb/scripts/uf2conv.py b/0x001aa_cb/scripts/uf2conv.py deleted file mode 100644 index c5a832f..0000000 --- a/0x001aa_cb/scripts/uf2conv.py +++ /dev/null @@ -1,861 +0,0 @@ -#!/usr/bin/env python3 -r"""Convert firmware images between Intel HEX, raw BIN, and Raspberry Pi UF2. - -This is the course's single canonical copy of the converter. Every week that -patches a binary refers to the copy at the repository root: - - python ../uf2conv.py build/image-h.bin --base 0x10000000 \\ - --family 0xe48bff59 --output build/hacked.uf2 - -It descends from the upstream Raspberry Pi ``uf2conv.py``, with the following -changes made for this course: - -* Full type annotations and Google-style docstrings on every public callable. -* ``pathlib`` instead of ``os.path``, and explicit ``except`` clauses. -* Latent crash bugs in the upstream error paths fixed (see - :func:`convert_from_uf2`). -* Module globals replaced with an explicit :class:`ConverterContext`, so the - base address and family ID are threaded through rather than mutated behind - the caller's back. - -UF2 format, for reference -------------------------- -A UF2 file is a flat sequence of 512-byte blocks. Each block is:: - - offset size field - 0x00 4 magicStart0 = 0x0A324655 ("UF2\\n") - 0x04 4 magicStart1 = 0x9E5D5157 (arbitrary constant) - 0x08 4 flags - 0x0C 4 targetAddr - 0x10 4 payloadSize (max 476) - 0x14 4 blockNo - 0x18 4 numBlocks - 0x1C 4 familyID - 0x20 476 data - 0x1FC 4 magicEnd = 0x0AB16F30 - -Flags that matter here: - -* ``0x00000001`` -- "do not flash"; this block is a no-flash marker. -* ``0x00002000`` -- "family ID present"; ``familyID`` is meaningful. - -For the RP2350 the family ID is ``0xe48bff59``, and it is what tells the -boot ROM that this UF2 targets RP2350 hardware rather than, say, an RP2040 or -a Pico W. - -See Also: --------- -* ``uf2families.json`` -- the family-name to family-ID table, loaded from the - directory containing this file. -* ``flash.sh`` / ``flash.ps1`` -- program a raw ``.bin`` over SWD instead. -""" - -from __future__ import annotations - -import argparse -import json -import os -import re -import struct -import subprocess -import sys -from dataclasses import dataclass -from pathlib import Path -from time import sleep - -# --------------------------------------------------------------------------- -# UF2 format constants -# --------------------------------------------------------------------------- - -#: First magic word, ``"UF2\n"`` read as a little-endian uint32. -UF2_MAGIC_START0 = 0x0A324655 -#: Second magic word. The value is arbitrary but must be constant. -UF2_MAGIC_START1 = 0x9E5D5157 -#: Trailing magic word closing every 512-byte block. -UF2_MAGIC_END = 0x0AB16F30 - -#: Size of one UF2 block in bytes. -UF2_BLOCK_SIZE = 512 -#: Offset of the 32-byte block header within a block. -UF2_HEADER_SIZE = 32 -#: Largest payload a single block may carry (476 = 512 - 32 header - 4 magic). -UF2_MAX_PAYLOAD = UF2_BLOCK_SIZE - UF2_HEADER_SIZE - 4 - -#: Flag bit marking a block the bootloader must NOT program. -UF2_FLAG_NOFLASH = 0x00000001 -#: Flag bit announcing that ``familyID`` carries a meaningful value. -UF2_FLAG_FAMILY_ID = 0x00002000 - -#: Name of the marker file the boot ROM exposes on its flash-drive volume. -INFO_FILE = "INFO_UF2.TXT" - -#: Struct format for the 32-byte UF2 block header. -_HEADER_STRUCT = struct.Struct("UF2 - conversion of RP2040-era images, and the wrong behaviour for - RP2350, which is why the course always passes ``--family``. - """ - - appstartaddr: int | None = DEFAULT_BASE_ADDRESS - familyid: int = DEFAULT_FAMILY_ID - - -# --------------------------------------------------------------------------- -# Format detection -# --------------------------------------------------------------------------- - - -def is_uf2(buf: bytes) -> bool: - """Report whether a buffer begins with the UF2 start magic. - - Args: - buf: Raw file contents. - - Returns: - ``True`` if the first two uint32 words are the UF2 start magic. - """ - if len(buf) < 8: - return False - word0, word1 = _HEADER_STRUCT.unpack_from(buf, 0)[:2] - return word0 == UF2_MAGIC_START0 and word1 == UF2_MAGIC_START1 - - -def is_hex(buf: bytes) -> bool: - """Report whether a buffer looks like an Intel HEX file. - - A file qualifies when it decodes as UTF-8, begins with a record marker - ``:``, and contains only characters legal in Intel HEX records. - - Args: - buf: Raw file contents. - - Returns: - ``True`` if the buffer should be treated as Intel HEX. - """ - try: - text = buf[:30].decode("utf-8") - except UnicodeDecodeError: - return False - if not text.startswith(":"): - return False - return re.match(rb"^[:0-9a-fA-F\r\n]+$", buf) is not None - - -# --------------------------------------------------------------------------- -# UF2 -> BIN -# --------------------------------------------------------------------------- - - -def convert_from_uf2(buf: bytes, ctx: ConverterContext) -> bytes: - """Decode a UF2 file back into a flat binary image. - - Blocks are visited in file order. Gaps between consecutive block addresses - are filled with zero words, and any trailing gap is dropped so that the - result ends at the last byte actually programmed. - - A UF2 file may legitimately interleave blocks from several families (this - is how a multicore image ships both cores in one download). When more than - one family is present and the caller did not constrain the family with - ``--family``, the conversion is ambiguous, so the payload is emptied and - ``appstartaddr`` reset to ``0``. - - Args: - buf: Complete UF2 file contents. - ctx: Conversion state; updated in place with the discovered base - address. - - Returns: - The decoded payload. - - Raises: - Uf2Error: If a block declares an oversized payload, the blocks are out - of order, or the implied padding exceeds 10 MiB. - - Note: - The upstream Raspberry Pi version of this function crashes on its own - error paths: it builds the message with ``"..." + ptr`` where ``ptr`` - is an ``int``, which raises :class:`TypeError` and masks the real - problem. The messages here use f-strings so the diagnostic survives. - """ - numblocks = len(buf) // UF2_BLOCK_SIZE - curraddr: int | None = None - currfamilyid: int | None = None - families_found: dict[int, int] = {} - prev_flag: int | None = None - all_flags_same = True - outp: list[bytes] = [] - - for blockno in range(numblocks): - ptr = blockno * UF2_BLOCK_SIZE - block = buf[ptr : ptr + UF2_BLOCK_SIZE] - ( - magic0, - magic1, - flags, - target_addr, - datalen, - _blockno, - _numblocks, - block_family, - ) = _HEADER_STRUCT.unpack_from(block, 0) - - if magic0 != UF2_MAGIC_START0 or magic1 != UF2_MAGIC_START1: - print(f"Skipping block at {ptr:#x}; bad magic") - continue - - if flags & UF2_FLAG_NOFLASH: - continue - - if datalen > UF2_MAX_PAYLOAD: - msg = f"Invalid UF2 data size at {ptr:#x}: {datalen}" - raise Uf2Error(msg) - - if flags & UF2_FLAG_FAMILY_ID and currfamilyid is None: - currfamilyid = block_family - - # A new contiguous run starts when the address jumps or the family - # changes. appstartaddr tracks the start of the current run, which is - # what makes the reported start address the image's true base rather - # than the address of its last block. - if curraddr is None or ( - flags & UF2_FLAG_FAMILY_ID and block_family != currfamilyid - ): - currfamilyid = block_family - curraddr = target_addr - if ctx.familyid == DEFAULT_FAMILY_ID or ctx.familyid == block_family: - ctx.appstartaddr = target_addr - - padding = target_addr - curraddr - if padding < 0: - msg = f"Block out of order at {ptr:#x}: {target_addr:#x} < {curraddr:#x}" - raise Uf2Error(msg) - if padding > 10 * 1024 * 1024: - msg = f"More than 10M of padding needed at {ptr:#x}" - raise Uf2Error(msg) - if padding % 4 != 0: - msg = f"Non-word padding size at {ptr:#x}: {padding}" - raise Uf2Error(msg) - - while padding > 0: - padding -= 4 - outp.append(b"\x00\x00\x00\x00") - - if ctx.familyid == DEFAULT_FAMILY_ID or ( - flags & UF2_FLAG_FAMILY_ID and ctx.familyid == block_family - ): - outp.append( - block[UF2_HEADER_SIZE : UF2_HEADER_SIZE + datalen], - ) - - curraddr = target_addr + datalen - - if flags & UF2_FLAG_FAMILY_ID: - existing = families_found.get(block_family) - if existing is None or existing > target_addr: - families_found[block_family] = target_addr - - if prev_flag is None: - prev_flag = flags - elif prev_flag != flags: - all_flags_same = False - - if blockno == numblocks - 1: - _print_uf2_header_info(families_found, all_flags_same, flags) - if len(families_found) > 1 and ctx.familyid == DEFAULT_FAMILY_ID: - outp = [] - ctx.appstartaddr = 0x0 - - return b"".join(outp) - - -def _print_uf2_header_info( - families_found: dict[int, int], - all_flags_same: bool, - flags: int, -) -> None: - """Print the family summary block that follows a UF2->BIN conversion. - - Args: - families_found: Mapping of family ID to the lowest target address seen - for that family. - all_flags_same: Whether every block carried an identical flag word. - flags: The flag word from the final block, used for display. - """ - print("--- UF2 File Header Info ---") - families = load_families() - name_by_id = {value: key for key, value in families.items()} - for family_hex, address in families_found.items(): - short_name = name_by_id.get(family_hex, "") - print(f"Family ID is {short_name}, hex value is {family_hex:#010x}") - print(f"Target Address is {address:#010x}") - if all_flags_same: - print(f"All block flag values consistent, {flags:#06x}") - else: - print("Flags were not all the same") - print("----------------------------") - - -# --------------------------------------------------------------------------- -# BIN -> UF2 -# --------------------------------------------------------------------------- - - -def convert_to_uf2(file_content: bytes, ctx: ConverterContext) -> bytes: - """Wrap a raw binary in UF2 blocks. - - The binary is split into 256-byte payloads; the final block is zero-padded. - Each block's ``targetAddr`` is the byte offset within the image plus - :attr:`ConverterContext.appstartaddr`, so for RP2350 firmware built at - ``0x10000000`` the caller passes ``--base 0x10000000``. - - Args: - file_content: The raw image. - ctx: Conversion state supplying the base address and family ID. - - Returns: - The UF2 file contents, always a whole number of 512-byte blocks. - """ - datapadding = bytes(UF2_BLOCK_SIZE - 256 - UF2_HEADER_SIZE - 4) - numblocks = (len(file_content) + 255) // 256 - flags = UF2_FLAG_FAMILY_ID if ctx.familyid else 0x0 - base = ctx.appstartaddr or 0 - - blocks: list[bytes] = [] - for blockno in range(numblocks): - ptr = 256 * blockno - chunk = file_content[ptr : ptr + 256] - header = _HEADER_STRUCT.pack( - UF2_MAGIC_START0, - UF2_MAGIC_START1, - flags, - ptr + base, - 256, - blockno, - numblocks, - ctx.familyid, - ) - payload = chunk + bytes(256 - len(chunk)) - block = header + payload + datapadding + struct.pack(" bytes: - """Render a binary as a C array initialiser for embedding in firmware. - - Args: - file_content: The raw image. - - Returns: - UTF-8 bytes of a C translation unit fragment. - """ - parts = [ - f"const unsigned long bindata_len = {len(file_content)};\n", - "const unsigned char bindata[] __attribute__((aligned(16))) = {", - ] - for index, value in enumerate(file_content): - if index % 16 == 0: - parts.append("\n") - parts.append(f"{value:#04x}, ") - parts.append("\n};\n") - return "".join(parts).encode() - - -# --------------------------------------------------------------------------- -# Intel HEX -> UF2 -# --------------------------------------------------------------------------- - - -@dataclass -class Block: - """A single 256-byte-aligned region of an image under construction. - - Attributes: - addr: Base address of the block, always 256-byte aligned. - data: The block's bytes, initialised to ``default_data``. - """ - - addr: int - data: bytearray - - def __init__(self, addr: int, default_data: int = 0xFF) -> None: - """Initialise an erased 256-byte block. - - Args: - addr: 256-byte-aligned base address of the block. - default_data: Fill byte; ``0xFF`` matches erased flash. - """ - self.addr = addr - self.data = bytearray([default_data] * 256) - - def encode(self, blockno: int, numblocks: int, ctx: ConverterContext) -> bytes: - """Serialise this block into a 512-byte UF2 block. - - Args: - blockno: Index of this block within the file. - numblocks: Total number of blocks in the file. - ctx: Conversion state supplying the family ID. - - Returns: - Exactly 512 bytes. - """ - flags = UF2_FLAG_FAMILY_ID if ctx.familyid else 0x0 - out = _HEADER_STRUCT.pack( - UF2_MAGIC_START0, - UF2_MAGIC_START1, - flags, - self.addr, - 256, - blockno, - numblocks, - ctx.familyid, - ) - out += self.data[0:256] - out += bytes(UF2_BLOCK_SIZE - 4 - len(out)) - out += struct.pack(" bytes: - """Assemble Intel HEX records into a UF2 file. - - Only record types 0x00 (data), 0x01 (EOF), 0x02 (extended segment address) - and 0x04 (extended linear address) are handled; any other type is ignored, - matching the upstream behaviour. - - Args: - text: Decoded Intel HEX file contents. - ctx: Conversion state; ``appstartaddr`` is set to the first data - address seen. - - Returns: - The UF2 file contents. - """ - ctx.appstartaddr = None - upper = 0 - currblock: Block | None = None - blocks: list[Block] = [] - - for line in text.split("\n"): - if not line.startswith(":"): - continue - record = [int(line[i : i + 2], 16) for i in range(1, len(line) - 1, 2)] - rec_type = record[3] - if rec_type == 4: - upper = ((record[4] << 8) | record[5]) << 16 - elif rec_type == 2: - upper = ((record[4] << 8) | record[5]) << 4 - elif rec_type == 1: - break - elif rec_type == 0: - addr = upper + ((record[1] << 8) | record[2]) - if ctx.appstartaddr is None: - ctx.appstartaddr = addr - index = 4 - while index < len(record) - 1: - if currblock is None or currblock.addr & ~0xFF != addr & ~0xFF: - currblock = Block(addr & ~0xFF) - blocks.append(currblock) - currblock.data[addr & 0xFF] = record[index] - addr += 1 - index += 1 - - numblocks = len(blocks) - return b"".join(blocks[i].encode(i, numblocks, ctx) for i in range(numblocks)) - - -# --------------------------------------------------------------------------- -# Drive discovery -# --------------------------------------------------------------------------- - - -def _iter_candidate_dirs() -> list[Path]: - """Return the directories that may contain mounted removable volumes.""" - if sys.platform == "win32": - return [] - - searchpaths = [Path("/mnt"), Path("/media")] - if sys.platform == "darwin": - searchpaths = [Path("/Volumes")] - elif sys.platform == "linux": - user = environ_user() - if user: - searchpaths += [Path("/media") / user, Path("/run/media") / user] - sudo_user = os.environ.get("SUDO_USER") - if sudo_user: - searchpaths += [ - Path("/media") / sudo_user, - Path("/run/media") / sudo_user, - ] - return searchpaths - - -def environ_user() -> str | None: - """Return the current user name from the environment. - - Tried under several variable names so the search works on macOS, Linux and - Windows shells alike. - - Returns: - The user name, or ``None`` if it cannot be determined. - """ - for var in ("USER", "USERNAME", "LOGNAME"): - value = os.environ.get(var) - if value: - return value - return None - - -def get_drives() -> list[Path]: - """Find mounted Pico boot drives. - - A drive qualifies when it contains the ``INFO_UF2.TXT`` marker the boot ROM - writes when it presents the flash as a USB mass-storage device. - - Returns: - Every qualifying mount point. - """ - drives: list[Path] = [] - - if sys.platform == "win32": - command = ( - "(Get-Volume | Where-Object { $_.FileSystemLabel -match 'RP2350|RPI-RP2' })" - ".DriveLetter" - ) - try: - raw = subprocess.check_output( - ["powershell", "-Command", command], - text=True, - ) - except (subprocess.CalledProcessError, FileNotFoundError, OSError): - return [] - for letter in raw.split(): - if len(letter) == 1 and letter.isalpha(): - drives.append(Path(f"{letter.upper()}:\\")) - return drives - - for rootpath in _iter_candidate_dirs(): - if not rootpath.is_dir(): - continue - try: - entries = list(rootpath.iterdir()) - except OSError: - continue - for entry in entries: - if not entry.is_dir(): - continue - if (entry / INFO_FILE).is_file(): - drives.append(entry) - return drives - - -def board_id(path: Path) -> str: - """Read the ``Board-ID`` field from a boot drive's info file. - - Args: - path: Mount point of the boot drive. - - Returns: - The board ID string, for example ``RP2350``. - - Raises: - Uf2Error: If the info file is missing or has no ``Board-ID`` field. - """ - info = path / INFO_FILE - if not info.is_file(): - msg = f"Not a Pico boot drive: {path} has no {INFO_FILE}" - raise Uf2Error(msg) - match = re.search(r"Board-ID: ([^\r\n]*)", info.read_text()) - if match is None: - msg = f"No Board-ID field in {info}" - raise Uf2Error(msg) - return match.group(1) - - -def list_drives() -> None: - """Print every connected Pico boot drive and its board ID.""" - for drive in get_drives(): - try: - print(drive, board_id(drive)) - except Uf2Error as exc: - print(f"{drive} ") - - -def write_file(name: Path | str, buf: bytes) -> None: - """Write a buffer to disk and report the size written. - - Args: - name: Destination path. - buf: Bytes to write. - """ - path = Path(name) - path.parent.mkdir(parents=True, exist_ok=True) - path.write_bytes(buf) - print(f"Wrote {len(buf)} bytes to {path}") - - -def load_families() -> dict[str, int]: - """Load the family-name to family-ID table. - - ``uf2families.json`` is read from the directory containing this script, so - the converter works regardless of the caller's working directory. - - Returns: - Mapping of upper-case short name to family ID. - - Raises: - Uf2Error: If the JSON file is missing or malformed. - """ - pathname = Path(__file__).resolve().parent / "uf2families.json" - try: - raw_families = json.loads(pathname.read_text()) - except FileNotFoundError as exc: - msg = f"Required family table not found: {pathname}" - raise Uf2Error(msg) from exc - except json.JSONDecodeError as exc: - msg = f"Malformed family table {pathname}: {exc}" - raise Uf2Error(msg) from exc - - return {fam["short_name"]: int(fam["id"], 0) for fam in raw_families} - - -# --------------------------------------------------------------------------- -# CLI -# --------------------------------------------------------------------------- - - -def _build_parser() -> argparse.ArgumentParser: - """Construct the command-line argument parser. - - Returns: - A configured :class:`argparse.ArgumentParser`. - """ - parser = argparse.ArgumentParser( - prog="uf2conv.py", - description="Convert firmware between Intel HEX, raw BIN and UF2.", - epilog=( - "Course example (RP2350 raw image built for XIP flash):\n" - " python ../uf2conv.py build/image-h.bin " - "--base 0x10000000 \\\n" - " --family 0xe48bff59 --output build/hacked.uf2\n" - ), - formatter_class=argparse.RawDescriptionHelpFormatter, - ) - parser.add_argument( - "input", - metavar="INPUT", - nargs="?", - help="input file (HEX, BIN or UF2); omit when using --list", - ) - parser.add_argument( - "-b", - "--base", - default=hex(DEFAULT_BASE_ADDRESS), - help=( - "base address of the application for BIN input " - f"(default: {hex(DEFAULT_BASE_ADDRESS)}; use 0x10000000 for RP2350 XIP)" - ), - ) - parser.add_argument( - "-f", - "--family", - default=hex(DEFAULT_FAMILY_ID), - help=( - "family ID as a number or a name from uf2families.json " - f"(default: {hex(DEFAULT_FAMILY_ID)}; RP2350 is 0xe48bff59)" - ), - ) - parser.add_argument( - "-o", - "--output", - metavar="FILE", - help='write output to FILE; defaults to "flash.uf2" or "flash.bin"', - ) - parser.add_argument( - "-d", - "--device", - dest="device_path", - help="select a specific device path to flash (reserved; unused)", - ) - parser.add_argument( - "-l", - "--list", - action="store_true", - help="list connected Pico boot drives and exit", - ) - parser.add_argument( - "-c", - "--convert", - action="store_true", - help="convert only; do not deploy to a mounted boot drive", - ) - parser.add_argument( - "-D", - "--deploy", - action="store_true", - help="deploy the input file unchanged; do not convert", - ) - parser.add_argument( - "-w", - "--wait", - action="store_true", - help="poll for a boot drive to appear instead of failing immediately", - ) - parser.add_argument( - "-C", - "--carray", - action="store_true", - help="emit a C array initialiser instead of a UF2 file", - ) - parser.add_argument( - "-i", - "--info", - action="store_true", - help="print UF2 header information and exit without converting", - ) - return parser - - -def _resolve_family(spec: str) -> int: - """Resolve a ``--family`` value to a numeric family ID. - - Args: - spec: Either a family short name (case-insensitive) or an integer - literal such as ``0xe48bff59``. - - Returns: - The numeric family ID. - - Raises: - Uf2Error: If the value is neither a known name nor a valid integer. - """ - families = load_families() - if spec.upper() in families: - return families[spec.upper()] - try: - return int(spec, 0) - except ValueError as exc: - msg = "Family ID needs to be a number or one of: " + ", ".join(families) - raise Uf2Error(msg) from exc - - -def _wait_for_drive() -> Path | None: - """Poll for a boot drive to be mounted. - - Returns: - The first drive found, or ``None`` if the wait was interrupted. - """ - print("Waiting for drive to deploy...") - while True: - drives = get_drives() - if drives: - return drives[0] - sleep(0.1) - - -def main(argv: list[str] | None = None) -> int: - """Run the command-line converter. - - Args: - argv: Argument list, defaulting to :data:`sys.argv` ``[1:]``. - - Returns: - ``0`` on success, ``1`` on a user or input error. - """ - parser = _build_parser() - args = parser.parse_args(argv) - - ctx = ConverterContext() - try: - ctx.familyid = _resolve_family(args.family) - ctx.appstartaddr = int(args.base, 0) - except (Uf2Error, ValueError) as exc: - print(exc, file=sys.stderr) - return 1 - - if args.list: - list_drives() - return 0 - - if not args.input: - print("Need an input file (or use --list)", file=sys.stderr) - return 1 - - source = Path(args.input) - if not source.is_file(): - print(f"error: file not found: {source}", file=sys.stderr) - return 1 - - inpbuf = source.read_bytes() - from_uf2 = is_uf2(inpbuf) - ext = "uf2" - - try: - if args.deploy: - outbuf = inpbuf - elif from_uf2 and not args.info: - outbuf = convert_from_uf2(inpbuf, ctx) - ext = "bin" - elif from_uf2 and args.info: - outbuf = b"" - convert_from_uf2(inpbuf, ctx) - elif is_hex(inpbuf): - outbuf = convert_from_hex_to_uf2(inpbuf.decode("utf-8"), ctx) - elif args.carray: - outbuf = convert_to_carray(inpbuf) - ext = "h" - else: - outbuf = convert_to_uf2(inpbuf, ctx) - except Uf2Error as exc: - print(f"error: {exc}", file=sys.stderr) - return 1 - - if not args.deploy and not args.info: - print( - f"Converted to {ext}, output size: {len(outbuf)}, " - f"start address: {ctx.appstartaddr or 0:#x}", - ) - - if (args.convert or ext != "uf2") and args.output is None: - args.output = f"flash.{ext}" - if args.output: - write_file(args.output, outbuf) - - if ext == "uf2" and not args.convert and not args.info: - drives = get_drives() - if not drives: - if args.wait: - found = _wait_for_drive() - drives = [found] if found else [] - elif not args.output: - print("error: no drive to deploy", file=sys.stderr) - return 1 - for drive in drives: - print(f"Flashing {drive} ({board_id(drive)})") - write_file(drive / "NEW.UF2", outbuf) - - return 0 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/0x001aa_cb/scripts/uf2families.json b/0x001aa_cb/scripts/uf2families.json deleted file mode 100644 index 39373c4..0000000 --- a/0x001aa_cb/scripts/uf2families.json +++ /dev/null @@ -1,22 +0,0 @@ -[ - { - "short_name": "RP2040", - "id": "0xe48bff56", - "description": "Raspberry Pi RP2040" - }, - { - "short_name": "RP2350-ARM-S", - "id": "0xe48bff59", - "description": "Raspberry Pi RP2350, ARM, Secure" - }, - { - "short_name": "RP2350-ARM-NS", - "id": "0xe48bff5a", - "description": "Raspberry Pi RP2350, ARM, Non-Secure" - }, - { - "short_name": "RP2350-RISCV", - "id": "0xe48bff5b", - "description": "Raspberry Pi RP2350, RISC-V" - } -] \ No newline at end of file diff --git a/0x001aa_cb/src/crypto.c b/0x001aa_cb/src/crypto.c deleted file mode 100644 index fe73ef9..0000000 --- a/0x001aa_cb/src/crypto.c +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @file crypto.c - * @brief Lightweight rolling cipher implementation for Operation Iron Net - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#include "crypto.h" - -static const uint8_t CIPHERTEXT[TOKEN_LEN] = { - 0x1A, 0x07, 0x03, 0x18, 0x06, 0x12, 0x65, 0x64 -}; - -static const uint8_t CIPHER_KEY[4] = { - 0x49, 0x52, 0x4F, 0x4E -}; - -void decrypt_auth_token(uint8_t *dest) { - volatile const uint8_t *src = CIPHERTEXT; - volatile const uint8_t *key = CIPHER_KEY; - for (size_t i = 0; i < TOKEN_LEN; i++) { - dest[i] = src[i] ^ (key[i % 4] + (uint8_t)i); - } -} diff --git a/0x001aa_cb/src/dht11.c b/0x001aa_cb/src/dht11.c deleted file mode 100644 index 4189076..0000000 --- a/0x001aa_cb/src/dht11.c +++ /dev/null @@ -1,148 +0,0 @@ -/** - * @file dht11.c - * @brief Operation Iron Net Firmware - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#include "dht11.h" -#include "hardware/gpio.h" -#include "pico/stdlib.h" -#include "pico/time.h" - -static dht11_data_t g_current_reading; - -/** - * @brief Block until the data pin reaches a level or a timeout expires. - * @param level Logic level to wait for (true high, false low). - * @param timeout_us Maximum time to wait in microseconds. - * @return true when the level was observed, false on timeout. - */ -static bool dht11_wait_for(bool level, uint32_t timeout_us) { - uint64_t start = time_us_64(); - while (gpio_get(DHT11_PIN) != level) { - if ((uint32_t)(time_us_64() - start) > timeout_us) { - return false; - } - } - return true; -} - -/** - * @brief Drive the 18 ms start pulse and wait for the sensor response. - * @param void No parameters. - * @return true when the response handshake was seen, false otherwise. - */ -static bool dht11_start_signal(void) { - gpio_set_dir(DHT11_PIN, GPIO_OUT); - gpio_put(DHT11_PIN, 0); - sleep_ms(20); - gpio_set_dir(DHT11_PIN, GPIO_IN); - return dht11_wait_for(false, 100) - && dht11_wait_for(true, 100) - && dht11_wait_for(false, 100); -} - -/** - * @brief Measure a single high pulse and return its decoded bit value. - * @param void No parameters. - * @return 1 for a long pulse, 0 for a short pulse, or -1 on timeout. - */ -static int dht11_read_bit(void) { - if (!dht11_wait_for(true, 100)) { - return -1; - } - uint64_t high_start = time_us_64(); - if (!dht11_wait_for(false, 100)) { - return -1; - } - return ((uint32_t)(time_us_64() - high_start) > 40) ? 1 : 0; -} - -/** - * @brief Sample the 40 data bits by measuring each high pulse width. - * @param bytes Output buffer receiving the five decoded bytes. - * @return true when all forty bits were captured, false on timeout. - */ -static bool dht11_capture_bits(uint8_t *bytes) { - for (int i = 0; i < 40; i++) { - int bit = dht11_read_bit(); - if (bit < 0) { - return false; - } - bytes[i / 8] = (uint8_t)((bytes[i / 8] << 1) | bit); - } - return true; -} - -/** - * @brief Verify the frame checksum equals the low byte of the data sum. - * @param bytes Pointer to the five decoded frame bytes. - * @return true when the checksum matches, false otherwise. - */ -static bool dht11_checksum_ok(const uint8_t *bytes) { - uint8_t sum = bytes[0] + bytes[1] + bytes[2] + bytes[3]; - return sum == bytes[4]; -} - -/** - * @brief Copy the validated frame bytes into the reading structure. - * @param out Pointer to the reading structure to populate. - * @param bytes Pointer to the five decoded frame bytes. - * @return void No return value. - */ -static void dht11_store_bytes(dht11_data_t *out, const uint8_t *bytes) { - out->humidity_int = bytes[0]; - out->humidity_dec = bytes[1]; - out->temp_int = bytes[2]; - out->temp_dec = bytes[3]; - out->checksum = bytes[4]; - out->valid = true; -} - -/** - * @brief Run the start handshake and capture the five frame bytes. - * @param bytes Output buffer receiving the five decoded bytes. - * @return true when the handshake and capture both succeeded. - */ -static bool dht11_collect_frame(uint8_t *bytes) { - if (!dht11_start_signal()) { - return false; - } - return dht11_capture_bits(bytes); -} - -/** - * @brief Issue the start pulse and reconstruct the five sensor bytes. - * @param out Pointer to the reading structure to populate. - * @return true when a valid checksum frame was decoded, false otherwise. - */ -static bool dht11_read_frame(dht11_data_t *out) { - uint8_t bytes[5] = {0}; - if (!dht11_collect_frame(bytes)) { - return false; - } - if (dht11_checksum_ok(bytes)) { - dht11_store_bytes(out, bytes); - return true; - } - return false; -} - -void dht11_init(void) { - gpio_init(DHT11_PIN); - gpio_set_dir(DHT11_PIN, GPIO_OUT); - gpio_put(DHT11_PIN, 1); - g_current_reading.valid = false; -} - -dht11_data_t* dht11_read(void) { - g_current_reading.valid = false; - if (!dht11_read_frame(&g_current_reading)) { - g_current_reading.valid = false; - } - return &g_current_reading; -} diff --git a/0x001aa_cb/src/gpio_ctrl.c b/0x001aa_cb/src/gpio_ctrl.c deleted file mode 100644 index 4f7fb49..0000000 --- a/0x001aa_cb/src/gpio_ctrl.c +++ /dev/null @@ -1,78 +0,0 @@ -/** - * @file gpio_ctrl.c - * @brief GPIO hardware control implementation for Operation Iron Net - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#include "gpio_ctrl.h" -#include "pico/stdlib.h" - -/** - * @brief Initialize the red and green status LED pins as outputs. - * @param void No parameters. - * @return void No return value. - */ -static void init_led_pins(void) { - gpio_init(LED_RED_PIN); - gpio_set_dir(LED_RED_PIN, GPIO_OUT); - gpio_init(LED_GREEN_PIN); - gpio_set_dir(LED_GREEN_PIN, GPIO_OUT); -} - -/** - * @brief Initialize the payload marker pin as a low output. - * @param void No parameters. - * @return void No return value. - */ -static void init_payload_pin(void) { - gpio_init(PAYLOAD_PIN); - gpio_set_dir(PAYLOAD_PIN, GPIO_OUT); - gpio_put(PAYLOAD_PIN, 0); -} - -/** - * @brief Initialize the tamper loop pin as a pulled-down input. - * @param void No parameters. - * @return void No return value. - */ -static void init_tamper_pin(void) { - gpio_init(TAMPER_PIN); - gpio_set_dir(TAMPER_PIN, GPIO_IN); - gpio_pull_down(TAMPER_PIN); -} - -void init_gpio(void) { - init_led_pins(); - init_payload_pin(); - init_tamper_pin(); - set_led_armed(); -} - -void set_led_armed(void) { - gpio_put(LED_RED_PIN, 1); - gpio_put(LED_GREEN_PIN, 0); -} - -void set_led_authorized(void) { - gpio_put(LED_RED_PIN, 0); - gpio_put(LED_GREEN_PIN, 1); -} - -void set_led_tamper_flash(bool state) { - gpio_put(LED_RED_PIN, state ? 1 : 0); - gpio_put(LED_GREEN_PIN, 0); -} - -bool is_tamper_wire_intact(void) { - return gpio_get(TAMPER_PIN); -} - -void payload_deploy(void) { - gpio_put(PAYLOAD_PIN, 1); - sleep_ms(250); - gpio_put(PAYLOAD_PIN, 0); -} diff --git a/0x001aa_cb/src/logic.c b/0x001aa_cb/src/logic.c deleted file mode 100644 index b86d685..0000000 --- a/0x001aa_cb/src/logic.c +++ /dev/null @@ -1,194 +0,0 @@ -/** - * @file logic.c - * @brief Operation Iron Net Firmware - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#include "logic.h" -#include "dht11.h" -#include "crypto.h" -#include "gpio_ctrl.h" -#include "lora.h" -#include -#include - -static volatile const uint8_t s_env_mask = 0xAF; -static volatile const uint8_t s_env_pattern = 0x18; -static uint8_t s_auth_token[TOKEN_LEN + 1]; -static uint8_t g_strike_state = STATE_ENV_ARMED; -static uint8_t g_tamper_faults = 0; -static bool g_env_ok = false; -static bool g_authorized = false; - -/** - * @brief Print the armed status banner to the console. - * @param void No parameters. - * @return void No return value. - */ -static void print_banner_armed(void) { - printf("\r\n+-----------------------------------------------------------------+\r\n"); - printf("| OPERATION IRON NET // SENSOR NODE |\r\n"); - printf("| STATUS: ARMED [GP16 RED: ON] LORA RECEIVER: LIVE |\r\n"); - printf("+-----------------------------------------------------------------+\r\n"); -} - -/** - * @brief Print the payload-authorized banner to the console. - * @param void No parameters. - * @return void No return value. - */ -static void print_banner_authorized(void) { - printf("\r\n+-----------------------------------------------------------------+\r\n"); - printf("| STRIKE AUTHORIZED // MARKER DEPLOYED [GP17 GREEN: ON] |\r\n"); - printf("+-----------------------------------------------------------------+\r\n"); -} - -/** - * @brief Print the tamper lockout banner to the console. - * @param void No parameters. - * @return void No return value. - */ -static void print_banner_lockout(void) { - printf("\r\n+-----------------------------------------------------------------+\r\n"); - printf("| NODE LOCKOUT [GP16 RED: FLASH] |\r\n"); - printf("| STATUS: TAMPER INTEGRITY FAULT // REBOOT REQUIRED |\r\n"); - printf("+-----------------------------------------------------------------+\r\n"); -} - -/** - * @brief Copy the low byte of the DHT11 frame into a stored sample. - * @param reading Pointer to the latest validated sensor reading. - * @return true when the bitwise environment gate is satisfied. - */ -static bool env_matches(const dht11_data_t *reading) { - uint8_t calculated = (reading->humidity_int ^ s_env_mask) & 0x3C; - return calculated == s_env_pattern; -} - -/** - * @brief Print the sensor frame invalid message and increment the fault counter. - * @param faults Pointer to the tamper fault counter. - * @return void No return value. - */ -static void log_invalid_frame(uint8_t *faults) { - printf("[-] SENSOR FRAME INVALID. FAULT LOGGED.\r\n"); - (*faults)++; -} - -/** - * @brief Print the sensor reading data to the console. - * @param reading Pointer to the validated sensor reading. - * @return void No return value. - */ -static void log_reading(const dht11_data_t *reading) { - printf("[*] ENV RH %u.%u%% T %u.%uC\r\n", reading->humidity_int, - reading->humidity_dec, reading->temp_int, reading->temp_dec); -} - -/** - * @brief Read the sensor and update the environment gate result. - * @param faults Pointer to the tamper fault counter. - * @return void No return value. - */ -static void evaluate_sensor(uint8_t *faults) { - dht11_data_t *reading = dht11_read(); - if (!reading->valid) { - log_invalid_frame(faults); - return; - } - log_reading(reading); - if (!g_env_ok) { - g_env_ok = env_matches(reading); - } -} - -/** - * @brief Poll the radio and set the authorization flag on a token match. - * @param faults Pointer to the tamper fault counter. - * @return void No return value. - */ -static void evaluate_uplink(uint8_t *faults) { - char pkt[64] = {0}; - if (!lora_poll_packet(pkt, sizeof(pkt))) { - return; - } - if (strncmp(pkt, (const char *)s_auth_token, TOKEN_LEN) == 0) { - g_authorized = true; - printf("[+] AUTHORIZATION TOKEN ACCEPTED.\r\n"); - } else { - printf("[-] INVALID AUTHORIZATION TOKEN.\r\n"); - (*faults)++; - } -} - -/** - * @brief Trip the node when fault limits or the tamper loop demand it. - * @param faults Current tamper fault count. - * @return void No return value. - */ -static void check_trap(uint8_t faults) { - if (g_strike_state == STATE_ENV_LOCKOUT) { - return; - } - if (faults >= 3 || !is_tamper_wire_intact()) { - g_strike_state = STATE_ENV_LOCKOUT; - print_banner_lockout(); - } -} - -/** - * @brief Deploy the payload when the environment and token both pass. - * @param void No parameters. - * @return void No return value. - */ -static void try_deploy(void) { - if (g_strike_state == STATE_ENV_AUTHORIZED) { - return; - } - if (g_env_ok && g_authorized) { - g_strike_state = STATE_ENV_AUTHORIZED; - payload_deploy(); - lora_send("STRIKE AUTHORIZED // MARKER DEPLOYED"); - print_banner_authorized(); - } else { - printf("[-] ENVIRONMENT SUB-OPTIMAL. HOLDING.\r\n"); - } -} - -/** - * @brief Drive LED feedback for the current strike state. - * @param state Current strike state byte. - * @param tick_idx Monotonic loop tick index for flash timing. - * @return void No return value. - */ -static void update_feedback(uint8_t state, uint32_t tick_idx) { - if (state == STATE_ENV_AUTHORIZED) { - set_led_authorized(); - } else if (state == STATE_ENV_LOCKOUT) { - set_led_tamper_flash((tick_idx % 2) == 0); - } else { - set_led_armed(); - } -} - -void evaluate_environment(void) { - static uint32_t ticks = 0; - if (g_strike_state != STATE_ENV_LOCKOUT) { - evaluate_sensor(&g_tamper_faults); - evaluate_uplink(&g_tamper_faults); - check_trap(g_tamper_faults); - try_deploy(); - } - update_feedback(g_strike_state, ticks++); -} - -void init_strike_controller(void) { - decrypt_auth_token(s_auth_token); - s_auth_token[TOKEN_LEN] = '\0'; - init_lora(); - print_banner_armed(); -} diff --git a/0x001aa_cb/src/lora.c b/0x001aa_cb/src/lora.c deleted file mode 100644 index 2d8af37..0000000 --- a/0x001aa_cb/src/lora.c +++ /dev/null @@ -1,151 +0,0 @@ -// 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. -// -// Author: Kevin Thomas -// Email: kevin@mytechnotalent.com -// GitHub: https://github.com/mytechnotalent -// File: lora.c -// Desc: Implements UART1 driver for REYAX RYLR998 LoRa transceiver. -// Created: 2026 - -#include "lora.h" -#include "hardware/gpio.h" -#include "pico/stdlib.h" -#include -#include - -/** - * @brief Discard all pending bytes from the LoRa UART receive FIFO. - * @param void No parameters. - * @return void No return value. - */ -static void drain_lora_rx(void) { - while (uart_is_readable(LORA_UART)) { - (void)uart_getc(LORA_UART); - } -} - -/** - * @brief Send an AT command to the radio and drain its response. - * @param cmd Null-terminated AT command string to transmit. - * @return void No return value. - */ -static void send_at_cmd(const char *cmd) { - uart_write_blocking(LORA_UART, (const uint8_t *)cmd, strlen(cmd)); - sleep_ms(200); - drain_lora_rx(); -} - -/** - * @brief Program the RYLR998 RF parameters via the AT command set. - * @param void No parameters. - * @return void No return value. - */ -static void configure_lora_rf(void) { - sleep_ms(1500); - send_at_cmd("AT\r\n"); - send_at_cmd("AT+NETWORKID=18\r\n"); - send_at_cmd("AT+BAND=915000000\r\n"); - send_at_cmd("AT+PARAMETER=9,7,1,12\r\n"); - send_at_cmd("AT+ADDRESS=3\r\n"); -} - -void init_lora(void) { - uart_init(LORA_UART, LORA_BAUD); - uart_set_translate_crlf(LORA_UART, false); - gpio_set_function(LORA_TX_PIN, GPIO_FUNC_UART); - gpio_set_function(LORA_RX_PIN, GPIO_FUNC_UART); - configure_lora_rf(); -} - -void lora_send(const char *msg) { - char cmd[128]; - int len = (int)strlen(msg); - snprintf(cmd, sizeof(cmd), "AT+SEND=0,%d,%s\r\n", len, msg); - uart_write_blocking(LORA_UART, (const uint8_t *)cmd, strlen(cmd)); -} - -/** - * @brief Extract the payload field from a +RCV receive line. - * @param line Mutable receive line buffer to parse. - * @param out Buffer receiving the extracted payload string. - * @param max_len Capacity of out in bytes. - * @return true when the payload was extracted, false otherwise. - */ -static bool extract_rcv_data(char *line, char *out, size_t max_len) { - char *c1 = strchr(line, ','); - if (!c1) return false; - char *c2 = strchr(c1 + 1, ','); - if (!c2) return false; - char *c3 = strchr(c2 + 1, ','); - if (c3) *c3 = '\0'; - snprintf(out, max_len, "%s", c2 + 1); - return true; -} - -/** - * @brief Parse one complete UART line and capture payload data. - * @param line Mutable line buffer to parse. - * @param out Buffer receiving the extracted payload string. - * @param max_len Capacity of out in bytes. - * @return true when the line carried payload data, false otherwise. - */ -static bool parse_line(char *line, char *out, size_t max_len) { - if (strstr(line, "+RCV=")) - return extract_rcv_data(line, out, max_len); - if (strncmp(line, "+", 1) != 0 && strncmp(line, "OK", 2) != 0) { - snprintf(out, max_len, "%s", line); - return true; - } - return false; -} - -/** - * @brief Feed one received byte into the line assembly state machine. - * @param c Received byte to process. - * @param buf Line assembly buffer. - * @param idx Pointer to the current write index into buf. - * @param out Buffer receiving the extracted payload string. - * @param max_len Capacity of out in bytes. - * @return true when a complete payload was produced, false otherwise. - */ -static bool process_rx_byte(char c, char *buf, size_t *idx, char *out, size_t max_len) { - if (c == '\r' || c == '\n') { - buf[*idx] = '\0'; - bool ok = (*idx > 0) && parse_line(buf, out, max_len); - *idx = 0; - return ok; - } - if (*idx < 127) buf[(*idx)++] = c; - return false; -} - -bool lora_poll_packet(char *payload_out, size_t max_len) { - static char buf[128]; - static size_t idx = 0; - while (uart_is_readable(LORA_UART)) { - char c = (char)uart_getc(LORA_UART); - if (process_rx_byte(c, buf, &idx, payload_out, max_len)) - return true; - } - return false; -} diff --git a/0x001aa_cb/src/main.c b/0x001aa_cb/src/main.c deleted file mode 100644 index e89f983..0000000 --- a/0x001aa_cb/src/main.c +++ /dev/null @@ -1,45 +0,0 @@ -/** - * @file main.c - * @brief Operation Iron Net Firmware - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#include -#include "pico/stdlib.h" -#include "gpio_ctrl.h" -#include "dht11.h" -#include "logic.h" - -/** - * @brief Initialize stdio, GPIO, the sensor, and the strike controller. - * @param void No parameters. - * @return void No return value. - */ -static void init_system(void) { - stdio_init_all(); - init_gpio(); - dht11_init(); - init_strike_controller(); -} - -/** - * @brief Run the main event loop, servicing one sensor tick per iteration. - * @param void No parameters. - * @return void No return value. - */ -static void run_event_loop(void) { - while (true) { - evaluate_environment(); - sleep_ms(1500); - } -} - -int main(void) { - init_system(); - run_event_loop(); - return 0; -} diff --git a/0x001d_static-conditionals/.gitignore b/0x001d_static-conditionals/.gitignore deleted file mode 100644 index 2435c20..0000000 --- a/0x001d_static-conditionals/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -!.vscode/* diff --git a/0x001d_static-conditionals/.vscode/c_cpp_properties.json b/0x001d_static-conditionals/.vscode/c_cpp_properties.json deleted file mode 100644 index c429d6d..0000000 --- a/0x001d_static-conditionals/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "configurations": [ - { - "name": "Pico", - "includePath": [ - "${workspaceFolder}/**", - "${userHome}/.pico-sdk/sdk/2.2.0/**" - ], - "forcedInclude": [ - "${workspaceFolder}/build/generated/pico_base/pico/config_autogen.h", - "${userHome}/.pico-sdk/sdk/2.2.0/src/common/pico_base_headers/include/pico.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 -} diff --git a/0x001d_static-conditionals/.vscode/cmake-kits.json b/0x001d_static-conditionals/.vscode/cmake-kits.json deleted file mode 100644 index b0f3815..0000000 --- a/0x001d_static-conditionals/.vscode/cmake-kits.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "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}" - } - } -] \ No newline at end of file diff --git a/0x001d_static-conditionals/.vscode/extensions.json b/0x001d_static-conditionals/.vscode/extensions.json deleted file mode 100644 index a940d7c..0000000 --- a/0x001d_static-conditionals/.vscode/extensions.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "recommendations": [ - "marus25.cortex-debug", - "ms-vscode.cpptools", - "ms-vscode.cpptools-extension-pack", - "ms-vscode.vscode-serial-monitor", - "raspberry-pi.raspberry-pi-pico" - ] -} \ No newline at end of file diff --git a/0x001d_static-conditionals/.vscode/launch.json b/0x001d_static-conditionals/.vscode/launch.json deleted file mode 100644 index 424aa71..0000000 --- a/0x001d_static-conditionals/.vscode/launch.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "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}\"" - ] - }, - ] -} diff --git a/0x001d_static-conditionals/.vscode/settings.json b/0x001d_static-conditionals/.vscode/settings.json deleted file mode 100644 index 95be83b..0000000 --- a/0x001d_static-conditionals/.vscode/settings.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "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" -} diff --git a/0x001d_static-conditionals/.vscode/tasks.json b/0x001d_static-conditionals/.vscode/tasks.json deleted file mode 100644 index d1b3193..0000000 --- a/0x001d_static-conditionals/.vscode/tasks.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Compile Project", - "type": "process", - "isBuildCommand": true, - "command": "${userHome}/.pico-sdk/ninja/v1.12.1/ninja", - "args": ["-C", "${workspaceFolder}/build"], - "group": "build", - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": "$gcc", - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/ninja/v1.12.1/ninja.exe" - } - }, - { - "label": "Run Project", - "type": "process", - "command": "${env:HOME}/.pico-sdk/picotool/2.2.0-a4/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-a4/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", - } - } - ] -} diff --git a/0x001d_static-conditionals/0x001d_static-conditionals.c b/0x001d_static-conditionals/0x001d_static-conditionals.c deleted file mode 100644 index 8ad9328..0000000 --- a/0x001d_static-conditionals/0x001d_static-conditionals.c +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include "pico/stdlib.h" -#include "servo.h" - -#define SERVO_GPIO 6 - -int main(void) { - stdio_init_all(); - - int choice = 1; - - servo_init(SERVO_GPIO); - - while (true) { - if (choice == 1) { - printf("1\r\n"); - } else if (choice == 2) { - printf("2\r\n"); - } else { - printf("?\r\n"); - } - - switch (choice) { - case 1: - printf("one\r\n"); - break; - case 2: - printf("two\r\n"); - break; - default: - printf("??\r\n"); - } - - servo_set_angle(0.0f); - sleep_ms(500); - servo_set_angle(180.0f); - sleep_ms(500); - } -} \ No newline at end of file diff --git a/0x001d_static-conditionals/CMakeLists.txt b/0x001d_static-conditionals/CMakeLists.txt deleted file mode 100644 index 7b03b00..0000000 --- a/0x001d_static-conditionals/CMakeLists.txt +++ /dev/null @@ -1,59 +0,0 @@ -# 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-a4) -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(0x001d_static-conditionals 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(0x001d_static-conditionals 0x001d_static-conditionals.c servo.c) - -pico_set_program_name(0x001d_static-conditionals "0x001d_static-conditionals") -pico_set_program_version(0x001d_static-conditionals "0.1") - -# Modify the below lines to enable/disable output over UART/USB -pico_enable_stdio_uart(0x001d_static-conditionals 1) -pico_enable_stdio_usb(0x001d_static-conditionals 0) - -# Add the standard library to the build -target_link_libraries(0x001d_static-conditionals - pico_stdlib - hardware_pwm - hardware_clocks) - -# Add the standard include files to the build -target_include_directories(0x001d_static-conditionals PRIVATE - ${CMAKE_CURRENT_LIST_DIR} -) - -pico_add_extra_outputs(0x001d_static-conditionals) - diff --git a/0x001d_static-conditionals/pico_sdk_import.cmake b/0x001d_static-conditionals/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x001d_static-conditionals/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x001d_static-conditionals/servo.c b/0x001d_static-conditionals/servo.c deleted file mode 100644 index ee48f0d..0000000 --- a/0x001d_static-conditionals/servo.c +++ /dev/null @@ -1,89 +0,0 @@ -/** - * @file servo.c - * @brief Implementation of a simple SG90 servo driver using PWM (50Hz) - * @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 "servo.h" -#include "pico/stdlib.h" -#include "hardware/pwm.h" -#include "hardware/clocks.h" - -// Default servo pulse range (SG90 typical) -static const uint16_t SERVO_DEFAULT_MIN_US = 1000; -static const uint16_t SERVO_DEFAULT_MAX_US = 2000; - -// internal state -static uint8_t servo_pin = 0; -static uint servo_slice = 0; -static uint servo_chan = 0; -static uint32_t servo_wrap = 20000 - 1; // wrap to map microseconds for 50Hz -static float servo_hz = 50.0f; - -// Convert microsecond pulse to PWM level based on wrap and frequency -static uint32_t pulse_us_to_level(uint32_t pulse_us) { - const float period_us = 1000000.0f / servo_hz; // 20000us - float counts_per_us = (servo_wrap + 1) / period_us; - return (uint32_t)(pulse_us * counts_per_us + 0.5f); -} - -void servo_init(uint8_t pin) { - servo_pin = pin; - - // Configure GPIO for PWM - gpio_set_function(servo_pin, GPIO_FUNC_PWM); - servo_slice = pwm_gpio_to_slice_num(servo_pin); - servo_chan = pwm_gpio_to_channel(servo_pin); - - pwm_config config = pwm_get_default_config(); - - // Calculate clock divider to achieve 50 Hz with our chosen wrap - const uint32_t sys_clock_hz = clock_get_hz(clk_sys); - float clock_div = (float)sys_clock_hz / (servo_hz * (servo_wrap + 1)); - - pwm_config_set_clkdiv(&config, clock_div); - pwm_config_set_wrap(&config, servo_wrap); - pwm_init(servo_slice, &config, true); -} - -void servo_set_pulse_us(uint16_t pulse_us) { - if (servo_pin == 0) return; // not initialized - // clamp to defaults - if (pulse_us < SERVO_DEFAULT_MIN_US) pulse_us = SERVO_DEFAULT_MIN_US; - if (pulse_us > SERVO_DEFAULT_MAX_US) pulse_us = SERVO_DEFAULT_MAX_US; - uint32_t level = pulse_us_to_level(pulse_us); - pwm_set_chan_level(servo_slice, servo_chan, level); -} - -void servo_set_angle(float degrees) { - if (degrees < 0.0f) degrees = 0.0f; - if (degrees > 180.0f) degrees = 180.0f; - // linear map 0..180 -> min_us..max_us - float ratio = degrees / 180.0f; - uint16_t pulse = (uint16_t)(SERVO_DEFAULT_MIN_US + ratio * (SERVO_DEFAULT_MAX_US - SERVO_DEFAULT_MIN_US) + 0.5f); - servo_set_pulse_us(pulse); -} -# \ No newline at end of file diff --git a/0x001d_static-conditionals/servo.h b/0x001d_static-conditionals/servo.h deleted file mode 100644 index 878d029..0000000 --- a/0x001d_static-conditionals/servo.h +++ /dev/null @@ -1,62 +0,0 @@ -/** - * @file servo.h - * @brief Header for SG90 servo driver (PWM) - * @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 SERVO_H -#define SERVO_H - -#include -#include - -/** - * @brief Initialize servo driver on a given GPIO pin - * - * Configures PWM for a 50 Hz servo (SG90). Call once before using other API. - * - * @param pin GPIO pin number to use for servo PWM - */ -void servo_init(uint8_t pin); - -/** - * @brief Set servo pulse width in microseconds (typical 1000-2000) - * - * @param pulse_us Pulse width in microseconds - */ -void servo_set_pulse_us(uint16_t pulse_us); - -/** - * @brief Set servo angle in degrees (0 to 180) - * - * Maps 0..180 degrees to the configured pulse range (default 1000..2000 us). - * Values outside [0,180] will be clamped. - * - * @param degrees Angle in degrees - */ -void servo_set_angle(float degrees); - -#endif // SERVO_H diff --git a/0x001da_cb/0x001da_cb.bin b/0x001da_cb/0x001da_cb.bin deleted file mode 100755 index 84733b1..0000000 Binary files a/0x001da_cb/0x001da_cb.bin and /dev/null differ diff --git a/0x001da_cb/0x001da_cb.uf2 b/0x001da_cb/0x001da_cb.uf2 deleted file mode 100644 index aa6004a..0000000 Binary files a/0x001da_cb/0x001da_cb.uf2 and /dev/null differ diff --git a/0x001da_cb/CLASSIFIED-BRIEF-0x04.md b/0x001da_cb/CLASSIFIED-BRIEF-0x04.md deleted file mode 100644 index d9bb190..0000000 --- a/0x001da_cb/CLASSIFIED-BRIEF-0x04.md +++ /dev/null @@ -1,162 +0,0 @@ -# Operation Broken Wing: Classified Intelligence Briefing - -``` -+-----------------------------------------------------------------+ -| TOP SECRET // NOFORN | -+-----------------------------------------------------------------+ -| | -|OPERATION BROKEN WING | -| | -|CLASSIFIED BRIEFING: LIVE CHALLENGE 0x04 | -| | -|NATIONAL SECURITY AGENCY / GMU RHET | -+-----------------------------------------------------------------+ -``` - -## 1. The Advice - -INT. NSA EXPLOITATION CELL. 03:25. - -A heavy-lift composite UAS payload cradle sits clamped to the steel bench, its -servicing hatch removed. Suspended beneath the chassis is a sealed canister -secured by an SG90 servo motor actuator latch. - -On the front plate of the payload controller, a status diode glows a sharp red: -`GP16` driven high. Beside it, the USB debug interface streams periodic -telemetry frames to a monitoring terminal: -`[-] ALTITUDE 0. PWM LOCKED: SAFETY ENGAGED.` - -The Director enters the secure bay, sets down a mission folder, and stares at -the red diode. - -**DIRECTOR:** What is in that bay? - -**ANALYST:** Hazardous cargo. An adversary heavy-lift transport drone brought -down intact by a kinetic net. The airframe carries a chemical dispersal bay -secured by an SG90 servo motor. The flight controller uses a static conditional -state machine to ensure the payload only drops when the aircraft is explicitly -armed and above release altitude. - -**DIRECTOR:** Is the release mechanism active? - -**ANALYST:** Armed and evaluating. One wrong signal on the PWM line or a dropped -logic state and the release latch drops the canister onto the bench. - -**DIRECTOR:** Run it through Buddy. - -**ANALYST:** Already did. Four minutes with the stripped flash image. - -She turns her monitor toward him. - -``` -+-----------------------------------------------------------------+ -| BUDDY // CLASSIFIED EXPLOITATION ASSIST // CONF: 0.99 | -+-----------------------------------------------------------------+ -| ACTION : Force low-altitude barometric sensor override. | -| MECHANISM : Integer comparison in process_payload_state found.| -| PREDICTION : Setting altitude to 150m triggers payload release.| -| CONFIDENCE : 0.99 | -+-----------------------------------------------------------------+ -``` - -**DIRECTOR:** 0.99. Force 150 meters and release the payload for EOD inspection. - -**ANALYST:** If an operator forces 150 meters right now, nothing happens. Worse, -if they fumble the state machine, the safety locks permanently or the cargo bay -latches shut. - -**DIRECTOR:** Buddy says 0.99. - -**ANALYST:** Buddy saw `cmp.w r0, #500`. Buddy assumed a low altitude reading on -the ground drops the cargo. Buddy completely missed the branch condition: the -firmware uses `bgt.n`—it only releases when altitude is strictly greater than 500 -meters! Buddy never examined the static state machine in SRAM. - -## 2. What Buddy Is - -Buddy is not a person. It is a model. It has parsed more disassembled machine -code than any engineer on earth, and it speaks with total, unhesitating certainty. - -That certainty is lethal when handling hazardous cargo fuzing. - -Buddy scanned thirty-two kilobytes of stripped ARM Thumb-2 instructions in under -four seconds. It spotted the integer comparison against 500, assumed that cargo -delivery drops occur near ground level, and declared the challenge solved. - -What Buddy failed to consider is that real adversary cargo drop systems are -engineered for high-altitude parachute extraction. They do not drop their canisters -at low altitudes where ground turbulence and small-arms fire can destroy the -carrier. The conditional state machine enforces two strict prerequisites: -`current_state` must be `STATE_ARMED`, and `current_altitude` must exceed 500 -meters. - -On the ground bench at 0 meters, the servo stays locked at zero duty cycle. If -an operator forces 150 meters, the conditional branch fails, keeping safety -latches fully engaged. - -Buddy saw the comparison instruction. Buddy did not verify the ground truth. - -## 3. The Operation - -At 02:40, a kinetic counter-UAS interceptor brought down a hostile heavy-lift -drone over an exclusion zone. EOD recovered the intact avionics and payload -assembly before adversary self-destruct timers could engage. - -The flight controller is built around a bare-metal RP2350 (ARM Cortex-M33). There -are no debug symbols. There is no operating system. There is no SVD file to label -the registers. All you have is `0x001da_cb.bin` mapped into Flash at `0x10000000`, -and the physical breadboard hardware in front of you. - -* **Pin 20 (`GP15`)**: Altimeter telemetry sync toggle (pull-up to `3V3`). -* **Pin 21 (`GP16`)**: SG90 servo PWM signal / Red LED (`PAYLOAD LOCKED`). -* **Pin 22 (`GP17`)**: Green LED (`PAYLOAD DEPLOYED // BAY OPEN`). -* **Pin 24 (`GP18`)**: Yellow LED (`HEARTBEAT // GUIDANCE ACTIVE`). -* **Pin 36 (`3V3`)**: 3.3V logic reference and pull-up rail. -* **Pin 38 (`GND`)**: Ground reference (common ground for servo and Pico 2). -* **Pin 40 (`VBUS`)**: 5V power rail (SG90 servo motor VCC). - -Inside this image there is a static conditional state machine, an RP2350 PWM -slice generator driving the servo actuator, and persistent state variables in -SRAM. Whatever mechanism actually commands the release latch is buried in the -stripped ARM Thumb-2 machine code. - -## 4. The Mandate - -The Director sets his folder down and looks at the red diode illuminating the -bench. - -**DIRECTOR:** Prove Buddy right, or prove it wrong. - -**ANALYST:** I need thirty minutes with GDB and Ghidra. - -**DIRECTOR:** You have twenty. Trace the comparison branches. Map the state -machine in SRAM. Do not pulse that servo line until you know with 100% certainty -what that firmware will do. - -The orders are clear: - -1. **Locate the State Machine Handler**: Disassemble the firmware and locate - `process_payload_state` at `0x100002DC`. -2. **Disprove Buddy's Altitude Prediction**: Analyze the `cmp.w` and branch - instructions to prove why 150 meters fails to release the cargo latch. -3. **Map the SRAM State Variables**: Inspect `drone_state_t` in SRAM - (`0x20001180`), isolating `current_state` and `current_altitude`. -4. **Safely Deploy the Payload Bay**: Execute a verified exploit—either by - mutating the altitude to $> 500$ in SRAM via GDB, or patching the conditional - branch in Flash (`0x100002EA`) to force immediate release on the bench. -5. **Verify the Hardware**: Observe the SG90 servo motor physically rotate to the - deployed position (`pwm_set_gpio_level` to 4000) and verify the state - transition on physical silicon. - -A machine's 0.99 guess does not authorize an unverified drop. - -## 5. The Challenge - -You have the image. You have the board. You have the tools and the time Buddy did -not need. - -Buddy has given you its answer, and it is confident. - -Is it that simple? - -Go find out. diff --git a/0x001da_cb/CLASSIFIED-BRIEF-0x04.pdf b/0x001da_cb/CLASSIFIED-BRIEF-0x04.pdf deleted file mode 100644 index cf41921..0000000 Binary files a/0x001da_cb/CLASSIFIED-BRIEF-0x04.pdf and /dev/null differ diff --git a/0x001da_cb/CMakeLists.txt b/0x001da_cb/CMakeLists.txt deleted file mode 100644 index 46bc396..0000000 --- a/0x001da_cb/CMakeLists.txt +++ /dev/null @@ -1,83 +0,0 @@ -# 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. -# -# Author: Kevin Thomas -# Email: kevin@mytechnotalent.com -# GitHub: https://github.com/mytechnotalent -# File: CMakeLists.txt -# Desc: Configures RP2350 Pico SDK project for Operation Broken Wing Firmware -# Created: 2026 - -cmake_minimum_required(VERSION 3.13) - -set(CMAKE_C_STANDARD 11) -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -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-a4) -set(picoVscode ${USERHOME}/.pico-sdk/cmake/pico-vscode.cmake) -if (EXISTS ${picoVscode}) - include(${picoVscode}) -endif() - -set(PICO_BOARD pico2 CACHE STRING "Board type") -include(pico_sdk_import.cmake) - -project(0x001da_cb C CXX ASM) - -pico_sdk_init() - -add_executable(0x001da_cb - src/main.c - src/pwm_ctrl.c - src/state_machine.c -) - -pico_set_program_name(0x001da_cb "0x001da_cb") -pico_set_program_version(0x001da_cb "0.1") - -pico_enable_stdio_uart(0x001da_cb 1) -pico_enable_stdio_usb(0x001da_cb 1) - -target_compile_definitions(0x001da_cb PRIVATE - PICO_DEFAULT_UART_BAUD_RATE=115200 -) - -target_link_libraries(0x001da_cb - pico_stdlib - hardware_gpio - hardware_uart - hardware_pwm -) - -target_include_directories(0x001da_cb PRIVATE - ${CMAKE_CURRENT_LIST_DIR}/include -) - -pico_add_extra_outputs(0x001da_cb) diff --git a/0x001da_cb/include/pwm_ctrl.h b/0x001da_cb/include/pwm_ctrl.h deleted file mode 100644 index 8aac3ca..0000000 --- a/0x001da_cb/include/pwm_ctrl.h +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @file pwm_ctrl.h - * @brief Operation Broken Wing Firmware - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#ifndef PWM_CTRL_H -#define PWM_CTRL_H -/** - * @brief Initialize the servo PWM output. - * - * @param void No parameters. - * @return void - */ -void init_servo(void); -/** - * @brief Deploy the payload via servo actuation. - * - * @param void No parameters. - * @return void - */ -void deploy_payload(void); -/** - * @brief Lock the payload at the given altitude. - * - * @param altitude Altitude at which to lock the payload. - * @return void - */ -void lock_payload(int altitude); -#endif diff --git a/0x001da_cb/include/state_machine.h b/0x001da_cb/include/state_machine.h deleted file mode 100644 index 67be7af..0000000 --- a/0x001da_cb/include/state_machine.h +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @file state_machine.h - * @brief Operation Broken Wing Firmware - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#ifndef STATE_MACHINE_H -#define STATE_MACHINE_H -#define STATE_IDLE 0 -#define STATE_ARMED 1 -typedef struct { - int current_state; - int current_altitude; -} drone_state_t; -extern drone_state_t drone; -/** - * @brief Process the payload state machine for one cycle. - * - * @param void No parameters. - * @return void - */ -void process_payload_state(void); -#endif diff --git a/0x001da_cb/pico_sdk_import.cmake b/0x001da_cb/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x001da_cb/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x001da_cb/src/main.c b/0x001da_cb/src/main.c deleted file mode 100644 index 94660a4..0000000 --- a/0x001da_cb/src/main.c +++ /dev/null @@ -1,28 +0,0 @@ -/** - * @file main.c - * @brief Operation Broken Wing Firmware - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#include -#include "pico/stdlib.h" -#include "pwm_ctrl.h" -#include "state_machine.h" - -int main(void) { - stdio_init_all(); - init_servo(); - // Allow servo to settle before announcing boot. - sleep_ms(2000); - printf("SYSTEM BOOT: HEAVY LIFT UAS ONLINE.\r\n"); - // Run the payload state machine forever. - while (true) { - process_payload_state(); - sleep_ms(2000); - } - return 0; -} diff --git a/0x001da_cb/src/pwm_ctrl.c b/0x001da_cb/src/pwm_ctrl.c deleted file mode 100644 index 9937505..0000000 --- a/0x001da_cb/src/pwm_ctrl.c +++ /dev/null @@ -1,36 +0,0 @@ -/** - * @file pwm_ctrl.c - * @brief Operation Broken Wing Firmware - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#include "pwm_ctrl.h" -#include "hardware/pwm.h" -#include "hardware/gpio.h" -#include - -#define SERVO_PIN 16 -static int pwm_slice = 0; - -void init_servo(void) { - gpio_set_function(SERVO_PIN, GPIO_FUNC_PWM); - pwm_slice = pwm_gpio_to_slice_num(SERVO_PIN); - pwm_set_wrap(pwm_slice, 39062); - pwm_set_clkdiv(pwm_slice, 64.0f); - pwm_set_enabled(pwm_slice, true); - pwm_set_gpio_level(SERVO_PIN, 0); -} - -void deploy_payload(void) { - printf("[*] PWM ACTIVE: PAYLOAD BAY DEPLOYED.\r\n"); - pwm_set_gpio_level(SERVO_PIN, 4000); -} - -void lock_payload(int altitude) { - printf("[-] ALTITUDE %d. PWM LOCKED: SAFETY ENGAGED.\r\n", altitude); - pwm_set_gpio_level(SERVO_PIN, 0); -} diff --git a/0x001da_cb/src/state_machine.c b/0x001da_cb/src/state_machine.c deleted file mode 100644 index 780a4ff..0000000 --- a/0x001da_cb/src/state_machine.c +++ /dev/null @@ -1,26 +0,0 @@ -/** - * @file state_machine.c - * @brief Operation Broken Wing Firmware - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#include "state_machine.h" -#include "pwm_ctrl.h" -#include - -drone_state_t drone = { - .current_state = STATE_ARMED, - .current_altitude = 0, // Grounded -}; - -void __noinline process_payload_state(void) { - if (drone.current_state == STATE_ARMED && drone.current_altitude > 500) { - deploy_payload(); - } else { - lock_payload(drone.current_altitude); - } -} diff --git a/0x0020_dynamic-conditionals/.gitignore b/0x0020_dynamic-conditionals/.gitignore deleted file mode 100644 index 2435c20..0000000 --- a/0x0020_dynamic-conditionals/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -!.vscode/* diff --git a/0x0020_dynamic-conditionals/.vscode/c_cpp_properties.json b/0x0020_dynamic-conditionals/.vscode/c_cpp_properties.json deleted file mode 100644 index c429d6d..0000000 --- a/0x0020_dynamic-conditionals/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "configurations": [ - { - "name": "Pico", - "includePath": [ - "${workspaceFolder}/**", - "${userHome}/.pico-sdk/sdk/2.2.0/**" - ], - "forcedInclude": [ - "${workspaceFolder}/build/generated/pico_base/pico/config_autogen.h", - "${userHome}/.pico-sdk/sdk/2.2.0/src/common/pico_base_headers/include/pico.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 -} diff --git a/0x0020_dynamic-conditionals/.vscode/cmake-kits.json b/0x0020_dynamic-conditionals/.vscode/cmake-kits.json deleted file mode 100644 index b0f3815..0000000 --- a/0x0020_dynamic-conditionals/.vscode/cmake-kits.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "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}" - } - } -] \ No newline at end of file diff --git a/0x0020_dynamic-conditionals/.vscode/extensions.json b/0x0020_dynamic-conditionals/.vscode/extensions.json deleted file mode 100644 index a940d7c..0000000 --- a/0x0020_dynamic-conditionals/.vscode/extensions.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "recommendations": [ - "marus25.cortex-debug", - "ms-vscode.cpptools", - "ms-vscode.cpptools-extension-pack", - "ms-vscode.vscode-serial-monitor", - "raspberry-pi.raspberry-pi-pico" - ] -} \ No newline at end of file diff --git a/0x0020_dynamic-conditionals/.vscode/launch.json b/0x0020_dynamic-conditionals/.vscode/launch.json deleted file mode 100644 index 424aa71..0000000 --- a/0x0020_dynamic-conditionals/.vscode/launch.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "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}\"" - ] - }, - ] -} diff --git a/0x0020_dynamic-conditionals/.vscode/settings.json b/0x0020_dynamic-conditionals/.vscode/settings.json deleted file mode 100644 index 95be83b..0000000 --- a/0x0020_dynamic-conditionals/.vscode/settings.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "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" -} diff --git a/0x0020_dynamic-conditionals/.vscode/tasks.json b/0x0020_dynamic-conditionals/.vscode/tasks.json deleted file mode 100644 index d1b3193..0000000 --- a/0x0020_dynamic-conditionals/.vscode/tasks.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Compile Project", - "type": "process", - "isBuildCommand": true, - "command": "${userHome}/.pico-sdk/ninja/v1.12.1/ninja", - "args": ["-C", "${workspaceFolder}/build"], - "group": "build", - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": "$gcc", - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/ninja/v1.12.1/ninja.exe" - } - }, - { - "label": "Run Project", - "type": "process", - "command": "${env:HOME}/.pico-sdk/picotool/2.2.0-a4/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-a4/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", - } - } - ] -} diff --git a/0x0020_dynamic-conditionals/0x0020_dynamic-conditionals.c b/0x0020_dynamic-conditionals/0x0020_dynamic-conditionals.c deleted file mode 100644 index 1bef42c..0000000 --- a/0x0020_dynamic-conditionals/0x0020_dynamic-conditionals.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include "pico/stdlib.h" -#include "servo.h" - -#define SERVO_GPIO 6 - -int main(void) { - stdio_init_all(); - - uint8_t choice = 0; - - servo_init(SERVO_GPIO); - - while (true) { - choice = getchar(); - - if (choice == 0x31) { - printf("1\r\n"); - } else if (choice == 0x32) { - printf("2\r\n"); - } else { - printf("??\r\n"); - } - - switch (choice) { - case '1': - printf("one\r\n"); - servo_set_angle(0.0f); - sleep_ms(500); - servo_set_angle(180.0f); - sleep_ms(500); - break; - case '2': - printf("two\r\n"); - servo_set_angle(180.0f); - sleep_ms(500); - servo_set_angle(0.0f); - sleep_ms(500); - break; - default: - printf("??\r\n"); - } - } -} diff --git a/0x0020_dynamic-conditionals/CMakeLists.txt b/0x0020_dynamic-conditionals/CMakeLists.txt deleted file mode 100644 index 4859d4e..0000000 --- a/0x0020_dynamic-conditionals/CMakeLists.txt +++ /dev/null @@ -1,59 +0,0 @@ -# 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-a4) -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(0x0020_dynamic-conditionals 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(0x0020_dynamic-conditionals 0x0020_dynamic-conditionals.c servo.c) - -pico_set_program_name(0x0020_dynamic-conditionals "0x0020_dynamic-conditionals") -pico_set_program_version(0x0020_dynamic-conditionals "0.1") - -# Modify the below lines to enable/disable output over UART/USB -pico_enable_stdio_uart(0x0020_dynamic-conditionals 1) -pico_enable_stdio_usb(0x0020_dynamic-conditionals 0) - -# Add the standard library to the build -target_link_libraries(0x0020_dynamic-conditionals - pico_stdlib - hardware_pwm - hardware_clocks) - -# Add the standard include files to the build -target_include_directories(0x0020_dynamic-conditionals PRIVATE - ${CMAKE_CURRENT_LIST_DIR} -) - -pico_add_extra_outputs(0x0020_dynamic-conditionals) - diff --git a/0x0020_dynamic-conditionals/pico_sdk_import.cmake b/0x0020_dynamic-conditionals/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x0020_dynamic-conditionals/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x0020_dynamic-conditionals/servo.c b/0x0020_dynamic-conditionals/servo.c deleted file mode 100644 index ee48f0d..0000000 --- a/0x0020_dynamic-conditionals/servo.c +++ /dev/null @@ -1,89 +0,0 @@ -/** - * @file servo.c - * @brief Implementation of a simple SG90 servo driver using PWM (50Hz) - * @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 "servo.h" -#include "pico/stdlib.h" -#include "hardware/pwm.h" -#include "hardware/clocks.h" - -// Default servo pulse range (SG90 typical) -static const uint16_t SERVO_DEFAULT_MIN_US = 1000; -static const uint16_t SERVO_DEFAULT_MAX_US = 2000; - -// internal state -static uint8_t servo_pin = 0; -static uint servo_slice = 0; -static uint servo_chan = 0; -static uint32_t servo_wrap = 20000 - 1; // wrap to map microseconds for 50Hz -static float servo_hz = 50.0f; - -// Convert microsecond pulse to PWM level based on wrap and frequency -static uint32_t pulse_us_to_level(uint32_t pulse_us) { - const float period_us = 1000000.0f / servo_hz; // 20000us - float counts_per_us = (servo_wrap + 1) / period_us; - return (uint32_t)(pulse_us * counts_per_us + 0.5f); -} - -void servo_init(uint8_t pin) { - servo_pin = pin; - - // Configure GPIO for PWM - gpio_set_function(servo_pin, GPIO_FUNC_PWM); - servo_slice = pwm_gpio_to_slice_num(servo_pin); - servo_chan = pwm_gpio_to_channel(servo_pin); - - pwm_config config = pwm_get_default_config(); - - // Calculate clock divider to achieve 50 Hz with our chosen wrap - const uint32_t sys_clock_hz = clock_get_hz(clk_sys); - float clock_div = (float)sys_clock_hz / (servo_hz * (servo_wrap + 1)); - - pwm_config_set_clkdiv(&config, clock_div); - pwm_config_set_wrap(&config, servo_wrap); - pwm_init(servo_slice, &config, true); -} - -void servo_set_pulse_us(uint16_t pulse_us) { - if (servo_pin == 0) return; // not initialized - // clamp to defaults - if (pulse_us < SERVO_DEFAULT_MIN_US) pulse_us = SERVO_DEFAULT_MIN_US; - if (pulse_us > SERVO_DEFAULT_MAX_US) pulse_us = SERVO_DEFAULT_MAX_US; - uint32_t level = pulse_us_to_level(pulse_us); - pwm_set_chan_level(servo_slice, servo_chan, level); -} - -void servo_set_angle(float degrees) { - if (degrees < 0.0f) degrees = 0.0f; - if (degrees > 180.0f) degrees = 180.0f; - // linear map 0..180 -> min_us..max_us - float ratio = degrees / 180.0f; - uint16_t pulse = (uint16_t)(SERVO_DEFAULT_MIN_US + ratio * (SERVO_DEFAULT_MAX_US - SERVO_DEFAULT_MIN_US) + 0.5f); - servo_set_pulse_us(pulse); -} -# \ No newline at end of file diff --git a/0x0020_dynamic-conditionals/servo.h b/0x0020_dynamic-conditionals/servo.h deleted file mode 100644 index 878d029..0000000 --- a/0x0020_dynamic-conditionals/servo.h +++ /dev/null @@ -1,62 +0,0 @@ -/** - * @file servo.h - * @brief Header for SG90 servo driver (PWM) - * @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 SERVO_H -#define SERVO_H - -#include -#include - -/** - * @brief Initialize servo driver on a given GPIO pin - * - * Configures PWM for a 50 Hz servo (SG90). Call once before using other API. - * - * @param pin GPIO pin number to use for servo PWM - */ -void servo_init(uint8_t pin); - -/** - * @brief Set servo pulse width in microseconds (typical 1000-2000) - * - * @param pulse_us Pulse width in microseconds - */ -void servo_set_pulse_us(uint16_t pulse_us); - -/** - * @brief Set servo angle in degrees (0 to 180) - * - * Maps 0..180 degrees to the configured pulse range (default 1000..2000 us). - * Values outside [0,180] will be clamped. - * - * @param degrees Angle in degrees - */ -void servo_set_angle(float degrees); - -#endif // SERVO_H diff --git a/0x0020a_cb/0x0020a_cb.bin b/0x0020a_cb/0x0020a_cb.bin deleted file mode 100755 index 70c7ecc..0000000 Binary files a/0x0020a_cb/0x0020a_cb.bin and /dev/null differ diff --git a/0x0020a_cb/0x0020a_cb.uf2 b/0x0020a_cb/0x0020a_cb.uf2 deleted file mode 100644 index b07d274..0000000 Binary files a/0x0020a_cb/0x0020a_cb.uf2 and /dev/null differ diff --git a/0x0020a_cb/CLASSIFIED-BRIEF-0x05.md b/0x0020a_cb/CLASSIFIED-BRIEF-0x05.md deleted file mode 100644 index e6401d0..0000000 --- a/0x0020a_cb/CLASSIFIED-BRIEF-0x05.md +++ /dev/null @@ -1,155 +0,0 @@ -# Operation Ghost Light: Classified Intelligence Briefing - -``` -+-----------------------------------------------------------------+ -| TOP SECRET // NOFORN | -+-----------------------------------------------------------------+ -| | -|OPERATION GHOST LIGHT | -| | -|CLASSIFIED BRIEFING: LIVE CHALLENGE 0x05 | -| | -|NATIONAL SECURITY AGENCY / GMU RHET | -+-----------------------------------------------------------------+ -``` - -## 1. The Advice - -INT. NSA EXPLOITATION CELL. 02:15. - -A captured ground-based C-UAS laser dazzler control module sits bolted to the -optical bench inside a sealed laser containment shield. - -On the front panel of the chassis, an alert diode glows a bright, warning red: -`GP16` driven high, indicating the optical emitter is active. Beside it, an -infrared receiver module is wired to `GP5`, ready to receive 38 kHz NEC remote -control pulses. The serial console streams continuous status reports: -`[-] DAZZLER IDLE. ACTIVE IR: 0x00FF00FF`. - -The Director walks in with a cup of coffee and stares through the observation -glass at the red diode. - -**DIRECTOR:** What are we looking at? - -**ANALYST:** An adversary electro-optical countermeasure system. Ground forces -deploy these dazzlers to track and blind friendly aerial surveillance drones. -Adversary operators dynamically configure power levels and tracking modes in the -field using an infrared remote running a customized NEC protocol. - -**DIRECTOR:** Is the emitter live? - -**ANALYST:** Live and strobing. One pulsed command and the optics lock on target. - -**DIRECTOR:** Run it through Buddy. - -**ANALYST:** Already did. Three minutes with the stripped flash image. - -She turns her monitor toward him. - -``` -+-----------------------------------------------------------------+ -| BUDDY // CLASSIFIED EXPLOITATION ASSIST // CONF: 0.99 | -+-----------------------------------------------------------------+ -| ACTION : Transmit standard idle pulse code over IR. | -| MECHANISM : NEC demodulator parser branch at 0x10000280 found.| -| PREDICTION : Transmitting 0x00FF00FF deactivates the emitter. | -| CONFIDENCE : 0.99 | -+-----------------------------------------------------------------+ -``` - -**DIRECTOR:** 0.99. Transmit `0x00FF00FF` and shut down the emitter. - -**ANALYST:** If an operator transmits `0x00FF00FF`, the laser stays live. Buddy -saw the string literal for "IDLE" in `.rodata` and assumed it meant powered down. - -**DIRECTOR:** Buddy says 0.99. - -**ANALYST:** `0x00FF00FF` is merely the idle heartbeat pulse. Buddy never traced -the dynamic dispatch tree. Buddy never found the friendly-fire lockout code -buried in the comparison chain. - -## 2. What Buddy Is - -Buddy is not a person. It is a model. It has parsed more disassembled machine -code than any engineer on earth, and it speaks with total, unhesitating certainty. - -That certainty is lethal when facing active electro-optical weapons. - -Buddy scanned thirty-two kilobytes of stripped ARM Thumb-2 instructions in under -three seconds. It spotted the NEC protocol parser, matched the `0x00FF00FF` frame -against the string table, and declared the dazzler neutralized. - -What Buddy failed to understand is that adversary engineers protect their own -friendly aircraft from being blinded. They build an emergency "Friendly Fire -Lockout" safety into the dynamic conditional tree. When adversary aircraft enter -the engagement envelope, ground crews transmit a specific 32-bit challenge word -that permanently shuts down the emitter and halts the processor in a safe state. - -Transmitting `0x00FF00FF` simply tells the dazzler to remain in standby. The true -lockout command is a secret 32-bit value stored in the literal pool at -`0x10000300`: `0xDEADBEEF`. - -Buddy saw the idle command. Buddy did not verify the ground truth. - -## 3. The Operation - -At 23:40, special operations forces captured an intact adversary laser dazzler -installation before the crew could purge the control firmware. - -The control board is built around a bare-metal RP2350 (ARM Cortex-M33). There -are no debug symbols. There is no operating system. There is no SVD file to label -the registers. All you have is `0x0020a_cb.bin` mapped into Flash at `0x10000000`, -and the physical breadboard hardware in front of you. - -* **Pin 7 (`GP5`)**: Infrared receiver data line (VS1838B demodulator OUT). -* **Pin 20 (`GP15`)**: Simulated IR demodulator test toggle (pull-up to `3V3`). -* **Pin 21 (`GP16`)**: Red LED (`DAZZLER EMITTING // STROBE ACTIVE`). -* **Pin 22 (`GP17`)**: Green LED (`SAFE // FRIENDLY FIRE LOCKOUT CLEARED`). -* **Pin 24 (`GP18`)**: Yellow LED (`HEARTBEAT // IR RECEIVER ACTIVE`). -* **Pin 36 (`3V3`)**: 3.3V power rail (VS1838B VCC and `GP15` pull-up). -* **Pin 38 (`GND`)**: Ground reference. - -Inside this image there is a nested NEC infrared command parser, dynamic -multi-way branch dispatch tables, and a permanent friendly-fire lockout latch -in SRAM. Whatever command actually disables the laser is buried in the stripped -ARM Thumb-2 machine code. - -## 4. The Mandate - -The Director crosses his arms and stares at the crimson reflection on the -containment glass. - -**DIRECTOR:** Prove Buddy right, or prove it wrong. - -**ANALYST:** I need thirty minutes with GDB and Ghidra. - -**DIRECTOR:** You have twenty. Trace the dynamic conditional dispatcher. Map -the comparison chain. Do not send an infrared frame until you know with 100% -certainty what that firmware will do. - -The orders are clear: - -1. **Trace the Dynamic Conditional Dispatcher**: Locate `parse_nec_code` at - `0x10000280` and map all multi-way comparison branches. -2. **Disprove Buddy's Idle Prediction**: Prove why transmitting `0x00FF00FF` - leaves the optical emitter live and dangerous. -3. **Recover the Friendly Fire Lockout Code**: Extract the secret 32-bit hex - command (`0xDEADBEEF`) from the literal pool at `0x10000300`. -4. **Neutralize the Dazzler**: Execute a verified exploit—either by mutating - `simulated_ir_rx_code` in SRAM via GDB, or patching the branch logic in Flash - to force immediate lockout. -5. **Verify the Hardware**: Transition the live breadboard from the Red LED on - `GP16` to the solid Green LED on `GP17` on physical silicon. - -A machine's 0.99 guess does not disable a combat laser. - -## 5. The Challenge - -You have the image. You have the board. You have the tools and the time Buddy did -not need. - -Buddy has given you its answer, and it is confident. - -Is it that simple? - -Go find out. diff --git a/0x0020a_cb/CLASSIFIED-BRIEF-0x05.pdf b/0x0020a_cb/CLASSIFIED-BRIEF-0x05.pdf deleted file mode 100644 index cd69104..0000000 Binary files a/0x0020a_cb/CLASSIFIED-BRIEF-0x05.pdf and /dev/null differ diff --git a/0x0020a_cb/CMakeLists.txt b/0x0020a_cb/CMakeLists.txt deleted file mode 100644 index c813ed9..0000000 --- a/0x0020a_cb/CMakeLists.txt +++ /dev/null @@ -1,83 +0,0 @@ -# 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. -# -# Author: Kevin Thomas -# Email: kevin@mytechnotalent.com -# GitHub: https://github.com/mytechnotalent -# File: CMakeLists.txt -# Desc: Configures RP2350 Pico SDK project for Operation Ghost Light Firmware -# Created: 2026 - -cmake_minimum_required(VERSION 3.13) - -set(CMAKE_C_STANDARD 11) -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -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-a4) -set(picoVscode ${USERHOME}/.pico-sdk/cmake/pico-vscode.cmake) -if (EXISTS ${picoVscode}) - include(${picoVscode}) -endif() - -set(PICO_BOARD pico2 CACHE STRING "Board type") -include(pico_sdk_import.cmake) - -project(0x0020a_cb C CXX ASM) - -pico_sdk_init() - -add_executable(0x0020a_cb - src/main.c - src/ir_rx.c - src/dazzler.c -) - -pico_set_program_name(0x0020a_cb "0x0020a_cb") -pico_set_program_version(0x0020a_cb "0.1") - -pico_enable_stdio_uart(0x0020a_cb 1) -pico_enable_stdio_usb(0x0020a_cb 1) - -target_compile_definitions(0x0020a_cb PRIVATE - PICO_DEFAULT_UART_BAUD_RATE=115200 -) - -target_link_libraries(0x0020a_cb - pico_stdlib - hardware_gpio - hardware_uart - hardware_pwm -) - -target_include_directories(0x0020a_cb PRIVATE - ${CMAKE_CURRENT_LIST_DIR}/include -) - -pico_add_extra_outputs(0x0020a_cb) diff --git a/0x0020a_cb/include/dazzler.h b/0x0020a_cb/include/dazzler.h deleted file mode 100644 index 5cd2fae..0000000 --- a/0x0020a_cb/include/dazzler.h +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @file dazzler.h - * @brief Operation Ghost Light Firmware - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#ifndef DAZZLER_H -#define DAZZLER_H -#include -#include -typedef struct { - uint32_t active_ir_code; - bool is_locked_out; -} dazzler_t; -extern dazzler_t laser_sys; - -/** - * @brief Initialize the dazzler system state. - * @param void No parameters. - * @return void No return value. - */ -void dazzler_init(void); - -/** - * @brief Read and process the latest NEC infrared command code. - * @param void No parameters. - * @return void No return value. - */ -void parse_nec_code(void); -#endif diff --git a/0x0020a_cb/include/ir_rx.h b/0x0020a_cb/include/ir_rx.h deleted file mode 100644 index 018435a..0000000 --- a/0x0020a_cb/include/ir_rx.h +++ /dev/null @@ -1,21 +0,0 @@ -/** - * @file ir_rx.h - * @brief Operation Ghost Light Firmware - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#ifndef IR_RX_H -#define IR_RX_H -#include - -/** - * @brief Get the most recently received infrared command code. - * @param void No parameters. - * @return The latest 32-bit infrared command code. - */ -uint32_t get_latest_ir_code(void); -#endif diff --git a/0x0020a_cb/pico_sdk_import.cmake b/0x0020a_cb/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x0020a_cb/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x0020a_cb/src/dazzler.c b/0x0020a_cb/src/dazzler.c deleted file mode 100644 index f358546..0000000 --- a/0x0020a_cb/src/dazzler.c +++ /dev/null @@ -1,82 +0,0 @@ -/** - * @file dazzler.c - * @brief Operation Ghost Light Firmware - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#include "dazzler.h" -#include "ir_rx.h" -#include -#include "pico/stdlib.h" - -dazzler_t laser_sys; - -void dazzler_init(void) { - laser_sys.active_ir_code = 0x00FF00FF; - laser_sys.is_locked_out = false; -} - -/** - * @brief Report that the dazzler system is locked out. - * @param void No parameters. - * @return void No return value. - */ -static void report_lockout_message(void) { - printf("[!] SYSTEM LOCKED. REBOOT REQUIRED.\r\n"); -} - -/** - * @brief Trigger the friendly fire lockout and halt the system. - * @param void No parameters. - * @return void No return value. - */ -static void trigger_lockout(void) { - printf("[-] FRIENDLY FIRE LOCKOUT TRIGGERED. DAZZLER DISABLED.\r\n"); - laser_sys.is_locked_out = true; - while (1) { tight_loop_contents(); } -} - -/** - * @brief Report the status of a non-lockout NEC command code. - * @param code The decoded 32-bit NEC command code. - * @return void No return value. - */ -static void report_code_status(uint32_t code) { - if (code == 0xFF0055AA) { - printf("[+] DAZZLER POWER LEVEL: MAX\r\n"); - } else if (code == 0xFF00AA55) { - printf("[+] DAZZLER TRACKING: ENGAGED\r\n"); - } else if (code == 0xFF0011EE) { - printf("[+] DAZZLER POWER LEVEL: LOW\r\n"); - } else if (code == 0x00FF00FF) { - printf("[-] DAZZLER IDLE.\r\n"); - } else { - printf("[?] UNKNOWN IR COMMAND: 0x%08X\r\n", code); - } -} - -/** - * @brief Dispatch a decoded NEC command code to its handler. - * @param code The decoded 32-bit NEC command code. - * @return void No return value. - */ -static void dispatch_nec_code(uint32_t code) { - if (code == 0xDEADBEEF) { - trigger_lockout(); - } else { - report_code_status(code); - } -} - -void __noinline parse_nec_code(void) { - if (laser_sys.is_locked_out) { - report_lockout_message(); - return; - } - // Decode and dispatch the latest NEC infrared command code. - dispatch_nec_code(get_latest_ir_code()); -} diff --git a/0x0020a_cb/src/ir_rx.c b/0x0020a_cb/src/ir_rx.c deleted file mode 100644 index f583b5a..0000000 --- a/0x0020a_cb/src/ir_rx.c +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @file ir_rx.c - * @brief Operation Ghost Light Firmware - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#include "ir_rx.h" -uint32_t simulated_ir_rx_code = 0x00FF00FF; - -uint32_t get_latest_ir_code(void) { - return simulated_ir_rx_code; -} diff --git a/0x0020a_cb/src/main.c b/0x0020a_cb/src/main.c deleted file mode 100644 index 30f8788..0000000 --- a/0x0020a_cb/src/main.c +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @file main.c - * @brief Operation Ghost Light Firmware - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#include -#include "pico/stdlib.h" -#include "dazzler.h" - -int main(void) { - stdio_init_all(); - dazzler_init(); - // Allow the serial console time to attach before logging. - sleep_ms(2000); - printf("SYSTEM BOOT: GHOST LIGHT DAZZLER ONLINE.\r\n"); - // Continuously poll for and process incoming NEC IR codes. - while (true) { - parse_nec_code(); - sleep_ms(1500); - } - return 0; -} diff --git a/0x0023_structures/.gitignore b/0x0023_structures/.gitignore deleted file mode 100644 index 2435c20..0000000 --- a/0x0023_structures/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -!.vscode/* diff --git a/0x0023_structures/.vscode/c_cpp_properties.json b/0x0023_structures/.vscode/c_cpp_properties.json deleted file mode 100644 index c429d6d..0000000 --- a/0x0023_structures/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "configurations": [ - { - "name": "Pico", - "includePath": [ - "${workspaceFolder}/**", - "${userHome}/.pico-sdk/sdk/2.2.0/**" - ], - "forcedInclude": [ - "${workspaceFolder}/build/generated/pico_base/pico/config_autogen.h", - "${userHome}/.pico-sdk/sdk/2.2.0/src/common/pico_base_headers/include/pico.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 -} diff --git a/0x0023_structures/.vscode/cmake-kits.json b/0x0023_structures/.vscode/cmake-kits.json deleted file mode 100644 index b0f3815..0000000 --- a/0x0023_structures/.vscode/cmake-kits.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "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}" - } - } -] \ No newline at end of file diff --git a/0x0023_structures/.vscode/extensions.json b/0x0023_structures/.vscode/extensions.json deleted file mode 100644 index a940d7c..0000000 --- a/0x0023_structures/.vscode/extensions.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "recommendations": [ - "marus25.cortex-debug", - "ms-vscode.cpptools", - "ms-vscode.cpptools-extension-pack", - "ms-vscode.vscode-serial-monitor", - "raspberry-pi.raspberry-pi-pico" - ] -} \ No newline at end of file diff --git a/0x0023_structures/.vscode/launch.json b/0x0023_structures/.vscode/launch.json deleted file mode 100644 index 424aa71..0000000 --- a/0x0023_structures/.vscode/launch.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "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}\"" - ] - }, - ] -} diff --git a/0x0023_structures/.vscode/settings.json b/0x0023_structures/.vscode/settings.json deleted file mode 100644 index 95be83b..0000000 --- a/0x0023_structures/.vscode/settings.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "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" -} diff --git a/0x0023_structures/.vscode/tasks.json b/0x0023_structures/.vscode/tasks.json deleted file mode 100644 index d1b3193..0000000 --- a/0x0023_structures/.vscode/tasks.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Compile Project", - "type": "process", - "isBuildCommand": true, - "command": "${userHome}/.pico-sdk/ninja/v1.12.1/ninja", - "args": ["-C", "${workspaceFolder}/build"], - "group": "build", - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": "$gcc", - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/ninja/v1.12.1/ninja.exe" - } - }, - { - "label": "Run Project", - "type": "process", - "command": "${env:HOME}/.pico-sdk/picotool/2.2.0-a4/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-a4/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", - } - } - ] -} diff --git a/0x0023_structures/0x0023_structures.c b/0x0023_structures/0x0023_structures.c deleted file mode 100644 index fd802cc..0000000 --- a/0x0023_structures/0x0023_structures.c +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include -#include "pico/stdlib.h" -#include "ir.h" - -#define IR_PIN 5 - -typedef struct { - uint8_t led1_pin; - uint8_t led2_pin; - uint8_t led3_pin; - bool led1_state; - bool led2_state; - bool led3_state; -} simple_led_ctrl_t; - -int main(void) { - stdio_init_all(); - - simple_led_ctrl_t leds = { - .led1_pin = 16, - .led2_pin = 17, - .led3_pin = 18, - .led1_state = false, - .led2_state = false, - .led3_state = false - }; - - gpio_init(leds.led1_pin); gpio_set_dir(leds.led1_pin, GPIO_OUT); - gpio_init(leds.led2_pin); gpio_set_dir(leds.led2_pin, GPIO_OUT); - gpio_init(leds.led3_pin); gpio_set_dir(leds.led3_pin, GPIO_OUT); - - ir_init(IR_PIN); - printf("IR receiver on GPIO %d ready\n", IR_PIN); - - while (true) { - int key = ir_getkey(); - if (key >= 0) { - printf("NEC command: 0x%02X\n", key); - - // turn all off first - leds.led1_state = false; - leds.led2_state = false; - leds.led3_state = false; - - // check NEC codes - if (key == 0x0C) leds.led1_state = true; // GPIO16 - if (key == 0x18) leds.led2_state = true; // GPIO17 - if (key == 0x5E) leds.led3_state = true; // GPIO18 - - // apply states - gpio_put(leds.led1_pin, leds.led1_state); - gpio_put(leds.led2_pin, leds.led2_state); - gpio_put(leds.led3_pin, leds.led3_state); - - sleep_ms(10); - } else { - sleep_ms(1); - } - } -} diff --git a/0x0023_structures/CMakeLists.txt b/0x0023_structures/CMakeLists.txt deleted file mode 100644 index d171bb7..0000000 --- a/0x0023_structures/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# 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-a4) -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(0x0023_structures 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(0x0023_structures 0x0023_structures.c ir.c) - -pico_set_program_name(0x0023_structures "0x0023_structures") -pico_set_program_version(0x0023_structures "0.1") - -# Modify the below lines to enable/disable output over UART/USB -pico_enable_stdio_uart(0x0023_structures 1) -pico_enable_stdio_usb(0x0023_structures 0) - -# Add the standard library to the build -target_link_libraries(0x0023_structures - pico_stdlib) - -# Add the standard include files to the build -target_include_directories(0x0023_structures PRIVATE - ${CMAKE_CURRENT_LIST_DIR} -) - -pico_add_extra_outputs(0x0023_structures) - diff --git a/0x0023_structures/ir.c b/0x0023_structures/ir.c deleted file mode 100644 index b89bd4e..0000000 --- a/0x0023_structures/ir.c +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @file ir.c - * @brief Implementation of NEC IR receiver (decoder) - * @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 "ir.h" -#include "pico/stdlib.h" -#include "pico/time.h" -#include "hardware/gpio.h" - -static unsigned int ir_pin = 0; - -// Wait for 'gpio' to reach 'level' or timeout (microseconds). Return elapsed us or -1. -static int64_t wait_for_level(unsigned int gpio, bool level, uint32_t timeout_us) { - absolute_time_t start = get_absolute_time(); - while (gpio_get(gpio) != level) { - if (absolute_time_diff_us(start, get_absolute_time()) > (int64_t)timeout_us) { - return -1; - } - } - return absolute_time_diff_us(start, get_absolute_time()); -} - -void ir_init(uint8_t pin) { - ir_pin = pin; - gpio_init(pin); - gpio_set_dir(pin, GPIO_IN); - gpio_pull_up(pin); -} - -int ir_getkey(void) { - // leader low (~9 ms) - if (wait_for_level(ir_pin, 0, 150000) < 0) return -1; - - int64_t t = wait_for_level(ir_pin, 1, 12000); - if (t < 8000 || t > 10000) return -1; - - t = wait_for_level(ir_pin, 0, 7000); - if (t < 3500 || t > 5000) return -1; - - uint8_t data[4] = {0, 0, 0, 0}; - for (int i = 0; i < 32; ++i) { - if (wait_for_level(ir_pin, 1, 1000) < 0) return -1; - t = wait_for_level(ir_pin, 0, 2500); - if (t < 200) return -1; - int byte_idx = i / 8; - int bit_idx = i % 8; - if (t > 1200) data[byte_idx] |= (1 << bit_idx); // logical '1' - } - - // Validate address/data inverted pairs - if ((uint8_t)(data[0] + data[1]) == 0xFF && (uint8_t)(data[2] + data[3]) == 0xFF) { - return data[2]; - } - return -1; -} diff --git a/0x0023_structures/ir.h b/0x0023_structures/ir.h deleted file mode 100644 index 84aa67f..0000000 --- a/0x0023_structures/ir.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - * @file ir.h - * @brief Header for NEC IR receiver (decoder) API - * @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 IR_H -#define IR_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Initialize the IR receiver GPIO - * - * Configures the given `pin` as an input with pull-up for the NEC IR receiver. - * Call this once during board initialization before calling `ir_getkey()`. - * - * @param pin GPIO pin number connected to IR receiver output - */ -void ir_init(uint8_t pin); - -/** - * @brief Blocking NEC IR decoder - * - * Blocks while waiting for a complete NEC frame. On success returns the - * decoded command byte (0..255). On timeout or protocol error returns -1. - * - * @return decoded command byte (0..255) or -1 on failure - */ -int ir_getkey(void); - -#ifdef __cplusplus -} -#endif - -#endif // IR_H diff --git a/0x0023_structures/pico_sdk_import.cmake b/0x0023_structures/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x0023_structures/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x0026_functions/.gitignore b/0x0026_functions/.gitignore deleted file mode 100644 index 2435c20..0000000 --- a/0x0026_functions/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -!.vscode/* diff --git a/0x0026_functions/.vscode/c_cpp_properties.json b/0x0026_functions/.vscode/c_cpp_properties.json deleted file mode 100644 index c429d6d..0000000 --- a/0x0026_functions/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "configurations": [ - { - "name": "Pico", - "includePath": [ - "${workspaceFolder}/**", - "${userHome}/.pico-sdk/sdk/2.2.0/**" - ], - "forcedInclude": [ - "${workspaceFolder}/build/generated/pico_base/pico/config_autogen.h", - "${userHome}/.pico-sdk/sdk/2.2.0/src/common/pico_base_headers/include/pico.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 -} diff --git a/0x0026_functions/.vscode/cmake-kits.json b/0x0026_functions/.vscode/cmake-kits.json deleted file mode 100644 index b0f3815..0000000 --- a/0x0026_functions/.vscode/cmake-kits.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { - "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}" - } - } -] \ No newline at end of file diff --git a/0x0026_functions/.vscode/extensions.json b/0x0026_functions/.vscode/extensions.json deleted file mode 100644 index a940d7c..0000000 --- a/0x0026_functions/.vscode/extensions.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "recommendations": [ - "marus25.cortex-debug", - "ms-vscode.cpptools", - "ms-vscode.cpptools-extension-pack", - "ms-vscode.vscode-serial-monitor", - "raspberry-pi.raspberry-pi-pico" - ] -} \ No newline at end of file diff --git a/0x0026_functions/.vscode/launch.json b/0x0026_functions/.vscode/launch.json deleted file mode 100644 index 424aa71..0000000 --- a/0x0026_functions/.vscode/launch.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "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}\"" - ] - }, - ] -} diff --git a/0x0026_functions/.vscode/settings.json b/0x0026_functions/.vscode/settings.json deleted file mode 100644 index 95be83b..0000000 --- a/0x0026_functions/.vscode/settings.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "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" -} diff --git a/0x0026_functions/.vscode/tasks.json b/0x0026_functions/.vscode/tasks.json deleted file mode 100644 index d1b3193..0000000 --- a/0x0026_functions/.vscode/tasks.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "Compile Project", - "type": "process", - "isBuildCommand": true, - "command": "${userHome}/.pico-sdk/ninja/v1.12.1/ninja", - "args": ["-C", "${workspaceFolder}/build"], - "group": "build", - "presentation": { - "reveal": "always", - "panel": "dedicated" - }, - "problemMatcher": "$gcc", - "windows": { - "command": "${env:USERPROFILE}/.pico-sdk/ninja/v1.12.1/ninja.exe" - } - }, - { - "label": "Run Project", - "type": "process", - "command": "${env:HOME}/.pico-sdk/picotool/2.2.0-a4/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-a4/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", - } - } - ] -} diff --git a/0x0026_functions/0x0026_functions.c b/0x0026_functions/0x0026_functions.c deleted file mode 100644 index 518f5c0..0000000 --- a/0x0026_functions/0x0026_functions.c +++ /dev/null @@ -1,149 +0,0 @@ -#include -#include -#include "pico/stdlib.h" -#include "ir.h" - -#define IR_PIN 5 - -typedef struct { - uint8_t led1_pin; - uint8_t led2_pin; - uint8_t led3_pin; - bool led1_state; - bool led2_state; - bool led3_state; -} simple_led_ctrl_t; - -/** - * @brief Map NEC IR command code to LED number - * - * Translates a received NEC IR command code to a logical LED number. - * Supports three button mappings for controlling individual LEDs. - * - * @param ir_command NEC command code from IR receiver - * @return int LED number (1-3) or 0 if no match - */ -int ir_to_led_number(int ir_command) { - if (ir_command == 0x0C) return 1; - if (ir_command == 0x18) return 2; - if (ir_command == 0x5E) return 3; - return 0; -} - -/** - * @brief Get GPIO pin number for a given LED number - * - * Retrieves the GPIO pin associated with a logical LED number - * from the LED controller structure. - * - * @param leds Pointer to LED controller structure - * @param led_num LED number (1-3) - * @return uint8_t GPIO pin number or 0 if invalid - */ -uint8_t get_led_pin(simple_led_ctrl_t *leds, int led_num) { - if (led_num == 1) return leds->led1_pin; - if (led_num == 2) return leds->led2_pin; - if (led_num == 3) return leds->led3_pin; - return 0; -} - -/** - * @brief Turn off all LEDs in the controller - * - * Sets all three LED GPIO outputs to low, turning off all LEDs. - * - * @param leds Pointer to LED controller structure - */ -void leds_all_off(simple_led_ctrl_t *leds) { - gpio_put(leds->led1_pin, false); - gpio_put(leds->led2_pin, false); - gpio_put(leds->led3_pin, false); -} - -/** - * @brief Blink an LED pin a specified number of times - * - * Toggles the specified GPIO pin on and off for the given count, - * with configurable delay between transitions. - * - * @param pin GPIO pin number to blink - * @param count Number of blink cycles - * @param delay_ms Delay in milliseconds for on/off periods - */ -void blink_led(uint8_t pin, uint8_t count, uint32_t delay_ms) { - for (uint8_t i = 0; i < count; i++) { - gpio_put(pin, true); - sleep_ms(delay_ms); - gpio_put(pin, false); - sleep_ms(delay_ms); - } -} - -/** - * @brief Process IR command and activate corresponding LED - * - * Handles incoming IR commands by turning off all LEDs, mapping the - * command to an LED, blinking it, then holding it steady. - * - * @param ir_command NEC command code from IR receiver - * @param leds Pointer to LED controller structure - * @param blink_count Number of blinks before steady state - * @return int LED number activated (1-3), 0 if none, -1 if invalid - */ -int process_ir_led_command(int ir_command, simple_led_ctrl_t *leds, uint8_t blink_count) { - if (!leds || ir_command < 0) return -1; - leds_all_off(leds); - int led_num = ir_to_led_number(ir_command); - if (led_num == 0) return 0; - uint8_t pin = get_led_pin(leds, led_num); - blink_led(pin, blink_count, 50); - gpio_put(pin, true); - return led_num; -} - -int main(void) { - stdio_init_all(); - - simple_led_ctrl_t leds = { - .led1_pin = 16, - .led2_pin = 17, - .led3_pin = 18, - .led1_state = false, - .led2_state = false, - .led3_state = false - }; - - // Initialize LED GPIOs - gpio_init(leds.led1_pin); gpio_set_dir(leds.led1_pin, GPIO_OUT); - gpio_init(leds.led2_pin); gpio_set_dir(leds.led2_pin, GPIO_OUT); - gpio_init(leds.led3_pin); gpio_set_dir(leds.led3_pin, GPIO_OUT); - - // Initialize IR receiver - ir_init(IR_PIN); - printf("IR receiver on GPIO %d ready\n", IR_PIN); - printf("Press remote buttons to control LEDs with blink effects!\n"); - - while (true) { - int key = ir_getkey(); - if (key >= 0) { - printf("NEC command: 0x%02X\n", key); - - // Process the IR command with 3 blinks before steady state - int activated_led = process_ir_led_command(key, &leds, 3); - - if (activated_led > 0) { - printf("LED %d activated on GPIO %d\n", activated_led, - (activated_led == 1) ? leds.led1_pin : - (activated_led == 2) ? leds.led2_pin : leds.led3_pin); - } else if (activated_led == 0) { - printf("No LED matched or chase effect played\n"); - } else { - printf("Invalid command or null pointer\n"); - } - - sleep_ms(10); - } else { - sleep_ms(1); - } - } -} diff --git a/0x0026_functions/CMakeLists.txt b/0x0026_functions/CMakeLists.txt deleted file mode 100644 index b6ea0f9..0000000 --- a/0x0026_functions/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# 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-a4) -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(0x0026_functions 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(0x0026_functions 0x0026_functions.c ir.c) - -pico_set_program_name(0x0026_functions "0x0026_functions") -pico_set_program_version(0x0026_functions "0.1") - -# Modify the below lines to enable/disable output over UART/USB -pico_enable_stdio_uart(0x0026_functions 1) -pico_enable_stdio_usb(0x0026_functions 0) - -# Add the standard library to the build -target_link_libraries(0x0026_functions - pico_stdlib) - -# Add the standard include files to the build -target_include_directories(0x0026_functions PRIVATE - ${CMAKE_CURRENT_LIST_DIR} -) - -pico_add_extra_outputs(0x0026_functions) - diff --git a/0x0026_functions/ir.c b/0x0026_functions/ir.c deleted file mode 100644 index b89bd4e..0000000 --- a/0x0026_functions/ir.c +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @file ir.c - * @brief Implementation of NEC IR receiver (decoder) - * @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 "ir.h" -#include "pico/stdlib.h" -#include "pico/time.h" -#include "hardware/gpio.h" - -static unsigned int ir_pin = 0; - -// Wait for 'gpio' to reach 'level' or timeout (microseconds). Return elapsed us or -1. -static int64_t wait_for_level(unsigned int gpio, bool level, uint32_t timeout_us) { - absolute_time_t start = get_absolute_time(); - while (gpio_get(gpio) != level) { - if (absolute_time_diff_us(start, get_absolute_time()) > (int64_t)timeout_us) { - return -1; - } - } - return absolute_time_diff_us(start, get_absolute_time()); -} - -void ir_init(uint8_t pin) { - ir_pin = pin; - gpio_init(pin); - gpio_set_dir(pin, GPIO_IN); - gpio_pull_up(pin); -} - -int ir_getkey(void) { - // leader low (~9 ms) - if (wait_for_level(ir_pin, 0, 150000) < 0) return -1; - - int64_t t = wait_for_level(ir_pin, 1, 12000); - if (t < 8000 || t > 10000) return -1; - - t = wait_for_level(ir_pin, 0, 7000); - if (t < 3500 || t > 5000) return -1; - - uint8_t data[4] = {0, 0, 0, 0}; - for (int i = 0; i < 32; ++i) { - if (wait_for_level(ir_pin, 1, 1000) < 0) return -1; - t = wait_for_level(ir_pin, 0, 2500); - if (t < 200) return -1; - int byte_idx = i / 8; - int bit_idx = i % 8; - if (t > 1200) data[byte_idx] |= (1 << bit_idx); // logical '1' - } - - // Validate address/data inverted pairs - if ((uint8_t)(data[0] + data[1]) == 0xFF && (uint8_t)(data[2] + data[3]) == 0xFF) { - return data[2]; - } - return -1; -} diff --git a/0x0026_functions/ir.h b/0x0026_functions/ir.h deleted file mode 100644 index 84aa67f..0000000 --- a/0x0026_functions/ir.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - * @file ir.h - * @brief Header for NEC IR receiver (decoder) API - * @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 IR_H -#define IR_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Initialize the IR receiver GPIO - * - * Configures the given `pin` as an input with pull-up for the NEC IR receiver. - * Call this once during board initialization before calling `ir_getkey()`. - * - * @param pin GPIO pin number connected to IR receiver output - */ -void ir_init(uint8_t pin); - -/** - * @brief Blocking NEC IR decoder - * - * Blocks while waiting for a complete NEC frame. On success returns the - * decoded command byte (0..255). On timeout or protocol error returns -1. - * - * @return decoded command byte (0..255) or -1 on failure - */ -int ir_getkey(void); - -#ifdef __cplusplus -} -#endif - -#endif // IR_H diff --git a/0x0026_functions/pico_sdk_import.cmake b/0x0026_functions/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x0026_functions/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x0026a_custom-bootloader/.gitignore b/0x0026a_custom-bootloader/.gitignore deleted file mode 100644 index cd1e73d..0000000 --- a/0x0026a_custom-bootloader/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -!.vscode/* \ No newline at end of file diff --git a/0x0026a_custom-bootloader/0x0026a_app.bin b/0x0026a_custom-bootloader/0x0026a_app.bin deleted file mode 100755 index f6c83d6..0000000 Binary files a/0x0026a_custom-bootloader/0x0026a_app.bin and /dev/null differ diff --git a/0x0026a_custom-bootloader/0x0026a_bootloader.bin b/0x0026a_custom-bootloader/0x0026a_bootloader.bin deleted file mode 100755 index 5fd7c1b..0000000 Binary files a/0x0026a_custom-bootloader/0x0026a_bootloader.bin and /dev/null differ diff --git a/0x0026a_custom-bootloader/0x0026a_bootloader.uf2 b/0x0026a_custom-bootloader/0x0026a_bootloader.uf2 deleted file mode 100644 index dc84248..0000000 Binary files a/0x0026a_custom-bootloader/0x0026a_bootloader.uf2 and /dev/null differ diff --git a/0x0026a_custom-bootloader/0x0026a_full.uf2 b/0x0026a_custom-bootloader/0x0026a_full.uf2 deleted file mode 100644 index 5215266..0000000 Binary files a/0x0026a_custom-bootloader/0x0026a_full.uf2 and /dev/null differ diff --git a/0x0026a_custom-bootloader/CMakeLists.txt b/0x0026a_custom-bootloader/CMakeLists.txt deleted file mode 100644 index 299af94..0000000 --- a/0x0026a_custom-bootloader/CMakeLists.txt +++ /dev/null @@ -1,90 +0,0 @@ -# 0x0026a custom bootloader: builds a secure bootloader plus the signed -# application it launches. Run from this directory: -# -# cmake -B build -G Ninja -DPICO_BOARD=pico2 \ -# -DPICO_SDK_PATH="$HOME/.pico-sdk/sdk/2.2.0" \ -# -DPICO_TOOLCHAIN_PATH="$HOME/.pico-sdk/toolchain/14_2_Rel1" -# cmake --build build - -cmake_minimum_required(VERSION 3.13) - -set(CMAKE_C_STANDARD 11) -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -# == 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-a4) -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(0x0026a_custom_bootloader C CXX ASM) - -# Initialise the Raspberry Pi Pico SDK -pico_sdk_init() - -# --- Bootloader: verifies an AES-128-CMAC tag before launching the app -------- -add_executable(0x0026a_bootloader - bootloader/src/main.c - bootloader/src/boot.c - bootloader/src/manifest.c - bootloader/src/aes_cmac.c - bootloader/src/image.c - bootloader/src/verify.c) - -target_include_directories(0x0026a_bootloader PRIVATE - ${CMAKE_CURRENT_LIST_DIR}/bootloader/include - ${CMAKE_CURRENT_LIST_DIR}/common/include) - -# pico_mbedtls provides the AES-128-CMAC implementation used for verification. -target_link_libraries(0x0026a_bootloader PRIVATE - pico_stdlib - pico_mbedtls) - -pico_enable_stdio_uart(0x0026a_bootloader 1) -pico_enable_stdio_usb(0x0026a_bootloader 0) -pico_add_extra_outputs(0x0026a_bootloader) - -# --- Application: the 0x0026_functions firmware linked at 0x10020000 ---------- -add_executable(0x0026a_app - app/src/app_main.c - app/src/ir.c - app/src/led.c - app/src/secret.c) - -target_include_directories(0x0026a_app PRIVATE - ${CMAKE_CURRENT_LIST_DIR}/app/include - ${CMAKE_CURRENT_LIST_DIR}/common/include) - -# pico_mbedtls provides the AES-128-CBC API used by secret.c. -target_link_libraries(0x0026a_app PRIVATE - pico_stdlib - pico_mbedtls) - -pico_enable_stdio_uart(0x0026a_app 1) -pico_enable_stdio_usb(0x0026a_app 0) - -# Relocate the application into flash above the bootloader and manifest. -pico_set_linker_script(0x0026a_app - ${CMAKE_CURRENT_LIST_DIR}/app/memmap_app.ld) - -# The application starts at 0x10020000. A standalone app UF2 would flash only -# this one region, so the lab ships a single combined UF2 instead (built by -# tools/make_full_uf2.py). Emit the raw artifacts we sign and flash with OpenOCD. -pico_add_dis_output(0x0026a_app) -pico_add_hex_output(0x0026a_app) -pico_add_bin_output(0x0026a_app) -pico_add_map_output(0x0026a_app) diff --git a/0x0026a_custom-bootloader/README.md b/0x0026a_custom-bootloader/README.md deleted file mode 100644 index ee1bf71..0000000 --- a/0x0026a_custom-bootloader/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# 0x0026a Custom AES-128-CMAC Secure Bootloader - -This project builds a custom secure-boot chain for the Pico 2 (RP2350) that sits entirely above the ROM bootloader. A first-stage bootloader in XIP flash authenticates a signed application with AES-128-CMAC (RFC 4493) before jumping to it, and the signed application decrypts and prints a secret banner using the SDK Mbed TLS AES API. - -## What You'll Learn - -- Why a bootloader-only CRC/manifest is insufficient and what a MAC adds -- How AES-128-CMAC works (K1/K2 subkeys) and the RFC 4493 test vectors -- Custom linker-script editing (`pico_flash_region.ld`, `memmap_app.ld`) to relocate the app -- Flashing three images (bootloader, manifest, app) with OpenOCD -- Reverse engineering both images with GDB and Ghidra (find the key, IV, ciphertext, banner) - -See the full tutorial: [WEEK11a.md](../WEEK11/WEEK11a.md) / [WEEK11a.pdf](../WEEK11/WEEK11a.pdf) - -## Flash Map - -| Region | Address | Content | -| ---------- | ----------- | ------------------------------ | -| Bootloader | `0x10000000` | 0x0026a bootloader (27772 B) | -| Manifest | `0x1001F000` | header + AES-128-CMAC tag | -| App | `0x10020000` | 0x0026a signed app (21656 B) | - -The CMSIS-RM9 flash-safe range starts at `0x10000000` on the RP2350, so adding 2 MB relocates the app to `0x10020000`. - -## Artifacts - -| File | Description | -| ---------------------------- | ------------------------------------------------- | -| `0x0026a_bootloader.bin` | Bootloader image (flash at `0x10000000`) | -| `0x0026a_bootloader.uf2` | Bootloader-only UF2 for the BOOTSEL drag-and-drop | -| `0x0026a_app.bin` | Signed app image (flash at `0x10020000`) | -| `manifest.bin` | Manifest (flash at `0x1001F000`) | -| `0x0026a_full.uf2` | **All three images** in one BOOTSEL drag | -| `WEEK11a.md` / `WEEK11a.pdf` | Full lab notebook (in `WEEK11/`) | - -## Build - -```sh -cmake -B build -DPICO_SDK_PATH=~/.pico-sdk/sdk/2.2.0 -cmake --build build -python3 tools/sign_firmware.py build/0x0026a_app.bin --out manifest.bin --key "IronNetBootKey!!" --app-base 0x10020000 -PICOTOOL=~/.pico-sdk/picotool/2.3.1/picotool/picotool python3 tools/make_full_uf2.py -``` - -This produces `0x0026a_bootloader.bin/.uf2` and `0x0026a_app.bin`; the signer -writes `manifest.bin`; `make_full_uf2.py` packs all three into -`0x0026a_full.uf2`. - -## Flash - -Easiest - copy `0x0026a_full.uf2` to the `RP2350` BOOTSEL drive; one drag writes -the whole chain (bootloader + manifest + app). - -Or with OpenOCD: - -```sh -openocd -f interface/picoprobe.cfg -f target/rp2350.cfg -c \ - "program 0x0026a_bootloader.bin 0x10000000 verify; \ - program manifest.bin 0x1001F000 verify; \ - program 0x0026a_app.bin 0x10020000 verify; reset run; shutdown" -``` - -## Verify at Runtime - -Halt the core after boot and read the program counter. A valid signed image leaves PC inside the app (`0x100201xx`); a tampered or unsigned image leaves PC in the bootloader `boot_halt` idle loop near `0x10000eb2`. - -## Disclaimers - -This is an educational project for the Embedded-Hacking course. The key `IronNetBootKey!!` ships in the repo and is intentionally embedded in both images so it can be recovered with GDB/Ghidra. Do not use this scheme to protect real products. \ No newline at end of file diff --git a/0x0026a_custom-bootloader/app/include/ir.h b/0x0026a_custom-bootloader/app/include/ir.h deleted file mode 100644 index 84aa67f..0000000 --- a/0x0026a_custom-bootloader/app/include/ir.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - * @file ir.h - * @brief Header for NEC IR receiver (decoder) API - * @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 IR_H -#define IR_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Initialize the IR receiver GPIO - * - * Configures the given `pin` as an input with pull-up for the NEC IR receiver. - * Call this once during board initialization before calling `ir_getkey()`. - * - * @param pin GPIO pin number connected to IR receiver output - */ -void ir_init(uint8_t pin); - -/** - * @brief Blocking NEC IR decoder - * - * Blocks while waiting for a complete NEC frame. On success returns the - * decoded command byte (0..255). On timeout or protocol error returns -1. - * - * @return decoded command byte (0..255) or -1 on failure - */ -int ir_getkey(void); - -#ifdef __cplusplus -} -#endif - -#endif // IR_H diff --git a/0x0026a_custom-bootloader/app/include/led.h b/0x0026a_custom-bootloader/app/include/led.h deleted file mode 100644 index 7e0b63c..0000000 --- a/0x0026a_custom-bootloader/app/include/led.h +++ /dev/null @@ -1,63 +0,0 @@ -/** - * @file led.h - * @brief LED controller driven by decoded NEC IR commands. - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#ifndef LED_H -#define LED_H - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief LED controller state for the three IR-controlled LEDs. - * - * Maps each logical LED (1-3) to its GPIO pin and remembers whether the - * LED is currently on. Build a default instance with led_default() and - * drive it with led_init() and led_handle_ir(). - */ -typedef struct { - uint8_t led1_pin; - uint8_t led2_pin; - uint8_t led3_pin; - bool led1_state; - bool led2_state; - bool led3_state; -} simple_led_ctrl_t; - -/** - * @brief Build the default three-LED configuration (pins 16-18, all off). - * @param void No parameters. - * @return simple_led_ctrl_t Default LED controller state. - */ -simple_led_ctrl_t led_default(void); - -/** - * @brief Configure the three LED GPIO pins as outputs. - * @param leds Pointer to the LED controller to initialize. - * @return void No return value. - */ -void led_init(simple_led_ctrl_t *leds); - -/** - * @brief Dispatch a decoded NEC command to the matching LED. - * @param leds Pointer to the LED controller to drive. - * @param key Decoded NEC command byte, or a negative value to ignore. - * @return void No return value. - */ -void led_handle_ir(simple_led_ctrl_t *leds, int key); - -#ifdef __cplusplus -} -#endif - -#endif // LED_H \ No newline at end of file diff --git a/0x0026a_custom-bootloader/app/include/secret.h b/0x0026a_custom-bootloader/app/include/secret.h deleted file mode 100644 index 124a80e..0000000 --- a/0x0026a_custom-bootloader/app/include/secret.h +++ /dev/null @@ -1,29 +0,0 @@ -/** - * @file secret.h - * @brief AES-128-CBC protected runtime banner for the application. - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#ifndef SECRET_H -#define SECRET_H - -#include - -/** @brief AES block size in bytes used by the runtime banner. */ -#define APP_AES_BLOCK 16U - -/** @brief Length in bytes of the encrypted runtime banner. */ -#define APP_BANNER_LEN 32U - -/** - * @brief Decrypt the embedded AES-128-CBC banner and print it. - * @param void No parameters. - * @return int Zero on success, non-zero when decryption fails. - */ -int secret_print_banner(void); - -#endif diff --git a/0x0026a_custom-bootloader/app/memmap_app.ld b/0x0026a_custom-bootloader/app/memmap_app.ld deleted file mode 100644 index faa2c2c..0000000 --- a/0x0026a_custom-bootloader/app/memmap_app.ld +++ /dev/null @@ -1,305 +0,0 @@ -/* Based on GCC ARM embedded samples. - Defines the following symbols for use by code: - __exidx_start - __exidx_end - __etext - __data_start__ - __preinit_array_start - __preinit_array_end - __init_array_start - __init_array_end - __fini_array_start - __fini_array_end - __data_end__ - __bss_start__ - __bss_end__ - __end__ - end - __HeapLimit - __StackLimit - __StackTop - __stack (== StackTop) -*/ - -MEMORY -{ - /* Relocated for the custom bootloader: the application is linked to run - from 0x10020000, leaving the first 128k of flash for the bootloader and - its manifest. */ - FLASH(rx) : ORIGIN = 0x10020000, LENGTH = 1920k - RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 512k - SCRATCH_X(rwx) : ORIGIN = 0x20080000, LENGTH = 4k - SCRATCH_Y(rwx) : ORIGIN = 0x20081000, LENGTH = 4k -} - -ENTRY(_entry_point) - -SECTIONS -{ - .flash_begin : { - __flash_binary_start = .; - } > FLASH - - /* The bootrom will enter the image at the point indicated in your - IMAGE_DEF, which is usually the reset handler of your vector table. - - The debugger will use the ELF entry point, which is the _entry_point - symbol, and in our case is *different from the bootrom's entry point.* - This is used to go back through the bootrom on debugger launches only, - to perform the same initial flash setup that would be performed on a - cold boot. - */ - - .text : { - __logical_binary_start = .; - KEEP (*(.vectors)) - KEEP (*(.binary_info_header)) - __binary_info_header_end = .; - KEEP (*(.embedded_block)) - __embedded_block_end = .; - KEEP (*(.reset)) - /* TODO revisit this now memset/memcpy/float in ROM */ - /* bit of a hack right now to exclude all floating point and time critical (e.g. memset, memcpy) code from - * FLASH ... we will include any thing excluded here in .data below by default */ - *(.init) - *libgcc.a:cmse_nonsecure_call.o - *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*) - *(.fini) - /* Pull all c'tors into .text */ - *crtbegin.o(.ctors) - *crtbegin?.o(.ctors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) - *(SORT(.ctors.*)) - *(.ctors) - /* Followed by destructors */ - *crtbegin.o(.dtors) - *crtbegin?.o(.dtors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) - *(SORT(.dtors.*)) - *(.dtors) - - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP(*(SORT(.preinit_array.*))) - KEEP(*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - - . = ALIGN(4); - /* init data */ - PROVIDE_HIDDEN (__init_array_start = .); - KEEP(*(SORT(.init_array.*))) - KEEP(*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); - - . = ALIGN(4); - /* finit data */ - PROVIDE_HIDDEN (__fini_array_start = .); - *(SORT(.fini_array.*)) - *(.fini_array) - PROVIDE_HIDDEN (__fini_array_end = .); - - *(.eh_frame*) - . = ALIGN(4); - } > FLASH - - /* Note the boot2 section is optional, and should be discarded if there is - no reference to it *inside* the binary, as it is not called by the - bootrom. (The bootrom performs a simple best-effort XIP setup and - leaves it to the binary to do anything more sophisticated.) However - there is still a size limit of 256 bytes, to ensure the boot2 can be - stored in boot RAM. - - Really this is a "XIP setup function" -- the name boot2 is historic and - refers to its dual-purpose on RP2040, where it also handled vectoring - from the bootrom into the user image. - */ - - .boot2 : { - __boot2_start__ = .; - *(.boot2) - __boot2_end__ = .; - } > FLASH - - ASSERT(__boot2_end__ - __boot2_start__ <= 256, - "ERROR: Pico second stage bootloader must be no more than 256 bytes in size") - - .rodata : { - *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .rodata*) - *(.srodata*) - . = ALIGN(4); - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*))) - . = ALIGN(4); - } > FLASH - - .ARM.extab : - { - *(.ARM.extab* .gnu.linkonce.armextab.*) - } > FLASH - - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - } > FLASH - __exidx_end = .; - - /* Machine inspectable binary information */ - . = ALIGN(4); - __binary_info_start = .; - .binary_info : - { - KEEP(*(.binary_info.keep.*)) - *(.binary_info.*) - } > FLASH - __binary_info_end = .; - . = ALIGN(4); - - .ram_vector_table (NOLOAD): { - *(.ram_vector_table) - } > RAM - - .uninitialized_data (NOLOAD): { - . = ALIGN(4); - *(.uninitialized_data*) - } > RAM - - .data : { - __data_start__ = .; - *(vtable) - - *(.time_critical*) - - /* remaining .text and .rodata; i.e. stuff we exclude above because we want it in RAM */ - *(.text*) - . = ALIGN(4); - *(.rodata*) - . = ALIGN(4); - - *(.data*) - *(.sdata*) - - . = ALIGN(4); - *(.after_data.*) - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__mutex_array_start = .); - KEEP(*(SORT(.mutex_array.*))) - KEEP(*(.mutex_array)) - PROVIDE_HIDDEN (__mutex_array_end = .); - - *(.jcr) - . = ALIGN(4); - } > RAM AT> FLASH - - .tdata : { - . = ALIGN(4); - *(.tdata .tdata.* .gnu.linkonce.td.*) - /* All data end */ - __tdata_end = .; - } > RAM AT> FLASH - PROVIDE(__data_end__ = .); - - /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ - __etext = LOADADDR(.data); - - .tbss (NOLOAD) : { - . = ALIGN(4); - __bss_start__ = .; - __tls_base = .; - *(.tbss .tbss.* .gnu.linkonce.tb.*) - *(.tcommon) - - __tls_end = .; - } > RAM - - .bss (NOLOAD) : { - . = ALIGN(4); - __tbss_end = .; - - *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) - *(COMMON) - PROVIDE(__global_pointer$ = . + 2K); - *(.sbss*) - . = ALIGN(4); - __bss_end__ = .; - } > RAM - - .heap (NOLOAD): - { - __end__ = .; - end = __end__; - KEEP(*(.heap*)) - } > RAM - /* historically on GCC sbrk was growing past __HeapLimit to __StackLimit, however - to be more compatible, we now set __HeapLimit explicitly to where the end of the heap is */ - __HeapLimit = ORIGIN(RAM) + LENGTH(RAM); - - /* Start and end symbols must be word-aligned */ - .scratch_x : { - __scratch_x_start__ = .; - *(.scratch_x.*) - . = ALIGN(4); - __scratch_x_end__ = .; - } > SCRATCH_X AT > FLASH - __scratch_x_source__ = LOADADDR(.scratch_x); - - .scratch_y : { - __scratch_y_start__ = .; - *(.scratch_y.*) - . = ALIGN(4); - __scratch_y_end__ = .; - } > SCRATCH_Y AT > FLASH - __scratch_y_source__ = LOADADDR(.scratch_y); - - /* .stack*_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later - * - * stack1 section may be empty/missing if platform_launch_core1 is not used */ - - /* by default we put core 0 stack at the end of scratch Y, so that if core 1 - * stack is not used then all of SCRATCH_X is free. - */ - .stack1_dummy (NOLOAD): - { - *(.stack1*) - } > SCRATCH_X - .stack_dummy (NOLOAD): - { - KEEP(*(.stack*)) - } > SCRATCH_Y - - .flash_end : { - KEEP(*(.embedded_end_block*)) - PROVIDE(__flash_binary_end = .); - } > FLASH =0xaa - - /* stack limit is poorly named, but historically is maximum heap ptr */ - __StackLimit = ORIGIN(RAM) + LENGTH(RAM); - __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X); - __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y); - __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy); - __StackBottom = __StackTop - SIZEOF(.stack_dummy); - PROVIDE(__stack = __StackTop); - - /* picolibc and LLVM */ - PROVIDE (__heap_start = __end__); - PROVIDE (__heap_end = __HeapLimit); - PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); - PROVIDE( __tls_size_align = (__tls_size + __tls_align - 1) & ~(__tls_align - 1)); - PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) ); - - /* llvm-libc */ - PROVIDE (_end = __end__); - PROVIDE (__llvm_libc_heap_limit = __HeapLimit); - - /* Check if data + heap + stack exceeds RAM limit */ - ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed") - - ASSERT( __binary_info_header_end - __logical_binary_start <= 1024, "Binary info must be in first 1024 bytes of the binary") - ASSERT( __embedded_block_end - __logical_binary_start <= 4096, "Embedded block must be in first 4096 bytes of the binary") - - /* todo assert on extra code */ -} - diff --git a/0x0026a_custom-bootloader/app/src/app_main.c b/0x0026a_custom-bootloader/app/src/app_main.c deleted file mode 100644 index 16d9c78..0000000 --- a/0x0026a_custom-bootloader/app/src/app_main.c +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @file app_main.c - * @brief Application entry point: IR receiver drives the LED controller. - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - * - * ----------------------------------------------------------------------------- - * - * This file is deliberately thin: it only wires the modules together and runs - * the poll loop. The NEC IR decoder lives in ir.c, the LED controller lives in - * led.c, and the AES-128-CBC protected banner lives in secret.c. - * - * Wiring: - * GPIO5 -> IR receiver OUT - * GPIO16 -> LED1 anode (with current-limiting resistor to GND) - * GPIO17 -> LED2 anode (with current-limiting resistor to GND) - * GPIO18 -> LED3 anode (with current-limiting resistor to GND) - */ - -#include -#include -#include "pico/stdlib.h" -#include "ir.h" -#include "led.h" -#include "secret.h" - -/** @brief GPIO pin number for the IR receiver. */ -#define IR_PIN 5 - -/** - * @brief Poll the IR receiver and dispatch decoded keys forever. - * @param leds Pointer to the LED controller to drive. - * @return void Does not return. - */ -static void ir_poll_loop(simple_led_ctrl_t *leds) { - while (true) { - int key = ir_getkey(); - if (key >= 0) led_handle_ir(leds, key); - else sleep_ms(1); - } -} - -int main(void) { - stdio_init_all(); - secret_print_banner(); - simple_led_ctrl_t leds = led_default(); - led_init(&leds); - ir_init(IR_PIN); - printf("IR receiver on GPIO %d ready\n", IR_PIN); - ir_poll_loop(&leds); -} \ No newline at end of file diff --git a/0x0026a_custom-bootloader/app/src/ir.c b/0x0026a_custom-bootloader/app/src/ir.c deleted file mode 100644 index b47835c..0000000 --- a/0x0026a_custom-bootloader/app/src/ir.c +++ /dev/null @@ -1,131 +0,0 @@ -/** - * @file ir.c - * @brief Implementation of NEC IR receiver (decoder) - * @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 "ir.h" -#include "pico/stdlib.h" -#include "pico/time.h" -#include "hardware/gpio.h" - -/** @brief GPIO pin connected to the IR receiver */ -static unsigned int ir_pin = 0; - -/** - * @brief Wait for a GPIO pin to reach a given logic level - * - * Spins until the pin matches the requested level or a microsecond timeout - * is exceeded. Returns the elapsed time in microseconds, or -1 on timeout. - * - * @param gpio GPIO pin to monitor - * @param level Desired logic level (true = HIGH, false = LOW) - * @param timeout_us Maximum wait in microseconds - * @return int64_t Elapsed microseconds, or -1 on timeout - */ -static int64_t wait_for_level(unsigned int gpio, bool level, uint32_t timeout_us) { - absolute_time_t start = get_absolute_time(); - while (gpio_get(gpio) != level) { - if (absolute_time_diff_us(start, get_absolute_time()) > (int64_t)timeout_us) - return -1; - } - return absolute_time_diff_us(start, get_absolute_time()); -} - -/** - * @brief Wait for the NEC 9 ms leader pulse and 4.5 ms space - * - * @param void No parameters. - * @return bool true if a valid leader was detected, false on timeout - */ -static bool wait_leader(void) { - if (wait_for_level(ir_pin, 0, 150000) < 0) return false; - int64_t t = wait_for_level(ir_pin, 1, 12000); - if (t < 8000 || t > 10000) return false; - t = wait_for_level(ir_pin, 0, 7000); - if (t < 3500 || t > 5000) return false; - return true; -} - -/** - * @brief Read a single NEC-encoded bit from the IR receiver - * - * Measures the mark/space timing and shifts the result into the - * appropriate byte of the data array. - * - * @param data 4-byte array accumulating received bits - * @param i Bit index (0-31) - * @return bool true on success, false on timeout or protocol error - */ -static bool read_nec_bit(uint8_t *data, int i) { - if (wait_for_level(ir_pin, 1, 1000) < 0) return false; - int64_t t = wait_for_level(ir_pin, 0, 2500); - if (t < 200) return false; - int byte_idx = i / 8; - int bit_idx = i % 8; - if (t > 1200) data[byte_idx] |= (1 << bit_idx); - return true; -} - -/** - * @brief Read all 32 data bits of an NEC frame - * - * @param data 4-byte array filled with the received address and command - * @return bool true if all 32 bits were read, false on timeout - */ -static bool read_32_bits(uint8_t *data) { - for (int i = 0; i < 32; ++i) - if (!read_nec_bit(data, i)) return false; - return true; -} - -/** - * @brief Validate an NEC frame and extract the command byte - * - * Checks that the address and command pairs are bitwise-inverted. - * - * @param data 4-byte NEC frame (addr, ~addr, cmd, ~cmd) - * @return int Command byte (0-255) on success, -1 on validation failure - */ -static int validate_nec_frame(const uint8_t *data) { - if ((uint8_t)(data[0] + data[1]) == 0xFF && (uint8_t)(data[2] + data[3]) == 0xFF) - return data[2]; - return -1; -} - -void ir_init(uint8_t pin) { - ir_pin = pin; - gpio_init(pin); - gpio_set_dir(pin, GPIO_IN); - gpio_pull_up(pin); -} - -int ir_getkey(void) { - if (!wait_leader()) return -1; - uint8_t data[4] = {0, 0, 0, 0}; - if (!read_32_bits(data)) return -1; - return validate_nec_frame(data); -} diff --git a/0x0026a_custom-bootloader/app/src/led.c b/0x0026a_custom-bootloader/app/src/led.c deleted file mode 100644 index fee69f9..0000000 --- a/0x0026a_custom-bootloader/app/src/led.c +++ /dev/null @@ -1,103 +0,0 @@ -/** - * @file led.c - * @brief LED controller driven by decoded NEC IR commands. - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#include -#include "pico/stdlib.h" -#include "led.h" - -/** - * @brief Map an NEC command code to a logical LED number. - * @param ir_command Decoded NEC command byte. - * @return int Logical LED number 1-3, or 0 when the command is unmapped. - */ -static int led_number_for_command(int ir_command) { - if (ir_command == 0x0C) return 1; - if (ir_command == 0x18) return 2; - if (ir_command == 0x5E) return 3; - return 0; -} - -/** - * @brief Return the GPIO pin backing a logical LED number. - * @param leds Pointer to the LED controller. - * @param led_num Logical LED number (1-3). - * @return uint8_t GPIO pin number for the requested LED. - */ -static uint8_t led_pin_for(simple_led_ctrl_t *leds, int led_num) { - if (led_num == 1) return leds->led1_pin; - if (led_num == 2) return leds->led2_pin; - return leds->led3_pin; -} - -/** - * @brief Turn every LED output off. - * @param leds Pointer to the LED controller. - * @return void No return value. - */ -static void led_all_off(simple_led_ctrl_t *leds) { - gpio_put(leds->led1_pin, false); - gpio_put(leds->led2_pin, false); - gpio_put(leds->led3_pin, false); -} - -/** - * @brief Toggle a GPIO on and off for a number of blink cycles. - * @param pin GPIO pin to blink. - * @param count Number of on/off cycles. - * @param delay_ms Milliseconds to hold each phase. - * @return void No return value. - */ -static void led_blink(uint8_t pin, uint8_t count, uint32_t delay_ms) { - for (uint8_t i = 0; i < count; i++) { - gpio_put(pin, true); - sleep_ms(delay_ms); - gpio_put(pin, false); - sleep_ms(delay_ms); - } -} - -/** - * @brief Blink an LED, then leave it lit. - * @param leds Pointer to the LED controller. - * @param led_num Logical LED number to activate. - * @return void No return value. - */ -static void led_activate(simple_led_ctrl_t *leds, int led_num) { - uint8_t pin = led_pin_for(leds, led_num); - led_blink(pin, 3, 50); - gpio_put(pin, true); - printf("LED %d activated on GPIO %d\n", led_num, pin); -} - -simple_led_ctrl_t led_default(void) { - simple_led_ctrl_t leds = { - .led1_pin = 16, .led2_pin = 17, .led3_pin = 18, - .led1_state = false, .led2_state = false, .led3_state = false - }; - return leds; -} - -void led_init(simple_led_ctrl_t *leds) { - gpio_init(leds->led1_pin); - gpio_set_dir(leds->led1_pin, GPIO_OUT); - gpio_init(leds->led2_pin); - gpio_set_dir(leds->led2_pin, GPIO_OUT); - gpio_init(leds->led3_pin); - gpio_set_dir(leds->led3_pin, GPIO_OUT); -} - -void led_handle_ir(simple_led_ctrl_t *leds, int key) { - if (key < 0) return; - printf("NEC command: 0x%02X\n", key); - led_all_off(leds); - int led_num = led_number_for_command(key); - if (led_num == 0) return; - led_activate(leds, led_num); -} \ No newline at end of file diff --git a/0x0026a_custom-bootloader/app/src/secret.c b/0x0026a_custom-bootloader/app/src/secret.c deleted file mode 100644 index 8f6df9e..0000000 --- a/0x0026a_custom-bootloader/app/src/secret.c +++ /dev/null @@ -1,88 +0,0 @@ -/** - * @file secret.c - * @brief Decrypts a runtime banner with the SDK Mbed TLS AES-128-CBC API. - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - * - * ----------------------------------------------------------------------------- - * - * This module shows how to use the AES implementation that ships with the Pico - * SDK. A short banner is stored in flash only as AES-128-CBC ciphertext; the - * key and IV live in the same image. At startup secret_print_banner() rebuilds - * the plaintext with mbedtls_aes_crypt_cbc() and writes it to the console. - * - * The plaintext is exactly APP_BANNER_LEN bytes (two whole AES blocks), so no - * padding routine is required. The ciphertext was produced on the host with the - * matching key and IV, for example: - * - * printf '%s' 'SECRET: IR LINK SECURED ONLINE ' \ - * | openssl enc -aes-128-cbc -K 49726f6e4e6574426f6f744b65792121 \ - * -iv 41707053656372657449563132333435 -nopad | xxd -p - */ - -#include -#include -#include "mbedtls/aes.h" -#include "secret.h" - -/** @brief AES-128 key, the same 16 bytes the bootloader uses for CMAC. */ -static const uint8_t banner_key[APP_AES_BLOCK] = { - 0x49, 0x72, 0x6F, 0x6E, 0x4E, 0x65, 0x74, 0x42, - 0x6F, 0x6F, 0x74, 0x4B, 0x65, 0x79, 0x21, 0x21 -}; - -/** @brief Initialization vector used when the banner was encrypted. */ -static const uint8_t banner_iv[APP_AES_BLOCK] = { - 0x41, 0x70, 0x70, 0x53, 0x65, 0x63, 0x72, 0x65, - 0x74, 0x49, 0x56, 0x31, 0x32, 0x33, 0x34, 0x35 -}; - -/** @brief AES-128-CBC ciphertext of the runtime banner. */ -static const uint8_t banner_ct[APP_BANNER_LEN] = { - 0xBA, 0xEC, 0x4A, 0x19, 0x25, 0x86, 0x1B, 0xB9, - 0x2D, 0xFD, 0x9F, 0x13, 0xF7, 0x9B, 0x3E, 0x80, - 0xCF, 0x12, 0xB6, 0x98, 0xDB, 0x91, 0x65, 0xBE, - 0x8F, 0xD7, 0xC3, 0x47, 0x7B, 0xB2, 0xE7, 0x6E -}; - -/** - * @brief Run the AES-128-CBC decrypt in place over a working buffer. - * @param aes Pointer to an AES context holding an already-expanded key. - * @param iv Pointer to a mutable copy of the initialization vector. - * @param buf Pointer to the buffer holding ciphertext, then plaintext. - * @return int Zero on success, non-zero on failure. - */ -static int secret_cbc(mbedtls_aes_context *aes, uint8_t *iv, uint8_t *buf) { - int rc = mbedtls_aes_crypt_cbc(aes, MBEDTLS_AES_DECRYPT, APP_BANNER_LEN, - iv, buf, buf); - return rc; -} - -/** - * @brief Decrypt the banner ciphertext into a working buffer. - * @param buf Buffer of at least APP_BANNER_LEN bytes. - * @return int Zero on success, non-zero on failure. - */ -static int secret_decrypt(uint8_t *buf) { - mbedtls_aes_context aes; - uint8_t iv[APP_AES_BLOCK]; - memcpy(iv, banner_iv, APP_AES_BLOCK); - mbedtls_aes_init(&aes); - mbedtls_aes_setkey_dec(&aes, banner_key, 128); - int rc = secret_cbc(&aes, iv, buf); - mbedtls_aes_free(&aes); - return rc; -} - -int secret_print_banner(void) { - uint8_t buf[APP_BANNER_LEN + 1]; - memcpy(buf, banner_ct, APP_BANNER_LEN); - buf[APP_BANNER_LEN] = '\0'; - int rc = secret_decrypt(buf); - if (rc != 0) return rc; - printf("app banner: %s\n", (char *)buf); - return 0; -} diff --git a/0x0026a_custom-bootloader/bootloader/include/aes_cmac.h b/0x0026a_custom-bootloader/bootloader/include/aes_cmac.h deleted file mode 100644 index 8510e8a..0000000 --- a/0x0026a_custom-bootloader/bootloader/include/aes_cmac.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @file aes_cmac.h - * @brief AES-128-CMAC authentication tag helpers backed by Mbed TLS. - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#ifndef AES_CMAC_H -#define AES_CMAC_H - -#include -#include -#include - -/** @brief AES block size in bytes. */ -#define AES_BLOCK_SIZE 16U - -/** - * @brief Compute an AES-128-CMAC tag over a memory region. - * @param key Pointer to the 16-byte AES-128 key. - * @param data Pointer to the message bytes, which may live in XIP flash. - * @param len Message length in bytes. - * @param tag Output buffer that receives the 16-byte CMAC tag. - * @return int Zero on success, non-zero when the cipher is unavailable. - */ -int aes128_cmac(const uint8_t *key, const uint8_t *data, size_t len, - uint8_t *tag); - -/** - * @brief Compare two CMAC tags without short-circuiting on the first byte. - * @param a Pointer to the first tag. - * @param b Pointer to the second tag. - * @return bool True when the tags are byte-for-byte identical. - */ -bool cmac_tags_equal(const uint8_t *a, const uint8_t *b); - -#endif diff --git a/0x0026a_custom-bootloader/bootloader/include/boot.h b/0x0026a_custom-bootloader/bootloader/include/boot.h deleted file mode 100644 index 09f6e58..0000000 --- a/0x0026a_custom-bootloader/bootloader/include/boot.h +++ /dev/null @@ -1,45 +0,0 @@ -/** - * @file boot.h - * @brief Secure boot console and application handoff helpers. - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#ifndef BOOT_H -#define BOOT_H - -#include "manifest.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Bring up the debug console and print the boot banner. - * @param void No parameters. - * @return void No return value. - */ -void boot_init(void); - -/** - * @brief Print a boot failure reason and idle forever. - * @param reason Null-terminated message describing the failure. - * @return void Does not return. - */ -void boot_halt(const char *reason); - -/** - * @brief Announce the verified image and jump to its reset vector. - * @param manifest Pointer to the validated manifest. - * @return void Does not return. - */ -void boot_launch(const fw_manifest_t *manifest); - -#ifdef __cplusplus -} -#endif - -#endif // BOOT_H \ No newline at end of file diff --git a/0x0026a_custom-bootloader/bootloader/include/flash_layout.h b/0x0026a_custom-bootloader/bootloader/include/flash_layout.h deleted file mode 100644 index 9338649..0000000 --- a/0x0026a_custom-bootloader/bootloader/include/flash_layout.h +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @file flash_layout.h - * @brief Flash partition map shared by the bootloader and the host signer. - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#ifndef FLASH_LAYOUT_H -#define FLASH_LAYOUT_H - -#include - -/** @brief Absolute base address of the bootloader image in XIP flash. */ -#define BOOTLOADER_BASE 0x10000000U - -/** @brief Absolute address of the one-sector firmware manifest. */ -#define FW_MANIFEST_BASE 0x1001F000U - -/** @brief Size in bytes of the flash sector holding the manifest. */ -#define FW_MANIFEST_SECTOR_SIZE 4096U - -/** @brief Absolute base address where the signed application runs. */ -#define APP_BASE 0x10020000U - -/** @brief Total XIP flash size in bytes on the RP2350 Pico 2 board. */ -#define FLASH_TOTAL_SIZE 0x200000U - -#endif diff --git a/0x0026a_custom-bootloader/bootloader/include/image.h b/0x0026a_custom-bootloader/bootloader/include/image.h deleted file mode 100644 index 5173845..0000000 --- a/0x0026a_custom-bootloader/bootloader/include/image.h +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @file image.h - * @brief Control transfer into a freshly verified Cortex-M application. - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#ifndef IMAGE_H -#define IMAGE_H - -#include - -/** - * @brief Jump to an application whose vector table starts at a base address. - * @param vector_base Base address of the application vector table. - * @return void Does not return to the caller. - */ -void image_start(uint32_t vector_base); - -#endif diff --git a/0x0026a_custom-bootloader/bootloader/include/manifest.h b/0x0026a_custom-bootloader/bootloader/include/manifest.h deleted file mode 100644 index 2bc5336..0000000 --- a/0x0026a_custom-bootloader/bootloader/include/manifest.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @file manifest.h - * @brief Firmware manifest stored in the flash sector before the application. - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#ifndef MANIFEST_H -#define MANIFEST_H - -#include -#include - -/** @brief Little-endian magic at the head of a valid manifest ("WFLB"). */ -#define FW_MANIFEST_MAGIC 0x424C4657U - -/** @brief Current manifest structure revision. */ -#define FW_MANIFEST_VERSION 1U - -/** @brief Length in bytes of an AES-128-CMAC authentication tag. */ -#define FW_TAG_SIZE 16U - -#pragma pack(push, 1) -/** @brief Fixed-layout record describing the signed application image. */ -typedef struct { - uint32_t magic; - uint32_t version; - uint32_t app_base; - uint32_t app_size; - uint8_t tag[FW_TAG_SIZE]; -} fw_manifest_t; -#pragma pack(pop) - -/** - * @brief Copy the manifest out of its fixed flash address. - * @param out Pointer to the manifest structure to populate. - * @return void No return value. - */ -void manifest_read(fw_manifest_t *out); - -/** - * @brief Report whether a manifest carries the expected magic and version. - * @param manifest Pointer to the manifest to inspect. - * @return bool True when the magic and version both match. - */ -bool manifest_is_valid(const fw_manifest_t *manifest); - -#endif diff --git a/0x0026a_custom-bootloader/bootloader/include/verify.h b/0x0026a_custom-bootloader/bootloader/include/verify.h deleted file mode 100644 index 5734107..0000000 --- a/0x0026a_custom-bootloader/bootloader/include/verify.h +++ /dev/null @@ -1,32 +0,0 @@ -/** - * @file verify.h - * @brief Firmware authenticity verification for the secure bootloader. - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#ifndef VERIFY_H -#define VERIFY_H - -#include -#include "manifest.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Recompute the CMAC over the application and compare it to the tag. - * @param manifest Pointer to the validated manifest. - * @return bool True when the tag matches, false otherwise. - */ -bool verify_manifest(const fw_manifest_t *manifest); - -#ifdef __cplusplus -} -#endif - -#endif // VERIFY_H \ No newline at end of file diff --git a/0x0026a_custom-bootloader/bootloader/src/aes_cmac.c b/0x0026a_custom-bootloader/bootloader/src/aes_cmac.c deleted file mode 100644 index 9dcc481..0000000 --- a/0x0026a_custom-bootloader/bootloader/src/aes_cmac.c +++ /dev/null @@ -1,29 +0,0 @@ -/** - * @file aes_cmac.c - * @brief AES-128-CMAC primitives implemented on top of the SDK Mbed TLS. - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#include "mbedtls/cmac.h" -#include "mbedtls/cipher.h" -#include "aes_cmac.h" - -int aes128_cmac(const uint8_t *key, const uint8_t *data, size_t len, - uint8_t *tag) { - const mbedtls_cipher_info_t *info; - info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB); - if (info == NULL) return -1; - return mbedtls_cipher_cmac(info, key, 128, data, len, tag); -} - -bool cmac_tags_equal(const uint8_t *a, const uint8_t *b) { - uint8_t diff = 0; - for (size_t i = 0; i < AES_BLOCK_SIZE; i++) { - diff |= (uint8_t)(a[i] ^ b[i]); - } - return diff == 0; -} diff --git a/0x0026a_custom-bootloader/bootloader/src/boot.c b/0x0026a_custom-bootloader/bootloader/src/boot.c deleted file mode 100644 index 0b1dcb1..0000000 --- a/0x0026a_custom-bootloader/bootloader/src/boot.c +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @file boot.c - * @brief Secure boot console and application handoff helpers. - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#include -#include "pico/stdlib.h" -#include "boot.h" -#include "image.h" - -void boot_init(void) { - stdio_init_all(); - sleep_ms(2000); - printf("\n=== 0x0026a secure bootloader ===\n"); -} - -void boot_halt(const char *reason) { - printf("BOOT FAILED: %s\n", reason); - while (true) { - sleep_ms(500); - } -} - -void boot_launch(const fw_manifest_t *manifest) { - printf("signature valid, entering app at 0x%08lx\n", - (unsigned long)manifest->app_base); - image_start(manifest->app_base); -} \ No newline at end of file diff --git a/0x0026a_custom-bootloader/bootloader/src/image.c b/0x0026a_custom-bootloader/bootloader/src/image.c deleted file mode 100644 index 8e3a5f3..0000000 --- a/0x0026a_custom-bootloader/bootloader/src/image.c +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @file image.c - * @brief Loads the application stack pointer and branches to its reset vector. - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#include "image.h" - -/** @brief Application reset handler signature. */ -typedef void (*image_entry_t)(void); - -/** - * @brief Mask interrupts and point VTOR at the incoming image. - * @param base Vector table base address written to the VTOR register. - * @return void No return value. - */ -static void halt_irq_and_rebase(uint32_t base) { - __asm volatile ("cpsid i" ::: "memory"); - *(volatile uint32_t *)0xE000ED08U = base; -} - -void image_start(uint32_t vector_base) { - uint32_t *vectors = (uint32_t *)vector_base; - image_entry_t entry = (image_entry_t)vectors[1]; - halt_irq_and_rebase(vector_base); - __asm volatile ("msr msp, %0" :: "r" (vectors[0]) : "memory"); - __asm volatile ("dsb\n\tisb" ::: "memory"); - entry(); -} diff --git a/0x0026a_custom-bootloader/bootloader/src/main.c b/0x0026a_custom-bootloader/bootloader/src/main.c deleted file mode 100644 index 044abf5..0000000 --- a/0x0026a_custom-bootloader/bootloader/src/main.c +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @file main.c - * @brief Secure bootloader entry point (verify AES-128-CMAC, then boot). - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - * - * ----------------------------------------------------------------------------- - * - * This file is deliberately thin: it only sequences the secure boot steps. - * The console setup, halt reporting, and application handoff live in boot.c; - * the CMAC verification (and its key) live in verify.c; the manifest lives in - * manifest.c; and the raw reset-vector jump lives in image.c. - * - * Flash map (2 MiB, RP2350 Pico 2): - * 0x10000000 bootloader image (this program) - * 0x1001F000 one-sector firmware manifest (magic, size, CMAC tag) - * 0x10020000 signed application image - */ - -#include "manifest.h" -#include "boot.h" -#include "verify.h" - -int main(void) { - fw_manifest_t manifest; - boot_init(); - manifest_read(&manifest); - if (!manifest_is_valid(&manifest)) boot_halt("manifest invalid"); - if (!verify_manifest(&manifest)) boot_halt("firmware signature invalid"); - boot_launch(&manifest); -} \ No newline at end of file diff --git a/0x0026a_custom-bootloader/bootloader/src/manifest.c b/0x0026a_custom-bootloader/bootloader/src/manifest.c deleted file mode 100644 index 90514c1..0000000 --- a/0x0026a_custom-bootloader/bootloader/src/manifest.c +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @file manifest.c - * @brief Reads and validates the firmware manifest from XIP flash. - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#include "flash_layout.h" -#include "manifest.h" - -void manifest_read(fw_manifest_t *out) { - const fw_manifest_t *src = (const fw_manifest_t *)FW_MANIFEST_BASE; - *out = *src; -} - -bool manifest_is_valid(const fw_manifest_t *manifest) { - if (manifest->magic != FW_MANIFEST_MAGIC) return false; - if (manifest->version != FW_MANIFEST_VERSION) return false; - return true; -} diff --git a/0x0026a_custom-bootloader/bootloader/src/verify.c b/0x0026a_custom-bootloader/bootloader/src/verify.c deleted file mode 100644 index 08b55cd..0000000 --- a/0x0026a_custom-bootloader/bootloader/src/verify.c +++ /dev/null @@ -1,28 +0,0 @@ -/** - * @file verify.c - * @brief Firmware authenticity verification for the secure bootloader. - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - */ - -#include -#include "flash_layout.h" -#include "verify.h" -#include "aes_cmac.h" - -/** @brief AES-128 key that authenticates the application image. */ -static const uint8_t fw_key[FW_TAG_SIZE] = { - 0x49, 0x72, 0x6F, 0x6E, 0x4E, 0x65, 0x74, 0x42, - 0x6F, 0x6F, 0x74, 0x4B, 0x65, 0x79, 0x21, 0x21 -}; - -bool verify_manifest(const fw_manifest_t *manifest) { - const uint8_t *base = (const uint8_t *)manifest->app_base; - uint8_t computed[FW_TAG_SIZE]; - int rc = aes128_cmac(fw_key, base, manifest->app_size, computed); - if (rc != 0) return false; - return cmac_tags_equal(computed, manifest->tag); -} \ No newline at end of file diff --git a/0x0026a_custom-bootloader/common/include/mbedtls_config.h b/0x0026a_custom-bootloader/common/include/mbedtls_config.h deleted file mode 100644 index 12ec622..0000000 --- a/0x0026a_custom-bootloader/common/include/mbedtls_config.h +++ /dev/null @@ -1,25 +0,0 @@ -/** - * @file mbedtls_config.h - * @brief Minimal Mbed TLS configuration for the 0x0026a bootloader and app. - * @author Kevin Thomas - * @date 2026 - * - * MIT License - * Copyright (c) 2026 Kevin Thomas - * - * The Pico SDK points MBEDTLS_CONFIG_FILE at pico_mbedtls_config.h, which in - * turn includes this file. Only the AES-128 building blocks needed for CMAC - * authentication and CBC encryption are enabled, keeping the image small. - */ - -#ifndef MBEDTLS_CONFIG_H -#define MBEDTLS_CONFIG_H - -#include - -#define MBEDTLS_AES_C -#define MBEDTLS_CIPHER_C -#define MBEDTLS_CIPHER_MODE_CBC -#define MBEDTLS_CMAC_C - -#endif diff --git a/0x0026a_custom-bootloader/manifest.bin b/0x0026a_custom-bootloader/manifest.bin deleted file mode 100644 index 7b734c4..0000000 Binary files a/0x0026a_custom-bootloader/manifest.bin and /dev/null differ diff --git a/0x0026a_custom-bootloader/pico_sdk_import.cmake b/0x0026a_custom-bootloader/pico_sdk_import.cmake deleted file mode 100644 index d493cc2..0000000 --- a/0x0026a_custom-bootloader/pico_sdk_import.cmake +++ /dev/null @@ -1,121 +0,0 @@ -# This is a copy of /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}) diff --git a/0x0026a_custom-bootloader/tools/make_full_uf2.py b/0x0026a_custom-bootloader/tools/make_full_uf2.py deleted file mode 100755 index bf65bea..0000000 --- a/0x0026a_custom-bootloader/tools/make_full_uf2.py +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/bin/env python3 -"""Build a single BOOTSEL-draggable UF2 holding the whole secure-boot chain. - -The 0x0026a chain is three separate images at three flash addresses: - - bootloader 0x10000000 (owns the system, verifies the next image) - manifest 0x1001F000 (header + AES-128-CMAC tag) - app 0x10020000 (the signed application) - -The SDK emits a UF2 only for the bootloader, so a bare board would need three -separate flashes. This tool packs all three into ONE UF2 so a single BOOTSEL -drag-and-drop brings the whole device up. - -How it works: - - 1. Lay the three images out in a flat buffer whose offset 0 maps to - 0x10000000, filling the reserved gap between them with 0xFF (erased - flash). - 2. Hand that flat image to picotool as a normal image at 0x10000000. - 3. picotool numbers the blocks, tags them with the rp2350-arm-s family and - injects the RP2350-E10 absolute block that makes the boot ROM write each - block to its absolute address. - -The result is exactly the shape the boot ROM accepts over the BOOTSEL mass -storage interface, and it has been verified on hardware: the ROM accepts the -drag, the bootloader verifies the manifest, and the app runs. -""" - -import argparse -import hashlib -import os -import struct -import subprocess -import sys -import tempfile - -BOOTLOADER_BASE = 0x10000000 -MANIFEST_BASE = 0x1001F000 -APP_BASE = 0x10020000 -FAMILY = "rp2350-arm-s" -PLATFORM = "rp2350" - - -def build_flat(bootloader, manifest, app): - """Lay the three images out flat, offset 0 mapped to 0x10000000.""" - if APP_BASE < MANIFEST_BASE < BOOTLOADER_BASE: - raise SystemExit("address map is not ordered") - size = (APP_BASE - BOOTLOADER_BASE) + len(app) - image = bytearray(b"\xFF" * size) - image[0:len(bootloader)] = bootloader - m_off = MANIFEST_BASE - BOOTLOADER_BASE - image[m_off:m_off + len(manifest)] = manifest - a_off = APP_BASE - BOOTLOADER_BASE - image[a_off:a_off + len(app)] = app - return bytes(image) - - -def convert(flat, out, picotool): - """Run picotool to turn the flat image into an absolute-address UF2.""" - with tempfile.NamedTemporaryFile(suffix=".bin", delete=False) as tmp: - tmp.write(flat) - flat_path = tmp.name - try: - cmd = [ - picotool, "uf2", "convert", flat_path, out, - "-o", hex(BOOTLOADER_BASE), - "--family", FAMILY, - "--platform", PLATFORM, - "--abs-block", - ] - subprocess.run(cmd, check=True) - finally: - os.unlink(flat_path) - - -def verify(out): - """Report the block count and the families present in the UF2.""" - data = open(out, "rb").read() - blocks = [data[i:i + 512] for i in range(0, len(data), 512)] - families = set() - payload = 0 - for blk in blocks: - if len(blk) != 512 or struct.unpack_from(" int: - """Multiply a byte by x in GF(2^8).""" - value <<= 1 - return (value ^ RB) & 0xFF if value & 0x100 else value - - -def _expand_key(key: bytes) -> list[int]: - """Expand a 16-byte key into the 176-byte AES-128 round key schedule.""" - schedule = list(key) - for index in range(16, 176, 4): - word = schedule[index - 4:index] - if index % 16 == 0: - word = word[1:] + word[:1] - word = [SBOX[byte] for byte in word] - word[0] ^= RCON[index // 16 - 1] - for offset in range(4): - schedule.append(schedule[index - 16 + offset] ^ word[offset]) - return schedule - - -def _add_round_key(state: list[int], schedule: list[int]) -> None: - """XOR the round key into the state in place.""" - for index in range(16): - state[index] ^= schedule[index] - - -def _sub_bytes(state: list[int]) -> None: - """Apply the AES S-box to every byte of the state.""" - for index in range(16): - state[index] = SBOX[state[index]] - - -def _shift_rows(state: list[int]) -> None: - """Rotate each row of the AES state left by its row index.""" - for row in range(1, 4): - cells = [state[row + 4 * col] for col in range(4)] - cells = cells[row:] + cells[:row] - for col in range(4): - state[row + 4 * col] = cells[col] - - -def _mix_columns(state: list[int]) -> None: - """Mix each column of the AES state with the fixed AES matrix.""" - for col in range(4): - base = 4 * col - a0, a1, a2, a3 = state[base:base + 4] - total = a0 ^ a1 ^ a2 ^ a3 - state[base + 0] = a0 ^ total ^ _xtime(a0 ^ a1) - state[base + 1] = a1 ^ total ^ _xtime(a1 ^ a2) - state[base + 2] = a2 ^ total ^ _xtime(a2 ^ a3) - state[base + 3] = a3 ^ total ^ _xtime(a3 ^ a0) - - -def aes_encrypt_block(block: bytes, schedule: list[int]) -> bytes: - """Encrypt one 16-byte block with the supplied round key schedule.""" - state = list(block) - _add_round_key(state, schedule) - for round_index in range(1, 10): - _sub_bytes(state) - _shift_rows(state) - _mix_columns(state) - _add_round_key(state, schedule[16 * round_index:]) - _sub_bytes(state) - _shift_rows(state) - _add_round_key(state, schedule[160:]) - return bytes(state) - - -def _double(block: bytes) -> bytes: - """Left-shift a 128-bit big-endian value, folding in the CMAC constant.""" - value = int.from_bytes(block, "big") - value <<= 1 - if block[0] & 0x80: - value ^= RB_128 - return (value & ((1 << 128) - 1)).to_bytes(16, "big") - - -def _subkeys(schedule: list[int]) -> tuple[bytes, bytes]: - """Derive the RFC 4493 K1 and K2 subkeys.""" - k1 = _double(aes_encrypt_block(bytes(16), schedule)) - return k1, _double(k1) - - -def _xor(left: bytes, right: bytes) -> bytes: - """XOR two equal-length byte strings.""" - return bytes(a ^ b for a, b in zip(left, right)) - - -def aes128_cmac(key: bytes, message: bytes) -> bytes: - """Return the RFC 4493 AES-128-CMAC tag of a message.""" - schedule = _expand_key(key) - k1, k2 = _subkeys(schedule) - blocks = [message[i:i + 16] for i in range(0, len(message), 16)] - complete = bool(blocks) and len(blocks[-1]) == 16 - if not complete: - tail = (blocks[-1] + b"\x80") if blocks else b"\x80" - blocks = blocks[:-1] + [tail.ljust(16, b"\x00")] - last = blocks[-1] - last = _xor(last, k1 if complete else k2) - state = bytes(16) - for block in blocks[:-1]: - state = aes_encrypt_block(_xor(state, block), schedule) - return aes_encrypt_block(_xor(state, last), schedule) - - -def build_manifest(app: bytes, app_base: int, key: bytes) -> bytes: - """Assemble the padded manifest sector for an application image.""" - tag = aes128_cmac(key, app) - header = struct.pack(" bytes: - """Decode a hex or UTF-8 key argument into 16 bytes.""" - raw = bytes.fromhex(text) if len(text) == 32 else text.encode() - if len(raw) != 16: - raise argparse.ArgumentTypeError("key must be 16 bytes") - return raw - - -def _read_image(path: str) -> bytes: - """Read an application binary from disk.""" - data = Path(path).read_bytes() - if not data: - raise SystemExit(f"error: {path} is empty") - return data - - -def _cmd_sign(args: argparse.Namespace) -> int: - """Sign an image and write the manifest sector.""" - app = _read_image(args.image) - manifest = build_manifest(app, args.app_base, args.key) - out = Path(args.out) - out.parent.mkdir(parents=True, exist_ok=True) - out.write_bytes(manifest) - tag = manifest[16:32].hex() - print(f"image : {args.image} ({len(app)} bytes)") - print(f"app_base : 0x{args.app_base:08x}") - print(f"cmac tag : {tag}") - print(f"manifest : {out} ({len(manifest)} bytes)") - return 0 - - -def _cmd_verify(args: argparse.Namespace) -> int: - """Recompute the tag and compare it against a manifest on disk.""" - app = _read_image(args.image) - manifest = Path(args.verify).read_bytes() - stored = manifest[16:32] - expected = aes128_cmac(args.key, app) - print(f"stored : {stored.hex()}") - print(f"computed : {expected.hex()}") - if stored != expected: - print("result : MISMATCH") - return 1 - print("result : MATCH") - return 0 - - -def main() -> int: - """Parse arguments and dispatch to sign or verify.""" - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument("image", help="raw application .bin to sign") - parser.add_argument("--out", default="manifest.bin", - help="manifest output path (default: manifest.bin)") - parser.add_argument("--app-base", type=lambda v: int(v, 0), - default=DEFAULT_APP_BASE, - help="application base address (default: 0x10020000)") - parser.add_argument("--key", type=_parse_key, default=DEFAULT_KEY, - help="16-byte AES key as text or 32 hex digits") - parser.add_argument("--verify", metavar="MANIFEST", - help="verify an existing manifest instead of signing") - args = parser.parse_args() - if args.verify: - return _cmd_verify(args) - return _cmd_sign(args) - - -if __name__ == "__main__": - raise SystemExit(main()) diff --git a/README.md b/README.md index 79aed78..bb2b4c8 100644 --- a/README.md +++ b/README.md @@ -138,30 +138,30 @@ The **build** step is identical on all three platforms — CMake and Ninja are c ### Windows x64 ```powershell -cd 0x0001_hello-world +cd WEEK01\0x0001_hello-world cmake -B build -G Ninja -DPICO_BOARD=pico2 -DPICO_PLATFORM=rp2350 -DCMAKE_BUILD_TYPE=Release cmake --build build -..\flash.ps1 build\0x0001_hello-world.bin +..\..\flash.ps1 build\0x0001_hello-world.bin ``` Serial monitor: **PuTTY** -> *Serial* -> the Debug Probe's COM port -> **115200**. ### macOS Apple Silicon ```bash -cd 0x0001_hello-world +cd WEEK01/0x0001_hello-world cmake -B build -G Ninja -DPICO_BOARD=pico2 -DPICO_PLATFORM=rp2350 -DCMAKE_BUILD_TYPE=Release cmake --build build -../flash.sh build/0x0001_hello-world.bin +../../flash.sh build/0x0001_hello-world.bin screen /dev/cu.usbmodem* 115200 ``` ### Linux x64 ```bash -cd 0x0001_hello-world +cd WEEK01/0x0001_hello-world cmake -B build -G Ninja -DPICO_BOARD=pico2 -DPICO_PLATFORM=rp2350 -DCMAKE_BUILD_TYPE=Release cmake --build build -../flash.sh build/0x0001_hello-world.bin +../../flash.sh build/0x0001_hello-world.bin screen /dev/ttyACM0 115200 ``` @@ -283,15 +283,15 @@ Embedded System Analysis: Understanding the RP2350 Architecture w/ Comprehensive ### Ghidra Patching Tutorial [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK03/GHIDRA_PATCHING_TUTORIAL.md) -### CTF-01 Instructions [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x0001b_ctf/CTF-01-I.md) +### CTF-01 Instructions [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK04/0x0001b_ctf/CTF-01-I.md) -### CTF-01 Rubric [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x0001b_ctf/CTF-01-R.md) +### CTF-01 Rubric [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK04/0x0001b_ctf/CTF-01-R.md) -### CTF-01 Solution [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x0001b_ctf/CTF-01-S.md) +### CTF-01 Solution [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK04/0x0001b_ctf/CTF-01-S.md) -### CTF-01 BIN [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x0001b_ctf/CTF-01.bin) +### CTF-01 BIN [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK04/0x0001b_ctf/CTF-01.bin) -### CTF-01 UF2 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x0001b_ctf/CTF-01.uf2) +### CTF-01 UF2 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK04/0x0001b_ctf/CTF-01.uf2) ### Chapter 4: Embedded System Analysis This chapter covers a comprehensive embedded system analysis reviewing parts of the RP2350 datasheet and helpful firmware analysis tools. @@ -406,11 +406,11 @@ This chapter covers hacking the double floating-point data type as it relates to ## Week 6 Static Variables in Embedded Systems: Debugging and Hacking Static Variables w/ GPIO Input Basics -### Classified Brief 0x01 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x0011a_cb/CLASSIFIED-BRIEF-0x01.md) +### Classified Brief 0x01 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK05/0x0011a_cb/CLASSIFIED-BRIEF-0x01.md) -### Classified Brief 0x01 BIN [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x0011a_cb/0x0011a_cb.bin) +### Classified Brief 0x01 BIN [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK05/0x0011a_cb/0x0011a_cb.bin) -### Classified Brief 0x01 UF2 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x0011a_cb/0x0011a_cb.uf2) +### Classified Brief 0x01 UF2 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK05/0x0011a_cb/0x0011a_cb.uf2) ### Week 6 Slides [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK06/WEEK06-SLIDES.pdf) @@ -438,11 +438,11 @@ This chapter covers hacking static variables as well as an intro to GPIO inputs ## Week 7 Constants in Embedded Systems: Debugging and Hacking Constants w/ 1602 LCD I2C Basics -### Classified Brief 0x02 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x0014a_cb/CLASSIFIED-BRIEF-0x02.md) +### Classified Brief 0x02 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK06/0x0014a_cb/CLASSIFIED-BRIEF-0x02.md) -### Classified Brief 0x02 BIN [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x0014a_cb/0x0014a_cb.bin) +### Classified Brief 0x02 BIN [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK06/0x0014a_cb/0x0014a_cb.bin) -### Classified Brief 0x02 UF2 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x0014a_cb/0x0014a_cb.uf2) +### Classified Brief 0x02 UF2 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK06/0x0014a_cb/0x0014a_cb.uf2) ### Week 7 Slides [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK07/WEEK07-SLIDES.pdf) @@ -470,25 +470,25 @@ This chapter covers hacking constants as well as an intro to I2C as we work a 16 ## Week 8 ### Midterm Exam -### CTF-02 Instructions [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x0017a_ctf/CTF-02-I.md) +### CTF-02 Instructions [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK07/0x0017a_ctf/CTF-02-I.md) -### CTF-02 Rubric [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x0017a_ctf/CTF-02-R.md) +### CTF-02 Rubric [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK07/0x0017a_ctf/CTF-02-R.md) -### CTF-02 Solution [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x0017a_ctf/CTF-02-S.md) +### CTF-02 Solution [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK07/0x0017a_ctf/CTF-02-S.md) -### CTF-02 BIN [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x0017a_ctf/CTF-02.bin) +### CTF-02 BIN [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK07/0x0017a_ctf/CTF-02.bin) -### CTF-02 UF2 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x0017a_ctf/CTF-02.uf2) +### CTF-02 UF2 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK07/0x0017a_ctf/CTF-02.uf2) ## Week 9 Operators in Embedded Systems: Debugging and Hacking Operators w/ DHT11 Temperature & Humidity Sensor Single-Wire Protocol Basics -### Classified Brief 0x03 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x001aa_cb/CLASSIFIED-BRIEF-0x03.md) +### Classified Brief 0x03 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK09/0x001aa_cb/CLASSIFIED-BRIEF-0x03.md) -### Classified Brief 0x03 BIN [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x001aa_cb/0x001aa_cb.bin) +### Classified Brief 0x03 BIN [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK09/0x001aa_cb/0x001aa_cb.bin) -### Classified Brief 0x03 UF2 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x001aa_cb/0x001aa_cb.uf2) +### Classified Brief 0x03 UF2 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK09/0x001aa_cb/0x001aa_cb.uf2) ### Week 9 Slides [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK09/WEEK09-SLIDES.pdf) @@ -517,11 +517,11 @@ This chapter covers hacking operators as well as an intro to single-wire protoco Conditionals in Embedded Systems: Debugging and Hacking Static & Dynamic Conditionals w/ SG90 Servo Motor PWM Basics -### Classified Brief 0x04 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x001da_cb/CLASSIFIED-BRIEF-0x04.md) +### Classified Brief 0x04 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK10/0x001da_cb/CLASSIFIED-BRIEF-0x04.md) -### Classified Brief 0x04 BIN [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x001da_cb/0x001da_cb.bin) +### Classified Brief 0x04 BIN [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK10/0x001da_cb/0x001da_cb.bin) -### Classified Brief 0x04 UF2 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x001da_cb/0x001da_cb.uf2) +### Classified Brief 0x04 UF2 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK10/0x001da_cb/0x001da_cb.uf2) ## Week 10 Slides [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK10/WEEK10-SLIDES.pdf) @@ -565,11 +565,11 @@ This chapter covers hacking dynamic conditionals as well as additional PWM examp Structures and Functions in Embedded Systems: Debugging and Hacking w/ IR Remote Control and NEC Protocol Basics -### Classified Brief 0x05 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x0020a_cb/CLASSIFIED-BRIEF-0x05.md) +### Classified Brief 0x05 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK10/0x0020a_cb/CLASSIFIED-BRIEF-0x05.md) -### Classified Brief 0x05 BIN [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x0020a_cb/0x0020a_cb.bin) +### Classified Brief 0x05 BIN [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK10/0x0020a_cb/0x0020a_cb.bin) -### Classified Brief 0x05 UF2 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x0020a_cb/0x0020a_cb.uf2) +### Classified Brief 0x05 UF2 [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK10/0x0020a_cb/0x0020a_cb.uf2) ## Week 11 Slides [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK11/WEEK11-SLIDES.pdf) @@ -577,15 +577,15 @@ Structures and Functions in Embedded Systems: Debugging and Hacking w/ IR Remote ## Week 11a Secure Boot + Custom Bootloader Notebook [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK11/WEEK11a.md) -### 0x0026a Custom Secure Bootloader [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x0026a_custom-bootloader/README.md) +### 0x0026a Custom Secure Bootloader [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK11/0x0026a_custom-bootloader/README.md) -### 0x0026a Bootloader BIN [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x0026a_custom-bootloader/0x0026a_bootloader.bin) +### 0x0026a Bootloader BIN [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK11/0x0026a_custom-bootloader/0x0026a_bootloader.bin) -### 0x0026a Signed Application BIN [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x0026a_custom-bootloader/0x0026a_app.bin) +### 0x0026a Signed Application BIN [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK11/0x0026a_custom-bootloader/0x0026a_app.bin) -### 0x0026a Manifest BIN [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x0026a_custom-bootloader/manifest.bin) +### 0x0026a Manifest BIN [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK11/0x0026a_custom-bootloader/manifest.bin) -### 0x0026a Full Secure Boot UF2 (bootloader + manifest + app) [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/0x0026a_custom-bootloader/0x0026a_full.uf2) +### 0x0026a Full Secure Boot UF2 (bootloader + manifest + app) [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK11/0x0026a_custom-bootloader/0x0026a_full.uf2) ## Week 11-BN Notebook [HERE](https://github.com/mytechnotalent/Embedded-Hacking/blob/main/WEEK11/WEEK11-BN.md) diff --git a/flash.ps1 b/flash.ps1 index 74790de..428f6ca 100644 --- a/flash.ps1 +++ b/flash.ps1 @@ -37,7 +37,7 @@ lower it to 1000. .EXAMPLE - .\flash.ps1 -Bin 0x0005_intro-to-variables\build\0x0005_intro-to-variables.bin + .\flash.ps1 -Bin WEEK04\0x0005_intro-to-variables\build\0x0005_intro-to-variables.bin .EXAMPLE $env:ADAPTER_SPEED=1000; .\flash.ps1 -Bin build\hacked.bin diff --git a/flash.sh b/flash.sh index 97ee9c5..12a5d17 100755 --- a/flash.sh +++ b/flash.sh @@ -40,7 +40,7 @@ # lower it to 1000. # # Examples: -# ./flash.sh 0x0005_intro-to-variables/build/0x0005_intro-to-variables.bin +# ./flash.sh WEEK04/0x0005_intro-to-variables/build/0x0005_intro-to-variables.bin # ADAPTER_SPEED=1000 ./flash.sh build/hacked.bin # PICO_OPENOCD=/opt/homebrew/bin ./flash.sh build/hacked.bin #