Skip to content

Commit 630a10e

Browse files
committed
Automated tests for EXT_FLASH/SPI_FLASH
1 parent c989a13 commit 630a10e

14 files changed

Lines changed: 677 additions & 97 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
*.i*86
3636
*.x86_64
3737
*.hex
38+
*.rom
3839

3940
# Debug files
4041
*.dSYM/

Makefile

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ LD:=$(CROSS_COMPILE)gcc
44
AS:=$(CROSS_COMPILE)gcc
55
OBJCOPY:=$(CROSS_COMPILE)objcopy
66
SIZE:=$(CROSS_COMPILE)size
7-
BOOT0_OFFSET?=`cat include/target.h |grep WOLFBOOT_PARTITION_BOOT_ADDRESS | sed -e "s/.*[ ]//g"`
7+
BOOT0_OFFSET?=`cat include/target.h |grep WOLFBOOT_PARTITION_BOOT_ADDRESS | head -1 | sed -e "s/.*[ ]//g"`
88
BOOT_IMG?=test-app/image.bin
99
SIGN?=ED25519
1010
TARGET?=stm32f4
@@ -17,6 +17,7 @@ SWAP?=1
1717
CORTEX_M0?=0
1818
NO_ASM?=0
1919
EXT_FLASH?=0
20+
SPI_FLASH?=0
2021
ALLOW_DOWNGRADE?=0
2122
NVM_FLASH_WRITEONCE?=0
2223
LSCRIPT:=hal/$(TARGET).ld
@@ -71,7 +72,7 @@ ifeq ($(FASTMATH),1)
7172
endif
7273

7374
CFLAGS+=-mthumb -Wall -Wextra -Wno-main -Wstack-usage=1024 -ffreestanding -Wno-unused \
74-
-Ilib/bootutil/include -Iinclude/ -Ilib/wolfssl -nostartfiles \
75+
-I. -Ilib/bootutil/include -Iinclude/ -Ilib/wolfssl -nostartfiles \
7576
-DWOLFSSL_USER_SETTINGS \
7677
-mthumb -mlittle-endian -mthumb-interwork \
7778
-DPLATFORM_$(TARGET)
@@ -81,10 +82,17 @@ ifeq ($(TARGET),kinetis)
8182
OBJS+= $(KINETIS_DRIVERS)/drivers/fsl_clock.o $(KINETIS_DRIVERS)/drivers/fsl_ftfx_flash.o $(KINETIS_DRIVERS)/drivers/fsl_ftfx_cache.o $(KINETIS_DRIVERS)/drivers/fsl_ftfx_controller.o
8283
endif
8384

85+
ifeq ($(SPI_FLASH),1)
86+
EXT_FLASH=1
87+
CFLAGS+= -DSPI_FLASH=1
88+
OBJS+= src/spi_flash.o hal/spi/spi_drv_$(TARGET).o
89+
endif
90+
8491
ifeq ($(EXT_FLASH),1)
8592
CFLAGS+= -DEXT_FLASH=1 -DPART_UPDATE_EXT=1 -DPART_SWAP_EXT=1
8693
endif
8794

95+
8896
ifeq ($(ALLOW_DOWNGRADE),1)
8997
CFLAGS+= -DALLOW_DOWNGRADE
9098
endif

hal/spi/spi_drv_stm32f4.c

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
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_stm32f4.h
8+
*
9+
* Copyright (C) 2018 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_stm32f4.h"
30+
31+
void spi_cs_off(void)
32+
{
33+
int i;
34+
GPIOE_BSRR |= (1 << SPI_FLASH_PIN);
35+
while(!(GPIOE_ODR & (1 << SPI_FLASH_PIN)))
36+
;
37+
for(i = 0; i < 168000; i++)
38+
;
39+
}
40+
41+
void spi_cs_on(void)
42+
{
43+
GPIOE_BSRR |= (1 << (SPI_FLASH_PIN + 16));
44+
while(GPIOE_ODR & (1 << SPI_FLASH_PIN))
45+
;
46+
}
47+
48+
49+
static void spi_flash_pin_setup(void)
50+
{
51+
uint32_t reg;
52+
AHB1_CLOCK_ER |= GPIOE_AHB1_CLOCK_ER;
53+
reg = GPIOE_MODE & ~ (0x03 << (SPI_FLASH_PIN * 2));
54+
GPIOE_MODE = reg | (1 << (SPI_FLASH_PIN * 2));
55+
56+
reg = GPIOE_PUPD & ~(0x03 << (SPI_FLASH_PIN * 2));
57+
GPIOE_PUPD = reg | (0x01 << (SPI_FLASH_PIN * 2));
58+
59+
reg = GPIOE_OSPD & ~(0x03 << (SPI_FLASH_PIN * 2));
60+
GPIOE_OSPD |= (0x03 << (SPI_FLASH_PIN * 2));
61+
62+
}
63+
64+
static void spi1_pins_setup(void)
65+
{
66+
uint32_t reg;
67+
AHB1_CLOCK_ER |= GPIOB_AHB1_CLOCK_ER;
68+
/* Set mode = AF */
69+
reg = GPIOB_MODE & ~ (0x03 << (SPI1_CLOCK_PIN * 2));
70+
GPIOB_MODE = reg | (2 << (SPI1_CLOCK_PIN * 2));
71+
reg = GPIOB_MODE & ~ (0x03 << (SPI1_MOSI_PIN * 2));
72+
GPIOB_MODE = reg | (2 << (SPI1_MOSI_PIN * 2));
73+
reg = GPIOB_MODE & ~ (0x03 << (SPI1_MISO_PIN * 2));
74+
GPIOB_MODE = reg | (2 << (SPI1_MISO_PIN * 2));
75+
76+
/* Alternate function: use low pins (5,6,7) */
77+
reg = GPIOB_AFL & ~(0xf << ((SPI1_CLOCK_PIN) * 4));
78+
GPIOB_AFL = reg | (SPI1_PIN_AF << ((SPI1_CLOCK_PIN) * 4));
79+
reg = GPIOB_AFL & ~(0xf << ((SPI1_MOSI_PIN) * 4));
80+
GPIOB_AFL = reg | (SPI1_PIN_AF << ((SPI1_MOSI_PIN) * 4));
81+
reg = GPIOB_AFL & ~(0xf << ((SPI1_MISO_PIN) * 4));
82+
GPIOB_AFL = reg | (SPI1_PIN_AF << ((SPI1_MISO_PIN) * 4));
83+
}
84+
85+
static void spi_pins_release(void)
86+
{
87+
uint32_t reg;
88+
/* Set mode = 0 */
89+
GPIOB_MODE &= ~ (0x03 << (SPI1_CLOCK_PIN * 2));
90+
GPIOB_MODE &= ~ (0x03 << (SPI1_MOSI_PIN * 2));
91+
GPIOB_MODE &= ~ (0x03 << (SPI1_MISO_PIN * 2));
92+
93+
/* Alternate function clear */
94+
GPIOB_AFL &= ~(0xf << ((SPI1_CLOCK_PIN) * 4));
95+
GPIOB_AFL &= ~(0xf << ((SPI1_MOSI_PIN) * 4));
96+
GPIOB_AFL &= ~(0xf << ((SPI1_MISO_PIN) * 4));
97+
98+
/* Floating */
99+
GPIOB_PUPD &= ~ (0x03 << (SPI1_CLOCK_PIN * 2));
100+
GPIOB_PUPD &= ~ (0x03 << (SPI1_MOSI_PIN * 2));
101+
GPIOB_PUPD &= ~ (0x03 << (SPI1_MISO_PIN * 2));
102+
103+
/* Release CS */
104+
GPIOE_MODE &= ~ (0x03 << (SPI_FLASH_PIN * 2));
105+
GPIOE_PUPD &= ~ (0x03 << (SPI_FLASH_PIN * 2));
106+
107+
/* Disable GPIOB+GPIOE clock */
108+
AHB1_CLOCK_ER &= ~(GPIOB_AHB1_CLOCK_ER | GPIOE_AHB1_CLOCK_ER);
109+
}
110+
111+
static void spi1_reset(void)
112+
{
113+
APB2_CLOCK_RST |= SPI1_APB2_CLOCK_ER_VAL;
114+
APB2_CLOCK_RST &= ~SPI1_APB2_CLOCK_ER_VAL;
115+
}
116+
117+
uint8_t spi_read(void)
118+
{
119+
volatile uint32_t reg;
120+
do {
121+
reg = SPI1_SR;
122+
} while(!(reg & SPI_SR_RX_NOTEMPTY));
123+
return (uint8_t)SPI1_DR;
124+
}
125+
126+
void spi_write(const char byte)
127+
{
128+
int i;
129+
volatile uint32_t reg;
130+
do {
131+
reg = SPI1_SR;
132+
} while ((reg & SPI_SR_TX_EMPTY) == 0);
133+
SPI1_DR = byte;
134+
do {
135+
reg = SPI1_SR;
136+
} while ((reg & SPI_SR_TX_EMPTY) == 0);
137+
}
138+
139+
140+
void spi_init(int polarity, int phase)
141+
{
142+
spi1_pins_setup();
143+
spi_flash_pin_setup();
144+
APB2_CLOCK_ER |= SPI1_APB2_CLOCK_ER_VAL;
145+
spi1_reset();
146+
SPI1_CR1 = SPI_CR1_MASTER | (5 << 3) | (polarity << 1) | (phase << 0);
147+
SPI1_CR2 |= SPI_CR2_SSOE;
148+
SPI1_CR1 |= SPI_CR1_SPI_EN;
149+
}
150+
151+
void spi_release(void)
152+
{
153+
spi1_reset();
154+
SPI1_CR2 &= ~SPI_CR2_SSOE;
155+
SPI1_CR1 = 0;
156+
spi_pins_release();
157+
}
158+

hal/spi/spi_drv_stm32f4.h

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
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 SPI_FLASH_PIN 1 /* Flash CS connected to GPIOE1 */
8+
#define SPI1_PIN_AF 5 /* Alternate function for SPI pins */
9+
#define SPI1_CLOCK_PIN 3 /* SPI_SCK: PB3 */
10+
#define SPI1_MISO_PIN 4 /* SPI_MISO PB4 */
11+
#define SPI1_MOSI_PIN 5 /* SPI_MOSI PB5 */
12+
13+
#define SPI1_CR1 (*(volatile uint32_t *)(SPI1))
14+
#define SPI1_CR2 (*(volatile uint32_t *)(SPI1 + 0x04))
15+
#define SPI1_SR (*(volatile uint32_t *)(SPI1 + 0x08))
16+
#define SPI1_DR (*(volatile uint32_t *)(SPI1 + 0x0c))
17+
18+
#define SPI_CR1_CLOCK_PHASE (1 << 0)
19+
#define SPI_CR1_CLOCK_POLARITY (1 << 1)
20+
#define SPI_CR1_MASTER (1 << 2)
21+
#define SPI_CR1_BAUDRATE (0x07 << 3)
22+
#define SPI_CR1_SPI_EN (1 << 6)
23+
#define SPI_CR1_LSBFIRST (1 << 7)
24+
#define SPI_CR1_SSI (1 << 8)
25+
#define SPI_CR1_SSM (1 << 9)
26+
#define SPI_CR1_16BIT_FORMAT (1 << 11)
27+
#define SPI_CR1_TX_CRC_NEXT (1 << 12)
28+
#define SPI_CR1_HW_CRC_EN (1 << 13)
29+
#define SPI_CR1_BIDIOE (1 << 14)
30+
#define SPI_CR2_SSOE (1 << 2)
31+
32+
33+
#define SPI_SR_RX_NOTEMPTY (1 << 0)
34+
#define SPI_SR_TX_EMPTY (1 << 1)
35+
#define SPI_SR_BUSY (1 << 7)
36+
37+
#define APB2_CLOCK_ER (*(volatile uint32_t *)(0x40023844))
38+
#define APB2_CLOCK_RST (*(volatile uint32_t *)(0x40023824))
39+
#define SPI1_APB2_CLOCK_ER_VAL (1 << 12)
40+
41+
42+
#define CLOCK_SPEED (168000000)
43+
44+
45+
#define AHB1_CLOCK_ER (*(volatile uint32_t *)(0x40023830))
46+
#define GPIOB_AHB1_CLOCK_ER (1 << 1)
47+
#define GPIOE_AHB1_CLOCK_ER (1 << 4)
48+
#define GPIOB_BASE 0x40020400
49+
#define GPIOE_BASE 0x40021000
50+
51+
#define GPIOB_MODE (*(volatile uint32_t *)(GPIOB_BASE + 0x00))
52+
#define GPIOB_AFL (*(volatile uint32_t *)(GPIOB_BASE + 0x20))
53+
#define GPIOB_AFH (*(volatile uint32_t *)(GPIOB_BASE + 0x24))
54+
#define GPIOB_OSPD (*(volatile uint32_t *)(GPIOB_BASE + 0x08))
55+
#define GPIOB_PUPD (*(volatile uint32_t *)(GPIOB_BASE + 0x0c))
56+
#define GPIOB_BSRR (*(volatile uint32_t *)(GPIOB_BASE + 0x18))
57+
#define GPIOE_MODE (*(volatile uint32_t *)(GPIOE_BASE + 0x00))
58+
#define GPIOE_AFL (*(volatile uint32_t *)(GPIOE_BASE + 0x20))
59+
#define GPIOE_AFH (*(volatile uint32_t *)(GPIOE_BASE + 0x24))
60+
#define GPIOE_OSPD (*(volatile uint32_t *)(GPIOE_BASE + 0x08))
61+
#define GPIOE_PUPD (*(volatile uint32_t *)(GPIOE_BASE + 0x0c))
62+
#define GPIOE_BSRR (*(volatile uint32_t *)(GPIOE_BASE + 0x18))
63+
#define GPIOE_ODR (*(volatile uint32_t *)(GPIOE_BASE + 0x14))
64+
#define GPIO_MODE_AF (2)
65+
66+
67+
#endif

hal/stm32f4.c

Lines changed: 4 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -326,81 +326,10 @@ void hal_init(void)
326326

327327
void hal_prepare_boot(void)
328328
{
329+
#ifdef SPI_FLASH
330+
spi_release();
331+
#endif
332+
329333
clock_pll_off();
330334
}
331335

332-
333-
#ifdef EXT_FLASH
334-
#define SIM_ADDRESS (0x40000)
335-
336-
int ext_flash_read(uint32_t address, uint8_t *data, int len)
337-
{
338-
int i;
339-
uint32_t val;
340-
address += SIM_ADDRESS;
341-
for (i = 0; i < len; i++)
342-
data[i] = *((uint8_t *)(address + i));
343-
return len;
344-
}
345-
346-
int ext_flash_write(uint32_t address, const uint8_t *data, int len)
347-
{
348-
int i;
349-
uint32_t val;
350-
address += SIM_ADDRESS;
351-
flash_wait_complete();
352-
clear_errors();
353-
/* Set 8-bit write */
354-
FLASH_CR &= (~(0x03 << 8));
355-
for (i = 0; i < len; i++) {
356-
FLASH_CR |= FLASH_CR_PG;
357-
*((uint8_t *)(address + i)) = data[i];
358-
flash_wait_complete();
359-
FLASH_CR &= ~FLASH_CR_PG;
360-
}
361-
return 0;
362-
}
363-
364-
void ext_flash_unlock(void)
365-
{
366-
FLASH_CR |= FLASH_CR_LOCK;
367-
FLASH_KEYR = FLASH_KEY1;
368-
FLASH_KEYR = FLASH_KEY2;
369-
}
370-
371-
void ext_flash_lock(void)
372-
{
373-
FLASH_CR |= FLASH_CR_LOCK;
374-
}
375-
376-
377-
int ext_flash_erase(uint32_t address, int len)
378-
{
379-
int start = -1, end = -1;
380-
uint32_t end_address;
381-
int i;
382-
address += SIM_ADDRESS;
383-
end_address = address + len - 1;
384-
385-
if (address < flash_sector[0] || end_address > FLASH_TOP)
386-
return -1;
387-
for (i = 0; i < 8; i++)
388-
{
389-
if ((address >= flash_sector[i]) && (address < flash_sector[i + 1])) {
390-
start = i;
391-
}
392-
if ((end_address >= flash_sector[i]) && (end_address < flash_sector[i + 1])) {
393-
end = i;
394-
}
395-
if (start > 0 && end > 0)
396-
break;
397-
}
398-
if (start < 0 || end < 0)
399-
return -1;
400-
for (i = start; i <= end; i++)
401-
flash_erase_sector(i);
402-
return 0;
403-
}
404-
405-
406-
#endif

0 commit comments

Comments
 (0)