Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
695a062
Build and compile inside build/ directory
webhdx May 4, 2025
e3d2947
Add family ID argument to process_ipl.py script
webhdx May 4, 2025
be9e488
Update .gitignore
webhdx May 4, 2025
4e81660
Add main build script
webhdx May 4, 2025
2715f09
Update build workflow
webhdx May 4, 2025
f57ab4a
Add GPIO status LED driver
webhdx May 7, 2025
b5eaaba
Add CYW43 status LED driver
webhdx May 7, 2025
330c575
Abstract Status LED from hardware platform
webhdx May 7, 2025
08d59ff
Detect HW at runtime
webhdx May 7, 2025
50d948e
Move version injection code to separate cmake file
webhdx May 7, 2025
3a034ea
Support rp2350-arm-s family ID in uf2 payload file
webhdx May 7, 2025
8958978
Adjust main program file to recent changes
webhdx May 7, 2025
ce4aab8
Update year in file headers
webhdx May 7, 2025
0fd35e2
Fix build script with platform workarounds
webhdx May 7, 2025
8315da0
Update release workflow for new dist structure
webhdx May 7, 2025
43c7469
Remove redundant tagging
webhdx May 7, 2025
b4c5717
Trigger build workflow after devcontainer
webhdx May 7, 2025
bd7164e
Update workflow names
webhdx May 7, 2025
e4b8bac
Revert "Trigger build workflow after devcontainer"
webhdx May 7, 2025
3926530
Never push devcontainer image in build workflow
webhdx May 7, 2025
5dc3c5a
Fix build workflow name
webhdx May 8, 2025
23fa012
Fetch full history before build
webhdx May 8, 2025
447e51b
Update build summary
webhdx May 8, 2025
4d8d611
Automatically generate release notes
webhdx May 8, 2025
5db9b61
Add changelog to release
webhdx May 8, 2025
e5d1c12
Fix changelog in releases
webhdx May 8, 2025
6f6673b
Use default commit template in release notes
webhdx May 8, 2025
f7f7cfb
Update changelog template
webhdx May 8, 2025
2da2def
Fix author and commit link in changelogs
webhdx May 8, 2025
e986208
Use payload.dol for making builds
webhdx May 8, 2025
1e3e962
Add script for aligning RP2040 binaries
webhdx May 8, 2025
76282d1
Move python scripts to tools/
webhdx May 8, 2025
a68b234
Fix process_ipl.py path
webhdx May 8, 2025
e62f947
Remove delay when waiting for USB
webhdx May 8, 2025
305ff14
Update .gitignore
webhdx May 8, 2025
1d6876f
Remove debugging info
webhdx May 8, 2025
b70b6dd
Revert "Remove debugging info"
webhdx May 8, 2025
4b74623
[Workaround] Delay LED initialization
webhdx May 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/build_summary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
### Files included in the build artifact

Most users should use one of the **`picoboot_full_*.uf2`** files (full package). Other files are intended for advanced users to update only specific parts of the firmware or payload.

| File Name | Platform | Description |
| ------------------------- | ------------------------------------ | --------------------------------- |
| `picoboot_full_pico.uf2` | Pico<br>Pico W | firmware + payload (full package) |
| `picoboot_full_pico2.uf2` | Pico 2<br>Pico 2 W | firmware + payload (full package) |
| `picoboot_pico.uf2` | Pico<br>Pico W | firmware only |
| `picoboot_pico2.uf2` | Pico 2<br>Pico 2 W | firmware only |
| `payload_pico.uf2` | Pico<br>Pico W | payload |
| `payload_pico2.uf2` | Pico 2<br>Pico 2 W | payload |
| `payload_universal.uf2` | Pico<br>Pico W<br>Pico 2<br>Pico 2 W | payload |
14 changes: 14 additions & 0 deletions .github/release_description.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@DESCRIPTION@

## Changes in this release

@CHANGELOG@

## Useful Links

✨ [Software features](https://github.com/redolution/gekkoboot/) | 🚀 [Installation Guide](https://support.webhdx.dev/gc/picoboot/installation-guide) | ⬆️ [Update Guide](https://support.webhdx.dev/gc/picoboot/update-picoboot) | 🛠️ [Troubleshooting](https://support.webhdx.dev/gc/picoboot/troubleshooting)

## Available files

* `picoboot_full_pico.uf2`: Compatible with Raspberry Pi Pico and Raspberry Pi Pico W.
* `picoboot_full_pico2.uf2`: Compatible with Raspberry Pi Pico 2 and Raspberry Pi Pico 2 W.
28 changes: 14 additions & 14 deletions .github/workflows/10-build.yml → .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build
name: Build PicoBoot
on:
push:
branches:
Expand Down Expand Up @@ -32,6 +32,8 @@ jobs:

- name: Checkout PicoBoot code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set outputs
id: vars
Expand All @@ -40,21 +42,19 @@ jobs:
- uses: robinraju/release-downloader@v1
id: gekkoboot-download
with:
repository: 'webhdx/iplboot'
repository: 'webhdx/gekkoboot'
latest: true
fileName: '*.zip'
out-file-path: gekkoboot
extract: true

- name: Copy gekkoboot uf2 payload
- name: Copy gekkoboot.dol
run: |
cd gekkoboot
if [ -f "gekkoboot_pico.uf2" ]; then
cp gekkoboot_pico.uf2 ${{ github.workspace }}/payload.uf2
elif [ -f "iplboot_pico.uf2" ]; then
cp iplboot_pico.uf2 ${{ github.workspace }}/payload.uf2
if [ -f "gekkoboot.dol" ]; then
cp gekkoboot.dol ${{ github.workspace }}/payload.dol
else
echo "Neither gekkoboot_pico.uf2 nor iplboot_pico.uf2 found."
echo "gekkoboot.dol not found"
exit 1
fi

Expand All @@ -63,15 +63,15 @@ jobs:
with:
imageName: ghcr.io/webhdx/picoboot
cacheFrom: ghcr.io/webhdx/picoboot
push: never
runCmd: |
cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE .
make
tools/build.sh

- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: picoboot-${{ steps.vars.outputs.sha_short }}
path: |
picoboot_full.uf2
picoboot.uf2
payload.uf2
path: dist/

- name: Add build summary
run: echo "$(cat .github/build_summary.md)" >> $GITHUB_STEP_SUMMARY
59 changes: 36 additions & 23 deletions .github/workflows/00-release.yml → .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
version:
description: 'Version to tag'
required: true
default: 'v0.4'
default: 'v0.5.0'
type: string
is_draft:
description: 'Is draft release?'
Expand Down Expand Up @@ -47,7 +47,7 @@ jobs:

build:
needs: tag
uses: ./.github/workflows/10-build.yml
uses: ./.github/workflows/build.yml

release:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -78,17 +78,40 @@ jobs:
with:
name: picoboot-${{ steps.vars.outputs.sha_short }}
path: dist/

- name: Build Changelog
id: build_changelog
uses: mikepenz/release-changelog-builder-action@v5
with:
mode: "COMMIT"
toTag: ${{ github.event.inputs.version }}
configurationJson: |
{
"template": "#{{UNCATEGORIZED}}",
"commit_template": "* #{{TITLE}} by @#{{AUTHOR}} (#{{MERGE_SHA}})",
"empty_template": "_No notable changes in this version._",
"categories": []
}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Prepare release description
run: |
touch release-description.md
echo "${{ github.event.inputs.release_description }}" >> release-description.md
- name: Prepare release description
env:
DESCRIPTION: ${{ github.event.inputs.release_description }}
RELEASE_NAME: ${{ steps.determine_name.outputs.name }}
CHANGELOG: ${{ steps.build_changelog.outputs.changelog }}
run: |
content=$(cat .github/release_description.md)
content=${content//@DESCRIPTION@/$DESCRIPTION}
content=${content//@CHANGELOG@/$CHANGELOG}
echo "$content" > release-description.md

- name: Calculate artifact checksum
run: |
echo '```' >> release-description.md
cd dist/
sha256sum picoboot_full.uf2 >> ../release-description.md
sha256sum picoboot_full_pico.uf2 >> ../release-description.md
sha256sum picoboot_full_pico2.uf2 >> ../release-description.md
cd ../
echo '```' >> release-description.md

Expand All @@ -98,23 +121,13 @@ jobs:
git config --global user.email "actions@github.com"

- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: softprops/action-gh-release@v2
with:
name: ${{ steps.determine_name.outputs.name }}
tag_name: ${{ github.event.inputs.version }}
release_name: ${{ steps.determine_name.outputs.name }}
body_path: ${{ github.workspace }}/release-description.md
draft: ${{ github.event.inputs.is_draft }}
prerelease: ${{ github.event.inputs.is_prerelease }}

- name: Upload Release Asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ${{ github.workspace }}/dist/picoboot_full.uf2
asset_name: picoboot_full.uf2
asset_content_type: application/octet-stream
body_path: ${{ github.workspace }}/release-description.md
files: |
dist/picoboot_full_pico.uf2
dist/picoboot_full_pico2.uf2
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ _deps

# Build environment
build/
dist/
CMakeFiles/
elf2uf2/
generated/
Expand All @@ -20,3 +21,6 @@ picoboot.elf.map
picoboot.hex
*.uf2
picoboot.pio.h
gekkoboot.dol
payload.dol
src/version.h
44 changes: 16 additions & 28 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,25 @@ cmake_minimum_required(VERSION 3.13)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

find_package(Git)
execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --always --dirty
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE GIT_REPO_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REGEX REPLACE "v([0-9]+\\.[0-9]+).*" "\\1" CMAKE_GIT_REPO_VERSION ${GIT_REPO_VERSION})
string(REGEX REPLACE "^(.......-.*)|(.......)$" "0.0.0" CMAKE_GIT_REPO_VERSION ${CMAKE_GIT_REPO_VERSION})
configure_file("src/version.h.in" "src/version.h")
message("GIT_REPO_VERSION is ${GIT_REPO_VERSION}")
message("CMAKE_GIT_REPO_VERSION is ${CMAKE_GIT_REPO_VERSION}")
include(cmake/extract_version.cmake)

# Pull in Raspberry Pi Pico SDK (must be before project)
include(pico_sdk_import.cmake)

project(picoboot LANGUAGES C CXX ASM VERSION ${CMAKE_GIT_REPO_VERSION})
project(picoboot LANGUAGES C CXX ASM VERSION ${PROJECT_VERSION_STRING})

# Initialise the Raspberry Pi Pico SDK
pico_sdk_init()

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/dist)

add_executable(picoboot
src/picoboot.c
src/hw.c
src/pio.c
src/status_led.c
src/status_led/gpio.c
src/status_led/cyw43.c
)

pico_generate_pio_header(picoboot
Expand All @@ -33,31 +30,22 @@ pico_generate_pio_header(picoboot

pico_set_program_name(picoboot "PicoBoot")
pico_set_program_description(picoboot "RP2040 based modchip for Nintendo GameCube")
pico_set_program_version(picoboot ${GIT_REPO_VERSION})
pico_set_program_version(picoboot ${FW_VER_STRING})
pico_set_program_url(picoboot "https://github.com/webhdx/PicoBoot")

pico_set_binary_type(picoboot copy_to_ram)
target_link_options(pico_standard_link INTERFACE "LINKER:--script=${CMAKE_CURRENT_LIST_DIR}/memmap_picoboot.ld")

pico_enable_stdio_uart(picoboot 0)
pico_enable_stdio_usb(picoboot 1)

target_include_directories(picoboot PRIVATE src)

target_link_libraries(picoboot PRIVATE pico_stdlib hardware_pio hardware_dma)
target_link_libraries(picoboot PRIVATE
hardware_adc
hardware_dma
hardware_pio
pico_cyw43_arch_none
pico_stdlib
)

pico_add_extra_outputs(picoboot)

function(merge_uf2 NAME BASE_TARGET INPUTS)
get_target_property(BASE_TARGET_NAME ${BASE_TARGET} OUTPUT_NAME)
if(BASE_TARGET_NAME STREQUAL "BASE_TARGET_NAME-NOTFOUND")
get_target_property(BASE_TARGET_NAME ${BASE_TARGET} NAME)
endif()

add_custom_target(${NAME} ALL
COMMAND ${CMAKE_CURRENT_LIST_DIR}/merge_uf2.py ${NAME}.uf2 ${BASE_TARGET_NAME}.uf2 ${INPUTS}
DEPENDS ${BASE_TARGET} ${INPUTS}
COMMAND_EXPAND_LISTS)
endfunction()

merge_uf2(picoboot_full picoboot "${CMAKE_CURRENT_LIST_DIR}/payload.uf2")
42 changes: 42 additions & 0 deletions cmake/extract_version.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# CMake script to extract version information from Git and configure version.h

find_package(Git REQUIRED)

execute_process(
COMMAND ${GIT_EXECUTABLE} describe --tags --always --dirty
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_DESCRIBE_OUTPUT
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE GIT_DESCRIBE_RESULT
)

set(FW_VER_STRING "0.0.0-unknown")
set(FW_VER_MAJOR 0)
set(FW_VER_MINOR 0)
set(FW_VER_PATCH 0)

if(GIT_DESCRIBE_RESULT EQUAL 0 AND GIT_DESCRIBE_OUTPUT)
set(FW_VER_STRING ${GIT_DESCRIBE_OUTPUT})
if(FW_VER_STRING MATCHES "^v([0-9]+)\.([0-9]+)\.([0-9]+)")
set(FW_VER_MAJOR ${CMAKE_MATCH_1})
set(FW_VER_MINOR ${CMAKE_MATCH_2})
set(FW_VER_PATCH ${CMAKE_MATCH_3})
else()
message(STATUS "Git version string '${FW_VER_STRING}' does not match vX.Y.Z format for MAJOR/MINOR/PATCH. Using 0.0.0 for these.")
endif()
else()
message(WARNING "git describe failed or returned empty. Using default version: ${FW_VER_STRING}, MAJOR: ${FW_VER_MAJOR}, MINOR: ${FW_VER_MINOR}, PATCH: ${FW_VER_PATCH}")
endif()

set(PROJECT_VERSION_STRING "${FW_VER_MAJOR}.${FW_VER_MINOR}.${FW_VER_PATCH}")

configure_file(
"${CMAKE_SOURCE_DIR}/src/version.h.in"
"${CMAKE_SOURCE_DIR}/src/version.h"
)

message(STATUS "FW_VER_STRING: ${FW_VER_STRING}")
message(STATUS "FW_VER_MAJOR: ${FW_VER_MAJOR}")
message(STATUS "FW_VER_MINOR: ${FW_VER_MINOR}")
message(STATUS "FW_VER_PATCH: ${FW_VER_PATCH}")
message(STATUS "PROJECT_VERSION_STRING: ${PROJECT_VERSION_STRING}")
56 changes: 56 additions & 0 deletions src/hw.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* Copyright (c) 2025 Maciej Kobus
*
* SPDX-License-Identifier: GPL-2.0-only
*/

#include "hardware/adc.h"
#include "pico/stdlib.h"
#include "pico/platform.h"

#include "hw.h"

#define ADC_PIN_VSYS 29
#define ADC_INPUT_VSYS 3

// Threshold for differentiating Pico from Pico W based on raw ADC reading.
// Pico W typically has a much lower reading on VSYS ADC (e.g., ~0x01c).
// Pico typically has a higher reading (e.g., ~0x2cd).
// A value around 0x100 should be a safe threshold.
#define PICO_W_ADC_THRESHOLD 0x100

hw_board_type_t hw_detect_board_type(void) {
adc_gpio_init(ADC_PIN_VSYS);
adc_select_input(ADC_INPUT_VSYS);

uint16_t adc_result = adc_read();

if (adc_result < PICO_W_ADC_THRESHOLD) {
#if defined(PICO_RP2350)
return HW_BOARD_TYPE_PICO_2_W;
#else
return HW_BOARD_TYPE_PICO_W;
#endif
} else {
#if defined(PICO_RP2350)
return HW_BOARD_TYPE_PICO_2;
#else
return HW_BOARD_TYPE_PICO;
#endif
}
}

const char* hw_board_type_to_string(hw_board_type_t board_type) {
switch (board_type) {
case HW_BOARD_TYPE_PICO:
return "Raspberry Pi Pico";
case HW_BOARD_TYPE_PICO_W:
return "Raspberry Pi Pico W";
case HW_BOARD_TYPE_PICO_2:
return "Raspberry Pi Pico 2";
case HW_BOARD_TYPE_PICO_2_W:
return "Raspberry Pi Pico 2 W";
default:
return "Unknown";
}
}
Loading