21
21
#include "mbed_assert.h"
22
22
#include "cmsis.h"
23
23
24
- #define NUM_PAGES_IN_SECTOR (1U)
25
- #define FLASH_SIZE (uint32_t)(*((uint16_t *)FLASHSIZE_BASE) * 1024U)
24
+ #ifndef FLASH_SIZE
25
+ #define FLASH_SIZE (uint32_t)(*((uint16_t *)FLASHSIZE_BASE) * 1024U)
26
+ #endif
27
+
28
+ // Minimum number of bytes to be programmed at a time
29
+ #define MIN_PROG_SIZE (4U)
26
30
31
+ /** Initialize the flash peripheral and the flash_t object
32
+ *
33
+ * @param obj The flash object
34
+ * @return 0 for success, -1 for error
35
+ */
27
36
int32_t flash_init (flash_t * obj )
28
37
{
29
38
return 0 ;
30
39
}
31
40
41
+ /** Uninitialize the flash peripheral and the flash_t object
42
+ *
43
+ * @param obj The flash object
44
+ * @return 0 for success, -1 for error
45
+ */
32
46
int32_t flash_free (flash_t * obj )
33
47
{
34
48
return 0 ;
@@ -55,6 +69,13 @@ static int32_t flash_lock(void)
55
69
}
56
70
}
57
71
72
+ /** Erase one sector starting at defined address
73
+ *
74
+ * The address should be at sector boundary. This function does not do any check for address alignments
75
+ * @param obj The flash object
76
+ * @param address The sector starting address
77
+ * @return 0 for success, -1 for error
78
+ */
58
79
int32_t flash_erase_sector (flash_t * obj , uint32_t address )
59
80
{
60
81
uint32_t PAGEError = 0 ;
@@ -70,11 +91,12 @@ int32_t flash_erase_sector(flash_t *obj, uint32_t address)
70
91
}
71
92
72
93
__HAL_FLASH_CLEAR_FLAG (FLASH_FLAG_EOP | FLASH_FLAG_WRPERR );
94
+
73
95
/* MBED HAL erases 1 sector at a time */
74
96
/* Fill EraseInit structure*/
75
97
EraseInitStruct .TypeErase = FLASH_TYPEERASE_PAGES ;
76
98
EraseInitStruct .PageAddress = address ;
77
- EraseInitStruct .NbPages = NUM_PAGES_IN_SECTOR ;
99
+ EraseInitStruct .NbPages = 1 ;
78
100
79
101
/* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
80
102
you have to make sure that these data are rewritten before they are accessed during code
@@ -88,9 +110,19 @@ int32_t flash_erase_sector(flash_t *obj, uint32_t address)
88
110
flash_lock ();
89
111
90
112
return status ;
91
-
92
113
}
93
114
115
+ /** Program one page starting at defined address
116
+ *
117
+ * The page should be at page boundary, should not cross multiple sectors.
118
+ * This function does not do any check for address alignments or if size
119
+ * is aligned to a page size.
120
+ * @param obj The flash object
121
+ * @param address The sector starting address
122
+ * @param data The data buffer to be programmed
123
+ * @param size The number of bytes to program
124
+ * @return 0 for success, -1 for error
125
+ */
94
126
int32_t flash_program_page (flash_t * obj , uint32_t address ,
95
127
const uint8_t * data , uint32_t size )
96
128
{
@@ -101,8 +133,7 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
101
133
return -1 ;
102
134
}
103
135
104
- if ((size % 4 ) != 0 ) {
105
- /* F3 flash devices can only be programmed 32bits/4 bytes at a time */
136
+ if ((size % MIN_PROG_SIZE ) != 0 ) {
106
137
return -1 ;
107
138
}
108
139
@@ -113,27 +144,27 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
113
144
/* Program the user Flash area word by word */
114
145
StartAddress = address ;
115
146
116
- /* HW needs an aligned address to program flash, which data
117
- * parameters doesn't ensure */
147
+ /* HW needs an aligned address to program flash, which data parameter doesn't ensure */
118
148
if ((uint32_t ) data % 4 != 0 ) {
149
+
119
150
volatile uint32_t data32 ;
120
151
while (address < (StartAddress + size ) && (status == 0 )) {
121
- for (uint8_t i = 0 ; i < 4 ; i ++ ) {
152
+ for (uint8_t i = 0 ; i < MIN_PROG_SIZE ; i ++ ) {
122
153
* (((uint8_t * ) & data32 ) + i ) = * (data + i );
123
154
}
124
155
125
156
if (HAL_FLASH_Program (FLASH_TYPEPROGRAM_WORD , address , data32 ) == HAL_OK ) {
126
- address = address + 4 ;
127
- data = data + 4 ;
157
+ address = address + MIN_PROG_SIZE ;
158
+ data = data + MIN_PROG_SIZE ;
128
159
} else {
129
160
status = -1 ;
130
161
}
131
162
}
132
163
} else { /* case where data is aligned, so let's avoid any copy */
133
164
while ((address < (StartAddress + size )) && (status == 0 )) {
134
165
if (HAL_FLASH_Program (FLASH_TYPEPROGRAM_WORD , address , * ((uint32_t * ) data )) == HAL_OK ) {
135
- address = address + 4 ;
136
- data = data + 4 ;
166
+ address = address + MIN_PROG_SIZE ;
167
+ data = data + MIN_PROG_SIZE ;
137
168
} else {
138
169
status = -1 ;
139
170
}
@@ -145,26 +176,47 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
145
176
return status ;
146
177
}
147
178
179
+ /** Get sector size
180
+ *
181
+ * @param obj The flash object
182
+ * @param address The sector starting address
183
+ * @return The size of a sector (in our case considering 1 sector = 1 page)
184
+ */
148
185
uint32_t flash_get_sector_size (const flash_t * obj , uint32_t address )
149
186
{
150
187
if (!(IS_FLASH_PROGRAM_ADDRESS (address ))) {
151
188
return MBED_FLASH_INVALID_SIZE ;
152
189
} else {
153
- return ( NUM_PAGES_IN_SECTOR * FLASH_PAGE_SIZE ) ;
190
+ return FLASH_PAGE_SIZE ;
154
191
}
155
192
}
156
193
194
+ /** Get page size
195
+ *
196
+ * @param obj The flash object
197
+ * @param address The page starting address
198
+ * @return The size of a page (in our case the minimum programmable size)
199
+ */
157
200
uint32_t flash_get_page_size (const flash_t * obj )
158
201
{
159
- /* Page size is the minimum programmable size, which is 4 bytes */
160
- return 4 ;
202
+ return MIN_PROG_SIZE ;
161
203
}
162
204
205
+ /** Get start address for the flash region
206
+ *
207
+ * @param obj The flash object
208
+ * @return The start address for the flash region
209
+ */
163
210
uint32_t flash_get_start_address (const flash_t * obj )
164
211
{
165
212
return FLASH_BASE ;
166
213
}
167
214
215
+ /** Get the flash region size
216
+ *
217
+ * @param obj The flash object
218
+ * @return The flash region size
219
+ */
168
220
uint32_t flash_get_size (const flash_t * obj )
169
221
{
170
222
return FLASH_SIZE ;
0 commit comments