├── .gitignore ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── Package.swift ├── Plugins └── Link │ └── Link.swift ├── README.md └── Sources ├── App └── App.swift ├── MMIOVolatile ├── LICENSE.txt ├── MMIOVolatile.h ├── README.md └── module.modulemap ├── RP2040 ├── GPIO.swift ├── RP2040.swift ├── Reset.swift ├── Runtime.swift └── Timer.swift ├── RP2040Boot2 ├── LICENSE.TXT ├── README.md ├── compile_time_choice.S ├── headers │ ├── addressmap.h │ ├── asm_helper.s.h │ ├── boot2_generic_03h.s.h │ ├── boot_stage2-config.h │ ├── exit_from_boot2.s.h │ ├── hardware_regs-ssi.h │ └── m0plus.h └── linker-script │ └── boot_stage2.ld ├── RP2040Boot2Checksum ├── CLI.swift └── CRC32.swift └── RP2040Support ├── LICENSE.TXT ├── README.md ├── bootrom.c ├── crt0.S ├── headers ├── addressmap.h ├── asm_helper.s.h ├── bootrom.h ├── hardware_regs-ssi.h └── m0plus.h ├── linker-script └── memmap_default.ld └── pico_int64_ops_aeabi.S /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | xcuserdata/ 5 | DerivedData/ 6 | .swiftpm/configuration/registries.json 7 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 8 | .netrc 9 | 10 | build/ 11 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // Docs: https://code.visualstudio.com/docs/editor/debugging#_launch-configurations 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "preLaunchTask": "Build (release)", 9 | "type": "probe-rs-debug", 10 | "request": "launch", 11 | "name": "Flash & run (release)", 12 | "cwd": "${workspaceFolder}", 13 | "chip": "RP2040", 14 | "connectUnderReset": false, 15 | "flashingConfig": { 16 | "flashingEnabled": true, 17 | "haltAfterReset": false 18 | }, 19 | "coreConfigs": [ 20 | { 21 | "coreIndex": 0, 22 | "programBinary": "./.build/plugins/Link/outputs/App.elf" 23 | } 24 | ] 25 | } 26 | ] 27 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "swift.path": "/Library/Developer/Toolchains/swift-latest.xctoolchain/usr/bin", 3 | "lldb.library": "/Library/Developer/Toolchains/swift-latest.xctoolchain/System/Library/PrivateFrameworks/LLDB.framework/Versions/A/LLDB", 4 | "lldb.launch.expressions": "native" 5 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "Build (release)", 6 | "type": "swift", 7 | "args": [ 8 | "package", 9 | "--triple", 10 | "armv6m-none-none-eabi", 11 | "--toolchain", 12 | "/Library/Developer/Toolchains/swift-latest.xctoolchain/", 13 | "link", 14 | "--objcopy=/opt/homebrew/opt/llvm/bin/llvm-objcopy" 15 | ], 16 | "disableTaskQueue": true, 17 | "problemMatcher": [ 18 | "$swiftc" 19 | ], 20 | "group": "build", 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 5.10 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "RP2040", 8 | products: [ 9 | // The main executable for the RP2040, written in Swift. 10 | // This is the program we want to flash to the RP2040. 11 | // 12 | // Ideally, this would be an executable product, but I couldn't get that 13 | // to work under Embedded Swift. So we build a static library and then 14 | // use the Link plugin to link it into an .elf file. 15 | .library(name: "App", type: .static, targets: ["App"]), 16 | .library(name: "RP2040Boot2", type: .static, targets: ["RP2040Boot2"]), 17 | ], 18 | targets: [ 19 | // The main executable for the RP2040, written in Swift. 20 | .target( 21 | name: "App", 22 | dependencies: ["RP2040"], 23 | swiftSettings: [ 24 | .enableExperimentalFeature("Embedded"), 25 | .unsafeFlags([ 26 | "-whole-module-optimization", 27 | "-Xfrontend", "-function-sections", 28 | ]), 29 | ] 30 | ), 31 | // Our RP2040 "SDK", written in Swift. Vends the APIs used by the app. 32 | .target( 33 | name: "RP2040", 34 | dependencies: ["MMIOVolatile", "RP2040Support"], 35 | swiftSettings: [ 36 | .enableExperimentalFeature("Embedded"), 37 | .unsafeFlags([ 38 | "-whole-module-optimization", 39 | "-Xfrontend", "-function-sections", 40 | ]), 41 | ] 42 | ), 43 | .target(name: "MMIOVolatile", publicHeadersPath: ""), 44 | // Minimal RP2040 runtime support, linker script, etc. 45 | .target( 46 | name: "RP2040Support", 47 | exclude: [ 48 | "linker-script", 49 | ], 50 | publicHeadersPath: "", 51 | cSettings: [ 52 | .headerSearchPath("headers"), 53 | .define("NDEBUG"), 54 | .unsafeFlags([ 55 | "-mfloat-abi=soft", 56 | "-march=armv6m", 57 | "-ffunction-sections", 58 | "-fdata-sections", 59 | ]), 60 | ] 61 | ), 62 | // The second-stage bootloader (Boot2) for the RP2040. 63 | .target( 64 | name: "RP2040Boot2", 65 | exclude: [ 66 | "linker-script", 67 | ], 68 | publicHeadersPath: "", 69 | cSettings: [ 70 | .headerSearchPath("headers"), 71 | .define("NDEBUG"), 72 | .unsafeFlags([ 73 | "-mfloat-abi=soft", 74 | "-march=armv6m", 75 | "-ffunction-sections", 76 | "-fdata-sections", 77 | ]), 78 | ] 79 | ), 80 | // SwiftPM plugin for linking the final executable. 81 | // This creates the .elf file we can flash to the RP2040. 82 | .plugin( 83 | name: "Link", 84 | capability: .command( 85 | intent: .custom( 86 | verb: "link", 87 | description: "Links the final executable for the RP2040" 88 | ) 89 | ), 90 | dependencies: [ 91 | "RP2040Boot2Checksum", 92 | ] 93 | ), 94 | // Computes the CRC32 checksum for the second-stage bootloader. 95 | .executableTarget(name: "RP2040Boot2Checksum"), 96 | ] 97 | ) 98 | -------------------------------------------------------------------------------- /Plugins/Link/Link.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import PackagePlugin 3 | 4 | @main 5 | struct LinkCommand: CommandPlugin { 6 | static let pluginName: String = "link" 7 | 8 | static var logPrefix: String { 9 | "[\(pluginName)]" 10 | } 11 | 12 | func performCommand( 13 | context: PluginContext, 14 | arguments commandLineArguments: [String] 15 | ) async throws { 16 | let arguments = try parseArguments(commandLineArguments) 17 | guard !arguments.shouldShowHelp else { 18 | print( 19 | """ 20 | link: A SwiftPM command plugin for building an executable 21 | for the RP2040 microcontroller. 22 | 23 | USAGE: 24 | swift package --triple armv6m-none-none-eabi link [options] 25 | 26 | OPTIONS: 27 | --help Display this help message. 28 | --objcopy Path to LLVM's objcopy tool, e.g. llvm-objcopy. 29 | If omitted, we look for a tool named objcopy in 30 | your PATH. 31 | """ 32 | ) 33 | return 34 | } 35 | 36 | // Create directory for intermediate files 37 | let intermediatesDir = context.pluginWorkDirectory 38 | .appending("intermediates") 39 | try FileManager.default.createDirectory( 40 | at: URL(fileURLWithPath: intermediatesDir.string, isDirectory: true), 41 | withIntermediateDirectories: true 42 | ) 43 | 44 | // TODO: Can we use the default build parameters the user is specifying on the command line (`-c release`, `--verbose`)? 45 | let buildParameters = PackageManager.BuildParameters( 46 | configuration: .release, 47 | logging: .concise 48 | ) 49 | 50 | // Find external tools 51 | let clang = CommandLineTool(try context.tool(named: "clang")) 52 | let commonClangArgs = [ 53 | "--target=armv6m-none-eabi", 54 | "-mfloat-abi=soft", 55 | "-march=armv6m", 56 | "-O3", 57 | "-nostdlib", 58 | ] 59 | 60 | let objcopy: CommandLineTool 61 | do { 62 | // tool(named:) will find the tool if it's in the PATH, but it won't 63 | // find it if arguments.objcopyPath is a fully specified absolute or 64 | // relative path to a specific executable in a directory. 65 | let tool = try context.tool(named: arguments.objcopyPath ?? "objcopy") 66 | objcopy = CommandLineTool(tool) 67 | } catch { 68 | if let objcopyPath = arguments.objcopyPath { 69 | // Try to resolve the given path against the current working dir. 70 | let toolURL = URL(fileURLWithPath: objcopyPath, isDirectory: false).absoluteURL 71 | objcopy = CommandLineTool(name: "objcopy", url: toolURL) 72 | } else { 73 | throw error 74 | } 75 | } 76 | 77 | Diagnostics.remark("\(Self.logPrefix) clang: \(clang.path)") 78 | Diagnostics.remark("\(Self.logPrefix) objcopy: \(objcopy.path)") 79 | 80 | // Build and postprocess boot2 81 | let padChecksum = CommandLineTool(try context.tool(named: "RP2040Boot2Checksum")) 82 | let boot2Product = try context.package.products(named: ["RP2040Boot2"])[0] 83 | let boot2Outputs = try buildAndPostprocessBoot2( 84 | product: boot2Product, 85 | packageManager: packageManager, 86 | buildParameters: buildParameters, 87 | intermediatesDir: intermediatesDir, 88 | clang: clang, 89 | commonCFlags: commonClangArgs, 90 | objcopy: objcopy, 91 | padChecksum: padChecksum 92 | ) 93 | 94 | // Build the app 95 | Diagnostics.remark("\(Self.logPrefix) Creating app executable") 96 | let appProduct = try context.package.products(named: ["App"])[0] 97 | Diagnostics.remark("\(Self.logPrefix) Building product '\(appProduct.name)' with config '\(buildParameters.configuration.rawValue)'") 98 | let buildResult = try packageManager.build( 99 | .product(appProduct.name), 100 | parameters: buildParameters 101 | ) 102 | guard buildResult.succeeded else { 103 | // TODO: Is printing correct? Or will this result in duplicated output? Should this be a Diagnostic? 104 | print(buildResult.logText) 105 | Diagnostics.error("\(Self.logPrefix) Building product '\(appProduct.name)' failed") 106 | throw BuildError() 107 | } 108 | let appStaticLib = buildResult.builtArtifacts[0] 109 | 110 | // Link the app 111 | let executableFilename = "\(appProduct.name).elf" 112 | let executable = context.pluginWorkDirectory 113 | .appending(executableFilename) 114 | let rp2040SupportTarget = appProduct 115 | .targets[0] 116 | .recursiveTargetDependencies 117 | .first(where: { $0.name == "RP2040Support" })! 118 | let appLinkerScript = rp2040SupportTarget 119 | .directory 120 | .appending("linker-script", "memmap_default.ld") 121 | var appClangArgs = commonClangArgs 122 | appClangArgs.append(contentsOf: [ 123 | "-DNDEBUG", 124 | "-Wl,--build-id=none", 125 | "-Xlinker", "--gc-sections", 126 | "-Xlinker", "--script=\(appLinkerScript.string)", 127 | "-Xlinker", "-z", "-Xlinker", "max-page-size=4096", 128 | "-Xlinker", "--wrap=__aeabi_lmul", 129 | ]) 130 | appClangArgs.append(contentsOf: boot2Outputs.map(\.string)) 131 | appClangArgs.append(contentsOf: [ 132 | appStaticLib.path.string, 133 | "-o", executable.string, 134 | ]) 135 | try runProgram(clang.url, arguments: appClangArgs) 136 | 137 | print("Executable: \(executable)") 138 | } 139 | } 140 | 141 | struct CLIArguments { 142 | var shouldShowHelp: Bool 143 | var objcopyPath: Optional = nil 144 | } 145 | 146 | private func parseArguments(_ arguments: [String]) throws -> CLIArguments { 147 | var argumentExtractor = ArgumentExtractor(arguments) 148 | let shouldShowHelp = argumentExtractor.extractFlag(named: "help") > 0 149 | let objcopyArgs = argumentExtractor.extractOption(named: "objcopy") 150 | if objcopyArgs.count > 1 { 151 | Diagnostics.error("\(LinkCommand.logPrefix) Argument --objcopy specified multiple times") 152 | throw BuildError() 153 | } 154 | if !argumentExtractor.remainingArguments.isEmpty { 155 | Diagnostics.error("\(LinkCommand.logPrefix) Unrecognized arguments: \(argumentExtractor.remainingArguments.joined(separator: " "))") 156 | throw BuildError() 157 | } 158 | return CLIArguments( 159 | shouldShowHelp: shouldShowHelp, 160 | objcopyPath: objcopyArgs.first 161 | ) 162 | } 163 | 164 | /// Duplicate of `PluginContext.Tool`. Needed because that struct has no public 165 | /// initializer. 166 | struct CommandLineTool { 167 | var name: String 168 | var url: URL 169 | 170 | var path: String { 171 | url.path 172 | } 173 | } 174 | 175 | extension CommandLineTool { 176 | init(_ pluginContextTool: PluginContext.Tool) { 177 | self.name = pluginContextTool.name 178 | self.url = URL(fileURLWithPath: pluginContextTool.path.string, isDirectory: false) 179 | } 180 | } 181 | 182 | /// Builds the RP2040 second-stage bootloader (boot2). 183 | /// 184 | /// - Returns: An array of paths to object files that must be linked into the 185 | /// main app to create a valid RP2040 executable. 186 | private func buildAndPostprocessBoot2( 187 | product: some Product, 188 | packageManager: PackageManager, 189 | buildParameters: PackageManager.BuildParameters, 190 | intermediatesDir: Path, 191 | clang: CommandLineTool, 192 | commonCFlags: [String], 193 | objcopy: CommandLineTool, 194 | padChecksum: CommandLineTool 195 | ) throws -> [Path] { 196 | Diagnostics.remark("\(LinkCommand.logPrefix) Building second-stage bootloader (boot2)") 197 | Diagnostics.remark("\(LinkCommand.logPrefix) Building product '\(product.name)' with config '\(buildParameters.configuration.rawValue)'") 198 | let buildResult = try packageManager.build( 199 | .product(product.name), 200 | parameters: buildParameters 201 | ) 202 | guard buildResult.succeeded else { 203 | // TODO: Is printing correct? Or will this result in duplicated output? Should this be a Diagnostic? 204 | print(buildResult.logText) 205 | Diagnostics.error("\(LinkCommand.logPrefix) Building product '\(product.name)' failed") 206 | throw BuildError() 207 | } 208 | 209 | // Postprocessing 210 | Diagnostics.remark("\(LinkCommand.logPrefix) Calculating boot2 checksum and embedding it into the binary") 211 | 212 | // 1. Link boot2 into .elf file 213 | let boot2Target = product.targets[0] 214 | let linkerScript = boot2Target 215 | .directory 216 | .appending("linker-script", "boot_stage2.ld") 217 | let preChecksumELF = intermediatesDir.appending("bs2_default.elf") 218 | var preChecksumClangArgs = commonCFlags 219 | preChecksumClangArgs.append(contentsOf: [ 220 | "-DNDEBUG", 221 | "-Wl,--build-id=none", 222 | // We must tell the linker to keep all .o files in the .a file. 223 | // Without this, the linker will create an empty .elf file because no 224 | // symbols are referenced. 225 | // 226 | // On macOS, we may need -all_load or similar here. 227 | "-Xlinker", "--whole-archive", 228 | "-Xlinker", "--script=\(linkerScript.string)", 229 | "-o", preChecksumELF.string 230 | ]) 231 | preChecksumClangArgs.append(contentsOf: buildResult.builtArtifacts.map(\.path.string)) 232 | try runProgram(clang.url, arguments: preChecksumClangArgs) 233 | 234 | // 2. Convert .elf to .bin 235 | let preChecksumBin = intermediatesDir.appending("\(preChecksumELF.stem).bin") 236 | let objcopyArgs = [ 237 | "-Obinary", 238 | preChecksumELF.string, 239 | preChecksumBin.string 240 | ] 241 | try runProgram(objcopy.url, arguments: objcopyArgs) 242 | 243 | // 3. Calculate checksum and write into assembly file 244 | let checksummedAsm = intermediatesDir.appending("bs2_default_padded_checksummed.s") 245 | let padChecksumArgs = [ 246 | preChecksumBin.string, 247 | checksummedAsm.string 248 | ] 249 | try runProgram(padChecksum.url, arguments: padChecksumArgs) 250 | 251 | // 4. Assemble checksummed boot2 loader 252 | let checksummedObj = intermediatesDir.appending("bs2_default_padded_checksummed.s.o") 253 | var checksummedObjClangArgs = commonCFlags 254 | checksummedObjClangArgs.append(contentsOf: [ 255 | "-c", checksummedAsm.string, 256 | "-o", checksummedObj.string 257 | ]) 258 | try runProgram(clang.url, arguments: checksummedObjClangArgs) 259 | 260 | return [checksummedObj] 261 | } 262 | 263 | /// Runs an external program and waits for it to finish. 264 | /// 265 | /// Emits SwiftPM diagnostics: 266 | /// - `remark` with the invocation (exectuable + arguments) 267 | /// - `error` on non-zero exit code 268 | /// 269 | /// - Throws: 270 | /// - When the program cannot be launched. 271 | /// - Throws `ExitCode` when the program completes with a non-zero status. 272 | private func runProgram( 273 | _ executable: URL, 274 | arguments: [String], 275 | workingDirectory: Path? = nil 276 | ) throws { 277 | // If the command is longer than approx. one line, format it neatly 278 | // on multiple lines for logging. 279 | let fullCommand = "\(executable.path) \(arguments.joined(separator: " "))" 280 | let logMessage = if fullCommand.count < 70 { 281 | fullCommand 282 | } else { 283 | """ 284 | \(executable.path) \\ 285 | \(arguments.joined(separator: " \\\n ")) 286 | """ 287 | } 288 | Diagnostics.remark("\(LinkCommand.logPrefix) \(logMessage)") 289 | 290 | let process = Process() 291 | process.executableURL = executable 292 | process.arguments = arguments 293 | if let workingDirectory { 294 | process.currentDirectoryURL = URL( 295 | fileURLWithPath: workingDirectory.string, 296 | isDirectory: true 297 | ) 298 | } 299 | try process.run() 300 | process.waitUntilExit() 301 | guard process.terminationStatus == 0 else { 302 | Diagnostics.error("\(LinkCommand.logPrefix) \(executable.lastPathComponent) exited with code \(process.terminationStatus)") 303 | throw ExitCode(process.terminationStatus) 304 | } 305 | } 306 | 307 | struct ExitCode: RawRepresentable, Error { 308 | var rawValue: Int32 309 | 310 | init(rawValue: Int32) { 311 | self.rawValue = rawValue 312 | } 313 | 314 | init(_ code: Int32) { 315 | self.init(rawValue: code) 316 | } 317 | } 318 | 319 | struct BuildError: Error {} 320 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ”Bare bare metal” Embedded Swift on the RP2040 (Raspberry Pi Pico) 2 | 3 | Build a Swift executable for the Raspberry Pi Pico without the Pico C SDK. Tested on macOS 14 and Linux (Ubuntu 22.04). 4 | 5 | Swift forum discussion thread: 6 | 7 | ## Installation 8 | 9 | ### On macOS 10 | 11 | 1. Download and install a current [nightly Swift toolchain](https://www.swift.org/download/#snapshots) ("Trunk Development (main)"). Tested with 2024-02-15, newer versions will probably work too. The download is a `.pkg` installer that will install the toolchain into `/Library/Developer/Toolchains` or `~/Library/Developer/Toolchains`. 12 | 13 | 2. Install LLVM using Homebrew: 14 | 15 | ```sh 16 | brew install llvm 17 | ``` 18 | 19 | Note: This is necessary even though Xcode already comes with LLVM. We need (a) a linker that can produce `.elf` files, and (b) the tool `llvm-objcopy`. Xcode currently doesn’t provide these. Don’t worry, installing LLVM from Homebrew, won’t mess up your Xcode setup; Homebrew won’t place these tools into your `PATH`. 20 | 21 | 3. Put the `ld.lld` executable (this is the linker from LLVM you just installed) in your `PATH`. SwiftPM will be looking for this program and it needs to be able to find it. I have a `~/bin` directory that's already in my `PATH`, so I put a symlink to `ld.lld` in that folder: 22 | 23 | ```sh 24 | ln -s /opt/homebrew/opt/llvm/bin/ld.lld ~/bin/ld.lld 25 | ``` 26 | 27 | (If you’re on an Intel Mac, the path to your Homebrew may vary.) 28 | 29 | Alternatively, you could put this symlink in `/usr/local/bin` or some other directory in your `PATH`. Note: I advise against putting the `llvm/bin` directory itself in your `PATH` as Xcode and other build tools might get confused which one to use, but I haven’t tested this. 30 | 31 | 5. Install [`elf2uf2-rs`](https://crates.io/crates/elf2uf2-rs) and [`probe-rs`](https://probe.rs/) (requires a working Rust installation; see for guidance): 32 | 33 | ```sh 34 | cargo install elf2uf2-rs --locked 35 | cargo install probe-rs --features cli 36 | ``` 37 | 38 | We’ll use these tools to create the UF2 file for the Pico and/or flash the ELF file to the Pico. If you have other tools to do these jobs, feel free to use them. These are not required for the actual build process. 39 | 40 | ### On Linux 41 | 42 | 1. Install a current [nightly Swift toolchain](https://www.swift.org/download/#snapshots) ("Trunk Development (main)"). You can probably use [swiftly](https://swift-server.github.io/swiftly/) or [swiftenv](https://swiftenv.fuller.li/), or use one of the official Swift Docker images (I tested with `swiftlang/swift:nightly-jammy`). 43 | 44 | 2. Install the `objcopy` tool if you don't have it already. You probably already have this installed, type `objcopy --version` to verify. If not, install it with your distribution's package manager. 45 | 46 | We use `objcopy` in one of the build steps for the second-stage bootloader to convert a linked `.elf` file into the raw binary machine code representation (to compute the checksum for the bootloader). 47 | 48 | 3. Install [`elf2uf2-rs`](https://crates.io/crates/elf2uf2-rs) and [`probe-rs`](https://probe.rs/) (requires a working Rust installation; see for guidance): 49 | 50 | ```sh 51 | cargo install elf2uf2-rs --locked 52 | cargo install probe-rs --features cli 53 | ``` 54 | 55 | We’ll use these tools to create the UF2 file for the Pico and/or flash the ELF file to the Pico. If you have other tools to do these jobs, feel free to use them. These are not required for the actual build process. 56 | 57 | ## Building 58 | 59 | The normal SwiftPM commands `swift build` and `swift run` won’t work. You need to call `swift package link` with the correct arguments (see below) to build. This will use our custom SwiftPM command plugin for building and linking. 60 | 61 | ### On macOS 62 | 63 | ```sh 64 | # Build and link final executable App.elf 65 | swift package --triple armv6m-none-none-eabi \ 66 | --toolchain /Library/Developer/Toolchains/swift-latest.xctoolchain/ \ 67 | link \ 68 | --objcopy /opt/homebrew/opt/llvm/bin/llvm-objcopy 69 | ``` 70 | 71 | Adjust the path to the Swift toolchain you downloaded accordingly. It should be either `/Library/Developer/…` or `~/Library/Developer/…`. Note that we’re passing in the path to `llvm-objcopy` from the Homebrew LLVM install. 72 | 73 | Note: as of 2024-02-22, the macOS build produces dozens of warnings of the type "Class xyz is implemented in both \[path to toolchain\] and \[path to Xcode\]. One of the two will be used. Which one is undefined." I don't understand why these messages appear, but they don’t seem to be a problem. 74 | 75 | ### On Linux 76 | 77 | ```sh 78 | # Build and link final executable App.elf 79 | swift package --triple armv6m-none-none-eabi link 80 | ``` 81 | 82 | ## Flashing the executable to the Raspberry Pi Pico 83 | 84 | The build will produce an RP2040 executable in `.build/plugins/Link/outputs/App.elf`. 85 | 86 | If you have a [Raspberry Pi Debug Probe](https://www.raspberrypi.com/documentation/microcontrollers/debug-probe.html) or a second Pico that you can use as a debug probe, use `probe-rs` to flash it to the Pico: 87 | 88 | ```sh 89 | probe-rs run --chip RP2040 .build/plugins/Link/outputs/App.elf 90 | ``` 91 | 92 | Note: If `probe-rs` shows an error of the form "ERROR probe_rs::cmd::run: Failed to attach to RTT continuing..." after it says "Finished", you can ignore it. Use Ctrl+C to exit probe-rs. 93 | 94 | Alternatively, use `elf2uf2-rs` to create a UF2 file which you can then copy to the Pico in BOOTSEL mode: 95 | 96 | ```sh 97 | # Creates .build/plugins/Link/outputs/App.elf 98 | elf2uf2-rs .build/plugins/Link/outputs/App.elf 99 | ``` 100 | 101 | You should see the Pico’s onboard LED blinking. 102 | 103 | Note: If the LED is blinking very fast (to the point where it appears to be permanently on), try disconnecting and reconnecting the Pico from power. After reconnecting, you should observe the blinking to be approximately 20× slower. This is caused by a bug in our after-boot init code. See [issue 7](https://github.com/ole/swift-rp-pico-bare/issues/7) for details. 104 | -------------------------------------------------------------------------------- /Sources/App/App.swift: -------------------------------------------------------------------------------- 1 | import RP2040 2 | 3 | @main 4 | struct App { 5 | static func main() { 6 | // The program must call runtimeInit before using any peripherals. 7 | // This should usually be the first thing you call in main(). 8 | runtimeInit() 9 | 10 | let onboardLED = 25 11 | gpioInit(pin: onboardLED) 12 | gpioSetDirection(pin: onboardLED, out: true) 13 | gpioSet(pin: onboardLED, high: false) 14 | 15 | while true { 16 | gpioSet(pin: onboardLED, high: true) 17 | delayByCounting(to: 120_000) 18 | gpioSet(pin: onboardLED, high: false) 19 | delayByCounting(to: 120_000) 20 | } 21 | } 22 | } 23 | 24 | /// crt0.s calls this function when `main()` returns. 25 | /// 26 | /// Most `main()` functions start an infinite loop and never return, in which 27 | /// case `exit()` isn't needed. But it exists just in case `main()` does return. 28 | /// 29 | /// The usual implementation is to start an infinite loop, as there is no OS to 30 | /// return to. 31 | /// 32 | /// - TODO: Move this into the RP2040 module if possible. 33 | @_cdecl("exit") 34 | func exit(_ status: CInt) { 35 | _exit(status) 36 | } 37 | 38 | /// - TODO: Move this into the RP2040 module if possible. 39 | @_cdecl("_exit") 40 | func _exit(_ status: CInt) { 41 | while true { 42 | // Infinite loop 43 | } 44 | } 45 | 46 | /// Artificial delay by counting in a loop. 47 | /// 48 | /// We can delete this once we can talk to the timer peripheral. 49 | func delayByCounting(to limit: Int32) { 50 | // Optimization barrier 51 | @inline(never) 52 | func increment(_ value: inout Int32) { 53 | value &+= 1 54 | } 55 | 56 | var counter: Int32 = 0 57 | while counter < limit { 58 | increment(&counter) 59 | } 60 | return 61 | } 62 | -------------------------------------------------------------------------------- /Sources/MMIOVolatile/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | 204 | 205 | ## Runtime Library Exception to the Apache 2.0 License: ## 206 | 207 | 208 | As an exception, if you use this Software to compile your source code and 209 | portions of this Software are embedded into the binary product as a result, 210 | you may redistribute such product without providing attribution as would 211 | otherwise be required by Sections 4(a), 4(b) and 4(d) of the License. 212 | -------------------------------------------------------------------------------- /Sources/MMIOVolatile/MMIOVolatile.h: -------------------------------------------------------------------------------- 1 | //===--------------------------------------------------------------*- c -*-===// 2 | // 3 | // This source file is part of the Swift MMIO open source project 4 | // 5 | // Copyright (c) 2023 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | #pragma once 13 | 14 | // These defines are used instead of uintX_t types to avoid a dependency on 15 | // "stdint.h". It is _not_ a safe universal assumption to map these C types to 16 | // specific bit widths, however it should be safe for the platforms that Swift 17 | // currently supports. We expect to replace this module with a Swift language 18 | // primitive for volatile before needing to build for a platform which breaks 19 | // this mapping. 20 | typedef unsigned char uint8_t; 21 | typedef unsigned short uint16_t; 22 | typedef unsigned int uint32_t; 23 | typedef unsigned long long int uint64_t; 24 | 25 | #define VOLATILE_LOAD(type) \ 26 | __attribute__((always_inline)) \ 27 | static type mmio_volatile_load_##type( \ 28 | const volatile type * _Nonnull pointer) { return *pointer; } 29 | VOLATILE_LOAD(uint8_t); 30 | VOLATILE_LOAD(uint16_t); 31 | VOLATILE_LOAD(uint32_t); 32 | VOLATILE_LOAD(uint64_t); 33 | 34 | #define VOLATILE_STORE(type) \ 35 | __attribute__((always_inline)) \ 36 | static void mmio_volatile_store_##type( \ 37 | volatile type * _Nonnull pointer, type value) { *pointer = value; } 38 | VOLATILE_STORE(uint8_t); 39 | VOLATILE_STORE(uint16_t); 40 | VOLATILE_STORE(uint32_t); 41 | VOLATILE_STORE(uint64_t); 42 | -------------------------------------------------------------------------------- /Sources/MMIOVolatile/README.md: -------------------------------------------------------------------------------- 1 | The files in this directory have been copied from Apple’s [Swift-MMIO package](https://github.com/apple/swift-mmio/). 2 | 3 | They are licensed under [their original license](https://github.com/apple/swift-mmio/blob/main/LICENSE.txt) (Apache License 2.0). 4 | 5 | Once we can use SwiftPM as a build system, we should add Swift-MMIO as a dependency instead and delete this directory. 6 | -------------------------------------------------------------------------------- /Sources/MMIOVolatile/module.modulemap: -------------------------------------------------------------------------------- 1 | module MMIOVolatile { 2 | header "MMIOVolatile.h" 3 | export * 4 | } 5 | -------------------------------------------------------------------------------- /Sources/RP2040/GPIO.swift: -------------------------------------------------------------------------------- 1 | import MMIOVolatile 2 | 3 | // SIO = the RP2040’s single-cycle I/O block. 4 | // Reference documentation: https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf#tab-registerlist_sio 5 | let SIO_BASE: UInt32 = 0xd0000000 6 | let SIO_GPIO_IN_OFFSET: UInt32 = 0x00000004 7 | let SIO_GPIO_OUT_SET_OFFSET: UInt32 = 0x00000014 8 | let SIO_GPIO_OUT_CLR_OFFSET: UInt32 = 0x00000018 9 | let SIO_GPIO_OUT_ENABLE_SET_OFFSET: UInt32 = 0x00000024 10 | let SIO_GPIO_OUT_ENABLE_CLR_OFFSET: UInt32 = 0x00000028 11 | 12 | // Reference to datasheet: https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf#tab-registerlist_pads_bank0 13 | let PADS_BANK0_BASE: UInt32 = 0x4001c000 14 | let PADS_BANK0_GPIO0_OFFSET: UInt32 = 0x00000004 15 | let PADS_BANK0_GPIO0_BITS: UInt32 = 0x000000ff 16 | let PADS_BANK0_GPIO0_RESET: UInt32 = 0x00000056 17 | let PADS_BANK0_GPIO0_IE_BITS: UInt32 = 0x00000040 18 | let PADS_BANK0_GPIO0_OD_BITS: UInt32 = 0x00000080 19 | let PADS_BANK0_GPIO0_PUE_BITS: UInt32 = 0x00000008 20 | let PADS_BANK0_GPIO0_PUE_LSB: UInt32 = 3 21 | let PADS_BANK0_GPIO0_PDE_BITS: UInt32 = 0x00000004 22 | let PADS_BANK0_GPIO0_PDE_LSB: UInt32 = 2 23 | 24 | let IO_BANK0_BASE: UInt32 = 0x40014000 25 | let IO_BANK0_GPIO0_CTRL_OFFSET: UInt32 = 0x00000004 26 | let IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB = 0 27 | 28 | // Register address offsets for atomic RMW aliases 29 | let REG_ALIAS_RW_BITS: UInt32 = 0x0000 30 | let REG_ALIAS_XOR_BITS: UInt32 = 0x1000 31 | let REG_ALIAS_SET_BITS: UInt32 = 0x2000 32 | let REG_ALIAS_CLR_BITS: UInt32 = 0x3000 33 | 34 | public func gpioInit(pin: Int) { 35 | gpioSetDirection(pin: pin, out: true) 36 | gpioSet(pin: pin, high: false) 37 | gpioSetFunction(pin: pin, .SIO) 38 | } 39 | 40 | public enum GPIOFunction: Int { 41 | case XIP = 0 42 | case SPI = 1 43 | case UART = 2 44 | case I2C = 3 45 | case PWM = 4 46 | case SIO = 5 47 | case PIO0 = 6 48 | case PIO1 = 7 49 | case GPCK = 8 50 | case USB = 9 51 | case NULL = 0x1f 52 | } 53 | 54 | /// Select function for this GPIO, and ensure input/output are enabled at the pad. 55 | /// This also clears the input/output/irq override bits. 56 | public func gpioSetFunction(pin: Int, _ function: GPIOFunction) { 57 | // Set input enable on, output disable off 58 | let padsBank = UnsafeMutablePointer(bitPattern: UInt(PADS_BANK0_BASE) + UInt(PADS_BANK0_GPIO0_OFFSET) + (UInt(pin) * UInt(MemoryLayout.stride)))! 59 | hwWriteMasked( 60 | address: padsBank, 61 | values: PADS_BANK0_GPIO0_IE_BITS, 62 | mask: PADS_BANK0_GPIO0_IE_BITS | PADS_BANK0_GPIO0_OD_BITS 63 | ) 64 | // Zero all fields apart from fsel; we want this IO to do what the peripheral tells it. 65 | // This doesn't affect e.g. pullup/pulldown, as these are in pad controls. 66 | let controlReg = UnsafeMutablePointer(bitPattern: UInt(IO_BANK0_BASE) + UInt(pin * 2 * MemoryLayout.stride) + UInt(IO_BANK0_GPIO0_CTRL_OFFSET))! 67 | mmio_volatile_store_uint32_t(controlReg, UInt32(function.rawValue) << IO_BANK0_GPIO0_CTRL_FUNCSEL_LSB) 68 | } 69 | 70 | public func gpioSetDirection(pin: Int, out: Bool) { 71 | let mask: UInt32 = 1 << pin 72 | if out { 73 | gpioSetDirectionOutMasked(mask: mask) 74 | } else { 75 | gpioSetDirectionInMasked(mask: mask) 76 | } 77 | } 78 | 79 | func gpioSetDirectionOutMasked(mask: UInt32) { 80 | // sio_hw->gpio_oe_set = mask; 81 | let ptr = UnsafeMutablePointer(bitPattern: UInt(SIO_BASE + SIO_GPIO_OUT_ENABLE_SET_OFFSET))! 82 | mmio_volatile_store_uint32_t(ptr, mask) 83 | } 84 | 85 | func gpioSetDirectionInMasked(mask: UInt32) { 86 | // sio_hw->gpio_oe_clr = mask; 87 | let ptr = UnsafeMutablePointer(bitPattern: UInt(SIO_BASE + SIO_GPIO_OUT_ENABLE_CLR_OFFSET))! 88 | mmio_volatile_store_uint32_t(ptr, mask) 89 | } 90 | 91 | /// Set the specified GPIO to be pulled up. 92 | public func gpioPullUp(pin: Int) { 93 | gpioSetPulls(pin: pin, up: true, down: false) 94 | } 95 | 96 | public func gpioPullDown(pin: Int) { 97 | gpioSetPulls(pin: pin, up: false, down: true) 98 | } 99 | 100 | /// Select up and down pulls on specific GPIO. 101 | /// 102 | /// On RP2040, setting both pulls enables a "bus keep" function, 103 | /// i.e. weak pull to whatever is current high/low state of GPIO. 104 | public func gpioSetPulls(pin: Int, up: Bool, down: Bool) { 105 | let padsBank = UnsafeMutablePointer(bitPattern: UInt(PADS_BANK0_BASE) + UInt(PADS_BANK0_GPIO0_OFFSET) + (UInt(pin) * UInt(MemoryLayout.stride)))! 106 | let value: UInt32 = (up ? 1 : 0) << PADS_BANK0_GPIO0_PUE_LSB 107 | | (down ? 1 : 0) << PADS_BANK0_GPIO0_PDE_LSB 108 | let mask = PADS_BANK0_GPIO0_PUE_BITS | PADS_BANK0_GPIO0_PDE_BITS 109 | hwWriteMasked(address: padsBank, values: value, mask: mask) 110 | } 111 | 112 | // Get the value of a single GPIO 113 | public func gpioGet(pin: Int) -> Bool { 114 | let mask: UInt32 = 1 << pin 115 | // sio_hw->gpio_in 116 | let ptr = UnsafeMutablePointer(bitPattern: UInt(SIO_BASE + SIO_GPIO_IN_OFFSET))! 117 | let gpioIn = mmio_volatile_load_uint32_t(ptr) 118 | let isOn = (gpioIn & mask) != 0 119 | return isOn 120 | } 121 | 122 | public func gpioSet(pin: Int, high: Bool) { 123 | let mask: UInt32 = 1 << pin 124 | if high { 125 | gpioSetMasked(mask: mask) 126 | } else { 127 | gpioClearMasked(mask: mask) 128 | } 129 | } 130 | 131 | func gpioSetMasked(mask: UInt32) { 132 | // sio_hw->gpio_set = mask; 133 | let ptr = UnsafeMutablePointer(bitPattern: UInt(SIO_BASE + SIO_GPIO_OUT_SET_OFFSET))! 134 | mmio_volatile_store_uint32_t(ptr, mask) 135 | } 136 | 137 | func gpioClearMasked(mask: UInt32) { 138 | // sio_hw->gpio_clr = mask; 139 | let ptr = UnsafeMutablePointer(bitPattern: UInt(SIO_BASE + SIO_GPIO_OUT_CLR_OFFSET))! 140 | mmio_volatile_store_uint32_t(ptr, mask) 141 | } 142 | -------------------------------------------------------------------------------- /Sources/RP2040/RP2040.swift: -------------------------------------------------------------------------------- 1 | @_exported import MMIOVolatile 2 | 3 | /// Set new values for a sub-set of the bits in a HW register. 4 | /// 5 | /// Sets destination bits to values specified in \p values, if and only if corresponding bit in \p write_mask is set. 6 | func hwWriteMasked(address: UnsafeMutablePointer, values: UInt32, mask writeMask: UInt32) { 7 | hwXORBits(address: address, mask: (address.pointee ^ values) & writeMask) 8 | } 9 | 10 | func hwXORBits(address: UnsafeMutablePointer, mask: UInt32) { 11 | let rawPtr = UnsafeMutableRawPointer(address).advanced(by: Int(REG_ALIAS_XOR_BITS)) 12 | let ptr = rawPtr.assumingMemoryBound(to: UInt32.self) 13 | mmio_volatile_store_uint32_t(ptr, mask) 14 | } 15 | 16 | func hwSetBits(address: UnsafeMutablePointer, mask: UInt32) { 17 | let rawPtr = UnsafeMutableRawPointer(address).advanced(by: Int(REG_ALIAS_SET_BITS)) 18 | let ptr = rawPtr.assumingMemoryBound(to: UInt32.self) 19 | mmio_volatile_store_uint32_t(ptr, mask) 20 | } 21 | 22 | func hwClearBits(address: UnsafeMutablePointer, mask: UInt32) { 23 | let rawPtr = UnsafeMutableRawPointer(address).advanced(by: Int(REG_ALIAS_CLR_BITS)) 24 | let ptr = rawPtr.assumingMemoryBound(to: UInt32.self) 25 | mmio_volatile_store_uint32_t(ptr, mask) 26 | } 27 | -------------------------------------------------------------------------------- /Sources/RP2040/Reset.swift: -------------------------------------------------------------------------------- 1 | public let RESETS_BASE: UInt32 = 0x4000c000 2 | public let RESETS_RESET_OFFSET: UInt32 = 0x00000000 3 | public let RESETS_RESET_DONE_OFFSET: UInt32 = 0x00000008 4 | public let RESETS_RESET_BITS: UInt32 = 0x01ffffff 5 | public let RESETS_RESET_ADC_BITS: UInt32 = 0x00000001 6 | public let RESETS_RESET_IO_QSPI_BITS: UInt32 = 0x00000040 7 | public let RESETS_RESET_PADS_QSPI_BITS: UInt32 = 0x00000200 8 | public let RESETS_RESET_PLL_SYS_BITS: UInt32 = 0x00001000 9 | public let RESETS_RESET_PLL_USB_BITS: UInt32 = 0x00002000 10 | public let RESETS_RESET_RTC_BITS: UInt32 = 0x00008000 11 | public let RESETS_RESET_SPI0_BITS: UInt32 = 0x00010000 12 | public let RESETS_RESET_SPI1_BITS: UInt32 = 0x00020000 13 | public let RESETS_RESET_SYSCFG_BITS: UInt32 = 0x00040000 14 | public let RESETS_RESET_UART0_BITS: UInt32 = 0x00400000 15 | public let RESETS_RESET_UART1_BITS: UInt32 = 0x00800000 16 | public let RESETS_RESET_USBCTRL_BITS: UInt32 = 0x01000000 17 | 18 | /// Reset the specified HW blocks 19 | public func resetBlock(bits: UInt32) { 20 | let resets = UnsafeMutablePointer(bitPattern: UInt(RESETS_BASE + RESETS_RESET_OFFSET))! 21 | hwSetBits(address: resets, mask: bits) 22 | } 23 | 24 | /// Bring the specified HW blocks out of reset 25 | public func unresetBlock(bits: UInt32) { 26 | let resets = UnsafeMutablePointer(bitPattern: UInt(RESETS_BASE + RESETS_RESET_OFFSET))! 27 | hwClearBits(address: resets, mask: bits) 28 | } 29 | 30 | /// Bring the specified HW blocks out of reset and wait for completion 31 | public func unresetBlockAndWait(bits: UInt32) { 32 | unresetBlock(bits: bits) 33 | let resetDone = UnsafeMutablePointer(bitPattern: UInt(RESETS_BASE + RESETS_RESET_DONE_OFFSET))! 34 | while true { 35 | let isResetDone = ~mmio_volatile_load_uint32_t(resetDone) & bits == 0 36 | if isResetDone { 37 | break 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Sources/RP2040/Runtime.swift: -------------------------------------------------------------------------------- 1 | /// Performs the default initialization after boot. Brings the RP2040 2 | /// peripherals out of reset and initializes the clocks, incl. ramping up 3 | /// the CPU clock speed to full. 4 | /// 5 | /// The program must call this before using any peripherals. This should 6 | /// usually be the first function you call in `main()`. 7 | /// 8 | /// - Note: The Raspberry Pi Pico C SDK defines a function called `runtime_init` 9 | /// and calls it automatically just before calling `main()`. We decided to 10 | /// make this call an explicit step for transparency into the boot process. 11 | public func runtimeInit() { 12 | // Reset all peripherals to put system into a known state, 13 | // - except for QSPI pads and the XIP IO bank, as this is fatal if running from flash 14 | // - and the PLLs, as this is fatal if clock muxing has not been reset on this boot 15 | // - and USB, syscfg, as this disturbs USB-to-SWD on core 1 16 | // 17 | // Disables all peripherals except the ones listed in the bitmask. 18 | resetBlock(bits: ~( 19 | RESETS_RESET_IO_QSPI_BITS | 20 | RESETS_RESET_PADS_QSPI_BITS | 21 | RESETS_RESET_PLL_USB_BITS | 22 | RESETS_RESET_USBCTRL_BITS | 23 | RESETS_RESET_SYSCFG_BITS | 24 | RESETS_RESET_PLL_SYS_BITS 25 | )) 26 | 27 | // Remove reset from peripherals which are clocked only by clk_sys and 28 | // clk_ref. Other peripherals stay in reset until we've configured clocks. 29 | // 30 | // Enables all peripherals except the ones listed in the bitmask. 31 | // I.e. the peripherals listed here are the ones that 32 | // "stay in reset until we've configured clocks". 33 | unresetBlockAndWait(bits: RESETS_RESET_BITS & ~( 34 | RESETS_RESET_ADC_BITS | 35 | RESETS_RESET_RTC_BITS | 36 | RESETS_RESET_SPI0_BITS | 37 | RESETS_RESET_SPI1_BITS | 38 | RESETS_RESET_UART0_BITS | 39 | RESETS_RESET_UART1_BITS | 40 | RESETS_RESET_USBCTRL_BITS 41 | )) 42 | 43 | // Status at this point: 44 | // - ADC, RTC, SPI0, SPI1, UART0, UART1 are in reset (= disabled) 45 | // - The reset status of USBCTRL is unchanged 46 | // - All other peripherals are out of reset (= enabled) 47 | } 48 | -------------------------------------------------------------------------------- /Sources/RP2040/Timer.swift: -------------------------------------------------------------------------------- 1 | import MMIOVolatile 2 | 3 | let TIMER_BASE: UInt32 = 0x40054000 4 | /// Write to bits 63:32 of time 5 | let TIMER_TIMEHW_OFFSET: UInt32 = 0x00000000 6 | /// Write to bits 31:0 of time 7 | let TIMER_TIMELW_OFFSET: UInt32 = 0x00000004 8 | /// Read from bits 63:32 of time 9 | let TIMER_TIMEHR_OFFSET: UInt32 = 0x00000008 10 | /// Read from bits 31:0 of time 11 | let TIMER_TIMELR_OFFSET: UInt32 = 0x0000000c 12 | /// Raw read from bits 63:32 of time (no side effects) 13 | let TIMER_TIMERAWH_OFFSET: UInt32 = 0x00000024 14 | /// Raw read from bits 31:0 of time (no side effects) 15 | let TIMER_TIMERAWL_OFFSET: UInt32 = 0x00000028 16 | 17 | public func sleep(milliseconds delay: Int64) { 18 | sleep(microseconds: delay * 1000) 19 | } 20 | 21 | public func sleep(microseconds delay: Int64) { 22 | guard let delay = UInt64(exactly: delay) else { 23 | return 24 | } 25 | busyWait(microseconds: delay) 26 | } 27 | 28 | /// Returns the current timer value (microseconds since boot). 29 | public func currentTime() -> UInt64 { 30 | // Need to make sure that the upper 32 bits of the timer 31 | // don't change, so read that first 32 | let timeRawH = UnsafePointer(bitPattern: UInt(TIMER_BASE) + UInt(TIMER_TIMERAWH_OFFSET))! 33 | let timeRawL = UnsafePointer(bitPattern: UInt(TIMER_BASE) + UInt(TIMER_TIMERAWL_OFFSET))! 34 | var hi: UInt32 = mmio_volatile_load_uint32_t(timeRawH) 35 | var lo: UInt32 36 | repeat { 37 | // Read the lower 32 bits 38 | lo = mmio_volatile_load_uint32_t(timeRawL) 39 | // Now read the upper 32 bits again and 40 | // check that it hasn't incremented. If it has loop around 41 | // and read the lower 32 bits again to get an accurate value 42 | let nextHi = mmio_volatile_load_uint32_t(timeRawH) 43 | if hi == nextHi { 44 | break 45 | } 46 | hi = nextHi 47 | } while true 48 | return (UInt64(hi) << 32) | UInt64(lo) 49 | } 50 | 51 | func busyWait(microseconds delay: UInt64) { 52 | let base = currentTime() 53 | let target = base + delay 54 | guard target > base else { 55 | return 56 | } 57 | while currentTime() < target { 58 | // Spin 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Sources/RP2040Boot2/LICENSE.TXT: -------------------------------------------------------------------------------- 1 | Copyright 2020 (c) 2020 Raspberry Pi (Trading) Ltd. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 4 | following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following 7 | disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 10 | disclaimer in the documentation and/or other materials provided with the distribution. 11 | 12 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 16 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 18 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 20 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 21 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /Sources/RP2040Boot2/README.md: -------------------------------------------------------------------------------- 1 | The files in this directory have been copied from the [Raspberry Pi Pico C/C++ SDK](https://github.com/raspberrypi/pico-sdk/). 2 | 3 | They are licensed under the [Pico SDK license](https://github.com/raspberrypi/pico-sdk/blob/master/LICENSE.TXT) (BSD 3-Clause "New" or "Revised" License). 4 | 5 | Some of the files have been modified to either strip out unneeded functionality or to remove dependencies on other parts of the Pico SDK. You can track the modifications through the commit history. 6 | 7 | If you add a new file to this directory, make sure that the first commit always reflects the original state of the file in the Pico SDK. Modifications must be committed separately. 8 | -------------------------------------------------------------------------------- /Sources/RP2040Boot2/compile_time_choice.S: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Second stage boot code 3 | // Copyright (c) 2019-2021 Raspberry Pi (Trading) Ltd. 4 | // SPDX-License-Identifier: BSD-3-Clause 5 | // ---------------------------------------------------------------------------- 6 | // 7 | // This implementation uses the PICO_BOOT_STAGE2_CHOOSE_ preprocessor defines to pick 8 | // amongst a menu of known boot stage 2 implementations, allowing the board 9 | // configuration header to be able to specify the boot stage 2 10 | 11 | #include "boot_stage2-config.h" 12 | 13 | #ifdef PICO_BUILD_BOOT_STAGE2_NAME 14 | // boot stage 2 is configured by cmake, so use the name specified there 15 | #error PICO_BUILD_BOOT_STAGE2_NAME should not be defined for compile_time_choice builds 16 | #else 17 | // boot stage 2 is selected by board config header, and PICO_BOOT_STAGE2_ASM is set in boot_stage2/config.h 18 | #include PICO_BOOT_STAGE2_ASM 19 | #endif 20 | -------------------------------------------------------------------------------- /Sources/RP2040Boot2/headers/addressmap.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2021 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | #ifndef _ADDRESSMAP_H_ 7 | #define _ADDRESSMAP_H_ 8 | 9 | // Register address offsets for atomic RMW aliases 10 | #define REG_ALIAS_RW_BITS (0x0u << 12u) 11 | #define REG_ALIAS_XOR_BITS (0x1u << 12u) 12 | #define REG_ALIAS_SET_BITS (0x2u << 12u) 13 | #define REG_ALIAS_CLR_BITS (0x3u << 12u) 14 | 15 | #define ROM_BASE _u(0x00000000) 16 | #define XIP_BASE _u(0x10000000) 17 | #define XIP_MAIN_BASE _u(0x10000000) 18 | #define XIP_NOALLOC_BASE _u(0x11000000) 19 | #define XIP_NOCACHE_BASE _u(0x12000000) 20 | #define XIP_NOCACHE_NOALLOC_BASE _u(0x13000000) 21 | #define XIP_CTRL_BASE _u(0x14000000) 22 | #define XIP_SRAM_BASE _u(0x15000000) 23 | #define XIP_SRAM_END _u(0x15004000) 24 | #define XIP_SSI_BASE _u(0x18000000) 25 | #define SRAM_BASE _u(0x20000000) 26 | #define SRAM_STRIPED_BASE _u(0x20000000) 27 | #define SRAM_STRIPED_END _u(0x20040000) 28 | #define SRAM4_BASE _u(0x20040000) 29 | #define SRAM5_BASE _u(0x20041000) 30 | #define SRAM_END _u(0x20042000) 31 | #define SRAM0_BASE _u(0x21000000) 32 | #define SRAM1_BASE _u(0x21010000) 33 | #define SRAM2_BASE _u(0x21020000) 34 | #define SRAM3_BASE _u(0x21030000) 35 | #define SYSINFO_BASE _u(0x40000000) 36 | #define SYSCFG_BASE _u(0x40004000) 37 | #define CLOCKS_BASE _u(0x40008000) 38 | #define RESETS_BASE _u(0x4000c000) 39 | #define PSM_BASE _u(0x40010000) 40 | #define IO_BANK0_BASE _u(0x40014000) 41 | #define IO_QSPI_BASE _u(0x40018000) 42 | #define PADS_BANK0_BASE _u(0x4001c000) 43 | #define PADS_QSPI_BASE _u(0x40020000) 44 | #define XOSC_BASE _u(0x40024000) 45 | #define PLL_SYS_BASE _u(0x40028000) 46 | #define PLL_USB_BASE _u(0x4002c000) 47 | #define BUSCTRL_BASE _u(0x40030000) 48 | #define UART0_BASE _u(0x40034000) 49 | #define UART1_BASE _u(0x40038000) 50 | #define SPI0_BASE _u(0x4003c000) 51 | #define SPI1_BASE _u(0x40040000) 52 | #define I2C0_BASE _u(0x40044000) 53 | #define I2C1_BASE _u(0x40048000) 54 | #define ADC_BASE _u(0x4004c000) 55 | #define PWM_BASE _u(0x40050000) 56 | #define TIMER_BASE _u(0x40054000) 57 | #define WATCHDOG_BASE _u(0x40058000) 58 | #define RTC_BASE _u(0x4005c000) 59 | #define ROSC_BASE _u(0x40060000) 60 | #define VREG_AND_CHIP_RESET_BASE _u(0x40064000) 61 | #define TBMAN_BASE _u(0x4006c000) 62 | #define DMA_BASE _u(0x50000000) 63 | #define USBCTRL_DPRAM_BASE _u(0x50100000) 64 | #define USBCTRL_BASE _u(0x50100000) 65 | #define USBCTRL_REGS_BASE _u(0x50110000) 66 | #define PIO0_BASE _u(0x50200000) 67 | #define PIO1_BASE _u(0x50300000) 68 | #define XIP_AUX_BASE _u(0x50400000) 69 | #define SIO_BASE _u(0xd0000000) 70 | #define PPB_BASE _u(0xe0000000) 71 | 72 | #endif // _ADDRESSMAP_H_ 73 | -------------------------------------------------------------------------------- /Sources/RP2040Boot2/headers/asm_helper.s.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | // From platform.h 8 | #define WRAPPER_FUNC_NAME(x) __wrap_##x 9 | 10 | # note we don't do this by default in this file for backwards comaptibility with user code 11 | # that may include this file, but not use unified syntax. Note that this macro does equivalent 12 | # setup to the pico_default_asm macro for inline assembly in C code. 13 | .macro pico_default_asm_setup 14 | .syntax unified 15 | .cpu cortex-m0plus 16 | .thumb 17 | .endm 18 | 19 | // do not put align in here as it is used mid function sometimes 20 | .macro regular_func x 21 | .global \x 22 | .type \x,%function 23 | .thumb_func 24 | \x: 25 | .endm 26 | 27 | .macro regular_func_with_section x 28 | .section .text.\x 29 | regular_func \x 30 | .endm 31 | 32 | // do not put align in here as it is used mid function sometimes 33 | .macro wrapper_func x 34 | regular_func WRAPPER_FUNC_NAME(\x) 35 | .endm 36 | 37 | .macro __pre_init func, priority_string 38 | .section .preinit_array.\priority_string 39 | .align 2 40 | .word \func 41 | .endm 42 | 43 | -------------------------------------------------------------------------------- /Sources/RP2040Boot2/headers/boot2_generic_03h.s.h: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Second stage boot code 3 | // Copyright (c) 2019-2021 Raspberry Pi (Trading) Ltd. 4 | // SPDX-License-Identifier: BSD-3-Clause 5 | // 6 | // Device: Anything which responds to 03h serial read command 7 | // 8 | // Details: * Configure SSI to translate each APB read into a 03h command 9 | // * 8 command clocks, 24 address clocks and 32 data clocks 10 | // * This enables you to boot from almost anything: you can pretty 11 | // much solder a potato to your PCB, or a piece of cheese 12 | // * The tradeoff is performance around 3x worse than QSPI XIP 13 | // 14 | // Building: * This code must be position-independent, and use stack only 15 | // * The code will be padded to a size of 256 bytes, including a 16 | // 4-byte checksum. Therefore code size cannot exceed 252 bytes. 17 | // ---------------------------------------------------------------------------- 18 | 19 | #include "asm_helper.s.h" 20 | #include "addressmap.h" 21 | #include "hardware_regs-ssi.h" 22 | 23 | // platform.defs.h 24 | #ifndef _u 25 | #ifdef __ASSEMBLER__ 26 | #define _u(x) x 27 | #else 28 | #define _u(x) x ## u 29 | #endif 30 | #endif 31 | 32 | pico_default_asm_setup 33 | 34 | // ---------------------------------------------------------------------------- 35 | // Config section 36 | // ---------------------------------------------------------------------------- 37 | // It should be possible to support most flash devices by modifying this section 38 | 39 | // The serial flash interface will run at clk_sys/PICO_FLASH_SPI_CLKDIV. 40 | // This must be a positive, even integer. 41 | // The bootrom is very conservative with SPI frequency, but here we should be 42 | // as aggressive as possible. 43 | #ifndef PICO_FLASH_SPI_CLKDIV 44 | #define PICO_FLASH_SPI_CLKDIV 4 45 | #endif 46 | 47 | #define CMD_READ 0x03 48 | 49 | // Value is number of address bits divided by 4 50 | #define ADDR_L 6 51 | 52 | #define CTRLR0_XIP \ 53 | (SSI_CTRLR0_SPI_FRF_VALUE_STD << SSI_CTRLR0_SPI_FRF_LSB) | /* Standard 1-bit SPI serial frames */ \ 54 | (31 << SSI_CTRLR0_DFS_32_LSB) | /* 32 clocks per data frame */ \ 55 | (SSI_CTRLR0_TMOD_VALUE_EEPROM_READ << SSI_CTRLR0_TMOD_LSB) /* Send instr + addr, receive data */ 56 | 57 | #define SPI_CTRLR0_XIP \ 58 | (CMD_READ << SSI_SPI_CTRLR0_XIP_CMD_LSB) | /* Value of instruction prefix */ \ 59 | (ADDR_L << SSI_SPI_CTRLR0_ADDR_L_LSB) | /* Total number of address + mode bits */ \ 60 | (2 << SSI_SPI_CTRLR0_INST_L_LSB) | /* 8 bit command prefix (field value is bits divided by 4) */ \ 61 | (SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_1C1A << SSI_SPI_CTRLR0_TRANS_TYPE_LSB) /* command and address both in serial format */ 62 | 63 | // ---------------------------------------------------------------------------- 64 | // Start of 2nd Stage Boot Code 65 | // ---------------------------------------------------------------------------- 66 | 67 | .section .text 68 | 69 | regular_func _stage2_boot 70 | push {lr} 71 | 72 | ldr r3, =XIP_SSI_BASE // Use as base address where possible 73 | 74 | // Disable SSI to allow further config 75 | movs r1, #0 76 | str r1, [r3, #SSI_SSIENR_OFFSET] 77 | 78 | // Set baud rate 79 | movs r1, #PICO_FLASH_SPI_CLKDIV 80 | str r1, [r3, #SSI_BAUDR_OFFSET] 81 | 82 | ldr r1, =(CTRLR0_XIP) 83 | str r1, [r3, #SSI_CTRLR0_OFFSET] 84 | 85 | ldr r1, =(SPI_CTRLR0_XIP) 86 | ldr r0, =(XIP_SSI_BASE + SSI_SPI_CTRLR0_OFFSET) 87 | str r1, [r0] 88 | 89 | // NDF=0 (single 32b read) 90 | movs r1, #0x0 91 | str r1, [r3, #SSI_CTRLR1_OFFSET] 92 | 93 | // Re-enable SSI 94 | movs r1, #1 95 | str r1, [r3, #SSI_SSIENR_OFFSET] 96 | 97 | // We are now in XIP mode. Any bus accesses to the XIP address window will be 98 | // translated by the SSI into 03h read commands to the external flash (if cache is missed), 99 | // and the data will be returned to the bus. 100 | 101 | // Pull in standard exit routine 102 | #include "exit_from_boot2.s.h" 103 | 104 | .global literals 105 | literals: 106 | .ltorg 107 | 108 | .end 109 | -------------------------------------------------------------------------------- /Sources/RP2040Boot2/headers/boot_stage2-config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _BOOT_STAGE2_CONFIG_H 8 | #define _BOOT_STAGE2_CONFIG_H 9 | 10 | // NOTE THIS HEADER IS INCLUDED FROM ASSEMBLY 11 | 12 | // pico_base/include/pico.h 13 | // We may be included by assembly which cant include 14 | #define __PICO_STRING(x) #x 15 | #define __PICO_XSTRING(x) __PICO_STRING(x) 16 | #define __PICO_CONCAT1(x, y) x ## y 17 | 18 | // PICO_CONFIG: PICO_BUILD_BOOT_STAGE2_NAME, The name of the boot stage 2 if selected by the build, group=boot_stage2 19 | #ifdef PICO_BUILD_BOOT_STAGE2_NAME 20 | #define _BOOT_STAGE2_SELECTED 21 | #else 22 | // check that multiple boot stage 2 options haven't been set... 23 | 24 | // PICO_CONFIG: PICO_BOOT_STAGE2_CHOOSE_IS25LP080, Select boot2_is25lp080 as the boot stage 2 when no boot stage 2 selection is made by the CMake build, type=bool, default=0, group=boot_stage2 25 | #ifndef PICO_BOOT_STAGE2_CHOOSE_IS25LP080 26 | #define PICO_BOOT_STAGE2_CHOOSE_IS25LP080 0 27 | #elif PICO_BOOT_STAGE2_CHOOSE_IS25LP080 28 | #ifdef _BOOT_STAGE2_SELECTED 29 | #error multiple boot stage 2 options chosen 30 | #endif 31 | #define _BOOT_STAGE2_SELECTED 32 | #endif 33 | // PICO_CONFIG: PICO_BOOT_STAGE2_CHOOSE_W25Q080, Select boot2_w25q080 as the boot stage 2 when no boot stage 2 selection is made by the CMake build, type=bool, default=0, group=boot_stage2 34 | #ifndef PICO_BOOT_STAGE2_CHOOSE_W25Q080 35 | #define PICO_BOOT_STAGE2_CHOOSE_W25Q080 0 36 | #elif PICO_BOOT_STAGE2_CHOOSE_W25Q080 37 | #ifdef _BOOT_STAGE2_SELECTED 38 | #error multiple boot stage 2 options chosen 39 | #endif 40 | #define _BOOT_STAGE2_SELECTED 41 | #endif 42 | // PICO_CONFIG: PICO_BOOT_STAGE2_CHOOSE_W25X10CL, Select boot2_w25x10cl as the boot stage 2 when no boot stage 2 selection is made by the CMake build, type=bool, default=0, group=boot_stage2 43 | #ifndef PICO_BOOT_STAGE2_CHOOSE_W25X10CL 44 | #define PICO_BOOT_STAGE2_CHOOSE_W25X10CL 0 45 | #elif PICO_BOOT_STAGE2_CHOOSE_W25X10CL 46 | #ifdef _BOOT_STAGE2_SELECTED 47 | #error multiple boot stage 2 options chosen 48 | #endif 49 | #define _BOOT_STAGE2_SELECTED 50 | #endif 51 | // PICO_CONFIG: PICO_BOOT_STAGE2_CHOOSE_AT25SF128A, Select boot2_at25sf128a as the boot stage 2 when no boot stage 2 selection is made by the CMake build, type=bool, default=0, group=boot_stage2 52 | #ifndef PICO_BOOT_STAGE2_CHOOSE_AT25SF128A 53 | #define PICO_BOOT_STAGE2_CHOOSE_AT25SF128A 0 54 | #elif PICO_BOOT_STAGE2_CHOOSE_AT25SF128A 55 | #ifdef _BOOT_STAGE2_SELECTED 56 | #error multiple boot stage 2 options chosen 57 | #endif 58 | #define _BOOT_STAGE2_SELECTED 59 | #endif 60 | 61 | // PICO_CONFIG: PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H, Select boot2_generic_03h as the boot stage 2 when no boot stage 2 selection is made by the CMake build, type=bool, default=1, group=boot_stage2 62 | #if defined(PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H) && PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H 63 | #ifdef _BOOT_STAGE2_SELECTED 64 | #error multiple boot stage 2 options chosen 65 | #endif 66 | #define _BOOT_STAGE2_SELECTED 67 | #endif 68 | 69 | #endif // PICO_BUILD_BOOT_STAGE2_NAME 70 | 71 | #ifdef PICO_BUILD_BOOT_STAGE2_NAME 72 | // boot stage 2 is configured by cmake, so use the name specified there 73 | #define PICO_BOOT_STAGE2_NAME PICO_BUILD_BOOT_STAGE2_NAME 74 | #else 75 | // boot stage 2 is selected by board config header, so we have to do some work 76 | #if PICO_BOOT_STAGE2_CHOOSE_IS25LP080 77 | #define _BOOT_STAGE2 boot2_is25lp080 78 | #elif PICO_BOOT_STAGE2_CHOOSE_W25Q080 79 | #define _BOOT_STAGE2 boot2_w25q080 80 | #elif PICO_BOOT_STAGE2_CHOOSE_W25X10CL 81 | #define _BOOT_STAGE2 boot2_w25x10cl 82 | #elif PICO_BOOT_STAGE2_CHOOSE_AT25SF128A 83 | #define _BOOT_STAGE2 boot2_at25sf128a 84 | #elif !defined(PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H) || PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H 85 | #undef PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H 86 | #define PICO_BOOT_STAGE2_CHOOSE_GENERIC_03H 1 87 | #define _BOOT_STAGE2 boot2_generic_03h 88 | #else 89 | #error no boot stage 2 is defined by PICO_BOOT_STAGE2_CHOOSE_ macro 90 | #endif 91 | // we can't include cdefs in assembly, so define our own, but avoid conflict with real ones for c inclusion 92 | #define PICO_BOOT_STAGE2_NAME __PICO_XSTRING(_BOOT_STAGE2) 93 | #define PICO_BOOT_STAGE2_ASM __PICO_XSTRING(__PICO_CONCAT1(_BOOT_STAGE2,.s.h)) 94 | #endif 95 | #endif 96 | -------------------------------------------------------------------------------- /Sources/RP2040Boot2/headers/exit_from_boot2.s.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _BOOT2_HELPER_EXIT_FROM_BOOT2 8 | #define _BOOT2_HELPER_EXIT_FROM_BOOT2 9 | 10 | #include "m0plus.h" 11 | 12 | // If entered from the bootrom, lr (which we earlier pushed) will be 0, 13 | // and we vector through the table at the start of the main flash image. 14 | // Any regular function call will have a nonzero value for lr. 15 | check_return: 16 | pop {r0} 17 | cmp r0, #0 18 | beq vector_into_flash 19 | bx r0 20 | vector_into_flash: 21 | ldr r0, =(XIP_BASE + 0x100) 22 | ldr r1, =(PPB_BASE + M0PLUS_VTOR_OFFSET) 23 | str r0, [r1] 24 | ldmia r0, {r0, r1} 25 | msr msp, r0 26 | bx r1 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /Sources/RP2040Boot2/headers/hardware_regs-ssi.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2021 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | // ============================================================================= 7 | // Register block : SSI 8 | // Version : 1 9 | // Bus type : apb 10 | // Description : DW_apb_ssi has the following features: 11 | // * APB interface – Allows for easy integration into a 12 | // DesignWare Synthesizable Components for AMBA 2 13 | // implementation. 14 | // * APB3 and APB4 protocol support. 15 | // * Scalable APB data bus width – Supports APB data bus widths 16 | // of 8, 16, and 32 bits. 17 | // * Serial-master or serial-slave operation – Enables serial 18 | // communication with serial-master or serial-slave peripheral 19 | // devices. 20 | // * Programmable Dual/Quad/Octal SPI support in Master Mode. 21 | // * Dual Data Rate (DDR) and Read Data Strobe (RDS) Support - 22 | // Enables the DW_apb_ssi master to perform operations with the 23 | // device in DDR and RDS modes when working in Dual/Quad/Octal 24 | // mode of operation. 25 | // * Data Mask Support - Enables the DW_apb_ssi to selectively 26 | // update the bytes in the device. This feature is applicable 27 | // only in enhanced SPI modes. 28 | // * eXecute-In-Place (XIP) support - Enables the DW_apb_ssi 29 | // master to behave as a memory mapped I/O and fetches the data 30 | // from the device based on the APB read request. This feature 31 | // is applicable only in enhanced SPI modes. 32 | // * DMA Controller Interface – Enables the DW_apb_ssi to 33 | // interface to a DMA controller over the bus using a 34 | // handshaking interface for transfer requests. 35 | // * Independent masking of interrupts – Master collision, 36 | // transmit FIFO overflow, transmit FIFO empty, receive FIFO 37 | // full, receive FIFO underflow, and receive FIFO overflow 38 | // interrupts can all be masked independently. 39 | // * Multi-master contention detection – Informs the processor 40 | // of multiple serial-master accesses on the serial bus. 41 | // * Bypass of meta-stability flip-flops for synchronous clocks 42 | // – When the APB clock (pclk) and the DW_apb_ssi serial clock 43 | // (ssi_clk) are synchronous, meta-stable flip-flops are not 44 | // used when transferring control signals across these clock 45 | // domains. 46 | // * Programmable delay on the sample time of the received 47 | // serial data bit (rxd); enables programmable control of 48 | // routing delays resulting in higher serial data-bit rates. 49 | // * Programmable features: 50 | // - Serial interface operation – Choice of Motorola SPI, Texas 51 | // Instruments Synchronous Serial Protocol or National 52 | // Semiconductor Microwire. 53 | // - Clock bit-rate – Dynamic control of the serial bit rate of 54 | // the data transfer; used in only serial-master mode of 55 | // operation. 56 | // - Data Item size (4 to 32 bits) – Item size of each data 57 | // transfer under the control of the programmer. 58 | // * Configured features: 59 | // - FIFO depth – 16 words deep. The FIFO width is fixed at 32 60 | // bits. 61 | // - 1 slave select output. 62 | // - Hardware slave-select – Dedicated hardware slave-select 63 | // line. 64 | // - Combined interrupt line - one combined interrupt line from 65 | // the DW_apb_ssi to the interrupt controller. 66 | // - Interrupt polarity – active high interrupt lines. 67 | // - Serial clock polarity – low serial-clock polarity directly 68 | // after reset. 69 | // - Serial clock phase – capture on first edge of serial-clock 70 | // directly after reset. 71 | // ============================================================================= 72 | #ifndef HARDWARE_REGS_SSI_DEFINED 73 | #define HARDWARE_REGS_SSI_DEFINED 74 | // ============================================================================= 75 | // Register : SSI_CTRLR0 76 | // Description : Control register 0 77 | #define SSI_CTRLR0_OFFSET _u(0x00000000) 78 | #define SSI_CTRLR0_BITS _u(0x017fffff) 79 | #define SSI_CTRLR0_RESET _u(0x00000000) 80 | // ----------------------------------------------------------------------------- 81 | // Field : SSI_CTRLR0_SSTE 82 | // Description : Slave select toggle enable 83 | #define SSI_CTRLR0_SSTE_RESET _u(0x0) 84 | #define SSI_CTRLR0_SSTE_BITS _u(0x01000000) 85 | #define SSI_CTRLR0_SSTE_MSB _u(24) 86 | #define SSI_CTRLR0_SSTE_LSB _u(24) 87 | #define SSI_CTRLR0_SSTE_ACCESS "RW" 88 | // ----------------------------------------------------------------------------- 89 | // Field : SSI_CTRLR0_SPI_FRF 90 | // Description : SPI frame format 91 | // 0x0 -> Standard 1-bit SPI frame format; 1 bit per SCK, 92 | // full-duplex 93 | // 0x1 -> Dual-SPI frame format; two bits per SCK, half-duplex 94 | // 0x2 -> Quad-SPI frame format; four bits per SCK, half-duplex 95 | #define SSI_CTRLR0_SPI_FRF_RESET _u(0x0) 96 | #define SSI_CTRLR0_SPI_FRF_BITS _u(0x00600000) 97 | #define SSI_CTRLR0_SPI_FRF_MSB _u(22) 98 | #define SSI_CTRLR0_SPI_FRF_LSB _u(21) 99 | #define SSI_CTRLR0_SPI_FRF_ACCESS "RW" 100 | #define SSI_CTRLR0_SPI_FRF_VALUE_STD _u(0x0) 101 | #define SSI_CTRLR0_SPI_FRF_VALUE_DUAL _u(0x1) 102 | #define SSI_CTRLR0_SPI_FRF_VALUE_QUAD _u(0x2) 103 | // ----------------------------------------------------------------------------- 104 | // Field : SSI_CTRLR0_DFS_32 105 | // Description : Data frame size in 32b transfer mode 106 | // Value of n -> n+1 clocks per frame. 107 | #define SSI_CTRLR0_DFS_32_RESET _u(0x00) 108 | #define SSI_CTRLR0_DFS_32_BITS _u(0x001f0000) 109 | #define SSI_CTRLR0_DFS_32_MSB _u(20) 110 | #define SSI_CTRLR0_DFS_32_LSB _u(16) 111 | #define SSI_CTRLR0_DFS_32_ACCESS "RW" 112 | // ----------------------------------------------------------------------------- 113 | // Field : SSI_CTRLR0_CFS 114 | // Description : Control frame size 115 | // Value of n -> n+1 clocks per frame. 116 | #define SSI_CTRLR0_CFS_RESET _u(0x0) 117 | #define SSI_CTRLR0_CFS_BITS _u(0x0000f000) 118 | #define SSI_CTRLR0_CFS_MSB _u(15) 119 | #define SSI_CTRLR0_CFS_LSB _u(12) 120 | #define SSI_CTRLR0_CFS_ACCESS "RW" 121 | // ----------------------------------------------------------------------------- 122 | // Field : SSI_CTRLR0_SRL 123 | // Description : Shift register loop (test mode) 124 | #define SSI_CTRLR0_SRL_RESET _u(0x0) 125 | #define SSI_CTRLR0_SRL_BITS _u(0x00000800) 126 | #define SSI_CTRLR0_SRL_MSB _u(11) 127 | #define SSI_CTRLR0_SRL_LSB _u(11) 128 | #define SSI_CTRLR0_SRL_ACCESS "RW" 129 | // ----------------------------------------------------------------------------- 130 | // Field : SSI_CTRLR0_SLV_OE 131 | // Description : Slave output enable 132 | #define SSI_CTRLR0_SLV_OE_RESET _u(0x0) 133 | #define SSI_CTRLR0_SLV_OE_BITS _u(0x00000400) 134 | #define SSI_CTRLR0_SLV_OE_MSB _u(10) 135 | #define SSI_CTRLR0_SLV_OE_LSB _u(10) 136 | #define SSI_CTRLR0_SLV_OE_ACCESS "RW" 137 | // ----------------------------------------------------------------------------- 138 | // Field : SSI_CTRLR0_TMOD 139 | // Description : Transfer mode 140 | // 0x0 -> Both transmit and receive 141 | // 0x1 -> Transmit only (not for FRF == 0, standard SPI mode) 142 | // 0x2 -> Receive only (not for FRF == 0, standard SPI mode) 143 | // 0x3 -> EEPROM read mode (TX then RX; RX starts after control 144 | // data TX'd) 145 | #define SSI_CTRLR0_TMOD_RESET _u(0x0) 146 | #define SSI_CTRLR0_TMOD_BITS _u(0x00000300) 147 | #define SSI_CTRLR0_TMOD_MSB _u(9) 148 | #define SSI_CTRLR0_TMOD_LSB _u(8) 149 | #define SSI_CTRLR0_TMOD_ACCESS "RW" 150 | #define SSI_CTRLR0_TMOD_VALUE_TX_AND_RX _u(0x0) 151 | #define SSI_CTRLR0_TMOD_VALUE_TX_ONLY _u(0x1) 152 | #define SSI_CTRLR0_TMOD_VALUE_RX_ONLY _u(0x2) 153 | #define SSI_CTRLR0_TMOD_VALUE_EEPROM_READ _u(0x3) 154 | // ----------------------------------------------------------------------------- 155 | // Field : SSI_CTRLR0_SCPOL 156 | // Description : Serial clock polarity 157 | #define SSI_CTRLR0_SCPOL_RESET _u(0x0) 158 | #define SSI_CTRLR0_SCPOL_BITS _u(0x00000080) 159 | #define SSI_CTRLR0_SCPOL_MSB _u(7) 160 | #define SSI_CTRLR0_SCPOL_LSB _u(7) 161 | #define SSI_CTRLR0_SCPOL_ACCESS "RW" 162 | // ----------------------------------------------------------------------------- 163 | // Field : SSI_CTRLR0_SCPH 164 | // Description : Serial clock phase 165 | #define SSI_CTRLR0_SCPH_RESET _u(0x0) 166 | #define SSI_CTRLR0_SCPH_BITS _u(0x00000040) 167 | #define SSI_CTRLR0_SCPH_MSB _u(6) 168 | #define SSI_CTRLR0_SCPH_LSB _u(6) 169 | #define SSI_CTRLR0_SCPH_ACCESS "RW" 170 | // ----------------------------------------------------------------------------- 171 | // Field : SSI_CTRLR0_FRF 172 | // Description : Frame format 173 | #define SSI_CTRLR0_FRF_RESET _u(0x0) 174 | #define SSI_CTRLR0_FRF_BITS _u(0x00000030) 175 | #define SSI_CTRLR0_FRF_MSB _u(5) 176 | #define SSI_CTRLR0_FRF_LSB _u(4) 177 | #define SSI_CTRLR0_FRF_ACCESS "RW" 178 | // ----------------------------------------------------------------------------- 179 | // Field : SSI_CTRLR0_DFS 180 | // Description : Data frame size 181 | #define SSI_CTRLR0_DFS_RESET _u(0x0) 182 | #define SSI_CTRLR0_DFS_BITS _u(0x0000000f) 183 | #define SSI_CTRLR0_DFS_MSB _u(3) 184 | #define SSI_CTRLR0_DFS_LSB _u(0) 185 | #define SSI_CTRLR0_DFS_ACCESS "RW" 186 | // ============================================================================= 187 | // Register : SSI_CTRLR1 188 | // Description : Master Control register 1 189 | #define SSI_CTRLR1_OFFSET _u(0x00000004) 190 | #define SSI_CTRLR1_BITS _u(0x0000ffff) 191 | #define SSI_CTRLR1_RESET _u(0x00000000) 192 | // ----------------------------------------------------------------------------- 193 | // Field : SSI_CTRLR1_NDF 194 | // Description : Number of data frames 195 | #define SSI_CTRLR1_NDF_RESET _u(0x0000) 196 | #define SSI_CTRLR1_NDF_BITS _u(0x0000ffff) 197 | #define SSI_CTRLR1_NDF_MSB _u(15) 198 | #define SSI_CTRLR1_NDF_LSB _u(0) 199 | #define SSI_CTRLR1_NDF_ACCESS "RW" 200 | // ============================================================================= 201 | // Register : SSI_SSIENR 202 | // Description : SSI Enable 203 | #define SSI_SSIENR_OFFSET _u(0x00000008) 204 | #define SSI_SSIENR_BITS _u(0x00000001) 205 | #define SSI_SSIENR_RESET _u(0x00000000) 206 | // ----------------------------------------------------------------------------- 207 | // Field : SSI_SSIENR_SSI_EN 208 | // Description : SSI enable 209 | #define SSI_SSIENR_SSI_EN_RESET _u(0x0) 210 | #define SSI_SSIENR_SSI_EN_BITS _u(0x00000001) 211 | #define SSI_SSIENR_SSI_EN_MSB _u(0) 212 | #define SSI_SSIENR_SSI_EN_LSB _u(0) 213 | #define SSI_SSIENR_SSI_EN_ACCESS "RW" 214 | // ============================================================================= 215 | // Register : SSI_MWCR 216 | // Description : Microwire Control 217 | #define SSI_MWCR_OFFSET _u(0x0000000c) 218 | #define SSI_MWCR_BITS _u(0x00000007) 219 | #define SSI_MWCR_RESET _u(0x00000000) 220 | // ----------------------------------------------------------------------------- 221 | // Field : SSI_MWCR_MHS 222 | // Description : Microwire handshaking 223 | #define SSI_MWCR_MHS_RESET _u(0x0) 224 | #define SSI_MWCR_MHS_BITS _u(0x00000004) 225 | #define SSI_MWCR_MHS_MSB _u(2) 226 | #define SSI_MWCR_MHS_LSB _u(2) 227 | #define SSI_MWCR_MHS_ACCESS "RW" 228 | // ----------------------------------------------------------------------------- 229 | // Field : SSI_MWCR_MDD 230 | // Description : Microwire control 231 | #define SSI_MWCR_MDD_RESET _u(0x0) 232 | #define SSI_MWCR_MDD_BITS _u(0x00000002) 233 | #define SSI_MWCR_MDD_MSB _u(1) 234 | #define SSI_MWCR_MDD_LSB _u(1) 235 | #define SSI_MWCR_MDD_ACCESS "RW" 236 | // ----------------------------------------------------------------------------- 237 | // Field : SSI_MWCR_MWMOD 238 | // Description : Microwire transfer mode 239 | #define SSI_MWCR_MWMOD_RESET _u(0x0) 240 | #define SSI_MWCR_MWMOD_BITS _u(0x00000001) 241 | #define SSI_MWCR_MWMOD_MSB _u(0) 242 | #define SSI_MWCR_MWMOD_LSB _u(0) 243 | #define SSI_MWCR_MWMOD_ACCESS "RW" 244 | // ============================================================================= 245 | // Register : SSI_SER 246 | // Description : Slave enable 247 | // For each bit: 248 | // 0 -> slave not selected 249 | // 1 -> slave selected 250 | #define SSI_SER_OFFSET _u(0x00000010) 251 | #define SSI_SER_BITS _u(0x00000001) 252 | #define SSI_SER_RESET _u(0x00000000) 253 | #define SSI_SER_MSB _u(0) 254 | #define SSI_SER_LSB _u(0) 255 | #define SSI_SER_ACCESS "RW" 256 | // ============================================================================= 257 | // Register : SSI_BAUDR 258 | // Description : Baud rate 259 | #define SSI_BAUDR_OFFSET _u(0x00000014) 260 | #define SSI_BAUDR_BITS _u(0x0000ffff) 261 | #define SSI_BAUDR_RESET _u(0x00000000) 262 | // ----------------------------------------------------------------------------- 263 | // Field : SSI_BAUDR_SCKDV 264 | // Description : SSI clock divider 265 | #define SSI_BAUDR_SCKDV_RESET _u(0x0000) 266 | #define SSI_BAUDR_SCKDV_BITS _u(0x0000ffff) 267 | #define SSI_BAUDR_SCKDV_MSB _u(15) 268 | #define SSI_BAUDR_SCKDV_LSB _u(0) 269 | #define SSI_BAUDR_SCKDV_ACCESS "RW" 270 | // ============================================================================= 271 | // Register : SSI_TXFTLR 272 | // Description : TX FIFO threshold level 273 | #define SSI_TXFTLR_OFFSET _u(0x00000018) 274 | #define SSI_TXFTLR_BITS _u(0x000000ff) 275 | #define SSI_TXFTLR_RESET _u(0x00000000) 276 | // ----------------------------------------------------------------------------- 277 | // Field : SSI_TXFTLR_TFT 278 | // Description : Transmit FIFO threshold 279 | #define SSI_TXFTLR_TFT_RESET _u(0x00) 280 | #define SSI_TXFTLR_TFT_BITS _u(0x000000ff) 281 | #define SSI_TXFTLR_TFT_MSB _u(7) 282 | #define SSI_TXFTLR_TFT_LSB _u(0) 283 | #define SSI_TXFTLR_TFT_ACCESS "RW" 284 | // ============================================================================= 285 | // Register : SSI_RXFTLR 286 | // Description : RX FIFO threshold level 287 | #define SSI_RXFTLR_OFFSET _u(0x0000001c) 288 | #define SSI_RXFTLR_BITS _u(0x000000ff) 289 | #define SSI_RXFTLR_RESET _u(0x00000000) 290 | // ----------------------------------------------------------------------------- 291 | // Field : SSI_RXFTLR_RFT 292 | // Description : Receive FIFO threshold 293 | #define SSI_RXFTLR_RFT_RESET _u(0x00) 294 | #define SSI_RXFTLR_RFT_BITS _u(0x000000ff) 295 | #define SSI_RXFTLR_RFT_MSB _u(7) 296 | #define SSI_RXFTLR_RFT_LSB _u(0) 297 | #define SSI_RXFTLR_RFT_ACCESS "RW" 298 | // ============================================================================= 299 | // Register : SSI_TXFLR 300 | // Description : TX FIFO level 301 | #define SSI_TXFLR_OFFSET _u(0x00000020) 302 | #define SSI_TXFLR_BITS _u(0x000000ff) 303 | #define SSI_TXFLR_RESET _u(0x00000000) 304 | // ----------------------------------------------------------------------------- 305 | // Field : SSI_TXFLR_TFTFL 306 | // Description : Transmit FIFO level 307 | #define SSI_TXFLR_TFTFL_RESET _u(0x00) 308 | #define SSI_TXFLR_TFTFL_BITS _u(0x000000ff) 309 | #define SSI_TXFLR_TFTFL_MSB _u(7) 310 | #define SSI_TXFLR_TFTFL_LSB _u(0) 311 | #define SSI_TXFLR_TFTFL_ACCESS "RO" 312 | // ============================================================================= 313 | // Register : SSI_RXFLR 314 | // Description : RX FIFO level 315 | #define SSI_RXFLR_OFFSET _u(0x00000024) 316 | #define SSI_RXFLR_BITS _u(0x000000ff) 317 | #define SSI_RXFLR_RESET _u(0x00000000) 318 | // ----------------------------------------------------------------------------- 319 | // Field : SSI_RXFLR_RXTFL 320 | // Description : Receive FIFO level 321 | #define SSI_RXFLR_RXTFL_RESET _u(0x00) 322 | #define SSI_RXFLR_RXTFL_BITS _u(0x000000ff) 323 | #define SSI_RXFLR_RXTFL_MSB _u(7) 324 | #define SSI_RXFLR_RXTFL_LSB _u(0) 325 | #define SSI_RXFLR_RXTFL_ACCESS "RO" 326 | // ============================================================================= 327 | // Register : SSI_SR 328 | // Description : Status register 329 | #define SSI_SR_OFFSET _u(0x00000028) 330 | #define SSI_SR_BITS _u(0x0000007f) 331 | #define SSI_SR_RESET _u(0x00000000) 332 | // ----------------------------------------------------------------------------- 333 | // Field : SSI_SR_DCOL 334 | // Description : Data collision error 335 | #define SSI_SR_DCOL_RESET _u(0x0) 336 | #define SSI_SR_DCOL_BITS _u(0x00000040) 337 | #define SSI_SR_DCOL_MSB _u(6) 338 | #define SSI_SR_DCOL_LSB _u(6) 339 | #define SSI_SR_DCOL_ACCESS "RO" 340 | // ----------------------------------------------------------------------------- 341 | // Field : SSI_SR_TXE 342 | // Description : Transmission error 343 | #define SSI_SR_TXE_RESET _u(0x0) 344 | #define SSI_SR_TXE_BITS _u(0x00000020) 345 | #define SSI_SR_TXE_MSB _u(5) 346 | #define SSI_SR_TXE_LSB _u(5) 347 | #define SSI_SR_TXE_ACCESS "RO" 348 | // ----------------------------------------------------------------------------- 349 | // Field : SSI_SR_RFF 350 | // Description : Receive FIFO full 351 | #define SSI_SR_RFF_RESET _u(0x0) 352 | #define SSI_SR_RFF_BITS _u(0x00000010) 353 | #define SSI_SR_RFF_MSB _u(4) 354 | #define SSI_SR_RFF_LSB _u(4) 355 | #define SSI_SR_RFF_ACCESS "RO" 356 | // ----------------------------------------------------------------------------- 357 | // Field : SSI_SR_RFNE 358 | // Description : Receive FIFO not empty 359 | #define SSI_SR_RFNE_RESET _u(0x0) 360 | #define SSI_SR_RFNE_BITS _u(0x00000008) 361 | #define SSI_SR_RFNE_MSB _u(3) 362 | #define SSI_SR_RFNE_LSB _u(3) 363 | #define SSI_SR_RFNE_ACCESS "RO" 364 | // ----------------------------------------------------------------------------- 365 | // Field : SSI_SR_TFE 366 | // Description : Transmit FIFO empty 367 | #define SSI_SR_TFE_RESET _u(0x0) 368 | #define SSI_SR_TFE_BITS _u(0x00000004) 369 | #define SSI_SR_TFE_MSB _u(2) 370 | #define SSI_SR_TFE_LSB _u(2) 371 | #define SSI_SR_TFE_ACCESS "RO" 372 | // ----------------------------------------------------------------------------- 373 | // Field : SSI_SR_TFNF 374 | // Description : Transmit FIFO not full 375 | #define SSI_SR_TFNF_RESET _u(0x0) 376 | #define SSI_SR_TFNF_BITS _u(0x00000002) 377 | #define SSI_SR_TFNF_MSB _u(1) 378 | #define SSI_SR_TFNF_LSB _u(1) 379 | #define SSI_SR_TFNF_ACCESS "RO" 380 | // ----------------------------------------------------------------------------- 381 | // Field : SSI_SR_BUSY 382 | // Description : SSI busy flag 383 | #define SSI_SR_BUSY_RESET _u(0x0) 384 | #define SSI_SR_BUSY_BITS _u(0x00000001) 385 | #define SSI_SR_BUSY_MSB _u(0) 386 | #define SSI_SR_BUSY_LSB _u(0) 387 | #define SSI_SR_BUSY_ACCESS "RO" 388 | // ============================================================================= 389 | // Register : SSI_IMR 390 | // Description : Interrupt mask 391 | #define SSI_IMR_OFFSET _u(0x0000002c) 392 | #define SSI_IMR_BITS _u(0x0000003f) 393 | #define SSI_IMR_RESET _u(0x00000000) 394 | // ----------------------------------------------------------------------------- 395 | // Field : SSI_IMR_MSTIM 396 | // Description : Multi-master contention interrupt mask 397 | #define SSI_IMR_MSTIM_RESET _u(0x0) 398 | #define SSI_IMR_MSTIM_BITS _u(0x00000020) 399 | #define SSI_IMR_MSTIM_MSB _u(5) 400 | #define SSI_IMR_MSTIM_LSB _u(5) 401 | #define SSI_IMR_MSTIM_ACCESS "RW" 402 | // ----------------------------------------------------------------------------- 403 | // Field : SSI_IMR_RXFIM 404 | // Description : Receive FIFO full interrupt mask 405 | #define SSI_IMR_RXFIM_RESET _u(0x0) 406 | #define SSI_IMR_RXFIM_BITS _u(0x00000010) 407 | #define SSI_IMR_RXFIM_MSB _u(4) 408 | #define SSI_IMR_RXFIM_LSB _u(4) 409 | #define SSI_IMR_RXFIM_ACCESS "RW" 410 | // ----------------------------------------------------------------------------- 411 | // Field : SSI_IMR_RXOIM 412 | // Description : Receive FIFO overflow interrupt mask 413 | #define SSI_IMR_RXOIM_RESET _u(0x0) 414 | #define SSI_IMR_RXOIM_BITS _u(0x00000008) 415 | #define SSI_IMR_RXOIM_MSB _u(3) 416 | #define SSI_IMR_RXOIM_LSB _u(3) 417 | #define SSI_IMR_RXOIM_ACCESS "RW" 418 | // ----------------------------------------------------------------------------- 419 | // Field : SSI_IMR_RXUIM 420 | // Description : Receive FIFO underflow interrupt mask 421 | #define SSI_IMR_RXUIM_RESET _u(0x0) 422 | #define SSI_IMR_RXUIM_BITS _u(0x00000004) 423 | #define SSI_IMR_RXUIM_MSB _u(2) 424 | #define SSI_IMR_RXUIM_LSB _u(2) 425 | #define SSI_IMR_RXUIM_ACCESS "RW" 426 | // ----------------------------------------------------------------------------- 427 | // Field : SSI_IMR_TXOIM 428 | // Description : Transmit FIFO overflow interrupt mask 429 | #define SSI_IMR_TXOIM_RESET _u(0x0) 430 | #define SSI_IMR_TXOIM_BITS _u(0x00000002) 431 | #define SSI_IMR_TXOIM_MSB _u(1) 432 | #define SSI_IMR_TXOIM_LSB _u(1) 433 | #define SSI_IMR_TXOIM_ACCESS "RW" 434 | // ----------------------------------------------------------------------------- 435 | // Field : SSI_IMR_TXEIM 436 | // Description : Transmit FIFO empty interrupt mask 437 | #define SSI_IMR_TXEIM_RESET _u(0x0) 438 | #define SSI_IMR_TXEIM_BITS _u(0x00000001) 439 | #define SSI_IMR_TXEIM_MSB _u(0) 440 | #define SSI_IMR_TXEIM_LSB _u(0) 441 | #define SSI_IMR_TXEIM_ACCESS "RW" 442 | // ============================================================================= 443 | // Register : SSI_ISR 444 | // Description : Interrupt status 445 | #define SSI_ISR_OFFSET _u(0x00000030) 446 | #define SSI_ISR_BITS _u(0x0000003f) 447 | #define SSI_ISR_RESET _u(0x00000000) 448 | // ----------------------------------------------------------------------------- 449 | // Field : SSI_ISR_MSTIS 450 | // Description : Multi-master contention interrupt status 451 | #define SSI_ISR_MSTIS_RESET _u(0x0) 452 | #define SSI_ISR_MSTIS_BITS _u(0x00000020) 453 | #define SSI_ISR_MSTIS_MSB _u(5) 454 | #define SSI_ISR_MSTIS_LSB _u(5) 455 | #define SSI_ISR_MSTIS_ACCESS "RO" 456 | // ----------------------------------------------------------------------------- 457 | // Field : SSI_ISR_RXFIS 458 | // Description : Receive FIFO full interrupt status 459 | #define SSI_ISR_RXFIS_RESET _u(0x0) 460 | #define SSI_ISR_RXFIS_BITS _u(0x00000010) 461 | #define SSI_ISR_RXFIS_MSB _u(4) 462 | #define SSI_ISR_RXFIS_LSB _u(4) 463 | #define SSI_ISR_RXFIS_ACCESS "RO" 464 | // ----------------------------------------------------------------------------- 465 | // Field : SSI_ISR_RXOIS 466 | // Description : Receive FIFO overflow interrupt status 467 | #define SSI_ISR_RXOIS_RESET _u(0x0) 468 | #define SSI_ISR_RXOIS_BITS _u(0x00000008) 469 | #define SSI_ISR_RXOIS_MSB _u(3) 470 | #define SSI_ISR_RXOIS_LSB _u(3) 471 | #define SSI_ISR_RXOIS_ACCESS "RO" 472 | // ----------------------------------------------------------------------------- 473 | // Field : SSI_ISR_RXUIS 474 | // Description : Receive FIFO underflow interrupt status 475 | #define SSI_ISR_RXUIS_RESET _u(0x0) 476 | #define SSI_ISR_RXUIS_BITS _u(0x00000004) 477 | #define SSI_ISR_RXUIS_MSB _u(2) 478 | #define SSI_ISR_RXUIS_LSB _u(2) 479 | #define SSI_ISR_RXUIS_ACCESS "RO" 480 | // ----------------------------------------------------------------------------- 481 | // Field : SSI_ISR_TXOIS 482 | // Description : Transmit FIFO overflow interrupt status 483 | #define SSI_ISR_TXOIS_RESET _u(0x0) 484 | #define SSI_ISR_TXOIS_BITS _u(0x00000002) 485 | #define SSI_ISR_TXOIS_MSB _u(1) 486 | #define SSI_ISR_TXOIS_LSB _u(1) 487 | #define SSI_ISR_TXOIS_ACCESS "RO" 488 | // ----------------------------------------------------------------------------- 489 | // Field : SSI_ISR_TXEIS 490 | // Description : Transmit FIFO empty interrupt status 491 | #define SSI_ISR_TXEIS_RESET _u(0x0) 492 | #define SSI_ISR_TXEIS_BITS _u(0x00000001) 493 | #define SSI_ISR_TXEIS_MSB _u(0) 494 | #define SSI_ISR_TXEIS_LSB _u(0) 495 | #define SSI_ISR_TXEIS_ACCESS "RO" 496 | // ============================================================================= 497 | // Register : SSI_RISR 498 | // Description : Raw interrupt status 499 | #define SSI_RISR_OFFSET _u(0x00000034) 500 | #define SSI_RISR_BITS _u(0x0000003f) 501 | #define SSI_RISR_RESET _u(0x00000000) 502 | // ----------------------------------------------------------------------------- 503 | // Field : SSI_RISR_MSTIR 504 | // Description : Multi-master contention raw interrupt status 505 | #define SSI_RISR_MSTIR_RESET _u(0x0) 506 | #define SSI_RISR_MSTIR_BITS _u(0x00000020) 507 | #define SSI_RISR_MSTIR_MSB _u(5) 508 | #define SSI_RISR_MSTIR_LSB _u(5) 509 | #define SSI_RISR_MSTIR_ACCESS "RO" 510 | // ----------------------------------------------------------------------------- 511 | // Field : SSI_RISR_RXFIR 512 | // Description : Receive FIFO full raw interrupt status 513 | #define SSI_RISR_RXFIR_RESET _u(0x0) 514 | #define SSI_RISR_RXFIR_BITS _u(0x00000010) 515 | #define SSI_RISR_RXFIR_MSB _u(4) 516 | #define SSI_RISR_RXFIR_LSB _u(4) 517 | #define SSI_RISR_RXFIR_ACCESS "RO" 518 | // ----------------------------------------------------------------------------- 519 | // Field : SSI_RISR_RXOIR 520 | // Description : Receive FIFO overflow raw interrupt status 521 | #define SSI_RISR_RXOIR_RESET _u(0x0) 522 | #define SSI_RISR_RXOIR_BITS _u(0x00000008) 523 | #define SSI_RISR_RXOIR_MSB _u(3) 524 | #define SSI_RISR_RXOIR_LSB _u(3) 525 | #define SSI_RISR_RXOIR_ACCESS "RO" 526 | // ----------------------------------------------------------------------------- 527 | // Field : SSI_RISR_RXUIR 528 | // Description : Receive FIFO underflow raw interrupt status 529 | #define SSI_RISR_RXUIR_RESET _u(0x0) 530 | #define SSI_RISR_RXUIR_BITS _u(0x00000004) 531 | #define SSI_RISR_RXUIR_MSB _u(2) 532 | #define SSI_RISR_RXUIR_LSB _u(2) 533 | #define SSI_RISR_RXUIR_ACCESS "RO" 534 | // ----------------------------------------------------------------------------- 535 | // Field : SSI_RISR_TXOIR 536 | // Description : Transmit FIFO overflow raw interrupt status 537 | #define SSI_RISR_TXOIR_RESET _u(0x0) 538 | #define SSI_RISR_TXOIR_BITS _u(0x00000002) 539 | #define SSI_RISR_TXOIR_MSB _u(1) 540 | #define SSI_RISR_TXOIR_LSB _u(1) 541 | #define SSI_RISR_TXOIR_ACCESS "RO" 542 | // ----------------------------------------------------------------------------- 543 | // Field : SSI_RISR_TXEIR 544 | // Description : Transmit FIFO empty raw interrupt status 545 | #define SSI_RISR_TXEIR_RESET _u(0x0) 546 | #define SSI_RISR_TXEIR_BITS _u(0x00000001) 547 | #define SSI_RISR_TXEIR_MSB _u(0) 548 | #define SSI_RISR_TXEIR_LSB _u(0) 549 | #define SSI_RISR_TXEIR_ACCESS "RO" 550 | // ============================================================================= 551 | // Register : SSI_TXOICR 552 | // Description : TX FIFO overflow interrupt clear 553 | // Clear-on-read transmit FIFO overflow interrupt 554 | #define SSI_TXOICR_OFFSET _u(0x00000038) 555 | #define SSI_TXOICR_BITS _u(0x00000001) 556 | #define SSI_TXOICR_RESET _u(0x00000000) 557 | #define SSI_TXOICR_MSB _u(0) 558 | #define SSI_TXOICR_LSB _u(0) 559 | #define SSI_TXOICR_ACCESS "RO" 560 | // ============================================================================= 561 | // Register : SSI_RXOICR 562 | // Description : RX FIFO overflow interrupt clear 563 | // Clear-on-read receive FIFO overflow interrupt 564 | #define SSI_RXOICR_OFFSET _u(0x0000003c) 565 | #define SSI_RXOICR_BITS _u(0x00000001) 566 | #define SSI_RXOICR_RESET _u(0x00000000) 567 | #define SSI_RXOICR_MSB _u(0) 568 | #define SSI_RXOICR_LSB _u(0) 569 | #define SSI_RXOICR_ACCESS "RO" 570 | // ============================================================================= 571 | // Register : SSI_RXUICR 572 | // Description : RX FIFO underflow interrupt clear 573 | // Clear-on-read receive FIFO underflow interrupt 574 | #define SSI_RXUICR_OFFSET _u(0x00000040) 575 | #define SSI_RXUICR_BITS _u(0x00000001) 576 | #define SSI_RXUICR_RESET _u(0x00000000) 577 | #define SSI_RXUICR_MSB _u(0) 578 | #define SSI_RXUICR_LSB _u(0) 579 | #define SSI_RXUICR_ACCESS "RO" 580 | // ============================================================================= 581 | // Register : SSI_MSTICR 582 | // Description : Multi-master interrupt clear 583 | // Clear-on-read multi-master contention interrupt 584 | #define SSI_MSTICR_OFFSET _u(0x00000044) 585 | #define SSI_MSTICR_BITS _u(0x00000001) 586 | #define SSI_MSTICR_RESET _u(0x00000000) 587 | #define SSI_MSTICR_MSB _u(0) 588 | #define SSI_MSTICR_LSB _u(0) 589 | #define SSI_MSTICR_ACCESS "RO" 590 | // ============================================================================= 591 | // Register : SSI_ICR 592 | // Description : Interrupt clear 593 | // Clear-on-read all active interrupts 594 | #define SSI_ICR_OFFSET _u(0x00000048) 595 | #define SSI_ICR_BITS _u(0x00000001) 596 | #define SSI_ICR_RESET _u(0x00000000) 597 | #define SSI_ICR_MSB _u(0) 598 | #define SSI_ICR_LSB _u(0) 599 | #define SSI_ICR_ACCESS "RO" 600 | // ============================================================================= 601 | // Register : SSI_DMACR 602 | // Description : DMA control 603 | #define SSI_DMACR_OFFSET _u(0x0000004c) 604 | #define SSI_DMACR_BITS _u(0x00000003) 605 | #define SSI_DMACR_RESET _u(0x00000000) 606 | // ----------------------------------------------------------------------------- 607 | // Field : SSI_DMACR_TDMAE 608 | // Description : Transmit DMA enable 609 | #define SSI_DMACR_TDMAE_RESET _u(0x0) 610 | #define SSI_DMACR_TDMAE_BITS _u(0x00000002) 611 | #define SSI_DMACR_TDMAE_MSB _u(1) 612 | #define SSI_DMACR_TDMAE_LSB _u(1) 613 | #define SSI_DMACR_TDMAE_ACCESS "RW" 614 | // ----------------------------------------------------------------------------- 615 | // Field : SSI_DMACR_RDMAE 616 | // Description : Receive DMA enable 617 | #define SSI_DMACR_RDMAE_RESET _u(0x0) 618 | #define SSI_DMACR_RDMAE_BITS _u(0x00000001) 619 | #define SSI_DMACR_RDMAE_MSB _u(0) 620 | #define SSI_DMACR_RDMAE_LSB _u(0) 621 | #define SSI_DMACR_RDMAE_ACCESS "RW" 622 | // ============================================================================= 623 | // Register : SSI_DMATDLR 624 | // Description : DMA TX data level 625 | #define SSI_DMATDLR_OFFSET _u(0x00000050) 626 | #define SSI_DMATDLR_BITS _u(0x000000ff) 627 | #define SSI_DMATDLR_RESET _u(0x00000000) 628 | // ----------------------------------------------------------------------------- 629 | // Field : SSI_DMATDLR_DMATDL 630 | // Description : Transmit data watermark level 631 | #define SSI_DMATDLR_DMATDL_RESET _u(0x00) 632 | #define SSI_DMATDLR_DMATDL_BITS _u(0x000000ff) 633 | #define SSI_DMATDLR_DMATDL_MSB _u(7) 634 | #define SSI_DMATDLR_DMATDL_LSB _u(0) 635 | #define SSI_DMATDLR_DMATDL_ACCESS "RW" 636 | // ============================================================================= 637 | // Register : SSI_DMARDLR 638 | // Description : DMA RX data level 639 | #define SSI_DMARDLR_OFFSET _u(0x00000054) 640 | #define SSI_DMARDLR_BITS _u(0x000000ff) 641 | #define SSI_DMARDLR_RESET _u(0x00000000) 642 | // ----------------------------------------------------------------------------- 643 | // Field : SSI_DMARDLR_DMARDL 644 | // Description : Receive data watermark level (DMARDLR+1) 645 | #define SSI_DMARDLR_DMARDL_RESET _u(0x00) 646 | #define SSI_DMARDLR_DMARDL_BITS _u(0x000000ff) 647 | #define SSI_DMARDLR_DMARDL_MSB _u(7) 648 | #define SSI_DMARDLR_DMARDL_LSB _u(0) 649 | #define SSI_DMARDLR_DMARDL_ACCESS "RW" 650 | // ============================================================================= 651 | // Register : SSI_IDR 652 | // Description : Identification register 653 | #define SSI_IDR_OFFSET _u(0x00000058) 654 | #define SSI_IDR_BITS _u(0xffffffff) 655 | #define SSI_IDR_RESET _u(0x51535049) 656 | // ----------------------------------------------------------------------------- 657 | // Field : SSI_IDR_IDCODE 658 | // Description : Peripheral dentification code 659 | #define SSI_IDR_IDCODE_RESET _u(0x51535049) 660 | #define SSI_IDR_IDCODE_BITS _u(0xffffffff) 661 | #define SSI_IDR_IDCODE_MSB _u(31) 662 | #define SSI_IDR_IDCODE_LSB _u(0) 663 | #define SSI_IDR_IDCODE_ACCESS "RO" 664 | // ============================================================================= 665 | // Register : SSI_SSI_VERSION_ID 666 | // Description : Version ID 667 | #define SSI_SSI_VERSION_ID_OFFSET _u(0x0000005c) 668 | #define SSI_SSI_VERSION_ID_BITS _u(0xffffffff) 669 | #define SSI_SSI_VERSION_ID_RESET _u(0x3430312a) 670 | // ----------------------------------------------------------------------------- 671 | // Field : SSI_SSI_VERSION_ID_SSI_COMP_VERSION 672 | // Description : SNPS component version (format X.YY) 673 | #define SSI_SSI_VERSION_ID_SSI_COMP_VERSION_RESET _u(0x3430312a) 674 | #define SSI_SSI_VERSION_ID_SSI_COMP_VERSION_BITS _u(0xffffffff) 675 | #define SSI_SSI_VERSION_ID_SSI_COMP_VERSION_MSB _u(31) 676 | #define SSI_SSI_VERSION_ID_SSI_COMP_VERSION_LSB _u(0) 677 | #define SSI_SSI_VERSION_ID_SSI_COMP_VERSION_ACCESS "RO" 678 | // ============================================================================= 679 | // Register : SSI_DR0 680 | // Description : Data Register 0 (of 36) 681 | #define SSI_DR0_OFFSET _u(0x00000060) 682 | #define SSI_DR0_BITS _u(0xffffffff) 683 | #define SSI_DR0_RESET _u(0x00000000) 684 | // ----------------------------------------------------------------------------- 685 | // Field : SSI_DR0_DR 686 | // Description : First data register of 36 687 | #define SSI_DR0_DR_RESET _u(0x00000000) 688 | #define SSI_DR0_DR_BITS _u(0xffffffff) 689 | #define SSI_DR0_DR_MSB _u(31) 690 | #define SSI_DR0_DR_LSB _u(0) 691 | #define SSI_DR0_DR_ACCESS "RW" 692 | // ============================================================================= 693 | // Register : SSI_RX_SAMPLE_DLY 694 | // Description : RX sample delay 695 | #define SSI_RX_SAMPLE_DLY_OFFSET _u(0x000000f0) 696 | #define SSI_RX_SAMPLE_DLY_BITS _u(0x000000ff) 697 | #define SSI_RX_SAMPLE_DLY_RESET _u(0x00000000) 698 | // ----------------------------------------------------------------------------- 699 | // Field : SSI_RX_SAMPLE_DLY_RSD 700 | // Description : RXD sample delay (in SCLK cycles) 701 | #define SSI_RX_SAMPLE_DLY_RSD_RESET _u(0x00) 702 | #define SSI_RX_SAMPLE_DLY_RSD_BITS _u(0x000000ff) 703 | #define SSI_RX_SAMPLE_DLY_RSD_MSB _u(7) 704 | #define SSI_RX_SAMPLE_DLY_RSD_LSB _u(0) 705 | #define SSI_RX_SAMPLE_DLY_RSD_ACCESS "RW" 706 | // ============================================================================= 707 | // Register : SSI_SPI_CTRLR0 708 | // Description : SPI control 709 | #define SSI_SPI_CTRLR0_OFFSET _u(0x000000f4) 710 | #define SSI_SPI_CTRLR0_BITS _u(0xff07fb3f) 711 | #define SSI_SPI_CTRLR0_RESET _u(0x03000000) 712 | // ----------------------------------------------------------------------------- 713 | // Field : SSI_SPI_CTRLR0_XIP_CMD 714 | // Description : SPI Command to send in XIP mode (INST_L = 8-bit) or to append 715 | // to Address (INST_L = 0-bit) 716 | #define SSI_SPI_CTRLR0_XIP_CMD_RESET _u(0x03) 717 | #define SSI_SPI_CTRLR0_XIP_CMD_BITS _u(0xff000000) 718 | #define SSI_SPI_CTRLR0_XIP_CMD_MSB _u(31) 719 | #define SSI_SPI_CTRLR0_XIP_CMD_LSB _u(24) 720 | #define SSI_SPI_CTRLR0_XIP_CMD_ACCESS "RW" 721 | // ----------------------------------------------------------------------------- 722 | // Field : SSI_SPI_CTRLR0_SPI_RXDS_EN 723 | // Description : Read data strobe enable 724 | #define SSI_SPI_CTRLR0_SPI_RXDS_EN_RESET _u(0x0) 725 | #define SSI_SPI_CTRLR0_SPI_RXDS_EN_BITS _u(0x00040000) 726 | #define SSI_SPI_CTRLR0_SPI_RXDS_EN_MSB _u(18) 727 | #define SSI_SPI_CTRLR0_SPI_RXDS_EN_LSB _u(18) 728 | #define SSI_SPI_CTRLR0_SPI_RXDS_EN_ACCESS "RW" 729 | // ----------------------------------------------------------------------------- 730 | // Field : SSI_SPI_CTRLR0_INST_DDR_EN 731 | // Description : Instruction DDR transfer enable 732 | #define SSI_SPI_CTRLR0_INST_DDR_EN_RESET _u(0x0) 733 | #define SSI_SPI_CTRLR0_INST_DDR_EN_BITS _u(0x00020000) 734 | #define SSI_SPI_CTRLR0_INST_DDR_EN_MSB _u(17) 735 | #define SSI_SPI_CTRLR0_INST_DDR_EN_LSB _u(17) 736 | #define SSI_SPI_CTRLR0_INST_DDR_EN_ACCESS "RW" 737 | // ----------------------------------------------------------------------------- 738 | // Field : SSI_SPI_CTRLR0_SPI_DDR_EN 739 | // Description : SPI DDR transfer enable 740 | #define SSI_SPI_CTRLR0_SPI_DDR_EN_RESET _u(0x0) 741 | #define SSI_SPI_CTRLR0_SPI_DDR_EN_BITS _u(0x00010000) 742 | #define SSI_SPI_CTRLR0_SPI_DDR_EN_MSB _u(16) 743 | #define SSI_SPI_CTRLR0_SPI_DDR_EN_LSB _u(16) 744 | #define SSI_SPI_CTRLR0_SPI_DDR_EN_ACCESS "RW" 745 | // ----------------------------------------------------------------------------- 746 | // Field : SSI_SPI_CTRLR0_WAIT_CYCLES 747 | // Description : Wait cycles between control frame transmit and data reception 748 | // (in SCLK cycles) 749 | #define SSI_SPI_CTRLR0_WAIT_CYCLES_RESET _u(0x00) 750 | #define SSI_SPI_CTRLR0_WAIT_CYCLES_BITS _u(0x0000f800) 751 | #define SSI_SPI_CTRLR0_WAIT_CYCLES_MSB _u(15) 752 | #define SSI_SPI_CTRLR0_WAIT_CYCLES_LSB _u(11) 753 | #define SSI_SPI_CTRLR0_WAIT_CYCLES_ACCESS "RW" 754 | // ----------------------------------------------------------------------------- 755 | // Field : SSI_SPI_CTRLR0_INST_L 756 | // Description : Instruction length (0/4/8/16b) 757 | // 0x0 -> No instruction 758 | // 0x1 -> 4-bit instruction 759 | // 0x2 -> 8-bit instruction 760 | // 0x3 -> 16-bit instruction 761 | #define SSI_SPI_CTRLR0_INST_L_RESET _u(0x0) 762 | #define SSI_SPI_CTRLR0_INST_L_BITS _u(0x00000300) 763 | #define SSI_SPI_CTRLR0_INST_L_MSB _u(9) 764 | #define SSI_SPI_CTRLR0_INST_L_LSB _u(8) 765 | #define SSI_SPI_CTRLR0_INST_L_ACCESS "RW" 766 | #define SSI_SPI_CTRLR0_INST_L_VALUE_NONE _u(0x0) 767 | #define SSI_SPI_CTRLR0_INST_L_VALUE_4B _u(0x1) 768 | #define SSI_SPI_CTRLR0_INST_L_VALUE_8B _u(0x2) 769 | #define SSI_SPI_CTRLR0_INST_L_VALUE_16B _u(0x3) 770 | // ----------------------------------------------------------------------------- 771 | // Field : SSI_SPI_CTRLR0_ADDR_L 772 | // Description : Address length (0b-60b in 4b increments) 773 | #define SSI_SPI_CTRLR0_ADDR_L_RESET _u(0x0) 774 | #define SSI_SPI_CTRLR0_ADDR_L_BITS _u(0x0000003c) 775 | #define SSI_SPI_CTRLR0_ADDR_L_MSB _u(5) 776 | #define SSI_SPI_CTRLR0_ADDR_L_LSB _u(2) 777 | #define SSI_SPI_CTRLR0_ADDR_L_ACCESS "RW" 778 | // ----------------------------------------------------------------------------- 779 | // Field : SSI_SPI_CTRLR0_TRANS_TYPE 780 | // Description : Address and instruction transfer format 781 | // 0x0 -> Command and address both in standard SPI frame format 782 | // 0x1 -> Command in standard SPI format, address in format 783 | // specified by FRF 784 | // 0x2 -> Command and address both in format specified by FRF 785 | // (e.g. Dual-SPI) 786 | #define SSI_SPI_CTRLR0_TRANS_TYPE_RESET _u(0x0) 787 | #define SSI_SPI_CTRLR0_TRANS_TYPE_BITS _u(0x00000003) 788 | #define SSI_SPI_CTRLR0_TRANS_TYPE_MSB _u(1) 789 | #define SSI_SPI_CTRLR0_TRANS_TYPE_LSB _u(0) 790 | #define SSI_SPI_CTRLR0_TRANS_TYPE_ACCESS "RW" 791 | #define SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_1C1A _u(0x0) 792 | #define SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_1C2A _u(0x1) 793 | #define SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_2C2A _u(0x2) 794 | // ============================================================================= 795 | // Register : SSI_TXD_DRIVE_EDGE 796 | // Description : TX drive edge 797 | #define SSI_TXD_DRIVE_EDGE_OFFSET _u(0x000000f8) 798 | #define SSI_TXD_DRIVE_EDGE_BITS _u(0x000000ff) 799 | #define SSI_TXD_DRIVE_EDGE_RESET _u(0x00000000) 800 | // ----------------------------------------------------------------------------- 801 | // Field : SSI_TXD_DRIVE_EDGE_TDE 802 | // Description : TXD drive edge 803 | #define SSI_TXD_DRIVE_EDGE_TDE_RESET _u(0x00) 804 | #define SSI_TXD_DRIVE_EDGE_TDE_BITS _u(0x000000ff) 805 | #define SSI_TXD_DRIVE_EDGE_TDE_MSB _u(7) 806 | #define SSI_TXD_DRIVE_EDGE_TDE_LSB _u(0) 807 | #define SSI_TXD_DRIVE_EDGE_TDE_ACCESS "RW" 808 | // ============================================================================= 809 | #endif // HARDWARE_REGS_SSI_DEFINED 810 | -------------------------------------------------------------------------------- /Sources/RP2040Boot2/linker-script/boot_stage2.ld: -------------------------------------------------------------------------------- 1 | MEMORY { 2 | /* We are loaded to the top 256 bytes of SRAM, which is above the bootrom 3 | stack. Note 4 bytes occupied by checksum. */ 4 | SRAM(rx) : ORIGIN = 0x20041f00, LENGTH = 252 5 | } 6 | 7 | SECTIONS { 8 | . = ORIGIN(SRAM); 9 | .text : { 10 | *(.entry) 11 | *(.text) 12 | } >SRAM 13 | } 14 | -------------------------------------------------------------------------------- /Sources/RP2040Boot2Checksum/CLI.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// A command-line tool for computing the checksum for the RP2040 second-stage 4 | /// bootloader (boot2) and writing the checksum into the file. The RP2040 won't 5 | /// boot if the checksum is missing or incorrect. 6 | /// 7 | /// This tool performs the same task as the `pad_checksum` Python script in the 8 | /// Raspberry Pi Pico SDK . 9 | /// Writing it in Swift avoids the Python dependency. 10 | /// 11 | /// As documented in the RP2040 Datasheet: 12 | /// 13 | /// > 2.8.1.3.1. Checksum 14 | /// > 15 | /// > The last four bytes of the image loaded from flash (which we hope is a valid 16 | /// > flash second stage) are a CRC32 checksum of the first 252 bytes. 17 | /// > The parameters of the checksum are: 18 | /// > 19 | /// > - Polynomial: `0x04c11db7` 20 | /// > - Input reflection: no 21 | /// > - Output reflection: no 22 | /// > - Initial value: `0xffffffff` 23 | /// > - Final XOR: 0x00000000 24 | /// > - Checksum value appears as little-endian integer at end of image 25 | /// > 26 | /// > The Bootrom makes 128 attempts of approximately 4 ms each for a total of 27 | /// > approximately 0.5 seconds before giving up and dropping into USB code to load 28 | /// > and checksum the second stage with varying SPI parameters. If it sees a 29 | /// > checksum pass it will immediately jump into the 252-byte payload which 30 | /// > contains the flash second stage. 31 | @main 32 | struct CLI { 33 | static func main() throws { 34 | // Do not use the ArgumentParser library 35 | // to avoid the dependency. This is fine because this is not a public 36 | // tool, we're only calling it from within the build process. 37 | // If we ever need ArgumentParser for other reasons, we should use it 38 | // here too. 39 | if CommandLine.arguments.count != 3 { 40 | throw CLIError(message: "Usage: \(CommandLine.arguments[0]) ") 41 | } 42 | 43 | let inputFile: String = CommandLine.arguments[1] 44 | let outputFile: String = CommandLine.arguments[2] 45 | 46 | let inputURL = URL(fileURLWithPath: inputFile) 47 | let inputData = try Data(contentsOf: inputURL) 48 | 49 | // Boot2 must be exactly 256 bytes long, including the checksum. 50 | let paddedSize = 256 51 | let checksumLength = 4 52 | let maxInputLength = paddedSize - checksumLength 53 | let paddingLength = maxInputLength - inputData.count 54 | guard paddingLength >= 0 else { 55 | throw CLIError(message: "Input file size (\(inputData.count) bytes) is too large for output size (\(paddedSize) bytes). Maximum allowed input file size: \(maxInputLength) bytes") 56 | } 57 | 58 | var padded = Array(inputData) 59 | padded.append(contentsOf: Array(repeating: 0, count: paddingLength)) 60 | 61 | let checksum = crc32( 62 | message: padded, 63 | polynomial: 0x04c1_1db7, 64 | initialValue: 0xffff_ffff, 65 | xorOut: 0x0000_0000 66 | ) 67 | var littleEndianChecksum = checksum.littleEndian 68 | var checksummed = padded 69 | withUnsafeBytes(of: &littleEndianChecksum) { buffer in 70 | for byte in buffer { 71 | checksummed.append(byte) 72 | } 73 | } 74 | 75 | // Write output file as assembly code that places the 256 bytes into the 76 | // correct section. The output file must then be assembled again in 77 | // another build step. 78 | // 79 | // We follow the formatting of the pad_checksum Python script in the 80 | // RP2040 SDK. 81 | var output = """ 82 | // Padded and checksummed copy of: \(inputURL.absoluteURL.path) 83 | 84 | .cpu cortex-m0plus 85 | .thumb 86 | 87 | .section .boot2, "ax" 88 | \n 89 | """ 90 | for bytes in checksummed.chunks(ofCount: 16) { 91 | let commaSeparatedHexBytes = bytes 92 | .map { byte in "0x\(byte.hex())" } 93 | .joined(separator: ", ") 94 | output.append(".byte \(commaSeparatedHexBytes)\n") 95 | } 96 | 97 | let outputURL = URL(fileURLWithPath: outputFile) 98 | try Data(output.utf8).write(to: outputURL) 99 | } 100 | } 101 | 102 | struct CLIError: Error { 103 | var message: String 104 | } 105 | 106 | extension Sequence { 107 | func chunks(ofCount chunkSize: Int) -> [[Element]] { 108 | precondition(chunkSize > 0, "Expected chunkSize > 0, actual value was \(chunkSize)") 109 | var result: [[Element]] = [] 110 | var iterator = self.makeIterator() 111 | var currentChunk: [Element] = [] 112 | while let element = iterator.next() { 113 | currentChunk.append(element) 114 | if currentChunk.count == chunkSize { 115 | result.append(currentChunk) 116 | currentChunk.removeAll(keepingCapacity: true) 117 | } 118 | } 119 | if !currentChunk.isEmpty { 120 | result.append(currentChunk) 121 | } 122 | return result 123 | } 124 | } 125 | 126 | extension UInt8 { 127 | func hex(uppercase: Bool = false) -> String { 128 | let hexString = String(self, radix: 16, uppercase: false) 129 | if self < 16 { 130 | return "0\(hexString)" 131 | } else { 132 | return hexString 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /Sources/RP2040Boot2Checksum/CRC32.swift: -------------------------------------------------------------------------------- 1 | func crc32( 2 | message: some Sequence, 3 | polynomial: UInt32, 4 | initialValue: UInt32 = 0xffff_ffff, 5 | xorOut: UInt32 = 0xffff_ffff 6 | ) -> UInt32 { 7 | var crc = initialValue 8 | for byte in message { 9 | crc ^= UInt32(byte) << 24; 10 | for _ in 0..<8 { 11 | let isTopmostBitSet = crc & (1 << 31) != 0 12 | crc <<= 1 13 | if isTopmostBitSet { 14 | crc ^= polynomial 15 | } 16 | } 17 | } 18 | return crc ^ xorOut 19 | } 20 | -------------------------------------------------------------------------------- /Sources/RP2040Support/LICENSE.TXT: -------------------------------------------------------------------------------- 1 | Copyright 2020 (c) 2020 Raspberry Pi (Trading) Ltd. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 4 | following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following 7 | disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 10 | disclaimer in the documentation and/or other materials provided with the distribution. 11 | 12 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 16 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 18 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 20 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 21 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /Sources/RP2040Support/README.md: -------------------------------------------------------------------------------- 1 | The files in this directory have been copied from the [Raspberry Pi Pico C/C++ SDK](https://github.com/raspberrypi/pico-sdk/). 2 | 3 | They are licensed under the [Pico SDK license](https://github.com/raspberrypi/pico-sdk/blob/master/LICENSE.TXT) (BSD 3-Clause "New" or "Revised" License). 4 | 5 | Some of the files have been modified to either strip out unneeded functionality or to remove dependencies on other parts of the Pico SDK. You can track the modifications through the commit history. 6 | 7 | If you add a new file to this directory, make sure that the first commit always reflects the original state of the file in the Pico SDK. Modifications must be committed separately. 8 | -------------------------------------------------------------------------------- /Sources/RP2040Support/bootrom.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #include "bootrom.h" 8 | 9 | void *rom_func_lookup(unsigned int code) { 10 | return rom_func_lookup_inline(code); 11 | } 12 | -------------------------------------------------------------------------------- /Sources/RP2040Support/crt0.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #include "asm_helper.s.h" 8 | 9 | // platform.defs.h 10 | #ifndef _u 11 | #ifdef __ASSEMBLER__ 12 | #define _u(x) x 13 | #else 14 | #define _u(x) x ## u 15 | #endif 16 | #endif 17 | 18 | // platform.h 19 | // PICO_CONFIG: PICO_STACK_SIZE, Stack Size, min=0x100, default=0x800, advanced=true, group=pico_platform 20 | #ifndef PICO_STACK_SIZE 21 | #define PICO_STACK_SIZE _u(0x800) 22 | #endif 23 | // PICO_CONFIG: PICO_HEAP_SIZE, Heap size to reserve, min=0x100, default=0x800, advanced=true, group=pico_platform 24 | #ifndef PICO_HEAP_SIZE 25 | #define PICO_HEAP_SIZE _u(0x800) 26 | #endif 27 | 28 | // m0plus.h 29 | // ============================================================================= 30 | // Register : M0PLUS_VTOR 31 | // Description : The VTOR holds the vector table offset address. 32 | #define M0PLUS_VTOR_OFFSET _u(0x0000ed08) 33 | #define M0PLUS_VTOR_BITS _u(0xffffff00) 34 | #define M0PLUS_VTOR_RESET _u(0x00000000) 35 | 36 | // sio.h 37 | // ============================================================================= 38 | // Register : SIO_CPUID 39 | // Description : Processor core identifier 40 | // Value is 0 when read from processor core 0, and 1 when read 41 | // from processor core 1. 42 | #define SIO_CPUID_OFFSET _u(0x00000000) 43 | #define SIO_CPUID_BITS _u(0xffffffff) 44 | #define SIO_CPUID_RESET "-" 45 | #define SIO_CPUID_MSB _u(31) 46 | #define SIO_CPUID_LSB _u(0) 47 | #define SIO_CPUID_ACCESS "RO" 48 | 49 | #ifdef NDEBUG 50 | #ifndef COLLAPSE_IRQS 51 | #define COLLAPSE_IRQS 52 | #endif 53 | #endif 54 | 55 | pico_default_asm_setup 56 | 57 | .section .vectors, "ax" 58 | .align 2 59 | 60 | .global __vectors, __VECTOR_TABLE 61 | __VECTOR_TABLE: 62 | __vectors: 63 | .word __StackTop 64 | .word _reset_handler 65 | .word isr_nmi 66 | .word isr_hardfault 67 | .word isr_invalid // Reserved, should never fire 68 | .word isr_invalid // Reserved, should never fire 69 | .word isr_invalid // Reserved, should never fire 70 | .word isr_invalid // Reserved, should never fire 71 | .word isr_invalid // Reserved, should never fire 72 | .word isr_invalid // Reserved, should never fire 73 | .word isr_invalid // Reserved, should never fire 74 | .word isr_svcall 75 | .word isr_invalid // Reserved, should never fire 76 | .word isr_invalid // Reserved, should never fire 77 | .word isr_pendsv 78 | .word isr_systick 79 | .word isr_irq0 80 | .word isr_irq1 81 | .word isr_irq2 82 | .word isr_irq3 83 | .word isr_irq4 84 | .word isr_irq5 85 | .word isr_irq6 86 | .word isr_irq7 87 | .word isr_irq8 88 | .word isr_irq9 89 | .word isr_irq10 90 | .word isr_irq11 91 | .word isr_irq12 92 | .word isr_irq13 93 | .word isr_irq14 94 | .word isr_irq15 95 | .word isr_irq16 96 | .word isr_irq17 97 | .word isr_irq18 98 | .word isr_irq19 99 | .word isr_irq20 100 | .word isr_irq21 101 | .word isr_irq22 102 | .word isr_irq23 103 | .word isr_irq24 104 | .word isr_irq25 105 | .word isr_irq26 106 | .word isr_irq27 107 | .word isr_irq28 108 | .word isr_irq29 109 | .word isr_irq30 110 | .word isr_irq31 111 | 112 | // all default exception handlers do nothing, and we can check for them being set to our 113 | // default values by seeing if they point to somewhere between __defaults_isrs_start and __default_isrs_end 114 | .global __default_isrs_start 115 | __default_isrs_start: 116 | 117 | // Declare a weak symbol for each ISR. 118 | // By default, they will fall through to the undefined IRQ handler below (breakpoint), 119 | // but can be overridden by C functions with correct name. 120 | 121 | .macro decl_isr_bkpt name 122 | .weak \name 123 | .type \name,%function 124 | .thumb_func 125 | \name: 126 | bkpt #0 127 | .endm 128 | 129 | // these are separated out for clarity 130 | decl_isr_bkpt isr_invalid 131 | decl_isr_bkpt isr_nmi 132 | decl_isr_bkpt isr_hardfault 133 | decl_isr_bkpt isr_svcall 134 | decl_isr_bkpt isr_pendsv 135 | decl_isr_bkpt isr_systick 136 | 137 | .global __default_isrs_end 138 | __default_isrs_end: 139 | 140 | .macro decl_isr name 141 | .weak \name 142 | .type \name,%function 143 | .thumb_func 144 | \name: 145 | .endm 146 | 147 | decl_isr isr_irq0 148 | decl_isr isr_irq1 149 | decl_isr isr_irq2 150 | decl_isr isr_irq3 151 | decl_isr isr_irq4 152 | decl_isr isr_irq5 153 | decl_isr isr_irq6 154 | decl_isr isr_irq7 155 | decl_isr isr_irq8 156 | decl_isr isr_irq9 157 | decl_isr isr_irq10 158 | decl_isr isr_irq11 159 | decl_isr isr_irq12 160 | decl_isr isr_irq13 161 | decl_isr isr_irq14 162 | decl_isr isr_irq15 163 | decl_isr isr_irq16 164 | decl_isr isr_irq17 165 | decl_isr isr_irq18 166 | decl_isr isr_irq19 167 | decl_isr isr_irq20 168 | decl_isr isr_irq21 169 | decl_isr isr_irq22 170 | decl_isr isr_irq23 171 | decl_isr isr_irq24 172 | decl_isr isr_irq25 173 | decl_isr isr_irq26 174 | decl_isr isr_irq27 175 | decl_isr isr_irq28 176 | decl_isr isr_irq29 177 | decl_isr isr_irq30 178 | decl_isr isr_irq31 179 | 180 | // All unhandled USER IRQs fall through to here 181 | .global __unhandled_user_irq 182 | .thumb_func 183 | __unhandled_user_irq: 184 | mrs r0, ipsr 185 | subs r0, #16 186 | // -- This symbol seems to be a debugging convenience. 187 | // -- "An unhandled user IRQ occurred. The IRQ number is in r0" 188 | .global unhandled_user_irq_num_in_r0 189 | unhandled_user_irq_num_in_r0: 190 | bkpt #0 191 | 192 | // ---------------------------------------------------------------------------- 193 | 194 | .section .reset, "ax" 195 | 196 | // On flash builds, the vector table comes first in the image (conventional). 197 | // On NO_FLASH builds, the reset handler section comes first, as the entry 198 | // point is at offset 0 (fixed due to bootrom), and VTOR is highly-aligned. 199 | // Image is entered in various ways: 200 | // 201 | // - NO_FLASH builds are entered from beginning by UF2 bootloader 202 | // 203 | // - Flash builds vector through the table into _reset_handler from boot2 204 | // 205 | // - Either type can be entered via _entry_point by the debugger, and flash builds 206 | // must then be sent back round the boot sequence to properly initialise flash 207 | 208 | // ELF entry point: 209 | .type _entry_point,%function 210 | .thumb_func 211 | .global _entry_point 212 | _entry_point: 213 | 214 | #if PICO_NO_FLASH 215 | // Vector through our own table (SP, VTOR will not have been set up at 216 | // this point). Same path for debugger entry and bootloader entry. 217 | ldr r0, =__vectors 218 | #else 219 | // Debugger tried to run code after loading, so SSI is in 03h-only mode. 220 | // Go back through bootrom + boot2 to properly initialise flash. 221 | movs r0, #0 222 | #endif 223 | ldr r1, =(PPB_BASE + M0PLUS_VTOR_OFFSET) 224 | str r0, [r1] 225 | ldmia r0!, {r1, r2} 226 | msr msp, r1 227 | bx r2 228 | 229 | // Reset handler: 230 | // - initialises .data 231 | // - clears .bss 232 | // - calls main 233 | // - calls exit (which should eventually hang the processor via _exit) 234 | 235 | .type _reset_handler,%function 236 | .thumb_func 237 | _reset_handler: 238 | // Only core 0 should run the C runtime startup code; core 1 is normally 239 | // sleeping in the bootrom at this point but check to be sure 240 | ldr r0, =(SIO_BASE + SIO_CPUID_OFFSET) 241 | ldr r0, [r0] 242 | cmp r0, #0 243 | bne hold_non_core0_in_bootrom 244 | 245 | // In a NO_FLASH binary, don't perform .data copy, since it's loaded 246 | // in-place by the SRAM load. Still need to clear .bss 247 | #if !PICO_NO_FLASH 248 | adr r4, data_cpy_table 249 | 250 | // assume there is at least one entry 251 | 1: 252 | ldmia r4!, {r1-r3} 253 | cmp r1, #0 254 | beq 2f 255 | bl data_cpy 256 | b 1b 257 | 2: 258 | #endif 259 | 260 | // Zero out the BSS 261 | ldr r1, =__bss_start__ 262 | ldr r2, =__bss_end__ 263 | movs r0, #0 264 | b bss_fill_test 265 | bss_fill_loop: 266 | stm r1!, {r0} 267 | bss_fill_test: 268 | cmp r1, r2 269 | bne bss_fill_loop 270 | 271 | platform_entry: // symbol for stack traces 272 | // Use 32-bit jumps, in case these symbols are moved out of branch range 273 | // (e.g. if main is in SRAM and crt0 in flash) 274 | ldr r1, =main 275 | blx r1 276 | ldr r1, =exit 277 | blx r1 278 | // exit should not return. If it does, hang the core. 279 | // (fall thru into our hang _exit impl 280 | 1: // separate label because _exit can be moved out of branch range 281 | bkpt #0 282 | b 1b 283 | 284 | #if !PICO_NO_FLASH 285 | data_cpy_loop: 286 | ldm r1!, {r0} 287 | stm r2!, {r0} 288 | data_cpy: 289 | cmp r2, r3 290 | blo data_cpy_loop 291 | bx lr 292 | #endif 293 | 294 | // Note the data copy table is still included for NO_FLASH builds, even though 295 | // we skip the copy, because it is listed in binary info 296 | 297 | .align 2 298 | data_cpy_table: 299 | #if PICO_COPY_TO_RAM 300 | .word __ram_text_source__ 301 | .word __ram_text_start__ 302 | .word __ram_text_end__ 303 | #endif 304 | .word __etext 305 | .word __data_start__ 306 | .word __data_end__ 307 | 308 | .word __scratch_x_source__ 309 | .word __scratch_x_start__ 310 | .word __scratch_x_end__ 311 | 312 | .word __scratch_y_source__ 313 | .word __scratch_y_start__ 314 | .word __scratch_y_end__ 315 | 316 | .word 0 // null terminator 317 | 318 | // ---------------------------------------------------------------------------- 319 | // If core 1 somehow gets into crt0 due to a spectacular VTOR mishap, we need to 320 | // catch it and send back to the sleep-and-launch code in the bootrom. Shouldn't 321 | // happen (it should sleep in the ROM until given an entry point via the 322 | // cross-core FIFOs) but it's good to be defensive. 323 | 324 | hold_non_core0_in_bootrom: 325 | ldr r0, = 'W' | ('V' << 8) 326 | bl rom_func_lookup 327 | bx r0 328 | 329 | // ---------------------------------------------------------------------------- 330 | // Stack/heap dummies to set size 331 | 332 | // Prior to SDK 1.5.1 these were `.section .stack` without the `, "a"`... Clang linker gives a warning about this, 333 | // however setting it explicitly to `, "a"` makes GCC *now* discard the section unless it is also KEEP. This 334 | // seems like very surprising behavior! 335 | // 336 | // Strictly the most correct thing to do (as .stack and .heap are unreferenced) is to mark them as "a", and also KEEP, which 337 | // works correctly for both GCC and Clang, however doing so may break anyone who already has custom linker scripts without 338 | // the KEEP. Therefore we will only add the "a" on Clang, but will also use KEEP to our own linker scripts. 339 | 340 | .macro spacer_section name 341 | #if PICO_ASSEMBLER_IS_CLANG 342 | .section \name, "a" 343 | #else 344 | .section \name 345 | #endif 346 | .endm 347 | 348 | spacer_section .stack 349 | // align to allow for memory protection (although this alignment is pretty much ignored by linker script) 350 | .p2align 5 351 | .equ StackSize, PICO_STACK_SIZE 352 | .space StackSize 353 | 354 | spacer_section .heap 355 | .p2align 2 356 | .equ HeapSize, PICO_HEAP_SIZE 357 | .space HeapSize 358 | -------------------------------------------------------------------------------- /Sources/RP2040Support/headers/addressmap.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2021 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | #ifndef _ADDRESSMAP_H_ 7 | #define _ADDRESSMAP_H_ 8 | 9 | // Register address offsets for atomic RMW aliases 10 | #define REG_ALIAS_RW_BITS (0x0u << 12u) 11 | #define REG_ALIAS_XOR_BITS (0x1u << 12u) 12 | #define REG_ALIAS_SET_BITS (0x2u << 12u) 13 | #define REG_ALIAS_CLR_BITS (0x3u << 12u) 14 | 15 | #define ROM_BASE _u(0x00000000) 16 | #define XIP_BASE _u(0x10000000) 17 | #define XIP_MAIN_BASE _u(0x10000000) 18 | #define XIP_NOALLOC_BASE _u(0x11000000) 19 | #define XIP_NOCACHE_BASE _u(0x12000000) 20 | #define XIP_NOCACHE_NOALLOC_BASE _u(0x13000000) 21 | #define XIP_CTRL_BASE _u(0x14000000) 22 | #define XIP_SRAM_BASE _u(0x15000000) 23 | #define XIP_SRAM_END _u(0x15004000) 24 | #define XIP_SSI_BASE _u(0x18000000) 25 | #define SRAM_BASE _u(0x20000000) 26 | #define SRAM_STRIPED_BASE _u(0x20000000) 27 | #define SRAM_STRIPED_END _u(0x20040000) 28 | #define SRAM4_BASE _u(0x20040000) 29 | #define SRAM5_BASE _u(0x20041000) 30 | #define SRAM_END _u(0x20042000) 31 | #define SRAM0_BASE _u(0x21000000) 32 | #define SRAM1_BASE _u(0x21010000) 33 | #define SRAM2_BASE _u(0x21020000) 34 | #define SRAM3_BASE _u(0x21030000) 35 | #define SYSINFO_BASE _u(0x40000000) 36 | #define SYSCFG_BASE _u(0x40004000) 37 | #define CLOCKS_BASE _u(0x40008000) 38 | #define RESETS_BASE _u(0x4000c000) 39 | #define PSM_BASE _u(0x40010000) 40 | #define IO_BANK0_BASE _u(0x40014000) 41 | #define IO_QSPI_BASE _u(0x40018000) 42 | #define PADS_BANK0_BASE _u(0x4001c000) 43 | #define PADS_QSPI_BASE _u(0x40020000) 44 | #define XOSC_BASE _u(0x40024000) 45 | #define PLL_SYS_BASE _u(0x40028000) 46 | #define PLL_USB_BASE _u(0x4002c000) 47 | #define BUSCTRL_BASE _u(0x40030000) 48 | #define UART0_BASE _u(0x40034000) 49 | #define UART1_BASE _u(0x40038000) 50 | #define SPI0_BASE _u(0x4003c000) 51 | #define SPI1_BASE _u(0x40040000) 52 | #define I2C0_BASE _u(0x40044000) 53 | #define I2C1_BASE _u(0x40048000) 54 | #define ADC_BASE _u(0x4004c000) 55 | #define PWM_BASE _u(0x40050000) 56 | #define TIMER_BASE _u(0x40054000) 57 | #define WATCHDOG_BASE _u(0x40058000) 58 | #define RTC_BASE _u(0x4005c000) 59 | #define ROSC_BASE _u(0x40060000) 60 | #define VREG_AND_CHIP_RESET_BASE _u(0x40064000) 61 | #define TBMAN_BASE _u(0x4006c000) 62 | #define DMA_BASE _u(0x50000000) 63 | #define USBCTRL_DPRAM_BASE _u(0x50100000) 64 | #define USBCTRL_BASE _u(0x50100000) 65 | #define USBCTRL_REGS_BASE _u(0x50110000) 66 | #define PIO0_BASE _u(0x50200000) 67 | #define PIO1_BASE _u(0x50300000) 68 | #define XIP_AUX_BASE _u(0x50400000) 69 | #define SIO_BASE _u(0xd0000000) 70 | #define PPB_BASE _u(0xe0000000) 71 | 72 | #endif // _ADDRESSMAP_H_ 73 | -------------------------------------------------------------------------------- /Sources/RP2040Support/headers/asm_helper.s.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | // From platform.h 8 | #define WRAPPER_FUNC_NAME(x) __wrap_##x 9 | 10 | # note we don't do this by default in this file for backwards comaptibility with user code 11 | # that may include this file, but not use unified syntax. Note that this macro does equivalent 12 | # setup to the pico_default_asm macro for inline assembly in C code. 13 | .macro pico_default_asm_setup 14 | .syntax unified 15 | .cpu cortex-m0plus 16 | .thumb 17 | .endm 18 | 19 | // do not put align in here as it is used mid function sometimes 20 | .macro regular_func x 21 | .global \x 22 | .type \x,%function 23 | .thumb_func 24 | \x: 25 | .endm 26 | 27 | .macro regular_func_with_section x 28 | .section .text.\x 29 | regular_func \x 30 | .endm 31 | 32 | // do not put align in here as it is used mid function sometimes 33 | .macro wrapper_func x 34 | regular_func WRAPPER_FUNC_NAME(\x) 35 | .endm 36 | 37 | .macro __pre_init func, priority_string 38 | .section .preinit_array.\priority_string 39 | .align 2 40 | .word \func 41 | .endm 42 | 43 | -------------------------------------------------------------------------------- /Sources/RP2040Support/headers/bootrom.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #ifndef _PICO_BOOTROM_H 8 | #define _PICO_BOOTROM_H 9 | 10 | // platform.h 11 | #ifndef __always_inline 12 | #define __always_inline __attribute__((__always_inline__)) 13 | #endif 14 | #define __force_inline __always_inline 15 | 16 | /** \file bootrom.h 17 | * \defgroup pico_bootrom pico_bootrom 18 | * Access to functions and data in the RP2040 bootrom 19 | * 20 | * This header may be included by assembly code 21 | */ 22 | 23 | #ifndef __ASSEMBLER__ 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | /*! 30 | * \brief Lookup a bootrom function by code 31 | * \ingroup pico_bootrom 32 | * \param code the code 33 | * \return a pointer to the function, or NULL if the code does not match any bootrom function 34 | */ 35 | void *rom_func_lookup(unsigned int code); 36 | 37 | // Bootrom function: rom_table_lookup 38 | // Returns the 32 bit pointer into the ROM if found or NULL otherwise. 39 | typedef void *(*rom_table_lookup_fn)(unsigned short *table, unsigned int code); 40 | 41 | #if PICO_C_COMPILER_IS_GNU && (__GNUC__ >= 12) 42 | // Convert a 16 bit pointer stored at the given rom address into a 32 bit pointer 43 | static inline void *rom_hword_as_ptr(uint16_t rom_address) { 44 | #pragma GCC diagnostic push 45 | #pragma GCC diagnostic ignored "-Warray-bounds" 46 | return (void *)(uintptr_t)*(uint16_t *)(uintptr_t)rom_address; 47 | #pragma GCC diagnostic pop 48 | } 49 | #else 50 | // Convert a 16 bit pointer stored at the given rom address into a 32 bit pointer 51 | #define rom_hword_as_ptr(rom_address) (void *)(unsigned int *)(*(unsigned short *)(unsigned int *)(rom_address)) 52 | #endif 53 | 54 | /*! 55 | * \brief Lookup a bootrom function by code. This method is forcibly inlined into the caller for FLASH/RAM sensitive code usage 56 | * \ingroup pico_bootrom 57 | * \param code the code 58 | * \return a pointer to the function, or NULL if the code does not match any bootrom function 59 | */ 60 | static __force_inline void *rom_func_lookup_inline(unsigned int code) { 61 | rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn) rom_hword_as_ptr(0x18); 62 | unsigned short *func_table = (unsigned short *) rom_hword_as_ptr(0x14); 63 | return rom_table_lookup(func_table, code); 64 | } 65 | 66 | #ifdef __cplusplus 67 | } 68 | #endif 69 | 70 | #endif // !__ASSEMBLER__ 71 | #endif 72 | -------------------------------------------------------------------------------- /Sources/RP2040Support/headers/hardware_regs-ssi.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2021 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | // ============================================================================= 7 | // Register block : SSI 8 | // Version : 1 9 | // Bus type : apb 10 | // Description : DW_apb_ssi has the following features: 11 | // * APB interface – Allows for easy integration into a 12 | // DesignWare Synthesizable Components for AMBA 2 13 | // implementation. 14 | // * APB3 and APB4 protocol support. 15 | // * Scalable APB data bus width – Supports APB data bus widths 16 | // of 8, 16, and 32 bits. 17 | // * Serial-master or serial-slave operation – Enables serial 18 | // communication with serial-master or serial-slave peripheral 19 | // devices. 20 | // * Programmable Dual/Quad/Octal SPI support in Master Mode. 21 | // * Dual Data Rate (DDR) and Read Data Strobe (RDS) Support - 22 | // Enables the DW_apb_ssi master to perform operations with the 23 | // device in DDR and RDS modes when working in Dual/Quad/Octal 24 | // mode of operation. 25 | // * Data Mask Support - Enables the DW_apb_ssi to selectively 26 | // update the bytes in the device. This feature is applicable 27 | // only in enhanced SPI modes. 28 | // * eXecute-In-Place (XIP) support - Enables the DW_apb_ssi 29 | // master to behave as a memory mapped I/O and fetches the data 30 | // from the device based on the APB read request. This feature 31 | // is applicable only in enhanced SPI modes. 32 | // * DMA Controller Interface – Enables the DW_apb_ssi to 33 | // interface to a DMA controller over the bus using a 34 | // handshaking interface for transfer requests. 35 | // * Independent masking of interrupts – Master collision, 36 | // transmit FIFO overflow, transmit FIFO empty, receive FIFO 37 | // full, receive FIFO underflow, and receive FIFO overflow 38 | // interrupts can all be masked independently. 39 | // * Multi-master contention detection – Informs the processor 40 | // of multiple serial-master accesses on the serial bus. 41 | // * Bypass of meta-stability flip-flops for synchronous clocks 42 | // – When the APB clock (pclk) and the DW_apb_ssi serial clock 43 | // (ssi_clk) are synchronous, meta-stable flip-flops are not 44 | // used when transferring control signals across these clock 45 | // domains. 46 | // * Programmable delay on the sample time of the received 47 | // serial data bit (rxd); enables programmable control of 48 | // routing delays resulting in higher serial data-bit rates. 49 | // * Programmable features: 50 | // - Serial interface operation – Choice of Motorola SPI, Texas 51 | // Instruments Synchronous Serial Protocol or National 52 | // Semiconductor Microwire. 53 | // - Clock bit-rate – Dynamic control of the serial bit rate of 54 | // the data transfer; used in only serial-master mode of 55 | // operation. 56 | // - Data Item size (4 to 32 bits) – Item size of each data 57 | // transfer under the control of the programmer. 58 | // * Configured features: 59 | // - FIFO depth – 16 words deep. The FIFO width is fixed at 32 60 | // bits. 61 | // - 1 slave select output. 62 | // - Hardware slave-select – Dedicated hardware slave-select 63 | // line. 64 | // - Combined interrupt line - one combined interrupt line from 65 | // the DW_apb_ssi to the interrupt controller. 66 | // - Interrupt polarity – active high interrupt lines. 67 | // - Serial clock polarity – low serial-clock polarity directly 68 | // after reset. 69 | // - Serial clock phase – capture on first edge of serial-clock 70 | // directly after reset. 71 | // ============================================================================= 72 | #ifndef HARDWARE_REGS_SSI_DEFINED 73 | #define HARDWARE_REGS_SSI_DEFINED 74 | // ============================================================================= 75 | // Register : SSI_CTRLR0 76 | // Description : Control register 0 77 | #define SSI_CTRLR0_OFFSET _u(0x00000000) 78 | #define SSI_CTRLR0_BITS _u(0x017fffff) 79 | #define SSI_CTRLR0_RESET _u(0x00000000) 80 | // ----------------------------------------------------------------------------- 81 | // Field : SSI_CTRLR0_SSTE 82 | // Description : Slave select toggle enable 83 | #define SSI_CTRLR0_SSTE_RESET _u(0x0) 84 | #define SSI_CTRLR0_SSTE_BITS _u(0x01000000) 85 | #define SSI_CTRLR0_SSTE_MSB _u(24) 86 | #define SSI_CTRLR0_SSTE_LSB _u(24) 87 | #define SSI_CTRLR0_SSTE_ACCESS "RW" 88 | // ----------------------------------------------------------------------------- 89 | // Field : SSI_CTRLR0_SPI_FRF 90 | // Description : SPI frame format 91 | // 0x0 -> Standard 1-bit SPI frame format; 1 bit per SCK, 92 | // full-duplex 93 | // 0x1 -> Dual-SPI frame format; two bits per SCK, half-duplex 94 | // 0x2 -> Quad-SPI frame format; four bits per SCK, half-duplex 95 | #define SSI_CTRLR0_SPI_FRF_RESET _u(0x0) 96 | #define SSI_CTRLR0_SPI_FRF_BITS _u(0x00600000) 97 | #define SSI_CTRLR0_SPI_FRF_MSB _u(22) 98 | #define SSI_CTRLR0_SPI_FRF_LSB _u(21) 99 | #define SSI_CTRLR0_SPI_FRF_ACCESS "RW" 100 | #define SSI_CTRLR0_SPI_FRF_VALUE_STD _u(0x0) 101 | #define SSI_CTRLR0_SPI_FRF_VALUE_DUAL _u(0x1) 102 | #define SSI_CTRLR0_SPI_FRF_VALUE_QUAD _u(0x2) 103 | // ----------------------------------------------------------------------------- 104 | // Field : SSI_CTRLR0_DFS_32 105 | // Description : Data frame size in 32b transfer mode 106 | // Value of n -> n+1 clocks per frame. 107 | #define SSI_CTRLR0_DFS_32_RESET _u(0x00) 108 | #define SSI_CTRLR0_DFS_32_BITS _u(0x001f0000) 109 | #define SSI_CTRLR0_DFS_32_MSB _u(20) 110 | #define SSI_CTRLR0_DFS_32_LSB _u(16) 111 | #define SSI_CTRLR0_DFS_32_ACCESS "RW" 112 | // ----------------------------------------------------------------------------- 113 | // Field : SSI_CTRLR0_CFS 114 | // Description : Control frame size 115 | // Value of n -> n+1 clocks per frame. 116 | #define SSI_CTRLR0_CFS_RESET _u(0x0) 117 | #define SSI_CTRLR0_CFS_BITS _u(0x0000f000) 118 | #define SSI_CTRLR0_CFS_MSB _u(15) 119 | #define SSI_CTRLR0_CFS_LSB _u(12) 120 | #define SSI_CTRLR0_CFS_ACCESS "RW" 121 | // ----------------------------------------------------------------------------- 122 | // Field : SSI_CTRLR0_SRL 123 | // Description : Shift register loop (test mode) 124 | #define SSI_CTRLR0_SRL_RESET _u(0x0) 125 | #define SSI_CTRLR0_SRL_BITS _u(0x00000800) 126 | #define SSI_CTRLR0_SRL_MSB _u(11) 127 | #define SSI_CTRLR0_SRL_LSB _u(11) 128 | #define SSI_CTRLR0_SRL_ACCESS "RW" 129 | // ----------------------------------------------------------------------------- 130 | // Field : SSI_CTRLR0_SLV_OE 131 | // Description : Slave output enable 132 | #define SSI_CTRLR0_SLV_OE_RESET _u(0x0) 133 | #define SSI_CTRLR0_SLV_OE_BITS _u(0x00000400) 134 | #define SSI_CTRLR0_SLV_OE_MSB _u(10) 135 | #define SSI_CTRLR0_SLV_OE_LSB _u(10) 136 | #define SSI_CTRLR0_SLV_OE_ACCESS "RW" 137 | // ----------------------------------------------------------------------------- 138 | // Field : SSI_CTRLR0_TMOD 139 | // Description : Transfer mode 140 | // 0x0 -> Both transmit and receive 141 | // 0x1 -> Transmit only (not for FRF == 0, standard SPI mode) 142 | // 0x2 -> Receive only (not for FRF == 0, standard SPI mode) 143 | // 0x3 -> EEPROM read mode (TX then RX; RX starts after control 144 | // data TX'd) 145 | #define SSI_CTRLR0_TMOD_RESET _u(0x0) 146 | #define SSI_CTRLR0_TMOD_BITS _u(0x00000300) 147 | #define SSI_CTRLR0_TMOD_MSB _u(9) 148 | #define SSI_CTRLR0_TMOD_LSB _u(8) 149 | #define SSI_CTRLR0_TMOD_ACCESS "RW" 150 | #define SSI_CTRLR0_TMOD_VALUE_TX_AND_RX _u(0x0) 151 | #define SSI_CTRLR0_TMOD_VALUE_TX_ONLY _u(0x1) 152 | #define SSI_CTRLR0_TMOD_VALUE_RX_ONLY _u(0x2) 153 | #define SSI_CTRLR0_TMOD_VALUE_EEPROM_READ _u(0x3) 154 | // ----------------------------------------------------------------------------- 155 | // Field : SSI_CTRLR0_SCPOL 156 | // Description : Serial clock polarity 157 | #define SSI_CTRLR0_SCPOL_RESET _u(0x0) 158 | #define SSI_CTRLR0_SCPOL_BITS _u(0x00000080) 159 | #define SSI_CTRLR0_SCPOL_MSB _u(7) 160 | #define SSI_CTRLR0_SCPOL_LSB _u(7) 161 | #define SSI_CTRLR0_SCPOL_ACCESS "RW" 162 | // ----------------------------------------------------------------------------- 163 | // Field : SSI_CTRLR0_SCPH 164 | // Description : Serial clock phase 165 | #define SSI_CTRLR0_SCPH_RESET _u(0x0) 166 | #define SSI_CTRLR0_SCPH_BITS _u(0x00000040) 167 | #define SSI_CTRLR0_SCPH_MSB _u(6) 168 | #define SSI_CTRLR0_SCPH_LSB _u(6) 169 | #define SSI_CTRLR0_SCPH_ACCESS "RW" 170 | // ----------------------------------------------------------------------------- 171 | // Field : SSI_CTRLR0_FRF 172 | // Description : Frame format 173 | #define SSI_CTRLR0_FRF_RESET _u(0x0) 174 | #define SSI_CTRLR0_FRF_BITS _u(0x00000030) 175 | #define SSI_CTRLR0_FRF_MSB _u(5) 176 | #define SSI_CTRLR0_FRF_LSB _u(4) 177 | #define SSI_CTRLR0_FRF_ACCESS "RW" 178 | // ----------------------------------------------------------------------------- 179 | // Field : SSI_CTRLR0_DFS 180 | // Description : Data frame size 181 | #define SSI_CTRLR0_DFS_RESET _u(0x0) 182 | #define SSI_CTRLR0_DFS_BITS _u(0x0000000f) 183 | #define SSI_CTRLR0_DFS_MSB _u(3) 184 | #define SSI_CTRLR0_DFS_LSB _u(0) 185 | #define SSI_CTRLR0_DFS_ACCESS "RW" 186 | // ============================================================================= 187 | // Register : SSI_CTRLR1 188 | // Description : Master Control register 1 189 | #define SSI_CTRLR1_OFFSET _u(0x00000004) 190 | #define SSI_CTRLR1_BITS _u(0x0000ffff) 191 | #define SSI_CTRLR1_RESET _u(0x00000000) 192 | // ----------------------------------------------------------------------------- 193 | // Field : SSI_CTRLR1_NDF 194 | // Description : Number of data frames 195 | #define SSI_CTRLR1_NDF_RESET _u(0x0000) 196 | #define SSI_CTRLR1_NDF_BITS _u(0x0000ffff) 197 | #define SSI_CTRLR1_NDF_MSB _u(15) 198 | #define SSI_CTRLR1_NDF_LSB _u(0) 199 | #define SSI_CTRLR1_NDF_ACCESS "RW" 200 | // ============================================================================= 201 | // Register : SSI_SSIENR 202 | // Description : SSI Enable 203 | #define SSI_SSIENR_OFFSET _u(0x00000008) 204 | #define SSI_SSIENR_BITS _u(0x00000001) 205 | #define SSI_SSIENR_RESET _u(0x00000000) 206 | // ----------------------------------------------------------------------------- 207 | // Field : SSI_SSIENR_SSI_EN 208 | // Description : SSI enable 209 | #define SSI_SSIENR_SSI_EN_RESET _u(0x0) 210 | #define SSI_SSIENR_SSI_EN_BITS _u(0x00000001) 211 | #define SSI_SSIENR_SSI_EN_MSB _u(0) 212 | #define SSI_SSIENR_SSI_EN_LSB _u(0) 213 | #define SSI_SSIENR_SSI_EN_ACCESS "RW" 214 | // ============================================================================= 215 | // Register : SSI_MWCR 216 | // Description : Microwire Control 217 | #define SSI_MWCR_OFFSET _u(0x0000000c) 218 | #define SSI_MWCR_BITS _u(0x00000007) 219 | #define SSI_MWCR_RESET _u(0x00000000) 220 | // ----------------------------------------------------------------------------- 221 | // Field : SSI_MWCR_MHS 222 | // Description : Microwire handshaking 223 | #define SSI_MWCR_MHS_RESET _u(0x0) 224 | #define SSI_MWCR_MHS_BITS _u(0x00000004) 225 | #define SSI_MWCR_MHS_MSB _u(2) 226 | #define SSI_MWCR_MHS_LSB _u(2) 227 | #define SSI_MWCR_MHS_ACCESS "RW" 228 | // ----------------------------------------------------------------------------- 229 | // Field : SSI_MWCR_MDD 230 | // Description : Microwire control 231 | #define SSI_MWCR_MDD_RESET _u(0x0) 232 | #define SSI_MWCR_MDD_BITS _u(0x00000002) 233 | #define SSI_MWCR_MDD_MSB _u(1) 234 | #define SSI_MWCR_MDD_LSB _u(1) 235 | #define SSI_MWCR_MDD_ACCESS "RW" 236 | // ----------------------------------------------------------------------------- 237 | // Field : SSI_MWCR_MWMOD 238 | // Description : Microwire transfer mode 239 | #define SSI_MWCR_MWMOD_RESET _u(0x0) 240 | #define SSI_MWCR_MWMOD_BITS _u(0x00000001) 241 | #define SSI_MWCR_MWMOD_MSB _u(0) 242 | #define SSI_MWCR_MWMOD_LSB _u(0) 243 | #define SSI_MWCR_MWMOD_ACCESS "RW" 244 | // ============================================================================= 245 | // Register : SSI_SER 246 | // Description : Slave enable 247 | // For each bit: 248 | // 0 -> slave not selected 249 | // 1 -> slave selected 250 | #define SSI_SER_OFFSET _u(0x00000010) 251 | #define SSI_SER_BITS _u(0x00000001) 252 | #define SSI_SER_RESET _u(0x00000000) 253 | #define SSI_SER_MSB _u(0) 254 | #define SSI_SER_LSB _u(0) 255 | #define SSI_SER_ACCESS "RW" 256 | // ============================================================================= 257 | // Register : SSI_BAUDR 258 | // Description : Baud rate 259 | #define SSI_BAUDR_OFFSET _u(0x00000014) 260 | #define SSI_BAUDR_BITS _u(0x0000ffff) 261 | #define SSI_BAUDR_RESET _u(0x00000000) 262 | // ----------------------------------------------------------------------------- 263 | // Field : SSI_BAUDR_SCKDV 264 | // Description : SSI clock divider 265 | #define SSI_BAUDR_SCKDV_RESET _u(0x0000) 266 | #define SSI_BAUDR_SCKDV_BITS _u(0x0000ffff) 267 | #define SSI_BAUDR_SCKDV_MSB _u(15) 268 | #define SSI_BAUDR_SCKDV_LSB _u(0) 269 | #define SSI_BAUDR_SCKDV_ACCESS "RW" 270 | // ============================================================================= 271 | // Register : SSI_TXFTLR 272 | // Description : TX FIFO threshold level 273 | #define SSI_TXFTLR_OFFSET _u(0x00000018) 274 | #define SSI_TXFTLR_BITS _u(0x000000ff) 275 | #define SSI_TXFTLR_RESET _u(0x00000000) 276 | // ----------------------------------------------------------------------------- 277 | // Field : SSI_TXFTLR_TFT 278 | // Description : Transmit FIFO threshold 279 | #define SSI_TXFTLR_TFT_RESET _u(0x00) 280 | #define SSI_TXFTLR_TFT_BITS _u(0x000000ff) 281 | #define SSI_TXFTLR_TFT_MSB _u(7) 282 | #define SSI_TXFTLR_TFT_LSB _u(0) 283 | #define SSI_TXFTLR_TFT_ACCESS "RW" 284 | // ============================================================================= 285 | // Register : SSI_RXFTLR 286 | // Description : RX FIFO threshold level 287 | #define SSI_RXFTLR_OFFSET _u(0x0000001c) 288 | #define SSI_RXFTLR_BITS _u(0x000000ff) 289 | #define SSI_RXFTLR_RESET _u(0x00000000) 290 | // ----------------------------------------------------------------------------- 291 | // Field : SSI_RXFTLR_RFT 292 | // Description : Receive FIFO threshold 293 | #define SSI_RXFTLR_RFT_RESET _u(0x00) 294 | #define SSI_RXFTLR_RFT_BITS _u(0x000000ff) 295 | #define SSI_RXFTLR_RFT_MSB _u(7) 296 | #define SSI_RXFTLR_RFT_LSB _u(0) 297 | #define SSI_RXFTLR_RFT_ACCESS "RW" 298 | // ============================================================================= 299 | // Register : SSI_TXFLR 300 | // Description : TX FIFO level 301 | #define SSI_TXFLR_OFFSET _u(0x00000020) 302 | #define SSI_TXFLR_BITS _u(0x000000ff) 303 | #define SSI_TXFLR_RESET _u(0x00000000) 304 | // ----------------------------------------------------------------------------- 305 | // Field : SSI_TXFLR_TFTFL 306 | // Description : Transmit FIFO level 307 | #define SSI_TXFLR_TFTFL_RESET _u(0x00) 308 | #define SSI_TXFLR_TFTFL_BITS _u(0x000000ff) 309 | #define SSI_TXFLR_TFTFL_MSB _u(7) 310 | #define SSI_TXFLR_TFTFL_LSB _u(0) 311 | #define SSI_TXFLR_TFTFL_ACCESS "RO" 312 | // ============================================================================= 313 | // Register : SSI_RXFLR 314 | // Description : RX FIFO level 315 | #define SSI_RXFLR_OFFSET _u(0x00000024) 316 | #define SSI_RXFLR_BITS _u(0x000000ff) 317 | #define SSI_RXFLR_RESET _u(0x00000000) 318 | // ----------------------------------------------------------------------------- 319 | // Field : SSI_RXFLR_RXTFL 320 | // Description : Receive FIFO level 321 | #define SSI_RXFLR_RXTFL_RESET _u(0x00) 322 | #define SSI_RXFLR_RXTFL_BITS _u(0x000000ff) 323 | #define SSI_RXFLR_RXTFL_MSB _u(7) 324 | #define SSI_RXFLR_RXTFL_LSB _u(0) 325 | #define SSI_RXFLR_RXTFL_ACCESS "RO" 326 | // ============================================================================= 327 | // Register : SSI_SR 328 | // Description : Status register 329 | #define SSI_SR_OFFSET _u(0x00000028) 330 | #define SSI_SR_BITS _u(0x0000007f) 331 | #define SSI_SR_RESET _u(0x00000000) 332 | // ----------------------------------------------------------------------------- 333 | // Field : SSI_SR_DCOL 334 | // Description : Data collision error 335 | #define SSI_SR_DCOL_RESET _u(0x0) 336 | #define SSI_SR_DCOL_BITS _u(0x00000040) 337 | #define SSI_SR_DCOL_MSB _u(6) 338 | #define SSI_SR_DCOL_LSB _u(6) 339 | #define SSI_SR_DCOL_ACCESS "RO" 340 | // ----------------------------------------------------------------------------- 341 | // Field : SSI_SR_TXE 342 | // Description : Transmission error 343 | #define SSI_SR_TXE_RESET _u(0x0) 344 | #define SSI_SR_TXE_BITS _u(0x00000020) 345 | #define SSI_SR_TXE_MSB _u(5) 346 | #define SSI_SR_TXE_LSB _u(5) 347 | #define SSI_SR_TXE_ACCESS "RO" 348 | // ----------------------------------------------------------------------------- 349 | // Field : SSI_SR_RFF 350 | // Description : Receive FIFO full 351 | #define SSI_SR_RFF_RESET _u(0x0) 352 | #define SSI_SR_RFF_BITS _u(0x00000010) 353 | #define SSI_SR_RFF_MSB _u(4) 354 | #define SSI_SR_RFF_LSB _u(4) 355 | #define SSI_SR_RFF_ACCESS "RO" 356 | // ----------------------------------------------------------------------------- 357 | // Field : SSI_SR_RFNE 358 | // Description : Receive FIFO not empty 359 | #define SSI_SR_RFNE_RESET _u(0x0) 360 | #define SSI_SR_RFNE_BITS _u(0x00000008) 361 | #define SSI_SR_RFNE_MSB _u(3) 362 | #define SSI_SR_RFNE_LSB _u(3) 363 | #define SSI_SR_RFNE_ACCESS "RO" 364 | // ----------------------------------------------------------------------------- 365 | // Field : SSI_SR_TFE 366 | // Description : Transmit FIFO empty 367 | #define SSI_SR_TFE_RESET _u(0x0) 368 | #define SSI_SR_TFE_BITS _u(0x00000004) 369 | #define SSI_SR_TFE_MSB _u(2) 370 | #define SSI_SR_TFE_LSB _u(2) 371 | #define SSI_SR_TFE_ACCESS "RO" 372 | // ----------------------------------------------------------------------------- 373 | // Field : SSI_SR_TFNF 374 | // Description : Transmit FIFO not full 375 | #define SSI_SR_TFNF_RESET _u(0x0) 376 | #define SSI_SR_TFNF_BITS _u(0x00000002) 377 | #define SSI_SR_TFNF_MSB _u(1) 378 | #define SSI_SR_TFNF_LSB _u(1) 379 | #define SSI_SR_TFNF_ACCESS "RO" 380 | // ----------------------------------------------------------------------------- 381 | // Field : SSI_SR_BUSY 382 | // Description : SSI busy flag 383 | #define SSI_SR_BUSY_RESET _u(0x0) 384 | #define SSI_SR_BUSY_BITS _u(0x00000001) 385 | #define SSI_SR_BUSY_MSB _u(0) 386 | #define SSI_SR_BUSY_LSB _u(0) 387 | #define SSI_SR_BUSY_ACCESS "RO" 388 | // ============================================================================= 389 | // Register : SSI_IMR 390 | // Description : Interrupt mask 391 | #define SSI_IMR_OFFSET _u(0x0000002c) 392 | #define SSI_IMR_BITS _u(0x0000003f) 393 | #define SSI_IMR_RESET _u(0x00000000) 394 | // ----------------------------------------------------------------------------- 395 | // Field : SSI_IMR_MSTIM 396 | // Description : Multi-master contention interrupt mask 397 | #define SSI_IMR_MSTIM_RESET _u(0x0) 398 | #define SSI_IMR_MSTIM_BITS _u(0x00000020) 399 | #define SSI_IMR_MSTIM_MSB _u(5) 400 | #define SSI_IMR_MSTIM_LSB _u(5) 401 | #define SSI_IMR_MSTIM_ACCESS "RW" 402 | // ----------------------------------------------------------------------------- 403 | // Field : SSI_IMR_RXFIM 404 | // Description : Receive FIFO full interrupt mask 405 | #define SSI_IMR_RXFIM_RESET _u(0x0) 406 | #define SSI_IMR_RXFIM_BITS _u(0x00000010) 407 | #define SSI_IMR_RXFIM_MSB _u(4) 408 | #define SSI_IMR_RXFIM_LSB _u(4) 409 | #define SSI_IMR_RXFIM_ACCESS "RW" 410 | // ----------------------------------------------------------------------------- 411 | // Field : SSI_IMR_RXOIM 412 | // Description : Receive FIFO overflow interrupt mask 413 | #define SSI_IMR_RXOIM_RESET _u(0x0) 414 | #define SSI_IMR_RXOIM_BITS _u(0x00000008) 415 | #define SSI_IMR_RXOIM_MSB _u(3) 416 | #define SSI_IMR_RXOIM_LSB _u(3) 417 | #define SSI_IMR_RXOIM_ACCESS "RW" 418 | // ----------------------------------------------------------------------------- 419 | // Field : SSI_IMR_RXUIM 420 | // Description : Receive FIFO underflow interrupt mask 421 | #define SSI_IMR_RXUIM_RESET _u(0x0) 422 | #define SSI_IMR_RXUIM_BITS _u(0x00000004) 423 | #define SSI_IMR_RXUIM_MSB _u(2) 424 | #define SSI_IMR_RXUIM_LSB _u(2) 425 | #define SSI_IMR_RXUIM_ACCESS "RW" 426 | // ----------------------------------------------------------------------------- 427 | // Field : SSI_IMR_TXOIM 428 | // Description : Transmit FIFO overflow interrupt mask 429 | #define SSI_IMR_TXOIM_RESET _u(0x0) 430 | #define SSI_IMR_TXOIM_BITS _u(0x00000002) 431 | #define SSI_IMR_TXOIM_MSB _u(1) 432 | #define SSI_IMR_TXOIM_LSB _u(1) 433 | #define SSI_IMR_TXOIM_ACCESS "RW" 434 | // ----------------------------------------------------------------------------- 435 | // Field : SSI_IMR_TXEIM 436 | // Description : Transmit FIFO empty interrupt mask 437 | #define SSI_IMR_TXEIM_RESET _u(0x0) 438 | #define SSI_IMR_TXEIM_BITS _u(0x00000001) 439 | #define SSI_IMR_TXEIM_MSB _u(0) 440 | #define SSI_IMR_TXEIM_LSB _u(0) 441 | #define SSI_IMR_TXEIM_ACCESS "RW" 442 | // ============================================================================= 443 | // Register : SSI_ISR 444 | // Description : Interrupt status 445 | #define SSI_ISR_OFFSET _u(0x00000030) 446 | #define SSI_ISR_BITS _u(0x0000003f) 447 | #define SSI_ISR_RESET _u(0x00000000) 448 | // ----------------------------------------------------------------------------- 449 | // Field : SSI_ISR_MSTIS 450 | // Description : Multi-master contention interrupt status 451 | #define SSI_ISR_MSTIS_RESET _u(0x0) 452 | #define SSI_ISR_MSTIS_BITS _u(0x00000020) 453 | #define SSI_ISR_MSTIS_MSB _u(5) 454 | #define SSI_ISR_MSTIS_LSB _u(5) 455 | #define SSI_ISR_MSTIS_ACCESS "RO" 456 | // ----------------------------------------------------------------------------- 457 | // Field : SSI_ISR_RXFIS 458 | // Description : Receive FIFO full interrupt status 459 | #define SSI_ISR_RXFIS_RESET _u(0x0) 460 | #define SSI_ISR_RXFIS_BITS _u(0x00000010) 461 | #define SSI_ISR_RXFIS_MSB _u(4) 462 | #define SSI_ISR_RXFIS_LSB _u(4) 463 | #define SSI_ISR_RXFIS_ACCESS "RO" 464 | // ----------------------------------------------------------------------------- 465 | // Field : SSI_ISR_RXOIS 466 | // Description : Receive FIFO overflow interrupt status 467 | #define SSI_ISR_RXOIS_RESET _u(0x0) 468 | #define SSI_ISR_RXOIS_BITS _u(0x00000008) 469 | #define SSI_ISR_RXOIS_MSB _u(3) 470 | #define SSI_ISR_RXOIS_LSB _u(3) 471 | #define SSI_ISR_RXOIS_ACCESS "RO" 472 | // ----------------------------------------------------------------------------- 473 | // Field : SSI_ISR_RXUIS 474 | // Description : Receive FIFO underflow interrupt status 475 | #define SSI_ISR_RXUIS_RESET _u(0x0) 476 | #define SSI_ISR_RXUIS_BITS _u(0x00000004) 477 | #define SSI_ISR_RXUIS_MSB _u(2) 478 | #define SSI_ISR_RXUIS_LSB _u(2) 479 | #define SSI_ISR_RXUIS_ACCESS "RO" 480 | // ----------------------------------------------------------------------------- 481 | // Field : SSI_ISR_TXOIS 482 | // Description : Transmit FIFO overflow interrupt status 483 | #define SSI_ISR_TXOIS_RESET _u(0x0) 484 | #define SSI_ISR_TXOIS_BITS _u(0x00000002) 485 | #define SSI_ISR_TXOIS_MSB _u(1) 486 | #define SSI_ISR_TXOIS_LSB _u(1) 487 | #define SSI_ISR_TXOIS_ACCESS "RO" 488 | // ----------------------------------------------------------------------------- 489 | // Field : SSI_ISR_TXEIS 490 | // Description : Transmit FIFO empty interrupt status 491 | #define SSI_ISR_TXEIS_RESET _u(0x0) 492 | #define SSI_ISR_TXEIS_BITS _u(0x00000001) 493 | #define SSI_ISR_TXEIS_MSB _u(0) 494 | #define SSI_ISR_TXEIS_LSB _u(0) 495 | #define SSI_ISR_TXEIS_ACCESS "RO" 496 | // ============================================================================= 497 | // Register : SSI_RISR 498 | // Description : Raw interrupt status 499 | #define SSI_RISR_OFFSET _u(0x00000034) 500 | #define SSI_RISR_BITS _u(0x0000003f) 501 | #define SSI_RISR_RESET _u(0x00000000) 502 | // ----------------------------------------------------------------------------- 503 | // Field : SSI_RISR_MSTIR 504 | // Description : Multi-master contention raw interrupt status 505 | #define SSI_RISR_MSTIR_RESET _u(0x0) 506 | #define SSI_RISR_MSTIR_BITS _u(0x00000020) 507 | #define SSI_RISR_MSTIR_MSB _u(5) 508 | #define SSI_RISR_MSTIR_LSB _u(5) 509 | #define SSI_RISR_MSTIR_ACCESS "RO" 510 | // ----------------------------------------------------------------------------- 511 | // Field : SSI_RISR_RXFIR 512 | // Description : Receive FIFO full raw interrupt status 513 | #define SSI_RISR_RXFIR_RESET _u(0x0) 514 | #define SSI_RISR_RXFIR_BITS _u(0x00000010) 515 | #define SSI_RISR_RXFIR_MSB _u(4) 516 | #define SSI_RISR_RXFIR_LSB _u(4) 517 | #define SSI_RISR_RXFIR_ACCESS "RO" 518 | // ----------------------------------------------------------------------------- 519 | // Field : SSI_RISR_RXOIR 520 | // Description : Receive FIFO overflow raw interrupt status 521 | #define SSI_RISR_RXOIR_RESET _u(0x0) 522 | #define SSI_RISR_RXOIR_BITS _u(0x00000008) 523 | #define SSI_RISR_RXOIR_MSB _u(3) 524 | #define SSI_RISR_RXOIR_LSB _u(3) 525 | #define SSI_RISR_RXOIR_ACCESS "RO" 526 | // ----------------------------------------------------------------------------- 527 | // Field : SSI_RISR_RXUIR 528 | // Description : Receive FIFO underflow raw interrupt status 529 | #define SSI_RISR_RXUIR_RESET _u(0x0) 530 | #define SSI_RISR_RXUIR_BITS _u(0x00000004) 531 | #define SSI_RISR_RXUIR_MSB _u(2) 532 | #define SSI_RISR_RXUIR_LSB _u(2) 533 | #define SSI_RISR_RXUIR_ACCESS "RO" 534 | // ----------------------------------------------------------------------------- 535 | // Field : SSI_RISR_TXOIR 536 | // Description : Transmit FIFO overflow raw interrupt status 537 | #define SSI_RISR_TXOIR_RESET _u(0x0) 538 | #define SSI_RISR_TXOIR_BITS _u(0x00000002) 539 | #define SSI_RISR_TXOIR_MSB _u(1) 540 | #define SSI_RISR_TXOIR_LSB _u(1) 541 | #define SSI_RISR_TXOIR_ACCESS "RO" 542 | // ----------------------------------------------------------------------------- 543 | // Field : SSI_RISR_TXEIR 544 | // Description : Transmit FIFO empty raw interrupt status 545 | #define SSI_RISR_TXEIR_RESET _u(0x0) 546 | #define SSI_RISR_TXEIR_BITS _u(0x00000001) 547 | #define SSI_RISR_TXEIR_MSB _u(0) 548 | #define SSI_RISR_TXEIR_LSB _u(0) 549 | #define SSI_RISR_TXEIR_ACCESS "RO" 550 | // ============================================================================= 551 | // Register : SSI_TXOICR 552 | // Description : TX FIFO overflow interrupt clear 553 | // Clear-on-read transmit FIFO overflow interrupt 554 | #define SSI_TXOICR_OFFSET _u(0x00000038) 555 | #define SSI_TXOICR_BITS _u(0x00000001) 556 | #define SSI_TXOICR_RESET _u(0x00000000) 557 | #define SSI_TXOICR_MSB _u(0) 558 | #define SSI_TXOICR_LSB _u(0) 559 | #define SSI_TXOICR_ACCESS "RO" 560 | // ============================================================================= 561 | // Register : SSI_RXOICR 562 | // Description : RX FIFO overflow interrupt clear 563 | // Clear-on-read receive FIFO overflow interrupt 564 | #define SSI_RXOICR_OFFSET _u(0x0000003c) 565 | #define SSI_RXOICR_BITS _u(0x00000001) 566 | #define SSI_RXOICR_RESET _u(0x00000000) 567 | #define SSI_RXOICR_MSB _u(0) 568 | #define SSI_RXOICR_LSB _u(0) 569 | #define SSI_RXOICR_ACCESS "RO" 570 | // ============================================================================= 571 | // Register : SSI_RXUICR 572 | // Description : RX FIFO underflow interrupt clear 573 | // Clear-on-read receive FIFO underflow interrupt 574 | #define SSI_RXUICR_OFFSET _u(0x00000040) 575 | #define SSI_RXUICR_BITS _u(0x00000001) 576 | #define SSI_RXUICR_RESET _u(0x00000000) 577 | #define SSI_RXUICR_MSB _u(0) 578 | #define SSI_RXUICR_LSB _u(0) 579 | #define SSI_RXUICR_ACCESS "RO" 580 | // ============================================================================= 581 | // Register : SSI_MSTICR 582 | // Description : Multi-master interrupt clear 583 | // Clear-on-read multi-master contention interrupt 584 | #define SSI_MSTICR_OFFSET _u(0x00000044) 585 | #define SSI_MSTICR_BITS _u(0x00000001) 586 | #define SSI_MSTICR_RESET _u(0x00000000) 587 | #define SSI_MSTICR_MSB _u(0) 588 | #define SSI_MSTICR_LSB _u(0) 589 | #define SSI_MSTICR_ACCESS "RO" 590 | // ============================================================================= 591 | // Register : SSI_ICR 592 | // Description : Interrupt clear 593 | // Clear-on-read all active interrupts 594 | #define SSI_ICR_OFFSET _u(0x00000048) 595 | #define SSI_ICR_BITS _u(0x00000001) 596 | #define SSI_ICR_RESET _u(0x00000000) 597 | #define SSI_ICR_MSB _u(0) 598 | #define SSI_ICR_LSB _u(0) 599 | #define SSI_ICR_ACCESS "RO" 600 | // ============================================================================= 601 | // Register : SSI_DMACR 602 | // Description : DMA control 603 | #define SSI_DMACR_OFFSET _u(0x0000004c) 604 | #define SSI_DMACR_BITS _u(0x00000003) 605 | #define SSI_DMACR_RESET _u(0x00000000) 606 | // ----------------------------------------------------------------------------- 607 | // Field : SSI_DMACR_TDMAE 608 | // Description : Transmit DMA enable 609 | #define SSI_DMACR_TDMAE_RESET _u(0x0) 610 | #define SSI_DMACR_TDMAE_BITS _u(0x00000002) 611 | #define SSI_DMACR_TDMAE_MSB _u(1) 612 | #define SSI_DMACR_TDMAE_LSB _u(1) 613 | #define SSI_DMACR_TDMAE_ACCESS "RW" 614 | // ----------------------------------------------------------------------------- 615 | // Field : SSI_DMACR_RDMAE 616 | // Description : Receive DMA enable 617 | #define SSI_DMACR_RDMAE_RESET _u(0x0) 618 | #define SSI_DMACR_RDMAE_BITS _u(0x00000001) 619 | #define SSI_DMACR_RDMAE_MSB _u(0) 620 | #define SSI_DMACR_RDMAE_LSB _u(0) 621 | #define SSI_DMACR_RDMAE_ACCESS "RW" 622 | // ============================================================================= 623 | // Register : SSI_DMATDLR 624 | // Description : DMA TX data level 625 | #define SSI_DMATDLR_OFFSET _u(0x00000050) 626 | #define SSI_DMATDLR_BITS _u(0x000000ff) 627 | #define SSI_DMATDLR_RESET _u(0x00000000) 628 | // ----------------------------------------------------------------------------- 629 | // Field : SSI_DMATDLR_DMATDL 630 | // Description : Transmit data watermark level 631 | #define SSI_DMATDLR_DMATDL_RESET _u(0x00) 632 | #define SSI_DMATDLR_DMATDL_BITS _u(0x000000ff) 633 | #define SSI_DMATDLR_DMATDL_MSB _u(7) 634 | #define SSI_DMATDLR_DMATDL_LSB _u(0) 635 | #define SSI_DMATDLR_DMATDL_ACCESS "RW" 636 | // ============================================================================= 637 | // Register : SSI_DMARDLR 638 | // Description : DMA RX data level 639 | #define SSI_DMARDLR_OFFSET _u(0x00000054) 640 | #define SSI_DMARDLR_BITS _u(0x000000ff) 641 | #define SSI_DMARDLR_RESET _u(0x00000000) 642 | // ----------------------------------------------------------------------------- 643 | // Field : SSI_DMARDLR_DMARDL 644 | // Description : Receive data watermark level (DMARDLR+1) 645 | #define SSI_DMARDLR_DMARDL_RESET _u(0x00) 646 | #define SSI_DMARDLR_DMARDL_BITS _u(0x000000ff) 647 | #define SSI_DMARDLR_DMARDL_MSB _u(7) 648 | #define SSI_DMARDLR_DMARDL_LSB _u(0) 649 | #define SSI_DMARDLR_DMARDL_ACCESS "RW" 650 | // ============================================================================= 651 | // Register : SSI_IDR 652 | // Description : Identification register 653 | #define SSI_IDR_OFFSET _u(0x00000058) 654 | #define SSI_IDR_BITS _u(0xffffffff) 655 | #define SSI_IDR_RESET _u(0x51535049) 656 | // ----------------------------------------------------------------------------- 657 | // Field : SSI_IDR_IDCODE 658 | // Description : Peripheral dentification code 659 | #define SSI_IDR_IDCODE_RESET _u(0x51535049) 660 | #define SSI_IDR_IDCODE_BITS _u(0xffffffff) 661 | #define SSI_IDR_IDCODE_MSB _u(31) 662 | #define SSI_IDR_IDCODE_LSB _u(0) 663 | #define SSI_IDR_IDCODE_ACCESS "RO" 664 | // ============================================================================= 665 | // Register : SSI_SSI_VERSION_ID 666 | // Description : Version ID 667 | #define SSI_SSI_VERSION_ID_OFFSET _u(0x0000005c) 668 | #define SSI_SSI_VERSION_ID_BITS _u(0xffffffff) 669 | #define SSI_SSI_VERSION_ID_RESET _u(0x3430312a) 670 | // ----------------------------------------------------------------------------- 671 | // Field : SSI_SSI_VERSION_ID_SSI_COMP_VERSION 672 | // Description : SNPS component version (format X.YY) 673 | #define SSI_SSI_VERSION_ID_SSI_COMP_VERSION_RESET _u(0x3430312a) 674 | #define SSI_SSI_VERSION_ID_SSI_COMP_VERSION_BITS _u(0xffffffff) 675 | #define SSI_SSI_VERSION_ID_SSI_COMP_VERSION_MSB _u(31) 676 | #define SSI_SSI_VERSION_ID_SSI_COMP_VERSION_LSB _u(0) 677 | #define SSI_SSI_VERSION_ID_SSI_COMP_VERSION_ACCESS "RO" 678 | // ============================================================================= 679 | // Register : SSI_DR0 680 | // Description : Data Register 0 (of 36) 681 | #define SSI_DR0_OFFSET _u(0x00000060) 682 | #define SSI_DR0_BITS _u(0xffffffff) 683 | #define SSI_DR0_RESET _u(0x00000000) 684 | // ----------------------------------------------------------------------------- 685 | // Field : SSI_DR0_DR 686 | // Description : First data register of 36 687 | #define SSI_DR0_DR_RESET _u(0x00000000) 688 | #define SSI_DR0_DR_BITS _u(0xffffffff) 689 | #define SSI_DR0_DR_MSB _u(31) 690 | #define SSI_DR0_DR_LSB _u(0) 691 | #define SSI_DR0_DR_ACCESS "RW" 692 | // ============================================================================= 693 | // Register : SSI_RX_SAMPLE_DLY 694 | // Description : RX sample delay 695 | #define SSI_RX_SAMPLE_DLY_OFFSET _u(0x000000f0) 696 | #define SSI_RX_SAMPLE_DLY_BITS _u(0x000000ff) 697 | #define SSI_RX_SAMPLE_DLY_RESET _u(0x00000000) 698 | // ----------------------------------------------------------------------------- 699 | // Field : SSI_RX_SAMPLE_DLY_RSD 700 | // Description : RXD sample delay (in SCLK cycles) 701 | #define SSI_RX_SAMPLE_DLY_RSD_RESET _u(0x00) 702 | #define SSI_RX_SAMPLE_DLY_RSD_BITS _u(0x000000ff) 703 | #define SSI_RX_SAMPLE_DLY_RSD_MSB _u(7) 704 | #define SSI_RX_SAMPLE_DLY_RSD_LSB _u(0) 705 | #define SSI_RX_SAMPLE_DLY_RSD_ACCESS "RW" 706 | // ============================================================================= 707 | // Register : SSI_SPI_CTRLR0 708 | // Description : SPI control 709 | #define SSI_SPI_CTRLR0_OFFSET _u(0x000000f4) 710 | #define SSI_SPI_CTRLR0_BITS _u(0xff07fb3f) 711 | #define SSI_SPI_CTRLR0_RESET _u(0x03000000) 712 | // ----------------------------------------------------------------------------- 713 | // Field : SSI_SPI_CTRLR0_XIP_CMD 714 | // Description : SPI Command to send in XIP mode (INST_L = 8-bit) or to append 715 | // to Address (INST_L = 0-bit) 716 | #define SSI_SPI_CTRLR0_XIP_CMD_RESET _u(0x03) 717 | #define SSI_SPI_CTRLR0_XIP_CMD_BITS _u(0xff000000) 718 | #define SSI_SPI_CTRLR0_XIP_CMD_MSB _u(31) 719 | #define SSI_SPI_CTRLR0_XIP_CMD_LSB _u(24) 720 | #define SSI_SPI_CTRLR0_XIP_CMD_ACCESS "RW" 721 | // ----------------------------------------------------------------------------- 722 | // Field : SSI_SPI_CTRLR0_SPI_RXDS_EN 723 | // Description : Read data strobe enable 724 | #define SSI_SPI_CTRLR0_SPI_RXDS_EN_RESET _u(0x0) 725 | #define SSI_SPI_CTRLR0_SPI_RXDS_EN_BITS _u(0x00040000) 726 | #define SSI_SPI_CTRLR0_SPI_RXDS_EN_MSB _u(18) 727 | #define SSI_SPI_CTRLR0_SPI_RXDS_EN_LSB _u(18) 728 | #define SSI_SPI_CTRLR0_SPI_RXDS_EN_ACCESS "RW" 729 | // ----------------------------------------------------------------------------- 730 | // Field : SSI_SPI_CTRLR0_INST_DDR_EN 731 | // Description : Instruction DDR transfer enable 732 | #define SSI_SPI_CTRLR0_INST_DDR_EN_RESET _u(0x0) 733 | #define SSI_SPI_CTRLR0_INST_DDR_EN_BITS _u(0x00020000) 734 | #define SSI_SPI_CTRLR0_INST_DDR_EN_MSB _u(17) 735 | #define SSI_SPI_CTRLR0_INST_DDR_EN_LSB _u(17) 736 | #define SSI_SPI_CTRLR0_INST_DDR_EN_ACCESS "RW" 737 | // ----------------------------------------------------------------------------- 738 | // Field : SSI_SPI_CTRLR0_SPI_DDR_EN 739 | // Description : SPI DDR transfer enable 740 | #define SSI_SPI_CTRLR0_SPI_DDR_EN_RESET _u(0x0) 741 | #define SSI_SPI_CTRLR0_SPI_DDR_EN_BITS _u(0x00010000) 742 | #define SSI_SPI_CTRLR0_SPI_DDR_EN_MSB _u(16) 743 | #define SSI_SPI_CTRLR0_SPI_DDR_EN_LSB _u(16) 744 | #define SSI_SPI_CTRLR0_SPI_DDR_EN_ACCESS "RW" 745 | // ----------------------------------------------------------------------------- 746 | // Field : SSI_SPI_CTRLR0_WAIT_CYCLES 747 | // Description : Wait cycles between control frame transmit and data reception 748 | // (in SCLK cycles) 749 | #define SSI_SPI_CTRLR0_WAIT_CYCLES_RESET _u(0x00) 750 | #define SSI_SPI_CTRLR0_WAIT_CYCLES_BITS _u(0x0000f800) 751 | #define SSI_SPI_CTRLR0_WAIT_CYCLES_MSB _u(15) 752 | #define SSI_SPI_CTRLR0_WAIT_CYCLES_LSB _u(11) 753 | #define SSI_SPI_CTRLR0_WAIT_CYCLES_ACCESS "RW" 754 | // ----------------------------------------------------------------------------- 755 | // Field : SSI_SPI_CTRLR0_INST_L 756 | // Description : Instruction length (0/4/8/16b) 757 | // 0x0 -> No instruction 758 | // 0x1 -> 4-bit instruction 759 | // 0x2 -> 8-bit instruction 760 | // 0x3 -> 16-bit instruction 761 | #define SSI_SPI_CTRLR0_INST_L_RESET _u(0x0) 762 | #define SSI_SPI_CTRLR0_INST_L_BITS _u(0x00000300) 763 | #define SSI_SPI_CTRLR0_INST_L_MSB _u(9) 764 | #define SSI_SPI_CTRLR0_INST_L_LSB _u(8) 765 | #define SSI_SPI_CTRLR0_INST_L_ACCESS "RW" 766 | #define SSI_SPI_CTRLR0_INST_L_VALUE_NONE _u(0x0) 767 | #define SSI_SPI_CTRLR0_INST_L_VALUE_4B _u(0x1) 768 | #define SSI_SPI_CTRLR0_INST_L_VALUE_8B _u(0x2) 769 | #define SSI_SPI_CTRLR0_INST_L_VALUE_16B _u(0x3) 770 | // ----------------------------------------------------------------------------- 771 | // Field : SSI_SPI_CTRLR0_ADDR_L 772 | // Description : Address length (0b-60b in 4b increments) 773 | #define SSI_SPI_CTRLR0_ADDR_L_RESET _u(0x0) 774 | #define SSI_SPI_CTRLR0_ADDR_L_BITS _u(0x0000003c) 775 | #define SSI_SPI_CTRLR0_ADDR_L_MSB _u(5) 776 | #define SSI_SPI_CTRLR0_ADDR_L_LSB _u(2) 777 | #define SSI_SPI_CTRLR0_ADDR_L_ACCESS "RW" 778 | // ----------------------------------------------------------------------------- 779 | // Field : SSI_SPI_CTRLR0_TRANS_TYPE 780 | // Description : Address and instruction transfer format 781 | // 0x0 -> Command and address both in standard SPI frame format 782 | // 0x1 -> Command in standard SPI format, address in format 783 | // specified by FRF 784 | // 0x2 -> Command and address both in format specified by FRF 785 | // (e.g. Dual-SPI) 786 | #define SSI_SPI_CTRLR0_TRANS_TYPE_RESET _u(0x0) 787 | #define SSI_SPI_CTRLR0_TRANS_TYPE_BITS _u(0x00000003) 788 | #define SSI_SPI_CTRLR0_TRANS_TYPE_MSB _u(1) 789 | #define SSI_SPI_CTRLR0_TRANS_TYPE_LSB _u(0) 790 | #define SSI_SPI_CTRLR0_TRANS_TYPE_ACCESS "RW" 791 | #define SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_1C1A _u(0x0) 792 | #define SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_1C2A _u(0x1) 793 | #define SSI_SPI_CTRLR0_TRANS_TYPE_VALUE_2C2A _u(0x2) 794 | // ============================================================================= 795 | // Register : SSI_TXD_DRIVE_EDGE 796 | // Description : TX drive edge 797 | #define SSI_TXD_DRIVE_EDGE_OFFSET _u(0x000000f8) 798 | #define SSI_TXD_DRIVE_EDGE_BITS _u(0x000000ff) 799 | #define SSI_TXD_DRIVE_EDGE_RESET _u(0x00000000) 800 | // ----------------------------------------------------------------------------- 801 | // Field : SSI_TXD_DRIVE_EDGE_TDE 802 | // Description : TXD drive edge 803 | #define SSI_TXD_DRIVE_EDGE_TDE_RESET _u(0x00) 804 | #define SSI_TXD_DRIVE_EDGE_TDE_BITS _u(0x000000ff) 805 | #define SSI_TXD_DRIVE_EDGE_TDE_MSB _u(7) 806 | #define SSI_TXD_DRIVE_EDGE_TDE_LSB _u(0) 807 | #define SSI_TXD_DRIVE_EDGE_TDE_ACCESS "RW" 808 | // ============================================================================= 809 | #endif // HARDWARE_REGS_SSI_DEFINED 810 | -------------------------------------------------------------------------------- /Sources/RP2040Support/linker-script/memmap_default.ld: -------------------------------------------------------------------------------- 1 | /* Based on GCC ARM embedded samples. 2 | Defines the following symbols for use by code: 3 | __exidx_start 4 | __exidx_end 5 | __etext 6 | __data_start__ 7 | __preinit_array_start 8 | __preinit_array_end 9 | __init_array_start 10 | __init_array_end 11 | __fini_array_start 12 | __fini_array_end 13 | __data_end__ 14 | __bss_start__ 15 | __bss_end__ 16 | __end__ 17 | end 18 | __HeapLimit 19 | __StackLimit 20 | __StackTop 21 | __stack (== StackTop) 22 | */ 23 | 24 | /* Why do we need this? */ 25 | SIO_BASE = 0xd0000000; 26 | PPB_BASE = 0xe0000000; 27 | 28 | /** 29 | Defines the memory map. 30 | Documentation: https://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_chapter/ld_3.html#SEC16 31 | */ 32 | MEMORY 33 | { 34 | FLASH(rx) : ORIGIN = 0x10000000, LENGTH = 2048k 35 | RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k 36 | /* ??? What's the purpose of these? */ 37 | SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k 38 | SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k 39 | } 40 | 41 | /** 42 | Sets the program entry point to this symbol (defined in crt0.S) 43 | Documentation: https://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_chapter/ld_3.html#SEC24 44 | 45 | Only relevant for the debugger because the boot2 stage will always start 46 | executing at the start of .text. 47 | */ 48 | ENTRY(_entry_point) 49 | 50 | /** 51 | Maps input sections to output sections incl. their exact location and order. 52 | Documentation: https://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_chapter/ld_3.html#SEC17 53 | */ 54 | SECTIONS 55 | { 56 | /* Second stage bootloader is prepended to the image. It must be 256 bytes big 57 | and checksummed. It is usually built by the boot_stage2 target 58 | in the Raspberry Pi Pico SDK 59 | */ 60 | 61 | .flash_begin : { 62 | __flash_binary_start = .; 63 | } > FLASH 64 | 65 | .boot2 : { 66 | __boot2_start__ = .; 67 | KEEP (*(.boot2)) 68 | __boot2_end__ = .; 69 | } > FLASH 70 | 71 | ASSERT(__boot2_end__ - __boot2_start__ == 256, 72 | "ERROR: Pico second stage bootloader must be 256 bytes in size") 73 | 74 | /* The second stage will always enter the image at the start of .text. 75 | The debugger will use the ELF entry point, which is the _entry_point 76 | symbol if present, otherwise defaults to start of .text. 77 | This can be used to transfer control back to the bootrom on debugger 78 | launches only, to perform proper flash setup. 79 | */ 80 | 81 | .text : { 82 | __logical_binary_start = .; 83 | KEEP (*(.vectors)) 84 | KEEP (*(.binary_info_header)) 85 | __binary_info_header_end = .; 86 | KEEP (*(.reset)) 87 | /* TODO revisit this now memset/memcpy/float in ROM */ 88 | /* bit of a hack right now to exclude all floating point and time critical (e.g. memset, memcpy) code from 89 | * FLASH ... we will include any thing excluded here in .data below by default */ 90 | *(.init) 91 | *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*) 92 | *(.fini) 93 | /* Pull all c'tors into .text */ 94 | *crtbegin.o(.ctors) 95 | *crtbegin?.o(.ctors) 96 | *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) 97 | *(SORT(.ctors.*)) 98 | *(.ctors) 99 | /* Followed by destructors */ 100 | *crtbegin.o(.dtors) 101 | *crtbegin?.o(.dtors) 102 | *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) 103 | *(SORT(.dtors.*)) 104 | *(.dtors) 105 | 106 | *(.eh_frame*) 107 | . = ALIGN(4); 108 | } > FLASH 109 | 110 | .rodata : { 111 | *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .rodata*) 112 | . = ALIGN(4); 113 | *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*))) 114 | . = ALIGN(4); 115 | } > FLASH 116 | 117 | /* ARM exception table */ 118 | .ARM.extab : 119 | { 120 | *(.ARM.extab* .gnu.linkonce.armextab.*) 121 | } > FLASH 122 | 123 | /* 124 | Sorted table of function start addresses plus extab lookup index. 125 | Used for stack unwinding and backtraces. 126 | */ 127 | __exidx_start = .; 128 | .ARM.exidx : 129 | { 130 | *(.ARM.exidx* .gnu.linkonce.armexidx.*) 131 | } > FLASH 132 | __exidx_end = .; 133 | 134 | /* Machine inspectable binary information */ 135 | . = ALIGN(4); 136 | __binary_info_start = .; 137 | .binary_info : 138 | { 139 | KEEP(*(.binary_info.keep.*)) 140 | *(.binary_info.*) 141 | } > FLASH 142 | __binary_info_end = .; 143 | . = ALIGN(4); 144 | 145 | .ram_vector_table (NOLOAD): { 146 | *(.ram_vector_table) 147 | } > RAM 148 | 149 | .data : { 150 | __data_start__ = .; 151 | *(vtable) 152 | 153 | *(.time_critical*) 154 | 155 | /* remaining .text and .rodata; i.e. stuff we exclude above because we want it in RAM */ 156 | *(.text*) 157 | . = ALIGN(4); 158 | *(.rodata*) 159 | . = ALIGN(4); 160 | 161 | *(.data*) 162 | 163 | . = ALIGN(4); 164 | *(.after_data.*) 165 | . = ALIGN(4); 166 | /* preinit data */ 167 | PROVIDE_HIDDEN (__mutex_array_start = .); 168 | KEEP(*(SORT(.mutex_array.*))) 169 | KEEP(*(.mutex_array)) 170 | PROVIDE_HIDDEN (__mutex_array_end = .); 171 | 172 | . = ALIGN(4); 173 | /* preinit data */ 174 | PROVIDE_HIDDEN (__preinit_array_start = .); 175 | KEEP(*(SORT(.preinit_array.*))) 176 | KEEP(*(.preinit_array)) 177 | PROVIDE_HIDDEN (__preinit_array_end = .); 178 | 179 | . = ALIGN(4); 180 | /* init data */ 181 | PROVIDE_HIDDEN (__init_array_start = .); 182 | KEEP(*(SORT(.init_array.*))) 183 | KEEP(*(.init_array)) 184 | PROVIDE_HIDDEN (__init_array_end = .); 185 | 186 | . = ALIGN(4); 187 | /* finit data */ 188 | PROVIDE_HIDDEN (__fini_array_start = .); 189 | *(SORT(.fini_array.*)) 190 | *(.fini_array) 191 | PROVIDE_HIDDEN (__fini_array_end = .); 192 | 193 | *(.jcr) 194 | . = ALIGN(4); 195 | /* All data end */ 196 | __data_end__ = .; 197 | } > RAM AT> FLASH 198 | /* __etext is (for backwards compatibility) the name of the .data init source pointer (...) */ 199 | __etext = LOADADDR(.data); 200 | 201 | .uninitialized_data (NOLOAD): { 202 | . = ALIGN(4); 203 | *(.uninitialized_data*) 204 | } > RAM 205 | 206 | /* Start and end symbols must be word-aligned */ 207 | .scratch_x : { 208 | __scratch_x_start__ = .; 209 | *(.scratch_x.*) 210 | . = ALIGN(4); 211 | __scratch_x_end__ = .; 212 | } > SCRATCH_X AT > FLASH 213 | __scratch_x_source__ = LOADADDR(.scratch_x); 214 | 215 | .scratch_y : { 216 | __scratch_y_start__ = .; 217 | *(.scratch_y.*) 218 | . = ALIGN(4); 219 | __scratch_y_end__ = .; 220 | } > SCRATCH_Y AT > FLASH 221 | __scratch_y_source__ = LOADADDR(.scratch_y); 222 | 223 | .bss : { 224 | . = ALIGN(4); 225 | __bss_start__ = .; 226 | *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) 227 | *(COMMON) 228 | . = ALIGN(4); 229 | __bss_end__ = .; 230 | } > RAM 231 | 232 | .heap (NOLOAD): 233 | { 234 | __end__ = .; 235 | end = __end__; 236 | KEEP(*(.heap*)) 237 | __HeapLimit = .; 238 | } > RAM 239 | 240 | /* .stack*_dummy section doesn't contains any symbols. It is only 241 | * used for linker to calculate size of stack sections, and assign 242 | * values to stack symbols later 243 | * 244 | * stack1 section may be empty/missing if platform_launch_core1 is not used */ 245 | 246 | /* by default we put core 0 stack at the end of scratch Y, so that if core 1 247 | * stack is not used then all of SCRATCH_X is free. 248 | */ 249 | .stack1_dummy (NOLOAD): 250 | { 251 | *(.stack1*) 252 | } > SCRATCH_X 253 | .stack_dummy (NOLOAD): 254 | { 255 | KEEP(*(.stack*)) 256 | } > SCRATCH_Y 257 | 258 | .flash_end : { 259 | PROVIDE(__flash_binary_end = .); 260 | } > FLASH 261 | 262 | /* stack limit is poorly named, but historically is maximum heap ptr */ 263 | __StackLimit = ORIGIN(RAM) + LENGTH(RAM); 264 | __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X); 265 | __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y); 266 | __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy); 267 | __StackBottom = __StackTop - SIZEOF(.stack_dummy); 268 | PROVIDE(__stack = __StackTop); 269 | 270 | /* Check if data + heap + stack exceeds RAM limit */ 271 | ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed") 272 | 273 | ASSERT( __binary_info_header_end - __logical_binary_start <= 256, "Binary info must be in first 256 bytes of the binary") 274 | /* todo assert on extra code */ 275 | } 276 | 277 | -------------------------------------------------------------------------------- /Sources/RP2040Support/pico_int64_ops_aeabi.S: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * 4 | * SPDX-License-Identifier: BSD-3-Clause 5 | */ 6 | 7 | #include "asm_helper.s.h" 8 | 9 | pico_default_asm_setup 10 | 11 | .macro int64_section name 12 | #if PICO_INT64_OPS_IN_RAM 13 | .section RAM_SECTION_NAME(\name), "ax" 14 | #else 15 | .section SECTION_NAME(\name), "ax" 16 | #endif 17 | .endm 18 | 19 | int64_section __aeabi_lmul 20 | 21 | wrapper_func __aeabi_lmul 22 | muls r1, r2 23 | muls r3, r0 24 | adds r1, r3 25 | mov r12, r1 26 | lsrs r1, r2, #16 27 | uxth r3, r0 28 | muls r3, r1 29 | push {r4} 30 | lsrs r4, r0, #16 31 | muls r1, r4 32 | uxth r2, r2 33 | uxth r0, r0 34 | muls r0, r2 35 | muls r2, r4 36 | lsls r4, r3, #16 37 | lsrs r3, #16 38 | adds r0, r4 39 | pop {r4} 40 | adcs r1, r3 41 | lsls r3, r2, #16 42 | lsrs r2, #16 43 | adds r0, r3 44 | adcs r1, r2 45 | add r1, r12 46 | bx lr 47 | --------------------------------------------------------------------------------