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
--- /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; +} +