mirror of https://github.com/wolfSSL/wolfBoot.git
STM32 QSPI cleanups.
parent
5331f5ee23
commit
c3cf21a81f
|
|
@ -218,6 +218,9 @@ int qspi_transfer(
|
|||
mode = 0; /* no data */
|
||||
}
|
||||
|
||||
/* Enable the QSPI peripheral */
|
||||
QUADSPI_CR |= QUADSPI_CR_EN;
|
||||
|
||||
if (dsz > 0) {
|
||||
QUADSPI_DLR = dsz-1;
|
||||
}
|
||||
|
|
@ -227,9 +230,6 @@ int qspi_transfer(
|
|||
adsz = addrSz-1;
|
||||
}
|
||||
|
||||
/* Enable the QSPI peripheral */
|
||||
QUADSPI_CR |= QUADSPI_CR_EN;
|
||||
|
||||
/* Configure QSPI: CCR register with all communications parameters */
|
||||
/* mode 1=1SPI, 2=2SPI, 3=4SPI */
|
||||
QUADSPI_CCR = (
|
||||
|
|
@ -303,9 +303,9 @@ void RAMFUNCTION spi_init(int polarity, int phase)
|
|||
|
||||
/* Setup clocks */
|
||||
#ifdef QSPI_FLASH
|
||||
/* Enable QUADSPI clock on HCLK3 (240MHz max) */
|
||||
/* Select QUADSPI clock source */
|
||||
RCC_D1CCIPR &= ~RCC_D1CCIPR_QSPISEL_MASK;
|
||||
RCC_D1CCIPR |= RCC_D1CCIPR_QSPISEL(0);
|
||||
RCC_D1CCIPR |= RCC_D1CCIPR_QSPISEL(QSPI_CLOCK_SEL);
|
||||
AHB3_CLOCK_EN |= RCC_AHB3ENR_QSPIEN;
|
||||
#endif
|
||||
#ifdef SPI_FLASH
|
||||
|
|
@ -333,16 +333,16 @@ void RAMFUNCTION spi_init(int polarity, int phase)
|
|||
#ifdef QSPI_FLASH
|
||||
/* Configure QSPI FIFO Threshold (1 byte) */
|
||||
QUADSPI_CR &= ~QUADSPI_CR_FTHRES_MASK;
|
||||
QUADSPI_CR |= QUADSPI_CR_FTHRES(1);
|
||||
QUADSPI_CR |= QUADSPI_CR_FTHRES(4);
|
||||
|
||||
/* Wait till BUSY flag cleared */
|
||||
while (QUADSPI_SR & QUADSPI_SR_BUSY) {};
|
||||
|
||||
/* Configure QSPI Clock Prescaler (240/X), Flash ID 0, Dual Flash=0,
|
||||
/* Configure QSPI Clock Prescaler (64/X), Flash ID 0, Dual Flash=0,
|
||||
* Sample Shift=None */
|
||||
QUADSPI_CR &= ~(QUADSPI_CR_PRESCALER_MASK | QUADSPI_CR_FSEL |
|
||||
QUADSPI_CR_DFM | QUADSPI_CR_SSHIFT);
|
||||
QUADSPI_CR |= (QUADSPI_CR_PRESCALER(HCLK3_MHZ/QSPI_CLOCK_MHZ));
|
||||
QUADSPI_CR |= (QUADSPI_CR_PRESCALER((QSPI_CLOCK_BASE/QSPI_CLOCK_MHZ)));
|
||||
|
||||
/* Configure QSPI Flash Size (16MB), CS High Time (1 clock) and
|
||||
* Clock Mode (0) */
|
||||
|
|
|
|||
|
|
@ -165,13 +165,25 @@
|
|||
#define RCC_D1CCIPR (*(volatile uint32_t *)(RCC_BASE + 0x4C)) /* RM0433 - 8.7.19 (RCC_D1CCIPR) */
|
||||
#define RCC_D1CCIPR_QSPISEL_MASK (0x3 << 4)
|
||||
#define RCC_D1CCIPR_QSPISEL(sel) (((sel) & 0x3) << 4) /* 0=hclk3, 1=pll1_q_ck, 2=pll2_r_ck, 3=per_ck */
|
||||
#define RCC_D1CCIPR_QSPISEL_HCLK3 0
|
||||
#define RCC_D1CCIPR_QSPISEL_PLL1 1
|
||||
#define RCC_D1CCIPR_QSPISEL_PLL2 2
|
||||
#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 HCLK3_MHZ 240000000
|
||||
#define HCLK3_MHZ 240000000
|
||||
#define PERCK_MHZ 64000000
|
||||
#ifndef QSPI_CLOCK_BASE
|
||||
#define QSPI_CLOCK_BASE PERCK_MHZ
|
||||
#endif
|
||||
#ifndef QSPI_CLOCK_SEL
|
||||
/* Enable QUADSPI clock on PER_CK (64MHz) */
|
||||
#define QSPI_CLOCK_SEL RCC_D1CCIPR_QSPISEL_PERCK
|
||||
#endif
|
||||
#ifndef QSPI_CLOCK_MHZ
|
||||
#define QSPI_CLOCK_MHZ 8000000
|
||||
#define QSPI_CLOCK_MHZ 16000000
|
||||
#endif
|
||||
|
||||
/* QSPI CLK PB2 */
|
||||
|
|
@ -370,13 +382,14 @@
|
|||
|
||||
#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(thr) ((((thr)-1) & 0xF) << 8) /* FIFO threshold level */
|
||||
#define QUADSPI_CR_FSEL (0x1 << 7) /* 0=Flash 1 or 1=Flash 2 */
|
||||
#define QUADSPI_CR_DFM (0x1 << 6) /* Dual-flash mode */
|
||||
#define QUADSPI_CR_SSHIFT (0x1 << 4) /* Sample shift 1=1/2 cycle shift */
|
||||
#define QUADSPI_CR_ABORT (0x1 << 1) /* Abort request */
|
||||
#define QUADSPI_CR_EN (0x1 << 0) /* Enable the QUADSPI */
|
||||
#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 */
|
||||
#define QUADSPI_CR_SSHIFT (1 << 4) /* Sample shift 1=1/2 cycle shift */
|
||||
#define QUADSPI_CR_ABORT (1 << 1) /* Abort request */
|
||||
#define QUADSPI_CR_EN (1 << 0) /* Enable the QUADSPI */
|
||||
|
||||
#define QUADSPI_CCR_DDRM (1 << 31) /* Double data rate mode */
|
||||
#define QUADSPI_CCR_DHHC (1 << 30) /* Delay the data output by 1/4 of the QUADSPI output clock cycle in DDR mode */
|
||||
|
|
@ -410,6 +423,6 @@
|
|||
|
||||
#define QUADSPI_SR_TCF (1 << 1) /* Transfer complete flag - set in indirect mode when the programmed number of data has been transferred */
|
||||
#define QUADSPI_SR_FTF (1 << 2) /* FIFO threshold flag */
|
||||
#define QUADSPI_SR_BUSY (1 << 5) /* Busy - operation is on going when set */
|
||||
#define QUADSPI_SR_BUSY (1 << 5) /* Busy - operation is ongoing when set */
|
||||
|
||||
#endif /* !SPI_DRV_STM32_H_INCLUDED */
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
#endif
|
||||
#define FLASH_NUM_SECTORS (FLASH_DEVICE_SIZE/FLASH_SECTOR_SIZE)
|
||||
|
||||
/* QSPI Configuration */
|
||||
/* QSPI Configuration - Use single/dual/quad mode for data transfers */
|
||||
#ifndef QSPI_ADDR_MODE
|
||||
#define QSPI_ADDR_MODE QSPI_ADDR_MODE_SPI
|
||||
#endif
|
||||
|
|
@ -60,7 +60,7 @@
|
|||
#define QSPI_ADDR_SZ 3
|
||||
#endif
|
||||
#ifndef QSPI_DUMMY_READ
|
||||
#define QSPI_DUMMY_READ (8) /* Number of dummy clock cycles for reads */
|
||||
#define QSPI_DUMMY_READ 8 /* Number of dummy clock cycles for reads */
|
||||
#endif
|
||||
#ifndef QSPI_FLASH_READY_TRIES
|
||||
#define QSPI_FLASH_READY_TRIES 1000
|
||||
|
|
@ -135,7 +135,6 @@
|
|||
/* forward declarations */
|
||||
static int qspi_wait_ready(void);
|
||||
static int qspi_status(uint8_t* status);
|
||||
static int qspi_wait_we(void);
|
||||
#ifdef TEST_FLASH
|
||||
static int test_flash(void);
|
||||
#endif
|
||||
|
|
@ -168,18 +167,35 @@ static int qspi_flash_read_id(uint8_t* id, uint32_t idSz)
|
|||
static int qspi_write_enable(void)
|
||||
{
|
||||
int ret;
|
||||
uint32_t timeout;
|
||||
uint8_t status = 0;
|
||||
|
||||
/* send write enable */
|
||||
ret = qspi_transfer(WRITE_ENABLE_CMD, 0, 0, NULL, 0, NULL, 0, 0,
|
||||
QSPI_ADDR_MODE_SPI);
|
||||
#if defined(DEBUG_QSPI) && DEBUG_QSPI > 1
|
||||
wolfBoot_printf("Write Enable: Ret %d\n", ret);
|
||||
#endif
|
||||
|
||||
qspi_wait_ready();
|
||||
/* wait until write enabled and not busy */
|
||||
timeout = 0;
|
||||
while (++timeout < QSPI_FLASH_READY_TRIES) {
|
||||
ret = qspi_status(&status);
|
||||
if (ret == 0 && (status & FLASH_SR_WRITE_EN)
|
||||
&& (status & FLASH_SR_BUSY) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (timeout >= QSPI_FLASH_READY_TRIES) {
|
||||
#ifdef DEBUG_QSPI
|
||||
wolfBoot_printf("Flash WE Timeout!\n");
|
||||
#endif
|
||||
return -1; /* timeout */
|
||||
}
|
||||
|
||||
ret = qspi_wait_we();
|
||||
#if defined(DEBUG_QSPI) && DEBUG_QSPI > 1
|
||||
wolfBoot_printf("Write Enabled: %s\n", ret == 0 ? "yes" : "no");
|
||||
wolfBoot_printf("Write Enabled: %s\n",
|
||||
(status & FLASH_SR_WRITE_EN) ? "yes" : "no");
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
|
|
@ -239,52 +255,33 @@ static int qspi_wait_ready(void)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int qspi_wait_we(void)
|
||||
{
|
||||
int ret;
|
||||
uint32_t timeout;
|
||||
uint8_t status = 0;
|
||||
|
||||
timeout = 0;
|
||||
while (++timeout < QSPI_FLASH_READY_TRIES) {
|
||||
ret = qspi_status(&status);
|
||||
if (ret == 0 && (status & FLASH_SR_WRITE_EN)) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_QSPI
|
||||
wolfBoot_printf("Flash WE Timeout!\n");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if QSPI_ADDR_MODE == QSPI_ADDR_MODE_QSPI
|
||||
static int qspi_quad_enable(void)
|
||||
{
|
||||
int ret;
|
||||
uint8_t data[4]; /* size multiple of uint32_t */
|
||||
|
||||
ret = qspi_write_enable();
|
||||
if (ret == 0) {
|
||||
memset(data, 0, sizeof(data));
|
||||
ret = qspi_transfer(READ_SR2_CMD, 0, 0, NULL, 0, data, 1, 0,
|
||||
QSPI_ADDR_MODE_SPI);
|
||||
memset(data, 0, sizeof(data));
|
||||
ret = qspi_transfer(READ_SR2_CMD, 0, 0, NULL, 0, data, 1, 0,
|
||||
QSPI_ADDR_MODE_SPI);
|
||||
#ifdef DEBUG_QSPI
|
||||
wolfBoot_printf("Status Reg 2: Ret %d, 0x%x\n", ret, data[0]);
|
||||
wolfBoot_printf("Status Reg 2: Ret %d, 0x%x\n", ret, data[0]);
|
||||
#endif
|
||||
if (ret == 0 && (data[0] & FLASH_SR2_QE) == 0) {
|
||||
ret = qspi_write_enable();
|
||||
if (ret == 0) {
|
||||
if ((data[0] & FLASH_SR2_QE) == 0) {
|
||||
data[0] |= FLASH_SR2_QE;
|
||||
ret = qspi_transfer(WRITE_SR2_CMD, 0, 0, data, 1, NULL, 0, 0,
|
||||
QSPI_ADDR_MODE_SPI);
|
||||
memset(data, 0, sizeof(data));
|
||||
data[0] |= FLASH_SR2_QE;
|
||||
ret = qspi_transfer(WRITE_SR2_CMD, 0, 0, data, 1, NULL, 0, 0,
|
||||
QSPI_ADDR_MODE_SPI);
|
||||
#ifdef DEBUG_QSPI
|
||||
wolfBoot_printf("Setting Quad Enable: Ret %d, SR2 0x%x\n",
|
||||
ret, data[0]);
|
||||
wolfBoot_printf("Setting Quad Enable: Ret %d, SR2 0x%x\n",
|
||||
ret, data[0]);
|
||||
#endif
|
||||
}
|
||||
|
||||
qspi_wait_ready();
|
||||
qspi_write_disable();
|
||||
}
|
||||
qspi_write_disable();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -296,8 +293,7 @@ static int qspi_enter_4byte_addr(void)
|
|||
int ret = qspi_write_enable();
|
||||
if (ret == 0) {
|
||||
ret = qspi_transfer(ENTER_4B_ADDR_MODE_CMD, 0, 0,
|
||||
NULL, 0, NULL, 0,
|
||||
0, QSPI_ADDR_MODE_SPI);
|
||||
NULL, 0, NULL, 0, 0, QSPI_ADDR_MODE_SPI);
|
||||
#ifdef DEBUG_QSPI
|
||||
wolfBoot_printf("Enter 4-byte address mode: Ret %d\n", ret);
|
||||
#endif
|
||||
|
|
@ -313,8 +309,7 @@ static int qspi_exit_4byte_addr(void)
|
|||
int ret = qspi_write_enable();
|
||||
if (ret == 0) {
|
||||
ret = qspi_transfer(EXIT_4B_ADDR_MODE_CMD, 0, 0,
|
||||
NULL, 0, NULL, 0,
|
||||
0, QSPI_ADDR_MODE_SPI);
|
||||
NULL, 0, NULL, 0, 0, QSPI_ADDR_MODE_SPI);
|
||||
#ifdef DEBUG_QSPI
|
||||
wolfBoot_printf("Enter 4-byte address mode: Ret %d\n", ret);
|
||||
#endif
|
||||
|
|
@ -357,8 +352,7 @@ int spi_flash_sector_erase(uint32_t address)
|
|||
if (ret == 0) {
|
||||
/* ------ Erase Flash ------ */
|
||||
ret = qspi_transfer(SEC_ERASE_CMD, address, QSPI_ADDR_SZ,
|
||||
NULL, 0, NULL, 0,
|
||||
0, QSPI_ADDR_MODE_SPI);
|
||||
NULL, 0, NULL, 0, 0, QSPI_ADDR_MODE_SPI);
|
||||
#ifdef DEBUG_QSPI
|
||||
wolfBoot_printf("Flash Erase: Ret %d, Address 0x%x\n", ret, address);
|
||||
#endif
|
||||
|
|
@ -384,8 +378,7 @@ int spi_flash_read(uint32_t address, void *data, int len)
|
|||
|
||||
/* ------ Read Flash ------ */
|
||||
ret = qspi_transfer(FLASH_READ_CMD, address, QSPI_ADDR_SZ,
|
||||
NULL, 0, data, len,
|
||||
QSPI_DUMMY_READ, QSPI_ADDR_MODE);
|
||||
NULL, 0, data, len, QSPI_DUMMY_READ, QSPI_ADDR_MODE);
|
||||
#ifdef DEBUG_QSPI
|
||||
wolfBoot_printf("Flash Read: Ret %d, Address 0x%x, Len %d, Cmd 0x%x\n",
|
||||
ret, address, len, FLASH_READ_CMD);
|
||||
|
|
|
|||
Loading…
Reference in New Issue