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_MAX32662_I2S_H_
27 #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32662_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   Sets the clock divider to provide the desired sampling rate.
197  *
198  * @param   smpl_rate   The desired sampling rate.
199  * @param   smpl_sz     The size of each sample.
200  *
201  * @return  If successful, the actual sampling rate. Otherwise, an error code. See \ref MXC_Error_Codes for a list of return codes.
202  */
203 int MXC_I2S_SetSampleRate(uint32_t smpl_rate, mxc_i2s_wsize_t smpl_sz);
204 
205 /**
206  * @brief   Returns the current sampling rate.
207  *
208  * @return  If successful, sampling rate. Otherwise, an error code. See \ref MXC_Error_Codes for a list of return codes.
209  */
210 int MXC_I2S_GetSampleRate(void);
211 
212 /**
213  * @brief   Calculates the value of the clock divider that should be used in order to get the desired sampling frequency.
214  *
215  * @param   smpl_rate   Desired sampling rate.
216  * @param   smple_sz    The size of each I2S word.
217  *
218  * @return  If successful, the clock divider value. Otherwise, an error code. See \ref MXC_Error_Codes for a list of return codes.
219  */
220 int MXC_I2S_CalculateClockDiv(uint32_t smpl_rate, mxc_i2s_wsize_t smpl_sz);
221 
222 /**
223  * @brief   Flush I2S FIFO
224  *
225  */
226 void MXC_I2S_Flush(void);
227 
228 /**
229  * @brief   Fill I2S FIFO with data to transmit
230  *
231  * @param   txData      Pointer to base address of the data buffer
232  * @param   wordSize    Size of the data samples
233  * @param   len         Number of samples in the data buffer
234  * @param   smpl_cnt    Number of samples already sent from the data buffer
235  *
236  * @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.
237  */
238 int MXC_I2S_FillTXFIFO(void *txData, mxc_i2s_wsize_t wordSize, int len, int smpl_cnt);
239 
240 /**
241  * @brief   Read audio samples from I2S receive buffer
242  *
243  * @param   rxData      Pointer to data buffer that will store the audio samples
244  * @param   wordSize    Size of the samples in the FIFO
245  * @param   len         Number of samples to read
246  * @param   smpl_cnt    Number of samples already received in the data buffer
247  *
248  * @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.
249  */
250 int MXC_I2S_ReadRXFIFO(void *rxData, mxc_i2s_wsize_t wordSize, int len, int smpl_cnt);
251 
252 /**
253  * @brief   Enable Interrupts
254  *
255  * @param   flags   Interrupt mask
256  */
257 void MXC_I2S_EnableInt(uint32_t flags);
258 
259 /**
260  * @brief   Disable Interrupt
261  *
262  * @param   flags   Interrupt mask
263  */
264 void MXC_I2S_DisableInt(uint32_t flags);
265 
266 /**
267  * @brief   Get the set interrupt flags
268  *
269  * @return  int     return the mask of the set interrupt flags
270  */
271 int MXC_I2S_GetFlags(void);
272 
273 /**
274  * @brief   Clears Interrupt Flags
275  *
276  * @param   flags   Interrupt flags to be cleared
277  */
278 void MXC_I2S_ClearFlags(uint32_t flags);
279 
280 /**
281  * @brief   Performs a blocking I2S transaction.
282  *
283  * @param   Pointer to transaction request structure
284  *
285  * @returns If successful, E_NO_ERROR. Otherwise, an error code. See \ref MXC_Error_Codes for a list of return codes.
286  */
287 int MXC_I2S_Transaction(mxc_i2s_req_t *i2s_req);
288 
289 /**
290  * @brief   Sets up an asynchronous I2S transaction.
291  *
292  * @param   Pointer to transaction request structure
293  *
294  * @returns If successful, E_NO_ERROR. Otherwise, an error code. See \ref MXC_Error_Codes for a list of return codes.
295  */
296 int MXC_I2S_TransactionAsync(mxc_i2s_req_t *i2s_req);
297 
298 /**
299  * @brief   Configure TX DMA transaction
300  *
301  * @param   src_addr    source address of data
302  * @param   len         length od the data to be transmitted
303  *
304  * @return  If successful, the DMA channel number used for the request. Otherwise, an error code. See \ref MXC_Error_Codes for a list of return codes.
305  */
306 int MXC_I2S_TXDMAConfig(void *src_addr, int len);
307 
308 /**
309  * @brief   Configure RX DMA transaction
310  *
311  * @param   dest_addr   destination address
312  * @param   len         length of the data to be received
313  *
314  * @return  If successful, the DMA channel number used for the request. Otherwise, an error code. See \ref MXC_Error_Codes for a list of return codes.
315  */
316 int MXC_I2S_RXDMAConfig(void *dest_addr, int len);
317 
318 /**
319  * @brief   Handler for asynchronous I2S transactions.
320  */
321 void MXC_I2S_Handler(void);
322 
323 /**
324  * @brief   Set the callback function pointer for I2S DMA transactions
325  *
326  * @param   callback    Function pointer to the DMA callback function
327  */
328 void MXC_I2S_RegisterDMACallback(void (*callback)(int, int));
329 
330 /**
331  * @brief   Sets the callback function for asynchronous I2S transactions
332  *
333  * @param   callback    Function pointer to the asynchronous transaction callback
334  */
335 void MXC_I2S_RegisterAsyncCallback(void (*callback)(int));
336 
337 #ifdef __cplusplus
338 }
339 #endif
340 
341 #endif // LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32662_I2S_H_
342