QSPI HAL Results

group group_hal_qspi

High level interface for interacting with the Quad-SPI interface.

QSPI is an SPI-based communication interface, often used with external memory devices. The QSPI driver supports sending and receiving commands to/from from another device via a single, dual, quad, or octal SPI interface.

Features

  • Standard SPI Master interface

  • Supports Single/Dual/Quad/Octal SPI memories

  • Supports Dual-Quad SPI mode

  • Execute-In-Place (XIP) from external Quad SPI Flash

  • Supports external serial memory initialization via Serial Flash Discoverable Parameters (SFDP) standard

Code Snippets

note

The following snippets show commands specific to the S25FL512S Cypress NOR Flash device. Refer to the datasheet of the external memory device for device specific memory commands.

Code Snippet 1: Initializing the cyhal_qspi_command_t structure

The following code snip demonstrates an example for initializing the cyhal_qspi_command_t structure for any given flash command. The cyhal_qspi_command_t.mode_bits structure has several other components which should be set as per the command. Mode bits are not required for single SPI read command, hence, mode_bits.disabled is set to TRUE in the below example code.

// Commands
#define DEVICE_SPECIFIC_READ_COMMAND                    (0x03)

// Defining QSPI command structure for READ command
cyhal_qspi_command_t device_specific_read_command =
{
    .instruction.bus_width = CYHAL_QSPI_CFG_BUS_SINGLE,    // Bus width for the instruction
    .instruction.value     = DEVICE_SPECIFIC_READ_COMMAND, // Instruction value
    .instruction.disabled  = false,                        // Instruction phase skipped if disabled
                                                           //   set to true
    .address.bus_width     = CYHAL_QSPI_CFG_BUS_SINGLE,    // Bus width for the address
    .address.size          = CYHAL_QSPI_CFG_SIZE_24,       // Address size in bits
    .address.value         = ADDRESS,                      // Address value
    .address.disabled      = false,                        // Address phase skipped if disabled set
                                                           //   to true
    .mode_bits.disabled    = true,                         // Mode bits phase skipped if disabled
                                                           //   set to true
    .dummy_count           = 0,                            // Dummy cycles count
    .data.bus_width        = CYHAL_QSPI_CFG_BUS_SINGLE,    // Bus width for data
};

Code Snippet 2: QSPI initialization and Reading Flash memory

This example function demonstrates the initialization of the QSPI component and use of the cyhal_qspi_read() function to complete the read operation and receive the read data in a buffer.

    cy_rslt_t    result;
    cyhal_qspi_t qspi_object;
    uint8_t      rx_buf[PACKET_SIZE];
    size_t       length = PACKET_SIZE;

    // Initialize QSPI peripheral with appropriate GPIOs
    result = cyhal_qspi_init(&qspi_object, CYBSP_QSPI_D0, CYBSP_QSPI_D1, CYBSP_QSPI_D2,
                             CYBSP_QSPI_D3, NC, NC, NC, NC,
                             CYBSP_QSPI_SCK, CYBSP_QSPI_SS, QSPI_BUS_FREQUENCY_HZ, 0);

    // HAL API for read operation
    result = cyhal_qspi_read(&qspi_object, &device_specific_read_command, rx_buf, &length);

Code Snippet 3: Erasing Flash memory

The following code snippet demonstrates the use of cyhal_qspi_transfer() API for sending single byte instruction that may or may not need any address or data bytes. It also shows the usage of status register read command within a while loop to poll the WIP bit status.

    cy_rslt_t    result;
    cyhal_qspi_t qspi_object;
    uint8_t      rx_buf[PACKET_SIZE];
    uint8_t      wip    = 0x01;
    size_t       length = 1;

    // HAL API for TX-RX transaction used for sending WREN command
    result = cyhal_qspi_transfer(&qspi_object, &device_specific_wren_command, NULL, 0, NULL, 0);

    // HAL API for TX-RX transaction used for sending SE command
    result = cyhal_qspi_transfer(&qspi_object, &device_specific_se_command, NULL, 0, NULL, 0);

    while (wip)
    {
        // Wait until the Erase operation is completed
        cyhal_qspi_read(&qspi_object, &device_specific_rdsr1_command, rx_buf, &length);
        wip = rx_buf[0] & 0x01;
    }

note

Flash memories need erase operation before programming.

Code Snippet 4: Programming Flash memory

This code snippet demonstrates the usage cyhal_qspi_write() API for executing program operation on flash memory.

    cy_rslt_t    result;
    cyhal_qspi_t qspi_object;
    uint8_t      tx_buf[PACKET_SIZE];
    uint8_t      rx_buf[PACKET_SIZE];
    size_t       length = PACKET_SIZE;
    uint8_t      wip    = 0x01;

    // Initialization of tx_buffer
    for (int i = 0; i < PACKET_SIZE; i++)
    {
        tx_buf[i] = i;
    }

    // HAL API for TX-RX transaction used for sending WREN command
    result = cyhal_qspi_transfer(&qspi_object, &device_specific_wren_command, NULL, 0, NULL, 0);

    // HAL API for write operation
    result = cyhal_qspi_write(&qspi_object, &device_specific_pp_command, tx_buf, &length);

    while (wip)
    {
        // Wait until the Write operation is completed
        cyhal_qspi_read(&qspi_object, &device_specific_rdsr1_command, rx_buf, &length);
        wip = rx_buf[0] & 0x01;
    }

Typedefs

typedef void (*cyhal_qspi_event_callback_t)(void *callback_arg, cyhal_qspi_event_t event)

Handler for QSPI callbacks.

Enums

enum cyhal_qspi_bus_width_t

cyhal_qspi_bus_width_t: QSPI Bus width.

Some parts of commands provide variable bus width.

Values:

enumerator CYHAL_QSPI_CFG_BUS_SINGLE

Normal SPI Mode.

enumerator CYHAL_QSPI_CFG_BUS_DUAL

Dual SPI Mode.

enumerator CYHAL_QSPI_CFG_BUS_QUAD

Quad SPI Mode.

enumerator CYHAL_QSPI_CFG_BUS_OCTAL

Octal SPI Mode.

enum cyhal_qspi_size_t

cyhal_qspi_size_t: Address size in bits.

Values:

enumerator CYHAL_QSPI_CFG_SIZE_8

8 bits address

enumerator CYHAL_QSPI_CFG_SIZE_16

16 bits address

enumerator CYHAL_QSPI_CFG_SIZE_24

24 bits address

enumerator CYHAL_QSPI_CFG_SIZE_32

32 bits address

enum cyhal_qspi_event_t

cyhal_qspi_event_t: QSPI interrupt triggers.

Values:

enumerator CYHAL_QSPI_EVENT_NONE

No event.

enumerator CYHAL_QSPI_IRQ_TRANSMIT_DONE

Async transmit done.

enumerator CYHAL_QSPI_IRQ_RECEIVE_DONE

Async receive done.

Functions

cy_rslt_t cyhal_qspi_init(cyhal_qspi_t *obj, cyhal_gpio_t io0, cyhal_gpio_t io1, cyhal_gpio_t io2, cyhal_gpio_t io3, cyhal_gpio_t io4, cyhal_gpio_t io5, cyhal_gpio_t io6, cyhal_gpio_t io7, cyhal_gpio_t sclk, cyhal_gpio_t ssel, uint32_t hz, uint8_t mode)

Initialize QSPI peripheral.

It should initialize QSPI pins (io0-io7, sclk and ssel), set frequency, clock polarity and phase mode. The clock for the peripheral should be enabled

note

Provided slave select pin will be set as active. This can be changed (as well as additional ssel pins can be added) by cyhal_qspi_slave_select_config and cyhal_qspi_select_active_ssel functions.

Return

The status of the init request

Parameters
  • [out] obj: Pointer to a QSPI object. The caller must allocate the memory for this object but the init function will initialize its contents.

  • [in] io0: Data pin 0

  • [in] io1: Data pin 1

  • [in] io2: Data pin 2

  • [in] io3: Data pin 3

  • [in] io4: Data pin 4

  • [in] io5: Data pin 5

  • [in] io6: Data pin 6

  • [in] io7: Data pin 7

  • [in] sclk: The clock pin

  • [in] ssel: The chip select pin

Parameters
  • [in] hz: The bus frequency

  • [in] mode: Clock polarity and phase mode (0 - 3)

void cyhal_qspi_free(cyhal_qspi_t *obj)

Deinitilize QSPI peripheral.

It should release pins that are associated with the QSPI object, and disable clocks for QSPI peripheral module that was associated with the object

Parameters
  • [inout] obj: QSPI object

cy_rslt_t cyhal_qspi_set_frequency(cyhal_qspi_t *obj, uint32_t hz)

Set the QSPI baud rate.

Actual frequency may differ from the desired frequency due to available dividers and the bus clock. Function will apply achieved frequency only if it is in +0% /-10% deviation bounds from desired. Use cyhal_qspi_get_frequency function to get actual frequency value that was achieved and set.

Return

The status of the set_frequency request

Parameters
  • [in] obj: The QSPI object to configure

  • [in] hz: The baud rate in Hz

uint32_t cyhal_qspi_get_frequency(cyhal_qspi_t *obj)

Get the actual frequency that QSPI is configured for.

Return

Frequency in Hz

Parameters
  • [in] obj: The QSPI object

cy_rslt_t cyhal_qspi_slave_select_config(cyhal_qspi_t *obj, cyhal_gpio_t ssel)

Configures provided pin to work as QSPI slave select (SSEL)

Multiple pins can be configured as QSPI slave select pins. Please refer to device datasheet for details. Switching between configured slave select pins is done by cyhal_qspi_select_active_ssel function. Unless modified with this function, the SSEL pin provided as part of cyhal_qspi_init is the default.

Return

The status of ssel pin configuration

Parameters
  • [in] obj: The QSPI object to configure

  • [in] ssel: Pin to be configured as QSPI SSEL

cy_rslt_t cyhal_qspi_select_active_ssel(cyhal_qspi_t *obj, cyhal_gpio_t ssel)

Selects an active slave select (SSEL) line from one of available.

SSEL pin should be configured by cyhal_qspi_slave_select_config or cyhal_qspi_init functions prior to selecting it as active.

Return

CY_RSLT_SUCCESS if slave select was switched successfully, otherwise - CYHAL_QSPI_RSLT_ERR_CANNOT_SWITCH_SSEL

Parameters
  • [in] obj: The QSPI object to configure

  • [in] ssel: SSEL pin to be set as active

cy_rslt_t cyhal_qspi_read(cyhal_qspi_t *obj, const cyhal_qspi_command_t *command, void *data, size_t *length)

Receive a command and block of data, synchronously.

This will read either length bytes or the number of bytes that are currently available in the receive buffer, whichever is less, then return. The value pointed to by length will be updated to reflect the number of bytes that were actually read.

Return

The status of the read request

Parameters
  • [in] obj: QSPI object

  • [in] command: QSPI command

  • [out] data: RX buffer

  • [in] length: RX buffer length in bytes

cy_rslt_t cyhal_qspi_read_async(cyhal_qspi_t *obj, const cyhal_qspi_command_t *command, void *data, size_t *length)

Receive a command and block of data in asynchronous mode.

This will transfer length bytes into the buffer pointed to by data in the background. When the requested quantity of data has been read, the CYHAL_QSPI_IRQ_RECEIVE_DONE event will be raised. See cyhal_qspi_register_callback and cyhal_qspi_enable_event.

Return

The status of the read request

Parameters
  • [in] obj: QSPI object

  • [in] command: QSPI command

  • [out] data: RX buffer

  • [in] length: RX buffer length in bytes

cy_rslt_t cyhal_qspi_write(cyhal_qspi_t *obj, const cyhal_qspi_command_t *command, const void *data, size_t *length)

Send a command and block of data, synchronously.

This will write either length bytes or until the write buffer is full, whichever is less, then return. The value pointed to by length will be updated to reflect the number of bytes that were actually written.

Return

The status of the write request

Parameters
  • [in] obj: QSPI object

  • [in] command: QSPI command

  • [in] data: TX buffer

  • [in] length: TX buffer length in bytes

cy_rslt_t cyhal_qspi_write_async(cyhal_qspi_t *obj, const cyhal_qspi_command_t *command, const void *data, size_t *length)

Send a command and block of data in asynchronous mode.

This will transfer length bytes into the tx buffer in the background. When the requested quantity of data has been queued in the transmit buffer, the CYHAL_QSPI_IRQ_TRANSMIT_DONE event will be raised. See cyhal_qspi_register_callback and cyhal_qspi_enable_event.

Return

The status of the write request

Parameters
  • [in] obj: QSPI object

  • [in] command: QSPI command

  • [in] data: TX buffer

  • [in] length: TX buffer length in bytes

cy_rslt_t cyhal_qspi_transfer(cyhal_qspi_t *obj, const cyhal_qspi_command_t *command, const void *tx_data, size_t tx_size, void *rx_data, size_t rx_size)

Send a command (and optionally data) and get the response.

Can be used to send/receive device specific commands

Return

The status of the transfer request

Parameters
  • [in] obj: QSPI object

  • [in] command: QSPI command

  • [in] tx_data: TX buffer

  • [in] tx_size: TX buffer length in bytes

  • [out] rx_data: RX buffer

  • [in] rx_size: RX buffer length in bytes

void cyhal_qspi_register_callback(cyhal_qspi_t *obj, cyhal_qspi_event_callback_t callback, void *callback_arg)

Register a QSPI event handler.

This function will be called when one of the events enabled by cyhal_qspi_enable_event occurs.

Parameters
  • [in] obj: The QSPI object

  • [in] callback: The callback handler which will be invoked when the interrupt fires

  • [in] callback_arg: Generic argument that will be provided to the handler when called

void cyhal_qspi_enable_event(cyhal_qspi_t *obj, cyhal_qspi_event_t event, uint8_t intr_priority, bool enable)

Configure QSPI interrupt enablement.

When an enabled event occurs, the function specified by cyhal_qspi_register_callback will be called.

Parameters
  • [in] obj: The QSPI object

  • [in] event: The QSPI event type

  • [in] intr_priority: The priority for NVIC interrupt events

  • [in] enable: True to turn on interrupts, False to turn off

struct cyhal_qspi_command_t
#include <cyhal_qspi.h>

QSPI command settings.

Public Members

struct cyhal_qspi_command_t::[anonymous] instruction

Instruction structure.

struct cyhal_qspi_command_t::[anonymous] address

Address structure.

struct cyhal_qspi_command_t::[anonymous] mode_bits

Mode bits structure.

uint8_t dummy_count

Dummy cycles count.

struct cyhal_qspi_command_t::[anonymous] data

Data structure.

cyhal_qspi_command_t.instruction

Public Members

cyhal_qspi_bus_width_t bus_width

Bus width for the instruction.

uint8_t value

Instruction value.

bool disabled

Instruction phase skipped if disabled is set to true.

cyhal_qspi_command_t.address

Public Members

cyhal_qspi_bus_width_t bus_width

Bus width for the address.

cyhal_qspi_size_t size

Address size.

uint32_t value

Address value.

bool disabled

Address phase skipped if disabled is set to true.

cyhal_qspi_command_t.mode_bits

Public Members

cyhal_qspi_bus_width_t bus_width

Bus width for mode bits.

cyhal_qspi_size_t size

Mode bits size.

uint32_t value

Mode bits value.

bool disabled

Mode bits phase skipped if disabled is set to true.

cyhal_qspi_command_t.data

Public Members

cyhal_qspi_bus_width_t bus_width

Bus width for data.