Skip to content

Commit c86f1ef

Browse files
committed
STM32F2: Add Flash API support
1 parent c832515 commit c86f1ef

File tree

4 files changed

+330
-1
lines changed

4 files changed

+330
-1
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/* mbed Microcontroller Library
2+
*******************************************************************************
3+
* Copyright (c) 2017, STMicroelectronics
4+
* All rights reserved.
5+
*
6+
* Redistribution and use in source and binary forms, with or without
7+
* modification, are permitted provided that the following conditions are met:
8+
*
9+
* 1. Redistributions of source code must retain the above copyright notice,
10+
* this list of conditions and the following disclaimer.
11+
* 2. Redistributions in binary form must reproduce the above copyright notice,
12+
* this list of conditions and the following disclaimer in the documentation
13+
* and/or other materials provided with the distribution.
14+
* 3. Neither the name of STMicroelectronics nor the names of its contributors
15+
* may be used to endorse or promote products derived from this software
16+
* without specific prior written permission.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28+
*******************************************************************************
29+
*/
30+
#ifndef MBED_FLASH_DATA_H
31+
#define MBED_FLASH_DATA_H
32+
33+
#include <stdint.h>
34+
35+
#if DEVICE_FLASH
36+
37+
#define FLASH_SIZE ((uint32_t)0x100000)
38+
39+
/* Base address of the Flash sectors */
40+
#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbytes */
41+
#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base @ of Sector 1, 16 Kbytes */
42+
#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base @ of Sector 2, 16 Kbytes */
43+
#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) /* Base @ of Sector 3, 16 Kbytes */
44+
#define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) /* Base @ of Sector 4, 64 Kbytes */
45+
#define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) /* Base @ of Sector 5, 128 Kbytes */
46+
#define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) /* Base @ of Sector 6, 128 Kbytes */
47+
#define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) /* Base @ of Sector 7, 128 Kbytes */
48+
#define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08080000) /* Base @ of Sector 8, 128 Kbytes */
49+
#define ADDR_FLASH_SECTOR_9 ((uint32_t)0x080A0000) /* Base @ of Sector 9, 128 Kbytes */
50+
#define ADDR_FLASH_SECTOR_10 ((uint32_t)0x080C0000) /* Base @ of Sector 10, 128 Kbytes */
51+
#define ADDR_FLASH_SECTOR_11 ((uint32_t)0x080E0000) /* Base @ of Sector 11, 128 Kbytes */
52+
53+
#endif
54+
#endif
Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
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+
#if DEVICE_FLASH
18+
19+
#include "flash_api.h"
20+
#include "flash_data.h"
21+
#include "platform/mbed_critical.h"
22+
23+
static uint32_t GetSector(uint32_t Address);
24+
static uint32_t GetSectorSize(uint32_t Sector);
25+
26+
/** Initialize the flash peripheral and the flash_t object
27+
*
28+
* @param obj The flash object
29+
* @return 0 for success, -1 for error
30+
*/
31+
int32_t flash_init(flash_t *obj)
32+
{
33+
return 0;
34+
}
35+
36+
/** Uninitialize the flash peripheral and the flash_t object
37+
*
38+
* @param obj The flash object
39+
* @return 0 for success, -1 for error
40+
*/
41+
int32_t flash_free(flash_t *obj)
42+
{
43+
return 0;
44+
}
45+
46+
static int32_t flash_unlock(void)
47+
{
48+
/* Allow Access to Flash control registers and user Falsh */
49+
if (HAL_FLASH_Unlock()) {
50+
return -1;
51+
} else {
52+
return 0;
53+
}
54+
}
55+
56+
static int32_t flash_lock(void)
57+
{
58+
/* Disable the Flash option control register access (recommended to protect
59+
the option Bytes against possible unwanted operations) */
60+
if (HAL_FLASH_Lock()) {
61+
return -1;
62+
} else {
63+
return 0;
64+
}
65+
}
66+
67+
/** Erase one sector starting at defined address
68+
*
69+
* The address should be at sector boundary. This function does not do any check for address alignments
70+
* @param obj The flash object
71+
* @param address The sector starting address
72+
* @return 0 for success, -1 for error
73+
*/
74+
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
75+
{
76+
static FLASH_EraseInitTypeDef EraseInitStruct;
77+
uint32_t FirstSector;
78+
uint32_t SectorError = 0;
79+
int32_t status = 0;
80+
81+
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
82+
return -1;
83+
}
84+
85+
if (flash_unlock() != HAL_OK) {
86+
return -1;
87+
}
88+
89+
/* Get the 1st sector to erase */
90+
FirstSector = GetSector(address);
91+
92+
/* Fill EraseInit structure*/
93+
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
94+
EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
95+
EraseInitStruct.Sector = FirstSector;
96+
EraseInitStruct.NbSectors = 1;
97+
98+
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK) {
99+
status = -1;
100+
}
101+
102+
flash_lock();
103+
104+
return status;
105+
}
106+
107+
/** Program one page starting at defined address
108+
*
109+
* The page should be at page boundary, should not cross multiple sectors.
110+
* This function does not do any check for address alignments or if size
111+
* is aligned to a page size.
112+
* @param obj The flash object
113+
* @param address The sector starting address
114+
* @param data The data buffer to be programmed
115+
* @param size The number of bytes to program
116+
* @return 0 for success, -1 for error
117+
*/
118+
int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size)
119+
{
120+
int32_t status = 0;
121+
122+
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
123+
return -1;
124+
}
125+
126+
if (flash_unlock() != HAL_OK) {
127+
return -1;
128+
}
129+
130+
/* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
131+
you have to make sure that these data are rewritten before they are accessed during code
132+
execution. If this cannot be done safely, it is recommended to flush the caches by setting the
133+
DCRST and ICRST bits in the FLASH_CR register. */
134+
__HAL_FLASH_DATA_CACHE_DISABLE();
135+
__HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
136+
137+
__HAL_FLASH_DATA_CACHE_RESET();
138+
__HAL_FLASH_INSTRUCTION_CACHE_RESET();
139+
140+
__HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
141+
__HAL_FLASH_DATA_CACHE_ENABLE();
142+
143+
while ((size > 0) && (status == 0)) {
144+
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, address, (uint64_t)*data) != HAL_OK) {
145+
status = -1;
146+
} else {
147+
size--;
148+
address++;
149+
data++;
150+
}
151+
}
152+
153+
flash_lock();
154+
155+
return status;
156+
}
157+
158+
/** Get sector size
159+
*
160+
* @param obj The flash object
161+
* @param address The sector starting address
162+
* @return The size of a sector (in our case considering 1 sector = 1 page)
163+
*/
164+
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
165+
{
166+
if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {
167+
return MBED_FLASH_INVALID_SIZE;
168+
} else {
169+
return (GetSectorSize(GetSector(address)));
170+
}
171+
}
172+
173+
/** Get page size
174+
*
175+
* @param obj The flash object
176+
* @param address The page starting address
177+
* @return The size of a page (in our case the minimum programmable size)
178+
*/
179+
uint32_t flash_get_page_size(const flash_t *obj)
180+
{
181+
// Flash of STM32F2 devices can be programed 1 byte at a time
182+
return 1;
183+
}
184+
185+
/** Get start address for the flash region
186+
*
187+
* @param obj The flash object
188+
* @return The start address for the flash region
189+
*/
190+
uint32_t flash_get_start_address(const flash_t *obj)
191+
{
192+
return FLASH_BASE;
193+
}
194+
195+
/** Get the flash region size
196+
*
197+
* @param obj The flash object
198+
* @return The flash region size
199+
*/
200+
uint32_t flash_get_size(const flash_t *obj)
201+
{
202+
return FLASH_SIZE;
203+
}
204+
205+
/**
206+
* @brief Gets the sector of a given address
207+
* @param None
208+
* @retval The sector of a given address
209+
*/
210+
static uint32_t GetSector(uint32_t address)
211+
{
212+
uint32_t sector = 0;
213+
uint32_t tmp = address - ADDR_FLASH_SECTOR_0;
214+
/* This function supports 1Mb and 2Mb flash sizes */
215+
#if defined(ADDR_FLASH_SECTOR_16)
216+
if (address & 0x100000) { // handle 2nd bank
217+
/* Sector will be at least 12 */
218+
sector = FLASH_SECTOR_12;
219+
tmp -= 0x100000;
220+
address -= 0x100000;
221+
}
222+
#endif
223+
if (address < ADDR_FLASH_SECTOR_4) { // 16k sectorsize
224+
sector += tmp >>14;
225+
}
226+
#if defined(ADDR_FLASH_SECTOR_5)
227+
else if (address < ADDR_FLASH_SECTOR_5) { //64k sector size
228+
sector += FLASH_SECTOR_4;
229+
} else {
230+
sector += 4 + (tmp >>17);
231+
}
232+
#else
233+
// In case ADDR_FLASH_SECTOR_5 is not defined, sector 4 is the last one.
234+
else { //64k sector size
235+
sector += FLASH_SECTOR_4;
236+
}
237+
#endif
238+
return sector;
239+
}
240+
241+
/**
242+
* @brief Gets sector Size
243+
* @param None
244+
* @retval The size of a given sector
245+
*/
246+
static uint32_t GetSectorSize(uint32_t Sector)
247+
{
248+
uint32_t sectorsize = 0x00;
249+
#if defined(FLASH_SECTOR_16)
250+
if((Sector == FLASH_SECTOR_0) || (Sector == FLASH_SECTOR_1) || (Sector == FLASH_SECTOR_2) ||\
251+
(Sector == FLASH_SECTOR_3) || (Sector == FLASH_SECTOR_12) || (Sector == FLASH_SECTOR_13) ||\
252+
(Sector == FLASH_SECTOR_14) || (Sector == FLASH_SECTOR_15)) {
253+
sectorsize = 16 * 1024;
254+
} else if((Sector == FLASH_SECTOR_4) || (Sector == FLASH_SECTOR_16)) {
255+
#else
256+
if((Sector == FLASH_SECTOR_0) || (Sector == FLASH_SECTOR_1) || (Sector == FLASH_SECTOR_2) ||\
257+
(Sector == FLASH_SECTOR_3)) {
258+
sectorsize = 16 * 1024;
259+
} else if(Sector == FLASH_SECTOR_4) {
260+
#endif
261+
sectorsize = 64 * 1024;
262+
} else {
263+
sectorsize = 128 * 1024;
264+
}
265+
return sectorsize;
266+
}
267+
268+
#endif

targets/TARGET_STM/TARGET_STM32F2/objects.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,13 @@ struct can_s {
145145
};
146146
#endif
147147

148+
#if DEVICE_FLASH
149+
struct flash_s {
150+
/* nothing to be stored for now */
151+
uint32_t dummy;
152+
};
153+
#endif
154+
148155
#define GPIO_IP_WITHOUT_BRR
149156
#include "gpio_object.h"
150157

targets/targets.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,7 @@
904904
},
905905
"detect_code": ["0835"],
906906
"macros_add": ["USBHOST_OTHER"],
907-
"device_has_add": ["ANALOGOUT", "CAN", "SERIAL_ASYNCH", "SERIAL_FC"],
907+
"device_has_add": ["ANALOGOUT", "CAN", "SERIAL_ASYNCH", "SERIAL_FC", "FLASH"],
908908
"features": ["LWIP"],
909909
"release_versions": ["2", "5"],
910910
"device_name": "STM32F207ZG"

0 commit comments

Comments
 (0)