@@ -74,6 +74,7 @@ using namespace mbed;
74
74
#define QSPIF_BASIC_PARAM_4K_ERASE_TYPE_BYTE 1
75
75
76
76
#define QSPIF_BASIC_PARAM_TABLE_SOFT_RESET_BYTE 61
77
+ #define QSPIF_BASIC_PARAM_TABLE_4BYTE_ADDR_BYTE 63
77
78
78
79
#define SOFT_RESET_RESET_INST_BITMASK 0b001000
79
80
#define SOFT_RESET_ENABLE_AND_RESET_INST_BITMASK 0b010000
@@ -84,6 +85,15 @@ using namespace mbed;
84
85
#define ERASE_BITMASK_NONE 0x00
85
86
#define ERASE_BITMASK_ALL 0x0F
86
87
88
+ // 4-Byte Addressing Support Bitmasks
89
+ #define FOURBYTE_ADDR_B7_BITMASK 0b00000001
90
+ #define FOURBYTE_ADDR_B7_WREN_BITMASK 0b00000010
91
+ #define FOURBYTE_ADDR_EXT_ADDR_REG_BITMASK 0b00000100
92
+ #define FOURBYTE_ADDR_BANK_REG_BITMASK 0b00001000
93
+ #define FOURBYTE_ADDR_CONF_REG_BITMASK 0b00010000
94
+ #define FOURBYTE_ADDR_INSTS_BITMASK 0b00100000
95
+ #define FOURBYTE_ADDR_ALWAYS_BITMASK 0b01000000
96
+
87
97
#define IS_MEM_READY_MAX_RETRIES 10000
88
98
89
99
enum qspif_default_instructions {
@@ -113,6 +123,9 @@ static int local_math_power(int base, int exp);
113
123
#define QSPIF_INST_WSR2_DEFAULT QSPI_NO_INST
114
124
#define QSPIF_INST_RSR2_DEFAULT 0x35
115
125
126
+ // Default 4-byte extended addressing register write instruction
127
+ #define QSPIF_INST_4BYTE_REG_WRITE_DEFAULT QSPI_NO_INST
128
+
116
129
/* Init function to initialize Different Devices CS static list */
117
130
static PinName *generate_initialized_active_qspif_csel_arr ();
118
131
// Static Members for different devices csel
@@ -142,6 +155,9 @@ QSPIFBlockDevice::QSPIFBlockDevice(PinName io0, PinName io1, PinName io2, PinNam
142
155
// Set default status register 2 write/read instructions
143
156
_write_status_reg_2_inst = QSPIF_INST_WSR2_DEFAULT;
144
157
_read_status_reg_2_inst = QSPIF_INST_RSR2_DEFAULT;
158
+
159
+ // Set default 4-byte addressing extension register write instruction
160
+ _4byte_msb_reg_write_inst = QSPIF_INST_4BYTE_REG_WRITE_DEFAULT;
145
161
}
146
162
147
163
int QSPIFBlockDevice::init ()
@@ -694,9 +710,9 @@ int QSPIFBlockDevice::_sfdp_parse_basic_param_table(uint32_t basic_table_addr, s
694
710
return -1 ;
695
711
}
696
712
697
- // Check address size, currently only supports 3byte addresses
698
- if ((param_table[2 ] & 0x4 ) != 0 || (param_table[ 7 ] & 0x80 ) != 0 ) {
699
- tr_error (" Init - verify 3byte addressing Failed " );
713
+ // Check that density is not greater than 4 gigabits (i.e. that addressing beyond 4 bytes is not required)
714
+ if ((param_table[7 ] & 0x80 ) != 0 ) {
715
+ tr_error (" Init - verify flash density failed " );
700
716
return -1 ;
701
717
}
702
718
@@ -745,6 +761,17 @@ int QSPIFBlockDevice::_sfdp_parse_basic_param_table(uint32_t basic_table_addr, s
745
761
_sfdp_set_qpi_enabled (param_table);
746
762
}
747
763
}
764
+
765
+ if (_sfdp_detect_and_enable_4byte_addressing (param_table, basic_table_size) != QSPIF_BD_ERROR_OK) {
766
+ tr_error (" Init - Detecting/enabling 4-byte addressing failed" );
767
+ return -1 ;
768
+ }
769
+
770
+ if (false == _is_mem_ready ()) {
771
+ tr_error (" Init - _is_mem_ready Failed" );
772
+ return -1 ;
773
+ }
774
+
748
775
return 0 ;
749
776
}
750
777
@@ -1033,6 +1060,84 @@ int QSPIFBlockDevice::_sfdp_detect_best_bus_read_mode(uint8_t *basic_param_table
1033
1060
return 0 ;
1034
1061
}
1035
1062
1063
+ int QSPIFBlockDevice::_sfdp_detect_and_enable_4byte_addressing (uint8_t *basic_param_table_ptr, int basic_param_table_size)
1064
+ {
1065
+ int status = QSPIF_BD_ERROR_OK;
1066
+ qspi_status_t qspi_status = QSPI_STATUS_OK;
1067
+
1068
+ // Always enable 4-byte addressing if possible
1069
+ if (basic_param_table_size > QSPIF_BASIC_PARAM_TABLE_4BYTE_ADDR_BYTE) {
1070
+ uint8_t examined_byte = basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_4BYTE_ADDR_BYTE];
1071
+
1072
+ if (examined_byte & FOURBYTE_ADDR_ALWAYS_BITMASK) {
1073
+ // No need to do anything if 4-byte addressing is always enabled
1074
+ _address_size = QSPI_CFG_ADDR_SIZE_32;
1075
+ } else if (examined_byte & FOURBYTE_ADDR_B7_BITMASK) {
1076
+ // Issue instruction B7h to enable 4-byte addressing
1077
+ qspi_status = _qspi_send_general_command (0xB7 , QSPI_NO_ADDRESS_COMMAND, NULL , 0 , NULL , 0 );
1078
+ status = (qspi_status == QSPI_STATUS_OK) ? QSPIF_BD_ERROR_OK : QSPIF_BD_ERROR_PARSING_FAILED;
1079
+ if (status == QSPIF_BD_ERROR_OK) {
1080
+ _address_size = QSPI_CFG_ADDR_SIZE_32;
1081
+ }
1082
+ } else if (examined_byte & FOURBYTE_ADDR_B7_WREN_BITMASK) {
1083
+ // Issue WREN and then instruction B7h to enable 4-byte addressing
1084
+ if (_set_write_enable () == 0 ) {
1085
+ qspi_status = _qspi_send_general_command (0xB7 , QSPI_NO_ADDRESS_COMMAND, NULL , 0 , NULL , 0 );
1086
+ status = (qspi_status == QSPI_STATUS_OK) ? QSPIF_BD_ERROR_OK : QSPIF_BD_ERROR_PARSING_FAILED;
1087
+
1088
+ if (status == QSPIF_BD_ERROR_OK) {
1089
+ _address_size = QSPI_CFG_ADDR_SIZE_32;
1090
+ }
1091
+ } else {
1092
+ tr_error (" Write enable failed" );
1093
+ status = QSPIF_BD_ERROR_WREN_FAILED;
1094
+ }
1095
+ } else if (examined_byte & FOURBYTE_ADDR_CONF_REG_BITMASK) {
1096
+ // Write 1 to bit 0 of a configuration register to enable 4-byte addressing
1097
+ // Write to register with instruction B1h, read from register with instruction B5h
1098
+ uint8_t conf_register = 0 ;
1099
+ qspi_status = _qspi_send_general_command (0xB5 , QSPI_NO_ADDRESS_COMMAND, NULL , 0 , (char *) &conf_register, 1 );
1100
+ status = (qspi_status == QSPI_STATUS_OK) ? QSPIF_BD_ERROR_OK : QSPIF_BD_ERROR_PARSING_FAILED;
1101
+
1102
+ if (status == QSPIF_BD_ERROR_OK) {
1103
+ conf_register |= 0b00000001 ;
1104
+ if (_set_write_enable () == 0 ) {
1105
+ qspi_status_t qspi_status = _qspi_send_general_command (0xB1 , QSPI_NO_ADDRESS_COMMAND, (char *) &conf_register, 1 , NULL , 0 );
1106
+ status = (qspi_status == QSPI_STATUS_OK) ? QSPIF_BD_ERROR_OK : QSPIF_BD_ERROR_PARSING_FAILED;
1107
+
1108
+ if (status == QSPIF_BD_ERROR_OK) {
1109
+ _address_size = QSPI_CFG_ADDR_SIZE_32;
1110
+ }
1111
+ } else {
1112
+ tr_error (" Write enable failed" );
1113
+ status = QSPIF_BD_ERROR_WREN_FAILED;
1114
+ }
1115
+ }
1116
+ } else if (examined_byte & FOURBYTE_ADDR_BANK_REG_BITMASK) {
1117
+ // Write 1 to bit 7 of a bank register to enable 4-byte addressing
1118
+ // Write to register with instruction 17h, read from register with instruction 16h
1119
+ uint8_t to_write = 0b10000000 ;
1120
+ qspi_status = _qspi_send_general_command (0x17 , QSPI_NO_ADDRESS_COMMAND, (char *) &to_write, 1 , NULL , 0 );
1121
+ status = (qspi_status == QSPI_STATUS_OK) ? QSPIF_BD_ERROR_OK : QSPIF_BD_ERROR_PARSING_FAILED;
1122
+ if (status == QSPIF_BD_ERROR_OK) {
1123
+ _address_size = QSPI_CFG_ADDR_SIZE_32;
1124
+ }
1125
+ } else if (examined_byte & FOURBYTE_ADDR_EXT_ADDR_REG_BITMASK) {
1126
+ // Extended address register stores most significant byte of a 4-byte address
1127
+ // Instructions are sent with the lower 3 bytes of the address
1128
+ // Write to register with instruction C5h, read from register with instruction C8h
1129
+ _4byte_msb_reg_write_inst = 0xC5 ;
1130
+ _address_size = QSPI_CFG_ADDR_SIZE_24;
1131
+ } else {
1132
+ // Either part specific instructions are required to use 4-byte addressing or it isn't supported, so use 3-byte addressing instead
1133
+ tr_debug (" _sfdp_detect_and_enable_4byte_addressing - 4-byte addressing not supported, falling back to 3-byte addressing" );
1134
+ _address_size = QSPI_CFG_ADDR_SIZE_24;
1135
+ }
1136
+ }
1137
+
1138
+ return status;
1139
+ }
1140
+
1036
1141
int QSPIFBlockDevice::_sfdp_detect_reset_protocol_and_reset (uint8_t *basic_param_table_ptr)
1037
1142
{
1038
1143
int status = QSPIF_BD_ERROR_OK;
@@ -1245,69 +1350,110 @@ qspi_status_t QSPIFBlockDevice::_qspi_set_frequency(int freq)
1245
1350
return _qspi.set_frequency (freq);
1246
1351
}
1247
1352
1353
+ qspi_status_t QSPIFBlockDevice::_qspi_update_4byte_ext_addr_reg (bd_addr_t addr)
1354
+ {
1355
+ qspi_status_t status = QSPI_STATUS_OK;
1356
+ // Only update register if in the extended address register mode
1357
+ if (_4byte_msb_reg_write_inst != QSPI_NO_INST) {
1358
+ // Set register to the most significant byte of the address
1359
+ uint8_t most_significant_byte = addr >> 24 ;
1360
+ if (_set_write_enable () == 0 ) {
1361
+ status = _qspi.command_transfer (_4byte_msb_reg_write_inst, (int ) QSPI_NO_ADDRESS_COMMAND,
1362
+ (char *) &most_significant_byte, 1 ,
1363
+ NULL , 0 );
1364
+ } else {
1365
+ tr_error (" Write enable failed" );
1366
+ status = QSPI_STATUS_ERROR;
1367
+ }
1368
+ } else if ((_address_size != QSPI_CFG_ADDR_SIZE_32) && (addr != QSPI_NO_ADDRESS_COMMAND) && (addr >= (1 << 24 ))) {
1369
+ tr_error (" Attempted to use 4-byte address but 4-byte addressing is not supported" );
1370
+ status = QSPI_STATUS_ERROR;
1371
+ }
1372
+ return status;
1373
+ }
1374
+
1248
1375
qspi_status_t QSPIFBlockDevice::_qspi_send_read_command (qspi_inst_t read_inst, void *buffer, bd_addr_t addr,
1249
1376
bd_size_t size)
1250
1377
{
1251
- // Send Read command to device driver
1252
1378
size_t buf_len = size;
1253
1379
1254
- if (_qspi.read (read_inst, (_alt_size == 0 ) ? -1 : QSPI_ALT_DEFAULT_VALUE, (unsigned int )addr, (char *)buffer, &buf_len) != QSPI_STATUS_OK) {
1255
- tr_error (" Read failed" );
1256
- return QSPI_STATUS_ERROR;
1380
+ qspi_status_t status = _qspi_update_4byte_ext_addr_reg (addr);
1381
+ if (QSPI_STATUS_OK != status) {
1382
+ tr_error (" QSPI Read - Updating 4-byte addressing extended address register failed" );
1383
+ return status;
1257
1384
}
1258
1385
1259
- return QSPI_STATUS_OK;
1386
+ // Send read command to device driver
1387
+ status = _qspi.read (read_inst, -1 , (unsigned int )addr, (char *)buffer, &buf_len);
1388
+ if (QSPI_STATUS_OK != status) {
1389
+ tr_error (" QSPI Read failed" );
1390
+ return status;
1391
+ }
1260
1392
1393
+ return QSPI_STATUS_OK;
1261
1394
}
1262
1395
1263
1396
qspi_status_t QSPIFBlockDevice::_qspi_send_program_command (qspi_inst_t progInst, const void *buffer, bd_addr_t addr,
1264
1397
bd_size_t *size)
1265
1398
{
1266
- // Send Program (write) command to device driver
1267
- qspi_status_t result = QSPI_STATUS_OK;
1268
1399
1269
- result = _qspi.write (progInst, -1 , addr, (char *)buffer, (size_t *)size);
1270
- if (result != QSPI_STATUS_OK) {
1400
+ qspi_status_t status = _qspi_update_4byte_ext_addr_reg (addr);
1401
+ if (QSPI_STATUS_OK != status) {
1402
+ tr_error (" QSPI Write - Updating 4-byte addressing extended address register failed" );
1403
+ return status;
1404
+ }
1405
+
1406
+ // Send program (write) command to device driver
1407
+ status = _qspi.write (prog_inst, -1 , addr, (char *)buffer, (size_t *)size);
1408
+ if (QSPI_STATUS_OK != status) {
1271
1409
tr_error (" QSPI Write failed" );
1410
+ return status;
1272
1411
}
1273
1412
1274
- return result ;
1413
+ return QSPI_STATUS_OK ;
1275
1414
}
1276
1415
1277
1416
qspi_status_t QSPIFBlockDevice::_qspi_send_erase_command (qspi_inst_t erase_inst, bd_addr_t addr, bd_size_t size)
1278
1417
{
1279
- // Send Erase Instruction command to driver
1280
- qspi_status_t result = QSPI_STATUS_OK;
1281
-
1282
1418
tr_debug (" Inst: 0x%xh, addr: %llu, size: %llu" , erase_inst, addr, size);
1283
1419
1284
- result = _qspi.command_transfer (erase_inst, // command to send
1285
- (((int )addr) & 0x00FFF000 ), // Align addr to 4096
1286
- NULL , // do not transmit
1287
- 0 , // do not transmit
1288
- NULL , // just receive two bytes of data
1289
- 0 ); // store received values in status_value
1420
+ qspi_status_t status = _qspi_update_4byte_ext_addr_reg (addr);
1421
+ if (QSPI_STATUS_OK != status) {
1422
+ tr_error (" QSPI Erase - Updating 4-byte addressing extended address register failed" );
1423
+ return status;
1424
+ }
1290
1425
1291
- if (QSPI_STATUS_OK != result) {
1426
+ // Send erase command to driver
1427
+ status = _qspi.command_transfer (erase_inst,
1428
+ (((int ) addr) & 0x00FFF000 ), // Align addr to 4096
1429
+ NULL , 0 , NULL , 0 ); // Do not transmit or receive
1430
+
1431
+ if (QSPI_STATUS_OK != status) {
1292
1432
tr_error (" QSPI Erase failed" );
1433
+ return status;
1293
1434
}
1294
1435
1295
- return result;
1296
-
1436
+ return QSPI_STATUS_OK;
1297
1437
}
1298
1438
1299
1439
qspi_status_t QSPIFBlockDevice::_qspi_send_general_command (qspi_inst_t instruction, bd_addr_t addr,
1300
1440
const char *tx_buffer,
1301
1441
mbed::bd_size_t tx_length, const char *rx_buffer, mbed::bd_size_t rx_length)
1302
1442
{
1303
- // Send a general command Instruction to driver
1304
- qspi_status_t status = _qspi.command_transfer (instruction, (int )addr, tx_buffer, tx_length, rx_buffer, rx_length);
1443
+ qspi_status_t status = _qspi_update_4byte_ext_addr_reg (addr);
1444
+ if (QSPI_STATUS_OK != status) {
1445
+ tr_error (" QSPI Generic command - Updating 4-byte addressing extended address register failed" );
1446
+ return status;
1447
+ }
1305
1448
1449
+ // Send a general command instruction to driver
1450
+ status = _qspi.command_transfer (instruction, (int )addr, tx_buffer, tx_length, rx_buffer, rx_length);
1306
1451
if (QSPI_STATUS_OK != status) {
1307
1452
tr_error (" Sending Generic command: %x" , instruction);
1453
+ return status;
1308
1454
}
1309
1455
1310
- return status ;
1456
+ return QSPI_STATUS_OK ;
1311
1457
}
1312
1458
1313
1459
qspi_status_t QSPIFBlockDevice::_qspi_configure_format (qspi_bus_width_t inst_width, qspi_bus_width_t address_width,
0 commit comments