1 /***************************************************************************//**
2 * \file cyhal_spi.h
3 *
4 * \brief
5 * Provides a high level interface for interacting with the Infineon SPI.
6 * This interface abstracts out the chip specific details. If any chip specific
7 * functionality is necessary, or performance is critical the low level functions
8 * can be used directly.
9 *
10 ********************************************************************************
11 * \copyright
12 * Copyright 2018-2022 Cypress Semiconductor Corporation (an Infineon company) or
13 * an affiliate of Cypress Semiconductor Corporation
14 *
15 * SPDX-License-Identifier: Apache-2.0
16 *
17 * Licensed under the Apache License, Version 2.0 (the "License");
18 * you may not use this file except in compliance with the License.
19 * You may obtain a copy of the License at
20 *
21 *     http://www.apache.org/licenses/LICENSE-2.0
22 *
23 * Unless required by applicable law or agreed to in writing, software
24 * distributed under the License is distributed on an "AS IS" BASIS,
25 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26 * See the License for the specific language governing permissions and
27 * limitations under the License.
28 *******************************************************************************/
29 
30 /**
31 * \addtogroup group_hal_spi SPI (Serial Peripheral Interface)
32 * \ingroup group_hal
33 * \{
34 * High level interface for interacting with the Serial Peripheral Interface (SPI).
35 *
36 * The SPI protocol is a synchronous serial interface protocol. Devices operate
37 * in either master or slave mode. The master initiates the data transfer.
38 *
39 * Motorola SPI modes 0, 1, 2, and 3 are supported, with either MSB or LSB first.
40 * The operating mode and data frame size can be configured via \ref cyhal_spi_cfg_t.
41 *
42 * \section section_spi_features Features
43 * * Supports master and slave functionality.
44 * * Supports Motorola modes - 0, 1, 2 and 3 - \ref cyhal_spi_mode_t
45 * * MSb or LSb first shift direction - \ref cyhal_spi_mode_t
46 * * Master supports up to four slave select lines
47 * * Supports data frame size of 8 or 16 bits
48 * * Configurable interrupt and callback assignment on SPI events:
49 * Data transfer to FIFO complete, Transfer complete and Transmission error - \ref cyhal_spi_event_t
50 * * Supports changing baud rate of the transaction in run time.
51 * * Provides functions to send/receive a single byte or block of data.
52 *
53 * \section section_spi_quickstart Quick Start
54 *
55 * Initialise a SPI master or slave interface using \ref cyhal_spi_init() and provide the SPI pins (<b>mosi</b>, <b>miso</b>, <b>sclk</b>, <b>ssel</b>),
56 * number of bits per frame (<b>data_bits</b>) and SPI Motorola <b>mode</b>. The data rate can be set using \ref cyhal_spi_set_frequency(). <br>
57 * See \ref section_spi_snippets for code snippets to send or receive the data.
58 *
59 * \section section_spi_snippets Code snippets
60 *
61 * \subsection subsection_spi_snippet_1 Snippet 1: SPI Master - Single byte transfer operation (Read and Write)
62 * The following code snippet initializes an SPI Master interface using the \ref cyhal_spi_init(). The data rate of transfer is set using \ref cyhal_spi_set_frequency().
63 * The code snippet shows how to transfer a single byte of data using \ref cyhal_spi_send() and \ref cyhal_spi_recv().
64 * \snippet hal_spi.c snippet_cyhal_spi_master_byte_operation
65 *
66 * \subsection subsection_spi_snippet_2 Snippet 2: SPI Slave - Single byte transfer operation (Read and Write)
67 * The following code snippet initializes an SPI Slave interface using the \ref cyhal_spi_init(). The data rate of transfer is set using \ref cyhal_spi_set_frequency.
68 * The code snippet shows how to transfer a single byte of data using \ref cyhal_spi_send() and \ref cyhal_spi_recv.
69 * \snippet hal_spi.c snippet_cyhal_spi_slave_byte_operation
70 *
71 * \subsection subsection_spi_snippet_3 Snippet 3: SPI Block Data transfer
72 * The following snippet sends and receives an array of data in a single SPI transaction using \ref cyhal_spi_transfer(). The example
73 * uses SPI master to transmit 5 bytes of data and receive 5 bytes of data in a single transaction.
74 * \snippet hal_spi.c snippet_cyhal_spi_block_data_transfer
75 *
76 * \subsection subsection_spi_snippet_4 Snippet 4: Interrupts on SPI events
77 * SPI interrupt events ( \ref cyhal_spi_event_t) can be mapped to an interrupt and assigned to a callback function.
78 * The callback function needs to be first registered and then the event needs to be enabled.
79 * The following snippet initialises a SPI master to perform a block transfer using \ref cyhal_spi_transfer_async(). This is a non-blocking function.
80 *  A callback function is registered using \ref cyhal_spi_register_callback to notify whenever the SPI transfer is complete.
81 * \snippet hal_spi.c snippet_cyhal_spi_interrupt_callback_events
82 
83 * \section subsection_spi_moreinfor More Information
84 *
85 * * <a href="https://github.com/infineon/mtb-example-psoc6-spi-master"><b>mtb-example-psoc6-spi-master</b></a>: This example project demonstrates
86 * use of SPI (HAL) resource in PSoC® 6 MCU in Master mode to write data to an SPI slave.
87 *
88 */
89 
90 #pragma once
91 
92 #include <stdint.h>
93 #include <stdbool.h>
94 #include "cy_result.h"
95 #include "cyhal_hw_types.h"
96 
97 #if defined(__cplusplus)
98 extern "C" {
99 #endif
100 
101 /** \addtogroup group_hal_results_spi SPI HAL Results
102  *  SPI specific return codes
103  *  \ingroup group_hal_results
104  *  \{ *//**
105  */
106 
107 /** Bad argument */
108 #define CYHAL_SPI_RSLT_BAD_ARGUMENT                     \
109     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SPI, 0))
110 /** Failed to initialize SPI clock or can't make changes in user-provided clock */
111 #define CYHAL_SPI_RSLT_CLOCK_ERROR                      \
112     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SPI, 1))
113 /** Failed to Transfer SPI data */
114 #define CYHAL_SPI_RSLT_TRANSFER_ERROR                   \
115     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SPI, 2))
116 /** Provided clock is not supported by SPI */
117 #define CYHAL_SPI_RSLT_CLOCK_NOT_SUPPORTED              \
118     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SPI, 3))
119 /** Provided PIN configuration is not supported by SPI */
120 #define CYHAL_SPI_RSLT_PIN_CONFIG_NOT_SUPPORTED         \
121     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SPI, 5))
122 /** Provided PIN configuration is not supported by SPI */
123 #define CYHAL_SPI_RSLT_INVALID_PIN_API_NOT_SUPPORTED    \
124     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SPI, 6))
125 /** The requested resource type is invalid */
126 #define CYHAL_SPI_RSLT_ERR_INVALID_PIN                  \
127     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SPI, 7))
128 /** Cannot configure SSEL signal */
129 #define CYHAL_SPI_RSLT_ERR_CANNOT_CONFIG_SSEL           \
130     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SPI, 8))
131 /** Cannot switch SSEL - device is busy or incorrect pin provided */
132 #define CYHAL_SPI_RSLT_ERR_CANNOT_SWITCH_SSEL           \
133     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SPI, 9))
134 /** Provided configuration is not supported */
135 #define CYHAL_SPI_RSLT_ERR_CFG_NOT_SUPPORTED            \
136     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SPI, 10))
137 /** Unsupported by this device */
138 #define CYHAL_SPI_RSLT_ERR_UNSUPPORTED                  \
139     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SPI, 11))
140 
141 /** Timeout warning */
142 #define CYHAL_SPI_RSLT_WARN_TIMEOUT                     \
143     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_WARNING, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_SPI, 20))
144 
145 /**
146  * \}
147  */
148 
149 /** Compatibility define for cyhal_spi_set_frequency. */
150 #define cyhal_spi_frequency cyhal_spi_set_frequency
151 
152 /** SPI interrupt triggers */
153 typedef enum {
154     /** All transfer data has been moved into data FIFO */
155     CYHAL_SPI_IRQ_DATA_IN_FIFO        = 1 << 1,
156     /** Transfer complete. */
157     CYHAL_SPI_IRQ_DONE                = 1 << 2,
158     /** An error occurred while transferring data */
159     CYHAL_SPI_IRQ_ERROR               = 1 << 3,
160 } cyhal_spi_event_t;
161 
162 /** SPI Slave Select polarity */
163 typedef enum {
164     /** SSEL signal is active low */
165     CYHAL_SPI_SSEL_ACTIVE_LOW         = 0,
166     /** SSEL signal is active high */
167     CYHAL_SPI_SSEL_ACTIVE_HIGH        = 1,
168 } cyhal_spi_ssel_polarity_t;
169 
170 /** Handler for SPI interrupts */
171 typedef void (*cyhal_spi_event_callback_t)(void *callback_arg, cyhal_spi_event_t event);
172 
173 /** Flag for SPI \ref cyhal_spi_mode_t values indicating that the LSB is sent first. */
174 #define CYHAL_SPI_MODE_FLAG_LSB             (0x01u)
175 /** Flag for SPI \ref cyhal_spi_mode_t values indicating that the CPHA=1. */
176 #define CYHAL_SPI_MODE_FLAG_CPHA            (0x02u)
177 /** Flag for SPI \ref cyhal_spi_mode_t values indicating that the CPOL=1. */
178 #define CYHAL_SPI_MODE_FLAG_CPOL            (0x04u)
179 /** Creates a \ref cyhal_spi_mode_t value given the cpol, cpha, lsb values. */
180 #define CYHAL_SPI_MODE(cpol, cpha, lsb)     ((((cpol) > 0) ? CYHAL_SPI_MODE_FLAG_CPOL : 0) | \
181                                              (((cpha) > 0) ? CYHAL_SPI_MODE_FLAG_CPHA : 0) | \
182                                               (((lsb) > 0) ? CYHAL_SPI_MODE_FLAG_LSB  : 0))
183 
184 /** SPI operating modes */
185 typedef enum
186 {
187     /** Standard motorola SPI CPOL=0, CPHA=0 with MSB first operation */
188     CYHAL_SPI_MODE_00_MSB = CYHAL_SPI_MODE(0, 0, 0),
189     /** Standard motorola SPI CPOL=0, CPHA=0 with LSB first operation */
190     CYHAL_SPI_MODE_00_LSB = CYHAL_SPI_MODE(0, 0, 1),
191     /** Standard motorola SPI CPOL=0, CPHA=1 with MSB first operation */
192     CYHAL_SPI_MODE_01_MSB = CYHAL_SPI_MODE(0, 1, 0),
193     /** Standard motorola SPI CPOL=0, CPHA=1 with LSB first operation */
194     CYHAL_SPI_MODE_01_LSB = CYHAL_SPI_MODE(0, 1, 1),
195     /** Standard motorola SPI CPOL=1, CPHA=0 with MSB first operation */
196     CYHAL_SPI_MODE_10_MSB = CYHAL_SPI_MODE(1, 0, 0),
197     /** Standard motorola SPI CPOL=1, CPHA=0 with LSB first operation */
198     CYHAL_SPI_MODE_10_LSB = CYHAL_SPI_MODE(1, 0, 1),
199     /** Standard motorola SPI CPOL=1, CPHA=1 with MSB first operation */
200     CYHAL_SPI_MODE_11_MSB = CYHAL_SPI_MODE(1, 1, 0),
201     /** Standard motorola SPI CPOL=1, CPHA=1 with LSB first operation */
202     CYHAL_SPI_MODE_11_LSB = CYHAL_SPI_MODE(1, 1, 1),
203 } cyhal_spi_mode_t;
204 
205 /** SPI FIFO type */
206 typedef enum
207 {
208     CYHAL_SPI_FIFO_RX, //!< Set RX FIFO level
209     CYHAL_SPI_FIFO_TX, //!< Set TX FIFO level
210 } cyhal_spi_fifo_type_t;
211 
212 /** Enum of possible output signals from an SPI */
213 typedef enum
214 {
215     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.
216     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.
217 } cyhal_spi_output_t;
218 
219 /** @brief Initial SPI configuration. */
220 typedef struct
221 {
222     cyhal_spi_mode_t mode; //!< The operating mode
223     uint8_t data_bits; //!< The number of bits per transfer
224     bool is_slave; //!< Whether the peripheral is operating as slave or master
225 } cyhal_spi_cfg_t;
226 
227 /** Initialize the SPI peripheral.
228  *
229  * Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral.
230  * Depending on the configuration, some pins may not be needed.
231  * Master mode: MOSI used, MISO unused: SCLK & SSEL are both optional
232  * Master mode: MISO used, MOSI unused: SCLK is mandatory, SSEL is optional
233  * Slave  mode: MOSI or MISO are used:  SCLK & SSEL are both mandatory
234  *
235  * @param[out] obj  Pointer to a SPI object. The caller must allocate the memory
236  *  for this object but the init function will initialize its contents.
237  * @param[in]  mosi The pin to use for MOSI
238  * @note At least MOSI or MISO pin should be non-NC
239  * @param[in]  miso The pin to use for MISO
240  * @note At least MOSI or MISO pin should be non-NC
241  * @param[in]  sclk The pin to use for SCLK
242  * @note This pin can be NC if in master mode with only MOSI used
243  * @param[in]  ssel The pin to use for SSEL
244  * @note Provided pin will be configured for \ref CYHAL_SPI_SSEL_ACTIVE_LOW polarity and set as active. This can be changed
245  * (as well as additional ssel pins can be added) by \ref cyhal_spi_slave_select_config and \ref cyhal_spi_select_active_ssel
246  * functions. This pin can be NC.
247  * @param[in]  clk The clock to use can be shared, if not provided a new clock will be allocated
248  * @param[in]  bits      The number of bits per frame
249  * @note \ref section_hal_impl_spi_data_width describes what data width options are supported by certain hardware
250  * @param[in]  mode      The SPI mode (clock polarity, phase, and shift direction)
251  * @param[in]  is_slave  false for master mode or true for slave mode operation
252  * @return The status of the init request
253  */
254 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,
255                          const cyhal_clock_t *clk, uint8_t bits, cyhal_spi_mode_t mode, bool is_slave);
256 
257 /** Release a SPI object
258  *
259  * Return the peripheral, pins and clock owned by the SPI object to their reset state
260  * @param[in,out] obj The SPI object to deinitialize
261  */
262 void cyhal_spi_free(cyhal_spi_t *obj);
263 
264 /** Set the SPI baud rate
265  *
266  * Actual frequency may differ from the desired frequency due to available dividers and bus clock
267  * Configures the SPI peripheral's baud rate
268  * @param[in,out] obj The SPI object to configure
269  * @param[in]     hz  The baud rate in Hz
270  * @return The status of the set_frequency request
271  */
272 cy_rslt_t cyhal_spi_set_frequency(cyhal_spi_t *obj, uint32_t hz);
273 
274 /** Configures provided ssel pin to work as SPI slave select with specified polarity.
275  *
276  * Multiple pins can be configured as SPI slave select pins. Please refer to device datasheet for details. Switching
277  * between configured slave select pins is done by \ref cyhal_spi_select_active_ssel function.
278  * Unless modified with this function, the SSEL pin provided as part of \ref cyhal_spi_init is the default.
279  * @param[in] obj       The SPI object to add slave select for
280  * @param[in] ssel      Slave select pin to be added
281  * @param[in] polarity  Polarity of slave select
282  * @return The status of ssel pin configuration
283  */
284 cy_rslt_t cyhal_spi_slave_select_config(cyhal_spi_t *obj, cyhal_gpio_t ssel, cyhal_spi_ssel_polarity_t polarity);
285 
286 /** Selects an active slave select line from one of available.
287  *
288  * This function is applicable for the master and slave.
289  * SSEL pin should be configured by \ref cyhal_spi_slave_select_config or \ref cyhal_spi_init functions prior
290  * to selecting it as active. The active slave select line will automatically be toggled as part of any transfer.
291  * @param[in] obj       The SPI object for switching
292  * @param[in] ssel      Slave select pin to be set as active
293  * @return CY_RSLT_SUCCESS if slave select was switched successfully, otherwise - CYHAL_SPI_RSLT_ERR_CANNOT_SWITCH_SSEL
294  */
295 cy_rslt_t cyhal_spi_select_active_ssel(cyhal_spi_t *obj, cyhal_gpio_t ssel);
296 
297 /** Synchronously get a received value out of the SPI receive buffer
298  *
299  * In Master mode - transmits fill-in value and read the data from RxFifo
300  * In Slave mode - Blocks until a value is available
301  *
302  * @param[in] obj   The SPI peripheral to read
303  * @param[in] value The value received
304  * @return The status of the read request
305  * @note
306  * - In Master mode, MISO pin required to be non-NC for this API to operate
307  * - In Slave mode, MOSI pin required to be non-NC for this API to operate
308  */
309 cy_rslt_t cyhal_spi_recv(cyhal_spi_t *obj, uint32_t* value);
310 
311 /** Synchronously send a byte out
312  *
313  * In Master mode transmits value to slave and read/drop a value from the RxFifo.
314  * In Slave mode writes a value to TxFifo
315  *
316  * @param[in] obj   The SPI peripheral to use for sending
317  * @param[in] value The value to send
318  * @return The status of the write request
319  * @note
320  * - In Master mode, MOSI pin required to be non-NC for this API to operate
321  * - In Slave mode, MISO pin required to be non-NC for this API to operate
322  */
323 cy_rslt_t cyhal_spi_send(cyhal_spi_t *obj, uint32_t value);
324 
325 /** Wait for master send data to RX buffer and store them to the user-defined buffer.
326  * NOTE: If size of actual data is less then expected the function copy only available data.
327  *
328  * @param[in]     obj        The SPI object
329  * @param[in]     dst_buff   Pointer on memory to store the data from the slave RX buffer.
330  * @param[in,out] size       [in] The number of bytes to read, [out] number actually read.
331  * @param[in]     timeout    Timeout in millisecond, set this value to 0 if you don't want to wait at all.
332  * @return  The status of the read request
333  * */
334 cy_rslt_t cyhal_spi_slave_read(cyhal_spi_t *obj, uint8_t *dst_buff, uint16_t *size, uint32_t timeout);
335 
336 /** Write data from the user-defined buffer to TX buffer.
337  * NOTE: If size of actual data is less then expected the function copy only available data.
338  *
339  * @param[in]     obj        The SPI object
340  * @param[in]     src_buff   Pointer on memory to copy the data to the slave TX buffer.
341  * @param[in,out] size       [in] The number of bytes to send, [out] number actually sent.
342  * @param[in]     timeout    Timeout in millisecond,  set this value to 0 if you don't want to wait at all.
343  * @return  The status of the write request
344  * */
345 cy_rslt_t cyhal_spi_slave_write(cyhal_spi_t *obj, const uint8_t *src_buff, uint16_t *size, uint32_t timeout);
346 
347 
348 /** Returns the number of bytes that can be read from the RX buffer.
349  *
350  * @param[in]  obj          The SPI object
351  * @return  The number of bytes in the RX buffer.
352  * */
353 uint32_t cyhal_spi_readable(cyhal_spi_t *obj);
354 
355 /** Returns the number of bytes that can be written to the TX buffer.
356  *
357  * @param[in]  obj          The SPI object
358  * @return  The number of bytes that can be written
359  * */
360 uint32_t cyhal_spi_writable(cyhal_spi_t *obj);
361 
362 /** Synchronously Write a block out and receive a value
363  *
364  *  The total number of bytes sent and received will be the maximum of tx_length
365  *  and rx_length. The bytes written will be padded (at the end) with the value
366  *  given by write_fill.
367  *
368  * This function will block for the duration of the transfer. \ref cyhal_spi_transfer_async
369  * can be used for non-blocking transfers.
370  *
371  * @param[in] obj           The SPI peripheral to use for sending
372  * @param[in] tx            Pointer to the byte-array of data to write to the device
373  * @param[in,out] tx_length Number of bytes to write, updated with the number actually written
374  * @param[out] rx           Pointer to the byte-array of data to read from the device
375  * @param[in,out] rx_length Number of bytes to read, updated with the number actually read
376  * @param[in] write_fill    Default data transmitted while performing a read
377  * @return The status of the transfer request
378  * @note Both MOSI and MISO pins required to be non-NC for this API to operate
379  */
380 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);
381 
382 /** Start an asynchronous SPI transfer.
383  *
384  * This will transfer `rx_length` bytes into the buffer pointed to by `rx`, while simultaneously transfering
385  * `tx_length` bytes of data from the buffer pointed to by `tx`, both in the background.
386  * When the transfer is complete, the @ref CYHAL_SPI_IRQ_DONE event will be raised.
387  * See @ref cyhal_spi_register_callback and @ref cyhal_spi_enable_event.
388  * \note For blocking transfers cyhal_spi_transfer can be used.
389  *
390  * @param[in] obj           The SPI object that holds the transfer information
391  * @param[in] tx            The transmit buffer
392  * @param[in,out] tx_length The number of bytes to transmit
393  * @param[out] rx           The receive buffer
394  * @param[in,out] rx_length The number of bytes to receive
395  * @return The status of the transfer_async request
396  * @note Both MOSI and MISO pins required to be non-NC for this API to operate
397  */
398 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);
399 
400 /** Checks if the specified SPI peripheral is in use
401  *
402  * @param[in] obj  The SPI peripheral to check
403  * @return Indication of whether the SPI is still transmitting
404  */
405 bool cyhal_spi_is_busy(cyhal_spi_t *obj);
406 
407 /** Abort an SPI transfer
408  *
409  * @param[in] obj The SPI peripheral to stop
410  * @return The status of the abort_async request
411  */
412 cy_rslt_t cyhal_spi_abort_async(cyhal_spi_t *obj);
413 
414 /** Register a SPI callback handler
415  *
416  * This function will be called when one of the events enabled by \ref cyhal_spi_enable_event occurs.
417  *
418  * @param[in] obj          The SPI object
419  * @param[in] callback     The callback handler which will be invoked when the interrupt fires
420  * @param[in] callback_arg Generic argument that will be provided to the callback when called
421  */
422 void cyhal_spi_register_callback(cyhal_spi_t *obj, cyhal_spi_event_callback_t callback, void *callback_arg);
423 
424 /** Configure SPI interrupt. This function is used for word-approach
425  *
426  * When an enabled event occurs, the function specified by \ref cyhal_spi_register_callback will be called.
427  *
428  * @param[in] obj            The SPI object
429  * @param[in] event          The SPI event type
430  * @param[in] intr_priority  The priority for NVIC interrupt events
431  * @param[in] enable         True to turn on interrupts, False to turn off
432  */
433 void cyhal_spi_enable_event(cyhal_spi_t *obj, cyhal_spi_event_t event, uint8_t intr_priority, bool enable);
434 
435 /** Sets a threshold level for a FIFO that will generate an interrupt and a
436  * trigger output. The RX FIFO interrupt and trigger will be activated when
437  * the receive FIFO has more entries than the threshold. The TX FIFO interrupt
438  * and trigger will be activated when the transmit FIFO has less entries than
439  * the threshold.
440  *
441  * @param[in]  obj        The SPI object
442  * @param[in]  type       FIFO type to set level for
443  * @param[in]  level      Level threshold to set
444  * @return The status of the level set
445  * */
446 cy_rslt_t cyhal_spi_set_fifo_level(cyhal_spi_t *obj, cyhal_spi_fifo_type_t type, uint16_t level);
447 
448 /** Enables the specified output signal from an SPI.
449  *
450  * @param[in]  obj        The SPI object
451  * @param[in]  output     Which output signal to enable
452  * @param[out] source     Pointer to user-allocated source signal object which
453  * will be initialized by enable_output. \p source should be passed to
454  * (dis)connect_digital functions to (dis)connect the associated endpoints.
455  * @return The status of the output enable
456  * */
457 cy_rslt_t cyhal_spi_enable_output(cyhal_spi_t *obj, cyhal_spi_output_t output, cyhal_source_t *source);
458 
459 /** Disables the specified output signal from an SPI
460  *
461  * @param[in]  obj        The SPI object
462  * @param[in]  output     Which output signal to disable
463  * @return The status of the output disable
464  * */
465 cy_rslt_t cyhal_spi_disable_output(cyhal_spi_t *obj, cyhal_spi_output_t output);
466 
467 /** Initialize the SPI peripheral using a configurator generated configuration struct.
468  *
469  * @param[in]  obj                  The SPI peripheral to configure
470  * @param[in]  cfg                  Configuration structure generated by a configurator.
471  * @return The status of the operation
472  */
473 cy_rslt_t cyhal_spi_init_cfg(cyhal_spi_t *obj, const cyhal_spi_configurator_t *cfg);
474 
475 /** Clear the SPI buffers
476  *
477  * @param[in]  obj        The SPI object
478  * @return The status of the clear request
479  * */
480 cy_rslt_t cyhal_spi_clear(cyhal_spi_t *obj);
481 
482 #if defined(__cplusplus)
483 }
484 #endif
485 
486 #ifdef CYHAL_SPI_IMPL_HEADER
487 #include CYHAL_SPI_IMPL_HEADER
488 #endif /* CYHAL_SPI_IMPL_HEADER */
489 
490 /** \} group_hal_spi */
491