18
18
#include "mbed_critical.h"
19
19
20
20
#if DEVICE_FLASH
21
+ #include <string.h>
21
22
#include "iodefine.h"
22
23
#include "spibsc_iobitmask.h"
23
24
#include "spibsc.h"
24
25
#include "mbed_drv_cfg.h"
25
26
26
27
/* ---- serial flash command ---- */
28
+ #if (FLASH_SIZE > 0x1000000 )
29
+ #define SPIBSC_OUTPUT_ADDR SPIBSC_OUTPUT_ADDR_32
30
+ #define SFLASHCMD_SECTOR_ERASE (0x21u) /* SE4B 4-byte address(1bit) */
31
+ #define SFLASHCMD_PAGE_PROGRAM (0x12u) /* PP4B 4-byte address(1bit), data(1bit) */
32
+ #else
33
+ #define SPIBSC_OUTPUT_ADDR SPIBSC_OUTPUT_ADDR_24
27
34
#define SFLASHCMD_SECTOR_ERASE (0x20u) /* SE 3-byte address(1bit) */
28
35
#define SFLASHCMD_PAGE_PROGRAM (0x02u) /* PP 3-byte address(1bit), data(1bit) */
36
+ #endif
29
37
#define SFLASHCMD_READ_STATUS_REG (0x05u) /* RDSR data(1bit) */
30
38
#define SFLASHCMD_WRITE_ENABLE (0x06u) /* WREN */
31
39
/* ---- serial flash register definitions ---- */
@@ -74,10 +82,6 @@ typedef struct {
74
82
uint32_t smwdr [2 ]; /* write data */
75
83
} st_spibsc_spimd_reg_t ;
76
84
77
- /* SPI Multi-I/O bus address space address definitions */
78
- #define SPIBSC_ADDR_START (0x18000000uL)
79
- #define SPIBSC_ADDR_END (0x1BFFFFFFuL)
80
-
81
85
typedef struct {
82
86
uint32_t b0 : 1 ; /* bit 0 : - (0) */
83
87
uint32_t b1 : 1 ; /* bit 1 : - (1) */
@@ -96,9 +100,10 @@ typedef struct {
96
100
uint32_t base_addr : 12 ; /* bit 31-20 : PA[31:20] PA(physical address) bits:bit31-20 */
97
101
} mmu_ttbl_desc_section_t ;
98
102
99
- static mmu_ttbl_desc_section_t desc_tbl [(SPIBSC_ADDR_END >> 20 ) - ( SPIBSC_ADDR_START >> 20 ) + 1 ];
103
+ static mmu_ttbl_desc_section_t desc_tbl [(FLASH_SIZE >> 20 )];
100
104
static volatile struct st_spibsc * SPIBSC = & SPIBSC0 ;
101
105
static st_spibsc_spimd_reg_t spimd_reg ;
106
+ static uint8_t write_tmp_buf [FLASH_PAGE_SIZE ];
102
107
103
108
#if defined(__ICCARM__ )
104
109
#define RAM_CODE_SEC __ramfunc
@@ -136,24 +141,12 @@ int32_t flash_free(flash_t *obj)
136
141
137
142
int32_t flash_erase_sector (flash_t * obj , uint32_t address )
138
143
{
139
- int32_t ret ;
140
-
141
- core_util_critical_section_enter ();
142
- ret = _sector_erase (address - FLASH_BASE );
143
- core_util_critical_section_exit ();
144
-
145
- return ret ;
144
+ return _sector_erase (address - FLASH_BASE );
146
145
}
147
146
148
147
int32_t flash_program_page (flash_t * obj , uint32_t address , const uint8_t * data , uint32_t size )
149
148
{
150
- int32_t ret ;
151
-
152
- core_util_critical_section_enter ();
153
- ret = _page_program (address - FLASH_BASE , data , size );
154
- core_util_critical_section_exit ();
155
-
156
- return ret ;
149
+ return _page_program (address - FLASH_BASE , data , size );
157
150
}
158
151
159
152
uint32_t flash_get_sector_size (const flash_t * obj , uint32_t address )
@@ -167,7 +160,7 @@ uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
167
160
168
161
uint32_t flash_get_page_size (const flash_t * obj )
169
162
{
170
- return 1 ;
163
+ return 8 ;
171
164
}
172
165
173
166
uint32_t flash_get_start_address (const flash_t * obj )
@@ -184,12 +177,14 @@ int32_t _sector_erase(uint32_t addr)
184
177
{
185
178
int32_t ret ;
186
179
180
+ core_util_critical_section_enter ();
187
181
spi_mode ();
188
182
189
183
/* ---- Write enable ---- */
190
184
ret = write_enable (); /* WREN Command */
191
185
if (ret != 0 ) {
192
186
ex_mode ();
187
+ core_util_critical_section_exit ();
193
188
return ret ;
194
189
}
195
190
@@ -202,20 +197,22 @@ int32_t _sector_erase(uint32_t addr)
202
197
spimd_reg .cmd = SFLASHCMD_SECTOR_ERASE ;
203
198
204
199
/* ---- address ---- */
205
- spimd_reg .ade = SPIBSC_OUTPUT_ADDR_24 ;
200
+ spimd_reg .ade = SPIBSC_OUTPUT_ADDR ;
206
201
spimd_reg .addre = SPIBSC_SDR_TRANS ; /* SDR */
207
202
spimd_reg .adb = SPIBSC_1BIT ;
208
203
spimd_reg .addr = addr ;
209
204
210
205
ret = spibsc_transfer (& spimd_reg );
211
206
if (ret != 0 ) {
212
207
ex_mode ();
208
+ core_util_critical_section_exit ();
213
209
return ret ;
214
210
}
215
211
216
212
ret = busy_wait ();
217
213
218
214
ex_mode ();
215
+ core_util_critical_section_exit ();
219
216
return ret ;
220
217
}
221
218
@@ -226,8 +223,6 @@ int32_t _page_program(uint32_t addr, const uint8_t * buf, int32_t size)
226
223
int32_t remainder ;
227
224
int32_t idx = 0 ;
228
225
229
- spi_mode ();
230
-
231
226
while (size > 0 ) {
232
227
if (size > FLASH_PAGE_SIZE ) {
233
228
program_size = FLASH_PAGE_SIZE ;
@@ -239,10 +234,15 @@ int32_t _page_program(uint32_t addr, const uint8_t * buf, int32_t size)
239
234
program_size = remainder ;
240
235
}
241
236
237
+ core_util_critical_section_enter ();
238
+ memcpy (write_tmp_buf , & buf [idx ], program_size );
239
+ spi_mode ();
240
+
242
241
/* ---- Write enable ---- */
243
242
ret = write_enable (); /* WREN Command */
244
243
if (ret != 0 ) {
245
244
ex_mode ();
245
+ core_util_critical_section_exit ();
246
246
return ret ;
247
247
}
248
248
@@ -256,7 +256,7 @@ int32_t _page_program(uint32_t addr, const uint8_t * buf, int32_t size)
256
256
spimd_reg .cmd = SFLASHCMD_PAGE_PROGRAM ;
257
257
258
258
/* ---- address ---- */
259
- spimd_reg .ade = SPIBSC_OUTPUT_ADDR_24 ;
259
+ spimd_reg .ade = SPIBSC_OUTPUT_ADDR ;
260
260
spimd_reg .addre = SPIBSC_SDR_TRANS ; /* SDR */
261
261
spimd_reg .adb = SPIBSC_1BIT ;
262
262
spimd_reg .addr = addr ;
@@ -267,28 +267,33 @@ int32_t _page_program(uint32_t addr, const uint8_t * buf, int32_t size)
267
267
ret = spibsc_transfer (& spimd_reg ); /* Command,Address */
268
268
if (ret != 0 ) {
269
269
ex_mode ();
270
+ core_util_critical_section_exit ();
270
271
return ret ;
271
272
}
272
273
273
274
/* ----------- 2. Data ---------------*/
274
- ret = data_send (SPIBSC_1BIT , SPIBSC_SPISSL_NEGATE , & buf [ idx ] , program_size );
275
+ ret = data_send (SPIBSC_1BIT , SPIBSC_SPISSL_NEGATE , write_tmp_buf , program_size );
275
276
if (ret != 0 ) {
276
277
ex_mode ();
278
+ core_util_critical_section_exit ();
277
279
return ret ;
278
280
}
279
281
280
282
ret = busy_wait ();
281
283
if (ret != 0 ) {
282
284
ex_mode ();
285
+ core_util_critical_section_exit ();
283
286
return ret ;
284
287
}
285
288
289
+ ex_mode ();
290
+ core_util_critical_section_exit ();
291
+
286
292
addr += program_size ;
287
293
idx += program_size ;
288
294
size -= program_size ;
289
295
}
290
296
291
- ex_mode ();
292
297
return ret ;
293
298
}
294
299
@@ -686,16 +691,16 @@ static void change_mmu_ttbl_spibsc(uint32_t type)
686
691
mmu_ttbl_desc_section_t * table = (mmu_ttbl_desc_section_t * )TTB ;
687
692
688
693
/* ==== Modify SPI Multi-I/O bus space settings in the MMU translation table ==== */
689
- for (index = (SPIBSC_ADDR_START >> 20 ); index <= ( SPIBSC_ADDR_END >> 20 ); index ++ ) {
694
+ for (index = (FLASH_BASE >> 20 ); index < (( FLASH_BASE + FLASH_SIZE ) >> 20 ); index ++ ) {
690
695
/* Modify memory attribute descriptor */
691
696
if (type == 0 ) { /* Spi */
692
697
desc = table [index ];
693
- desc_tbl [index - (SPIBSC_ADDR_START >> 20 )] = desc ;
698
+ desc_tbl [index - (FLASH_BASE >> 20 )] = desc ;
694
699
desc .AP1_0 = 0x0u ; /* AP[2:0] = b'000 (No access) */
695
700
desc .AP2 = 0x0u ;
696
701
desc .XN = 0x1u ; /* XN = 1 (Execute never) */
697
702
} else { /* Xip */
698
- desc = desc_tbl [index - (SPIBSC_ADDR_START >> 20 )];
703
+ desc = desc_tbl [index - (FLASH_BASE >> 20 )];
699
704
}
700
705
/* Write descriptor back to translation table */
701
706
table [index ] = desc ;
0 commit comments