mirror of https://github.com/wolfSSL/wolfBoot.git
STM32 QSPI Flash support. Refactor SPI to allow different GPIO base/AF for each pin. Adds `DEBUG_UART` support for H7.
parent
ac6f5207c7
commit
a9526bab8f
2
Makefile
2
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) ARCH=$(ARCH) \
|
||||
$(Q)$(MAKE) -C test-app TARGET=$(TARGET) EXT_FLASH=$(EXT_FLASH) SPI_FLASH=$(SPI_FLASH) QSPI_FLASH=$(QSPI_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) \
|
||||
|
|
|
@ -3,11 +3,13 @@ TARGET?=stm32h7
|
|||
SIGN?=ECC256
|
||||
HASH?=SHA256
|
||||
DEBUG?=0
|
||||
DEBUG_UART?=0
|
||||
VTOR?=1
|
||||
CORTEX_M0?=0
|
||||
NO_ASM?=0
|
||||
EXT_FLASH?=0
|
||||
SPI_FLASH?=0
|
||||
QSPI_FLASH?=0
|
||||
ALLOW_DOWNGRADE?=0
|
||||
NVM_FLASH_WRITEONCE?=0
|
||||
WOLFBOOT_VERSION?=1
|
||||
|
|
|
@ -704,6 +704,8 @@ The STM32H7 build can be built using:
|
|||
make TARGET=stm32h7 SIGN=ECC256
|
||||
```
|
||||
|
||||
The STM32H7 also supports using the QSPI for external flash. To enable use `QSPI_FLASH=1` in your configuration. The pins are defined in `hal/spi/spi_drv_stm32.h`. A built-in alternate pin configuration can be used with `QSPI_ALT_CONFIGURATION`. The flash and QSPI parameters are defined in `src/qspi_flash.c` and can be overrriden at build time.
|
||||
|
||||
### STM32H7 Programming
|
||||
|
||||
ST-Link Flash Tools:
|
||||
|
@ -735,6 +737,13 @@ booting.
|
|||
|
||||
ST-Link: `st-util -p 3333`
|
||||
|
||||
ST-Link: `ST-LINK_gdbserver -d -e -r 1 -p 3333`
|
||||
|
||||
Mac OS:
|
||||
```
|
||||
/Applications/STM32CubeIDE.app/Contents/Eclipse/plugins/com.st.stm32cube.ide.mcu.externaltools.stlink-gdb-server.macos64_2.0.300.202203231527/tools/bin/ST-LINK_gdbserver -d -cp /Applications/STM32CubeIDE.app/Contents/Eclipse/plugins/com.st.stm32cube.ide.mcu.externaltools.cubeprogrammer.macos64_2.0.200.202202231230/tools/bin -e -r 1 -p 3333
|
||||
```
|
||||
|
||||
2. Start GDB Client from wolfBoot root:
|
||||
|
||||
```sh
|
||||
|
|
|
@ -50,27 +50,28 @@
|
|||
#define SPI_FREQUENCY *((volatile uint32_t *)(SPI + 0x524))
|
||||
#define SPI_CONFIG *((volatile uint32_t *)(SPI + 0x554))
|
||||
|
||||
#define K125 0x02000000
|
||||
#define K250 0x04000000
|
||||
#define K500 0x08000000
|
||||
#define M1 0x10000000
|
||||
#define M2 0x20000000
|
||||
#define M4 0x40000000
|
||||
#define M8 0x80000000
|
||||
#define K125 0x02000000
|
||||
#define K250 0x04000000
|
||||
#define K500 0x08000000
|
||||
#define M1 0x10000000
|
||||
#define M2 0x20000000
|
||||
#define M4 0x40000000
|
||||
#define M8 0x80000000
|
||||
|
||||
void RAMFUNCTION spi_cs_off(int pin)
|
||||
void RAMFUNCTION spi_cs_off(uint32_t base, int pin)
|
||||
{
|
||||
GPIO_OUTSET = (1 << pin);
|
||||
while ((GPIO_OUT & (1 << pin)) == 0)
|
||||
;
|
||||
(void)base;
|
||||
}
|
||||
|
||||
void RAMFUNCTION spi_cs_on(int pin)
|
||||
void RAMFUNCTION spi_cs_on(uint32_t base, int pin)
|
||||
{
|
||||
GPIO_OUTCLR = (1 << pin);
|
||||
while ((GPIO_OUT & (1 << pin)) != 0)
|
||||
;
|
||||
|
||||
(void)base;
|
||||
}
|
||||
|
||||
uint8_t RAMFUNCTION spi_read(void)
|
||||
|
|
|
@ -47,8 +47,8 @@
|
|||
#endif
|
||||
|
||||
|
||||
#define SPI_CS_FLASH SPI_CS_PIN
|
||||
|
||||
#define SPI_CS_FLASH SPI_CS_PIN
|
||||
#define SPI_CS_PIO_BASE GPIO_BASE
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*
|
||||
* Pinout: see spi_drv_stm32.h
|
||||
*
|
||||
* Copyright (C) 2021 wolfSSL Inc.
|
||||
* Copyright (C) 2022 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfBoot.
|
||||
*
|
||||
|
@ -25,146 +25,233 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "spi_drv.h"
|
||||
#include "spi_drv_stm32.h"
|
||||
|
||||
void RAMFUNCTION spi_cs_off(int pin)
|
||||
#if defined(SPI_FLASH) || defined(QSPI_FLASH)
|
||||
|
||||
void RAMFUNCTION stm_gpio_config(uint32_t base, uint32_t pin, uint32_t af,
|
||||
uint32_t pull, uint32_t speed)
|
||||
{
|
||||
SPI_PIO_CS_BSRR |= (1 << pin);
|
||||
while(!(SPI_PIO_CS_ODR & (1 << pin)))
|
||||
uint32_t reg;
|
||||
uint32_t base_num = 0;
|
||||
|
||||
/* Determine GPIO clock bit */
|
||||
if (base == GPIOA_BASE)
|
||||
base_num = 0;
|
||||
else if (base == GPIOB_BASE)
|
||||
base_num = 1;
|
||||
#ifdef GPIOC_BASE
|
||||
else if (base == GPIOC_BASE)
|
||||
base_num = 2;
|
||||
#endif
|
||||
#ifdef GPIOD_BASE
|
||||
else if (base == GPIOD_BASE)
|
||||
base_num = 3;
|
||||
#endif
|
||||
#ifdef GPIOE_BASE
|
||||
else if (base == GPIOE_BASE)
|
||||
base_num = 4;
|
||||
#endif
|
||||
#ifdef GPIOF_BASE
|
||||
else if (base == GPIOF_BASE)
|
||||
base_num = 5;
|
||||
#endif
|
||||
#ifdef GPIOG_BASE
|
||||
else if (base == GPIOG_BASE)
|
||||
base_num = 6;
|
||||
#endif
|
||||
#ifdef GPIOH_BASE
|
||||
else if (base == GPIOH_BASE)
|
||||
base_num = 7;
|
||||
#endif
|
||||
#ifdef GPIOI_BASE
|
||||
else if (base == GPIOI_BASE)
|
||||
base_num = 8;
|
||||
#endif
|
||||
#ifdef GPIOJ_BASE
|
||||
else if (base == GPIOJ_BASE)
|
||||
base_num = 9;
|
||||
#endif
|
||||
#ifdef GPIOK_BASE
|
||||
else if (base == GPIOK_BASE)
|
||||
base_num = 10;
|
||||
#endif
|
||||
|
||||
/* Enable GPIO clock */
|
||||
RCC_GPIO_CLOCK_ER |= (1 << base);
|
||||
|
||||
/* Set Mode and Alternate Function */
|
||||
if (af == 0) {
|
||||
/* mode = 0, af = 0 */
|
||||
SPI_PIO_MODE(base) &= ~(0x03 << (pin * 2));
|
||||
if (pin < 8)
|
||||
SPI_PIO_AFL(base) &= ~(0xf << (pin * 4));
|
||||
else
|
||||
SPI_PIO_AFH(base) &= ~(0xf << ((pin - 8) * 4));
|
||||
}
|
||||
else {
|
||||
/* mode = 2 (af) */
|
||||
reg = SPI_PIO_MODE(base) & ~(0x03 << (pin * 2));
|
||||
SPI_PIO_MODE(base) = reg | (2 << (pin * 2));
|
||||
|
||||
/* alternate mode */
|
||||
if (pin < 8) {
|
||||
reg = SPI_PIO_AFL(base) & ~(0xf << (pin * 4));
|
||||
SPI_PIO_AFL(base) = reg | (af << (pin * 4));
|
||||
}
|
||||
else {
|
||||
reg = SPI_PIO_AFH(base) & ~(0xf << ((pin - 8) * 4));
|
||||
SPI_PIO_AFH(base) = reg | (af << ((pin - 8) * 4));
|
||||
}
|
||||
}
|
||||
|
||||
/* configure for pull 0=float, 1=pull up, 2=pull down */
|
||||
reg = SPI_PIO_PUPD(base) & ~(0x03 << (pin * 2));
|
||||
SPI_PIO_PUPD(base) = reg | (pull << (pin * 2));
|
||||
|
||||
/* configure output speed 0=low, 1=med, 2=high, 3=very high */
|
||||
reg = SPI_PIO_OSPD(base) & ~(0x03 << (pin * 2));
|
||||
SPI_PIO_OSPD(base) |= (speed << (pin * 2));
|
||||
}
|
||||
|
||||
#ifdef SPI_FLASH
|
||||
void RAMFUNCTION spi_cs_off(uint32_t base, int pin)
|
||||
{
|
||||
SPI_PIO_BSRR(base) |= (1 << pin);
|
||||
while (!(SPI_PIO_ODR(base) & (1 << pin)))
|
||||
;
|
||||
}
|
||||
|
||||
void RAMFUNCTION spi_cs_on(int pin)
|
||||
void RAMFUNCTION spi_cs_on(uint32_t base, int pin)
|
||||
{
|
||||
SPI_PIO_CS_BSRR |= (1 << (pin + 16));
|
||||
while(SPI_PIO_CS_ODR & (1 << pin))
|
||||
SPI_PIO_BSRR(base) |= (1 << (pin + 16));
|
||||
while (SPI_PIO_ODR(base) & (1 << pin))
|
||||
;
|
||||
}
|
||||
#endif /* SPI_FLASH */
|
||||
|
||||
|
||||
static void RAMFUNCTION spi_flash_pin_setup(void)
|
||||
static void RAMFUNCTION stm_pins_setup(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
RCC_GPIO_CLOCK_ER |= SPI_PIO_CS_CEN;
|
||||
reg = SPI_PIO_CS_MODE & ~ (0x03 << (SPI_CS_FLASH * 2));
|
||||
SPI_PIO_CS_MODE = reg | (1 << (SPI_CS_FLASH * 2));
|
||||
reg = SPI_PIO_CS_PUPD & ~(0x03 << (SPI_CS_FLASH * 2));
|
||||
SPI_PIO_CS_PUPD = reg | (0x01 << (SPI_CS_FLASH * 2));
|
||||
reg = SPI_PIO_CS_OSPD & ~(0x03 << (SPI_CS_FLASH * 2));
|
||||
SPI_PIO_CS_OSPD |= (0x03 << (SPI_CS_FLASH * 2));
|
||||
spi_cs_off(SPI_CS_FLASH);
|
||||
}
|
||||
|
||||
static void spi_tpm2_pin_setup(void)
|
||||
{
|
||||
#ifdef WOLFBOOT_TPM
|
||||
uint32_t reg;
|
||||
RCC_GPIO_CLOCK_ER |= SPI_PIO_CS_CEN;
|
||||
reg = SPI_PIO_CS_MODE & ~ (0x03 << (SPI_CS_TPM * 2));
|
||||
SPI_PIO_CS_MODE = reg | (1 << (SPI_CS_TPM * 2));
|
||||
reg = SPI_PIO_CS_PUPD & ~(0x03 << (SPI_CS_TPM * 2));
|
||||
SPI_PIO_CS_PUPD = reg | (0x01 << (SPI_CS_TPM * 2));
|
||||
reg = SPI_PIO_CS_OSPD & ~(0x03 << (SPI_CS_TPM * 2));
|
||||
SPI_PIO_CS_OSPD |= (0x03 << (SPI_CS_TPM * 2));
|
||||
spi_cs_off(SPI_CS_TPM);
|
||||
#ifdef SPI_FLASH
|
||||
stm_gpio_config(SPI_CLOCK_PIO_BASE, SPI_CLOCK_PIN, SPI_CLOCK_PIN_AF, 2, 3);
|
||||
stm_gpio_config(SPI_MOSI_PIO_BASE, SPI_MOSI_PIN, SPI_MOSI_PIN_AF, 2, 3);
|
||||
stm_gpio_config(SPI_MISO_PIO_BASE, SPI_MISO_PIN, SPI_MISO_PIN_AF, 2, 3);
|
||||
#endif
|
||||
#ifdef QSPI_FLASH
|
||||
stm_gpio_config(QSPI_CS_PIO_BASE, QSPI_CS_FLASH_PIN, QSPI_CS_FLASH_AF, 0, 0);
|
||||
stm_gpio_config(QSPI_CLOCK_PIO_BASE, QSPI_CLOCK_PIN, QSPI_CLOCK_PIN_AF, 0, 0);
|
||||
stm_gpio_config(QSPI_IO0_PIO_BASE, QSPI_IO0_PIN, QSPI_IO0_PIN_AF, 0, 0);
|
||||
stm_gpio_config(QSPI_IO1_PIO_BASE, QSPI_IO1_PIN, QSPI_IO1_PIN_AF, 0, 0);
|
||||
stm_gpio_config(QSPI_IO2_PIO_BASE, QSPI_IO2_PIN, QSPI_IO2_PIN_AF, 0, 0);
|
||||
stm_gpio_config(QSPI_IO3_PIO_BASE, QSPI_IO3_PIN, QSPI_IO3_PIN_AF, 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void RAMFUNCTION spi1_pins_setup(void)
|
||||
static void stm_pins_release(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
RCC_GPIO_CLOCK_ER |= SPI_PIO_CEN;
|
||||
/* Set mode = AF */
|
||||
reg = SPI_PIO_MODE & ~ (0x03 << (SPI1_CLOCK_PIN * 2));
|
||||
SPI_PIO_MODE = reg | (2 << (SPI1_CLOCK_PIN * 2));
|
||||
reg = SPI_PIO_MODE & ~ (0x03 << (SPI1_MOSI_PIN * 2));
|
||||
SPI_PIO_MODE = reg | (2 << (SPI1_MOSI_PIN * 2));
|
||||
reg = SPI_PIO_MODE & ~ (0x03 << (SPI1_MISO_PIN * 2));
|
||||
SPI_PIO_MODE = reg | (2 << (SPI1_MISO_PIN * 2));
|
||||
|
||||
/* Alternate function */
|
||||
#if SPI1_CLOCK_PIN < 8
|
||||
reg = SPI_PIO_AFL & ~(0xf << ((SPI1_CLOCK_PIN) * 4));
|
||||
SPI_PIO_AFL = reg | (SPI1_PIN_AF << ((SPI1_CLOCK_PIN) * 4));
|
||||
#else
|
||||
reg = SPI_PIO_AFH & ~(0xf << ((SPI1_CLOCK_PIN - 8) * 4));
|
||||
SPI_PIO_AFH = reg | (SPI1_PIN_AF << ((SPI1_CLOCK_PIN - 8) * 4));
|
||||
#ifdef SPI_FLASH
|
||||
stm_gpio_config(SPI_CLOCK_PIO_BASE, SPI_CLOCK_PIN, 0, 0, 0);
|
||||
stm_gpio_config(SPI_MOSI_PIO_BASE, SPI_MOSI_PIN, 0, 0, 0);
|
||||
stm_gpio_config(SPI_MISO_PIO_BASE, SPI_MISO_PIN, 0, 0, 0);
|
||||
#endif
|
||||
#if SPI1_MOSI_PIN < 8
|
||||
reg = SPI_PIO_AFL & ~(0xf << ((SPI1_MOSI_PIN) * 4));
|
||||
SPI_PIO_AFL = reg | (SPI1_PIN_AF << ((SPI1_MOSI_PIN) * 4));
|
||||
#else
|
||||
reg = SPI_PIO_AFH & ~(0xf << ((SPI1_MOSI_PIN-8) * 4));
|
||||
SPI_PIO_AFH = reg | (SPI1_PIN_AF << ((SPI1_MOSI_PIN - 8) * 4));
|
||||
#endif
|
||||
#if SPI1_MISO_PIN < 8
|
||||
reg = SPI_PIO_AFL & ~(0xf << ((SPI1_MISO_PIN) * 4));
|
||||
SPI_PIO_AFL = reg | (SPI1_PIN_AF << ((SPI1_MISO_PIN) * 4));
|
||||
#else
|
||||
reg = SPI_PIO_AFH & ~(0xf << ((SPI1_MISO_PIN-8) * 4));
|
||||
SPI_PIO_AFH = reg | (SPI1_PIN_AF << ((SPI1_MISO_PIN - 8) * 4));
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_stm32l0
|
||||
reg = SPI_PIO_PUPD & ~(0x03 << (SPI1_CLOCK_PIN * 2));
|
||||
SPI_PIO_PUPD = reg | (0x02 << (SPI1_CLOCK_PIN * 2));
|
||||
reg = SPI_PIO_PUPD & ~(0x03 << (SPI1_MOSI_PIN * 2));
|
||||
SPI_PIO_PUPD = reg | (0x02 << (SPI1_MOSI_PIN * 2));
|
||||
reg = SPI_PIO_PUPD & ~(0x03 << (SPI1_MISO_PIN * 2));
|
||||
SPI_PIO_PUPD = reg | (0x02 << (SPI1_MISO_PIN * 2));
|
||||
|
||||
reg = SPI_PIO_OSPD & ~(0x03 << (SPI1_CLOCK_PIN * 2));
|
||||
SPI_PIO_OSPD |= (0x03 << (SPI1_CLOCK_PIN * 2));
|
||||
reg = SPI_PIO_OSPD & ~(0x03 << (SPI1_MOSI_PIN * 2));
|
||||
SPI_PIO_OSPD |= (0x03 << (SPI1_MOSI_PIN * 2));
|
||||
reg = SPI_PIO_OSPD & ~(0x03 << (SPI1_MISO_PIN * 2));
|
||||
SPI_PIO_OSPD |= (0x03 << (SPI1_MISO_PIN * 2));
|
||||
#ifdef QSPI_FLASH
|
||||
stm_gpio_config(QSPI_CS_PIO_BASE, QSPI_CS_FLASH_PIN, 0, 0, 0);
|
||||
stm_gpio_config(QSPI_CLOCK_PIO_BASE, QSPI_CLOCK_PIN, 0, 0, 0);
|
||||
stm_gpio_config(QSPI_IO0_PIO_BASE, QSPI_IO0_PIN, 0, 0, 0);
|
||||
stm_gpio_config(QSPI_IO1_PIO_BASE, QSPI_IO1_PIN, 0, 0, 0);
|
||||
stm_gpio_config(QSPI_IO2_PIO_BASE, QSPI_IO2_PIN, 0, 0, 0);
|
||||
stm_gpio_config(QSPI_IO3_PIO_BASE, QSPI_IO3_PIN, 0, 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void spi_pins_release(void)
|
||||
static void RAMFUNCTION spi_reset(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
/* Set mode = 0 */
|
||||
SPI_PIO_MODE &= ~ (0x03 << (SPI1_CLOCK_PIN * 2));
|
||||
SPI_PIO_MODE &= ~ (0x03 << (SPI1_MOSI_PIN * 2));
|
||||
SPI_PIO_MODE &= ~ (0x03 << (SPI1_MISO_PIN * 2));
|
||||
|
||||
/* Alternate function clear */
|
||||
#if SPI1_CLOCK_PIN < 8
|
||||
SPI_PIO_AFL &= ~(0xf << ((SPI1_CLOCK_PIN) * 4));
|
||||
#else
|
||||
SPI_PIO_AFH &= ~(0xf << ((SPI1_CLOCK_PIN - 8) * 4));
|
||||
#ifdef QSPI_FLASH
|
||||
AHB3_CLOCK_RST |= RCC_AHB3ENR_QSPIEN;
|
||||
AHB3_CLOCK_RST &= ~RCC_AHB3ENR_QSPIEN;
|
||||
#endif
|
||||
#if SPI1_MOSI_PIN < 8
|
||||
SPI_PIO_AFL &= ~(0xf << ((SPI1_MOSI_PIN) * 4));
|
||||
#else
|
||||
SPI_PIO_AFL &= ~(0xf << ((SPI1_MOSI_PIN - 8) * 4));
|
||||
#endif
|
||||
#if SPI1_MISO_PIN < 8
|
||||
SPI_PIO_AFL &= ~(0xf << ((SPI1_MISO_PIN) * 4));
|
||||
#else
|
||||
SPI_PIO_AFL &= ~(0xf << ((SPI1_MISO_PIN - 8) * 4));
|
||||
#endif
|
||||
|
||||
/* Floating */
|
||||
SPI_PIO_PUPD &= ~ (0x03 << (SPI1_CLOCK_PIN * 2));
|
||||
SPI_PIO_PUPD &= ~ (0x03 << (SPI1_MOSI_PIN * 2));
|
||||
SPI_PIO_PUPD &= ~ (0x03 << (SPI1_MISO_PIN * 2));
|
||||
|
||||
/* Release CS */
|
||||
SPI_PIO_CS_MODE &= ~ (0x03 << (SPI_CS_FLASH * 2));
|
||||
SPI_PIO_CS_PUPD &= ~ (0x03 << (SPI_CS_FLASH * 2));
|
||||
|
||||
}
|
||||
|
||||
static void RAMFUNCTION spi1_reset(void)
|
||||
{
|
||||
#ifdef SPI_FLASH
|
||||
APB2_CLOCK_RST |= SPI1_APB2_CLOCK_ER_VAL;
|
||||
APB2_CLOCK_RST &= ~SPI1_APB2_CLOCK_ER_VAL;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef QSPI_FLASH
|
||||
int qspi_transfer(
|
||||
const uint8_t cmd, uint32_t addr, uint32_t addrSz,
|
||||
const uint8_t* txData, uint32_t txSz,
|
||||
uint8_t* rxData, uint32_t rxSz, uint32_t dummySz,
|
||||
uint32_t mode)
|
||||
{
|
||||
uint32_t fmode = 0, amode = 0;
|
||||
uint32_t adsz = 0, dsz = 0;
|
||||
uint8_t* dptr = NULL;
|
||||
|
||||
if (txData != NULL && txSz > 0) {
|
||||
fmode = 0; /* indirect write */
|
||||
dsz = txSz;
|
||||
dptr = (uint8_t*)txData;
|
||||
}
|
||||
else if (rxData != NULL && rxSz > 0) {
|
||||
fmode = 1; /* indirect read */
|
||||
dsz = rxSz;
|
||||
dptr = rxData;
|
||||
}
|
||||
else {
|
||||
mode = 0; /* no data */
|
||||
}
|
||||
|
||||
if (dsz > 0) {
|
||||
QUADSPI_DLR = dsz-1;
|
||||
}
|
||||
|
||||
if (addrSz > 0) {
|
||||
amode = 1;
|
||||
adsz = addrSz-1;
|
||||
}
|
||||
|
||||
/* Configure QSPI: CCR register with all communications parameters */
|
||||
/* mode 1=1SPI, 2=2SPI, 3=4SPI */
|
||||
QUADSPI_CCR = (
|
||||
QUADSPI_CCR_FMODE(fmode) | /* Functional Mode */
|
||||
QUADSPI_CCR_IMODE(1) | /* Instruction Mode */
|
||||
QUADSPI_CCR_ADMODE(amode) | /* Address Mode */
|
||||
QUADSPI_CCR_ADSIZE(adsz) | /* Address Size */
|
||||
QUADSPI_CCR_ABMODE(0) | /* Alternate byte (none) */
|
||||
QUADSPI_CCR_DMODE(mode) | /* Data Mode */
|
||||
QUADSPI_CCR_DCYC(dummySz) | /* Dummy Cycles (between instruction and read) */
|
||||
cmd /* Instruction / Command byte */
|
||||
);
|
||||
|
||||
/* Set command address 4 or 3 byte */
|
||||
QUADSPI_AR = addr;
|
||||
|
||||
while (dsz > 0U) {
|
||||
if (fmode == 0) {
|
||||
while ((QUADSPI_SR & QUADSPI_SR_FTF));
|
||||
QUADSPI_DR = *dptr;
|
||||
}
|
||||
else {
|
||||
while ((QUADSPI_SR & (QUADSPI_SR_FTF | QUADSPI_SR_TCF)) == 0);
|
||||
*dptr = QUADSPI_DR;
|
||||
}
|
||||
dsz--;
|
||||
dptr++;
|
||||
}
|
||||
|
||||
/* wait for transfer complete */
|
||||
while ((QUADSPI_SR & QUADSPI_SR_TCF) == 0);
|
||||
QUADSPI_FCR |= QUADSPI_SR_TCF; /* clear transfer complete */
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* QSPI_FLASH */
|
||||
|
||||
|
||||
#ifdef SPI_FLASH
|
||||
uint8_t RAMFUNCTION spi_read(void)
|
||||
{
|
||||
volatile uint32_t reg;
|
||||
|
@ -186,32 +273,86 @@ void RAMFUNCTION spi_write(const char byte)
|
|||
reg = SPI1_SR;
|
||||
} while ((reg & SPI_SR_TX_EMPTY) == 0);
|
||||
}
|
||||
#endif /* SPI_FLASH */
|
||||
|
||||
|
||||
static int initialized = 0;
|
||||
void RAMFUNCTION spi_init(int polarity, int phase)
|
||||
{
|
||||
static int initialized = 0;
|
||||
if (!initialized) {
|
||||
initialized++;
|
||||
spi1_pins_setup();
|
||||
spi_flash_pin_setup();
|
||||
spi_tpm2_pin_setup();
|
||||
APB2_CLOCK_ER |= SPI1_APB2_CLOCK_ER_VAL;
|
||||
spi1_reset();
|
||||
#ifdef PLATFORM_stm32l0
|
||||
SPI1_CR1 = SPI_CR1_MASTER | (polarity << 1) | (phase << 0);
|
||||
#else
|
||||
SPI1_CR1 = SPI_CR1_MASTER | (5 << 3) | (polarity << 1) | (phase << 0);
|
||||
|
||||
stm_pins_setup();
|
||||
|
||||
#ifdef SPI_FLASH
|
||||
stm_gpio_config(SPI_CS_PIO_BASE, SPI_CS_FLASH, SPI_CS_FLASH_AF, 1, 3);
|
||||
spi_cs_off(SPI_CS_PIO_BASE, SPI_CS_FLASH);
|
||||
#endif
|
||||
#ifdef WOLFBOOT_TPM
|
||||
stm_gpio_config(SPI_CS_TPM_PIO_BASE, SPI_CS_TPM, SPI_CS_TPM_AF, 1, 3);
|
||||
spi_cs_off(SPI_CS_TPM_PIO_BASE, SPI_CS_TPM);
|
||||
#endif
|
||||
|
||||
#ifdef QSPI_FLASH
|
||||
/* Enable QUADSPI clock on HCLK3 (240MHz max) */
|
||||
RCC_D1CCIPR &= ~RCC_D1CCIPR_QSPISEL_MASK;
|
||||
RCC_D1CCIPR |= RCC_D1CCIPR_QSPISEL(0);
|
||||
AHB3_CLOCK_EN |= RCC_AHB3ENR_QSPIEN;
|
||||
#endif
|
||||
#ifdef SPI_FLASH
|
||||
APB2_CLOCK_ER |= SPI1_APB2_CLOCK_ER_VAL;
|
||||
#endif
|
||||
|
||||
spi_reset();
|
||||
|
||||
#ifdef QSPI_FLASH
|
||||
/* Configure QSPI FIFO Threshold (1 byte) */
|
||||
QUADSPI_CR &= ~QUADSPI_CR_FTHRES_MASK;
|
||||
QUADSPI_CR |= QUADSPI_CR_FTHRES(1);
|
||||
|
||||
/* Wait till BUSY flag cleared */
|
||||
while (QUADSPI_SR & QUADSPI_SR_BUSY) {};
|
||||
|
||||
/* Configure QSPI Clock Prescaler (240/4=60 MHz), 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(30));
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Enable the QSPI peripheral */
|
||||
QUADSPI_CR |= QUADSPI_CR_EN;
|
||||
#endif /* QSPI_FLASH */
|
||||
#ifdef SPI_FLASH
|
||||
/* Configure SPI1 for master mode */
|
||||
# ifdef PLATFORM_stm32l0
|
||||
SPI1_CR1 = SPI_CR1_MASTER | (polarity << 1) | (phase << 0);
|
||||
# else
|
||||
/* baud rate 5 (hclk/6) */
|
||||
SPI1_CR1 = SPI_CR1_MASTER | (5 << 3) | (polarity << 1) | (phase << 0);
|
||||
# endif
|
||||
SPI1_CR2 |= SPI_CR2_SSOE;
|
||||
SPI1_CR1 |= SPI_CR1_SPI_EN;
|
||||
#endif /* SPI_FLASH */
|
||||
}
|
||||
}
|
||||
|
||||
void RAMFUNCTION spi_release(void)
|
||||
{
|
||||
spi1_reset();
|
||||
SPI1_CR2 &= ~SPI_CR2_SSOE;
|
||||
SPI1_CR1 = 0;
|
||||
spi_pins_release();
|
||||
if (initialized > 0) {
|
||||
initialized--;
|
||||
}
|
||||
if (initialized == 0) {
|
||||
spi_reset();
|
||||
#ifdef QSPI_FLASH
|
||||
QUADSPI_CR &= ~QUADSPI_CR_EN;
|
||||
#endif
|
||||
#ifdef SPI_FLASH
|
||||
SPI1_CR2 &= ~SPI_CR2_SSOE;
|
||||
SPI1_CR1 = 0;
|
||||
#endif
|
||||
stm_pins_release();
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SPI_FLASH || QSPI_FLASH */
|
||||
|
|
|
@ -17,17 +17,8 @@
|
|||
|
||||
#ifndef SPI_DRV_STM32_H_INCLUDED
|
||||
#define SPI_DRV_STM32_H_INCLUDED
|
||||
|
||||
#include <stdint.h>
|
||||
/** SPI settings **/
|
||||
|
||||
#define SPI1 (0x40013000)/* SPI1 base address */
|
||||
#define SPI1_APB2_CLOCK_ER_VAL (1 << 12)
|
||||
|
||||
#define CEN_GPIOA (1 << 0)
|
||||
#define CEN_GPIOB (1 << 1)
|
||||
#define CEN_GPIOC (1 << 2)
|
||||
#define CEN_GPIOD (1 << 3)
|
||||
#define CEN_GPIOE (1 << 4)
|
||||
|
||||
#ifdef PLATFORM_stm32f4
|
||||
#define APB2_CLOCK_ER (*(volatile uint32_t *)(0x40023844))
|
||||
|
@ -38,18 +29,18 @@
|
|||
#define GPIOC_BASE (0x40020800)
|
||||
#define GPIOD_BASE (0x40020C00)
|
||||
#define GPIOE_BASE (0x40021000)
|
||||
#define SPI_GPIO GPIOB_BASE
|
||||
#define SPI_CS_GPIO GPIOE_BASE
|
||||
#define SPI_CS_FLASH 1 /* Flash CS connected to GPIOE1 */
|
||||
#define SPI_CS_TPM 0 /* TPM CS connected to GPIOE0 */
|
||||
#define SPI1_PIN_AF 5 /* Alternate function for SPI pins */
|
||||
#define SPI1_CLOCK_PIN 3 /* SPI_SCK: PB3 */
|
||||
#define SPI1_MISO_PIN 4 /* SPI_MISO PB4 */
|
||||
#define SPI1_MOSI_PIN 5 /* SPI_MOSI PB5 */
|
||||
#endif
|
||||
#define SPI_GPIO GPIOB_BASE
|
||||
#define SPI_CS_GPIO GPIOE_BASE
|
||||
#define SPI_CS_FLASH 1 /* Flash CS connected to GPIOE1 */
|
||||
#define SPI_CS_TPM 0 /* TPM CS connected to GPIOE0 */
|
||||
#define SPI_PIN_AF 5 /* Alternate function for SPI pins */
|
||||
#define SPI_CLOCK_PIN 3 /* SPI_SCK: PB3 */
|
||||
#define SPI_MISO_PIN 4 /* SPI_MISO PB4 */
|
||||
#define SPI_MOSI_PIN 5 /* SPI_MOSI PB5 */
|
||||
#endif /* PLATFORM_stm32f4 */
|
||||
|
||||
|
||||
#ifdef PLATFORM_stm32u5
|
||||
|
||||
#ifdef TZEN
|
||||
#define PERIPH_BASE (0x50000000UL)
|
||||
#else
|
||||
|
@ -59,36 +50,34 @@
|
|||
#define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000UL)
|
||||
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x02020000UL)
|
||||
|
||||
#undef SPI1
|
||||
#define SPI1 (APB2PERIPH_BASE + 0x3000UL)
|
||||
#define SPI1_BASE (APB2PERIPH_BASE + 0x3000UL)
|
||||
|
||||
#define RCC_BASE (APB2PERIPH_BASE + 0x0C00UL)
|
||||
#define RCC_BASE (APB2PERIPH_BASE + 0x0C00UL)
|
||||
#define APB2_CLOCK_ER (*(volatile uint32_t *)(RCC_BASE + 0xA4))
|
||||
#define APB2_CLOCK_RST (*(volatile uint32_t *)(RCC_BASE + 0x7C))
|
||||
#define RCC_GPIO_CLOCK_ER (*(volatile uint32_t *)(RCC_BASE + 0x8C))
|
||||
|
||||
#define GPIO_BASE (APB2PERIPH_BASE + 0x02020000UL)
|
||||
#define GPIOA_BASE (GPIO_BASE + 0x00000UL)
|
||||
#define GPIOB_BASE (GPIO_BASE + 0x00400UL)
|
||||
#define GPIOC_BASE (GPIO_BASE + 0x00800UL)
|
||||
#define GPIOD_BASE (GPIO_BASE + 0x00C00UL)
|
||||
#define GPIOE_BASE (GPIO_BASE + 0x01000UL)
|
||||
#define GPIOF_BASE (GPIO_BASE + 0x01400UL)
|
||||
#define GPIOG_BASE (GPIO_BASE + 0x01800UL)
|
||||
#define GPIOH_BASE (GPIO_BASE + 0x01C00UL)
|
||||
#define GPIOI_BASE (GPIO_BASE + 0x02000UL)
|
||||
#define GPIO_BASE (APB2PERIPH_BASE + 0x02020000UL)
|
||||
#define GPIOA_BASE (GPIO_BASE + 0x00000UL)
|
||||
#define GPIOB_BASE (GPIO_BASE + 0x00400UL)
|
||||
#define GPIOC_BASE (GPIO_BASE + 0x00800UL)
|
||||
#define GPIOD_BASE (GPIO_BASE + 0x00C00UL)
|
||||
#define GPIOE_BASE (GPIO_BASE + 0x01000UL)
|
||||
#define GPIOF_BASE (GPIO_BASE + 0x01400UL)
|
||||
#define GPIOG_BASE (GPIO_BASE + 0x01800UL)
|
||||
#define GPIOH_BASE (GPIO_BASE + 0x01C00UL)
|
||||
#define GPIOI_BASE (GPIO_BASE + 0x02000UL)
|
||||
|
||||
/* STMOD+ Port */
|
||||
#define SPI_GPIO GPIOE_BASE
|
||||
#define SPI_CS_GPIO GPIOE_BASE
|
||||
#define SPI_CS_FLASH 11 /* Flash CS connected to GPIOE11 */
|
||||
#define SPI_CS_TPM 10 /* TPM CS connected to GPIOE10 */
|
||||
|
||||
#define SPI1_PIN_AF 5 /* Alternate function for SPI pins */
|
||||
#define SPI1_CLOCK_PIN 13 /* SPI_SCK: PE13 */
|
||||
#define SPI1_MISO_PIN 14 /* SPI_MISO PE14 */
|
||||
#define SPI1_MOSI_PIN 15 /* SPI_MOSI PE15 */
|
||||
#define SPI_GPIO GPIOE_BASE
|
||||
#define SPI_CS_GPIO GPIOE_BASE
|
||||
#define SPI_CS_FLASH 11 /* Flash CS connected to GPIOE11 */
|
||||
#define SPI_CS_TPM 10 /* TPM CS connected to GPIOE10 */
|
||||
|
||||
#define SPI_PIN_AF 5 /* Alternate function for SPI pins */
|
||||
#define SPI_CLOCK_PIN 13 /* SPI_SCK: PE13 */
|
||||
#define SPI_MISO_PIN 14 /* SPI_MISO PE14 */
|
||||
#define SPI_MOSI_PIN 15 /* SPI_MOSI PE15 */
|
||||
#endif /* PLATFORM_stm32u5 */
|
||||
|
||||
|
||||
|
@ -102,15 +91,16 @@
|
|||
#define GPIOD_BASE (0x48000C00)
|
||||
|
||||
/* STM32WB55 NUCLEO: CN9: D13=SCK, D12=MISO, D11=MOSI, FLASHCS=D10, TPMCS=D9 */
|
||||
#define SPI_GPIO GPIOA_BASE
|
||||
#define SPI_CS_GPIO GPIOA_BASE
|
||||
#define SPI_CS_FLASH 4 /* Flash CS connected to GPIOA4 */
|
||||
#define SPI_CS_TPM 9 /* TPM CS connected to GPIOA9 */
|
||||
#define SPI1_PIN_AF 5 /* Alternate function for SPI pins */
|
||||
#define SPI1_CLOCK_PIN 5 /* SPI_SCK: PA5 */
|
||||
#define SPI1_MISO_PIN 6 /* SPI_MISO PA6 */
|
||||
#define SPI1_MOSI_PIN 7 /* SPI_MOSI PA7 */
|
||||
#endif
|
||||
#define SPI_GPIO GPIOA_BASE
|
||||
#define SPI_CS_GPIO GPIOA_BASE
|
||||
#define SPI_CS_FLASH 4 /* Flash CS connected to GPIOA4 */
|
||||
#define SPI_CS_TPM 9 /* TPM CS connected to GPIOA9 */
|
||||
#define SPI_PIN_AF 5 /* Alternate function for SPI pins */
|
||||
#define SPI_CLOCK_PIN 5 /* SPI_SCK: PA5 */
|
||||
#define SPI_MISO_PIN 6 /* SPI_MISO PA6 */
|
||||
#define SPI_MOSI_PIN 7 /* SPI_MOSI PA7 */
|
||||
#endif /* PLATFORM_stm32wb */
|
||||
|
||||
|
||||
#ifdef PLATFORM_stm32l0
|
||||
#define APB2_CLOCK_ER (*(volatile uint32_t *)(0x40021034))
|
||||
|
@ -120,55 +110,206 @@
|
|||
#define GPIOB_BASE (0x50000400)
|
||||
|
||||
#define SPI_CS_GPIO GPIOB_BASE
|
||||
#define SPI1_PIN_AF 0 /* Alternate function for SPI pins */
|
||||
#define SPI_PIN_AF 0 /* Alternate function for SPI pins */
|
||||
|
||||
#ifndef SPI_ALT_CONFIGURATION
|
||||
#define SPI_GPIO GPIOB_BASE
|
||||
#define SPI_CS_FLASH 8 /* Flash CS connected to GPIOB8 */
|
||||
#define SPI1_CLOCK_PIN 3 /* SPI_SCK: PB3 */
|
||||
#define SPI1_MISO_PIN 4 /* SPI_MISO PB4 */
|
||||
#define SPI1_MOSI_PIN 5 /* SPI_MOSI PB5 */
|
||||
#define SPI_GPIO GPIOB_BASE
|
||||
#define SPI_CS_FLASH 8 /* Flash CS connected to GPIOB8 */
|
||||
#define SPI_CLOCK_PIN 3 /* SPI_SCK: PB3 */
|
||||
#define SPI_MISO_PIN 4 /* SPI_MISO PB4 */
|
||||
#define SPI_MOSI_PIN 5 /* SPI_MOSI PB5 */
|
||||
#else
|
||||
#define SPI_GPIO GPIOA_BASE
|
||||
#define SPI_CS_FLASH 6 /* Flash CS connected to GPIOB6 */
|
||||
#define SPI1_CLOCK_PIN 5 /* SPI_SCK: PA5 */
|
||||
#define SPI1_MISO_PIN 6 /* SPI_MISO PA6 */
|
||||
#define SPI1_MOSI_PIN 7 /* SPI_MOSI PA7 */
|
||||
#define SPI_GPIO GPIOA_BASE
|
||||
#define SPI_CS_FLASH 6 /* Flash CS connected to GPIOB6 */
|
||||
#define SPI_CLOCK_PIN 5 /* SPI_SCK: PA5 */
|
||||
#define SPI_MISO_PIN 6 /* SPI_MISO PA6 */
|
||||
#define SPI_MOSI_PIN 7 /* SPI_MOSI PA7 */
|
||||
#endif /* SPI_ALT_CONFIGURATION */
|
||||
#endif /* PLATFORM_stm32l0 */
|
||||
|
||||
#define SPI_PIO_BASE SPI_GPIO
|
||||
#define SPI_CS_PIO_BASE SPI_CS_GPIO
|
||||
|
||||
#if (SPI_GPIO == GPIOA_BASE)
|
||||
# define SPI_PIO_CEN CEN_GPIOA
|
||||
#elif (SPI_GPIO == GPIOB_BASE)
|
||||
# define SPI_PIO_CEN CEN_GPIOB
|
||||
#elif (SPI_GPIO == GPIOC_BASE)
|
||||
# define SPI_PIO_CEN CEN_GPIOC
|
||||
#elif (SPI_GPIO == GPIOD_BASE)
|
||||
# define SPI_PIO_CEN CEN_GPIOD
|
||||
#elif (SPI_GPIO == GPIOE_BASE)
|
||||
# define SPI_PIO_CEN CEN_GPIOE
|
||||
#ifdef PLATFORM_stm32h7
|
||||
|
||||
#define RCC_BASE (0x58024400UL)
|
||||
#define RCC_GPIO_CLOCK_ER (*(volatile uint32_t *)(RCC_BASE + 0xE0)) /* RM0433 - 8.7.43 (RCC_AHB4ENR) */
|
||||
#define APB2_CLOCK_ER (*(volatile uint32_t *)(RCC_BASE + 0xF0)) /* RM0433 - 8.7.47 */
|
||||
#define APB2_CLOCK_RST (*(volatile uint32_t *)(RCC_BASE + 0x98)) /* RM0433 - 8.7.35 */
|
||||
|
||||
#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)
|
||||
|
||||
|
||||
/** QSPI **/
|
||||
/* Default Base (E) and AF (alternate function=10) for QSPI */
|
||||
#define QSPI_GPIO GPIOE_BASE
|
||||
#define QSPI_PIN_AF 10
|
||||
|
||||
/* QSPI uses hclk3 (240MHz max) by default */
|
||||
#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 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)
|
||||
|
||||
/* QSPI CLK PB2 */
|
||||
#define QSPI_CLOCK_PIO_BASE GPIOB_BASE
|
||||
#define QSPI_CLOCK_PIN 2
|
||||
#define QSPI_CLOCK_PIN_AF 9
|
||||
|
||||
/* nQSPI_CS PG6 (alt PB6) */
|
||||
#ifndef QSPI_ALT_CONFIGURATION
|
||||
#define QSPI_CS_PIO_BASE GPIOG_BASE
|
||||
#define QSPI_CS_FLASH_PIN 6
|
||||
#define QSPI_CS_FLASH_AF 10
|
||||
#else
|
||||
#define QSPI_CS_PIO_BASE GPIOB_BASE
|
||||
#define QSPI_CS_FLASH_PIN 6
|
||||
#define QSPI_CS_FLASH_AF 10
|
||||
#endif
|
||||
|
||||
#if (SPI_CS_GPIO == GPIOA_BASE)
|
||||
# define SPI_PIO_CS_CEN CEN_GPIOA
|
||||
#elif (SPI_CS_GPIO == GPIOB_BASE)
|
||||
# define SPI_PIO_CS_CEN CEN_GPIOB
|
||||
#elif (SPI_CS_GPIO == GPIOC_BASE)
|
||||
# define SPI_PIO_CS_CEN CEN_GPIOC
|
||||
#elif (SPI_CS_GPIO == GPIOD_BASE)
|
||||
# define SPI_PIO_CS_CEN CEN_GPIOD
|
||||
#elif (SPI_CS_GPIO == GPIOE_BASE)
|
||||
# define SPI_PIO_CS_CEN CEN_GPIOE
|
||||
/* QSPI_IO0 (MOSI) - PD11 (alt PE7) */
|
||||
#ifndef QSPI_ALT_CONFIGURATION
|
||||
#define QSPI_IO0_PIO_BASE GPIOD_BASE
|
||||
#define QSPI_IO0_PIN 11
|
||||
#define QSPI_IO0_PIN_AF 9
|
||||
#else
|
||||
#define QSPI_IO0_PIO_BASE GPIOE_BASE
|
||||
#define QSPI_IO0_PIN 7
|
||||
#define QSPI_IO0_PIN_AF 10
|
||||
#endif
|
||||
|
||||
/* QSPI_IO1 (MISO) - PD12 (alt PE8) */
|
||||
#ifndef QSPI_ALT_CONFIGURATION
|
||||
#define QSPI_IO1_PIO_BASE GPIOD_BASE
|
||||
#define QSPI_IO1_PIN 12
|
||||
#define QSPI_IO1_PIN_AF 9
|
||||
#else
|
||||
#define QSPI_IO1_PIO_BASE GPIOE_BASE
|
||||
#define QSPI_IO1_PIN 8
|
||||
#define QSPI_IO1_PIN_AF 10
|
||||
#endif
|
||||
|
||||
#define SPI1_CR1 (*(volatile uint32_t *)(SPI1))
|
||||
#define SPI1_CR2 (*(volatile uint32_t *)(SPI1 + 0x04))
|
||||
#define SPI1_SR (*(volatile uint32_t *)(SPI1 + 0x08))
|
||||
#define SPI1_DR (*(volatile uint32_t *)(SPI1 + 0x0c))
|
||||
/* QSPI_IO2 - PE2 (alt PE9) */
|
||||
#ifndef QSPI_ALT_CONFIGURATION
|
||||
#define QSPI_IO2_PIO_BASE GPIOE_BASE
|
||||
#define QSPI_IO2_PIN 2
|
||||
#define QSPI_IO2_PIN_AF 9
|
||||
#else
|
||||
#define QSPI_IO2_PIO_BASE GPIOE_BASE
|
||||
#define QSPI_IO2_PIN 9
|
||||
#define QSPI_IO2_PIN_AF 10
|
||||
#endif
|
||||
|
||||
/* QSPI_IO3 - PD13 (alt PE10) */
|
||||
#ifndef QSPI_ALT_CONFIGURATION
|
||||
#define QSPI_IO3_PIO_BASE GPIOD_BASE
|
||||
#define QSPI_IO3_PIN 13
|
||||
#define QSPI_IO3_PIN_AF 9
|
||||
#else
|
||||
#define QSPI_IO3_PIO_BASE GPIOE_BASE
|
||||
#define QSPI_IO3_PIN 10
|
||||
#endif
|
||||
|
||||
#endif /* PLATFORM_stm32h7 */
|
||||
|
||||
|
||||
/* Setup SPI PIO Bases */
|
||||
#ifndef SPI_CLOCK_PIO_BASE
|
||||
#define SPI_CLOCK_PIO_BASE SPI_GPIO
|
||||
#endif
|
||||
#ifndef SPI_MISO_PIO_BASE
|
||||
#define SPI_MISO_PIO_BASE SPI_GPIO
|
||||
#endif
|
||||
#ifndef SPI_MOSI_PIO_BASE
|
||||
#define SPI_MOSI_PIO_BASE SPI_GPIO
|
||||
#endif
|
||||
#ifndef SPI_CS_PIO_BASE
|
||||
#define SPI_CS_PIO_BASE SPI_CS_GPIO
|
||||
#endif
|
||||
#ifndef SPI_CS_TPM_PIO_BASE
|
||||
#define SPI_CS_TPM_PIO_BASE SPI_CS_GPIO
|
||||
#endif
|
||||
|
||||
#ifdef QSPI_FLASH
|
||||
#ifndef QSPI_CS_PIO_BASE
|
||||
#define QSPI_CS_PIO_BASE QSPI_CS_GPIO
|
||||
#endif
|
||||
#ifndef QSPI_CLOCK_PIO_BASE
|
||||
#define QSPI_CLOCK_PIO_BASE QSPI_GPIO
|
||||
#endif
|
||||
#ifndef QSPI_IO0_PIO_BASE
|
||||
#define QSPI_IO0_PIO_BASE QSPI_GPIO
|
||||
#endif
|
||||
#ifndef QSPI_IO1_PIO_BASE
|
||||
#define QSPI_IO1_PIO_BASE QSPI_GPIO
|
||||
#endif
|
||||
#ifndef QSPI_IO2_PIO_BASE
|
||||
#define QSPI_IO2_PIO_BASE QSPI_GPIO
|
||||
#endif
|
||||
#ifndef QSPI_IO3_PIO_BASE
|
||||
#define QSPI_IO3_PIO_BASE QSPI_GPIO
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Setup alternate functions */
|
||||
#ifndef SPI_CLOCK_PIN_AF
|
||||
#define SPI_CLOCK_PIN_AF SPI_PIN_AF
|
||||
#endif
|
||||
#ifndef SPI_MISO_PIN_AF
|
||||
#define SPI_MISO_PIN_AF SPI_PIN_AF
|
||||
#endif
|
||||
#ifndef SPI_MOSI_PIN_AF
|
||||
#define SPI_MOSI_PIN_AF SPI_PIN_AF
|
||||
#endif
|
||||
#ifndef SPI_CS_FLASH_AF
|
||||
#define SPI_CS_FLASH_AF SPI_PIN_AF
|
||||
#endif
|
||||
#ifndef SPI_CS_TPM_AF
|
||||
#define SPI_CS_TPM_AF SPI_PIN_AF
|
||||
#endif
|
||||
|
||||
#ifdef QSPI_FLASH
|
||||
#ifndef QSPI_CS_FLASH_AF
|
||||
#define QSPI_CS_FLASH_AF QSPI_PIN_AF
|
||||
#endif
|
||||
#ifndef QSPI_CLOCK_PIN_AF
|
||||
#define QSPI_CLOCK_PIN_AF QSPI_PIN_AF
|
||||
#endif
|
||||
#ifndef QSPI_IO0_PIN_AF
|
||||
#define QSPI_IO0_PIN_AF QSPI_PIN_AF
|
||||
#endif
|
||||
#ifndef QSPI_IO1_PIN_AF
|
||||
#define QSPI_IO1_PIN_AF QSPI_PIN_AF
|
||||
#endif
|
||||
#ifndef QSPI_IO2_PIN_AF
|
||||
#define QSPI_IO2_PIN_AF QSPI_PIN_AF
|
||||
#endif
|
||||
#ifndef QSPI_IO3_PIN_AF
|
||||
#define QSPI_IO3_PIN_AF QSPI_PIN_AF
|
||||
#endif
|
||||
#endif /* QSPI_FLASH */
|
||||
|
||||
|
||||
#define GPIO_MODE_AF (2)
|
||||
|
||||
|
||||
/* SPI */
|
||||
#ifndef SPI1_BASE
|
||||
#define SPI1_BASE (0x40013000) /* SPI1 base address */
|
||||
#endif
|
||||
|
||||
#define SPI1_APB2_CLOCK_ER_VAL (1 << 12)
|
||||
|
||||
#define SPI1_CR1 (*(volatile uint32_t *)(SPI1_BASE))
|
||||
#define SPI1_CR2 (*(volatile uint32_t *)(SPI1_BASE + 0x04))
|
||||
#define SPI1_SR (*(volatile uint32_t *)(SPI1_BASE + 0x08))
|
||||
#define SPI1_DR (*(volatile uint32_t *)(SPI1_BASE + 0x0c))
|
||||
|
||||
#define SPI_CR1_CLOCK_PHASE (1 << 0)
|
||||
#define SPI_CR1_CLOCK_POLARITY (1 << 1)
|
||||
|
@ -184,26 +325,79 @@
|
|||
#define SPI_CR1_BIDIOE (1 << 14)
|
||||
#define SPI_CR2_SSOE (1 << 2)
|
||||
|
||||
|
||||
#define SPI_SR_RX_NOTEMPTY (1 << 0)
|
||||
#define SPI_SR_TX_EMPTY (1 << 1)
|
||||
#define SPI_SR_BUSY (1 << 7)
|
||||
|
||||
#define SPI_PIO_MODE(base) (*(volatile uint32_t *)(base + 0x00))
|
||||
#define SPI_PIO_AFL(base) (*(volatile uint32_t *)(base + 0x20))
|
||||
#define SPI_PIO_AFH(base) (*(volatile uint32_t *)(base + 0x24))
|
||||
#define SPI_PIO_OSPD(base) (*(volatile uint32_t *)(base + 0x08))
|
||||
#define SPI_PIO_PUPD(base) (*(volatile uint32_t *)(base + 0x0c))
|
||||
#define SPI_PIO_ODR(base) (*(volatile uint32_t *)(base + 0x14))
|
||||
#define SPI_PIO_BSRR(base) (*(volatile uint32_t *)(base + 0x18))
|
||||
|
||||
#define SPI_PIO_MODE (*(volatile uint32_t *)(SPI_PIO_BASE + 0x00))
|
||||
#define SPI_PIO_AFL (*(volatile uint32_t *)(SPI_PIO_BASE + 0x20))
|
||||
#define SPI_PIO_AFH (*(volatile uint32_t *)(SPI_PIO_BASE + 0x24))
|
||||
#define SPI_PIO_OSPD (*(volatile uint32_t *)(SPI_PIO_BASE + 0x08))
|
||||
#define SPI_PIO_PUPD (*(volatile uint32_t *)(SPI_PIO_BASE + 0x0c))
|
||||
#define SPI_PIO_BSRR (*(volatile uint32_t *)(SPI_PIO_BASE + 0x18))
|
||||
#define SPI_PIO_CS_MODE (*(volatile uint32_t *)(SPI_CS_PIO_BASE + 0x00))
|
||||
#define SPI_PIO_CS_AFL (*(volatile uint32_t *)(SPI_CS_PIO_BASE + 0x20))
|
||||
#define SPI_PIO_CS_AFH (*(volatile uint32_t *)(SPI_CS_PIO_BASE + 0x24))
|
||||
#define SPI_PIO_CS_OSPD (*(volatile uint32_t *)(SPI_CS_PIO_BASE + 0x08))
|
||||
#define SPI_PIO_CS_PUPD (*(volatile uint32_t *)(SPI_CS_PIO_BASE + 0x0c))
|
||||
#define SPI_PIO_CS_BSRR (*(volatile uint32_t *)(SPI_CS_PIO_BASE + 0x18))
|
||||
#define SPI_PIO_CS_ODR (*(volatile uint32_t *)(SPI_CS_PIO_BASE + 0x14))
|
||||
#define GPIO_MODE_AF (2)
|
||||
|
||||
/* QUADSPI */
|
||||
#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 + 0x23)) /* Data register */
|
||||
#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_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_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 */
|
||||
#define QUADSPI_CCR_FRCM (1 << 29) /* Free running clock mode */
|
||||
#define QUADSPI_CCR_SIOO (1 << 28) /* Send instruction only once mode */
|
||||
#define QUADSPI_CCR_FMODE_MASK (0x3 << 26)
|
||||
#define QUADSPI_CCR_FMODE(fmode) (((fmode) & 0x3) << 26) /* Functional Mode (0=indirect write, 1=indirect read, 2=auto poll, 3=mem mapped) */
|
||||
#define QUADSPI_CCR_DMODE_MASK (0x3 << 24)
|
||||
#define QUADSPI_CCR_DMODE(dmode) (((dmode) & 0x3) << 24) /* Data mode (0=no data, 1=data on single line, 2=data on two lines, 3=data on four lines) */
|
||||
#define QUADSPI_CCR_DCYC_MASK (0x1F << 18)
|
||||
#define QUADSPI_CCR_DCYC(dcyc) (((dcyc) & 0x1F) << 18) /* Number of dummy cycles */
|
||||
#define QUADSPI_CCR_ABSIZE_MASK (0x3 << 16)
|
||||
#define QUADSPI_CCR_ABSIZE(absz) (((absz) & 0x3) << 16) /* Alternate bytes size */
|
||||
#define QUADSPI_CCR_ABMODE_MASK (0x3 << 14)
|
||||
#define QUADSPI_CCR_ABMODE(abmode) (((abmode) & 0x3) << 14) /* Alternate bytes mode (0=no alt data, 1=alt on single line, 2=alt on two lines, 3=alt on four lines) */
|
||||
#define QUADSPI_CCR_ADSIZE_MASK (0x3 << 12)
|
||||
#define QUADSPI_CCR_ADSIZE(sz) (((sz) & 0x3) << 12) /* Address bytes size (0=8-bit, 1=16-bit, 2=24-bit, 3=32-bit) */
|
||||
#define QUADSPI_CCR_ADMODE_MASK (0x3 << 10)
|
||||
#define QUADSPI_CCR_ADMODE(admode) (((admode) & 0x3) << 10) /* Address mode (0=no addr, 1=addr on single line, 2=addr on two lines, 3=addr on four lines) */
|
||||
#define QUADSPI_CCR_IMODE_MASK (0x3 << 8)
|
||||
#define QUADSPI_CCR_IMODE(imode) (((imode) & 0x3) << 8) /* Instruction mode (0=no instr, 1=instr on single line, 2=instr on two lines, 3=instr on four lines) */
|
||||
#define QUADSPI_CCR_INSTRUCTION_MASK (0xFF << 0)
|
||||
#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_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 */
|
||||
#define QUADSPI_DCR_CKMODE_0 (0) /* Clock mode 0 - clk low while nCS released */
|
||||
|
||||
#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 */
|
||||
|
||||
#endif /* !SPI_DRV_STM32_H_INCLUDED */
|
||||
|
|
|
@ -31,13 +31,15 @@
|
|||
|
||||
#ifdef SPI_FLASH
|
||||
|
||||
void spi_cs_off(int pin)
|
||||
void spi_cs_off(uint32_t base, int pin)
|
||||
{
|
||||
(void)base;
|
||||
(void)pin;
|
||||
}
|
||||
|
||||
void spi_cs_on(int pin)
|
||||
void spi_cs_on(uint32_t base, int pin)
|
||||
{
|
||||
(void)base;
|
||||
(void)pin;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#define SPI_DRV_ZYNQ_H_INCLUDED
|
||||
#include <stdint.h>
|
||||
|
||||
#define SPI_CS_FLASH 0
|
||||
#define SPI_CS_FLASH 0
|
||||
#define SPI_CS_PIO_BASE 0UL
|
||||
|
||||
#endif /* !SPI_DRV_ZYNQ_H_INCLUDED */
|
||||
|
|
|
@ -343,7 +343,7 @@ void hal_init(void)
|
|||
void hal_prepare_boot(void)
|
||||
{
|
||||
#ifdef SPI_FLASH
|
||||
spi_release();
|
||||
spi_flash_release();
|
||||
#endif
|
||||
|
||||
clock_pll_off();
|
||||
|
|
|
@ -114,7 +114,7 @@
|
|||
#define FLASH_OPTKEY2 (0x4C5D6E7F)
|
||||
|
||||
|
||||
/* FLASH Geometry
|
||||
/* FLASH Geometry
|
||||
*
|
||||
* per ST AN4826, two configurations are possible on STM32F7:
|
||||
*
|
||||
|
@ -421,7 +421,7 @@ void hal_init(void)
|
|||
void RAMFUNCTION hal_prepare_boot(void)
|
||||
{
|
||||
#ifdef SPI_FLASH
|
||||
spi_release();
|
||||
spi_flash_release();
|
||||
#endif
|
||||
|
||||
clock_pll_off();
|
||||
|
|
|
@ -331,7 +331,7 @@ static void RAMFUNCTION do_secure_boot(void)
|
|||
void RAMFUNCTION hal_prepare_boot(void)
|
||||
{
|
||||
#ifdef SPI_FLASH
|
||||
spi_release();
|
||||
spi_flash_release();
|
||||
#endif
|
||||
clock_pll_off();
|
||||
#ifdef FLASH_SECURABLE_MEMORY_SUPPORT
|
||||
|
|
302
hal/stm32h7.c
302
hal/stm32h7.c
|
@ -30,7 +30,6 @@
|
|||
|
||||
/* 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 */
|
||||
|
@ -42,10 +41,15 @@
|
|||
#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 APB1_CLOCK_LER (*(volatile uint32_t *)(RCC_BASE + 0xE8)) /* RM0433 - 7.7.45 */
|
||||
#define APB1_CLOCK_HER (*(volatile uint32_t *)(RCC_BASE + 0xEC)) /* RM0433 - 7.7.46 */
|
||||
#define APB2_CLOCK_ER (*(volatile uint32_t *)(RCC_BASE + 0xF0)) /* RM0433 - 7.7.47 */
|
||||
#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)
|
||||
|
@ -72,6 +76,25 @@
|
|||
|
||||
#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 */
|
||||
|
@ -95,6 +118,85 @@
|
|||
#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 */
|
||||
#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 */
|
||||
#endif
|
||||
|
||||
#define UART_PIN_AF 7 /* AF stands for Alternate Function. USART TX/RX */
|
||||
|
||||
/* 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 USART_CR2_LINEN (1 << 14)
|
||||
#define USART_CR2_CLKEN (1 << 11)
|
||||
|
||||
#define USART_CR3_SCEN (1 << 5)
|
||||
#define USART_CR3_HDSEL (1 << 3)
|
||||
#define USART_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_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 */
|
||||
|
||||
|
@ -102,25 +204,25 @@
|
|||
#define FLASH_ACR (*(volatile uint32_t *)(FLASH_BASE + 0x00)) /* RM0433 - 3.9.1 - FLASH_ACR */
|
||||
#define FLASH_OPTSR_CUR (*(volatile uint32_t *)(FLASH_BASE + 0x1C))
|
||||
|
||||
/*bank 1 */
|
||||
#define FLASH_KEYR1 (*(volatile uint32_t *)(FLASH_BASE + 0x04)) /* RM0433 - 3.9.2 - FLASH_KEYR 1 */
|
||||
#define FLASH_SR1 (*(volatile uint32_t *)(FLASH_BASE + 0x10)) /* RM0433 - 3.9.5 - FLASH_SR 1 */
|
||||
#define FLASH_CR1 (*(volatile uint32_t *)(FLASH_BASE + 0x0C)) /* RM0433 - 3.9.4 - FLASH_CR 1 */
|
||||
/* Bank 1 */
|
||||
#define FLASH_KEYR1 (*(volatile uint32_t *)(FLASH_BASE + 0x04)) /* RM0433 - 3.9.2 - FLASH_KEYR 1 */
|
||||
#define FLASH_SR1 (*(volatile uint32_t *)(FLASH_BASE + 0x10)) /* RM0433 - 3.9.5 - FLASH_SR 1 */
|
||||
#define FLASH_CR1 (*(volatile uint32_t *)(FLASH_BASE + 0x0C)) /* RM0433 - 3.9.4 - FLASH_CR 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 */
|
||||
/* 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_ACR_LATENCY_MASK (0x07)
|
||||
#define FLASH_SR_BSY (1 << 0)
|
||||
#define FLASH_SR_WBNE (1 << 1)
|
||||
#define FLASH_SR_QW (1 << 2)
|
||||
|
@ -148,8 +250,8 @@
|
|||
#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 (0x45670123)
|
||||
#define FLASH_KEY2 (0xCDEF89AB)
|
||||
#define FLASH_KEY1 (0x45670123)
|
||||
#define FLASH_KEY2 (0xCDEF89AB)
|
||||
|
||||
|
||||
/* STM32H7: Due to ECC functionality, it is not possible to write partition/sector
|
||||
|
@ -182,33 +284,37 @@ static void RAMFUNCTION flash_set_waitstates(unsigned int waitstates)
|
|||
{
|
||||
uint32_t reg = FLASH_ACR;
|
||||
if ((reg & FLASH_ACR_LATENCY_MASK) != waitstates)
|
||||
FLASH_ACR = (reg & ~FLASH_ACR_LATENCY_MASK) | waitstates;
|
||||
FLASH_ACR = (reg & ~FLASH_ACR_LATENCY_MASK) | waitstates;
|
||||
}
|
||||
|
||||
static RAMFUNCTION void flash_wait_last(void)
|
||||
{
|
||||
while((FLASH_OPTSR_CUR & FLASH_OPTSR_CUR_BSY))
|
||||
while ((FLASH_OPTSR_CUR & FLASH_OPTSR_CUR_BSY))
|
||||
;
|
||||
}
|
||||
|
||||
static RAMFUNCTION void flash_wait_complete(uint8_t bank)
|
||||
{
|
||||
if (bank==0)
|
||||
while ((FLASH_SR1 & FLASH_SR_QW) == FLASH_SR_QW);
|
||||
if (bank==1)
|
||||
while ((FLASH_SR2 & FLASH_SR_QW) == FLASH_SR_QW);
|
||||
if (bank == 0) {
|
||||
while ((FLASH_SR1 & FLASH_SR_QW) == FLASH_SR_QW);
|
||||
}
|
||||
else {
|
||||
while ((FLASH_SR2 & FLASH_SR_QW) == FLASH_SR_QW);
|
||||
}
|
||||
}
|
||||
|
||||
static void RAMFUNCTION flash_clear_errors(uint8_t bank)
|
||||
{
|
||||
if (bank==0)
|
||||
if (bank == 0) {
|
||||
FLASH_SR1 |= (FLASH_SR_WRPERR | FLASH_SR_PGSERR | FLASH_SR_STRBERR |
|
||||
FLASH_SR_INCERR | FLASH_SR_OPERR | FLASH_SR_RDPERR |
|
||||
FLASH_SR_RDSERR | FLASH_SR_SNECCERR | FLASH_SR_DBECCERR);
|
||||
if (bank==1)
|
||||
}
|
||||
else {
|
||||
FLASH_SR2 |= (FLASH_SR_WRPERR | FLASH_SR_PGSERR | FLASH_SR_STRBERR |
|
||||
FLASH_SR_INCERR | FLASH_SR_OPERR | FLASH_SR_RDPERR |
|
||||
FLASH_SR_RDSERR | FLASH_SR_SNECCERR | FLASH_SR_DBECCERR);
|
||||
}
|
||||
}
|
||||
|
||||
static void RAMFUNCTION flash_program_on(uint8_t bank)
|
||||
|
@ -217,7 +323,8 @@ static void RAMFUNCTION flash_program_on(uint8_t bank)
|
|||
FLASH_CR1 |= FLASH_CR_PG;
|
||||
while ((FLASH_CR1 & FLASH_CR_PG) == 0)
|
||||
;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
FLASH_CR2 |= FLASH_CR_PG;
|
||||
while ((FLASH_CR2 & FLASH_CR_PG) == 0)
|
||||
;
|
||||
|
@ -228,7 +335,8 @@ static void RAMFUNCTION flash_program_off(uint8_t bank)
|
|||
{
|
||||
if (bank == 0) {
|
||||
FLASH_CR1 &= ~FLASH_CR_PG;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
FLASH_CR2 &= ~FLASH_CR_PG;
|
||||
}
|
||||
}
|
||||
|
@ -261,7 +369,8 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
|
|||
dst[ii] = src[ii];
|
||||
}
|
||||
i+=32;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
int off = (address + i) - (((address + i) >> 5) << 5);
|
||||
uint32_t base_addr = (address + i) & (~0x1F); /* aligned to 256 bit */
|
||||
dst = (uint32_t *)(base_addr);
|
||||
|
@ -274,15 +383,17 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
|
|||
return -1;
|
||||
hal_flash_erase(STM32H7_PART_BOOT_FLAGS_PAGE_ADDRESS,
|
||||
STM32H7_SECTOR_SIZE);
|
||||
} else if (STM32H7_UPDATE_FLAGS_PAGE(address)) {
|
||||
}
|
||||
else if (STM32H7_UPDATE_FLAGS_PAGE(address)) {
|
||||
if (base_addr != STM32H7_PART_UPDATE_END - STM32H7_WORD_SIZE)
|
||||
return -1;
|
||||
hal_flash_erase(STM32H7_PART_UPDATE_FLAGS_PAGE_ADDRESS,
|
||||
STM32H7_SECTOR_SIZE);
|
||||
}
|
||||
/* Replace bytes in cache */
|
||||
while ((off < STM32H7_WORD_SIZE) && (i < len))
|
||||
while ((off < STM32H7_WORD_SIZE) && (i < len)) {
|
||||
vbytes[off++] = data[i++];
|
||||
}
|
||||
|
||||
/* Actual write from cache to FLASH */
|
||||
flash_wait_last();
|
||||
|
@ -350,8 +461,7 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
|
|||
p < end_address;
|
||||
p += FLASH_PAGE_SIZE)
|
||||
{
|
||||
if (p < FLASH_BANK2_BASE_REL)
|
||||
{
|
||||
if (p < FLASH_BANK2_BASE_REL) {
|
||||
uint32_t reg = FLASH_CR1 &
|
||||
(~((FLASH_CR_SNB_MASK << FLASH_CR_SNB_SHIFT) | FLASH_CR_PSIZE));
|
||||
FLASH_CR1 = reg |
|
||||
|
@ -361,8 +471,7 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
|
|||
flash_wait_complete(1);
|
||||
}
|
||||
if ((p>= FLASH_BANK2_BASE_REL) &&
|
||||
(p <= (FLASH_TOP - FLASHMEM_ADDRESS_SPACE)))
|
||||
{
|
||||
(p <= (FLASH_TOP - FLASHMEM_ADDRESS_SPACE))) {
|
||||
uint32_t reg = FLASH_CR2 &
|
||||
(~((FLASH_CR_SNB_MASK << FLASH_CR_SNB_SHIFT) | FLASH_CR_PSIZE));
|
||||
p-= (FLASH_BANK2_BASE);
|
||||
|
@ -376,6 +485,108 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_UART
|
||||
static int uart_init(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
/* Set general UART clock source (all uarts but nr 1 and 6) */
|
||||
/* USART234578SEL bits 2:0 */
|
||||
RCC_D2CCIP2R &= ~(0x7 << 0);
|
||||
RCC_D2CCIP2R |= (0x3 << 0); /* 000 = pclk1 (120MHz), 011 = hsi (64MHz) */
|
||||
|
||||
#if UART_PORT == 3
|
||||
/* Enable clock for USART_3 and reset */
|
||||
APB1_CLOCK_LER |= RCC_APB1_USART3_EN;
|
||||
|
||||
APB1_CLOCK_LRST |= RCC_APB1_USART3_EN;
|
||||
APB1_CLOCK_LRST &= ~RCC_APB1_USART3_EN;
|
||||
#else
|
||||
/* Enable clock for USART_2 and reset */
|
||||
APB1_CLOCK_LER |= RCC_APB1_USART2_EN;
|
||||
|
||||
APB1_CLOCK_LRST |= RCC_APB1_USART2_EN;
|
||||
APB1_CLOCK_LRST &= ~RCC_APB1_USART2_EN;
|
||||
#endif
|
||||
|
||||
/* Enable UART pins */
|
||||
AHB4_CLOCK_ENR |= RCC_AHB4_GPIOD_EN;
|
||||
|
||||
/* Set mode = AF. The PORT D I/O pin is first reset and then set to AF
|
||||
* (bit config 10:Alternate function mode) */
|
||||
reg = GPIO_MODE(UART_GPIO_BASE) & ~(0x03 << (UART_TX_PIN * 2));
|
||||
GPIO_MODE(UART_GPIO_BASE) = reg | (2 << (UART_TX_PIN * 2));
|
||||
reg = GPIO_MODE(UART_GPIO_BASE) & ~(0x03 << (UART_RX_PIN * 2));
|
||||
GPIO_MODE(UART_GPIO_BASE) = reg | (2 << (UART_RX_PIN * 2));
|
||||
|
||||
/* Alternate function. Use AFLR for pins 0-7 and AFHR for pins 8-15 */
|
||||
#if UART_TX_PIN < 8
|
||||
reg = GPIO_AFRL(UART_GPIO_BASE) & ~(0xf << ((UART_TX_PIN) * 4));
|
||||
GPIO_AFRL(UART_GPIO_BASE) = reg | (UART_PIN_AF << ((UART_TX_PIN) * 4));
|
||||
#else
|
||||
reg = GPIO_AFRH(UART_GPIO_BASE) & ~(0xf << ((UART_TX_PIN - 8) * 4));
|
||||
GPIO_AFRH(UART_GPIO_BASE) = reg | (UART_PIN_AF << ((UART_TX_PIN - 8) * 4));
|
||||
#endif
|
||||
#if UART_RX_PIN < 8
|
||||
reg = GPIO_AFRL(UART_GPIO_BASE) & ~(0xf << ((UART_RX_PIN)*4));
|
||||
GPIO_AFRL(UART_GPIO_BASE) = reg | (UART_PIN_AF << ((UART_RX_PIN)*4));
|
||||
#else
|
||||
reg = GPIO_AFRH(UART_GPIO_BASE) & ~(0xf << ((UART_RX_PIN - 8) * 4));
|
||||
GPIO_AFRH(UART_GPIO_BASE) = reg | (UART_PIN_AF << ((UART_RX_PIN - 8) * 4));
|
||||
#endif
|
||||
|
||||
/* Disable UART to enable settings to be written into the registers. */
|
||||
if (UART_CR1(UART_BASE) & UART_CR1_UART_ENABLE) {
|
||||
UART_CR1(UART_BASE) &= ~UART_CR1_UART_ENABLE;
|
||||
}
|
||||
|
||||
/* Clock Prescaler */
|
||||
UART_PRESC(UART_BASE) = 0; /* no div (div=1) */
|
||||
|
||||
/* Configure clock (speed/bitrate). Requires UE = 0. */
|
||||
UART_BRR(UART_BASE) = (uint16_t)(CLOCK_SPEED / BAUD_RATE);
|
||||
|
||||
/* Enable FIFO mode */
|
||||
UART_CR1(UART_BASE) |= UART_CR1_FIFOEN;
|
||||
|
||||
/* Enable 16-bit oversampling */
|
||||
UART_CR1(UART_BASE) &= ~UART_CR1_OVER8;
|
||||
|
||||
/* Configure the M bits (word length) */
|
||||
/* Word length is 8 bits by default (0=1 start, 8 data, 0 stop) */
|
||||
UART_CR1(UART_BASE) &= ~(UART_CR1_M0 | UART_CR1_M1);
|
||||
|
||||
/* Configure stop bits (00: 1 stop bit / 10: 2 stop bits.) */
|
||||
UART_CR2(UART_BASE) &= ~UART_CR2_STOP_MASK;
|
||||
UART_CR2(UART_BASE) |= UART_CR2_STOP(0);
|
||||
|
||||
/* Configure parity bits, disabled */
|
||||
UART_CR1(UART_BASE) &= ~(UART_CR1_PARITY_ENABLED | UART_CR1_PARITY_ODD);
|
||||
|
||||
/* In asynchronous mode, the following bits must be kept cleared:
|
||||
* - LINEN and CLKEN bits in the USART_CR2 register,
|
||||
* - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/
|
||||
UART_CR2(UART_BASE) &= ~(USART_CR2_LINEN | USART_CR2_CLKEN);
|
||||
UART_CR3(UART_BASE) &= ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN);
|
||||
|
||||
/* Turn on UART */
|
||||
UART_CR1(UART_BASE) |= (UART_CR1_TX_ENABLE | UART_CR1_RX_ENABLE |
|
||||
UART_CR1_UART_ENABLE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uart_write(const char* buf, unsigned int sz)
|
||||
{
|
||||
uint32_t pos = 0;
|
||||
while (sz-- > 0) {
|
||||
while ((UART_ISR(UART_BASE) & UART_ISR_TX_FIFO_NOT_FULL) == 0);
|
||||
|
||||
UART_TDR(UART_BASE) = buf[pos++];
|
||||
}
|
||||
}
|
||||
#endif /* DEBUG_UART */
|
||||
|
||||
static void clock_pll_off(void)
|
||||
{
|
||||
uint32_t reg32;
|
||||
|
@ -391,12 +602,12 @@ static void clock_pll_off(void)
|
|||
}
|
||||
|
||||
/* This implementation will setup HSI RC 16 MHz as PLL Source Mux, PLLCLK
|
||||
* as System Clock Source*/
|
||||
* as System Clock Source */
|
||||
static void clock_pll_on(int powersave)
|
||||
{
|
||||
uint32_t reg32;
|
||||
uint32_t cpu_freq, plln, pllm, pllq, pllp, pllr, hpre, d1cpre, d1ppre;
|
||||
uint32_t d2ppre1,d2ppre2, d3ppre , flash_waitstates;
|
||||
uint32_t d2ppre1, d2ppre2, d3ppre, flash_waitstates;
|
||||
|
||||
PWR_CR3 |= PWR_CR3_LDOEN;
|
||||
while ((PWR_CSR1 & PWR_CSR1_ACTVOSRDY) == 0) {};
|
||||
|
@ -415,12 +626,12 @@ static void clock_pll_on(int powersave)
|
|||
pllp = 2;
|
||||
pllq = 20;
|
||||
pllr = 2;
|
||||
d1cpre = RCC_PRESCALER_DIV_NONE;
|
||||
hpre = RCC_PRESCALER_DIV_2;
|
||||
d1ppre = (RCC_PRESCALER_DIV_2 >>1 );
|
||||
d2ppre1 = (RCC_PRESCALER_DIV_2>>1);
|
||||
d2ppre2 = (RCC_PRESCALER_DIV_2 >>1);
|
||||
d3ppre = (RCC_PRESCALER_DIV_2 >>1);
|
||||
d1cpre = RCC_PRESCALER_DIV_NONE;
|
||||
hpre = RCC_PRESCALER_DIV_2;
|
||||
d1ppre = (RCC_PRESCALER_DIV_2 >> 1);
|
||||
d2ppre1 = (RCC_PRESCALER_DIV_2 >> 1);
|
||||
d2ppre2 = (RCC_PRESCALER_DIV_2 >> 1);
|
||||
d3ppre = (RCC_PRESCALER_DIV_2 >> 1);
|
||||
flash_waitstates = 4;
|
||||
|
||||
flash_set_waitstates(flash_waitstates);
|
||||
|
@ -534,8 +745,17 @@ void RAMFUNCTION hal_flash_dualbank_swap(void)
|
|||
void hal_init(void)
|
||||
{
|
||||
clock_pll_on(0);
|
||||
|
||||
#ifdef DEBUG_UART
|
||||
uart_init();
|
||||
uart_write("wolfBoot Init\n", 14);
|
||||
#endif
|
||||
}
|
||||
|
||||
void hal_prepare_boot(void)
|
||||
{
|
||||
#ifdef SPI_FLASH
|
||||
spi_flash_release();
|
||||
#endif
|
||||
clock_pll_off();
|
||||
}
|
||||
|
|
|
@ -259,7 +259,7 @@ void hal_init(void)
|
|||
void hal_prepare_boot(void)
|
||||
{
|
||||
#ifdef SPI_FLASH
|
||||
spi_release();
|
||||
spi_flash_release();
|
||||
#endif
|
||||
hal_flash_lock();
|
||||
if ((FLASH_PECR & FLASH_PECR_PELOCK) == 0)
|
||||
|
|
|
@ -249,7 +249,7 @@ void hal_init(void)
|
|||
void hal_prepare_boot(void)
|
||||
{
|
||||
#ifdef SPI_FLASH
|
||||
spi_release();
|
||||
spi_flash_release();
|
||||
#endif
|
||||
|
||||
clock_pll_off();
|
||||
|
|
|
@ -323,7 +323,7 @@ void hal_init(void)
|
|||
void hal_prepare_boot(void)
|
||||
{
|
||||
#ifdef SPI_FLASH
|
||||
spi_release();
|
||||
spi_flash_release();
|
||||
#endif
|
||||
clock_pll_off();
|
||||
}
|
||||
|
|
|
@ -1333,9 +1333,7 @@ static int test_flash(QspiDev_t* dev)
|
|||
{
|
||||
int ret;
|
||||
uint32_t i;
|
||||
#ifndef USE_XQSPIPSU
|
||||
uint8_t pageData[FLASH_PAGE_SIZE];
|
||||
#endif
|
||||
|
||||
#ifndef TEST_FLASH_READONLY
|
||||
/* Erase sector */
|
||||
|
|
|
@ -66,7 +66,7 @@ void hal_prepare_boot(void);
|
|||
void *hal_get_dts_update_address(void);
|
||||
#endif
|
||||
|
||||
#ifndef SPI_FLASH
|
||||
#if !defined(SPI_FLASH) && !defined(QSPI_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);
|
||||
|
@ -81,11 +81,16 @@ void hal_prepare_boot(void);
|
|||
#define ext_flash_write spi_flash_write
|
||||
static inline int ext_flash_erase(uintptr_t address, int len)
|
||||
{
|
||||
int ret = 0;
|
||||
uint32_t end = address + len - 1;
|
||||
uint32_t p;
|
||||
for (p = address; p <= end; p += SPI_FLASH_SECTOR_SIZE)
|
||||
spi_flash_sector_erase(p);
|
||||
return 0;
|
||||
for (p = address; p <= end; p += SPI_FLASH_SECTOR_SIZE) {
|
||||
ret = spi_flash_sector_erase(p);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif /* !SPI_FLASH */
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* implementing the spi_ calls below.
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2021 wolfSSL Inc.
|
||||
* Copyright (C) 2022 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfBoot.
|
||||
*
|
||||
|
@ -32,9 +32,11 @@
|
|||
#include <stdint.h>
|
||||
#include "image.h"
|
||||
|
||||
#if defined(SPI_FLASH) || defined(QSPI_FLASH)
|
||||
|
||||
#if defined(PLATFORM_stm32f4) || defined(PLATFORM_stm32f7) || \
|
||||
defined(PLATFORM_stm32wb) || defined(PLATFORM_stm32l0) || \
|
||||
defined(PLATFORM_stm32u5)
|
||||
defined(PLATFORM_stm32u5) || defined(PLATFORM_stm32h7)
|
||||
#include "hal/spi/spi_drv_stm32.h"
|
||||
#endif
|
||||
|
||||
|
@ -47,9 +49,30 @@
|
|||
#endif
|
||||
|
||||
void spi_init(int polarity, int phase);
|
||||
void spi_release(void);
|
||||
|
||||
#ifdef SPI_FLASH
|
||||
void spi_cs_on(uint32_t base, int pin);
|
||||
void spi_cs_off(uint32_t base, int pin);
|
||||
void spi_write(const char byte);
|
||||
uint8_t spi_read(void);
|
||||
void spi_cs_on(int pin);
|
||||
void spi_cs_off(int pin);
|
||||
#endif /* SPI_FLASH */
|
||||
|
||||
|
||||
#ifdef QSPI_FLASH
|
||||
enum QSPIMode {
|
||||
QSPI_ADDR_MODE_SPI = 1,
|
||||
QSPI_ADDR_MODE_DSPI = 2,
|
||||
QSPI_ADDR_MODE_QSPI = 3,
|
||||
};
|
||||
|
||||
int qspi_transfer(
|
||||
const uint8_t cmd, uint32_t addr, uint32_t addrSz,
|
||||
const uint8_t* txData, uint32_t txSz,
|
||||
uint8_t* rxData, uint32_t rxSz, uint32_t dummySz,
|
||||
uint32_t mode);
|
||||
#endif /* QSPI_FLASH */
|
||||
|
||||
#endif /* SPI_FLASH || QSPI_FLASH */
|
||||
|
||||
#endif /* !SPI_DRV_H_INCLUDED */
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* Compile with SPI_FLASH=1
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2021 wolfSSL Inc.
|
||||
* Copyright (C) 2022 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfBoot.
|
||||
*
|
||||
|
@ -28,24 +28,30 @@
|
|||
#ifndef SPI_FLASH_DRI_H
|
||||
#define SPI_FLASH_DRI_H
|
||||
|
||||
#ifndef SPI_FLASH_SECTOR_SIZE
|
||||
#define SPI_FLASH_SECTOR_SIZE (4096)
|
||||
#define SPI_FLASH_PAGE_SIZE (256)
|
||||
#endif
|
||||
|
||||
#ifdef SPI_FLASH
|
||||
#ifndef SPI_FLASH_PAGE_SIZE
|
||||
#define SPI_FLASH_PAGE_SIZE (256)
|
||||
#endif
|
||||
|
||||
#if defined(SPI_FLASH) || defined(QSPI_FLASH)
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* returns (manuf << 8 | product) */
|
||||
uint16_t spi_flash_probe(void);
|
||||
void spi_release(void);
|
||||
void spi_flash_release(void);
|
||||
|
||||
void spi_flash_sector_erase(uint32_t address);
|
||||
int spi_flash_sector_erase(uint32_t address);
|
||||
int spi_flash_read(uint32_t address, void *data, int len);
|
||||
int spi_flash_write(uint32_t address, const void *data, int len);
|
||||
|
||||
#else
|
||||
|
||||
#define spi_flash_probe() do{}while(0)
|
||||
#define spi_release() do{}while(0)
|
||||
#define spi_flash_release() do{}while(0)
|
||||
|
||||
#endif /* SPI_FLASH */
|
||||
|
||||
|
|
|
@ -303,6 +303,13 @@ ifeq ($(SPI_FLASH),1)
|
|||
WOLFCRYPT_OBJS+=hal/spi/spi_drv_$(SPI_TARGET).o
|
||||
endif
|
||||
|
||||
ifeq ($(QSPI_FLASH),1)
|
||||
EXT_FLASH=1
|
||||
CFLAGS+=-D"QSPI_FLASH=1"
|
||||
OBJS+= src/qspi_flash.o
|
||||
WOLFCRYPT_OBJS+=hal/spi/spi_drv_$(SPI_TARGET).o
|
||||
endif
|
||||
|
||||
ifeq ($(UART_FLASH),1)
|
||||
EXT_FLASH=1
|
||||
endif
|
||||
|
|
|
@ -693,14 +693,14 @@ static int TPM2_IoCb(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
|
|||
(void)userCtx;
|
||||
(void)ctx;
|
||||
word16 i;
|
||||
spi_cs_on(SPI_CS_TPM);
|
||||
spi_cs_on(SPI_CS_TPM_PIO_BASE, SPI_CS_TPM);
|
||||
memset(rxBuf, 0, xferSz);
|
||||
for (i = 0; i < xferSz; i++)
|
||||
{
|
||||
spi_write(txBuf[i]);
|
||||
rxBuf[i] = spi_read();
|
||||
}
|
||||
spi_cs_off(SPI_CS_TPM);
|
||||
spi_cs_off(SPI_CS_TPM_PIO_BASE, SPI_CS_TPM);
|
||||
/*
|
||||
printf("\r\nSPI TX: ");
|
||||
printbin(txBuf, xferSz);
|
||||
|
|
|
@ -0,0 +1,425 @@
|
|||
/* qspi_flash.c
|
||||
*
|
||||
* Generic implementation of the read/write/erase
|
||||
* functionalities, on top of the spi_drv.h HAL.
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2022 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 2 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
|
||||
*/
|
||||
|
||||
#include "spi_drv.h"
|
||||
#include "spi_flash.h"
|
||||
|
||||
#ifdef QSPI_FLASH
|
||||
|
||||
#include "string.h"
|
||||
#include "printf.h"
|
||||
|
||||
#ifdef DEBUG_UART
|
||||
#define DEBUG_QSPI
|
||||
#endif
|
||||
|
||||
/* Flash Parameters:
|
||||
* Winbond W25Q128FV 128Mbit serial flash
|
||||
*/
|
||||
#ifndef FLASH_DEVICE_SIZE
|
||||
#define FLASH_DEVICE_SIZE (16 * 1024 * 1024)
|
||||
#endif
|
||||
#ifndef FLASH_PAGE_SIZE
|
||||
#define FLASH_PAGE_SIZE 256
|
||||
#endif
|
||||
#ifndef FLASH_NUM_PAGES
|
||||
#define FLASH_NUM_PAGES 0x10000
|
||||
#endif
|
||||
#ifndef FLASH_SECTOR_SIZE
|
||||
#define FLASH_SECTOR_SIZE WOLFBOOT_SECTOR_SIZE
|
||||
#endif
|
||||
#define FLASH_NUM_SECTORS (FLASH_DEVICE_SIZE/FLASH_SECTOR_SIZE)
|
||||
|
||||
/* QSPI Configuration */
|
||||
#ifndef QSPI_ADDR_MODE
|
||||
#define QSPI_ADDR_MODE QSPI_ADDR_MODE_QSPI
|
||||
#endif
|
||||
#ifndef QSPI_ADDR_SZ
|
||||
#define QSPI_ADDR_SZ 3
|
||||
#endif
|
||||
#ifndef QSPI_DUMMY_READ
|
||||
#define QSPI_DUMMY_READ (8) /* Number of dummy clock cycles for reads */
|
||||
#endif
|
||||
#ifndef QSPI_FLASH_READY_TRIES
|
||||
#define QSPI_FLASH_READY_TRIES 1000
|
||||
#endif
|
||||
|
||||
|
||||
/* Flash Commands */
|
||||
#define WRITE_ENABLE_CMD 0x06U
|
||||
#define READ_SR_CMD 0x05U
|
||||
#define WRITE_DISABLE_CMD 0x04U
|
||||
#define READ_ID_CMD 0x9FU
|
||||
|
||||
#define ENTER_QSPI_MODE_CMD 0x38U
|
||||
#define EXIT_QSPI_MODE_CMD 0xFFU
|
||||
|
||||
#define ENTER_4B_ADDR_MODE_CMD 0xB7U
|
||||
#define EXIT_4B_ADDR_MODE_CMD 0xE9U
|
||||
|
||||
#define FAST_READ_CMD 0x0BU
|
||||
#define DUAL_READ_CMD 0x3BU
|
||||
#define QUAD_READ_CMD 0xEBU
|
||||
#define FAST_READ_4B_CMD 0x0CU
|
||||
#define DUAL_READ_4B_CMD 0x3CU
|
||||
#define QUAD_READ_4B_CMD 0x6CU
|
||||
|
||||
#define PAGE_PROG_CMD 0x02U
|
||||
#define DUAL_PROG_CMD 0xA2U
|
||||
#define QUAD_PROG_CMD 0x22U
|
||||
#define PAGE_PROG_4B_CMD 0x12U
|
||||
#define DUAL_PROG_4B_CMD 0x12U
|
||||
#define QUAD_PROG_4B_CMD 0x34U
|
||||
|
||||
#define SEC_ERASE_CMD 0x20U /* 4KB */
|
||||
#define BLOCK_ERASE_CMD 0xD8U /* 64KB */
|
||||
#define RESET_ENABLE_CMD 0x66U
|
||||
#define RESET_MEMORY_CMD 0x99U
|
||||
|
||||
#define FLASH_SR_WRITE_EN 0x02 /* 1=Write Enabled, 0=Write Disabled */
|
||||
#define FLASH_SR_BUSY 0x01 /* 1=Busy, 0=Ready */
|
||||
|
||||
#if QSPI_ADDR_MODE == QSPI_ADDR_MODE_QSPI && QSPI_ADDR_SZ == 4
|
||||
#define FLASH_READ_CMD QUAD_READ_4B_CMD
|
||||
#elif QSPI_ADDR_MODE == QSPI_ADDR_MODE_DSPI && QSPI_ADDR_SZ == 4
|
||||
#define FLASH_READ_CMD DUAL_READ_4B_CMD
|
||||
#elif QSPI_ADDR_SZ == 4
|
||||
#define FLASH_READ_CMD FAST_READ_4B_CMD
|
||||
#elif QSPI_ADDR_MODE == QSPI_ADDR_MODE_QSPI
|
||||
#define FLASH_READ_CMD QUAD_READ_CMD
|
||||
#elif QSPI_ADDR_MODE == QSPI_ADDR_MODE_DSPI
|
||||
#define FLASH_READ_CMD DUAL_READ_CMD
|
||||
#else
|
||||
#define FLASH_READ_CMD FAST_READ_CMD
|
||||
#endif
|
||||
|
||||
|
||||
/* 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
|
||||
|
||||
static int qspi_flash_read_id(uint8_t* id, uint32_t idSz)
|
||||
{
|
||||
int ret;
|
||||
uint8_t data[4]; /* size multiple of uint32_t */
|
||||
uint32_t status = 0;
|
||||
|
||||
memset(data, 0, sizeof(data));
|
||||
ret = qspi_transfer(READ_ID_CMD, 0, 0, NULL, 0, data, 3, 0,
|
||||
QSPI_ADDR_MODE_SPI);
|
||||
qspi_status((uint8_t*)&status);
|
||||
#ifdef DEBUG_QSPI
|
||||
wolfBoot_printf("Flash: Ret %d: ID: %x, Cmd %x, status %x\n",
|
||||
ret, (uint32_t)data, FLASH_READ_CMD, status);
|
||||
#endif
|
||||
|
||||
/* optionally return id data */
|
||||
if (ret == 0 && id) {
|
||||
if (idSz > sizeof(data))
|
||||
idSz = sizeof(data);
|
||||
memcpy(id, data, idSz);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qspi_write_enable(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = qspi_transfer(WRITE_ENABLE_CMD, 0, 0, NULL, 0, NULL, 0, 0,
|
||||
QSPI_ADDR_MODE_SPI);
|
||||
#ifdef DEBUG_QSPI
|
||||
wolfBoot_printf("Write Enable: Ret %d\n", ret);
|
||||
#endif
|
||||
|
||||
qspi_wait_ready();
|
||||
|
||||
ret = qspi_wait_we();
|
||||
#ifdef DEBUG_QSPI
|
||||
wolfBoot_printf("Write Enabled: %s\n", ret == 0 ? "yes" : "no");
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qspi_write_disable(void)
|
||||
{
|
||||
int ret = qspi_transfer(WRITE_DISABLE_CMD, 0, 0, NULL, 0, NULL, 0, 0,
|
||||
QSPI_ADDR_MODE_SPI);
|
||||
#ifdef DEBUG_QSPI
|
||||
wolfBoot_printf("Write Disable: Ret %d\n", ret);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qspi_status(uint8_t* status)
|
||||
{
|
||||
int ret;
|
||||
uint8_t data[4]; /* size multiple of uint32_t */
|
||||
|
||||
memset(data, 0, sizeof(data));
|
||||
ret = qspi_transfer(READ_SR_CMD, 0, 0, NULL, 0, data, 1, 0,
|
||||
QSPI_ADDR_MODE_SPI);
|
||||
#ifdef DEBUG_QSPI
|
||||
wolfBoot_printf("Status (ret %d): %02x\n", ret, data[0]);
|
||||
#endif
|
||||
if (ret == 0 && status) {
|
||||
*status = data[0];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qspi_wait_ready(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_BUSY) == 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_QSPI
|
||||
wolfBoot_printf("Flash Ready Timeout!\n");
|
||||
#endif
|
||||
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_SZ == 4
|
||||
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);
|
||||
#ifdef DEBUG_QSPI
|
||||
wolfBoot_printf("Enter 4-byte address mode: Ret %d\n", ret);
|
||||
#endif
|
||||
if (ret == 0) {
|
||||
ret = qspi_wait_ready(); /* Wait for not busy */
|
||||
}
|
||||
qspi_write_disable();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
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);
|
||||
#ifdef DEBUG_QSPI
|
||||
wolfBoot_printf("Enter 4-byte address mode: Ret %d\n", ret);
|
||||
#endif
|
||||
if (ret == 0) {
|
||||
ret = qspi_wait_ready(); /* Wait for not busy */
|
||||
}
|
||||
qspi_write_disable();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
uint16_t spi_flash_probe(void)
|
||||
{
|
||||
spi_init(0,0);
|
||||
qspi_flash_read_id(NULL, 0);
|
||||
|
||||
#if QSPI_ADDR_SZ == 4
|
||||
qspi_enter_4byte_addr();
|
||||
#endif
|
||||
|
||||
#ifdef TEST_FLASH
|
||||
test_flash();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int spi_flash_sector_erase(uint32_t address)
|
||||
{
|
||||
int ret;
|
||||
uint32_t idx = 0;
|
||||
|
||||
ret = qspi_write_enable();
|
||||
if (ret == 0) {
|
||||
/* ------ Erase Flash ------ */
|
||||
ret = qspi_transfer(SEC_ERASE_CMD, address, QSPI_ADDR_SZ,
|
||||
NULL, 0, NULL, 0,
|
||||
0, QSPI_ADDR_MODE_SPI);
|
||||
#ifdef DEBUG_QSPI
|
||||
wolfBoot_printf("Flash Erase: Ret %d\n", ret);
|
||||
#endif
|
||||
if (ret == 0) {
|
||||
ret = qspi_wait_ready(); /* Wait for not busy */
|
||||
}
|
||||
qspi_write_disable();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int spi_flash_read(uint32_t address, void *data, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* ------ Read Flash ------ */
|
||||
ret = qspi_transfer(FLASH_READ_CMD, address, QSPI_ADDR_SZ,
|
||||
NULL, 0, data, len,
|
||||
QSPI_DUMMY_READ, QSPI_ADDR_MODE);
|
||||
#ifdef DEBUG_QSPI
|
||||
wolfBoot_printf("Flash Read: Ret %d\r\n", ret);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int spi_flash_write(uint32_t address, const void *data, int len)
|
||||
{
|
||||
int ret = 0;
|
||||
uint8_t cmd[8]; /* size multiple of uint32_t */
|
||||
uint32_t xferSz, page, pages, idx = 0;
|
||||
uintptr_t addr;
|
||||
|
||||
/* write by page */
|
||||
pages = ((len + (FLASH_PAGE_SIZE-1)) / FLASH_PAGE_SIZE);
|
||||
for (page = 0; page < pages; page++) {
|
||||
ret = qspi_write_enable();
|
||||
if (ret == 0) {
|
||||
xferSz = len;
|
||||
if (xferSz > FLASH_PAGE_SIZE)
|
||||
xferSz = FLASH_PAGE_SIZE;
|
||||
|
||||
addr = address + (page * FLASH_PAGE_SIZE);
|
||||
|
||||
/* ------ Write Flash (page at a time) ------ */
|
||||
ret = qspi_transfer(PAGE_PROG_CMD, addr, QSPI_ADDR_SZ,
|
||||
(const uint8_t*)(data + (page * FLASH_PAGE_SIZE)), xferSz,
|
||||
NULL, 0, 0, QSPI_ADDR_MODE_SPI);
|
||||
#ifdef DEBUG_QSPI
|
||||
wolfBoot_printf("Flash Page %d Write: Ret %d\n", page, ret);
|
||||
#endif
|
||||
if (ret != 0)
|
||||
break;
|
||||
|
||||
ret = qspi_wait_ready(); /* Wait for not busy */
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
qspi_write_disable();
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void spi_flash_release(void)
|
||||
{
|
||||
#if QSPI_ADDR_SZ == 4
|
||||
qspi_exit_4byte_addr();
|
||||
#endif
|
||||
|
||||
spi_release();
|
||||
}
|
||||
|
||||
#endif /* QSPI_FLASH */
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef TEST_FLASH
|
||||
#define TEST_ADDRESS (2 * 1024 * 1024) /* 2MB */
|
||||
static int test_flash(void)
|
||||
{
|
||||
int ret;
|
||||
uint32_t i;
|
||||
uint8_t pageData[FLASH_PAGE_SIZE];
|
||||
uint32_t wait = 0;
|
||||
|
||||
/* long wait */
|
||||
while (++wait < 1000000);
|
||||
|
||||
#ifndef TEST_FLASH_READONLY
|
||||
/* Erase sector */
|
||||
ret = ext_flash_erase(TEST_ADDRESS, WOLFBOOT_SECTOR_SIZE);
|
||||
wolfBoot_printf("Erase Sector: Ret %d\n", ret);
|
||||
|
||||
/* Write Pages */
|
||||
for (i=0; i<sizeof(pageData); i++) {
|
||||
pageData[i] = (i & 0xff);
|
||||
}
|
||||
ret = ext_flash_write(TEST_ADDRESS, pageData, sizeof(pageData));
|
||||
wolfBoot_printf("Write Page: Ret %d\n", ret);
|
||||
#endif /* !TEST_FLASH_READONLY */
|
||||
|
||||
/* Read page */
|
||||
memset(pageData, 0, sizeof(pageData));
|
||||
ret = ext_flash_read(TEST_ADDRESS, pageData, sizeof(pageData));
|
||||
wolfBoot_printf("Read Page: Ret %d\n", ret);
|
||||
|
||||
wolfBoot_printf("Checking...\n");
|
||||
/* Check data */
|
||||
for (i=0; i<sizeof(pageData); i++) {
|
||||
wolfBoot_printf("check[%3d] %02x\n", i, pageData[i]);
|
||||
if (pageData[i] != (i & 0xff)) {
|
||||
wolfBoot_printf("Check Data @ %d failed\n", i);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
wolfBoot_printf("Flash Test Passed\n");
|
||||
return ret;
|
||||
}
|
||||
#endif /* TEST_FLASH */
|
|
@ -68,21 +68,21 @@ static void RAMFUNCTION write_address(uint32_t address)
|
|||
static uint8_t RAMFUNCTION read_status(void)
|
||||
{
|
||||
uint8_t status;
|
||||
spi_cs_on(SPI_CS_FLASH);
|
||||
spi_cs_on(SPI_CS_PIO_BASE, SPI_CS_FLASH);
|
||||
spi_write(RDSR);
|
||||
spi_read();
|
||||
spi_write(0xFF);
|
||||
status = spi_read();
|
||||
spi_cs_off(SPI_CS_FLASH);
|
||||
spi_cs_off(SPI_CS_PIO_BASE, SPI_CS_FLASH);
|
||||
return status;
|
||||
}
|
||||
|
||||
static void RAMFUNCTION spi_cmd(uint8_t cmd)
|
||||
{
|
||||
spi_cs_on(SPI_CS_FLASH);
|
||||
spi_cs_on(SPI_CS_PIO_BASE, SPI_CS_FLASH);
|
||||
spi_write(cmd);
|
||||
spi_read();
|
||||
spi_cs_off(SPI_CS_FLASH);
|
||||
spi_cs_off(SPI_CS_PIO_BASE, SPI_CS_FLASH);
|
||||
}
|
||||
|
||||
static void RAMFUNCTION flash_write_enable(void)
|
||||
|
@ -118,7 +118,7 @@ static int RAMFUNCTION spi_flash_write_page(uint32_t address, const void *data,
|
|||
flash_write_enable();
|
||||
wait_busy();
|
||||
|
||||
spi_cs_on(SPI_CS_FLASH);
|
||||
spi_cs_on(SPI_CS_PIO_BASE, SPI_CS_FLASH);
|
||||
spi_write(BYTE_WRITE);
|
||||
spi_read();
|
||||
write_address(address);
|
||||
|
@ -128,7 +128,7 @@ static int RAMFUNCTION spi_flash_write_page(uint32_t address, const void *data,
|
|||
spi_read();
|
||||
len--;
|
||||
} while ((address & (SPI_FLASH_PAGE_SIZE - 1)) != 0);
|
||||
spi_cs_off(SPI_CS_FLASH);
|
||||
spi_cs_off(SPI_CS_PIO_BASE, SPI_CS_FLASH);
|
||||
}
|
||||
wait_busy();
|
||||
return 0;
|
||||
|
@ -145,13 +145,13 @@ static int RAMFUNCTION spi_flash_write_sb(uint32_t address, const void *data, in
|
|||
return -1;
|
||||
while (len > 0) {
|
||||
flash_write_enable();
|
||||
spi_cs_on(SPI_CS_FLASH);
|
||||
spi_cs_on(SPI_CS_PIO_BASE, SPI_CS_FLASH);
|
||||
spi_write(BYTE_WRITE);
|
||||
spi_read();
|
||||
write_address(address);
|
||||
spi_write(buf[j]);
|
||||
spi_read();
|
||||
spi_cs_off(SPI_CS_FLASH);
|
||||
spi_cs_off(SPI_CS_PIO_BASE, SPI_CS_FLASH);
|
||||
wait_busy();
|
||||
spi_flash_read(address, &verify, 1);
|
||||
if ((verify & ~(buf[j])) == 0) {
|
||||
|
@ -174,7 +174,7 @@ uint16_t spi_flash_probe(void)
|
|||
int i;
|
||||
spi_init(0,0);
|
||||
wait_busy();
|
||||
spi_cs_on(SPI_CS_FLASH);
|
||||
spi_cs_on(SPI_CS_PIO_BASE, SPI_CS_FLASH);
|
||||
spi_write(MDID);
|
||||
b0 = spi_read();
|
||||
|
||||
|
@ -183,36 +183,37 @@ uint16_t spi_flash_probe(void)
|
|||
manuf = spi_read();
|
||||
spi_write(0xFF);
|
||||
product = spi_read();
|
||||
spi_cs_off(SPI_CS_FLASH);
|
||||
spi_cs_off(SPI_CS_PIO_BASE, SPI_CS_FLASH);
|
||||
if (manuf == 0xBF || manuf == 0xC2)
|
||||
chip_write_mode = SST_SINGLEBYTE;
|
||||
if (manuf == 0xEF)
|
||||
chip_write_mode = WB_WRITEPAGE;
|
||||
|
||||
#ifndef READONLY
|
||||
spi_cs_on(SPI_CS_FLASH);
|
||||
spi_cs_on(SPI_CS_PIO_BASE, SPI_CS_FLASH);
|
||||
spi_write(WRSR);
|
||||
spi_read();
|
||||
spi_write(0x00);
|
||||
spi_read();
|
||||
spi_cs_off(SPI_CS_FLASH);
|
||||
spi_cs_off(SPI_CS_PIO_BASE, SPI_CS_FLASH);
|
||||
#endif
|
||||
return (uint16_t)(manuf << 8 | product);
|
||||
}
|
||||
|
||||
|
||||
void RAMFUNCTION spi_flash_sector_erase(uint32_t address)
|
||||
int RAMFUNCTION spi_flash_sector_erase(uint32_t address)
|
||||
{
|
||||
address &= (~(SPI_FLASH_SECTOR_SIZE - 1));
|
||||
|
||||
wait_busy();
|
||||
flash_write_enable();
|
||||
spi_cs_on(SPI_CS_FLASH);
|
||||
spi_cs_on(SPI_CS_PIO_BASE, SPI_CS_FLASH);
|
||||
spi_write(SECTOR_ERASE);
|
||||
spi_read();
|
||||
write_address(address);
|
||||
spi_cs_off(SPI_CS_FLASH);
|
||||
spi_cs_off(SPI_CS_PIO_BASE, SPI_CS_FLASH);
|
||||
wait_busy();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RAMFUNCTION spi_flash_read(uint32_t address, void *data, int len)
|
||||
|
@ -220,7 +221,7 @@ int RAMFUNCTION spi_flash_read(uint32_t address, void *data, int len)
|
|||
uint8_t *buf = data;
|
||||
int i = 0;
|
||||
wait_busy();
|
||||
spi_cs_on(SPI_CS_FLASH);
|
||||
spi_cs_on(SPI_CS_PIO_BASE, SPI_CS_FLASH);
|
||||
spi_write(BYTE_READ);
|
||||
spi_read();
|
||||
write_address(address);
|
||||
|
@ -229,7 +230,7 @@ int RAMFUNCTION spi_flash_read(uint32_t address, void *data, int len)
|
|||
buf[i++] = spi_read();
|
||||
len--;
|
||||
}
|
||||
spi_cs_off(SPI_CS_FLASH);
|
||||
spi_cs_off(SPI_CS_PIO_BASE, SPI_CS_FLASH);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -242,4 +243,9 @@ int RAMFUNCTION spi_flash_write(uint32_t address, const void *data, int len)
|
|||
return -1;
|
||||
}
|
||||
|
||||
void spi_flash_release(void)
|
||||
{
|
||||
spi_release();
|
||||
}
|
||||
|
||||
#endif /* SPI_FLASH */
|
||||
|
|
|
@ -45,6 +45,10 @@ endif
|
|||
|
||||
include ../arch.mk
|
||||
|
||||
ifeq ($(DEBUG_UART),1)
|
||||
APP_OBJS+=../src/string.o
|
||||
endif
|
||||
|
||||
ifeq ($(TZEN),1)
|
||||
APP_OBJS+=../hal/$(TARGET)_ns.o
|
||||
else
|
||||
|
@ -136,6 +140,11 @@ ifeq ($(SPI_FLASH),1)
|
|||
APP_OBJS+=../hal/spi/spi_drv_$(SPI_TARGET).o ../src/spi_flash.o
|
||||
endif
|
||||
|
||||
ifeq ($(QSPI_FLASH),1)
|
||||
CFLAGS+=-D"QSPI_FLASH"
|
||||
APP_OBJS+=../hal/spi/spi_drv_$(SPI_TARGET).o ../src/qspi_flash.o
|
||||
endif
|
||||
|
||||
ifeq ($(UART_FLASH),1)
|
||||
CFLAGS+=-D"UART_FLASH=1"
|
||||
APP_OBJS+= ../src/uart_flash.o ../hal/uart/uart_drv_$(UART_TARGET).o
|
||||
|
|
|
@ -305,7 +305,7 @@ void main(void) {
|
|||
/* Update complete */
|
||||
spi_flash_probe();
|
||||
wolfBoot_update_trigger();
|
||||
spi_release();
|
||||
spi_flash_release();
|
||||
hal_flash_lock();
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
* |
|
||||
* The following application runs on the above mentioned board. |
|
||||
* It contains setup of LD1, LD2 and LD3. |
|
||||
* As well as setup of UART serial communication using USART2 on pins PD5 (TX) and PD6 (RX). |
|
||||
* USART serial communication defaults to using USART3 on pins PD8 (TX) and PD9 (RX) (VCOM Port). |
|
||||
* To use USART2 set UART_PORT=2 to use pins PD5 (TX) and PD6 (RX). |
|
||||
* --------------------------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
@ -86,6 +87,8 @@
|
|||
#define GPIOB_AFH (*(volatile uint32_t *)(GPIOB_BASE + 0x24))
|
||||
#define GPIOB_AHB4_CLOCK_ER (1 << 1)
|
||||
|
||||
#define GPIOD_BASE (0x58020C00)
|
||||
|
||||
/* GPIO GROUP E */
|
||||
#define GPIOE_BASE 0x58021000
|
||||
#define GPIOE_MODE (*(volatile uint32_t *)(GPIOE_BASE + 0x00))
|
||||
|
@ -97,14 +100,23 @@
|
|||
|
||||
/* UART SETUP */
|
||||
/* ====================================================================== */
|
||||
#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_TX_PIN 8 /* PD8, USART Transmit pin */
|
||||
#define UART_RX_PIN 9 /* PD9, USART Receive pin */
|
||||
#else
|
||||
/* USART2 Base address (chosen because of its pin layout on Nucleo board) */
|
||||
#define UART_BASE (0x40004400)
|
||||
#define RCC_BASE (0x58024400)
|
||||
#define GPIOD_BASE (0x58020C00)
|
||||
|
||||
#define UART_PIN_AF 7 /* AF stands for Alternate Function. For PD5/PD6 AF7 equals USART2 RX/TX. */
|
||||
#define UART_TX_PIN 5 /* PD5, USART Transmit pin */
|
||||
#define UART_RX_PIN 6 /* PD6, USART Receive pin */
|
||||
#endif
|
||||
|
||||
#define UART_PIN_AF 7 /* AF stands for Alternate Function. USART TX/RX */
|
||||
|
||||
/* UART/USART: Defining register start addresses. */
|
||||
#define UART_CR1 (*(volatile uint32_t *)(UART_BASE + 0x00))
|
||||
|
@ -116,6 +128,7 @@
|
|||
#define UART_RQR (*(volatile uint32_t *)(UART_BASE + 0x18))
|
||||
|
||||
/* RCC: Defining register start addresses. */
|
||||
#define RCC_BASE (0x58024400)
|
||||
#define RCC_D2CCIP2R (*(volatile uint32_t *)(RCC_BASE + 0x54))
|
||||
#define RCC_AHB1ENR (*(volatile uint32_t *)(RCC_BASE + 0xD8))
|
||||
#define RCC_AHB4ENR (*(volatile uint32_t *)(RCC_BASE + 0xE0))
|
||||
|
@ -154,7 +167,9 @@
|
|||
#define RCC_AHB4_GPIOD_EN (1 << 3)
|
||||
|
||||
/* HSI Clock speed */
|
||||
#ifndef CLOCK_SPEED
|
||||
#define CLOCK_SPEED 64000000
|
||||
#endif
|
||||
|
||||
/* Marking the update partition as ready to be swapped and executed. */
|
||||
#define UPDATE_PARTITION_BASE (0x08060000)
|
||||
|
@ -177,16 +192,13 @@
|
|||
|
||||
static void ld1_write(uint8_t led_status)
|
||||
{
|
||||
if (led_status == 0)
|
||||
{
|
||||
if (led_status == 0) {
|
||||
SET_BIT(GPIOB_BSRR, (1 << (LD1_PIN + 16)));
|
||||
}
|
||||
else if (led_status == 2)
|
||||
{
|
||||
else if (led_status == 2) {
|
||||
SET_BIT(GPIOB_BSRR, (1 << LD1_PIN));
|
||||
}
|
||||
else if (led_status == 1)
|
||||
{
|
||||
else if (led_status == 1) {
|
||||
uint32_t reg;
|
||||
uint32_t pin = LD1_PIN;
|
||||
SET_BIT(RCC_AHB4ENR, GPIOB_AHB4_CLOCK_ER);
|
||||
|
@ -200,16 +212,13 @@ static void ld1_write(uint8_t led_status)
|
|||
|
||||
static void ld2_write(uint8_t led_status)
|
||||
{
|
||||
if (led_status == 0)
|
||||
{
|
||||
if (led_status == 0) {
|
||||
GPIOE_BSRR |= (1 << (LD2_PIN + 16));
|
||||
}
|
||||
else if (led_status == 2)
|
||||
{
|
||||
else if (led_status == 2) {
|
||||
SET_BIT(GPIOE_BSRR, (1 << LD2_PIN));
|
||||
}
|
||||
else if (led_status == 1)
|
||||
{
|
||||
else if (led_status == 1) {
|
||||
uint32_t reg;
|
||||
uint32_t pin = LD2_PIN;
|
||||
RCC_AHB4ENR |= GPIOE_AHB4_CLOCK_ER;
|
||||
|
@ -259,14 +268,23 @@ int uart_setup(uint32_t bitrate)
|
|||
GPIOD_MODE = reg | (2 << (UART_RX_PIN * 2));
|
||||
|
||||
/* Alternate function. Use AFLR for pins 0-7 and AFHR for pins 8-15 */
|
||||
#if UART_TX_PIN >= 8
|
||||
reg = GPIOD_AFRH & ~(0xf << ((UART_TX_PIN & 0x07)*4));
|
||||
GPIOD_AFRH = reg | (UART_PIN_AF << ((UART_TX_PIN & 0x07)*4));
|
||||
#else
|
||||
reg = GPIOD_AFRL & ~(0xf << ((UART_TX_PIN)*4));
|
||||
GPIOD_AFRL = reg | (UART_PIN_AF << ((UART_TX_PIN)*4));
|
||||
#endif
|
||||
#if UART_RX_PIN >= 8
|
||||
reg = GPIOD_AFRH & ~(0xf << ((UART_RX_PIN & 0x07)*4));
|
||||
GPIOD_AFRH = reg | (UART_PIN_AF << ((UART_RX_PIN & 0x07)*4));
|
||||
#else
|
||||
reg = GPIOD_AFRL & ~(0xf << ((UART_RX_PIN)*4));
|
||||
GPIOD_AFRL = reg | (UART_PIN_AF << ((UART_RX_PIN)*4));
|
||||
#endif
|
||||
|
||||
/* Disable UART to enable settings to be written into the registers. */
|
||||
if (READ_BIT(UART_CR1, UART_CR1_UART_ENABLE) == 1)
|
||||
{
|
||||
if (READ_BIT(UART_CR1, UART_CR1_UART_ENABLE) == 1) {
|
||||
CLEAR_BIT(UART_CR1, UART_CR1_UART_ENABLE);
|
||||
}
|
||||
|
||||
|
@ -276,8 +294,13 @@ int uart_setup(uint32_t bitrate)
|
|||
SET_BIT(RCC_D2CCIP2R, (1 << 1));
|
||||
CLEAR_BIT(RCC_D2CCIP2R, (1 << 2));
|
||||
|
||||
#if UART_PORT == 3
|
||||
/* Enable clock for USART_3 */
|
||||
SET_BIT(RCC_APB1ENR, RCC_APB1_USART3_EN);
|
||||
#else
|
||||
/* Enable clock for USART_2 */
|
||||
SET_BIT(RCC_APB1ENR, RCC_APB1_USART2_EN);
|
||||
#endif
|
||||
|
||||
/* Enable FIFO mode */
|
||||
SET_BIT(UART_CR1, (1 << 29));
|
||||
|
@ -313,9 +336,9 @@ int uart_setup(uint32_t bitrate)
|
|||
return -1;
|
||||
}
|
||||
|
||||
void uart_write(const char c)
|
||||
static void uart_write(const char c)
|
||||
{
|
||||
/* USART transmit data register(TDR), bit 0-8 contains the data character
|
||||
/* USART transmit data register(TDR), bit 0-8 contains the data character
|
||||
* to be transmitted.
|
||||
* The register mus be written only when TXE/TXFNF = 1;
|
||||
* TXE : Set by hardware when the content of the USART_TDR register has
|
||||
|
@ -334,8 +357,7 @@ void uart_write(const char c)
|
|||
void uart_print(const char *s)
|
||||
{
|
||||
int i = 0;
|
||||
while (s[i])
|
||||
{
|
||||
while (s[i]) {
|
||||
uart_write(s[i++]);
|
||||
}
|
||||
}
|
||||
|
@ -352,7 +374,7 @@ void main(void)
|
|||
ld3_write(LED_INIT);
|
||||
|
||||
/* LED Indicator of successful UART initialization. SUCCESS = ON, FAIL = OFF */
|
||||
if (uart_setup(9600) < 0)
|
||||
if (uart_setup(115200) < 0)
|
||||
ld2_write(LED_OFF);
|
||||
else
|
||||
ld2_write(LED_INIT);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* main.c
|
||||
/* app_stm32l0.c
|
||||
*
|
||||
* Test bare-metal boot-led-on application
|
||||
*
|
||||
|
@ -32,6 +32,143 @@
|
|||
|
||||
#ifdef PLATFORM_stm32l0
|
||||
|
||||
#define UART2 (0x40004400)
|
||||
#define UART2_CR1 (*(volatile uint32_t *)(UART2 + 0x00))
|
||||
#define UART2_CR2 (*(volatile uint32_t *)(UART2 + 0x04))
|
||||
#define UART2_CR3 (*(volatile uint32_t *)(UART2 + 0x08))
|
||||
#define UART2_BRR (*(volatile uint32_t *)(UART2 + 0x0c))
|
||||
#define UART2_ISR (*(volatile uint32_t *)(UART2 + 0x1c))
|
||||
#define UART2_ICR (*(volatile uint32_t *)(UART2 + 0x20))
|
||||
#define UART2_RDR (*(volatile uint32_t *)(UART2 + 0x24))
|
||||
#define UART2_TDR (*(volatile uint32_t *)(UART2 + 0x28))
|
||||
|
||||
#define UART_CR1_UART_ENABLE (1 << 0)
|
||||
#define UART_CR1_SYMBOL_LEN (1 << 12)
|
||||
#define UART_CR1_PARITY_ENABLED (1 << 10)
|
||||
#define UART_CR1_OVER8 (1 << 15)
|
||||
#define UART_CR1_PARITY_ODD (1 << 9)
|
||||
#define UART_CR1_TX_ENABLE (1 << 3)
|
||||
#define UART_CR1_RX_ENABLE (1 << 2)
|
||||
#define UART_CR2_STOPBITS (3 << 12)
|
||||
#define UART_CR2_LINEN (1 << 14)
|
||||
#define UART_CR2_CLKEN (1 << 11)
|
||||
#define UART_CR3_HDSEL (1 << 3)
|
||||
#define UART_CR3_SCEN (1 << 5)
|
||||
#define UART_CR3_IREN (1 << 1)
|
||||
#define UART_ISR_TX_EMPTY (1 << 7)
|
||||
#define UART_ISR_RX_NOTEMPTY (1 << 5)
|
||||
|
||||
#define RCC_IOPENR (*(volatile uint32_t *)(0x4002102C))
|
||||
#define APB1_CLOCK_ER (*(volatile uint32_t *)(0x40021038))
|
||||
#define IOPAEN (1 << 0)
|
||||
#define IOPCEN (1 << 2)
|
||||
|
||||
#define UART2_APB1_CLOCK_ER_VAL (1 << 17)
|
||||
|
||||
#define GPIOA_BASE 0x50000000
|
||||
#define GPIOA_MODE (*(volatile uint32_t *)(GPIOA_BASE + 0x00))
|
||||
#define GPIOA_OTYPE (*(volatile uint32_t *)(GPIOA_BASE + 0x04))
|
||||
#define GPIOA_OSPD (*(volatile uint32_t *)(GPIOA_BASE + 0x08))
|
||||
#define GPIOA_PUPD (*(volatile uint32_t *)(GPIOA_BASE + 0x0c))
|
||||
#define GPIOA_ODR (*(volatile uint32_t *)(GPIOA_BASE + 0x14))
|
||||
#define GPIOA_BSRR (*(volatile uint32_t *)(GPIOA_BASE + 0x18))
|
||||
#define GPIOA_AFL (*(volatile uint32_t *)(GPIOA_BASE + 0x20))
|
||||
#define GPIOA_AFH (*(volatile uint32_t *)(GPIOA_BASE + 0x24))
|
||||
|
||||
#define GPIO_MODE_AF (2)
|
||||
#define UART2_PIN_AF 4
|
||||
#define UART2_RX_PIN 2
|
||||
#define UART2_TX_PIN 3
|
||||
|
||||
#ifndef CPU_FREQ
|
||||
#define CPU_FREQ (24000000)
|
||||
#endif
|
||||
|
||||
#ifndef UART_FLASH
|
||||
|
||||
static void uart2_pins_setup(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
RCC_IOPENR |= IOPAEN;
|
||||
/* Set mode = AF */
|
||||
reg = GPIOA_MODE & ~ (0x03 << (UART2_RX_PIN * 2));
|
||||
GPIOA_MODE = reg | (2 << (UART2_RX_PIN * 2));
|
||||
reg = GPIOA_MODE & ~ (0x03 << (UART2_TX_PIN * 2));
|
||||
GPIOA_MODE = reg | (2 << (UART2_TX_PIN * 2));
|
||||
|
||||
/* Alternate function: use low pins (2 and 3) */
|
||||
reg = GPIOA_AFL & ~(0xf << (UART2_TX_PIN * 4));
|
||||
GPIOA_AFL = reg | (UART2_PIN_AF << (UART2_TX_PIN * 4));
|
||||
reg = GPIOA_AFL & ~(0xf << (UART2_RX_PIN * 4));
|
||||
GPIOA_AFL = reg | (UART2_PIN_AF << (UART2_RX_PIN * 4));
|
||||
|
||||
}
|
||||
|
||||
int uart_setup(uint32_t bitrate)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
/* Enable pins and configure for AF */
|
||||
uart2_pins_setup();
|
||||
|
||||
/* Turn on the device */
|
||||
APB1_CLOCK_ER |= UART2_APB1_CLOCK_ER_VAL;
|
||||
|
||||
/* Enable 16-bit oversampling */
|
||||
UART2_CR1 &= (~UART_CR1_OVER8);
|
||||
|
||||
/* Configure clock */
|
||||
UART2_BRR |= (uint16_t)(CPU_FREQ / bitrate);
|
||||
|
||||
/* Configure data bits to 8 */
|
||||
UART2_CR1 &= ~UART_CR1_SYMBOL_LEN;
|
||||
|
||||
/* Disable parity */
|
||||
UART2_CR1 &= ~(UART_CR1_PARITY_ENABLED | UART_CR1_PARITY_ODD);
|
||||
|
||||
/* Set stop bits */
|
||||
UART2_CR2 = UART2_CR2 & ~UART_CR2_STOPBITS;
|
||||
|
||||
/* Clear flags for async mode */
|
||||
UART2_CR2 &= ~(UART_CR2_LINEN | UART_CR2_CLKEN);
|
||||
UART2_CR3 &= ~(UART_CR3_SCEN | UART_CR3_HDSEL | UART_CR3_IREN);
|
||||
|
||||
/* Configure for RX+TX, turn on. */
|
||||
UART2_CR1 |= UART_CR1_TX_ENABLE | UART_CR1_RX_ENABLE | UART_CR1_UART_ENABLE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uart_write(const uint8_t c)
|
||||
{
|
||||
volatile uint32_t reg;
|
||||
do {
|
||||
reg = UART2_ISR;
|
||||
} while ((reg & UART_ISR_TX_EMPTY) == 0);
|
||||
UART2_TDR = c;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int uart_read(uint8_t *c, int len)
|
||||
{
|
||||
volatile uint32_t reg;
|
||||
int i = 0;
|
||||
reg = UART2_ISR;
|
||||
if (reg & UART_ISR_RX_NOTEMPTY) {
|
||||
*c = (uint8_t)UART2_RDR;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uart_print(const char *s)
|
||||
{
|
||||
int i = 0;
|
||||
while (s[i]) {
|
||||
uart_write(s[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Matches all keys:
|
||||
* - chacha (32 + 12)
|
||||
* - aes128 (16 + 16)
|
||||
|
@ -41,9 +178,14 @@
|
|||
char enc_key[] = "0123456789abcdef0123456789abcdef"
|
||||
"0123456789abcdef";
|
||||
|
||||
void main(void) {
|
||||
void main(void)
|
||||
{
|
||||
uint32_t version;
|
||||
volatile uint32_t i, j;
|
||||
|
||||
uart_setup(115200);
|
||||
uart_print("STM32L0 Test Application\n\r");
|
||||
|
||||
#ifdef SPI_FLASH
|
||||
spi_flash_probe();
|
||||
#endif
|
||||
|
|
|
@ -57,9 +57,9 @@ void hal_prepare_boot(void)
|
|||
{
|
||||
}
|
||||
|
||||
void spi_flash_sector_erase(uint32_t address)
|
||||
int spi_flash_sector_erase(uint32_t address)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
int spi_flash_read(uint32_t address, void *data, int len)
|
||||
{
|
||||
|
|
|
@ -19,6 +19,7 @@ ifeq ($(ARCH),)
|
|||
NO_ASM?=0
|
||||
EXT_FLASH?=0
|
||||
SPI_FLASH?=0
|
||||
QSPI_FLASH?=0
|
||||
NO_XIP?=0
|
||||
UART_FLASH?=0
|
||||
ALLOW_DOWNGRADE?=0
|
||||
|
|
Loading…
Reference in New Issue