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

This commit is contained in:
Kevin Thomas
2023-10-06 14:27:20 -04:00
commit 46e8b76762
1231 changed files with 110385 additions and 0 deletions
+308
View File
@@ -0,0 +1,308 @@
/**
* @file rp2350.h
* @brief RP2350 Device Peripheral Access Layer Header File.
* @author Kevin Thomas
* @date 2026
*
* Memory-mapped register structures and peripheral base addresses
* for the RP2350 microcontroller (Cortex-M33 dual-core). All
* register offsets verified against the RP2350 datasheet
* (RP-008373-DS-2).
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RP2350_H
#define __RP2350_H
#include <stdint.h>
#include <stdbool.h>
/*!< Defines 'read / write' permissions */
#define __IO volatile
/*!< Stack addresses */
#define STACK_TOP 0x20082000UL
#define STACK_LIMIT 0x2007A000UL
/*!< Memory map */
#define XIP_BASE 0x10000000UL
#define SRAM_BASE 0x20000000UL
#define SIO_BASE 0xD0000000UL
#define PPB_BASE 0xE0000000UL
/*!< APB peripherals */
#define PSM_BASE 0x40018000UL
#define CLOCKS_BASE 0x40010000UL
#define RESETS_BASE 0x40020000UL
#define IO_BANK0_BASE 0x40028000UL
#define PADS_BANK0_BASE 0x40038000UL
#define XOSC_BASE 0x40048000UL
#define UART0_BASE 0x40070000UL
#define WATCHDOG_BASE 0x400D8000UL
#define TICKS_BASE 0x40108000UL
/*!< Atomic register alias offsets */
#define ATOMIC_SET_OFFSET 0x2000UL
#define ATOMIC_CLR_OFFSET 0x3000UL
/**
* @brief XOSC (External Crystal Oscillator)
*/
typedef struct
{
__IO uint32_t CTRL; // Control register Address offset: 0x00
__IO uint32_t STATUS; // Status register Address offset: 0x04
__IO uint32_t DORMANT; // Dormant mode Address offset: 0x08
__IO uint32_t STARTUP; // Startup delay Address offset: 0x0C
__IO uint32_t COUNT; // Frequency count Address offset: 0x10
} XOSC_TypeDef;
/**
* @brief CLOCKS
*/
typedef struct
{
__IO uint32_t RESERVED0[12]; // GPOUT0..GPOUT3 registers Address offset: 0x00-0x2C
__IO uint32_t CLK_REF_CTRL; // Reference clock control Address offset: 0x30
__IO uint32_t RESERVED1[5]; // CLK_REF_DIV..CLK_SYS_SELECTED Address offset: 0x34-0x44
__IO uint32_t CLK_PERI_CTRL; // Peripheral clock control Address offset: 0x48
} CLOCKS_TypeDef;
/**
* @brief RESETS
*/
typedef struct
{
__IO uint32_t RESET; // Reset control Address offset: 0x00
__IO uint32_t WDSEL; // Watchdog select Address offset: 0x04
__IO uint32_t RESET_DONE; // Reset done status Address offset: 0x08
} RESETS_TypeDef;
/**
* @brief IO_BANK0 GPIO Control (one per GPIO)
*/
typedef struct
{
__IO uint32_t STATUS; // GPIO status Address offset: 0x00
__IO uint32_t CTRL; // GPIO control Address offset: 0x04
} IO_BANK0_GPIO_TypeDef;
/**
* @brief IO_BANK0
*/
typedef struct
{
IO_BANK0_GPIO_TypeDef GPIO[30]; // GPIO 0-29 status/ctrl pairs Address offset: 0x000-0x0E8
} IO_BANK0_TypeDef;
/**
* @brief PADS_BANK0
*/
typedef struct
{
__IO uint32_t VOLTAGE_SELECT; // Voltage select Address offset: 0x00
__IO uint32_t GPIO[30]; // GPIO 0-29 pad control Address offset: 0x04-0x78
} PADS_BANK0_TypeDef;
/**
* @brief PSM (Power-on State Machine)
*/
typedef struct
{
__IO uint32_t FRCE_ON; // Force block out of reset Address offset: 0x00
__IO uint32_t FRCE_OFF; // Force block into reset Address offset: 0x04
__IO uint32_t WDSEL; // Watchdog select Address offset: 0x08
__IO uint32_t DONE; // Subsystem ready status Address offset: 0x0C
} PSM_TypeDef;
/**
* @brief WATCHDOG
*/
typedef struct
{
__IO uint32_t CTRL; // Watchdog control Address offset: 0x00
__IO uint32_t LOAD; // Load the watchdog timer (bits 23:0) Address offset: 0x04
__IO uint32_t REASON; // Reason for last reset Address offset: 0x08
__IO uint32_t SCRATCH[8]; // Scratch registers 0-7 Address offset: 0x0C-0x28
} WATCHDOG_TypeDef;
/**
* @brief TICKS (Tick Generator entry, one per source)
*/
typedef struct
{
__IO uint32_t CTRL; // Enable tick generator (bit 0) Address offset: 0x00
__IO uint32_t CYCLES; // Number of CLK_REF cycles per tick (bits 8:0) Address offset: 0x04
__IO uint32_t COUNT; // Running counter of ticks (read-only) Address offset: 0x08
} TICKS_Entry_TypeDef;
/**
* @brief Peripheral Definitions
*/
#define PSM ((PSM_TypeDef *) PSM_BASE)
#define XOSC ((XOSC_TypeDef *) XOSC_BASE)
#define CLOCKS ((CLOCKS_TypeDef *) CLOCKS_BASE)
#define RESETS ((RESETS_TypeDef *) RESETS_BASE)
#define IO_BANK0 ((IO_BANK0_TypeDef *) IO_BANK0_BASE)
#define PADS_BANK0 ((PADS_BANK0_TypeDef *) PADS_BANK0_BASE)
#define SIO ((volatile uint32_t *) SIO_BASE)
#define CPACR ((volatile uint32_t *) (PPB_BASE + 0x0ED88UL))
#define WATCHDOG ((WATCHDOG_TypeDef *) WATCHDOG_BASE)
/**
* @brief TICKS entries (indexed from TICKS_BASE, 12-byte stride)
*/
#define TICKS_WATCHDOG ((TICKS_Entry_TypeDef *) (TICKS_BASE + 0x00UL))
/**
* @brief XOSC bit definitions
*/
#define XOSC_STATUS_STABLE_SHIFT 31U
/**
* @brief CPACR bit definitions
*/
#define CPACR_CP0_SHIFT 0U
#define CPACR_CP1_SHIFT 1U
/**
* @brief CLK_REF bit definitions
*/
#define CLK_REF_CTRL_SRC_XOSC 2U
/**
* @brief CLOCKS bit definitions
*/
#define CLK_PERI_CTRL_ENABLE_SHIFT 11U
#define CLK_PERI_CTRL_AUXSRC_SHIFT 5U
#define CLK_PERI_CTRL_AUXSRC_MASK (0x07U << CLK_PERI_CTRL_AUXSRC_SHIFT)
#define CLK_PERI_CTRL_AUXSRC_XOSC 4U
/**
* @brief RESETS bit definitions
*/
#define RESETS_RESET_IO_BANK0_SHIFT 6U
#define RESETS_RESET_PADS_BANK0_SHIFT 9U
#define RESETS_RESET_UART0_SHIFT 26U
/**
* @brief IO_BANK0 bit definitions
*/
#define IO_BANK0_CTRL_FUNCSEL_MASK 0x1FU
#define IO_BANK0_CTRL_FUNCSEL_UART 0x02U
#define IO_BANK0_CTRL_FUNCSEL_SIO 0x05U
#define IO_BANK0_CTRL_FUNCSEL_NULL 0x1FU
/**
* @brief PADS_BANK0 bit definitions
*/
#define PADS_BANK0_OD_SHIFT 7U
#define PADS_BANK0_IE_SHIFT 6U
#define PADS_BANK0_ISO_SHIFT 8U
#define PADS_BANK0_PUE_SHIFT 3U
#define PADS_BANK0_PDE_SHIFT 2U
/**
* @brief SIO GPIO register offsets (word indices from SIO_BASE)
*/
#define SIO_GPIO_OUT_SET_OFFSET (0x018U / 4U)
#define SIO_GPIO_OUT_CLR_OFFSET (0x020U / 4U)
#define SIO_GPIO_OE_SET_OFFSET (0x038U / 4U)
/**
* @brief UART register offsets (word indices from UART0_BASE)
*/
#define UART_DR_OFFSET (0x000U / 4U)
#define UART_FR_OFFSET (0x018U / 4U)
#define UART_IBRD_OFFSET (0x024U / 4U)
#define UART_FBRD_OFFSET (0x028U / 4U)
#define UART_LCR_H_OFFSET (0x02CU / 4U)
#define UART_CR_OFFSET (0x030U / 4U)
/**
* @brief UART flag register bit definitions
*/
#define UART_FR_TXFF_MASK 32U
#define UART_FR_RXFE_MASK 16U
/**
* @brief UART line control and enable values
*/
#define UART_LCR_H_8N1_FIFO 0x70U
#define UART_CR_ENABLE ((3U << 8) | 1U)
/**
* @brief PSM bit definitions
*/
#define PSM_WDSEL_ALL_MASK 0x01FFFFFFUL
#define PSM_WDSEL_ROSC_SHIFT 2U
#define PSM_WDSEL_XOSC_SHIFT 3U
/**
* @brief WATCHDOG CTRL bit definitions
*/
#define WATCHDOG_CTRL_TRIGGER_SHIFT 31U
#define WATCHDOG_CTRL_ENABLE_SHIFT 30U
#define WATCHDOG_CTRL_PAUSE_DBG1_SHIFT 26U
#define WATCHDOG_CTRL_PAUSE_DBG0_SHIFT 25U
#define WATCHDOG_CTRL_PAUSE_JTAG_SHIFT 24U
#define WATCHDOG_CTRL_TIME_MASK 0x00FFFFFFUL
/**
* @brief WATCHDOG LOAD bit definitions
*/
#define WATCHDOG_LOAD_MAX 0x00FFFFFFUL
/**
* @brief WATCHDOG REASON bit definitions
*/
#define WATCHDOG_REASON_FORCE_SHIFT 1U
#define WATCHDOG_REASON_TIMER_SHIFT 0U
/**
* @brief TICKS bit definitions
*/
#define TICKS_CTRL_ENABLE_SHIFT 0U
#define TICKS_CYCLES_12MHZ 12U
/*!< Bootrom function lookup */
#define BOOTROM_TABLE_LOOKUP_OFFSET 0x16U
#define RT_FLAG_FUNC_ARM_SEC 0x0004U
#define RT_FLAG_FUNC_ARM_NONSEC 0x0010U
/*!< ROM function codes */
#define ROM_FUNC_CONNECT_INTERNAL_FLASH (('I') | (('F') << 8))
#define ROM_FUNC_FLASH_EXIT_XIP (('E') | (('X') << 8))
#define ROM_FUNC_FLASH_RANGE_ERASE (('R') | (('E') << 8))
#define ROM_FUNC_FLASH_RANGE_PROGRAM (('R') | (('P') << 8))
#define ROM_FUNC_FLASH_FLUSH_CACHE (('F') | (('C') << 8))
#define ROM_FUNC_FLASH_ENTER_CMD_XIP (('C') | (('X') << 8))
/*!< Flash geometry */
#define FLASH_SIZE (4U * 1024U * 1024U)
#define FLASH_SECTOR_SIZE 4096U
#define FLASH_PAGE_SIZE 256U
#define FLASH_BLOCK_SIZE (1U << 16)
#define FLASH_BLOCK_ERASE_CMD 0xD8U
#endif /* __RP2350_H */
+69
View File
@@ -0,0 +1,69 @@
/**
* @file rp2350_flash.h
* @brief On-chip flash driver header for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Bare-metal flash erase, program, and read driver using ROM
* bootrom functions. Write operations run from RAM to avoid
* XIP conflicts.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RP2350_FLASH_H
#define __RP2350_FLASH_H
#include "rp2350.h"
/**
* @brief Erase the containing sector(s) and program data to flash.
*
* The data buffer must reside in RAM (not flash). Guards against
* NULL @p data and out-of-range @p offset, returning immediately
* if either is invalid. If @p len would exceed the flash boundary
* it is clamped to the remaining space. Interrupts are disabled
* for the erase/program cycle. The write length must be a multiple
* of FLASH_PAGE_SIZE (256 bytes); pad with 0xFF if necessary.
*
* @param offset byte offset from the start of flash (sector-aligned)
* @param data pointer to the source buffer in RAM (must not be NULL)
* @param len number of bytes to write
* @retval None
*/
void flash_write(uint32_t offset, const uint8_t *data, uint32_t len);
/**
* @brief Read bytes from on-chip flash via the XIP memory map.
*
* Guards against NULL @p out and out-of-range @p offset, returning
* immediately if either is invalid. If @p len would exceed the flash
* boundary it is clamped to the remaining space before the read.
*
* @param offset byte offset from the start of flash
* @param out pointer to the destination buffer (must not be NULL)
* @param len number of bytes to read
* @retval None
*/
void flash_read(uint32_t offset, uint8_t *out, uint32_t len);
#endif /* __RP2350_FLASH_H */
+42
View File
@@ -0,0 +1,42 @@
/**
* @file rp2350_reset.h
* @brief Reset controller driver header for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Provides subsystem reset release for IO_BANK0.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RP2350_RESET_H
#define __RP2350_RESET_H
#include "rp2350.h"
/**
* @brief Release IO_BANK0 from reset and wait until ready.
* @retval None
*/
void reset_init_subsystem(void);
#endif /* __RP2350_RESET_H */
@@ -0,0 +1,42 @@
/**
* @file rp2350_reset_handler.h
* @brief Reset handler header for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Entry point after reset. Performs stack initialization, XOSC
* setup, subsystem reset release, UART initialization,
* and branches to main().
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RP2350_RESET_HANDLER_H
#define __RP2350_RESET_HANDLER_H
/**
* @brief Reset handler entry point (naked, noreturn).
* @retval None
*/
void Reset_Handler(void) __attribute__((noreturn));
#endif /* __RP2350_RESET_HANDLER_H */
+43
View File
@@ -0,0 +1,43 @@
/**
* @file rp2350_stack.h
* @brief Stack pointer initialization header for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Sets MSP, PSP, MSPLIM, and PSPLIM from the STACK_TOP and
* STACK_LIMIT values defined in rp2350.h.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RP2350_STACK_H
#define __RP2350_STACK_H
#include "rp2350.h"
/**
* @brief Initialize MSP, PSP, MSPLIM, and PSPLIM stack pointers.
* @retval None
*/
void stack_init(void);
#endif /* __RP2350_STACK_H */
+82
View File
@@ -0,0 +1,82 @@
/**
* @file rp2350_uart.h
* @brief UART0 driver header for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Bare-metal UART0 driver supporting TX/RX on GPIO 0/1 at
* 115200 baud (12 MHz XOSC clock).
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RP2350_UART_H
#define __RP2350_UART_H
#include "rp2350.h"
/**
* @brief Release UART0 from reset and wait until ready.
* @retval None
*/
void uart_release_reset(void);
/**
* @brief Initialize UART0 pins, baud rate, line control, and enable.
* @retval None
*/
void uart_init(void);
/**
* @brief Check whether a received byte is waiting in the UART FIFO.
* @retval bool true if at least one byte is available
*/
bool uart_is_readable(void);
/**
* @brief Read one character from UART0 (blocking).
* @retval char the received character
*/
char uart_getchar(void);
/**
* @brief Transmit one character over UART0 (blocking).
* @param c character to transmit
* @retval None
*/
void uart_putchar(char c);
/**
* @brief Transmit a null-terminated string over UART0.
* @param str pointer to the string to send
* @retval None
*/
void uart_puts(const char *str);
/**
* @brief Convert a lowercase ASCII character to uppercase.
* @param c input character
* @retval char uppercase equivalent or original character
*/
char uart_to_upper(char c);
#endif /* __RP2350_UART_H */
+55
View File
@@ -0,0 +1,55 @@
/**
* @file rp2350_xosc.h
* @brief XOSC driver header for RP2350.
* @author Kevin Thomas
* @date 2026
*
* External crystal oscillator initialization and peripheral
* clock enable using the XOSC registers.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef __RP2350_XOSC_H
#define __RP2350_XOSC_H
#include "rp2350.h"
/**
* @brief Initialize the external crystal oscillator and wait until stable.
* @retval None
*/
void xosc_init(void);
/**
* @brief Enable the XOSC peripheral clock via CLK_PERI_CTRL.
* @retval None
*/
void xosc_enable_peri_clk(void);
/**
* @brief Switch CLK_REF source to XOSC for a stable 12 MHz clk_sys.
* @retval None
*/
void xosc_set_clk_ref(void);
#endif /* __RP2350_XOSC_H */
+84
View File
@@ -0,0 +1,84 @@
# ------------------------------------------------------------------------------
# @file Makefile
# @author Kevin Thomas
# @brief Build script for RP2350 bare-metal C flash driver.
#
# Compiles, links, and generates UF2 firmware for the RP2350.
# ------------------------------------------------------------------------------
# OS detection
ifeq ($(OS),Windows_NT)
MKDIR = if not exist $(subst /,\\,$(BUILD_DIR)) mkdir $(subst /,\\,$(BUILD_DIR))
RM = if exist $(subst /,\\,$(BUILD_DIR)) rmdir /s /q $(subst /,\\,$(BUILD_DIR))
else
MKDIR = mkdir -p $(BUILD_DIR)
RM = rm -rf $(BUILD_DIR)
endif
# Toolchain
CC = arm-none-eabi-gcc
OBJCOPY = arm-none-eabi-objcopy
SIZE = arm-none-eabi-size
# Target
TARGET = flash
# Directories
SRC_DIR = Src
INC_DIR = Inc
BUILD_DIR = build
# CPU flags
CPU_FLAGS = -mcpu=cortex-m33 -mthumb
# Compiler flags
CFLAGS = $(CPU_FLAGS) -Og -g3 -Wall -Wextra \
-ffunction-sections -fdata-sections \
-I$(INC_DIR)
# Linker flags
LDFLAGS = $(CPU_FLAGS) -T linker.ld -nostdlib -Wl,--gc-sections
# Source files
SRCS = $(SRC_DIR)/vector_table.c \
$(SRC_DIR)/rp2350_reset_handler.c \
$(SRC_DIR)/rp2350_stack.c \
$(SRC_DIR)/rp2350_xosc.c \
$(SRC_DIR)/rp2350_reset.c \
$(SRC_DIR)/rp2350_uart.c \
$(SRC_DIR)/rp2350_flash.c \
$(SRC_DIR)/main.c \
$(SRC_DIR)/image_def.c
# Object files
OBJS = $(patsubst $(SRC_DIR)/%.c,$(BUILD_DIR)/%.o,$(SRCS))
# Rules
.PHONY: all clean flash
all: $(BUILD_DIR)/$(TARGET).bin
@echo "==================================="
@echo "SUCCESS! Created $(TARGET).elf and $(TARGET).bin"
@echo "==================================="
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c | $(BUILD_DIR)
$(CC) $(CFLAGS) -c $< -o $@
$(BUILD_DIR)/$(TARGET).elf: $(OBJS)
$(CC) $(LDFLAGS) $(OBJS) -o $@
$(SIZE) $@
$(BUILD_DIR)/$(TARGET).bin: $(BUILD_DIR)/$(TARGET).elf
$(OBJCOPY) -O binary $< $@
$(BUILD_DIR):
$(MKDIR)
clean:
$(RM)
flash: $(BUILD_DIR)/$(TARGET).elf
openocd -f interface/cmsis-dap.cfg -f target/rp2350.cfg \
-c "adapter speed 5000" \
-c "program $< verify reset exit"
+41
View File
@@ -0,0 +1,41 @@
/**
* @file image_def.c
* @brief RP2350 IMAGE_DEF block for boot ROM image recognition.
* @author Kevin Thomas
* @date 2026
*
* Must appear within the first 4 KB of flash for the boot ROM
* to accept the image.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <stdint.h>
__attribute__((section(".embedded_block"), used))
const uint8_t picobin_block[] = {
0xD3, 0xDE, 0xFF, 0xFF,
0x42, 0x01, 0x21, 0x10,
0xFF, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x79, 0x35, 0x12, 0xAB
};
+84
View File
@@ -0,0 +1,84 @@
/**
* @file main.c
* @brief On-chip flash write / read demonstration.
* @author Kevin Thomas
* @date 2026
*
* Writes "Embedded Hacking flash driver demo" to the last
* sector of flash, reads it back via XIP, and prints the
* result over UART.
*
* Wiring:
* GPIO0 -> UART TX (USB-to-UART adapter RX)
* GPIO1 -> UART RX (USB-to-UART adapter TX)
* No external components required
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "rp2350_flash.h"
#include "rp2350_uart.h"
/**
* @brief Target offset: last sector of the 4 MB flash chip.
*/
/** @brief Flash offset for the target storage sector */
#define FLASH_TARGET_OFFSET (FLASH_SIZE - FLASH_SECTOR_SIZE)
/**
* @brief Fill a page buffer with 0xFF and copy the demo string.
* @param buf destination buffer (FLASH_PAGE_SIZE bytes in RAM)
* @retval None
*/
static void prepare_write_buf(uint8_t *buf)
{
uint32_t i;
const char *msg = "Embedded Hacking flash driver demo";
for (i = 0; i < FLASH_PAGE_SIZE; i++)
buf[i] = 0xFFU;
for (i = 0; msg[i] != '\0'; i++)
buf[i] = (uint8_t)msg[i];
buf[i] = 0x00U;
}
/**
* @brief Write the demo string to flash and print the read-back.
* @retval None
*/
static void write_and_verify(void)
{
uint8_t write_buf[FLASH_PAGE_SIZE];
uint8_t read_buf[FLASH_PAGE_SIZE];
prepare_write_buf(write_buf);
flash_write(FLASH_TARGET_OFFSET, write_buf, FLASH_PAGE_SIZE);
flash_read(FLASH_TARGET_OFFSET, read_buf, FLASH_PAGE_SIZE);
uart_puts("Flash readback: ");
uart_puts((const char *)read_buf);
uart_puts("\r\n");
}
int main(void)
{
write_and_verify();
while (1)
__asm volatile ("wfi");
}
+148
View File
@@ -0,0 +1,148 @@
/**
* @file rp2350_flash.c
* @brief On-chip flash driver implementation for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Erases and programs flash sectors using ROM bootrom
* functions. The erase/program trampoline executes from RAM
* (placed in .ram_func) because XIP is disabled while the
* flash chip is being modified.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "rp2350_flash.h"
/**
* @brief ROM table lookup function pointer type (RP2350 ARM).
*/
typedef void *(*rom_table_lookup_fn)(uint32_t code, uint32_t mask);
/**
* @brief ROM void function pointer (no parameters, no return).
*/
typedef void (*rom_void_fn)(void);
/**
* @brief ROM flash range erase function pointer.
*/
typedef void (*rom_flash_erase_fn)(uint32_t addr, uint32_t count,
uint32_t block_size, uint8_t block_cmd);
/**
* @brief ROM flash range program function pointer.
*/
typedef void (*rom_flash_program_fn)(uint32_t addr, const uint8_t *data,
uint32_t count);
/**
* @brief Collection of ROM flash function pointers.
*/
typedef struct
{
rom_void_fn connect; /**< @brief Connect to internal flash */
rom_void_fn exit_xip; /**< @brief Exit XIP mode */
rom_flash_erase_fn erase; /**< @brief Erase flash range */
rom_flash_program_fn program; /**< @brief Program flash range */
rom_void_fn flush_cache; /**< @brief Flush XIP cache */
rom_void_fn enter_xip; /**< @brief Re-enter XIP mode */
} FlashRomFns;
/**
* @brief Look up a ROM function by its two-character code.
* @param code ROM_FUNC_* code from rp2350.h
* @retval void* pointer to the ROM function
*/
static void *rom_func_lookup(uint32_t code)
{
rom_table_lookup_fn fn =
(rom_table_lookup_fn)(uintptr_t)(*(uint16_t *)BOOTROM_TABLE_LOOKUP_OFFSET);
return fn(code, RT_FLAG_FUNC_ARM_SEC);
}
/**
* @brief Populate all ROM flash function pointers.
* @param fns pointer to the struct to fill
* @retval None
*/
static void lookup_rom_fns(FlashRomFns *fns)
{
fns->connect = (rom_void_fn)rom_func_lookup(ROM_FUNC_CONNECT_INTERNAL_FLASH);
fns->exit_xip = (rom_void_fn)rom_func_lookup(ROM_FUNC_FLASH_EXIT_XIP);
fns->erase = (rom_flash_erase_fn)rom_func_lookup(ROM_FUNC_FLASH_RANGE_ERASE);
fns->program = (rom_flash_program_fn)rom_func_lookup(ROM_FUNC_FLASH_RANGE_PROGRAM);
fns->flush_cache = (rom_void_fn)rom_func_lookup(ROM_FUNC_FLASH_FLUSH_CACHE);
fns->enter_xip = (rom_void_fn)rom_func_lookup(ROM_FUNC_FLASH_ENTER_CMD_XIP);
}
/**
* @brief RAM-resident trampoline that erases and programs flash.
*
* Must not call any function residing in flash. All ROM
* function pointers are passed via the fns struct.
*
* @param fns pointer to ROM function pointers (in RAM/stack)
* @param offset byte offset from start of flash
* @param data pointer to source buffer (must be in RAM)
* @param len number of bytes to program
* @retval None
*/
__attribute__((section(".ram_func"), noinline))
static void flash_erase_program_ram(const FlashRomFns *fns, uint32_t offset,
const uint8_t *data, uint32_t len)
{
fns->connect();
fns->exit_xip();
uint32_t erase_addr = offset & ~(FLASH_SECTOR_SIZE - 1U);
uint32_t erase_end = (offset + len + FLASH_SECTOR_SIZE - 1U) & ~(FLASH_SECTOR_SIZE - 1U);
fns->erase(erase_addr, erase_end - erase_addr, FLASH_BLOCK_SIZE, FLASH_BLOCK_ERASE_CMD);
fns->program(offset, data, len);
fns->flush_cache();
fns->enter_xip();
}
void flash_write(uint32_t offset, const uint8_t *data, uint32_t len)
{
if (data == NULL || offset >= FLASH_SIZE)
return;
if (len > FLASH_SIZE - offset)
len = FLASH_SIZE - offset;
FlashRomFns fns;
lookup_rom_fns(&fns);
uint32_t primask;
__asm volatile ("mrs %0, primask" : "=r" (primask));
__asm volatile ("cpsid i");
flash_erase_program_ram(&fns, offset, data, len);
__asm volatile ("msr primask, %0" :: "r" (primask));
}
void flash_read(uint32_t offset, uint8_t *out, uint32_t len)
{
if (out == NULL || offset >= FLASH_SIZE)
return;
if (len > FLASH_SIZE - offset)
len = FLASH_SIZE - offset;
const uint8_t *src = (const uint8_t *)(XIP_BASE + offset);
for (uint32_t i = 0; i < len; i++)
out[i] = src[i];
}
+41
View File
@@ -0,0 +1,41 @@
/**
* @file rp2350_reset.c
* @brief Reset controller driver implementation for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Releases IO_BANK0 from reset and waits until the subsystem
* is ready.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "rp2350_reset.h"
void reset_init_subsystem(void)
{
uint32_t value;
value = RESETS->RESET;
value &= ~(1U << RESETS_RESET_IO_BANK0_SHIFT);
RESETS->RESET = value;
while ((RESETS->RESET_DONE & (1U << RESETS_RESET_IO_BANK0_SHIFT)) == 0) {}
}
@@ -0,0 +1,80 @@
/**
* @file rp2350_reset_handler.c
* @brief Reset handler implementation for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Entry point after power-on or system reset. Copies the
* .data section from flash to RAM, initializes the stack,
* XOSC, subsystem resets, UART, then branches to main().
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "rp2350_reset_handler.h"
#include "rp2350_stack.h"
#include "rp2350_xosc.h"
#include "rp2350_reset.h"
#include "rp2350_uart.h"
extern int main(void);
extern uint32_t __data_lma;
extern uint32_t __data_start;
extern uint32_t __data_end;
extern uint32_t __bss_start;
extern uint32_t __bss_end;
static void _data_copy_init(void)
{
uint32_t *src = &__data_lma;
uint32_t *dst = &__data_start;
while (dst < &__data_end)
*dst++ = *src++;
}
static void _bss_zero_init(void)
{
uint32_t *dst = &__bss_start;
while (dst < &__bss_end)
*dst++ = 0U;
}
void _ram_init(void)
{
stack_init();
_data_copy_init();
_bss_zero_init();
}
void __attribute__((naked, noreturn)) Reset_Handler(void)
{
__asm__ volatile (
"bl _ram_init\n\t"
"bl xosc_init\n\t"
"bl xosc_enable_peri_clk\n\t"
"bl reset_init_subsystem\n\t"
"bl uart_release_reset\n\t"
"bl uart_init\n\t"
"b main\n\t"
);
}
+47
View File
@@ -0,0 +1,47 @@
/**
* @file rp2350_stack.c
* @brief Stack pointer initialization for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Sets MSP, PSP, MSPLIM, and PSPLIM using inline assembly.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "rp2350_stack.h"
void stack_init(void)
{
__asm__ volatile (
"ldr r0, =%0\n\t"
"msr PSP, r0\n\t"
"ldr r0, =%1\n\t"
"msr MSPLIM, r0\n\t"
"msr PSPLIM, r0\n\t"
"ldr r0, =%0\n\t"
"msr MSP, r0\n\t"
:
: "i" (STACK_TOP), "i" (STACK_LIMIT)
: "r0"
);
}
+134
View File
@@ -0,0 +1,134 @@
/**
* @file rp2350_uart.c
* @brief UART0 driver implementation for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Configures UART0 on GPIO 0 (TX) and GPIO 1 (RX) at 115200
* baud using the 12 MHz XOSC clock.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "rp2350_uart.h"
/** @brief Base address pointer for UART0 peripheral registers */
#define UART_BASE ((volatile uint32_t *) UART0_BASE)
/**
* @brief Clear the UART0 reset bit in the reset controller.
* @retval None
*/
static void uart_clear_reset_bit(void)
{
uint32_t value;
value = RESETS->RESET;
value &= ~(1U << RESETS_RESET_UART0_SHIFT);
RESETS->RESET = value;
}
/**
* @brief Wait until the UART0 block is out of reset.
* @retval None
*/
static void uart_wait_reset_done(void)
{
while ((RESETS->RESET_DONE & (1U << RESETS_RESET_UART0_SHIFT)) == 0) {}
}
/**
* @brief Configure GPIO pins 0 (TX) and 1 (RX) for UART function.
* @retval None
*/
static void uart_configure_pins(void)
{
IO_BANK0->GPIO[0].CTRL = IO_BANK0_CTRL_FUNCSEL_UART;
IO_BANK0->GPIO[1].CTRL = IO_BANK0_CTRL_FUNCSEL_UART;
PADS_BANK0->GPIO[0] = 0x04;
PADS_BANK0->GPIO[1] = 0x40;
}
/**
* @brief Set UART0 baud rate divisors for 115200 at 12 MHz.
* @retval None
*/
static void uart_set_baud(void)
{
UART_BASE[UART_CR_OFFSET] = 0;
UART_BASE[UART_IBRD_OFFSET] = 6;
UART_BASE[UART_FBRD_OFFSET] = 33;
}
/**
* @brief Configure line control and enable UART0.
* @retval None
*/
static void uart_enable(void)
{
UART_BASE[UART_LCR_H_OFFSET] = UART_LCR_H_8N1_FIFO;
UART_BASE[UART_CR_OFFSET] = UART_CR_ENABLE;
}
void uart_release_reset(void)
{
uart_clear_reset_bit();
uart_wait_reset_done();
}
void uart_init(void)
{
uart_configure_pins();
uart_set_baud();
uart_enable();
}
bool uart_is_readable(void)
{
return (UART_BASE[UART_FR_OFFSET] & UART_FR_RXFE_MASK) == 0;
}
char uart_getchar(void)
{
while (UART_BASE[UART_FR_OFFSET] & UART_FR_RXFE_MASK) {}
return (char)(UART_BASE[UART_DR_OFFSET] & 0xFF);
}
void uart_putchar(char c)
{
while (UART_BASE[UART_FR_OFFSET] & UART_FR_TXFF_MASK) {}
UART_BASE[UART_DR_OFFSET] = (uint32_t)c;
}
void uart_puts(const char *str)
{
while (*str)
{
uart_putchar(*str++);
}
}
char uart_to_upper(char c)
{
if (c >= 'a' && c <= 'z')
return (char)(c - 32);
return c;
}
+54
View File
@@ -0,0 +1,54 @@
/**
* @file rp2350_xosc.c
* @brief XOSC driver implementation for RP2350.
* @author Kevin Thomas
* @date 2026
*
* Configures the external crystal oscillator and enables the
* peripheral clock sourced from XOSC.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "rp2350_xosc.h"
void xosc_init(void)
{
XOSC->STARTUP = 0x00C4U;
XOSC->CTRL = 0x00FABAA0U;
while ((XOSC->STATUS & (1U << XOSC_STATUS_STABLE_SHIFT)) == 0) {}
}
void xosc_enable_peri_clk(void)
{
uint32_t value;
value = CLOCKS->CLK_PERI_CTRL;
value &= ~CLK_PERI_CTRL_AUXSRC_MASK;
value |= (1U << CLK_PERI_CTRL_ENABLE_SHIFT);
value |= (CLK_PERI_CTRL_AUXSRC_XOSC << CLK_PERI_CTRL_AUXSRC_SHIFT);
CLOCKS->CLK_PERI_CTRL = value;
}
void xosc_set_clk_ref(void)
{
CLOCKS->CLK_REF_CTRL = CLK_REF_CTRL_SRC_XOSC;
}
+44
View File
@@ -0,0 +1,44 @@
/**
* @file vector_table.c
* @brief Vector table with initial stack pointer and reset handler.
* @author Kevin Thomas
* @date 2026
*
* Placed in the .vectors section at the start of flash.
* The Thumb bit (bit 0 = 1) is automatically set by the
* linker for function pointers in Thumb mode.
*
* MIT License
*
* Copyright (c) 2026 Kevin Thomas
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <stdint.h>
extern uint32_t _stack_top;
extern void Reset_Handler(void);
typedef void (*vector_func_t)(void);
__attribute__((section(".vectors"), used))
const void *_vectors[2] = {
&_stack_top,
Reset_Handler
};
Binary file not shown.
+144
View File
@@ -0,0 +1,144 @@
/**
******************************************************************************
* @file linker.ld
* @author Kevin Thomas
* @brief Minimal linker script for bare-metal RP2350 development.
*
* Defines FLASH (XIP 32 MB) and RAM (520 kB SRAM) regions.
* The vector table is placed at the start of flash (0x10000000).
*
******************************************************************************
* @attention
*
* Copyright (c) 2026 Kevin Thomas.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/**
* Entry point.
*/
ENTRY(Reset_Handler)
/**
* Define memory regions.
*/
__XIP_BASE = 0x10000000;
__XIP_SIZE = 32M;
__SRAM_BASE = 0x20000000;
__SRAM_SIZE = 520K;
__STACK_SIZE = 32K;
/**
* Memory layout.
*/
MEMORY
{
RAM (rwx) : ORIGIN = __SRAM_BASE, LENGTH = __SRAM_SIZE
FLASH (rx) : ORIGIN = __XIP_BASE, LENGTH = __XIP_SIZE
}
/**
* Program headers.
*/
PHDRS
{
text PT_LOAD FLAGS(5);
data PT_LOAD FLAGS(6);
}
/**
* Section placement.
*/
SECTIONS
{
. = ORIGIN(FLASH);
/**
* Vector table MUST be first at 0x10000000.
*/
.vectors :
{
KEEP(*(.vectors))
} > FLASH :text
/**
* Verify vector table placement.
*/
ASSERT((ADDR(.vectors) == ORIGIN(FLASH)),
"Vector table must be at start of flash (0x10000000)")
/**
* Text and read-only data.
*/
.text :
{
. = ALIGN(4);
*(.text*)
*(.rodata*)
KEEP(*(.init))
KEEP(*(.fini))
KEEP(*(.ARM.attributes))
} > FLASH :text
/**
* IMAGE_DEF block at end of code.
*/
.embedded_block :
{
KEEP(*(.embedded_block))
} > FLASH :text
/**
* Initialized data and RAM-resident code (LMA in flash, VMA in RAM).
* Startup copies from __data_lma to __data_start..__data_end.
*/
.data :
{
. = ALIGN(4);
__data_start = .;
*(.ram_func*)
*(.data*)
. = ALIGN(4);
__data_end = .;
} > RAM AT> FLASH :data
__data_lma = LOADADDR(.data);
/**
* Uninitialized data (BSS) in RAM.
*/
.bss (NOLOAD) :
{
. = ALIGN(4);
__bss_start = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end = .;
} > RAM
/**
* Non-secure stack symbols.
*/
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - __STACK_SIZE;
__stack = __StackTop;
_stack_top = __StackTop;
/**
* Stack section (no load).
*/
.stack (NOLOAD) : { . = ALIGN(8); } > RAM
/**
* Provide vector table symbol to startup code.
*/
PROVIDE(__Vectors = ADDR(.vectors));
}