mirror of
https://github.com/mytechnotalent/Embedded-Hacking.git
synced 2026-06-08 07:13:56 +02:00
refactor: convert 0x01_uart_cbm and 0x02_blink_cbm to bare-metal Inc/Src structure
- Restructure flat files into Inc/ (headers) and Src/ (sources) - Replace constants.h with rp2350.h register layer (datasheet-verified) - Add full Doxygen docstrings on all files, functions, and structs - Replace build.bat/clean.bat with cross-platform Makefile - Fix GPIO_IN offset (0x004), XOSC COUNT offset (0x10), SRAM size (520K) - Rename blink_* API to led_* (name after peripheral, not feature) - Build outputs to build/ directory - Cross-platform .vscode configs (Windows/macOS/Linux)
This commit is contained in:
@@ -1,11 +0,0 @@
|
|||||||
# C files
|
|
||||||
*.c linguist-language=C
|
|
||||||
|
|
||||||
# Exclude from language statistics
|
|
||||||
*.ld linguist-vendored
|
|
||||||
*.bat linguist-vendored
|
|
||||||
*.py linguist-vendored
|
|
||||||
linker.ld linguist-vendored
|
|
||||||
build.bat linguist-vendored
|
|
||||||
clean.bat linguist-vendored
|
|
||||||
uf2conv.py linguist-vendored
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
# Build artifacts
|
|
||||||
*.o
|
|
||||||
*.elf
|
|
||||||
*.bin
|
|
||||||
*.uf2
|
|
||||||
compile_commands.json
|
|
||||||
|
|
||||||
# OS files
|
|
||||||
.DS_Store
|
|
||||||
Thumbs.db
|
|
||||||
+21
-1
@@ -3,7 +3,27 @@
|
|||||||
{
|
{
|
||||||
"name": "ARM GCC",
|
"name": "ARM GCC",
|
||||||
"includePath": [
|
"includePath": [
|
||||||
"${workspaceFolder}/**"
|
"${workspaceFolder}/Inc/**"
|
||||||
|
],
|
||||||
|
"defines": [
|
||||||
|
"__GNUC__",
|
||||||
|
"__ARM_ARCH_8M_MAIN__",
|
||||||
|
"__ARMCC_VERSION"
|
||||||
|
],
|
||||||
|
"compilerPath": "${userHome}/.pico-sdk/toolchain/14_2_Rel1/bin/arm-none-eabi-gcc",
|
||||||
|
"compileCommands": "${workspaceFolder}/compile_commands.json",
|
||||||
|
"cStandard": "c11",
|
||||||
|
"cppStandard": "c++17",
|
||||||
|
"intelliSenseMode": "gcc-arm",
|
||||||
|
"compilerArgs": [
|
||||||
|
"-mcpu=cortex-m33",
|
||||||
|
"-mthumb"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ARM GCC (Windows)",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/Inc/**"
|
||||||
],
|
],
|
||||||
"defines": [
|
"defines": [
|
||||||
"__GNUC__",
|
"__GNUC__",
|
||||||
|
|||||||
+16
-6
@@ -4,19 +4,21 @@
|
|||||||
{
|
{
|
||||||
"name": "Debug RP2350 (OpenOCD)",
|
"name": "Debug RP2350 (OpenOCD)",
|
||||||
"cwd": "${workspaceFolder}",
|
"cwd": "${workspaceFolder}",
|
||||||
"executable": "${workspaceFolder}/uart.elf",
|
"executable": "${workspaceFolder}/build/uart.elf",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"type": "cortex-debug",
|
"type": "cortex-debug",
|
||||||
"servertype": "openocd",
|
"servertype": "openocd",
|
||||||
"serverpath": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
|
"serverpath": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd",
|
||||||
"searchDir": ["${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/scripts"],
|
"searchDir": [
|
||||||
"gdbPath": "${env:USERPROFILE}/.pico-sdk/toolchain/14_2_Rel1/bin/arm-none-eabi-gdb.exe",
|
"${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts"
|
||||||
|
],
|
||||||
|
"gdbPath": "${userHome}/.pico-sdk/toolchain/14_2_Rel1/bin/arm-none-eabi-gdb",
|
||||||
"device": "RP2350",
|
"device": "RP2350",
|
||||||
"configFiles": [
|
"configFiles": [
|
||||||
"interface/cmsis-dap.cfg",
|
"interface/cmsis-dap.cfg",
|
||||||
"target/rp2350.cfg"
|
"target/rp2350.cfg"
|
||||||
],
|
],
|
||||||
"svdFile": "${env:USERPROFILE}/.pico-sdk/sdk/2.2.0/src/rp2350/hardware_regs/RP2350.svd",
|
"svdFile": "${userHome}/.pico-sdk/sdk/2.2.0/src/rp2350/hardware_regs/RP2350.svd",
|
||||||
"overrideLaunchCommands": [
|
"overrideLaunchCommands": [
|
||||||
"set arch armv8-m.main",
|
"set arch armv8-m.main",
|
||||||
"set output-radix 16",
|
"set output-radix 16",
|
||||||
@@ -31,7 +33,15 @@
|
|||||||
"adapter speed 5000"
|
"adapter speed 5000"
|
||||||
],
|
],
|
||||||
"preLaunchTask": "Compile Project",
|
"preLaunchTask": "Compile Project",
|
||||||
"showDevDebugOutput": "raw"
|
"showDevDebugOutput": "raw",
|
||||||
|
"windows": {
|
||||||
|
"serverpath": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
|
||||||
|
"searchDir": [
|
||||||
|
"${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/scripts"
|
||||||
|
],
|
||||||
|
"gdbPath": "${env:USERPROFILE}/.pico-sdk/toolchain/14_2_Rel1/bin/arm-none-eabi-gdb.exe",
|
||||||
|
"svdFile": "${env:USERPROFILE}/.pico-sdk/sdk/2.2.0/src/rp2350/hardware_regs/RP2350.svd"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
+34
-13
@@ -4,7 +4,7 @@
|
|||||||
{
|
{
|
||||||
"label": "Compile Project",
|
"label": "Compile Project",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": ".\\build.bat",
|
"command": "make",
|
||||||
"group": {
|
"group": {
|
||||||
"kind": "build",
|
"kind": "build",
|
||||||
"isDefault": true
|
"isDefault": true
|
||||||
@@ -13,26 +13,32 @@
|
|||||||
"reveal": "always",
|
"reveal": "always",
|
||||||
"panel": "dedicated"
|
"panel": "dedicated"
|
||||||
},
|
},
|
||||||
"problemMatcher": "$gcc"
|
"problemMatcher": "$gcc",
|
||||||
|
"windows": {
|
||||||
|
"command": ".\\build.bat"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Clean Project",
|
"label": "Clean Project",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": ".\\clean.bat",
|
"command": "make clean",
|
||||||
"group": "build",
|
"group": "build",
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"reveal": "always",
|
"reveal": "always",
|
||||||
"panel": "dedicated"
|
"panel": "dedicated"
|
||||||
},
|
},
|
||||||
"problemMatcher": []
|
"problemMatcher": [],
|
||||||
|
"windows": {
|
||||||
|
"command": ".\\clean.bat"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Run Project",
|
"label": "Run Project",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "${env:USERPROFILE}/.pico-sdk/picotool/2.2.0-a4/picotool/picotool.exe",
|
"command": "${userHome}/.pico-sdk/picotool/2.2.0-a4/picotool/picotool",
|
||||||
"args": [
|
"args": [
|
||||||
"load",
|
"load",
|
||||||
"uart.uf2",
|
"build/uart.uf2",
|
||||||
"-fx"
|
"-fx"
|
||||||
],
|
],
|
||||||
"presentation": {
|
"presentation": {
|
||||||
@@ -40,29 +46,39 @@
|
|||||||
"panel": "dedicated"
|
"panel": "dedicated"
|
||||||
},
|
},
|
||||||
"problemMatcher": [],
|
"problemMatcher": [],
|
||||||
"dependsOn": ["Compile Project"]
|
"dependsOn": [
|
||||||
|
"Compile Project"
|
||||||
|
],
|
||||||
|
"windows": {
|
||||||
|
"command": "${env:USERPROFILE}/.pico-sdk/picotool/2.2.0-a4/picotool/picotool.exe"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Flash",
|
"label": "Flash",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
|
"command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd",
|
||||||
"args": [
|
"args": [
|
||||||
"-s",
|
"-s",
|
||||||
"${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/scripts",
|
"${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts",
|
||||||
"-f",
|
"-f",
|
||||||
"interface/cmsis-dap.cfg",
|
"interface/cmsis-dap.cfg",
|
||||||
"-f",
|
"-f",
|
||||||
"target/rp2350.cfg",
|
"target/rp2350.cfg",
|
||||||
"-c",
|
"-c",
|
||||||
"adapter speed 5000; program uart.elf verify reset exit"
|
"adapter speed 5000; program build/uart.elf verify reset exit"
|
||||||
],
|
],
|
||||||
"problemMatcher": [],
|
"problemMatcher": [],
|
||||||
"dependsOn": ["Compile Project"]
|
"dependsOn": [
|
||||||
|
"Compile Project"
|
||||||
|
],
|
||||||
|
"windows": {
|
||||||
|
"command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Rescue Reset",
|
"label": "Rescue Reset",
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
|
"command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd",
|
||||||
"args": [
|
"args": [
|
||||||
"-s",
|
"-s",
|
||||||
"${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts",
|
"${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts",
|
||||||
@@ -81,7 +97,7 @@
|
|||||||
{
|
{
|
||||||
"label": "RISC-V Reset (RP2350)",
|
"label": "RISC-V Reset (RP2350)",
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
|
"command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd",
|
||||||
"args": [
|
"args": [
|
||||||
"-s",
|
"-s",
|
||||||
"${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts",
|
"${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts",
|
||||||
@@ -105,3 +121,8 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"problemMatcher": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,194 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350.h
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief RP2350 Device Peripheral Access Layer Header File.
|
||||||
|
*
|
||||||
|
* 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).
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RP2350_H
|
||||||
|
#define __RP2350_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/*!< Defines 'read / write' permissions */
|
||||||
|
#define __IO volatile
|
||||||
|
|
||||||
|
/*!< Stack addresses */
|
||||||
|
#define STACK_TOP 0x20082000UL
|
||||||
|
#define STACK_LIMIT 0x2007A000UL
|
||||||
|
|
||||||
|
/*!< Memory map */
|
||||||
|
#define XIP_BASE 0x10000000UL
|
||||||
|
#define SRAM_BASE 0x20000000UL
|
||||||
|
#define SIO_BASE 0xD0000000UL
|
||||||
|
#define PPB_BASE 0xE0000000UL
|
||||||
|
|
||||||
|
/*!< APB peripherals */
|
||||||
|
#define CLOCKS_BASE 0x40010000UL
|
||||||
|
#define RESETS_BASE 0x40020000UL
|
||||||
|
#define IO_BANK0_BASE 0x40028000UL
|
||||||
|
#define PADS_BANK0_BASE 0x40038000UL
|
||||||
|
#define XOSC_BASE 0x40048000UL
|
||||||
|
#define UART0_BASE 0x40070000UL
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XOSC (External Crystal Oscillator)
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IO uint32_t CTRL; // Control register Address offset: 0x00
|
||||||
|
__IO uint32_t STATUS; // Status register Address offset: 0x04
|
||||||
|
__IO uint32_t DORMANT; // Dormant mode Address offset: 0x08
|
||||||
|
__IO uint32_t STARTUP; // Startup delay Address offset: 0x0C
|
||||||
|
__IO uint32_t COUNT; // Frequency count Address offset: 0x10
|
||||||
|
} XOSC_TypeDef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CLOCKS
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IO uint32_t RESERVED0[18]; // Other clock registers Address offset: 0x00-0x44
|
||||||
|
__IO uint32_t CLK_PERI_CTRL; // Peripheral clock control Address offset: 0x48
|
||||||
|
} CLOCKS_TypeDef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief RESETS
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IO uint32_t RESET; // Reset control Address offset: 0x00
|
||||||
|
__IO uint32_t WDSEL; // Watchdog select Address offset: 0x04
|
||||||
|
__IO uint32_t RESET_DONE; // Reset done status Address offset: 0x08
|
||||||
|
} RESETS_TypeDef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief IO_BANK0 GPIO Control (one per GPIO)
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IO uint32_t STATUS; // GPIO status Address offset: 0x00
|
||||||
|
__IO uint32_t CTRL; // GPIO control Address offset: 0x04
|
||||||
|
} IO_BANK0_GPIO_TypeDef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief IO_BANK0
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
IO_BANK0_GPIO_TypeDef GPIO[30]; // GPIO 0-29 status/ctrl pairs Address offset: 0x000-0x0E8
|
||||||
|
} IO_BANK0_TypeDef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PADS_BANK0
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IO uint32_t VOLTAGE_SELECT; // Voltage select Address offset: 0x00
|
||||||
|
__IO uint32_t GPIO[30]; // GPIO 0-29 pad control Address offset: 0x04-0x78
|
||||||
|
} PADS_BANK0_TypeDef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Peripheral Definitions
|
||||||
|
*/
|
||||||
|
#define XOSC ((XOSC_TypeDef *) XOSC_BASE)
|
||||||
|
#define CLOCKS ((CLOCKS_TypeDef *) CLOCKS_BASE)
|
||||||
|
#define RESETS ((RESETS_TypeDef *) RESETS_BASE)
|
||||||
|
#define IO_BANK0 ((IO_BANK0_TypeDef *) IO_BANK0_BASE)
|
||||||
|
#define PADS_BANK0 ((PADS_BANK0_TypeDef *) PADS_BANK0_BASE)
|
||||||
|
#define SIO ((volatile uint32_t *) SIO_BASE)
|
||||||
|
#define CPACR ((volatile uint32_t *) (PPB_BASE + 0x0ED88UL))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XOSC bit definitions
|
||||||
|
*/
|
||||||
|
#define XOSC_STATUS_STABLE_SHIFT 31U
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CPACR bit definitions
|
||||||
|
*/
|
||||||
|
#define CPACR_CP0_SHIFT 0U
|
||||||
|
#define CPACR_CP1_SHIFT 1U
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CLOCKS bit definitions
|
||||||
|
*/
|
||||||
|
#define CLK_PERI_CTRL_ENABLE_SHIFT 11U
|
||||||
|
#define CLK_PERI_CTRL_AUXSRC_SHIFT 5U
|
||||||
|
#define CLK_PERI_CTRL_AUXSRC_XOSC 4U
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief RESETS bit definitions
|
||||||
|
*/
|
||||||
|
#define RESETS_RESET_IO_BANK0_SHIFT 6U
|
||||||
|
#define RESETS_RESET_UART0_SHIFT 26U
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief IO_BANK0 bit definitions
|
||||||
|
*/
|
||||||
|
#define IO_BANK0_CTRL_FUNCSEL_MASK 0x1FU
|
||||||
|
#define IO_BANK0_CTRL_FUNCSEL_UART 0x02U
|
||||||
|
#define IO_BANK0_CTRL_FUNCSEL_SIO 0x05U
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PADS_BANK0 bit definitions
|
||||||
|
*/
|
||||||
|
#define PADS_BANK0_OD_SHIFT 7U
|
||||||
|
#define PADS_BANK0_IE_SHIFT 6U
|
||||||
|
#define PADS_BANK0_ISO_SHIFT 8U
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief UART register offsets (word indices from UART0_BASE)
|
||||||
|
*/
|
||||||
|
#define UART_DR_OFFSET (0x000U / 4U)
|
||||||
|
#define UART_FR_OFFSET (0x018U / 4U)
|
||||||
|
#define UART_IBRD_OFFSET (0x024U / 4U)
|
||||||
|
#define UART_FBRD_OFFSET (0x028U / 4U)
|
||||||
|
#define UART_LCR_H_OFFSET (0x02CU / 4U)
|
||||||
|
#define UART_CR_OFFSET (0x030U / 4U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief UART flag register bit definitions
|
||||||
|
*/
|
||||||
|
#define UART_FR_TXFF_MASK 32U
|
||||||
|
#define UART_FR_RXFE_MASK 16U
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief UART line control and enable values
|
||||||
|
*/
|
||||||
|
#define UART_LCR_H_8N1_FIFO 0x70U
|
||||||
|
#define UART_CR_ENABLE ((3U << 8) | 1U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GPIO pin definitions
|
||||||
|
*/
|
||||||
|
#define LED_PIN 25U
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SIO GPIO register offsets (word indices from SIO_BASE)
|
||||||
|
*/
|
||||||
|
#define SIO_GPIO_IN_OFFSET (0x004U / 4U)
|
||||||
|
#define SIO_GPIO_OUT_SET_OFFSET (0x018U / 4U)
|
||||||
|
#define SIO_GPIO_OUT_CLR_OFFSET (0x020U / 4U)
|
||||||
|
#define SIO_GPIO_OUT_XOR_OFFSET (0x028U / 4U)
|
||||||
|
#define SIO_GPIO_OE_SET_OFFSET (0x038U / 4U)
|
||||||
|
|
||||||
|
#endif /* __RP2350_H */
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_coprocessor.h
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief Coprocessor access control driver header for RP2350.
|
||||||
|
*
|
||||||
|
* Enables coprocessor access via the CPACR register.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RP2350_COPROCESSOR_H
|
||||||
|
#define __RP2350_COPROCESSOR_H
|
||||||
|
|
||||||
|
#include "rp2350.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable coprocessor access via CPACR with DSB/ISB barriers.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void coprocessor_enable(void);
|
||||||
|
|
||||||
|
#endif /* __RP2350_COPROCESSOR_H */
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_reset.h
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief Reset controller driver header for RP2350.
|
||||||
|
*
|
||||||
|
* Provides subsystem reset release for IO_BANK0.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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,33 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_reset_handler.h
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief Reset handler header for RP2350.
|
||||||
|
*
|
||||||
|
* Entry point after reset. Performs stack initialization, XOSC
|
||||||
|
* setup, subsystem reset release, UART initialization,
|
||||||
|
* coprocessor enable, and branches to main().
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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 */
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_stack.h
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief Stack pointer initialization header for RP2350.
|
||||||
|
*
|
||||||
|
* Sets MSP, PSP, MSPLIM, and PSPLIM from the STACK_TOP and
|
||||||
|
* STACK_LIMIT values defined in rp2350.h.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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 */
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_uart.h
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief UART0 driver header for RP2350.
|
||||||
|
*
|
||||||
|
* Bare-metal UART0 driver supporting TX/RX on GPIO 0/1 at
|
||||||
|
* 115200 baud (14.5 MHz XOSC clock).
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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 */
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_xosc.h
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief XOSC driver header for RP2350.
|
||||||
|
*
|
||||||
|
* External crystal oscillator initialization and peripheral
|
||||||
|
* clock enable using the XOSC registers.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RP2350_XOSC_H
|
||||||
|
#define __RP2350_XOSC_H
|
||||||
|
|
||||||
|
#include "rp2350.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the external crystal oscillator and wait until stable.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void xosc_init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the XOSC peripheral clock via CLK_PERI_CTRL.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void xosc_enable_peri_clk(void);
|
||||||
|
|
||||||
|
#endif /* __RP2350_XOSC_H */
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# @file Makefile
|
||||||
|
# @author Kevin Thomas
|
||||||
|
# @brief Build script for RP2350 bare-metal C UART driver.
|
||||||
|
#
|
||||||
|
# Compiles, links, and generates UF2 firmware for the RP2350.
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Toolchain
|
||||||
|
CC = arm-none-eabi-gcc
|
||||||
|
OBJCOPY = arm-none-eabi-objcopy
|
||||||
|
SIZE = arm-none-eabi-size
|
||||||
|
|
||||||
|
# Target
|
||||||
|
TARGET = uart
|
||||||
|
|
||||||
|
# Directories
|
||||||
|
SRC_DIR = Src
|
||||||
|
INC_DIR = Inc
|
||||||
|
BUILD_DIR = build
|
||||||
|
|
||||||
|
# CPU flags
|
||||||
|
CPU_FLAGS = -mcpu=cortex-m33 -mthumb
|
||||||
|
|
||||||
|
# Compiler flags
|
||||||
|
CFLAGS = $(CPU_FLAGS) -Og -g3 -Wall -Wextra \
|
||||||
|
-ffunction-sections -fdata-sections \
|
||||||
|
-I$(INC_DIR)
|
||||||
|
|
||||||
|
# Linker flags
|
||||||
|
LDFLAGS = $(CPU_FLAGS) -T linker.ld -nostdlib -Wl,--gc-sections
|
||||||
|
|
||||||
|
# Source files
|
||||||
|
SRCS = $(SRC_DIR)/vector_table.c \
|
||||||
|
$(SRC_DIR)/rp2350_reset_handler.c \
|
||||||
|
$(SRC_DIR)/rp2350_stack.c \
|
||||||
|
$(SRC_DIR)/rp2350_xosc.c \
|
||||||
|
$(SRC_DIR)/rp2350_reset.c \
|
||||||
|
$(SRC_DIR)/rp2350_coprocessor.c \
|
||||||
|
$(SRC_DIR)/rp2350_uart.c \
|
||||||
|
$(SRC_DIR)/main.c \
|
||||||
|
$(SRC_DIR)/image_def.c
|
||||||
|
|
||||||
|
# Object files
|
||||||
|
OBJS = $(patsubst $(SRC_DIR)/%.c,$(BUILD_DIR)/%.o,$(SRCS))
|
||||||
|
|
||||||
|
# Rules
|
||||||
|
.PHONY: all clean flash
|
||||||
|
|
||||||
|
all: $(BUILD_DIR)/$(TARGET).uf2
|
||||||
|
@echo "==================================="
|
||||||
|
@echo "SUCCESS! Created $(TARGET).bin and $(TARGET).uf2"
|
||||||
|
@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)/$(TARGET).uf2: $(BUILD_DIR)/$(TARGET).bin
|
||||||
|
python3 uf2conv.py -b 0x10000000 -f 0xe48bff59 -o $@ $<
|
||||||
|
|
||||||
|
$(BUILD_DIR):
|
||||||
|
mkdir -p $(BUILD_DIR)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(BUILD_DIR)
|
||||||
|
|
||||||
|
flash: $(BUILD_DIR)/$(TARGET).elf
|
||||||
|
openocd -f interface/cmsis-dap.cfg -f target/rp2350.cfg \
|
||||||
|
-c "adapter speed 5000" \
|
||||||
|
-c "program $< verify reset exit"
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file image_def.c
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief RP2350 IMAGE_DEF block for boot ROM image recognition.
|
||||||
|
*
|
||||||
|
* Must appear within the first 4 KB of flash for the boot ROM
|
||||||
|
* to accept the image.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief IMAGE_DEF block structure placed in flash
|
||||||
|
*/
|
||||||
|
__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
|
||||||
|
};
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file main.c
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief UART demonstration: echo received characters in uppercase.
|
||||||
|
*
|
||||||
|
* Demonstrates hardware UART0 using the bare-metal UART driver.
|
||||||
|
* Characters typed into a terminal via a USB-to-UART adapter
|
||||||
|
* are echoed back in uppercase.
|
||||||
|
*
|
||||||
|
* Wiring:
|
||||||
|
* GPIO0 (TX) -> USB-to-UART adapter RX
|
||||||
|
* GPIO1 (RX) -> USB-to-UART adapter TX
|
||||||
|
* GND -> USB-to-UART adapter GND
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rp2350_uart.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Application entry point for the UART uppercase echo demo.
|
||||||
|
* @retval int does not return
|
||||||
|
*/
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
uart_puts("UART driver ready (115200 8N1)\r\n");
|
||||||
|
uart_puts("Type characters to echo them back in UPPERCASE:\r\n");
|
||||||
|
while (1) {
|
||||||
|
if (uart_is_readable()) {
|
||||||
|
char c = uart_getchar();
|
||||||
|
char upper = uart_to_upper(c);
|
||||||
|
uart_putchar(upper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_coprocessor.c
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief Coprocessor access control driver implementation for RP2350.
|
||||||
|
*
|
||||||
|
* Grants access to coprocessors 0 and 1 by setting the
|
||||||
|
* corresponding bits in CPACR with DSB/ISB barriers.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rp2350_coprocessor.h"
|
||||||
|
|
||||||
|
void coprocessor_enable(void)
|
||||||
|
{
|
||||||
|
uint32_t value;
|
||||||
|
value = *CPACR;
|
||||||
|
value |= (1U << CPACR_CP1_SHIFT);
|
||||||
|
value |= (1U << CPACR_CP0_SHIFT);
|
||||||
|
*CPACR = value;
|
||||||
|
__asm__ volatile ("dsb");
|
||||||
|
__asm__ volatile ("isb");
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_reset.c
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief Reset controller driver implementation for RP2350.
|
||||||
|
*
|
||||||
|
* Releases IO_BANK0 from reset and waits until the subsystem
|
||||||
|
* is ready.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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,45 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_reset_handler.c
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief Reset handler implementation for RP2350.
|
||||||
|
*
|
||||||
|
* Entry point after power-on or system reset. Initializes the
|
||||||
|
* stack, XOSC, subsystem resets, UART, and coprocessor, then
|
||||||
|
* branches to main().
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rp2350_reset_handler.h"
|
||||||
|
#include "rp2350_stack.h"
|
||||||
|
#include "rp2350_xosc.h"
|
||||||
|
#include "rp2350_reset.h"
|
||||||
|
#include "rp2350_uart.h"
|
||||||
|
#include "rp2350_coprocessor.h"
|
||||||
|
|
||||||
|
extern int main(void);
|
||||||
|
|
||||||
|
void __attribute__((naked, noreturn)) Reset_Handler(void)
|
||||||
|
{
|
||||||
|
__asm__ volatile (
|
||||||
|
"bl stack_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"
|
||||||
|
"bl coprocessor_enable\n\t"
|
||||||
|
"b main\n\t"
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_stack.c
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief Stack pointer initialization for RP2350.
|
||||||
|
*
|
||||||
|
* Sets MSP, PSP, MSPLIM, and PSPLIM using inline assembly.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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"
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_uart.c
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief UART0 driver implementation for RP2350.
|
||||||
|
*
|
||||||
|
* Configures UART0 on GPIO 0 (TX) and GPIO 1 (RX) at 115200
|
||||||
|
* baud using the 14.5 MHz XOSC clock.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rp2350_uart.h"
|
||||||
|
|
||||||
|
#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 14.5 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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_xosc.c
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief XOSC driver implementation for RP2350.
|
||||||
|
*
|
||||||
|
* Configures the external crystal oscillator and enables the
|
||||||
|
* peripheral clock sourced from XOSC.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rp2350_xosc.h"
|
||||||
|
|
||||||
|
void xosc_init(void)
|
||||||
|
{
|
||||||
|
XOSC->STARTUP = 0x00C4U;
|
||||||
|
XOSC->CTRL = 0x00FABAA0U;
|
||||||
|
while ((XOSC->STATUS & (1U << XOSC_STATUS_STABLE_SHIFT)) == 0) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void xosc_enable_peri_clk(void)
|
||||||
|
{
|
||||||
|
uint32_t value;
|
||||||
|
value = CLOCKS->CLK_PERI_CTRL;
|
||||||
|
value |= (1U << CLK_PERI_CTRL_ENABLE_SHIFT);
|
||||||
|
value |= (CLK_PERI_CTRL_AUXSRC_XOSC << CLK_PERI_CTRL_AUXSRC_SHIFT);
|
||||||
|
CLOCKS->CLK_PERI_CTRL = value;
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file vector_table.c
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief Vector table with initial stack pointer and reset handler.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
extern uint32_t _stack_top;
|
||||||
|
extern void Reset_Handler(void);
|
||||||
|
|
||||||
|
typedef void (*vector_func_t)(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Vector table placed in .vectors section
|
||||||
|
*/
|
||||||
|
__attribute__((section(".vectors"), used))
|
||||||
|
const void *_vectors[2] = {
|
||||||
|
&_stack_top,
|
||||||
|
Reset_Handler
|
||||||
|
};
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
@echo off
|
|
||||||
REM ==============================================================================
|
|
||||||
REM FILE: build.bat
|
|
||||||
REM
|
|
||||||
REM DESCRIPTION:
|
|
||||||
REM Build script for RP2350 bare-metal C UART driver.
|
|
||||||
REM
|
|
||||||
REM BRIEF:
|
|
||||||
REM Automates the process of compiling, linking, and generating UF2 firmware.
|
|
||||||
REM
|
|
||||||
REM AUTHOR: Kevin Thomas
|
|
||||||
REM CREATION DATE: 2025
|
|
||||||
REM UPDATE DATE: 2025
|
|
||||||
REM ==============================================================================
|
|
||||||
|
|
||||||
echo Building C bare-metal version...
|
|
||||||
|
|
||||||
REM ==============================================================================
|
|
||||||
REM Compile C Source Files
|
|
||||||
REM ==============================================================================
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -Og -g3 -Wall -Wextra -ffunction-sections -fdata-sections -c vector_table.c -o vector_table.o
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -Og -g3 -Wall -Wextra -ffunction-sections -fdata-sections -c reset_handler.c -o reset_handler.o
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -Og -g3 -Wall -Wextra -ffunction-sections -fdata-sections -c stack.c -o stack.o
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -Og -g3 -Wall -Wextra -ffunction-sections -fdata-sections -c xosc.c -o xosc.o
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -Og -g3 -Wall -Wextra -ffunction-sections -fdata-sections -c reset.c -o reset.o
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -Og -g3 -Wall -Wextra -ffunction-sections -fdata-sections -c coprocessor.c -o coprocessor.o
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -Og -g3 -Wall -Wextra -ffunction-sections -fdata-sections -c uart.c -o uart.o
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -Og -g3 -Wall -Wextra -ffunction-sections -fdata-sections -c delay.c -o delay.o
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -Og -g3 -Wall -Wextra -ffunction-sections -fdata-sections -c main.c -o main.o
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -Og -g3 -Wall -Wextra -ffunction-sections -fdata-sections -c image_def.c -o image_def.o
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
REM ==============================================================================
|
|
||||||
REM Link Object Files
|
|
||||||
REM ==============================================================================
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -T linker.ld -nostdlib -Wl,--gc-sections vector_table.o reset_handler.o stack.o xosc.o reset.o coprocessor.o uart.o delay.o main.o image_def.o -o uart.elf
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
REM ==============================================================================
|
|
||||||
REM Create Raw Binary from ELF
|
|
||||||
REM ==============================================================================
|
|
||||||
arm-none-eabi-objcopy -O binary uart.elf uart.bin
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
REM ==============================================================================
|
|
||||||
REM Create UF2 Image for RP2350
|
|
||||||
REM -b 0x10000000 : base address
|
|
||||||
REM -f 0xe48bff59 : RP2350 family ID
|
|
||||||
REM ==============================================================================
|
|
||||||
python uf2conv.py -b 0x10000000 -f 0xe48bff59 -o uart.uf2 uart.bin
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
REM ==============================================================================
|
|
||||||
REM Success Message and Flashing Instructions
|
|
||||||
REM ==============================================================================
|
|
||||||
echo.
|
|
||||||
echo =================================
|
|
||||||
echo SUCCESS! Created uart.uf2
|
|
||||||
echo =================================
|
|
||||||
echo.
|
|
||||||
echo To flash via UF2:
|
|
||||||
echo 1. Hold BOOTSEL button
|
|
||||||
echo 2. Plug in USB
|
|
||||||
echo 3. Copy uart.uf2 to RP2350 drive
|
|
||||||
echo.
|
|
||||||
echo To flash via OpenOCD (debug probe):
|
|
||||||
echo openocd -f interface/cmsis-dap.cfg -f target/rp2350.cfg -c "adapter speed 5000" -c "program uart.elf verify reset exit"
|
|
||||||
echo.
|
|
||||||
goto end
|
|
||||||
|
|
||||||
REM ==============================================================================
|
|
||||||
REM Error Handling
|
|
||||||
REM ==============================================================================
|
|
||||||
:error
|
|
||||||
echo.
|
|
||||||
echo BUILD FAILED!
|
|
||||||
echo.
|
|
||||||
|
|
||||||
:end
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
@echo off
|
|
||||||
REM ==============================================================================
|
|
||||||
REM FILE: clean.bat
|
|
||||||
REM
|
|
||||||
REM DESCRIPTION:
|
|
||||||
REM Clean script for RP2350 bare-metal C UART driver.
|
|
||||||
REM
|
|
||||||
REM BRIEF:
|
|
||||||
REM Removes all build artifacts and generated files.
|
|
||||||
REM
|
|
||||||
REM AUTHOR: Kevin Thomas
|
|
||||||
REM CREATION DATE: 2025
|
|
||||||
REM UPDATE DATE: 2025
|
|
||||||
REM ==============================================================================
|
|
||||||
|
|
||||||
echo Cleaning build artifacts...
|
|
||||||
|
|
||||||
REM Remove object files
|
|
||||||
if exist *.o del /Q *.o
|
|
||||||
|
|
||||||
REM Remove ELF file
|
|
||||||
if exist uart.elf del /Q uart.elf
|
|
||||||
|
|
||||||
REM Remove binary file
|
|
||||||
if exist uart.bin del /Q uart.bin
|
|
||||||
|
|
||||||
REM Remove UF2 file
|
|
||||||
if exist uart.uf2 del /Q uart.uf2
|
|
||||||
|
|
||||||
echo Clean complete!
|
|
||||||
@@ -1,195 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file constants.h
|
|
||||||
* @brief Memory-mapped register structures and peripheral base addresses
|
|
||||||
* @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 CONSTANTS_H
|
|
||||||
#define CONSTANTS_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stack addresses.
|
|
||||||
*/
|
|
||||||
#define STACK_TOP 0x20082000U
|
|
||||||
#define STACK_LIMIT 0x2007A000U
|
|
||||||
|
|
||||||
/**
|
|
||||||
* XOSC (External Crystal Oscillator) Register Structure.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
volatile uint32_t CTRL; /**< 0x00: Control register */
|
|
||||||
volatile uint32_t STATUS; /**< 0x04: Status register */
|
|
||||||
volatile uint32_t DORMANT; /**< 0x08: Dormant mode */
|
|
||||||
volatile uint32_t STARTUP; /**< 0x0C: Startup delay */
|
|
||||||
volatile uint32_t RESERVED[3]; /**< 0x10-0x18: Reserved */
|
|
||||||
volatile uint32_t COUNT; /**< 0x1C: Frequency count */
|
|
||||||
} xosc_hw_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* XOSC base address and pointer.
|
|
||||||
*/
|
|
||||||
#define XOSC_BASE 0x40048000U
|
|
||||||
#define XOSC ((xosc_hw_t *)XOSC_BASE)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* XOSC status bit definitions.
|
|
||||||
*/
|
|
||||||
#define XOSC_STATUS_STABLE_SHIFT 31U
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CPACR (Coprocessor Access Control Register) in PPB.
|
|
||||||
*/
|
|
||||||
#define PPB_BASE 0xE0000000U
|
|
||||||
#define CPACR ((volatile uint32_t *)(PPB_BASE + 0x0ED88U))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Coprocessor access control bit definitions.
|
|
||||||
*/
|
|
||||||
#define CPACR_CP0_SHIFT 0U
|
|
||||||
#define CPACR_CP1_SHIFT 1U
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CLOCKS Register Structure.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
volatile uint32_t RESERVED0[18]; /**< 0x00-0x44: Other clock registers */
|
|
||||||
volatile uint32_t CLK_PERI_CTRL; /**< 0x48: Peripheral clock control */
|
|
||||||
} clocks_hw_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CLOCKS base address and pointer.
|
|
||||||
*/
|
|
||||||
#define CLOCKS_BASE 0x40010000U
|
|
||||||
#define CLOCKS ((clocks_hw_t *)CLOCKS_BASE)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clock control bit definitions.
|
|
||||||
*/
|
|
||||||
#define CLOCKS_CLK_PERI_CTRL_ENABLE_SHIFT 11U
|
|
||||||
#define CLOCKS_CLK_PERI_CTRL_AUXSRC_SHIFT 5U
|
|
||||||
#define CLOCKS_CLK_PERI_CTRL_AUXSRC_XOSC 4U
|
|
||||||
|
|
||||||
/**
|
|
||||||
* RESETS Register Structure.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
volatile uint32_t RESET; /**< 0x00: Reset control */
|
|
||||||
volatile uint32_t WDSEL; /**< 0x04: Watchdog select */
|
|
||||||
volatile uint32_t RESET_DONE; /**< 0x08: Reset done status */
|
|
||||||
} resets_hw_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* RESETS base address and pointer.
|
|
||||||
*/
|
|
||||||
#define RESETS_BASE 0x40020000U
|
|
||||||
#define RESETS ((resets_hw_t *)RESETS_BASE)
|
|
||||||
#define RESETS_RESET_CLEAR ((volatile uint32_t *)(RESETS_BASE + 0x3000U))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset control bit definitions.
|
|
||||||
*/
|
|
||||||
#define RESETS_RESET_IO_BANK0_SHIFT 6U
|
|
||||||
#define RESETS_RESET_UART0_SHIFT 26U
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IO_BANK0 GPIO Control Register (one per GPIO).
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
volatile uint32_t STATUS; /**< 0x00: GPIO status */
|
|
||||||
volatile uint32_t CTRL; /**< 0x04: GPIO control */
|
|
||||||
} io_bank0_gpio_ctrl_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IO_BANK0 Register Structure.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
io_bank0_gpio_ctrl_t GPIO[30]; /**< 0x000-0x0E8: GPIO 0-29 */
|
|
||||||
} io_bank0_hw_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IO_BANK0 base address and pointer.
|
|
||||||
*/
|
|
||||||
#define IO_BANK0_BASE 0x40028000U
|
|
||||||
#define IO_BANK0 ((io_bank0_hw_t *)IO_BANK0_BASE)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GPIO control bit definitions.
|
|
||||||
*/
|
|
||||||
#define IO_BANK0_CTRL_FUNCSEL_MASK 0x1FU
|
|
||||||
#define IO_BANK0_CTRL_FUNCSEL_UART 0x02U
|
|
||||||
#define IO_BANK0_CTRL_FUNCSEL_SIO 0x05U
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PADS_BANK0 Register Structure.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
volatile uint32_t VOLTAGE_SELECT; /**< 0x00: Voltage select */
|
|
||||||
volatile uint32_t GPIO[30]; /**< 0x04-0x78: GPIO 0-29 pad control */
|
|
||||||
} pads_bank0_hw_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PADS_BANK0 base address and pointer.
|
|
||||||
*/
|
|
||||||
#define PADS_BANK0_BASE 0x40038000U
|
|
||||||
#define PADS_BANK0 ((pads_bank0_hw_t *)PADS_BANK0_BASE)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pad control bit definitions.
|
|
||||||
*/
|
|
||||||
#define PADS_BANK0_OD_SHIFT 7U
|
|
||||||
#define PADS_BANK0_IE_SHIFT 6U
|
|
||||||
#define PADS_BANK0_ISO_SHIFT 8U
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UART0 base address.
|
|
||||||
*/
|
|
||||||
#define UART0_BASE 0x40070000U
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UART register offsets (as word indices from UART0_BASE).
|
|
||||||
*/
|
|
||||||
#define UART_DR_OFFSET (0x00U / 4U)
|
|
||||||
#define UART_FR_OFFSET (0x18U / 4U)
|
|
||||||
#define UART_IBRD_OFFSET (0x24U / 4U)
|
|
||||||
#define UART_FBRD_OFFSET (0x28U / 4U)
|
|
||||||
#define UART_LCR_H_OFFSET (0x2CU / 4U)
|
|
||||||
#define UART_CR_OFFSET (0x30U / 4U)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UART flag register bit definitions.
|
|
||||||
*/
|
|
||||||
#define UART_FR_TXFF_MASK 32U
|
|
||||||
#define UART_FR_RXFE_MASK 16U
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UART line control and enable values.
|
|
||||||
*/
|
|
||||||
#define UART_LCR_H_8N1_FIFO 0x70U
|
|
||||||
#define UART_CR_ENABLE ((3U << 8) | 1U)
|
|
||||||
|
|
||||||
#endif // CONSTANTS_H
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file coprocessor.c
|
|
||||||
* @brief Coprocessor access control enable functions
|
|
||||||
* @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 "coprocessor.h"
|
|
||||||
#include "constants.h"
|
|
||||||
|
|
||||||
void Enable_Coprocessor(void) {
|
|
||||||
uint32_t value;
|
|
||||||
|
|
||||||
// read CPACR value
|
|
||||||
value = *CPACR;
|
|
||||||
// set CP1: Ctrl access priv coproc 1 bit
|
|
||||||
value |= (1U << CPACR_CP1_SHIFT);
|
|
||||||
// set CP0: Ctrl access priv coproc 0 bit
|
|
||||||
value |= (1U << CPACR_CP0_SHIFT);
|
|
||||||
// store value into CPACR
|
|
||||||
*CPACR = value;
|
|
||||||
// data sync barrier
|
|
||||||
__asm__ volatile ("dsb");
|
|
||||||
// instruction sync barrier
|
|
||||||
__asm__ volatile ("isb");
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file coprocessor.h
|
|
||||||
* @brief Coprocessor access control enable functions
|
|
||||||
* @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 COPROCESSOR_H
|
|
||||||
#define COPROCESSOR_H
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enable coprocessor access via CPACR
|
|
||||||
*
|
|
||||||
* Grants full access to coprocessors 0 and 1 by setting the
|
|
||||||
* corresponding bits in the Coprocessor Access Control Register,
|
|
||||||
* then issues DSB and ISB barriers.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void Enable_Coprocessor(void);
|
|
||||||
|
|
||||||
#endif // COPROCESSOR_H
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file delay.c
|
|
||||||
* @brief Millisecond delay functions based on a 14.5 MHz clock
|
|
||||||
* @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 "delay.h"
|
|
||||||
|
|
||||||
void Delay_MS(uint32_t ms) {
|
|
||||||
if (ms == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
__asm__ volatile (
|
|
||||||
"mov r4, #3600\n\t"
|
|
||||||
"mul r5, %0, r4\n\t"
|
|
||||||
"1:\n\t"
|
|
||||||
"subs r5, #1\n\t"
|
|
||||||
"bne 1b\n\t"
|
|
||||||
:
|
|
||||||
: "r" (ms)
|
|
||||||
: "r4", "r5", "cc"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file delay.h
|
|
||||||
* @brief Millisecond delay functions based on a 14.5 MHz clock
|
|
||||||
* @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 DELAY_H
|
|
||||||
#define DELAY_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Delay for the specified number of milliseconds
|
|
||||||
*
|
|
||||||
* Busy-waits using a calibrated loop count (3600 iterations per ms)
|
|
||||||
* based on a 14.5 MHz clock. Returns immediately if ms is zero.
|
|
||||||
*
|
|
||||||
* @param ms Number of milliseconds to delay
|
|
||||||
*/
|
|
||||||
void Delay_MS(uint32_t ms);
|
|
||||||
|
|
||||||
#endif // DELAY_H
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file image_def.c
|
|
||||||
* @brief RP2350 IMAGE_DEF block for boot ROM image recognition
|
|
||||||
* @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 <stdint.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IMAGE_DEF block structure placed in flash.
|
|
||||||
* Must appear within the first 4 KB for the boot ROM to accept the image.
|
|
||||||
*/
|
|
||||||
__attribute__((section(".embedded_block"), used))
|
|
||||||
const uint8_t picobin_block[] = {
|
|
||||||
// PICOBIN_BLOCK_MARKER_START (word: 0xffffded3)
|
|
||||||
0xD3, 0xDE, 0xFF, 0xFF,
|
|
||||||
// PICOBIN_BLOCK_ITEM_1BS_IMAGE_TYPE
|
|
||||||
0x42, 0x01, 0x21, 0x10,
|
|
||||||
// PICOBIN_BLOCK_ITEM_2BS_LAST
|
|
||||||
0xFF, 0x01, 0x00, 0x00,
|
|
||||||
// Relative pointer to next block (loop to self)
|
|
||||||
0x00, 0x00, 0x00, 0x00,
|
|
||||||
// PICOBIN_BLOCK_MARKER_END (word: 0xab123579)
|
|
||||||
0x79, 0x35, 0x12, 0xAB
|
|
||||||
};
|
|
||||||
@@ -1,44 +1,43 @@
|
|||||||
/**
|
/**
|
||||||
* @file linker.ld
|
******************************************************************************
|
||||||
* @brief Minimal linker script for bare-metal RP2350 development
|
* @file linker.ld
|
||||||
* @author Kevin Thomas
|
* @author Kevin Thomas
|
||||||
* @date 2025
|
* @brief Minimal linker script for bare-metal RP2350 development.
|
||||||
*
|
*
|
||||||
* MIT License
|
* Defines FLASH (XIP 32 MB) and RAM (520 kB SRAM) regions.
|
||||||
*
|
* The vector table is placed at the start of flash (0x10000000).
|
||||||
* Copyright (c) 2025 Kevin Thomas
|
*
|
||||||
*
|
******************************************************************************
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* @attention
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
*
|
||||||
* in the Software without restriction, including without limitation the rights
|
* Copyright (c) 2026 Kevin Thomas.
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* All rights reserved.
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
*
|
||||||
* furnished to do so, subject to the following conditions:
|
* This software is licensed under terms that can be found in the LICENSE file
|
||||||
*
|
* in the root directory of this software component.
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entry point.
|
||||||
|
*/
|
||||||
ENTRY(Reset_Handler)
|
ENTRY(Reset_Handler)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define memory regions.
|
* Define memory regions.
|
||||||
*/
|
*/
|
||||||
__XIP_BASE = 0x10000000;
|
__XIP_BASE = 0x10000000;
|
||||||
__XIP_SIZE = 32M;
|
__XIP_SIZE = 32M;
|
||||||
|
|
||||||
__SRAM_BASE = 0x20000000;
|
__SRAM_BASE = 0x20000000;
|
||||||
__SRAM_SIZE = 512K;
|
__SRAM_SIZE = 520K;
|
||||||
__STACK_SIZE = 32K;
|
__STACK_SIZE = 32K;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Memory layout.
|
||||||
|
*/
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
RAM (rwx) : ORIGIN = __SRAM_BASE, LENGTH = __SRAM_SIZE
|
RAM (rwx) : ORIGIN = __SRAM_BASE, LENGTH = __SRAM_SIZE
|
||||||
@@ -46,34 +45,37 @@ MEMORY
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program headers.
|
* Program headers.
|
||||||
*/
|
*/
|
||||||
PHDRS
|
PHDRS
|
||||||
{
|
{
|
||||||
text PT_LOAD FLAGS(5);
|
text PT_LOAD FLAGS(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Section placement.
|
* Section placement.
|
||||||
*/
|
*/
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = ORIGIN(FLASH);
|
. = ORIGIN(FLASH);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vector table MUST be first at 0x10000000.
|
* Vector table MUST be first at 0x10000000.
|
||||||
*/
|
*/
|
||||||
.vectors :
|
.vectors :
|
||||||
{
|
{
|
||||||
KEEP(*(.vectors))
|
KEEP(*(.vectors))
|
||||||
} > FLASH :text
|
} > FLASH :text
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify vector table placement.
|
||||||
|
*/
|
||||||
ASSERT((ADDR(.vectors) == ORIGIN(FLASH)),
|
ASSERT((ADDR(.vectors) == ORIGIN(FLASH)),
|
||||||
"Vector table must be at start of flash (0x10000000)")
|
"Vector table must be at start of flash (0x10000000)")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Text and read-only data.
|
* Text and read-only data.
|
||||||
*/
|
*/
|
||||||
.text :
|
.text :
|
||||||
{
|
{
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
@@ -85,22 +87,28 @@ SECTIONS
|
|||||||
} > FLASH :text
|
} > FLASH :text
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IMAGE_DEF block at end of code.
|
* IMAGE_DEF block at end of code.
|
||||||
*/
|
*/
|
||||||
.embedded_block :
|
.embedded_block :
|
||||||
{
|
{
|
||||||
KEEP(*(.embedded_block))
|
KEEP(*(.embedded_block))
|
||||||
} > FLASH :text
|
} > FLASH :text
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Non-secure stack symbols.
|
* Non-secure stack symbols.
|
||||||
*/
|
*/
|
||||||
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
|
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
|
||||||
__StackLimit = __StackTop - __STACK_SIZE;
|
__StackLimit = __StackTop - __STACK_SIZE;
|
||||||
__stack = __StackTop;
|
__stack = __StackTop;
|
||||||
_stack_top = __StackTop;
|
_stack_top = __StackTop;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stack section (no load).
|
||||||
|
*/
|
||||||
.stack (NOLOAD) : { . = ALIGN(8); } > RAM
|
.stack (NOLOAD) : { . = ALIGN(8); } > RAM
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide vector table symbol to startup code.
|
||||||
|
*/
|
||||||
PROVIDE(__Vectors = ADDR(.vectors));
|
PROVIDE(__Vectors = ADDR(.vectors));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,78 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file main.c
|
|
||||||
* @brief UART demonstration: echo received characters back in uppercase
|
|
||||||
* @author Kevin Thomas
|
|
||||||
* @date 2025
|
|
||||||
*
|
|
||||||
* MIT License
|
|
||||||
*
|
|
||||||
* Copyright (c) 2025 Kevin Thomas
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* -----------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* Demonstrates bare-metal UART0 using the uart driver (uart.h / uart.c).
|
|
||||||
* Characters typed into a terminal via a USB-to-UART adapter are echoed
|
|
||||||
* back in uppercase, illustrating full-duplex raw UART operation at the
|
|
||||||
* register level without the Pico SDK.
|
|
||||||
*
|
|
||||||
* Wiring:
|
|
||||||
* GPIO0 (TX) -> USB-to-UART adapter RX
|
|
||||||
* GPIO1 (RX) -> USB-to-UART adapter TX
|
|
||||||
* GND -> USB-to-UART adapter GND
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "uart.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Echo received characters back as uppercase
|
|
||||||
*
|
|
||||||
* @details Polls UART0 for incoming data. When a character is
|
|
||||||
* available, reads it, converts to uppercase, and echoes
|
|
||||||
* it back. Never returns.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void _echo_uppercase(void) {
|
|
||||||
while (1) {
|
|
||||||
if (uart_driver_is_readable()) {
|
|
||||||
char c = uart_driver_getchar();
|
|
||||||
char upper = uart_driver_to_upper(c);
|
|
||||||
uart_driver_putchar(upper);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Application entry point for the UART uppercase echo demo
|
|
||||||
*
|
|
||||||
* Prints two banner messages over UART0, then enters the echo loop.
|
|
||||||
* UART0 hardware initialization is performed by Reset_Handler before
|
|
||||||
* main() is called.
|
|
||||||
*
|
|
||||||
* @return int Does not return
|
|
||||||
*/
|
|
||||||
int main(void) {
|
|
||||||
uart_driver_puts("UART driver ready (115200 8N1)\r\n");
|
|
||||||
uart_driver_puts("Type characters to echo them back in UPPERCASE:\r\n");
|
|
||||||
_echo_uppercase();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file reset.c
|
|
||||||
* @brief Reset controller functions for subsystem initialization
|
|
||||||
* @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 "reset.h"
|
|
||||||
#include "constants.h"
|
|
||||||
|
|
||||||
void Init_Subsystem(void) {
|
|
||||||
uint32_t value;
|
|
||||||
|
|
||||||
// read RESETS->RESET value
|
|
||||||
value = RESETS->RESET;
|
|
||||||
// clear IO_BANK0 bit
|
|
||||||
value &= ~(1U << RESETS_RESET_IO_BANK0_SHIFT);
|
|
||||||
// store value into RESETS->RESET address
|
|
||||||
RESETS->RESET = value;
|
|
||||||
// wait until done
|
|
||||||
while ((RESETS->RESET_DONE & (1U << RESETS_RESET_IO_BANK0_SHIFT)) == 0) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file reset.h
|
|
||||||
* @brief Reset controller functions for subsystem initialization
|
|
||||||
* @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 RESET_H
|
|
||||||
#define RESET_H
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize the IO_BANK0 subsystem by clearing its reset bit
|
|
||||||
*
|
|
||||||
* Clears the IO_BANK0 reset bit in the Reset controller and waits
|
|
||||||
* until the RESET_DONE register confirms the block is out of reset.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void Init_Subsystem(void);
|
|
||||||
|
|
||||||
#endif // RESET_H
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file reset_handler.c
|
|
||||||
* @brief Reset handler entry point after power-on or system reset
|
|
||||||
* @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 "reset_handler.h"
|
|
||||||
#include "stack.h"
|
|
||||||
#include "xosc.h"
|
|
||||||
#include "reset.h"
|
|
||||||
#include "uart.h"
|
|
||||||
#include "coprocessor.h"
|
|
||||||
|
|
||||||
extern int main(void);
|
|
||||||
|
|
||||||
void __attribute__((naked, noreturn)) Reset_Handler(void) {
|
|
||||||
__asm__ volatile (
|
|
||||||
"bl Init_Stack\n\t"
|
|
||||||
"bl Init_XOSC\n\t"
|
|
||||||
"bl Enable_XOSC_Peri_Clock\n\t"
|
|
||||||
"bl Init_Subsystem\n\t"
|
|
||||||
"bl UART_Release_Reset\n\t"
|
|
||||||
"bl UART_Init\n\t"
|
|
||||||
"bl Enable_Coprocessor\n\t"
|
|
||||||
"b main\n\t"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file reset_handler.h
|
|
||||||
* @brief Reset handler entry point after power-on or system reset
|
|
||||||
* @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 RESET_HANDLER_H
|
|
||||||
#define RESET_HANDLER_H
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Reset handler for the RP2350
|
|
||||||
*
|
|
||||||
* Entry point after reset. Performs stack initialization, XOSC setup,
|
|
||||||
* subsystem reset release, UART initialization, coprocessor enable,
|
|
||||||
* and branches to main().
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void Reset_Handler(void) __attribute__((noreturn));
|
|
||||||
|
|
||||||
#endif // RESET_HANDLER_H
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file stack.c
|
|
||||||
* @brief Stack pointer initialization for MSP/PSP and their limits
|
|
||||||
* @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 "stack.h"
|
|
||||||
#include "constants.h"
|
|
||||||
|
|
||||||
void Init_Stack(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"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file stack.h
|
|
||||||
* @brief Stack pointer initialization for MSP/PSP and their limits
|
|
||||||
* @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 STACK_H
|
|
||||||
#define STACK_H
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize stack pointers
|
|
||||||
*
|
|
||||||
* Sets Main and Process Stack Pointers (MSP/PSP) and their limits
|
|
||||||
* using the STACK_TOP and STACK_LIMIT values from constants.h.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void Init_Stack(void);
|
|
||||||
|
|
||||||
#endif // STACK_H
|
|
||||||
@@ -1,165 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file uart.c
|
|
||||||
* @brief Implementation of the bare-metal UART0 driver
|
|
||||||
* @author Kevin Thomas
|
|
||||||
* @date 2025
|
|
||||||
*
|
|
||||||
* MIT License
|
|
||||||
*
|
|
||||||
* Copyright (c) 2025 Kevin Thomas
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "uart.h"
|
|
||||||
#include "constants.h"
|
|
||||||
|
|
||||||
#define UART_BASE ((volatile uint32_t *)UART0_BASE)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Clear the UART0 reset bit in the reset controller
|
|
||||||
*
|
|
||||||
* @details Reads RESETS->RESET, clears bit 26 (UART0), and writes
|
|
||||||
* the value back.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void _uart_clear_reset_bit(void) {
|
|
||||||
uint32_t value;
|
|
||||||
|
|
||||||
// read RESETS->RESET value
|
|
||||||
value = RESETS->RESET;
|
|
||||||
// clear UART0 reset bit (bit 26)
|
|
||||||
value &= ~(1U << RESETS_RESET_UART0_SHIFT);
|
|
||||||
// write value back to RESETS->RESET
|
|
||||||
RESETS->RESET = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Wait until the UART0 block is out of reset
|
|
||||||
*
|
|
||||||
* @details Polls RESETS->RESET_DONE until bit 26 (UART0) is set.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void _uart_wait_reset_done(void) {
|
|
||||||
// loop until UART0 is out of reset
|
|
||||||
while ((RESETS->RESET_DONE & (1U << RESETS_RESET_UART0_SHIFT)) == 0) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Configure GPIO pins 0 (TX) and 1 (RX) for UART function
|
|
||||||
*
|
|
||||||
* @details Sets IO_BANK0 FUNCSEL to UART (0x02) for both pins and
|
|
||||||
* programs the corresponding pad controls.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void _uart_configure_pins(void) {
|
|
||||||
// FUNCSEL = 2 -> select UART function
|
|
||||||
IO_BANK0->GPIO[0].CTRL = IO_BANK0_CTRL_FUNCSEL_UART;
|
|
||||||
IO_BANK0->GPIO[1].CTRL = IO_BANK0_CTRL_FUNCSEL_UART;
|
|
||||||
// pad config value for TX (pull/func recommended)
|
|
||||||
PADS_BANK0->GPIO[0] = 0x04;
|
|
||||||
// pad config value for RX (input enable)
|
|
||||||
PADS_BANK0->GPIO[1] = 0x40;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set UART0 baud rate divisors for 115200 baud at 14.5 MHz
|
|
||||||
*
|
|
||||||
* @details Programs UARTIBRD = 6 and UARTFBRD = 33 for the integer
|
|
||||||
* and fractional baud rate divisors respectively.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void _uart_set_baud(void) {
|
|
||||||
// disable UART while configuring
|
|
||||||
UART_BASE[UART_CR_OFFSET] = 0;
|
|
||||||
// set integer baud divisor
|
|
||||||
UART_BASE[UART_IBRD_OFFSET] = 6;
|
|
||||||
// set fractional baud divisor
|
|
||||||
UART_BASE[UART_FBRD_OFFSET] = 33;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Configure line control and enable UART0
|
|
||||||
*
|
|
||||||
* @details Sets 8-bit word length with FIFOs enabled, then enables
|
|
||||||
* UART0 with both TX and RX.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void _uart_enable(void) {
|
|
||||||
// configure line control: FIFO enable + 8-bit
|
|
||||||
UART_BASE[UART_LCR_H_OFFSET] = UART_LCR_H_8N1_FIFO;
|
|
||||||
// enable UART with TX and RX enabled
|
|
||||||
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_driver_is_readable(void) {
|
|
||||||
// test bit 4, RX FIFO empty (RXFE)
|
|
||||||
return (UART_BASE[UART_FR_OFFSET] & UART_FR_RXFE_MASK) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char uart_driver_getchar(void) {
|
|
||||||
// wait for RX FIFO to be not empty
|
|
||||||
while (UART_BASE[UART_FR_OFFSET] & UART_FR_RXFE_MASK) {
|
|
||||||
}
|
|
||||||
// read data from UARTDR
|
|
||||||
return (char)(UART_BASE[UART_DR_OFFSET] & 0xFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uart_driver_putchar(char c) {
|
|
||||||
// wait for TX FIFO to be not full
|
|
||||||
while (UART_BASE[UART_FR_OFFSET] & UART_FR_TXFF_MASK) {
|
|
||||||
}
|
|
||||||
// write data to UARTDR
|
|
||||||
UART_BASE[UART_DR_OFFSET] = (uint32_t)c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uart_driver_puts(const char *str) {
|
|
||||||
while (*str) {
|
|
||||||
uart_driver_putchar(*str++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char uart_driver_to_upper(char c) {
|
|
||||||
if (c >= 'a' && c <= 'z') {
|
|
||||||
return (char)(c - 32);
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file uart.h
|
|
||||||
* @brief Header for bare-metal UART0 driver (raw TX/RX, GPIO 0/1)
|
|
||||||
* @author Kevin Thomas
|
|
||||||
* @date 2025
|
|
||||||
*
|
|
||||||
* MIT License
|
|
||||||
*
|
|
||||||
* Copyright (c) 2025 Kevin Thomas
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef UART_H
|
|
||||||
#define UART_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Release UART0 from reset and wait until it is ready
|
|
||||||
*
|
|
||||||
* Clears the UART0 reset bit in the Reset controller and polls
|
|
||||||
* RESET_DONE until the UART0 block is out of reset.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void UART_Release_Reset(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize UART0 (pins, baud divisors, line control, enable)
|
|
||||||
*
|
|
||||||
* Configures IO_BANK0 pins 0 (TX) and 1 (RX) to the UART function,
|
|
||||||
* programs pad controls, sets baud rate divisors (IBRD=6, FBRD=33
|
|
||||||
* for 115200 baud at 14.5 MHz), configures 8N1 with FIFOs, and
|
|
||||||
* enables UART0 with TX and RX.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void UART_Init(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check whether a received character is waiting in the UART FIFO
|
|
||||||
*
|
|
||||||
* Returns immediately without blocking. Use this to poll for incoming
|
|
||||||
* data before calling uart_driver_getchar().
|
|
||||||
*
|
|
||||||
* @return bool true if at least one byte is available, false otherwise
|
|
||||||
*/
|
|
||||||
bool uart_driver_is_readable(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Read one character from UART0 (blocking)
|
|
||||||
*
|
|
||||||
* Blocks until a byte arrives in the receive FIFO, then returns it.
|
|
||||||
* Prefer pairing with uart_driver_is_readable() to avoid indefinite blocking.
|
|
||||||
*
|
|
||||||
* @return char The received character
|
|
||||||
*/
|
|
||||||
char uart_driver_getchar(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Transmit one character over UART0 (blocking)
|
|
||||||
*
|
|
||||||
* Waits until the transmit FIFO has space, then writes the character
|
|
||||||
* to UARTDR.
|
|
||||||
*
|
|
||||||
* @param c Character to transmit
|
|
||||||
*/
|
|
||||||
void uart_driver_putchar(char c);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Transmit a null-terminated string over UART0
|
|
||||||
*
|
|
||||||
* Calls uart_driver_putchar() for every character in the string up to
|
|
||||||
* and not including the null terminator.
|
|
||||||
*
|
|
||||||
* @param str Pointer to the null-terminated ASCII string to send
|
|
||||||
*/
|
|
||||||
void uart_driver_puts(const char *str);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Convert a lowercase ASCII character to uppercase
|
|
||||||
*
|
|
||||||
* Returns the uppercase equivalent if the character is in 'a'-'z';
|
|
||||||
* all other characters are passed through unchanged.
|
|
||||||
*
|
|
||||||
* @param c Input character
|
|
||||||
* @return char Uppercase equivalent, or the original character
|
|
||||||
*/
|
|
||||||
char uart_driver_to_upper(char c);
|
|
||||||
|
|
||||||
#endif // UART_H
|
|
||||||
@@ -10,9 +10,9 @@ import json
|
|||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
|
|
||||||
UF2_MAGIC_START0 = 0x0A324655 # "UF2\n"
|
UF2_MAGIC_START0 = 0x0A324655 # "UF2\n"
|
||||||
UF2_MAGIC_START1 = 0x9E5D5157 # Randomly selected
|
UF2_MAGIC_START1 = 0x9E5D5157 # Randomly selected
|
||||||
UF2_MAGIC_END = 0x0AB16F30 # Ditto
|
UF2_MAGIC_END = 0x0AB16F30 # Ditto
|
||||||
|
|
||||||
INFO_FILE = "/INFO_UF2.TXT"
|
INFO_FILE = "/INFO_UF2.TXT"
|
||||||
|
|
||||||
@@ -24,15 +24,17 @@ def is_uf2(buf):
|
|||||||
w = struct.unpack("<II", buf[0:8])
|
w = struct.unpack("<II", buf[0:8])
|
||||||
return w[0] == UF2_MAGIC_START0 and w[1] == UF2_MAGIC_START1
|
return w[0] == UF2_MAGIC_START0 and w[1] == UF2_MAGIC_START1
|
||||||
|
|
||||||
|
|
||||||
def is_hex(buf):
|
def is_hex(buf):
|
||||||
try:
|
try:
|
||||||
w = buf[0:30].decode("utf-8")
|
w = buf[0:30].decode("utf-8")
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
return False
|
return False
|
||||||
if w[0] == ':' and re.match(rb"^[:0-9a-fA-F\r\n]+$", buf):
|
if w[0] == ":" and re.match(rb"^[:0-9a-fA-F\r\n]+$", buf):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def convert_from_uf2(buf):
|
def convert_from_uf2(buf):
|
||||||
global appstartaddr
|
global appstartaddr
|
||||||
global familyid
|
global familyid
|
||||||
@@ -45,7 +47,7 @@ def convert_from_uf2(buf):
|
|||||||
outp = []
|
outp = []
|
||||||
for blockno in range(numblocks):
|
for blockno in range(numblocks):
|
||||||
ptr = blockno * 512
|
ptr = blockno * 512
|
||||||
block = buf[ptr:ptr + 512]
|
block = buf[ptr : ptr + 512]
|
||||||
hd = struct.unpack(b"<IIIIIIII", block[0:32])
|
hd = struct.unpack(b"<IIIIIIII", block[0:32])
|
||||||
if hd[0] != UF2_MAGIC_START0 or hd[1] != UF2_MAGIC_START1:
|
if hd[0] != UF2_MAGIC_START0 or hd[1] != UF2_MAGIC_START1:
|
||||||
print("Skipping block at " + ptr + "; bad magic")
|
print("Skipping block at " + ptr + "; bad magic")
|
||||||
@@ -62,12 +64,12 @@ def convert_from_uf2(buf):
|
|||||||
if curraddr == None or ((hd[2] & 0x2000) and hd[7] != currfamilyid):
|
if curraddr == None or ((hd[2] & 0x2000) and hd[7] != currfamilyid):
|
||||||
currfamilyid = hd[7]
|
currfamilyid = hd[7]
|
||||||
curraddr = newaddr
|
curraddr = newaddr
|
||||||
if familyid == 0x0 or familyid == hd[7]:
|
if familyid == 0x0 or familyid == hd[7]:
|
||||||
appstartaddr = newaddr
|
appstartaddr = newaddr
|
||||||
padding = newaddr - curraddr
|
padding = newaddr - curraddr
|
||||||
if padding < 0:
|
if padding < 0:
|
||||||
assert False, "Block out of order at " + ptr
|
assert False, "Block out of order at " + ptr
|
||||||
if padding > 10*1024*1024:
|
if padding > 10 * 1024 * 1024:
|
||||||
assert False, "More than 10M of padding needed at " + ptr
|
assert False, "More than 10M of padding needed at " + ptr
|
||||||
if padding % 4 != 0:
|
if padding % 4 != 0:
|
||||||
assert False, "Non-word padding size at " + ptr
|
assert False, "Non-word padding size at " + ptr
|
||||||
@@ -95,7 +97,11 @@ def convert_from_uf2(buf):
|
|||||||
for name, value in families.items():
|
for name, value in families.items():
|
||||||
if value == family_hex:
|
if value == family_hex:
|
||||||
family_short_name = name
|
family_short_name = name
|
||||||
print("Family ID is {:s}, hex value is 0x{:08x}".format(family_short_name,family_hex))
|
print(
|
||||||
|
"Family ID is {:s}, hex value is 0x{:08x}".format(
|
||||||
|
family_short_name, family_hex
|
||||||
|
)
|
||||||
|
)
|
||||||
print("Target Address is 0x{:08x}".format(families_found[family_hex]))
|
print("Target Address is 0x{:08x}".format(families_found[family_hex]))
|
||||||
if all_flags_same:
|
if all_flags_same:
|
||||||
print("All block flag values consistent, 0x{:04x}".format(hd[2]))
|
print("All block flag values consistent, 0x{:04x}".format(hd[2]))
|
||||||
@@ -107,6 +113,7 @@ def convert_from_uf2(buf):
|
|||||||
appstartaddr = 0x0
|
appstartaddr = 0x0
|
||||||
return b"".join(outp)
|
return b"".join(outp)
|
||||||
|
|
||||||
|
|
||||||
def convert_to_carray(file_content):
|
def convert_to_carray(file_content):
|
||||||
outp = "const unsigned long bindata_len = %d;\n" % len(file_content)
|
outp = "const unsigned long bindata_len = %d;\n" % len(file_content)
|
||||||
outp += "const unsigned char bindata[] __attribute__((aligned(16))) = {"
|
outp += "const unsigned char bindata[] __attribute__((aligned(16))) = {"
|
||||||
@@ -117,6 +124,7 @@ def convert_to_carray(file_content):
|
|||||||
outp += "\n};\n"
|
outp += "\n};\n"
|
||||||
return bytes(outp, "utf-8")
|
return bytes(outp, "utf-8")
|
||||||
|
|
||||||
|
|
||||||
def convert_to_uf2(file_content):
|
def convert_to_uf2(file_content):
|
||||||
global familyid
|
global familyid
|
||||||
datapadding = b""
|
datapadding = b""
|
||||||
@@ -126,13 +134,21 @@ def convert_to_uf2(file_content):
|
|||||||
outp = []
|
outp = []
|
||||||
for blockno in range(numblocks):
|
for blockno in range(numblocks):
|
||||||
ptr = 256 * blockno
|
ptr = 256 * blockno
|
||||||
chunk = file_content[ptr:ptr + 256]
|
chunk = file_content[ptr : ptr + 256]
|
||||||
flags = 0x0
|
flags = 0x0
|
||||||
if familyid:
|
if familyid:
|
||||||
flags |= 0x2000
|
flags |= 0x2000
|
||||||
hd = struct.pack(b"<IIIIIIII",
|
hd = struct.pack(
|
||||||
UF2_MAGIC_START0, UF2_MAGIC_START1,
|
b"<IIIIIIII",
|
||||||
flags, ptr + appstartaddr, 256, blockno, numblocks, familyid)
|
UF2_MAGIC_START0,
|
||||||
|
UF2_MAGIC_START1,
|
||||||
|
flags,
|
||||||
|
ptr + appstartaddr,
|
||||||
|
256,
|
||||||
|
blockno,
|
||||||
|
numblocks,
|
||||||
|
familyid,
|
||||||
|
)
|
||||||
while len(chunk) < 256:
|
while len(chunk) < 256:
|
||||||
chunk += b"\x00"
|
chunk += b"\x00"
|
||||||
block = hd + chunk + datapadding + struct.pack(b"<I", UF2_MAGIC_END)
|
block = hd + chunk + datapadding + struct.pack(b"<I", UF2_MAGIC_END)
|
||||||
@@ -140,6 +156,7 @@ def convert_to_uf2(file_content):
|
|||||||
outp.append(block)
|
outp.append(block)
|
||||||
return b"".join(outp)
|
return b"".join(outp)
|
||||||
|
|
||||||
|
|
||||||
class Block:
|
class Block:
|
||||||
def __init__(self, addr, default_data=0xFF):
|
def __init__(self, addr, default_data=0xFF):
|
||||||
self.addr = addr
|
self.addr = addr
|
||||||
@@ -150,28 +167,37 @@ class Block:
|
|||||||
flags = 0x0
|
flags = 0x0
|
||||||
if familyid:
|
if familyid:
|
||||||
flags |= 0x2000
|
flags |= 0x2000
|
||||||
hd = struct.pack("<IIIIIIII",
|
hd = struct.pack(
|
||||||
UF2_MAGIC_START0, UF2_MAGIC_START1,
|
"<IIIIIIII",
|
||||||
flags, self.addr, 256, blockno, numblocks, familyid)
|
UF2_MAGIC_START0,
|
||||||
|
UF2_MAGIC_START1,
|
||||||
|
flags,
|
||||||
|
self.addr,
|
||||||
|
256,
|
||||||
|
blockno,
|
||||||
|
numblocks,
|
||||||
|
familyid,
|
||||||
|
)
|
||||||
hd += self.bytes[0:256]
|
hd += self.bytes[0:256]
|
||||||
while len(hd) < 512 - 4:
|
while len(hd) < 512 - 4:
|
||||||
hd += b"\x00"
|
hd += b"\x00"
|
||||||
hd += struct.pack("<I", UF2_MAGIC_END)
|
hd += struct.pack("<I", UF2_MAGIC_END)
|
||||||
return hd
|
return hd
|
||||||
|
|
||||||
|
|
||||||
def convert_from_hex_to_uf2(buf):
|
def convert_from_hex_to_uf2(buf):
|
||||||
global appstartaddr
|
global appstartaddr
|
||||||
appstartaddr = None
|
appstartaddr = None
|
||||||
upper = 0
|
upper = 0
|
||||||
currblock = None
|
currblock = None
|
||||||
blocks = []
|
blocks = []
|
||||||
for line in buf.split('\n'):
|
for line in buf.split("\n"):
|
||||||
if line[0] != ":":
|
if line[0] != ":":
|
||||||
continue
|
continue
|
||||||
i = 1
|
i = 1
|
||||||
rec = []
|
rec = []
|
||||||
while i < len(line) - 1:
|
while i < len(line) - 1:
|
||||||
rec.append(int(line[i:i+2], 16))
|
rec.append(int(line[i : i + 2], 16))
|
||||||
i += 2
|
i += 2
|
||||||
tp = rec[3]
|
tp = rec[3]
|
||||||
if tp == 4:
|
if tp == 4:
|
||||||
@@ -186,10 +212,10 @@ def convert_from_hex_to_uf2(buf):
|
|||||||
appstartaddr = addr
|
appstartaddr = addr
|
||||||
i = 4
|
i = 4
|
||||||
while i < len(rec) - 1:
|
while i < len(rec) - 1:
|
||||||
if not currblock or currblock.addr & ~0xff != addr & ~0xff:
|
if not currblock or currblock.addr & ~0xFF != addr & ~0xFF:
|
||||||
currblock = Block(addr & ~0xff)
|
currblock = Block(addr & ~0xFF)
|
||||||
blocks.append(currblock)
|
blocks.append(currblock)
|
||||||
currblock.bytes[addr & 0xff] = rec[i]
|
currblock.bytes[addr & 0xFF] = rec[i]
|
||||||
addr += 1
|
addr += 1
|
||||||
i += 1
|
i += 1
|
||||||
numblocks = len(blocks)
|
numblocks = len(blocks)
|
||||||
@@ -198,17 +224,21 @@ def convert_from_hex_to_uf2(buf):
|
|||||||
resfile += blocks[i].encode(i, numblocks)
|
resfile += blocks[i].encode(i, numblocks)
|
||||||
return resfile
|
return resfile
|
||||||
|
|
||||||
|
|
||||||
def to_str(b):
|
def to_str(b):
|
||||||
return b.decode("utf-8")
|
return b.decode("utf-8")
|
||||||
|
|
||||||
|
|
||||||
def get_drives():
|
def get_drives():
|
||||||
drives = []
|
drives = []
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
r = subprocess.check_output([
|
r = subprocess.check_output(
|
||||||
"powershell",
|
[
|
||||||
"-Command",
|
"powershell",
|
||||||
'(Get-WmiObject Win32_LogicalDisk -Filter "VolumeName=\'RPI-RP2\'").DeviceID'
|
"-Command",
|
||||||
])
|
"(Get-WmiObject Win32_LogicalDisk -Filter \"VolumeName='RPI-RP2'\").DeviceID",
|
||||||
|
]
|
||||||
|
)
|
||||||
drive = to_str(r).strip()
|
drive = to_str(r).strip()
|
||||||
if drive:
|
if drive:
|
||||||
drives.append(drive)
|
drives.append(drive)
|
||||||
@@ -217,7 +247,10 @@ def get_drives():
|
|||||||
if sys.platform == "darwin":
|
if sys.platform == "darwin":
|
||||||
searchpaths = ["/Volumes"]
|
searchpaths = ["/Volumes"]
|
||||||
elif sys.platform == "linux":
|
elif sys.platform == "linux":
|
||||||
searchpaths += ["/media/" + os.environ["USER"], "/run/media/" + os.environ["USER"]]
|
searchpaths += [
|
||||||
|
"/media/" + os.environ["USER"],
|
||||||
|
"/run/media/" + os.environ["USER"],
|
||||||
|
]
|
||||||
if "SUDO_USER" in os.environ.keys():
|
if "SUDO_USER" in os.environ.keys():
|
||||||
searchpaths += ["/media/" + os.environ["SUDO_USER"]]
|
searchpaths += ["/media/" + os.environ["SUDO_USER"]]
|
||||||
searchpaths += ["/run/media/" + os.environ["SUDO_USER"]]
|
searchpaths += ["/run/media/" + os.environ["SUDO_USER"]]
|
||||||
@@ -228,7 +261,6 @@ def get_drives():
|
|||||||
if os.path.isdir(os.path.join(rootpath, d)):
|
if os.path.isdir(os.path.join(rootpath, d)):
|
||||||
drives.append(os.path.join(rootpath, d))
|
drives.append(os.path.join(rootpath, d))
|
||||||
|
|
||||||
|
|
||||||
def has_info(d):
|
def has_info(d):
|
||||||
try:
|
try:
|
||||||
return os.path.isfile(d + INFO_FILE)
|
return os.path.isfile(d + INFO_FILE)
|
||||||
@@ -239,7 +271,7 @@ def get_drives():
|
|||||||
|
|
||||||
|
|
||||||
def board_id(path):
|
def board_id(path):
|
||||||
with open(path + INFO_FILE, mode='r') as file:
|
with open(path + INFO_FILE, mode="r") as file:
|
||||||
file_content = file.read()
|
file_content = file.read()
|
||||||
return re.search(r"Board-ID: ([^\r\n]*)", file_content).group(1)
|
return re.search(r"Board-ID: ([^\r\n]*)", file_content).group(1)
|
||||||
|
|
||||||
@@ -273,34 +305,70 @@ def load_families():
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
global appstartaddr, familyid
|
global appstartaddr, familyid
|
||||||
|
|
||||||
def error(msg):
|
def error(msg):
|
||||||
print(msg, file=sys.stderr)
|
print(msg, file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
parser = argparse.ArgumentParser(description='Convert to UF2 or flash directly.')
|
|
||||||
parser.add_argument('input', metavar='INPUT', type=str, nargs='?',
|
parser = argparse.ArgumentParser(description="Convert to UF2 or flash directly.")
|
||||||
help='input file (HEX, BIN or UF2)')
|
parser.add_argument(
|
||||||
parser.add_argument('-b', '--base', dest='base', type=str,
|
"input",
|
||||||
default="0x2000",
|
metavar="INPUT",
|
||||||
help='set base address of application for BIN format (default: 0x2000)')
|
type=str,
|
||||||
parser.add_argument('-f', '--family', dest='family', type=str,
|
nargs="?",
|
||||||
default="0x0",
|
help="input file (HEX, BIN or UF2)",
|
||||||
help='specify familyID - number or name (default: 0x0)')
|
)
|
||||||
parser.add_argument('-o', '--output', metavar="FILE", dest='output', type=str,
|
parser.add_argument(
|
||||||
help='write output to named file; defaults to "flash.uf2" or "flash.bin" where sensible')
|
"-b",
|
||||||
parser.add_argument('-d', '--device', dest="device_path",
|
"--base",
|
||||||
help='select a device path to flash')
|
dest="base",
|
||||||
parser.add_argument('-l', '--list', action='store_true',
|
type=str,
|
||||||
help='list connected devices')
|
default="0x2000",
|
||||||
parser.add_argument('-c', '--convert', action='store_true',
|
help="set base address of application for BIN format (default: 0x2000)",
|
||||||
help='do not flash, just convert')
|
)
|
||||||
parser.add_argument('-D', '--deploy', action='store_true',
|
parser.add_argument(
|
||||||
help='just flash, do not convert')
|
"-f",
|
||||||
parser.add_argument('-w', '--wait', action='store_true',
|
"--family",
|
||||||
help='wait for device to flash')
|
dest="family",
|
||||||
parser.add_argument('-C', '--carray', action='store_true',
|
type=str,
|
||||||
help='convert binary file to a C array, not UF2')
|
default="0x0",
|
||||||
parser.add_argument('-i', '--info', action='store_true',
|
help="specify familyID - number or name (default: 0x0)",
|
||||||
help='display header information from UF2, do not convert')
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-o",
|
||||||
|
"--output",
|
||||||
|
metavar="FILE",
|
||||||
|
dest="output",
|
||||||
|
type=str,
|
||||||
|
help='write output to named file; defaults to "flash.uf2" or "flash.bin" where sensible',
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-d", "--device", dest="device_path", help="select a device path to flash"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-l", "--list", action="store_true", help="list connected devices"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-c", "--convert", action="store_true", help="do not flash, just convert"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-D", "--deploy", action="store_true", help="just flash, do not convert"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-w", "--wait", action="store_true", help="wait for device to flash"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-C",
|
||||||
|
"--carray",
|
||||||
|
action="store_true",
|
||||||
|
help="convert binary file to a C array, not UF2",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-i",
|
||||||
|
"--info",
|
||||||
|
action="store_true",
|
||||||
|
help="display header information from UF2, do not convert",
|
||||||
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
appstartaddr = int(args.base, 0)
|
appstartaddr = int(args.base, 0)
|
||||||
|
|
||||||
@@ -312,14 +380,17 @@ def main():
|
|||||||
try:
|
try:
|
||||||
familyid = int(args.family, 0)
|
familyid = int(args.family, 0)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
error("Family ID needs to be a number or one of: " + ", ".join(families.keys()))
|
error(
|
||||||
|
"Family ID needs to be a number or one of: "
|
||||||
|
+ ", ".join(families.keys())
|
||||||
|
)
|
||||||
|
|
||||||
if args.list:
|
if args.list:
|
||||||
list_drives()
|
list_drives()
|
||||||
else:
|
else:
|
||||||
if not args.input:
|
if not args.input:
|
||||||
error("Need input file")
|
error("Need input file")
|
||||||
with open(args.input, mode='rb') as f:
|
with open(args.input, mode="rb") as f:
|
||||||
inpbuf = f.read()
|
inpbuf = f.read()
|
||||||
from_uf2 = is_uf2(inpbuf)
|
from_uf2 = is_uf2(inpbuf)
|
||||||
ext = "uf2"
|
ext = "uf2"
|
||||||
@@ -339,8 +410,10 @@ def main():
|
|||||||
else:
|
else:
|
||||||
outbuf = convert_to_uf2(inpbuf)
|
outbuf = convert_to_uf2(inpbuf)
|
||||||
if not args.deploy and not args.info:
|
if not args.deploy and not args.info:
|
||||||
print("Converted to %s, output size: %d, start address: 0x%x" %
|
print(
|
||||||
(ext, len(outbuf), appstartaddr))
|
"Converted to %s, output size: %d, start address: 0x%x"
|
||||||
|
% (ext, len(outbuf), appstartaddr)
|
||||||
|
)
|
||||||
if args.convert or ext != "uf2":
|
if args.convert or ext != "uf2":
|
||||||
if args.output == None:
|
if args.output == None:
|
||||||
args.output = "flash." + ext
|
args.output = "flash." + ext
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file vector_table.c
|
|
||||||
* @brief Vector table with initial stack pointer and reset handler
|
|
||||||
* @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 <stdint.h>
|
|
||||||
|
|
||||||
extern uint32_t _stack_top;
|
|
||||||
extern void Reset_Handler(void);
|
|
||||||
|
|
||||||
typedef void (*vector_func_t)(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Vector table placed in .vectors section.
|
|
||||||
* The Thumb bit (bit 0 = 1) is automatically set by the linker
|
|
||||||
* for function pointers in Thumb mode.
|
|
||||||
*/
|
|
||||||
__attribute__((section(".vectors"), used))
|
|
||||||
const void *_vectors[2] = {
|
|
||||||
&_stack_top,
|
|
||||||
Reset_Handler
|
|
||||||
};
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file xosc.c
|
|
||||||
* @brief External crystal oscillator (XOSC) initialization and clock enable
|
|
||||||
* @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 "xosc.h"
|
|
||||||
#include "constants.h"
|
|
||||||
|
|
||||||
void Init_XOSC(void) {
|
|
||||||
// set delay 50,000 cycles
|
|
||||||
XOSC->STARTUP = 0x00C4U;
|
|
||||||
// set 1_15MHz, freq range, actual 14.5MHz
|
|
||||||
XOSC->CTRL = 0x00FABAA0U;
|
|
||||||
// wait until stable bit is set
|
|
||||||
while ((XOSC->STATUS & (1U << XOSC_STATUS_STABLE_SHIFT)) == 0) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Enable_XOSC_Peri_Clock(void) {
|
|
||||||
uint32_t value;
|
|
||||||
|
|
||||||
// read CLK_PERI_CTRL value
|
|
||||||
value = CLOCKS->CLK_PERI_CTRL;
|
|
||||||
// set ENABLE bit
|
|
||||||
value |= (1U << CLOCKS_CLK_PERI_CTRL_ENABLE_SHIFT);
|
|
||||||
// set AUXSRC: XOSC_CLKSRC
|
|
||||||
value |= (CLOCKS_CLK_PERI_CTRL_AUXSRC_XOSC << CLOCKS_CLK_PERI_CTRL_AUXSRC_SHIFT);
|
|
||||||
// store value into CLK_PERI_CTRL
|
|
||||||
CLOCKS->CLK_PERI_CTRL = value;
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file xosc.h
|
|
||||||
* @brief External crystal oscillator (XOSC) initialization and clock enable
|
|
||||||
* @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 XOSC_H
|
|
||||||
#define XOSC_H
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize the external crystal oscillator and wait until stable
|
|
||||||
*
|
|
||||||
* Configures the XOSC startup delay and frequency range, then polls
|
|
||||||
* the status register until the STABLE bit is set.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void Init_XOSC(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enable the XOSC peripheral clock
|
|
||||||
*
|
|
||||||
* Sets the peripheral clock to use XOSC as its auxiliary source and
|
|
||||||
* enables it via CLK_PERI_CTRL.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void Enable_XOSC_Peri_Clock(void);
|
|
||||||
|
|
||||||
#endif // XOSC_H
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
# C files
|
|
||||||
*.c linguist-language=C
|
|
||||||
|
|
||||||
# Exclude from language statistics
|
|
||||||
*.ld linguist-vendored
|
|
||||||
*.bat linguist-vendored
|
|
||||||
*.py linguist-vendored
|
|
||||||
linker.ld linguist-vendored
|
|
||||||
build.bat linguist-vendored
|
|
||||||
clean.bat linguist-vendored
|
|
||||||
uf2conv.py linguist-vendored
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
# Build artifacts
|
|
||||||
*.o
|
|
||||||
*.elf
|
|
||||||
*.bin
|
|
||||||
*.uf2
|
|
||||||
compile_commands.json
|
|
||||||
|
|
||||||
# OS files
|
|
||||||
.DS_Store
|
|
||||||
Thumbs.db
|
|
||||||
+21
-1
@@ -3,7 +3,27 @@
|
|||||||
{
|
{
|
||||||
"name": "ARM GCC",
|
"name": "ARM GCC",
|
||||||
"includePath": [
|
"includePath": [
|
||||||
"${workspaceFolder}/**"
|
"${workspaceFolder}/Inc/**"
|
||||||
|
],
|
||||||
|
"defines": [
|
||||||
|
"__GNUC__",
|
||||||
|
"__ARM_ARCH_8M_MAIN__",
|
||||||
|
"__ARMCC_VERSION"
|
||||||
|
],
|
||||||
|
"compilerPath": "${userHome}/.pico-sdk/toolchain/14_2_Rel1/bin/arm-none-eabi-gcc",
|
||||||
|
"compileCommands": "${workspaceFolder}/compile_commands.json",
|
||||||
|
"cStandard": "c11",
|
||||||
|
"cppStandard": "c++17",
|
||||||
|
"intelliSenseMode": "gcc-arm",
|
||||||
|
"compilerArgs": [
|
||||||
|
"-mcpu=cortex-m33",
|
||||||
|
"-mthumb"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ARM GCC (Windows)",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/Inc/**"
|
||||||
],
|
],
|
||||||
"defines": [
|
"defines": [
|
||||||
"__GNUC__",
|
"__GNUC__",
|
||||||
|
|||||||
+16
-6
@@ -4,19 +4,21 @@
|
|||||||
{
|
{
|
||||||
"name": "Debug RP2350 (OpenOCD)",
|
"name": "Debug RP2350 (OpenOCD)",
|
||||||
"cwd": "${workspaceFolder}",
|
"cwd": "${workspaceFolder}",
|
||||||
"executable": "${workspaceFolder}/blink.elf",
|
"executable": "${workspaceFolder}/build/blink.elf",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"type": "cortex-debug",
|
"type": "cortex-debug",
|
||||||
"servertype": "openocd",
|
"servertype": "openocd",
|
||||||
"serverpath": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
|
"serverpath": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd",
|
||||||
"searchDir": ["${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/scripts"],
|
"searchDir": [
|
||||||
"gdbPath": "${env:USERPROFILE}/.pico-sdk/toolchain/14_2_Rel1/bin/arm-none-eabi-gdb.exe",
|
"${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts"
|
||||||
|
],
|
||||||
|
"gdbPath": "${userHome}/.pico-sdk/toolchain/14_2_Rel1/bin/arm-none-eabi-gdb",
|
||||||
"device": "RP2350",
|
"device": "RP2350",
|
||||||
"configFiles": [
|
"configFiles": [
|
||||||
"interface/cmsis-dap.cfg",
|
"interface/cmsis-dap.cfg",
|
||||||
"target/rp2350.cfg"
|
"target/rp2350.cfg"
|
||||||
],
|
],
|
||||||
"svdFile": "${env:USERPROFILE}/.pico-sdk/sdk/2.2.0/src/rp2350/hardware_regs/RP2350.svd",
|
"svdFile": "${userHome}/.pico-sdk/sdk/2.2.0/src/rp2350/hardware_regs/RP2350.svd",
|
||||||
"overrideLaunchCommands": [
|
"overrideLaunchCommands": [
|
||||||
"set arch armv8-m.main",
|
"set arch armv8-m.main",
|
||||||
"set output-radix 16",
|
"set output-radix 16",
|
||||||
@@ -31,7 +33,15 @@
|
|||||||
"adapter speed 5000"
|
"adapter speed 5000"
|
||||||
],
|
],
|
||||||
"preLaunchTask": "Compile Project",
|
"preLaunchTask": "Compile Project",
|
||||||
"showDevDebugOutput": "raw"
|
"showDevDebugOutput": "raw",
|
||||||
|
"windows": {
|
||||||
|
"serverpath": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
|
||||||
|
"searchDir": [
|
||||||
|
"${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/scripts"
|
||||||
|
],
|
||||||
|
"gdbPath": "${env:USERPROFILE}/.pico-sdk/toolchain/14_2_Rel1/bin/arm-none-eabi-gdb.exe",
|
||||||
|
"svdFile": "${env:USERPROFILE}/.pico-sdk/sdk/2.2.0/src/rp2350/hardware_regs/RP2350.svd"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
+34
-13
@@ -4,7 +4,7 @@
|
|||||||
{
|
{
|
||||||
"label": "Compile Project",
|
"label": "Compile Project",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": ".\\build.bat",
|
"command": "make",
|
||||||
"group": {
|
"group": {
|
||||||
"kind": "build",
|
"kind": "build",
|
||||||
"isDefault": true
|
"isDefault": true
|
||||||
@@ -13,26 +13,32 @@
|
|||||||
"reveal": "always",
|
"reveal": "always",
|
||||||
"panel": "dedicated"
|
"panel": "dedicated"
|
||||||
},
|
},
|
||||||
"problemMatcher": "$gcc"
|
"problemMatcher": "$gcc",
|
||||||
|
"windows": {
|
||||||
|
"command": ".\\build.bat"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Clean Project",
|
"label": "Clean Project",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": ".\\clean.bat",
|
"command": "make clean",
|
||||||
"group": "build",
|
"group": "build",
|
||||||
"presentation": {
|
"presentation": {
|
||||||
"reveal": "always",
|
"reveal": "always",
|
||||||
"panel": "dedicated"
|
"panel": "dedicated"
|
||||||
},
|
},
|
||||||
"problemMatcher": []
|
"problemMatcher": [],
|
||||||
|
"windows": {
|
||||||
|
"command": ".\\clean.bat"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Run Project",
|
"label": "Run Project",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "${env:USERPROFILE}/.pico-sdk/picotool/2.2.0-a4/picotool/picotool.exe",
|
"command": "${userHome}/.pico-sdk/picotool/2.2.0-a4/picotool/picotool",
|
||||||
"args": [
|
"args": [
|
||||||
"load",
|
"load",
|
||||||
"blink.uf2",
|
"build/blink.uf2",
|
||||||
"-fx"
|
"-fx"
|
||||||
],
|
],
|
||||||
"presentation": {
|
"presentation": {
|
||||||
@@ -40,29 +46,39 @@
|
|||||||
"panel": "dedicated"
|
"panel": "dedicated"
|
||||||
},
|
},
|
||||||
"problemMatcher": [],
|
"problemMatcher": [],
|
||||||
"dependsOn": ["Compile Project"]
|
"dependsOn": [
|
||||||
|
"Compile Project"
|
||||||
|
],
|
||||||
|
"windows": {
|
||||||
|
"command": "${env:USERPROFILE}/.pico-sdk/picotool/2.2.0-a4/picotool/picotool.exe"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Flash",
|
"label": "Flash",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
|
"command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd",
|
||||||
"args": [
|
"args": [
|
||||||
"-s",
|
"-s",
|
||||||
"${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/scripts",
|
"${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts",
|
||||||
"-f",
|
"-f",
|
||||||
"interface/cmsis-dap.cfg",
|
"interface/cmsis-dap.cfg",
|
||||||
"-f",
|
"-f",
|
||||||
"target/rp2350.cfg",
|
"target/rp2350.cfg",
|
||||||
"-c",
|
"-c",
|
||||||
"adapter speed 5000; program blink.elf verify reset exit"
|
"adapter speed 5000; program build/blink.elf verify reset exit"
|
||||||
],
|
],
|
||||||
"problemMatcher": [],
|
"problemMatcher": [],
|
||||||
"dependsOn": ["Compile Project"]
|
"dependsOn": [
|
||||||
|
"Compile Project"
|
||||||
|
],
|
||||||
|
"windows": {
|
||||||
|
"command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Rescue Reset",
|
"label": "Rescue Reset",
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
|
"command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd",
|
||||||
"args": [
|
"args": [
|
||||||
"-s",
|
"-s",
|
||||||
"${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts",
|
"${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts",
|
||||||
@@ -81,7 +97,7 @@
|
|||||||
{
|
{
|
||||||
"label": "RISC-V Reset (RP2350)",
|
"label": "RISC-V Reset (RP2350)",
|
||||||
"type": "process",
|
"type": "process",
|
||||||
"command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
|
"command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd",
|
||||||
"args": [
|
"args": [
|
||||||
"-s",
|
"-s",
|
||||||
"${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts",
|
"${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts",
|
||||||
@@ -105,3 +121,8 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"problemMatcher": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,194 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350.h
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief RP2350 Device Peripheral Access Layer Header File.
|
||||||
|
*
|
||||||
|
* 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).
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RP2350_H
|
||||||
|
#define __RP2350_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/*!< Defines 'read / write' permissions */
|
||||||
|
#define __IO volatile
|
||||||
|
|
||||||
|
/*!< Stack addresses */
|
||||||
|
#define STACK_TOP 0x20082000UL
|
||||||
|
#define STACK_LIMIT 0x2007A000UL
|
||||||
|
|
||||||
|
/*!< Memory map */
|
||||||
|
#define XIP_BASE 0x10000000UL
|
||||||
|
#define SRAM_BASE 0x20000000UL
|
||||||
|
#define SIO_BASE 0xD0000000UL
|
||||||
|
#define PPB_BASE 0xE0000000UL
|
||||||
|
|
||||||
|
/*!< APB peripherals */
|
||||||
|
#define CLOCKS_BASE 0x40010000UL
|
||||||
|
#define RESETS_BASE 0x40020000UL
|
||||||
|
#define IO_BANK0_BASE 0x40028000UL
|
||||||
|
#define PADS_BANK0_BASE 0x40038000UL
|
||||||
|
#define XOSC_BASE 0x40048000UL
|
||||||
|
#define UART0_BASE 0x40070000UL
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XOSC (External Crystal Oscillator)
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IO uint32_t CTRL; // Control register Address offset: 0x00
|
||||||
|
__IO uint32_t STATUS; // Status register Address offset: 0x04
|
||||||
|
__IO uint32_t DORMANT; // Dormant mode Address offset: 0x08
|
||||||
|
__IO uint32_t STARTUP; // Startup delay Address offset: 0x0C
|
||||||
|
__IO uint32_t COUNT; // Frequency count Address offset: 0x10
|
||||||
|
} XOSC_TypeDef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CLOCKS
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IO uint32_t RESERVED0[18]; // Other clock registers Address offset: 0x00-0x44
|
||||||
|
__IO uint32_t CLK_PERI_CTRL; // Peripheral clock control Address offset: 0x48
|
||||||
|
} CLOCKS_TypeDef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief RESETS
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IO uint32_t RESET; // Reset control Address offset: 0x00
|
||||||
|
__IO uint32_t WDSEL; // Watchdog select Address offset: 0x04
|
||||||
|
__IO uint32_t RESET_DONE; // Reset done status Address offset: 0x08
|
||||||
|
} RESETS_TypeDef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief IO_BANK0 GPIO Control (one per GPIO)
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IO uint32_t STATUS; // GPIO status Address offset: 0x00
|
||||||
|
__IO uint32_t CTRL; // GPIO control Address offset: 0x04
|
||||||
|
} IO_BANK0_GPIO_TypeDef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief IO_BANK0
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
IO_BANK0_GPIO_TypeDef GPIO[30]; // GPIO 0-29 status/ctrl pairs Address offset: 0x000-0x0E8
|
||||||
|
} IO_BANK0_TypeDef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PADS_BANK0
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IO uint32_t VOLTAGE_SELECT; // Voltage select Address offset: 0x00
|
||||||
|
__IO uint32_t GPIO[30]; // GPIO 0-29 pad control Address offset: 0x04-0x78
|
||||||
|
} PADS_BANK0_TypeDef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Peripheral Definitions
|
||||||
|
*/
|
||||||
|
#define XOSC ((XOSC_TypeDef *) XOSC_BASE)
|
||||||
|
#define CLOCKS ((CLOCKS_TypeDef *) CLOCKS_BASE)
|
||||||
|
#define RESETS ((RESETS_TypeDef *) RESETS_BASE)
|
||||||
|
#define IO_BANK0 ((IO_BANK0_TypeDef *) IO_BANK0_BASE)
|
||||||
|
#define PADS_BANK0 ((PADS_BANK0_TypeDef *) PADS_BANK0_BASE)
|
||||||
|
#define SIO ((volatile uint32_t *) SIO_BASE)
|
||||||
|
#define CPACR ((volatile uint32_t *) (PPB_BASE + 0x0ED88UL))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief XOSC bit definitions
|
||||||
|
*/
|
||||||
|
#define XOSC_STATUS_STABLE_SHIFT 31U
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CPACR bit definitions
|
||||||
|
*/
|
||||||
|
#define CPACR_CP0_SHIFT 0U
|
||||||
|
#define CPACR_CP1_SHIFT 1U
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CLOCKS bit definitions
|
||||||
|
*/
|
||||||
|
#define CLK_PERI_CTRL_ENABLE_SHIFT 11U
|
||||||
|
#define CLK_PERI_CTRL_AUXSRC_SHIFT 5U
|
||||||
|
#define CLK_PERI_CTRL_AUXSRC_XOSC 4U
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief RESETS bit definitions
|
||||||
|
*/
|
||||||
|
#define RESETS_RESET_IO_BANK0_SHIFT 6U
|
||||||
|
#define RESETS_RESET_UART0_SHIFT 26U
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief IO_BANK0 bit definitions
|
||||||
|
*/
|
||||||
|
#define IO_BANK0_CTRL_FUNCSEL_MASK 0x1FU
|
||||||
|
#define IO_BANK0_CTRL_FUNCSEL_UART 0x02U
|
||||||
|
#define IO_BANK0_CTRL_FUNCSEL_SIO 0x05U
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief PADS_BANK0 bit definitions
|
||||||
|
*/
|
||||||
|
#define PADS_BANK0_OD_SHIFT 7U
|
||||||
|
#define PADS_BANK0_IE_SHIFT 6U
|
||||||
|
#define PADS_BANK0_ISO_SHIFT 8U
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief UART register offsets (word indices from UART0_BASE)
|
||||||
|
*/
|
||||||
|
#define UART_DR_OFFSET (0x000U / 4U)
|
||||||
|
#define UART_FR_OFFSET (0x018U / 4U)
|
||||||
|
#define UART_IBRD_OFFSET (0x024U / 4U)
|
||||||
|
#define UART_FBRD_OFFSET (0x028U / 4U)
|
||||||
|
#define UART_LCR_H_OFFSET (0x02CU / 4U)
|
||||||
|
#define UART_CR_OFFSET (0x030U / 4U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief UART flag register bit definitions
|
||||||
|
*/
|
||||||
|
#define UART_FR_TXFF_MASK 32U
|
||||||
|
#define UART_FR_RXFE_MASK 16U
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief UART line control and enable values
|
||||||
|
*/
|
||||||
|
#define UART_LCR_H_8N1_FIFO 0x70U
|
||||||
|
#define UART_CR_ENABLE ((3U << 8) | 1U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief GPIO pin definitions
|
||||||
|
*/
|
||||||
|
#define LED_PIN 25U
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SIO GPIO register offsets (word indices from SIO_BASE)
|
||||||
|
*/
|
||||||
|
#define SIO_GPIO_IN_OFFSET (0x004U / 4U)
|
||||||
|
#define SIO_GPIO_OUT_SET_OFFSET (0x018U / 4U)
|
||||||
|
#define SIO_GPIO_OUT_CLR_OFFSET (0x020U / 4U)
|
||||||
|
#define SIO_GPIO_OUT_XOR_OFFSET (0x028U / 4U)
|
||||||
|
#define SIO_GPIO_OE_SET_OFFSET (0x038U / 4U)
|
||||||
|
|
||||||
|
#endif /* __RP2350_H */
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_coprocessor.h
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief Coprocessor access control driver header for RP2350.
|
||||||
|
*
|
||||||
|
* Enables coprocessor access via the CPACR register.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RP2350_COPROCESSOR_H
|
||||||
|
#define __RP2350_COPROCESSOR_H
|
||||||
|
|
||||||
|
#include "rp2350.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable coprocessor access via CPACR with DSB/ISB barriers.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void coprocessor_enable(void);
|
||||||
|
|
||||||
|
#endif /* __RP2350_COPROCESSOR_H */
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_delay.h
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief Delay driver header for RP2350.
|
||||||
|
*
|
||||||
|
* Millisecond busy-wait delay calibrated for a 14.5 MHz clock.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RP2350_DELAY_H
|
||||||
|
#define __RP2350_DELAY_H
|
||||||
|
|
||||||
|
#include "rp2350.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Delay for the specified number of milliseconds.
|
||||||
|
* @param ms number of milliseconds to delay
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void delay_ms(uint32_t ms);
|
||||||
|
|
||||||
|
#endif /* __RP2350_DELAY_H */
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_gpio.h
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief GPIO driver header for RP2350.
|
||||||
|
*
|
||||||
|
* SIO-based GPIO configuration, set, clear, toggle, and read
|
||||||
|
* functions for the RP2350 GPIO pins 0-29.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RP2350_GPIO_H
|
||||||
|
#define __RP2350_GPIO_H
|
||||||
|
|
||||||
|
#include "rp2350.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configure a GPIO pin as SIO output.
|
||||||
|
* @param gpio_num GPIO pin number (0-29)
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void gpio_config(uint32_t gpio_num);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Drive a GPIO output high.
|
||||||
|
* @param gpio_num GPIO pin number (0-29)
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void gpio_set(uint32_t gpio_num);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Drive a GPIO output low.
|
||||||
|
* @param gpio_num GPIO pin number (0-29)
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void gpio_clear(uint32_t gpio_num);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Toggle a GPIO output.
|
||||||
|
* @param gpio_num GPIO pin number (0-29)
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void gpio_toggle(uint32_t gpio_num);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read the current input level of a GPIO pin.
|
||||||
|
* @param gpio_num GPIO pin number (0-29)
|
||||||
|
* @retval bool true if pin is high, false if low
|
||||||
|
*/
|
||||||
|
bool gpio_get(uint32_t gpio_num);
|
||||||
|
|
||||||
|
#endif /* __RP2350_GPIO_H */
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_led.h
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief LED driver header for RP2350.
|
||||||
|
*
|
||||||
|
* High-level GPIO output / LED driver wrapping the
|
||||||
|
* low-level GPIO functions.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RP2350_LED_H
|
||||||
|
#define __RP2350_LED_H
|
||||||
|
|
||||||
|
#include "rp2350.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize a GPIO pin as a push-pull digital output.
|
||||||
|
* @param pin GPIO pin number to configure
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void led_init(uint32_t pin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Drive the output pin high (LED on).
|
||||||
|
* @param pin GPIO pin number
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void led_on(uint32_t pin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Drive the output pin low (LED off).
|
||||||
|
* @param pin GPIO pin number
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void led_off(uint32_t pin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Toggle the current state of the output pin.
|
||||||
|
* @param pin GPIO pin number
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void led_toggle(uint32_t pin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Query the current drive state of the output pin.
|
||||||
|
* @param pin GPIO pin number
|
||||||
|
* @retval bool true if the pin is driven high, false if low
|
||||||
|
*/
|
||||||
|
bool led_get_state(uint32_t pin);
|
||||||
|
|
||||||
|
#endif /* __RP2350_LED_H */
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_reset.h
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief Reset controller driver header for RP2350.
|
||||||
|
*
|
||||||
|
* Provides subsystem reset release for IO_BANK0.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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,33 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_reset_handler.h
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief Reset handler header for RP2350.
|
||||||
|
*
|
||||||
|
* Entry point after reset. Performs stack initialization, XOSC
|
||||||
|
* setup, subsystem reset release, UART initialization,
|
||||||
|
* coprocessor enable, and branches to main().
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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 */
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_stack.h
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief Stack pointer initialization header for RP2350.
|
||||||
|
*
|
||||||
|
* Sets MSP, PSP, MSPLIM, and PSPLIM from the STACK_TOP and
|
||||||
|
* STACK_LIMIT values defined in rp2350.h.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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 */
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_uart.h
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief UART0 driver header for RP2350.
|
||||||
|
*
|
||||||
|
* Bare-metal UART0 driver supporting TX/RX on GPIO 0/1 at
|
||||||
|
* 115200 baud (14.5 MHz XOSC clock).
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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 */
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_xosc.h
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief XOSC driver header for RP2350.
|
||||||
|
*
|
||||||
|
* External crystal oscillator initialization and peripheral
|
||||||
|
* clock enable using the XOSC registers.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RP2350_XOSC_H
|
||||||
|
#define __RP2350_XOSC_H
|
||||||
|
|
||||||
|
#include "rp2350.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the external crystal oscillator and wait until stable.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void xosc_init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the XOSC peripheral clock via CLK_PERI_CTRL.
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
void xosc_enable_peri_clk(void);
|
||||||
|
|
||||||
|
#endif /* __RP2350_XOSC_H */
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# @file Makefile
|
||||||
|
# @author Kevin Thomas
|
||||||
|
# @brief Build script for RP2350 bare-metal C blink driver.
|
||||||
|
#
|
||||||
|
# Compiles, links, and generates UF2 firmware for the RP2350.
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Toolchain
|
||||||
|
CC = arm-none-eabi-gcc
|
||||||
|
OBJCOPY = arm-none-eabi-objcopy
|
||||||
|
SIZE = arm-none-eabi-size
|
||||||
|
|
||||||
|
# Target
|
||||||
|
TARGET = blink
|
||||||
|
|
||||||
|
# Directories
|
||||||
|
SRC_DIR = Src
|
||||||
|
INC_DIR = Inc
|
||||||
|
BUILD_DIR = build
|
||||||
|
|
||||||
|
# CPU flags
|
||||||
|
CPU_FLAGS = -mcpu=cortex-m33 -mthumb
|
||||||
|
|
||||||
|
# Compiler flags
|
||||||
|
CFLAGS = $(CPU_FLAGS) -Og -g3 -Wall -Wextra \
|
||||||
|
-ffunction-sections -fdata-sections \
|
||||||
|
-I$(INC_DIR)
|
||||||
|
|
||||||
|
# Linker flags
|
||||||
|
LDFLAGS = $(CPU_FLAGS) -T linker.ld -nostdlib -Wl,--gc-sections
|
||||||
|
|
||||||
|
# Source files
|
||||||
|
SRCS = $(SRC_DIR)/vector_table.c \
|
||||||
|
$(SRC_DIR)/rp2350_reset_handler.c \
|
||||||
|
$(SRC_DIR)/rp2350_stack.c \
|
||||||
|
$(SRC_DIR)/rp2350_xosc.c \
|
||||||
|
$(SRC_DIR)/rp2350_reset.c \
|
||||||
|
$(SRC_DIR)/rp2350_coprocessor.c \
|
||||||
|
$(SRC_DIR)/rp2350_uart.c \
|
||||||
|
$(SRC_DIR)/rp2350_gpio.c \
|
||||||
|
$(SRC_DIR)/rp2350_led.c \
|
||||||
|
$(SRC_DIR)/rp2350_delay.c \
|
||||||
|
$(SRC_DIR)/main.c \
|
||||||
|
$(SRC_DIR)/image_def.c
|
||||||
|
|
||||||
|
# Object files
|
||||||
|
OBJS = $(patsubst $(SRC_DIR)/%.c,$(BUILD_DIR)/%.o,$(SRCS))
|
||||||
|
|
||||||
|
# Rules
|
||||||
|
.PHONY: all clean flash
|
||||||
|
|
||||||
|
all: $(BUILD_DIR)/$(TARGET).uf2
|
||||||
|
@echo "==================================="
|
||||||
|
@echo "SUCCESS! Created $(TARGET).bin and $(TARGET).uf2"
|
||||||
|
@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)/$(TARGET).uf2: $(BUILD_DIR)/$(TARGET).bin
|
||||||
|
python3 uf2conv.py -b 0x10000000 -f 0xe48bff59 -o $@ $<
|
||||||
|
|
||||||
|
$(BUILD_DIR):
|
||||||
|
mkdir -p $(BUILD_DIR)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(BUILD_DIR)
|
||||||
|
|
||||||
|
flash: $(BUILD_DIR)/$(TARGET).elf
|
||||||
|
openocd -f interface/cmsis-dap.cfg -f target/rp2350.cfg \
|
||||||
|
-c "adapter speed 5000" \
|
||||||
|
-c "program $< verify reset exit"
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file image_def.c
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief RP2350 IMAGE_DEF block for boot ROM image recognition.
|
||||||
|
*
|
||||||
|
* Must appear within the first 4 KB of flash for the boot ROM
|
||||||
|
* to accept the image.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief IMAGE_DEF block structure placed in flash
|
||||||
|
*/
|
||||||
|
__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
|
||||||
|
};
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file main.c
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief Blink demonstration: toggle onboard LED every 500 ms.
|
||||||
|
*
|
||||||
|
* Demonstrates GPIO output control using the blink driver.
|
||||||
|
* The onboard LED on GPIO 25 is toggled every 500 ms and the
|
||||||
|
* current state is reported over UART.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rp2350_led.h"
|
||||||
|
#include "rp2350_uart.h"
|
||||||
|
#include "rp2350_delay.h"
|
||||||
|
|
||||||
|
#define BLINK_DELAY_MS 500
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Print the current LED state over UART.
|
||||||
|
* @param pin GPIO pin number to query
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
static void _print_led_state(uint32_t pin)
|
||||||
|
{
|
||||||
|
if (led_get_state(pin))
|
||||||
|
uart_puts("LED: ON\r\n");
|
||||||
|
else
|
||||||
|
uart_puts("LED: OFF\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Application entry point for the LED blink demo.
|
||||||
|
* @retval int does not return
|
||||||
|
*/
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
led_init(LED_PIN);
|
||||||
|
uart_puts("LED driver initialized on GPIO 25\r\n");
|
||||||
|
while (1) {
|
||||||
|
led_toggle(LED_PIN);
|
||||||
|
_print_led_state(LED_PIN);
|
||||||
|
delay_ms(BLINK_DELAY_MS);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_coprocessor.c
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief Coprocessor access control driver implementation for RP2350.
|
||||||
|
*
|
||||||
|
* Grants access to coprocessors 0 and 1 by setting the
|
||||||
|
* corresponding bits in CPACR with DSB/ISB barriers.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rp2350_coprocessor.h"
|
||||||
|
|
||||||
|
void coprocessor_enable(void)
|
||||||
|
{
|
||||||
|
uint32_t value;
|
||||||
|
value = *CPACR;
|
||||||
|
value |= (1U << CPACR_CP1_SHIFT);
|
||||||
|
value |= (1U << CPACR_CP0_SHIFT);
|
||||||
|
*CPACR = value;
|
||||||
|
__asm__ volatile ("dsb");
|
||||||
|
__asm__ volatile ("isb");
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_delay.c
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief Delay driver implementation for RP2350.
|
||||||
|
*
|
||||||
|
* Busy-wait millisecond delay calibrated for a 14.5 MHz clock
|
||||||
|
* (3600 loop iterations per millisecond).
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rp2350_delay.h"
|
||||||
|
|
||||||
|
void delay_ms(uint32_t ms)
|
||||||
|
{
|
||||||
|
if (ms == 0)
|
||||||
|
return;
|
||||||
|
__asm__ volatile (
|
||||||
|
"mov r4, #3600\n\t"
|
||||||
|
"mul r5, %0, r4\n\t"
|
||||||
|
"1:\n\t"
|
||||||
|
"subs r5, #1\n\t"
|
||||||
|
"bne 1b\n\t"
|
||||||
|
:
|
||||||
|
: "r" (ms)
|
||||||
|
: "r4", "r5", "cc"
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_gpio.c
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief GPIO driver implementation for RP2350.
|
||||||
|
*
|
||||||
|
* SIO-based GPIO configuration using IO_BANK0 and PADS_BANK0
|
||||||
|
* register structs defined in rp2350.h. All register offsets
|
||||||
|
* verified against the RP2350 datasheet (RP-008373-DS-2).
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rp2350_gpio.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configure pad control for a GPIO pin.
|
||||||
|
* @param gpio_num GPIO pin number (0-29)
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
static void _gpio_config_pad(uint32_t gpio_num)
|
||||||
|
{
|
||||||
|
uint32_t value;
|
||||||
|
value = PADS_BANK0->GPIO[gpio_num];
|
||||||
|
value &= ~(1U << PADS_BANK0_OD_SHIFT);
|
||||||
|
value |= (1U << PADS_BANK0_IE_SHIFT);
|
||||||
|
value &= ~(1U << PADS_BANK0_ISO_SHIFT);
|
||||||
|
PADS_BANK0->GPIO[gpio_num] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set IO_BANK0 FUNCSEL to SIO for a GPIO pin.
|
||||||
|
* @param gpio_num GPIO pin number (0-29)
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
static void _gpio_config_funcsel(uint32_t gpio_num)
|
||||||
|
{
|
||||||
|
uint32_t value;
|
||||||
|
value = IO_BANK0->GPIO[gpio_num].CTRL;
|
||||||
|
value &= ~IO_BANK0_CTRL_FUNCSEL_MASK;
|
||||||
|
value |= IO_BANK0_CTRL_FUNCSEL_SIO;
|
||||||
|
IO_BANK0->GPIO[gpio_num].CTRL = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the output driver for a GPIO pin via SIO.
|
||||||
|
* @param gpio_num GPIO pin number (0-29)
|
||||||
|
* @retval None
|
||||||
|
*/
|
||||||
|
static void _gpio_enable_output(uint32_t gpio_num)
|
||||||
|
{
|
||||||
|
SIO[SIO_GPIO_OE_SET_OFFSET] = (1U << gpio_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gpio_config(uint32_t gpio_num)
|
||||||
|
{
|
||||||
|
_gpio_config_pad(gpio_num);
|
||||||
|
_gpio_config_funcsel(gpio_num);
|
||||||
|
_gpio_enable_output(gpio_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gpio_set(uint32_t gpio_num)
|
||||||
|
{
|
||||||
|
SIO[SIO_GPIO_OUT_SET_OFFSET] = (1U << gpio_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gpio_clear(uint32_t gpio_num)
|
||||||
|
{
|
||||||
|
SIO[SIO_GPIO_OUT_CLR_OFFSET] = (1U << gpio_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gpio_toggle(uint32_t gpio_num)
|
||||||
|
{
|
||||||
|
SIO[SIO_GPIO_OUT_XOR_OFFSET] = (1U << gpio_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool gpio_get(uint32_t gpio_num)
|
||||||
|
{
|
||||||
|
return (SIO[SIO_GPIO_IN_OFFSET] & (1U << gpio_num)) != 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_led.c
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief LED driver implementation for RP2350.
|
||||||
|
*
|
||||||
|
* High-level wrapper around the GPIO driver for LED control.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rp2350_led.h"
|
||||||
|
#include "rp2350_gpio.h"
|
||||||
|
|
||||||
|
void led_init(uint32_t pin)
|
||||||
|
{
|
||||||
|
gpio_config(pin);
|
||||||
|
gpio_clear(pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void led_on(uint32_t pin)
|
||||||
|
{
|
||||||
|
gpio_set(pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void led_off(uint32_t pin)
|
||||||
|
{
|
||||||
|
gpio_clear(pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void led_toggle(uint32_t pin)
|
||||||
|
{
|
||||||
|
gpio_toggle(pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool led_get_state(uint32_t pin)
|
||||||
|
{
|
||||||
|
return gpio_get(pin);
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_reset.c
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief Reset controller driver implementation for RP2350.
|
||||||
|
*
|
||||||
|
* Releases IO_BANK0 from reset and waits until the subsystem
|
||||||
|
* is ready.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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,45 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_reset_handler.c
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief Reset handler implementation for RP2350.
|
||||||
|
*
|
||||||
|
* Entry point after power-on or system reset. Initializes the
|
||||||
|
* stack, XOSC, subsystem resets, UART, coprocessor, then
|
||||||
|
* branches to main().
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rp2350_reset_handler.h"
|
||||||
|
#include "rp2350_stack.h"
|
||||||
|
#include "rp2350_xosc.h"
|
||||||
|
#include "rp2350_reset.h"
|
||||||
|
#include "rp2350_uart.h"
|
||||||
|
#include "rp2350_coprocessor.h"
|
||||||
|
|
||||||
|
extern int main(void);
|
||||||
|
|
||||||
|
void __attribute__((naked, noreturn)) Reset_Handler(void)
|
||||||
|
{
|
||||||
|
__asm__ volatile (
|
||||||
|
"bl stack_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"
|
||||||
|
"bl coprocessor_enable\n\t"
|
||||||
|
"b main\n\t"
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_stack.c
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief Stack pointer initialization for RP2350.
|
||||||
|
*
|
||||||
|
* Sets MSP, PSP, MSPLIM, and PSPLIM using inline assembly.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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"
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_uart.c
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief UART0 driver implementation for RP2350.
|
||||||
|
*
|
||||||
|
* Configures UART0 on GPIO 0 (TX) and GPIO 1 (RX) at 115200
|
||||||
|
* baud using the 14.5 MHz XOSC clock.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rp2350_uart.h"
|
||||||
|
|
||||||
|
#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 14.5 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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file rp2350_xosc.c
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief XOSC driver implementation for RP2350.
|
||||||
|
*
|
||||||
|
* Configures the external crystal oscillator and enables the
|
||||||
|
* peripheral clock sourced from XOSC.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rp2350_xosc.h"
|
||||||
|
|
||||||
|
void xosc_init(void)
|
||||||
|
{
|
||||||
|
XOSC->STARTUP = 0x00C4U;
|
||||||
|
XOSC->CTRL = 0x00FABAA0U;
|
||||||
|
while ((XOSC->STATUS & (1U << XOSC_STATUS_STABLE_SHIFT)) == 0) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void xosc_enable_peri_clk(void)
|
||||||
|
{
|
||||||
|
uint32_t value;
|
||||||
|
value = CLOCKS->CLK_PERI_CTRL;
|
||||||
|
value |= (1U << CLK_PERI_CTRL_ENABLE_SHIFT);
|
||||||
|
value |= (CLK_PERI_CTRL_AUXSRC_XOSC << CLK_PERI_CTRL_AUXSRC_SHIFT);
|
||||||
|
CLOCKS->CLK_PERI_CTRL = value;
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file vector_table.c
|
||||||
|
* @author Kevin Thomas
|
||||||
|
* @brief Vector table with initial stack pointer and reset handler.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @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.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
extern uint32_t _stack_top;
|
||||||
|
extern void Reset_Handler(void);
|
||||||
|
|
||||||
|
typedef void (*vector_func_t)(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Vector table placed in .vectors section
|
||||||
|
*/
|
||||||
|
__attribute__((section(".vectors"), used))
|
||||||
|
const void *_vectors[2] = {
|
||||||
|
&_stack_top,
|
||||||
|
Reset_Handler
|
||||||
|
};
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file blink.c
|
|
||||||
* @brief Implementation of the GPIO output / LED blink driver
|
|
||||||
* @author Kevin Thomas
|
|
||||||
* @date 2025
|
|
||||||
*
|
|
||||||
* MIT License
|
|
||||||
*
|
|
||||||
* Copyright (c) 2025 Kevin Thomas
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "blink.h"
|
|
||||||
#include "gpio.h"
|
|
||||||
|
|
||||||
void blink_init(uint32_t pin) {
|
|
||||||
GPIO_Config(pin);
|
|
||||||
GPIO_Clear(pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
void blink_on(uint32_t pin) {
|
|
||||||
GPIO_Set(pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
void blink_off(uint32_t pin) {
|
|
||||||
GPIO_Clear(pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
void blink_toggle(uint32_t pin) {
|
|
||||||
GPIO_Toggle(pin);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool blink_get_state(uint32_t pin) {
|
|
||||||
return GPIO_Get(pin);
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file blink.h
|
|
||||||
* @brief Header for GPIO output / LED blink driver
|
|
||||||
* @author Kevin Thomas
|
|
||||||
* @date 2025
|
|
||||||
*
|
|
||||||
* MIT License
|
|
||||||
*
|
|
||||||
* Copyright (c) 2025 Kevin Thomas
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BLINK_H
|
|
||||||
#define BLINK_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize a GPIO pin as a push-pull digital output
|
|
||||||
*
|
|
||||||
* Configures the pad control, sets IO_BANK0 FUNCSEL to SIO, and
|
|
||||||
* enables the output driver. The initial drive level is low (LED off).
|
|
||||||
*
|
|
||||||
* @param pin GPIO pin number to configure as a digital output
|
|
||||||
*/
|
|
||||||
void blink_init(uint32_t pin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Drive the output pin high (LED on)
|
|
||||||
*
|
|
||||||
* @param pin GPIO pin number previously initialized with blink_init()
|
|
||||||
*/
|
|
||||||
void blink_on(uint32_t pin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Drive the output pin low (LED off)
|
|
||||||
*
|
|
||||||
* @param pin GPIO pin number previously initialized with blink_init()
|
|
||||||
*/
|
|
||||||
void blink_off(uint32_t pin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Toggle the current state of the output pin
|
|
||||||
*
|
|
||||||
* Reads the current GPIO output level and inverts it. If the LED was on
|
|
||||||
* it is turned off, and vice versa.
|
|
||||||
*
|
|
||||||
* @param pin GPIO pin number previously initialized with blink_init()
|
|
||||||
*/
|
|
||||||
void blink_toggle(uint32_t pin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Query the current drive state of the output pin
|
|
||||||
*
|
|
||||||
* @param pin GPIO pin number previously initialized with blink_init()
|
|
||||||
* @return bool true if the pin is driven high, false if driven low
|
|
||||||
*/
|
|
||||||
bool blink_get_state(uint32_t pin);
|
|
||||||
|
|
||||||
#endif // BLINK_H
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
@echo off
|
|
||||||
REM ==============================================================================
|
|
||||||
REM FILE: build.bat
|
|
||||||
REM
|
|
||||||
REM DESCRIPTION:
|
|
||||||
REM Build script for RP2350 bare-metal C Blink driver.
|
|
||||||
REM
|
|
||||||
REM BRIEF:
|
|
||||||
REM Automates the process of compiling, linking, and generating UF2 firmware.
|
|
||||||
REM
|
|
||||||
REM AUTHOR: Kevin Thomas
|
|
||||||
REM CREATION DATE: 2025
|
|
||||||
REM UPDATE DATE: 2025
|
|
||||||
REM ==============================================================================
|
|
||||||
|
|
||||||
echo Building C bare-metal version...
|
|
||||||
|
|
||||||
REM ==============================================================================
|
|
||||||
REM Compile C Source Files
|
|
||||||
REM ==============================================================================
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -Og -g3 -Wall -Wextra -ffunction-sections -fdata-sections -c vector_table.c -o vector_table.o
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -Og -g3 -Wall -Wextra -ffunction-sections -fdata-sections -c reset_handler.c -o reset_handler.o
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -Og -g3 -Wall -Wextra -ffunction-sections -fdata-sections -c stack.c -o stack.o
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -Og -g3 -Wall -Wextra -ffunction-sections -fdata-sections -c xosc.c -o xosc.o
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -Og -g3 -Wall -Wextra -ffunction-sections -fdata-sections -c reset.c -o reset.o
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -Og -g3 -Wall -Wextra -ffunction-sections -fdata-sections -c coprocessor.c -o coprocessor.o
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -Og -g3 -Wall -Wextra -ffunction-sections -fdata-sections -c uart.c -o uart.o
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -Og -g3 -Wall -Wextra -ffunction-sections -fdata-sections -c gpio.c -o gpio.o
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -Og -g3 -Wall -Wextra -ffunction-sections -fdata-sections -c blink.c -o blink.o
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -Og -g3 -Wall -Wextra -ffunction-sections -fdata-sections -c delay.c -o delay.o
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -Og -g3 -Wall -Wextra -ffunction-sections -fdata-sections -c main.c -o main.o
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -Og -g3 -Wall -Wextra -ffunction-sections -fdata-sections -c image_def.c -o image_def.o
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
REM ==============================================================================
|
|
||||||
REM Link Object Files
|
|
||||||
REM ==============================================================================
|
|
||||||
arm-none-eabi-gcc -mcpu=cortex-m33 -mthumb -T linker.ld -nostdlib -Wl,--gc-sections vector_table.o reset_handler.o stack.o xosc.o reset.o coprocessor.o uart.o gpio.o blink.o delay.o main.o image_def.o -o blink.elf
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
REM ==============================================================================
|
|
||||||
REM Create Raw Binary from ELF
|
|
||||||
REM ==============================================================================
|
|
||||||
arm-none-eabi-objcopy -O binary blink.elf blink.bin
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
REM ==============================================================================
|
|
||||||
REM Create UF2 Image for RP2350
|
|
||||||
REM -b 0x10000000 : base address
|
|
||||||
REM -f 0xe48bff59 : RP2350 family ID
|
|
||||||
REM ==============================================================================
|
|
||||||
python uf2conv.py -b 0x10000000 -f 0xe48bff59 -o blink.uf2 blink.bin
|
|
||||||
if errorlevel 1 goto error
|
|
||||||
|
|
||||||
REM ==============================================================================
|
|
||||||
REM Success Message and Flashing Instructions
|
|
||||||
REM ==============================================================================
|
|
||||||
echo.
|
|
||||||
echo =================================
|
|
||||||
echo SUCCESS! Created blink.uf2
|
|
||||||
echo =================================
|
|
||||||
echo.
|
|
||||||
echo To flash via UF2:
|
|
||||||
echo 1. Hold BOOTSEL button
|
|
||||||
echo 2. Plug in USB
|
|
||||||
echo 3. Copy blink.uf2 to RP2350 drive
|
|
||||||
echo.
|
|
||||||
echo To flash via OpenOCD (debug probe):
|
|
||||||
echo openocd -f interface/cmsis-dap.cfg -f target/rp2350.cfg -c "adapter speed 5000" -c "program blink.elf verify reset exit"
|
|
||||||
echo.
|
|
||||||
goto end
|
|
||||||
|
|
||||||
REM ==============================================================================
|
|
||||||
REM Error Handling
|
|
||||||
REM ==============================================================================
|
|
||||||
:error
|
|
||||||
echo.
|
|
||||||
echo BUILD FAILED!
|
|
||||||
echo.
|
|
||||||
|
|
||||||
:end
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
@echo off
|
|
||||||
REM ==============================================================================
|
|
||||||
REM FILE: clean.bat
|
|
||||||
REM
|
|
||||||
REM DESCRIPTION:
|
|
||||||
REM Clean script for RP2350 bare-metal C Blink driver.
|
|
||||||
REM
|
|
||||||
REM BRIEF:
|
|
||||||
REM Removes all build artifacts and generated files.
|
|
||||||
REM
|
|
||||||
REM AUTHOR: Kevin Thomas
|
|
||||||
REM CREATION DATE: 2025
|
|
||||||
REM UPDATE DATE: 2025
|
|
||||||
REM ==============================================================================
|
|
||||||
|
|
||||||
echo Cleaning build artifacts...
|
|
||||||
|
|
||||||
REM Remove object files
|
|
||||||
if exist *.o del /Q *.o
|
|
||||||
|
|
||||||
REM Remove ELF file
|
|
||||||
if exist blink.elf del /Q blink.elf
|
|
||||||
|
|
||||||
REM Remove binary file
|
|
||||||
if exist blink.bin del /Q blink.bin
|
|
||||||
|
|
||||||
REM Remove UF2 file
|
|
||||||
if exist blink.uf2 del /Q blink.uf2
|
|
||||||
|
|
||||||
echo Clean complete!
|
|
||||||
@@ -1,214 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file constants.h
|
|
||||||
* @brief Memory-mapped register structures and peripheral base addresses
|
|
||||||
* @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 CONSTANTS_H
|
|
||||||
#define CONSTANTS_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stack addresses.
|
|
||||||
*/
|
|
||||||
#define STACK_TOP 0x20082000U
|
|
||||||
#define STACK_LIMIT 0x2007A000U
|
|
||||||
|
|
||||||
/**
|
|
||||||
* XOSC (External Crystal Oscillator) Register Structure.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
volatile uint32_t CTRL; /**< 0x00: Control register */
|
|
||||||
volatile uint32_t STATUS; /**< 0x04: Status register */
|
|
||||||
volatile uint32_t DORMANT; /**< 0x08: Dormant mode */
|
|
||||||
volatile uint32_t STARTUP; /**< 0x0C: Startup delay */
|
|
||||||
volatile uint32_t RESERVED[3]; /**< 0x10-0x18: Reserved */
|
|
||||||
volatile uint32_t COUNT; /**< 0x1C: Frequency count */
|
|
||||||
} xosc_hw_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* XOSC base address and pointer.
|
|
||||||
*/
|
|
||||||
#define XOSC_BASE 0x40048000U
|
|
||||||
#define XOSC ((xosc_hw_t *)XOSC_BASE)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* XOSC status bit definitions.
|
|
||||||
*/
|
|
||||||
#define XOSC_STATUS_STABLE_SHIFT 31U
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CPACR (Coprocessor Access Control Register) in PPB.
|
|
||||||
*/
|
|
||||||
#define PPB_BASE 0xE0000000U
|
|
||||||
#define CPACR ((volatile uint32_t *)(PPB_BASE + 0x0ED88U))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Coprocessor access control bit definitions.
|
|
||||||
*/
|
|
||||||
#define CPACR_CP0_SHIFT 0U
|
|
||||||
#define CPACR_CP1_SHIFT 1U
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CLOCKS Register Structure.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
volatile uint32_t RESERVED0[18]; /**< 0x00-0x44: Other clock registers */
|
|
||||||
volatile uint32_t CLK_PERI_CTRL; /**< 0x48: Peripheral clock control */
|
|
||||||
} clocks_hw_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CLOCKS base address and pointer.
|
|
||||||
*/
|
|
||||||
#define CLOCKS_BASE 0x40010000U
|
|
||||||
#define CLOCKS ((clocks_hw_t *)CLOCKS_BASE)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clock control bit definitions.
|
|
||||||
*/
|
|
||||||
#define CLOCKS_CLK_PERI_CTRL_ENABLE_SHIFT 11U
|
|
||||||
#define CLOCKS_CLK_PERI_CTRL_AUXSRC_SHIFT 5U
|
|
||||||
#define CLOCKS_CLK_PERI_CTRL_AUXSRC_XOSC 4U
|
|
||||||
|
|
||||||
/**
|
|
||||||
* RESETS Register Structure.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
volatile uint32_t RESET; /**< 0x00: Reset control */
|
|
||||||
volatile uint32_t WDSEL; /**< 0x04: Watchdog select */
|
|
||||||
volatile uint32_t RESET_DONE; /**< 0x08: Reset done status */
|
|
||||||
} resets_hw_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* RESETS base address and pointer.
|
|
||||||
*/
|
|
||||||
#define RESETS_BASE 0x40020000U
|
|
||||||
#define RESETS ((resets_hw_t *)RESETS_BASE)
|
|
||||||
#define RESETS_RESET_CLEAR ((volatile uint32_t *)(RESETS_BASE + 0x3000U))
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset control bit definitions.
|
|
||||||
*/
|
|
||||||
#define RESETS_RESET_IO_BANK0_SHIFT 6U
|
|
||||||
#define RESETS_RESET_UART0_SHIFT 26U
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IO_BANK0 GPIO Control Register (one per GPIO).
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
volatile uint32_t STATUS; /**< 0x00: GPIO status */
|
|
||||||
volatile uint32_t CTRL; /**< 0x04: GPIO control */
|
|
||||||
} io_bank0_gpio_ctrl_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IO_BANK0 Register Structure.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
io_bank0_gpio_ctrl_t GPIO[30]; /**< 0x000-0x0E8: GPIO 0-29 */
|
|
||||||
} io_bank0_hw_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IO_BANK0 base address and pointer.
|
|
||||||
*/
|
|
||||||
#define IO_BANK0_BASE 0x40028000U
|
|
||||||
#define IO_BANK0 ((io_bank0_hw_t *)IO_BANK0_BASE)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GPIO control bit definitions.
|
|
||||||
*/
|
|
||||||
#define IO_BANK0_CTRL_FUNCSEL_MASK 0x1FU
|
|
||||||
#define IO_BANK0_CTRL_FUNCSEL_UART 0x02U
|
|
||||||
#define IO_BANK0_CTRL_FUNCSEL_SIO 0x05U
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PADS_BANK0 Register Structure.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
volatile uint32_t VOLTAGE_SELECT; /**< 0x00: Voltage select */
|
|
||||||
volatile uint32_t GPIO[30]; /**< 0x04-0x78: GPIO 0-29 pad control */
|
|
||||||
} pads_bank0_hw_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PADS_BANK0 base address and pointer.
|
|
||||||
*/
|
|
||||||
#define PADS_BANK0_BASE 0x40038000U
|
|
||||||
#define PADS_BANK0 ((pads_bank0_hw_t *)PADS_BANK0_BASE)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pad control bit definitions.
|
|
||||||
*/
|
|
||||||
#define PADS_BANK0_OD_SHIFT 7U
|
|
||||||
#define PADS_BANK0_IE_SHIFT 6U
|
|
||||||
#define PADS_BANK0_ISO_SHIFT 8U
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UART0 base address.
|
|
||||||
*/
|
|
||||||
#define UART0_BASE 0x40070000U
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UART register offsets (as word indices from UART0_BASE).
|
|
||||||
*/
|
|
||||||
#define UART_DR_OFFSET (0x00U / 4U)
|
|
||||||
#define UART_FR_OFFSET (0x18U / 4U)
|
|
||||||
#define UART_IBRD_OFFSET (0x24U / 4U)
|
|
||||||
#define UART_FBRD_OFFSET (0x28U / 4U)
|
|
||||||
#define UART_LCR_H_OFFSET (0x2CU / 4U)
|
|
||||||
#define UART_CR_OFFSET (0x30U / 4U)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UART flag register bit definitions.
|
|
||||||
*/
|
|
||||||
#define UART_FR_TXFF_MASK 32U
|
|
||||||
#define UART_FR_RXFE_MASK 16U
|
|
||||||
|
|
||||||
/**
|
|
||||||
* UART line control and enable values.
|
|
||||||
*/
|
|
||||||
#define UART_LCR_H_8N1_FIFO 0x70U
|
|
||||||
#define UART_CR_ENABLE ((3U << 8) | 1U)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* GPIO pin definitions.
|
|
||||||
*/
|
|
||||||
#define LED_PIN 25U
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SIO (Single-cycle IO) base address.
|
|
||||||
*/
|
|
||||||
#define SIO_BASE 0xD0000000U
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SIO GPIO output register offsets (as word indices).
|
|
||||||
*/
|
|
||||||
#define SIO_GPIO_OUT_SET_OFFSET (0x018U / 4U)
|
|
||||||
#define SIO_GPIO_OUT_CLR_OFFSET (0x020U / 4U)
|
|
||||||
#define SIO_GPIO_OUT_XOR_OFFSET (0x028U / 4U)
|
|
||||||
#define SIO_GPIO_OE_SET_OFFSET (0x038U / 4U)
|
|
||||||
#define SIO_GPIO_IN_OFFSET (0x008U / 4U)
|
|
||||||
|
|
||||||
#endif // CONSTANTS_H
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file coprocessor.c
|
|
||||||
* @brief Coprocessor access control enable functions
|
|
||||||
* @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 "coprocessor.h"
|
|
||||||
#include "constants.h"
|
|
||||||
|
|
||||||
void Enable_Coprocessor(void) {
|
|
||||||
uint32_t value;
|
|
||||||
|
|
||||||
// read CPACR value
|
|
||||||
value = *CPACR;
|
|
||||||
// set CP1: Ctrl access priv coproc 1 bit
|
|
||||||
value |= (1U << CPACR_CP1_SHIFT);
|
|
||||||
// set CP0: Ctrl access priv coproc 0 bit
|
|
||||||
value |= (1U << CPACR_CP0_SHIFT);
|
|
||||||
// store value into CPACR
|
|
||||||
*CPACR = value;
|
|
||||||
// data sync barrier
|
|
||||||
__asm__ volatile ("dsb");
|
|
||||||
// instruction sync barrier
|
|
||||||
__asm__ volatile ("isb");
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file coprocessor.h
|
|
||||||
* @brief Coprocessor access control enable functions
|
|
||||||
* @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 COPROCESSOR_H
|
|
||||||
#define COPROCESSOR_H
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enable coprocessor access via CPACR
|
|
||||||
*
|
|
||||||
* Grants full access to coprocessors 0 and 1 by setting the
|
|
||||||
* corresponding bits in the Coprocessor Access Control Register,
|
|
||||||
* then issues DSB and ISB barriers.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void Enable_Coprocessor(void);
|
|
||||||
|
|
||||||
#endif // COPROCESSOR_H
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file delay.c
|
|
||||||
* @brief Millisecond delay functions based on a 14.5 MHz clock
|
|
||||||
* @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 "delay.h"
|
|
||||||
|
|
||||||
void Delay_MS(uint32_t ms) {
|
|
||||||
if (ms == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
__asm__ volatile (
|
|
||||||
"mov r4, #3600\n\t"
|
|
||||||
"mul r5, %0, r4\n\t"
|
|
||||||
"1:\n\t"
|
|
||||||
"subs r5, #1\n\t"
|
|
||||||
"bne 1b\n\t"
|
|
||||||
:
|
|
||||||
: "r" (ms)
|
|
||||||
: "r4", "r5", "cc"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file delay.h
|
|
||||||
* @brief Millisecond delay functions based on a 14.5 MHz clock
|
|
||||||
* @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 DELAY_H
|
|
||||||
#define DELAY_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Delay for the specified number of milliseconds
|
|
||||||
*
|
|
||||||
* Busy-waits using a calibrated loop count (3600 iterations per ms)
|
|
||||||
* based on a 14.5 MHz clock. Returns immediately if ms is zero.
|
|
||||||
*
|
|
||||||
* @param ms Number of milliseconds to delay
|
|
||||||
*/
|
|
||||||
void Delay_MS(uint32_t ms);
|
|
||||||
|
|
||||||
#endif // DELAY_H
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file gpio.c
|
|
||||||
* @brief GPIO configuration, set, clear, toggle, and read functions
|
|
||||||
* @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 "gpio.h"
|
|
||||||
#include "constants.h"
|
|
||||||
|
|
||||||
#define SIO ((volatile uint32_t *)SIO_BASE)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Configure pad control for a GPIO pin
|
|
||||||
*
|
|
||||||
* @details Clears OD (output disable), sets IE (input enable), and
|
|
||||||
* clears ISO (isolation) in PADS_BANK0.
|
|
||||||
*
|
|
||||||
* @param gpio_num GPIO pin number (0-29)
|
|
||||||
*/
|
|
||||||
static void _gpio_config_pad(uint32_t gpio_num) {
|
|
||||||
uint32_t value;
|
|
||||||
|
|
||||||
// read PAD value
|
|
||||||
value = PADS_BANK0->GPIO[gpio_num];
|
|
||||||
// clear OD bit (output disable)
|
|
||||||
value &= ~(1U << PADS_BANK0_OD_SHIFT);
|
|
||||||
// set IE bit (input enable)
|
|
||||||
value |= (1U << PADS_BANK0_IE_SHIFT);
|
|
||||||
// clear ISO bit (isolate)
|
|
||||||
value &= ~(1U << PADS_BANK0_ISO_SHIFT);
|
|
||||||
// store value into PAD
|
|
||||||
PADS_BANK0->GPIO[gpio_num] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set IO_BANK0 FUNCSEL to SIO for a GPIO pin
|
|
||||||
*
|
|
||||||
* @details Reads the control register, clears FUNCSEL bits, sets
|
|
||||||
* FUNCSEL to SIO (0x05), and writes back.
|
|
||||||
*
|
|
||||||
* @param gpio_num GPIO pin number (0-29)
|
|
||||||
*/
|
|
||||||
static void _gpio_config_funcsel(uint32_t gpio_num) {
|
|
||||||
uint32_t value;
|
|
||||||
|
|
||||||
// read CTRL value
|
|
||||||
value = IO_BANK0->GPIO[gpio_num].CTRL;
|
|
||||||
// clear FUNCSEL bits
|
|
||||||
value &= ~IO_BANK0_CTRL_FUNCSEL_MASK;
|
|
||||||
// set FUNCSEL to SIO (0x05)
|
|
||||||
value |= IO_BANK0_CTRL_FUNCSEL_SIO;
|
|
||||||
// store value into CTRL
|
|
||||||
IO_BANK0->GPIO[gpio_num].CTRL = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enable the output driver for a GPIO pin via SIO
|
|
||||||
*
|
|
||||||
* @details Sets the corresponding bit in the SIO output-enable set
|
|
||||||
* register.
|
|
||||||
*
|
|
||||||
* @param gpio_num GPIO pin number (0-29)
|
|
||||||
*/
|
|
||||||
static void _gpio_enable_output(uint32_t gpio_num) {
|
|
||||||
SIO[SIO_GPIO_OE_SET_OFFSET] = (1U << gpio_num);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPIO_Config(uint32_t gpio_num) {
|
|
||||||
_gpio_config_pad(gpio_num);
|
|
||||||
_gpio_config_funcsel(gpio_num);
|
|
||||||
_gpio_enable_output(gpio_num);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPIO_Set(uint32_t gpio_num) {
|
|
||||||
SIO[SIO_GPIO_OUT_SET_OFFSET] = (1U << gpio_num);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPIO_Clear(uint32_t gpio_num) {
|
|
||||||
SIO[SIO_GPIO_OUT_CLR_OFFSET] = (1U << gpio_num);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPIO_Toggle(uint32_t gpio_num) {
|
|
||||||
SIO[SIO_GPIO_OUT_XOR_OFFSET] = (1U << gpio_num);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GPIO_Get(uint32_t gpio_num) {
|
|
||||||
return (SIO[SIO_GPIO_IN_OFFSET] & (1U << gpio_num)) != 0;
|
|
||||||
}
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file gpio.h
|
|
||||||
* @brief GPIO configuration, set, clear, toggle, and read functions
|
|
||||||
* @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 GPIO_H
|
|
||||||
#define GPIO_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Configure a GPIO pin as SIO output
|
|
||||||
*
|
|
||||||
* Configures the pad control (clear OD, set IE, clear ISO), sets
|
|
||||||
* IO_BANK0 FUNCSEL to SIO (0x05), and enables the output driver
|
|
||||||
* via the SIO output-enable set register.
|
|
||||||
*
|
|
||||||
* @param gpio_num GPIO pin number (0-29)
|
|
||||||
*/
|
|
||||||
void GPIO_Config(uint32_t gpio_num);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Drive a GPIO output high
|
|
||||||
*
|
|
||||||
* Sets the specified bit in the SIO GPIO output set register.
|
|
||||||
*
|
|
||||||
* @param gpio_num GPIO pin number (0-29)
|
|
||||||
*/
|
|
||||||
void GPIO_Set(uint32_t gpio_num);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Drive a GPIO output low
|
|
||||||
*
|
|
||||||
* Sets the specified bit in the SIO GPIO output clear register.
|
|
||||||
*
|
|
||||||
* @param gpio_num GPIO pin number (0-29)
|
|
||||||
*/
|
|
||||||
void GPIO_Clear(uint32_t gpio_num);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Toggle a GPIO output
|
|
||||||
*
|
|
||||||
* Sets the specified bit in the SIO GPIO output XOR register,
|
|
||||||
* which inverts the current output level.
|
|
||||||
*
|
|
||||||
* @param gpio_num GPIO pin number (0-29)
|
|
||||||
*/
|
|
||||||
void GPIO_Toggle(uint32_t gpio_num);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Read the current input level of a GPIO pin
|
|
||||||
*
|
|
||||||
* Reads the SIO GPIO input register and returns the state of the
|
|
||||||
* specified pin.
|
|
||||||
*
|
|
||||||
* @param gpio_num GPIO pin number (0-29)
|
|
||||||
* @return bool true if pin is high, false if low
|
|
||||||
*/
|
|
||||||
bool GPIO_Get(uint32_t gpio_num);
|
|
||||||
|
|
||||||
#endif // GPIO_H
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file image_def.c
|
|
||||||
* @brief RP2350 IMAGE_DEF block for boot ROM image recognition
|
|
||||||
* @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 <stdint.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IMAGE_DEF block structure placed in flash.
|
|
||||||
* Must appear within the first 4 KB for the boot ROM to accept the image.
|
|
||||||
*/
|
|
||||||
__attribute__((section(".embedded_block"), used))
|
|
||||||
const uint8_t picobin_block[] = {
|
|
||||||
// PICOBIN_BLOCK_MARKER_START (word: 0xffffded3)
|
|
||||||
0xD3, 0xDE, 0xFF, 0xFF,
|
|
||||||
// PICOBIN_BLOCK_ITEM_1BS_IMAGE_TYPE
|
|
||||||
0x42, 0x01, 0x21, 0x10,
|
|
||||||
// PICOBIN_BLOCK_ITEM_2BS_LAST
|
|
||||||
0xFF, 0x01, 0x00, 0x00,
|
|
||||||
// Relative pointer to next block (loop to self)
|
|
||||||
0x00, 0x00, 0x00, 0x00,
|
|
||||||
// PICOBIN_BLOCK_MARKER_END (word: 0xab123579)
|
|
||||||
0x79, 0x35, 0x12, 0xAB
|
|
||||||
};
|
|
||||||
@@ -1,44 +1,43 @@
|
|||||||
/**
|
/**
|
||||||
* @file linker.ld
|
******************************************************************************
|
||||||
* @brief Minimal linker script for bare-metal RP2350 development
|
* @file linker.ld
|
||||||
* @author Kevin Thomas
|
* @author Kevin Thomas
|
||||||
* @date 2025
|
* @brief Minimal linker script for bare-metal RP2350 development.
|
||||||
*
|
*
|
||||||
* MIT License
|
* Defines FLASH (XIP 32 MB) and RAM (520 kB SRAM) regions.
|
||||||
*
|
* The vector table is placed at the start of flash (0x10000000).
|
||||||
* Copyright (c) 2025 Kevin Thomas
|
*
|
||||||
*
|
******************************************************************************
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* @attention
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
*
|
||||||
* in the Software without restriction, including without limitation the rights
|
* Copyright (c) 2026 Kevin Thomas.
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
* All rights reserved.
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
*
|
||||||
* furnished to do so, subject to the following conditions:
|
* This software is licensed under terms that can be found in the LICENSE file
|
||||||
*
|
* in the root directory of this software component.
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entry point.
|
||||||
|
*/
|
||||||
ENTRY(Reset_Handler)
|
ENTRY(Reset_Handler)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define memory regions.
|
* Define memory regions.
|
||||||
*/
|
*/
|
||||||
__XIP_BASE = 0x10000000;
|
__XIP_BASE = 0x10000000;
|
||||||
__XIP_SIZE = 32M;
|
__XIP_SIZE = 32M;
|
||||||
|
|
||||||
__SRAM_BASE = 0x20000000;
|
__SRAM_BASE = 0x20000000;
|
||||||
__SRAM_SIZE = 512K;
|
__SRAM_SIZE = 520K;
|
||||||
__STACK_SIZE = 32K;
|
__STACK_SIZE = 32K;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Memory layout.
|
||||||
|
*/
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
RAM (rwx) : ORIGIN = __SRAM_BASE, LENGTH = __SRAM_SIZE
|
RAM (rwx) : ORIGIN = __SRAM_BASE, LENGTH = __SRAM_SIZE
|
||||||
@@ -46,34 +45,37 @@ MEMORY
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program headers.
|
* Program headers.
|
||||||
*/
|
*/
|
||||||
PHDRS
|
PHDRS
|
||||||
{
|
{
|
||||||
text PT_LOAD FLAGS(5);
|
text PT_LOAD FLAGS(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Section placement.
|
* Section placement.
|
||||||
*/
|
*/
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = ORIGIN(FLASH);
|
. = ORIGIN(FLASH);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vector table MUST be first at 0x10000000.
|
* Vector table MUST be first at 0x10000000.
|
||||||
*/
|
*/
|
||||||
.vectors :
|
.vectors :
|
||||||
{
|
{
|
||||||
KEEP(*(.vectors))
|
KEEP(*(.vectors))
|
||||||
} > FLASH :text
|
} > FLASH :text
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify vector table placement.
|
||||||
|
*/
|
||||||
ASSERT((ADDR(.vectors) == ORIGIN(FLASH)),
|
ASSERT((ADDR(.vectors) == ORIGIN(FLASH)),
|
||||||
"Vector table must be at start of flash (0x10000000)")
|
"Vector table must be at start of flash (0x10000000)")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Text and read-only data.
|
* Text and read-only data.
|
||||||
*/
|
*/
|
||||||
.text :
|
.text :
|
||||||
{
|
{
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
@@ -85,22 +87,28 @@ SECTIONS
|
|||||||
} > FLASH :text
|
} > FLASH :text
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IMAGE_DEF block at end of code.
|
* IMAGE_DEF block at end of code.
|
||||||
*/
|
*/
|
||||||
.embedded_block :
|
.embedded_block :
|
||||||
{
|
{
|
||||||
KEEP(*(.embedded_block))
|
KEEP(*(.embedded_block))
|
||||||
} > FLASH :text
|
} > FLASH :text
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Non-secure stack symbols.
|
* Non-secure stack symbols.
|
||||||
*/
|
*/
|
||||||
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
|
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
|
||||||
__StackLimit = __StackTop - __STACK_SIZE;
|
__StackLimit = __StackTop - __STACK_SIZE;
|
||||||
__stack = __StackTop;
|
__stack = __StackTop;
|
||||||
_stack_top = __StackTop;
|
_stack_top = __StackTop;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stack section (no load).
|
||||||
|
*/
|
||||||
.stack (NOLOAD) : { . = ALIGN(8); } > RAM
|
.stack (NOLOAD) : { . = ALIGN(8); } > RAM
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide vector table symbol to startup code.
|
||||||
|
*/
|
||||||
PROVIDE(__Vectors = ADDR(.vectors));
|
PROVIDE(__Vectors = ADDR(.vectors));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,78 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file main.c
|
|
||||||
* @brief Blink demonstration: toggle onboard LED every 500 ms
|
|
||||||
* @author Kevin Thomas
|
|
||||||
* @date 2025
|
|
||||||
*
|
|
||||||
* MIT License
|
|
||||||
*
|
|
||||||
* Copyright (c) 2025 Kevin Thomas
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*
|
|
||||||
* -----------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* Demonstrates GPIO output control using the blink driver (blink.h / blink.c).
|
|
||||||
* The onboard LED on GPIO 25 is toggled every BLINK_DELAY_MS milliseconds and
|
|
||||||
* the current state is reported over UART.
|
|
||||||
*
|
|
||||||
* Wiring:
|
|
||||||
* GPIO25 -> Onboard LED (no external wiring needed)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "blink.h"
|
|
||||||
#include "uart.h"
|
|
||||||
#include "delay.h"
|
|
||||||
#include "constants.h"
|
|
||||||
|
|
||||||
#define BLINK_DELAY_MS 500
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Print the current LED state over UART
|
|
||||||
*
|
|
||||||
* @details Queries the blink driver for the pin state and prints
|
|
||||||
* "LED: ON\r\n" or "LED: OFF\r\n" over UART0.
|
|
||||||
*
|
|
||||||
* @param pin GPIO pin number to query
|
|
||||||
*/
|
|
||||||
static void _print_led_state(uint32_t pin) {
|
|
||||||
if (blink_get_state(pin)) {
|
|
||||||
uart_driver_puts("LED: ON\r\n");
|
|
||||||
} else {
|
|
||||||
uart_driver_puts("LED: OFF\r\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Application entry point for the LED blink demo
|
|
||||||
*
|
|
||||||
* Initializes the onboard LED and enters an infinite loop that
|
|
||||||
* toggles the LED state every BLINK_DELAY_MS milliseconds.
|
|
||||||
*
|
|
||||||
* @return int Does not return
|
|
||||||
*/
|
|
||||||
int main(void) {
|
|
||||||
blink_init(LED_PIN);
|
|
||||||
uart_driver_puts("Blink driver initialized on GPIO 25\r\n");
|
|
||||||
while (1) {
|
|
||||||
blink_toggle(LED_PIN);
|
|
||||||
_print_led_state(LED_PIN);
|
|
||||||
Delay_MS(BLINK_DELAY_MS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file reset.c
|
|
||||||
* @brief Reset controller functions for subsystem initialization
|
|
||||||
* @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 "reset.h"
|
|
||||||
#include "constants.h"
|
|
||||||
|
|
||||||
void Init_Subsystem(void) {
|
|
||||||
uint32_t value;
|
|
||||||
|
|
||||||
// read RESETS->RESET value
|
|
||||||
value = RESETS->RESET;
|
|
||||||
// clear IO_BANK0 bit
|
|
||||||
value &= ~(1U << RESETS_RESET_IO_BANK0_SHIFT);
|
|
||||||
// store value into RESETS->RESET address
|
|
||||||
RESETS->RESET = value;
|
|
||||||
// wait until done
|
|
||||||
while ((RESETS->RESET_DONE & (1U << RESETS_RESET_IO_BANK0_SHIFT)) == 0) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file reset.h
|
|
||||||
* @brief Reset controller functions for subsystem initialization
|
|
||||||
* @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 RESET_H
|
|
||||||
#define RESET_H
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize the IO_BANK0 subsystem by clearing its reset bit
|
|
||||||
*
|
|
||||||
* Clears the IO_BANK0 reset bit in the Reset controller and waits
|
|
||||||
* until the RESET_DONE register confirms the block is out of reset.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void Init_Subsystem(void);
|
|
||||||
|
|
||||||
#endif // RESET_H
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file reset_handler.c
|
|
||||||
* @brief Reset handler entry point after power-on or system reset
|
|
||||||
* @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 "reset_handler.h"
|
|
||||||
#include "stack.h"
|
|
||||||
#include "xosc.h"
|
|
||||||
#include "reset.h"
|
|
||||||
#include "uart.h"
|
|
||||||
#include "coprocessor.h"
|
|
||||||
|
|
||||||
extern int main(void);
|
|
||||||
|
|
||||||
void __attribute__((naked, noreturn)) Reset_Handler(void) {
|
|
||||||
__asm__ volatile (
|
|
||||||
"bl Init_Stack\n\t"
|
|
||||||
"bl Init_XOSC\n\t"
|
|
||||||
"bl Enable_XOSC_Peri_Clock\n\t"
|
|
||||||
"bl Init_Subsystem\n\t"
|
|
||||||
"bl UART_Release_Reset\n\t"
|
|
||||||
"bl UART_Init\n\t"
|
|
||||||
"bl Enable_Coprocessor\n\t"
|
|
||||||
"b main\n\t"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file reset_handler.h
|
|
||||||
* @brief Reset handler entry point after power-on or system reset
|
|
||||||
* @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 RESET_HANDLER_H
|
|
||||||
#define RESET_HANDLER_H
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Reset handler for the RP2350
|
|
||||||
*
|
|
||||||
* Entry point after reset. Performs stack initialization, XOSC setup,
|
|
||||||
* subsystem reset release, UART initialization, coprocessor enable,
|
|
||||||
* and branches to main().
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void Reset_Handler(void) __attribute__((noreturn));
|
|
||||||
|
|
||||||
#endif // RESET_HANDLER_H
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file stack.c
|
|
||||||
* @brief Stack pointer initialization for MSP/PSP and their limits
|
|
||||||
* @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 "stack.h"
|
|
||||||
#include "constants.h"
|
|
||||||
|
|
||||||
void Init_Stack(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"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file stack.h
|
|
||||||
* @brief Stack pointer initialization for MSP/PSP and their limits
|
|
||||||
* @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 STACK_H
|
|
||||||
#define STACK_H
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize stack pointers
|
|
||||||
*
|
|
||||||
* Sets Main and Process Stack Pointers (MSP/PSP) and their limits
|
|
||||||
* using the STACK_TOP and STACK_LIMIT values from constants.h.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void Init_Stack(void);
|
|
||||||
|
|
||||||
#endif // STACK_H
|
|
||||||
@@ -1,165 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file uart.c
|
|
||||||
* @brief Implementation of the bare-metal UART0 driver
|
|
||||||
* @author Kevin Thomas
|
|
||||||
* @date 2025
|
|
||||||
*
|
|
||||||
* MIT License
|
|
||||||
*
|
|
||||||
* Copyright (c) 2025 Kevin Thomas
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "uart.h"
|
|
||||||
#include "constants.h"
|
|
||||||
|
|
||||||
#define UART_BASE ((volatile uint32_t *)UART0_BASE)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Clear the UART0 reset bit in the reset controller
|
|
||||||
*
|
|
||||||
* @details Reads RESETS->RESET, clears bit 26 (UART0), and writes
|
|
||||||
* the value back.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void _uart_clear_reset_bit(void) {
|
|
||||||
uint32_t value;
|
|
||||||
|
|
||||||
// read RESETS->RESET value
|
|
||||||
value = RESETS->RESET;
|
|
||||||
// clear UART0 reset bit (bit 26)
|
|
||||||
value &= ~(1U << RESETS_RESET_UART0_SHIFT);
|
|
||||||
// write value back to RESETS->RESET
|
|
||||||
RESETS->RESET = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Wait until the UART0 block is out of reset
|
|
||||||
*
|
|
||||||
* @details Polls RESETS->RESET_DONE until bit 26 (UART0) is set.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void _uart_wait_reset_done(void) {
|
|
||||||
// loop until UART0 is out of reset
|
|
||||||
while ((RESETS->RESET_DONE & (1U << RESETS_RESET_UART0_SHIFT)) == 0) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Configure GPIO pins 0 (TX) and 1 (RX) for UART function
|
|
||||||
*
|
|
||||||
* @details Sets IO_BANK0 FUNCSEL to UART (0x02) for both pins and
|
|
||||||
* programs the corresponding pad controls.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void _uart_configure_pins(void) {
|
|
||||||
// FUNCSEL = 2 -> select UART function
|
|
||||||
IO_BANK0->GPIO[0].CTRL = IO_BANK0_CTRL_FUNCSEL_UART;
|
|
||||||
IO_BANK0->GPIO[1].CTRL = IO_BANK0_CTRL_FUNCSEL_UART;
|
|
||||||
// pad config value for TX (pull/func recommended)
|
|
||||||
PADS_BANK0->GPIO[0] = 0x04;
|
|
||||||
// pad config value for RX (input enable)
|
|
||||||
PADS_BANK0->GPIO[1] = 0x40;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set UART0 baud rate divisors for 115200 baud at 14.5 MHz
|
|
||||||
*
|
|
||||||
* @details Programs UARTIBRD = 6 and UARTFBRD = 33 for the integer
|
|
||||||
* and fractional baud rate divisors respectively.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void _uart_set_baud(void) {
|
|
||||||
// disable UART while configuring
|
|
||||||
UART_BASE[UART_CR_OFFSET] = 0;
|
|
||||||
// set integer baud divisor
|
|
||||||
UART_BASE[UART_IBRD_OFFSET] = 6;
|
|
||||||
// set fractional baud divisor
|
|
||||||
UART_BASE[UART_FBRD_OFFSET] = 33;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Configure line control and enable UART0
|
|
||||||
*
|
|
||||||
* @details Sets 8-bit word length with FIFOs enabled, then enables
|
|
||||||
* UART0 with both TX and RX.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
static void _uart_enable(void) {
|
|
||||||
// configure line control: FIFO enable + 8-bit
|
|
||||||
UART_BASE[UART_LCR_H_OFFSET] = UART_LCR_H_8N1_FIFO;
|
|
||||||
// enable UART with TX and RX enabled
|
|
||||||
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_driver_is_readable(void) {
|
|
||||||
// test bit 4, RX FIFO empty (RXFE)
|
|
||||||
return (UART_BASE[UART_FR_OFFSET] & UART_FR_RXFE_MASK) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char uart_driver_getchar(void) {
|
|
||||||
// wait for RX FIFO to be not empty
|
|
||||||
while (UART_BASE[UART_FR_OFFSET] & UART_FR_RXFE_MASK) {
|
|
||||||
}
|
|
||||||
// read data from UARTDR
|
|
||||||
return (char)(UART_BASE[UART_DR_OFFSET] & 0xFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uart_driver_putchar(char c) {
|
|
||||||
// wait for TX FIFO to be not full
|
|
||||||
while (UART_BASE[UART_FR_OFFSET] & UART_FR_TXFF_MASK) {
|
|
||||||
}
|
|
||||||
// write data to UARTDR
|
|
||||||
UART_BASE[UART_DR_OFFSET] = (uint32_t)c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uart_driver_puts(const char *str) {
|
|
||||||
while (*str) {
|
|
||||||
uart_driver_putchar(*str++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char uart_driver_to_upper(char c) {
|
|
||||||
if (c >= 'a' && c <= 'z') {
|
|
||||||
return (char)(c - 32);
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file uart.h
|
|
||||||
* @brief Header for bare-metal UART0 driver (raw TX/RX, GPIO 0/1)
|
|
||||||
* @author Kevin Thomas
|
|
||||||
* @date 2025
|
|
||||||
*
|
|
||||||
* MIT License
|
|
||||||
*
|
|
||||||
* Copyright (c) 2025 Kevin Thomas
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef UART_H
|
|
||||||
#define UART_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Release UART0 from reset and wait until it is ready
|
|
||||||
*
|
|
||||||
* Clears the UART0 reset bit in the Reset controller and polls
|
|
||||||
* RESET_DONE until the UART0 block is out of reset.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void UART_Release_Reset(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize UART0 (pins, baud divisors, line control, enable)
|
|
||||||
*
|
|
||||||
* Configures IO_BANK0 pins 0 (TX) and 1 (RX) to the UART function,
|
|
||||||
* programs pad controls, sets baud rate divisors (IBRD=6, FBRD=33
|
|
||||||
* for 115200 baud at 14.5 MHz), configures 8N1 with FIFOs, and
|
|
||||||
* enables UART0 with TX and RX.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void UART_Init(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check whether a received character is waiting in the UART FIFO
|
|
||||||
*
|
|
||||||
* Returns immediately without blocking. Use this to poll for incoming
|
|
||||||
* data before calling uart_driver_getchar().
|
|
||||||
*
|
|
||||||
* @return bool true if at least one byte is available, false otherwise
|
|
||||||
*/
|
|
||||||
bool uart_driver_is_readable(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Read one character from UART0 (blocking)
|
|
||||||
*
|
|
||||||
* Blocks until a byte arrives in the receive FIFO, then returns it.
|
|
||||||
* Prefer pairing with uart_driver_is_readable() to avoid indefinite blocking.
|
|
||||||
*
|
|
||||||
* @return char The received character
|
|
||||||
*/
|
|
||||||
char uart_driver_getchar(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Transmit one character over UART0 (blocking)
|
|
||||||
*
|
|
||||||
* Waits until the transmit FIFO has space, then writes the character
|
|
||||||
* to UARTDR.
|
|
||||||
*
|
|
||||||
* @param c Character to transmit
|
|
||||||
*/
|
|
||||||
void uart_driver_putchar(char c);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Transmit a null-terminated string over UART0
|
|
||||||
*
|
|
||||||
* Calls uart_driver_putchar() for every character in the string up to
|
|
||||||
* and not including the null terminator.
|
|
||||||
*
|
|
||||||
* @param str Pointer to the null-terminated ASCII string to send
|
|
||||||
*/
|
|
||||||
void uart_driver_puts(const char *str);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Convert a lowercase ASCII character to uppercase
|
|
||||||
*
|
|
||||||
* Returns the uppercase equivalent if the character is in 'a'-'z';
|
|
||||||
* all other characters are passed through unchanged.
|
|
||||||
*
|
|
||||||
* @param c Input character
|
|
||||||
* @return char Uppercase equivalent, or the original character
|
|
||||||
*/
|
|
||||||
char uart_driver_to_upper(char c);
|
|
||||||
|
|
||||||
#endif // UART_H
|
|
||||||
@@ -10,9 +10,9 @@ import json
|
|||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
|
|
||||||
UF2_MAGIC_START0 = 0x0A324655 # "UF2\n"
|
UF2_MAGIC_START0 = 0x0A324655 # "UF2\n"
|
||||||
UF2_MAGIC_START1 = 0x9E5D5157 # Randomly selected
|
UF2_MAGIC_START1 = 0x9E5D5157 # Randomly selected
|
||||||
UF2_MAGIC_END = 0x0AB16F30 # Ditto
|
UF2_MAGIC_END = 0x0AB16F30 # Ditto
|
||||||
|
|
||||||
INFO_FILE = "/INFO_UF2.TXT"
|
INFO_FILE = "/INFO_UF2.TXT"
|
||||||
|
|
||||||
@@ -24,15 +24,17 @@ def is_uf2(buf):
|
|||||||
w = struct.unpack("<II", buf[0:8])
|
w = struct.unpack("<II", buf[0:8])
|
||||||
return w[0] == UF2_MAGIC_START0 and w[1] == UF2_MAGIC_START1
|
return w[0] == UF2_MAGIC_START0 and w[1] == UF2_MAGIC_START1
|
||||||
|
|
||||||
|
|
||||||
def is_hex(buf):
|
def is_hex(buf):
|
||||||
try:
|
try:
|
||||||
w = buf[0:30].decode("utf-8")
|
w = buf[0:30].decode("utf-8")
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
return False
|
return False
|
||||||
if w[0] == ':' and re.match(rb"^[:0-9a-fA-F\r\n]+$", buf):
|
if w[0] == ":" and re.match(rb"^[:0-9a-fA-F\r\n]+$", buf):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def convert_from_uf2(buf):
|
def convert_from_uf2(buf):
|
||||||
global appstartaddr
|
global appstartaddr
|
||||||
global familyid
|
global familyid
|
||||||
@@ -45,7 +47,7 @@ def convert_from_uf2(buf):
|
|||||||
outp = []
|
outp = []
|
||||||
for blockno in range(numblocks):
|
for blockno in range(numblocks):
|
||||||
ptr = blockno * 512
|
ptr = blockno * 512
|
||||||
block = buf[ptr:ptr + 512]
|
block = buf[ptr : ptr + 512]
|
||||||
hd = struct.unpack(b"<IIIIIIII", block[0:32])
|
hd = struct.unpack(b"<IIIIIIII", block[0:32])
|
||||||
if hd[0] != UF2_MAGIC_START0 or hd[1] != UF2_MAGIC_START1:
|
if hd[0] != UF2_MAGIC_START0 or hd[1] != UF2_MAGIC_START1:
|
||||||
print("Skipping block at " + ptr + "; bad magic")
|
print("Skipping block at " + ptr + "; bad magic")
|
||||||
@@ -62,12 +64,12 @@ def convert_from_uf2(buf):
|
|||||||
if curraddr == None or ((hd[2] & 0x2000) and hd[7] != currfamilyid):
|
if curraddr == None or ((hd[2] & 0x2000) and hd[7] != currfamilyid):
|
||||||
currfamilyid = hd[7]
|
currfamilyid = hd[7]
|
||||||
curraddr = newaddr
|
curraddr = newaddr
|
||||||
if familyid == 0x0 or familyid == hd[7]:
|
if familyid == 0x0 or familyid == hd[7]:
|
||||||
appstartaddr = newaddr
|
appstartaddr = newaddr
|
||||||
padding = newaddr - curraddr
|
padding = newaddr - curraddr
|
||||||
if padding < 0:
|
if padding < 0:
|
||||||
assert False, "Block out of order at " + ptr
|
assert False, "Block out of order at " + ptr
|
||||||
if padding > 10*1024*1024:
|
if padding > 10 * 1024 * 1024:
|
||||||
assert False, "More than 10M of padding needed at " + ptr
|
assert False, "More than 10M of padding needed at " + ptr
|
||||||
if padding % 4 != 0:
|
if padding % 4 != 0:
|
||||||
assert False, "Non-word padding size at " + ptr
|
assert False, "Non-word padding size at " + ptr
|
||||||
@@ -95,7 +97,11 @@ def convert_from_uf2(buf):
|
|||||||
for name, value in families.items():
|
for name, value in families.items():
|
||||||
if value == family_hex:
|
if value == family_hex:
|
||||||
family_short_name = name
|
family_short_name = name
|
||||||
print("Family ID is {:s}, hex value is 0x{:08x}".format(family_short_name,family_hex))
|
print(
|
||||||
|
"Family ID is {:s}, hex value is 0x{:08x}".format(
|
||||||
|
family_short_name, family_hex
|
||||||
|
)
|
||||||
|
)
|
||||||
print("Target Address is 0x{:08x}".format(families_found[family_hex]))
|
print("Target Address is 0x{:08x}".format(families_found[family_hex]))
|
||||||
if all_flags_same:
|
if all_flags_same:
|
||||||
print("All block flag values consistent, 0x{:04x}".format(hd[2]))
|
print("All block flag values consistent, 0x{:04x}".format(hd[2]))
|
||||||
@@ -107,6 +113,7 @@ def convert_from_uf2(buf):
|
|||||||
appstartaddr = 0x0
|
appstartaddr = 0x0
|
||||||
return b"".join(outp)
|
return b"".join(outp)
|
||||||
|
|
||||||
|
|
||||||
def convert_to_carray(file_content):
|
def convert_to_carray(file_content):
|
||||||
outp = "const unsigned long bindata_len = %d;\n" % len(file_content)
|
outp = "const unsigned long bindata_len = %d;\n" % len(file_content)
|
||||||
outp += "const unsigned char bindata[] __attribute__((aligned(16))) = {"
|
outp += "const unsigned char bindata[] __attribute__((aligned(16))) = {"
|
||||||
@@ -117,6 +124,7 @@ def convert_to_carray(file_content):
|
|||||||
outp += "\n};\n"
|
outp += "\n};\n"
|
||||||
return bytes(outp, "utf-8")
|
return bytes(outp, "utf-8")
|
||||||
|
|
||||||
|
|
||||||
def convert_to_uf2(file_content):
|
def convert_to_uf2(file_content):
|
||||||
global familyid
|
global familyid
|
||||||
datapadding = b""
|
datapadding = b""
|
||||||
@@ -126,13 +134,21 @@ def convert_to_uf2(file_content):
|
|||||||
outp = []
|
outp = []
|
||||||
for blockno in range(numblocks):
|
for blockno in range(numblocks):
|
||||||
ptr = 256 * blockno
|
ptr = 256 * blockno
|
||||||
chunk = file_content[ptr:ptr + 256]
|
chunk = file_content[ptr : ptr + 256]
|
||||||
flags = 0x0
|
flags = 0x0
|
||||||
if familyid:
|
if familyid:
|
||||||
flags |= 0x2000
|
flags |= 0x2000
|
||||||
hd = struct.pack(b"<IIIIIIII",
|
hd = struct.pack(
|
||||||
UF2_MAGIC_START0, UF2_MAGIC_START1,
|
b"<IIIIIIII",
|
||||||
flags, ptr + appstartaddr, 256, blockno, numblocks, familyid)
|
UF2_MAGIC_START0,
|
||||||
|
UF2_MAGIC_START1,
|
||||||
|
flags,
|
||||||
|
ptr + appstartaddr,
|
||||||
|
256,
|
||||||
|
blockno,
|
||||||
|
numblocks,
|
||||||
|
familyid,
|
||||||
|
)
|
||||||
while len(chunk) < 256:
|
while len(chunk) < 256:
|
||||||
chunk += b"\x00"
|
chunk += b"\x00"
|
||||||
block = hd + chunk + datapadding + struct.pack(b"<I", UF2_MAGIC_END)
|
block = hd + chunk + datapadding + struct.pack(b"<I", UF2_MAGIC_END)
|
||||||
@@ -140,6 +156,7 @@ def convert_to_uf2(file_content):
|
|||||||
outp.append(block)
|
outp.append(block)
|
||||||
return b"".join(outp)
|
return b"".join(outp)
|
||||||
|
|
||||||
|
|
||||||
class Block:
|
class Block:
|
||||||
def __init__(self, addr, default_data=0xFF):
|
def __init__(self, addr, default_data=0xFF):
|
||||||
self.addr = addr
|
self.addr = addr
|
||||||
@@ -150,28 +167,37 @@ class Block:
|
|||||||
flags = 0x0
|
flags = 0x0
|
||||||
if familyid:
|
if familyid:
|
||||||
flags |= 0x2000
|
flags |= 0x2000
|
||||||
hd = struct.pack("<IIIIIIII",
|
hd = struct.pack(
|
||||||
UF2_MAGIC_START0, UF2_MAGIC_START1,
|
"<IIIIIIII",
|
||||||
flags, self.addr, 256, blockno, numblocks, familyid)
|
UF2_MAGIC_START0,
|
||||||
|
UF2_MAGIC_START1,
|
||||||
|
flags,
|
||||||
|
self.addr,
|
||||||
|
256,
|
||||||
|
blockno,
|
||||||
|
numblocks,
|
||||||
|
familyid,
|
||||||
|
)
|
||||||
hd += self.bytes[0:256]
|
hd += self.bytes[0:256]
|
||||||
while len(hd) < 512 - 4:
|
while len(hd) < 512 - 4:
|
||||||
hd += b"\x00"
|
hd += b"\x00"
|
||||||
hd += struct.pack("<I", UF2_MAGIC_END)
|
hd += struct.pack("<I", UF2_MAGIC_END)
|
||||||
return hd
|
return hd
|
||||||
|
|
||||||
|
|
||||||
def convert_from_hex_to_uf2(buf):
|
def convert_from_hex_to_uf2(buf):
|
||||||
global appstartaddr
|
global appstartaddr
|
||||||
appstartaddr = None
|
appstartaddr = None
|
||||||
upper = 0
|
upper = 0
|
||||||
currblock = None
|
currblock = None
|
||||||
blocks = []
|
blocks = []
|
||||||
for line in buf.split('\n'):
|
for line in buf.split("\n"):
|
||||||
if line[0] != ":":
|
if line[0] != ":":
|
||||||
continue
|
continue
|
||||||
i = 1
|
i = 1
|
||||||
rec = []
|
rec = []
|
||||||
while i < len(line) - 1:
|
while i < len(line) - 1:
|
||||||
rec.append(int(line[i:i+2], 16))
|
rec.append(int(line[i : i + 2], 16))
|
||||||
i += 2
|
i += 2
|
||||||
tp = rec[3]
|
tp = rec[3]
|
||||||
if tp == 4:
|
if tp == 4:
|
||||||
@@ -186,10 +212,10 @@ def convert_from_hex_to_uf2(buf):
|
|||||||
appstartaddr = addr
|
appstartaddr = addr
|
||||||
i = 4
|
i = 4
|
||||||
while i < len(rec) - 1:
|
while i < len(rec) - 1:
|
||||||
if not currblock or currblock.addr & ~0xff != addr & ~0xff:
|
if not currblock or currblock.addr & ~0xFF != addr & ~0xFF:
|
||||||
currblock = Block(addr & ~0xff)
|
currblock = Block(addr & ~0xFF)
|
||||||
blocks.append(currblock)
|
blocks.append(currblock)
|
||||||
currblock.bytes[addr & 0xff] = rec[i]
|
currblock.bytes[addr & 0xFF] = rec[i]
|
||||||
addr += 1
|
addr += 1
|
||||||
i += 1
|
i += 1
|
||||||
numblocks = len(blocks)
|
numblocks = len(blocks)
|
||||||
@@ -198,17 +224,21 @@ def convert_from_hex_to_uf2(buf):
|
|||||||
resfile += blocks[i].encode(i, numblocks)
|
resfile += blocks[i].encode(i, numblocks)
|
||||||
return resfile
|
return resfile
|
||||||
|
|
||||||
|
|
||||||
def to_str(b):
|
def to_str(b):
|
||||||
return b.decode("utf-8")
|
return b.decode("utf-8")
|
||||||
|
|
||||||
|
|
||||||
def get_drives():
|
def get_drives():
|
||||||
drives = []
|
drives = []
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
r = subprocess.check_output([
|
r = subprocess.check_output(
|
||||||
"powershell",
|
[
|
||||||
"-Command",
|
"powershell",
|
||||||
'(Get-WmiObject Win32_LogicalDisk -Filter "VolumeName=\'RPI-RP2\'").DeviceID'
|
"-Command",
|
||||||
])
|
"(Get-WmiObject Win32_LogicalDisk -Filter \"VolumeName='RPI-RP2'\").DeviceID",
|
||||||
|
]
|
||||||
|
)
|
||||||
drive = to_str(r).strip()
|
drive = to_str(r).strip()
|
||||||
if drive:
|
if drive:
|
||||||
drives.append(drive)
|
drives.append(drive)
|
||||||
@@ -217,7 +247,10 @@ def get_drives():
|
|||||||
if sys.platform == "darwin":
|
if sys.platform == "darwin":
|
||||||
searchpaths = ["/Volumes"]
|
searchpaths = ["/Volumes"]
|
||||||
elif sys.platform == "linux":
|
elif sys.platform == "linux":
|
||||||
searchpaths += ["/media/" + os.environ["USER"], "/run/media/" + os.environ["USER"]]
|
searchpaths += [
|
||||||
|
"/media/" + os.environ["USER"],
|
||||||
|
"/run/media/" + os.environ["USER"],
|
||||||
|
]
|
||||||
if "SUDO_USER" in os.environ.keys():
|
if "SUDO_USER" in os.environ.keys():
|
||||||
searchpaths += ["/media/" + os.environ["SUDO_USER"]]
|
searchpaths += ["/media/" + os.environ["SUDO_USER"]]
|
||||||
searchpaths += ["/run/media/" + os.environ["SUDO_USER"]]
|
searchpaths += ["/run/media/" + os.environ["SUDO_USER"]]
|
||||||
@@ -228,7 +261,6 @@ def get_drives():
|
|||||||
if os.path.isdir(os.path.join(rootpath, d)):
|
if os.path.isdir(os.path.join(rootpath, d)):
|
||||||
drives.append(os.path.join(rootpath, d))
|
drives.append(os.path.join(rootpath, d))
|
||||||
|
|
||||||
|
|
||||||
def has_info(d):
|
def has_info(d):
|
||||||
try:
|
try:
|
||||||
return os.path.isfile(d + INFO_FILE)
|
return os.path.isfile(d + INFO_FILE)
|
||||||
@@ -239,7 +271,7 @@ def get_drives():
|
|||||||
|
|
||||||
|
|
||||||
def board_id(path):
|
def board_id(path):
|
||||||
with open(path + INFO_FILE, mode='r') as file:
|
with open(path + INFO_FILE, mode="r") as file:
|
||||||
file_content = file.read()
|
file_content = file.read()
|
||||||
return re.search(r"Board-ID: ([^\r\n]*)", file_content).group(1)
|
return re.search(r"Board-ID: ([^\r\n]*)", file_content).group(1)
|
||||||
|
|
||||||
@@ -273,34 +305,70 @@ def load_families():
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
global appstartaddr, familyid
|
global appstartaddr, familyid
|
||||||
|
|
||||||
def error(msg):
|
def error(msg):
|
||||||
print(msg, file=sys.stderr)
|
print(msg, file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
parser = argparse.ArgumentParser(description='Convert to UF2 or flash directly.')
|
|
||||||
parser.add_argument('input', metavar='INPUT', type=str, nargs='?',
|
parser = argparse.ArgumentParser(description="Convert to UF2 or flash directly.")
|
||||||
help='input file (HEX, BIN or UF2)')
|
parser.add_argument(
|
||||||
parser.add_argument('-b', '--base', dest='base', type=str,
|
"input",
|
||||||
default="0x2000",
|
metavar="INPUT",
|
||||||
help='set base address of application for BIN format (default: 0x2000)')
|
type=str,
|
||||||
parser.add_argument('-f', '--family', dest='family', type=str,
|
nargs="?",
|
||||||
default="0x0",
|
help="input file (HEX, BIN or UF2)",
|
||||||
help='specify familyID - number or name (default: 0x0)')
|
)
|
||||||
parser.add_argument('-o', '--output', metavar="FILE", dest='output', type=str,
|
parser.add_argument(
|
||||||
help='write output to named file; defaults to "flash.uf2" or "flash.bin" where sensible')
|
"-b",
|
||||||
parser.add_argument('-d', '--device', dest="device_path",
|
"--base",
|
||||||
help='select a device path to flash')
|
dest="base",
|
||||||
parser.add_argument('-l', '--list', action='store_true',
|
type=str,
|
||||||
help='list connected devices')
|
default="0x2000",
|
||||||
parser.add_argument('-c', '--convert', action='store_true',
|
help="set base address of application for BIN format (default: 0x2000)",
|
||||||
help='do not flash, just convert')
|
)
|
||||||
parser.add_argument('-D', '--deploy', action='store_true',
|
parser.add_argument(
|
||||||
help='just flash, do not convert')
|
"-f",
|
||||||
parser.add_argument('-w', '--wait', action='store_true',
|
"--family",
|
||||||
help='wait for device to flash')
|
dest="family",
|
||||||
parser.add_argument('-C', '--carray', action='store_true',
|
type=str,
|
||||||
help='convert binary file to a C array, not UF2')
|
default="0x0",
|
||||||
parser.add_argument('-i', '--info', action='store_true',
|
help="specify familyID - number or name (default: 0x0)",
|
||||||
help='display header information from UF2, do not convert')
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-o",
|
||||||
|
"--output",
|
||||||
|
metavar="FILE",
|
||||||
|
dest="output",
|
||||||
|
type=str,
|
||||||
|
help='write output to named file; defaults to "flash.uf2" or "flash.bin" where sensible',
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-d", "--device", dest="device_path", help="select a device path to flash"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-l", "--list", action="store_true", help="list connected devices"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-c", "--convert", action="store_true", help="do not flash, just convert"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-D", "--deploy", action="store_true", help="just flash, do not convert"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-w", "--wait", action="store_true", help="wait for device to flash"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-C",
|
||||||
|
"--carray",
|
||||||
|
action="store_true",
|
||||||
|
help="convert binary file to a C array, not UF2",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"-i",
|
||||||
|
"--info",
|
||||||
|
action="store_true",
|
||||||
|
help="display header information from UF2, do not convert",
|
||||||
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
appstartaddr = int(args.base, 0)
|
appstartaddr = int(args.base, 0)
|
||||||
|
|
||||||
@@ -312,14 +380,17 @@ def main():
|
|||||||
try:
|
try:
|
||||||
familyid = int(args.family, 0)
|
familyid = int(args.family, 0)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
error("Family ID needs to be a number or one of: " + ", ".join(families.keys()))
|
error(
|
||||||
|
"Family ID needs to be a number or one of: "
|
||||||
|
+ ", ".join(families.keys())
|
||||||
|
)
|
||||||
|
|
||||||
if args.list:
|
if args.list:
|
||||||
list_drives()
|
list_drives()
|
||||||
else:
|
else:
|
||||||
if not args.input:
|
if not args.input:
|
||||||
error("Need input file")
|
error("Need input file")
|
||||||
with open(args.input, mode='rb') as f:
|
with open(args.input, mode="rb") as f:
|
||||||
inpbuf = f.read()
|
inpbuf = f.read()
|
||||||
from_uf2 = is_uf2(inpbuf)
|
from_uf2 = is_uf2(inpbuf)
|
||||||
ext = "uf2"
|
ext = "uf2"
|
||||||
@@ -339,8 +410,10 @@ def main():
|
|||||||
else:
|
else:
|
||||||
outbuf = convert_to_uf2(inpbuf)
|
outbuf = convert_to_uf2(inpbuf)
|
||||||
if not args.deploy and not args.info:
|
if not args.deploy and not args.info:
|
||||||
print("Converted to %s, output size: %d, start address: 0x%x" %
|
print(
|
||||||
(ext, len(outbuf), appstartaddr))
|
"Converted to %s, output size: %d, start address: 0x%x"
|
||||||
|
% (ext, len(outbuf), appstartaddr)
|
||||||
|
)
|
||||||
if args.convert or ext != "uf2":
|
if args.convert or ext != "uf2":
|
||||||
if args.output == None:
|
if args.output == None:
|
||||||
args.output = "flash." + ext
|
args.output = "flash." + ext
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file vector_table.c
|
|
||||||
* @brief Vector table with initial stack pointer and reset handler
|
|
||||||
* @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 <stdint.h>
|
|
||||||
|
|
||||||
extern uint32_t _stack_top;
|
|
||||||
extern void Reset_Handler(void);
|
|
||||||
|
|
||||||
typedef void (*vector_func_t)(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Vector table placed in .vectors section.
|
|
||||||
* The Thumb bit (bit 0 = 1) is automatically set by the linker
|
|
||||||
* for function pointers in Thumb mode.
|
|
||||||
*/
|
|
||||||
__attribute__((section(".vectors"), used))
|
|
||||||
const void *_vectors[2] = {
|
|
||||||
&_stack_top,
|
|
||||||
Reset_Handler
|
|
||||||
};
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file xosc.c
|
|
||||||
* @brief External crystal oscillator (XOSC) initialization and clock enable
|
|
||||||
* @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 "xosc.h"
|
|
||||||
#include "constants.h"
|
|
||||||
|
|
||||||
void Init_XOSC(void) {
|
|
||||||
// set delay 50,000 cycles
|
|
||||||
XOSC->STARTUP = 0x00C4U;
|
|
||||||
// set 1_15MHz, freq range, actual 14.5MHz
|
|
||||||
XOSC->CTRL = 0x00FABAA0U;
|
|
||||||
// wait until stable bit is set
|
|
||||||
while ((XOSC->STATUS & (1U << XOSC_STATUS_STABLE_SHIFT)) == 0) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Enable_XOSC_Peri_Clock(void) {
|
|
||||||
uint32_t value;
|
|
||||||
|
|
||||||
// read CLK_PERI_CTRL value
|
|
||||||
value = CLOCKS->CLK_PERI_CTRL;
|
|
||||||
// set ENABLE bit
|
|
||||||
value |= (1U << CLOCKS_CLK_PERI_CTRL_ENABLE_SHIFT);
|
|
||||||
// set AUXSRC: XOSC_CLKSRC
|
|
||||||
value |= (CLOCKS_CLK_PERI_CTRL_AUXSRC_XOSC << CLOCKS_CLK_PERI_CTRL_AUXSRC_SHIFT);
|
|
||||||
// store value into CLK_PERI_CTRL
|
|
||||||
CLOCKS->CLK_PERI_CTRL = value;
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
/**
|
|
||||||
* @file xosc.h
|
|
||||||
* @brief External crystal oscillator (XOSC) initialization and clock enable
|
|
||||||
* @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 XOSC_H
|
|
||||||
#define XOSC_H
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize the external crystal oscillator and wait until stable
|
|
||||||
*
|
|
||||||
* Configures the XOSC startup delay and frequency range, then polls
|
|
||||||
* the status register until the STABLE bit is set.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void Init_XOSC(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enable the XOSC peripheral clock
|
|
||||||
*
|
|
||||||
* Sets the peripheral clock to use XOSC as its auxiliary source and
|
|
||||||
* enables it via CLK_PERI_CTRL.
|
|
||||||
*
|
|
||||||
* @param None
|
|
||||||
* @retval None
|
|
||||||
*/
|
|
||||||
void Enable_XOSC_Peri_Clock(void);
|
|
||||||
|
|
||||||
#endif // XOSC_H
|
|
||||||
Reference in New Issue
Block a user