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:
- 0:f741508e07a3
- Child:
- 1:cc0165946232
diff -r 000000000000 -r f741508e07a3 main.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Thu Dec 07 11:13:38 2017 -0600
@@ -0,0 +1,246 @@
+#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
+// Command for reading status register
+#define QSPI_STD_CMD_RDSR 0x05
+// Command for writing status 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
+// Read/Write commands
+#define QSPI_PP_COMMAND_NRF_ENUM (0x0) //This corresponds to Flash command 0x02
+#define QSPI_READ2O_COMMAND_NRF_ENUM (0x1) //This corresponds to Flash command 0x3B
+#define QSPI_READ2IO_COMMAND_NRF_ENUM (0x2) //This corresponds to Flash command 0xBB
+#define QSPI_PP4IO_COMMAND_NRF_ENUM (0x3) //This corresponds to Flash command 0x38
+#define QSPI_READ4IO_COMMAND_NRF_ENUM (0x4) //This corresponds to Flash command 0xEB
+
+//#define DEBUG_ON 1
+#ifdef DEBUG_ON
+ #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();
+
+// 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");
+ } else {
+ printf("\nERROR: Failed creating QSPI driver object");
+ 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");
+ return -1;
+ }
+
+ if( false == InitializeFlashMem()) {
+ printf("\nUnable to initialize flash memory, tests failed\n");
+ return -1;
+ }
+
+ if( false == WriteReadSimple() ) {
+ printf("\nUnable to read/write using QuadSPI\n");
+ return -1;
+ }
+
+ printf("\nDone...\n");
+}
+
+bool WriteReadSimple()
+{
+ int result = 0;
+ 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);
+ return false;
+ }
+
+ if( false == WaitForMemReady()) {
+ printf("\nERROR: Device not ready, tests failed\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( false == WaitForMemReady()) {
+ printf("\nERROR: Device not ready, tests failed\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");
+ return false;
+ }
+ if( buf_len != sizeof(rx_buf) ) {
+ printf( "\nERROR: Unable to read the entire buffer" );
+ 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);
+
+ return true;
+}
+
+bool InitializeFlashMem()
+{
+ 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]));
+ } else {
+ printf("\nERROR: Reading Status Register failed\n");
+ ret_status = 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;
+ }
+ }
+ }
+ }
+
+ return ret_status;
+}
+
+bool WaitForMemReady()
+{
+ 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]));
+ } else {
+ printf("\nERROR: Reading Status Register failed\n");
+ }
+ } while( (status_value[0] & 0x1) != 0 && retries <10000 );
+
+ if((status_value[0] & 0x1) != 0) return false;
+ return true;
+}
+
+bool SectorErase(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"));
+ } else {
+ printf("\nERROR: Sending WREN command failed\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"));
+ } else {
+ printf("\nERROR: Readng SECT_ERASE command failed\n");
+ return false;
+ }
+
+ return true;
+}
+

