Last active
August 9, 2024 20:59
-
-
Save Ferdi265/2b6a3ffb808d5b1a3d2465342259cb6c to your computer and use it in GitHub Desktop.
CMake that generates the Picotool flash unique ID access payload
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cmake_minimum_required(VERSION 3.20) | |
# default build type | |
set(CMAKE_BUILD_TYPE "MinSizeRel" CACHE STRING "build type") | |
include(pico_sdk_import.cmake) | |
project(flash_id C CXX ASM) | |
pico_sdk_init() | |
add_executable(flash_id flash_id.c) | |
target_link_libraries(flash_id PRIVATE | |
hardware_regs hardware_structs hardware_flash_headers | |
) | |
target_link_options(flash_id PRIVATE -nostartfiles -nodefaultlibs -Ttext=0) | |
pico_add_bin_output(flash_id) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "hardware/regs/io_qspi.h" | |
#include "hardware/structs/ioqspi.h" | |
#include "hardware/structs/ssi.h" | |
#include "hardware/flash.h" | |
asm( | |
".macro static_assert value, msg\n" | |
".if !(\\value)\n" | |
".err \\msg\n" | |
".endif\n" | |
".endm\n" | |
".set FLASH_RUID_CMD, 0x4b\n" | |
".set FLASH_RUID_DUMMY_BYTES, 4\n" | |
".set FLASH_RUID_DATA_BYTES, 8\n" | |
".set FLASH_RUID_TOTAL_BYTES, (1 + FLASH_RUID_DUMMY_BYTES + FLASH_RUID_DATA_BYTES)\n" | |
); | |
void flash_do_cmd(const uint8_t * txbuf, uint8_t *rxbuf, size_t count); | |
void __attribute__((naked)) flash_get_unique_id_raw(void) { | |
asm( | |
".Lflash_get_unique_id_raw:\n" | |
"adr r0, .Ltxbuf\n" | |
"adr r1, .Lrxbuf\n" | |
"ldr r2, .Lbuflen\n" | |
"b flash_do_cmd\n" | |
".Lbuflen:\n" | |
".word FLASH_RUID_TOTAL_BYTES\n" | |
".Ltxbuf:\n" | |
".byte FLASH_RUID_CMD\n" | |
".zero (FLASH_RUID_TOTAL_BYTES - 1)\n" | |
".zero (16 - FLASH_RUID_TOTAL_BYTES)\n" | |
".Lrxbuf:\n" | |
".zero FLASH_RUID_TOTAL_BYTES\n" | |
".zero (16 - FLASH_RUID_TOTAL_BYTES)\n" | |
"static_assert ((.Lrxbuf - flash_get_unique_id_raw) == 28), \"rxbuf offset incorrect\"\n" | |
); | |
} | |
static inline void __attribute__((always_inline)) flash_cs_force(_Bool high) { | |
uint32_t field_val = high ? | |
IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_VALUE_HIGH : | |
IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_VALUE_LOW; | |
hw_write_masked(&ioqspi_hw->io[1].ctrl, | |
field_val << IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_LSB, | |
IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_BITS | |
); | |
} | |
void flash_do_cmd(const uint8_t * txbuf, uint8_t *rxbuf, size_t count) { | |
flash_cs_force(0); | |
size_t tx_remaining = count; | |
size_t rx_remaining = count; | |
// We may be interrupted -- don't want FIFO to overflow if we're distracted. | |
const size_t max_in_flight = 16 - 2; | |
while (tx_remaining || rx_remaining) { | |
uint32_t flags = ssi_hw->sr; | |
bool can_put = !!(flags & SSI_SR_TFNF_BITS); | |
bool can_get = !!(flags & SSI_SR_RFNE_BITS); | |
if (can_put && tx_remaining && rx_remaining - tx_remaining < max_in_flight) { | |
ssi_hw->dr0 = *txbuf++; | |
--tx_remaining; | |
} | |
if (can_get && rx_remaining) { | |
*rxbuf++ = (uint8_t)ssi_hw->dr0; | |
--rx_remaining; | |
} | |
} | |
flash_cs_force(1); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This is a copy of <PICO_SDK_PATH>/external/pico_sdk_import.cmake | |
# This can be dropped into an external project to help locate this SDK | |
# It should be include()ed prior to project() | |
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 () | |
# GIT_SUBMODULES_RECURSE was added in 3.17 | |
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") | |
FetchContent_Declare( | |
pico_sdk | |
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk | |
GIT_TAG ${PICO_SDK_FETCH_FROM_GIT_TAG} | |
GIT_SUBMODULES_RECURSE FALSE | |
) | |
else () | |
FetchContent_Declare( | |
pico_sdk | |
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk | |
GIT_TAG ${PICO_SDK_FETCH_FROM_GIT_TAG} | |
) | |
endif () | |
if (NOT pico_sdk) | |
message("Downloading Raspberry Pi Pico SDK") | |
FetchContent_Populate(pico_sdk) | |
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}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment