@@ -118,6 +118,11 @@ static int local_math_power(int base, int exp);
118
118
// General QSPI instructions
119
119
#define QSPIF_INST_WSR1 0x01 // Write status register 1
120
120
#define QSPIF_INST_RSR1 0x05 // Read status register 1
121
+ #define QSPIF_INST_RSFDP 0x5A // Read SFDP
122
+ #define QSPIF_INST_RDID 0x9F // Read Manufacturer and JDEC Device ID
123
+
124
+ // Device-specific instructions
125
+ #define QSPIF_INST_ULBPR 0x98 // Clear all write-protection bits in the Block-Protection register
121
126
122
127
// Default status register 2 read/write instructions
123
128
#define QSPIF_INST_WSR2_DEFAULT QSPI_NO_INST
@@ -126,6 +131,11 @@ static int local_math_power(int base, int exp);
126
131
// Default 4-byte extended addressing register write instruction
127
132
#define QSPIF_INST_4BYTE_REG_WRITE_DEFAULT QSPI_NO_INST
128
133
134
+
135
+ // Length of data returned from RDID instruction
136
+ #define QSPI_RDID_DATA_LENGTH 3
137
+
138
+
129
139
/* Init function to initialize Different Devices CS static list */
130
140
static PinName *generate_initialized_active_qspif_csel_arr ();
131
141
// Static Members for different devices csel
@@ -172,14 +182,11 @@ int QSPIFBlockDevice::init()
172
182
return QSPIF_BD_ERROR_DEVICE_MAX_EXCEED;
173
183
}
174
184
175
- uint8_t vendor_device_ids[4 ];
176
- size_t data_length = 3 ;
177
185
int status = QSPIF_BD_ERROR_OK;
178
186
uint32_t basic_table_addr = 0 ;
179
187
size_t basic_table_size = 0 ;
180
188
uint32_t sector_map_table_addr = 0 ;
181
189
size_t sector_map_table_size = 0 ;
182
- int qspi_status = QSPI_STATUS_OK;
183
190
184
191
_mutex.lock ();
185
192
@@ -211,26 +218,6 @@ int QSPIFBlockDevice::init()
211
218
goto exit_point;
212
219
}
213
220
214
- /* Read Manufacturer ID (1byte), and Device ID (2bytes)*/
215
- qspi_status = _qspi_send_general_command (QSPIF_RDID, QSPI_NO_ADDRESS_COMMAND, NULL , 0 , (char *)vendor_device_ids,
216
- data_length);
217
- if (qspi_status != QSPI_STATUS_OK) {
218
- tr_error (" Init - Read Vendor ID Failed" );
219
- status = QSPIF_BD_ERROR_DEVICE_ERROR;
220
- goto exit_point;
221
- }
222
-
223
- tr_debug (" Vendor device ID = 0x%x 0x%x 0x%x 0x%x" , vendor_device_ids[0 ],
224
- vendor_device_ids[1 ], vendor_device_ids[2 ], vendor_device_ids[3 ]);
225
- switch (vendor_device_ids[0 ]) {
226
- case 0xbf :
227
- // SST devices come preset with block protection
228
- // enabled for some regions, issue global protection unlock to clear
229
- _set_write_enable ();
230
- _qspi_send_general_command (QSPIF_ULBPR, QSPI_NO_ADDRESS_COMMAND, NULL , 0 , NULL , 0 );
231
- break ;
232
- }
233
-
234
221
// Synchronize Device
235
222
if (false == _is_mem_ready ()) {
236
223
tr_error (" Init - _is_mem_ready Failed" );
@@ -275,6 +262,12 @@ int QSPIFBlockDevice::init()
275
262
goto exit_point;
276
263
}
277
264
265
+ if (0 != _clear_block_protection ()) {
266
+ tr_error (" Init - clearing block protection failed" );
267
+ status = QSPIF_BD_ERROR_PARSING_FAILED;
268
+ goto exit_point;
269
+ }
270
+
278
271
_is_initialized = true ;
279
272
280
273
exit_point:
@@ -1233,6 +1226,64 @@ int QSPIFBlockDevice::_sfdp_parse_sector_map_table(uint32_t sector_map_table_add
1233
1226
return 0 ;
1234
1227
}
1235
1228
1229
+ int QSPIFBlockDevice::_clear_block_protection ()
1230
+ {
1231
+ uint8_t vendor_device_ids[QSPI_RDID_DATA_LENGTH] = {0 };
1232
+ uint8_t status_regs[QSPI_STATUS_REGISTER_COUNT] = {0 };
1233
+
1234
+ if (false == _is_mem_ready ()) {
1235
+ tr_error (" Device not ready, clearing block protection failed" );
1236
+ return -1 ;
1237
+ }
1238
+
1239
+ /* Read Manufacturer ID (1byte), and Device ID (2bytes) */
1240
+ qspi_status_t status = _qspi_send_general_command (QSPIF_INST_RDID, QSPI_NO_ADDRESS_COMMAND,
1241
+ NULL , 0 ,
1242
+ (char *) vendor_device_ids, QSPI_RDID_DATA_LENGTH);
1243
+ if (QSPI_STATUS_OK != status) {
1244
+ tr_error (" Read Vendor ID Failed" );
1245
+ return -1 ;
1246
+ }
1247
+
1248
+ tr_debug (" Vendor device ID = 0x%x 0x%x 0x%x" , vendor_device_ids[0 ], vendor_device_ids[1 ], vendor_device_ids[2 ]);
1249
+ switch (vendor_device_ids[0 ]) {
1250
+ case 0xbf :
1251
+ // SST devices come preset with block protection
1252
+ // enabled for some regions, issue global protection unlock to clear
1253
+ if (0 != _set_write_enable ()) {
1254
+ tr_error (" Write enable failed" );
1255
+ return -1 ;
1256
+ }
1257
+ status = _qspi_send_general_command (QSPIF_INST_ULBPR, QSPI_NO_ADDRESS_COMMAND, NULL , 0 , NULL , 0 );
1258
+ if (QSPI_STATUS_OK != status) {
1259
+ tr_error (" Global block protection unlock failed" );
1260
+ return -1 ;
1261
+ }
1262
+ break ;
1263
+ default :
1264
+ // For all other devices, clear all bits in status register 1 that aren't the WIP or WEL bits to clear the block protection bits
1265
+ status = _qspi_read_status_registers (status_regs);
1266
+ if (QSPI_STATUS_OK != status) {
1267
+ tr_error (" _clear_block_protection - Status register read failed" );
1268
+ return -1 ;
1269
+ }
1270
+ status_regs[0 ] &= (QSPIF_STATUS_BIT_WIP | QSPIF_STATUS_BIT_WEL);
1271
+ status = _qspi_write_status_registers (status_regs);
1272
+ if (QSPI_STATUS_OK != status) {
1273
+ tr_error (" __clear_block_protection - Status register write failed" );
1274
+ return -1 ;
1275
+ }
1276
+ break ;
1277
+ }
1278
+
1279
+ if (false == _is_mem_ready ()) {
1280
+ tr_error (" Device not ready, clearing block protection failed" );
1281
+ return -1 ;
1282
+ }
1283
+
1284
+ return 0 ;
1285
+ }
1286
+
1236
1287
int QSPIFBlockDevice::_set_write_enable ()
1237
1288
{
1238
1289
// Check Status Register Busy Bit to Verify the Device isn't Busy
0 commit comments