/* stm32h7.h * * Copyright (C) 2021 wolfSSL Inc. * * This file is part of wolfBoot. * * wolfBoot is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * wolfBoot is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ #ifndef HAL_STM32H7_H #define HAL_STM32H7_H #include #include "image.h" #include "hal.h" /* Assembly helpers */ #define DMB() __asm__ volatile ("dmb") #define ISB() __asm__ volatile ("isb") #define DSB() __asm__ volatile ("dsb") /* STM32 H7 register configuration */ /*** RCC ***/ #define RCC_BASE (0x58024400) /* RM0433 - Table 8 */ #define RCC_CR (*(volatile uint32_t *)(RCC_BASE + 0x00)) /* RM0433 - 7.7.2 */ #define RCC_PLLCKSELR (*(volatile uint32_t *)(RCC_BASE + 0x28)) /* RM0433 - 7.7.11 */ #define RCC_PLLCFGR (*(volatile uint32_t *)(RCC_BASE + 0x2C)) /* RM0433 - 7.7.12 */ #define RCC_PLL1DIVR (*(volatile uint32_t *)(RCC_BASE + 0x30)) /* RM0433 - 7.7.13 */ #define RCC_CFGR (*(volatile uint32_t *)(RCC_BASE + 0x10)) /* RM0433 - 7.7.7 */ #define RCC_D1CFGR (*(volatile uint32_t *)(RCC_BASE + 0x18)) /* RM0433 - 7.7.8 */ #define RCC_D2CFGR (*(volatile uint32_t *)(RCC_BASE + 0x1C)) /* RM0433 - 7.7.8 */ #define RCC_D3CFGR (*(volatile uint32_t *)(RCC_BASE + 0x20)) /* RM0433 - 7.7.9 */ #define RCC_D2CCIP2R (*(volatile uint32_t *)(RCC_BASE + 0x54)) /* RM0433 - 8.7.21 */ #define APB1_CLOCK_LRST (*(volatile uint32_t *)(RCC_BASE + 0x90)) /* RM0433 - 8.7.33 - RCC_APB1LRSTR */ #define AHB4_CLOCK_ENR (*(volatile uint32_t *)(RCC_BASE + 0xE0)) /* RM0433 - 8.7.43 */ #define APB1_CLOCK_LER (*(volatile uint32_t *)(RCC_BASE + 0xE8)) /* RM0433 - 8.7.45 - RCC_APB1LENR */ #define APB1_CLOCK_HER (*(volatile uint32_t *)(RCC_BASE + 0xEC)) /* RM0433 - 8.7.46 */ #define APB2_CLOCK_ER (*(volatile uint32_t *)(RCC_BASE + 0xF0)) /* RM0433 - 8.7.47 */ #define AHB3_CLOCK_ER (*(volatile uint32_t *)(RCC_BASE + 0xD4)) /* RM0433 - 8.7.40 */ #define RCC_CR_PLL1RDY (1 << 25) #define RCC_CR_PLL1ON (1 << 24) #define RCC_CR_HSEBYP (1 << 18) #define RCC_CR_HSERDY (1 << 17) #define RCC_CR_HSEON (1 << 16) #define RCC_CR_HSIRDY (1 << 2) #define RCC_CR_HSION (1 << 0) #define RCC_CFGR_SW_HSISYS 0x0 #define RCC_CFGR_SW_PLL 0x3 #define RCC_PLLCFGR_DIVR1EN (1 << 18) #define RCC_PLLCFGR_DIVQ1EN (1 << 17) #define RCC_PLLCFGR_DIVP1EN (1 << 16) #define RCC_PLLCFGR_PLL1VCOSEL (1 << 1) #define RCC_PLLCFGR_PLL1RGE_2_4 0x1 #define RCC_PLLCFGR_PLL1RGE_SHIFT 0x2 #define RCC_PLLCKSELR_DIVM1 (1 << 4) #define RCC_PLLCKSELR_PLLSRC_HSI 0x0 #define RCC_PLLCKSELR_PLLSRC_HSE 0x2 #define RCC_PLLCKSELR_DIVM1_NONE 0x1 /*** GPIO ***/ #define GPIOA_BASE (0x58020000) #define GPIOB_BASE (0x58020400) #define GPIOC_BASE (0x58020800) #define GPIOD_BASE (0x58020C00) #define GPIOE_BASE (0x58021000) #define GPIOF_BASE (0x58021400) #define GPIOG_BASE (0x58021800) #define GPIO_MODE(base) (*(volatile uint32_t *)((base) + 0x00)) #define GPIO_OTYPE(base) (*(volatile uint32_t *)((base) + 0x04)) #define GPIO_OSPD(base) (*(volatile uint32_t *)((base) + 0x08)) #define GPIO_PUPD(base) (*(volatile uint32_t *)((base) + 0x0c)) #define GPIO_ODR(base) (*(volatile uint32_t *)((base) + 0x14)) #define GPIO_BSRR(base) (*(volatile uint32_t *)((base) + 0x18)) #define GPIO_AFRL(base) (*(volatile uint32_t *)((base) + 0x20)) #define GPIO_AFRH(base) (*(volatile uint32_t *)((base) + 0x24)) /*** PWR ***/ #define PWR_BASE (0x58024800) /* RM0433 - Table 8 */ #define PWR_CSR1 (*(volatile uint32_t *)(PWR_BASE + 0x04)) /* RM0433 - 5.8.x */ #define PWR_CSR1_ACTVOSRDY (1 << 13) #define PWR_CR3 (*(volatile uint32_t *)(PWR_BASE + 0x0C)) /* RM0433 - 5.8.4 */ #define PWR_CR3_SCUEN (1 << 2) #define PWR_CR3_LDOEN (1 << 1) #define PWR_D3CR (*(volatile uint32_t *)(PWR_BASE + 0x18)) /* RM0433 - 5.8.6 */ #define PWR_D3CR_VOSRDY (1 << 13) #define PWR_D3CR_VOS_SHIFT (14) #define PWR_D3CR_VOS_SCALE_1 (3) #define SYSCFG_BASE (0x58000400) /* RM0433 - Table 8 */ #define SYSCFG_PMCR (*(volatile uint32_t *)(SYSCFG_BASE + 0x04)) /* RM0433 - 5.8.4 */ #define SYSCFG_PWRCR (*(volatile uint32_t *)(SYSCFG_BASE + 0x04)) /* RM0433 - 5.8.4 */ #define SYSCFG_UR0 (*(volatile uint32_t *)(SYSCFG_BASE + 0x300)) /* RM0433 - 12.3.1.2 */ #define SYSCFG_PWRCR_ODEN (1 << 0) #define SYSCFG_UR0_BKS (1 << 0) /* bank swap */ /*** APB PRESCALER ***/ #define RCC_PRESCALER_DIV_NONE 0 #define RCC_PRESCALER_DIV_2 8 /*** UART ***/ #ifndef CLOCK_SPEED #define CLOCK_SPEED 64000000UL /* 120MHz pclk1, 64MHz HSI */ #endif #ifndef BAUD_RATE #define BAUD_RATE 115200 #endif #ifndef UART_PORT #define UART_PORT 3 /* default to Nucleo VCOM port */ #endif #if UART_PORT == 3 /* USART3 Base address (connected to ST virtual com port on Nucleo board) */ #define UART_BASE (0x40004800) #define UART_GPIO_BASE GPIOD_BASE #define UART_TX_PIN 8 /* PD8, USART Transmit pin */ #define UART_RX_PIN 9 /* PD9, USART Receive pin */ #define UART_PIN_AF 7 /* AF stands for Alternate Function. USART TX/RX */ #elif UART_PORT == 5 /* USART5 Base address */ #define UART_BASE (0x40005000) #define UART_GPIO_BASE GPIOB_BASE #define UART_TX_PIN 13 /* PB13, USART Transmit pin */ #define UART_RX_PIN 12 /* PB12, USART Receive pin */ #define UART_PIN_AF 14 /* AF stands for Alternate Function. USART TX/RX */ #else /* USART2 Base address (chosen because of its pin layout on Nucleo board) */ #define UART_BASE (0x40004400) #define UART_GPIO_BASE GPIOD_BASE #define UART_TX_PIN 5 /* PD5, USART Transmit pin */ #define UART_RX_PIN 6 /* PD6, USART Receive pin */ #define UART_PIN_AF 7 /* AF stands for Alternate Function. USART TX/RX */ #endif /* UART/USART: Defining register start addresses. */ #define UART_CR1(base) (*(volatile uint32_t *)((base) + 0x00)) #define UART_CR2(base) (*(volatile uint32_t *)((base) + 0x04)) #define UART_CR3(base) (*(volatile uint32_t *)((base) + 0x08)) #define UART_BRR(base) (*(volatile uint32_t *)((base) + 0x0C)) #define UART_RQR(base) (*(volatile uint32_t *)((base) + 0x18)) #define UART_ISR(base) (*(volatile uint32_t *)((base) + 0x1C)) #define UART_ICR(base) (*(volatile uint32_t *)((base) + 0x20)) #define UART_RDR(base) (*(volatile uint32_t *)((base) + 0x24)) #define UART_TDR(base) (*(volatile uint32_t *)((base) + 0x28)) #define UART_PRESC(base) (*(volatile uint32_t *)((base) + 0x2C)) /* UART/USART: Defining register bit placement for CR1 and ISR register for readability. */ #define UART_CR1_UART_ENABLE (1 << 0) #define UART_CR1_TX_ENABLE (1 << 3) #define UART_CR1_RX_ENABLE (1 << 2) #define UART_CR1_M1 (1 << 28) #define UART_CR1_M0 (1 << 12) #define UART_CR1_PARITY_ENABLED (1 << 10) #define UART_CR1_PARITY_ODD (1 << 9) #define UART_CR1_FIFOEN (1 << 29) #define UART_CR1_OVER8 (1 << 15) #define UART_CR2_STOP_MASK (0x3 << 12) #define UART_CR2_STOP(bits) (((bits) & 0x3) << 12) #define UART_CR2_LINEN (1 << 14) #define UART_CR2_CLKEN (1 << 11) #define UART_CR3_SCEN (1 << 5) #define UART_CR3_HDSEL (1 << 3) #define UART_CR3_IREN (1 << 1) #define UART_ISR_TX_FIFO_NOT_FULL (1 << 7) /* Transmit Data Empty (TXE) or TX FIFO Not Full (TXFNF) */ #define UART_ISR_RX_FIFO_NOT_EMPTY (1 << 5) #define UART_ISR_TRANSMISSION_COMPLETE (1 << 6) /* RCC: Defining register bit placement for APB1, APB2, AHB1 and AHB4 register for readability. */ #define RCC_APB1_USART2_EN (1 << 17) #define RCC_APB1_USART3_EN (1 << 18) #define RCC_APB1_UART4_EN (1 << 19) #define RCC_APB1_UART5_EN (1 << 20) #define RCC_APB1_UART7_EN (1 << 30) #define RCC_APB1_UART8_EN (1 << 31) #define RCC_APB2_USART1_EN (1 << 4) #define RCC_APB2_USART6_EN (1 << 5) #define RCC_AHB4_GPIOB_EN (1 << 1) #define RCC_AHB4_GPIOD_EN (1 << 3) /*** QSPI ***/ /* See hal/spi/spi_drv_stm32.c */ /*** FLASH ***/ #define SYSCFG_APB4_CLOCK_ER_VAL (1 << 0) /* RM0433 - 7.7.48 - RCC_APB4ENR - SYSCFGEN */ #define FLASH_BASE (0x52002000) /* RM0433 - Table 8 */ #define FLASH_ACR (*(volatile uint32_t *)(FLASH_BASE + 0x00)) /* RM0433 - 3.9.1 - FLASH_ACR */ #define FLASH_OPTKEYR (*(volatile uint32_t *)(FLASH_BASE + 0x08)) /* FLASH option key register */ #define FLASH_OPTCR (*(volatile uint32_t *)(FLASH_BASE + 0x18)) /* FLASH option control register */ #define FLASH_OPTSR_CUR (*(volatile uint32_t *)(FLASH_BASE + 0x1C)) /* FLASH option status register */ /* Bank 1 */ #define FLASH_KEYR1 (*(volatile uint32_t *)(FLASH_BASE + 0x04)) /* RM0433 - 3.9.2 - FLASH_KEYR 1 */ #define FLASH_CR1 (*(volatile uint32_t *)(FLASH_BASE + 0x0C)) /* RM0433 - 3.9.4 - FLASH_CR 1 */ #define FLASH_SR1 (*(volatile uint32_t *)(FLASH_BASE + 0x10)) /* RM0433 - 3.9.5 - FLASH_SR 1 */ /* Bank 2 */ #define FLASH_KEYR2 (*(volatile uint32_t *)(FLASH_BASE + 0x104)) /* RM0433 - 3.9.24 - FLASH_KEYR 2 */ #define FLASH_SR2 (*(volatile uint32_t *)(FLASH_BASE + 0x110)) /* RM0433 - 3.9.26 - FLASH_SR 2 */ #define FLASH_CR2 (*(volatile uint32_t *)(FLASH_BASE + 0x10C)) /* RM0433 - 3.9.25 - FLASH_CR 2 */ /* Flash Configuration */ #define FLASHMEM_ADDRESS_SPACE (0x08000000UL) #define FLASH_PAGE_SIZE (0x20000) /* 128KB */ #define FLASH_BANK2_BASE (0x08100000UL) /*!< Base address of : (up to 1 MB) Flash Bank2 accessible over AXI */ #define FLASH_BANK2_BASE_REL (FLASH_BANK2_BASE - FLASHMEM_ADDRESS_SPACE) #define FLASH_TOP (0x081FFFFFUL) /*!< FLASH end address */ /* Register values */ #define FLASH_ACR_LATENCY_MASK (0x07) #define FLASH_SR_BSY (1 << 0) #define FLASH_SR_WBNE (1 << 1) #define FLASH_SR_QW (1 << 2) #define FLASH_SR_WRPERR (1 << 17) #define FLASH_SR_PGSERR (1 << 18) #define FLASH_SR_STRBERR (1 << 19) #define FLASH_SR_INCERR (1 << 21) #define FLASH_SR_OPERR (1 << 22) #define FLASH_SR_RDPERR (1 << 23) #define FLASH_SR_RDSERR (1 << 24) #define FLASH_SR_SNECCERR (1 << 25) #define FLASH_SR_DBECCERR (1 << 26) #define FLASH_SR_EOP (1 << 16) #define FLASH_CR_LOCK (1 << 0) /* RM0433 - 3.7.5 - FLASH_CR */ #define FLASH_CR_STRT (1 << 7) #define FLASH_CR_PSIZE (1 << 4) #define FLASH_CR_BER (1 << 3) #define FLASH_CR_SER (1 << 2) #define FLASH_CR_PG (1 << 1) #define FLASH_CR2_SPSS2 (1 << 14) #define FLASH_OPTSR_CUR_BSY (1 << 0) #define FLASH_OPTCR_OPTLOCK (1 << 0) /* lock option configuration bit */ #define FLASH_OPTCR_OPTSTART (1 << 1) /* Option byte start change option configuration bit */ #define FLASH_OPTCR_MER (1 << 4) /* Mass erase request */ #define FLASH_OPTCR_PG_OTP (1 << 5) /* OTP program control bit */ #define FLASH_OPTCR_OPTCHANGEERRIE (1 << 30) /* Option byte change error interrupt enable bit */ #define FLASH_OPTCR_SWAP_BANK (1 << 31) /* Bank swapping option configuration bit */ #define FLASH_CR_SNB_SHIFT 8 /* SNB bits 10:8 */ #define FLASH_CR_SNB_MASK 0x7 /* SNB bits 10:8 - 3 bits */ #define FLASH_KEY1 (0x45670123U) #define FLASH_KEY2 (0xCDEF89ABU) #define FLASH_OPT_KEY1 (0x08192A3BU) #define FLASH_OPT_KEY2 (0x4C5D6E7FU) /* OTP FLASH AREA */ #define FLASH_OTP_BASE 0x08FFF000 #define FLASH_OTP_END 0x08FFF3FF #define OTP_SIZE 1024 #define OTP_BLOCKS 16 /* STM32H7: Due to ECC functionality, it is not possible to write partition/sector * flags and signature more than once. This flags_cache is used to intercept write operations and * ensures that the sector is always erased before each write. */ #define STM32H7_SECTOR_SIZE 0x20000 #if defined(WOLFBOOT_PARTITION_SIZE) && \ (WOLFBOOT_PARTITION_SIZE < (2 * STM32H7_SECTOR_SIZE)) # error "Please use a bigger WOLFBOOT_PARTITION_SIZE, since the last 128KB on each partition will be reserved for bootloader flags" #endif #define STM32H7_PART_BOOT_END (WOLFBOOT_PARTITION_BOOT_ADDRESS + WOLFBOOT_PARTITION_SIZE) #define STM32H7_PART_UPDATE_END (WOLFBOOT_PARTITION_UPDATE_ADDRESS + WOLFBOOT_PARTITION_SIZE) #define STM32H7_WORD_SIZE (32) #define STM32H7_PART_BOOT_FLAGS_PAGE_ADDRESS \ (((STM32H7_PART_BOOT_END - 1) / STM32H7_SECTOR_SIZE) * STM32H7_SECTOR_SIZE) #define STM32H7_PART_UPDATE_FLAGS_PAGE_ADDRESS \ (((STM32H7_PART_UPDATE_END - 1) / STM32H7_SECTOR_SIZE) * STM32H7_SECTOR_SIZE) #define STM32H7_BOOT_FLAGS_PAGE(x) \ ((x >= STM32H7_PART_BOOT_FLAGS_PAGE_ADDRESS) && (x < STM32H7_PART_BOOT_END)) #define STM32H7_UPDATE_FLAGS_PAGE(x) \ ((x >= STM32H7_PART_UPDATE_FLAGS_PAGE_ADDRESS) && (x < STM32H7_PART_UPDATE_END)) #endif /* HAL_STM32H7_H */