Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: main.cpp
- Revision:
- 2:3165b07182ad
- Parent:
- 1:cc0165946232
- Child:
- 5:da509493e3e6
diff -r cc0165946232 -r 3165b07182ad main.cpp
--- a/main.cpp Fri Dec 08 10:48:19 2017 -0600
+++ b/main.cpp Mon Sep 03 14:02:44 2018 +0200
@@ -1,240 +1,365 @@
#include "mbed.h"
-#include "cmsis_os.h"
-#include "PinNames.h"
#include "QSPI.h"
// The below values are command codes defined in Datasheet for MX25R6435F Macronix Flash Memory
+// should work for whole MX25RXX35F chip family
+
// Command for reading status register
#define QSPI_STD_CMD_RDSR 0x05
-// Command for writing status register
+// Command for reading configuration register
+#define QSPI_STD_CMD_RDCR 0x15
+// Command for writing status/configuration register
#define QSPI_STD_CMD_WRSR 0x01
-// Command for reading control register (supported only by some memories)
-#define QSPI_STD_CMD_RDCR 0x35
-// Command for writing control register (supported only by some memories)
-#define QSPI_STD_CMD_WRCR 0x3E
-// Command for setting Reset Enable (supported only by some memories)
-#define QSPI_STD_CMD_RSTEN 0x66
-// Command for setting Reset (supported only by some memories)
-#define QSPI_STD_CMD_RST 0x99
// Command for setting WREN (supported only by some memories)
#define QSPI_STD_CMD_WREN 0x06
// Command for Sector erase (supported only by some memories)
#define QSPI_STD_CMD_SECT_ERASE 0x20
+//
+#define QSPI_STD_CMD_WRITE_1IO 0x02 // 1-1-1 mode
+#define QSPI_STD_CMD_WRITE_4IO 0x38 // 1-4-4 mode
+#define QSPI_STD_CMD_READ_1IO 0x03 // 1-1-1 mode
+#define QSPI_STD_CMD_READ_4IO 0xEB // 1-4-4 mode
+
+#define QSPI_STD_CMD_RSTEN 0x66
+// Command for setting Reset (supported only by some memories)
+#define QSPI_STD_CMD_RST 0x99
+
+#define STATUS_BIT_WIP (1 << 0) // write in progress bit
+#define STATUS_BIT_QE (1 << 6) // Quad Enable
+
+#define QSPI_STATUS_REG_SIZE 1
+
+#define QSPI_READ_4IO_DUMMY_CYCLE 6
+
+#define QSPI_MAX_WAIT_TIME 1000 // 1000 ms
+
+
+
//#define DEBUG_ON 1
#ifdef DEBUG_ON
- #define VERBOSE_PRINT(x) printf x
-#else
- #define VERBOSE_PRINT(x)
+#define VERBOSE_PRINT(x) printf x
+#else
+#define VERBOSE_PRINT(x)
#endif
-QSPI *myQspi = NULL;
-
-bool InitializeFlashMem();
-bool WaitForMemReady();
-bool SectorErase(unsigned int flash_addr);
-bool WriteReadSimple();
-
+
+bool InitializeFlashMem(QSPI &qspi);
+bool WaitForMemReady(QSPI &qspi);
+bool SectorErase(QSPI &qspi, unsigned int flash_addr);
+
+bool WriteReadQuad(QSPI &qspi, unsigned int flash_addr);
+
+bool QuadEnable(QSPI &qspi);
+bool QuadDisable(QSPI &qspi);
+
+
+#define TEST_FLASH_ADDRESS 0x1000
+
// main() runs in its own thread in the OS
-int main() {
- myQspi = new QSPI((PinName)QSPI_PIN_IO0, (PinName)QSPI_PIN_IO1, (PinName)QSPI_PIN_IO2, (PinName)QSPI_PIN_IO3, (PinName)QSPI_PIN_SCK, (PinName)QSPI_PIN_CSN);
- if(myQspi) {
- printf("\nCreated QSPI driver object succesfully");
+int main()
+{
+ printf(">>> Start...\r\n");
+ QSPI myQspi((PinName)QSPI_FLASH1_IO0, (PinName)QSPI_FLASH1_IO1, (PinName)QSPI_FLASH1_IO2, (PinName)QSPI_FLASH1_IO3, (PinName)QSPI_FLASH1_SCK, (PinName)QSPI_FLASH1_CSN);
+
+ if (QSPI_STATUS_OK == myQspi.configure_format(QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, QSPI_CFG_ADDR_SIZE_24, QSPI_CFG_BUS_SINGLE, QSPI_CFG_ALT_SIZE_8, QSPI_CFG_BUS_SINGLE, 0)) {
+ printf("[main] Configured QSPI driver succesfully: 1-1-1\r\n");
} else {
- printf("\nERROR: Failed creating QSPI driver object");
+ printf("[main] ERROR: Failed configuring QSPI driver\r\n");
return -1;
}
-
- printf("\n\nQSPI Config = 1_4_4");
- if(QSPI_STATUS_OK == myQspi->configure_format( QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_QUAD, QSPI_CFG_ADDR_SIZE_24, QSPI_CFG_BUS_SINGLE, QSPI_CFG_ALT_SIZE_NONE, QSPI_CFG_BUS_QUAD, 0, 0 )) {
- printf("\nConfigured QSPI driver configured succesfully");
- } else {
- printf("\nERROR: Failed configuring QSPI driver");
+
+ if (false == InitializeFlashMem(myQspi)) {
+ printf("[main] Unable to initialize flash memory, tests failed\r\n");
return -1;
}
-
- if( false == InitializeFlashMem()) {
- printf("\nUnable to initialize flash memory, tests failed\n");
+
+ if (false == WriteReadQuad(myQspi, TEST_FLASH_ADDRESS)) {
+ printf("[main] Unable to read/write using QuadSPI\r\n");
return -1;
}
-
- if( false == WriteReadSimple() ) {
- printf("\nUnable to read/write using QuadSPI\n");
- return -1;
- }
-
- printf("\nDone...\n");
+
+ printf("<<< Done...\r\n");
}
-bool WriteReadSimple()
+bool WriteReadQuad(QSPI &qspi, unsigned int flash_addr)
{
int result = 0;
- char tx_buf[] = { 'H', 'E', 'L', 'L', 'O', ' ', 'Q', 'U', 'A', 'D', '-', 'S', 'P', 'I', '!', 0 };
- char rx_buf[16];
+ char tx_buf[] = { 'H', 'E', 'L', 'L', 'O', ' ', 'Q', 'U', 'A', 'D', '-', 'S', 'P', 'I', '!', 0 };
+ char rx_buf[16];
size_t buf_len = sizeof(tx_buf);
-
- uint32_t flash_addr = 0x1000;
- if( false == SectorErase(flash_addr)) {
- printf("\nERROR: SectorErase failed(addr = 0x%08X)\n", flash_addr);
+
+ if (false == SectorErase(qspi, flash_addr)) {
+ printf("[WriteReadQuad] ERROR: SectorErase failed(addr = 0x%08lX)\r\n", flash_addr);
+ return false;
+ }
+
+ if (false == QuadEnable(qspi)) {
+ printf("[WriteReadQuad] ERROR: Quad enable failed\r\n");
return false;
}
-
- if( false == WaitForMemReady()) {
- printf("\nERROR: Device not ready, tests failed\n");
+
+ // Send write enable
+ if (QSPI_STATUS_OK == qspi.command_transfer(QSPI_STD_CMD_WREN, // command to send
+ -1, // no address to transmit
+ NULL, 0, // do not transmit
+ NULL, 0)) { // do not receive
+ VERBOSE_PRINT(("[WriteReadQuad] Sending WREN command success\r\n"));
+ } else {
+ printf("[WriteReadQuad] ERROR: Sending WREN command failed\r\n");
+ return false;
+ }
+
+ if (QSPI_STATUS_OK == qspi.configure_format(QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_QUAD, QSPI_CFG_ADDR_SIZE_24, QSPI_CFG_BUS_QUAD, QSPI_CFG_ALT_SIZE_8, QSPI_CFG_BUS_QUAD, 0)) {
+ printf("[WriteReadQuad] Configured QSPI driver succesfully: 1-4-4\r\n");
+ } else {
+ printf("[WriteReadQuad] ERROR: Failed configuring QSPI driver\r\n");
+ return -1;
+ }
+
+ printf("[WriteReadQuad] Writing: %s\r\n", tx_buf);
+ result = qspi.write(QSPI_STD_CMD_WRITE_4IO, 0, flash_addr, tx_buf, &buf_len);
+ if ((result != QSPI_STATUS_OK) || buf_len != sizeof(tx_buf)) {
+ printf("[WriteReadQuad] ERROR: Write failed\r\n");
+ }
+
+ if (false == WaitForMemReady(qspi)) {
+ printf("[WriteReadQuad] ERROR: Device not ready, tests failed\r\n");
return false;
}
-
- printf("\nWriting: %s", tx_buf);
- result = myQspi->write( flash_addr, tx_buf, &buf_len );
- if( ( result != QSPI_STATUS_OK ) || buf_len != sizeof(tx_buf) ) {
- printf("\nERROR: Write failed");
+
+ if (QSPI_STATUS_OK == qspi.configure_format(QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_QUAD, QSPI_CFG_ADDR_SIZE_24, QSPI_CFG_BUS_QUAD, QSPI_CFG_ALT_SIZE_8, QSPI_CFG_BUS_QUAD, QSPI_READ_4IO_DUMMY_CYCLE)) {
+ printf("[WriteReadQuad] Configured QSPI driver succesfully: 1-4-4\r\n");
+ } else {
+ printf("[WriteReadQuad] ERROR: Failed configuring QSPI driver\r\n");
+ return -1;
}
-
- if( false == WaitForMemReady()) {
- printf("\nERROR: Device not ready, tests failed\n");
+
+ memset(rx_buf, 0, sizeof(rx_buf));
+ result = qspi.read(QSPI_STD_CMD_READ_4IO, 0, flash_addr, rx_buf, &buf_len);
+ if (result != QSPI_STATUS_OK) {
+ printf("[WriteReadQuad] ERROR: Read failed\r\n");
return false;
}
-
- memset( rx_buf, 0, sizeof(rx_buf) );
- result = myQspi->read( flash_addr, rx_buf, &buf_len );
- if( result != QSPI_STATUS_OK ) {
- printf("\nERROR: Read failed");
+
+ if (QSPI_STATUS_OK == qspi.configure_format(QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE, QSPI_CFG_ADDR_SIZE_24, QSPI_CFG_BUS_SINGLE, QSPI_CFG_ALT_SIZE_8, QSPI_CFG_BUS_SINGLE, 0)) {
+ printf("[WriteReadQuad] Configured QSPI driver succesfully: 1-1-1\r\n");
+ } else {
+ printf("[WriteReadQuad] ERROR: Failed configuring QSPI driver\r\n");
+ return -1;
+ }
+
+ if (false == QuadDisable(qspi)) {
+ printf("[WriteReadQuad] ERROR: Quad disable failed\r\n");
+ return false;
+ }
+
+ if (buf_len != sizeof(rx_buf)) {
+ printf("[WriteReadQuad] ERROR: Unable to read the entire buffer\r\n");
return false;
}
- if( buf_len != sizeof(rx_buf) ) {
- printf( "\nERROR: Unable to read the entire buffer" );
+
+ if (0 != (memcmp(rx_buf, tx_buf, sizeof(rx_buf)))) {
+ printf("[WriteReadQuad] ERROR: Buffer contents are invalid\r\n");
+ printf("tx_buf: ");
+ for (uint32_t i = 0; i < buf_len; i++) {
+ printf("%d ", tx_buf[i]);
+ }
+ printf("\r\n");
+ printf("rx_buf: ");
+ for (uint32_t i = 0; i < buf_len; i++) {
+ printf("%d ", rx_buf[i]);
+ }
+ printf("\r\n");
return false;
}
- if(0 != (memcmp( rx_buf, tx_buf, sizeof(rx_buf)))) {
- printf("\nERROR: Buffer contents are invalid");
- return false;
- }
- printf("\nRead: %s", rx_buf);
-
+ printf("[WriteReadQuad] Read: %s\r\n", rx_buf);
+
return true;
}
-bool InitializeFlashMem()
+bool InitializeFlashMem(QSPI &qspi)
{
- bool ret_status = true;
- char status_value[2];
-
- //Read the Status Register from device
- if (QSPI_STATUS_OK == myQspi->command_transfer(QSPI_STD_CMD_RDSR, // command to send
- 0, // do not transmit
- NULL, // do not transmit
- status_value, // just receive two bytes of data
- 2)) { // store received values in status_value
- VERBOSE_PRINT(("\nReading Status Register Success: value = 0x%02X:0x%02X\n", status_value[0], status_value[1]));
+ char reg_data[QSPI_STATUS_REG_SIZE];
+
+ // Read the Status Register from device
+ if (QSPI_STATUS_OK == qspi.command_transfer(QSPI_STD_CMD_RDSR, // command to send
+ -1, // no address to transmit
+ NULL, 0, // do not transmit
+ reg_data, QSPI_STATUS_REG_SIZE)) {
+ VERBOSE_PRINT(("[InitializeFlashMem] Reading Status Register Success: value = 0x%02X\r\n", status_value[0]));
} else {
- printf("\nERROR: Reading Status Register failed\n");
- ret_status = false;
+ printf("[InitializeFlashMem] ERROR: Reading Status Register failed\r\n");
+ return false;
}
-
- if(ret_status)
- {
- //Send Reset Enable
- if (QSPI_STATUS_OK == myQspi->command_transfer(QSPI_STD_CMD_RSTEN, // command to send
- 0, // do not transmit
- NULL, // do not transmit
- 0, // just receive two bytes of data
- NULL)) { // store received values in status_value
- VERBOSE_PRINT(("\nSending RSTEN Success\n"));
- } else {
- printf("\nERROR: Sending RSTEN failed\n");
- ret_status = false;
- }
-
- if(ret_status)
- {
- //Send Reset
- if (QSPI_STATUS_OK == myQspi->command_transfer(QSPI_STD_CMD_RST, // command to send
- 0, // do not transmit
- NULL, // do not transmit
- status_value, // just receive two bytes of data
- 2)) { // store received values in status_value
- VERBOSE_PRINT(("\nSending RST Success\n"));
- } else {
- printf("\nERROR: Sending RST failed\n");
- ret_status = false;
- }
-
- if(ret_status)
- {
- status_value[0] |= 0x40;
- //Write the Status Register to set QE enable bit
- if (QSPI_STATUS_OK == myQspi->command_transfer(QSPI_STD_CMD_WRSR, // command to send
- status_value,
- 1,
- NULL,
- 0)) { // store received values in status_value
- VERBOSE_PRINT(("\nWriting Status Register Success\n"));
- } else {
- printf("\nERROR: Writing Status Register failed\n");
- ret_status = false;
- }
- }
- }
+
+ // Send Reset Enable
+ if (QSPI_STATUS_OK == qspi.command_transfer(QSPI_STD_CMD_RSTEN, // command to send
+ -1, // no address to transmit
+ NULL, 0, // do not transmit
+ NULL, 0)) { // do not receive
+ VERBOSE_PRINT(("[InitializeFlashMem] Sending RSTEN Success\r\n"));
+ } else {
+ printf("[InitializeFlashMem] ERROR: Sending RSTEN failed\r\n");
+ return false;
}
-
- return ret_status;
+
+ // Reset device
+ if (QSPI_STATUS_OK == qspi.command_transfer(QSPI_STD_CMD_RST, // command to send
+ -1, // no address to transmit
+ NULL, 0, // do not transmit
+ NULL, 0)) { // do not receive
+ VERBOSE_PRINT(("[InitializeFlashMem] Sending RST Success\r\n"));
+ } else {
+ printf("[InitializeFlashMem] ERROR: Sending RST failed\r\n");
+ return false;
+ }
+
+ return true;
}
-bool WaitForMemReady()
+bool WaitForMemReady(QSPI &qspi)
{
- char status_value[2];
- int retries = 0;
-
- do
- {
- retries++;
- //Read the Status Register from device
- if (QSPI_STATUS_OK == myQspi->command_transfer(QSPI_STD_CMD_RDSR, // command to send
- 0, // do not transmit
- NULL, // do not transmit
- status_value, // just receive two bytes of data
- 2)) { // store received values in status_value
- VERBOSE_PRINT(("\nReadng Status Register Success: value = 0x%02X:0x%02X\n", status_value[0], status_value[1]));
+ char status_value[QSPI_STATUS_REG_SIZE];
+ Timer timer;
+
+ timer.start();
+ do {
+ // Read the Status Register from device
+ if (QSPI_STATUS_OK == qspi.command_transfer(QSPI_STD_CMD_RDSR, // command to send
+ -1, // no address to transmit
+ NULL, 0, // do not transmit
+ status_value, QSPI_STATUS_REG_SIZE)) {
+ VERBOSE_PRINT(("[WaitForMemReady] Readng Status Register Success: value = 0x%02X\r\n", status_value[0]));
} else {
- printf("\nERROR: Reading Status Register failed\n");
+ printf("[WaitForMemReady] ERROR: Reading Status Register failed\r\n");
}
- } while( (status_value[0] & 0x1) != 0 && retries <10000 );
-
- if((status_value[0] & 0x1) != 0) return false;
+ } while ((status_value[0] & STATUS_BIT_WIP) != 0 && timer.read_ms() < QSPI_MAX_WAIT_TIME);
+
+ if ((status_value[0] & STATUS_BIT_WIP) != 0) {
+ return false;
+ }
return true;
}
-bool SectorErase(unsigned int flash_addr)
+bool SectorErase(QSPI &qspi, unsigned int flash_addr)
{
- char addrbytes[3] = {0};
-
- addrbytes[2]=flash_addr & 0xFF;
- addrbytes[1]=(flash_addr >> 8) & 0xFF;
- addrbytes[0]=(flash_addr >> 16) & 0xFF;
-
- //Send WREN
- if (QSPI_STATUS_OK == myQspi->command_transfer(QSPI_STD_CMD_WREN, // command to send
- 0, // do not transmit
- NULL, // do not transmit
- 0, // just receive two bytes of data
- NULL)) { // store received values in status_value
- VERBOSE_PRINT(("\nSending WREN command success\n"));
+ // Set wite enable
+ if (QSPI_STATUS_OK == qspi.command_transfer(QSPI_STD_CMD_WREN, // command to send
+ -1, // no address to transmit
+ NULL, 0, // do not transmit
+ NULL, 0)) { // do not receive
+ VERBOSE_PRINT(("[SectorErase] Sending WREN command success\r\n"));
} else {
- printf("\nERROR: Sending WREN command failed\n");
+ printf("[SectorErase] ERROR: Sending WREN command failed\r\n");
return false;
}
-
- if (QSPI_STATUS_OK == myQspi->command_transfer(QSPI_STD_CMD_SECT_ERASE, // command to send
- addrbytes, // do not transmit
- 3, // do not transmit
- 0, // just receive two bytes of data
- NULL)) { // store received values in status_value
- VERBOSE_PRINT(("\nSending SECT_ERASE command success\n"));
+ // sector erase
+ if (QSPI_STATUS_OK == qspi.command_transfer(QSPI_STD_CMD_SECT_ERASE, // command to send
+ flash_addr, // sector address (any address within sector)
+ NULL, 0, // do not transmit
+ NULL, 0)) { // do not receive
+ VERBOSE_PRINT(("[SectorErase] Sending SECT_ERASE command success\r\n"));
} else {
- printf("\nERROR: Readng SECT_ERASE command failed\n");
+ printf("[SectorErase] ERROR: Readng SECT_ERASE command failed\r\n");
return false;
}
-
+
+ if (false == WaitForMemReady(qspi)) {
+ printf("[SectorErase] ERROR: Device not ready, tests failed\r\n");
+ return false;
+ }
+
return true;
}
+bool QuadEnable(QSPI &qspi)
+{
+ char reg_data[QSPI_STATUS_REG_SIZE];
+
+ //Read the Status Register from device
+ if (QSPI_STATUS_OK == qspi.command_transfer(QSPI_STD_CMD_RDSR, // command to send
+ -1, // no address to transmit
+ NULL, 0, // do not transmit
+ reg_data, QSPI_STATUS_REG_SIZE)) {
+ VERBOSE_PRINT(("[QuadEnable] Reading Status Register Success: value = 0x%02X\r\n", reg_data[0]));
+ } else {
+ printf("ERROR: Reading Status Register failed\r\n");
+ return false;
+ }
+
+ if (QSPI_STATUS_OK == qspi.command_transfer(QSPI_STD_CMD_WREN, // command to send
+ -1, // no address to transmit
+ NULL, 0, // do not transmit
+ NULL, 0)) { // do not receive
+ VERBOSE_PRINT(("[QuadEnable] Sending WREN command success\r\n"));
+ } else {
+ printf("[QuadEnable] ERROR: Sending WREN command failed\r\n");
+ return false;
+ }
+
+ reg_data[0] |= (STATUS_BIT_QE);
+ //Set the Status Register to set QE enable bit
+ if (QSPI_STATUS_OK == qspi.command_transfer(QSPI_STD_CMD_WRSR, // command to send
+ -1, // no address to transmit
+ reg_data, QSPI_STATUS_REG_SIZE,
+ NULL, 0)) { // do not receive
+ VERBOSE_PRINT(("[QuadEnable] Writing Status Register Success\r\n"));
+ } else {
+ printf("[QuadEnable] ERROR: Writing Status Register failed\r\n");
+ return false;
+ }
+
+ if (false == WaitForMemReady(qspi)) {
+ printf("[QuadEnable] ERROR: Device not ready, tests failed\r\n");
+ return false;
+ }
+
+ return true;
+}
+
+bool QuadDisable(QSPI &qspi)
+{
+ char reg_data[QSPI_STATUS_REG_SIZE];
+
+ // Read the Status Register from device
+ if (QSPI_STATUS_OK == qspi.command_transfer(QSPI_STD_CMD_RDSR, // command to send
+ -1, // no address to transmit
+ NULL, 0, // do not transmit
+ reg_data, QSPI_STATUS_REG_SIZE)) {
+ VERBOSE_PRINT(("[QuadDisable] Reading Status Register Success: value = 0x%02X\r\n", reg_data[0]));
+ } else {
+ printf("[QuadDisable] ERROR: Reading Status Register failed\r\n");
+ return false;
+ }
+
+ // Set write enable
+ if (QSPI_STATUS_OK == qspi.command_transfer(QSPI_STD_CMD_WREN, // command to send
+ -1, // no address to transmit
+ NULL, 0, // do not transmit
+ NULL, 0)) { // do not receive
+ VERBOSE_PRINT(("[QuadDisable] Sending WREN command success\r\n"));
+ } else {
+ printf("[QuadDisable] ERROR: Sending WREN command failed\r\n");
+ return false;
+ }
+
+ reg_data[0] &= ~(STATUS_BIT_QE);
+ //Set the Status Register to reset QE enable bit
+ if (QSPI_STATUS_OK == qspi.command_transfer(QSPI_STD_CMD_WRSR, // command to send
+ -1, // no address to transmit
+ reg_data, QSPI_STATUS_REG_SIZE,
+ NULL, 0)) { // do not receive
+ VERBOSE_PRINT(("[QuadDisable] Writing Status Register Success\r\n"));
+ } else {
+ printf("[QuadDisable] ERROR: Writing Status Register failed\r\n");
+ return false;
+ }
+
+ if (false == WaitForMemReady(qspi)) {
+ printf("[QuadDisable] ERROR: Device not ready, tests failed\r\n");
+ return false;
+ }
+
+ return true;
+}

