aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml2
-rw-r--r--CHANGELOG.md2
-rw-r--r--README.md4
-rw-r--r--asm-cm7-r0p1.s8
-rw-r--r--asm-fpu.s21
-rw-r--r--asm-v7.s51
-rw-r--r--asm-v8-main.s15
-rw-r--r--asm-v8.s15
-rw-r--r--asm.s56
-rwxr-xr-xassemble.sh32
-rw-r--r--bin/thumbv6m-none-eabi.abin3070 -> 5814 bytes
-rw-r--r--bin/thumbv7em-none-eabi.abin5298 -> 11226 bytes
-rw-r--r--bin/thumbv7em-none-eabihf.abin5298 -> 13292 bytes
-rw-r--r--bin/thumbv7m-none-eabi.abin4240 -> 8984 bytes
-rw-r--r--bin/thumbv8m.base-none-eabi.abin4170 -> 8262 bytes
-rw-r--r--bin/thumbv8m.main-none-eabi.abin6580 -> 14036 bytes
-rw-r--r--bin/thumbv8m.main-none-eabihf.abin6580 -> 16108 bytes
-rw-r--r--src/asm.rs28
-rw-r--r--src/interrupt.rs4
-rw-r--r--src/lib.rs4
-rw-r--r--src/peripheral/icb.rs30
-rw-r--r--src/peripheral/itm.rs13
-rw-r--r--src/peripheral/mod.rs49
-rw-r--r--src/peripheral/mpu.rs37
-rw-r--r--src/peripheral/scb.rs26
-rw-r--r--src/register/apsr.rs2
-rw-r--r--src/register/basepri.rs6
-rw-r--r--src/register/basepri_max.rs4
-rw-r--r--src/register/control.rs4
-rw-r--r--src/register/faultmask.rs2
-rw-r--r--src/register/fpscr.rs343
-rw-r--r--src/register/lr.rs4
-rw-r--r--src/register/mod.rs7
-rw-r--r--src/register/msp.rs4
-rw-r--r--src/register/msplim.rs4
-rw-r--r--src/register/pc.rs4
-rw-r--r--src/register/primask.rs2
-rw-r--r--src/register/psp.rs4
-rw-r--r--src/register/psplim.rs4
39 files changed, 724 insertions, 67 deletions
diff --git a/.travis.yml b/.travis.yml
index 64ba50b..bbe3d48 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,8 @@
language: rust
matrix:
+ allow_failures:
+ - rust: nightly
include:
- env: TARGET=x86_64-unknown-linux-gnu
rust: stable
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 92b5893..274eb80 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -572,7 +572,7 @@ fn main() {
- Functions to get the vector table
- Wrappers over miscellaneous instructions like `bkpt`
-[Unreleased]: https://github.com/rust-embedded/cortex-m/compare/v0.6.1...HEAD
+[Unreleased]: https://github.com/rust-embedded/cortex-m/compare/v0.6.2...HEAD
[v0.6.2]: https://github.com/rust-embedded/cortex-m/compare/v0.6.1...v0.6.2
[v0.6.1]: https://github.com/rust-embedded/cortex-m/compare/v0.6.0...v0.6.1
[v0.6.0]: https://github.com/rust-embedded/cortex-m/compare/v0.5.8...v0.6.0
diff --git a/README.md b/README.md
index 18fac62..a098d98 100644
--- a/README.md
+++ b/README.md
@@ -9,6 +9,10 @@ This project is developed and maintained by the [Cortex-M team][team].
## [Documentation](https://docs.rs/crate/cortex-m)
+## Minimum Supported Rust Version (MSRV)
+
+This crate is guaranteed to compile on stable Rust 1.31 and up. It might compile with older versions but that may change in any new patch release.
+
## License
Licensed under either of
diff --git a/asm-cm7-r0p1.s b/asm-cm7-r0p1.s
index a9ebf4a..28c3384 100644
--- a/asm-cm7-r0p1.s
+++ b/asm-cm7-r0p1.s
@@ -1,7 +1,10 @@
+ .cfi_sections .debug_frame
+
.section .text.__basepri_max_cm7_r0p1
.global __basepri_max_cm7_r0p1
.syntax unified
.thumb_func
+ .cfi_startproc
__basepri_max_cm7_r0p1:
mrs r1, PRIMASK
cpsid i
@@ -11,11 +14,14 @@ __basepri_max_cm7_r0p1:
bxne lr
cpsie i
bx lr
+ .cfi_endproc
+ .size __basepri_max_cm7_r0p1, . - __basepri_max_cm7_r0p1
.section .text.__basepri_w_cm7_r0p1
.global __basepri_w_cm7_r0p1
.syntax unified
.thumb_func
+ .cfi_startproc
__basepri_w_cm7_r0p1:
mrs r1, PRIMASK
cpsid i
@@ -25,3 +31,5 @@ __basepri_w_cm7_r0p1:
bxne lr
cpsie i
bx lr
+ .cfi_endproc
+ .size __basepri_w_cm7_r0p1, . - __basepri_w_cm7_r0p1
diff --git a/asm-fpu.s b/asm-fpu.s
new file mode 100644
index 0000000..417d199
--- /dev/null
+++ b/asm-fpu.s
@@ -0,0 +1,21 @@
+ .cfi_sections .debug_frame
+
+ .section .text.__get_FPSCR
+ .global __get_FPSCR
+ .thumb_func
+ .cfi_startproc
+__get_FPSCR:
+ vmrs r0, fpscr
+ bx lr
+ .cfi_endproc
+ .size __get_FPSCR, . - __get_FPSCR
+
+ .section .text.__set_FPSCR
+ .global __set_FPSCR
+ .thumb_func
+ .cfi_startproc
+__set_FPSCR:
+ vmsr fpscr, r0
+ bx lr
+ .cfi_endproc
+ .size __set_FPSCR, . - __set_FPSCR
diff --git a/asm-v7.s b/asm-v7.s
index c4c6dfb..17d7110 100644
--- a/asm-v7.s
+++ b/asm-v7.s
@@ -1,27 +1,78 @@
+ .syntax unified
+ .cfi_sections .debug_frame
+
.section .text.__basepri_max
.global __basepri_max
.thumb_func
+ .cfi_startproc
__basepri_max:
msr BASEPRI_MAX, r0
bx lr
+ .cfi_endproc
+ .size __basepri_max, . - __basepri_max
.section .text.__basepri_r
.global __basepri_r
.thumb_func
+ .cfi_startproc
__basepri_r:
mrs r0, BASEPRI
bx lr
+ .cfi_endproc
+ .size __basepri_r, . - __basepri_r
.section .text.__basepri_w
.global __basepri_w
.thumb_func
+ .cfi_startproc
__basepri_w:
msr BASEPRI, r0
bx lr
+ .cfi_endproc
+ .size __basepri_w, . - __basepri_w
.section .text.__faultmask
.global __faultmask
.thumb_func
+ .cfi_startproc
__faultmask:
mrs r0, FAULTMASK
bx lr
+ .cfi_endproc
+ .size __faultmask, . - __faultmask
+
+ .section .text.__enable_icache
+ .global __enable_icache
+ .thumb_func
+ .cfi_startproc
+__enable_icache:
+ ldr r0, =0xE000ED14 @ CCR
+ mrs r2, PRIMASK @ save critical nesting info
+ cpsid i @ mask interrupts
+ ldr r1, [r0] @ read CCR
+ orr.w r1, r1, #(1 << 17) @ Set bit 17, IC
+ str r1, [r0] @ write it back
+ dsb @ ensure store completes
+ isb @ synchronize pipeline
+ msr PRIMASK, r2 @ unnest critical section
+ bx lr
+ .cfi_endproc
+ .size __enable_icache, . - __enable_icache
+
+ .section .text.__enable_dcache
+ .global __enable_dcache
+ .thumb_func
+ .cfi_startproc
+__enable_dcache:
+ ldr r0, =0xE000ED14 @ CCR
+ mrs r2, PRIMASK @ save critical nesting info
+ cpsid i @ mask interrupts
+ ldr r1, [r0] @ read CCR
+ orr.w r1, r1, #(1 << 16) @ Set bit 16, DC
+ str r1, [r0] @ write it back
+ dsb @ ensure store completes
+ isb @ synchronize pipeline
+ msr PRIMASK, r2 @ unnest critical section
+ bx lr
+ .cfi_endproc
+ .size __enable_dcache, . - __enable_dcache
diff --git a/asm-v8-main.s b/asm-v8-main.s
index a59845c..1fad155 100644
--- a/asm-v8-main.s
+++ b/asm-v8-main.s
@@ -1,28 +1,43 @@
+
+ .cfi_sections .debug_frame
+
.section .text.__msplim_r
.global __msplim_r
.thumb_func
+ .cfi_startproc
__msplim_r:
mrs r0, MSPLIM
bx lr
+ .cfi_endproc
+ .size __msplim_r, . - __msplim_r
.section .text.__msplim_w
.global __msplim_w
.thumb_func
+ .cfi_startproc
__msplim_w:
msr MSPLIM, r0
bx lr
+ .cfi_endproc
+ .size __msplim_w, . - __msplim_w
.section .text.__psplim_r
.global __psplim_r
.thumb_func
+ .cfi_startproc
__psplim_r:
mrs r0, PSPLIM
bx lr
+ .cfi_endproc
+ .size __psplim_r, . - __psplim_r
.section .text.__psplim_w
.global __psplim_w
.thumb_func
+ .cfi_startproc
__psplim_w:
msr PSPLIM, r0
bx lr
+ .cfi_endproc
+ .size __psplim_w, . - __psplim_w
diff --git a/asm-v8.s b/asm-v8.s
index b667bf0..7d3a8c9 100644
--- a/asm-v8.s
+++ b/asm-v8.s
@@ -1,27 +1,42 @@
+ .cfi_sections .debug_frame
+
.section .text.__tt
.global __tt
.thumb_func
+ .cfi_startproc
__tt:
tt r0, r0
bx lr
+ .cfi_endproc
+ .size __tt, . - __tt
.section .text.__ttt
.global __ttt
.thumb_func
+ .cfi_startproc
__ttt:
ttt r0, r0
bx lr
+ .cfi_endproc
+ .size __ttt, . - __ttt
.section .text.__tta
.global __tta
.thumb_func
+ .cfi_startproc
__tta:
tta r0, r0
bx lr
+ .cfi_endproc
+ .size __tta, . - __tta
+
.section .text.__ttat
.global __ttat
.thumb_func
+ .cfi_startproc
__ttat:
ttat r0, r0
bx lr
+ .cfi_endproc
+ .size __ttat, . - __ttat
diff --git a/asm.s b/asm.s
index ed1ec3f..3d1a54b 100644
--- a/asm.s
+++ b/asm.s
@@ -1,77 +1,109 @@
+ .cfi_sections .debug_frame
+
.section .text.__bkpt
.global __bkpt
.thumb_func
+ .cfi_startproc
__bkpt:
bkpt
bx lr
+ .cfi_endproc
+ .size __bkpt, . - __bkpt
.section .text.__control_r
.global __control_r
.thumb_func
+ .cfi_startproc
__control_r:
mrs r0, CONTROL
bx lr
+ .cfi_endproc
+ .size __control_r, . - __control_r
.section .text.__control_w
.global __control_w
.thumb_func
+ .cfi_startproc
__control_w:
msr CONTROL, r0
bx lr
+ .cfi_endproc
+ .size __control_w, . - __control_w
.section .text.__cpsid
.global __cpsid
.thumb_func
+ .cfi_startproc
__cpsid:
cpsid i
bx lr
+ .cfi_endproc
+ .size __cpsid, . - __cpsid
.section .text.__cpsie
.global __cpsie
.thumb_func
+ .cfi_startproc
__cpsie:
cpsie i
bx lr
+ .cfi_endproc
+ .size __cpsie, . - __cpsie
.section .text.__delay
.global __delay
.syntax unified
.thumb_func
+ .cfi_startproc
__delay:
1:
nop
subs r0, #1
bne 1b // Branch to 1 instead of __delay does not generate R_ARM_THM_JUMP8 relocation, which breaks linking on the thumbv6m-none-eabi target
bx lr
+ .cfi_endproc
+ .size __delay, . - __delay
.section .text.__dmb
.global __dmb
.thumb_func
+ .cfi_startproc
__dmb:
dmb 0xF
bx lr
+ .cfi_endproc
+ .size __dmb, . - __dmb
.section .text.__dsb
.global __dsb
.thumb_func
+ .cfi_startproc
__dsb:
dsb 0xF
bx lr
+ .cfi_endproc
+ .size __dsb, . - __dsb
.section .text.__isb
.global __isb
.thumb_func
+ .cfi_startproc
__isb:
isb 0xF
bx lr
+ .cfi_endproc
+ .size __isb, . - __isb
.section .text.__msp_r
.global __msp_r
.thumb_func
+ .cfi_startproc
__msp_r:
mrs r0, MSP
bx lr
+ .cfi_endproc
+ .size __msp_r, . - __msp_r
.section .text.__msp_w
.global __msp_w
@@ -79,26 +111,36 @@ __msp_r:
__msp_w:
msr MSP, r0
bx lr
+ .size __msp_w, . - __msp_w
.section .text.__nop
.global __nop
.thumb_func
+ .cfi_startproc
__nop:
bx lr
+ .cfi_endproc
+ .size __nop, . - __nop
.section .text.__primask
.global __primask
.thumb_func
+ .cfi_startproc
__primask:
mrs r0, PRIMASK
bx lr
+ .cfi_endproc
+ .size __primask, . - __primask
.section .text.__psp_r
.global __psp_r
.thumb_func
+ .cfi_startproc
__psp_r:
mrs r0, PSP
bx lr
+ .cfi_endproc
+ .size __psp_r, . - __psp_r
.section .text.__psp_w
.global __psp_w
@@ -106,31 +148,45 @@ __psp_r:
__psp_w:
msr PSP, r0
bx lr
+ .size __psp_w, . - __psp_w
.section .text.__sev
.global __sev
.thumb_func
+ .cfi_startproc
__sev:
sev
bx lr
+ .cfi_endproc
+ .size __sev, . - __sev
.section .text.__udf
.global __udf
.thumb_func
+ .cfi_startproc
__udf:
udf
+ .cfi_endproc
+ .size __udf, . - __udf
.section .text.__wfe
.global __wfe
.thumb_func
+ .cfi_startproc
__wfe:
wfe
bx lr
+ .cfi_endproc
+ .size __wfe, . - __wfe
+
.section .text.__wfi
.global __wfi
.thumb_func
+ .cfi_startproc
__wfi:
wfi
bx lr
+ .cfi_endproc
+ .size __wfi, . - __wfi
diff --git a/assemble.sh b/assemble.sh
index f63e837..775eccb 100755
--- a/assemble.sh
+++ b/assemble.sh
@@ -9,32 +9,36 @@ 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
+arm-none-eabi-as -g -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
+arm-none-eabi-as -g -march=armv7-m asm.s -o bin/$crate.o
+arm-none-eabi-as -g -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
+arm-none-eabi-as -g -march=armv7e-m asm.s -o bin/$crate.o
+arm-none-eabi-as -g -march=armv7e-m asm-fpu.s -mfpu=fpv4-sp-d16 -o bin/$crate-v7-fpu.o
+arm-none-eabi-as -g -march=armv7e-m asm-cm7-r0p1.s -o bin/$crate-cm7-r0p1.o
+arm-none-eabi-as -g -march=armv7e-m asm-v7.s -o bin/$crate-v7.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
+ar crs bin/thumbv7em-none-eabihf.a bin/$crate.o bin/$crate-v7.o bin/$crate-cm7-r0p1.o bin/$crate-v7-fpu.o
-arm-none-eabi-as -march=armv8-m.base asm.s -o bin/$crate.o
-arm-none-eabi-as -march=armv8-m.base asm-v8.s -o bin/$crate-v8.o
+arm-none-eabi-as -g -march=armv8-m.base asm.s -o bin/$crate.o
+arm-none-eabi-as -g -march=armv8-m.base asm-v8.s -o bin/$crate-v8.o
ar crs bin/thumbv8m.base-none-eabi.a bin/$crate.o bin/$crate-v8.o
-arm-none-eabi-as -march=armv8-m.main asm.s -o bin/$crate.o
-arm-none-eabi-as -march=armv8-m.main asm-v7.s -o bin/$crate-v7.o
-arm-none-eabi-as -march=armv8-m.main asm-v8.s -o bin/$crate-v8.o
-arm-none-eabi-as -march=armv8-m.main asm-v8-main.s -o bin/$crate-v8-main.o
+arm-none-eabi-as -g -march=armv8-m.main asm.s -o bin/$crate.o
+arm-none-eabi-as -g -march=armv8-m.main asm-v7.s -o bin/$crate-v7.o
+arm-none-eabi-as -g -march=armv8-m.main asm-v8.s -o bin/$crate-v8.o
+arm-none-eabi-as -g -march=armv8-m.main asm-v8-main.s -o bin/$crate-v8-main.o
+arm-none-eabi-as -g -march=armv8-m.main asm-fpu.s -mfpu=fpv5-sp-d16 -o bin/$crate-v8-fpu.o
ar crs bin/thumbv8m.main-none-eabi.a bin/$crate.o bin/$crate-v7.o bin/$crate-v8.o bin/$crate-v8-main.o
-ar crs bin/thumbv8m.main-none-eabihf.a bin/$crate.o bin/$crate-v7.o bin/$crate-v8.o bin/$crate-v8-main.o
+ar crs bin/thumbv8m.main-none-eabihf.a bin/$crate.o bin/$crate-v7.o bin/$crate-v8.o bin/$crate-v8-main.o bin/$crate-v8-fpu.o
rm bin/$crate.o
rm bin/$crate-v7.o
+rm bin/$crate-v7-fpu.o
+rm bin/$crate-v8-fpu.o
rm bin/$crate-cm7-r0p1.o
rm bin/$crate-v8.o
rm bin/$crate-v8-main.o
diff --git a/bin/thumbv6m-none-eabi.a b/bin/thumbv6m-none-eabi.a
index 06a7cb7..cb7a9f9 100644
--- a/bin/thumbv6m-none-eabi.a
+++ b/bin/thumbv6m-none-eabi.a
Binary files differ
diff --git a/bin/thumbv7em-none-eabi.a b/bin/thumbv7em-none-eabi.a
index 48da24d..b518e41 100644
--- a/bin/thumbv7em-none-eabi.a
+++ b/bin/thumbv7em-none-eabi.a
Binary files differ
diff --git a/bin/thumbv7em-none-eabihf.a b/bin/thumbv7em-none-eabihf.a
index 48da24d..84ff03b 100644
--- a/bin/thumbv7em-none-eabihf.a
+++ b/bin/thumbv7em-none-eabihf.a
Binary files differ
diff --git a/bin/thumbv7m-none-eabi.a b/bin/thumbv7m-none-eabi.a
index 296f66f..5fca383 100644
--- a/bin/thumbv7m-none-eabi.a
+++ 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
index 026250b..2913d30 100644
--- a/bin/thumbv8m.base-none-eabi.a
+++ 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
index 6848518..49f4b10 100644
--- a/bin/thumbv8m.main-none-eabi.a
+++ b/bin/thumbv8m.main-none-eabi.a
Binary files differ
diff --git a/bin/thumbv8m.main-none-eabihf.a b/bin/thumbv8m.main-none-eabihf.a
index 6848518..bb1ce2e 100644
--- a/bin/thumbv8m.main-none-eabihf.a
+++ b/bin/thumbv8m.main-none-eabihf.a
Binary files differ
diff --git a/src/asm.rs b/src/asm.rs
index b7ff19e..ebd61b3 100644
--- a/src/asm.rs
+++ b/src/asm.rs
@@ -8,7 +8,7 @@
pub fn bkpt() {
match () {
#[cfg(all(cortex_m, feature = "inline-asm"))]
- () => unsafe { asm!("bkpt" :::: "volatile") },
+ () => unsafe { llvm_asm!("bkpt" :::: "volatile") },
#[cfg(all(cortex_m, not(feature = "inline-asm")))]
() => unsafe {
@@ -36,7 +36,7 @@ pub fn delay(_n: u32) {
match () {
#[cfg(all(cortex_m, feature = "inline-asm"))]
() => unsafe {
- asm!("1:
+ llvm_asm!("1:
nop
subs $0, $$1
bne.n 1b"
@@ -65,7 +65,7 @@ pub fn delay(_n: u32) {
pub fn nop() {
match () {
#[cfg(all(cortex_m, feature = "inline-asm"))]
- () => unsafe { asm!("nop" :::: "volatile") },
+ () => unsafe { llvm_asm!("nop" :::: "volatile") },
#[cfg(all(cortex_m, not(feature = "inline-asm")))]
() => unsafe {
@@ -90,7 +90,7 @@ pub fn udf() -> ! {
match () {
#[cfg(all(cortex_m, feature = "inline-asm"))]
() => unsafe {
- asm!("udf" :::: "volatile");
+ llvm_asm!("udf" :::: "volatile");
core::hint::unreachable_unchecked();
},
@@ -115,7 +115,7 @@ pub fn udf() -> ! {
pub fn wfe() {
match () {
#[cfg(all(cortex_m, feature = "inline-asm"))]
- () => unsafe { asm!("wfe" :::: "volatile") },
+ () => unsafe { llvm_asm!("wfe" :::: "volatile") },
#[cfg(all(cortex_m, not(feature = "inline-asm")))]
() => unsafe {
@@ -136,7 +136,7 @@ pub fn wfe() {
pub fn wfi() {
match () {
#[cfg(all(cortex_m, feature = "inline-asm"))]
- () => unsafe { asm!("wfi" :::: "volatile") },
+ () => unsafe { llvm_asm!("wfi" :::: "volatile") },
#[cfg(all(cortex_m, not(feature = "inline-asm")))]
() => unsafe {
@@ -157,7 +157,7 @@ pub fn wfi() {
pub fn sev() {
match () {
#[cfg(all(cortex_m, feature = "inline-asm"))]
- () => unsafe { asm!("sev" :::: "volatile") },
+ () => unsafe { llvm_asm!("sev" :::: "volatile") },
#[cfg(all(cortex_m, not(feature = "inline-asm")))]
() => unsafe {
@@ -181,7 +181,7 @@ pub fn sev() {
pub fn isb() {
match () {
#[cfg(all(cortex_m, feature = "inline-asm"))]
- () => unsafe { asm!("isb 0xF" ::: "memory" : "volatile") },
+ () => unsafe { llvm_asm!("isb 0xF" ::: "memory" : "volatile") },
#[cfg(all(cortex_m, not(feature = "inline-asm")))]
() => unsafe {
@@ -209,7 +209,7 @@ pub fn isb() {
pub fn dsb() {
match () {
#[cfg(all(cortex_m, feature = "inline-asm"))]
- () => unsafe { asm!("dsb 0xF" ::: "memory" : "volatile") },
+ () => unsafe { llvm_asm!("dsb 0xF" ::: "memory" : "volatile") },
#[cfg(all(cortex_m, not(feature = "inline-asm")))]
() => unsafe {
@@ -235,7 +235,7 @@ pub fn dsb() {
pub fn dmb() {
match () {
#[cfg(all(cortex_m, feature = "inline-asm"))]
- () => unsafe { asm!("dmb 0xF" ::: "memory" : "volatile") },
+ () => unsafe { llvm_asm!("dmb 0xF" ::: "memory" : "volatile") },
#[cfg(all(cortex_m, not(feature = "inline-asm")))]
() => unsafe {
@@ -267,7 +267,7 @@ pub fn tt(addr: *mut u32) -> u32 {
() => {
let tt_resp: u32;
unsafe {
- asm!("tt $0, $1" : "=r"(tt_resp) : "r"(addr) :: "volatile");
+ llvm_asm!("tt $0, $1" : "=r"(tt_resp) : "r"(addr) :: "volatile");
}
tt_resp
}
@@ -302,7 +302,7 @@ pub fn ttt(addr: *mut u32) -> u32 {
() => {
let tt_resp: u32;
unsafe {
- asm!("ttt $0, $1" : "=r"(tt_resp) : "r"(addr) :: "volatile");
+ llvm_asm!("ttt $0, $1" : "=r"(tt_resp) : "r"(addr) :: "volatile");
}
tt_resp
}
@@ -338,7 +338,7 @@ pub fn tta(addr: *mut u32) -> u32 {
() => {
let tt_resp: u32;
unsafe {
- asm!("tta $0, $1" : "=r"(tt_resp) : "r"(addr) :: "volatile");
+ llvm_asm!("tta $0, $1" : "=r"(tt_resp) : "r"(addr) :: "volatile");
}
tt_resp
}
@@ -374,7 +374,7 @@ pub fn ttat(addr: *mut u32) -> u32 {
() => {
let tt_resp: u32;
unsafe {
- asm!("ttat $0, $1" : "=r"(tt_resp) : "r"(addr) :: "volatile");
+ llvm_asm!("ttat $0, $1" : "=r"(tt_resp) : "r"(addr) :: "volatile");
}
tt_resp
}
diff --git a/src/interrupt.rs b/src/interrupt.rs
index 2d53865..4d5ef0f 100644
--- a/src/interrupt.rs
+++ b/src/interrupt.rs
@@ -10,7 +10,7 @@ pub fn disable() {
match () {
#[cfg(all(cortex_m, feature = "inline-asm"))]
() => unsafe {
- asm!("cpsid i" ::: "memory" : "volatile");
+ llvm_asm!("cpsid i" ::: "memory" : "volatile");
},
#[cfg(all(cortex_m, not(feature = "inline-asm")))]
@@ -37,7 +37,7 @@ pub fn disable() {
pub unsafe fn enable() {
match () {
#[cfg(all(cortex_m, feature = "inline-asm"))]
- () => asm!("cpsie i" ::: "memory" : "volatile"),
+ () => llvm_asm!("cpsie i" ::: "memory" : "volatile"),
#[cfg(all(cortex_m, not(feature = "inline-asm")))]
() => {
diff --git a/src/lib.rs b/src/lib.rs
index aedb95a..89f420d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -12,7 +12,7 @@
//! ## `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
+//! `register` modules use inline assembly (`llvm_asm!`) instead of external assembly (FFI into separate
//! assembly files pre-compiled using `arm-none-eabi-gcc`). The advantages of enabling `inline-asm`
//! are:
//!
@@ -29,7 +29,7 @@
//! This crate is guaranteed to compile on stable Rust 1.31 and up. It *might*
//! compile with older versions but that may change in any new patch release.
-#![cfg_attr(feature = "inline-asm", feature(asm))]
+#![cfg_attr(feature = "inline-asm", feature(llvm_asm))]
#![deny(missing_docs)]
#![no_std]
#![allow(clippy::identity_op)]
diff --git a/src/peripheral/icb.rs b/src/peripheral/icb.rs
new file mode 100644
index 0000000..77ffd5d
--- /dev/null
+++ b/src/peripheral/icb.rs
@@ -0,0 +1,30 @@
+//! Implementation Control Block
+
+use volatile_register::{RO, RW};
+
+/// Register block
+#[repr(C)]
+pub struct RegisterBlock {
+ /// Interrupt Controller Type Register
+ ///
+ /// The bottom four bits of this register give the number of implemented
+ /// interrupt lines, divided by 32. So a value of `0b0010` indicates 64
+ /// interrupts.
+ #[cfg(any(armv7m, armv8m, target_arch = "x86_64"))]
+ pub ictr: RO<u32>,
+
+ /// The ICTR is not defined in the ARMv6-M Architecture Reference manual, so
+ /// we replace it with this.
+ #[cfg(not(any(armv7m, armv8m, target_arch = "x86_64")))]
+ _reserved: u32,
+
+ /// Auxiliary Control Register
+ ///
+ /// This register is entirely implementation defined -- the standard gives
+ /// it an address, but does not define its role or contents.
+ pub actlr: RW<u32>,
+
+ /// Coprocessor Power Control Register
+ #[cfg(armv8m)]
+ pub cppwr: RW<u32>,
+}
diff --git a/src/peripheral/itm.rs b/src/peripheral/itm.rs
index 0b63524..c0d560f 100644
--- a/src/peripheral/itm.rs
+++ b/src/peripheral/itm.rs
@@ -53,8 +53,19 @@ impl Stim {
}
/// Returns `true` if the stimulus port is ready to accept more data
+ #[cfg(not(armv8m))]
#[inline]
pub fn is_fifo_ready(&self) -> bool {
- unsafe { ptr::read_volatile(self.register.get()) == 1 }
+ unsafe { ptr::read_volatile(self.register.get()) & 0b1 == 1 }
+ }
+
+ /// Returns `true` if the stimulus port is ready to accept more data
+ #[cfg(armv8m)]
+ #[inline]
+ pub fn is_fifo_ready(&self) -> bool {
+ // ARMv8-M adds a disabled bit; we indicate that we are ready to
+ // proceed with a stimulus write if the port is either ready (bit 0) or
+ // disabled (bit 1).
+ unsafe { ptr::read_volatile(self.register.get()) & 0b11 != 0 }
}
}
diff --git a/src/peripheral/mod.rs b/src/peripheral/mod.rs
index 04fae31..0838dca 100644
--- a/src/peripheral/mod.rs
+++ b/src/peripheral/mod.rs
@@ -55,7 +55,7 @@
//!
//! - ARMv7-M Architecture Reference Manual (Issue E.b) - Chapter B3
-// TODO stand-alone registers: ICTR, ACTLR and STIR
+// TODO stand-alone register: STIR
use core::marker::PhantomData;
use core::ops;
@@ -72,6 +72,7 @@ pub mod fpb;
// NOTE(target_arch) is for documentation purposes
#[cfg(any(has_fpu, target_arch = "x86_64"))]
pub mod fpu;
+pub mod icb;
#[cfg(all(not(armv6m), not(armv8m_base)))]
pub mod itm;
pub mod mpu;
@@ -90,6 +91,7 @@ mod test;
/// Core peripherals
#[allow(non_snake_case)]
+#[allow(clippy::manual_non_exhaustive)]
pub struct Peripherals {
/// Cache and branch predictor maintenance operations.
/// Not available on Armv6-M.
@@ -111,6 +113,12 @@ pub struct Peripherals {
/// Floating Point Unit.
pub FPU: FPU,
+ /// Implementation Control Block.
+ ///
+ /// The name is from the v8-M spec, but the block existed in earlier
+ /// revisions, without a name.
+ pub ICB: ICB,
+
/// Instrumentation Trace Macrocell.
/// Not available on Armv6-M and Armv8-M Baseline.
pub ITM: ITM,
@@ -181,6 +189,9 @@ impl Peripherals {
FPU: FPU {
_marker: PhantomData,
},
+ ICB: ICB {
+ _marker: PhantomData,
+ },
ITM: ITM {
_marker: PhantomData,
},
@@ -364,6 +375,42 @@ impl ops::Deref for FPU {
}
}
+/// Implementation Control Block.
+///
+/// This block contains implementation-defined registers like `ictr` and
+/// `actlr`. It's called the "implementation control block" in the ARMv8-M
+/// standard, but earlier standards contained the registers, just without a
+/// name.
+pub struct ICB {
+ _marker: PhantomData<*const ()>,
+}
+
+unsafe impl Send for ICB {}
+
+impl ICB {
+ /// Returns a pointer to the register block
+ #[inline(always)]
+ pub fn ptr() -> *mut icb::RegisterBlock {
+ 0xE000_E004 as *mut _
+ }
+}
+
+impl ops::Deref for ICB {
+ type Target = self::icb::RegisterBlock;
+
+ #[inline(always)]
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*Self::ptr() }
+ }
+}
+
+impl ops::DerefMut for ICB {
+ #[inline(always)]
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ unsafe { &mut *Self::ptr() }
+ }
+}
+
/// Instrumentation Trace Macrocell
pub struct ITM {
_marker: PhantomData<*const ()>,
diff --git a/src/peripheral/mpu.rs b/src/peripheral/mpu.rs
index 09d06f0..4d53eb5 100644
--- a/src/peripheral/mpu.rs
+++ b/src/peripheral/mpu.rs
@@ -2,7 +2,8 @@
use volatile_register::{RO, RW};
-/// Register block
+/// Register block for ARMv7-M
+#[cfg(any(armv6m, armv7m, target_arch = "x86_64"))] // x86-64 is for rustdoc
#[repr(C)]
pub struct RegisterBlock {
/// Type
@@ -28,3 +29,37 @@ pub struct RegisterBlock {
/// Alias 3 of RSAR
pub rsar_a3: RW<u32>,
}
+
+/// Register block for ARMv8-M
+#[cfg(armv8m)]
+#[repr(C)]
+pub struct RegisterBlock {
+ /// Type
+ pub _type: RO<u32>,
+ /// Control
+ pub ctrl: RW<u32>,
+ /// Region Number
+ pub rnr: RW<u32>,
+ /// Region Base Address
+ pub rbar: RW<u32>,
+ /// Region Limit Address
+ pub rlar: RW<u32>,
+ /// Alias 1 of RBAR
+ pub rbar_a1: RW<u32>,
+ /// Alias 1 of RLAR
+ pub rlar_a1: RW<u32>,
+ /// Alias 2 of RBAR
+ pub rbar_a2: RW<u32>,
+ /// Alias 2 of RLAR
+ pub rlar_a2: RW<u32>,
+ /// Alias 3 of RBAR
+ pub rbar_a3: RW<u32>,
+ /// Alias 3 of RLAR
+ pub rlar_a3: RW<u32>,
+
+ // Reserved word at offset 0xBC
+ _reserved: u32,
+
+ /// Memory Attribute Indirection register 0 and 1
+ pub mair: [RW<u32>; 2],
+}
diff --git a/src/peripheral/scb.rs b/src/peripheral/scb.rs
index 7fb4505..001bb14 100644
--- a/src/peripheral/scb.rs
+++ b/src/peripheral/scb.rs
@@ -331,11 +331,15 @@ impl SCB {
cbp.iciallu();
// Enable I-cache
- // NOTE(unsafe): We have synchronised access by &mut self
- unsafe { self.ccr.modify(|r| r | SCB_CCR_IC_MASK) };
+ extern "C" {
+ // see asm-v7m.s
+ fn __enable_icache();
+ }
- crate::asm::dsb();
- crate::asm::isb();
+ // NOTE(unsafe): The asm routine manages exclusive access to the SCB
+ // registers and applies the proper barriers; it is technically safe on
+ // its own, and is only `unsafe` here because it's `extern "C"`.
+ unsafe { __enable_icache(); }
}
/// Disables I-cache if currently enabled.
@@ -400,11 +404,15 @@ impl SCB {
unsafe { self.invalidate_dcache(cpuid) };
// Now turn on the D-cache
- // NOTE(unsafe): We have synchronised access by &mut self
- unsafe { self.ccr.modify(|r| r | SCB_CCR_DC_MASK) };
+ extern "C" {
+ // see asm-v7m.s
+ fn __enable_dcache();
+ }
- crate::asm::dsb();
- crate::asm::isb();
+ // NOTE(unsafe): The asm routine manages exclusive access to the SCB
+ // registers and applies the proper barriers; it is technically safe on
+ // its own, and is only `unsafe` here because it's `extern "C"`.
+ unsafe { __enable_dcache(); }
}
/// Disables D-cache if currently enabled.
@@ -877,7 +885,7 @@ impl SCB {
}
}
- /// Set the PENDSTCLR bit in the ICSR register which will clear a pending SysTick interrupt
+ /// Set the PENDSTSET bit in the ICSR register which will pend a SysTick interrupt
#[inline]
pub fn set_pendst() {
unsafe {
diff --git a/src/register/apsr.rs b/src/register/apsr.rs
index 97a9f01..3db8aeb 100644
--- a/src/register/apsr.rs
+++ b/src/register/apsr.rs
@@ -55,7 +55,7 @@ pub fn read() -> Apsr {
() => {
let r: u32;
unsafe {
- asm!("mrs $0, APSR" : "=r"(r) ::: "volatile");
+ llvm_asm!("mrs $0, APSR" : "=r"(r) ::: "volatile");
}
Apsr { bits: r }
}
diff --git a/src/register/basepri.rs b/src/register/basepri.rs
index a09e34b..6caf938 100644
--- a/src/register/basepri.rs
+++ b/src/register/basepri.rs
@@ -8,7 +8,7 @@ pub fn read() -> u8 {
() => {
let r: u32;
unsafe {
- asm!("mrs $0, BASEPRI" : "=r"(r) ::: "volatile");
+ llvm_asm!("mrs $0, BASEPRI" : "=r"(r) ::: "volatile");
}
r as u8
}
@@ -37,10 +37,10 @@ pub unsafe fn write(_basepri: u8) {
#[cfg(all(cortex_m, feature = "inline-asm"))]
() => match () {
#[cfg(not(feature = "cm7-r0p1"))]
- () => asm!("msr BASEPRI, $0" :: "r"(_basepri) : "memory" : "volatile"),
+ () => llvm_asm!("msr BASEPRI, $0" :: "r"(_basepri) : "memory" : "volatile"),
#[cfg(feature = "cm7-r0p1")]
() => crate::interrupt::free(
- |_| asm!("msr BASEPRI, $0" :: "r"(_basepri) : "memory" : "volatile"),
+ |_| llvm_asm!("msr BASEPRI, $0" :: "r"(_basepri) : "memory" : "volatile"),
),
},
diff --git a/src/register/basepri_max.rs b/src/register/basepri_max.rs
index 694fd75..0e66f69 100644
--- a/src/register/basepri_max.rs
+++ b/src/register/basepri_max.rs
@@ -14,10 +14,10 @@ pub fn write(_basepri: u8) {
() => unsafe {
match () {
#[cfg(not(feature = "cm7-r0p1"))]
- () => asm!("msr BASEPRI_MAX, $0" :: "r"(_basepri) : "memory" : "volatile"),
+ () => llvm_asm!("msr BASEPRI_MAX, $0" :: "r"(_basepri) : "memory" : "volatile"),
#[cfg(feature = "cm7-r0p1")]
() => crate::interrupt::free(
- |_| asm!("msr BASEPRI_MAX, $0" :: "r"(_basepri) : "memory" : "volatile"),
+ |_| llvm_asm!("msr BASEPRI_MAX, $0" :: "r"(_basepri) : "memory" : "volatile"),
),
}
},
diff --git a/src/register/control.rs b/src/register/control.rs
index 07b26c3..211b532 100644
--- a/src/register/control.rs
+++ b/src/register/control.rs
@@ -163,7 +163,7 @@ pub fn read() -> Control {
#[cfg(feature = "inline-asm")]
() => {
let r: u32;
- unsafe { asm!("mrs $0, CONTROL" : "=r"(r) ::: "volatile") }
+ unsafe { llvm_asm!("mrs $0, CONTROL" : "=r"(r) ::: "volatile") }
r
}
@@ -194,7 +194,7 @@ pub unsafe fn write(_control: Control) {
#[cfg(feature = "inline-asm")]
() => {
let control = _control.bits();
- asm!("msr CONTROL, $0" :: "r"(control) : "memory" : "volatile");
+ llvm_asm!("msr CONTROL, $0" :: "r"(control) : "memory" : "volatile");
}
#[cfg(not(feature = "inline-asm"))]
diff --git a/src/register/faultmask.rs b/src/register/faultmask.rs
index 811385f..06f60fe 100644
--- a/src/register/faultmask.rs
+++ b/src/register/faultmask.rs
@@ -34,7 +34,7 @@ pub fn read() -> Faultmask {
#[cfg(feature = "inline-asm")]
() => {
let r: u32;
- unsafe { asm!("mrs $0, FAULTMASK" : "=r"(r) ::: "volatile") }
+ unsafe { llvm_asm!("mrs $0, FAULTMASK" : "=r"(r) ::: "volatile") }
r
}
diff --git a/src/register/fpscr.rs b/src/register/fpscr.rs
new file mode 100644
index 0000000..569d3a7
--- /dev/null
+++ b/src/register/fpscr.rs
@@ -0,0 +1,343 @@
+//! Floating-point Status Control Register
+
+/// Floating-point Status Control Register
+#[allow(clippy::missing_inline_in_public_items)]
+#[derive(Clone, Copy, Debug)]
+pub struct Fpscr {
+ bits: u32,
+}
+
+impl Fpscr {
+ /// Creates a `Fspcr` value from raw bits.
+ #[inline]
+ pub fn from_bits(bits: u32) -> Self {
+ Self { bits }
+ }
+
+ /// Returns the contents of the register as raw bits
+ #[inline]
+ pub fn bits(self) -> u32 {
+ self.bits
+ }
+
+ /// Read the Negative condition code flag
+ #[inline]
+ pub fn n(self) -> bool {
+ self.bits & (1 << 31) != 0
+ }
+
+ /// Sets the Negative condition code flag
+ #[inline]
+ pub fn set_n(&mut self, n: bool) {
+ let mask = 1 << 31;
+ match n {
+ true => self.bits |= mask,
+ false => self.bits &= !mask,
+ }
+ }
+
+ /// Read the Zero condition code flag
+ #[inline]
+ pub fn z(self) -> bool {
+ self.bits & (1 << 30) != 0
+ }
+
+ /// Sets the Zero condition code flag
+ #[inline]
+ pub fn set_z(&mut self, z: bool) {
+ let mask = 1 << 30;
+ match z {
+ true => self.bits |= mask,
+ false => self.bits &= !mask,
+ }
+ }
+
+ /// Read the Carry condition code flag
+ #[inline]
+ pub fn c(self) -> bool {
+ self.bits & (1 << 29) != 0
+ }
+
+ /// Sets the Carry condition code flag
+ #[inline]
+ pub fn set_c(&mut self, c: bool) {
+ let mask = 1 << 29;
+ match c {
+ true => self.bits |= mask,
+ false => self.bits &= !mask,
+ }
+ }
+
+ /// Read the Overflow condition code flag
+ #[inline]
+ pub fn v(self) -> bool {
+ self.bits & (1 << 28) != 0
+ }
+
+ /// Sets the Zero condition code flag
+ #[inline]
+ pub fn set_v(&mut self, v: bool) {
+ let mask = 1 << 28;
+ match v {
+ true => self.bits |= mask,
+ false => self.bits &= !mask,
+ }
+ }
+
+ /// Read the Alternative Half Precision bit
+ #[inline]
+ pub fn ahp(self) -> bool {
+ self.bits & (1 << 26) != 0
+ }
+
+ /// Sets the Alternative Half Precision bit
+ #[inline]
+ pub fn set_ahp(&mut self, ahp: bool) {
+ let mask = 1 << 26;
+ match ahp {
+ true => self.bits |= mask,
+ false => self.bits &= !mask,
+ }
+ }
+
+ /// Read the Default NaN mode bit
+ #[inline]
+ pub fn dn(self) -> bool {
+ self.bits & (1 << 25) != 0
+ }
+
+ /// Sets the Default NaN mode bit
+ #[inline]
+ pub fn set_dn(&mut self, dn: bool) {
+ let mask = 1 << 25;
+ match dn {
+ true => self.bits |= mask,
+ false => self.bits &= !mask,
+ }
+ }
+
+ /// Read the Flush to Zero mode bit
+ #[inline]
+ pub fn fz(self) -> bool {
+ self.bits & (1 << 24) != 0
+ }
+
+ /// Sets the Flush to Zero mode bit
+ #[inline]
+ pub fn set_fz(&mut self, fz: bool) {
+ let mask = 1 << 24;
+ match fz {
+ true => self.bits |= mask,
+ false => self.bits &= !mask,
+ }
+ }
+
+ /// Read the Rounding Mode control field
+ #[inline]
+ pub fn rmode(self) -> RMode {
+ match (self.bits & (3 << 22)) >> 22 {
+ 0 => RMode::Nearest,
+ 1 => RMode::PlusInfinity,
+ 2 => RMode::MinusInfinity,
+ _ => RMode::Zero,
+ }
+ }
+
+ /// Sets the Rounding Mode control field
+ #[inline]
+ pub fn set_rmode(&mut self, rmode: RMode) {
+ let mask = 3 << 22;
+ match rmode {
+ RMode::Nearest => self.bits = self.bits & !mask,
+ RMode::PlusInfinity => self.bits = (self.bits & !mask) | (1 << 22),
+ RMode::MinusInfinity => self.bits = (self.bits & !mask) | (2 << 22),
+ RMode::Zero => self.bits = self.bits | mask,
+ }
+ }
+
+ /// Read the Input Denormal cumulative exception bit
+ #[inline]
+ pub fn idc(self) -> bool {
+ self.bits & (1 << 7) != 0
+ }
+
+ /// Sets the Input Denormal cumulative exception bit
+ #[inline]
+ pub fn set_idc(&mut self, idc: bool) {
+ let mask = 1 << 7;
+ match idc {
+ true => self.bits |= mask,
+ false => self.bits &= !mask,
+ }
+ }
+
+ /// Read the Inexact cumulative exception bit
+ #[inline]
+ pub fn ixc(self) -> bool {
+ self.bits & (1 << 4) != 0
+ }
+
+ /// Sets the Inexact cumulative exception bit
+ #[inline]
+ pub fn set_ixc(&mut self, ixc: bool) {
+ let mask = 1 << 4;
+ match ixc {
+ true => self.bits |= mask,
+ false => self.bits &= !mask,
+ }
+ }
+
+ /// Read the Underflow cumulative exception bit
+ #[inline]
+ pub fn ufc(self) -> bool {
+ self.bits & (1 << 3) != 0
+ }
+
+ /// Sets the Underflow cumulative exception bit
+ #[inline]
+ pub fn set_ufc(&mut self, ufc: bool) {
+ let mask = 1 << 3;
+ match ufc {
+ true => self.bits |= mask,
+ false => self.bits &= !mask,
+ }
+ }
+
+ /// Read the Overflow cumulative exception bit
+ #[inline]
+ pub fn ofc(self) -> bool {
+ self.bits & (1 << 2) != 0
+ }
+
+ /// Sets the Overflow cumulative exception bit
+ #[inline]
+ pub fn set_ofc(&mut self, ofc: bool) {
+ let mask = 1 << 2;
+ match ofc {
+ true => self.bits |= mask,
+ false => self.bits &= !mask,
+ }
+ }
+
+ /// Read the Division by Zero cumulative exception bit
+ #[inline]
+ pub fn dzc(self) -> bool {
+ self.bits & (1 << 1) != 0
+ }
+
+ /// Sets the Division by Zero cumulative exception bit
+ #[inline]
+ pub fn set_dzc(&mut self, dzc: bool) {
+ let mask = 1 << 1;
+ match dzc {
+ true => self.bits |= mask,
+ false => self.bits &= !mask,
+ }
+ }
+
+ /// Read the Invalid Operation cumulative exception bit
+ #[inline]
+ pub fn ioc(self) -> bool {
+ self.bits & (1 << 0) != 0
+ }
+
+ /// Sets the Invalid Operation cumulative exception bit
+ #[inline]
+ pub fn set_ioc(&mut self, ioc: bool) {
+ let mask = 1 << 0;
+ match ioc {
+ true => self.bits |= mask,
+ false => self.bits &= !mask,
+ }
+ }
+}
+
+/// Rounding mode
+#[allow(clippy::missing_inline_in_public_items)]
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub enum RMode {
+ /// Round to Nearest (RN) mode. This is the reset value.
+ Nearest,
+ /// Round towards Plus Infinity (RP) mode.
+ PlusInfinity,
+ /// Round towards Minus Infinity (RM) mode.
+ MinusInfinity,
+ /// Round towards Zero (RZ) mode.
+ Zero,
+}
+
+impl RMode {
+ /// Is Nearest the current rounding mode?
+ #[inline]
+ pub fn is_nearest(self) -> bool {
+ self == RMode::Nearest
+ }
+
+ /// Is Plus Infinity the current rounding mode?
+ #[inline]
+ pub fn is_plus_infinity(self) -> bool {
+ self == RMode::PlusInfinity
+ }
+
+ /// Is Minus Infinity the current rounding mode?
+ #[inline]
+ pub fn is_minus_infinity(self) -> bool {
+ self == RMode::MinusInfinity
+ }
+
+ /// Is Zero the current rounding mode?
+ #[inline]
+ pub fn is_zero(self) -> bool {
+ self == RMode::Zero
+ }
+}
+
+/// Read the FPSCR register
+#[inline]
+pub fn read() -> Fpscr {
+ match () {
+ #[cfg(all(cortex_m, feature = "inline-asm"))]
+ () => {
+ let r: u32;
+ unsafe {
+ llvm_asm!("vmrs $0, fpscr" : "=r"(r) ::: "volatile");
+ }
+ Fpscr::from_bits(r)
+ }
+
+ #[cfg(all(cortex_m, not(feature = "inline-asm")))]
+ () => unsafe {
+ extern "C" {
+ fn __get_FPSCR() -> u32;
+ }
+ Fpscr::from_bits(__get_FPSCR())
+ },
+
+ #[cfg(not(cortex_m))]
+ () => unimplemented!(),
+ }
+}
+
+/// Set the value of the FPSCR register
+#[inline]
+pub unsafe fn write(_fspcr: Fpscr) {
+ match () {
+ #[cfg(all(cortex_m, feature = "inline-asm"))]
+ () => {
+ let bits = _fspcr.bits();
+ llvm_asm!("vmsr fpscr, $0" :: "r"(bits) :: "volatile");
+ }
+
+ #[cfg(all(cortex_m, not(feature = "inline-asm")))]
+ () => {
+ extern "C" {
+ fn __set_FPSCR(bits: u32);
+ }
+
+ __set_FPSCR(_fspcr.bits());
+ }
+
+ #[cfg(not(cortex_m))]
+ () => unimplemented!(),
+ }
+}
diff --git a/src/register/lr.rs b/src/register/lr.rs
index a17f7ac..6919e10 100644
--- a/src/register/lr.rs
+++ b/src/register/lr.rs
@@ -9,7 +9,7 @@ pub fn read() -> u32 {
#[cfg(cortex_m)]
() => {
let r: u32;
- unsafe { asm!("mov $0,R14" : "=r"(r) ::: "volatile") }
+ unsafe { llvm_asm!("mov $0,R14" : "=r"(r) ::: "volatile") }
r
}
@@ -25,7 +25,7 @@ pub fn read() -> u32 {
pub unsafe fn write(_bits: u32) {
match () {
#[cfg(cortex_m)]
- () => asm!("mov R14,$0" :: "r"(_bits) :: "volatile"),
+ () => llvm_asm!("mov R14,$0" :: "r"(_bits) :: "volatile"),
#[cfg(not(cortex_m))]
() => unimplemented!(),
diff --git a/src/register/mod.rs b/src/register/mod.rs
index d69c1a5..efbe6ef 100644
--- a/src/register/mod.rs
+++ b/src/register/mod.rs
@@ -22,6 +22,10 @@
//! - BASEPRI
//! - FAULTMASK
//!
+//! The following registers are only available for devices with an FPU:
+//!
+//! - FPSCR
+//!
//! # References
//!
//! - Cortex-M* Devices Generic User Guide - Section 2.1.3 Core registers
@@ -37,6 +41,9 @@ pub mod control;
#[cfg(all(not(armv6m), not(armv8m_base)))]
pub mod faultmask;
+#[cfg(has_fpu)]
+pub mod fpscr;
+
pub mod msp;
pub mod primask;
diff --git a/src/register/msp.rs b/src/register/msp.rs
index 082a7fc..b5460ed 100644
--- a/src/register/msp.rs
+++ b/src/register/msp.rs
@@ -7,7 +7,7 @@ pub fn read() -> u32 {
#[cfg(all(cortex_m, feature = "inline-asm"))]
() => {
let r;
- unsafe { asm!("mrs $0,MSP" : "=r"(r) ::: "volatile") }
+ unsafe { llvm_asm!("mrs $0,MSP" : "=r"(r) ::: "volatile") }
r
}
@@ -30,7 +30,7 @@ pub fn read() -> u32 {
pub unsafe fn write(_bits: u32) {
match () {
#[cfg(all(cortex_m, feature = "inline-asm"))]
- () => asm!("msr MSP,$0" :: "r"(_bits) :: "volatile"),
+ () => llvm_asm!("msr MSP,$0" :: "r"(_bits) :: "volatile"),
#[cfg(all(cortex_m, not(feature = "inline-asm")))]
() => {
diff --git a/src/register/msplim.rs b/src/register/msplim.rs
index df3642a..68915c4 100644
--- a/src/register/msplim.rs
+++ b/src/register/msplim.rs
@@ -7,7 +7,7 @@ pub fn read() -> u32 {
#[cfg(all(cortex_m, feature = "inline-asm"))]
() => {
let r;
- unsafe { asm!("mrs $0,MSPLIM" : "=r"(r) ::: "volatile") }
+ unsafe { llvm_asm!("mrs $0,MSPLIM" : "=r"(r) ::: "volatile") }
r
}
@@ -30,7 +30,7 @@ pub fn read() -> u32 {
pub unsafe fn write(_bits: u32) {
match () {
#[cfg(all(cortex_m, feature = "inline-asm"))]
- () => asm!("msr MSPLIM,$0" :: "r"(_bits) :: "volatile"),
+ () => llvm_asm!("msr MSPLIM,$0" :: "r"(_bits) :: "volatile"),
#[cfg(all(cortex_m, not(feature = "inline-asm")))]
() => {
diff --git a/src/register/pc.rs b/src/register/pc.rs
index 37176e8..f4486c4 100644
--- a/src/register/pc.rs
+++ b/src/register/pc.rs
@@ -9,7 +9,7 @@ pub fn read() -> u32 {
#[cfg(cortex_m)]
() => {
let r;
- unsafe { asm!("mov $0,R15" : "=r"(r) ::: "volatile") }
+ unsafe { llvm_asm!("mov $0,R15" : "=r"(r) ::: "volatile") }
r
}
@@ -25,7 +25,7 @@ pub fn read() -> u32 {
pub unsafe fn write(_bits: u32) {
match () {
#[cfg(cortex_m)]
- () => asm!("mov R15,$0" :: "r"(_bits) :: "volatile"),
+ () => llvm_asm!("mov R15,$0" :: "r"(_bits) :: "volatile"),
#[cfg(not(cortex_m))]
() => unimplemented!(),
diff --git a/src/register/primask.rs b/src/register/primask.rs
index 018c45b..4b6df3c 100644
--- a/src/register/primask.rs
+++ b/src/register/primask.rs
@@ -34,7 +34,7 @@ pub fn read() -> Primask {
#[cfg(feature = "inline-asm")]
() => {
let r: u32;
- unsafe { asm!("mrs $0, PRIMASK" : "=r"(r) ::: "volatile") }
+ unsafe { llvm_asm!("mrs $0, PRIMASK" : "=r"(r) ::: "volatile") }
r
}
diff --git a/src/register/psp.rs b/src/register/psp.rs
index b6618b0..c020e4f 100644
--- a/src/register/psp.rs
+++ b/src/register/psp.rs
@@ -7,7 +7,7 @@ pub fn read() -> u32 {
#[cfg(all(cortex_m, feature = "inline-asm"))]
() => {
let r;
- unsafe { asm!("mrs $0,PSP" : "=r"(r) ::: "volatile") }
+ unsafe { llvm_asm!("mrs $0,PSP" : "=r"(r) ::: "volatile") }
r
}
@@ -30,7 +30,7 @@ pub fn read() -> u32 {
pub unsafe fn write(_bits: u32) {
match () {
#[cfg(all(cortex_m, feature = "inline-asm"))]
- () => asm!("msr PSP,$0" :: "r"(_bits) :: "volatile"),
+ () => llvm_asm!("msr PSP,$0" :: "r"(_bits) :: "volatile"),
#[cfg(all(cortex_m, not(feature = "inline-asm")))]
() => {
diff --git a/src/register/psplim.rs b/src/register/psplim.rs
index 6c27008..8cb8f1c 100644
--- a/src/register/psplim.rs
+++ b/src/register/psplim.rs
@@ -7,7 +7,7 @@ pub fn read() -> u32 {
#[cfg(all(cortex_m, feature = "inline-asm"))]
() => {
let r;
- unsafe { asm!("mrs $0,PSPLIM" : "=r"(r) ::: "volatile") }
+ unsafe { llvm_asm!("mrs $0,PSPLIM" : "=r"(r) ::: "volatile") }
r
}
@@ -30,7 +30,7 @@ pub fn read() -> u32 {
pub unsafe fn write(_bits: u32) {
match () {
#[cfg(all(cortex_m, feature = "inline-asm"))]
- () => asm!("msr PSPLIM,$0" :: "r"(_bits) :: "volatile"),
+ () => llvm_asm!("msr PSPLIM,$0" :: "r"(_bits) :: "volatile"),
#[cfg(all(cortex_m, not(feature = "inline-asm")))]
() => {