mbed_example / Mbed OS mbed-os-example-qspi
Committer:
Senthil Ramakrishnan
Date:
Thu Dec 07 11:13:38 2017 -0600
Revision:
0:f741508e07a3
Child:
1:cc0165946232
QuadSPI example for NRF52840_DK

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Senthil Ramakrishnan 0:f741508e07a3 1 #include "mbed.h"
Senthil Ramakrishnan 0:f741508e07a3 2 #include "cmsis_os.h"
Senthil Ramakrishnan 0:f741508e07a3 3 #include "PinNames.h"
Senthil Ramakrishnan 0:f741508e07a3 4 #include "QSPI.h"
Senthil Ramakrishnan 0:f741508e07a3 5
Senthil Ramakrishnan 0:f741508e07a3 6 // The below values are command codes defined in Datasheet for MX25R6435F Macronix Flash Memory
Senthil Ramakrishnan 0:f741508e07a3 7 // Command for reading status register
Senthil Ramakrishnan 0:f741508e07a3 8 #define QSPI_STD_CMD_RDSR 0x05
Senthil Ramakrishnan 0:f741508e07a3 9 // Command for writing status register
Senthil Ramakrishnan 0:f741508e07a3 10 #define QSPI_STD_CMD_WRSR 0x01
Senthil Ramakrishnan 0:f741508e07a3 11 // Command for reading control register (supported only by some memories)
Senthil Ramakrishnan 0:f741508e07a3 12 #define QSPI_STD_CMD_RDCR 0x35
Senthil Ramakrishnan 0:f741508e07a3 13 // Command for writing control register (supported only by some memories)
Senthil Ramakrishnan 0:f741508e07a3 14 #define QSPI_STD_CMD_WRCR 0x3E
Senthil Ramakrishnan 0:f741508e07a3 15 // Command for setting Reset Enable (supported only by some memories)
Senthil Ramakrishnan 0:f741508e07a3 16 #define QSPI_STD_CMD_RSTEN 0x66
Senthil Ramakrishnan 0:f741508e07a3 17 // Command for setting Reset (supported only by some memories)
Senthil Ramakrishnan 0:f741508e07a3 18 #define QSPI_STD_CMD_RST 0x99
Senthil Ramakrishnan 0:f741508e07a3 19 // Command for setting WREN (supported only by some memories)
Senthil Ramakrishnan 0:f741508e07a3 20 #define QSPI_STD_CMD_WREN 0x06
Senthil Ramakrishnan 0:f741508e07a3 21 // Command for Sector erase (supported only by some memories)
Senthil Ramakrishnan 0:f741508e07a3 22 #define QSPI_STD_CMD_SECT_ERASE 0x20
Senthil Ramakrishnan 0:f741508e07a3 23 // Read/Write commands
Senthil Ramakrishnan 0:f741508e07a3 24 #define QSPI_PP_COMMAND_NRF_ENUM (0x0) //This corresponds to Flash command 0x02
Senthil Ramakrishnan 0:f741508e07a3 25 #define QSPI_READ2O_COMMAND_NRF_ENUM (0x1) //This corresponds to Flash command 0x3B
Senthil Ramakrishnan 0:f741508e07a3 26 #define QSPI_READ2IO_COMMAND_NRF_ENUM (0x2) //This corresponds to Flash command 0xBB
Senthil Ramakrishnan 0:f741508e07a3 27 #define QSPI_PP4IO_COMMAND_NRF_ENUM (0x3) //This corresponds to Flash command 0x38
Senthil Ramakrishnan 0:f741508e07a3 28 #define QSPI_READ4IO_COMMAND_NRF_ENUM (0x4) //This corresponds to Flash command 0xEB
Senthil Ramakrishnan 0:f741508e07a3 29
Senthil Ramakrishnan 0:f741508e07a3 30 //#define DEBUG_ON 1
Senthil Ramakrishnan 0:f741508e07a3 31 #ifdef DEBUG_ON
Senthil Ramakrishnan 0:f741508e07a3 32 #define VERBOSE_PRINT(x) printf x
Senthil Ramakrishnan 0:f741508e07a3 33 #else
Senthil Ramakrishnan 0:f741508e07a3 34 #define VERBOSE_PRINT(x)
Senthil Ramakrishnan 0:f741508e07a3 35 #endif
Senthil Ramakrishnan 0:f741508e07a3 36
Senthil Ramakrishnan 0:f741508e07a3 37 QSPI *myQspi = NULL;
Senthil Ramakrishnan 0:f741508e07a3 38
Senthil Ramakrishnan 0:f741508e07a3 39 bool InitializeFlashMem();
Senthil Ramakrishnan 0:f741508e07a3 40 bool WaitForMemReady();
Senthil Ramakrishnan 0:f741508e07a3 41 bool SectorErase(unsigned int flash_addr);
Senthil Ramakrishnan 0:f741508e07a3 42 bool WriteReadSimple();
Senthil Ramakrishnan 0:f741508e07a3 43
Senthil Ramakrishnan 0:f741508e07a3 44 // main() runs in its own thread in the OS
Senthil Ramakrishnan 0:f741508e07a3 45 int main() {
Senthil Ramakrishnan 0:f741508e07a3 46 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);
Senthil Ramakrishnan 0:f741508e07a3 47 if(myQspi) {
Senthil Ramakrishnan 0:f741508e07a3 48 printf("\nCreated QSPI driver object succesfully");
Senthil Ramakrishnan 0:f741508e07a3 49 } else {
Senthil Ramakrishnan 0:f741508e07a3 50 printf("\nERROR: Failed creating QSPI driver object");
Senthil Ramakrishnan 0:f741508e07a3 51 return -1;
Senthil Ramakrishnan 0:f741508e07a3 52 }
Senthil Ramakrishnan 0:f741508e07a3 53
Senthil Ramakrishnan 0:f741508e07a3 54 printf("\n\nQSPI Config = 1_4_4");
Senthil Ramakrishnan 0:f741508e07a3 55 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 )) {
Senthil Ramakrishnan 0:f741508e07a3 56 printf("\nConfigured QSPI driver configured succesfully");
Senthil Ramakrishnan 0:f741508e07a3 57 } else {
Senthil Ramakrishnan 0:f741508e07a3 58 printf("\nERROR: Failed configuring QSPI driver");
Senthil Ramakrishnan 0:f741508e07a3 59 return -1;
Senthil Ramakrishnan 0:f741508e07a3 60 }
Senthil Ramakrishnan 0:f741508e07a3 61
Senthil Ramakrishnan 0:f741508e07a3 62 if( false == InitializeFlashMem()) {
Senthil Ramakrishnan 0:f741508e07a3 63 printf("\nUnable to initialize flash memory, tests failed\n");
Senthil Ramakrishnan 0:f741508e07a3 64 return -1;
Senthil Ramakrishnan 0:f741508e07a3 65 }
Senthil Ramakrishnan 0:f741508e07a3 66
Senthil Ramakrishnan 0:f741508e07a3 67 if( false == WriteReadSimple() ) {
Senthil Ramakrishnan 0:f741508e07a3 68 printf("\nUnable to read/write using QuadSPI\n");
Senthil Ramakrishnan 0:f741508e07a3 69 return -1;
Senthil Ramakrishnan 0:f741508e07a3 70 }
Senthil Ramakrishnan 0:f741508e07a3 71
Senthil Ramakrishnan 0:f741508e07a3 72 printf("\nDone...\n");
Senthil Ramakrishnan 0:f741508e07a3 73 }
Senthil Ramakrishnan 0:f741508e07a3 74
Senthil Ramakrishnan 0:f741508e07a3 75 bool WriteReadSimple()
Senthil Ramakrishnan 0:f741508e07a3 76 {
Senthil Ramakrishnan 0:f741508e07a3 77 int result = 0;
Senthil Ramakrishnan 0:f741508e07a3 78 char tx_buf[] = { 'H', 'E', 'L', 'L', 'O', ' ', 'Q', 'U', 'A', 'D', '-', 'S', 'P', 'I', '!', 0 };
Senthil Ramakrishnan 0:f741508e07a3 79 char rx_buf[16];
Senthil Ramakrishnan 0:f741508e07a3 80 size_t buf_len = sizeof(tx_buf);
Senthil Ramakrishnan 0:f741508e07a3 81
Senthil Ramakrishnan 0:f741508e07a3 82 uint32_t flash_addr = 0x1000;
Senthil Ramakrishnan 0:f741508e07a3 83 if( false == SectorErase(flash_addr)) {
Senthil Ramakrishnan 0:f741508e07a3 84 printf("\nERROR: SectorErase failed(addr = 0x%08X)\n", flash_addr);
Senthil Ramakrishnan 0:f741508e07a3 85 return false;
Senthil Ramakrishnan 0:f741508e07a3 86 }
Senthil Ramakrishnan 0:f741508e07a3 87
Senthil Ramakrishnan 0:f741508e07a3 88 if( false == WaitForMemReady()) {
Senthil Ramakrishnan 0:f741508e07a3 89 printf("\nERROR: Device not ready, tests failed\n");
Senthil Ramakrishnan 0:f741508e07a3 90 return false;
Senthil Ramakrishnan 0:f741508e07a3 91 }
Senthil Ramakrishnan 0:f741508e07a3 92
Senthil Ramakrishnan 0:f741508e07a3 93 printf("\nWriting: %s", tx_buf);
Senthil Ramakrishnan 0:f741508e07a3 94 result = myQspi->write( flash_addr, tx_buf, &buf_len );
Senthil Ramakrishnan 0:f741508e07a3 95 if( ( result != QSPI_STATUS_OK ) || buf_len != sizeof(tx_buf) ) {
Senthil Ramakrishnan 0:f741508e07a3 96 printf("\nERROR: Write failed");
Senthil Ramakrishnan 0:f741508e07a3 97 }
Senthil Ramakrishnan 0:f741508e07a3 98
Senthil Ramakrishnan 0:f741508e07a3 99 if( false == WaitForMemReady()) {
Senthil Ramakrishnan 0:f741508e07a3 100 printf("\nERROR: Device not ready, tests failed\n");
Senthil Ramakrishnan 0:f741508e07a3 101 return false;
Senthil Ramakrishnan 0:f741508e07a3 102 }
Senthil Ramakrishnan 0:f741508e07a3 103
Senthil Ramakrishnan 0:f741508e07a3 104 memset( rx_buf, 0, sizeof(rx_buf) );
Senthil Ramakrishnan 0:f741508e07a3 105 result = myQspi->read( flash_addr, rx_buf, &buf_len );
Senthil Ramakrishnan 0:f741508e07a3 106 if( result != QSPI_STATUS_OK ) {
Senthil Ramakrishnan 0:f741508e07a3 107 printf("\nERROR: Read failed");
Senthil Ramakrishnan 0:f741508e07a3 108 return false;
Senthil Ramakrishnan 0:f741508e07a3 109 }
Senthil Ramakrishnan 0:f741508e07a3 110 if( buf_len != sizeof(rx_buf) ) {
Senthil Ramakrishnan 0:f741508e07a3 111 printf( "\nERROR: Unable to read the entire buffer" );
Senthil Ramakrishnan 0:f741508e07a3 112 return false;
Senthil Ramakrishnan 0:f741508e07a3 113 }
Senthil Ramakrishnan 0:f741508e07a3 114 if(0 != (memcmp( rx_buf, tx_buf, sizeof(rx_buf)))) {
Senthil Ramakrishnan 0:f741508e07a3 115 printf("\nERROR: Buffer contents are invalid");
Senthil Ramakrishnan 0:f741508e07a3 116 return false;
Senthil Ramakrishnan 0:f741508e07a3 117 }
Senthil Ramakrishnan 0:f741508e07a3 118 printf("\nRead: %s", rx_buf);
Senthil Ramakrishnan 0:f741508e07a3 119
Senthil Ramakrishnan 0:f741508e07a3 120 return true;
Senthil Ramakrishnan 0:f741508e07a3 121 }
Senthil Ramakrishnan 0:f741508e07a3 122
Senthil Ramakrishnan 0:f741508e07a3 123 bool InitializeFlashMem()
Senthil Ramakrishnan 0:f741508e07a3 124 {
Senthil Ramakrishnan 0:f741508e07a3 125 bool ret_status = true;
Senthil Ramakrishnan 0:f741508e07a3 126 char status_value[2];
Senthil Ramakrishnan 0:f741508e07a3 127
Senthil Ramakrishnan 0:f741508e07a3 128 //Read the Status Register from device
Senthil Ramakrishnan 0:f741508e07a3 129 if (QSPI_STATUS_OK == myQspi->command_transfer(QSPI_STD_CMD_RDSR, // command to send
Senthil Ramakrishnan 0:f741508e07a3 130 0, // do not transmit
Senthil Ramakrishnan 0:f741508e07a3 131 NULL, // do not transmit
Senthil Ramakrishnan 0:f741508e07a3 132 status_value, // just receive two bytes of data
Senthil Ramakrishnan 0:f741508e07a3 133 2)) { // store received values in status_value
Senthil Ramakrishnan 0:f741508e07a3 134 VERBOSE_PRINT(("\nReading Status Register Success: value = 0x%02X:0x%02X\n", status_value[0], status_value[1]));
Senthil Ramakrishnan 0:f741508e07a3 135 } else {
Senthil Ramakrishnan 0:f741508e07a3 136 printf("\nERROR: Reading Status Register failed\n");
Senthil Ramakrishnan 0:f741508e07a3 137 ret_status = false;
Senthil Ramakrishnan 0:f741508e07a3 138 }
Senthil Ramakrishnan 0:f741508e07a3 139
Senthil Ramakrishnan 0:f741508e07a3 140 if(ret_status)
Senthil Ramakrishnan 0:f741508e07a3 141 {
Senthil Ramakrishnan 0:f741508e07a3 142 //Send Reset Enable
Senthil Ramakrishnan 0:f741508e07a3 143 if (QSPI_STATUS_OK == myQspi->command_transfer(QSPI_STD_CMD_RSTEN, // command to send
Senthil Ramakrishnan 0:f741508e07a3 144 0, // do not transmit
Senthil Ramakrishnan 0:f741508e07a3 145 NULL, // do not transmit
Senthil Ramakrishnan 0:f741508e07a3 146 0, // just receive two bytes of data
Senthil Ramakrishnan 0:f741508e07a3 147 NULL)) { // store received values in status_value
Senthil Ramakrishnan 0:f741508e07a3 148 VERBOSE_PRINT(("\nSending RSTEN Success\n"));
Senthil Ramakrishnan 0:f741508e07a3 149 } else {
Senthil Ramakrishnan 0:f741508e07a3 150 printf("\nERROR: Sending RSTEN failed\n");
Senthil Ramakrishnan 0:f741508e07a3 151 ret_status = false;
Senthil Ramakrishnan 0:f741508e07a3 152 }
Senthil Ramakrishnan 0:f741508e07a3 153
Senthil Ramakrishnan 0:f741508e07a3 154 if(ret_status)
Senthil Ramakrishnan 0:f741508e07a3 155 {
Senthil Ramakrishnan 0:f741508e07a3 156 //Send Reset
Senthil Ramakrishnan 0:f741508e07a3 157 if (QSPI_STATUS_OK == myQspi->command_transfer(QSPI_STD_CMD_RST, // command to send
Senthil Ramakrishnan 0:f741508e07a3 158 0, // do not transmit
Senthil Ramakrishnan 0:f741508e07a3 159 NULL, // do not transmit
Senthil Ramakrishnan 0:f741508e07a3 160 status_value, // just receive two bytes of data
Senthil Ramakrishnan 0:f741508e07a3 161 2)) { // store received values in status_value
Senthil Ramakrishnan 0:f741508e07a3 162 VERBOSE_PRINT(("\nSending RST Success\n"));
Senthil Ramakrishnan 0:f741508e07a3 163 } else {
Senthil Ramakrishnan 0:f741508e07a3 164 printf("\nERROR: Sending RST failed\n");
Senthil Ramakrishnan 0:f741508e07a3 165 ret_status = false;
Senthil Ramakrishnan 0:f741508e07a3 166 }
Senthil Ramakrishnan 0:f741508e07a3 167
Senthil Ramakrishnan 0:f741508e07a3 168 if(ret_status)
Senthil Ramakrishnan 0:f741508e07a3 169 {
Senthil Ramakrishnan 0:f741508e07a3 170 status_value[0] |= 0x40;
Senthil Ramakrishnan 0:f741508e07a3 171 //Write the Status Register to set QE enable bit
Senthil Ramakrishnan 0:f741508e07a3 172 if (QSPI_STATUS_OK == myQspi->command_transfer(QSPI_STD_CMD_WRSR, // command to send
Senthil Ramakrishnan 0:f741508e07a3 173 status_value,
Senthil Ramakrishnan 0:f741508e07a3 174 1,
Senthil Ramakrishnan 0:f741508e07a3 175 NULL,
Senthil Ramakrishnan 0:f741508e07a3 176 0)) { // store received values in status_value
Senthil Ramakrishnan 0:f741508e07a3 177 VERBOSE_PRINT(("\nWriting Status Register Success\n"));
Senthil Ramakrishnan 0:f741508e07a3 178 } else {
Senthil Ramakrishnan 0:f741508e07a3 179 printf("\nERROR: Writing Status Register failed\n");
Senthil Ramakrishnan 0:f741508e07a3 180 ret_status = false;
Senthil Ramakrishnan 0:f741508e07a3 181 }
Senthil Ramakrishnan 0:f741508e07a3 182 }
Senthil Ramakrishnan 0:f741508e07a3 183 }
Senthil Ramakrishnan 0:f741508e07a3 184 }
Senthil Ramakrishnan 0:f741508e07a3 185
Senthil Ramakrishnan 0:f741508e07a3 186 return ret_status;
Senthil Ramakrishnan 0:f741508e07a3 187 }
Senthil Ramakrishnan 0:f741508e07a3 188
Senthil Ramakrishnan 0:f741508e07a3 189 bool WaitForMemReady()
Senthil Ramakrishnan 0:f741508e07a3 190 {
Senthil Ramakrishnan 0:f741508e07a3 191 char status_value[2];
Senthil Ramakrishnan 0:f741508e07a3 192 int retries = 0;
Senthil Ramakrishnan 0:f741508e07a3 193
Senthil Ramakrishnan 0:f741508e07a3 194 do
Senthil Ramakrishnan 0:f741508e07a3 195 {
Senthil Ramakrishnan 0:f741508e07a3 196 retries++;
Senthil Ramakrishnan 0:f741508e07a3 197 //Read the Status Register from device
Senthil Ramakrishnan 0:f741508e07a3 198 if (QSPI_STATUS_OK == myQspi->command_transfer(QSPI_STD_CMD_RDSR, // command to send
Senthil Ramakrishnan 0:f741508e07a3 199 0, // do not transmit
Senthil Ramakrishnan 0:f741508e07a3 200 NULL, // do not transmit
Senthil Ramakrishnan 0:f741508e07a3 201 status_value, // just receive two bytes of data
Senthil Ramakrishnan 0:f741508e07a3 202 2)) { // store received values in status_value
Senthil Ramakrishnan 0:f741508e07a3 203 VERBOSE_PRINT(("\nReadng Status Register Success: value = 0x%02X:0x%02X\n", status_value[0], status_value[1]));
Senthil Ramakrishnan 0:f741508e07a3 204 } else {
Senthil Ramakrishnan 0:f741508e07a3 205 printf("\nERROR: Reading Status Register failed\n");
Senthil Ramakrishnan 0:f741508e07a3 206 }
Senthil Ramakrishnan 0:f741508e07a3 207 } while( (status_value[0] & 0x1) != 0 && retries <10000 );
Senthil Ramakrishnan 0:f741508e07a3 208
Senthil Ramakrishnan 0:f741508e07a3 209 if((status_value[0] & 0x1) != 0) return false;
Senthil Ramakrishnan 0:f741508e07a3 210 return true;
Senthil Ramakrishnan 0:f741508e07a3 211 }
Senthil Ramakrishnan 0:f741508e07a3 212
Senthil Ramakrishnan 0:f741508e07a3 213 bool SectorErase(unsigned int flash_addr)
Senthil Ramakrishnan 0:f741508e07a3 214 {
Senthil Ramakrishnan 0:f741508e07a3 215 char addrbytes[3] = {0};
Senthil Ramakrishnan 0:f741508e07a3 216
Senthil Ramakrishnan 0:f741508e07a3 217 addrbytes[2]=flash_addr & 0xFF;
Senthil Ramakrishnan 0:f741508e07a3 218 addrbytes[1]=(flash_addr >> 8) & 0xFF;
Senthil Ramakrishnan 0:f741508e07a3 219 addrbytes[0]=(flash_addr >> 16) & 0xFF;
Senthil Ramakrishnan 0:f741508e07a3 220
Senthil Ramakrishnan 0:f741508e07a3 221 //Send WREN
Senthil Ramakrishnan 0:f741508e07a3 222 if (QSPI_STATUS_OK == myQspi->command_transfer(QSPI_STD_CMD_WREN, // command to send
Senthil Ramakrishnan 0:f741508e07a3 223 0, // do not transmit
Senthil Ramakrishnan 0:f741508e07a3 224 NULL, // do not transmit
Senthil Ramakrishnan 0:f741508e07a3 225 0, // just receive two bytes of data
Senthil Ramakrishnan 0:f741508e07a3 226 NULL)) { // store received values in status_value
Senthil Ramakrishnan 0:f741508e07a3 227 VERBOSE_PRINT(("\nSending WREN command success\n"));
Senthil Ramakrishnan 0:f741508e07a3 228 } else {
Senthil Ramakrishnan 0:f741508e07a3 229 printf("\nERROR: Sending WREN command failed\n");
Senthil Ramakrishnan 0:f741508e07a3 230 return false;
Senthil Ramakrishnan 0:f741508e07a3 231 }
Senthil Ramakrishnan 0:f741508e07a3 232
Senthil Ramakrishnan 0:f741508e07a3 233 if (QSPI_STATUS_OK == myQspi->command_transfer(QSPI_STD_CMD_SECT_ERASE, // command to send
Senthil Ramakrishnan 0:f741508e07a3 234 addrbytes, // do not transmit
Senthil Ramakrishnan 0:f741508e07a3 235 3, // do not transmit
Senthil Ramakrishnan 0:f741508e07a3 236 0, // just receive two bytes of data
Senthil Ramakrishnan 0:f741508e07a3 237 NULL)) { // store received values in status_value
Senthil Ramakrishnan 0:f741508e07a3 238 VERBOSE_PRINT(("\nSending SECT_ERASE command success\n"));
Senthil Ramakrishnan 0:f741508e07a3 239 } else {
Senthil Ramakrishnan 0:f741508e07a3 240 printf("\nERROR: Readng SECT_ERASE command failed\n");
Senthil Ramakrishnan 0:f741508e07a3 241 return false;
Senthil Ramakrishnan 0:f741508e07a3 242 }
Senthil Ramakrishnan 0:f741508e07a3 243
Senthil Ramakrishnan 0:f741508e07a3 244 return true;
Senthil Ramakrishnan 0:f741508e07a3 245 }
Senthil Ramakrishnan 0:f741508e07a3 246