Skip to content

Commit 2545574

Browse files
committed
Make Stm32 SPI driver more generic to reuse on other STM32 platforms
1 parent 453a07b commit 2545574

6 files changed

Lines changed: 314 additions & 5 deletions

File tree

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ ifeq ($(SPI_FLASH),1)
9595
EXT_FLASH=1
9696
CFLAGS+= -DSPI_FLASH=1
9797
OBJS+= src/spi_flash.o
98-
WOLFCRYPT_OBJS+=hal/spi/spi_drv_$(TARGET).o
98+
WOLFCRYPT_OBJS+=hal/spi/spi_drv_$(SPI_TARGET).o
9999
endif
100100

101101
ifeq ($(EXT_FLASH),1)
@@ -132,7 +132,7 @@ OBJS += lib/wolfTPM/src/tpm2.o \
132132
lib/wolfTPM/src/tpm2_tis.o \
133133
lib/wolfTPM/src/tpm2_wrap.o \
134134
src/ecc256_pub_key.o \
135-
hal/spi/spi_drv_$(TARGET).o
135+
hal/spi/spi_drv_$(SPI_TARGET).o
136136
CFLAGS+=-DWOLFTPM_SLB9670 -DWOLFTPM2_NO_WOLFCRYPT -DSIZEOF_LONG=4 -Ilib/wolfTPM \
137137
-DMAX_COMMAND_SIZE=1024 -DMAX_RESPONSE_SIZE=1024 -DWOLFTPM2_MAX_BUFFER=1500 -DMAX_SESSION_NUM=1 -DMAX_DIGEST_BUFFER=973 \
138138
-DWOLFTPM_SMALL_STACK

arch.mk

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ endif
1010
# Default flash offset
1111
ARCH_FLASH_OFFSET=0x0
1212

13+
# Default SPI driver name
14+
SPI_TARGET=$(TARGET)
15+
1316
## ARM
1417
ifeq ($(ARCH),ARM)
1518
CROSS_COMPILE:=arm-none-eabi-
@@ -32,10 +35,12 @@ ifeq ($(ARCH),ARM)
3235

3336
ifeq ($(TARGET),stm32f7)
3437
ARCH_FLASH_OFFSET=0x08000000
38+
SPI_TARGET=stm32
3539
endif
3640

3741
ifeq ($(TARGET),stm32h7)
3842
ARCH_FLASH_OFFSET=0x08000000
43+
SPI_TARGET=stm32
3944
endif
4045

4146
## Cortex-M CPU
@@ -102,8 +107,12 @@ OBJCOPY:=$(CROSS_COMPILE)objcopy
102107
SIZE:=$(CROSS_COMPILE)size
103108
BOOT_IMG?=test-app/image.bin
104109

110+
ifeq ($(TARGET),stm32f4)
111+
SPI_TARGET=stm32
112+
endif
105113

106114
ifeq ($(TARGET),stm32wb)
115+
SPI_TARGET=stm32
107116
ifneq ($(PKA),0)
108117
ECC_EXTRA_OBJS+= $(STM32CUBE)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pka.o ./lib/wolfssl/wolfcrypt/src/port/st/stm32.o
109118
ECC_EXTRA_CFLAGS+=-DWOLFSSL_STM32_PKA -I$(STM32CUBE)/Drivers/STM32WBxx_HAL_Driver/Inc \

hal/spi/spi_drv_stm32.c

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
/* spi_drv.h
2+
*
3+
* Driver for the SPI back-end of the SPI_FLASH module.
4+
*
5+
* Example implementation for stm32F4, using SPI1.
6+
*
7+
* Pinout: see spi_drv_stm32.h
8+
*
9+
* Copyright (C) 2019 wolfSSL Inc.
10+
*
11+
* This file is part of wolfBoot.
12+
*
13+
* wolfBoot is free software; you can redistribute it and/or modify
14+
* it under the terms of the GNU General Public License as published by
15+
* the Free Software Foundation; either version 2 of the License, or
16+
* (at your option) any later version.
17+
*
18+
* wolfBoot is distributed in the hope that it will be useful,
19+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
20+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21+
* GNU General Public License for more details.
22+
*
23+
* You should have received a copy of the GNU General Public License
24+
* along with this program; if not, write to the Free Software
25+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
26+
*/
27+
#include <stdint.h>
28+
#include "spi_drv.h"
29+
#include "spi_drv_stm32.h"
30+
31+
void spi_cs_off(int pin)
32+
{
33+
SPI_PIO_CS_BSRR |= (1 << pin);
34+
while(!(SPI_PIO_CS_ODR & (1 << pin)))
35+
;
36+
}
37+
38+
void spi_cs_on(int pin)
39+
{
40+
SPI_PIO_CS_BSRR |= (1 << (pin + 16));
41+
while(SPI_PIO_CS_ODR & (1 << pin))
42+
;
43+
}
44+
45+
46+
static void spi_flash_pin_setup(void)
47+
{
48+
uint32_t reg;
49+
RCC_GPIO_CLOCK_ER |= SPI_PIO_CS_CEN;
50+
reg = SPI_PIO_CS_MODE & ~ (0x03 << (SPI_CS_FLASH * 2));
51+
SPI_PIO_CS_MODE = reg | (1 << (SPI_CS_FLASH * 2));
52+
reg = SPI_PIO_CS_PUPD & ~(0x03 << (SPI_CS_FLASH * 2));
53+
SPI_PIO_CS_PUPD = reg | (0x01 << (SPI_CS_FLASH * 2));
54+
reg = SPI_PIO_CS_OSPD & ~(0x03 << (SPI_CS_FLASH * 2));
55+
SPI_PIO_CS_OSPD |= (0x03 << (SPI_CS_FLASH * 2));
56+
spi_cs_off(SPI_CS_FLASH);
57+
}
58+
59+
static void spi_tpm2_pin_setup(void)
60+
{
61+
#ifdef WOLFTPM2_NO_WOLFCRYPT
62+
uint32_t reg;
63+
RCC_GPIO_CLOCK_ER |= SPI_PIO_CS_EN;
64+
reg = SPI_PIO_CS_MODE & ~ (0x03 << (SPI_CS_TPM * 2));
65+
SPI_PIO_CS_MODE = reg | (1 << (SPI_CS_TPM * 2));
66+
reg = SPI_PIO_CS_PUPD & ~(0x03 << (SPI_CS_TPM * 2));
67+
SPI_PIO_CS_PUPD = reg | (0x01 << (SPI_CS_TPM * 2));
68+
reg = SPI_PIO_CS_OSPD & ~(0x03 << (SPI_CS_TPM * 2));
69+
SPI_PIO_CS_OSPD |= (0x03 << (SPI_CS_TPM * 2));
70+
spi_cs_off(SPI_CS_TPM);
71+
#endif
72+
}
73+
74+
static void spi1_pins_setup(void)
75+
{
76+
uint32_t reg;
77+
RCC_GPIO_CLOCK_ER |= SPI_PIO_CEN;
78+
/* Set mode = AF */
79+
reg = SPI_PIO_MODE & ~ (0x03 << (SPI1_CLOCK_PIN * 2));
80+
SPI_PIO_MODE = reg | (2 << (SPI1_CLOCK_PIN * 2));
81+
reg = SPI_PIO_MODE & ~ (0x03 << (SPI1_MOSI_PIN * 2));
82+
SPI_PIO_MODE = reg | (2 << (SPI1_MOSI_PIN * 2));
83+
reg = SPI_PIO_MODE & ~ (0x03 << (SPI1_MISO_PIN * 2));
84+
SPI_PIO_MODE = reg | (2 << (SPI1_MISO_PIN * 2));
85+
86+
/* Alternate function: use low pins (5,6,7) */
87+
reg = SPI_PIO_AFL & ~(0xf << ((SPI1_CLOCK_PIN) * 4));
88+
SPI_PIO_AFL = reg | (SPI1_PIN_AF << ((SPI1_CLOCK_PIN) * 4));
89+
reg = SPI_PIO_AFL & ~(0xf << ((SPI1_MOSI_PIN) * 4));
90+
SPI_PIO_AFL = reg | (SPI1_PIN_AF << ((SPI1_MOSI_PIN) * 4));
91+
reg = SPI_PIO_AFL & ~(0xf << ((SPI1_MISO_PIN) * 4));
92+
SPI_PIO_AFL = reg | (SPI1_PIN_AF << ((SPI1_MISO_PIN) * 4));
93+
}
94+
95+
static void spi_pins_release(void)
96+
{
97+
uint32_t reg;
98+
/* Set mode = 0 */
99+
SPI_PIO_MODE &= ~ (0x03 << (SPI1_CLOCK_PIN * 2));
100+
SPI_PIO_MODE &= ~ (0x03 << (SPI1_MOSI_PIN * 2));
101+
SPI_PIO_MODE &= ~ (0x03 << (SPI1_MISO_PIN * 2));
102+
103+
/* Alternate function clear */
104+
SPI_PIO_AFL &= ~(0xf << ((SPI1_CLOCK_PIN) * 4));
105+
SPI_PIO_AFL &= ~(0xf << ((SPI1_MOSI_PIN) * 4));
106+
SPI_PIO_AFL &= ~(0xf << ((SPI1_MISO_PIN) * 4));
107+
108+
/* Floating */
109+
SPI_PIO_PUPD &= ~ (0x03 << (SPI1_CLOCK_PIN * 2));
110+
SPI_PIO_PUPD &= ~ (0x03 << (SPI1_MOSI_PIN * 2));
111+
SPI_PIO_PUPD &= ~ (0x03 << (SPI1_MISO_PIN * 2));
112+
113+
/* Release CS */
114+
SPI_PIO_CS_MODE &= ~ (0x03 << (SPI_CS_FLASH * 2));
115+
SPI_PIO_CS_PUPD &= ~ (0x03 << (SPI_CS_TPM * 2));
116+
117+
}
118+
119+
static void spi1_reset(void)
120+
{
121+
APB2_CLOCK_RST |= SPI1_APB2_CLOCK_ER_VAL;
122+
APB2_CLOCK_RST &= ~SPI1_APB2_CLOCK_ER_VAL;
123+
}
124+
125+
uint8_t spi_read(void)
126+
{
127+
volatile uint32_t reg;
128+
do {
129+
reg = SPI1_SR;
130+
} while(!(reg & SPI_SR_RX_NOTEMPTY));
131+
return (uint8_t)SPI1_DR;
132+
}
133+
134+
void spi_write(const char byte)
135+
{
136+
int i;
137+
volatile uint32_t reg;
138+
do {
139+
reg = SPI1_SR;
140+
} while ((reg & SPI_SR_TX_EMPTY) == 0);
141+
SPI1_DR = byte;
142+
do {
143+
reg = SPI1_SR;
144+
} while ((reg & SPI_SR_TX_EMPTY) == 0);
145+
}
146+
147+
148+
void spi_init(int polarity, int phase)
149+
{
150+
static int initialized = 0;
151+
if (!initialized) {
152+
initialized++;
153+
spi1_pins_setup();
154+
spi_flash_pin_setup();
155+
spi_tpm2_pin_setup();
156+
APB2_CLOCK_ER |= SPI1_APB2_CLOCK_ER_VAL;
157+
spi1_reset();
158+
SPI1_CR1 = SPI_CR1_MASTER | (5 << 3) | (polarity << 1) | (phase << 0);
159+
SPI1_CR2 |= SPI_CR2_SSOE;
160+
SPI1_CR1 |= SPI_CR1_SPI_EN;
161+
}
162+
}
163+
164+
void spi_release(void)
165+
{
166+
spi1_reset();
167+
SPI1_CR2 &= ~SPI_CR2_SSOE;
168+
SPI1_CR1 = 0;
169+
spi_pins_release();
170+
}
171+

hal/spi/spi_drv_stm32.h

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
#ifndef SPI_DRV_STM32_H_INCLUDED
2+
#define SPI_DRV_STM32_H_INCLUDED
3+
#include <stdint.h>
4+
/** SPI settings **/
5+
6+
#define SPI1 (0x40013000)/* SPI1 base address */
7+
#define SPI1_APB2_CLOCK_ER_VAL (1 << 12)
8+
9+
#define CEN_GPIOA (1 << 0)
10+
#define CEN_GPIOB (1 << 1)
11+
#define CEN_GPIOC (1 << 2)
12+
#define CEN_GPIOD (1 << 3)
13+
#define CEN_GPIOE (1 << 4)
14+
15+
#ifdef PLATFORM_stm32f4
16+
#define APB2_CLOCK_ER (*(volatile uint32_t *)(0x40023844))
17+
#define APB2_CLOCK_RST (*(volatile uint32_t *)(0x40023824))
18+
#define CLOCK_SPEED (168000000)
19+
#define RCC_GPIO_CLOCK_ER (*(volatile uint32_t *)(0x40023830))
20+
#define GPIOA_BASE (0x40020000)
21+
#define GPIOB_BASE (0x40020400)
22+
#define GPIOC_BASE (0x40020800)
23+
#define GPIOD_BASE (0x40020C00)
24+
#define GPIOE_BASE (0x40021000)
25+
#define SPI_GPIO GPIOB_BASE
26+
#define SPI_CS_GPIO GPIOB_BASE
27+
#define SPI_PIO_BASE GPIOB_BASE
28+
#define SPI_CS_PIO_BASE GPIOE_BASE
29+
#define SPI_CS_FLASH 1 /* Flash CS connected to GPIOE1 */
30+
#define SPI_CS_TPM 0 /* TPM CS connected to GPIOE0 */
31+
#define SPI1_PIN_AF 5 /* Alternate function for SPI pins */
32+
#define SPI1_CLOCK_PIN 3 /* SPI_SCK: PB3 */
33+
#define SPI1_MISO_PIN 4 /* SPI_MISO PB4 */
34+
#define SPI1_MOSI_PIN 5 /* SPI_MOSI PB5 */
35+
#endif
36+
37+
#ifdef PLATFORM_stm32wb
38+
#define APB2_CLOCK_ER (*(volatile uint32_t *)(0x58000060))
39+
#define APB2_CLOCK_RST (*(volatile uint32_t *)(0x58000040))
40+
#define SPI_GPIO GPIOA_BASE
41+
#define RCC_GPIO_CLOCK_ER (*(volatile uint32_t *)(0x5800004C))
42+
#define GPIOA_BASE (0x48000000)
43+
#define GPIOB_BASE (0x48000400)
44+
#define GPIOC_BASE (0x48000800)
45+
#define GPIOD_BASE (0x48000C00)
46+
47+
#define SPI_CS_GPIO GPIOA_BASE
48+
#define SPI_CS_FLASH 4 /* Flash CS connected to GPIOA4 */
49+
#define SPI_CS_TPM 0 /* TPM CS connected to GPIOA0 */
50+
#define SPI1_PIN_AF 5 /* Alternate function for SPI pins */
51+
#define SPI1_CLOCK_PIN 5 /* SPI_SCK: PA5 */
52+
#define SPI1_MISO_PIN 6 /* SPI_MISO PA6 */
53+
#define SPI1_MOSI_PIN 7 /* SPI_MOSI PA7 */
54+
#endif
55+
56+
#define SPI_PIO_BASE SPI_GPIO
57+
#define SPI_CS_PIO_BASE SPI_CS_GPIO
58+
59+
#if (SPI_GPIO == GPIOA_BASE)
60+
# define SPI_PIO_CEN CEN_GPIOA
61+
#elif (SPI_GPIO == GPIOB_BASE)
62+
# define SPI_PIO_CEN CEN_GPIOB
63+
#elif (SPI_GPIO == GPIOC_BASE)
64+
# define SPI_PIO_CEN CEN_GPIOC
65+
#elif (SPI_GPIO == GPIOD_BASE)
66+
# define SPI_PIO_CEN CEN_GPIOD
67+
#elif (SPI_GPIO == GPIOE_BASE)
68+
# define SPI_PIO_CEN CEN_GPIOE
69+
#endif
70+
71+
#if (SPI_CS_GPIO == GPIOA_BASE)
72+
# define SPI_PIO_CS_CEN CEN_GPIOA
73+
#elif (SPI_CS_GPIO == GPIOB_BASE)
74+
# define SPI_PIO_CS_CEN CEN_GPIOB
75+
#elif (SPI_CS_GPIO == GPIOC_BASE)
76+
# define SPI_PIO_CS_CEN CEN_GPIOC
77+
#elif (SPI_CS_GPIO == GPIOD_BASE)
78+
# define SPI_PIO_CS_CEN CEN_GPIOD
79+
#elif (SPI_CS_GPIO == GPIOE_BASE)
80+
# define SPI_PIO_CS_CEN CEN_GPIOE
81+
#endif
82+
83+
84+
#define SPI1_CR1 (*(volatile uint32_t *)(SPI1))
85+
#define SPI1_CR2 (*(volatile uint32_t *)(SPI1 + 0x04))
86+
#define SPI1_SR (*(volatile uint32_t *)(SPI1 + 0x08))
87+
#define SPI1_DR (*(volatile uint32_t *)(SPI1 + 0x0c))
88+
89+
#define SPI_CR1_CLOCK_PHASE (1 << 0)
90+
#define SPI_CR1_CLOCK_POLARITY (1 << 1)
91+
#define SPI_CR1_MASTER (1 << 2)
92+
#define SPI_CR1_BAUDRATE (0x07 << 3)
93+
#define SPI_CR1_SPI_EN (1 << 6)
94+
#define SPI_CR1_LSBFIRST (1 << 7)
95+
#define SPI_CR1_SSI (1 << 8)
96+
#define SPI_CR1_SSM (1 << 9)
97+
#define SPI_CR1_16BIT_FORMAT (1 << 11)
98+
#define SPI_CR1_TX_CRC_NEXT (1 << 12)
99+
#define SPI_CR1_HW_CRC_EN (1 << 13)
100+
#define SPI_CR1_BIDIOE (1 << 14)
101+
#define SPI_CR2_SSOE (1 << 2)
102+
103+
104+
#define SPI_SR_RX_NOTEMPTY (1 << 0)
105+
#define SPI_SR_TX_EMPTY (1 << 1)
106+
#define SPI_SR_BUSY (1 << 7)
107+
108+
109+
110+
111+
112+
113+
#define SPI_PIO_MODE (*(volatile uint32_t *)(SPI_PIO_BASE + 0x00))
114+
#define SPI_PIO_AFL (*(volatile uint32_t *)(SPI_PIO_BASE + 0x20))
115+
#define SPI_PIO_AFH (*(volatile uint32_t *)(SPI_PIO_BASE + 0x24))
116+
#define SPI_PIO_OSPD (*(volatile uint32_t *)(SPI_PIO_BASE + 0x08))
117+
#define SPI_PIO_PUPD (*(volatile uint32_t *)(SPI_PIO_BASE + 0x0c))
118+
#define SPI_PIO_BSRR (*(volatile uint32_t *)(SPI_PIO_BASE + 0x18))
119+
#define SPI_PIO_CS_MODE (*(volatile uint32_t *)(SPI_CS_PIO_BASE + 0x00))
120+
#define SPI_PIO_CS_AFL (*(volatile uint32_t *)(SPI_CS_PIO_BASE + 0x20))
121+
#define SPI_PIO_CS_AFH (*(volatile uint32_t *)(SPI_CS_PIO_BASE + 0x24))
122+
#define SPI_PIO_CS_OSPD (*(volatile uint32_t *)(SPI_CS_PIO_BASE + 0x08))
123+
#define SPI_PIO_CS_PUPD (*(volatile uint32_t *)(SPI_CS_PIO_BASE + 0x0c))
124+
#define SPI_PIO_CS_BSRR (*(volatile uint32_t *)(SPI_CS_PIO_BASE + 0x18))
125+
#define SPI_PIO_CS_ODR (*(volatile uint32_t *)(SPI_CS_PIO_BASE + 0x14))
126+
#define GPIO_MODE_AF (2)
127+
128+
129+
#endif

include/spi_drv.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@
3030
#define SPI_DRV_H_INCLUDED
3131

3232
#include <stdint.h>
33-
#ifdef PLATFORM_stm32f4
34-
#include "hal/spi/spi_drv_stm32f4.h"
33+
#if defined(PLATFORM_stm32f4) || defined(PLATFORM_stm32f7) || defined(PLATFORM_stm32wb)
34+
#include "hal/spi/spi_drv_stm32.h"
3535
#endif
3636

3737
void spi_init(int polarity, int phase);

test-app/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ endif
4040

4141
ifeq ($(SPI_FLASH),1)
4242
CFLAGS+=-DSPI_FLASH
43-
APP_OBJS+=../hal/spi/spi_drv_$(TARGET).o ../src/spi_flash.o
43+
APP_OBJS+=../hal/spi/spi_drv_$(SPI_TARGET).o ../src/spi_flash.o
4444
endif
4545

4646
ifeq ($(TARGET),kinetis)

0 commit comments

Comments
 (0)