diff --git a/include/libopencm3/stm32/f7/pwr.h b/include/libopencm3/stm32/f7/pwr.h
new file mode 100644
index 00000000..a1184d1d
--- /dev/null
+++ b/include/libopencm3/stm32/f7/pwr.h
@@ -0,0 +1,282 @@
+/** @defgroup pwr_defines PWR Defines
+
+@brief Defined Constants and Types for the STM32F7xx Power Control
+
+@ingroup STM32F7xx_defines
+
+@version 1.0.0
+
+@author @htmlonly © @endhtmlonly 2017 Matthew Lai
+
+@date 12 March 2017
+
+LGPL License Terms @ref lgpl_license
+ */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2017 Matthew Lai
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+
+#ifndef LIBOPENCM3_PWR_H
+#define LIBOPENCM3_PWR_H
+
+/**@{*/
+
+/* --- PWR registers ------------------------------------------------------- */
+
+/* Power control register (PWR_CR1) */
+#define PWR_CR1 MMIO32(POWER_CONTROL_BASE + 0x00)
+
+/* Power control/status register (PWR_CSR1) */
+#define PWR_CSR1 MMIO32(POWER_CONTROL_BASE + 0x04)
+
+/* Power control register 2 (PWR_CR2) */
+#define PWR_CR2 MMIO32(POWER_CONTROL_BASE + 0x08)
+
+/* Power control/status register 2 (PWR_CSR2) */
+#define PWR_CSR2 MMIO32(POWER_CONTROL_BASE + 0x0c)
+
+/* --- PWR_CR1 values ------------------------------------------------------- */
+
+/* Bits [31:20]: Reserved, must be kept at reset value. */
+
+/* UDEN[19:18]: Under-drive enable in stop mode */
+#define PWR_CR1_UDEN_LSB 18
+/** @defgroup pwr_uden Under-drive enable in stop mode
+@ingroup STM32F_pwr_defines
+
+@{*/
+#define PWR_CR1_UDEN_DISABLED (0x0 << PWR_CR1_UDEN_LSB)
+#define PWR_CR1_UDEN_ENABLED (0x3 << PWR_CR1_UDEN_LSB)
+/**@}*/
+#define PWR_CR1_UDEN_MASK (0x3 << PWR_CR1_UDEN_LSB)
+
+/* ODSWEN: Over-drive switching enabled */
+#define PWR_CR1_ODSWEN (1 << 17)
+
+/* ODEN: Over-drive enable */
+#define PWR_CR1_ODEN (1 << 16)
+
+/* VOS[15:14]: Regulator voltage scaling output selection */
+#define PWR_CR1_VOS_LSB 14
+/** @defgroup pwr_vos Regulator voltage scaling output selection
+@ingroup STM32F_pwr_defines
+
+@{*/
+#define PWR_CR1_VOS_SCALE_3 (0x1 << PWR_CR1_VOS_LSB)
+#define PWR_CR1_VOS_SCALE_2 (0x2 << PWR_CR1_VOS_LSB)
+#define PWR_CR1_VOS_SCALE_1 (0x3 << PWR_CR1_VOS_LSB)
+/**@}*/
+#define PWR_CR1_VOS_MASK (0x3 << PWR_CR1_VOS_LSB)
+
+/* ADCDC1: Masks extra flash accesses by prefetch (see AN4073) */
+#define PWR_CR1_ADCDC1 (1 << 13)
+
+/* Bit 12: Reserved, must be kept at reset value. */
+
+/* MRUDS: Main regulator in deepsleep under-drive mode */
+#define PWR_CR1_MRUDS (1 << 11)
+
+/* LPUDS: Low-power regulator in deepsleep under-drive mode */
+#define PWR_CR1_LPUDS (1 << 10)
+
+/* FPDS: Flash power-down in Stop mode */
+#define PWR_CR1_FPDS (1 << 9)
+
+/* DBP: Disable backup domain write protection */
+#define PWR_CR1_DBP (1 << 8)
+
+/* PLS[7:5]: PVD level selection */
+#define PWR_CR1_PLS_LSB 5
+/** @defgroup pwr_pls PVD level selection
+@ingroup STM32F_pwr_defines
+
+@{*/
+#define PWR_CR1_PLS_2V0 (0x0 << PWR_CR_PLS_LSB)
+#define PWR_CR1_PLS_2V1 (0x1 << PWR_CR_PLS_LSB)
+#define PWR_CR1_PLS_2V3 (0x2 << PWR_CR_PLS_LSB)
+#define PWR_CR1_PLS_2V5 (0x3 << PWR_CR_PLS_LSB)
+#define PWR_CR1_PLS_2V6 (0x4 << PWR_CR_PLS_LSB)
+#define PWR_CR1_PLS_2V7 (0x5 << PWR_CR_PLS_LSB)
+#define PWR_CR1_PLS_2V8 (0x6 << PWR_CR_PLS_LSB)
+#define PWR_CR1_PLS_2V9 (0x7 << PWR_CR_PLS_LSB)
+/**@}*/
+#define PWR_CR1_PLS_MASK (0x7 << PWR_CR_PLS_LSB)
+
+/* PVDE: Power voltage detector enable */
+#define PWR_CR1_PVDE (1 << 4)
+
+/* CSBF: Clear standby flag */
+#define PWR_CR1_CSBF (1 << 3)
+
+/* Bit 2: Reserved, must be kept at reset value. */
+
+/* PDDS: Power down deepsleep */
+#define PWR_CR1_PDDS (1 << 1)
+
+/* LPDS: Low-power deepsleep */
+#define PWR_CR1_LPDS (1 << 0)
+
+/* --- PWR_CSR1 values ------------------------------------------------------ */
+
+/* Bits [31:20]: Reserved, must be kept at reset value. */
+
+/* UDRDY[19:18]: Under-drive ready flag */
+#define PWR_CSR1_UDRDY_LSB 18
+/** @defgroup pwr_udrdy Under-drive ready flag
+@ingroup STM32F_pwr_defines
+
+@{*/
+#define PWR_CSR1_UDRDY_DISABLED (0x0 << PWR_CSR1_UDRDY_LSB)
+#define PWR_CSR1_UDRDY_ACTIVATED (0x3 << PWR_CSR1_UDRDY_LSB)
+/**@}*/
+#define PWR_CSR1_UDRDY_MASK (0x3 << PWR_CSR1_UDRDY_LSB)
+
+/* ODSWRDY: Over-drive mode switching ready */
+#define PWR_CSR1_ODSWRDY (1 << 17)
+
+/* ODRDY: Over-drive mode ready */
+#define PWR_CSR1_ODRDY (1 << 16)
+
+/* Bit 15: Reserved, must be kept at reset value. */
+
+/* VOSRDY: Regulator voltage scaling output selection ready bit */
+#define PWR_CSR1_VOSRDY (1 << 14)
+
+/* Bits [13:10]: Reserved, must be kept at reset value. */
+
+/* BRE: Backup regulator enable */
+#define PWR_CSR1_BRE (1 << 9)
+
+/* EIWUP: Enable internal wakeup */
+#define PWR_CSR1_EIWUP (1 << 8)
+
+/* Bits [7:4]: Reserved, must be kept at reset value. */
+
+/* BRR: Backup regulator ready */
+#define PWR_CSR1_BRR (1 << 3)
+
+/* PVDO: PVD output */
+#define PWR_CSR1_PVDO (1 << 2)
+
+/* SBF: Standby flag */
+#define PWR_CSR1_SBF (1 << 1)
+
+/* WUIF: Wakeup internal flag */
+#define PWR_CSR1_WUIF (1 << 0)
+
+/* --- PWR_CR2 values ------------------------------------------------------ */
+
+/* Bits [31:14]: Reserved, must be kept at reset value. */
+
+/* WUPP6: Wakeup pin polarity bit for PI11 */
+#define PWR_CR2_WUPP6 (1 << 13)
+
+/* WUPP5: Wakeup pin polarity bit for PI8 */
+#define PWR_CR2_WUPP5 (1 << 12)
+
+/* WUPP4: Wakeup pin polarity bit for PC13 */
+#define PWR_CR2_WUPP4 (1 << 11)
+
+/* WUPP3: Wakeup pin polarity bit for PC1 */
+#define PWR_CR2_WUPP3 (1 << 10)
+
+/* WUPP2: Wakeup pin polarity bit for PA2 */
+#define PWR_CR2_WUPP2 (1 << 9)
+
+/* WUPP1: Wakeup pin polarity bit for PA0 */
+#define PWR_CR2_WUPP1 (1 << 8)
+
+/* Bits [7:6]: Reserved, must be kept at reset value. */
+
+/* CWUPF6: Clear Wakeup Pin flag for PI11 */
+#define PWR_CR2_CWUPF6 (1 << 5)
+
+/* CWUPF5: Clear Wakeup Pin flag for PI8 */
+#define PWR_CR2_CWUPF5 (1 << 4)
+
+/* CWUPF4: Clear Wakeup Pin flag for PC13 */
+#define PWR_CR2_CWUPF4 (1 << 3)
+
+/* CWUPF3: Clear Wakeup Pin flag for PC1 */
+#define PWR_CR2_CWUPF3 (1 << 2)
+
+/* CWUPF2: Clear Wakeup Pin flag for PA2 */
+#define PWR_CR2_CWUPF2 (1 << 1)
+
+/* CWUPF1: Clear Wakeup Pin flag for PA0 */
+#define PWR_CR2_CWUPF1 (1 << 0)
+
+/* --- PWR_CSR2 values ------------------------------------------------------ */
+
+/* Bits [31:14]: Reserved, must be kept at reset value. */
+
+/* EWUP6: Enable Wakeup pin for PI11 */
+#define PWR_CSR2_EWUP6 (1 << 13)
+
+/* EWUP5: Enable Wakeup pin for PI8 */
+#define PWR_CSR2_EWUP5 (1 << 12)
+
+/* EWUP4: Enable Wakeup pin for PC13 */
+#define PWR_CSR2_EWUP4 (1 << 11)
+
+/* EWUP3: Enable Wakeup pin for PC1 */
+#define PWR_CSR2_EWUP3 (1 << 10)
+
+/* EWUP2: Enable Wakeup pin for PA2 */
+#define PWR_CSR2_EWUP2 (1 << 19)
+
+/* EWUP1: Enable Wakeup pin for PA0 */
+#define PWR_CSR2_EWUP1 (1 << 18)
+
+/* Bits [7:6]: Reserved, must be kept at reset value. */
+
+/* WUPF6: Wakeup Pin flag for PI11 */
+#define PWR_CSR2_WUPF6 (1 << 5)
+
+/* WUPF5: Wakeup Pin flag for PI8 */
+#define PWR_CSR2_WUPF5 (1 << 4)
+
+/* WUPF4: Wakeup Pin flag for PC13 */
+#define PWR_CSR2_WUPF4 (1 << 3)
+
+/* WUPF3: Wakeup Pin flag for PC1 */
+#define PWR_CSR2_WUPF3 (1 << 2)
+
+/* WUPF2: Wakeup Pin flag for PA2 */
+#define PWR_CSR2_WUPF2 (1 << 1)
+
+/* WUPF1: Wakeup Pin flag for PA0 */
+#define PWR_CSR2_WUPF1 (1 << 0)
+
+/* --- Function prototypes ------------------------------------------------- */
+
+enum pwr_vos_scale {
+ PWR_SCALE1, /** <= 180MHz w/o overdrive, <= 216MHz w/ overdrive */
+ PWR_SCALE2, /** <= 168MHz w/o overdrive, <= 180MHz w/ overdrive */
+ PWR_SCALE3, /** <= 144MHz */
+};
+
+BEGIN_DECLS
+
+void pwr_set_vos_scale(enum pwr_vos_scale scale);
+void pwr_enable_overdrive(void);
+void pwr_disable_overdrive(void);
+
+END_DECLS
+
+#endif
diff --git a/include/libopencm3/stm32/f7/rcc.h b/include/libopencm3/stm32/f7/rcc.h
index 2f7891e6..ff49b2a4 100644
--- a/include/libopencm3/stm32/f7/rcc.h
+++ b/include/libopencm3/stm32/f7/rcc.h
@@ -36,6 +36,8 @@
#ifndef LIBOPENCM3_RCC_H
#define LIBOPENCM3_RCC_H
+#include
+
/* --- RCC registers ------------------------------------------------------- */
#define RCC_CR MMIO32(RCC_BASE + 0x00)
@@ -617,7 +619,8 @@ struct rcc_clock_scale {
uint8_t hpre;
uint8_t ppre1;
uint8_t ppre2;
- uint8_t power_save;
+ enum pwr_vos_scale vos_scale;
+ uint8_t overdrive;
uint32_t apb1_frequency;
uint32_t apb2_frequency;
};
diff --git a/include/libopencm3/stm32/pwr.h b/include/libopencm3/stm32/pwr.h
index 57aefdb4..2b21be58 100644
--- a/include/libopencm3/stm32/pwr.h
+++ b/include/libopencm3/stm32/pwr.h
@@ -30,6 +30,8 @@
# include
#elif defined(STM32F4)
# include
+#elif defined(STM32F7)
+# include
#elif defined(STM32L1)
# include
#elif defined(STM32L0)
diff --git a/lib/stm32/f7/Makefile b/lib/stm32/f7/Makefile
index aa71b0f9..97c31d6a 100644
--- a/lib/stm32/f7/Makefile
+++ b/lib/stm32/f7/Makefile
@@ -42,7 +42,7 @@ TGT_CFLAGS += $(STANDARD_FLAGS)
ARFLAGS = rcs
-OBJS = rcc.o gpio.o gpio_common_all.o gpio_common_f0234.o
+OBJS = pwr.o rcc.o gpio.o gpio_common_all.o gpio_common_f0234.o
OBJS += rcc_common_all.o flash_common_f234.o flash_common_f24.o
diff --git a/lib/stm32/f7/pwr.c b/lib/stm32/f7/pwr.c
new file mode 100644
index 00000000..93bb845d
--- /dev/null
+++ b/lib/stm32/f7/pwr.c
@@ -0,0 +1,66 @@
+/** @defgroup pwr_file PWR
+ *
+ * @ingroup STM32F7xx
+ *
+ * @brief libopencm3 STM32F7xx Power Control
+ *
+ * @version 1.0.0
+ *
+ * @author @htmlonly © @endhtmlonly 2011 Stephen Caudle
+ * @author @htmlonly © @endhtmlonly 2017 Matthew Lai
+ *
+ * @date 12 March 2017
+ *
+ * This library supports the power control system for the
+ * STM32F7 series of ARM Cortex Microcontrollers by ST Microelectronics.
+ *
+ * LGPL License Terms @ref lgpl_license
+ */
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2011 Stephen Caudle
+ * Copyright (C) 2017 Matthew Lai
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ */
+
+#include
+
+void pwr_set_vos_scale(enum pwr_vos_scale scale)
+{
+ PWR_CR1 &= ~PWR_CR1_VOS_MASK;
+
+ if (scale == PWR_SCALE1) {
+ PWR_CR1 |= PWR_CR1_VOS_SCALE_1;
+ } else if (scale == PWR_SCALE2) {
+ PWR_CR1 |= PWR_CR1_VOS_SCALE_2;
+ } else if (scale == PWR_SCALE3) {
+ PWR_CR1 |= PWR_CR1_VOS_SCALE_3;
+ }
+}
+
+void pwr_enable_overdrive(void)
+{
+ PWR_CR1 |= PWR_CR1_ODEN;
+ while (!(PWR_CSR1 & PWR_CSR1_ODRDY));
+ PWR_CR1 |= PWR_CR1_ODSWEN;
+ while (!(PWR_CSR1 & PWR_CSR1_ODSWRDY));
+}
+
+void pwr_disable_overdrive(void)
+{
+ PWR_CR1 &= ~(PWR_CR1_ODEN | PWR_CR1_ODSWEN);
+ while (!(PWR_CSR1 & PWR_CSR1_ODSWRDY));
+}
diff --git a/lib/stm32/f7/rcc.c b/lib/stm32/f7/rcc.c
index 3de4762c..10e1d2ef 100644
--- a/lib/stm32/f7/rcc.c
+++ b/lib/stm32/f7/rcc.c
@@ -1,5 +1,6 @@
#include
#include
+#include
#include
uint32_t rcc_ahb_frequency = 16000000;
@@ -12,11 +13,13 @@ const struct rcc_clock_scale rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_END] = {
.plln = 432,
.pllp = 2,
.pllq = 9,
+ .flash_config = FLASH_ACR_ICEN | FLASH_ACR_DCEN |
+ FLASH_ACR_LATENCY_7WS,
.hpre = RCC_CFGR_HPRE_DIV_NONE,
.ppre1 = RCC_CFGR_PPRE_DIV_4,
.ppre2 = RCC_CFGR_PPRE_DIV_2,
- .flash_config = FLASH_ACR_ICEN | FLASH_ACR_DCEN |
- FLASH_ACR_LATENCY_7WS,
+ .vos_scale = PWR_SCALE1,
+ .overdrive = 1,
.apb1_frequency = 108000000,
.apb2_frequency = 216000000,
},
@@ -338,13 +341,13 @@ void rcc_clock_setup_hse_3v3(const struct rcc_clock_scale *clock)
rcc_osc_on(RCC_HSE);
rcc_wait_for_osc_ready(RCC_HSE);
- /* Enable/disable high performance mode */
-/* if (!clock->power_save) {
- pwr_set_vos_scale(SCALE1);
- } else {
- pwr_set_vos_scale(SCALE2);
+ rcc_periph_clock_enable(RCC_PWR);
+ pwr_set_vos_scale(clock->vos_scale);
+
+ if (clock->overdrive) {
+ pwr_enable_overdrive();
}
-*/
+
/*
* Set prescalers for AHB, ADC, ABP1, ABP2.
* Do this before touching the PLL (TODO: why?).