@@ -31,7 +31,10 @@ using namespace mbed;
3131/* ***************************/
3232#define QSPIF_DEFAULT_PAGE_SIZE 256
3333#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
3538#ifndef UINT64_MAX
3639#define UINT64_MAX -1
3740#endif
@@ -110,6 +113,7 @@ using namespace mbed;
110113
111114// Device-specific instructions
112115#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
113117
114118// Default read/legacy erase instructions
115119#define QSPIF_INST_READ_DEFAULT 0x03
@@ -174,6 +178,7 @@ QSPIFBlockDevice::QSPIFBlockDevice(PinName io0, PinName io1, PinName io2, PinNam
174178 _read_instruction = QSPIF_INST_READ_DEFAULT;
175179 _legacy_erase_instruction = QSPIF_INST_LEGACY_ERASE_DEFAULT;
176180
181+ _num_status_registers = QSPI_DEFAULT_STATUS_REGISTERS;
177182 // Set default status register 2 write/read instructions
178183 _write_status_reg_2_inst = QSPIF_INST_WSR2_DEFAULT;
179184 _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
757762
758763int QSPIFBlockDevice::_sfdp_set_quad_enabled (uint8_t *basic_param_table_ptr)
759764{
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 };
762767
763768 // QUAD Enable procedure is specified by 3 bits
764769 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)
807812 _qspi_read_status_registers (status_regs);
808813
809814 // 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++) {
811816 status_regs[i] |= status_reg_setup[i];
812817 }
813818
@@ -820,7 +825,7 @@ int QSPIFBlockDevice::_sfdp_set_quad_enabled(uint8_t *basic_param_table_ptr)
820825 }
821826
822827 // For Debug
823- memset (status_regs, 0 , QSPI_STATUS_REGISTER_COUNT );
828+ memset (status_regs, 0 , QSPI_MAX_STATUS_REGISTERS );
824829 _qspi_read_status_registers (status_regs);
825830 if (((status_regs[0 ] & status_reg_setup[0 ]) | (status_regs[1 ] & status_reg_setup[1 ])) == 0 ) {
826831 tr_error (" Status register not set correctly" );
@@ -1233,14 +1238,22 @@ int QSPIFBlockDevice::_handle_vendor_quirks()
12331238 tr_debug (" Applying quirks for SST" );
12341239 _clear_protection_method = QSPIF_BP_ULBPR;
12351240 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 ;
12361249 }
12371250
12381251 return 0 ;
12391252}
12401253
12411254int QSPIFBlockDevice::_clear_block_protection ()
12421255{
1243- uint8_t status_regs[QSPI_STATUS_REGISTER_COUNT ] = {0 };
1256+ uint8_t status_regs[QSPI_MAX_STATUS_REGISTERS ] = {0 };
12441257
12451258 if (false == _is_mem_ready ()) {
12461259 tr_error (" Device not ready, clearing block protection failed" );
@@ -1329,10 +1342,9 @@ int QSPIFBlockDevice::_set_write_enable()
13291342
13301343int QSPIFBlockDevice::_enable_fast_mode ()
13311344{
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 };
13341346 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 };
13361348
13371349 status_reg_qer_setup[2 ] = 0x2 ; // Bit 1 of config Reg 2
13381350
@@ -1347,15 +1359,15 @@ int QSPIFBlockDevice::_enable_fast_mode()
13471359 // Read Status Register
13481360 if (QSPI_STATUS_OK == _qspi_send_general_command (read_conf_register_inst, QSPI_NO_ADDRESS_COMMAND, NULL , 0 ,
13491361 &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
13511363 tr_debug (" Reading Config Register Success: value = 0x%x" , (int )status_reg[2 ]);
13521364 } else {
13531365 tr_error (" Reading Config Register failed" );
13541366 return -1 ;
13551367 }
13561368
13571369 // 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++) {
13591371 status_reg[i] |= status_reg_qer_setup[i];
13601372 }
13611373
@@ -1366,7 +1378,7 @@ int QSPIFBlockDevice::_enable_fast_mode()
13661378 }
13671379
13681380 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 ,
13701382 0 )) { // Write Fast mode bit to status_register
13711383 tr_debug (" fast mode enable - Writing Config Register Success: value = 0x%x" ,
13721384 (int )status_reg[2 ]);
@@ -1381,10 +1393,10 @@ int QSPIFBlockDevice::_enable_fast_mode()
13811393 }
13821394
13831395 // For Debug
1384- memset (status_reg, 0 , NUM_REGISTERS );
1396+ memset (status_reg, 0 , QSPI_MAX_STATUS_REGISTERS );
13851397 if (QSPI_STATUS_OK == _qspi_send_general_command (read_conf_register_inst, QSPI_NO_ADDRESS_COMMAND, NULL , 0 ,
13861398 &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
13881400 tr_debug (" Verifying Config Register Success: value = 0x%x" , (int )status_reg[2 ]);
13891401 } else {
13901402 tr_error (" Verifying Config Register failed" );
@@ -1647,12 +1659,16 @@ qspi_status_t QSPIFBlockDevice::_qspi_read_status_registers(uint8_t *reg_buffer)
16471659 return status;
16481660 }
16491661
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
16511664 status = _qspi_send_general_command (_read_status_reg_2_inst, QSPI_NO_ADDRESS_COMMAND,
16521665 NULL , 0 ,
1653- (char *) ®_buffer[1 ], 1 );
1666+ (char *) ®_buffer[1 ], read_length );
16541667 if (QSPI_STATUS_OK == status) {
16551668 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+ }
16561672 } else {
16571673 tr_error (" Reading Status Register 2 failed" );
16581674 return status;
@@ -1672,17 +1688,21 @@ qspi_status_t QSPIFBlockDevice::_qspi_write_status_registers(uint8_t *reg_buffer
16721688 return QSPI_STATUS_ERROR;
16731689 }
16741690 status = _qspi_send_general_command (QSPIF_INST_WSR1, QSPI_NO_ADDRESS_COMMAND,
1675- (char *) reg_buffer, 2 ,
1691+ (char *) reg_buffer, _num_status_registers ,
16761692 NULL , 0 );
16771693 if (QSPI_STATUS_OK == status) {
16781694 tr_debug (" Writing Status Registers Success: reg 1 value = 0x%x, reg 2 value = 0x%x" ,
16791695 (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+ }
16801699 } else {
16811700 tr_error (" Writing Status Registers failed" );
16821701 return status;
16831702 }
16841703 } else {
16851704 // 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
16861706
16871707 // Write status register 1
16881708 if (_set_write_enable () != 0 ) {
0 commit comments