@@ -31,7 +31,10 @@ using namespace mbed;
31
31
/* ***************************/
32
32
#define QSPIF_DEFAULT_PAGE_SIZE 256
33
33
#define QSPIF_DEFAULT_SE_SIZE 4096
34
- #define QSPI_STATUS_REGISTER_COUNT 2
34
+ // The SFDP spec only defines two status registers. But some devices,
35
+ // have three "status-like" registers (one status, two config)
36
+ #define QSPI_MAX_STATUS_REGISTERS 3
37
+ #define QSPI_DEFAULT_STATUS_REGISTERS 2
35
38
#ifndef UINT64_MAX
36
39
#define UINT64_MAX -1
37
40
#endif
@@ -110,6 +113,7 @@ using namespace mbed;
110
113
111
114
// Device-specific instructions
112
115
#define QSPIF_INST_ULBPR 0x98 // Clear all write-protection bits in the Block-Protection register
116
+ #define QSPIF_INST_RDCR 0x15 // Read the two control registers
113
117
114
118
// Default read/legacy erase instructions
115
119
#define QSPIF_INST_READ_DEFAULT 0x03
@@ -174,6 +178,7 @@ QSPIFBlockDevice::QSPIFBlockDevice(PinName io0, PinName io1, PinName io2, PinNam
174
178
_read_instruction = QSPIF_INST_READ_DEFAULT;
175
179
_legacy_erase_instruction = QSPIF_INST_LEGACY_ERASE_DEFAULT;
176
180
181
+ _num_status_registers = QSPI_DEFAULT_STATUS_REGISTERS;
177
182
// Set default status register 2 write/read instructions
178
183
_write_status_reg_2_inst = QSPIF_INST_WSR2_DEFAULT;
179
184
_read_status_reg_2_inst = QSPIF_INST_RSR2_DEFAULT;
@@ -757,8 +762,8 @@ int QSPIFBlockDevice::_sfdp_parse_basic_param_table(uint32_t basic_table_addr, s
757
762
758
763
int QSPIFBlockDevice::_sfdp_set_quad_enabled (uint8_t *basic_param_table_ptr)
759
764
{
760
- uint8_t status_reg_setup[QSPI_STATUS_REGISTER_COUNT ] = {0 };
761
- uint8_t status_regs[QSPI_STATUS_REGISTER_COUNT ] = {0 };
765
+ uint8_t status_reg_setup[QSPI_MAX_STATUS_REGISTERS ] = {0 };
766
+ uint8_t status_regs[QSPI_MAX_STATUS_REGISTERS ] = {0 };
762
767
763
768
// QUAD Enable procedure is specified by 3 bits
764
769
uint8_t qer_value = (basic_param_table_ptr[QSPIF_BASIC_PARAM_TABLE_QER_BYTE] & 0x70 ) >> 4 ;
@@ -807,7 +812,7 @@ int QSPIFBlockDevice::_sfdp_set_quad_enabled(uint8_t *basic_param_table_ptr)
807
812
_qspi_read_status_registers (status_regs);
808
813
809
814
// Set Bits for Quad Enable
810
- for (int i = 0 ; i < QSPI_STATUS_REGISTER_COUNT ; i++) {
815
+ for (int i = 0 ; i < QSPI_MAX_STATUS_REGISTERS ; i++) {
811
816
status_regs[i] |= status_reg_setup[i];
812
817
}
813
818
@@ -820,7 +825,7 @@ int QSPIFBlockDevice::_sfdp_set_quad_enabled(uint8_t *basic_param_table_ptr)
820
825
}
821
826
822
827
// For Debug
823
- memset (status_regs, 0 , QSPI_STATUS_REGISTER_COUNT );
828
+ memset (status_regs, 0 , QSPI_MAX_STATUS_REGISTERS );
824
829
_qspi_read_status_registers (status_regs);
825
830
if (((status_regs[0 ] & status_reg_setup[0 ]) | (status_regs[1 ] & status_reg_setup[1 ])) == 0 ) {
826
831
tr_error (" Status register not set correctly" );
@@ -1233,14 +1238,22 @@ int QSPIFBlockDevice::_handle_vendor_quirks()
1233
1238
tr_debug (" Applying quirks for SST" );
1234
1239
_clear_protection_method = QSPIF_BP_ULBPR;
1235
1240
break ;
1241
+ case 0xc2 :
1242
+ // Macronix devices have two quirks:
1243
+ // 1. Have one status register and 2 config registers, with a nonstandard instruction for reading the config registers
1244
+ // 2. Require setting a "fast mode" bit in config register 2 to operate at higher clock rates
1245
+ tr_debug (" Applying quirks for macronix" );
1246
+ _num_status_registers = 3 ;
1247
+ _read_status_reg_2_inst = QSPIF_INST_RDCR;
1248
+ break ;
1236
1249
}
1237
1250
1238
1251
return 0 ;
1239
1252
}
1240
1253
1241
1254
int QSPIFBlockDevice::_clear_block_protection ()
1242
1255
{
1243
- uint8_t status_regs[QSPI_STATUS_REGISTER_COUNT ] = {0 };
1256
+ uint8_t status_regs[QSPI_MAX_STATUS_REGISTERS ] = {0 };
1244
1257
1245
1258
if (false == _is_mem_ready ()) {
1246
1259
tr_error (" Device not ready, clearing block protection failed" );
@@ -1329,10 +1342,9 @@ int QSPIFBlockDevice::_set_write_enable()
1329
1342
1330
1343
int QSPIFBlockDevice::_enable_fast_mode ()
1331
1344
{
1332
- const int NUM_REGISTERS = QSPI_STATUS_REGISTER_COUNT + 1 ; // Status registers + one config register
1333
- char status_reg[NUM_REGISTERS] = {0 };
1345
+ char status_reg[QSPI_MAX_STATUS_REGISTERS] = {0 };
1334
1346
unsigned int read_conf_register_inst = 0x15 ;
1335
- char status_reg_qer_setup[NUM_REGISTERS ] = {0 };
1347
+ char status_reg_qer_setup[QSPI_MAX_STATUS_REGISTERS ] = {0 };
1336
1348
1337
1349
status_reg_qer_setup[2 ] = 0x2 ; // Bit 1 of config Reg 2
1338
1350
@@ -1347,15 +1359,15 @@ int QSPIFBlockDevice::_enable_fast_mode()
1347
1359
// Read Status Register
1348
1360
if (QSPI_STATUS_OK == _qspi_send_general_command (read_conf_register_inst, QSPI_NO_ADDRESS_COMMAND, NULL , 0 ,
1349
1361
&status_reg[1 ],
1350
- NUM_REGISTERS - 1 )) { // store received values in status_value
1362
+ QSPI_MAX_STATUS_REGISTERS - 1 )) { // store received values in status_value
1351
1363
tr_debug (" Reading Config Register Success: value = 0x%x" , (int )status_reg[2 ]);
1352
1364
} else {
1353
1365
tr_error (" Reading Config Register failed" );
1354
1366
return -1 ;
1355
1367
}
1356
1368
1357
1369
// Set Bits for Quad Enable
1358
- for (int i = 0 ; i < NUM_REGISTERS ; i++) {
1370
+ for (int i = 0 ; i < QSPI_MAX_STATUS_REGISTERS ; i++) {
1359
1371
status_reg[i] |= status_reg_qer_setup[i];
1360
1372
}
1361
1373
@@ -1366,7 +1378,7 @@ int QSPIFBlockDevice::_enable_fast_mode()
1366
1378
}
1367
1379
1368
1380
if (QSPI_STATUS_OK == _qspi_send_general_command (QSPIF_INST_WSR1, QSPI_NO_ADDRESS_COMMAND, status_reg,
1369
- NUM_REGISTERS , NULL ,
1381
+ QSPI_MAX_STATUS_REGISTERS , NULL ,
1370
1382
0 )) { // Write Fast mode bit to status_register
1371
1383
tr_debug (" fast mode enable - Writing Config Register Success: value = 0x%x" ,
1372
1384
(int )status_reg[2 ]);
@@ -1381,10 +1393,10 @@ int QSPIFBlockDevice::_enable_fast_mode()
1381
1393
}
1382
1394
1383
1395
// For Debug
1384
- memset (status_reg, 0 , NUM_REGISTERS );
1396
+ memset (status_reg, 0 , QSPI_MAX_STATUS_REGISTERS );
1385
1397
if (QSPI_STATUS_OK == _qspi_send_general_command (read_conf_register_inst, QSPI_NO_ADDRESS_COMMAND, NULL , 0 ,
1386
1398
&status_reg[1 ],
1387
- NUM_REGISTERS - 1 )) { // store received values in status_value
1399
+ QSPI_MAX_STATUS_REGISTERS - 1 )) { // store received values in status_value
1388
1400
tr_debug (" Verifying Config Register Success: value = 0x%x" , (int )status_reg[2 ]);
1389
1401
} else {
1390
1402
tr_error (" Verifying Config Register failed" );
@@ -1647,12 +1659,16 @@ qspi_status_t QSPIFBlockDevice::_qspi_read_status_registers(uint8_t *reg_buffer)
1647
1659
return status;
1648
1660
}
1649
1661
1650
- // Read Status Register 2
1662
+ // Read Status Register 2 (and beyond, if applicable)
1663
+ unsigned int read_length = _num_status_registers - 1 ; // We already read status reg 1 above
1651
1664
status = _qspi_send_general_command (_read_status_reg_2_inst, QSPI_NO_ADDRESS_COMMAND,
1652
1665
NULL , 0 ,
1653
- (char *) ®_buffer[1 ], 1 );
1666
+ (char *) ®_buffer[1 ], read_length );
1654
1667
if (QSPI_STATUS_OK == status) {
1655
1668
tr_debug (" Reading Status Register 2 Success: value = 0x%x" , (int ) reg_buffer[1 ]);
1669
+ if (_num_status_registers > 2 ) {
1670
+ tr_debug (" Reading Register 3 Success: value = 0x%x" , (int ) reg_buffer[2 ]);
1671
+ }
1656
1672
} else {
1657
1673
tr_error (" Reading Status Register 2 failed" );
1658
1674
return status;
@@ -1672,17 +1688,21 @@ qspi_status_t QSPIFBlockDevice::_qspi_write_status_registers(uint8_t *reg_buffer
1672
1688
return QSPI_STATUS_ERROR;
1673
1689
}
1674
1690
status = _qspi_send_general_command (QSPIF_INST_WSR1, QSPI_NO_ADDRESS_COMMAND,
1675
- (char *) reg_buffer, 2 ,
1691
+ (char *) reg_buffer, _num_status_registers ,
1676
1692
NULL , 0 );
1677
1693
if (QSPI_STATUS_OK == status) {
1678
1694
tr_debug (" Writing Status Registers Success: reg 1 value = 0x%x, reg 2 value = 0x%x" ,
1679
1695
(int ) reg_buffer[0 ], (int ) reg_buffer[1 ]);
1696
+ if (_num_status_registers > 2 ) {
1697
+ tr_debug (" Writing Register 3 Success: value = 0x%x" , (int ) reg_buffer[2 ]);
1698
+ }
1680
1699
} else {
1681
1700
tr_error (" Writing Status Registers failed" );
1682
1701
return status;
1683
1702
}
1684
1703
} else {
1685
1704
// Status registers are written using different commands
1705
+ MBED_ASSERT (_num_status_registers == 2 ); // This flow doesn't support a nonstandard third status/config register
1686
1706
1687
1707
// Write status register 1
1688
1708
if (_set_write_enable () != 0 ) {
0 commit comments