1 /**
2  * @file    i2s.h
3  * @brief   I2S (Inter-Integrated Sound) driver function prototypes and data types.
4  */
5 
6 /******************************************************************************
7  *
8  * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
9  * Analog Devices, Inc.),
10  * Copyright (C) 2023-2024 Analog Devices, Inc.
11  *
12  * Licensed under the Apache License, Version 2.0 (the "License");
13  * you may not use this file except in compliance with the License.
14  * You may obtain a copy of the License at
15  *
16  *     http://www.apache.org/licenses/LICENSE-2.0
17  *
18  * Unless required by applicable law or agreed to in writing, software
19  * distributed under the License is distributed on an "AS IS" BASIS,
20  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21  * See the License for the specific language governing permissions and
22  * limitations under the License.
23  *
24  ******************************************************************************/
25 
26 #ifndef LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32680_I2S_H_
27 #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32680_I2S_H_
28 
29 /* **** Includes **** */
30 #include "mxc_sys.h"
31 #include "dma.h"
32 #include "i2s_regs.h"
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 /**
39  * @defgroup i2s Inter-Integrated Sound (I2S)
40  * @ingroup periphlibs
41  * @{
42  */
43 
44 /* **** Definitions **** */
45 
46 /** @brief I2S stereo mode select */
47 typedef enum {
48     MXC_I2S_STEREO = 0,
49     MXC_I2S_MONO_LEFT_CH = 2,
50     MXC_I2S_MONO_RIGHT_CH = 3
51 } mxc_i2s_stereo_t;
52 
53 /** @brief I2S polarity configuration */
54 typedef enum { MXC_I2S_POL_NORMAL, MXC_I2S_POL_INVERSE } mxc_i2s_polarity_t;
55 
56 /** @brief I2S transaction bit order */
57 typedef enum { MXC_I2S_MSB_FIRST, MXC_I2S_LSB_FIRST } mxc_i2s_bitorder_t;
58 
59 /** @brief I2S transaction justify order */
60 typedef enum { MXC_I2S_MSB_JUSTIFY, MXC_I2S_LSB_JUSTIFY } mxc_i2s_justify_t;
61 
62 /** @brief I2S transaction word size.
63  *
64  * Set this field to the desired width for data writes and reads from the FIFO. */
65 typedef enum {
66     MXC_I2S_WSIZE_BYTE, ///< Set 8-bit FIFO transactions
67     MXC_I2S_WSIZE_HALFWORD, ///< Set 16-bit FIFO transactions
68     MXC_I2S_WSIZE_WORD, ///< Set 32-bit FIFO transactions
69 
70     MXC_I2S_DATASIZE_BYTE = MXC_I2S_WSIZE_BYTE, ///< Legacy name.  Use MXC_I2S_WSIZE_BYTE instead.
71     MXC_I2S_DATASIZE_HALFWORD =
72         MXC_I2S_WSIZE_HALFWORD, ///< Legacy name.  Use MXC_I2S_WSIZE_HALFWORD instead.
73     MXC_I2S_DATASIZE_WORD = MXC_I2S_WSIZE_WORD, ///< Legacy name.  Use MXC_I2S_WSIZE_WORD instead.
74 } mxc_i2s_wsize_t;
75 
76 /** @brief  I2S transaction adjust position.
77  *
78  * This field is used to determine which bits are used if the sample size is less than the bits per word.*/
79 typedef enum {
80     MXC_I2S_ADJUST_LEFT,
81     MXC_I2S_ADJUST_RIGHT,
82 } mxc_i2s_adjust_t;
83 
84 /** @brief  I2S channel mode */
85 typedef enum {
86     MXC_I2S_INTERNAL_SCK_WS_0,
87     MXC_I2S_INTERNAL_SCK_WS_1,
88     MXC_I2S_EXTERNAL_SCK_INTERNAL_WS,
89     MXC_I2S_EXTERNAL_SCK_EXTERNAL_WS,
90 } mxc_i2s_ch_mode_t;
91 
92 #define MXC_I2S_SAMPLESIZE_EIGHT (8)
93 #define MXC_I2S_SAMPLESIZE_SIXTEEN (16)
94 #define MXC_I2S_SAMPLESIZE_TWENTY (20)
95 #define MXC_I2S_SAMPLESIZE_TWENTYFOUR (24)
96 #define MXC_I2S_SAMPLESIZE_THIRTYTWO (32)
97 
98 typedef uint8_t mxc_i2s_samplesize_t;
99 
100 /** @brief I2S Configuration Struct
101  *
102  * Most common audio configurations.
103  *  __________________________________________________________________
104  * |   Audio Sample  | bitsWord | sampleSize |        wordSize        |
105  * | Width / Samples |          |            |  \ref mxc_i2s_wsize_t  |
106  * |------------------------------------------------------------------|
107  * |     8 bits / 16 |    8     |      8     |     MXC_I2S_WSIZE_BYTE |
108  * |    16 bits / 32 |   16     |     16     | MXC_I2S_WSIZE_HALFWORD |
109  * |    20 bits / 40 |   20     |     20     |     MXC_I2S_WSIZE_WORD |
110  * |    24 bits / 48 |   24     |     24     |     MXC_I2S_WSIZE_WORD |
111  * |    24 bits / 64 |   32     |     24     |     MXC_I2S_WSIZE_WORD |
112  * |    32 bits / 64 |   32     |     32     |     MXC_I2S_WSIZE_WORD |
113  * |_________________|__________|____________|________________________|
114 */
115 typedef struct {
116     mxc_i2s_ch_mode_t channelMode;
117     mxc_i2s_stereo_t stereoMode;
118     mxc_i2s_wsize_t wordSize;
119     mxc_i2s_justify_t justify;
120     mxc_i2s_bitorder_t bitOrder;
121     mxc_i2s_polarity_t wsPolarity;
122     mxc_i2s_samplesize_t
123         sampleSize; ///< Optional - Between zero and bitsWord. Consider setting 'adjust' field with this.
124     uint16_t clkdiv;
125     mxc_i2s_adjust_t adjust;
126     uint8_t bitsWord; ///< MAX=0x1F.
127     void *rawData;
128     void *txData;
129     void *rxData;
130     uint32_t length;
131 } mxc_i2s_req_t;
132 
133 /* **** Function Prototypes **** */
134 
135 /**
136  * @brief   Initialize I2S resources
137  *
138  * @param   req           see \ref mxc_i2s_req_t I2S Request Struct
139  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
140  */
141 int MXC_I2S_Init(mxc_i2s_req_t *req);
142 
143 /**
144  * @brief   Release I2S, clear configuration and flush FIFOs
145  *
146  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
147  */
148 int MXC_I2S_Shutdown(void);
149 
150 /**
151  * @brief   Configure data to be transmitted based on word and sample size
152  *
153  * @param   req           see \ref mxc_i2s_req_t I2S Request Struct
154  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
155  */
156 int MXC_I2S_ConfigData(mxc_i2s_req_t *req);
157 
158 /**
159  * @brief   Enable TX channel
160  */
161 void MXC_I2S_TXEnable(void);
162 
163 /**
164  * @brief   Disable TX channel
165  */
166 void MXC_I2S_TXDisable(void);
167 
168 /**
169  * @brief   Enable RX channel
170  */
171 void MXC_I2S_RXEnable(void);
172 
173 /**
174  * @brief   Disable RX channel
175  */
176 void MXC_I2S_RXDisable(void);
177 
178 /**
179  * @brief   Set threshold for RX FIFO
180  *
181  * @param   threshold
182  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
183  */
184 int MXC_I2S_SetRXThreshold(uint8_t threshold);
185 
186 /**
187  * @brief   Set I2S Frequency, automatically called by I2S_Init
188  *
189  * @param   mode    Channel mode to select clock
190  * @param   clkdiv  clock divider to set baudrate
191  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
192  */
193 int MXC_I2S_SetFrequency(mxc_i2s_ch_mode_t mode, uint16_t clkdiv);
194 
195 /**
196  * @brief   Flush I2S FIFO
197  *
198  */
199 void MXC_I2S_Flush(void);
200 
201 /**
202  * @brief   Fill I2S FIFO with data to transmit
203  *
204  * @param   txData      Pointer to base address of the data buffer
205  * @param   wordSize    Size of the data samples
206  * @param   len         Number of samples in the data buffer
207  * @param   smpl_cnt    Number of samples already sent from the data buffer
208  *
209  * @returns If successful the number of samples successfuly written to the FIFO. Otherwise, an error code. See \ref MXC_Error_Codes for a list of return codes.
210  */
211 int MXC_I2S_FillTXFIFO(void *txData, mxc_i2s_wsize_t wordSize, int len, int smpl_cnt);
212 
213 /**
214  * @brief   Read audio samples from I2S receive buffer
215  *
216  * @param   rxData      Pointer to data buffer that will store the audio samples
217  * @param   wordSize    Size of the samples in the FIFO
218  * @param   len         Number of samples to read
219  * @param   smpl_cnt    Number of samples already received in the data buffer
220  *
221  * @returns If successful, the number of samples actually read from the buffer. Otherwise, an error code. See \ref MXC_Error_Codes for a list of return codes.
222  */
223 int MXC_I2S_ReadRXFIFO(void *rxData, mxc_i2s_wsize_t wordSize, int len, int smpl_cnt);
224 
225 /**
226  * @brief   Enable Interrupts
227  *
228  * @param   flags   Interrupt mask
229  */
230 void MXC_I2S_EnableInt(uint32_t flags);
231 
232 /**
233  * @brief   Disable Interrupt
234  *
235  * @param   flags   Interrupt mask
236  */
237 void MXC_I2S_DisableInt(uint32_t flags);
238 
239 /**
240  * @brief   Get the set interrupt flags
241  *
242  * @return  int     return the mask of the set interrupt flags
243  */
244 int MXC_I2S_GetFlags(void);
245 
246 /**
247  * @brief   Clears Interrupt Flags
248  *
249  * @param   flags   Interrupt flags to be cleared
250  */
251 void MXC_I2S_ClearFlags(uint32_t flags);
252 
253 /**
254  * @brief   Performs a blocking I2S transaction.
255  *
256  * @param   Pointer to transaction request structure
257  *
258  * @returns If successful, E_NO_ERROR. Otherwise, an error code. See \ref MXC_Error_Codes for a list of return codes.
259  */
260 int MXC_I2S_Transaction(mxc_i2s_req_t *i2s_req);
261 
262 /**
263  * @brief   Sets up an asynchronous I2S transaction.
264  *
265  * @param   Pointer to transaction request structure
266  *
267  * @returns If successful, E_NO_ERROR. Otherwise, an error code. See \ref MXC_Error_Codes for a list of return codes.
268  */
269 int MXC_I2S_TransactionAsync(mxc_i2s_req_t *i2s_req);
270 
271 /**
272  * @brief   Configure TX DMA transaction
273  *
274  * @param   src_addr    source address of data
275  * @param   len         length od the data to be transmitted
276  */
277 int MXC_I2S_TXDMAConfig(void *src_addr, int len);
278 
279 /**
280  * @brief   Configure RX DMA transaction
281  *
282  * @param   dest_addr   destination address
283  * @param   len         length of the data to be received
284  */
285 int MXC_I2S_RXDMAConfig(void *dest_addr, int len);
286 
287 /**
288  * @brief   Handler for asynchronous I2S transactions.
289  */
290 void MXC_I2S_Handler(void);
291 
292 /**
293  * @brief   Set the callback function pointer for I2S DMA transactions
294  *
295  * @param   callback    Function pointer to the DMA callback function
296  */
297 void MXC_I2S_RegisterDMACallback(void (*callback)(int, int));
298 
299 /**
300  * @brief   Sets the callback function for asynchronous I2S transactions
301  *
302  * @param   callback    Function pointer to the asynchronous transaction callback
303  */
304 void MXC_I2S_RegisterAsyncCallback(void (*callback)(int));
305 
306 #ifdef __cplusplus
307 }
308 #endif
309 
310 #endif // LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32680_I2S_H_
311