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