1 /*******************************************************************************
2 * File Name: cyhal_audio_common.h
3 *
4 * Description:
5 * Provides common functionality for the I2S and TDM audio drivers.
6 *
7 ********************************************************************************
8 * \copyright
9 * Copyright 2018-2022 Cypress Semiconductor Corporation (an Infineon company) or
10 * an affiliate of Cypress Semiconductor Corporation
11 *
12 * SPDX-License-Identifier: Apache-2.0
13 *
14 * Licensed under the Apache License, Version 2.0 (the "License");
15 * you may not use this file except in compliance with the License.
16 * You may obtain a copy of the License at
17 *
18 *     http://www.apache.org/licenses/LICENSE-2.0
19 *
20 * Unless required by applicable law or agreed to in writing, software
21 * distributed under the License is distributed on an "AS IS" BASIS,
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 * See the License for the specific language governing permissions and
24 * limitations under the License.
25 *******************************************************************************/
26 
27 #pragma once
28 
29 #include <stdbool.h>
30 #include <stdint.h>
31 #include "cyhal_gpio.h"
32 #include "cyhal_hw_resources.h"
33 
34 #if (CYHAL_DRIVER_AVAILABLE_I2S || CYHAL_DRIVER_AVAILABLE_TDM)
35 
36 #if defined(__cplusplus)
37 extern "C"
38 {
39 #endif
40 
41 /** \cond INTERNAL */
42 
43 #if (CYHAL_DRIVER_AVAILABLE_TDM_RX || CYHAL_DRIVER_AVAILABLE_I2S_RX)
44 #define _CYHAL_AUDIOSS_RX_ENABLED
45 #endif
46 
47 /* Pins to use for one direction of an audio interface */
48 typedef struct {
49     cyhal_gpio_t sck;   // Clock pin
50     cyhal_gpio_t ws;    // Word select
51     cyhal_gpio_t data;  // Data pin (sdo or sdi)
52     cyhal_gpio_t mclk;  // mclk input (may be NC if unused)
53 } _cyhal_audioss_pins_t;
54 
55 /* AUDIOSS Configuration */
56 typedef struct {
57     /* Configure TX to operate a slave (true) or master (false) */
58     bool is_tx_slave;
59     /* Configure RX to operate a slave (true) or master (false) **/
60     bool is_rx_slave;
61     /* Frequency, in hertz, of the master clock if it is provided by an external pin.
62      * If the mclk pin is not NC, this must be nonzero.
63      * If the mclk pin is NC, this must be zero.
64      */
65     uint32_t mclk_hz;
66     /* Number of bits in each channel. See the implementation specific documentation for supported values. **/
67     uint8_t channel_length;
68     /* Number of bits in each word. Must be less than or equal to channel_length.
69      * If word_length < channel_length, the excess bits will be padded with 0's.
70      */
71     uint8_t word_length;
72     /* Sample rate in Hz */
73     uint32_t sample_rate_hz;
74     /* Number of channels */
75     uint8_t num_channels;
76     /* Channel enable mask. 1=enabled, 0=disabled */
77     uint32_t channel_mask;
78     /* false = TX WS pulse is a single SCK cycle. true = TX WS pulse spans a full channel */
79     bool tx_ws_full;
80 #if defined(_CYHAL_AUDIOSS_RX_ENABLED)
81     /* false = RX WS pulse is a single SCK cycle. true = RX WS pulse spans a full channel */
82     bool rx_ws_full;
83 #endif
84     /* Is this block being used as I2S. */
85     bool is_i2s;
86 } _cyhal_audioss_config_t;
87 
88 cy_rslt_t _cyhal_audioss_init(_cyhal_audioss_t *obj, const _cyhal_audioss_pins_t* tx_pins, const _cyhal_audioss_pins_t* rx_pins, const _cyhal_audioss_config_t* config, cyhal_clock_t* clk, const _cyhal_audioss_interface_t* interface);
89 
90 cy_rslt_t _cyhal_audioss_init_cfg(_cyhal_audioss_t *obj, const _cyhal_audioss_configurator_t *cfg, const _cyhal_audioss_interface_t* interface);
91 
92 void _cyhal_audioss_free(_cyhal_audioss_t *obj);
93 
94 cy_rslt_t _cyhal_audioss_set_sample_rate(_cyhal_audioss_t *obj, uint32_t sample_rate_hz);
95 
96 void _cyhal_audioss_enable_event(_cyhal_audioss_t *obj, uint32_t event, uint8_t intr_priority, bool enable);
97 
98 cy_rslt_t _cyhal_audioss_start_tx(_cyhal_audioss_t *obj);
99 
100 cy_rslt_t _cyhal_audioss_stop_tx(_cyhal_audioss_t *obj);
101 
102 cy_rslt_t _cyhal_audioss_clear_tx(_cyhal_audioss_t *obj);
103 
104 cy_rslt_t _cyhal_audioss_start_rx(_cyhal_audioss_t *obj);
105 
106 cy_rslt_t _cyhal_audioss_stop_rx(_cyhal_audioss_t *obj);
107 
108 cy_rslt_t _cyhal_audioss_clear_rx(_cyhal_audioss_t *obj);
109 
110 cy_rslt_t _cyhal_audioss_read(_cyhal_audioss_t *obj, void *data, size_t* length);
111 
112 cy_rslt_t _cyhal_audioss_write(_cyhal_audioss_t *obj, const void *data, size_t *length);
113 
114 bool _cyhal_audioss_is_tx_enabled(_cyhal_audioss_t *obj);
115 
116 bool _cyhal_audioss_is_tx_busy(_cyhal_audioss_t *obj);
117 
118 bool _cyhal_audioss_is_rx_enabled(_cyhal_audioss_t *obj);
119 
120 bool _cyhal_audioss_is_rx_busy(_cyhal_audioss_t *obj);
121 
122 cy_rslt_t _cyhal_audioss_read_async(_cyhal_audioss_t *obj, void *rx, size_t rx_length);
123 
124 cy_rslt_t _cyhal_audioss_write_async(_cyhal_audioss_t *obj, const void *tx, size_t tx_length);
125 
126 cy_rslt_t _cyhal_audioss_set_async_mode(_cyhal_audioss_t *obj, cyhal_async_mode_t mode, uint8_t dma_priority);
127 
128 bool _cyhal_audioss_is_read_pending(_cyhal_audioss_t *obj);
129 
130 bool _cyhal_audioss_is_write_pending(_cyhal_audioss_t *obj);
131 
132 cy_rslt_t _cyhal_audioss_abort_read_async(_cyhal_audioss_t *obj);
133 
134 cy_rslt_t _cyhal_audioss_abort_write_async(_cyhal_audioss_t *obj);
135 
136 cy_rslt_t _cyhal_audioss_enable_output(_cyhal_audioss_t *obj, bool is_rx, cyhal_source_t *source);
137 
138 cy_rslt_t _cyhal_audioss_disable_output(_cyhal_audioss_t *obj, bool is_rx);
139 
140 /** \endcond */
141 
142 #if defined(__cplusplus)
143 }
144 #endif
145 
146 #endif /* CYHAL_DRIVER_AVAILABLE_I2S */
147