From 4a1652c47673ccb44f733af9dddaff5f04de431c Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 24 May 2024 15:37:56 -0700 Subject: [PATCH] QSPI fixes. --- Makefile | 1 + hal/rx65n.c | 9 +++++++++ hal/rx72n.c | 54 ++++++++++++++++++++++++++++++++++++----------------- 3 files changed, 47 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index 7d4f31189..93978000a 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,7 @@ OBJCOPY_FLAGS= BIG_ENDIAN?=0 USE_GCC?=1 USE_GCC_HEADLESS?=1 +FLASH_OTP_KEYSTORE?=0 OBJS:= \ ./src/string.o \ diff --git a/hal/rx65n.c b/hal/rx65n.c index 00157d629..94c4bcf87 100644 --- a/hal/rx65n.c +++ b/hal/rx65n.c @@ -238,6 +238,10 @@ #define RSPI_SPDCR2_BYSW (1 << 0) /* Byte Swap: 0=Byte swapping of SPDR data disabled, 1=Byte swapping of SPDR data enabled */ +#if defined(EXT_FLASH) && defined(TEST_FLASH) +static int test_flash(void); +#endif + static void hal_delay_us(uint32_t us) { uint32_t delay; @@ -586,6 +590,11 @@ void hal_init(void) #ifdef DEBUG_UART uart_init(); uart_write("wolfBoot HAL Init\n", 18); +#endif +#if defined(EXT_FLASH) && defined(TEST_FLASH) + if (test_flash() != 0) { + wolfBoot_printf("Flash Test Failed!\n"); + } #endif return; } diff --git a/hal/rx72n.c b/hal/rx72n.c index 6495c1d52..2ff40e29b 100644 --- a/hal/rx72n.c +++ b/hal/rx72n.c @@ -20,10 +20,11 @@ */ /* HAL for Renesas RX72N */ -/* Default configuration: +/* Tested with: * RX72N Envision Kit (HMI IoT) * R5F572NNHDFB 144-pin LFQFP (PLQP0144KA-B) * 4MB Flash, 1MB RAM, 32KB Data Flash, 240MHz, TSIP + * QSPI: Macronix MX25L3233FM2I-08G: 4MB QSPI Serial Flash */ #include @@ -248,6 +249,8 @@ #define QSPI_SPCR (*(volatile uint8_t *)(QSPI_BASE + 0x00)) /* QSPI Control Register */ #define QSPI_SPCR_MSTR (1 << 3) /* 0=Slave, 1=Master */ #define QSPI_SPCR_SPE (1 << 6) /* 1=Enable RSPI */ +#define QSPI_SSLP (*(volatile uint8_t *)(QSPI_BASE + 0x01)) /* QSPI Slave Select Polarity */ +#define QSPI_SSLP_SSLP (1 << 0) /* 0=active low (default), 1=active high */ #define QSPI_SPPCR (*(volatile uint8_t *)(QSPI_BASE + 0x02)) /* Pin Control */ #define QSPI_SPPCR_IO2FV (1 << 1) /* Single-/Dual-SPI Mode QIO2 */ #define QSPI_SPPCR_IO3FV (1 << 2) /* Single-/Dual-SPI Mode QIO3 */ @@ -261,7 +264,7 @@ #define QSPI_SPDR8 (*(volatile uint8_t *)(QSPI_BASE + 0x04)) /* Data */ #define QSPI_SPDR16 (*(volatile uint16_t *)(QSPI_BASE + 0x04)) /* Data */ #define QSPI_SPDR32 (*(volatile uint32_t *)(QSPI_BASE + 0x04)) /* Data */ -#define QSPI_SPSCR (*(volatile uint32_t *)(QSPI_BASE + 0x08)) /* Sequence Control */ +#define QSPI_SPSCR (*(volatile uint8_t *)(QSPI_BASE + 0x08)) /* Sequence Control */ #define QSPI_SPSCR_SPSC(s) ((s) & 0x3) /* Number of SPCMDn register to be referenced (n = 0 to 3) */ #define QSPI_SPSSR (*(volatile uint8_t *)(QSPI_BASE + 0x09)) /* Sequence Status */ #define QSPI_SPSSR_SPSS(s) ((s) & 0x3) /* Sequence Status: 0=SPCMD0, 1=SPCMD1, 2=SPCMD2, 3=SPCMD3 */ @@ -290,9 +293,9 @@ #define QSPI_SPCMD_SPNDEN (1 << 13) /* Next-Access Delay Enable */ #define QSPI_SPCMD_SLNDEN (1 << 14) /* SSL Negation Delay Setting Enable */ #define QSPI_SPCMD_SCKDEN (1 << 15) /* QSPCLK Delay Setting Enable */ -#define QSPI_SPBFCR (*(volatile uint8_t *)(QSPI_BASE + 0x1E)) /* Buffer Control */ +#define QSPI_SPBFCR (*(volatile uint8_t *)(QSPI_BASE + 0x18)) /* Buffer Control */ #define QSPI_SPBFCR_RXTRG(n) ((n) & 0x7) /* Receive Buffer Data Trigger Num */ -#define QSPI_SPBFCR_TXTRG(n) (((n) & 0x7) >> 3) /* Transmit Buffer Data Trigger Num */ +#define QSPI_SPBFCR_TXTRG(n) (((n) & 0x7) << 3) /* Transmit Buffer Data Trigger Num */ #define QSPI_SPBFCR_RXRST (1 << 6) /* Receive Buffer Data Reset */ #define QSPI_SPBFCR_TXRST (1 << 7) /* Transmit Buffer Data Reset */ #define QSPI_SPBDCR (*(volatile uint16_t *)(QSPI_BASE + 0x1A)) /* Buffer Data Count Set */ @@ -302,6 +305,11 @@ #define QSPI_FIFO_SIZE 32 /* bytes */ + +#if defined(EXT_FLASH) && defined(TEST_FLASH) +static int test_flash(void); +#endif + static void hal_delay_us(uint32_t us) { uint32_t delay; @@ -312,15 +320,11 @@ static void hal_delay_us(uint32_t us) #if defined(SPI_FLASH) || defined(QSPI_FLASH) -/* Macronix MX25L3233FM2I-08G: 4MB QSPI Serial Flash */ /* RSPI1: P27/RSPCKB-A, P26/MOSIB-A, P30/MISOB-A, P31/SSLB0-A */ /* QSPI: PD2/QIO2-B, PD3/QIO3-B, PD4/QSSL-B, PD5/QSPCLK-B, PD6/QIO0-B, PD7/QIO1-B */ #ifndef FLASH_RSPI_PORT #define FLASH_RSPI_PORT 1 /* RSPI1 */ #endif -#ifndef FLASH_CLK_HZ -#define FLASH_CLK_HZ 15000000 -#endif #define FLASH_SPI_USE_HW_CS void spi_init(int polarity, int phase) { @@ -413,6 +417,7 @@ void spi_init(int polarity, int phase) /* Configure QSPI */ QSPI_SPCR = QSPI_SPCR_MSTR; /* Master mode */ + QSPI_SSLP &= ~QSPI_SSLP_SSLP; /* SS Active low */ QSPI_SPPCR = (QSPI_SPPCR_MOIFV | QSPI_SPPCR_MOIDE); /* enable idle fixing */ QSPI_SPBR = 1; /* 30Mbps */ QSPI_SPCKD = QSPI_SPCKD_SCKDL(0); /* 1 clock delay (SSL assert and first clock cycle) */ @@ -424,7 +429,7 @@ void spi_init(int polarity, int phase) reg = ( QSPI_SPCMD_SPIMOD(0) | /* Single SPI */ QSPI_SPCMD_SPB(0) | /* use byte */ - QSPI_SPCMD_BRDV(0) | /* div/1 */ + QSPI_SPCMD_BRDV(0) | /* div/1 (no div) */ QSPI_SPCMD_SSLKP | /* keep signal level between transfers */ QSPI_SPCMD_SPNDEN | /* enable Next-Access Delay */ QSPI_SPCMD_SLNDEN | /* enable negation Delay */ @@ -504,13 +509,13 @@ static int qspi_data(const uint32_t* txData, uint32_t* rxData, uint32_t dataSz) uint8_t *pTx, *pRx; /* Do full FIFO (32 bytes) TX/RX - word */ - while (dataSz >= QSPI_FIFO_SIZE/2) { + while (dataSz >= ((QSPI_FIFO_SIZE/2) - fifoLvl)) { /* Set FIFO Trigger Level: RX Trig=16 bytes, TX Trig=16 bytes */ QSPI_SPBFCR = QSPI_SPBFCR_RXTRG(5) | QSPI_SPBFCR_TXTRG(3); tmp = QSPI_SPBFCR; /* Per ref manual: SPBFCR requires dummy read after write */ /* Transmit Data */ - for (fifoLvl=0; fifoLvl 0) { + while (fifoLvl > 0) { tmp = QSPI_SPDR32; if (rxData) { #ifndef BIG_ENDIAN_ORDER @@ -538,6 +544,7 @@ static int qspi_data(const uint32_t* txData, uint32_t* rxData, uint32_t dataSz) #endif *rxData++ = tmp; } + fifoLvl -= 4; } /* Clear receive buffer full flag */ QSPI_SPSR |= QSPI_SPSR_SPRFF; @@ -568,18 +575,16 @@ static int qspi_data(const uint32_t* txData, uint32_t* rxData, uint32_t dataSz) while ((QSPI_SPSR & QSPI_SPSR_SPTEF) == 0); /* Recieve bytes */ - while (fifoLvl-- > 0) { + while (fifoLvl > 0) { /* Wait for receive full */ while ((QSPI_SPSR & QSPI_SPSR_SPRFF) == 0); if (rxData) *pRx++ = QSPI_SPDR8; else tmp = QSPI_SPDR8; + fifoLvl--; } - /* Clear flags */ - QSPI_SPSR |= (QSPI_SPSR_SPTEF | QSPI_SPSR_SPRFF | QSPI_SPSR_SPSSLF); - return 0; } @@ -636,6 +641,9 @@ int qspi_transfer(uint8_t fmode, const uint8_t cmd, seq++; } + /* End CS (set high) on last transaction */ + QSPI_SPCMD(seq-1) &= ~QSPI_SPCMD_SSLKP; + /* Set number of sequences */ QSPI_SPSCR = QSPI_SPSCR_SPSC(seq-1); @@ -653,11 +661,17 @@ int qspi_transfer(uint8_t fmode, const uint8_t cmd, if (dummySz > 0) { qspi_data(NULL, NULL, dummySz); } - qspi_data(&alt, NULL, altSz); + if (fmode == QSPI_MODE_READ) + qspi_data(NULL, (uint32_t*)data, dataSz); + else + qspi_data((const uint32_t*)data, NULL, dataSz); /* Wait for QSSL negation */ while ((QSPI_SPSR & QSPI_SPSR_SPSSLF) == 0); + /* Clear flags */ + QSPI_SPSR |= (QSPI_SPSR_SPTEF | QSPI_SPSR_SPRFF | QSPI_SPSR_SPSSLF); + /* Disable QSPI */ QSPI_SPCR &= ~QSPI_SPCR_SPE; @@ -892,6 +906,12 @@ void hal_init(void) uart_init(); uart_write("wolfBoot HAL Init\n", 18); #endif +#if defined(EXT_FLASH) && defined(TEST_FLASH) + if (test_flash() != 0) { + wolfBoot_printf("Flash Test Failed!\n"); + } +#endif + return; } int hal_flash_write(uint32_t address, const uint8_t *data, int len)