Skip to content

Commit 0d09f6d

Browse files
committed
STM32F3: add Flash api
1 parent eda0acc commit 0d09f6d

File tree

2 files changed

+180
-0
lines changed

2 files changed

+180
-0
lines changed

targets/TARGET_STM/TARGET_STM32F3/common_objects.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,13 @@ struct can_s {
132132
};
133133
#endif
134134

135+
#if DEVICE_FLASH
136+
struct flash_s {
137+
/* nothing to be stored for now */
138+
uint32_t dummy;
139+
};
140+
#endif
141+
135142
#include "gpio_object.h"
136143

137144
#ifdef __cplusplus
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2017 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "flash_api.h"
18+
#include "mbed_critical.h"
19+
20+
#if DEVICE_FLASH
21+
#include "mbed_assert.h"
22+
#include "cmsis.h"
23+
24+
#define NUM_PAGES_IN_SECTOR (1U)
25+
#define FLASH_SIZE (uint32_t)(*((uint16_t *)FLASHSIZE_BASE) * 1024U)
26+
27+
int32_t flash_init(flash_t *obj)
28+
{
29+
return 0;
30+
}
31+
32+
int32_t flash_free(flash_t *obj)
33+
{
34+
return 0;
35+
}
36+
37+
static int32_t flash_unlock(void)
38+
{
39+
/* Allow Access to Flash control registers and user Falsh */
40+
if (HAL_FLASH_Unlock()) {
41+
return -1;
42+
} else {
43+
return 0;
44+
}
45+
}
46+
47+
static int32_t flash_lock(void)
48+
{
49+
/* Disable the Flash option control register access (recommended to protect
50+
the option Bytes against possible unwanted operations) */
51+
if (HAL_FLASH_Lock()) {
52+
return -1;
53+
} else {
54+
return 0;
55+
}
56+
}
57+
58+
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
59+
{
60+
uint32_t PAGEError = 0;
61+
FLASH_EraseInitTypeDef EraseInitStruct;
62+
int32_t status = 0;
63+
64+
if (!(IS_FLASH_PROGRAM_ADDRESS(address))) {
65+
return -1;
66+
}
67+
68+
if (flash_unlock() != HAL_OK) {
69+
return -1;
70+
}
71+
72+
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR);
73+
/* MBED HAL erases 1 sector at a time */
74+
/* Fill EraseInit structure*/
75+
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
76+
EraseInitStruct.PageAddress = address;
77+
EraseInitStruct.NbPages = NUM_PAGES_IN_SECTOR;
78+
79+
/* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
80+
you have to make sure that these data are rewritten before they are accessed during code
81+
execution. If this cannot be done safely, it is recommended to flush the caches by setting the
82+
DCRST and ICRST bits in the FLASH_CR register. */
83+
84+
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
85+
status = -1;
86+
}
87+
88+
flash_lock();
89+
90+
return status;
91+
92+
}
93+
94+
int32_t flash_program_page(flash_t *obj, uint32_t address,
95+
const uint8_t *data, uint32_t size)
96+
{
97+
uint32_t StartAddress = 0;
98+
int32_t status = 0;
99+
100+
if (!(IS_FLASH_PROGRAM_ADDRESS(address))) {
101+
return -1;
102+
}
103+
104+
if ((size % 4) != 0) {
105+
/* F3 flash devices can only be programmed 32bits/4 bytes at a time */
106+
return -1;
107+
}
108+
109+
if (flash_unlock() != HAL_OK) {
110+
return -1;
111+
}
112+
113+
/* Program the user Flash area word by word */
114+
StartAddress = address;
115+
116+
/* HW needs an aligned address to program flash, which data
117+
* parameters doesn't ensure */
118+
if ((uint32_t) data % 4 != 0) {
119+
volatile uint32_t data32;
120+
while (address < (StartAddress + size) && (status == 0)) {
121+
for (uint8_t i =0; i < 4; i++) {
122+
*(((uint8_t *) &data32) + i) = *(data + i);
123+
}
124+
125+
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data32) == HAL_OK) {
126+
address = address + 4;
127+
data = data + 4;
128+
} else {
129+
status = -1;
130+
}
131+
}
132+
} else { /* case where data is aligned, so let's avoid any copy */
133+
while ((address < (StartAddress + size)) && (status == 0)) {
134+
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, *((uint32_t*) data)) == HAL_OK) {
135+
address = address + 4;
136+
data = data + 4;
137+
} else {
138+
status = -1;
139+
}
140+
}
141+
}
142+
143+
flash_lock();
144+
145+
return status;
146+
}
147+
148+
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
149+
{
150+
if (!(IS_FLASH_PROGRAM_ADDRESS(address))) {
151+
return MBED_FLASH_INVALID_SIZE;
152+
} else {
153+
return (NUM_PAGES_IN_SECTOR * FLASH_PAGE_SIZE);
154+
}
155+
}
156+
157+
uint32_t flash_get_page_size(const flash_t *obj)
158+
{
159+
/* Page size is the minimum programmable size, which is 4 bytes */
160+
return 4;
161+
}
162+
163+
uint32_t flash_get_start_address(const flash_t *obj)
164+
{
165+
return FLASH_BASE;
166+
}
167+
168+
uint32_t flash_get_size(const flash_t *obj)
169+
{
170+
return FLASH_SIZE;
171+
}
172+
173+
#endif

0 commit comments

Comments
 (0)