stm32f429i-disc1: Enable hardware FPU
* Add Cortex-M4 toolchains with floating point hardware instructions.
* Update stm32f429i-disc1 to use hardware fpu toolchain by default.
* Add code to enable FPU in pw_dumb_io.
Verified tests that use floating point operations continue to pass.
Change-Id: I76bc7eeaf457eca1abacbc60992648d63dc85bf2
diff --git a/pw_dumb_io_baremetal_stm32f429/BUILD b/pw_dumb_io_baremetal_stm32f429/BUILD
new file mode 100644
index 0000000..2d9f88b
--- /dev/null
+++ b/pw_dumb_io_baremetal_stm32f429/BUILD
@@ -0,0 +1,25 @@
+# Copyright 2019 The Pigweed Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not
+# use this file except in compliance with the License. You may obtain a copy of
+# the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations under
+# the License.
+
+package(default_visibility = ["//visibility:public"])
+
+licenses(["notice"]) # Apache License 2.0
+
+filegroup(
+ name = "pw_dumb_io_baremetal_stm32f429",
+ srcs = [
+ "core_init.c",
+ "dumb_io_baremetal.cc",
+ ],
+)
diff --git a/pw_dumb_io_baremetal_stm32f429/dumb_io_baremetal.cc b/pw_dumb_io_baremetal_stm32f429/dumb_io_baremetal.cc
index 43f5c42..1c6b288 100644
--- a/pw_dumb_io_baremetal_stm32f429/dumb_io_baremetal.cc
+++ b/pw_dumb_io_baremetal_stm32f429/dumb_io_baremetal.cc
@@ -161,6 +161,19 @@
usart1.baud_rate = CalcBaudRegister(kSystemCoreClock, /*target_baud=*/115200);
usart1.config1 = kEnableUsart | kReceiveEnable | kTransmitEnable;
+
+// TODO(pwbug/17): Replace when Pigweed config system is added.
+#if defined(PW_ARMV7M_ENABLE_FPU) && PW_ARMV7M_ENABLE_FPU == 1
+ // Enable FPU if built using hardware FPU instructions.
+ // CPCAR mask that enables FPU. (ARMv7-M Section B3.2.20)
+ constexpr uint32_t kFpuEnableMask = (0xFu << 20);
+
+ // Memory mapped register to enable FPU. (ARMv7-M Section B3.2.2, Table B3-4)
+ volatile uint32_t& arm_v7m_cpacr =
+ *reinterpret_cast<volatile uint32_t*>(0xE000ED88u);
+
+ arm_v7m_cpacr |= kFpuEnableMask;
+#endif // defined(PW_ARMV7M_ENABLE_FPU) && PW_ARMV7M_ENABLE_FPU == 1
}
namespace pw::dumb_io {
diff --git a/pw_toolchain/BUILD.gn b/pw_toolchain/BUILD.gn
index f723c13..f7f9962 100644
--- a/pw_toolchain/BUILD.gn
+++ b/pw_toolchain/BUILD.gn
@@ -74,10 +74,20 @@
generate_toolchains("cortex_m4") {
toolchain_template = "arm_gcc_toolchain"
+ software_fpu_cflags = [ "-mfloat-abi=soft" ]
+
+ hardware_fpu_cflags = [
+ # When hardware FPU is enabled, PW_ARMV7M_ENABLE_FPU is set to 1.
+ # TODO(pwbug/17): Replace when there's a more sophisticated configuration
+ # system.
+ "-DPW_ARMV7M_ENABLE_FPU=1",
+ "-mfloat-abi=hard",
+ "-mfpu=fpv4-sp-d16",
+ ]
+
common_toolchain_cflags = [
"-mabi=aapcs",
"-mcpu=cortex-m4",
- "-mfloat-abi=soft",
"-mthumb",
"-specs=nano.specs",
"-specs=nosys.specs",
@@ -89,21 +99,48 @@
]
toolchains = [
+ # Cortex-M4 toolchains that use software-emulated floating point.
{
toolchain_name = "arm_gcc_cortex_m4_og"
additional_cflags = [ "-Og" ]
+ additional_cflags += software_fpu_cflags
},
{
toolchain_name = "arm_gcc_cortex_m4_o1"
additional_cflags = [ "-O1" ]
+ additional_cflags += software_fpu_cflags
},
{
toolchain_name = "arm_gcc_cortex_m4_o2"
additional_cflags = [ "-O2" ]
+ additional_cflags += software_fpu_cflags
},
{
toolchain_name = "arm_gcc_cortex_m4_os"
additional_cflags = [ "-Os" ]
+ additional_cflags += software_fpu_cflags
+ },
+
+ # Cortex-M4 toolchains that use hardware FPU instructions.
+ {
+ toolchain_name = "arm_gcc_cortex_m4f_og"
+ additional_cflags = [ "-Og" ]
+ additional_cflags += hardware_fpu_cflags
+ },
+ {
+ toolchain_name = "arm_gcc_cortex_m4f_o1"
+ additional_cflags = [ "-O1" ]
+ additional_cflags += hardware_fpu_cflags
+ },
+ {
+ toolchain_name = "arm_gcc_cortex_m4f_o2"
+ additional_cflags = [ "-O2" ]
+ additional_cflags += hardware_fpu_cflags
+ },
+ {
+ toolchain_name = "arm_gcc_cortex_m4f_os"
+ additional_cflags = [ "-Os" ]
+ additional_cflags += hardware_fpu_cflags
},
]
}
diff --git a/targets/stm32f429i-disc1/target_config.gni b/targets/stm32f429i-disc1/target_config.gni
index b10a89a..ff3d7c6 100644
--- a/targets/stm32f429i-disc1/target_config.gni
+++ b/targets/stm32f429i-disc1/target_config.gni
@@ -23,7 +23,7 @@
declare_args() {
# Specifies the toolchain to use for this build.
- pw_target_toolchain = "$dir_pw_toolchain:arm_gcc_cortex_m4_og"
+ pw_target_toolchain = "$dir_pw_toolchain:arm_gcc_cortex_m4f_og"
}
# Executable wrapper that includes some baremetal startup code.