1 /*
2  * Copyright  2016-2021 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef _FSL_SDMA_H_
10 #define _FSL_SDMA_H_
11 
12 #include "fsl_common.h"
13 #include "fsl_sdma_script.h"
14 
15 /*!
16  * @addtogroup sdma
17  * @{
18  */
19 
20 /*******************************************************************************
21  * Definitions
22  ******************************************************************************/
23 
24 /*! @name Driver version */
25 /*@{*/
26 /*! @brief SDMA driver version */
27 #define FSL_SDMA_DRIVER_VERSION (MAKE_VERSION(2, 4, 1)) /*!< Version 2.4.1. */
28 /*@}*/
29 
30 #ifndef SDMA_DRIVER_LOAD_RAM_SCRIPT
31 #define SDMA_DRIVER_LOAD_RAM_SCRIPT (1)
32 #endif
33 
34 /*! @brief SDMA transfer configuration */
35 typedef enum _sdma_transfer_size
36 {
37     kSDMA_TransferSize1Bytes = 0x1U, /*!< Source/Destination data transfer size is 1 byte every time */
38     kSDMA_TransferSize2Bytes = 0x2U, /*!< Source/Destination data transfer size is 2 bytes every time */
39     kSDMA_TransferSize3Bytes = 0x3U, /*!< Source/Destination data transfer size is 3 bytes every time */
40     kSDMA_TransferSize4Bytes = 0x0U, /*!< Source/Destination data transfer size is 4 bytes every time */
41 } sdma_transfer_size_t;
42 
43 /*! @brief SDMA buffer descriptor status */
44 typedef enum _sdma_bd_status
45 {
46     kSDMA_BDStatusDone       = 0x1U,  /*!< BD ownership, 0 means ARM core owns the BD, while 1 means SDMA owns BD. */
47     kSDMA_BDStatusWrap       = 0x2U,  /*!< While this BD is last one, the next BD will be the first one */
48     kSDMA_BDStatusContinuous = 0x4U,  /*!< Buffer is allowed to transfer/receive to/from multiple buffers */
49     kSDMA_BDStatusInterrupt  = 0x8U,  /*!< While this BD finished, send an interrupt. */
50     kSDMA_BDStatusError      = 0x10U, /*!< Error occurred on buffer descriptor command. */
51     kSDMA_BDStatusLast =
52         0x20U, /*!< This BD is the last BD in this array. It means the transfer ended after this buffer */
53     kSDMA_BDStatusExtend = 0x80U, /*!< Buffer descriptor extend status for SDMA scripts */
54 } sdma_bd_status_t;
55 
56 /*! @brief SDMA buffer descriptor command */
57 typedef enum _sdma_bd_command
58 {
59     kSDMA_BDCommandSETDM  = 0x1U, /*!< Load SDMA data memory from ARM core memory buffer. */
60     kSDMA_BDCommandGETDM  = 0x2U, /*!< Copy SDMA data memory to ARM core memory buffer. */
61     kSDMA_BDCommandSETPM  = 0x4U, /*!< Load SDMA program memory from ARM core memory buffer. */
62     kSDMA_BDCommandGETPM  = 0x6U, /*!< Copy SDMA program memory to ARM core memory buffer. */
63     kSDMA_BDCommandSETCTX = 0x7U, /*!< Load context for one channel into SDMA RAM from ARM platform memory buffer. */
64     kSDMA_BDCommandGETCTX = 0x3U, /*!< Copy context for one channel from SDMA RAM to ARM platform memory buffer. */
65 } sdma_bd_command_t;
66 
67 /*! @brief SDMA context switch mode */
68 typedef enum _sdma_context_switch_mode
69 {
70     kSDMA_ContextSwitchModeStatic = 0x0U,     /*!< SDMA context switch mode static */
71     kSDMA_ContextSwitchModeDynamicLowPower,   /*!< SDMA context switch mode dynamic with low power */
72     kSDMA_ContextSwitchModeDynamicWithNoLoop, /*!< SDMA context switch mode dynamic with no loop */
73     kSDMA_ContextSwitchModeDynamic,           /*!< SDMA context switch mode dynamic */
74 } sdma_context_switch_mode_t;
75 
76 /*! @brief SDMA core clock frequency ratio to the ARM DMA interface. */
77 typedef enum _sdma_clock_ratio
78 {
79     kSDMA_HalfARMClockFreq = 0x0U, /*!< SDMA core clock frequency half of ARM platform */
80     kSDMA_ARMClockFreq,            /*!< SDMA core clock frequency equals to ARM platform */
81 } sdma_clock_ratio_t;
82 
83 /*! @brief SDMA transfer type */
84 typedef enum _sdma_transfer_type
85 {
86     kSDMA_MemoryToMemory = 0x0U,  /*!< Transfer from memory to memory */
87     kSDMA_PeripheralToMemory,     /*!< Transfer from peripheral to memory */
88     kSDMA_MemoryToPeripheral,     /*!< Transfer from memory to peripheral */
89     kSDMA_PeripheralToPeripheral, /*!< Transfer from peripheral to peripheral */
90 } sdma_transfer_type_t;
91 
92 /*! @brief Peripheral type use SDMA */
93 typedef enum sdma_peripheral
94 {
95     kSDMA_PeripheralTypeMemory = 0x0, /*!< Peripheral DDR memory */
96     kSDMA_PeripheralTypeUART,         /*!< UART use SDMA */
97     kSDMA_PeripheralTypeUART_SP,      /*!< UART instance in SPBA use SDMA */
98     kSDMA_PeripheralTypeSPDIF,        /*!< SPDIF use SDMA */
99     kSDMA_PeripheralNormal,           /*!< Normal peripheral use SDMA */
100     kSDMA_PeripheralNormal_SP,        /*!< Normal peripheral in SPBA use SDMA */
101     kSDMA_PeripheralMultiFifoPDM,     /*!< multi fifo PDM */
102     kSDMA_PeripheralMultiFifoSaiRX,   /*!< multi fifo sai rx use SDMA */
103     kSDMA_PeripheralMultiFifoSaiTX,   /*!< multi fifo sai tx use SDMA */
104     kSDMA_PeripheralASRCM2P,          /*!< asrc m2p */
105     kSDMA_PeripheralASRCP2M,          /*!< asrc p2m */
106     kSDMA_PeripheralASRCP2P,          /*!< asrc p2p */
107 } sdma_peripheral_t;
108 
109 /*! @brief _sdma_transfer_status SDMA transfer status */
110 enum
111 {
112     kStatus_SDMA_ERROR = MAKE_STATUS(kStatusGroup_SDMA, 0), /*!< SDMA context error. */
113     kStatus_SDMA_Busy  = MAKE_STATUS(kStatusGroup_SDMA, 1), /*!< Channel is busy and can't handle the
114                                                                  transfer request. */
115 };
116 
117 /*! @brief _sdma_multi_fifo_mask SDMA multi fifo mask */
118 enum
119 {
120     kSDMA_MultiFifoWatermarkLevelMask = 0xFFFU, /*!< multi fifo watermark level mask */
121     kSDMA_MultiFifoNumsMask           = 0xFU,   /*!< multi fifo nums mask */
122     kSDMA_MultiFifoOffsetMask         = 0xFU,   /*!< multi fifo offset mask */
123     kSDMA_MultiFifoSwDoneMask         = 0x1U,   /*!< multi fifo sw done mask */
124     kSDMA_MultiFifoSwDoneSelectorMask = 0xFU,   /*!< multi fifo sw done selector mask */
125 };
126 
127 /*! @brief _sdma_multi_fifo_shift SDMA multi fifo shift */
128 enum
129 {
130     kSDMA_MultiFifoWatermarkLevelShift = 0U,  /*!< multi fifo watermark level shift */
131     kSDMA_MultiFifoNumsShift           = 12U, /*!< multi fifo nums shift */
132     kSDMA_MultiFifoOffsetShift         = 16U, /*!< multi fifo offset shift */
133     kSDMA_MultiFifoSwDoneShift         = 23U, /*!< multi fifo sw done shift */
134     kSDMA_MultiFifoSwDoneSelectorShift = 24U, /*!< multi fifo sw done selector shift */
135 };
136 
137 /*! @brief _sdma_done_channel SDMA done channel */
138 enum
139 {
140     kSDMA_DoneChannel0 = 0U, /*!< SDMA done channel 0 */
141     kSDMA_DoneChannel1 = 1U, /*!< SDMA done channel 1 */
142     kSDMA_DoneChannel2 = 2U, /*!< SDMA done channel 2 */
143     kSDMA_DoneChannel3 = 3U, /*!< SDMA done channel 3 */
144     kSDMA_DoneChannel4 = 4U, /*!< SDMA done channel 4 */
145     kSDMA_DoneChannel5 = 5U, /*!< SDMA done channel 5 */
146     kSDMA_DoneChannel6 = 6U, /*!< SDMA done channel 6 */
147     kSDMA_DoneChannel7 = 7U, /*!< SDMA done channel 7 */
148 };
149 
150 /*! @brief SDMA done source */
151 typedef enum _sdma_done_src
152 {
153     kSDMA_DoneSrcSW         = 0U,  /*!< software done */
154     kSDMA_DoneSrcHwEvent0U  = 1U,  /*!< HW event 0 is used for DONE event */
155     kSDMA_DoneSrcHwEvent1U  = 2U,  /*!< HW event 1 is used for DONE event */
156     kSDMA_DoneSrcHwEvent2U  = 3U,  /*!< HW event 2 is used for DONE event */
157     kSDMA_DoneSrcHwEvent3U  = 4U,  /*!< HW event 3 is used for DONE event */
158     kSDMA_DoneSrcHwEvent4U  = 5U,  /*!< HW event 4 is used for DONE event */
159     kSDMA_DoneSrcHwEvent5U  = 6U,  /*!< HW event 5 is used for DONE event */
160     kSDMA_DoneSrCHwEvent6U  = 7U,  /*!< HW event 6 is used for DONE event */
161     kSDMA_DoneSrcHwEvent7U  = 8U,  /*!< HW event 7 is used for DONE event */
162     kSDMA_DoneSrcHwEvent8U  = 9U,  /*!< HW event 8 is used for DONE event */
163     kSDMA_DoneSrcHwEvent9U  = 10U, /*!< HW event 9 is used for DONE event */
164     kSDMA_DoneSrcHwEvent10U = 11U, /*!< HW event 10 is used for DONE event */
165     kSDMA_DoneSrcHwEvent11U = 12U, /*!< HW event 11 is used for DONE event */
166     kSDMA_DoneSrcHwEvent12U = 13U, /*!< HW event 12 is used for DONE event */
167     kSDMA_DoneSrcHwEvent13U = 14U, /*!< HW event 13 is used for DONE event */
168     kSDMA_DoneSrcHwEvent14U = 15U, /*!< HW event 14 is used for DONE event */
169     kSDMA_DoneSrcHwEvent15U = 16U, /*!< HW event 15 is used for DONE event */
170     kSDMA_DoneSrcHwEvent16U = 17U, /*!< HW event 16 is used for DONE event */
171     kSDMA_DoneSrcHwEvent17U = 18U, /*!< HW event 17 is used for DONE event */
172     kSDMA_DoneSrcHwEvent18U = 19U, /*!< HW event 18 is used for DONE event */
173     kSDMA_DoneSrcHwEvent19U = 20U, /*!< HW event 19 is used for DONE event */
174     kSDMA_DoneSrcHwEvent20U = 21U, /*!< HW event 20 is used for DONE event */
175     kSDMA_DoneSrcHwEvent21U = 22U, /*!< HW event 21 is used for DONE event */
176     kSDMA_DoneSrcHwEvent22U = 23U, /*!< HW event 22 is used for DONE event */
177     kSDMA_DoneSrcHwEvent23U = 24U, /*!< HW event 23 is used for DONE event */
178     kSDMA_DoneSrcHwEvent24U = 25U, /*!< HW event 24 is used for DONE event */
179     kSDMA_DoneSrcHwEvent25U = 26U, /*!< HW event 25 is used for DONE event */
180     kSDMA_DoneSrcHwEvent26U = 27U, /*!< HW event 26 is used for DONE event */
181     kSDMA_DoneSrcHwEvent27U = 28U, /*!< HW event 27 is used for DONE event */
182     kSDMA_DoneSrcHwEvent28U = 29U, /*!< HW event 28 is used for DONE event */
183     kSDMA_DoneSrcHwEvent29U = 30U, /*!< HW event 29 is used for DONE event */
184     kSDMA_DoneSrcHwEvent30U = 31U, /*!< HW event 30 is used for DONE event */
185     kSDMA_DoneSrcHwEvent31U = 32U, /*!< HW event 31 is used for DONE event */
186 } sdma_done_src_t;
187 
188 /*! @brief SDMA global configuration structure.*/
189 typedef struct _sdma_config
190 {
191     bool enableRealTimeDebugPin;   /*!< If enable real-time debug pin, default is closed to reduce power consumption.*/
192     bool isSoftwareResetClearLock; /*!< If software reset clears the LOCK bit which prevent writing SDMA scripts into
193                                       SDMA.*/
194     sdma_clock_ratio_t ratio;      /*!< SDMA core clock ratio to ARM platform DMA interface */
195 } sdma_config_t;
196 
197 /*! @brief SDMA multi fifo configurations.*/
198 typedef struct _sdma_multi_fifo_config
199 {
200     uint8_t fifoNums;   /*!< fifo numbers */
201     uint8_t fifoOffset; /*!< offset between multi fifo data register address */
202 } sdma_multi_fifo_config_t;
203 
204 /*! @brief SDMA sw done configurations.*/
205 typedef struct _sdma_sw_done_config
206 {
207     bool enableSwDone; /*!< true is enable sw done, false is disable */
208     uint8_t swDoneSel; /*!< sw done channel number per peripheral type */
209 } sdma_sw_done_config_t;
210 
211 /*! @brief SDMA peripheral to peripheral R7 config*/
212 typedef struct _sdma_p2p_config
213 {
214     uint8_t sourceWatermark; /*!< lower watermark value */
215     uint8_t destWatermark;   /*!< higher water makr value */
216     bool continuousTransfer; /*!< 0: the amount of samples to be transferred is equal to the cont field of mode word
217                                       1: the amount of samples to be transferred is unknown and script will keep on
218                                 transferring as long as both events are detected and script must be stopped by
219                                 application.*/
220 } sdma_p2p_config_t;
221 
222 /*!
223  * @brief SDMA transfer configuration
224  *
225  * This structure configures the source/destination transfer attribute.
226  */
227 typedef struct _sdma_transfer_config
228 {
229     uint32_t srcAddr;                      /*!< Source address of the transfer */
230     uint32_t destAddr;                     /*!< Destination address of the transfer */
231     sdma_transfer_size_t srcTransferSize;  /*!< Source data transfer size. */
232     sdma_transfer_size_t destTransferSize; /*!< Destination data transfer size. */
233     uint32_t bytesPerRequest;              /*!< Bytes to transfer in a minor loop*/
234     uint32_t transferSzie;                 /*!< Bytes to transfer for this descriptor */
235     uint32_t scriptAddr;                   /*!< SDMA script address located in SDMA ROM. */
236     uint32_t eventSource;  /*!< Event source number for the channel. 0 means no event, use software trigger */
237     uint32_t eventSource1; /*!< event source 1 */
238     bool isEventIgnore;    /*!< True means software trigger, false means hardware trigger */
239     bool
240         isSoftTriggerIgnore; /*!< If ignore the HE bit, 1 means use hardware events trigger, 0 means software trigger */
241     sdma_transfer_type_t type;          /*!< Transfer type, transfer type used to decide the SDMA script. */
242     sdma_multi_fifo_config_t multiFifo; /*!< multi fifo configurations */
243     sdma_sw_done_config_t swDone;       /*!< sw done selector */
244     uint32_t watermarkLevel;            /*!< watermark level */
245     uint32_t eventMask0;                /*!< event mask 0 */
246     uint32_t eventMask1;                /*!< event mask 1 */
247 
248 } sdma_transfer_config_t;
249 
250 /*!
251  * @brief SDMA buffer descriptor structure.
252  *
253  * This structure is a buffer descriptor, this structure describes the buffer start address and other options
254  */
255 typedef struct _sdma_buffer_descriptor
256 {
257     uint32_t count : 16;       /*!< Bytes of the buffer length for this buffer descriptor. */
258     uint32_t status : 8;       /*!< E,R,I,C,W,D status bits stored here */
259     uint32_t command : 8;      /*!< command mostlky used for channel 0 */
260     uint32_t bufferAddr;       /*!< Buffer start address for this descriptor. */
261     uint32_t extendBufferAddr; /*!< External buffer start address, this is an optional for a transfer. */
262 } sdma_buffer_descriptor_t;
263 
264 /*!
265  * @brief SDMA channel control descriptor structure.
266  */
267 typedef struct _sdma_channel_control
268 {
269     uint32_t currentBDAddr; /*!< Address of current buffer descriptor processed  */
270     uint32_t baseBDAddr;    /*!< The start address of the buffer descriptor array */
271     uint32_t channelDesc;   /*!< Optional for transfer */
272     uint32_t status;        /*!< Channel status */
273 } sdma_channel_control_t;
274 
275 /*!
276  * @brief SDMA context structure for each channel. This structure can be load into SDMA core, with this structure, SDMA
277  * scripts can start work.
278  */
279 typedef struct _sdma_context_data
280 {
281     uint32_t PC : 14;
282     uint32_t unused1 : 1;
283     uint32_t T : 1;
284     uint32_t RPC : 14;
285     uint32_t unused0 : 1;
286     uint32_t SF : 1;
287     uint32_t SPC : 14;
288     uint32_t unused2 : 1;
289     uint32_t DF : 1;
290     uint32_t EPC : 14;
291     uint32_t LM : 2;
292     uint32_t GeneralReg[8]; /*!< 8 general regsiters used for SDMA RISC core */
293     uint32_t MDA;
294     uint32_t MSA;
295     uint32_t MS;
296     uint32_t MD;
297     uint32_t PDA;
298     uint32_t PSA;
299     uint32_t PS;
300     uint32_t PD;
301     uint32_t CA;
302     uint32_t CS;
303     uint32_t DDA;
304     uint32_t DSA;
305     uint32_t DS;
306     uint32_t DD;
307     uint32_t Scratch0;
308     uint32_t Scratch1;
309     uint32_t Scratch2;
310     uint32_t Scratch3;
311     uint32_t Scratch4;
312     uint32_t Scratch5;
313     uint32_t Scratch6;
314     uint32_t Scratch7;
315 } sdma_context_data_t;
316 
317 /*! @brief Callback for SDMA */
318 struct _sdma_handle;
319 
320 /*! @brief Define callback function for SDMA. */
321 typedef void (*sdma_callback)(struct _sdma_handle *handle, void *userData, bool transferDone, uint32_t bdIndex);
322 
323 /*! @brief SDMA transfer handle structure */
324 typedef struct _sdma_handle
325 {
326     sdma_callback callback;           /*!< Callback function for major count exhausted. */
327     void *userData;                   /*!< Callback function parameter. */
328     SDMAARM_Type *base;               /*!< SDMA peripheral base address. */
329     sdma_buffer_descriptor_t *BDPool; /*!< Pointer to memory stored BD arrays. */
330     uint32_t bdCount;                 /*!< How many buffer descriptor   */
331     uint32_t bdIndex;                 /*!< How many buffer descriptor   */
332     uint32_t eventSource;             /*!< Event source count for the channel */
333     uint32_t eventSource1;            /*!< Event source 1 count for the channel */
334     sdma_context_data_t *context;     /*!< Channel context to exectute in SDMA */
335     uint8_t channel;                  /*!< SDMA channel number. */
336     uint8_t priority;                 /*!< SDMA channel priority */
337     uint8_t flags;                    /*!< The status of the current channel. */
338 
339 #if SDMA_DRIVER_LOAD_RAM_SCRIPT
340     bool isRamscriptLoaded; /*!< Flag to indicate the status of ram script */
341 #endif
342 
343 } sdma_handle_t;
344 
345 /*******************************************************************************
346  * APIs
347  ******************************************************************************/
348 #if defined(__cplusplus)
349 extern "C" {
350 #endif /* __cplusplus */
351 
352 /*!
353  * @name SDMA initialization and de-initialization
354  * @{
355  */
356 
357 /*!
358  * @brief Initializes the SDMA peripheral.
359  *
360  * This function ungates the SDMA clock and configures the SDMA peripheral according
361  * to the configuration structure.
362  *
363  * @param base SDMA peripheral base address.
364  * @param config A pointer to the configuration structure, see "sdma_config_t".
365  * @note This function enables the minor loop map feature.
366  */
367 void SDMA_Init(SDMAARM_Type *base, const sdma_config_t *config);
368 
369 /*!
370  * @brief Deinitializes the SDMA peripheral.
371  *
372  * This function gates the SDMA clock.
373  *
374  * @param base SDMA peripheral base address.
375  */
376 void SDMA_Deinit(SDMAARM_Type *base);
377 
378 /*!
379  * @brief Gets the SDMA default configuration structure.
380  *
381  * This function sets the configuration structure to default values.
382  * The default configuration is set to the following values.
383  * @code
384  *   config.enableRealTimeDebugPin = false;
385  *   config.isSoftwareResetClearLock = true;
386  *   config.ratio = kSDMA_HalfARMClockFreq;
387  * @endcode
388  *
389  * @param config A pointer to the SDMA configuration structure.
390  */
391 void SDMA_GetDefaultConfig(sdma_config_t *config);
392 
393 /*!
394  * @brief Sets all SDMA core register to reset status.
395  *
396  * If only reset ARM core, SDMA register cannot return to reset value, shall call this function to reset all SDMA
397  * register to reset value. But the internal status cannot be reset.
398  *
399  * @param base SDMA peripheral base address.
400  */
401 void SDMA_ResetModule(SDMAARM_Type *base);
402 
403 /* @} */
404 /*!
405  * @name SDMA Channel Operation
406  * @{
407  */
408 /*!
409  * @brief Enables the interrupt source for the SDMA error.
410  *
411  * Enable this will trigger an interrupt while SDMA occurs error while executing scripts.
412  *
413  * @param base SDMA peripheral base address.
414  * @param channel SDMA channel number.
415  */
SDMA_EnableChannelErrorInterrupts(SDMAARM_Type * base,uint32_t channel)416 static inline void SDMA_EnableChannelErrorInterrupts(SDMAARM_Type *base, uint32_t channel)
417 {
418     base->INTRMASK |= (1UL << channel);
419 }
420 
421 /*!
422  * @brief Disables the interrupt source for the SDMA error.
423  *
424  * @param base SDMA peripheral base address.
425  * @param channel SDMA channel number.
426  */
SDMA_DisableChannelErrorInterrupts(SDMAARM_Type * base,uint32_t channel)427 static inline void SDMA_DisableChannelErrorInterrupts(SDMAARM_Type *base, uint32_t channel)
428 {
429     base->INTRMASK &= ~(1UL << channel);
430 }
431 
432 /* @} */
433 /*!
434  * @name SDMA Buffer Descriptor Operation
435  * @{
436  */
437 
438 /*!
439  * @brief Sets buffer descriptor contents.
440  *
441  * This function sets the descriptor contents such as source, dest address and status bits.
442  *
443  * @param bd Pointer to the buffer descriptor structure.
444  * @param srcAddr Source address for the buffer descriptor.
445  * @param destAddr Destination address for the buffer descriptor.
446  * @param busWidth The transfer width, it only can be a member of sdma_transfer_size_t.
447  * @param bufferSize Buffer size for this descriptor, this number shall less than 0xFFFF. If need to transfer a big
448  * size,
449  * shall divide into several buffer descriptors.
450  * @param isLast Is the buffer descriptor the last one for the channel to transfer. If only one descriptor used for
451  * the channel, this bit shall set to TRUE.
452  * @param enableInterrupt If trigger an interrupt while this buffer descriptor transfer finished.
453  * @param isWrap Is the buffer descriptor need to be wrapped. While this bit set to true, it will automatically wrap
454  * to the first buffer descrtiptor to do transfer.
455  * @param type Transfer type, memory to memory, peripheral to memory or memory to peripheral.
456  */
457 void SDMA_ConfigBufferDescriptor(sdma_buffer_descriptor_t *bd,
458                                  uint32_t srcAddr,
459                                  uint32_t destAddr,
460                                  sdma_transfer_size_t busWidth,
461                                  size_t bufferSize,
462                                  bool isLast,
463                                  bool enableInterrupt,
464                                  bool isWrap,
465                                  sdma_transfer_type_t type);
466 
467 /*! @} */
468 /*!
469  * @name SDMA Channel Transfer Operation
470  * @{
471  */
472 
473 /*!
474  * @brief Set SDMA channel priority.
475  *
476  * This function sets the channel priority. The default value is 0 for all channels, priority 0 will prevents
477  * channel from starting, so the priority must be set before start a channel.
478  *
479  * @param base SDMA peripheral base address.
480  * @param channel SDMA channel number.
481  * @param priority SDMA channel priority.
482  */
SDMA_SetChannelPriority(SDMAARM_Type * base,uint32_t channel,uint8_t priority)483 static inline void SDMA_SetChannelPriority(SDMAARM_Type *base, uint32_t channel, uint8_t priority)
484 {
485     base->SDMA_CHNPRI[channel] = priority;
486 }
487 
488 /*!
489  * @brief Set SDMA request source mapping channel.
490  *
491  * This function sets which channel will be triggered by the dma request source.
492  *
493  * @param base SDMA peripheral base address.
494  * @param source SDMA dma request source number.
495  * @param channelMask SDMA channel mask. 1 means channel 0, 2 means channel 1, 4 means channel 3. SDMA supports
496  * an event trigger multi-channel. A channel can also be triggered by several source events.
497  */
SDMA_SetSourceChannel(SDMAARM_Type * base,uint32_t source,uint32_t channelMask)498 static inline void SDMA_SetSourceChannel(SDMAARM_Type *base, uint32_t source, uint32_t channelMask)
499 {
500     base->CHNENBL[source] = channelMask;
501 }
502 
503 /*!
504  * @brief Start a SDMA channel by software trigger.
505  *
506  * This function start a channel.
507  *
508  * @param base SDMA peripheral base address.
509  * @param channel SDMA channel number.
510  */
SDMA_StartChannelSoftware(SDMAARM_Type * base,uint32_t channel)511 static inline void SDMA_StartChannelSoftware(SDMAARM_Type *base, uint32_t channel)
512 {
513     base->HSTART = (1UL << channel);
514 }
515 
516 /*!
517  * @brief Start a SDMA channel by hardware events.
518  *
519  * This function start a channel.
520  *
521  * @param base SDMA peripheral base address.
522  * @param channel SDMA channel number.
523  */
SDMA_StartChannelEvents(SDMAARM_Type * base,uint32_t channel)524 static inline void SDMA_StartChannelEvents(SDMAARM_Type *base, uint32_t channel)
525 {
526     base->EVTPEND = (1UL << channel);
527 }
528 
529 /*!
530  * @brief Stop a SDMA channel.
531  *
532  * This function stops a channel.
533  *
534  * @param base SDMA peripheral base address.
535  * @param channel SDMA channel number.
536  */
SDMA_StopChannel(SDMAARM_Type * base,uint32_t channel)537 static inline void SDMA_StopChannel(SDMAARM_Type *base, uint32_t channel)
538 {
539     base->STOP_STAT = (1UL << channel);
540 }
541 
542 /*!
543  * @brief Set the SDMA context switch mode.
544  *
545  * @param base SDMA peripheral base address.
546  * @param mode SDMA context switch mode.
547  */
548 void SDMA_SetContextSwitchMode(SDMAARM_Type *base, sdma_context_switch_mode_t mode);
549 
550 /*! @} */
551 
552 /*!
553  * @name SDMA Channel Status Operation
554  * @{
555  */
556 
557 /*!
558  * @brief Gets the SDMA interrupt status of all channels.
559  *
560  * @param base SDMA peripheral base address.
561  * @return The interrupt status for all channels. Check the relevant bits for specific channel.
562  */
SDMA_GetChannelInterruptStatus(SDMAARM_Type * base)563 static inline uint32_t SDMA_GetChannelInterruptStatus(SDMAARM_Type *base)
564 {
565     return base->INTR;
566 }
567 
568 /*!
569  * @brief Clear the SDMA channel interrupt status of specific channels.
570  *
571  * @param base SDMA peripheral base address.
572  * @param mask The interrupt status need to be cleared.
573  */
SDMA_ClearChannelInterruptStatus(SDMAARM_Type * base,uint32_t mask)574 static inline void SDMA_ClearChannelInterruptStatus(SDMAARM_Type *base, uint32_t mask)
575 {
576     base->INTR = mask;
577 }
578 
579 /*!
580  * @brief Gets the SDMA stop status of all channels.
581  *
582  * @param base SDMA peripheral base address.
583  * @return The stop status for all channels. Check the relevant bits for specific channel.
584  */
SDMA_GetChannelStopStatus(SDMAARM_Type * base)585 static inline uint32_t SDMA_GetChannelStopStatus(SDMAARM_Type *base)
586 {
587     return base->STOP_STAT;
588 }
589 
590 /*!
591  * @brief Clear the SDMA channel stop status of specific channels.
592  *
593  * @param base SDMA peripheral base address.
594  * @param mask The stop status need to be cleared.
595  */
SDMA_ClearChannelStopStatus(SDMAARM_Type * base,uint32_t mask)596 static inline void SDMA_ClearChannelStopStatus(SDMAARM_Type *base, uint32_t mask)
597 {
598     base->STOP_STAT = mask;
599 }
600 
601 /*!
602  * @brief Gets the SDMA channel pending status of all channels.
603  *
604  * @param base SDMA peripheral base address.
605  * @return The pending status for all channels. Check the relevant bits for specific channel.
606  */
SDMA_GetChannelPendStatus(SDMAARM_Type * base)607 static inline uint32_t SDMA_GetChannelPendStatus(SDMAARM_Type *base)
608 {
609     return base->EVTPEND;
610 }
611 
612 /*!
613  * @brief Clear the SDMA channel pending status of specific channels.
614  *
615  * @param base SDMA peripheral base address.
616  * @param mask The pending status need to be cleared.
617  */
SDMA_ClearChannelPendStatus(SDMAARM_Type * base,uint32_t mask)618 static inline void SDMA_ClearChannelPendStatus(SDMAARM_Type *base, uint32_t mask)
619 {
620     base->EVTPEND = mask;
621 }
622 
623 /*!
624  * @brief Gets the SDMA channel error status.
625  *
626  * SDMA channel error flag is asserted while an incoming DMA request was detected and it triggers a channel
627  * that is already pending or being serviced. This probably means there is an overflow of data for that channel.
628  *
629  * @param base SDMA peripheral base address.
630  * @return The error status for all channels. Check the relevant bits for specific channel.
631  */
SDMA_GetErrorStatus(SDMAARM_Type * base)632 static inline uint32_t SDMA_GetErrorStatus(SDMAARM_Type *base)
633 {
634     return base->EVTERR;
635 }
636 
637 /*!
638  * @brief Gets the SDMA request source pending status.
639  *
640  * @param base SDMA peripheral base address.
641  * @param source DMA request source number.
642  * @return True means the request source is pending, otherwise not pending.
643  */
644 bool SDMA_GetRequestSourceStatus(SDMAARM_Type *base, uint32_t source);
645 
646 /*! @} */
647 /*!
648  * @name SDMA Transactional Operation
649  */
650 
651 /*!
652  * @brief Creates the SDMA handle.
653  *
654  * This function is called if using the transactional API for SDMA. This function
655  * initializes the internal state of the SDMA handle.
656  *
657  * @param handle SDMA handle pointer. The SDMA handle stores callback function and parameters.
658  * @param base SDMA peripheral base address.
659  * @param channel SDMA channel number.
660  * @param context Context structure for the channel to download into SDMA. Users shall make sure the context located
661  * in a non-cacheable memory, or it will cause SDMA run fail. Users shall not touch the context contents, it only be
662  * filled by SDMA driver in SDMA_SubmitTransfer function.
663  */
664 void SDMA_CreateHandle(sdma_handle_t *handle, SDMAARM_Type *base, uint32_t channel, sdma_context_data_t *context);
665 
666 /*!
667  * @brief Installs the BDs memory pool into the SDMA handle.
668  *
669  * This function is called after the SDMA_CreateHandle to use multi-buffer feature.
670  *
671  * @param handle SDMA handle pointer.
672  * @param BDPool A memory pool to store BDs. It must be located in non-cacheable address.
673  * @param BDCount The number of BD slots.
674  */
675 void SDMA_InstallBDMemory(sdma_handle_t *handle, sdma_buffer_descriptor_t *BDPool, uint32_t BDCount);
676 
677 /*!
678  * @brief Installs a callback function for the SDMA transfer.
679  *
680  * This callback is called in the SDMA IRQ handler. Use the callback to do something after
681  * the current major loop transfer completes.
682  *
683  * @param handle SDMA handle pointer.
684  * @param callback SDMA callback function pointer.
685  * @param userData A parameter for the callback function.
686  */
687 void SDMA_SetCallback(sdma_handle_t *handle, sdma_callback callback, void *userData);
688 
689 /*!
690  * @brief multi fifo configurations.
691  *
692  * This api is used to support multi fifo for SDMA, if user want to get multi fifo data, then this api
693  * shoule be called before submit transfer.
694  *
695  * @param config transfer configurations.
696  * @param fifoNums fifo numbers that multi fifo operation perform, support up to 15 fifo numbers.
697  * @param fifoOffset fifoOffset = fifo address offset / sizeof(uint32_t) - 1.
698  */
699 void SDMA_SetMultiFifoConfig(sdma_transfer_config_t *config, uint32_t fifoNums, uint32_t fifoOffset);
700 
701 /*!
702  * @brief enable sdma sw done feature.
703  *
704  * @deprecated Do not use this function. It has been superceded by @ref SDMA_SetDoneConfig.
705  *
706  * @param base SDMA base.
707  * @param config transfer configurations.
708  * @param sel sw done selector.
709  * @param type peripheral type is used to determine the corresponding peripheral sw done selector bit.
710  */
711 void SDMA_EnableSwDone(SDMAARM_Type *base, sdma_transfer_config_t *config, uint8_t sel, sdma_peripheral_t type);
712 
713 /*!
714  * @brief sdma channel done configurations.
715  *
716  * @param base SDMA base.
717  * @param config transfer configurations.
718  * @param type peripheral type.
719  * @param doneSrc reference sdma_done_src_t.
720  */
721 void SDMA_SetDoneConfig(SDMAARM_Type *base,
722                         sdma_transfer_config_t *config,
723                         sdma_peripheral_t type,
724                         sdma_done_src_t doneSrc);
725 
726 /*!
727  * @brief load script to sdma program memory.
728  *
729  * @param base SDMA base.
730  * @param destAddr dest script address, should be SDMA program memory address.
731  * @param srcAddr source address of target script.
732  * @param bufferSizeBytes bytes size of script.
733  */
734 void SDMA_LoadScript(SDMAARM_Type *base, uint32_t destAddr, void *srcAddr, size_t bufferSizeBytes);
735 
736 /*!
737  * @brief dump script from sdma program memory.
738  *
739  * @param base SDMA base.
740  * @param srcAddr should be SDMA program memory address.
741  * @param destAddr address to store scripts.
742  * @param bufferSizeBytes bytes size of script.
743  */
744 void SDMA_DumpScript(SDMAARM_Type *base, uint32_t srcAddr, void *destAddr, size_t bufferSizeBytes);
745 
746 /*!
747  * @brief Get RAM script version.
748  *
749  * @param base SDMA base.
750  * @return The script version of RAM.
751  */
SDMA_GetRamScriptVersion(SDMAARM_Type * base)752 static inline const char * SDMA_GetRamScriptVersion(SDMAARM_Type *base)
753 {
754     return FSL_SDMA_SCRIPT_VERSION;
755 }
756 
757 /*!
758  * @brief Prepares the SDMA transfer structure.
759  *
760  * This function prepares the transfer configuration structure according to the user input.
761  *
762  * @param config The user configuration structure of type sdma_transfer_t.
763  * @param srcAddr SDMA transfer source address.
764  * @param destAddr SDMA transfer destination address.
765  * @param srcWidth SDMA transfer source address width(bytes).
766  * @param destWidth SDMA transfer destination address width(bytes).
767  * @param bytesEachRequest SDMA transfer bytes per channel request.
768  * @param transferSize SDMA transfer bytes to be transferred.
769  * @param eventSource Event source number for the transfer, if use software trigger, just write 0.
770  * @param peripheral Peripheral type, used to decide if need to use some special scripts.
771  * @param type SDMA transfer type. Used to decide the correct SDMA script address in SDMA ROM.
772  * @note The data address and the data width must be consistent. For example, if the SRC
773  *       is 4 bytes, the source address must be 4 bytes aligned, or it results in
774  *       source address error.
775  */
776 void SDMA_PrepareTransfer(sdma_transfer_config_t *config,
777                           uint32_t srcAddr,
778                           uint32_t destAddr,
779                           uint32_t srcWidth,
780                           uint32_t destWidth,
781                           uint32_t bytesEachRequest,
782                           uint32_t transferSize,
783                           uint32_t eventSource,
784                           sdma_peripheral_t peripheral,
785                           sdma_transfer_type_t type);
786 
787 /*!
788  * @brief Prepares the SDMA P2P transfer structure.
789  *
790  * This function prepares the transfer configuration structure according to the user input.
791  *
792  * @param config The user configuration structure of type sdma_transfer_t.
793  * @param srcAddr SDMA transfer source address.
794  * @param destAddr SDMA transfer destination address.
795  * @param srcWidth SDMA transfer source address width(bytes).
796  * @param destWidth SDMA transfer destination address width(bytes).
797  * @param bytesEachRequest SDMA transfer bytes per channel request.
798  * @param transferSize SDMA transfer bytes to be transferred.
799  * @param eventSource Event source number for the transfer.
800  * @param eventSource1 Event source1 number for the transfer.
801  * @param peripheral Peripheral type, used to decide if need to use some special scripts.
802  * @param p2p sdma p2p configuration pointer.
803  * @note The data address and the data width must be consistent. For example, if the SRC
804  *       is 4 bytes, the source address must be 4 bytes aligned, or it results in
805  *       source address error.
806  */
807 void SDMA_PrepareP2PTransfer(sdma_transfer_config_t *config,
808                              uint32_t srcAddr,
809                              uint32_t destAddr,
810                              uint32_t srcWidth,
811                              uint32_t destWidth,
812                              uint32_t bytesEachRequest,
813                              uint32_t transferSize,
814                              uint32_t eventSource,
815                              uint32_t eventSource1,
816                              sdma_peripheral_t peripheral,
817                              sdma_p2p_config_t *p2p);
818 
819 /*!
820  * @brief Submits the SDMA transfer request.
821  *
822  * This function submits the SDMA transfer request according to the transfer configuration structure.
823  *
824  * @param handle SDMA handle pointer.
825  * @param config Pointer to SDMA transfer configuration structure.
826  */
827 void SDMA_SubmitTransfer(sdma_handle_t *handle, const sdma_transfer_config_t *config);
828 
829 /*!
830  * @brief SDMA starts transfer.
831  *
832  * This function enables the channel request. Users can call this function after submitting the transfer request
833  * or before submitting the transfer request.
834  *
835  * @param handle SDMA handle pointer.
836  */
837 void SDMA_StartTransfer(sdma_handle_t *handle);
838 
839 /*!
840  * @brief SDMA stops transfer.
841  *
842  * This function disables the channel request to pause the transfer. Users can call SDMA_StartTransfer()
843  * again to resume the transfer.
844  *
845  * @param handle SDMA handle pointer.
846  */
847 void SDMA_StopTransfer(sdma_handle_t *handle);
848 
849 /*!
850  * @brief SDMA aborts transfer.
851  *
852  * This function disables the channel request and clear transfer status bits.
853  * Users can submit another transfer after calling this API.
854  *
855  * @param handle DMA handle pointer.
856  */
857 void SDMA_AbortTransfer(sdma_handle_t *handle);
858 
859 /*!
860  * @brief Get transferred bytes while not using BD pools.
861  *
862  * This function returns the buffer descriptor count value if not using buffer descriptor.
863  * While do a simple transfer, which only uses one descriptor, the SDMA driver inside handle the
864  * buffer descriptor. In uart receive case, it can tell users how many data already received, also
865  * it can tells users how many data transfferd while error occurred.
866  * Notice, the count would not change while transfer is on-going using default SDMA script.
867  *
868  * @param handle DMA handle pointer.
869  * @return Transferred bytes.
870  */
871 uint32_t SDMA_GetTransferredBytes(sdma_handle_t *handle);
872 
873 #if defined FSL_FEATURE_SOC_SPBA_COUNT && (FSL_FEATURE_SOC_SPBA_COUNT > 0)
874 /*!
875  * @brief Judge if address located in SPBA.
876  *
877  * @param addr Address which need to judge.
878  * @retval True means located in SPBA, false means not.
879  */
880 bool SDMA_IsPeripheralInSPBA(uint32_t addr);
881 #endif /* FSL_FEATURE_SOC_SPBA_COUNT */
882 
883 /*!
884  * @brief SDMA IRQ handler for complete a buffer descriptor transfer.
885  *
886  * This function clears the interrupt flags and also handle the CCB for the channel.
887  *
888  * @param handle SDMA handle pointer.
889  */
890 void SDMA_HandleIRQ(sdma_handle_t *handle);
891 
892 /* @} */
893 
894 #if defined(__cplusplus)
895 }
896 #endif /* __cplusplus */
897 
898 /* @} */
899 
900 #endif /*_FSL_SDMA_H_*/
901