From 8dd0ee347fdd5c343335c561a89045718f757cad Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 17 Jan 2023 12:32:46 -0800 Subject: [PATCH] Support for the STM32 OCTOSPI peripheral. --- .github/workflows/test-configs.yml | 6 ++ Makefile | 2 +- arch.mk | 21 +++- config/examples/stm32h7-octospi.config | 25 +++++ config/examples/stm32h7.config | 2 +- hal/spi/spi_drv_stm32.c | 139 +++++++++++++++++++++--- hal/spi/spi_drv_stm32.h | 144 ++++++++++++++++++++----- include/hal.h | 2 +- include/spi_drv.h | 9 +- include/spi_flash.h | 4 +- options.mk | 8 ++ src/qspi_flash.c | 6 +- test-app/Makefile | 5 + tools/config.mk | 4 +- 14 files changed, 319 insertions(+), 58 deletions(-) create mode 100644 config/examples/stm32h7-octospi.config diff --git a/.github/workflows/test-configs.yml b/.github/workflows/test-configs.yml index 43a472b9..50589f55 100644 --- a/.github/workflows/test-configs.yml +++ b/.github/workflows/test-configs.yml @@ -125,6 +125,12 @@ jobs: config-file: ./config/examples/stm32h7.config make-args: QSPI_FLASH=1 + stm32h7_octospi_test: + uses: ./.github/workflows/test-build.yml + with: + arch: arm + config-file: ./config/examples/stm32h7-octospi.config + stm32l0_test: uses: ./.github/workflows/test-build.yml with: diff --git a/Makefile b/Makefile index 3a3f97ae..1c6f19dd 100644 --- a/Makefile +++ b/Makefile @@ -119,7 +119,7 @@ test-app/image.bin: wolfboot.elf $(Q)$(SIZE) test-app/image.elf standalone: - $(Q)$(MAKE) -C test-app TARGET=$(TARGET) EXT_FLASH=$(EXT_FLASH) SPI_FLASH=$(SPI_FLASH) QSPI_FLASH=$(QSPI_FLASH) ARCH=$(ARCH) \ + $(Q)$(MAKE) -C test-app TARGET=$(TARGET) EXT_FLASH=$(EXT_FLASH) SPI_FLASH=$(SPI_FLASH) QSPI_FLASH=$(QSPI_FLASH) OCTOSPI_FLASH=$(OCTOSPI_FLASH) ARCH=$(ARCH) \ NO_XIP=$(NO_XIP) V=$(V) RAM_CODE=$(RAM_CODE) WOLFBOOT_VERSION=$(WOLFBOOT_VERSION)\ MCUXPRESSO=$(MCUXPRESSO) MCUXPRESSO_CPU=$(MCUXPRESSO_CPU) MCUXPRESSO_DRIVERS=$(MCUXPRESSO_DRIVERS) \ MCUXPRESSO_CMSIS=$(MCUXPRESSO_CMSIS) NVM_FLASH_WRITEONCE=$(NVM_FLASH_WRITEONCE) \ diff --git a/arch.mk b/arch.mk index ef24151b..1003b7fc 100644 --- a/arch.mk +++ b/arch.mk @@ -82,11 +82,13 @@ ifeq ($(ARCH),ARM) endif ifeq ($(TARGET),stm32f7) + CORTEX_M7=1 ARCH_FLASH_OFFSET=0x08000000 SPI_TARGET=stm32 endif ifeq ($(TARGET),stm32h7) + CORTEX_M7=1 ARCH_FLASH_OFFSET=0x08000000 SPI_TARGET=stm32 endif @@ -107,7 +109,7 @@ ifeq ($(ARCH),ARM) ifeq ($(TARGET),stm32l5) CORTEX_M33=1 - CFLAGS+=-Ihal -DCORTEX_M33 + CFLAGS+=-Ihal ARCH_FLASH_OFFSET=0x08000000 ifeq ($(TZEN),1) WOLFBOOT_ORIGIN=0x0C000000 @@ -118,7 +120,7 @@ ifeq ($(ARCH),ARM) ifeq ($(TARGET),stm32u5) CORTEX_M33=1 - CFLAGS+=-Ihal -DCORTEX_M33 + CFLAGS+=-Ihal ARCH_FLASH_OFFSET=0x08000000 ifeq ($(TZEN),1) WOLFBOOT_ORIGIN=0x0C000000 @@ -130,7 +132,7 @@ ifeq ($(ARCH),ARM) ## Cortex-M CPU ifeq ($(CORTEX_M33),1) - CFLAGS+=-mcpu=cortex-m33 + CFLAGS+=-mcpu=cortex-m33 -DCORTEX_M33 LDFLAGS+=-mcpu=cortex-m33 ifeq ($(TZEN),1) CFLAGS += -mcmse @@ -139,6 +141,18 @@ ifeq ($(ARCH),ARM) MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o endif else + ifeq ($(CORTEX_M7),1) + CFLAGS+=-mcpu=cortex-m7 + LDFLAGS+=-mcpu=cortex-m7 + ifeq ($(SPMATH),1) + ifeq ($(NO_ASM),1) + MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o + else + CFLAGS+=-DWOLFSSL_SP_ASM -DWOLFSSL_SP_ARM_CORTEX_M_ASM + MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_cortexm.o + endif + endif + else ifeq ($(CORTEX_M0),1) CFLAGS+=-mcpu=cortex-m0 LDFLAGS+=-mcpu=cortex-m0 @@ -168,6 +182,7 @@ ifeq ($(ARCH),ARM) endif endif endif +endif ifeq ($(TZEN),1) CFLAGS+=-DTZEN diff --git a/config/examples/stm32h7-octospi.config b/config/examples/stm32h7-octospi.config new file mode 100644 index 00000000..4ba8a744 --- /dev/null +++ b/config/examples/stm32h7-octospi.config @@ -0,0 +1,25 @@ +ARCH?=ARM +TARGET?=stm32h7 +SIGN?=ECC256 +HASH?=SHA256 +DEBUG?=1 +DEBUG_UART?=1 +VTOR?=1 +NO_ASM?=0 +EXT_FLASH?=1 +SPI_FLASH?=0 +QSPI_FLASH?=1 +OCTOSPI_FLASH?=1 +ALLOW_DOWNGRADE?=0 +NVM_FLASH_WRITEONCE?=0 +WOLFBOOT_VERSION?=1 +V?=0 +SPMATH?=1 +RAM_CODE?=0 +DUALBANK_SWAP?=0 +WOLFBOOT_PARTITION_SIZE?=0xD0000 +WOLFBOOT_SECTOR_SIZE?=0x20000 +WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x8020000 +WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x80F0000 +WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x81C0000 +CFLAGS_EXTRA=-DQSPI_ALT_CONFIGURATION diff --git a/config/examples/stm32h7.config b/config/examples/stm32h7.config index 09759f27..e2a1f3cb 100644 --- a/config/examples/stm32h7.config +++ b/config/examples/stm32h7.config @@ -5,11 +5,11 @@ HASH?=SHA256 DEBUG?=0 DEBUG_UART?=0 VTOR?=1 -CORTEX_M0?=0 NO_ASM?=0 EXT_FLASH?=0 SPI_FLASH?=0 QSPI_FLASH?=0 +OCTOSPI_FLASH?=0 ALLOW_DOWNGRADE?=0 NVM_FLASH_WRITEONCE?=0 WOLFBOOT_VERSION?=1 diff --git a/hal/spi/spi_drv_stm32.c b/hal/spi/spi_drv_stm32.c index 0c693e13..9516deb0 100644 --- a/hal/spi/spi_drv_stm32.c +++ b/hal/spi/spi_drv_stm32.c @@ -29,7 +29,8 @@ #include "spi_drv.h" #include "spi_drv_stm32.h" -#if defined(SPI_FLASH) || defined(WOLFBOOT_TPM) || defined(QSPI_FLASH) +#if defined(SPI_FLASH) || defined(WOLFBOOT_TPM) || defined(QSPI_FLASH) || \ + defined(OCTOSPI_FLASH) void RAMFUNCTION stm_gpio_config(uint32_t base, uint32_t pin, uint32_t mode, uint32_t af, uint32_t pull, uint32_t speed) @@ -148,7 +149,7 @@ static void RAMFUNCTION stm_pins_setup(void) SPI_MISO_PIN_AF, 1, 0); #endif #endif -#ifdef QSPI_FLASH +#if defined(QSPI_FLASH) || defined(OCTOSPI_FLASH) stm_gpio_config(QSPI_CS_PIO_BASE, QSPI_CS_FLASH_PIN, GPIO_MODE_AF, QSPI_CS_FLASH_AF, 1, 3); stm_gpio_config(QSPI_CLOCK_PIO_BASE, QSPI_CLOCK_PIN, GPIO_MODE_AF, @@ -171,7 +172,7 @@ static void stm_pins_release(void) stm_gpio_config(SPI_MOSI_PIO_BASE, SPI_MOSI_PIN, GPIO_MODE_INPUT, 0, 0, 0); stm_gpio_config(SPI_MISO_PIO_BASE, SPI_MISO_PIN, GPIO_MODE_INPUT, 0, 0, 0); #endif -#ifdef QSPI_FLASH +#if defined(QSPI_FLASH) || defined(OCTOSPI_FLASH) stm_gpio_config(QSPI_CS_PIO_BASE, QSPI_CS_FLASH_PIN, GPIO_MODE_INPUT, 0, 0, 0); stm_gpio_config(QSPI_CLOCK_PIO_BASE, QSPI_CLOCK_PIN, GPIO_MODE_INPUT, 0, 0, 0); stm_gpio_config(QSPI_IO0_PIO_BASE, QSPI_IO0_PIN, GPIO_MODE_INPUT, 0, 0, 0); @@ -183,7 +184,7 @@ static void stm_pins_release(void) static void RAMFUNCTION spi_reset(void) { -#ifdef QSPI_FLASH +#if defined(QSPI_FLASH) || defined(OCTOSPI_FLASH) AHB3_CLOCK_RST |= RCC_AHB3ENR_QSPIEN; AHB3_CLOCK_RST &= ~RCC_AHB3ENR_QSPIEN; #endif @@ -193,7 +194,89 @@ static void RAMFUNCTION spi_reset(void) #endif } -#ifdef QSPI_FLASH +#ifdef OCTOSPI_FLASH +int qspi_transfer(uint8_t fmode, const uint8_t cmd, + uint32_t addr, uint32_t addrSz, uint32_t addrMode, + uint32_t alt, uint32_t altSz, uint32_t altMode, + uint32_t dummySz, + uint8_t* data, uint32_t dataSz, uint32_t dataMode) +{ + uint32_t adsz = 0, absz = 0; + + if (addrSz > 0) { + adsz = addrSz-1; + } + if (altSz > 0) { + absz = altSz-1; + } + + /* Enable the QSPI peripheral */ + OCTOSPI_CR &= ~(OCTOSPI_CR_EN | OCTOSPI_CR_FMODE_MASK); + OCTOSPI_CR |= OCTOSPI_CR_EN | OCTOSPI_CR_FMODE(fmode); + + if (dataSz > 0) { + OCTOSPI_DLR = dataSz-1; + } + + /* Configure QSPI: CCR register with all communications parameters */ + /* mode 1=1SPI, 2=2SPI, 3=4SPI, 4=8SPI */ + OCTOSPI_CCR = ( + OCTOSPI_CCR_IMODE(1) | /* Instruction Mode - always single SPI */ + OCTOSPI_CCR_ADMODE(addrMode) | /* Address Mode */ + OCTOSPI_CCR_ADSIZE(adsz) | /* Address Size */ + OCTOSPI_CCR_ABMODE(altMode) | /* Alternate byte mode */ + OCTOSPI_CCR_ABSIZE(absz ) | /* Alternate byte size */ + OCTOSPI_CCR_DMODE(dataMode) /* Data Mode */ + ); + OCTOSPI_TCR = OCTOSPI_TCR_DCYC(dummySz); /* Dummy Cycles (between instruction and read) */ + OCTOSPI_IR = cmd; + + /* Set optional alternate bytes */ + if (altSz > 0) { + OCTOSPI_ABR = alt; + } + + /* Set command address 4 or 3 byte */ + OCTOSPI_AR = addr; + + /* Fill data 32-bits at a time */ + while (dataSz >= 4U) { + if (fmode == 0) { + while ((OCTOSPI_SR & OCTOSPI_SR_FTF) == 0); + OCTOSPI_DR32 = *(uint32_t*)data; + } + else { + while ((OCTOSPI_SR & (OCTOSPI_SR_FTF | OCTOSPI_SR_TCF)) == 0); + *(uint32_t*)data = OCTOSPI_DR32; + } + dataSz -= 4; + data += 4; + } + + /* Fill remainder bytes */ + while (dataSz > 0U) { + if (fmode == 0) { + while ((OCTOSPI_SR & OCTOSPI_SR_FTF) == 0); + OCTOSPI_DR = *data; + } + else { + while ((OCTOSPI_SR & (OCTOSPI_SR_FTF | OCTOSPI_SR_TCF)) == 0); + *data = OCTOSPI_DR; + } + dataSz--; + data++; + } + + /* wait for transfer complete */ + while ((OCTOSPI_SR & OCTOSPI_SR_TCF) == 0); + OCTOSPI_FCR |= OCTOSPI_SR_TCF; /* clear transfer complete */ + + /* Disable QSPI */ + OCTOSPI_CR &= ~OCTOSPI_CR_EN; + + return 0; +} +#elif defined(QSPI_FLASH) int qspi_transfer(uint8_t fmode, const uint8_t cmd, uint32_t addr, uint32_t addrSz, uint32_t addrMode, uint32_t alt, uint32_t altSz, uint32_t altMode, @@ -232,7 +315,7 @@ int qspi_transfer(uint8_t fmode, const uint8_t cmd, /* Set optional alternate bytes */ if (altSz > 0) { - QUADSPI_ABR = alt; + QUADSPI_ABR= alt; } /* Set command address 4 or 3 byte */ @@ -277,7 +360,6 @@ int qspi_transfer(uint8_t fmode, const uint8_t cmd, } #endif /* QSPI_FLASH */ - #if defined(SPI_FLASH) || defined(WOLFBOOT_TPM) uint8_t RAMFUNCTION spi_read(void) { @@ -309,7 +391,7 @@ void RAMFUNCTION spi_init(int polarity, int phase) initialized++; /* Setup clocks */ -#ifdef QSPI_FLASH +#if defined(QSPI_FLASH) || defined(OCTOSPI_FLASH) /* Select QUADSPI clock source */ RCC_D1CCIPR &= ~RCC_D1CCIPR_QSPISEL_MASK; RCC_D1CCIPR |= RCC_D1CCIPR_QSPISEL(QSPI_CLOCK_SEL); @@ -337,9 +419,35 @@ void RAMFUNCTION spi_init(int polarity, int phase) spi_cs_off(SPI_CS_TPM_PIO_BASE, SPI_CS_TPM); #endif +#ifdef OCTOSPI_FLASH + /* STM32 OCTOSPI Peripheral */ + /* Configure OCTOSPI FIFO Threshold (4 bytes) */ + OCTOSPI_CR &= ~OCTOSPI_CR_FTHRES_MASK; + OCTOSPI_CR |= OCTOSPI_CR_FTHRES(4); -#ifdef QSPI_FLASH - /* Configure QSPI FIFO Threshold (1 byte) */ + /* Wait till BUSY flag cleared */ + while (OCTOSPI_SR & OCTOSPI_SR_BUSY) {}; + + /* Configure OCTOSPI Clock Prescaler (64/X), Flash ID 2 (IO4-7) + * Sample Shift=None */ + OCTOSPI_DCR2 &= ~OCTOSPI_DCR2_PRESCALER_MASK; + OCTOSPI_DCR2 |= OCTOSPI_DCR2_PRESCALER((QSPI_CLOCK_BASE/QSPI_CLOCK_MHZ)); + OCTOSPI_CR &= ~OCTOSPI_CR_FSEL; + #if QSPI_FLASH_BANK == 2 + OCTOSPI_CR |= OCTOSPI_CR_FSEL; + #endif + OCTOSPI_TCR &= ~OCTOSPI_TCR_SSHIFT; + + /* Configure OCTOSPI Flash Size (16MB), CS High Time (1 clock) and + * Clock Mode (0) */ + OCTOSPI_DCR1 &= ~(OCTOSPI_DCR1_DEVSIZE_MASK | OCTOSPI_DCR1_CSHT_MASK | + OCTOSPI_DCR1_CKMODE_3); + OCTOSPI_DCR1 |= (OCTOSPI_DCR1_DEVSIZE(QSPI_FLASH_SIZE) | + OCTOSPI_DCR1_CSHT(0) | OCTOSPI_DCR1_CKMODE_0); + +#elif defined(QSPI_FLASH) + /* STM32 QSPI Peripheral */ + /* Configure QSPI FIFO Threshold (4 bytes) */ QUADSPI_CR &= ~QUADSPI_CR_FTHRES_MASK; QUADSPI_CR |= QUADSPI_CR_FTHRES(4); @@ -351,14 +459,17 @@ void RAMFUNCTION spi_init(int polarity, int phase) QUADSPI_CR &= ~(QUADSPI_CR_PRESCALER_MASK | QUADSPI_CR_FSEL | QUADSPI_CR_DFM | QUADSPI_CR_SSHIFT); QUADSPI_CR |= (QUADSPI_CR_PRESCALER((QSPI_CLOCK_BASE/QSPI_CLOCK_MHZ))); + #if QSPI_FLASH_BANK == 2 + QUADSPI_CR |= QUADSPI_CR_FSEL; + #endif /* Configure QSPI Flash Size (16MB), CS High Time (1 clock) and * Clock Mode (0) */ QUADSPI_DCR &= ~(QUADSPI_DCR_FSIZE_MASK | QUADSPI_DCR_CSHT_MASK | QUADSPI_DCR_CKMODE_3); - QUADSPI_DCR |= (QUADSPI_DCR_FSIZE(22) | QUADSPI_DCR_CSHT(0) | - QUADSPI_DCR_CKMODE_0); -#endif /* QSPI_FLASH */ + QUADSPI_DCR |= (QUADSPI_DCR_FSIZE(QSPI_FLASH_SIZE) | + QUADSPI_DCR_CSHT(0) | QUADSPI_DCR_CKMODE_0); +#endif #if defined(SPI_FLASH) || defined(WOLFBOOT_TPM) /* Configure SPI1 for master mode */ # ifdef PLATFORM_stm32l0 @@ -388,4 +499,4 @@ void RAMFUNCTION spi_release(void) } } -#endif /* SPI_FLASH || QSPI_FLASH || WOLFBOOT_TPM */ +#endif /* SPI_FLASH || WOLFBOOT_TPM || QSPI_FLASH || OCTOSPI_FLASH */ diff --git a/hal/spi/spi_drv_stm32.h b/hal/spi/spi_drv_stm32.h index 0c7a80f6..eb68239c 100644 --- a/hal/spi/spi_drv_stm32.h +++ b/hal/spi/spi_drv_stm32.h @@ -161,6 +161,18 @@ /* Default Base (E) and AF (alternate function=10) for QSPI */ #define QSPI_GPIO GPIOE_BASE #define QSPI_PIN_AF 10 +/* Default to flash bank 1 (2 for alt) */ +#ifndef QSPI_FLASH_BANK + #ifdef QSPI_ALT_CONFIGURATION + #define QSPI_FLASH_BANK 2 + #else + #define QSPI_FLASH_BANK 1 + #endif +#endif +/* Default flash size to 16MB */ +#ifndef QSPI_FLASH_SIZE +#define QSPI_FLASH_SIZE 23 /* 2^24 = 16 MB */ +#endif /* QSPI uses hclk3 (240MHz max) by default */ #define RCC_D1CCIPR (*(volatile uint32_t *)(RCC_BASE + 0x4C)) /* RM0433 - 8.7.19 (RCC_D1CCIPR) */ @@ -172,7 +184,7 @@ #define RCC_D1CCIPR_QSPISEL_PERCK 3 #define AHB3_CLOCK_RST (*(volatile uint32_t *)(RCC_BASE + 0x7C)) /* RM0433 - 8.7.28 - RCC_AHB3RSTR */ #define AHB3_CLOCK_EN (*(volatile uint32_t *)(RCC_BASE + 0xD4)) /* RM0433 - 8.7.40 - RCC_AHB3ENR */ -#define RCC_AHB3ENR_QSPIEN (1 << 14) /* QUADSPI and QUADSPI Delay clock enabled */ +#define RCC_AHB3ENR_QSPIEN (1 << 14) /* QUADSPI/OCTOSPI clock enabled */ #define HCLK3_MHZ 240000000 #define PERCK_MHZ 64000000 @@ -187,12 +199,12 @@ #define QSPI_CLOCK_MHZ 16000000 #endif -/* QSPI CLK PB2 */ +/* QSPI CLK PB2 (alt OCTOSPIM_P1_CLK)*/ #define QSPI_CLOCK_PIO_BASE GPIOB_BASE #define QSPI_CLOCK_PIN 2 #define QSPI_CLOCK_PIN_AF 9 -/* nQSPI_CS PG6 (alt PB6) */ +/* nQSPI_CS PG6 (alt PB6 -> OCTOSPIM_P1_NCS) */ #ifndef QSPI_ALT_CONFIGURATION #define QSPI_CS_PIO_BASE GPIOG_BASE #define QSPI_CS_FLASH_PIN 6 @@ -201,7 +213,7 @@ #define QSPI_CS_FLASH_PIN 6 #endif -/* QSPI_IO0 (MOSI) - PD11 (alt PE7) */ +/* QSPI_IO0 (MOSI) - PD11 (alt PE7 -> OCTOSPIM_P1_IO4) */ #ifndef QSPI_ALT_CONFIGURATION #define QSPI_IO0_PIO_BASE GPIOD_BASE #define QSPI_IO0_PIN 11 @@ -211,7 +223,7 @@ #define QSPI_IO0_PIN 7 #endif -/* QSPI_IO1 (MISO) - PD12 (alt PE8) */ +/* QSPI_IO1 (MISO) - PD12 (alt PE8 -> OCTOSPIM_P1_IO5) */ #ifndef QSPI_ALT_CONFIGURATION #define QSPI_IO1_PIO_BASE GPIOD_BASE #define QSPI_IO1_PIN 12 @@ -221,7 +233,7 @@ #define QSPI_IO1_PIN 8 #endif -/* QSPI_IO2 - PE2 (alt PE9) */ +/* QSPI_IO2 - PE2 (alt PE9 -> OCTOSPIM_P1_IO6) */ #ifndef QSPI_ALT_CONFIGURATION #define QSPI_IO2_PIO_BASE GPIOE_BASE #define QSPI_IO2_PIN 2 @@ -231,7 +243,7 @@ #define QSPI_IO2_PIN 9 #endif -/* QSPI_IO3 - PD13 (alt PE10) */ +/* QSPI_IO3 - PD13 (alt PE10 -> OCTOSPIM_P1_IO7) */ #ifndef QSPI_ALT_CONFIGURATION #define QSPI_IO3_PIO_BASE GPIOD_BASE #define QSPI_IO3_PIN 13 @@ -261,7 +273,7 @@ #define SPI_CS_TPM_PIO_BASE SPI_CS_GPIO #endif -#ifdef QSPI_FLASH +#if defined(QSPI_FLASH) || defined(OCTOSPI_FLASH) #ifndef QSPI_CS_PIO_BASE #define QSPI_CS_PIO_BASE QSPI_CS_GPIO #endif @@ -280,7 +292,7 @@ #ifndef QSPI_IO3_PIO_BASE #define QSPI_IO3_PIO_BASE QSPI_GPIO #endif -#endif +#endif /* QSPI_FLASH || OCTOSPI_FLASH */ /* Setup alternate functions */ #ifndef SPI_CLOCK_PIN_AF @@ -293,7 +305,7 @@ #define SPI_MOSI_PIN_AF SPI_PIN_AF #endif -#ifdef QSPI_FLASH +#if defined(QSPI_FLASH) || defined(OCTOSPI_FLASH) #ifndef QSPI_CS_FLASH_AF #define QSPI_CS_FLASH_AF QSPI_PIN_AF #endif @@ -313,7 +325,7 @@ #ifndef QSPI_IO3_PIN_AF #define QSPI_IO3_PIN_AF QSPI_PIN_AF #endif -#endif /* QSPI_FLASH */ +#endif /* QSPI_FLASH || OCTOSPI_FLASH */ /* SPI */ @@ -367,25 +379,26 @@ #ifndef QUADSPI_BASE #define QUADSPI_BASE 0x52005000UL #endif -#define QUADSPI_CR (*(volatile uint32_t *)(QUADSPI_BASE + 0x00)) /* Control register */ -#define QUADSPI_DCR (*(volatile uint32_t *)(QUADSPI_BASE + 0x04)) /* Device Configuration register */ -#define QUADSPI_SR (*(volatile uint32_t *)(QUADSPI_BASE + 0x08)) /* Status register */ -#define QUADSPI_FCR (*(volatile uint32_t *)(QUADSPI_BASE + 0x0C)) /* Flag Clear register */ -#define QUADSPI_DLR (*(volatile uint32_t *)(QUADSPI_BASE + 0x10)) /* Data Length register */ -#define QUADSPI_CCR (*(volatile uint32_t *)(QUADSPI_BASE + 0x14)) /* Communication Configuration register */ -#define QUADSPI_AR (*(volatile uint32_t *)(QUADSPI_BASE + 0x18)) /* Address register */ -#define QUADSPI_ABR (*(volatile uint32_t *)(QUADSPI_BASE + 0x1C)) /* Alternate Bytes register */ -#define QUADSPI_DR (*(volatile uint8_t *)(QUADSPI_BASE + 0x20)) /* Data register */ -#define QUADSPI_DR32 (*(volatile uint32_t *)(QUADSPI_BASE + 0x20)) /* Data register - 32 bit */ -#define QUADSPI_PSMKR (*(volatile uint32_t *)(QUADSPI_BASE + 0x24)) /* Polling Status Mask register */ -#define QUADSPI_PSMAR (*(volatile uint32_t *)(QUADSPI_BASE + 0x28)) /* Polling Status Match register */ -#define QUADSPI_PIR (*(volatile uint32_t *)(QUADSPI_BASE + 0x2C)) /* Polling Interval register */ -#define QUADSPI_LPTR (*(volatile uint32_t *)(QUADSPI_BASE + 0x30)) /* Low Power Timeout register */ + +#define QUADSPI_CR (*(volatile uint32_t *)(QUADSPI_BASE + 0x00)) /* Control register */ +#define QUADSPI_DCR (*(volatile uint32_t *)(QUADSPI_BASE + 0x04)) /* Device Configuration register */ +#define QUADSPI_SR (*(volatile uint32_t *)(QUADSPI_BASE + 0x08)) /* Status register */ +#define QUADSPI_FCR (*(volatile uint32_t *)(QUADSPI_BASE + 0x0C)) /* Flag Clear register */ +#define QUADSPI_DLR (*(volatile uint32_t *)(QUADSPI_BASE + 0x10)) /* Data Length register */ +#define QUADSPI_CCR (*(volatile uint32_t *)(QUADSPI_BASE + 0x14)) /* Communication Configuration register */ +#define QUADSPI_AR (*(volatile uint32_t *)(QUADSPI_BASE + 0x18)) /* Address register */ +#define QUADSPI_ABR (*(volatile uint32_t *)(QUADSPI_BASE + 0x1C)) /* Alternate Bytes register */ +#define QUADSPI_DR (*(volatile uint8_t *)(QUADSPI_BASE + 0x20)) /* Data register */ +#define QUADSPI_DR32 (*(volatile uint32_t *)(QUADSPI_BASE + 0x20)) /* Data register - 32 bit */ +#define QUADSPI_PSMKR (*(volatile uint32_t *)(QUADSPI_BASE + 0x24)) /* Polling Status Mask register */ +#define QUADSPI_PSMAR (*(volatile uint32_t *)(QUADSPI_BASE + 0x28)) /* Polling Status Match register */ +#define QUADSPI_PIR (*(volatile uint32_t *)(QUADSPI_BASE + 0x2C)) /* Polling Interval register */ +#define QUADSPI_LPTR (*(volatile uint32_t *)(QUADSPI_BASE + 0x30)) /* Low Power Timeout register */ #define QUADSPI_CR_PRESCALER_MASK (0xFF << 24) #define QUADSPI_CR_PRESCALER(pre) ((((pre)-1) & 0xFF) << 24) /* Clock prescaler: quadspi_ker_ck/pre+1 */ #define QUADSPI_CR_FTIE (1 << 13) /* FIFO threshold interrupt enable */ -#define QUADSPI_CR_FTHRES_MASK (0xF << 8) +#define QUADSPI_CR_FTHRES_MASK (0x1F << 8) #define QUADSPI_CR_FTHRES(thr) ((((thr)-1) & 0x1F) << 8) /* FIFO threshold level */ #define QUADSPI_CR_FSEL (1 << 7) /* 0=Flash 1 or 1=Flash 2 */ #define QUADSPI_CR_DFM (1 << 6) /* Dual-flash mode */ @@ -417,7 +430,7 @@ #define QUADSPI_CCR_INSTRUCTION(ins) (((ins) & 0xFF) << 0) /* Instruction to be send to the external SPI device */ #define QUADSPI_DCR_FSIZE_MASK (0x1F << 16) -#define QUADSPI_DCR_FSIZE(fsz) (((fsz) & 0x1F) << 16) /* Flash memory size (2 ^ (fsize + 1)). Example 16MB is 22 */ +#define QUADSPI_DCR_FSIZE(fsz) (((fsz) & 0x1F) << 16) /* Flash memory size (2 ^ (fsize + 1)). Example 16MB is 23 */ #define QUADSPI_DCR_CSHT_MASK (0x7 << 8) #define QUADSPI_DCR_CSHT(csht) (((csht) & 0x7) << 8) /* Chip select high time - Number of clock cycles (+1) nCS to remain high between commands */ #define QUADSPI_DCR_CKMODE_3 (1 << 0) /* Clock mode 3 - clk high while nCS released */ @@ -427,4 +440,81 @@ #define QUADSPI_SR_FTF (1 << 2) /* FIFO threshold flag */ #define QUADSPI_SR_BUSY (1 << 5) /* Busy - operation is ongoing when set */ + +/* OCTOSPI (1=0x5000, 2=0xA000)*/ +#ifndef OCTOSPI_BASE +#define OCTOSPI_BASE 0x52005000 +#endif + +#define OCTOSPI_CR (*(volatile uint32_t *)(OCTOSPI_BASE + 0x00)) /* Control register */ +#define OCTOSPI_DCR1 (*(volatile uint32_t *)(OCTOSPI_BASE + 0x08)) /* Device Configuration register 1 */ +#define OCTOSPI_DCR2 (*(volatile uint32_t *)(OCTOSPI_BASE + 0x0C)) /* Device Configuration register 2 */ +#define OCTOSPI_DCR3 (*(volatile uint32_t *)(OCTOSPI_BASE + 0x10)) /* Device Configuration register 3 */ +#define OCTOSPI_DCR4 (*(volatile uint32_t *)(OCTOSPI_BASE + 0x14)) /* Device Configuration register 4 */ +#define OCTOSPI_SR (*(volatile uint32_t *)(OCTOSPI_BASE + 0x20)) /* Status register */ +#define OCTOSPI_FCR (*(volatile uint32_t *)(OCTOSPI_BASE + 0x24)) /* Flag Clear register */ +#define OCTOSPI_DLR (*(volatile uint32_t *)(OCTOSPI_BASE + 0x40)) /* Data Length register */ +#define OCTOSPI_AR (*(volatile uint32_t *)(OCTOSPI_BASE + 0x48)) /* Address register */ +#define OCTOSPI_DR (*(volatile uint8_t *)(OCTOSPI_BASE + 0x50)) /* Data register */ +#define OCTOSPI_DR32 (*(volatile uint32_t *)(OCTOSPI_BASE + 0x50)) /* Data register - 32 bit */ +#define OCTOSPI_PSMKR (*(volatile uint32_t *)(OCTOSPI_BASE + 0x80)) /* Polling Status Mask register */ +#define OCTOSPI_PSMAR (*(volatile uint32_t *)(OCTOSPI_BASE + 0x88)) /* Polling Status Match register */ +#define OCTOSPI_PIR (*(volatile uint32_t *)(OCTOSPI_BASE + 0x90)) /* Polling Interval register */ +#define OCTOSPI_CCR (*(volatile uint32_t *)(OCTOSPI_BASE + 0x100)) /* Communication Configuration register */ +#define OCTOSPI_TCR (*(volatile uint32_t *)(OCTOSPI_BASE + 0x108)) /* Timing Configuration register */ +#define OCTOSPI_IR (*(volatile uint32_t *)(OCTOSPI_BASE + 0x110)) /* Instruction register */ +#define OCTOSPI_ABR (*(volatile uint32_t *)(OCTOSPI_BASE + 0x120)) /* Alternate Bytes register */ +#define OCTOSPI_LPTR (*(volatile uint32_t *)(OCTOSPI_BASE + 0x130)) /* Low Power Timeout register */ + +#define OCTOSPI_CR_FMODE_MASK (0x3 << 28) +#define OCTOSPI_CR_FMODE(fmode) (((fmode) & 0x3) << 28) /* Functional Mode (0=indirect write, 1=indirect read, 2=auto poll, 3=mem mapped) */ +#define OCTOSPI_CR_FTIE (1 << 18) /* FIFO threshold interrupt enable */ +#define OCTOSPI_CR_TCIE (1 << 17) /* Transfer complete inerrupt enable */ +#define OCTOSPI_CR_FTHRES_MASK (0x1F << 8) +#define OCTOSPI_CR_FTHRES(thr) ((((thr)-1) & 0x1F) << 8) /* FIFO threshold level */ +#define OCTOSPI_CR_FSEL (1 << 7) /* 0=Flash 1 or 1=Flash 2 */ +#define OCTOSPI_CR_ABORT (1 << 1) /* Abort request */ +#define OCTOSPI_CR_EN (1 << 0) /* Enable the QUADSPI */ + +#define OCTOCPI_DCR1_MTYP_MASK (0x7 << 24) +#define OCTOCPI_DCR1_MTYP(mtyp) (((mtyp) & 0x7) << 24) /* Memory type: 0=Micron, 1=Macronix, 2=Std, 3=Macronix RAM, 4=HyperBus mem, 5=HyperBus reg */ +#define OCTOSPI_DCR1_DEVSIZE_MASK (0x1F << 16) +#define OCTOSPI_DCR1_DEVSIZE(dsz) (((dsz) & 0x1F) << 16) /* Device memory size (2 ^ (fsize + 1)). Example 16MB is 23 */ +#define OCTOSPI_DCR1_CSHT_MASK (0x3F << 8) +#define OCTOSPI_DCR1_CSHT(csht) (((csht) & 0x3F) << 8) /* Chip select high time - Number of clock cycles (+1) nCS to remain high between commands */ +#define OCTOSPI_DCR1_CKMODE_3 (1 << 0) /* Clock mode 3 - clk high while nCS released */ +#define OCTOSPI_DCR1_CKMODE_0 (0) /* Clock mode 0 - clk low while nCS released */ + +#define OCTOSPI_DCR2_PRESCALER_MASK (0xFF << 0) +#define OCTOSPI_DCR2_PRESCALER(pre) ((((pre)-1) & 0xFF) << 0) /* Clock prescaler: quadspi_ker_ck/pre+1 */ + +#define OCTOSPI_SR_TCF (1 << 1) /* Transfer complete flag - set in indirect mode when the programmed number of data has been transferred */ +#define OCTOSPI_SR_FTF (1 << 2) /* FIFO threshold flag */ +#define OCTOSPI_SR_BUSY (1 << 5) /* Busy - operation is ongoing when set */ +#define OCTOSPI_SR_FLEVEL(sr) (((sr) >> 8) & 0x3F) /* FIFO level */ + +#define OCTOSPI_CCR_SIOO (1 << 31) /* Send instruction only once mode */ +#define OCTOSPI_CCR_DDTR (1 << 27) /* Data Double transfer rate mode */ +#define OCTOSPI_CCR_DMODE_MASK (0x7 << 24) +#define OCTOSPI_CCR_DMODE(dmode) (((dmode) & 0x7) << 24) /* Data mode (0=no data, 1=data on single line, 2=data on two lines, 3=data on four lines, 4=data on eight lines) */ +#define OCTOSPI_CCR_ABSIZE_MASK (0x3 << 20) +#define OCTOSPI_CCR_ABSIZE(absz) (((absz) & 0x3) << 20) /* Alternate bytes size */ +#define OCTOSPI_CCR_ABDTR (1 << 19) /* Alternate bytes Double transfer rate mode */ +#define OCTOSPI_CCR_ABMODE_MASK (0x7 << 16) +#define OCTOSPI_CCR_ABMODE(abm) (((abm) & 0x7) << 16) /* Alternate bytes mode (0=no alt data, 1=alt on single line, 2=alt on two lines, 3=alt on four lines, 4=alt on eight lines) */ +#define OCTOSPI_CCR_ADSIZE_MASK (0x3 << 12) +#define OCTOSPI_CCR_ADSIZE(sz) (((sz) & 0x3) << 12) /* Address bytes size (0=8-bit, 1=16-bit, 2=24-bit, 3=32-bit) */ +#define OCTOSPI_CCR_ADMODE_MASK (0x7 << 8) +#define OCTOSPI_CCR_ADMODE(adm) (((adm) & 0x7) << 8) /* Address mode (0=no addr, 1=addr on single line, 2=addr on two lines, 3=addr on four lines, 4=addr on eight lines) */ +#define OCTOSPI_CCR_ISIZE_MASK (0x3 << 4) +#define OCTOSPI_CCR_ISIZE(sz) (((sz) & 0x3) << 4) /* Instruction size (0=8-bit, 1=16-bit, 2=24-bit, 3=32-bit) */ +#define OCTOSPI_CCR_IMODE_MASK (0x7 << 0) +#define OCTOSPI_CCR_IMODE(imode) (((imode) & 0x7) << 0) /* Instruction mode (0=no instr, 1=instr on single line, 2=instr on two lines, 3=instr on four lines, 4=instr on eight lines) */ + +#define OCTOSPI_TCR_SSHIFT (1 << 30) /* Sample shift 1=1/2 cycle shift */ +#define OCTOSPI_TCR_DHQC (1 << 28) /* Delay the data output by 1/4 of clock cycle */ +#define OCTOSPI_TCR_DCYC_MASK (0x1F << 0) +#define OCTOSPI_TCR_DCYC(dcyc) (((dcyc) & 0x1F) << 0) /* Number of dummy cycles */ + + #endif /* !SPI_DRV_STM32_H_INCLUDED */ diff --git a/include/hal.h b/include/hal.h index c41349ef..54411f83 100644 --- a/include/hal.h +++ b/include/hal.h @@ -66,7 +66,7 @@ void hal_prepare_boot(void); void *hal_get_dts_update_address(void); #endif -#if !defined(SPI_FLASH) && !defined(QSPI_FLASH) +#if !defined(SPI_FLASH) && !defined(QSPI_FLASH) && !defined(OCTOSPI_FLASH) /* user supplied external flash interfaces */ int ext_flash_write(uintptr_t address, const uint8_t *data, int len); int ext_flash_read(uintptr_t address, uint8_t *data, int len); diff --git a/include/spi_drv.h b/include/spi_drv.h index 6e2b3e1d..e42d65e9 100644 --- a/include/spi_drv.h +++ b/include/spi_drv.h @@ -32,7 +32,8 @@ #include #include "image.h" -#if defined(SPI_FLASH) || defined(WOLFBOOT_TPM) || defined(QSPI_FLASH) +#if defined(SPI_FLASH) || defined(WOLFBOOT_TPM) || defined(QSPI_FLASH) || \ + defined(OCTOSPI_FLASH) #if defined(PLATFORM_stm32f4) || defined(PLATFORM_stm32f7) || \ defined(PLATFORM_stm32wb) || defined(PLATFORM_stm32l0) || \ @@ -58,7 +59,7 @@ void spi_write(const char byte); uint8_t spi_read(void); #endif /* SPI_FLASH || WOLFBOOT_TPM */ -#ifdef QSPI_FLASH +#if defined(QSPI_FLASH) || defined(OCTOSPI_FLASH) #define QSPI_MODE_WRITE 0 #define QSPI_MODE_READ 1 @@ -75,8 +76,8 @@ int qspi_transfer(uint8_t fmode, const uint8_t cmd, uint32_t dummySz, uint8_t* data, uint32_t dataSz, uint32_t dataMode ); -#endif /* QSPI_FLASH */ +#endif /* QSPI_FLASH || OCTOSPI_FLASH */ -#endif /* SPI_FLASH || QSPI_FLASH */ +#endif /* SPI_FLASH || WOLFBOOT_TPM || QSPI_FLASH || OCTOSPI_FLASH */ #endif /* !SPI_DRV_H_INCLUDED */ diff --git a/include/spi_flash.h b/include/spi_flash.h index e6fb27b0..4b0754f6 100644 --- a/include/spi_flash.h +++ b/include/spi_flash.h @@ -36,7 +36,7 @@ #define SPI_FLASH_PAGE_SIZE (256) #endif -#if defined(SPI_FLASH) || defined(QSPI_FLASH) +#if defined(SPI_FLASH) || defined(QSPI_FLASH) || defined(OCTOSPI_FLASH) #include @@ -53,6 +53,6 @@ int spi_flash_write(uint32_t address, const void *data, int len); #define spi_flash_probe() do{}while(0) #define spi_flash_release() do{}while(0) -#endif /* SPI_FLASH */ +#endif /* SPI_FLASH || QSPI_FLASH || OCTOSPI_FLASH */ #endif /* !SPI_FLASH_DRI_H */ diff --git a/options.mk b/options.mk index bfb98a9a..14917be6 100644 --- a/options.mk +++ b/options.mk @@ -303,6 +303,12 @@ ifeq ($(SPI_FLASH),1) WOLFCRYPT_OBJS+=hal/spi/spi_drv_$(SPI_TARGET).o endif +ifeq ($(OCTOSPI_FLASH),1) + EXT_FLASH=1 + QSPI_FLASH=1 + CFLAGS+=-D"OCTOSPI_FLASH=1" +endif + ifeq ($(QSPI_FLASH),1) EXT_FLASH=1 CFLAGS+=-D"QSPI_FLASH=1" @@ -469,3 +475,5 @@ ifeq ($(RAM_CODE),1) endif endif endif + +CFLAGS+=$(CFLAGS_EXTRA) diff --git a/src/qspi_flash.c b/src/qspi_flash.c index 145b690e..37c12f49 100644 --- a/src/qspi_flash.c +++ b/src/qspi_flash.c @@ -26,7 +26,7 @@ #include "spi_drv.h" #include "spi_flash.h" -#ifdef QSPI_FLASH +#if defined(QSPI_FLASH) || defined(OCTOSPI_FLASH) #include "string.h" #include "printf.h" @@ -474,9 +474,7 @@ void spi_flash_release(void) spi_release(); } -#endif /* QSPI_FLASH */ - - +#endif /* QSPI_FLASH || OCTOSPI_FLASH */ #ifdef TEST_FLASH diff --git a/test-app/Makefile b/test-app/Makefile index 4c8a4319..bb20499a 100644 --- a/test-app/Makefile +++ b/test-app/Makefile @@ -140,6 +140,11 @@ ifeq ($(SPI_FLASH),1) APP_OBJS+=../hal/spi/spi_drv_$(SPI_TARGET).o ../src/spi_flash.o endif +ifeq ($(OCTOSPI_FLASH),1) + QSPI_FLASH = 1 + CFLAGS+=-D"OCTOSPI_FLASH" +endif + ifeq ($(QSPI_FLASH),1) CFLAGS+=-D"QSPI_FLASH" APP_OBJS+=../hal/spi/spi_drv_$(SPI_TARGET).o ../src/qspi_flash.o diff --git a/tools/config.mk b/tools/config.mk index 0f3edcee..656d847f 100644 --- a/tools/config.mk +++ b/tools/config.mk @@ -16,6 +16,8 @@ ifeq ($(ARCH),) DEBUG?=0 VTOR?=1 CORTEX_M0?=0 + CORTEX_M33?=0 + CORTEX_M7?=0 NO_ASM?=0 EXT_FLASH?=0 SPI_FLASH?=0 @@ -59,7 +61,7 @@ endif CONFIG_VARS:= ARCH TARGET SIGN HASH MCUXPRESSO MCUXPRESSO_CPU MCUXPRESSO_DRIVERS \ MCUXPRESSO_CMSIS FREEDOM_E_SDK STM32CUBE CYPRESS_PDL CYPRESS_CORE_LIB CYPRESS_TARGET_LIB DEBUG VTOR \ - CORTEX_M0 CORTEX_M33 NO_ASM EXT_FLASH SPI_FLASH NO_XIP UART_FLASH ALLOW_DOWNGRADE NVM_FLASH_WRITEONCE \ + CORTEX_M0 CORTEX_M7 CORTEX_M33 NO_ASM EXT_FLASH SPI_FLASH NO_XIP UART_FLASH ALLOW_DOWNGRADE NVM_FLASH_WRITEONCE \ DISABLE_BACKUP WOLFBOOT_VERSION V NO_MPU ENCRYPT FLAGS_HOME FLAGS_INVERT \ SPMATH RAM_CODE DUALBANK_SWAP IMAGE_HEADER_SIZE PKA TZEN PSOC6_CRYPTO WOLFTPM \ WOLFBOOT_PARTITION_SIZE WOLFBOOT_SECTOR_SIZE \