1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * o Redistributions of source code must retain the above copyright notice, this list
9  *   of conditions and the following disclaimer.
10  *
11  * o Redistributions in binary form must reproduce the above copyright notice, this
12  *   list of conditions and the following disclaimer in the documentation and/or
13  *   other materials provided with the distribution.
14  *
15  * o Neither the name of the copyright holder nor the names of its
16  *   contributors may be used to endorse or promote products derived from this
17  *   software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 #ifndef _FSL_SAI_EDMA_H_
31 #define _FSL_SAI_EDMA_H_
32 
33 #include "fsl_sai.h"
34 #include "fsl_edma.h"
35 
36 /*!
37  * @addtogroup sai_edma
38  * @{
39  */
40 
41 /*******************************************************************************
42  * Definitions
43  ******************************************************************************/
44 
45 typedef struct _sai_edma_handle sai_edma_handle_t;
46 
47 /*! @brief SAI eDMA transfer callback function for finish and error */
48 typedef void (*sai_edma_callback_t)(I2S_Type *base, sai_edma_handle_t *handle, status_t status, void *userData);
49 
50 /*! @brief SAI DMA transfer handle, users should not touch the content of the handle.*/
51 struct _sai_edma_handle
52 {
53     edma_handle_t *dmaHandle;                     /*!< DMA handler for SAI send */
54     uint8_t nbytes;                               /*!< eDMA minor byte transfer count initially configured. */
55     uint8_t bytesPerFrame;                        /*!< Bytes in a frame */
56     uint8_t channel;                              /*!< Which data channel */
57     uint8_t count;                                /*!< The transfer data count in a DMA request */
58     uint32_t state;                               /*!< Internal state for SAI eDMA transfer */
59     sai_edma_callback_t callback;                 /*!< Callback for users while transfer finish or error occurs */
60     void *userData;                               /*!< User callback parameter */
61     edma_tcd_t tcd[SAI_XFER_QUEUE_SIZE + 1U];     /*!< TCD pool for eDMA transfer. */
62     sai_transfer_t saiQueue[SAI_XFER_QUEUE_SIZE]; /*!< Transfer queue storing queued transfer. */
63     size_t transferSize[SAI_XFER_QUEUE_SIZE];     /*!< Data bytes need to transfer */
64     volatile uint8_t queueUser;                   /*!< Index for user to queue transfer. */
65     volatile uint8_t queueDriver;                 /*!< Index for driver to get the transfer data and size */
66 };
67 
68 /*******************************************************************************
69  * APIs
70  ******************************************************************************/
71 #if defined(__cplusplus)
72 extern "C" {
73 #endif
74 
75 /*!
76  * @name eDMA Transactional
77  * @{
78  */
79 
80 /*!
81  * @brief Initializes the SAI eDMA handle.
82  *
83  * This function initializes the SAI master DMA handle, which can be used for other SAI master transactional APIs.
84  * Usually, for a specified SAI instance, call this API once to get the initialized handle.
85  *
86  * @param base SAI base pointer.
87  * @param handle SAI eDMA handle pointer.
88  * @param base SAI peripheral base address.
89  * @param callback Pointer to user callback function.
90  * @param userData User parameter passed to the callback function.
91  * @param dmaHandle eDMA handle pointer, this handle shall be static allocated by users.
92  */
93 void SAI_TransferTxCreateHandleEDMA(
94     I2S_Type *base, sai_edma_handle_t *handle, sai_edma_callback_t callback, void *userData, edma_handle_t *dmaHandle);
95 
96 /*!
97  * @brief Initializes the SAI Rx eDMA handle.
98  *
99  * This function initializes the SAI slave DMA handle, which can be used for other SAI master transactional APIs.
100  * Usually, for a specified SAI instance, call this API once to get the initialized handle.
101  *
102  * @param base SAI base pointer.
103  * @param handle SAI eDMA handle pointer.
104  * @param base SAI peripheral base address.
105  * @param callback Pointer to user callback function.
106  * @param userData User parameter passed to the callback function.
107  * @param dmaHandle eDMA handle pointer, this handle shall be static allocated by users.
108  */
109 void SAI_TransferRxCreateHandleEDMA(
110     I2S_Type *base, sai_edma_handle_t *handle, sai_edma_callback_t callback, void *userData, edma_handle_t *dmaHandle);
111 
112 /*!
113  * @brief Configures the SAI Tx audio format.
114  *
115  * The audio format can be changed at run-time. This function configures the sample rate and audio data
116  * format to be transferred. This function also sets the eDMA parameter according to formatting requirements.
117  *
118  * @param base SAI base pointer.
119  * @param handle SAI eDMA handle pointer.
120  * @param format Pointer to SAI audio data format structure.
121  * @param mclkSourceClockHz SAI master clock source frequency in Hz.
122  * @param bclkSourceClockHz SAI bit clock source frequency in Hz. If bit clock source is master
123  * clock, this value should equals to masterClockHz in format.
124  * @retval kStatus_Success Audio format set successfully.
125  * @retval kStatus_InvalidArgument The input argument is invalid.
126 */
127 void SAI_TransferTxSetFormatEDMA(I2S_Type *base,
128                                  sai_edma_handle_t *handle,
129                                  sai_transfer_format_t *format,
130                                  uint32_t mclkSourceClockHz,
131                                  uint32_t bclkSourceClockHz);
132 
133 /*!
134  * @brief Configures the SAI Rx audio format.
135  *
136  * The audio format can be changed at run-time. This function configures the sample rate and audio data
137  * format to be transferred. This function also sets the eDMA parameter according to formatting requirements.
138  *
139  * @param base SAI base pointer.
140  * @param handle SAI eDMA handle pointer.
141  * @param format Pointer to SAI audio data format structure.
142  * @param mclkSourceClockHz SAI master clock source frequency in Hz.
143  * @param bclkSourceClockHz SAI bit clock source frequency in Hz. If a bit clock source is the master
144  * clock, this value should equal to masterClockHz in format.
145  * @retval kStatus_Success Audio format set successfully.
146  * @retval kStatus_InvalidArgument The input argument is invalid.
147 */
148 void SAI_TransferRxSetFormatEDMA(I2S_Type *base,
149                                  sai_edma_handle_t *handle,
150                                  sai_transfer_format_t *format,
151                                  uint32_t mclkSourceClockHz,
152                                  uint32_t bclkSourceClockHz);
153 
154 /*!
155  * @brief Performs a non-blocking SAI transfer using DMA.
156  *
157  * @note This interface returns immediately after the transfer initiates. Call
158  * SAI_GetTransferStatus to poll the transfer status and check whether the SAI transfer is finished.
159  *
160  * @param base SAI base pointer.
161  * @param handle SAI eDMA handle pointer.
162  * @param xfer Pointer to the DMA transfer structure.
163  * @retval kStatus_Success Start a SAI eDMA send successfully.
164  * @retval kStatus_InvalidArgument The input argument is invalid.
165  * @retval kStatus_TxBusy SAI is busy sending data.
166  */
167 status_t SAI_TransferSendEDMA(I2S_Type *base, sai_edma_handle_t *handle, sai_transfer_t *xfer);
168 
169 /*!
170  * @brief Performs a non-blocking SAI receive using eDMA.
171  *
172  * @note This interface returns immediately after the transfer initiates. Call
173  * the SAI_GetReceiveRemainingBytes to poll the transfer status and check whether the SAI transfer is finished.
174  *
175  * @param base SAI base pointer
176  * @param handle SAI eDMA handle pointer.
177  * @param xfer Pointer to DMA transfer structure.
178  * @retval kStatus_Success Start a SAI eDMA receive successfully.
179  * @retval kStatus_InvalidArgument The input argument is invalid.
180  * @retval kStatus_RxBusy SAI is busy receiving data.
181  */
182 status_t SAI_TransferReceiveEDMA(I2S_Type *base, sai_edma_handle_t *handle, sai_transfer_t *xfer);
183 
184 /*!
185  * @brief Aborts a SAI transfer using eDMA.
186  *
187  * @param base SAI base pointer.
188  * @param handle SAI eDMA handle pointer.
189  */
190 void SAI_TransferAbortSendEDMA(I2S_Type *base, sai_edma_handle_t *handle);
191 
192 /*!
193  * @brief Aborts a SAI receive using eDMA.
194  *
195  * @param base SAI base pointer
196  * @param handle SAI eDMA handle pointer.
197  */
198 void SAI_TransferAbortReceiveEDMA(I2S_Type *base, sai_edma_handle_t *handle);
199 
200 /*!
201  * @brief Gets byte count sent by SAI.
202  *
203  * @param base SAI base pointer.
204  * @param handle SAI eDMA handle pointer.
205  * @param count Bytes count sent by SAI.
206  * @retval kStatus_Success Succeed get the transfer count.
207  * @retval kStatus_NoTransferInProgress There is no non-blocking transaction in progress.
208  */
209 status_t SAI_TransferGetSendCountEDMA(I2S_Type *base, sai_edma_handle_t *handle, size_t *count);
210 
211 /*!
212  * @brief Gets byte count received by SAI.
213  *
214  * @param base SAI base pointer
215  * @param handle SAI eDMA handle pointer.
216  * @param count Bytes count received by SAI.
217  * @retval kStatus_Success Succeed get the transfer count.
218  * @retval kStatus_NoTransferInProgress There is no non-blocking transaction in progress.
219  */
220 status_t SAI_TransferGetReceiveCountEDMA(I2S_Type *base, sai_edma_handle_t *handle, size_t *count);
221 
222 /*! @} */
223 
224 #if defined(__cplusplus)
225 }
226 #endif
227 
228 /*!
229  * @}
230  */
231 #endif
232