Skip to content

Commit bfc2ea6

Browse files
FRASTMMaureenHelm
authored andcommitted
drivers: flash: Add STM32G0XX flash support
Add flash support for STM32G0X SoC series. Signed-off-by: Philippe Retornaz <[email protected] Signed-off-by: Francois Ramu <[email protected]>
1 parent 7ea0013 commit bfc2ea6

File tree

8 files changed

+267
-6
lines changed

8 files changed

+267
-6
lines changed

drivers/flash/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ if(CONFIG_CLOCK_CONTROL_STM32_CUBE)
2626
zephyr_sources_ifdef(CONFIG_SOC_SERIES_STM32F7X flash_stm32f7x.c)
2727
zephyr_sources_ifdef(CONFIG_SOC_SERIES_STM32L4X flash_stm32l4x.c)
2828
zephyr_sources_ifdef(CONFIG_SOC_SERIES_STM32WBX flash_stm32wbx.c)
29+
zephyr_sources_ifdef(CONFIG_SOC_SERIES_STM32G0X flash_stm32g0x.c)
2930
endif()
3031

3132
zephyr_include_directories_ifdef(

drivers/flash/Kconfig.stm32

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,24 @@ if SOC_FAMILY_STM32
1010

1111
menuconfig SOC_FLASH_STM32
1212
bool "STM32 flash driver"
13-
depends on (SOC_SERIES_STM32F0X || SOC_SERIES_STM32F3X || SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X || SOC_SERIES_STM32L4X || SOC_SERIES_STM32WBX)
13+
depends on (SOC_SERIES_STM32F0X || SOC_SERIES_STM32F3X || SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X || SOC_SERIES_STM32L4X || SOC_SERIES_STM32WBX || SOC_SERIES_STM32G0X)
1414
select FLASH_HAS_DRIVER_ENABLED
1515
default y
1616
select FLASH_PAGE_LAYOUT if SOC_SERIES_STM32F0X
1717
select FLASH_PAGE_LAYOUT if SOC_SERIES_STM32F3X
18+
select FLASH_PAGE_LAYOUT if SOC_SERIES_STM32G0X
1819
select FLASH_PAGE_LAYOUT if SOC_SERIES_STM32F4X
1920
select FLASH_PAGE_LAYOUT if SOC_SERIES_STM32F7X
2021
select FLASH_PAGE_LAYOUT if SOC_SERIES_STM32L4X
2122
select FLASH_PAGE_LAYOUT if SOC_SERIES_STM32WBX
2223
select FLASH_HAS_PAGE_LAYOUT if SOC_SERIES_STM32F0X
2324
select FLASH_HAS_PAGE_LAYOUT if SOC_SERIES_STM32F3X
25+
select FLASH_HAS_PAGE_LAYOUT if SOC_SERIES_STM32G0X
2426
select FLASH_HAS_PAGE_LAYOUT if SOC_SERIES_STM32F4X
2527
select FLASH_HAS_PAGE_LAYOUT if SOC_SERIES_STM32F7X
2628
select FLASH_HAS_PAGE_LAYOUT if SOC_SERIES_STM32L4X
2729
select FLASH_HAS_PAGE_LAYOUT if SOC_SERIES_STM32WBX
2830
help
29-
Enable STM32F0x, STM32F3x, STM32F4x, STM32F7x, STM32L4x or
30-
STM32WBx series flash driver.
31+
Enable STM32F0x, STM32F3x, STM32F4x, STM32F7x, STM32L4x, STM32WBx or STM32G0x series flash driver.
3132

3233
endif

drivers/flash/flash_stm32.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@
3333
/* STM32WB: maximum erase time of 24.5ms for a 4K sector */
3434
#elif defined(CONFIG_SOC_SERIES_STM32WBX)
3535
#define STM32_FLASH_MAX_ERASE_TIME (K_MSEC(25))
36+
#elif defined(CONFIG_SOC_SERIES_STM32G0X)
37+
/* STM32G0: maximum erase time of 40ms for a 2K sector */
38+
#define STM32_FLASH_MAX_ERASE_TIME (K_MSEC(40))
3639
#endif
3740

3841
/* Let's wait for double the max erase time to be sure that the operation is
@@ -123,7 +126,8 @@ int flash_stm32_wait_flash_idle(struct device *dev)
123126
static void flash_stm32_flush_caches(struct device *dev,
124127
off_t offset, size_t len)
125128
{
126-
#if defined(CONFIG_SOC_SERIES_STM32F0X) || defined(CONFIG_SOC_SERIES_STM32F3X)
129+
#if defined(CONFIG_SOC_SERIES_STM32F0X) || defined(CONFIG_SOC_SERIES_STM32F3X) || \
130+
defined(CONFIG_SOC_SERIES_STM32G0X)
127131
ARG_UNUSED(dev);
128132
ARG_UNUSED(offset);
129133
ARG_UNUSED(len);
@@ -226,6 +230,8 @@ static int flash_stm32_write_protection(struct device *dev, bool enable)
226230
struct stm32l4x_flash *regs = FLASH_STM32_REGS(dev);
227231
#elif defined(CONFIG_SOC_SERIES_STM32WBX)
228232
struct stm32wbx_flash *regs = FLASH_STM32_REGS(dev);
233+
#elif defined(CONFIG_SOC_SERIES_STM32G0X)
234+
struct stm32g0x_flash *regs = FLASH_STM32_REGS(dev);
229235
#endif
230236
int rc = 0;
231237

@@ -269,6 +275,10 @@ static struct flash_stm32_priv flash_data = {
269275
.enr = LL_AHB1_GRP1_PERIPH_FLASH },
270276
#elif defined(CONFIG_SOC_SERIES_STM32WBX)
271277
.regs = (struct stm32wbx_flash *) DT_FLASH_DEV_BASE_ADDRESS,
278+
#elif defined(CONFIG_SOC_SERIES_STM32G0X)
279+
.regs = (struct stm32g0x_flash *) DT_FLASH_DEV_BASE_ADDRESS,
280+
.pclken = { .bus = STM32_CLOCK_BUS_AHB1,
281+
.enr = LL_AHB1_GRP1_PERIPH_FLASH },
272282
#endif
273283
};
274284

@@ -294,7 +304,8 @@ static int stm32_flash_init(struct device *dev)
294304
struct flash_stm32_priv *p = FLASH_STM32_PRIV(dev);
295305
#if defined(CONFIG_SOC_SERIES_STM32L4X) || \
296306
defined(CONFIG_SOC_SERIES_STM32F0X) || \
297-
defined(CONFIG_SOC_SERIES_STM32F3X)
307+
defined(CONFIG_SOC_SERIES_STM32F3X) || \
308+
defined(CONFIG_SOC_SERIES_STM32G0X)
298309
struct device *clk = device_get_binding(STM32_CLOCK_CONTROL_NAME);
299310

300311
/*

drivers/flash/flash_stm32.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212

1313
#if defined(CONFIG_SOC_SERIES_STM32L4X) || \
1414
defined(CONFIG_SOC_SERIES_STM32F0X) || \
15-
defined(CONFIG_SOC_SERIES_STM32F3X)
15+
defined(CONFIG_SOC_SERIES_STM32F3X) || \
16+
defined(CONFIG_SOC_SERIES_STM32G0X)
1617
#include <drivers/clock_control.h>
1718
#include <clock_control/stm32_clock_control.h>
1819
#endif
@@ -36,6 +37,10 @@ struct flash_stm32_priv {
3637
struct stm32_pclken pclken;
3738
#elif defined(CONFIG_SOC_SERIES_STM32WBX)
3839
struct stm32wbx_flash *regs;
40+
#elif defined(CONFIG_SOC_SERIES_STM32G0X)
41+
struct stm32g0x_flash *regs;
42+
/* clock subsystem driving this peripheral */
43+
struct stm32_pclken pclken;
3944
#endif
4045
struct k_sem sem;
4146
};

drivers/flash/flash_stm32g0x.c

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
/*
2+
* Copyright (c) 2019 Philippe Retornaz <[email protected]>
3+
* Copyright (c) 2017 Linaro Limited
4+
* Copyright (c) 2017 BayLibre, SAS
5+
*
6+
* SPDX-License-Identifier: Apache-2.0
7+
*/
8+
9+
#define LOG_DOMAIN flash_stm32g0
10+
#define LOG_LEVEL CONFIG_FLASH_LOG_LEVEL
11+
#include <logging/log.h>
12+
LOG_MODULE_REGISTER(LOG_DOMAIN);
13+
14+
#include <kernel.h>
15+
#include <device.h>
16+
#include <string.h>
17+
#include <flash.h>
18+
#include <init.h>
19+
#include <soc.h>
20+
21+
#include "flash_stm32.h"
22+
23+
24+
#define STM32G0X_PAGE_SHIFT 11
25+
26+
27+
/*
28+
* offset and len must be aligned on 8 for write,
29+
* positive and not beyond end of flash
30+
*/
31+
bool flash_stm32_valid_range(struct device *dev, off_t offset, u32_t len,
32+
bool write)
33+
{
34+
return (!write || (offset % 8 == 0 && len % 8 == 0)) &&
35+
flash_stm32_range_exists(dev, offset, len);
36+
}
37+
38+
/*
39+
* STM32G0xx devices can have up to 64 2K pages
40+
*/
41+
static unsigned int get_page(off_t offset)
42+
{
43+
return offset >> STM32G0X_PAGE_SHIFT;
44+
}
45+
46+
static int write_dword(struct device *dev, off_t offset, u64_t val)
47+
{
48+
volatile u32_t *flash = (u32_t *)(offset + CONFIG_FLASH_BASE_ADDRESS);
49+
struct stm32g0x_flash *regs = FLASH_STM32_REGS(dev);
50+
u32_t tmp;
51+
int rc;
52+
53+
/* if the control register is locked, do not fail silently */
54+
if (regs->cr & FLASH_CR_LOCK) {
55+
return -EIO;
56+
}
57+
58+
/* Check that no Flash main memory operation is ongoing */
59+
rc = flash_stm32_wait_flash_idle(dev);
60+
if (rc < 0) {
61+
return rc;
62+
}
63+
64+
/* Check if this double word is erased */
65+
if (flash[0] != 0xFFFFFFFFUL ||
66+
flash[1] != 0xFFFFFFFFUL) {
67+
return -EIO;
68+
}
69+
70+
/* Set the PG bit */
71+
regs->cr |= FLASH_CR_PG;
72+
73+
/* Flush the register write */
74+
tmp = regs->cr;
75+
76+
/* Perform the data write operation at the desired memory address */
77+
flash[0] = (u32_t)val;
78+
flash[1] = (u32_t)(val >> 32);
79+
80+
/* Wait until the BSY bit is cleared */
81+
rc = flash_stm32_wait_flash_idle(dev);
82+
83+
/* Clear the PG bit */
84+
regs->cr &= (~FLASH_CR_PG);
85+
86+
return rc;
87+
}
88+
89+
static int erase_page(struct device *dev, unsigned int page)
90+
{
91+
struct stm32g0x_flash *regs = FLASH_STM32_REGS(dev);
92+
u32_t tmp;
93+
int rc;
94+
95+
/* if the control register is locked, do not fail silently */
96+
if (regs->cr & FLASH_CR_LOCK) {
97+
return -EIO;
98+
}
99+
100+
/* Check that no Flash memory operation is ongoing */
101+
rc = flash_stm32_wait_flash_idle(dev);
102+
if (rc < 0) {
103+
return rc;
104+
}
105+
106+
/* Set the PER bit and select the page you wish to erase */
107+
regs->cr |= FLASH_CR_PER;
108+
regs->cr &= ~FLASH_CR_PNB_Msk;
109+
regs->cr |= ((page % 256) << 3);
110+
111+
/* Set the STRT bit */
112+
regs->cr |= FLASH_CR_STRT;
113+
114+
/* flush the register write */
115+
tmp = regs->cr;
116+
117+
/* Wait for the BSY bit */
118+
rc = flash_stm32_wait_flash_idle(dev);
119+
120+
regs->cr &= ~FLASH_CR_PER;
121+
122+
return rc;
123+
}
124+
125+
int flash_stm32_block_erase_loop(struct device *dev, unsigned int offset,
126+
unsigned int len)
127+
{
128+
int i, rc = 0;
129+
130+
i = get_page(offset);
131+
for (; i <= get_page(offset + len - 1) ; ++i) {
132+
rc = erase_page(dev, i);
133+
if (rc < 0) {
134+
break;
135+
}
136+
}
137+
138+
return rc;
139+
}
140+
141+
int flash_stm32_write_range(struct device *dev, unsigned int offset,
142+
const void *data, unsigned int len)
143+
{
144+
int i, rc = 0;
145+
146+
for (i = 0; i < len; i += 8, offset += 8) {
147+
rc = write_dword(dev, offset, ((const u64_t *) data)[i>>3]);
148+
if (rc < 0) {
149+
return rc;
150+
}
151+
}
152+
153+
return rc;
154+
}
155+
156+
void flash_stm32_page_layout(struct device *dev,
157+
const struct flash_pages_layout **layout,
158+
size_t *layout_size)
159+
{
160+
static struct flash_pages_layout stm32g0_flash_layout = {
161+
.pages_count = 0,
162+
.pages_size = 0,
163+
};
164+
165+
ARG_UNUSED(dev);
166+
167+
if (stm32g0_flash_layout.pages_count == 0) {
168+
stm32g0_flash_layout.pages_count = FLASH_SIZE / FLASH_PAGE_SIZE;
169+
stm32g0_flash_layout.pages_size = FLASH_PAGE_SIZE;
170+
}
171+
172+
*layout = &stm32g0_flash_layout;
173+
*layout_size = 1;
174+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
title: STM32 G0 Flash Controller
3+
version: 0.1
4+
5+
description: >
6+
This binding gives a base representation of the STM32 G0 Flash Controller
7+
8+
inherits:
9+
!include flash-controller.yaml
10+
11+
properties:
12+
compatible:
13+
constraint: "st,stm32g0-flash-controller"

soc/arm/st_stm32/stm32g0/dts_fixup.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,7 @@
88

99
#define DT_NUM_IRQ_PRIO_BITS DT_ARM_V6M_NVIC_E000E100_ARM_NUM_IRQ_PRIORITY_BITS
1010

11+
#define DT_FLASH_DEV_BASE_ADDRESS DT_ST_STM32G0_FLASH_CONTROLLER_40022000_BASE_ADDRESS
12+
#define DT_FLASH_DEV_NAME DT_ST_STM32G0_FLASH_CONTROLLER_40022000_LABEL
13+
1114
/* End of SoC Level DTS fixup file */
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright (c) 2019 Philippe Retornaz <[email protected]>
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef _STM32G0X_FLASH_REGISTERS_H_
8+
#define _STM32G0X_FLASH_REGISTERS_H_
9+
10+
#define FLASH_SR_BSY FLASH_SR_BSY1
11+
12+
enum {
13+
STM32_FLASH_LATENCY_0 = 0x0,
14+
STM32_FLASH_LATENCY_1 = 0x1,
15+
STM32_FLASH_LATENCY_2 = 0x2,
16+
};
17+
18+
/* 3.7.1 FLASH_ACR */
19+
union __ef_acr {
20+
u32_t val;
21+
struct {
22+
u32_t latency :3 __packed;
23+
u32_t rsvd__3_7 :5 __packed;
24+
u32_t prften :1 __packed;
25+
u32_t icen :1 __packed;
26+
u32_t rsvd__10 :1 __packed;
27+
u32_t icrst :1 __packed;
28+
u32_t rsvd__12_15 :4 __packed;
29+
u32_t empty :1 __packed;
30+
u32_t rsvd__17 :1 __packed;
31+
u32_t dbg_swend :1 __packed;
32+
u32_t rsvd__19_31 :13 __packed;
33+
} bit;
34+
};
35+
36+
/* FLASH register map */
37+
struct stm32g0x_flash {
38+
volatile union __ef_acr acr;
39+
volatile u32_t rsvd__4;
40+
volatile u32_t keyr;
41+
volatile u32_t optkeyr;
42+
volatile u32_t sr;
43+
volatile u32_t cr;
44+
volatile u32_t eccr;
45+
volatile u32_t rsvd_0;
46+
volatile u32_t optr;
47+
volatile u32_t pcrop1sr;
48+
volatile u32_t pcrop1er;
49+
volatile u32_t wrp1ar;
50+
volatile u32_t wrp1br;
51+
};
52+
53+
#endif /* _STM32G0X_FLASH_REGISTERS_H_ */

0 commit comments

Comments
 (0)