1 /***************************************************************************//**
2 * \file cyhal_i2s.h
3 *
4 * \brief
5 * Provides a high level interface for interacting with the Infineon I2S.
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_i2s I2S (Inter-IC Sound)
32 * \ingroup group_hal
33 * \{
34 * High level interface for interacting with the Inter-IC Sound (I2S).
35 *
36 * The I2S protocol is a asynchronous serial interface protocol. This driver supports
37 * both transmit and receive modes of operation. The communication frequency, sample rate,
38 * word size, and channel size can all be configured.
39 *
40 * \note Certain platforms may not support all of the functionality and configuration options
41 * provided by this driver. Please refer to implementation specific documentation for details
42 * on available options.
43 *
44 * \section section_i2s_features Features
45 *
46 * * Transmit and receive functionality
47 * * Configurable data rates
48 * * Configurable channel and word size
49 * * Configurable interrupt and callback assignment from I2S events - \ref cyhal_i2s_event_t
50 *
51 * \section section_i2s_quickstart Quick Start
52 * Initialize an I2S instance using the \ref cyhal_i2s_init and provide the transmit (tx) and/or receive (rx) pins. Call
53 * \ref cyhal_i2s_start_tx and/or \ref cyhal_i2s_start_rx to enable transmit and/or receive functionality as desired.<br>
54 * See \ref subsection_i2s_snippet_1 for example initialization as transmit or receive.
55 * \note The clock parameter (const \ref cyhal_clock_t *clk) is optional and can be set
56 * to NULL to generate and use an available clock resource with a default frequency.
57 *
58 * The sclk frequency is determined as `sclk = sample_rate_hz * channel_length * 2`
59 * (multiplying by 2 for 2 channels - left and right). The input clock must be a multiple of this sclk
60 * frequency; see the implementation specific documentation for the supported multipliers.
61 *
62 * It is possible to use either only TX functionality, only RX functionality, or both RX and TX functionality at the same time.
63 * If RX and TX are both in use, the same sample rate, channel length, word length, sclk frequency will be used for both.
64 *
65 * \section section_i2s_snippets Code Snippets
66 *
67 * \subsection subsection_i2s_snippet_1 Snippet 1: I2S Initialization and Configuration
68 * This snippet initializes an I2S resource for transmit or receive and assigns the pins.
69 *
70 * Initializing as I2S transmitter
71 * \snippet hal_i2s.c snippet_cyhal_i2s_transmit_init
72 *
73 * Initializing as I2S receiver
74 * \snippet hal_i2s.c snippet_cyhal_i2s_receive_init
75 *
76 * \subsection subsection_i2s_snippet_2 Snippet 2: I2S Transmit One-shot
77 * This snippet shows how to transmit data using \ref cyhal_i2s_write_async when the entire sample
78 * is available at once. <br>
79 *
80 * \snippet hal_i2s.c snippet_cyhal_i2s_async_transmit_one_shot
81 
82 * \subsection subsection_i2s_snippet_3 Snippet 3: I2S Transmit Streaming
83 * This snippet shows how to transmit data using \ref cyhal_i2s_write_async when sample data is
84 * being continuously loaded and transmitted (e.g. streaming over the network). <br>
85 *
86 * \snippet hal_i2s.c snippet_cyhal_i2s_async_transmit_streaming
87 
88 * \subsection subsection_i2s_snippet_4 Snippet 4: I2S Receive
89 * This snippet shows how to receive data using \ref cyhal_i2s_read_async. <br>
90 *
91 * \snippet hal_i2s.c snippet_cyhal_i2s_async_receive
92 *
93 * \section subsection_i2s_moreinformation More Information
94 *
95 * <b>Code examples (Github)</b>
96 * * <a href="https://github.com/infineon/mtb-example-psoc6-i2s" ><b>
97 PSoC™ 6 MCU: Inter-IC Sound (I2S)</b></a>
98 * * <a href="https://github.com/infineon/mtb-example-psoc6-pdm-to-i2s" ><b>
99 PSoC™ 6 MCU: PDM to I2S</b></a>
100 */
101 
102 #pragma once
103 
104 #include <stdint.h>
105 #include <stdbool.h>
106 #include "cy_result.h"
107 #include "cyhal_general_types.h"
108 #include "cyhal_hw_types.h"
109 #include "cyhal_gpio.h"
110 
111 #if defined(__cplusplus)
112 extern "C" {
113 #endif
114 
115 /** \addtogroup group_hal_results_i2s I2S HAL Results
116  *  I2S specific return codes
117  *  \ingroup group_hal_results
118  *  \{ *//**
119  */
120 
121 /** An invalid pin location was specified */
122 #define CYHAL_I2S_RSLT_ERR_INVALID_PIN                  \
123     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_I2S, 0))
124 /** An argument was provided */
125 #define CYHAL_I2S_RSLT_ERR_INVALID_ARG                  \
126     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_I2S, 1))
127 /** Initialization of the I2S hardware failed*/
128 #define CYHAL_I2S_RSLT_ERR_INIT_FAILED                  \
129     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_I2S, 2))
130 /** The requested clock frequency could not be achieved */
131 #define CYHAL_I2S_RSLT_ERR_CLOCK \
132     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_I2S, 3))
133 /** The requested configuration is not supported. */
134 #define CYHAL_I2S_RSLT_NOT_SUPPORTED \
135     (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_I2S, 4))
136 
137 
138 /**
139  * \}
140  */
141 
142 /** I2S events */
143 typedef enum {
144     /** TX HW Buffer is not full */
145     CYHAL_I2S_TX_NOT_FULL         = 1 << 0,
146     /** TX HW Buffer is half empty */
147     CYHAL_I2S_TX_HALF_EMPTY       = 1 << 1,
148     /** TX HW Buffer is Empty */
149     CYHAL_I2S_TX_EMPTY            = 1 << 2,
150     /** Attempt to write when TX HW Buffer is full */
151     CYHAL_I2S_TX_OVERFLOW         = 1 << 3,
152     /** Interface ready to transfer data but HW TX buffer is empty */
153     CYHAL_I2S_TX_UNDERFLOW        = 1 << 4,
154     /** Pending async transmit is complete (but the HW buffer may still contain unsent data) */
155     CYHAL_I2S_ASYNC_TX_COMPLETE   = 1 << 5,
156     /** RX HW Buffer is not Empty */
157     CYHAL_I2S_RX_NOT_EMPTY        = 1 << 6,
158     /** RX HW Buffer is half full */
159     CYHAL_I2S_RX_HALF_FULL        = 1 << 7,
160     /** RX HW Buffer is FULL */
161     CYHAL_I2S_RX_FULL             = 1 << 8,
162     /** Attempt to write when RX HW Buffer is full */
163     CYHAL_I2S_RX_OVERFLOW         = 1 << 9,
164     /** Attempt to read when HW RX buffer is empty */
165     CYHAL_I2S_RX_UNDERFLOW        = 1 << 10,
166     /** Pending async receive is complete */
167     CYHAL_I2S_ASYNC_RX_COMPLETE   = 1 << 11,
168 } cyhal_i2s_event_t;
169 
170 /** Selections for I2S output signals  */
171 typedef enum
172 {
173     /** An output signal should be triggered when the receive buffer is half full */
174     CYHAL_I2S_TRIGGER_RX_HALF_FULL,
175     /** An output signal should be triggered when the transmit buffer is half empty */
176     CYHAL_I2S_TRIGGER_TX_HALF_EMPTY,
177 }
178 cyhal_i2s_output_t;
179 
180 /** Pins to use for one I2S direction */
181 typedef struct {
182     cyhal_gpio_t sck;   //!< Clock pin
183     cyhal_gpio_t ws;    //!< Word select
184     cyhal_gpio_t data;  //!< Data pin (sdo or sdi)
185     cyhal_gpio_t mclk;  //!< Mclk input pin. Set to NC if an internal clock source should be used
186 } cyhal_i2s_pins_t;
187 
188 /** I2S Configuration */
189 typedef struct {
190     /** Configure TX to operate a slave (true) or master (false) */
191     bool is_tx_slave;
192     /** Configure RX to operate a slave (true) or master (false) **/
193     bool is_rx_slave;
194     /** Frequency, in hertz, of the master clock if it is provided by an external pin.
195      * If at least one mclk pin is not NC, this must be nonzero.
196      * If both mclk pins are NC, this must be zero.
197      */
198     uint32_t mclk_hz;
199     /** Number of bits in each channel. See the implementation specific documentation for supported values. **/
200     uint8_t channel_length;
201     /** Number of bits in each word. Must be less than or equal to channel_length.
202      * If word_length < channel_length, the excess bits will be padded with 0's.
203      */
204     uint8_t word_length;
205     /** Sample rate in Hz */
206     uint32_t sample_rate_hz;
207 } cyhal_i2s_config_t;
208 
209 /** Handler for I2S event callbacks */
210 typedef void (*cyhal_i2s_event_callback_t)(void *callback_arg, cyhal_i2s_event_t event);
211 
212 /** Initialize the I2S peripheral. It sets the default parameters for I2S
213  *  peripheral, and configures its specifieds pins.
214  *  If only one direction is to be used, then the pins for the other direction need not be specified (i.e. they may be set to NC).
215  *  For example, if only RX is needed, tx_sck, tx_ws, and tx_sdo may all be set to NC.
216  *  If one pin is specified for a direction, all pins for that direction must be specified.
217  *
218  * @param[out] obj          Pointer to an I2S object. The caller must allocate the memory
219  *                            for this object but the init function will initialize its contents.
220  * @param[in]  tx_pins      Pins for I2S transmit. If NULL, transmit functionality will be disabled.
221  * @param[in]  rx_pins      Pins for I2S receive. If NULL, receive functionality will be disabled.
222  * @param[in]  config       Initial block configuration
223  * @param[in]  clk          Clock source to use for this instance. If NULL, a dedicated clock divider will be allocated for this instance.
224  * @return The status of the init request
225  */
226 cy_rslt_t cyhal_i2s_init(cyhal_i2s_t *obj, const cyhal_i2s_pins_t* tx_pins, const cyhal_i2s_pins_t* rx_pins,
227                          const cyhal_i2s_config_t* config, cyhal_clock_t* clk);
228 
229 /** Initialize the I2S peripheral using a configurator generated configuration struct
230   *
231  * @param[out] obj              Pointer to a I2S object. The caller must allocate the memory
232  *                              for this object but the init function will initialize its contents.
233  * @param[in] cfg               Configuration structure generated by a configurator.
234  * @return The status of the init request
235  */
236  cy_rslt_t cyhal_i2s_init_cfg(cyhal_i2s_t *obj, const cyhal_i2s_configurator_t *cfg);
237 
238 /** Deinitialize the i2s object
239  *
240  * @param[in,out] obj The i2s object
241  */
242 void cyhal_i2s_free(cyhal_i2s_t *obj);
243 
244 /** Set the I2S sample rate
245  *
246  * @param[in] obj The I2S object
247  * @param[in] sample_rate_hz Sample rate in Hz
248  * @return The status of the set sample rate request
249  */
250 cy_rslt_t cyhal_i2s_set_sample_rate(cyhal_i2s_t *obj, uint32_t sample_rate_hz);
251 
252 /** Starts transmitting data. Transmission will continue until it is stopped by
253   * calling @ref cyhal_i2s_stop_tx.
254   *
255   * @param[in] obj The I2S object
256   * @return The status of the start request.
257   */
258 cy_rslt_t cyhal_i2s_start_tx(cyhal_i2s_t *obj);
259 
260 /** Stops transmitting data. This immediately terminates transmission.
261   *
262   * @param[in] obj The I2S object
263   * @return The status of the stop request.
264   */
265 cy_rslt_t cyhal_i2s_stop_tx(cyhal_i2s_t *obj);
266 
267 /** Clears the tx hardware buffer
268  *
269  * @param[in] obj The i2s peripheral
270  * @return The status of the clear request
271  */
272 cy_rslt_t cyhal_i2s_clear_tx(cyhal_i2s_t *obj);
273 
274 /** Starts receiving data. Data will continue to be received until it is
275   * stopped by calling @ref cyhal_i2s_stop_rx.
276   *
277   * @param[in] obj The I2S object
278   * @return The status of the start request.
279   */
280 cy_rslt_t cyhal_i2s_start_rx(cyhal_i2s_t *obj);
281 
282 /** Stops receiving data. This immediately terminates data receipt.
283   *
284   * @param[in] obj The I2S object
285   * @return The status of the stop request.
286   */
287 cy_rslt_t cyhal_i2s_stop_rx(cyhal_i2s_t *obj);
288 
289 /** Clears the rx hardware buffer
290  *
291  * @param[in] obj The i2s peripheral
292  * @return The status of the clear request
293  */
294 cy_rslt_t cyhal_i2s_clear_rx(cyhal_i2s_t *obj);
295 
296 /** Read data synchronously
297  *
298  * This will read the number of words specified by the `length` parameter, or the number of words that
299  * are currently available in the receive buffer, whichever is less, then return. The value pointed to
300  * by `length` will be updated to reflect the number of words that were actually read.
301  *
302  * @param[in]  obj    The I2S object
303  * @param[out] data   The buffer for receiving
304  * @param[in,out] length Number of words to (as configured in cyhal_i2s_config_t.word_length) read, updated with the number actually read
305  * @return The status of the read request
306  *
307  * @note Each word will be aligned to the next largest power of 2. For example, if the word length is 16 bits,
308  * each word will consume two bytes. But if the word length is 20, each word will consume 32 bytes.
309  * @return The status of the read request
310  */
311 cy_rslt_t cyhal_i2s_read(cyhal_i2s_t *obj, void *data, size_t* length);
312 
313 /** Send data synchronously
314  *
315  * This will write either `length` words or until the write buffer is full, whichever is less,
316  * then return. The value pointed to by `length` will be updated to reflect the number of words
317  * that were actually written.
318  * @note This function only queues data into the write buffer; it does not block until the
319  *  data has all been sent out over the wire.
320  *
321  * @param[in] obj     The I2S object
322  * @param[in] data    The buffer for sending
323  * @param[in,out] length Number of words to write (as configured in cyhal_i2s_config_t.word_length, updated with the number actually written
324  * @return The status of the write request
325  *
326  * @note Each word will be aligned to the next largest power of 2. For example, if the word length is 16 bits,
327  * each word will consume two bytes. But if the word length is 20, each word will consume 32 bytes.
328  */
329 cy_rslt_t cyhal_i2s_write(cyhal_i2s_t *obj, const void *data, size_t *length);
330 
331 /** Checks if the transmit functionality is enabled for the specified I2S peripheral (regardless of whether data
332   * is currently queued for transmission).
333   *
334   * The transmit functionality can be enabled by calling @ref cyhal_i2s_start_tx and disabled by calling
335   * @ref cyhal_i2s_stop_tx
336   *
337   * @param[in] obj  The I2S peripheral to check
338   * @return Whether the I2S transmit function is enabled.
339   */
340 bool cyhal_i2s_is_tx_enabled(cyhal_i2s_t *obj);
341 
342 /** Checks if the specified I2S peripheral is transmitting data, including if a pending async transfer is waiting
343   * to write more data to the transmit buffer.
344   *
345   * @param[in] obj  The I2S peripheral to check
346   * @return Whether the I2S is still transmitting
347   */
348 bool cyhal_i2s_is_tx_busy(cyhal_i2s_t *obj);
349 
350 /** Checks if the receive functionality is enabled for the specified I2S peripheral (regardless of whether any
351   * unread data has been received).
352   *
353   * The receive functionality can be enabled by calling @ref cyhal_i2s_start_rx and disabled by calling
354   * @ref cyhal_i2s_stop_rx
355   *
356   * @param[in] obj  The I2S peripheral to check
357   * @return Whether the I2S receive function is enabled.
358   */
359 bool cyhal_i2s_is_rx_enabled(cyhal_i2s_t *obj);
360 
361 /** Checks if the specified I2S peripheral has received data that has not yet been read out of the hardware buffer.
362   * This includes if an async read transfer is pending.
363   *
364   * @param[in] obj  The I2S peripheral to check
365   * @return Whether the I2S is still transmitting
366   */
367 bool cyhal_i2s_is_rx_busy(cyhal_i2s_t *obj);
368 
369 /** Start I2S asynchronous read.
370  *
371  * This will transfer `rx_length` words into the buffer pointed to by `rx` in the background. When the
372  * requested quantity of data has been read, the @ref CYHAL_I2S_ASYNC_RX_COMPLETE event will be raised.
373  * See @ref cyhal_i2s_register_callback and @ref cyhal_i2s_enable_event.
374  *
375  * cyhal_i2s_set_async_mode can be used to control whether this uses DMA or a CPU-driven transfer.
376  *
377  * @note If D-cache is enabled, cyhal_i2s_set_async_mode is DMA and data Cache line is 32 bytes,
378  * the user needs to make sure that the rx pointer passed to the cyhal_i2s_read_async
379  * function points to a 32 byte aligned array of words that contains the buffer data.
380  * The size of buffer data must be a multiple of 32 bytes to ensure cache coherency.
381  * CY_ALIGN(__SCB_DCACHE_LINE_SIZE) macro can be used for 32 byte alignment.
382  *
383  * Refer to \ref DCACHE_Management for more information.
384  *
385  * @note Each word will be aligned to the next largest power of 2. For example, if the word length is 16 bits,
386  * each word will consume two bytes. But if the word length is 20, each word will consume 32 bytes.
387  *
388  * @param[in]     obj       The I2S object
389  * @param[out]    rx        The receive buffer.
390  * @param[in]     rx_length Number of words (as configured in cyhal_i2s_config_t.word_length) to read.
391  * @return The status of the read_async request
392  */
393 cy_rslt_t cyhal_i2s_read_async(cyhal_i2s_t *obj, void *rx, size_t rx_length);
394 
395 /** Start I2S asynchronous write.
396  *
397  * This will transfer `tx_length` words into the tx buffer in the background. When the requested
398  * quantity of data has been queued in the transmit buffer, the @ref CYHAL_I2S_ASYNC_TX_COMPLETE
399  * event will be raised. See @ref cyhal_i2s_register_callback and @ref cyhal_i2s_enable_event.
400  *
401  * cyhal_i2s_set_async_mode can be used to control whether this uses DMA or a SW (CPU-driven) transfer.
402  *
403  * @note If D-cache is enabled, cyhal_i2s_set_async_mode is DMA and data Cache line is 32 bytes,
404  * the user needs to make sure that the tx pointer passed to the cyhal_i2s_write_async
405  * function points to a 32 byte aligned array of words that contains the buffer data.
406  * The size of buffer data must be a multiple of 32 bytes to ensure cache coherency.
407  * CY_ALIGN(__SCB_DCACHE_LINE_SIZE) macro can be used for 32 byte alignment.
408  *
409  * Refer to \ref DCACHE_Management for more information.
410  *
411  * @note Each word will be aligned to the next largest power of 2. For example, if the word length is 16 bits,
412  * each word will consume two bytes. But if the word length is 20, each word will consume 32 bytes.
413  *
414  * @param[in]     obj       The I2S object
415  * @param[in]     tx        The transmit buffer.
416  * @param[in]     tx_length The number of words to transmit.
417  * @return The status of the transfer_async request
418  */
419 cy_rslt_t cyhal_i2s_write_async(cyhal_i2s_t *obj, const void *tx, size_t tx_length);
420 
421 /** Set the mechanism that is used to perform I2S asynchronous transfers. The default is SW.
422  *  @warning The effect of calling this function while an async transfer is pending is undefined.
423  *
424  * @param[in]     obj          The I2S object
425  * @param[in]     mode         The transfer mode
426  * @param[in]     dma_priority The priority, if DMA is used. Valid values are the same as for @ref cyhal_dma_init.
427  *                             If DMA is not selected, the only valid value is CYHAL_DMA_PRIORITY_DEFAULT, and no
428                                guarantees are made about prioritization.
429  * @return The status of the set mode request
430  */
431 cy_rslt_t cyhal_i2s_set_async_mode(cyhal_i2s_t *obj, cyhal_async_mode_t mode, uint8_t dma_priority);
432 
433 /** Checks if the specified I2S peripheral is in the process of reading data from the hardware buffer into RAM.
434  *
435  * @note: This only checks whether there is an ongoing transfer (e.g. via cyhal_i2s_read_async) into RAM from the
436  *  I2S peripheral's hardware buffer. It does not check whether unread data exists in the hardware buffer.
437  *
438  * @param[in] obj  The I2S peripheral to check
439  * @return Whether an asynchronous read operation is still in progress
440  */
441 bool cyhal_i2s_is_read_pending(cyhal_i2s_t *obj);
442 
443 /** Checks if the specified I2S peripheral is in the process of writing data into the hardware buffer.
444  *
445  * @note: This only checks whether there is an ongoing transfer (e.g. via cyhal_i2s_transfer_async) from RAM into the
446  *  I2S peripheral's hardware buffer. It does not check whether unwritten data exists in the hardware buffer.
447  *
448  * @param[in] obj  The I2S peripheral to check
449  * @return Whether an asynchronous write operation is still in progress
450  */
451 bool cyhal_i2s_is_write_pending(cyhal_i2s_t *obj);
452 
453 /** Abort I2S asynchronous read
454  *
455  * This function does not perform any validation before aborting the transfer.
456  * Any validation which is required is the responsibility of the application.
457  *
458  * @param[in] obj The I2S object
459  * @return The status of the abort_async_read request
460  */
461 cy_rslt_t cyhal_i2s_abort_read_async(cyhal_i2s_t *obj);
462 
463 /** Abort I2S asynchronous write
464  *
465  * This function does not perform any validation before aborting the transfer.
466  * Any validation which is required is the responsibility of the application.
467  *
468  * @param[in] obj The I2S object
469  * @return The status of the abort_async_write request
470  */
471 cy_rslt_t cyhal_i2s_abort_write_async(cyhal_i2s_t *obj);
472 
473 /** Register an I2S callback handler
474  *
475  * This function will be called when one of the events enabled by \ref cyhal_i2s_enable_event occurs.
476  *
477  * @param[in] obj          The I2S object
478  * @param[in] callback     The callback handler which will be invoked when the interrupt fires
479  * @param[in] callback_arg Generic argument that will be provided to the callback when called
480  */
481 void cyhal_i2s_register_callback(cyhal_i2s_t *obj, cyhal_i2s_event_callback_t callback, void *callback_arg);
482 
483 /** Configure I2S events.
484  *
485  * When an enabled event occurs, the function specified by \ref cyhal_i2s_register_callback will be called.
486  *
487  * @param[in] obj            The I2S object
488  * @param[in] event          The I2S event type
489  * @param[in] intr_priority  The priority for NVIC interrupt events
490  * @param[in] enable         True to turn on specified events, False to turn off
491  */
492 void cyhal_i2s_enable_event(cyhal_i2s_t *obj, cyhal_i2s_event_t event, uint8_t intr_priority, bool enable);
493 
494 /** Enables the specified output signal
495  *
496  * @param[in]  obj          The I2S object
497  * @param[in]  output       Which output signal to enable
498  * @param[out] source       Pointer to user-allocated source signal object
499  * which will be initialized by enable_output. \p source should be passed to
500  * (dis)connect_digital functions to (dis)connect the associated endpoints.
501   * @return The status of the output enable
502  */
503 cy_rslt_t cyhal_i2s_enable_output(cyhal_i2s_t *obj, cyhal_i2s_output_t output, cyhal_source_t *source);
504 
505 /** Disables the specified output signal
506  *
507  * @param[in]  obj          The I2S object
508  * @param[in]  output       Which output signal to disable
509  *
510  * @return The status of the disablement
511  */
512 cy_rslt_t cyhal_i2s_disable_output(cyhal_i2s_t *obj, cyhal_i2s_output_t output);
513 
514 #if defined(__cplusplus)
515 }
516 #endif
517 
518 #ifdef CYHAL_I2S_IMPL_HEADER
519 #include CYHAL_I2S_IMPL_HEADER
520 #endif /* CYHAL_I2S_IMPL_HEADER */
521 
522 /** \} group_hal_i2s */
523