High level interface for interacting with the Serial Peripheral Interface (SPI).
The SPI protocol is a synchronous serial interface protocol. Devices operate in either master or slave mode. The master initiates the data transfer.
Motorola SPI modes 0, 1, 2, and 3 are supported, with either MSB or LSB first. The operating mode and data frame size can be configured via cyhal_spi_cfg_t.
Features
- Supports master and slave functionality.
- Supports Motorola modes - 0, 1, 2 and 3 - cyhal_spi_mode_t
- MSb or LSb first shift direction - cyhal_spi_mode_t
- Master supports up to four slave select lines
- Supports data frame size of 8 or 16 bits
- Configurable interrupt and callback assignment on SPI events: Data transfer to FIFO complete, Transfer complete and Transmission error - cyhal_spi_event_t
- Supports changing baud rate of the transaction in run time.
- Provides functions to send/receive a single byte or block of data.
Quick Start
Initialise a SPI master or slave interface using cyhal_spi_init() and provide the SPI pins (mosi, miso, sclk, ssel), number of bits per frame (data_bits) and SPI Motorola mode. The data rate can be set using cyhal_spi_set_frequency().
See Code snippets for code snippets to send or receive the data.
Code snippets
Snippet 1: SPI Master - Single byte transfer operation (Read and Write)
The following code snippet initializes an SPI Master interface using the cyhal_spi_init(). The data rate of transfer is set using cyhal_spi_set_frequency(). The code snippet shows how to transfer a single byte of data using cyhal_spi_send() and cyhal_spi_recv().
uint32_t spi_master_frequency = 1000000;
uint32_t transmit_data = 0x01;
uint32_t receive_data;
rslt =
cyhal_spi_init(&mSPI, CYBSP_SPI_MOSI, CYBSP_SPI_MISO, CYBSP_SPI_CLK, CYBSP_SPI_CS, NULL,
{
{
}
}
Snippet 2: SPI Slave - Single byte transfer operation (Read and Write)
The following code snippet initializes an SPI Slave interface using the cyhal_spi_init(). The data rate of transfer is set using cyhal_spi_set_frequency. The code snippet shows how to transfer a single byte of data using cyhal_spi_send() and cyhal_spi_recv.
uint32_t spi_slave_frequency = 1000000;
uint32_t transmit_data = 1;
uint32_t receive_data;
rslt =
cyhal_spi_init(&sSPI, CYBSP_SPI_MOSI, CYBSP_SPI_MISO, CYBSP_SPI_CLK, CYBSP_SPI_CS, NULL,
{
{
}
}
Snippet 3: SPI Block Data transfer
The following snippet sends and receives an array of data in a single SPI transaction using cyhal_spi_transfer(). The example uses SPI master to transmit 5 bytes of data and receive 5 bytes of data in a single transaction.
uint32_t spi_frequency = 1000000;
uint8_t transmit_data[5] = { 0x1, 0x2, 0x3, 0x4, 0x5 };
uint8_t receive_data[5];
memset(&mSPI, 0, sizeof(mSPI));
rslt =
cyhal_spi_init(&mSPI, CYBSP_SPI_MOSI, CYBSP_SPI_MISO, CYBSP_SPI_CLK, CYBSP_SPI_CS, NULL,
{
}
Snippet 4: Interrupts on SPI events
SPI interrupt events ( cyhal_spi_event_t) can be mapped to an interrupt and assigned to a callback function. The callback function needs to be first registered and then the event needs to be enabled. The following snippet initialises a SPI master to perform a block transfer using cyhal_spi_transfer_async(). This is a non-blocking function. A callback function is registered using cyhal_spi_register_callback to notify whenever the SPI transfer is complete.
{
(void)arg;
{
}
}
cy_rslt_t snippet_cyhal_interrupt_callback_events(
void)
{
uint32_t spi_frequency = 1000000;
uint32_t rx_transfer_count = 5, tx_transfer_count = 5;
uint8_t receive_data[5];
uint8_t transmit_data[5] = { 0x1, 0x2, 0x3, 0x4, 0x5 };
rslt =
cyhal_spi_init(&mSPI, CYBSP_SPI_MOSI, CYBSP_SPI_MISO, CYBSP_SPI_CLK, CYBSP_SPI_CS, NULL,
{
}
{
NULL);
tx_transfer_count))
{
}
}
return rslt;
}
More Information
- mtb-example-psoc6-spi-master: This example project demonstrates use of SPI (HAL) resource in PSoCĀ® 6 MCU in Master mode to write data to an SPI slave.
|
enum | cyhal_spi_event_t {
CYHAL_SPI_IRQ_DATA_IN_FIFO = 1 << 1,
CYHAL_SPI_IRQ_DONE = 1 << 2,
CYHAL_SPI_IRQ_ERROR = 1 << 3
} |
| SPI interrupt triggers. More...
|
|
enum | cyhal_spi_ssel_polarity_t {
CYHAL_SPI_SSEL_ACTIVE_LOW = 0,
CYHAL_SPI_SSEL_ACTIVE_HIGH = 1
} |
| SPI Slave Select polarity. More...
|
|
enum | cyhal_spi_mode_t {
CYHAL_SPI_MODE_00_MSB = CYHAL_SPI_MODE(0, 0, 0),
CYHAL_SPI_MODE_00_LSB = CYHAL_SPI_MODE(0, 0, 1),
CYHAL_SPI_MODE_01_MSB = CYHAL_SPI_MODE(0, 1, 0),
CYHAL_SPI_MODE_01_LSB = CYHAL_SPI_MODE(0, 1, 1),
CYHAL_SPI_MODE_10_MSB = CYHAL_SPI_MODE(1, 0, 0),
CYHAL_SPI_MODE_10_LSB = CYHAL_SPI_MODE(1, 0, 1),
CYHAL_SPI_MODE_11_MSB = CYHAL_SPI_MODE(1, 1, 0),
CYHAL_SPI_MODE_11_LSB = CYHAL_SPI_MODE(1, 1, 1)
} |
| SPI operating modes. More...
|
|
enum | cyhal_spi_fifo_type_t {
CYHAL_SPI_FIFO_RX,
CYHAL_SPI_FIFO_TX
} |
| SPI FIFO type. More...
|
|
enum | cyhal_spi_output_t {
CYHAL_SPI_OUTPUT_TRIGGER_RX_FIFO_LEVEL_REACHED,
CYHAL_SPI_OUTPUT_TRIGGER_TX_FIFO_LEVEL_REACHED
} |
| Enum of possible output signals from an SPI. More...
|
|
|
cy_rslt_t | cyhal_spi_init (cyhal_spi_t *obj, cyhal_gpio_t mosi, cyhal_gpio_t miso, cyhal_gpio_t sclk, cyhal_gpio_t ssel, const cyhal_clock_t *clk, uint8_t bits, cyhal_spi_mode_t mode, bool is_slave) |
| Initialize the SPI peripheral. More...
|
|
void | cyhal_spi_free (cyhal_spi_t *obj) |
| Release a SPI object. More...
|
|
cy_rslt_t | cyhal_spi_set_frequency (cyhal_spi_t *obj, uint32_t hz) |
| Set the SPI baud rate. More...
|
|
cy_rslt_t | cyhal_spi_slave_select_config (cyhal_spi_t *obj, cyhal_gpio_t ssel, cyhal_spi_ssel_polarity_t polarity) |
| Configures provided ssel pin to work as SPI slave select with specified polarity. More...
|
|
cy_rslt_t | cyhal_spi_select_active_ssel (cyhal_spi_t *obj, cyhal_gpio_t ssel) |
| Selects an active slave select line from one of available. More...
|
|
cy_rslt_t | cyhal_spi_recv (cyhal_spi_t *obj, uint32_t *value) |
| Synchronously get a received value out of the SPI receive buffer. More...
|
|
cy_rslt_t | cyhal_spi_send (cyhal_spi_t *obj, uint32_t value) |
| Synchronously send a byte out. More...
|
|
cy_rslt_t | cyhal_spi_transfer (cyhal_spi_t *obj, const uint8_t *tx, size_t tx_length, uint8_t *rx, size_t rx_length, uint8_t write_fill) |
| Synchronously Write a block out and receive a value. More...
|
|
cy_rslt_t | cyhal_spi_transfer_async (cyhal_spi_t *obj, const uint8_t *tx, size_t tx_length, uint8_t *rx, size_t rx_length) |
| Start an asynchronous SPI transfer. More...
|
|
bool | cyhal_spi_is_busy (cyhal_spi_t *obj) |
| Checks if the specified SPI peripheral is in use. More...
|
|
cy_rslt_t | cyhal_spi_abort_async (cyhal_spi_t *obj) |
| Abort an SPI transfer. More...
|
|
void | cyhal_spi_register_callback (cyhal_spi_t *obj, cyhal_spi_event_callback_t callback, void *callback_arg) |
| Register a SPI callback handler. More...
|
|
void | cyhal_spi_enable_event (cyhal_spi_t *obj, cyhal_spi_event_t event, uint8_t intr_priority, bool enable) |
| Configure SPI interrupt. More...
|
|
cy_rslt_t | cyhal_spi_set_fifo_level (cyhal_spi_t *obj, cyhal_spi_fifo_type_t type, uint16_t level) |
| Sets a threshold level for a FIFO that will generate an interrupt and a trigger output. More...
|
|
cy_rslt_t | cyhal_spi_enable_output (cyhal_spi_t *obj, cyhal_spi_output_t output, cyhal_source_t *source) |
| Enables the specified output signal from an SPI. More...
|
|
cy_rslt_t | cyhal_spi_disable_output (cyhal_spi_t *obj, cyhal_spi_output_t output) |
| Disables the specified output signal from an SPI. More...
|
|
cy_rslt_t | cyhal_spi_init_cfg (cyhal_spi_t *obj, const cyhal_spi_configurator_t *cfg) |
| Initialize the SPI peripheral using a configurator generated configuration struct. More...
|
|
◆ cyhal_spi_cfg_t
Data Fields |
cyhal_spi_mode_t |
mode |
The operating mode. |
uint8_t |
data_bits |
The number of bits per transfer. |
bool |
is_slave |
Whether the peripheral is operating as slave or master. |
◆ cyhal_spi_frequency
Compatibility define for cyhal_spi_set_frequency.
◆ CYHAL_SPI_MODE_FLAG_LSB
#define CYHAL_SPI_MODE_FLAG_LSB (0x01u) |
◆ CYHAL_SPI_MODE_FLAG_CPHA
#define CYHAL_SPI_MODE_FLAG_CPHA (0x02u) |
◆ CYHAL_SPI_MODE_FLAG_CPOL
#define CYHAL_SPI_MODE_FLAG_CPOL (0x04u) |
◆ CYHAL_SPI_MODE
#define CYHAL_SPI_MODE |
( |
|
cpol, |
|
|
|
cpha, |
|
|
|
lsb |
|
) |
| |
Value:#define CYHAL_SPI_MODE_FLAG_CPHA
Flag for SPI cyhal_spi_mode_t values indicating that the CPHA=1.
Definition: cyhal_spi.h:169
#define CYHAL_SPI_MODE_FLAG_CPOL
Flag for SPI cyhal_spi_mode_t values indicating that the CPOL=1.
Definition: cyhal_spi.h:171
#define CYHAL_SPI_MODE_FLAG_LSB
Flag for SPI cyhal_spi_mode_t values indicating that the LSB is sent first.
Definition: cyhal_spi.h:167
Creates a cyhal_spi_mode_t value given the cpol, cpha, lsb values.
◆ cyhal_spi_event_t
SPI interrupt triggers.
Enumerator |
---|
CYHAL_SPI_IRQ_DATA_IN_FIFO | All transfer data has been moved into data FIFO.
|
CYHAL_SPI_IRQ_DONE | Transfer complete.
|
CYHAL_SPI_IRQ_ERROR | An error occurred while transferring data.
|
◆ cyhal_spi_ssel_polarity_t
SPI Slave Select polarity.
Enumerator |
---|
CYHAL_SPI_SSEL_ACTIVE_LOW | SSEL signal is active low.
|
CYHAL_SPI_SSEL_ACTIVE_HIGH | SSEL signal is active high.
|
◆ cyhal_spi_mode_t
SPI operating modes.
Enumerator |
---|
CYHAL_SPI_MODE_00_MSB | Standard motorola SPI CPOL=0, CPHA=0 with MSB first operation.
|
CYHAL_SPI_MODE_00_LSB | Standard motorola SPI CPOL=0, CPHA=0 with LSB first operation.
|
CYHAL_SPI_MODE_01_MSB | Standard motorola SPI CPOL=0, CPHA=1 with MSB first operation.
|
CYHAL_SPI_MODE_01_LSB | Standard motorola SPI CPOL=0, CPHA=1 with LSB first operation.
|
CYHAL_SPI_MODE_10_MSB | Standard motorola SPI CPOL=1, CPHA=0 with MSB first operation.
|
CYHAL_SPI_MODE_10_LSB | Standard motorola SPI CPOL=1, CPHA=0 with LSB first operation.
|
CYHAL_SPI_MODE_11_MSB | Standard motorola SPI CPOL=1, CPHA=1 with MSB first operation.
|
CYHAL_SPI_MODE_11_LSB | Standard motorola SPI CPOL=1, CPHA=1 with LSB first operation.
|
◆ cyhal_spi_fifo_type_t
SPI FIFO type.
Enumerator |
---|
CYHAL_SPI_FIFO_RX | Set RX FIFO level.
|
CYHAL_SPI_FIFO_TX | Set TX FIFO level.
|
◆ cyhal_spi_output_t
Enum of possible output signals from an SPI.
Enumerator |
---|
CYHAL_SPI_OUTPUT_TRIGGER_RX_FIFO_LEVEL_REACHED | Output the RX FIFO signal which is triggered when the receive FIFO has more entries than the configured level.
|
CYHAL_SPI_OUTPUT_TRIGGER_TX_FIFO_LEVEL_REACHED | Output the TX FIFO signal which is triggered when the transmit FIFO has less entries than the configured level.
|
◆ cyhal_spi_init()
Initialize the SPI peripheral.
Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral. Depending on the configuration, some pins may not be needed. Master mode: MOSI used, MISO unused: SCLK & SSEL are both optional Master mode: MISO used, MOSI unused: SCLK is mandatory, SSEL is optional Slave mode: MOSI or MISO are used: SCLK & SSEL are both mandatory
- Parameters
-
[out] | obj | Pointer to a SPI object. The caller must allocate the memory for this object but the init function will initialize its contents. |
[in] | mosi | The pin to use for MOSI |
- Note
- At least MOSI or MISO pin should be non-NC
- Parameters
-
[in] | miso | The pin to use for MISO |
- Note
- At least MOSI or MISO pin should be non-NC
- Parameters
-
[in] | sclk | The pin to use for SCLK |
- Note
- This pin can be NC if in master mode with only MOSI used
- Parameters
-
[in] | ssel | The pin to use for SSEL |
- Note
- Provided pin will be configured for CYHAL_SPI_SSEL_ACTIVE_LOW polarity and set as active. This can be changed (as well as additional ssel pins can be added) by cyhal_spi_slave_select_config and cyhal_spi_select_active_ssel functions. This pin can be NC.
- Parameters
-
[in] | clk | The clock to use can be shared, if not provided a new clock will be allocated |
[in] | bits | The number of bits per frame |
- Note
- bits should be 8 or 16
- Parameters
-
[in] | mode | The SPI mode (clock polarity, phase, and shift direction) |
[in] | is_slave | false for master mode or true for slave mode operation |
- Returns
- The status of the init request
◆ cyhal_spi_free()
Release a SPI object.
Return the peripheral, pins and clock owned by the SPI object to their reset state
- Parameters
-
[in,out] | obj | The SPI object to deinitialize |
◆ cyhal_spi_set_frequency()
Set the SPI baud rate.
Actual frequency may differ from the desired frequency due to available dividers and bus clock Configures the SPI peripheral's baud rate
- Parameters
-
[in,out] | obj | The SPI object to configure |
[in] | hz | The baud rate in Hz |
- Returns
- The status of the set_frequency request
◆ cyhal_spi_slave_select_config()
Configures provided ssel pin to work as SPI slave select with specified polarity.
Multiple pins can be configured as SPI slave select pins. Please refer to device datasheet for details. Switching between configured slave select pins is done by cyhal_spi_select_active_ssel function. Unless modified with this function, the SSEL pin provided as part of cyhal_spi_init is the default.
- Parameters
-
[in] | obj | The SPI object to add slave select for |
[in] | ssel | Slave select pin to be added |
[in] | polarity | Polarity of slave select |
- Returns
- The status of ssel pin configuration
◆ cyhal_spi_select_active_ssel()
Selects an active slave select line from one of available.
This function is applicable for the master and slave. SSEL pin should be configured by cyhal_spi_slave_select_config or cyhal_spi_init functions prior to selecting it as active. The active slave select line will automatically be toggled as part of any transfer.
- Parameters
-
[in] | obj | The SPI object for switching |
[in] | ssel | Slave select pin to be set as active |
- Returns
- CY_RSLT_SUCCESS if slave select was switched successfully, otherwise - CYHAL_SPI_RSLT_ERR_CANNOT_SWITCH_SSEL
◆ cyhal_spi_recv()
Synchronously get a received value out of the SPI receive buffer.
In Master mode - transmits fill-in value and read the data from RxFifo In Slave mode - Blocks until a value is available
- Parameters
-
[in] | obj | The SPI peripheral to read |
[in] | value | The value received |
- Returns
- The status of the read request
- Note
- In Master mode, MISO pin required to be non-NC for this API to operate
- In Slave mode, MOSI pin required to be non-NC for this API to operate
◆ cyhal_spi_send()
Synchronously send a byte out.
In Master mode transmits value to slave and read/drop a value from the RxFifo. In Slave mode writes a value to TxFifo
- Parameters
-
[in] | obj | The SPI peripheral to use for sending |
[in] | value | The value to send |
- Returns
- The status of the write request
- Note
- In Master mode, MOSI pin required to be non-NC for this API to operate
- In Slave mode, MISO pin required to be non-NC for this API to operate
◆ cyhal_spi_transfer()
cy_rslt_t cyhal_spi_transfer |
( |
cyhal_spi_t * |
obj, |
|
|
const uint8_t * |
tx, |
|
|
size_t |
tx_length, |
|
|
uint8_t * |
rx, |
|
|
size_t |
rx_length, |
|
|
uint8_t |
write_fill |
|
) |
| |
Synchronously Write a block out and receive a value.
The total number of bytes sent and received will be the maximum of tx_length and rx_length. The bytes written will be padded (at the end) with the value given by write_fill.
This function will block for the duration of the transfer. cyhal_spi_transfer_async can be used for non-blocking transfers.
- Parameters
-
[in] | obj | The SPI peripheral to use for sending |
[in] | tx | Pointer to the byte-array of data to write to the device |
[in,out] | tx_length | Number of bytes to write, updated with the number actually written |
[out] | rx | Pointer to the byte-array of data to read from the device |
[in,out] | rx_length | Number of bytes to read, updated with the number actually read |
[in] | write_fill | Default data transmitted while performing a read |
- Returns
- The status of the transfer request
- Note
- Both MOSI and MISO pins required to be non-NC for this API to operate
◆ cyhal_spi_transfer_async()
cy_rslt_t cyhal_spi_transfer_async |
( |
cyhal_spi_t * |
obj, |
|
|
const uint8_t * |
tx, |
|
|
size_t |
tx_length, |
|
|
uint8_t * |
rx, |
|
|
size_t |
rx_length |
|
) |
| |
Start an asynchronous SPI transfer.
This will transfer rx_length
bytes into the buffer pointed to by rx
, while simultaneously transfering tx_length
bytes of data from the buffer pointed to by tx
, both in the background. When the transfer is complete, the CYHAL_SPI_IRQ_DONE event will be raised. See cyhal_spi_register_callback and cyhal_spi_enable_event.
- Note
- For blocking transfers cyhal_spi_transfer can be used.
- Parameters
-
[in] | obj | The SPI object that holds the transfer information |
[in] | tx | The transmit buffer |
[in,out] | tx_length | The number of bytes to transmit |
[out] | rx | The receive buffer |
[in,out] | rx_length | The number of bytes to receive |
- Returns
- The status of the transfer_async request
- Note
- Both MOSI and MISO pins required to be non-NC for this API to operate
◆ cyhal_spi_is_busy()
Checks if the specified SPI peripheral is in use.
- Parameters
-
[in] | obj | The SPI peripheral to check |
- Returns
- Indication of whether the SPI is still transmitting
◆ cyhal_spi_abort_async()
Abort an SPI transfer.
- Parameters
-
[in] | obj | The SPI peripheral to stop |
- Returns
- The status of the abort_async request
◆ cyhal_spi_register_callback()
Register a SPI callback handler.
This function will be called when one of the events enabled by cyhal_spi_enable_event occurs.
- Parameters
-
[in] | obj | The SPI 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 callback when called |
◆ cyhal_spi_enable_event()
Configure SPI interrupt.
This function is used for word-approach
When an enabled event occurs, the function specified by cyhal_spi_register_callback will be called.
- Parameters
-
[in] | obj | The SPI object |
[in] | event | The SPI event type |
[in] | intr_priority | The priority for NVIC interrupt events |
[in] | enable | True to turn on interrupts, False to turn off |
◆ cyhal_spi_set_fifo_level()
Sets a threshold level for a FIFO that will generate an interrupt and a trigger output.
The RX FIFO interrupt and trigger will be activated when the receive FIFO has more entries than the threshold. The TX FIFO interrupt and trigger will be activated when the transmit FIFO has less entries than the threshold.
- Parameters
-
[in] | obj | The SPI object |
[in] | type | FIFO type to set level for |
[in] | level | Level threshold to set |
- Returns
- The status of the level set
◆ cyhal_spi_enable_output()
Enables the specified output signal from an SPI.
- Parameters
-
[in] | obj | The SPI object |
[in] | output | Which output signal to enable |
[out] | source | Pointer to user-allocated source signal object which will be initialized by enable_output. source should be passed to (dis)connect_digital functions to (dis)connect the associated endpoints. |
- Returns
- The status of the output enable
◆ cyhal_spi_disable_output()
Disables the specified output signal from an SPI.
- Parameters
-
[in] | obj | The SPI object |
[in] | output | Which output signal to disable |
- Returns
- The status of the output disable
◆ cyhal_spi_init_cfg()
Initialize the SPI peripheral using a configurator generated configuration struct.
- Parameters
-
[in] | obj | The SPI peripheral to configure |
[in] | cfg | Configuration structure generated by a configurator. |
- Returns
- The status of the operation