RAFW Flexible Software Package Documentation  Release v2.0.1

 
QSPI (r_qspi_w)

Driver for the QSPI peripheral on RRQ MCUs. This module implements the SPI Flash Interface.

Overview

Features

The QSPI driver has the following key features:

Configuration

Build Time Configurations for r_qspi_w

The following build time configurations are defined in fsp_cfg/r_qspi_w_cfg.h:

ConfigurationOptionsDefaultDescription
Parameter Checking
  • Default (BSP)
  • Enabled
  • Disabled
Default (BSP) If selected code for parameter checking is included in the build.

Configurations for Storage > QSPI FLASH (r_qspi_w)

This module can be added to the Stacks tab via New Stack > Storage > QSPI FLASH (r_qspi_w).

ConfigurationOptionsDefaultDescription
General
NameName must be a valid C symbolg_qspi_w0 Module name.
ChannelChannel not available on selected MCU0 Module Channel.
Address Bytes
  • 3
  • 4
  • 4 with 4-byte read code
3 Select the number of address bytes. Selecting '4 with 4-byte read code' converts the default read code determined in Read Mode to the 4-byte version. If 4-byte mode is selected without using 4-byte commands, the application must issue the EN4B command using R_QSPI_W_Direct().
Page Size BytesMust be an integer greater than 0256 The maximum number of bytes allowed for a single write.
Data Rate ModeSDRSDR Select QSPI Mode.
Drive CurrentMCU Specific OptionsSet the Drive Strength of the QSPI Controller.
Slew RateMCU Specific OptionsSet the Slew Rate of the QSPI Controller.
Data CacheMCU Specific OptionsEnable the dCache Controller.
SPI Clock Polarity
  • Low
  • High
Low Select the polarity of QSPI_W_CLK when QSPI_W_CS is high.
Wrap Mode
  • TX/RX Disabled
  • RX Enabled/TX Disabled
  • TX Enabled/RX Disabled
  • TX/RX Enabled
module.driver.qspi_w.wrap_mode.disabled Select if Wrapping Burst is enabled.
Memory Burst LengthMCU Specific OptionsSet the external memory burst length of the QSPI Controller.
Command Definitions
Command Definitions > Read Command
Read Mode OpcodeValue must be a non-negative integer0xEB Select the read mode for memory mapped access.
Read Mode Wrapping Burst OpcodeValue must be a non-negative integer0 Enter the read opcode for wrapping burst memory mapped access.
Extra Byte ValueValue must be a non-negative integer0xFF Enter the value for the extra byte.
Extra Byte Enable
  • Disabled
  • Enabled
Disabled Enable the transmission of the extra byte.
CS High Minimum CyclesValue must be a non-negative integer0x01 Between the transmissions of two different instructions to the memory device, the SPI bus stays in idle state (QSPI_CS high) for at least this number of QSPI_SCK clock cycles.
Instruction Opcode Bus Lines
  • 1
  • 2
  • 4
1 Select the number of lines to use for sending the instruction's opcode. This can be determined by referencing the datasheet for the external QSPI.
Address & Dummy Data Bus Lines
  • 1
  • 2
  • 4
4 Select the number of lines to use for the address bytes & dummy bytes. This can be determined by referencing the datasheet for the external QSPI.
Data Bus Lines
  • 1
  • 2
  • 4
4 Select the number of lines to use for the data bytes. This can be determined by referencing the datasheet for the external QSPI.
Dummy ClocksMCU Specific OptionsSelect the number of dummy clocks for fast read operations. Default is 6 clocks for Fast Read Quad I/O, 4 clocks for Fast Read Dual I/O, and 8 clocks for other fast read instructions including Fast Read Quad Output, Fast Read Dual Output, and Fast Read
Instruction Mode
  • TX Instr At Any Burst Access
  • TX Instr Only At First Access
TX Instr At Any Burst Access Select whether you want to transmit instruction at any burst access or only in the first access after the selection of Auto Mode.
Command Definitions > Page Program Command
Page Program Command OpcodeMust be an 8-bit QSPI Page Program Command0x02 The command to program a page. If 'Support Multiple Line Program in Extended SPI Mode' is Enabled, this command must use the same number of data lines as the selected read mode.
Page Program Command Wrapping Burst OpcodeValue must be a non-negative integer0 Enter the page program opcode for wrapping burst memory mapped access.
CS High Minimum CyclesValue must be a non-negative integer0x01 After the execution of the write command, the QSPI_CS remains high for at least this number of QSPI_SCK clock cycles.
Instruction Opcode Bus Lines
  • 1
  • 2
  • 4
1 Select the number of lines to use for sending the instruction's opcode. This can be determined by referencing the datasheet for the external QSPI. It should either be 1 or match the number of data lines used for memory mapped fast read operations.
Address, Dummy Data & Data Bus Lines
  • 1
  • 2
  • 4
1 Select the number of lines to use for the address bytes, dummy bytes & data bytes. This can be determined by referencing the datasheet for the external QSPI. It should either be 1 or match the number of data lines used for memory mapped fast read operations.
Dummy ClocksMCU Specific OptionsSelect the number of dummy clocks for fast read operations. Default is 6 clocks for Fast Read Quad I/O, 4 clocks for Fast Read Dual I/O, and 8 clocks for other fast read instructions including Fast Read Quad Output, Fast Read Dual Output, and Fast Read
Command Definitions > Status Command
OpcodeMust be an 8-bit QSPI Status Command0x05 The command to query the status of a write or erase command.
Instruction Opcode Bus Lines
  • 1
  • 2
  • 4
1 Select the number of lines to use for sending the instruction's opcode. This can be determined by referencing the datasheet for the external QSPI. It should either be 1 or match the number of data lines used for memory mapped fast read operations.
Receive Data Bus Lines
  • 1
  • 2
  • 4
1 Select the number of lines to use for the received data bytes. This can be determined by referencing the datasheet for the external QSPI.
Write Status Bit PosMust be an integer between 0 and 70 Which bit contains the write in progress status returned from the Write Status Command.
Command Definitions > Write Enable Command
OpcodeMust be an 8-bit QSPI Write Enable Command0x06 The command to enable write.
Write Enable Bit PosMust be an integer between 0 and 71 This bit will wait until the write data to be available before to start sending the write command sequence.
Data Bus Lines
  • 1
  • 2
  • 4
1 Select the number of lines to use for the opcode byte. This can be determined by referencing the datasheet for the external QSPI.
Command Definitions > Erase Command
Sector Erase OpcodeMust be an 8-bit QSPI Sector Erase Opcode under Command Definitions|Erase Command0x20 The command to erase a sector. Set Sector Erase Size to 0 if unused.
Sector Erase SizeMust be an integer greater than or equal to 04096 The sector erase size. Set Sector Erase Size to 0 if Sector Erase is not supported.
Block Erase OpcodeMust be an 8-bit QSPI Block Erase Opcode under Command Definitions|Erase Command0xD8 The command to erase a block. Set Block Erase Size to 0 if unused.
Block Erase SizeMust be an integer greater than or equal to 065536 The block erase size. Set Block Erase Size to 0 if Block Erase is not supported.
Block Erase 32KB OpcodeMust be an 8-bit QSPI Block Erase 32KB Opcode under Command Definitions|Erase Command0x52 The command to erase a 32KB block. Set Block Erase Size to 0 if unused.
Block Erase 32KB SizeMust be an integer greater than or equal to 032768 The block erase 32KB size. Set Block Erase 32KB Size to 0 if Block Erase 32KB is not supported.
Chip Erase OpcodeMust be an 8-bit QSPI Chip Erase Opcode under Command Definitions|Erase Command0xC7 The command to erase the entire chip. Set Chip Erase Command to 0 if unused.
Instruction Opcode Bus Lines
  • 1
  • 2
  • 4
1 Select the number of lines to use for sending the instruction's opcode. This can be determined by referencing the datasheet for the external QSPI. It should either be 1 or match the number of data lines used for memory mapped fast read operations.
Dummy Data & Data Bus Lines
  • 1
  • 2
  • 4
1 Select the number of lines to use for the address bytes, dummy bytes & data bytes. This can be determined by referencing the datasheet for the external QSPI. It should either be 1 or match the number of data lines used for memory mapped fast read operations.
Command Definitions > XIP Command
Enter CommandMust be an 8-bit QSPI XIP Enter M7-M0 command under Command Definitions|XIPCommand0xA5 How to set M7-M0 to enter XIP mode.
Exit CommandMust be an 8-bit QSPI XIP Exit M7-M0 command under Command Definitions|XIPCommand0xFF How to set M7-M0 exit XIP mode.

Clock Configuration

The QSPI clock is derived from PCLKA.

Pin Configuration

The following pins are available to connect to an external QSPI device:

Usage Notes

QSPI Memory Mapped Access

After R_QSPI_W_Open() completes successfully, the QSPI flash device contents are mapped to address 0x16000000 and can be read like on-chip flash.

Examples

Basic Example

This is a basic example of minimal use of the QSPI in an application.

#define QSPI_W_EXAMPLE_DATA_LENGTH (1024)
uint8_t g_dest[QSPI_W_EXAMPLE_DATA_LENGTH];
/* Place data in the .qspi_flash section to flash it during programming. */
const uint8_t g_src[QSPI_W_EXAMPLE_DATA_LENGTH] BSP_PLACE_IN_SECTION(".qspi_flash") = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
/* Place code in the .qspi_flash_code section to flash it during programming. */
void r_qspi_w_example_function(void) BSP_PLACE_IN_SECTION(".qspi_flash_code") __attribute__((noinline));
void r_qspi_w_example_function (void)
{
/* Add code here. */
}
void r_qspi_w_basic_example (void)
{
/* Open the QSPI instance. */
fsp_err_t err = R_QSPI_W_Open(&g_qspi0_ctrl, &g_qspi0_cfg);
if (FSP_SUCCESS != err)
{
__BKPT(0);
}
/* (Optional) Send device specific initialization commands. */
r_qspi_w_example_init();
/* After R_QSPI_W_Open() and any required device specific intiialization, data can be read directly from the QSPI flash. */
memcpy(&g_dest[0], &g_src[0], QSPI_W_EXAMPLE_DATA_LENGTH);
/* After R_QSPI_W_Open() and any required device specific intiialization, functions in the QSPI flash can be called. */
r_qspi_w_example_function();
}

Initialization Command Structure Example

This is an example of the types of commands that can be used to initialize the QSPI.

#define QSPI_W_COMMAND_WRITE_ENABLE (0x06U)
#define QSPI_W_COMMAND_WRITE_STATUS_REGISTER (0x01U)
#define QSPI_W_COMMAND_ENTER_QPI_MODE (0x35U)
#define QSPI_W_EXAMPLE_STATUS_REGISTER_1 (0x40)
#define QSPI_W_EXAMPLE_STATUS_REGISTER_2 (0x00)
static void r_qspi_w_example_init (void)
{
/* Write status registers */
/* Write one byte to enable writing to the status register, then deassert QSSL. */
uint8_t data[4];
fsp_err_t err;
data[0] = QSPI_W_COMMAND_WRITE_ENABLE;
err = R_QSPI_W_DirectWrite(&g_qspi0_ctrl, &data[0], 1, false);
if (FSP_SUCCESS != err)
{
__BKPT(0);
}
/* Write 3 bytes, including the write status register command followed by values for both status registers. In the
* status registers, set QE to 1 and other bits to their default setting. After all data is written, deassert the
* QSSL line. */
data[0] = QSPI_W_COMMAND_WRITE_STATUS_REGISTER;
data[1] = QSPI_W_EXAMPLE_STATUS_REGISTER_1;
data[2] = QSPI_W_EXAMPLE_STATUS_REGISTER_2;
err = R_QSPI_W_DirectWrite(&g_qspi0_ctrl, &data[0], 3, false);
if (FSP_SUCCESS != err)
{
__BKPT(0);
}
/* Wait for status register to update. */
do
{
(void) R_QSPI_W_StatusGet(&g_qspi0_ctrl, &status);
} while (true == status.write_in_progress);
/* Write one byte to enter QSPI mode, then deassert QSSL. After entering QPI mode on the device, change the SPI
* protocol to QPI mode on the MCU peripheral. */
data[0] = QSPI_W_COMMAND_ENTER_QPI_MODE;
err = R_QSPI_W_DirectWrite(&g_qspi0_ctrl, &data[0], 1, false);
if (FSP_SUCCESS != err)
{
__BKPT(0);
}
}

Reading Status Register Example (R_QSPI_W_DirectWrite, R_QSPI_W_DirectRead)

This is an example of using R_QSPI_W_DirectWrite followed by R_QSPI_W_DirectRead to send the read status register command and read back the status register from the device.

#define QSPI_W_COMMAND_READ_STATUS_REGISTER (0x05U)
void r_qspi_w_direct_example (void)
{
/* Read a status register. */
/* Write one byte to read the status register. Do not deassert QSSL. */
uint8_t data;
fsp_err_t err;
data = QSPI_W_COMMAND_READ_STATUS_REGISTER;
err = R_QSPI_W_DirectWrite(&g_qspi0_ctrl, &data, 1, true);
if (FSP_SUCCESS != err)
{
__BKPT(0);
}
/* Read one byte. After all data is read, deassert the QSSL line. */
err = R_QSPI_W_DirectRead(&g_qspi0_ctrl, &data, 1);
if (FSP_SUCCESS != err)
{
__BKPT(0);
}
/* Status register contents are available in variable 'data'. */
}

Querying Device Size Example (R_QSPI_W_DirectWrite, R_QSPI_W_DirectRead)

This is an example of using R_QSPI_W_DirectWrite followed by R_QSPI_W_DirectRead to query the device size.

#define QSPI_W_EXAMPLE_COMMAND_READ_ID (0x9F)
#define QSPI_W_EXAMPLE_COMMAND_READ_SFDP (0x5A)
void r_qspi_w_size_example (void)
{
/* Many QSPI devices support more than one way to query the device size. Consult the datasheet for your
* QSPI device to determine which of these methods are supported (if any). */
uint32_t device_size_bytes;
fsp_err_t err;
#ifdef QSPI_W_EXAMPLE_COMMAND_READ_ID
/* This example shows how to get the device size by reading the manufacturer ID. */
uint8_t data[4];
data[0] = QSPI_W_EXAMPLE_COMMAND_READ_ID;
err = R_QSPI_W_DirectWrite(&g_qspi0_ctrl, &data[0], 1, true);
if (FSP_SUCCESS != err)
{
__BKPT(0);
}
/* Read 3 bytes. The third byte often represents the size of the QSPI, where the size of the QSPI = 2 ^ N. */
err = R_QSPI_W_DirectRead(&g_qspi0_ctrl, &data[0], 3);
if (FSP_SUCCESS != err)
{
__BKPT(0);
}
device_size_bytes = 1U << data[2];
FSP_PARAMETER_NOT_USED(device_size_bytes);
#endif
#ifdef QSPI_W_EXAMPLE_COMMAND_READ_SFDP
/* Read the JEDEC SFDP header to locate the JEDEC flash parameters table. Reference JESD216 "Serial Flash
* Discoverable Parameters (SFDP)". */
/* Send the standard 0x5A command followed by 3 address bytes (SFDP header is at address 0). */
uint8_t buffer[16];
memset(&buffer[0], 0, sizeof(buffer));
buffer[0] = QSPI_W_EXAMPLE_COMMAND_READ_SFDP;
err = R_QSPI_W_DirectWrite(&g_qspi0_ctrl, &buffer[0], 4, true);
if (FSP_SUCCESS != err)
{
__BKPT(0);
}
/* Read out 16 bytes (1 dummy byte followed by 15 data bytes). */
err = R_QSPI_W_DirectRead(&g_qspi0_ctrl, &buffer[0], 16);
if (FSP_SUCCESS != err)
{
__BKPT(0);
}
/* Read the JEDEC flash parameters to locate the memory size. */
/* Send the standard 0x5A command followed by 3 address bytes (located in big endian order at offset 0xC-0xE).
* These bytes are accessed at 0xD-0xF because the first byte read is a dummy byte. */
buffer[0] = QSPI_W_EXAMPLE_COMMAND_READ_SFDP;
buffer[1] = buffer[0xF];
buffer[2] = buffer[0xE];
buffer[3] = buffer[0xD];
err = R_QSPI_W_DirectWrite(&g_qspi0_ctrl, &buffer[0], 4, true);
if (FSP_SUCCESS != err)
{
__BKPT(0);
}
/* Read out 9 bytes (1 dummy byte followed by 8 data bytes). */
err = R_QSPI_W_DirectRead(&g_qspi0_ctrl, &buffer[0], 9);
if (FSP_SUCCESS != err)
{
__BKPT(0);
}
/* Read the memory density (located in big endian order at offset 0x4-0x7). These bytes are accessed at 0x5-0x8
* because the first byte read is a dummy byte. */
uint32_t memory_density = (uint32_t) ((buffer[8] << 24) | (buffer[7] << 16) | (buffer[6] << 8) | buffer[5]);
if ((1U << 31) & memory_density)
{
/* For densities 4 gigabits and above, bit-31 is set to 1b. The field 30:0 defines ‘N’ where the density is
* computed as 2^N bits (N must be >= 32). This code subtracts 3 from N to divide by 8 to get the size in
* bytes instead of bits. */
device_size_bytes = 1U << ((memory_density & ~(1U << 31)) - 3U);
}
else
{
/* For densities 2 gigabits or less, bit-31 is set to 0b. The field 30:0 defines the size in bits. This
* code divides the memory density by 8 to get the size in bytes instead of bits. */
device_size_bytes = (memory_density / 8) + 1;
}
FSP_PARAMETER_NOT_USED(device_size_bytes);
#endif
}