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_MAX32655_I2S_H_
27 #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32655_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 polarity configuration */
63 typedef enum { MXC_I2S_CLKSRC_ERFO, MXC_I2S_CLKSRC_EXT } mxc_i2s_clksrc_t;
64 
65 /** @brief I2S transaction word size.
66  *
67  * Set this field to the desired width for data writes and reads from the FIFO. */
68 typedef enum {
69     MXC_I2S_WSIZE_BYTE, ///< Set 8-bit FIFO transactions
70     MXC_I2S_WSIZE_HALFWORD, ///< Set 16-bit FIFO transactions
71     MXC_I2S_WSIZE_WORD, ///< Set 32-bit FIFO transactions
72 
73     MXC_I2S_DATASIZE_BYTE = MXC_I2S_WSIZE_BYTE, ///< Legacy name.  Use MXC_I2S_WSIZE_BYTE instead.
74     MXC_I2S_DATASIZE_HALFWORD =
75         MXC_I2S_WSIZE_HALFWORD, ///< Legacy name.  Use MXC_I2S_WSIZE_HALFWORD instead.
76     MXC_I2S_DATASIZE_WORD = MXC_I2S_WSIZE_WORD, ///< Legacy name.  Use MXC_I2S_WSIZE_WORD instead.
77 } mxc_i2s_wsize_t;
78 
79 /** @brief  I2S transaction adjust position.
80  *
81  * This field is used to determine which bits are used if the sample size is less than the bits per word.*/
82 typedef enum {
83     MXC_I2S_ADJUST_LEFT,
84     MXC_I2S_ADJUST_RIGHT,
85 } mxc_i2s_adjust_t;
86 
87 /** @brief  I2S channel mode */
88 typedef enum {
89     MXC_I2S_INTERNAL_SCK_WS_0,
90     MXC_I2S_INTERNAL_SCK_WS_1,
91     MXC_I2S_EXTERNAL_SCK_INTERNAL_WS,
92     MXC_I2S_EXTERNAL_SCK_EXTERNAL_WS,
93 } mxc_i2s_ch_mode_t;
94 
95 #define MXC_I2S_SAMPLESIZE_EIGHT (8)
96 #define MXC_I2S_SAMPLESIZE_SIXTEEN (16)
97 #define MXC_I2S_SAMPLESIZE_TWENTY (20)
98 #define MXC_I2S_SAMPLESIZE_TWENTYFOUR (24)
99 #define MXC_I2S_SAMPLESIZE_THIRTYTWO (32)
100 
101 typedef uint8_t mxc_i2s_samplesize_t;
102 
103 /** @brief I2S Configuration Struct
104  *
105  * Most common audio configurations.
106  *  __________________________________________________________________
107  * |   Audio Sample  | bitsWord | sampleSize |        wordSize        |
108  * | Width / Samples |          |            |  \ref mxc_i2s_wsize_t  |
109  * |------------------------------------------------------------------|
110  * |     8 bits / 16 |    8     |      8     |     MXC_I2S_WSIZE_BYTE |
111  * |    16 bits / 32 |   16     |     16     | MXC_I2S_WSIZE_HALFWORD |
112  * |    20 bits / 40 |   20     |     20     |     MXC_I2S_WSIZE_WORD |
113  * |    24 bits / 48 |   24     |     24     |     MXC_I2S_WSIZE_WORD |
114  * |    24 bits / 64 |   32     |     24     |     MXC_I2S_WSIZE_WORD |
115  * |    32 bits / 64 |   32     |     32     |     MXC_I2S_WSIZE_WORD |
116  * |_________________|__________|____________|________________________|
117 */
118 typedef struct {
119     mxc_i2s_ch_mode_t channelMode;
120     mxc_i2s_stereo_t stereoMode;
121     mxc_i2s_wsize_t wordSize;
122     mxc_i2s_justify_t justify;
123     mxc_i2s_bitorder_t bitOrder;
124     mxc_i2s_polarity_t wsPolarity;
125     mxc_i2s_samplesize_t
126         sampleSize; ///< Optional - Between zero and bitsWord. Consider setting 'adjust' field with this.
127     uint16_t clkdiv;
128     mxc_i2s_adjust_t adjust;
129     uint8_t bitsWord; ///< MAX=0x1F.
130     void *rawData;
131     void *txData;
132     void *rxData;
133     uint32_t length;
134 } mxc_i2s_req_t;
135 
136 /* **** Function Prototypes **** */
137 
138 /**
139  * @brief   Initialize I2S resources
140  *
141  * @param   req           see \ref mxc_i2s_req_t I2S Request Struct
142  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
143  */
144 int MXC_I2S_Init(mxc_i2s_req_t *req);
145 
146 /**
147  * @brief   Release I2S, clear configuration and flush FIFOs
148  *
149  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
150  */
151 int MXC_I2S_Shutdown(void);
152 
153 /**
154  * @brief   Configure data to be transmitted based on word and sample size
155  *
156  * @param   req           see \ref mxc_i2s_req_t I2S Request Struct
157  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
158  */
159 int MXC_I2S_ConfigData(mxc_i2s_req_t *req);
160 
161 /**
162  * @brief   This function enables and selects the source clock for I2S master mode. By default
163  *          the driver assumes the ERFO will be used so this function only needs to be called
164  *          if switching to/from the external clock is required for the application.
165  *
166  * @warning This function should be called before MXC_I2S_SetSampleRate, MXC_I2S_GetSampleRate, and
167  *          MXC_I2S_CalculateClockDiv to ensure they operate correctly.
168  *
169  * @param   clk_src     Selects which clock source to use.
170  * @param   freq_ext    Frequency of the clock source. This param only required if
171  *                      MXC_I2S_CLKSRC_EXT selected for clk_src.
172  *
173  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
174  */
175 int MXC_I2S_SelectClockSource(mxc_i2s_clksrc_t clk_src, uint32_t freq_ext);
176 
177 /**
178  * @brief   Enable TX channel
179  */
180 void MXC_I2S_TXEnable(void);
181 
182 /**
183  * @brief   Disable TX channel
184  */
185 void MXC_I2S_TXDisable(void);
186 
187 /**
188  * @brief   Enable RX channel
189  */
190 void MXC_I2S_RXEnable(void);
191 
192 /**
193  * @brief   Disable RX channel
194  */
195 void MXC_I2S_RXDisable(void);
196 
197 /**
198  * @brief   Set threshold for RX FIFO
199  *
200  * @param   threshold
201  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
202  */
203 int MXC_I2S_SetRXThreshold(uint8_t threshold);
204 
205 /**
206  * @brief   Set I2S Frequency, automatically called by I2S_Init
207  *
208  * @param   mode    Channel mode to select clock
209  * @param   clkdiv  clock divider to set baudrate
210  * @return  Success/Fail, see \ref MXC_Error_Codes for a list of return codes.
211  */
212 int MXC_I2S_SetFrequency(mxc_i2s_ch_mode_t mode, uint16_t clkdiv);
213 
214 /**
215  * @brief   Sets the clock divider to provide the desired sampling rate.
216  *
217  * @param   smpl_rate   The desired sampling rate.
218  * @param   smpl_sz     The size of each sample.
219  *
220  * @return  If successful, the actual sampling rate. Otherwise, an error code. See \ref MXC_Error_Codes for a list of return codes.
221  */
222 int MXC_I2S_SetSampleRate(uint32_t smpl_rate, mxc_i2s_wsize_t smpl_sz);
223 
224 /**
225  * @brief   Returns the current sampling rate.
226  *
227  * @return  If successful, sampling rate. Otherwise, an error code. See \ref MXC_Error_Codes for a list of return codes.
228  */
229 int MXC_I2S_GetSampleRate(void);
230 
231 /**
232  * @brief   Calculates the value of the clock divider that should be used in order to get the desired sampling frequency.
233  *
234  * @param   smpl_rate   Desired sampling rate.
235  * @param   smple_sz    The size of each I2S word.
236  *
237  * @return  If successful, the clock divider value. Otherwise, an error code. See \ref MXC_Error_Codes for a list of return codes.
238  */
239 int MXC_I2S_CalculateClockDiv(uint32_t smpl_rate, mxc_i2s_wsize_t smpl_sz);
240 
241 /**
242  * @brief   Flush I2S FIFO
243  *
244  */
245 void MXC_I2S_Flush(void);
246 
247 /**
248  * @brief   Fill I2S FIFO with data to transmit
249  *
250  * @param   txData      Pointer to base address of the data buffer
251  * @param   wordSize    Size of the data samples
252  * @param   len         Number of samples in the data buffer
253  * @param   smpl_cnt    Number of samples already sent from the data buffer
254  *
255  * @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.
256  */
257 int MXC_I2S_FillTXFIFO(void *txData, mxc_i2s_wsize_t wordSize, int len, int smpl_cnt);
258 
259 /**
260  * @brief   Read audio samples from I2S receive buffer
261  *
262  * @param   rxData      Pointer to data buffer that will store the audio samples
263  * @param   wordSize    Size of the samples in the FIFO
264  * @param   len         Number of samples to read
265  * @param   smpl_cnt    Number of samples already received in the data buffer
266  *
267  * @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.
268  */
269 int MXC_I2S_ReadRXFIFO(void *rxData, mxc_i2s_wsize_t wordSize, int len, int smpl_cnt);
270 
271 /**
272  * @brief   Enable Interrupts
273  *
274  * @param   flags   Interrupt mask
275  */
276 void MXC_I2S_EnableInt(uint32_t flags);
277 
278 /**
279  * @brief   Disable Interrupt
280  *
281  * @param   flags   Interrupt mask
282  */
283 void MXC_I2S_DisableInt(uint32_t flags);
284 
285 /**
286  * @brief   Get the set interrupt flags
287  *
288  * @return  int     return the mask of the set interrupt flags
289  */
290 int MXC_I2S_GetFlags(void);
291 
292 /**
293  * @brief   Clears Interrupt Flags
294  *
295  * @param   flags   Interrupt flags to be cleared
296  */
297 void MXC_I2S_ClearFlags(uint32_t flags);
298 
299 /**
300  * @brief   Performs a blocking I2S transaction.
301  *
302  * @param   Pointer to transaction request structure
303  *
304  * @returns If successful, E_NO_ERROR. Otherwise, an error code. See \ref MXC_Error_Codes for a list of return codes.
305  */
306 int MXC_I2S_Transaction(mxc_i2s_req_t *i2s_req);
307 
308 /**
309  * @brief   Sets up an asynchronous I2S transaction.
310  *
311  * @param   Pointer to transaction request structure
312  *
313  * @returns If successful, E_NO_ERROR. Otherwise, an error code. See \ref MXC_Error_Codes for a list of return codes.
314  */
315 int MXC_I2S_TransactionAsync(mxc_i2s_req_t *i2s_req);
316 
317 /**
318  * @brief   Configure TX DMA transaction
319  *
320  * @param   src_addr    source address of data
321  * @param   len         length od the data to be transmitted
322  *
323  * @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.
324  */
325 int MXC_I2S_TXDMAConfig(void *src_addr, int len);
326 
327 /**
328  * @brief   Configure RX DMA transaction
329  *
330  * @param   dest_addr   destination address
331  * @param   len         length of the data to be received
332  *
333  * @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.
334  */
335 int MXC_I2S_RXDMAConfig(void *dest_addr, int len);
336 
337 /**
338  * @brief   Handler for asynchronous I2S transactions.
339  */
340 void MXC_I2S_Handler(void);
341 
342 /**
343  * @brief   Set the callback function pointer for I2S DMA transactions
344  *
345  * @param   callback    Function pointer to the DMA callback function
346  */
347 void MXC_I2S_RegisterDMACallback(void (*callback)(int, int));
348 
349 /**
350  * @brief   Sets the callback function for asynchronous I2S transactions
351  *
352  * @param   callback    Function pointer to the asynchronous transaction callback
353  */
354 void MXC_I2S_RegisterAsyncCallback(void (*callback)(int));
355 
356 #ifdef __cplusplus
357 }
358 #endif
359 
360 #endif // LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32655_I2S_H_
361