aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/CODEOWNERS1
-rw-r--r--.github/bors.toml4
-rw-r--r--.gitignore3
-rw-r--r--.travis.yml56
-rw-r--r--CHANGELOG.md131
-rw-r--r--CODE_OF_CONDUCT.md37
-rw-r--r--Cargo.toml15
-rw-r--r--README.md11
-rw-r--r--asm-cm7-r0p1.s27
-rw-r--r--asm-v7.s27
-rw-r--r--asm.s120
-rw-r--r--asm/basepri_max-cm7-r0p1.s11
-rw-r--r--asm/basepri_max.s4
-rw-r--r--asm/basepri_r.s4
-rw-r--r--asm/basepri_w-cm7-r0p1.s11
-rw-r--r--asm/basepri_w.s4
-rw-r--r--asm/bkpt.s4
-rw-r--r--asm/control.s4
-rw-r--r--asm/cpsid.s4
-rw-r--r--asm/cpsie.s4
-rw-r--r--asm/delay.s8
-rw-r--r--asm/dmb.s4
-rw-r--r--asm/dsb.s4
-rw-r--r--asm/faultmask.s4
-rw-r--r--asm/isb.s4
-rw-r--r--asm/msp_r.s4
-rw-r--r--asm/msp_w.s4
-rw-r--r--asm/nop.s3
-rw-r--r--asm/primask.s4
-rw-r--r--asm/psp_r.s4
-rw-r--r--asm/psp_w.s4
-rw-r--r--asm/sev.s4
-rw-r--r--asm/wfe.s4
-rw-r--r--asm/wfi.s4
-rwxr-xr-xassemble.sh33
-rw-r--r--bin/thumbv6m-none-eabi.abin0 -> 2862 bytes
-rw-r--r--bin/thumbv7em-none-eabi.abin0 -> 5094 bytes
-rw-r--r--bin/thumbv7em-none-eabihf.abin0 -> 5094 bytes
-rw-r--r--bin/thumbv7m-none-eabi.abin0 -> 4036 bytes
-rw-r--r--bin/thumbv8m.base-none-eabi.abin0 -> 2870 bytes
-rw-r--r--bin/thumbv8m.main-none-eabi.abin0 -> 2720 bytes
-rw-r--r--bors.toml3
-rw-r--r--build.rs48
-rwxr-xr-xcheck-blobs.sh21
-rw-r--r--ci/install.sh9
-rw-r--r--ci/script.sh13
-rw-r--r--src/itm.rs6
-rw-r--r--src/lib.rs10
-rw-r--r--src/macros.rs6
-rw-r--r--src/peripheral/dcb.rs21
-rw-r--r--src/peripheral/mod.rs1
-rw-r--r--src/peripheral/nvic.rs35
-rw-r--r--src/peripheral/scb.rs211
-rw-r--r--src/register/basepri.rs21
-rw-r--r--src/register/basepri_max.rs21
55 files changed, 739 insertions, 261 deletions
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 0000000..d810925
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1 @@
+* @rust-embedded/cortex-m \ No newline at end of file
diff --git a/.github/bors.toml b/.github/bors.toml
new file mode 100644
index 0000000..ca42be0
--- /dev/null
+++ b/.github/bors.toml
@@ -0,0 +1,4 @@
+block_labels = ["needs-decision"]
+delete_merged_branches = true
+required_approvals = 1
+status = ["continuous-integration/travis-ci/push"]
diff --git a/.gitignore b/.gitignore
index 1839608..9c3fcb4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,7 @@
*.rs.bk
.#*
Cargo.lock
+bin/*.after
+bin/*.before
+bin/*.o
target
diff --git a/.travis.yml b/.travis.yml
index 5352915..1aead9b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,67 +3,50 @@ language: rust
matrix:
include:
- env: TARGET=x86_64-unknown-linux-gnu
+ rust: stable
+ if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
- env: TARGET=thumbv6m-none-eabi
- rust: beta
- addons:
- apt:
- packages:
- - gcc-arm-none-eabi
+ rust: stable
+ if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
- env: TARGET=thumbv7m-none-eabi
- rust: beta
- addons:
- apt:
- packages:
- - gcc-arm-none-eabi
+ rust: stable
+ if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
- env: TARGET=thumbv7em-none-eabi
- rust: beta
- addons:
- apt:
- packages:
- - gcc-arm-none-eabi
+ rust: stable
+ if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
- env: TARGET=thumbv7em-none-eabihf
- rust: beta
- addons:
- apt:
- packages:
- - gcc-arm-none-eabi
+ rust: stable
+ if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
- env: TARGET=thumbv6m-none-eabi
rust: nightly
- addons:
- apt:
- packages:
- - gcc-arm-none-eabi
+ if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
- env: TARGET=thumbv7m-none-eabi
rust: nightly
- addons:
- apt:
- packages:
- - gcc-arm-none-eabi
+ if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
- env: TARGET=thumbv7em-none-eabi
rust: nightly
- addons:
- apt:
- packages:
- - gcc-arm-none-eabi
+ if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
- env: TARGET=thumbv7em-none-eabihf
rust: nightly
- addons:
- apt:
- packages:
- - gcc-arm-none-eabi
+ if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
+
+ - env: TARGET=thumbv8m.main-none-eabi
+ rust: nightly
+ if: (branch = staging OR branch = trying) OR (type = pull_request AND branch = master)
before_install: set -e
install:
- bash ci/install.sh
+ - export PATH="$PATH:$PWD/gcc/bin"
script:
- bash ci/script.sh
@@ -77,6 +60,7 @@ before_cache:
branches:
only:
+ - master
- staging
- trying
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 420aead..f265594 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,75 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
+## [Unreleased]
+
+## [v0.5.8] - 2018-10-27
+
+### Added
+
+- `SCB` gained methods to set, clear and check the pending state of the PendSV
+ exception.
+
+- `SCB` gained methods to set, clear and check the pending state of the SysTick
+ exception.
+
+- `SCB` gained methods to set and get the priority of system handlers like
+ SVCall and SysTick.
+
+- `NVIC` gained *static* methods, `pend` and `unpend`, to set and clear the
+ pending state of interrupts.
+
+### Changed
+
+- The `NVIC.{clear,set}_pending` methods have been deprecated in favor of
+ `NVIC::{unpend,pend}`.
+
+## [v0.5.7] - 2018-09-06
+
+### Added
+
+- `DCB::enable_trace()` and `DCB::disable_trace()`
+
+### Changed
+
+- `iprintln!` no longer depends on `iprint!`. `cortex_m::iprintln!` will work
+ even if `cortex_m::iprint` has not been imported.
+
+## [v0.5.6] - 2018-08-27
+
+### Fixed
+
+- Removed duplicated symbols from binary blobs
+
+- The check-blobs.sh script
+
+## [v0.5.5] - 2018-08-27 - YANKED
+
+### Changed
+
+- This crate no longer depends on `arm-none-eabi-gcc`.
+
+## [v0.5.4] - 2018-08-11
+
+### Added
+
+- A method to trigger a system reset. See `SCB.system_reset`.
+
+### Fixed
+
+- Made the VTOR register (see peripheral::SCB) available on `thumbv6m-none-eabi`. This register is
+ present on Cortex-M0+, but not on Cortex-M0.
+
+- Linking with LLD by marking all external assembly functions as `.thumb_func`. See
+ https://bugs.llvm.org/show_bug.cgi?id=38435 for details.
+
+## [v0.5.3] - 2018-08-02
+
+### Fixed
+
+- Don't assemble basepri*.s and faultmask.s for ARMv6-M. This fix the build when using `clang` as
+ the assembler.
+
## [v0.5.2] - 2018-05-18
### Added
@@ -460,31 +529,37 @@ fn main() {
- Functions to get the vector table
- Wrappers over miscellaneous instructions like `bkpt`
-[Unreleased]: https://github.com/japaric/cortex-m/compare/v0.5.2...HEAD
-[v0.5.2]: https://github.com/japaric/cortex-m/compare/v0.5.1...v0.5.2
-[v0.5.1]: https://github.com/japaric/cortex-m/compare/v0.5.0...v0.5.1
-[v0.5.0]: https://github.com/japaric/cortex-m/compare/v0.4.3...v0.5.0
-[v0.4.3]: https://github.com/japaric/cortex-m/compare/v0.4.2...v0.4.3
-[v0.4.2]: https://github.com/japaric/cortex-m/compare/v0.4.1...v0.4.2
-[v0.4.1]: https://github.com/japaric/cortex-m/compare/v0.4.0...v0.4.1
-[v0.4.0]: https://github.com/japaric/cortex-m/compare/v0.3.1...v0.4.0
-[v0.3.1]: https://github.com/japaric/cortex-m/compare/v0.3.0...v0.3.1
-[v0.3.0]: https://github.com/japaric/cortex-m/compare/v0.2.11...v0.3.0
-[v0.2.11]: https://github.com/japaric/cortex-m/compare/v0.2.10...v0.2.11
-[v0.2.10]: https://github.com/japaric/cortex-m/compare/v0.2.9...v0.2.10
-[v0.2.9]: https://github.com/japaric/cortex-m/compare/v0.2.8...v0.2.9
-[v0.2.8]: https://github.com/japaric/cortex-m/compare/v0.2.7...v0.2.8
-[v0.2.7]: https://github.com/japaric/cortex-m/compare/v0.2.6...v0.2.7
-[v0.2.6]: https://github.com/japaric/cortex-m/compare/v0.2.5...v0.2.6
-[v0.2.5]: https://github.com/japaric/cortex-m/compare/v0.2.4...v0.2.5
-[v0.2.4]: https://github.com/japaric/cortex-m/compare/v0.2.3...v0.2.4
-[v0.2.3]: https://github.com/japaric/cortex-m/compare/v0.2.2...v0.2.3
-[v0.2.2]: https://github.com/japaric/cortex-m/compare/v0.2.1...v0.2.2
-[v0.2.1]: https://github.com/japaric/cortex-m/compare/v0.2.0...v0.2.1
-[v0.2.0]: https://github.com/japaric/cortex-m/compare/v0.1.6...v0.2.0
-[v0.1.6]: https://github.com/japaric/cortex-m/compare/v0.1.5...v0.1.6
-[v0.1.5]: https://github.com/japaric/cortex-m/compare/v0.1.4...v0.1.5
-[v0.1.4]: https://github.com/japaric/cortex-m/compare/v0.1.3...v0.1.4
-[v0.1.3]: https://github.com/japaric/cortex-m/compare/v0.1.2...v0.1.3
-[v0.1.2]: https://github.com/japaric/cortex-m/compare/v0.1.1...v0.1.2
-[v0.1.1]: https://github.com/japaric/cortex-m/compare/v0.1.0...v0.1.1
+[Unreleased]: https://github.com/rust-embedded/cortex-m/compare/v0.5.8...HEAD
+[v0.5.8]: https://github.com/rust-embedded/cortex-m/compare/v0.5.7...v0.5.8
+[v0.5.7]: https://github.com/rust-embedded/cortex-m/compare/v0.5.6...v0.5.7
+[v0.5.6]: https://github.com/rust-embedded/cortex-m/compare/v0.5.5...v0.5.6
+[v0.5.5]: https://github.com/rust-embedded/cortex-m/compare/v0.5.4...v0.5.5
+[v0.5.4]: https://github.com/rust-embedded/cortex-m/compare/v0.5.3...v0.5.4
+[v0.5.3]: https://github.com/rust-embedded/cortex-m/compare/v0.5.2...v0.5.3
+[v0.5.2]: https://github.com/rust-embedded/cortex-m/compare/v0.5.1...v0.5.2
+[v0.5.1]: https://github.com/rust-embedded/cortex-m/compare/v0.5.0...v0.5.1
+[v0.5.0]: https://github.com/rust-embedded/cortex-m/compare/v0.4.3...v0.5.0
+[v0.4.3]: https://github.com/rust-embedded/cortex-m/compare/v0.4.2...v0.4.3
+[v0.4.2]: https://github.com/rust-embedded/cortex-m/compare/v0.4.1...v0.4.2
+[v0.4.1]: https://github.com/rust-embedded/cortex-m/compare/v0.4.0...v0.4.1
+[v0.4.0]: https://github.com/rust-embedded/cortex-m/compare/v0.3.1...v0.4.0
+[v0.3.1]: https://github.com/rust-embedded/cortex-m/compare/v0.3.0...v0.3.1
+[v0.3.0]: https://github.com/rust-embedded/cortex-m/compare/v0.2.11...v0.3.0
+[v0.2.11]: https://github.com/rust-embedded/cortex-m/compare/v0.2.10...v0.2.11
+[v0.2.10]: https://github.com/rust-embedded/cortex-m/compare/v0.2.9...v0.2.10
+[v0.2.9]: https://github.com/rust-embedded/cortex-m/compare/v0.2.8...v0.2.9
+[v0.2.8]: https://github.com/rust-embedded/cortex-m/compare/v0.2.7...v0.2.8
+[v0.2.7]: https://github.com/rust-embedded/cortex-m/compare/v0.2.6...v0.2.7
+[v0.2.6]: https://github.com/rust-embedded/cortex-m/compare/v0.2.5...v0.2.6
+[v0.2.5]: https://github.com/rust-embedded/cortex-m/compare/v0.2.4...v0.2.5
+[v0.2.4]: https://github.com/rust-embedded/cortex-m/compare/v0.2.3...v0.2.4
+[v0.2.3]: https://github.com/rust-embedded/cortex-m/compare/v0.2.2...v0.2.3
+[v0.2.2]: https://github.com/rust-embedded/cortex-m/compare/v0.2.1...v0.2.2
+[v0.2.1]: https://github.com/rust-embedded/cortex-m/compare/v0.2.0...v0.2.1
+[v0.2.0]: https://github.com/rust-embedded/cortex-m/compare/v0.1.6...v0.2.0
+[v0.1.6]: https://github.com/rust-embedded/cortex-m/compare/v0.1.5...v0.1.6
+[v0.1.5]: https://github.com/rust-embedded/cortex-m/compare/v0.1.4...v0.1.5
+[v0.1.4]: https://github.com/rust-embedded/cortex-m/compare/v0.1.3...v0.1.4
+[v0.1.3]: https://github.com/rust-embedded/cortex-m/compare/v0.1.2...v0.1.3
+[v0.1.2]: https://github.com/rust-embedded/cortex-m/compare/v0.1.1...v0.1.2
+[v0.1.1]: https://github.com/rust-embedded/cortex-m/compare/v0.1.0...v0.1.1
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..3ab76c6
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,37 @@
+# The Rust Code of Conduct
+
+## Conduct
+
+**Contact**: [Cortex-M team](https://github.com/rust-embedded/wg#the-cortex-m-team)
+
+* We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other similar characteristic.
+* On IRC, please avoid using overtly sexual nicknames or other nicknames that might detract from a friendly, safe and welcoming environment for all.
+* Please be kind and courteous. There's no need to be mean or rude.
+* Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer.
+* Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and see how it works.
+* We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behavior. We interpret the term "harassment" as including the definition in the [Citizen Code of Conduct](http://citizencodeofconduct.org/); if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups.
+* Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel ops or any of the [Cortex-M team][team] immediately. Whether you're a regular contributor or a newcomer, we care about making this community a safe place for you and we've got your back.
+* Likewise any spamming, trolling, flaming, baiting or other attention-stealing behavior is not welcome.
+
+## Moderation
+
+These are the policies for upholding our community's standards of conduct.
+
+1. Remarks that violate the Rust standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.)
+2. Remarks that moderators find inappropriate, whether listed in the code of conduct or not, are also not allowed.
+3. Moderators will first respond to such remarks with a warning.
+4. If the warning is unheeded, the user will be "kicked," i.e., kicked out of the communication channel to cool off.
+5. If the user comes back and continues to make trouble, they will be banned, i.e., indefinitely excluded.
+6. Moderators may choose at their discretion to un-ban the user if it was a first offense and they offer the offended party a genuine apology.
+7. If a moderator bans someone and you think it was unjustified, please take it up with that moderator, or with a different moderator, **in private**. Complaints about bans in-channel are not allowed.
+8. Moderators are held to a higher standard than other community members. If a moderator creates an inappropriate situation, they should expect less leeway than others.
+
+In the Rust community we strive to go the extra step to look out for each other. Don't just aim to be technically unimpeachable, try to be your best self. In particular, avoid flirting with offensive or sensitive issues, particularly if they're off-topic; this all too often leads to unnecessary fights, hurt feelings, and damaged trust; worse, it can drive people away from the community entirely.
+
+And if someone takes issue with something you said or did, resist the urge to be defensive. Just stop doing what it was they complained about and apologize. Even if you feel you were misinterpreted or unfairly accused, chances are good there was something you could've communicated better — remember that it's your responsibility to make your fellow Rustaceans comfortable. Everyone wants to get along and we are all here first and foremost because we want to talk about cool technology. You will find that people will be eager to assume good intent and forgive as long as you earn their trust.
+
+The enforcement policies listed above apply to all official embedded WG venues; including official IRC channels (#rust-embedded); GitHub repositories under rust-embedded; and all forums under rust-embedded.org (forum.rust-embedded.org).
+
+*Adapted from the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling) as well as the [Contributor Covenant v1.3.0](https://www.contributor-covenant.org/version/1/3/0/).*
+
+[team]: https://github.com/rust-embedded/wg#the-cortex-m-team
diff --git a/Cargo.toml b/Cargo.toml
index dfb504b..96d4f20 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,23 +1,24 @@
[package]
-authors = ["Jorge Aparicio <jorge@japaric.io>"]
+authors = [
+ "The Cortex-M Team <cortex-m@teams.rust-embedded.org>",
+ "Jorge Aparicio <jorge@japaric.io>",
+]
categories = ["embedded", "hardware-support", "no-std"]
description = "Low level access to Cortex-M processors"
documentation = "https://docs.rs/cortex-m"
keywords = ["arm", "cortex-m", "register", "peripheral"]
license = "MIT OR Apache-2.0"
name = "cortex-m"
+readme = "README.md"
repository = "https://github.com/japaric/cortex-m"
-version = "0.5.2"
-
-[build-dependencies]
-cc = "1.0.10"
+version = "0.5.8"
[dependencies]
-aligned = "0.2.0"
+aligned = "0.3.1"
bare-metal = "0.2.0"
volatile-register = "0.2.0"
[features]
cm7-r0p1 = []
const-fn = ["bare-metal/const-fn"]
-inline-asm = [] \ No newline at end of file
+inline-asm = []
diff --git a/README.md b/README.md
index 995a490..18fac62 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,8 @@
> Low level access to Cortex-M processors
+This project is developed and maintained by the [Cortex-M team][team].
+
## [Documentation](https://docs.rs/crate/cortex-m)
## License
@@ -22,3 +24,12 @@ at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the
work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
additional terms or conditions.
+
+## Code of Conduct
+
+Contribution to this crate is organized under the terms of the [Rust Code of
+Conduct][CoC], the maintainer of this crate, the [Cortex-M team][team], promises
+to intervene to uphold that code of conduct.
+
+[CoC]: CODE_OF_CONDUCT.md
+[team]: https://github.com/rust-embedded/wg#the-cortex-m-team
diff --git a/asm-cm7-r0p1.s b/asm-cm7-r0p1.s
new file mode 100644
index 0000000..a9ebf4a
--- /dev/null
+++ b/asm-cm7-r0p1.s
@@ -0,0 +1,27 @@
+ .section .text.__basepri_max_cm7_r0p1
+ .global __basepri_max_cm7_r0p1
+ .syntax unified
+ .thumb_func
+__basepri_max_cm7_r0p1:
+ mrs r1, PRIMASK
+ cpsid i
+ tst.w r1, #1
+ msr BASEPRI_MAX, r0
+ it ne
+ bxne lr
+ cpsie i
+ bx lr
+
+ .section .text.__basepri_w_cm7_r0p1
+ .global __basepri_w_cm7_r0p1
+ .syntax unified
+ .thumb_func
+__basepri_w_cm7_r0p1:
+ mrs r1, PRIMASK
+ cpsid i
+ tst.w r1, #1
+ msr BASEPRI, r0
+ it ne
+ bxne lr
+ cpsie i
+ bx lr
diff --git a/asm-v7.s b/asm-v7.s
new file mode 100644
index 0000000..c4c6dfb
--- /dev/null
+++ b/asm-v7.s
@@ -0,0 +1,27 @@
+ .section .text.__basepri_max
+ .global __basepri_max
+ .thumb_func
+__basepri_max:
+ msr BASEPRI_MAX, r0
+ bx lr
+
+ .section .text.__basepri_r
+ .global __basepri_r
+ .thumb_func
+__basepri_r:
+ mrs r0, BASEPRI
+ bx lr
+
+ .section .text.__basepri_w
+ .global __basepri_w
+ .thumb_func
+__basepri_w:
+ msr BASEPRI, r0
+ bx lr
+
+ .section .text.__faultmask
+ .global __faultmask
+ .thumb_func
+__faultmask:
+ mrs r0, FAULTMASK
+ bx lr
diff --git a/asm.s b/asm.s
new file mode 100644
index 0000000..bf2fd46
--- /dev/null
+++ b/asm.s
@@ -0,0 +1,120 @@
+ .section .text.__bkpt
+ .global __bkpt
+ .thumb_func
+__bkpt:
+ bkpt
+ bx lr
+
+ .section .text.__control
+ .global __control
+ .thumb_func
+__control:
+ mrs r0, CONTROL
+ bx lr
+
+ .section .text.__cpsid
+ .global __cpsid
+ .thumb_func
+__cpsid:
+ cpsid i
+ bx lr
+
+ .section .text.__cpsie
+ .global __cpsie
+ .thumb_func
+__cpsie:
+ cpsie i
+ bx lr
+
+ .section .text.__delay
+ .global __delay
+ .syntax unified
+ .thumb_func
+__delay:
+ nop
+ subs r0, #1
+ bne __delay
+ bx lr
+
+ .section .text.__dmb
+ .global __dmb
+ .thumb_func
+__dmb:
+ dmb 0xF
+ bx lr
+
+ .section .text.__dsb
+ .global __dsb
+ .thumb_func
+__dsb:
+ dsb 0xF
+ bx lr
+
+ .section .text.__isb
+ .global __isb
+ .thumb_func
+__isb:
+ isb 0xF
+ bx lr
+
+ .section .text.__msp_r
+ .global __msp_r
+ .thumb_func
+__msp_r:
+ mrs r0, MSP
+ bx lr
+
+ .section .text.__msp_w
+ .global __msp_w
+ .thumb_func
+__msp_w:
+ msr MSP, r0
+ bx lr
+
+ .section .text.__nop
+ .global __nop
+ .thumb_func
+__nop:
+ bx lr
+
+ .section .text.__primask
+ .global __primask
+ .thumb_func
+__primask:
+ mrs r0, PRIMASK
+ bx lr
+
+ .section .text.__psp_r
+ .global __psp_r
+ .thumb_func
+__psp_r:
+ mrs r0, PSP
+ bx lr
+
+ .section .text.__psp_w
+ .global __psp_w
+ .thumb_func
+__psp_w:
+ msr PSP, r0
+ bx lr
+
+ .section .text.__sev
+ .global __sev
+ .thumb_func
+__sev:
+ sev
+ bx lr
+
+ .section .text.__wfe
+ .global __wfe
+ .thumb_func
+__wfe:
+ wfe
+ bx lr
+
+ .section .text.__wfi
+ .global __wfi
+ .thumb_func
+__wfi:
+ wfi
+ bx lr
diff --git a/asm/basepri_max-cm7-r0p1.s b/asm/basepri_max-cm7-r0p1.s
deleted file mode 100644
index 573bd9c..0000000
--- a/asm/basepri_max-cm7-r0p1.s
+++ /dev/null
@@ -1,11 +0,0 @@
- .global __basepri_max
- .syntax unified
-__basepri_max:
- mrs r1, PRIMASK
- cpsid i
- tst.w r1, #1
- msr BASEPRI_MAX, r0
- it ne
- bxne lr
- cpsie i
- bx lr
diff --git a/asm/basepri_max.s b/asm/basepri_max.s
deleted file mode 100644
index 0ac3a5e..0000000
--- a/asm/basepri_max.s
+++ /dev/null
@@ -1,4 +0,0 @@
- .global __basepri_max
-__basepri_max:
- msr BASEPRI_MAX, r0
- bx lr
diff --git a/asm/basepri_r.s b/asm/basepri_r.s
deleted file mode 100644
index 9f727ab..0000000
--- a/asm/basepri_r.s
+++ /dev/null
@@ -1,4 +0,0 @@
- .global __basepri_r
-__basepri_r:
- mrs r0, BASEPRI
- bx lr
diff --git a/asm/basepri_w-cm7-r0p1.s b/asm/basepri_w-cm7-r0p1.s
deleted file mode 100644
index 5ac0209..0000000
--- a/asm/basepri_w-cm7-r0p1.s
+++ /dev/null
@@ -1,11 +0,0 @@
- .global __basepri_w
- .syntax unified
-__basepri_w:
- mrs r1, PRIMASK
- cpsid i
- tst.w r1, #1
- msr BASEPRI, r0
- it ne
- bxne lr
- cpsie i
- bx lr
diff --git a/asm/basepri_w.s b/asm/basepri_w.s
deleted file mode 100644
index b1f8709..0000000
--- a/asm/basepri_w.s
+++ /dev/null
@@ -1,4 +0,0 @@
- .global __basepri_w
-__basepri_w:
- msr BASEPRI, r0
- bx lr
diff --git a/asm/bkpt.s b/asm/bkpt.s
deleted file mode 100644
index 3d9d347..0000000
--- a/asm/bkpt.s
+++ /dev/null
@@ -1,4 +0,0 @@
- .global __bkpt
-__bkpt:
- bkpt
- bx lr
diff --git a/asm/control.s b/asm/control.s
deleted file mode 100644
index 81c35e6..0000000
--- a/asm/control.s
+++ /dev/null
@@ -1,4 +0,0 @@
- .global __control
-__control:
- mrs r0, CONTROL
- bx lr
diff --git a/asm/cpsid.s b/asm/cpsid.s
deleted file mode 100644
index ae4701d..0000000
--- a/asm/cpsid.s
+++ /dev/null
@@ -1,4 +0,0 @@
- .global __cpsid
-__cpsid:
- cpsid i
- bx lr
diff --git a/asm/cpsie.s b/asm/cpsie.s
deleted file mode 100644
index cba3a39..0000000
--- a/asm/cpsie.s
+++ /dev/null
@@ -1,4 +0,0 @@
- .global __cpsie
-__cpsie:
- cpsie i
- bx lr
diff --git a/asm/delay.s b/asm/delay.s
deleted file mode 100644
index 2bf92f1..0000000
--- a/asm/delay.s
+++ /dev/null
@@ -1,8 +0,0 @@
- .global __delay
- .syntax unified
- .thumb_func
-__delay:
- nop
- subs r0, #1
- bne __delay
- bx lr
diff --git a/asm/dmb.s b/asm/dmb.s
deleted file mode 100644
index 9fd38dd..0000000
--- a/asm/dmb.s
+++ /dev/null
@@ -1,4 +0,0 @@
- .global __dmb
-__dmb:
- dmb 0xF
- bx lr
diff --git a/asm/dsb.s b/asm/dsb.s
deleted file mode 100644
index a5f1da1..0000000
--- a/asm/dsb.s
+++ /dev/null
@@ -1,4 +0,0 @@
- .global __dsb
-__dsb:
- dsb 0xF
- bx lr
diff --git a/asm/faultmask.s b/asm/faultmask.s
deleted file mode 100644
index 5f08370..0000000
--- a/asm/faultmask.s
+++ /dev/null
@@ -1,4 +0,0 @@
- .global __faultmask
-__faultmask:
- mrs r0, FAULTMASK
- bx lr
diff --git a/asm/isb.s b/asm/isb.s
deleted file mode 100644
index a007a79..0000000
--- a/asm/isb.s
+++ /dev/null
@@ -1,4 +0,0 @@
- .global __isb
-__isb:
- isb 0xF
- bx lr
diff --git a/asm/msp_r.s b/asm/msp_r.s
deleted file mode 100644
index b31a715..0000000
--- a/asm/msp_r.s
+++ /dev/null
@@ -1,4 +0,0 @@
- .global __msp_r
-__msp_r:
- mrs r0, MSP
- bx lr
diff --git a/asm/msp_w.s b/asm/msp_w.s
deleted file mode 100644
index c589c0e..0000000
--- a/asm/msp_w.s
+++ /dev/null
@@ -1,4 +0,0 @@
- .global __msp_w
-__msp_w:
- msr MSP, r0
- bx lr
diff --git a/asm/nop.s b/asm/nop.s
deleted file mode 100644
index be35529..0000000
--- a/asm/nop.s
+++ /dev/null
@@ -1,3 +0,0 @@
- .global __nop
-__nop:
- bx lr
diff --git a/asm/primask.s b/asm/primask.s
deleted file mode 100644
index a3ff709..0000000
--- a/asm/primask.s
+++ /dev/null
@@ -1,4 +0,0 @@
- .global __primask
-__primask:
- mrs r0, PRIMASK
- bx lr
diff --git a/asm/psp_r.s b/asm/psp_r.s
deleted file mode 100644
index 1c5ff81..0000000
--- a/asm/psp_r.s
+++ /dev/null
@@ -1,4 +0,0 @@
- .global __psp_r
-__psp_r:
- mrs r0, PSP
- bx lr
diff --git a/asm/psp_w.s b/asm/psp_w.s
deleted file mode 100644
index 8ad1559..0000000
--- a/asm/psp_w.s
+++ /dev/null
@@ -1,4 +0,0 @@
- .global __psp_w
-__psp_w:
- msr PSP, r0
- bx lr
diff --git a/asm/sev.s b/asm/sev.s
deleted file mode 100644
index 2fa80a0..0000000
--- a/asm/sev.s
+++ /dev/null
@@ -1,4 +0,0 @@
- .global __sev
-__sev:
- sev
- bx lr
diff --git a/asm/wfe.s b/asm/wfe.s
deleted file mode 100644
index 8a30570..0000000
--- a/asm/wfe.s
+++ /dev/null
@@ -1,4 +0,0 @@
- .global __wfe
-__wfe:
- wfe
- bx lr
diff --git a/asm/wfi.s b/asm/wfi.s
deleted file mode 100644
index 2f31cf6..0000000
--- a/asm/wfi.s
+++ /dev/null
@@ -1,4 +0,0 @@
- .global __wfi
-__wfi:
- wfi
- bx lr
diff --git a/assemble.sh b/assemble.sh
new file mode 100755
index 0000000..28494a9
--- /dev/null
+++ b/assemble.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+set -euxo pipefail
+
+# cflags taken from cc 1.0.22
+
+crate=cortex-m
+
+# remove existing blobs because otherwise this will append object files to the old blobs
+rm -f bin/*.a
+
+arm-none-eabi-as -march=armv6s-m asm.s -o bin/$crate.o
+ar crs bin/thumbv6m-none-eabi.a bin/$crate.o
+
+arm-none-eabi-as -march=armv7-m asm.s -o bin/$crate.o
+arm-none-eabi-as -march=armv7-m asm-v7.s -o bin/$crate-v7.o
+ar crs bin/thumbv7m-none-eabi.a bin/$crate.o bin/$crate-v7.o
+
+arm-none-eabi-as -march=armv7e-m asm.s -o bin/$crate.o
+arm-none-eabi-as -march=armv7e-m asm-v7.s -o bin/$crate-v7.o
+arm-none-eabi-as -march=armv7e-m asm-cm7-r0p1.s -o bin/$crate-cm7-r0p1.o
+ar crs bin/thumbv7em-none-eabi.a bin/$crate.o bin/$crate-v7.o bin/$crate-cm7-r0p1.o
+ar crs bin/thumbv7em-none-eabihf.a bin/$crate.o bin/$crate-v7.o bin/$crate-cm7-r0p1.o
+
+arm-none-eabi-as -march=armv8-m.base asm.s -o bin/$crate.o
+ar crs bin/thumbv8m.base-none-eabi.a bin/$crate.o
+
+arm-none-eabi-as -march=armv8-m.main asm.s -o bin/$crate.o
+ar crs bin/thumbv8m.main-none-eabi.a bin/$crate.o
+
+rm bin/$crate.o
+rm bin/$crate-v7.o
+rm bin/$crate-cm7-r0p1.o
diff --git a/bin/thumbv6m-none-eabi.a b/bin/thumbv6m-none-eabi.a
new file mode 100644
index 0000000..2418bfc
--- /dev/null
+++ b/bin/thumbv6m-none-eabi.a
Binary files differ
diff --git a/bin/thumbv7em-none-eabi.a b/bin/thumbv7em-none-eabi.a
new file mode 100644
index 0000000..bd58e2b
--- /dev/null
+++ b/bin/thumbv7em-none-eabi.a
Binary files differ
diff --git a/bin/thumbv7em-none-eabihf.a b/bin/thumbv7em-none-eabihf.a
new file mode 100644
index 0000000..bd58e2b
--- /dev/null
+++ b/bin/thumbv7em-none-eabihf.a
Binary files differ
diff --git a/bin/thumbv7m-none-eabi.a b/bin/thumbv7m-none-eabi.a
new file mode 100644
index 0000000..9e34403
--- /dev/null
+++ b/bin/thumbv7m-none-eabi.a
Binary files differ
diff --git a/bin/thumbv8m.base-none-eabi.a b/bin/thumbv8m.base-none-eabi.a
new file mode 100644
index 0000000..6c6ce41
--- /dev/null
+++ b/bin/thumbv8m.base-none-eabi.a
Binary files differ
diff --git a/bin/thumbv8m.main-none-eabi.a b/bin/thumbv8m.main-none-eabi.a
new file mode 100644
index 0000000..6dddb2e
--- /dev/null
+++ b/bin/thumbv8m.main-none-eabi.a
Binary files differ
diff --git a/bors.toml b/bors.toml
deleted file mode 100644
index 5ccee21..0000000
--- a/bors.toml
+++ /dev/null
@@ -1,3 +0,0 @@
-status = [
- "continuous-integration/travis-ci/push",
-] \ No newline at end of file
diff --git a/build.rs b/build.rs
index 87e082e..47e86bb 100644
--- a/build.rs
+++ b/build.rs
@@ -1,44 +1,19 @@
-extern crate cc;
-
-use std::env;
+use std::path::PathBuf;
+use std::{env, fs};
fn main() {
let target = env::var("TARGET").unwrap();
+ let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
+ let name = env::var("CARGO_PKG_NAME").unwrap();
if target.starts_with("thumb") && env::var_os("CARGO_FEATURE_INLINE_ASM").is_none() {
- // NOTE we need to place each routine in a separate assembly file or the linker won't be
- // able to discard the unused routines
- let mut build = cc::Build::new();
- build
- .file("asm/basepri_r.s")
- .file("asm/bkpt.s")
- .file("asm/control.s")
- .file("asm/cpsid.s")
- .file("asm/cpsie.s")
- .file("asm/delay.s")
- .file("asm/dmb.s")
- .file("asm/dsb.s")
- .file("asm/faultmask.s")
- .file("asm/isb.s")
- .file("asm/msp_r.s")
- .file("asm/msp_w.s")
- .file("asm/nop.s")
- .file("asm/primask.s")
- .file("asm/psp_r.s")
- .file("asm/psp_w.s")
- .file("asm/sev.s")
- .file("asm/wfe.s")
- .file("asm/wfi.s");
-
- if env::var_os("CARGO_FEATURE_CM7_R0P1").is_some() {
- build.file("asm/basepri_max-cm7-r0p1.s");
- build.file("asm/basepri_w-cm7-r0p1.s");
- } else {
- build.file("asm/basepri_max.s");
- build.file("asm/basepri_w.s");
- }
+ fs::copy(
+ format!("bin/{}.a", target),
+ out_dir.join(format!("lib{}.a", name)),
+ ).unwrap();
- build.compile("asm");
+ println!("cargo:rustc-link-lib=static={}", name);
+ println!("cargo:rustc-link-search={}", out_dir.display());
}
if target.starts_with("thumbv6m-") {
@@ -51,6 +26,9 @@ fn main() {
println!("cargo:rustc-cfg=cortex_m");
println!("cargo:rustc-cfg=armv7m");
//println!("cargo:rustc-cfg=armv7em");
+ } else if target.starts_with("thumbv8m") {
+ println!("cargo:rustc-cfg=cortex_m");
+ println!("cargo:rustc-cfg=armv8m");
}
if target.ends_with("-eabihf") {
diff --git a/check-blobs.sh b/check-blobs.sh
new file mode 100755
index 0000000..94fde42
--- /dev/null
+++ b/check-blobs.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+# Checks that the blobs are up to date with the committed assembly files
+
+set -euxo pipefail
+
+for lib in $(ls bin/*.a); do
+ filename=$(basename $lib)
+ arm-none-eabi-objdump -Cd $lib > bin/${filename%.a}.before
+done
+
+./assemble.sh
+
+for lib in $(ls bin/*.a); do
+ filename=$(basename $lib)
+ arm-none-eabi-objdump -Cd $lib > bin/${filename%.a}.after
+done
+
+for cksum in $(ls bin/*.after); do
+ diff -u $cksum ${cksum%.after}.before
+done
diff --git a/ci/install.sh b/ci/install.sh
index a0cbf43..371cc8e 100644
--- a/ci/install.sh
+++ b/ci/install.sh
@@ -6,9 +6,10 @@ main() {
rustup target add $TARGET
;;
esac
+
+ mkdir gcc
+
+ curl -L https://developer.arm.com/-/media/Files/downloads/gnu-rm/7-2018q2/gcc-arm-none-eabi-7-2018-q2-update-linux.tar.bz2?revision=bc2c96c0-14b5-4bb4-9f18-bceb4050fee7?product=GNU%20Arm%20Embedded%20Toolchain,64-bit,,Linux,7-2018-q2-update | tar --strip-components=1 -C gcc -xj
}
-# NOTE(TRAVIS_BRANCH) Travis is configured to only build *pushes* (not PRs)
-if [ $TRAVIS_BRANCH != master ] || [ $TRAVIS_EVENT_TYPE = cron ]; then
- main
-fi
+main
diff --git a/ci/script.sh b/ci/script.sh
index 9fd46a3..20a8ea2 100644
--- a/ci/script.sh
+++ b/ci/script.sh
@@ -1,6 +1,10 @@
set -euxo pipefail
main() {
+ if [ $TRAVIS_RUST_VERSION = nightly ]; then
+ export RUSTFLAGS="-D warnings"
+ fi
+
cargo check --target $TARGET
if [ $TRAVIS_RUST_VERSION = nightly ]; then
@@ -23,9 +27,10 @@ main() {
cargo test --target $TARGET
;;
esac
+
+ if [ $TARGET = x86_64-unknown-linux-gnu ]; then
+ ./check-blobs.sh
+ fi
}
-# NOTE See the NOTE in `install.sh`
-if [ $TRAVIS_BRANCH != master ] || [ $TRAVIS_EVENT_TYPE = cron ]; then
- main
-fi
+main
diff --git a/src/itm.rs b/src/itm.rs
index 0e32e3c..4f8dcf8 100644
--- a/src/itm.rs
+++ b/src/itm.rs
@@ -4,7 +4,7 @@
use core::{fmt, mem, ptr, slice};
-use aligned::Aligned;
+use aligned::{Aligned, A4};
use peripheral::itm::Stim;
@@ -77,7 +77,7 @@ pub fn write_all(port: &mut Stim, buffer: &[u8]) {
/// # Examples
///
/// ``` ignore
-/// let mut buffer: Aligned<u32, _> = Aligned([0; 14]);
+/// let mut buffer: Aligned<A4, _> = Aligned([0; 14]);
///
/// buffer.copy_from_slice(b"Hello, world!\n");
///
@@ -86,7 +86,7 @@ pub fn write_all(port: &mut Stim, buffer: &[u8]) {
/// // Or equivalently
/// itm::write_aligned(&itm.stim[0], &Aligned(*b"Hello, world!\n"));
/// ```
-pub fn write_aligned(port: &mut Stim, buffer: &Aligned<u32, [u8]>) {
+pub fn write_aligned(port: &mut Stim, buffer: &Aligned<A4, [u8]>) {
unsafe {
let len = buffer.len();
diff --git a/src/lib.rs b/src/lib.rs
index 540bc4d..fda3e01 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -7,25 +7,18 @@
//! - Interrupt manipulation mechanisms
//! - Safe wrappers around Cortex-M specific instructions like `bkpt`
//!
-//! # Requirements
-//!
-//! To use this crate on the stable or beta channel `arm-none-eabi-gcc` needs to be installed and
-//! available in your `$PATH`.
-//!
//! # Optional features
//!
//! ## `inline-asm`
//!
//! When this feature is enabled the implementation of all the functions inside the `asm` and
//! `register` modules use inline assembly (`asm!`) instead of external assembly (FFI into separate
-//! assembly files compiled using `arm-none-eabi-gcc`). The advantages the enabling `inline-asm`
+//! assembly files pre-compiled using `arm-none-eabi-gcc`). The advantages of enabling `inline-asm`
//! are:
//!
//! - Reduced overhead. FFI eliminates the possibility of inlining so all operations include a
//! function call overhead when `inline-asm` is not enabled.
//!
-//! - `arm-none-eabi-gcc` is not required for building this crate.
-//!
//! - Some of the `register` API only becomes available only when `inline-asm` is enabled. Check the
//! API docs for details.
//!
@@ -39,7 +32,6 @@
#![cfg_attr(feature = "inline-asm", feature(asm))]
#![deny(missing_docs)]
-#![deny(warnings)]
#![no_std]
extern crate aligned;
diff --git a/src/macros.rs b/src/macros.rs
index e41cdc5..813552f 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -13,13 +13,13 @@ macro_rules! iprint {
#[macro_export]
macro_rules! iprintln {
($channel:expr) => {
- iprint!($channel, "\n");
+ $crate::itm::write_str($channel, "\n");
};
($channel:expr, $fmt:expr) => {
- iprint!($channel, concat!($fmt, "\n"));
+ $crate::itm::write_str($channel, concat!($fmt, "\n"));
};
($channel:expr, $fmt:expr, $($arg:tt)*) => {
- iprint!($channel, concat!($fmt, "\n"), $($arg)*);
+ $crate::itm::write_fmt($channel, format_args!(concat!($fmt, "\n"), $($arg)*));
};
}
diff --git a/src/peripheral/dcb.rs b/src/peripheral/dcb.rs
index 02ec901..14dc75b 100644
--- a/src/peripheral/dcb.rs
+++ b/src/peripheral/dcb.rs
@@ -2,6 +2,10 @@
use volatile_register::{RW, WO};
+use peripheral::DCB;
+
+const DCB_DEMCR_TRCENA: u32 = 1 << 24;
+
/// Register block
#[repr(C)]
pub struct RegisterBlock {
@@ -14,3 +18,20 @@ pub struct RegisterBlock {
/// Debug Exception and Monitor Control
pub demcr: RW<u32>,
}
+
+impl DCB {
+ /// Enables TRACE. This is for example required by the
+ /// `peripheral::DWT` cycle counter to work properly.
+ /// As by STM documentation, this flag is not reset on
+ /// soft-reset, only on power reset.
+ pub fn enable_trace(&mut self) {
+ // set bit 24 / TRCENA
+ unsafe { self.demcr.modify(|w| w | DCB_DEMCR_TRCENA); }
+ }
+
+ /// Disables TRACE. See `DCB::enable_trace()` for more details
+ pub fn disable_trace(&mut self) {
+ // unset bit 24 / TRCENA
+ unsafe { self.demcr.modify(|w| w & !DCB_DEMCR_TRCENA); }
+ }
+}
diff --git a/src/peripheral/mod.rs b/src/peripheral/mod.rs
index fe52bd1..6aacb73 100644
--- a/src/peripheral/mod.rs
+++ b/src/peripheral/mod.rs
@@ -77,7 +77,6 @@
// TODO stand-alone registers: ICTR, ACTLR and STIR
-#![allow(private_no_mangle_statics)]
use core::marker::PhantomData;
use core::ops;
diff --git a/src/peripheral/nvic.rs b/src/peripheral/nvic.rs
index 1a6a027..c59c2c8 100644
--- a/src/peripheral/nvic.rs
+++ b/src/peripheral/nvic.rs
@@ -69,13 +69,12 @@ pub struct RegisterBlock {
impl NVIC {
/// Clears `interrupt`'s pending state
+ #[deprecated(since = "0.5.8", note = "Use `NVIC::unpend`")]
pub fn clear_pending<I>(&mut self, interrupt: I)
where
I: Nr,
{
- let nr = interrupt.nr();
-
- unsafe { self.icpr[usize::from(nr / 32)].write(1 << (nr % 32)) }
+ Self::unpend(interrupt)
}
/// Disables `interrupt`
@@ -161,13 +160,23 @@ impl NVIC {
}
/// Forces `interrupt` into pending state
- pub fn set_pending<I>(&mut self, interrupt: I)
+ pub fn pend<I>(interrupt: I)
where
I: Nr,
{
let nr = interrupt.nr();
- unsafe { self.ispr[usize::from(nr / 32)].write(1 << (nr % 32)) }
+ // NOTE(unsafe) atomic stateless write; ICPR doesn't store any state
+ unsafe { (*Self::ptr()).ispr[usize::from(nr / 32)].write(1 << (nr % 32)) }
+ }
+
+ /// Forces `interrupt` into pending state
+ #[deprecated(since = "0.5.8", note = "Use `NVIC::pend`")]
+ pub fn set_pending<I>(&mut self, interrupt: I)
+ where
+ I: Nr,
+ {
+ Self::pend(interrupt)
}
/// Sets the "priority" of `interrupt` to `prio`
@@ -177,6 +186,11 @@ impl NVIC {
///
/// On ARMv6-M, updating an interrupt priority requires a read-modify-write operation. On
/// ARMv7-M, the operation is performed in a single atomic write operation.
+ ///
+ /// # Unsafety
+ ///
+ /// Changing priority levels can break priority-based critical sections (see
+ /// [`register::basepri`](../register/basepri/index.html)) and compromise memory safety.
pub unsafe fn set_priority<I>(&mut self, interrupt: I, prio: u8)
where
I: Nr,
@@ -198,6 +212,17 @@ impl NVIC {
}
}
+ /// Clears `interrupt`'s pending state
+ pub fn unpend<I>(interrupt: I)
+ where
+ I: Nr,
+ {
+ let nr = interrupt.nr();
+
+ // NOTE(unsafe) atomic stateless write; ICPR doesn't store any state
+ unsafe { (*Self::ptr()).icpr[usize::from(nr / 32)].write(1 << (nr % 32)) }
+ }
+
#[cfg(armv6m)]
fn ipr_index<I>(interrupt: &I) -> usize
where
diff --git a/src/peripheral/scb.rs b/src/peripheral/scb.rs
index ba36093..c82e098 100644
--- a/src/peripheral/scb.rs
+++ b/src/peripheral/scb.rs
@@ -7,9 +7,9 @@ use volatile_register::RW;
#[cfg(not(armv6m))]
use super::cpuid::CsselrCacheType;
#[cfg(not(armv6m))]
-use super::CPUID;
-#[cfg(not(armv6m))]
use super::CBP;
+#[cfg(not(armv6m))]
+use super::CPUID;
use super::SCB;
/// Register block
@@ -19,10 +19,7 @@ pub struct RegisterBlock {
pub icsr: RW<u32>,
/// Vector Table Offset (not present on Cortex-M0 variants)
- #[cfg(not(armv6m))]
pub vtor: RW<u32>,
- #[cfg(armv6m)]
- _reserved0: u32,
/// Application Interrupt and Reset Control
pub aircr: RW<u32>,
@@ -598,3 +595,207 @@ impl SCB {
}
}
}
+
+const SCB_SCR_SLEEPONEXIT: u32 = 0x1 << 1;
+
+impl SCB {
+ /// Set the SLEEPONEXIT bit in the SCR register
+ pub fn set_sleeponexit(&mut self) {
+ unsafe {
+ self.scr.modify(|scr| scr | SCB_SCR_SLEEPONEXIT);
+ }
+ }
+
+ /// Clear the SLEEPONEXIT bit in the SCR register
+ pub fn clear_sleeponexit(&mut self) {
+ unsafe {
+ self.scr.modify(|scr| scr & !SCB_SCR_SLEEPONEXIT);
+ }
+ }
+}
+
+const SCB_AIRCR_VECTKEY: u32 = 0x05FA << 16;
+const SCB_AIRCR_PRIGROUP_MASK: u32 = 0x5 << 8;
+const SCB_AIRCR_SYSRESETREQ: u32 = 1 << 2;
+
+impl SCB {
+ /// Initiate a system reset request to reset the MCU
+ pub fn system_reset(&mut self) -> ! {
+ ::asm::dsb();
+ unsafe {
+ self.aircr.modify(
+ |r| {
+ SCB_AIRCR_VECTKEY | // otherwise the write is ignored
+ r & SCB_AIRCR_PRIGROUP_MASK | // keep priority group unchanged
+ SCB_AIRCR_SYSRESETREQ
+ }, // set the bit
+ )
+ };
+ ::asm::dsb();
+ loop {
+ // wait for the reset
+ ::asm::nop(); // avoid rust-lang/rust#28728
+ }
+ }
+}
+
+const SCB_ICSR_PENDSVSET: u32 = 1 << 28;
+const SCB_ICSR_PENDSVCLR: u32 = 1 << 27;
+
+const SCB_ICSR_PENDSTSET: u32 = 1 << 26;
+const SCB_ICSR_PENDSTCLR: u32 = 1 << 25;
+
+impl SCB {
+ /// Set the PENDSVSET bit in the ICSR register which will pend the PendSV interrupt
+ pub fn set_pendsv() {
+ unsafe {
+ (*Self::ptr()).icsr.write(SCB_ICSR_PENDSVSET);
+ }
+ }
+
+ /// Check if PENDSVSET bit in the ICSR register is set meaning PendSV interrupt is pending
+ pub fn is_pendsv_pending() -> bool {
+ unsafe { (*Self::ptr()).icsr.read() & SCB_ICSR_PENDSVSET == SCB_ICSR_PENDSVSET }
+ }
+
+ /// Set the PENDSVCLR bit in the ICSR register which will clear a pending PendSV interrupt
+ pub fn clear_pendsv() {
+ unsafe {
+ (*Self::ptr()).icsr.write(SCB_ICSR_PENDSVCLR);
+ }
+ }
+
+ /// Set the PENDSTCLR bit in the ICSR register which will clear a pending SysTick interrupt
+ #[inline]
+ pub fn set_pendst() {
+ unsafe {
+ (*Self::ptr()).icsr.write(SCB_ICSR_PENDSTSET);
+ }
+ }
+
+ /// Check if PENDSTSET bit in the ICSR register is set meaning SysTick interrupt is pending
+ #[inline]
+ pub fn is_pendst_pending() -> bool {
+ unsafe { (*Self::ptr()).icsr.read() & SCB_ICSR_PENDSTSET == SCB_ICSR_PENDSTSET }
+ }
+
+ /// Set the PENDSTCLR bit in the ICSR register which will clear a pending SysTick interrupt
+ #[inline]
+ pub fn clear_pendst() {
+ unsafe {
+ (*Self::ptr()).icsr.write(SCB_ICSR_PENDSTCLR);
+ }
+ }
+}
+
+/// System handlers, exceptions with configurable priority
+#[allow(non_camel_case_types)]
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub enum SystemHandler {
+ // NonMaskableInt, // priority is fixed
+ // HardFault, // priority is fixed
+ /// Memory management interrupt (not present on Cortex-M0 variants)
+ #[cfg(not(armv6m))]
+ MemoryManagement,
+
+ /// Bus fault interrupt (not present on Cortex-M0 variants)
+ #[cfg(not(armv6m))]
+ BusFault,
+
+ /// Usage fault interrupt (not present on Cortex-M0 variants)
+ #[cfg(not(armv6m))]
+ UsageFault,
+
+ /// Secure fault interrupt (only on ARMv8-M)
+ #[cfg(any(armv8m, target_arch = "x86_64"))]
+ SecureFault,
+
+ /// SV call interrupt
+ SVCall,
+
+ /// Debug monitor interrupt (not present on Cortex-M0 variants)
+ #[cfg(not(armv6m))]
+ DebugMonitor,
+
+ /// Pend SV interrupt
+ PendSV,
+
+ /// System Tick interrupt
+ SysTick,
+}
+
+impl SystemHandler {
+ fn index(&self) -> u8 {
+ match *self {
+ #[cfg(not(armv6m))]
+ SystemHandler::MemoryManagement => 4,
+ #[cfg(not(armv6m))]
+ SystemHandler::BusFault => 5,
+ #[cfg(not(armv6m))]
+ SystemHandler::UsageFault => 6,
+ #[cfg(any(armv8m, target_arch = "x86_64"))]
+ SystemHandler::SecureFault => 7,
+ SystemHandler::SVCall => 11,
+ #[cfg(not(armv6m))]
+ SystemHandler::DebugMonitor => 12,
+ SystemHandler::PendSV => 14,
+ SystemHandler::SysTick => 15,
+ }
+ }
+}
+
+impl SCB {
+ /// Returns the hardware priority of `system_handler`
+ ///
+ /// *NOTE*: Hardware priority does not exactly match logical priority levels. See
+ /// [`NVIC.get_priority`](struct.NVIC.html#method.get_priority) for more details.
+ pub fn get_priority(system_handler: SystemHandler) -> u8 {
+ let index = system_handler.index();
+
+ #[cfg(not(armv6m))]
+ {
+ // NOTE(unsafe) atomic read with no side effects
+ unsafe { (*Self::ptr()).shpr[usize::from(index - 4)].read() }
+ }
+
+ #[cfg(armv6m)]
+ {
+ // NOTE(unsafe) atomic read with no side effects
+ let shpr = unsafe { (*Self::ptr()).shpr[usize::from((index - 8) / 4)].read() };
+ let prio = (shpr >> (8 * (index % 4))) & 0x000000ff;
+ prio as u8
+ }
+ }
+
+ /// Sets the hardware priority of `system_handler` to `prio`
+ ///
+ /// *NOTE*: Hardware priority does not exactly match logical priority levels. See
+ /// [`NVIC.get_priority`](struct.NVIC.html#method.get_priority) for more details.
+ ///
+ /// On ARMv6-M, updating a system handler priority requires a read-modify-write operation. On
+ /// ARMv7-M, the operation is performed in a single, atomic write operation.
+ ///
+ /// # Unsafety
+ ///
+ /// Changing priority levels can break priority-based critical sections (see
+ /// [`register::basepri`](../register/basepri/index.html)) and compromise memory safety.
+ pub unsafe fn set_priority(&mut self, system_handler: SystemHandler, prio: u8) {
+ let index = system_handler.index();
+
+ #[cfg(not(armv6m))]
+ {
+ self.shpr[usize::from(index - 4)].write(prio)
+ }
+
+ #[cfg(armv6m)]
+ {
+ self.shpr[usize::from((index - 8) / 4)].modify(|value| {
+ let shift = 8 * (index % 4);
+ let mask = 0x000000ff << shift;
+ let prio = u32::from(prio) << shift;
+
+ (value & !mask) | prio
+ });
+ }
+ }
+}
diff --git a/src/register/basepri.rs b/src/register/basepri.rs
index c9f09cc..a9cd6ef 100644
--- a/src/register/basepri.rs
+++ b/src/register/basepri.rs
@@ -45,13 +45,24 @@ pub unsafe fn write(_basepri: u8) {
},
#[cfg(all(cortex_m, not(feature = "inline-asm")))]
- () => {
- extern "C" {
- fn __basepri_w(_: u8);
+ () => match () {
+ #[cfg(not(feature = "cm7-r0p1"))]
+ () => {
+ extern "C" {
+ fn __basepri_w(_: u8);
+ }
+
+ __basepri_w(_basepri);
}
+ #[cfg(feature = "cm7-r0p1")]
+ () => {
+ extern "C" {
+ fn __basepri_w_cm7_r0p1(_: u8);
+ }
- __basepri_w(_basepri);
- }
+ __basepri_w_cm7_r0p1(_basepri);
+ }
+ },
#[cfg(not(cortex_m))]
() => unimplemented!(),
diff --git a/src/register/basepri_max.rs b/src/register/basepri_max.rs
index 91698b6..59ddb44 100644
--- a/src/register/basepri_max.rs
+++ b/src/register/basepri_max.rs
@@ -24,11 +24,24 @@ pub fn write(_basepri: u8) {
#[cfg(all(cortex_m, not(feature = "inline-asm")))]
() => unsafe {
- extern "C" {
- fn __basepri_max(_: u8);
- }
+ match () {
+ #[cfg(not(feature = "cm7-r0p1"))]
+ () => {
+ extern "C" {
+ fn __basepri_max(_: u8);
+ }
- __basepri_max(_basepri)
+ __basepri_max(_basepri)
+ }
+ #[cfg(feature = "cm7-r0p1")]
+ () => {
+ extern "C" {
+ fn __basepri_max_cm7_r0p1(_: u8);
+ }
+
+ __basepri_max_cm7_r0p1(_basepri)
+ }
+ }
},
#[cfg(not(cortex_m))]