Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:38

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * Copyright (C) 2020 embedded brains GmbH & Co. KG
0005  *
0006  * Redistribution and use in source and binary forms, with or without
0007  * modification, are permitted provided that the following conditions
0008  * are met:
0009  * 1. Redistributions of source code must retain the above copyright
0010  *    notice, this list of conditions and the following disclaimer.
0011  * 2. Redistributions in binary form must reproduce the above copyright
0012  *    notice, this list of conditions and the following disclaimer in the
0013  *    documentation and/or other materials provided with the distribution.
0014  *
0015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0025  * POSSIBILITY OF SUCH DAMAGE.
0026  */
0027 
0028 #ifdef HAVE_CONFIG_H
0029 #include "config.h"
0030 #endif
0031 
0032 #include <stm32h7/hal.h>
0033 
0034 #include <rtems.h>
0035 
0036 stm32h7_module_index stm32h7_get_module_index(const void *regs)
0037 {
0038   switch ((uintptr_t) regs) {
0039     case GPIOA_BASE:
0040       return STM32H7_MODULE_GPIOA;
0041     case GPIOB_BASE:
0042       return STM32H7_MODULE_GPIOB;
0043     case GPIOC_BASE:
0044       return STM32H7_MODULE_GPIOC;
0045     case GPIOD_BASE:
0046       return STM32H7_MODULE_GPIOD;
0047     case GPIOE_BASE:
0048       return STM32H7_MODULE_GPIOE;
0049     case GPIOF_BASE:
0050       return STM32H7_MODULE_GPIOF;
0051     case GPIOG_BASE:
0052       return STM32H7_MODULE_GPIOG;
0053     case GPIOH_BASE:
0054       return STM32H7_MODULE_GPIOH;
0055     case GPIOI_BASE:
0056       return STM32H7_MODULE_GPIOI;
0057     case GPIOJ_BASE:
0058       return STM32H7_MODULE_GPIOJ;
0059     case GPIOK_BASE:
0060       return STM32H7_MODULE_GPIOK;
0061     case USART1_BASE:
0062       return STM32H7_MODULE_USART1;
0063     case USART2_BASE:
0064       return STM32H7_MODULE_USART2;
0065     case USART3_BASE:
0066       return STM32H7_MODULE_USART3;
0067     case UART4_BASE:
0068       return STM32H7_MODULE_UART4;
0069     case UART5_BASE:
0070       return STM32H7_MODULE_UART5;
0071     case USART6_BASE:
0072       return STM32H7_MODULE_USART6;
0073     case UART7_BASE:
0074       return STM32H7_MODULE_UART7;
0075     case UART8_BASE:
0076       return STM32H7_MODULE_UART8;
0077 #ifdef UART9_BASE
0078     case UART9_BASE:
0079       return STM32H7_MODULE_UART9;
0080 #endif
0081 #ifdef USART10_BASE
0082     case USART10_BASE:
0083       return STM32H7_MODULE_USART10;
0084 #endif
0085     case RNG_BASE:
0086       return STM32H7_MODULE_RNG;
0087     case SDMMC1_BASE:
0088     case DLYB_SDMMC1_BASE:
0089       return STM32H7_MODULE_SDMMC1;
0090     case SDMMC2_BASE:
0091     case DLYB_SDMMC2_BASE:
0092       return STM32H7_MODULE_SDMMC2;
0093     case SPI1_BASE:
0094       return STM32H7_MODULE_SPI1;
0095     case SPI2_BASE:
0096       return STM32H7_MODULE_SPI2;
0097     case SPI3_BASE:
0098       return STM32H7_MODULE_SPI3;
0099     case SPI4_BASE:
0100       return STM32H7_MODULE_SPI4;
0101     case SPI5_BASE:
0102       return STM32H7_MODULE_SPI5;
0103     case SPI6_BASE:
0104       return STM32H7_MODULE_SPI6;
0105   }
0106 
0107   return STM32H7_MODULE_INVALID;
0108 }
0109 
0110 typedef struct {
0111   __IO uint32_t *enr;
0112   uint32_t enable_bit;
0113 } stm32h7_clk_info;
0114 
0115 static const stm32h7_clk_info stm32h7_clk[] = {
0116   [STM32H7_MODULE_INVALID] = { NULL, 0 },
0117   [STM32H7_MODULE_GPIOA] = { &RCC->AHB4ENR, RCC_AHB4ENR_GPIOAEN },
0118   [STM32H7_MODULE_GPIOB] = { &RCC->AHB4ENR, RCC_AHB4ENR_GPIOBEN },
0119   [STM32H7_MODULE_GPIOC] = { &RCC->AHB4ENR, RCC_AHB4ENR_GPIOCEN },
0120   [STM32H7_MODULE_GPIOD] = { &RCC->AHB4ENR, RCC_AHB4ENR_GPIODEN },
0121   [STM32H7_MODULE_GPIOE] = { &RCC->AHB4ENR, RCC_AHB4ENR_GPIOEEN },
0122   [STM32H7_MODULE_GPIOF] = { &RCC->AHB4ENR, RCC_AHB4ENR_GPIOFEN },
0123   [STM32H7_MODULE_GPIOG] = { &RCC->AHB4ENR, RCC_AHB4ENR_GPIOGEN },
0124   [STM32H7_MODULE_GPIOH] = { &RCC->AHB4ENR, RCC_AHB4ENR_GPIOHEN },
0125   [STM32H7_MODULE_GPIOI] = { &RCC->AHB4ENR, RCC_AHB4ENR_GPIOIEN },
0126   [STM32H7_MODULE_GPIOJ] = { &RCC->AHB4ENR, RCC_AHB4ENR_GPIOJEN },
0127   [STM32H7_MODULE_GPIOK] = { &RCC->AHB4ENR, RCC_AHB4ENR_GPIOKEN },
0128   [STM32H7_MODULE_USART1] = { &RCC->APB2ENR, RCC_APB2ENR_USART1EN },
0129   [STM32H7_MODULE_USART2] = { &RCC->APB1LENR, RCC_APB1LENR_USART2EN },
0130   [STM32H7_MODULE_USART3] = { &RCC->APB1LENR, RCC_APB1LENR_USART3EN },
0131   [STM32H7_MODULE_UART4] = { &RCC->APB1LENR, RCC_APB1LENR_UART4EN },
0132   [STM32H7_MODULE_UART5] = { &RCC->APB1LENR, RCC_APB1LENR_UART5EN },
0133   [STM32H7_MODULE_USART6] = { &RCC->APB2ENR, RCC_APB2ENR_USART6EN },
0134   [STM32H7_MODULE_UART7] = { &RCC->APB1LENR, RCC_APB1LENR_UART7EN },
0135   [STM32H7_MODULE_UART8] = { &RCC->APB1LENR, RCC_APB1LENR_UART8EN },
0136 #ifdef UART9_BASE
0137   [STM32H7_MODULE_UART9] = { &RCC->APB2ENR, RCC_APB2ENR_UART9EN },
0138 #else
0139   [STM32H7_MODULE_UART9] = { NULL, 0 },
0140 #endif
0141 #ifdef USART10_BASE
0142   [STM32H7_MODULE_USART10] = { &RCC->APB2ENR, RCC_APB2ENR_USART10EN },
0143 #else
0144   [STM32H7_MODULE_USART10] = { NULL, 0 },
0145 #endif
0146   [STM32H7_MODULE_RNG] = { &RCC->AHB2ENR, RCC_AHB2ENR_RNGEN },
0147 #ifdef RCC_AHB1ENR_ETH1MACEN
0148   [STM32H7_MODULE_ETH1MAC] = { &RCC->AHB1ENR, RCC_AHB1ENR_ETH1MACEN },
0149 #endif
0150 #ifdef RCC_AHB1ENR_ETH1TXEN
0151   [STM32H7_MODULE_ETH1TX] = { &RCC->AHB1ENR, RCC_AHB1ENR_ETH1TXEN },
0152 #endif
0153 #ifdef RCC_AHB1ENR_ETH1RXEN
0154   [STM32H7_MODULE_ETH1RX] = { &RCC->AHB1ENR, RCC_AHB1ENR_ETH1RXEN },
0155 #endif
0156   [STM32H7_MODULE_USB1_OTG] = { &RCC->AHB1ENR, RCC_AHB1ENR_USB1OTGHSEN },
0157   [STM32H7_MODULE_USB1_OTG_ULPI] = { &RCC->AHB1ENR, RCC_AHB1ENR_USB1OTGHSULPIEN },
0158 #ifdef RCC_AHB1ENR_USB2OTGHSEN
0159   [STM32H7_MODULE_USB2_OTG] = { &RCC->AHB1ENR, RCC_AHB1ENR_USB2OTGHSEN },
0160 #endif
0161 #ifdef RCC_AHB1ENR_USB2OTGHSULPIEN
0162   [STM32H7_MODULE_USB2_OTG_ULPI] = { &RCC->AHB1ENR, RCC_AHB1ENR_USB2OTGHSULPIEN },
0163 #endif
0164   [STM32H7_MODULE_SDMMC1] = { &RCC->AHB3ENR, RCC_AHB3ENR_SDMMC1EN },
0165   [STM32H7_MODULE_SDMMC2] = { &RCC->AHB2ENR, RCC_AHB2ENR_SDMMC2EN },
0166   [STM32H7_MODULE_SPI1] = { &RCC->APB2ENR, RCC_APB2ENR_SPI1EN },
0167   [STM32H7_MODULE_SPI2] = { &RCC->APB1LENR, RCC_APB1LENR_SPI2EN },
0168   [STM32H7_MODULE_SPI3] = { &RCC->APB1LENR, RCC_APB1LENR_SPI3EN },
0169   [STM32H7_MODULE_SPI4] = { &RCC->APB2ENR, RCC_APB2ENR_SPI4EN },
0170   [STM32H7_MODULE_SPI5] = { &RCC->APB2ENR, RCC_APB2ENR_SPI5EN },
0171   [STM32H7_MODULE_SPI6] = { &RCC->APB4ENR, RCC_APB4ENR_SPI6EN },
0172 };
0173 
0174 void stm32h7_clk_enable(stm32h7_module_index index)
0175 {
0176   __IO uint32_t *enr;
0177   uint32_t enable_bit;
0178   rtems_interrupt_level level;
0179 
0180   enr = stm32h7_clk[index].enr;
0181   enable_bit = stm32h7_clk[index].enable_bit;
0182 
0183   rtems_interrupt_disable(level);
0184   SET_BIT(*enr, enable_bit);
0185   /* Delay after an RCC peripheral clock enabling */
0186   *enr;
0187   rtems_interrupt_enable(level);
0188 }
0189 
0190 void stm32h7_clk_disable(stm32h7_module_index index)
0191 {
0192   __IO uint32_t *enr;
0193   uint32_t enable_bit;
0194   rtems_interrupt_level level;
0195 
0196   enr = stm32h7_clk[index].enr;
0197   enable_bit = stm32h7_clk[index].enable_bit;
0198 
0199   rtems_interrupt_disable(level);
0200   CLEAR_BIT(*enr, enable_bit);
0201   rtems_interrupt_enable(level);
0202 }
0203 
0204 static const stm32h7_clk_info stm32h7_clk_low_power[] = {
0205   [STM32H7_MODULE_INVALID] = { NULL, 0 },
0206   [STM32H7_MODULE_GPIOA] = { &RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOALPEN },
0207   [STM32H7_MODULE_GPIOB] = { &RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOBLPEN },
0208   [STM32H7_MODULE_GPIOC] = { &RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOCLPEN },
0209   [STM32H7_MODULE_GPIOD] = { &RCC->AHB4LPENR, RCC_AHB4LPENR_GPIODLPEN },
0210   [STM32H7_MODULE_GPIOE] = { &RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOELPEN },
0211   [STM32H7_MODULE_GPIOF] = { &RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOFLPEN },
0212   [STM32H7_MODULE_GPIOG] = { &RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOGLPEN },
0213   [STM32H7_MODULE_GPIOH] = { &RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOHLPEN },
0214   [STM32H7_MODULE_GPIOI] = { &RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOILPEN },
0215   [STM32H7_MODULE_GPIOJ] = { &RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOJLPEN },
0216   [STM32H7_MODULE_GPIOK] = { &RCC->AHB4LPENR, RCC_AHB4LPENR_GPIOKLPEN },
0217   [STM32H7_MODULE_USART1] = { &RCC->APB2LPENR, RCC_APB2LPENR_USART1LPEN },
0218   [STM32H7_MODULE_USART2] = { &RCC->APB1LLPENR, RCC_APB1LLPENR_USART2LPEN },
0219   [STM32H7_MODULE_USART3] = { &RCC->APB1LLPENR, RCC_APB1LLPENR_USART3LPEN },
0220   [STM32H7_MODULE_UART4] = { &RCC->APB1LLPENR, RCC_APB1LLPENR_UART4LPEN },
0221   [STM32H7_MODULE_UART5] = { &RCC->APB1LLPENR, RCC_APB1LLPENR_UART5LPEN },
0222   [STM32H7_MODULE_USART6] = { &RCC->APB2LPENR, RCC_APB2LPENR_USART6LPEN },
0223   [STM32H7_MODULE_UART7] = { &RCC->APB1LLPENR, RCC_APB1LLPENR_UART7LPEN },
0224   [STM32H7_MODULE_UART8] = { &RCC->APB1LLPENR, RCC_APB1LLPENR_UART8LPEN },
0225 #ifdef UART9_BASE
0226   [STM32H7_MODULE_UART9] = { &RCC->APB2LPENR, RCC_APB2LPENR_UART9LPEN },
0227 #else
0228   [STM32H7_MODULE_UART9] = { NULL, 0 },
0229 #endif
0230 #ifdef USART10_BASE
0231   [STM32H7_MODULE_USART10] = { &RCC->APB2LPENR, RCC_APB2LPENR_USART10LPEN },
0232 #else
0233   [STM32H7_MODULE_USART10] = { NULL, 0 },
0234 #endif
0235   [STM32H7_MODULE_RNG] = { &RCC->AHB2LPENR, RCC_AHB2LPENR_RNGLPEN },
0236 #ifdef RCC_AHB1LPENR_ETH1MACLPEN
0237   [STM32H7_MODULE_ETH1MAC] = { &RCC->AHB1LPENR, RCC_AHB1LPENR_ETH1MACLPEN },
0238 #endif
0239 #ifdef RCC_AHB1LPENR_ETH1TXLPEN
0240   [STM32H7_MODULE_ETH1TX] = { &RCC->AHB1LPENR, RCC_AHB1LPENR_ETH1TXLPEN },
0241 #endif
0242 #ifdef RCC_AHB1LPENR_ETH1RXLPEN
0243   [STM32H7_MODULE_ETH1RX] = { &RCC->AHB1LPENR, RCC_AHB1LPENR_ETH1RXLPEN },
0244 #endif
0245   [STM32H7_MODULE_USB1_OTG] = { &RCC->AHB1LPENR, RCC_AHB1LPENR_USB1OTGHSLPEN },
0246   [STM32H7_MODULE_USB1_OTG_ULPI] = { &RCC->AHB1LPENR, RCC_AHB1LPENR_USB1OTGHSULPILPEN },
0247 #ifdef RCC_AHB1LPENR_USB2OTGHSLPEN
0248   [STM32H7_MODULE_USB2_OTG] = { &RCC->AHB1LPENR, RCC_AHB1LPENR_USB2OTGHSLPEN },
0249 #endif
0250 #ifdef RCC_AHB1LPENR_USB2OTGHSULPILPEN
0251   [STM32H7_MODULE_USB2_OTG_ULPI] = { &RCC->AHB1LPENR, RCC_AHB1LPENR_USB2OTGHSULPILPEN },
0252 #endif
0253   [STM32H7_MODULE_SDMMC1] = { &RCC->AHB3LPENR, RCC_AHB3LPENR_SDMMC1LPEN },
0254   [STM32H7_MODULE_SDMMC2] = { &RCC->AHB2LPENR, RCC_AHB2LPENR_SDMMC2LPEN },
0255   [STM32H7_MODULE_SPI1] = { &RCC->APB2LPENR, RCC_APB2LPENR_SPI1LPEN },
0256   [STM32H7_MODULE_SPI2] = { &RCC->APB1LLPENR, RCC_APB1LLPENR_SPI2LPEN },
0257   [STM32H7_MODULE_SPI3] = { &RCC->APB1LLPENR, RCC_APB1LLPENR_SPI3LPEN },
0258   [STM32H7_MODULE_SPI4] = { &RCC->APB2LPENR, RCC_APB2LPENR_SPI4LPEN },
0259   [STM32H7_MODULE_SPI5] = { &RCC->APB2LPENR, RCC_APB2LPENR_SPI5LPEN },
0260   [STM32H7_MODULE_SPI6] = { &RCC->APB4LPENR, RCC_APB4LPENR_SPI6LPEN },
0261 };
0262 
0263 void stm32h7_clk_low_power_enable(stm32h7_module_index index)
0264 {
0265   __IO uint32_t *enr;
0266   uint32_t enable_bit;
0267   rtems_interrupt_level level;
0268 
0269   enr = stm32h7_clk_low_power[index].enr;
0270   enable_bit = stm32h7_clk_low_power[index].enable_bit;
0271 
0272   rtems_interrupt_disable(level);
0273   SET_BIT(*enr, enable_bit);
0274   /* Delay after an RCC peripheral clock enabling */
0275   *enr;
0276   rtems_interrupt_enable(level);
0277 }
0278 
0279 void stm32h7_clk_low_power_disable(stm32h7_module_index index)
0280 {
0281   __IO uint32_t *enr;
0282   uint32_t enable_bit;
0283   rtems_interrupt_level level;
0284 
0285   enr = stm32h7_clk_low_power[index].enr;
0286   enable_bit = stm32h7_clk_low_power[index].enable_bit;
0287 
0288   rtems_interrupt_disable(level);
0289   CLEAR_BIT(*enr, enable_bit);
0290   rtems_interrupt_enable(level);
0291 }
0292 
0293 void stm32h7_gpio_init(const stm32h7_gpio_config *config)
0294 {
0295   stm32h7_module_index index;
0296 
0297   index = stm32h7_get_module_index(config->regs);
0298   stm32h7_clk_enable(index);
0299   HAL_GPIO_Init(config->regs, RTEMS_DECONST( GPIO_InitTypeDef *, &config->config ));
0300 }
0301 
0302 void stm32h7_uart_polled_write(rtems_termios_device_context *base, char c)
0303 {
0304   stm32h7_uart_context *ctx;
0305   USART_TypeDef *regs;
0306 
0307   ctx = stm32h7_uart_get_context(base);
0308   regs = ctx->uart.Instance;
0309 
0310   while ((regs->ISR & USART_ISR_TXE_TXFNF) == 0) {
0311     /* Wait */
0312   }
0313 
0314   regs->TDR = (uint8_t) c;
0315 }
0316 
0317 int stm32h7_uart_polled_read(rtems_termios_device_context *base)
0318 {
0319   stm32h7_uart_context *ctx;
0320   USART_TypeDef *regs;
0321 
0322   ctx = stm32h7_uart_get_context(base);
0323   regs = ctx->uart.Instance;
0324 
0325   if ((regs->ISR & USART_ISR_RXNE_RXFNE) == 0) {
0326     return -1;
0327   }
0328 
0329   return (uint8_t) regs->RDR;
0330 }