summaryrefslogtreecommitdiffstats
path: root/bsps/arm/stm32h7/start/stm32h7-hal.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--bsps/arm/stm32h7/start/stm32h7-hal.c276
1 files changed, 276 insertions, 0 deletions
diff --git a/bsps/arm/stm32h7/start/stm32h7-hal.c b/bsps/arm/stm32h7/start/stm32h7-hal.c
new file mode 100644
index 0000000000..3dcc3098f4
--- /dev/null
+++ b/bsps/arm/stm32h7/start/stm32h7-hal.c
@@ -0,0 +1,276 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stm32h7/hal.h>
+
+#include <rtems.h>
+
+stm32h7_module_index stm32h7_get_module_index(const void *regs)
+{
+ switch ((uintptr_t) regs) {
+ case GPIOA_BASE:
+ return STM32H7_MODULE_GPIOA;
+ case GPIOB_BASE:
+ return STM32H7_MODULE_GPIOB;
+ case GPIOC_BASE:
+ return STM32H7_MODULE_GPIOC;
+ case GPIOD_BASE:
+ return STM32H7_MODULE_GPIOD;
+ case GPIOE_BASE:
+ return STM32H7_MODULE_GPIOE;
+ case GPIOF_BASE:
+ return STM32H7_MODULE_GPIOF;
+ case GPIOG_BASE:
+ return STM32H7_MODULE_GPIOG;
+ case GPIOH_BASE:
+ return STM32H7_MODULE_GPIOH;
+ case GPIOI_BASE:
+ return STM32H7_MODULE_GPIOI;
+ case GPIOJ_BASE:
+ return STM32H7_MODULE_GPIOJ;
+ case GPIOK_BASE:
+ return STM32H7_MODULE_GPIOK;
+ case USART1_BASE:
+ return STM32H7_MODULE_USART1;
+ case USART2_BASE:
+ return STM32H7_MODULE_USART2;
+ case USART3_BASE:
+ return STM32H7_MODULE_USART3;
+ case UART4_BASE:
+ return STM32H7_MODULE_UART4;
+ case UART5_BASE:
+ return STM32H7_MODULE_UART5;
+ case USART6_BASE:
+ return STM32H7_MODULE_USART6;
+ case UART7_BASE:
+ return STM32H7_MODULE_UART7;
+ case UART8_BASE:
+ return STM32H7_MODULE_UART8;
+#ifdef UART9_BASE
+ case UART9_BASE:
+ return STM32H7_MODULE_UART9;
+#endif
+#ifdef USART10_BASE
+ case USART10_BASE:
+ return STM32H7_MODULE_USART10;
+#endif
+ case RNG_BASE:
+ return STM32H7_MODULE_RNG;
+ }
+
+ return STM32H7_MODULE_INVALID;
+}
+
+typedef struct {
+ __IO uint32_t *enr;
+ uint32_t enable_bit;
+} stm32h7_clk_info;
+
+static const stm32h7_clk_info stm32h7_clk[] = {
+ [STM32H7_MODULE_INVALID] = { NULL, 0 },
+ [STM32H7_MODULE_GPIOA] = { &RCC->AHB4ENR, RCC_AHB4ENR_GPIOAEN },
+ [STM32H7_MODULE_GPIOB] = { &RCC->AHB4ENR, RCC_AHB4ENR_GPIOBEN },
+ [STM32H7_MODULE_GPIOC] = { &RCC->AHB4ENR, RCC_AHB4ENR_GPIOCEN },
+ [STM32H7_MODULE_GPIOD] = { &RCC->AHB4ENR, RCC_AHB4ENR_GPIODEN },
+ [STM32H7_MODULE_GPIOE] = { &RCC->AHB4ENR, RCC_AHB4ENR_GPIOEEN },
+ [STM32H7_MODULE_GPIOF] = { &RCC->AHB4ENR, RCC_AHB4ENR_GPIOFEN },
+ [STM32H7_MODULE_GPIOG] = { &RCC->AHB4ENR, RCC_AHB4ENR_GPIOGEN },
+ [STM32H7_MODULE_GPIOH] = { &RCC->AHB4ENR, RCC_AHB4ENR_GPIOHEN },
+ [STM32H7_MODULE_GPIOI] = { &RCC->AHB4ENR, RCC_AHB4ENR_GPIOIEN },
+ [STM32H7_MODULE_GPIOJ] = { &RCC->AHB4ENR, RCC_AHB4ENR_GPIOJEN },
+ [STM32H7_MODULE_GPIOK] = { &RCC->AHB4ENR, RCC_AHB4ENR_GPIOKEN },
+ [STM32H7_MODULE_USART1] = { &RCC->APB2ENR, RCC_APB2ENR_USART1EN },
+ [STM32H7_MODULE_USART2] = { &RCC->APB1LENR, RCC_APB1LENR_USART2EN },
+ [STM32H7_MODULE_USART3] = { &RCC->APB1LENR, RCC_APB1LENR_USART3EN },
+ [STM32H7_MODULE_UART4] = { &RCC->APB1LENR, RCC_APB1LENR_UART4EN },
+ [STM32H7_MODULE_UART5] = { &RCC->APB1LENR, RCC_APB1LENR_UART5EN },
+ [STM32H7_MODULE_USART6] = { &RCC->APB2ENR, RCC_APB2ENR_USART6EN },
+ [STM32H7_MODULE_UART7] = { &RCC->APB1LENR, RCC_APB1LENR_UART7EN },
+ [STM32H7_MODULE_UART8] = { &RCC->APB1LENR, RCC_APB1LENR_UART8EN },
+#ifdef UART9_BASE
+ [STM32H7_MODULE_UART9] = { &RCC->APB2ENR, RCC_APB2ENR_UART9EN },
+#else
+ [STM32H7_MODULE_UART9] = { NULL, 0 },
+#endif
+#ifdef USART10_BASE
+ [STM32H7_MODULE_USART10] = { &RCC->APB2ENR, RCC_APB2ENR_USART10EN },
+#else
+ [STM32H7_MODULE_USART10] = { NULL, 0 },
+#endif
+ [STM32H7_MODULE_RNG] = { &RCC->AHB2ENR, RCC_AHB2ENR_RNGEN },
+ [STM32H7_MODULE_ETH1MAC] = { &RCC->AHB1ENR, RCC_AHB1ENR_ETH1MACEN },
+ [STM32H7_MODULE_ETH1TX] = { &RCC->AHB1ENR, RCC_AHB1ENR_ETH1TXEN },
+ [STM32H7_MODULE_ETH1RX] = { &RCC->AHB1ENR, RCC_AHB1ENR_ETH1RXEN },
+ [STM32H7_MODULE_USB1_OTG] = { &RCC->AHB1ENR, RCC_AHB1ENR_USB1OTGHSEN },
+ [STM32H7_MODULE_USB1_OTG_ULPI] = { &RCC->AHB1ENR, RCC_AHB1ENR_USB1OTGHSULPIEN },
+ [STM32H7_MODULE_USB2_OTG] = { &RCC->AHB1ENR, RCC_AHB1ENR_USB2OTGHSEN },
+ [STM32H7_MODULE_USB2_OTG_ULPI] = { &RCC->AHB1ENR, RCC_AHB1ENR_USB2OTGHSULPIEN }
+};
+
+void stm32h7_clk_enable(stm32h7_module_index index)
+{
+ __IO uint32_t *enr;
+ uint32_t enable_bit;
+ rtems_interrupt_level level;
+
+ enr = stm32h7_clk[index].enr;
+ enable_bit = stm32h7_clk[index].enable_bit;
+
+ rtems_interrupt_disable(level);
+ SET_BIT(*enr, enable_bit);
+ /* Delay after an RCC peripheral clock enabling */
+ *enr;
+ rtems_interrupt_enable(level);
+}
+
+void stm32h7_clk_disable(stm32h7_module_index index)
+{
+ __IO uint32_t *enr;
+ uint32_t enable_bit;
+ rtems_interrupt_level level;
+
+ enr = stm32h7_clk[index].enr;
+ enable_bit = stm32h7_clk[index].enable_bit;
+
+ rtems_interrupt_disable(level);
+ CLEAR_BIT(*enr, enable_bit);
+ rtems_interrupt_enable(level);
+}
+
+static const stm32h7_clk_info stm32h7_clk_low_power[] = {
+ [STM32H7_MODULE_INVALID] = { NULL, 0 },
+ [STM32H7_MODULE_GPIOA] = { &RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOALPEN },
+ [STM32H7_MODULE_GPIOB] = { &RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOBLPEN },
+ [STM32H7_MODULE_GPIOC] = { &RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOCLPEN },
+ [STM32H7_MODULE_GPIOD] = { &RCC->AHB4LPENR, RCC_AHB4LPENR_GPIODLPEN },
+ [STM32H7_MODULE_GPIOE] = { &RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOELPEN },
+ [STM32H7_MODULE_GPIOF] = { &RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOFLPEN },
+ [STM32H7_MODULE_GPIOG] = { &RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOGLPEN },
+ [STM32H7_MODULE_GPIOH] = { &RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOHLPEN },
+ [STM32H7_MODULE_GPIOI] = { &RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOILPEN },
+ [STM32H7_MODULE_GPIOJ] = { &RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOJLPEN },
+ [STM32H7_MODULE_GPIOK] = { &RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOKLPEN },
+ [STM32H7_MODULE_USART1] = { &RCC->APB2LPENR, RCC_APB2LPENR_USART1LPEN },
+ [STM32H7_MODULE_USART2] = { &RCC->APB1LLPENR, RCC_APB1LLPENR_USART2LPEN },
+ [STM32H7_MODULE_USART3] = { &RCC->APB1LLPENR, RCC_APB1LLPENR_USART3LPEN },
+ [STM32H7_MODULE_UART4] = { &RCC->APB1LLPENR, RCC_APB1LLPENR_UART4LPEN },
+ [STM32H7_MODULE_UART5] = { &RCC->APB1LLPENR, RCC_APB1LLPENR_UART5LPEN },
+ [STM32H7_MODULE_USART6] = { &RCC->APB2LPENR, RCC_APB2LPENR_USART6LPEN },
+ [STM32H7_MODULE_UART7] = { &RCC->APB1LLPENR, RCC_APB1LLPENR_UART7LPEN },
+ [STM32H7_MODULE_UART8] = { &RCC->APB1LLPENR, RCC_APB1LLPENR_UART8LPEN },
+#ifdef UART9_BASE
+ [STM32H7_MODULE_UART9] = { &RCC->APB2LPENR, RCC_APB2LPENR_UART9LPEN },
+#else
+ [STM32H7_MODULE_UART9] = { NULL, 0 },
+#endif
+#ifdef USART10_BASE
+ [STM32H7_MODULE_USART10] = { &RCC->APB2LPENR, RCC_APB2LPENR_USART10LPEN },
+#else
+ [STM32H7_MODULE_USART10] = { NULL, 0 },
+#endif
+ [STM32H7_MODULE_RNG] = { &RCC->AHB2LPENR, RCC_AHB2LPENR_RNGLPEN },
+ [STM32H7_MODULE_ETH1MAC] = { &RCC->AHB1LPENR, RCC_AHB1LPENR_ETH1MACLPEN },
+ [STM32H7_MODULE_ETH1TX] = { &RCC->AHB1LPENR, RCC_AHB1LPENR_ETH1TXLPEN },
+ [STM32H7_MODULE_ETH1RX] = { &RCC->AHB1LPENR, RCC_AHB1LPENR_ETH1RXLPEN },
+ [STM32H7_MODULE_USB1_OTG] = { &RCC->AHB1LPENR, RCC_AHB1LPENR_USB1OTGHSLPEN },
+ [STM32H7_MODULE_USB1_OTG_ULPI] = { &RCC->AHB1LPENR, RCC_AHB1LPENR_USB1OTGHSULPILPEN },
+ [STM32H7_MODULE_USB2_OTG] = { &RCC->AHB1LPENR, RCC_AHB1LPENR_USB2OTGHSLPEN },
+ [STM32H7_MODULE_USB2_OTG_ULPI] = { &RCC->AHB1LPENR, RCC_AHB1LPENR_USB2OTGHSULPILPEN }
+};
+
+void stm32h7_clk_low_power_enable(stm32h7_module_index index)
+{
+ __IO uint32_t *enr;
+ uint32_t enable_bit;
+ rtems_interrupt_level level;
+
+ enr = stm32h7_clk_low_power[index].enr;
+ enable_bit = stm32h7_clk_low_power[index].enable_bit;
+
+ rtems_interrupt_disable(level);
+ SET_BIT(*enr, enable_bit);
+ /* Delay after an RCC peripheral clock enabling */
+ *enr;
+ rtems_interrupt_enable(level);
+}
+
+void stm32h7_clk_low_power_disable(stm32h7_module_index index)
+{
+ __IO uint32_t *enr;
+ uint32_t enable_bit;
+ rtems_interrupt_level level;
+
+ enr = stm32h7_clk_low_power[index].enr;
+ enable_bit = stm32h7_clk_low_power[index].enable_bit;
+
+ rtems_interrupt_disable(level);
+ CLEAR_BIT(*enr, enable_bit);
+ rtems_interrupt_enable(level);
+}
+
+void stm32h7_gpio_init(const stm32h7_gpio_config *config)
+{
+ stm32h7_module_index index;
+
+ index = stm32h7_get_module_index(config->regs);
+ stm32h7_clk_enable(index);
+ HAL_GPIO_Init(config->regs, &config->config);
+}
+
+void stm32h7_uart_polled_write(rtems_termios_device_context *base, char c)
+{
+ stm32h7_uart_context *ctx;
+ USART_TypeDef *regs;
+
+ ctx = stm32h7_uart_get_context(base);
+ regs = ctx->uart.Instance;
+
+ while ((regs->ISR & USART_ISR_TXE_TXFNF) == 0) {
+ /* Wait */
+ }
+
+ regs->TDR = (uint8_t) c;
+}
+
+int stm32h7_uart_polled_read(rtems_termios_device_context *base)
+{
+ stm32h7_uart_context *ctx;
+ USART_TypeDef *regs;
+
+ ctx = stm32h7_uart_get_context(base);
+ regs = ctx->uart.Instance;
+
+ if ((regs->ISR & USART_ISR_RXNE_RXFNE) == 0) {
+ return -1;
+ }
+
+ return (uint8_t) regs->RDR;
+}