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.
#define DEVICE_SPECIFIC_READ_COMMAND (0x03)
{
.instruction.two_byte_cmd = false,
.instruction.value = DEVICE_SPECIFIC_READ_COMMAND,
.instruction.disabled = false,
.address.disabled = false,
.mode_bits.disabled = true,
.dummy_cycles.dummy_count = 0,
};
struct cyhal_qspi_command_t::@0 instruction
Instruction structure.
@ CYHAL_QSPI_CFG_SIZE_24
24 bits address
Definition: cyhal_qspi.h:156
@ CYHAL_QSPI_DATARATE_SDR
Single data rate.
Definition: cyhal_qspi.h:171
@ CYHAL_QSPI_CFG_BUS_SINGLE
Normal SPI Mode.
Definition: cyhal_qspi.h:145
QSPI command settings.
Definition: cyhal_qspi.h:177
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.
uint8_t rx_buf[PACKET_SIZE];
size_t length = PACKET_SIZE;
{
.
io = { CYBSP_QSPI_D0, CYBSP_QSPI_D1, CYBSP_QSPI_D2, CYBSP_QSPI_D3,
NC,
NC,
NC,
NC },
.ssel = CYBSP_QSPI_SS_0
};
result =
cyhal_qspi_init(&qspi_object, CYBSP_QSPI_SCK, &memory_pin_set, QSPI_BUS_FREQUENCY_HZ,
0, NULL);
result =
cyhal_qspi_read(&qspi_object, &device_specific_read_command, ADDRESS, rx_buf, &length);
QSPI object.
Definition: cyhal_hw_types.h:632
@ NC
No Connect/Invalid Pin.
Definition: cyhal_pin_package.h:54
cyhal_gpio_t io[8]
IOx lines of connected memory.
Definition: cyhal_qspi.h:221
cy_rslt_t cyhal_qspi_init(cyhal_qspi_t *obj, cyhal_gpio_t sclk, const cyhal_qspi_slave_pin_config_t *pin_set, uint32_t hz, uint8_t mode, cyhal_clock_t *clk)
Initialize QSPI peripheral.
cy_rslt_t cyhal_qspi_read(cyhal_qspi_t *obj, const cyhal_qspi_command_t *command, uint32_t address, void *data, size_t *length)
Receive a command and block of data, synchronously.
QSPI slave pin set.
Definition: cyhal_qspi.h:220
uint32_t cy_rslt_t
Provides the result of an operation as a structured bitfield.
Definition: cy_result.h:438
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.
uint8_t rx_buf[PACKET_SIZE];
uint8_t wip = 0x01;
size_t length = 1;
NULL, 0);
NULL, 0);
while (wip)
{
cyhal_qspi_read(&qspi_object, &device_specific_rdsr1_command, ADDRESS, rx_buf, &length);
wip = rx_buf[0] & 0x01;
}
cy_rslt_t cyhal_qspi_transfer(cyhal_qspi_t *obj, const cyhal_qspi_command_t *command, uint32_t address, 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.
- 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.
uint8_t tx_buf[PACKET_SIZE];
uint8_t rx_buf[PACKET_SIZE];
size_t length = PACKET_SIZE;
uint8_t wip = 0x01;
for (int i = 0; i < PACKET_SIZE; i++)
{
tx_buf[i] = i;
}
NULL, 0);
result =
cyhal_qspi_write(&qspi_object, &device_specific_pp_command, ADDRESS, tx_buf, &length);
while (wip)
{
cyhal_qspi_read(&qspi_object, &device_specific_rdsr1_command, ADDRESS, rx_buf, &length);
wip = rx_buf[0] & 0x01;
}
cy_rslt_t cyhal_qspi_write(cyhal_qspi_t *obj, const cyhal_qspi_command_t *command, uint32_t address, const void *data, size_t *length)
Send a command and block of data, synchronously.
Code Snippet 5: Configuring multiple memories
This code snippet demonstrates the usage cyhal_qspi_slave_configure() and cyhal_qspi_select_active_ssel() API for for initialization environment for additional (additional to one, that was initialized in scope of cyhal_qspi_init()) QSPI memory and switching between memories.
{
.ssel = CYBSP_QSPI_SS_0
};
result =
cyhal_qspi_init(&qspi_object, CYBSP_QSPI_SCK, &memory_0_pin_set, QSPI_BUS_FREQUENCY_HZ,
0, NULL);
{
.ssel = CYBSP_QSPI_SS_1
};
cyhal_gpio_t ssel
Slave Select line of connected memory.
Definition: cyhal_qspi.h:222
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 and previously configured.
cy_rslt_t cyhal_qspi_slave_configure(cyhal_qspi_t *obj, const cyhal_qspi_slave_pin_config_t *pin_set)
Configure provided set of pins to service additional slave memory.
|
#define | CYHAL_API_AVAILABLE_QSPI_IS_BUSY |
| Indicates, that cyhal_qspi_is_busy function is available in this version of HAL.
|
|
#define | CYHAL_API_AVAILABLE_QSPI_IS_PENDING |
| Indicates, that cyhal_qspi_is_pending function is available in this version of HAL.
|
|
|
typedef void(* | cyhal_qspi_event_callback_t) (void *callback_arg, cyhal_qspi_event_t event) |
| Handler for QSPI callbacks.
|
|
|
cy_rslt_t | cyhal_qspi_init (cyhal_qspi_t *obj, cyhal_gpio_t sclk, const cyhal_qspi_slave_pin_config_t *pin_set, uint32_t hz, uint8_t mode, cyhal_clock_t *clk) |
| Initialize QSPI peripheral. More...
|
|
cy_rslt_t | cyhal_qspi_init_cfg (cyhal_qspi_t *obj, const cyhal_qspi_configurator_t *cfg) |
| Initialize the QSPI peripheral using a configurator generated configuration struct. More...
|
|
void | cyhal_qspi_free (cyhal_qspi_t *obj) |
| Deinitilize QSPI peripheral. More...
|
|
cy_rslt_t | cyhal_qspi_set_frequency (cyhal_qspi_t *obj, uint32_t hz) |
| Set the QSPI baud rate. More...
|
|
uint32_t | cyhal_qspi_get_frequency (cyhal_qspi_t *obj) |
| Get the actual frequency that QSPI is configured for. More...
|
|
cy_rslt_t | cyhal_qspi_slave_configure (cyhal_qspi_t *obj, const cyhal_qspi_slave_pin_config_t *pin_set) |
| Configure provided set of pins to service additional slave memory. More...
|
|
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 and previously configured. More...
|
|
cy_rslt_t | cyhal_qspi_read (cyhal_qspi_t *obj, const cyhal_qspi_command_t *command, uint32_t address, void *data, size_t *length) |
| Receive a command and block of data, synchronously. More...
|
|
cy_rslt_t | cyhal_qspi_read_async (cyhal_qspi_t *obj, const cyhal_qspi_command_t *command, uint32_t address, void *data, size_t *length) |
| Receive a command and block of data in asynchronous mode. More...
|
|
cy_rslt_t | cyhal_qspi_write (cyhal_qspi_t *obj, const cyhal_qspi_command_t *command, uint32_t address, const void *data, size_t *length) |
| Send a command and block of data, synchronously. More...
|
|
cy_rslt_t | cyhal_qspi_write_async (cyhal_qspi_t *obj, const cyhal_qspi_command_t *command, uint32_t address, const void *data, size_t *length) |
| Send a command and block of data in asynchronous mode. More...
|
|
cy_rslt_t | cyhal_qspi_transfer (cyhal_qspi_t *obj, const cyhal_qspi_command_t *command, uint32_t address, 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. More...
|
|
void | cyhal_qspi_register_callback (cyhal_qspi_t *obj, cyhal_qspi_event_callback_t callback, void *callback_arg) |
| Register a QSPI event handler. More...
|
|
void | cyhal_qspi_enable_event (cyhal_qspi_t *obj, cyhal_qspi_event_t event, uint8_t intr_priority, bool enable) |
| Configure QSPI interrupt enablement. More...
|
|
bool | cyhal_qspi_is_busy (cyhal_qspi_t *obj) |
| Checks if the specified QSPI peripheral is in use. More...
|
|
bool | cyhal_qspi_is_pending (cyhal_qspi_t *obj) |
| Checks if an async read operation is pending. More...
|
|
◆ cyhal_qspi_command_t
struct cyhal_qspi_command_t |
◆ cyhal_qspi_slave_pin_config_t
struct cyhal_qspi_slave_pin_config_t |
◆ cyhal_qspi_command_t.instruction
struct cyhal_qspi_command_t.instruction |
Data Fields |
cyhal_qspi_bus_width_t |
bus_width |
Bus width for the instruction. |
cyhal_qspi_datarate_t |
data_rate |
Data rate SDR/DDR. |
bool |
two_byte_cmd |
Defines whether cmd is 2-byte value, or 1-byte (if false) |
uint16_t |
value |
Instruction value. |
bool |
disabled |
Instruction phase skipped if disabled is set to true. |
◆ cyhal_qspi_command_t.address
struct cyhal_qspi_command_t.address |
◆ cyhal_qspi_command_t.mode_bits
struct cyhal_qspi_command_t.mode_bits |
◆ cyhal_qspi_command_t.dummy_cycles
struct cyhal_qspi_command_t.dummy_cycles |
◆ cyhal_qspi_command_t.data
struct cyhal_qspi_command_t.data |
◆ cyhal_qspi_bus_width_t
QSPI Bus width.
Some parts of commands provide variable bus width.
Enumerator |
---|
CYHAL_QSPI_CFG_BUS_SINGLE | Normal SPI Mode.
|
CYHAL_QSPI_CFG_BUS_DUAL | Dual SPI Mode.
|
CYHAL_QSPI_CFG_BUS_QUAD | Quad SPI Mode.
|
CYHAL_QSPI_CFG_BUS_OCTAL | Octal SPI Mode.
|
◆ cyhal_qspi_size_t
Address size in bits.
Enumerator |
---|
CYHAL_QSPI_CFG_SIZE_8 | 8 bits address
|
CYHAL_QSPI_CFG_SIZE_16 | 16 bits address
|
CYHAL_QSPI_CFG_SIZE_24 | 24 bits address
|
CYHAL_QSPI_CFG_SIZE_32 | 32 bits address
|
◆ cyhal_qspi_event_t
QSPI interrupt triggers.
Enumerator |
---|
CYHAL_QSPI_EVENT_NONE | No event.
|
CYHAL_QSPI_IRQ_TRANSMIT_DONE | Async transmit done.
|
CYHAL_QSPI_IRQ_RECEIVE_DONE | Async receive done.
|
◆ cyhal_qspi_datarate_t
QSPI data rate.
Enumerator |
---|
CYHAL_QSPI_DATARATE_SDR | Single data rate.
|
CYHAL_QSPI_DATARATE_DDR | Double data rate.
|
◆ cyhal_qspi_init()
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
- 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] | sclk | The clock pin |
[in] | pin_set | Set of pins, that will primarily be used for communication with memory. Depends on device, QSPI HAL can service multiple memories which can be registered and controlled using cyhal_qspi_slave_configure and cyhal_qspi_select_active_ssel functions. There is no need to call cyhal_qspi_select_active_ssel after this function - provided ssel pin as part of pin_set parameter become active. |
[in] | hz | The bus frequency |
[in] | mode | Clock polarity and phase mode (0 - 3) |
[in] | clk | The clock to use can be shared, if not provided a new clock will be allocated |
- Note
- QSPI HAL cannot make changes into provided clock configuration. In this case cyhal_qspi_set_frequency function cannot be used and will return error once called. With provided clock only user application can configure QSPI bus frequency by configuring parameters of shared clock.
- Returns
- The status of the init request
◆ cyhal_qspi_init_cfg()
Initialize the QSPI peripheral using a configurator generated configuration struct.
This function may not support all features, that can be configured via configurator. For limitations list please refer to Configurator-generated features limitations section.
- Parameters
-
[in] | obj | The QSPI peripheral to configure |
[in] | cfg | Configuration structure generated by a configurator. |
- Returns
- The status of the operation
◆ cyhal_qspi_free()
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
-
◆ cyhal_qspi_set_frequency()
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.
- Parameters
-
[in] | obj | The QSPI object to configure |
[in] | hz | The baud rate in Hz |
- Returns
- The status of the set_frequency request
◆ cyhal_qspi_get_frequency()
Get the actual frequency that QSPI is configured for.
- Parameters
-
- Returns
- Frequency in Hz
◆ cyhal_qspi_slave_configure()
Configure provided set of pins to service additional slave memory.
Multiple pins can be configured as QSPI slave select pins as well as IO pins may be (or may not be) shared and used to service multiple connected slave memories. This function can be called multiple times - each call for each additional slave memory. 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. Please refer to Code Snippet 5: Configuring multiple memories for example of configuration multiple memory devices and switching between them.
- Note
- Provided IO pins can overlap with those, that are configured in scope of cyhal_qspi_init function.
- Parameters
-
[in] | obj | The QSPI object to configure |
[in] | pin_set | Set of pins, that will be used to service additional slave memory. |
- Returns
- The status of pin configuration
◆ cyhal_qspi_select_active_ssel()
Selects an active slave select (SSEL) line from one of available and previously configured.
Slave memories (in addition to one, that was configured in scope of cyhal_qspi_init) can be added with help of cyhal_qspi_slave_configure function.
- Parameters
-
[in] | obj | The QSPI object to configure |
[in] | ssel | SSEL pin to be set as active |
- Returns
- CY_RSLT_SUCCESS if slave select was switched successfully, otherwise - CYHAL_QSPI_RSLT_ERR_CANNOT_SWITCH_SSEL
◆ cyhal_qspi_read()
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.
- Parameters
-
[in] | obj | QSPI object |
[in] | command | QSPI command |
[in] | address | Address to access to |
[out] | data | RX buffer |
[in] | length | RX buffer length in bytes |
- Returns
- The status of the read request
◆ cyhal_qspi_read_async()
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.
- Parameters
-
[in] | obj | QSPI object |
[in] | command | QSPI command |
[in] | address | Address to access to |
[out] | data | RX buffer |
[in] | length | RX buffer length in bytes |
- Returns
- The status of the read request
◆ cyhal_qspi_write()
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.
- Parameters
-
[in] | obj | QSPI object |
[in] | command | QSPI command |
[in] | address | Address to access to |
[in] | data | TX buffer |
[in] | length | TX buffer length in bytes |
- Returns
- The status of the write request
◆ cyhal_qspi_write_async()
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.
- Parameters
-
[in] | obj | QSPI object |
[in] | command | QSPI command |
[in] | address | Address to access to |
[in] | data | TX buffer |
[in] | length | TX buffer length in bytes |
- Returns
- The status of the write request
◆ cyhal_qspi_transfer()
Send a command (and optionally data) and get the response.
Can be used to send/receive device specific commands
- Parameters
-
[in] | obj | QSPI object |
[in] | command | QSPI command |
[in] | address | Address to access to |
[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 |
- Returns
- The status of the transfer request
◆ cyhal_qspi_register_callback()
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 |
◆ cyhal_qspi_enable_event()
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 |
◆ cyhal_qspi_is_busy()
Checks if the specified QSPI peripheral is in use.
- Parameters
-
[in] | obj | The QSPI peripheral to check |
- Returns
- Indication of whether the QSPI is still transmitting
◆ cyhal_qspi_is_pending()
Checks if an async read operation is pending.
- Parameters
-
[in] | obj | The QSPI peripheral to check |
- Returns
- Indication of whether a QSPI async operation is pending