From c911aaf822d245568792cb11cff3d627314e39c2 Mon Sep 17 00:00:00 2001 From: Prasanna Karthik Date: Tue, 1 Nov 2016 17:32:11 -0700 Subject: [PATCH 1/2] stm32f746 discovery kit zephyr port Signed-off-by: Prasanna Karthik --- .../st_stm32/stm32f7/Kconfig.defconfig.series | 96 +++++ .../stm32f7/Kconfig.defconfig.stm32f7xx | 34 ++ arch/arm/soc/st_stm32/stm32f7/Kconfig.series | 25 ++ arch/arm/soc/st_stm32/stm32f7/Kconfig.soc | 25 ++ arch/arm/soc/st_stm32/stm32f7/Makefile | 7 + .../soc/st_stm32/stm32f7/flash_registers.h | 90 +++++ .../arm/soc/st_stm32/stm32f7/gpio_registers.h | 64 ++++ arch/arm/soc/st_stm32/stm32f7/linker.ld | 19 + arch/arm/soc/st_stm32/stm32f7/rcc_registers.h | 170 +++++++++ arch/arm/soc/st_stm32/stm32f7/soc.c | 67 ++++ arch/arm/soc/st_stm32/stm32f7/soc.h | 104 +++++ arch/arm/soc/st_stm32/stm32f7/soc_gpio.c | 266 +++++++++++++ arch/arm/soc/st_stm32/stm32f7/soc_irq.h | 135 +++++++ arch/arm/soc/st_stm32/stm32f7/soc_pinmux.c | 94 +++++ arch/arm/soc/st_stm32/stm32f7/soc_registers.h | 25 ++ boards/arm/discovery_smt32f7/Kconfig.board | 20 + .../arm/discovery_smt32f7/Kconfig.defconfig | 23 ++ boards/arm/discovery_smt32f7/Makefile | 2 + boards/arm/discovery_smt32f7/Makefile.board | 6 + boards/arm/discovery_smt32f7/board.h | 22 ++ .../discovery_smt32f7_defconfig | 36 ++ .../arm/discovery_smt32f7/support/openocd.cfg | 12 + drivers/clock_control/Kconfig | 2 + drivers/clock_control/Kconfig.stm32f7x | 151 ++++++++ drivers/clock_control/Makefile | 1 + drivers/clock_control/stm32f7x_clock.c | 360 ++++++++++++++++++ drivers/gpio/gpio_stm32.c | 14 +- drivers/gpio/gpio_stm32.h | 2 +- drivers/pinmux/stm32/pinmux_stm32.c | 2 +- drivers/pinmux/stm32/pinmux_stm32f7.h | 33 ++ 30 files changed, 1898 insertions(+), 9 deletions(-) create mode 100644 arch/arm/soc/st_stm32/stm32f7/Kconfig.defconfig.series create mode 100644 arch/arm/soc/st_stm32/stm32f7/Kconfig.defconfig.stm32f7xx create mode 100644 arch/arm/soc/st_stm32/stm32f7/Kconfig.series create mode 100644 arch/arm/soc/st_stm32/stm32f7/Kconfig.soc create mode 100644 arch/arm/soc/st_stm32/stm32f7/Makefile create mode 100644 arch/arm/soc/st_stm32/stm32f7/flash_registers.h create mode 100644 arch/arm/soc/st_stm32/stm32f7/gpio_registers.h create mode 100644 arch/arm/soc/st_stm32/stm32f7/linker.ld create mode 100644 arch/arm/soc/st_stm32/stm32f7/rcc_registers.h create mode 100644 arch/arm/soc/st_stm32/stm32f7/soc.c create mode 100644 arch/arm/soc/st_stm32/stm32f7/soc.h create mode 100644 arch/arm/soc/st_stm32/stm32f7/soc_gpio.c create mode 100644 arch/arm/soc/st_stm32/stm32f7/soc_irq.h create mode 100644 arch/arm/soc/st_stm32/stm32f7/soc_pinmux.c create mode 100644 arch/arm/soc/st_stm32/stm32f7/soc_registers.h create mode 100644 boards/arm/discovery_smt32f7/Kconfig.board create mode 100644 boards/arm/discovery_smt32f7/Kconfig.defconfig create mode 100644 boards/arm/discovery_smt32f7/Makefile create mode 100644 boards/arm/discovery_smt32f7/Makefile.board create mode 100644 boards/arm/discovery_smt32f7/board.h create mode 100644 boards/arm/discovery_smt32f7/discovery_smt32f7_defconfig create mode 100644 boards/arm/discovery_smt32f7/support/openocd.cfg create mode 100644 drivers/clock_control/Kconfig.stm32f7x create mode 100644 drivers/clock_control/stm32f7x_clock.c create mode 100644 drivers/pinmux/stm32/pinmux_stm32f7.h diff --git a/arch/arm/soc/st_stm32/stm32f7/Kconfig.defconfig.series b/arch/arm/soc/st_stm32/stm32f7/Kconfig.defconfig.series new file mode 100644 index 00000000000000..b83d6e30933e9f --- /dev/null +++ b/arch/arm/soc/st_stm32/stm32f7/Kconfig.defconfig.series @@ -0,0 +1,96 @@ +# Kconfig.defconfig.eries - ST Microelectronics STM32F7 MCU linue +# +# Copyright (c) 2016 Linaro Limited +# +# 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 +# +# http://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. +# + +if SOC_SERIES_STM32F7X + +source "arch/arm/soc/st_stm32/stm32f7/Kconfig.defconfig.stm32f7*" + +config SOC_SERIES + default stm32f7 + +config NUM_IRQ_PRIO_BITS + int + default 4 + +config SERIAL + def_bool y + +if SERIAL + +config CONSOLE + def_bool y + +config UART_CONSOLE + def_bool y + +config UART_CONSOLE_ON_DEV_NAME + default UART_1 if BOARD_DISCOVERY_STM32F7 + +config UART_STM32 + def_bool y + +config UART_STM32_PORT_0 + def_bool y + +config UART_STM32_PORT_0_NAME + default UART_0 + +config UART_STM32_PORT_0_BAUD_RATE + default 115200 + +config UART_STM32_PORT_1 + def_bool y + +config UART_STM32_PORT_1_NAME + default UART_1 + +config UART_STM32_PORT_1_BAUD_RATE + default 115200 + +endif #SERIAL + +if CLOCK_CONTROL + +config CLOCK_CONTROL_STM32F7X + def_bool y + +endif #CLOCK_CONTROL + +if GPIO + +config GPIO_STM32 + def_bool y + +config GPIO_STM32_PORTA + def_bool y + +config GPIO_STM32_PORTB + def_bool y + +config GPIO_STM32_PORTC + def_bool y + +endif #GPIO + +if PINMUX + +config PINMUX_STM32 + def_bool y + +endif #PINMUX + +endif # SOC_SERIES_STM32F7X diff --git a/arch/arm/soc/st_stm32/stm32f7/Kconfig.defconfig.stm32f7xx b/arch/arm/soc/st_stm32/stm32f7/Kconfig.defconfig.stm32f7xx new file mode 100644 index 00000000000000..fa247c9ad8e2a2 --- /dev/null +++ b/arch/arm/soc/st_stm32/stm32f7/Kconfig.defconfig.stm32f7xx @@ -0,0 +1,34 @@ +# Kconfig - ST STM32F401RE MCU configuration options +# +# Copyright (c) 2016 Linaro Limited. +# +# 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 +# +# http://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. +# + +if SOC_STM32F7XX + +config SOC + string + default stm32f7xx + +config SRAM_SIZE + default 256 + +config FLASH_SIZE + default 1024 + +config NUM_IRQS + int + default 85 + +endif # SOC_STM32F401RE diff --git a/arch/arm/soc/st_stm32/stm32f7/Kconfig.series b/arch/arm/soc/st_stm32/stm32f7/Kconfig.series new file mode 100644 index 00000000000000..791aa2504eca6e --- /dev/null +++ b/arch/arm/soc/st_stm32/stm32f7/Kconfig.series @@ -0,0 +1,25 @@ +# Kconfig - ST Microelectronics STM32F1 MCU series +# +# Copyright (c) 2016 Linaro Limited +# +# 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 +# +# http://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. +# + +config SOC_SERIES_STM32F7X + bool "STM32F7x Series MCU" + select CPU_CORTEX_M + select CPU_CORTEX_M7 + select SOC_FAMILY_STM32 + select SYS_POWER_LOW_POWER_STATE_SUPPORTED + help + Enable support for STM32F7 MCU series diff --git a/arch/arm/soc/st_stm32/stm32f7/Kconfig.soc b/arch/arm/soc/st_stm32/stm32f7/Kconfig.soc new file mode 100644 index 00000000000000..76ab22f11e4d69 --- /dev/null +++ b/arch/arm/soc/st_stm32/stm32f7/Kconfig.soc @@ -0,0 +1,25 @@ +# Kconfig.soc - ST Microelectronics STM32F4 MCU line +# +# Copyright (c) 2016 Linaro Limited. +# +# 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 +# +# http://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. +# + +choice +prompt "STM32F7x MCU Selection" +depends on SOC_SERIES_STM32F7X + +config SOC_STM32F7XX + bool "STM32F76xxx" + +endchoice diff --git a/arch/arm/soc/st_stm32/stm32f7/Makefile b/arch/arm/soc/st_stm32/stm32f7/Makefile new file mode 100644 index 00000000000000..6ae6e190c48e03 --- /dev/null +++ b/arch/arm/soc/st_stm32/stm32f7/Makefile @@ -0,0 +1,7 @@ +obj-y += soc.o + +obj-$(CONFIG_GPIO) += soc_gpio.o +obj-$(CONFIG_PINMUX) += soc_pinmux.o + +zephyr: $(KERNEL_HEX_NAME) +all: $(KERNEL_HEX_NAME) diff --git a/arch/arm/soc/st_stm32/stm32f7/flash_registers.h b/arch/arm/soc/st_stm32/stm32f7/flash_registers.h new file mode 100644 index 00000000000000..792553117779b7 --- /dev/null +++ b/arch/arm/soc/st_stm32/stm32f7/flash_registers.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2016 Linaro Limited. + * + * 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 + * + * http://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. + */ + +#ifndef _STM32F4X_FLASH_REGISTERS_H_ +#define _STM32F4X_FLASH_REGISTERS_H_ + +/** + * @brief + * + * Based on reference manual: + * + * Chapter 3.4: Embedded Flash Memory + */ + +enum { + STM32F7X_FLASH_LATENCY_0 = 0x0, + STM32F7X_FLASH_LATENCY_1 = 0x1, + STM32F7X_FLASH_LATENCY_2 = 0x2, + STM32F7X_FLASH_LATENCY_3 = 0x3, + STM32F7X_FLASH_LATENCY_4 = 0x4, + STM32F7X_FLASH_LATENCY_5 = 0x5, + STM32F7X_FLASH_LATENCY_6 = 0x6, + STM32F7X_FLASH_LATENCY_7 = 0x7, + STM32F7X_FLASH_LATENCY_8 = 0x8, + STM32F7X_FLASH_LATENCY_9 = 0x9, +}; + +union __flash_acr { + uint32_t val; + struct { + uint32_t latency :4 __packed; + uint32_t rsvd__4_7 :4 __packed; + uint32_t prften :1 __packed; + uint32_t arten :1 __packed; + uint32_t rsvd__10 :1 __packed; + uint32_t artrst :1 __packed; + uint32_t rsvd__12_31 :20 __packed; + } bit; +}; + +/* 3.7 Embedded flash registers */ +struct stm32f7x_flash { + union __flash_acr acr; + uint32_t key; + uint32_t optkey; + volatile uint32_t status; + volatile uint32_t ctrl; + uint32_t optctrl; + uint32_t optctrl1; + +}; + +/** + * @brief setup embedded flash controller + * + * Configure flash access time latency depending on SYSCLK. + */ +static inline void __setup_flash(void) +{ + volatile struct stm32f7x_flash *regs; + uint32_t tmpreg = 0; + + regs = (struct stm32f7x_flash *) FLASH_R_BASE; + + if (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC <= 30000000) { + regs->acr.bit.latency = STM32F7X_FLASH_LATENCY_0; + } else if (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC <= 60000000) { + regs->acr.bit.latency = STM32F7X_FLASH_LATENCY_1; + } else if (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC <= 90000000) { + regs->acr.bit.latency = STM32F7X_FLASH_LATENCY_2; + } + + /* Make sure latency was set */ + tmpreg = regs->acr.bit.latency; +} + +#endif /* _STM32F7X_FLASHREGISTERS_H_ */ diff --git a/arch/arm/soc/st_stm32/stm32f7/gpio_registers.h b/arch/arm/soc/st_stm32/stm32f7/gpio_registers.h new file mode 100644 index 00000000000000..3ea91a1b89de5b --- /dev/null +++ b/arch/arm/soc/st_stm32/stm32f7/gpio_registers.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2016 Linaro Limited. + * + * 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 + * + * http://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. + */ + +#ifndef _STM32F7X_GPIO_REGISTERS_H_ +#define _STM32F7X_GPIO_REGISTERS_H_ + +/** + * @brief Driver for GPIO of STM32F4X family processor. + * + * Based on reference manual: + * RM0410 Reference manual STM32F7XXX + * advanced ARM ® -based 32-bit MCUs + * + * Chapter 6: General-purpose I/Os (GPIOs) + */ + +/* 6.4 GPIO registers - each GPIO port controls 16 pins */ +struct stm32f7x_gpio { + uint32_t mode; + uint32_t otype; + uint32_t ospeed; + uint32_t pupdr; + uint32_t idr; + uint32_t odr; + uint32_t bsr; + uint32_t lck; + uint32_t afr[2]; + uint32_t afrh[2]; +}; + +union syscfg_exticr { + uint32_t val; + struct { + uint16_t rsvd__16_31; + uint16_t exti; + } bit; +}; + +/* 7.2 SYSCFG registers */ +struct stm32f7x_syscfg { + uint32_t memrmp; + uint32_t pmc; + union syscfg_exticr exticr1; + union syscfg_exticr exticr2; + union syscfg_exticr exticr3; + union syscfg_exticr exticr4; + uint32_t cbr; + uint32_t cmpcr; +}; + +#endif /* _STM32F7X_GPIO_REGISTERS_H_ */ diff --git a/arch/arm/soc/st_stm32/stm32f7/linker.ld b/arch/arm/soc/st_stm32/stm32f7/linker.ld new file mode 100644 index 00000000000000..220d80cc101f23 --- /dev/null +++ b/arch/arm/soc/st_stm32/stm32f7/linker.ld @@ -0,0 +1,19 @@ +/* linker.ld - Linker command/script file */ + +/* + * Copyright (c) 2014-2016 Wind River Systems, Inc. + * + * 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 + * + * http://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. + */ + +#include diff --git a/arch/arm/soc/st_stm32/stm32f7/rcc_registers.h b/arch/arm/soc/st_stm32/stm32f7/rcc_registers.h new file mode 100644 index 00000000000000..68b71e99d9b3d6 --- /dev/null +++ b/arch/arm/soc/st_stm32/stm32f7/rcc_registers.h @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2016 Linaro Limited. + * + * 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 + * + * http://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 andSTM + * limitations under the License. + */ + +#ifndef _STM32F7X_CLOCK_H_ +#define _STM32F7X_CLOCK_H_ + +/** + * @brief Driver for Reset & Clock Control of STM32F4X family processor. + * + * Based on reference manual: + * RM0410 Reference manual STM32F7xx + * advanced ARM ® -based 32-bit MCUs + * + * Chapter 5. Reset and Clock control (RCC) for STM43F401xB/C and STM32F401xD/E + */ + +enum { + STM32F7X_RCC_CFG_PLL_SRC_HSI = 0x0, + STM32F7X_RCC_CFG_PLL_SRC_HSE = 0x1, +}; + +enum { + STM32F7X_RCC_CFG_SYSCLK_SRC_HSI = 0x0, + STM32F7X_RCC_CFG_SYSCLK_SRC_HSE = 0x1, + STM32F7X_RCC_CFG_SYSCLK_SRC_PLL = 0x2, +}; + +enum { + STM32F7X_RCC_CFG_PLLP_DIV_2 = 0x0, + STM32F7X_RCC_CFG_PLLP_DIV_4 = 0x1, + STM32F7X_RCC_CFG_PLLP_DIV_6 = 0x2, + STM32F7X_RCC_CFG_PLLP_DIV_8 = 0x3, +}; + +enum { + STM32F7X_RCC_CFG_HCLK_DIV_0 = 0x0, + STM32F7X_RCC_CFG_HCLK_DIV_2 = 0x4, + STM32F7X_RCC_CFG_HCLK_DIV_4 = 0x5, + STM32F7X_RCC_CFG_HCLK_DIV_8 = 0x6, + STM32F7X_RCC_CFG_HCLK_DIV_16 = 0x7, +}; + +enum { + STM32F7X_RCC_CFG_SYSCLK_DIV_0 = 0x0, + STM32F7X_RCC_CFG_SYSCLK_DIV_2 = 0x8, + STM32F7X_RCC_CFG_SYSCLK_DIV_4 = 0x9, + STM32F7X_RCC_CFG_SYSCLK_DIV_8 = 0xa, + STM32F7X_RCC_CFG_SYSCLK_DIV_16 = 0xb, + STM32F7X_RCC_CFG_SYSCLK_DIV_64 = 0xc, + STM32F7X_RCC_CFG_SYSCLK_DIV_128 = 0xd, + STM32F7X_RCC_CFG_SYSCLK_DIV_256 = 0xe, + STM32F7X_RCC_CFG_SYSCLK_DIV_512 = 0xf, +}; + +/** + * @brief Reset and Clock Control + */ + +/* Helpers */ +enum { + STM32F7X_RCC_APB1ENR_PWREN = 0x10000000U, +}; + +union __rcc_cr { + uint32_t val; + struct { + uint32_t hsion :1 __packed; + uint32_t hsirdy :1 __packed; + uint32_t rsvd__2 :1 __packed; + uint32_t hsitrim :5 __packed; + uint32_t hsical :8 __packed; + uint32_t hseon :1 __packed; + uint32_t hserdy :1 __packed; + uint32_t hsebyp :1 __packed; + uint32_t csson :1 __packed; + uint32_t rsvd__20_23 :4 __packed; + uint32_t pllon :1 __packed; + uint32_t pllrdy :1 __packed; + uint32_t plli2son :1 __packed; + uint32_t plli2srdy :1 __packed; + uint32_t pllsaion :1 __packed; + uint32_t pllsairdy :1 __packed; + uint32_t rsvd__30_31 :2 __packed; + } bit; +}; + +union __rcc_pllcfgr { + uint32_t val; + struct { + uint32_t pllm :6 __packed; + uint32_t plln :9 __packed; + uint32_t rsvd__15 :1 __packed; + uint32_t pllp :2 __packed; + uint32_t rsvd__18_21 :4 __packed; + uint32_t pllsrc :1 __packed; + uint32_t rsvd__23 :1 __packed; + uint32_t pllq :4 __packed; + uint32_t rsvd__28_31 :4 __packed; + } bit; +}; + +union __rcc_cfgr { + uint32_t val; + struct { + uint32_t sw :2 __packed; + uint32_t sws :2 __packed; + uint32_t hpre :4 __packed; + uint32_t rsvd__8_9 :2 __packed; + uint32_t ppre1 :3 __packed; + uint32_t ppre2 :3 __packed; + uint32_t rtcpre :5 __packed; + uint32_t mco1 :2 __packed; + uint32_t i2sscr :1 __packed; + uint32_t mco1pre :3 __packed; + uint32_t mco2pre :3 __packed; + uint32_t mco2 :2 __packed; + } bit; +}; + +struct stm32f7x_rcc { + union __rcc_cr cr; + union __rcc_pllcfgr pllcfgr; + union __rcc_cfgr cfgr; + uint32_t cir; + uint32_t ahb1rstr; + uint32_t ahb2rstr; + uint32_t ahb3rstr; + //uint32_t rsvd0; + uint32_t apb1rstr; + uint32_t apb2rstr; + //uint32_t rsvd1[2]; + uint32_t ahb1enr; + uint32_t ahb2enr; + uint32_t ahb3enr; + //uint32_t rsvd2; + uint32_t apb1enr; + uint32_t apb2enr; + //uint32_t rsvd3[2]; + uint32_t ahb1lpenr; + uint32_t ahb2lpenr; + uint32_t ahb3lpenr; + //uint32_t rsvd4; + uint32_t apb1lpenr; + uint32_t apb2lpenr; + //uint32_t rsvd5[2]; + uint32_t bdcr; + uint32_t csr; + //uint32_t rsvd6[2]; + uint32_t sscgr; + uint32_t plli2scfgr; + uint32_t pllsaicfgr; + //uint32_t rsvd7; + uint32_t dckcfgr; + uint32_t dckcfgr2; +}; + +#endif /* _STM32F7X_CLOCK_H_ */ diff --git a/arch/arm/soc/st_stm32/stm32f7/soc.c b/arch/arm/soc/st_stm32/stm32f7/soc.c new file mode 100644 index 00000000000000..7e017b053e9476 --- /dev/null +++ b/arch/arm/soc/st_stm32/stm32f7/soc.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2016 Open-RnD Sp. z o.o. + * Copyright (c) 2016 Linaro Limited. + * + * 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 + * + * http://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. + */ + +/** + * @file + * @brief System/hardware module for STM32F4 processor + */ + +#include +#include +#include +#include +#include + +/** + * @brief Perform basic hardware initialization at boot. + * + * This needs to be run from the very beginning. + * So the init priority has to be 0 (zero). + * + * @return 0 + */ +static int st_stm32f7_init(struct device *arg) +{ + uint32_t key; + + ARG_UNUSED(arg); + + key = irq_lock(); + + /* Setup the vector table offset register (VTOR), + * which is located at the beginning of flash area. + */ + _scs_relocate_vector_table((void *)CONFIG_FLASH_BASE_ADDRESS); + + /* Clear all faults */ + _ScbMemFaultAllFaultsReset(); + _ScbBusFaultAllFaultsReset(); + _ScbUsageFaultAllFaultsReset(); + + _ScbHardFaultAllFaultsReset(); + + /* Install default handler that simply resets the CPU + * if configured in the kernel, NOP otherwise + */ + NMI_INIT(); + + irq_unlock(key); + + return 0; +} + +SYS_INIT(st_stm32f7_init, PRIMARY, 0); diff --git a/arch/arm/soc/st_stm32/stm32f7/soc.h b/arch/arm/soc/st_stm32/stm32f7/soc.h new file mode 100644 index 00000000000000..101c7e70b3f73e --- /dev/null +++ b/arch/arm/soc/st_stm32/stm32f7/soc.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2016 Open-RnD Sp. z o.o. + * Copyright (c) 2016 Linaro Limited. + * + * 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 + * + * http://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. + */ + +/** + * @file SoC configuration macros for the ST STM32F7 family processors. + * + * Based on reference manual: + * RM0368 Reference manual STM32F701xB/C and STM32F701xD/E + * advanced ARM ® -based 32-bit MCUs + * + * Chapter 2.3: Memory Map + */ + +#ifndef _STM32F7_SOC_H_ +#define _STM32F7_SOC_H_ + +/* peripherals start address */ +#define PERIPH_BASE 0x40000000 + +/* use naming consistent with STMF4 Peripherals Library */ +#define APB1PERIPH_BASE PERIPH_BASE +#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) +#define AHB1PERIPH_BASE (PERIPH_BASE + 0x20000) +#define AHB2PERIPH_BASE (PERIPH_BASE + 0x10000000) + +/* UART */ +#define USART1_ADDR (APB2PERIPH_BASE + 0x1000) +#define USART2_ADDR (APB1PERIPH_BASE + 0x4400) +#define USART6_ADDR (APB2PERIPH_BASE + 0x1400) + +/* Reset and Clock Control */ +#define RCC_BASE (AHB1PERIPH_BASE + 0x3800) + +#define GPIO_REG_SIZE 0x400 +#define GPIOA_BASE (AHB1PERIPH_BASE + 0x0000) +#define GPIOB_BASE (AHB1PERIPH_BASE + 0x0400) +#define GPIOC_BASE (AHB1PERIPH_BASE + 0x0800) +#define GPIOD_BASE (AHB1PERIPH_BASE + 0x0C00) +#define GPIOE_BASE (AHB1PERIPH_BASE + 0x1000) +#define GPIOH_BASE (AHB1PERIPH_BASE + 0x1C00) +#define GPIOI_BASE (AHB1PERIPH_BASE + 0x2000) +#define GPIOJ_BASE (AHB1PERIPH_BASE + 0x2400) +#define GPIOK_BASE (AHB1PERIPH_BASE + 0x2800) + +/* base address for where GPIO registers start */ +#define GPIO_PORTS_BASE (GPIOA_BASE) + +/* EXTI */ +#define EXTI_BASE (APB2PERIPH_BASE + 0x3C00) + +/* IWDG */ +#define IWDG_BASE (APB1PERIPH_BASE + 0x3000) + +/* FLASH */ +#define FLASH_R_BASE (AHB1PERIPH_BASE + 0x3C00) + +/* SYSCFG */ +#define SYSCFG_BASE (APB2PERIPH_BASE + 0x3800) + +#ifndef _ASMLANGUAGE + +#include +#include +#include + +/* IO pin functions */ +enum stm32f7x_pin_config_mode { + STM32F7X_PIN_CONFIG_DRIVE_PUSH_PULL, + STM32F7X_PIN_CONFIG_DRIVE_PUSH_UP, + STM32F7X_PIN_CONFIG_DRIVE_PUSH_DOWN, + STM32F7X_PIN_CONFIG_DRIVE_OPEN_DRAIN, + STM32F7X_PIN_CONFIG_DRIVE_OPEN_UP, + STM32F7X_PIN_CONFIG_DRIVE_OPEN_DOWN, + STM32F7X_PIN_CONFIG_AF_PUSH_PULL, + STM32F7X_PIN_CONFIG_AF_PUSH_UP, + STM32F7X_PIN_CONFIG_AF_PUSH_DOWN, + STM32F7X_PIN_CONFIG_AF_OPEN_DRAIN, + STM32F7X_PIN_CONFIG_AF_OPEN_UP, + STM32F7X_PIN_CONFIG_AF_OPEN_DOWN, + STM32F7X_PIN_CONFIG_BIAS_HIGH_IMPEDANCE, + STM32F7X_PIN_CONFIG_BIAS_PULL_UP, + STM32F7X_PIN_CONFIG_BIAS_PULL_DOWN, + STM32F7X_PIN_CONFIG_ANALOG, +}; + +#include "soc_irq.h" + +#endif /* !_ASMLANGUAGE */ + +#endif /* _STM32F7_SOC_H_ */ diff --git a/arch/arm/soc/st_stm32/stm32f7/soc_gpio.c b/arch/arm/soc/st_stm32/stm32f7/soc_gpio.c new file mode 100644 index 00000000000000..3d99ae0caa337c --- /dev/null +++ b/arch/arm/soc/st_stm32/stm32f7/soc_gpio.c @@ -0,0 +1,266 @@ +/* + * Copyright (c) Linaro Limited. + * + * 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 + * + * http://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. + */ + +/** + * @brief + * + * Based on reference manual: + * RM0368 Reference manual STM32F401xB/C and STM32F401xD/E + * advanced ARM ® -based 32-bit MCUs + * + * Chapter 8: General-purpose I/Os (GPIOs) + */ + +#include + +#include +#include "soc.h" +#include "soc_registers.h" +#include +#include + +/** + * @brief map pin function to MODE register value + */ +static uint32_t __func_to_mode(int func) +{ + switch (func) { + case STM32F7X_PIN_CONFIG_BIAS_HIGH_IMPEDANCE: + case STM32F7X_PIN_CONFIG_BIAS_PULL_UP: + case STM32F7X_PIN_CONFIG_BIAS_PULL_DOWN: + return 0x0; + case STM32F7X_PIN_CONFIG_DRIVE_PUSH_PULL: + case STM32F7X_PIN_CONFIG_DRIVE_PUSH_UP: + case STM32F7X_PIN_CONFIG_DRIVE_PUSH_DOWN: + case STM32F7X_PIN_CONFIG_DRIVE_OPEN_DRAIN: + case STM32F7X_PIN_CONFIG_DRIVE_OPEN_UP: + case STM32F7X_PIN_CONFIG_DRIVE_OPEN_DOWN: + return 0x1; + case STM32F7X_PIN_CONFIG_AF_PUSH_PULL: + case STM32F7X_PIN_CONFIG_AF_PUSH_UP: + case STM32F7X_PIN_CONFIG_AF_PUSH_DOWN: + case STM32F7X_PIN_CONFIG_AF_OPEN_DRAIN: + case STM32F7X_PIN_CONFIG_AF_OPEN_UP: + case STM32F7X_PIN_CONFIG_AF_OPEN_DOWN: + return 0x2; + case STM32F7X_PIN_CONFIG_ANALOG: + return 0x3; + } + + return 0; +} + +/** + * @brief map pin function to OTYPE register value + */ +static uint32_t __func_to_otype(int func) +{ + switch (func) { + case STM32F7X_PIN_CONFIG_DRIVE_OPEN_DRAIN: + case STM32F7X_PIN_CONFIG_DRIVE_OPEN_UP: + case STM32F7X_PIN_CONFIG_DRIVE_OPEN_DOWN: + case STM32F7X_PIN_CONFIG_AF_OPEN_DRAIN: + case STM32F7X_PIN_CONFIG_AF_OPEN_UP: + case STM32F7X_PIN_CONFIG_AF_OPEN_DOWN: + return 0x1; + } + + return 0; +} + +/** + * @brief map pin function to OSPEED register value + */ +static uint32_t __func_to_ospeed(int func) +{ + switch (func) { + case STM32F7X_PIN_CONFIG_DRIVE_PUSH_PULL: + case STM32F7X_PIN_CONFIG_DRIVE_PUSH_UP: + case STM32F7X_PIN_CONFIG_DRIVE_PUSH_DOWN: + case STM32F7X_PIN_CONFIG_DRIVE_OPEN_DRAIN: + case STM32F7X_PIN_CONFIG_DRIVE_OPEN_UP: + case STM32F7X_PIN_CONFIG_DRIVE_OPEN_DOWN: + case STM32F7X_PIN_CONFIG_AF_PUSH_PULL: + case STM32F7X_PIN_CONFIG_AF_PUSH_UP: + case STM32F7X_PIN_CONFIG_AF_PUSH_DOWN: + case STM32F7X_PIN_CONFIG_AF_OPEN_DRAIN: + case STM32F7X_PIN_CONFIG_AF_OPEN_UP: + case STM32F7X_PIN_CONFIG_AF_OPEN_DOWN: + /* Force fast speed by default */ + return 0x2; + } + + return 0; +} + +/** + * @brief map pin function to PUPD register value + */ +static uint32_t __func_to_pupd(int func) +{ + switch (func) { + case STM32F7X_PIN_CONFIG_DRIVE_PUSH_PULL: + case STM32F7X_PIN_CONFIG_DRIVE_OPEN_DRAIN: + case STM32F7X_PIN_CONFIG_AF_PUSH_PULL: + case STM32F7X_PIN_CONFIG_AF_OPEN_DRAIN: + case STM32F7X_PIN_CONFIG_BIAS_HIGH_IMPEDANCE: + case STM32F7X_PIN_CONFIG_ANALOG: + return 0x0; + case STM32F7X_PIN_CONFIG_DRIVE_PUSH_UP: + case STM32F7X_PIN_CONFIG_DRIVE_OPEN_UP: + case STM32F7X_PIN_CONFIG_AF_PUSH_UP: + case STM32F7X_PIN_CONFIG_AF_OPEN_UP: + case STM32F7X_PIN_CONFIG_BIAS_PULL_UP: + return 0x1; + case STM32F7X_PIN_CONFIG_DRIVE_PUSH_DOWN: + case STM32F7X_PIN_CONFIG_DRIVE_OPEN_DOWN: + case STM32F7X_PIN_CONFIG_AF_PUSH_DOWN: + case STM32F7X_PIN_CONFIG_AF_OPEN_DOWN: + case STM32F7X_PIN_CONFIG_BIAS_PULL_DOWN: + return 0x2; + } + + return 0; +} + + +int stm32_gpio_flags_to_conf(int flags, int *pincfg) +{ + int direction = flags & GPIO_DIR_MASK; + int pud = flags & GPIO_PUD_MASK; + + if (!pincfg) { + return -EINVAL; + } + + if (direction == GPIO_DIR_OUT) { + if (pud == GPIO_PUD_PULL_UP) { + *pincfg = STM32F7X_PIN_CONFIG_DRIVE_PUSH_UP; + } else if (pud == GPIO_PUD_PULL_DOWN) { + *pincfg = STM32F7X_PIN_CONFIG_DRIVE_PUSH_DOWN; + } else { + *pincfg = STM32F7X_PIN_CONFIG_DRIVE_PUSH_PULL; + } + } else if (direction == GPIO_DIR_IN) { + if (pud == GPIO_PUD_PULL_UP) { + *pincfg = STM32F7X_PIN_CONFIG_BIAS_PULL_UP; + } else if (pud == GPIO_PUD_PULL_DOWN) { + *pincfg = STM32F7X_PIN_CONFIG_BIAS_PULL_DOWN; + } else { + *pincfg = STM32F7X_PIN_CONFIG_BIAS_HIGH_IMPEDANCE; + } + } else { + return -ENOTSUP; + } + + return 0; +} + +int stm32_gpio_configure(uint32_t *base_addr, int pin, int conf, int altf) +{ + volatile struct stm32f7x_gpio *gpio = + (struct stm32f7x_gpio *)(base_addr); + uint32_t mode = __func_to_mode(conf); + uint32_t otype = __func_to_otype(conf); + uint32_t ospeed = __func_to_ospeed(conf); + uint32_t pupd = __func_to_pupd(conf); + uint32_t tmpreg = 0; + + /* TODO: validate if indeed alternate */ + if (altf) { + /* Set the alternate function */ + tmpreg = gpio->afr[pin >> 0x3]; + tmpreg &= ~(0xf << ((pin & 0x07) * 4)); + tmpreg |= (altf << ((pin & 0x07) * 4)); + gpio->afr[pin >> 0x3] = tmpreg; + } + + /* Set the IO direction mode */ + tmpreg = gpio->mode; + tmpreg &= ~(0x3 << (pin * 2)); + tmpreg |= (mode << (pin * 2)); + gpio->mode = tmpreg; + + if (otype) { + tmpreg = gpio->otype; + tmpreg &= ~(0x1 << pin); + tmpreg |= (otype << pin); + gpio->otype = tmpreg; + } + + if (ospeed) { + tmpreg = gpio->ospeed; + tmpreg &= ~(0x3 << (pin * 2)); + tmpreg |= (ospeed << (pin * 2)); + gpio->ospeed = tmpreg; + } + + tmpreg = gpio->pupdr; + tmpreg &= ~(0x3 << (pin * 2)); + tmpreg |= (pupd << (pin * 2)); + gpio->pupdr = tmpreg; + + return 0; +} + +int stm32_gpio_set(uint32_t *base, int pin, int value) +{ + struct stm32f7x_gpio *gpio = (struct stm32f7x_gpio *)base; + + int pval = 1 << (pin & 0xf); + + if (value) { + gpio->odr |= pval; + } else { + gpio->odr &= ~pval; + } + + return 0; +} + +int stm32_gpio_get(uint32_t *base, int pin) +{ + struct stm32f7x_gpio *gpio = (struct stm32f7x_gpio *)base; + + return (gpio->idr >> pin) & 0x1; +} + +int stm32_gpio_enable_int(int port, int pin) +{ + volatile struct stm32f7x_syscfg *syscfg = + (struct stm32f7x_syscfg *)SYSCFG_BASE; + volatile union __syscfg_exticr *exticr; + int shift = 0; + + if (pin <= 3) { + exticr = &syscfg->exticr1; + } else if (pin <= 7) { + exticr = &syscfg->exticr2; + } else if (pin <= 11) { + exticr = &syscfg->exticr3; + } else if (pin <= 15) { + exticr = &syscfg->exticr4; + } else { + return -EINVAL; + } + + shift = 4 * (pin % 4); + + exticr->val &= ~(0xf << shift); + exticr->val |= port << shift; + + return 0; +} diff --git a/arch/arm/soc/st_stm32/stm32f7/soc_irq.h b/arch/arm/soc/st_stm32/stm32f7/soc_irq.h new file mode 100644 index 00000000000000..54e7a15cc0657a --- /dev/null +++ b/arch/arm/soc/st_stm32/stm32f7/soc_irq.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2016 Linaro Limited. + * + * 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 + * + * http://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. + */ + +/** + * @file Interrupt numbers for STM32F7 family processors. + * + * Based on reference manual: + * RM0368 Reference manual STM32F701xB/C and STM32F701xD/E + * advanced ARM-based 32-bit MCUs + * + * Chapter 10.1.3: Interrupt and exception vectors + */ + + +#ifndef _STM32F7_SOC_IRQ_H_ +#define _STM32F7_SOC_IRQ_H_ + +#define STM32F7_IRQ_WWDG 0 +#define STM32F7_IRQ_PVD 1 +#define STM32F7_IRQ_EXTI16 STM32F7_IRQ_PVD +#define STM32F7_IRQ_TAMP_STAMP 2 +#define STM32F7_IRQ_EXTI21 STM32F7_IRQ_TAMP_STAMP +#define STM32F7_IRQ_RTC_WKUP 3 +#define STM32F7_IRQ_EXTI22 STM32F7_IRQ_RTC_WKUP +#define STM32F7_IRQ_FLASH 4 +#define STM32F7_IRQ_RCC 5 +#define STM32F7_IRQ_EXTI0 6 +#define STM32F7_IRQ_EXTI1 7 +#define STM32F7_IRQ_EXTI2 8 +#define STM32F7_IRQ_EXTI3 9 +#define STM32F7_IRQ_EXTI4 10 +#define STM32F7_IRQ_DMA1_STREAM0 11 +#define STM32F7_IRQ_DMA1_STREAM1 12 +#define STM32F7_IRQ_DMA1_STREAM2 13 +#define STM32F7_IRQ_DMA1_STREAM3 14 +#define STM32F7_IRQ_DMA1_STREAM4 15 +#define STM32F7_IRQ_DMA1_STREAM5 16 +#define STM32F7_IRQ_DMA1_STREAM6 17 +#define STM32F7_IRQ_ADC 18 +#define STM32F7_IRQ_CAN1_TX 19 +#define STM32F7_IRQ_CAN1_RX0 20 +#define STM32F7_IRQ_CAN1_RX1 21 +#define STM32F7_IRQ_CAN1_SCE 22 +#define STM32F7_IRQ_EXTI9_5 23 +#define STM32F7_IRQ_TIM1_BRK_TIM9 24 +#define STM32F7_IRQ_TIM1_UP_TIM10 25 +#define STM32F7_IRQ_TIM1_TRG_COM_TIM11 26 +#define STM32F7_IRQ_TIM1_CC 27 +#define STM32F7_IRQ_TIM2 28 +#define STM32F7_IRQ_TIM3 29 +#define STM32F7_IRQ_TIM4 30 +#define STM32F7_IRQ_I2C1_EV 31 +#define STM32F7_IRQ_I2C1_ER 32 +#define STM32F7_IRQ_I2C2_EV 33 +#define STM32F7_IRQ_I2C2_ER 34 +#define STM32F7_IRQ_SPI1 35 +#define STM32F7_IRQ_SPI2 36 +#define STM32F7_IRQ_USART1 37 +#define STM32F7_IRQ_USART2 38 +#define STM32F7_IRQ_USART3 39 +#define STM32F7_IRQ_EXTI15_10 40 +#define STM32F7_IRQ_RTC_ALARM 41 +#define STM32F7_IRQ_EXTI17 STM32F7_IRQ_RTC_ALARM +#define STM32F7_IRQ_OTG_FS_WKUP 42 +#define STM32F7_IRQ_EXTI18 STM32F7_IRQ_OTG_FS_WKUP +#define STM32F7_IRQ_TIM8_BRK_TIM12 43 +#define STM32F7_IRQ_TIM8_UP_TIM12 44 +#define STM32F7_IRQ_TIM8_TRG_COM_TIM14 45 +#define STM32F7_IRQ_TIM8_CC 46 +#define STM32F7_IRQ_DMA1_STREAM7 47 +#define STM32F7_IRQ_FSMC 48 +#define STM32F7_IRQ_SDIO 49 +#define STM32F7_IRQ_TIM5 50 +#define STM32F7_IRQ_SPI3 51 +#define STM32F7_IRQ_UART4 52 +#define STM32F7_IRQ_UART5 53 +#define STM32F7_IRQ_TIM6_DAC 54 +#define STM32F7_IRQ_TIM7 55 +#define STM32F7_IRQ_DMA2_STREAM0 56 +#define STM32F7_IRQ_DMA2_STREAM1 57 +#define STM32F7_IRQ_DMA2_STREAM2 58 +#define STM32F7_IRQ_DMA2_STREAM3 59 +#define STM32F7_IRQ_DMA2_STREAM4 60 +#define STM32F7_IRQ_ETH 61 +#define STM32F7_IRQ_ETH_WKUP 62 +#define STM32F7_IRQ_CAN2_TX 63 +#define STM32F7_IRQ_CAN2_RX0 64 +#define STM32F7_IRQ_CAN2_RX1 65 +#define STM32F7_IRQ_CAN2_SCE 66 +#define STM32F7_IRQ_OTG_FS 67 +#define STM32F7_IRQ_DMA2_STREAM5 68 +#define STM32F7_IRQ_DMA2_STREAM6 69 +#define STM32F7_IRQ_DMA2_STREAM7 70 +#define STM32F7_IRQ_USART6 71 +#define STM32F7_IRQ_I2C3_EV 72 +#define STM32F7_IRQ_I2C3_ER 73 +#define STM32F7_IRQ_OTG_HS_EP1_OUT 74 +#define STM32F7_IRQ_OTG_HS_EP1_IN 75 +#define STM32F7_IRQ_OTG_HS_WKUP 76 +#define STM32F7_IRQ_OTG_HS 77 +#define STM32F7_IRQ_DCMI 78 +#define STM32F7_IRQ_CRYP 79 +#define STM32F7_IRQ_HASH_RNG 80 +#define STM32F7_IRQ_FPU 81 +#define STM32F7_IRQ_UART7 82 +#define STM32F7_IRQ_UART8 83 +#define STM32F7_IRQ_SPI4 84 +#define STM32F7_IRQ_SPI5 85 +#define STM32F7_IRQ_SPI6 86 +#define STM32F7_IRQ_SAI1 87 +#define STM32F7_IRQ_LCD_TFT 88 +#define STM32F7_IRQ_GLCD_TFT 89 +#define STM32F7_IRQ_DMA2D 90 +#define STM32F7_IRQ_SAI2 91 +#define STM32F7_IRQ_QUADSPI 92 +#define STM32F7_IRQ_LPTIMER 93 +#define STM32F7_IRQ_CEC 94 +#define STM32F7_IRQ_FMPI2C1_EV 95 +#define STM32F7_IRQ_FMPI2C1_ER 96 +#define STM32F7_IRQ_SPDI_FRX 97 + +#endif /* _STM32F7_SOC_IRQ_H_ */ diff --git a/arch/arm/soc/st_stm32/stm32f7/soc_pinmux.c b/arch/arm/soc/st_stm32/stm32f7/soc_pinmux.c new file mode 100644 index 00000000000000..5a6a0761c24f8d --- /dev/null +++ b/arch/arm/soc/st_stm32/stm32f7/soc_pinmux.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2016 Linaro Limited. + * + * 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 + * + * http://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. + */ + +#include + +#include "soc.h" +#include +#include +#include +#include + +static const stm32_pin_func_t pin_pa9_funcs[] = { + [STM32F4_PINMUX_FUNC_PA9_USART1_TX - 1] = + STM32F4X_PIN_CONFIG_AF_PUSH_UP, +}; + +static const stm32_pin_func_t pin_pa10_funcs[] = { + [STM32F4_PINMUX_FUNC_PA10_USART1_RX - 1] = + STM32F4X_PIN_CONFIG_AF_PUSH_UP, +}; + +static const stm32_pin_func_t pin_pb6_funcs[] = { + [STM32F4_PINMUX_FUNC_PB6_USART1_TX - 1] = + STM32F4X_PIN_CONFIG_AF_PUSH_UP, +}; + +static const stm32_pin_func_t pin_pb7_funcs[] = { + [STM32F4_PINMUX_FUNC_PB7_USART1_RX - 1] = + STM32F4X_PIN_CONFIG_AF_PUSH_UP, +}; + +static const stm32_pin_func_t pin_pa2_funcs[] = { + [STM32F4_PINMUX_FUNC_PA2_USART2_TX - 1] = + STM32F4X_PIN_CONFIG_AF_PUSH_UP, +}; + +static const stm32_pin_func_t pin_pa3_funcs[] = { + [STM32F4_PINMUX_FUNC_PA3_USART2_RX - 1] = + STM32F4X_PIN_CONFIG_AF_PUSH_UP, +}; + +/** + * @brief pin configuration + */ +static const struct stm32_pinmux_conf pins[] = { + STM32_PIN_CONF(STM32_PIN_PA9, pin_pa9_funcs), + STM32_PIN_CONF(STM32_PIN_PA10, pin_pa10_funcs), + STM32_PIN_CONF(STM32_PIN_PB6, pin_pb6_funcs), + STM32_PIN_CONF(STM32_PIN_PB7, pin_pb7_funcs), + STM32_PIN_CONF(STM32_PIN_PA2, pin_pa2_funcs), + STM32_PIN_CONF(STM32_PIN_PA3, pin_pa3_funcs), +}; + +int stm32_get_pin_config(int pin, int func) +{ + /* GPIO function is always available, to save space it is not + * listed in alternate functions array + */ + if (func == STM32_PINMUX_FUNC_GPIO) { + return STM32F4X_PIN_CONFIG_BIAS_HIGH_IMPEDANCE; + } + + /* analog function is another 'known' setting */ + if (func == STM32_PINMUX_FUNC_ANALOG) { + return STM32F4X_PIN_CONFIG_ANALOG; + } + + func -= 1; + + for (int i = 0; i < ARRAY_SIZE(pins); i++) { + if (pins[i].pin == pin) { + if (func > pins[i].nfuncs) { + return -EINVAL; + } + + return pins[i].funcs[func]; + } + } + + return -EINVAL; +} diff --git a/arch/arm/soc/st_stm32/stm32f7/soc_registers.h b/arch/arm/soc/st_stm32/stm32f7/soc_registers.h new file mode 100644 index 00000000000000..20eb0d8f0a55e3 --- /dev/null +++ b/arch/arm/soc/st_stm32/stm32f7/soc_registers.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2016 Linaro Limited. + * + * 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 + * + * http://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. + */ + +#ifndef _STM32F7_SOC_REGISTERS_H_ +#define _STM32F7_SOC_REGISTERS_H_ + +/* include register mapping headers */ +#include "rcc_registers.h" +#include "flash_registers.h" +#include "gpio_registers.h" + +#endif /* _STM32F7_SOC_REGISTERS_H_ */ diff --git a/boards/arm/discovery_smt32f7/Kconfig.board b/boards/arm/discovery_smt32f7/Kconfig.board new file mode 100644 index 00000000000000..39d017fcc02de8 --- /dev/null +++ b/boards/arm/discovery_smt32f7/Kconfig.board @@ -0,0 +1,20 @@ +# Kconfig - NUCLEO-64 F401RE board configuration +# +# Copyright (c) 2016 Linaro Limited. +# +# 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 +# +# http://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. +# + +config BOARD_DISCOVERY_STM32F7 + bool "SMT327F7 Development Board" + depends on SOC_STM32F7XX diff --git a/boards/arm/discovery_smt32f7/Kconfig.defconfig b/boards/arm/discovery_smt32f7/Kconfig.defconfig new file mode 100644 index 00000000000000..b8f6a2da903618 --- /dev/null +++ b/boards/arm/discovery_smt32f7/Kconfig.defconfig @@ -0,0 +1,23 @@ +# Kconfig - NUCLEO-64 F401RE board configuration +# +# Copyright (c) 2016 Linaro Limited. +# +# 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 +# +# http://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. +# + +if BOARD_DISCOVERY_STM32F7 + +config BOARD + default discovery_smt32f7 + +endif # BOARD_DISCOVERY_STM32F7 diff --git a/boards/arm/discovery_smt32f7/Makefile b/boards/arm/discovery_smt32f7/Makefile new file mode 100644 index 00000000000000..c925263c43a731 --- /dev/null +++ b/boards/arm/discovery_smt32f7/Makefile @@ -0,0 +1,2 @@ +# No C files (yet) +obj- += dummy.o diff --git a/boards/arm/discovery_smt32f7/Makefile.board b/boards/arm/discovery_smt32f7/Makefile.board new file mode 100644 index 00000000000000..7d02aa38866a42 --- /dev/null +++ b/boards/arm/discovery_smt32f7/Makefile.board @@ -0,0 +1,6 @@ +FLASH_SCRIPT = openocd.sh + +OPENOCD_LOAD_CMD = "flash write_image erase ${O}/${KERNEL_BIN_NAME} ${CONFIG_FLASH_BASE_ADDRESS}" +OPENOCD_VERIFY_CMD = "verify_image ${O}/${KERNEL_BIN_NAME} ${CONFIG_FLASH_BASE_ADDRESS}" + +export FLASH_SCRIPT OPENOCD_LOAD_CMD OPENOCD_VERIFY_CMD diff --git a/boards/arm/discovery_smt32f7/board.h b/boards/arm/discovery_smt32f7/board.h new file mode 100644 index 00000000000000..a793beb55b14a1 --- /dev/null +++ b/boards/arm/discovery_smt32f7/board.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2016 Linaro Limited. + * + * 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 + * + * http://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. + */ + +#ifndef __INC_BOARD_H +#define __INC_BOARD_H + +#include + +#endif /* __INC_BOARD_H */ diff --git a/boards/arm/discovery_smt32f7/discovery_smt32f7_defconfig b/boards/arm/discovery_smt32f7/discovery_smt32f7_defconfig new file mode 100644 index 00000000000000..33113c99ca6a9a --- /dev/null +++ b/boards/arm/discovery_smt32f7/discovery_smt32f7_defconfig @@ -0,0 +1,36 @@ +CONFIG_ARM=y +CONFIG_BOARD_DISCOVERY_STM32F7=y +CONFIG_SOC_SERIES_STM32F7X=y +CONFIG_SOC_STM32F7XX=y +# 84MHz system clock +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=84000000 +CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 + +# enable USART2 - passthrough to STLINK v2 connector +CONFIG_UART_STM32_PORT_1=y +CONFIG_UART_STM32_PORT_1_BAUD_RATE=115200 +# enable console on this port by default +CONFIG_UART_CONSOLE_ON_DEV_NAME="UART_1" + +# enable pinmux +CONFIG_PINMUX=y + +# enable GPIO ports A, B, C +CONFIG_GPIO=y + +# clock configuration +CONFIG_CLOCK_CONTROL=y +CONFIG_CLOCK_STM32F4X_SYSCLK_SRC_PLL=y +# use HSE as PLL input +CONFIG_CLOCK_STM32F4X_PLL_SRC_HSE=y +# however, the board does not have an external oscillator, so just use +# the 8MHz clock signal coming from integrated STLink +CONFIG_CLOCK_STM32F4X_HSE_BYPASS=y +# produce 84MHz clock at PLL output +CONFIG_CLOCK_STM32F4X_PLLM_DIV_FACTOR=8 +CONFIG_CLOCK_STM32F4X_PLLN_MULTIPLIER=336 +CONFIG_CLOCK_STM32F4X_PLLP_DIV_FACTOR=4 +CONFIG_CLOCK_STM32F4X_PLLQ_DIV_FACTOR=7 +CONFIG_CLOCK_STM32F4X_AHB_PRESCALER=0 +CONFIG_CLOCK_STM32F4X_APB1_PRESCALER=2 +CONFIG_CLOCK_STM32F4X_APB2_PRESCALER=0 diff --git a/boards/arm/discovery_smt32f7/support/openocd.cfg b/boards/arm/discovery_smt32f7/support/openocd.cfg new file mode 100644 index 00000000000000..d1426b667d5a66 --- /dev/null +++ b/boards/arm/discovery_smt32f7/support/openocd.cfg @@ -0,0 +1,12 @@ +source [find board/st_nucleo_f4.cfg] + +$_TARGETNAME configure -event gdb-attach { + echo "Debugger attaching: halting execution" + reset halt + gdb_breakpoint_override hard +} + +$_TARGETNAME configure -event gdb-detach { + echo "Debugger detaching: resuming execution" + resume +} diff --git a/drivers/clock_control/Kconfig b/drivers/clock_control/Kconfig index 4c2adf9352059b..e803587bfc945c 100644 --- a/drivers/clock_control/Kconfig +++ b/drivers/clock_control/Kconfig @@ -57,6 +57,8 @@ source "drivers/clock_control/Kconfig.stm32f10x" source "drivers/clock_control/Kconfig.stm32f4x" +source "drivers/clock_control/Kconfig.stm32f7x" + source "drivers/clock_control/Kconfig.nrf5" endif # CLOCK_CONTROL diff --git a/drivers/clock_control/Kconfig.stm32f7x b/drivers/clock_control/Kconfig.stm32f7x new file mode 100644 index 00000000000000..0f6ce979ef9251 --- /dev/null +++ b/drivers/clock_control/Kconfig.stm32f7x @@ -0,0 +1,151 @@ +# Kconfig - STM32F7 MCU clock control driver config +# +# Copyright (c) 2016 Open-RnD Sp. z o.o. +# Copyright (c) Linaro Limited. +# +# 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 +# +# http://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. +# + +if SOC_SERIES_STM32F7X + +menuconfig CLOCK_CONTROL_STM32F7X + bool + prompt "STM32F7X Reset & Clock Control" + depends on CLOCK_CONTROL && SOC_SERIES_STM32F7X + default y if SOC_SERIES_STM32F7X + help + Enable driver for Reset & Clock Control subsystem found + in STM32F7 family of MCUs + +config CLOCK_CONTROL_STM32F7X_DEVICE_INIT_PRIORITY + int "Clock Control Device Priority" + default 1 + depends on CLOCK_CONTROL_STM32F7X + help + This option controls the priority of clock control + device initialization. Higher priority ensures that the device + is initialized earlier in the startup cycle. If unsure, leave + at default value 1 + +choice +prompt "STM32F7X System Clock Source" +depends on CLOCK_CONTROL_STM32F7X + +config CLOCK_STM32F7X_SYSCLK_SRC_HSI + bool "HSI" + help + Use HSI as source of SYSCLK + +config CLOCK_STM32F7X_SYSCLK_SRC_HSE + bool "HSE" + help + Use HSE as source of SYSCLK + +config CLOCK_STM32F7X_SYSCLK_SRC_PLL + bool "PLL" + help + Use PLL as source of SYSCLK + +endchoice + +choice +prompt "STM32F7X PLL Clock Source" +depends on CLOCK_CONTROL_STM32F7X && CLOCK_STM32F4X_SYSCLK_SRC_PLL + +config CLOCK_STM32F7X_PLL_SRC_HSI + bool "HSI" + help + Use HSI as source of PLL + +config CLOCK_STM32F7X_PLL_SRC_HSE + bool "HSE" + help + Use HSE as source of PLL + +endchoice + +config CLOCK_STM32F7X_HSE_BYPASS + bool "HSE bypass" + depends on CLOCK_CONTROL_STM32F7X && (CLOCK_STM32F4X_PLL_SRC_HSE || CLOCK_STM32F4X_SYSCLK_SRC_HSE) + help + Enable this option to bypass external high-speed clock (HSE). + +config CLOCK_STM32F7X_PLLM_DIV_FACTOR + int "Division factor for PLL VCO input clock" + depends on CLOCK_CONTROL_STM32F7X && CLOCK_STM32F4X_SYSCLK_SRC_PLL + default 8 + range 2 63 + help + PLLM division factor needs to be set correctly to ensure that the VCO + input frequency ranges from 1 to 2 MHz. It is recommended to select a + frequency of 2 MHz to limit PLL jitter. + Allowed values: 2-63 + +config CLOCK_STM32F7X_PLLN_MULTIPLIER + int "Multiplier factor for PLL VCO output clock" + depends on CLOCK_CONTROL_STM32F7X && CLOCK_STM32F4X_SYSCLK_SRC_PLL + default 336 + range 192 432 + help + PLLN multiplier factor needs to be set correctly to ensure that the + VCO output frequency is between 192 and 432 MHz. + Allowed values: 192-432 + +config CLOCK_STM32F7X_PLLP_DIV_FACTOR + int "PLL division factor for main system clock" + depends on CLOCK_CONTROL_STM32F7X && CLOCK_STM32F4X_SYSCLK_SRC_PLL + default 4 + range 2 8 + help + PLLP division factor needs to be set correctly to not exceed 84MHz. + Allowed values: 2, 4, 6, 8 + +config CLOCK_STM32F7X_PLLQ_DIV_FACTOR + int "Division factor for OTG FS, SDIO and RNG clocks" + depends on CLOCK_CONTROL_STM32F7X && CLOCK_STM32F4X_SYSCLK_SRC_PLL + default 7 + range 2 15 + help + The USB OTG FS requires a 48MHz clock to work correctly. SDIO and RNG + need a frequency lower than or equal to 48 MHz to work correctly. + Allowed values: 2-15 + +config CLOCK_STM32F7X_AHB_PRESCALER + int "AHB prescaler" + depends on CLOCK_CONTROL_STM32F7X + default 0 + range 0 512 + help + AHB prescaler, allowed values: 0, 2, 4, 8, 16, 64, 128, + 256, 512. + +config CLOCK_STM32F7X_APB1_PRESCALER + int "APB1 low speed clock prescaler" + depends on CLOCK_CONTROL_STM32F7X + default 2 + range 0 16 + help + APB1 Low speed clock (PCLK1) prescaler, allowed values: + 0, 2, 4, 8, 16. The APB1 clock must not exceed 42MHz. + +config CLOCK_STM32F7X_APB2_PRESCALER + int "APB2 high speed clock prescaler" + depends on CLOCK_CONTROL_STM32F7X + default 0 + range 0 16 + help + APB2 High speed clock (PCLK2) prescaler, allowed values: + 0, 2, 4, 8, 16. The APB2 clock must not exceed 84MHz. + +endif + diff --git a/drivers/clock_control/Makefile b/drivers/clock_control/Makefile index b23147eb9369ca..4c46e7f0402edf 100644 --- a/drivers/clock_control/Makefile +++ b/drivers/clock_control/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_CLOCK_CONTROL_QUARK_SE) += quark_se_clock_control.o obj-$(CONFIG_CLOCK_CONTROL_STM32F10X) += stm32f10x_clock.o obj-$(CONFIG_CLOCK_CONTROL_STM32F4X) += stm32f4x_clock.o +obj-$(CONFIG_CLOCK_CONTROL_STM32F7X) += stm32f7x_clock.o obj-$(CONFIG_CLOCK_CONTROL_NRF5) += nrf5_power_clock.o diff --git a/drivers/clock_control/stm32f7x_clock.c b/drivers/clock_control/stm32f7x_clock.c new file mode 100644 index 00000000000000..d1623e348e8bbe --- /dev/null +++ b/drivers/clock_control/stm32f7x_clock.c @@ -0,0 +1,360 @@ +/* + * Copyright (c) 2016 Open-RnD Sp. z o.o. + * Copyright (c) 2016 Linaro Limited. + * + * 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 + * + * http://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. + */ + + +/** + * @brief Driver for Reset & Clock Control of STM32F7X family processor. + * + * Based on reference manual: + * RM0368 Reference manual STM32F701xB/C and STM32F701xD/E + * advanced ARM ® -based 32-bit MCUs + * + * Chapter 6. Reset and Clock control (RCC) for STM43F401xB/C and STM32F701xD/E + */ + +#include +#include +#include +#include +#include + +struct stm32f7x_rcc_data { + uint8_t *base; +}; + +static inline int stm32f7x_clock_control_on(struct device *dev, + clock_control_subsys_t sub_system) +{ + struct stm32f7x_rcc_data *data = dev->driver_data; + volatile struct stm32f7x_rcc *rcc = (struct stm32f7x_rcc *)(data->base); + struct stm32f7x_pclken *pclken = (struct stm32f7x_pclken *)(sub_system); + uint32_t tmpreg = 0; /* Register delay helper */ + + switch (pclken->bus) { + case STM32F7X_CLOCK_BUS_AHB1: + rcc->ahb1enr |= pclken->enr; + tmpreg = rcc->ahb1enr; + break; + case STM32F7X_CLOCK_BUS_AHB2: + rcc->ahb2enr |= pclken->enr; + tmpreg = rcc->ahb2enr; + break; + case STM32F7X_CLOCK_BUS_APB1: + rcc->apb1enr |= pclken->enr; + tmpreg = rcc->apb1enr; + break; + case STM32F7X_CLOCK_BUS_APB2: + rcc->apb2enr |= pclken->enr; + tmpreg = rcc->apb2enr; + break; + } + + return 0; +} + +static inline int stm32f7x_clock_control_off(struct device *dev, + clock_control_subsys_t sub_system) +{ + struct stm32f7x_rcc_data *data = dev->driver_data; + volatile struct stm32f7x_rcc *rcc = (struct stm32f7x_rcc *)(data->base); + struct stm32f7x_pclken *pclken = (struct stm32f7x_pclken *)(sub_system); + uint32_t tmpreg = 0; /* Register delay helper */ + + switch (pclken->bus) { + case STM32F7X_CLOCK_BUS_AHB1: + rcc->ahb1enr &= ~pclken->enr; + tmpreg = rcc->ahb1enr; + break; + case STM32F7X_CLOCK_BUS_AHB2: + rcc->ahb2enr &= ~pclken->enr; + tmpreg = rcc->ahb2enr; + break; + case STM32F7X_CLOCK_BUS_APB1: + rcc->apb1enr &= ~pclken->enr; + tmpreg = rcc->apb1enr; + break; + case STM32F7X_CLOCK_BUS_APB2: + rcc->apb2enr &= ~pclken->enr; + tmpreg = rcc->apb2enr; + break; + } + + return 0; +} + +/** + * @brief helper for mapping a setting to register value + */ +struct regval_map { + int val; + int reg; +}; + +int map_reg_val(const struct regval_map *map, size_t cnt, int val) +{ + for (int i = 0; i < cnt; i++) { + if (map[i].val == val) { + return map[i].reg; + } + } + + return 0; +} + +/** + * @brief map APB prescaler setting to register value + */ +static int __apb_prescaler(int prescaler) +{ + if (prescaler == 0) { + return STM32F7X_RCC_CFG_HCLK_DIV_0; + } + + const struct regval_map map[] = { + {0, STM32F7X_RCC_CFG_HCLK_DIV_0}, + {2, STM32F7X_RCC_CFG_HCLK_DIV_2}, + {4, STM32F7X_RCC_CFG_HCLK_DIV_4}, + {8, STM32F7X_RCC_CFG_HCLK_DIV_8}, + {16, STM32F7X_RCC_CFG_HCLK_DIV_16}, + }; + + return map_reg_val(map, ARRAY_SIZE(map), prescaler); +} + +/** + * @brief map AHB prescaler setting to register value + */ +static int __ahb_prescaler(int prescaler) +{ + if (prescaler == 0) { + return STM32F7X_RCC_CFG_SYSCLK_DIV_0; + } + + const struct regval_map map[] = { + {0, STM32F7X_RCC_CFG_SYSCLK_DIV_0}, + {2, STM32F7X_RCC_CFG_SYSCLK_DIV_2}, + {4, STM32F7X_RCC_CFG_SYSCLK_DIV_4}, + {8, STM32F7X_RCC_CFG_SYSCLK_DIV_8}, + {16, STM32F7X_RCC_CFG_SYSCLK_DIV_16}, + {64, STM32F7X_RCC_CFG_SYSCLK_DIV_64}, + {128, STM32F7X_RCC_CFG_SYSCLK_DIV_128}, + {256, STM32F7X_RCC_CFG_SYSCLK_DIV_256}, + {512, STM32F7X_RCC_CFG_SYSCLK_DIV_512}, + }; + + return map_reg_val(map, ARRAY_SIZE(map), prescaler); +} + +#ifdef CONFIG_CLOCK_STM32F7X_SYSCLK_SRC_PLL +/** + * @brief map PPLP division factor to register value + */ +static int __pllp_div(int div) +{ + if (div == 0) { + return STM32F7X_RCC_CFG_PLLP_DIV_2; + } + + const struct regval_map map[] = { + {2, STM32F7X_RCC_CFG_PLLP_DIV_2}, + {4, STM32F7X_RCC_CFG_PLLP_DIV_4}, + {6, STM32F7X_RCC_CFG_PLLP_DIV_6}, + {8, STM32F7X_RCC_CFG_PLLP_DIV_8}, + }; + + return map_reg_val(map, ARRAY_SIZE(map), div); +} +#endif /* CONFIG_CLOCK_STM32F7X_SYSCLK_SRC_PLL */ + +uint32_t __get_ahb_clock(uint32_t sysclk) +{ + /* AHB clock is generated based on SYSCLK */ + uint32_t sysclk_div = CONFIG_CLOCK_STM32F7X_AHB_PRESCALER; + + if (sysclk_div == 0) { + sysclk_div = 1; + } + + return sysclk / sysclk_div; +} + +uint32_t __get_apb_clock(uint32_t ahb_clock, uint32_t prescaler) +{ + if (prescaler == 0) { + prescaler = 1; + } + + return ahb_clock / prescaler; +} + +static int stm32f7x_clock_control_get_subsys_rate(struct device *clock, + clock_control_subsys_t sub_system, + uint32_t *rate) +{ + struct stm32f7x_pclken *pclken = (struct stm32f7x_pclken *)(sub_system); + /* assumes SYSCLK is SYS_CLOCK_HW_CYCLES_PER_SEC */ + uint32_t ahb_clock = + __get_ahb_clock(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC); + uint32_t apb1_clock = __get_apb_clock(ahb_clock, + CONFIG_CLOCK_STM32F7X_APB1_PRESCALER); + uint32_t apb2_clock = __get_apb_clock(ahb_clock, + CONFIG_CLOCK_STM32F7X_APB2_PRESCALER); + ARG_UNUSED(clock); + + switch (pclken->bus) { + case STM32F7X_CLOCK_BUS_AHB1: + case STM32F7X_CLOCK_BUS_AHB2: + *rate = ahb_clock; + break; + case STM32F7X_CLOCK_BUS_APB1: + *rate = apb1_clock; + break; + case STM32F7X_CLOCK_BUS_APB2: + *rate = apb2_clock; + break; + } + + return 0; +} + +static struct clock_control_driver_api stm32f7x_clock_control_api = { + .on = stm32f7x_clock_control_on, + .off = stm32f7x_clock_control_off, + .get_rate = stm32f7x_clock_control_get_subsys_rate, +}; + +int stm32f7x_clock_control_init(struct device *dev) +{ + struct stm32f7x_rcc_data *data = dev->driver_data; + volatile struct stm32f7x_rcc *rcc = + (struct stm32f7x_rcc *)(data->base); + /* SYSCLK source defaults to HSI */ + int sysclk_src = STM32F7X_RCC_CFG_SYSCLK_SRC_HSI; + uint32_t hpre = __ahb_prescaler(CONFIG_CLOCK_STM32F7X_AHB_PRESCALER); + uint32_t ppre1 = __apb_prescaler(CONFIG_CLOCK_STM32F7X_APB1_PRESCALER); + uint32_t ppre2 = __apb_prescaler(CONFIG_CLOCK_STM32F7X_APB2_PRESCALER); +#ifdef CONFIG_CLOCK_STM32F7X_SYSCLK_SRC_PLL + uint32_t pllmdiv = CONFIG_CLOCK_STM32F7X_PLLM_DIV_FACTOR; + uint32_t pllnmul = CONFIG_CLOCK_STM32F7X_PLLN_MULTIPLIER; + uint32_t pllpdiv = __pllp_div(CONFIG_CLOCK_STM32F7X_PLLP_DIV_FACTOR); + uint32_t pllqdiv = CONFIG_CLOCK_STM32F7X_PLLQ_DIV_FACTOR; +#endif /* CONFIG_CLOCK_STM32F7X_SYSCLK_SRC_PLL */ + /* Register delay helper */ + uint32_t tmpreg = 0; + + /* Enable power control clock */ + rcc->apb1enr |= STM32F7X_RCC_APB1ENR_PWREN; + tmpreg = rcc->apb1enr; + + /* disable PLL */ + rcc->cr.bit.pllon = 0; + /* disable HSE */ + rcc->cr.bit.hseon = 0; + +#ifdef CONFIG_CLOCK_STM32F7X_HSE_BYPASS + /* HSE is disabled, HSE bypass can be enabled */ + rcc->cr.bit.hsebyp = 1; +#endif + +#ifdef CONFIG_CLOCK_STM32F7X_PLL_SRC_HSI + /* enable HSI clock */ + rcc->cr.bit.hsion = 1; + + /* this should end after one test */ + while (rcc->cr.bit.hsirdy != 1) { + } + + /* TODO: should we care about HSI calibration adjustment? */ + + /* PLL input from HSI */ + rcc->pllcfgr.bit.pllsrc = STM32F7X_RCC_CFG_PLL_SRC_HSI; +#endif /* CONFIG_CLOCK_STM32F7X_PLL_SRC_HSI */ + +#ifdef CONFIG_CLOCK_STM32F7X_PLL_SRC_HSE + /* wait for to become ready */ + rcc->cr.bit.hseon = 1; + + while (rcc->cr.bit.hserdy != 1) { + } + + /* TODO: should we disable HSI if HSE gets used? */ + + rcc->pllcfgr.bit.pllsrc = STM32F7X_RCC_CFG_PLL_SRC_HSE; +#endif /* CONFIG_CLOCK_STM32F7X_PLL_SRC_HSE */ + + /* setup AHB prescaler */ + rcc->cfgr.bit.hpre = hpre; + + /* setup APB1, must not exceed 42MHz */ + rcc->cfgr.bit.ppre1 = ppre1; + + /* setup APB2 */ + rcc->cfgr.bit.ppre2 = ppre2; + +#ifdef CONFIG_CLOCK_STM32F7X_SYSCLK_SRC_PLL + /* default set of dividers and multipliers (PLL must be disabled) */ + rcc->pllcfgr.bit.pllm = pllmdiv; + rcc->pllcfgr.bit.plln = pllnmul; + rcc->pllcfgr.bit.pllp = pllpdiv; + rcc->pllcfgr.bit.pllq = pllqdiv; + + /* enable PLL */ + rcc->cr.bit.pllon = 1; + + /* wait for PLL to become ready */ + while (rcc->cr.bit.pllrdy != 1) { + } + + sysclk_src = STM32F7X_RCC_CFG_SYSCLK_SRC_PLL; +#elif defined(CONFIG_CLOCK_STM32F7X_SYSCLK_SRC_HSE) + /* wait for to become ready */ + rcc->cr.bit.hseon = 1; + while (rcc->cr.bit.hserdy != 1) { + } + + sysclk_src = STM32F7X_RCC_CFG_SYSCLK_SRC_HSE; +#endif + + /* configure flash access latency before SYSCLK source switch */ + __setup_flash(); + + /* set SYSCLK clock value */ + rcc->cfgr.bit.sw = sysclk_src; + + /* wait for SYSCLK to switch the source */ + while (rcc->cfgr.bit.sws != sysclk_src) { + } + + return 0; +} + +static struct stm32f7x_rcc_data stm32f7x_rcc_data = { + .base = (uint8_t *)RCC_BASE, +}; + +/* FIXME: move prescaler/multiplier defines into device config */ + +/** + * @brief RCC device, note that priority is intentionally set to 1 so + * that the device init runs just after SOC init + */ +DEVICE_AND_API_INIT(rcc_stm32f7x, STM32_CLOCK_CONTROL_NAME, + &stm32f7x_clock_control_init, + &stm32f7x_rcc_data, NULL, + PRIMARY, + CONFIG_CLOCK_CONTROL_STM32F7X_DEVICE_INIT_PRIORITY, + &stm32f7x_clock_control_api); diff --git a/drivers/gpio/gpio_stm32.c b/drivers/gpio/gpio_stm32.c index c8a720a953a2f5..23e39f097aac09 100644 --- a/drivers/gpio/gpio_stm32.c +++ b/drivers/gpio/gpio_stm32.c @@ -200,7 +200,7 @@ static int gpio_stm32_init(struct device *device) #ifdef CONFIG_SOC_SERIES_STM32F1X clock_control_on(clk, cfg->clock_subsys); -#elif CONFIG_SOC_SERIES_STM32F4X +#elif CONFIG_SOC_SERIES_STM32F4X || CONFIG_SOC_SERIES_STM32F7X clock_control_on(clk, (clock_control_subsys_t *) &cfg->pclken); #endif @@ -226,7 +226,7 @@ DEVICE_AND_API_INIT(gpio_stm32_## __suffix, \ CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ &gpio_stm32_driver); -#elif CONFIG_SOC_SERIES_STM32F4X +#elif CONFIG_SOC_SERIES_STM32F4X || CONFIG_SOC_SERIES_STM32F7X #define GPIO_DEVICE_INIT(__name, __suffix, __base_addr, __port, __cenr) \ static const struct gpio_stm32_config gpio_stm32_cfg_## __suffix = { \ @@ -250,7 +250,7 @@ GPIO_DEVICE_INIT("GPIOA", a, GPIOA_BASE, STM32_PORTA, #ifdef CONFIG_SOC_SERIES_STM32F1X STM32F10X_CLOCK_SUBSYS_IOPA | STM32F10X_CLOCK_SUBSYS_AFIO -#elif CONFIG_SOC_SERIES_STM32F4X +#elif CONFIG_SOC_SERIES_STM32F4X || CONFIG_SOC_SERIES_STM32F7X STM32F4X_CLOCK_ENABLE_GPIOA #endif ); @@ -261,7 +261,7 @@ GPIO_DEVICE_INIT("GPIOB", b, GPIOB_BASE, STM32_PORTB, #ifdef CONFIG_SOC_SERIES_STM32F1X STM32F10X_CLOCK_SUBSYS_IOPB | STM32F10X_CLOCK_SUBSYS_AFIO -#elif CONFIG_SOC_SERIES_STM32F4X +#elif CONFIG_SOC_SERIES_STM32F4X || CONFIG_SOC_SERIES_STM32F7X STM32F4X_CLOCK_ENABLE_GPIOB #endif ); @@ -272,7 +272,7 @@ GPIO_DEVICE_INIT("GPIOC", c, GPIOC_BASE, STM32_PORTC, #ifdef CONFIG_SOC_SERIES_STM32F1X STM32F10X_CLOCK_SUBSYS_IOPC | STM32F10X_CLOCK_SUBSYS_AFIO -#elif CONFIG_SOC_SERIES_STM32F4X +#elif CONFIG_SOC_SERIES_STM32F4X || CONFIG_SOC_SERIES_STM32F7X STM32F4X_CLOCK_ENABLE_GPIOC #endif ); @@ -283,7 +283,7 @@ GPIO_DEVICE_INIT("GPIOD", d, GPIOD_BASE, STM32_PORTD, #ifdef CONFIG_SOC_SERIES_STM32F1X STM32F10X_CLOCK_SUBSYS_IOPD | STM32F10X_CLOCK_SUBSYS_AFIO -#elif CONFIG_SOC_SERIES_STM32F4X +#elif CONFIG_SOC_SERIES_STM32F4X || CONFIG_SOC_SERIES_STM32F7X STM32F4X_CLOCK_ENABLE_GPIOD #endif ); @@ -294,7 +294,7 @@ GPIO_DEVICE_INIT("GPIOE", e, GPIOE_BASE, STM32_PORTE, #ifdef CONFIG_SOC_SERIES_STM32F1X STM32F10X_CLOCK_SUBSYS_IOPE | STM32F10X_CLOCK_SUBSYS_AFIO -#elif CONFIG_SOC_SERIES_STM32F4X +#elif CONFIG_SOC_SERIES_STM32F4X || CONFIG_SOC_SERIES_STM32F7X STM32F4X_CLOCK_ENABLE_GPIOE #endif ); diff --git a/drivers/gpio/gpio_stm32.h b/drivers/gpio/gpio_stm32.h index 29fa1684031adf..9690e767d348e2 100644 --- a/drivers/gpio/gpio_stm32.h +++ b/drivers/gpio/gpio_stm32.h @@ -37,7 +37,7 @@ struct gpio_stm32_config { #ifdef CONFIG_SOC_SERIES_STM32F1X /* clock subsystem */ clock_control_subsys_t clock_subsys; -#elif CONFIG_SOC_SERIES_STM32F4X +#elif CONFIG_SOC_SERIES_STM32F4X || CONFIG_SOC_SERIES_STM32F7X struct stm32f4x_pclken pclken; #endif }; diff --git a/drivers/pinmux/stm32/pinmux_stm32.c b/drivers/pinmux/stm32/pinmux_stm32.c index 724c49bed2e084..0cf4f9280d5185 100644 --- a/drivers/pinmux/stm32/pinmux_stm32.c +++ b/drivers/pinmux/stm32/pinmux_stm32.c @@ -32,7 +32,7 @@ #include #include -#ifdef CONFIG_SOC_SERIES_STM32F4X +#if CONFIG_SOC_SERIES_STM32F4X || CONFIG_SOC_SERIES_STM32F7X static const uint32_t ports_enable[STM32_PORTS_MAX] = { STM32F4X_CLOCK_ENABLE_GPIOA, STM32F4X_CLOCK_ENABLE_GPIOB, diff --git a/drivers/pinmux/stm32/pinmux_stm32f7.h b/drivers/pinmux/stm32/pinmux_stm32f7.h new file mode 100644 index 00000000000000..90078c0cb733bb --- /dev/null +++ b/drivers/pinmux/stm32/pinmux_stm32f7.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016 Linaro Limited. + * + * 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 + * + * http://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. + */ + +#ifndef _STM32F7_PINMUX_H_ +#define _STM32F7_PINMUX_H_ + +/** + * @file Header for STM32F7 pin multiplexing helper + */ + +#define STM32F7_PINMUX_FUNC_PA9_USART1_TX STM32_PINMUX_FUNC_ALT_7 +#define STM32F7_PINMUX_FUNC_PA10_USART1_RX STM32_PINMUX_FUNC_ALT_7 + +#define STM32F7_PINMUX_FUNC_PB6_USART1_TX STM32_PINMUX_FUNC_ALT_7 +#define STM32F7_PINMUX_FUNC_PB7_USART1_RX STM32_PINMUX_FUNC_ALT_7 + +#define STM32F7_PINMUX_FUNC_PA2_USART2_TX STM32_PINMUX_FUNC_ALT_7 +#define STM32F7_PINMUX_FUNC_PA3_USART2_RX STM32_PINMUX_FUNC_ALT_7 + +#endif /* _STM32F7_PINMUX_H_ */ From 95a12d96009510ce80d26a376916eae69108d38b Mon Sep 17 00:00:00 2001 From: Prasanna Karthik Date: Fri, 4 Nov 2016 16:37:13 -0700 Subject: [PATCH 2/2] Resolved assembler error, stm32f7 pinmux patches Signed-off-by: Prasanna Karthik --- arch/arm/Makefile | 3 +- arch/arm/soc/st_stm32/stm32f7/soc_gpio.c | 7 +- arch/arm/soc/st_stm32/stm32f7/soc_pinmux.c | 28 ++-- drivers/gpio/gpio_stm32.c | 30 ++++- drivers/gpio/gpio_stm32.h | 4 +- drivers/interrupt_controller/exti_stm32.c | 32 ++++- drivers/pinmux/stm32/pinmux_stm32.c | 14 +- drivers/pinmux/stm32/pinmux_stm32.h | 2 + .../clock_control/stm32_clock_control.h | 2 + .../clock_control/stm32f7_clock_control.h | 125 ++++++++++++++++++ 10 files changed, 222 insertions(+), 25 deletions(-) create mode 100644 include/drivers/clock_control/stm32f7_clock_control.h diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 4c8de9c6d25481..a33e9247649173 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -14,7 +14,8 @@ cflags-cortex-m3 = $(call cc-option,-mabi=aapcs -mthumb -mcpu=cortex-m3) \ $(call cc-option,-mthumb -march=armv7-m) cflags-cortex-m4 = $(call cc-option,-mabi=aapcs -mthumb -mcpu=cortex-m4) \ $(call cc-option,-mthumb -march=armv7e-m) -cflags-cortex-m7 = $(call cc-option,-mabi=aapcs -mthumb -mcpu=cortex-m7) +cflags-cortex-m7 = $(call cc-option,-mabi=aapcs -mthumb-mcpu=cortex-m7) \ + $(call cc-option,-mthumb -march=armv7-m) ifeq ($(CONFIG_FLOAT), y) ifeq ($(CONFIG_FP_SOFTABI), y) diff --git a/arch/arm/soc/st_stm32/stm32f7/soc_gpio.c b/arch/arm/soc/st_stm32/stm32f7/soc_gpio.c index 3d99ae0caa337c..d047af0cea88d4 100644 --- a/arch/arm/soc/st_stm32/stm32f7/soc_gpio.c +++ b/arch/arm/soc/st_stm32/stm32f7/soc_gpio.c @@ -242,7 +242,12 @@ int stm32_gpio_enable_int(int port, int pin) { volatile struct stm32f7x_syscfg *syscfg = (struct stm32f7x_syscfg *)SYSCFG_BASE; - volatile union __syscfg_exticr *exticr; + volatile union syscfg_exticr *exticr; + struct device *clk = device_get_binding(STM32_CLOCK_CONTROL_NAME); + struct stm32f7x_pclken pclken = { + .bus = STM32F7X_CLOCK_BUS_APB2, + .enr = STM32F7X_CLOCK_ENABLE_SYSCFG + }; int shift = 0; if (pin <= 3) { diff --git a/arch/arm/soc/st_stm32/stm32f7/soc_pinmux.c b/arch/arm/soc/st_stm32/stm32f7/soc_pinmux.c index 5a6a0761c24f8d..2aafb2e246fc93 100644 --- a/arch/arm/soc/st_stm32/stm32f7/soc_pinmux.c +++ b/arch/arm/soc/st_stm32/stm32f7/soc_pinmux.c @@ -23,33 +23,33 @@ #include static const stm32_pin_func_t pin_pa9_funcs[] = { - [STM32F4_PINMUX_FUNC_PA9_USART1_TX - 1] = - STM32F4X_PIN_CONFIG_AF_PUSH_UP, + [STM32F7_PINMUX_FUNC_PA9_USART1_TX - 1] = + STM32F7X_PIN_CONFIG_AF_PUSH_UP, }; static const stm32_pin_func_t pin_pa10_funcs[] = { - [STM32F4_PINMUX_FUNC_PA10_USART1_RX - 1] = - STM32F4X_PIN_CONFIG_AF_PUSH_UP, + [STM32F7_PINMUX_FUNC_PA10_USART1_RX - 1] = + STM32F7X_PIN_CONFIG_AF_PUSH_UP, }; static const stm32_pin_func_t pin_pb6_funcs[] = { - [STM32F4_PINMUX_FUNC_PB6_USART1_TX - 1] = - STM32F4X_PIN_CONFIG_AF_PUSH_UP, + [STM32F7_PINMUX_FUNC_PB6_USART1_TX - 1] = + STM32F7X_PIN_CONFIG_AF_PUSH_UP, }; static const stm32_pin_func_t pin_pb7_funcs[] = { - [STM32F4_PINMUX_FUNC_PB7_USART1_RX - 1] = - STM32F4X_PIN_CONFIG_AF_PUSH_UP, + [STM32F7_PINMUX_FUNC_PB7_USART1_RX - 1] = + STM32F7X_PIN_CONFIG_AF_PUSH_UP, }; static const stm32_pin_func_t pin_pa2_funcs[] = { - [STM32F4_PINMUX_FUNC_PA2_USART2_TX - 1] = - STM32F4X_PIN_CONFIG_AF_PUSH_UP, + [STM32F7_PINMUX_FUNC_PA2_USART2_TX - 1] = + STM32F7X_PIN_CONFIG_AF_PUSH_UP, }; static const stm32_pin_func_t pin_pa3_funcs[] = { - [STM32F4_PINMUX_FUNC_PA3_USART2_RX - 1] = - STM32F4X_PIN_CONFIG_AF_PUSH_UP, + [STM32F7_PINMUX_FUNC_PA3_USART2_RX - 1] = + STM32F7X_PIN_CONFIG_AF_PUSH_UP, }; /** @@ -70,12 +70,12 @@ int stm32_get_pin_config(int pin, int func) * listed in alternate functions array */ if (func == STM32_PINMUX_FUNC_GPIO) { - return STM32F4X_PIN_CONFIG_BIAS_HIGH_IMPEDANCE; + return STM32F7X_PIN_CONFIG_BIAS_HIGH_IMPEDANCE; } /* analog function is another 'known' setting */ if (func == STM32_PINMUX_FUNC_ANALOG) { - return STM32F4X_PIN_CONFIG_ANALOG; + return STM32F7X_PIN_CONFIG_ANALOG; } func -= 1; diff --git a/drivers/gpio/gpio_stm32.c b/drivers/gpio/gpio_stm32.c index 23e39f097aac09..e6349c4333e699 100644 --- a/drivers/gpio/gpio_stm32.c +++ b/drivers/gpio/gpio_stm32.c @@ -226,7 +226,7 @@ DEVICE_AND_API_INIT(gpio_stm32_## __suffix, \ CONFIG_KERNEL_INIT_PRIORITY_DEVICE, \ &gpio_stm32_driver); -#elif CONFIG_SOC_SERIES_STM32F4X || CONFIG_SOC_SERIES_STM32F7X +#elif CONFIG_SOC_SERIES_STM32F4X #define GPIO_DEVICE_INIT(__name, __suffix, __base_addr, __port, __cenr) \ static const struct gpio_stm32_config gpio_stm32_cfg_## __suffix = { \ @@ -234,6 +234,14 @@ static const struct gpio_stm32_config gpio_stm32_cfg_## __suffix = { \ .port = __port, \ .pclken = { .bus = STM32F4X_CLOCK_BUS_AHB1, .enr = __cenr }, \ }; \ + +#elif CONFIG_SOC_SERIES_STM32F7X +#define GPIO_DEVICE_INIT(__name, __suffix, __base_addr, __port, __cenr) \ +static const struct gpio_stm32_config gpio_stm32_cfg_## __suffix = { \ + .base = (uint32_t *)__base_addr, \ + .port = __port, \ + .pclken = { .bus = STM32F7X_CLOCK_BUS_AHB1, .enr = __cenr }, \ +}; \ static struct gpio_stm32_data gpio_stm32_data_## __suffix; \ DEVICE_AND_API_INIT(gpio_stm32_## __suffix, \ __name, \ @@ -250,8 +258,10 @@ GPIO_DEVICE_INIT("GPIOA", a, GPIOA_BASE, STM32_PORTA, #ifdef CONFIG_SOC_SERIES_STM32F1X STM32F10X_CLOCK_SUBSYS_IOPA | STM32F10X_CLOCK_SUBSYS_AFIO -#elif CONFIG_SOC_SERIES_STM32F4X || CONFIG_SOC_SERIES_STM32F7X +#elif CONFIG_SOC_SERIES_STM32F4X STM32F4X_CLOCK_ENABLE_GPIOA +#elif CONFIG_SOC_SERIES_STM32F7X + STM32F7X_CLOCK_ENABLE_GPIOA #endif ); #endif /* CONFIG_GPIO_STM32_PORTA */ @@ -261,8 +271,10 @@ GPIO_DEVICE_INIT("GPIOB", b, GPIOB_BASE, STM32_PORTB, #ifdef CONFIG_SOC_SERIES_STM32F1X STM32F10X_CLOCK_SUBSYS_IOPB | STM32F10X_CLOCK_SUBSYS_AFIO -#elif CONFIG_SOC_SERIES_STM32F4X || CONFIG_SOC_SERIES_STM32F7X +#elif CONFIG_SOC_SERIES_STM32F4X STM32F4X_CLOCK_ENABLE_GPIOB +#elif CONFIG_SOC_SERIES_STM32F7X + STM32F7X_CLOCK_ENABLE_GPIOB #endif ); #endif /* CONFIG_GPIO_STM32_PORTB */ @@ -272,8 +284,10 @@ GPIO_DEVICE_INIT("GPIOC", c, GPIOC_BASE, STM32_PORTC, #ifdef CONFIG_SOC_SERIES_STM32F1X STM32F10X_CLOCK_SUBSYS_IOPC | STM32F10X_CLOCK_SUBSYS_AFIO -#elif CONFIG_SOC_SERIES_STM32F4X || CONFIG_SOC_SERIES_STM32F7X +#elif CONFIG_SOC_SERIES_STM32F4X STM32F4X_CLOCK_ENABLE_GPIOC +#elif CONFIG_SOC_SERIES_STM32F7X + STM32F7X_CLOCK_ENABLE_GPIOC #endif ); #endif /* CONFIG_GPIO_STM32_PORTC */ @@ -283,8 +297,10 @@ GPIO_DEVICE_INIT("GPIOD", d, GPIOD_BASE, STM32_PORTD, #ifdef CONFIG_SOC_SERIES_STM32F1X STM32F10X_CLOCK_SUBSYS_IOPD | STM32F10X_CLOCK_SUBSYS_AFIO -#elif CONFIG_SOC_SERIES_STM32F4X || CONFIG_SOC_SERIES_STM32F7X +#elif CONFIG_SOC_SERIES_STM32F4X STM32F4X_CLOCK_ENABLE_GPIOD +#elif CONFIG_SOC_SERIES_STM32F7X + STM32F7X_CLOCK_ENABLE_GPIOD #endif ); #endif /* CONFIG_GPIO_STM32_PORTD */ @@ -294,8 +310,10 @@ GPIO_DEVICE_INIT("GPIOE", e, GPIOE_BASE, STM32_PORTE, #ifdef CONFIG_SOC_SERIES_STM32F1X STM32F10X_CLOCK_SUBSYS_IOPE | STM32F10X_CLOCK_SUBSYS_AFIO -#elif CONFIG_SOC_SERIES_STM32F4X || CONFIG_SOC_SERIES_STM32F7X +#elif CONFIG_SOC_SERIES_STM32F4X STM32F4X_CLOCK_ENABLE_GPIOE +#elif CONFIG_SOC_SERIES_STM32F7X + STM32F7X_CLOCK_ENABLE_GPIOE #endif ); #endif /* CONFIG_GPIO_STM32_PORTE */ diff --git a/drivers/gpio/gpio_stm32.h b/drivers/gpio/gpio_stm32.h index 9690e767d348e2..f884d9ada7edf7 100644 --- a/drivers/gpio/gpio_stm32.h +++ b/drivers/gpio/gpio_stm32.h @@ -37,8 +37,10 @@ struct gpio_stm32_config { #ifdef CONFIG_SOC_SERIES_STM32F1X /* clock subsystem */ clock_control_subsys_t clock_subsys; -#elif CONFIG_SOC_SERIES_STM32F4X || CONFIG_SOC_SERIES_STM32F7X +#elif CONFIG_SOC_SERIES_STM32F4X struct stm32f4x_pclken pclken; +#elif CONFIG_SOC_SERIES_STM32F7X + struct stm32f7x_pclken pclken; #endif }; diff --git a/drivers/interrupt_controller/exti_stm32.c b/drivers/interrupt_controller/exti_stm32.c index 6409f93817de48..229189581b988a 100644 --- a/drivers/interrupt_controller/exti_stm32.c +++ b/drivers/interrupt_controller/exti_stm32.c @@ -59,6 +59,9 @@ struct __exti_cb { #define EXTI_LINES 19 #elif CONFIG_SOC_SERIES_STM32F4X #define EXTI_LINES 23 +#elif CONFIG_SOC_SERIES_STM32F7X +#define EXTI_LINES 25 + #endif /* driver data */ @@ -88,7 +91,7 @@ void stm32_exti_enable(int line) /* pins 0..4 are mapped to EXTI0.. EXTI4 */ irqnum = STM32F1_IRQ_EXTI0 + line; } -#elif CONFIG_SOC_SERIES_STM32F4X +#elif CONFIG_SOC_SERIES_STM32F4X if (line >= 5 && line <= 9) { irqnum = STM32F4_IRQ_EXTI9_5; } else if (line >= 10 && line <= 15) { @@ -115,6 +118,33 @@ void stm32_exti_enable(int line) break; } } +#elif CONFIG_SOC_SERIES_STM32F7X + if (line >= 5 && line <= 9) { + irqnum = STM32F7_IRQ_EXTI9_5; + } else if (line >= 10 && line <= 15) { + irqnum = STM32F7_IRQ_EXTI15_10; + } else if (line >= 0 && line <= 4) { + /* pins 0..4 are mapped to EXTI0.. EXTI4 */ + irqnum = STM32F7_IRQ_EXTI0 + line; + } else { + switch (line) { + case 16: + irqnum = STM32F7_IRQ_EXTI16; + break; + case 17: + irqnum = STM32F7_IRQ_EXTI17; + break; + case 18: + irqnum = STM32F7_IRQ_EXTI18; + break; + case 21: + irqnum = STM32F7_IRQ_EXTI21; + break; + case 22: + irqnum = STM32F7_IRQ_EXTI22; + break; + } + } #else #error "Unknown STM32 SoC" #endif diff --git a/drivers/pinmux/stm32/pinmux_stm32.c b/drivers/pinmux/stm32/pinmux_stm32.c index 0cf4f9280d5185..e0c8a68573c8d6 100644 --- a/drivers/pinmux/stm32/pinmux_stm32.c +++ b/drivers/pinmux/stm32/pinmux_stm32.c @@ -32,7 +32,7 @@ #include #include -#if CONFIG_SOC_SERIES_STM32F4X || CONFIG_SOC_SERIES_STM32F7X +#if CONFIG_SOC_SERIES_STM32F4X static const uint32_t ports_enable[STM32_PORTS_MAX] = { STM32F4X_CLOCK_ENABLE_GPIOA, STM32F4X_CLOCK_ENABLE_GPIOB, @@ -43,8 +43,20 @@ static const uint32_t ports_enable[STM32_PORTS_MAX] = { STM32F4X_CLOCK_ENABLE_GPIOG, STM32F4X_CLOCK_ENABLE_GPIOH, }; +#elif CONFIG_SOC_SERIES_STM32F7X +static const uint32_t ports_enable[STM32_PORTS_MAX] = { + STM32F7X_CLOCK_ENABLE_GPIOA, + STM32F7X_CLOCK_ENABLE_GPIOB, + STM32F7X_CLOCK_ENABLE_GPIOC, + STM32F7X_CLOCK_ENABLE_GPIOD, + STM32F7X_CLOCK_ENABLE_GPIOE, + STM32F7X_CLOCK_ENABLE_GPIOF, + STM32F7X_CLOCK_ENABLE_GPIOG, + STM32F7X_CLOCK_ENABLE_GPIOH, +}; #endif + /** * @brief enable IO port clock * diff --git a/drivers/pinmux/stm32/pinmux_stm32.h b/drivers/pinmux/stm32/pinmux_stm32.h index 02cfe042b934f3..b1b72b7a40ed95 100644 --- a/drivers/pinmux/stm32/pinmux_stm32.h +++ b/drivers/pinmux/stm32/pinmux_stm32.h @@ -295,6 +295,8 @@ void stm32_setup_pins(const struct pin_config *pinconf, #include "pinmux_stm32f1.h" #elif CONFIG_SOC_SERIES_STM32F4X #include "pinmux_stm32f4.h" +#elif CONFIG_SOC_SERIES_STM32F7X +#include "pinmux_stm32f7.h" #endif #endif /* _STM32_PINMUX_H_ */ diff --git a/include/drivers/clock_control/stm32_clock_control.h b/include/drivers/clock_control/stm32_clock_control.h index 2d6084c1596e66..eb1bb28f21f2d9 100644 --- a/include/drivers/clock_control/stm32_clock_control.h +++ b/include/drivers/clock_control/stm32_clock_control.h @@ -25,6 +25,8 @@ #include "stm32f1_clock_control.h" #elif CONFIG_SOC_SERIES_STM32F4X #include "stm32f4_clock_control.h" +#elif CONFIG_SOC_SERIES_STM32F7X +#include "stm32f7_clock_control.h" #endif #endif /* _STM32_CLOCK_CONTROL_H_ */ diff --git a/include/drivers/clock_control/stm32f7_clock_control.h b/include/drivers/clock_control/stm32f7_clock_control.h new file mode 100644 index 00000000000000..ed3e85011f4ae1 --- /dev/null +++ b/include/drivers/clock_control/stm32f7_clock_control.h @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2016 Open-RnD Sp. z o.o. + * (c) 2016 Linaro Limited. + * + * 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 + * + * http://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. + */ +#ifndef _STM32F7_CLOCK_CONTROL_H_ +#define _STM32F7_CLOCK_CONTROL_H_ + +/** + * @file + * + * @brief Clock subsystem IDs for STM32F7 family + */ + +/* Bus */ +enum { + STM32F7X_CLOCK_BUS_AHB1, + STM32F7X_CLOCK_BUS_AHB2, + STM32F7X_CLOCK_BUS_APB1, + STM32F7X_CLOCK_BUS_APB2, +}; + +/* AHB1 pins */ +enum { + /* AHB1 */ + STM32F7X_CLOCK_ENABLE_GPIOA = 1 << 0, + STM32F7X_CLOCK_ENABLE_GPIOB = 1 << 1, + STM32F7X_CLOCK_ENABLE_GPIOC = 1 << 2, + STM32F7X_CLOCK_ENABLE_GPIOD = 1 << 3, + STM32F7X_CLOCK_ENABLE_GPIOE = 1 << 4, + STM32F7X_CLOCK_ENABLE_GPIOF = 1 << 5, + STM32F7X_CLOCK_ENABLE_GPIOG = 1 << 6, + STM32F7X_CLOCK_ENABLE_GPIOH = 1 << 7, + STM32F7X_CLOCK_ENABLE_GPIOI = 1 << 8, + STM32F7X_CLOCK_ENABLE_GPIOJ = 1 << 9, + STM32F7X_CLOCK_ENABLE_GPIOK = 1 << 10, + STM32F7X_CLOCK_ENABLE_CRC = 1 << 12, + STM32F7X_CLOCK_ENABLE_BKPSRAM = 1 << 14, + STM32F7X_CLOCK_ENABLE_CCMDATARAM = 1 << 16, + STM32F7X_CLOCK_ENABLE_DMA1 = 1 << 21, + STM32F7X_CLOCK_ENABLE_DMA2 = 1 << 22, + STM32F7X_CLOCK_ENABLE_ETHMAC = 1 << 25, + STM32F7X_CLOCK_ENABLE_ETHMACTX = 1 << 26, + STM32F7X_CLOCK_ENABLE_ETHMACRX = 1 << 27, + STM32F7X_CLOCK_ENABLE_ETHMACPTP = 1 << 28, + STM32F7X_CLOCK_ENABLE_OTGHS = 1 << 29, + STM32F7X_CLOCK_ENABLE_OTGHSULPI = 1 << 30, +}; + +/* AHB2 pins */ +enum { + STM32F7X_CLOCK_ENABLE_DCMI = 1 << 0, + STM32F7X_CLOCK_ENABLE_CRYP = 1 << 4, + STM32F7X_CLOCK_ENABLE_HASH = 1 << 5, + STM32F7X_CLOCK_ENABLE_RNG = 1 << 6, + STM32F7X_CLOCK_ENABLE_OTGFS = 1 << 7, +}; + +/* APB1 pins */ +enum { + STM32F7X_CLOCK_ENABLE_TIM2 = 1 << 0, + STM32F7X_CLOCK_ENABLE_TIM3 = 1 << 1, + STM32F7X_CLOCK_ENABLE_TIM4 = 1 << 2, + STM32F7X_CLOCK_ENABLE_TIM5 = 1 << 3, + STM32F7X_CLOCK_ENABLE_TIM6 = 1 << 4, + STM32F7X_CLOCK_ENABLE_TIM7 = 1 << 5, + STM32F7X_CLOCK_ENABLE_TIM12 = 1 << 6, + STM32F7X_CLOCK_ENABLE_TIM13 = 1 << 7, + STM32F7X_CLOCK_ENABLE_TIM14 = 1 << 8, + STM32F7X_CLOCK_ENABLE_WWDG = 1 << 11, + STM32F7X_CLOCK_ENABLE_SPI2 = 1 << 14, + STM32F7X_CLOCK_ENABLE_SPI3 = 1 << 15, + STM32F7X_CLOCK_ENABLE_USART2 = 1 << 17, + STM32F7X_CLOCK_ENABLE_USART3 = 1 << 18, + STM32F7X_CLOCK_ENABLE_UART4 = 1 << 19, + STM32F7X_CLOCK_ENABLE_UART5 = 1 << 20, + STM32F7X_CLOCK_ENABLE_I2C1 = 1 << 21, + STM32F7X_CLOCK_ENABLE_I2C2 = 1 << 22, + STM32F7X_CLOCK_ENABLE_I2C3 = 1 << 23, + STM32F7X_CLOCK_ENABLE_CAN1 = 1 << 25, + STM32F7X_CLOCK_ENABLE_CAN2 = 1 << 26, + STM32F7X_CLOCK_ENABLE_PWR = 1 << 28, + STM32F7X_CLOCK_ENABLE_DAC = 1 << 29, + STM32F7X_CLOCK_ENABLE_UART7 = 1 << 30, + STM32F7X_CLOCK_ENABLE_UART8 = 1 << 31, +}; + +/* APB2 pins */ +enum { + STM32F7X_CLOCK_ENABLE_TIM1 = 1 << 0, + STM32F7X_CLOCK_ENABLE_TIM8 = 1 << 1, + STM32F7X_CLOCK_ENABLE_USART1 = 1 << 4, + STM32F7X_CLOCK_ENABLE_USART6 = 1 << 5, + STM32F7X_CLOCK_ENABLE_ADC = 1 << 8, + STM32F7X_CLOCK_ENABLE_SDIO = 1 << 11, + STM32F7X_CLOCK_ENABLE_SPI1 = 1 << 12, + STM32F7X_CLOCK_ENABLE_SPI4 = 1 << 13, + STM32F7X_CLOCK_ENABLE_SYSCFG = 1 << 14, + STM32F7X_CLOCK_ENABLE_TIM9 = 1 << 16, + STM32F7X_CLOCK_ENABLE_TIM10 = 1 << 17, + STM32F7X_CLOCK_ENABLE_TIM11 = 1 << 18, + STM32F7X_CLOCK_ENABLE_SPI5 = 1 << 20, + STM32F7X_CLOCK_ENABLE_SPI6 = 1 << 21, + STM32F7X_CLOCK_ENABLE_SAI1 = 1 << 22, + STM32F7X_CLOCK_ENABLE_LTDC = 1 << 26, + STM32F7X_CLOCK_ENABLE_DSI = 1 << 27, +}; + +struct stm32f7x_pclken { + uint32_t bus; + uint32_t enr; +}; + +#endif /* _STM32F7_CLOCK_CONTROL_H_ */