1 /*
2  * Copyright (C) 2017-2020 Alibaba Group Holding Limited
3  */
4 
5 /******************************************************************************
6  * @file     drv/i2s.h
7  * @brief    header file for i2s driver
8  * @version  V1.0
9  * @date     16. Mar 2020
10  * @model    i2s
11  ******************************************************************************/
12 
13 #ifndef _DRV_I2S_H_
14 #define _DRV_I2S_H_
15 
16 #include <stdint.h>
17 #include <stdbool.h>
18 #include <drv/common.h>
19 #include <drv/dma.h>
20 #include "drv/ringbuffer.h"
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 typedef enum {
27     I2S_MODE_MASTER,                                     ///< I2s transmitter master mode
28     I2S_MODE_SLAVE,                                      ///< I2s transmitter slave mode
29 } csi_i2s_mode_t;
30 
31 typedef enum {
32     I2S_PROTOCOL_I2S,                                    ///< I2S protocol
33     I2S_PROTOCOL_MSB_JUSTIFIED,                          ///< MSB (left) justified protocol
34     I2S_PROTOCOL_LSB_JUSTIFIED,                          ///< LSB (right) justified protocol
35     I2S_PROTOCOL_PCM,                                    ///< PCM protocol
36 } csi_i2s_protocol_t;
37 
38 typedef enum {
39     I2S_LEFT_POLARITY_LOW,                               ///< Low level represents the left channel
40     I2S_LEFT_POLARITY_HIGH,                              ///< High level represents the left channel
41 } csi_i2s_ws_left_polarity_t;
42 
43 typedef enum {
44     I2S_SAMPLE_RATE_8000              = 8000U,           ///< I2S sample rate is 8000
45     I2S_SAMPLE_RATE_11025             = 11025U,
46     I2S_SAMPLE_RATE_12000             = 12000U,
47     I2S_SAMPLE_RATE_16000             = 16000U,
48     I2S_SAMPLE_RATE_22050             = 22050U,
49     I2S_SAMPLE_RATE_24000             = 24000U,
50     I2S_SAMPLE_RATE_32000             = 32000U,
51     I2S_SAMPLE_RATE_44100             = 44100U,
52     I2S_SAMPLE_RATE_48000             = 48000U,
53     I2S_SAMPLE_RATE_96000             = 96000U,
54     I2S_SAMPLE_RATE_192000            = 192000U,
55     I2S_SAMPLE_RATE_256000            = 256000U,
56 } csi_i2s_sample_rate_t;
57 
58 typedef enum {
59     I2S_SAMPLE_WIDTH_16BIT = 16U,                        ///< I2S sample width is 16bit
60     I2S_SAMPLE_WIDTH_24BIT = 24U,
61     I2S_SAMPLE_WIDTH_32BIT = 32U,
62 } csi_i2s_sample_width_t;
63 
64 typedef enum {
65     I2S_SCLK_16FS = 16U,                                ///< SCLK frequency is 16 times that of I2S sample rate
66     I2S_SCLK_32FS = 32U,
67     I2S_SCLK_48FS = 48U,
68     I2S_SCLK_64FS = 64U,
69 } csi_i2s_sclk_freq_t;
70 
71 typedef enum {
72     I2S_MCLK_256FS = 256U,                              ///< MCLK frequency is 256 times that of I2S sample rate
73     I2S_MCLK_384FS = 384U,
74 } csi_i2s_mclk_freq_t;
75 
76 typedef struct {
77     csi_i2s_mode_t             mode;                    ///< I2S work mode
78     csi_i2s_protocol_t         protocol;                ///< Protocols used by I2S
79     csi_i2s_ws_left_polarity_t polarity;                ///< left channel polarity
80     csi_i2s_sample_rate_t      rate;                    ///< I2S sample rate
81     csi_i2s_sample_width_t     width;                   ///< I2S sample width
82     csi_i2s_sclk_freq_t        sclk_nfs;                ///< SCLK frequency is N times that of I2S sample rate
83     csi_i2s_mclk_freq_t        mclk_nfs;                ///< MCLK frequency is N times that of I2S sample rate
84 } csi_i2s_format_t;
85 
86 typedef enum {
87     I2S_LEFT_CHANNEL,
88     I2S_RIGHT_CHANNEL,
89     I2S_LEFT_RIGHT_CHANNEL,
90 } csi_i2s_sound_channel_t;
91 
92 typedef enum {
93     I2S_EVENT_SEND_COMPLETE,
94     I2S_EVENT_RECEIVE_COMPLETE,
95     I2S_EVENT_TX_BUFFER_EMPTY,
96     I2S_EVENT_RX_BUFFER_FULL,
97     I2S_EVENT_ERROR_OVERFLOW,
98     I2S_EVENT_ERROR_UNDERFLOW,
99     I2S_EVENT_ERROR,
100 } csi_i2s_event_t;
101 
102 typedef struct csi_i2s csi_i2s_t;
103 
104 struct csi_i2s {
105     csi_dev_t               dev;                ///< I2S hw-device info
106     void (*callback)(csi_i2s_t *i2s, csi_i2s_event_t event, void *arg); ///< I2S event callback for user
107     void                    *arg;               ///< user private param passed to user callback
108     ringbuffer_t            *tx_buf;            ///< I2S send buffer
109     ringbuffer_t            *rx_buf;            ///< I2S receive buffer
110     csi_dma_ch_t            *tx_dma;            ///< send dma channel handle
111     csi_dma_ch_t            *rx_dma;            ///< receive dma channel handle
112     uint32_t                tx_period;          ///< I2S send period num data will callback
113     uint32_t                rx_period;          ///< I2S receive period num data will callback
114     csi_state_t             state;              ///< I2S communication state
115     void                    *priv;
116 };
117 
118 /**
119   \brief       Init i2s
120   \param[in]   i2s    I2s handle to operate
121   \param[in]   idx    I2s interface idx
122   \return      error code \ref csi_error_t
123 */
124 csi_error_t csi_i2s_init(csi_i2s_t *i2s, uint32_t idx);
125 
126 /**
127   \brief       Uninit i2s
128   \param[in]   i2s    I2s handle to operate
129   \return      none
130 */
131 void csi_i2s_uninit(csi_i2s_t *i2s);
132 
133 /**
134   \brief       Enable i2s
135   \param[in]   i2s   I2s handle to operate
136   \param[in]   en    True enable, False disable
137   \return      None
138 */
139 void csi_i2s_enable(csi_i2s_t *i2s, bool enable);
140 
141 /**
142   \brief       I2s config format
143   \param[in]   i2s       I2s handle to operate
144   \param[in]   format    I2s config param \ref csi_i2s_format_t
145   \return      error code \ref csi_error_t
146 */
147 csi_error_t csi_i2s_format(csi_i2s_t *i2s, csi_i2s_format_t *format);
148 
149 /**
150   \brief       Set the i2s tx mono
151   \param[in]   i2s   I2s handle to operate
152   \param[in]   ch    Mono channel selection
153   \return      error code \ref csi_error_t
154 */
155 csi_error_t csi_i2s_tx_select_sound_channel(csi_i2s_t *i2s, csi_i2s_sound_channel_t ch);
156 
157 /**
158   \brief       Set the i2s rx mono
159   \param[in]   i2s   I2s handle to operate
160   \param[in]   ch    Mono channel selection
161   \return      error code \ref csi_error_t
162 */
163 csi_error_t csi_i2s_rx_select_sound_channel(csi_i2s_t *i2s, csi_i2s_sound_channel_t ch);
164 
165 /**
166   \brief       Link DMA channel to i2s device
167   \param[in]   i2s       I2s handle to operate
168   \param[in]   rx_dma    The DMA channel  for receive, when it is NULL means to unused dma
169   \return      error code \ref csi_error_t
170 */
171 csi_error_t csi_i2s_rx_link_dma(csi_i2s_t *i2s, csi_dma_ch_t *rx_dma);
172 
173 /**
174   \brief       Link DMA channel to i2s device
175   \param[in]   i2s       I2s handle to operate
176   \param[in]   tx_dma    The DMA channel for send, when it is NULL means to unused dma
177   \return      error code \ref csi_error_t
178 */
179 csi_error_t csi_i2s_tx_link_dma(csi_i2s_t *i2s, csi_dma_ch_t *tx_dma);
180 
181 /**
182   \brief       I2s rx buffer config
183   \param[in]   i2s       I2s handle to operate
184   \param[in]   buffer    I2s rx buffer
185   \return      None
186 */
187 void csi_i2s_rx_set_buffer(csi_i2s_t *i2s, ringbuffer_t *buffer);
188 
189 /**
190   \brief       I2s tx buffer config
191   \param[in]   i2s       I2s handle to operate
192   \param[in]   buffer    I2s tx buffer
193   \return      None
194 */
195 void csi_i2s_tx_set_buffer(csi_i2s_t *i2s, ringbuffer_t *buffer);
196 
197 /**
198   \brief       I2s rx set period.The value of period is to report a receive completion event
199                after each period value data is received
200   \param[in]   i2s       I2s handle to operate
201   \param[in]   period    I2s rx period
202   \return      error code \ref csi_error_t
203 */
204 csi_error_t csi_i2s_rx_set_period(csi_i2s_t *i2s, uint32_t period);
205 
206 /**
207   \brief       I2s tx set period.The value of period is to report a receive completion event
208                after each period value data is send
209   \param[in]   i2s       I2s handle to operate
210   \param[in]   period    I2s tx period
211   \return      error code \ref csi_error_t
212 */
213 csi_error_t csi_i2s_tx_set_period(csi_i2s_t *i2s, uint32_t period);
214 
215 /**
216   \brief       Get rx ringbuffer buffer free space
217   \param[in]   i2s    I2s handle to operate
218   \return      Buffer free space (bytes)
219 */
220 uint32_t csi_i2s_rx_buffer_avail(csi_i2s_t *i2s);
221 
222 /**
223   \brief       Get rx ringbuffer buffer used space
224   \param[in]   i2s    I2s handle to operate
225   \return      Buffer used space (bytes)
226 */
227 uint32_t csi_i2s_rx_buffer_remain(csi_i2s_t *i2s);
228 
229 /**
230   \brief       Reset the rx ringbuffer, discard all data in the buffer
231   \param[in]   i2s    I2s handle to operate
232   \return      error code \ref csi_error_t
233 */
234 csi_error_t csi_i2s_rx_buffer_reset(csi_i2s_t *i2s);
235 
236 /**
237   \brief        Get tx ringbuffer buffer free space
238   \param[in]    i2s    I2s handle to operate
239   \return       Buffer free space (bytes)
240 */
241 uint32_t    csi_i2s_tx_buffer_avail(csi_i2s_t *i2s);
242 
243 /**
244   \brief        Get tx ringbuffer buffer used space
245   \param[in]    i2s    I2s handle to operate
246   \return       Buffer used space (bytes)
247 */
248 uint32_t    csi_i2s_tx_buffer_remain(csi_i2s_t *i2s);
249 
250 /**
251   \brief       Reset the tx ringbuffer, discard all data in the buffer
252   \param[in]   i2s    Handle to operate
253   \return      error code \ref csi_error_t
254 */
255 csi_error_t csi_i2s_tx_buffer_reset(csi_i2s_t *i2s);
256 
257 /**
258   \brief       Send an amount of data to buffer in blocking mode
259   \param[in]   i2s     Operate handle
260   \param[in]   data    Pointer to send data buffer
261   \param[in]   size    Send data size
262   \return      The num of data witch is send successful
263 */
264 int32_t    csi_i2s_send(csi_i2s_t *i2s, const void *data, uint32_t size);
265 
266 /**
267   \brief       Receive an amount of data to buffer in blocking mode
268   \param[in]   i2s     Operate handle
269   \param[out]  data    Pointer to receive data buffer
270   \param[in]   size    Receive data size
271   \return      The size of data receive successfully
272 */
273 int32_t    csi_i2s_receive(csi_i2s_t *i2s, const void *data, uint32_t size);
274 
275 /**
276   \brief       Write data to the buffer
277                With asynchronous sending
278                The data is first written to the buffer and then output through the i2s interface
279                Return value is the number of data that was successfully written to the buffer
280   \param[in]   i2s     Operate handle
281   \param[in]   data    Pointer to send data buffer
282   \param[in]   size    Send data size
283   \return      The data size that write to buffer
284 */
285 uint32_t    csi_i2s_send_async(csi_i2s_t *i2s, const void *data, uint32_t size);
286 
287 /**
288   \brief       Read data from the buffer
289                Using asynchronous receive, i2s writes the received data to the buffer
290                This function reads data from the buffer, returns the number of successful reads
291                Returns 0 if there is no data in the buffer
292   \param[in]   i2s     Operate handle
293   \param[out]  data    Pointer to receive data buffer
294   \param[in]   size    Receive data size
295   \return      The size of data read successfully
296 */
297 uint32_t    csi_i2s_receive_async(csi_i2s_t *i2s, const void *data, uint32_t size);
298 
299 /**
300   \brief       Start i2s pause asynchronous send
301   \param[in]   i2s    Operate handle
302   \return      error code \ref csi_error_t
303 */
304 csi_error_t csi_i2s_send_pause(csi_i2s_t *i2s);
305 
306 /**
307   \brief       Start i2s resume asynchronous send
308   \param[in]   i2s    Operate handle
309   \return      error code \ref csi_error_t
310 */
311 csi_error_t csi_i2s_send_resume(csi_i2s_t *i2s);
312 
313 /**
314   \brief       Start i2s asynchronous send
315   \param[in]   i2s    Operate handle
316   \return      error code \ref csi_error_t
317 */
318 csi_error_t csi_i2s_send_start(csi_i2s_t *i2s);
319 
320 /**
321   \brief       Start i2s asynchronous receive
322   \param[in]   i2s    Operate handle
323   \return      error code \ref csi_error_t
324 */
325 csi_error_t csi_i2s_receive_start(csi_i2s_t *i2s);
326 
327 /**
328   \brief       Stop i2s asynchronous send
329   \param[in]   i2s    Operate handle
330   \return      None
331 */
332 void csi_i2s_send_stop(csi_i2s_t *i2s);
333 
334 /**
335   \brief       Stop i2s asynchronous receive
336   \param[in]   i2s    Operate handle
337   \return      None
338 */
339 void csi_i2s_receive_stop(csi_i2s_t *i2s);
340 
341 /**
342   \brief       Attach the callback handler to i2s
343   \param[in]   i2s    Operate handle
344   \param[in]   cb     Callback function
345   \param[in]   arg    User private param
346   \return      error code \ref csi_error_t
347 */
348 csi_error_t csi_i2s_attach_callback(csi_i2s_t *i2s, void *callback, void *arg);
349 
350 /**
351   \brief       Detach the callback handler
352   \param[in]   i2s    Operate handle
353   \return      None
354 */
355 void csi_i2s_detach_callback(csi_i2s_t *i2s);
356 
357 /**
358   \brief       Get i2s status
359   \param[in]   i2s      I2s handle to operate
360   \param[out]  state    I2s state
361   \return      error code \ref csi_error_t
362 */
363 csi_error_t csi_i2s_get_state(csi_i2s_t *i2s, csi_state_t *state);
364 
365 /**
366   \brief       Enable i2s power manage
367   \param[in]   i2s    I2s handle to operate
368   \return      error code \ref csi_error_t
369 */
370 csi_error_t csi_i2s_enable_pm(csi_i2s_t *i2s);
371 
372 /**
373   \brief       Disable i2s power manage
374   \param[in]   i2s    I2s handle to operate
375   \return      None
376 */
377 void csi_i2s_disable_pm(csi_i2s_t *i2s);
378 
379 #ifdef __cplusplus
380 }
381 #endif
382 
383 #endif /* _DRV_I2S_H_ */
384