iLLD_TC27xC  1.0
IfxDma_Dma.h
Go to the documentation of this file.
1 /**
2  * \file IfxDma_Dma.h
3  * \brief DMA DMA details
4  * \ingroup IfxLld_Dma
5  *
6  * \version iLLD_0_1_0_10
7  * \copyright Copyright (c) 2013 Infineon Technologies AG. All rights reserved.
8  *
9  *
10  * IMPORTANT NOTICE
11  *
12  *
13  * Infineon Technologies AG (Infineon) is supplying this file for use
14  * exclusively with Infineon's microcontroller products. This file can be freely
15  * distributed within development tools that are supporting such microcontroller
16  * products.
17  *
18  * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
19  * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
20  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
21  * INFINEON SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
22  * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
23  *
24  * \defgroup IfxLld_Dma_Dma_Usage How to use the DMA Interface driver?
25  * \ingroup IfxLld_Dma
26  *
27  * The DMA interface driver provides a default configuration for data moves without intervention of the CPU or other on chip devices.
28  *
29  * In the following sections it will be described, how to integrate the driver into the application framework for different use cases.
30  *
31  * \section IfxLld_Dma_Dma_Preparation Preparation
32  * \subsection IfxLld_Dma_Dma_Include Include Files
33  *
34  * Include following header file into your C code:
35  *
36  * \code
37  * #include <Dma/Dma/IfxDma_Dma.h>
38  * \endcode
39  *
40  *
41  * \subsection IfxLld_Dma_Dma_Module Module initialisation
42  *
43  * Declare the dma handle as a global variable:
44  *
45  * \code
46  * // DMA handle
47  * IfxDma_Dma dma;
48  * \endcode
49  *
50  * Initialize the DMA with following code:
51  * \code
52  * // create module config
53  * IfxDma_Dma_Config dmaConfig;
54  * IfxDma_Dma_initModuleConfig(&dmaConfig, &MODULE_DMA);
55  *
56  * // initialize module
57  * // IfxDma_Dma dma; // declared globally
58  * IfxDma_Dma_initModule(&dma, &dmaConfig);
59  * \endcode
60  *
61  * This only has to be done once in the application.
62  *
63  * The "IfxDma_Dma dma" handle should either be declared as a global variable (as shown in this example),
64  * or it can be created locally if desired:
65  *
66  * \code
67  * IfxDma_Dma dma;
68  * IfxDma_Dma_createModuleHandle(&dma, &MODULE_DMA);
69  * \endcode
70  *
71  * \subsection IfxLld_Dma_Dma_Simple Memory-to-Memory Transfers
72  *
73  * A large amount of data should be copied between SRI based memories, e.g. from Flash into the DSPR
74  * of the current CPU. It's recommended to use 256 bit moves for this purpose for best performance.
75  *
76  * This requires, that source and target locations are 256 bit (32 byte) aligned. With the GCC compiler
77  * this can be achieved by adding __attribute__ ((aligned(64))) to the arrays:
78  *
79  * \code
80  * #define MEMORY_TRANSFER_NUM_WORDS 1024
81  * uint32 __attribute__ ((aligned(64))) memoryDestination[MEMORY_TRANSFER_NUM_WORDS];
82  * \endcode
83  *
84  * Channel configuration and handling for the data move:
85  * \code
86  * // construct the channel configuration
87  * IfxDma_Dma_ChannelConfig chnCfg;
88  * IfxDma_Dma_initChannelConfig(&chnCfg, &dma);
89  *
90  * // select DMA channel which should be used
91  * chnCfg.channelId = IfxDma_ChannelId_0;
92  *
93  * // source and destination address
94  * chnCfg.sourceAddress = (uint32)0x80000000; // somewhere in flash section, here: start of PFlash (only for demo)
95  * chnCfg.destinationAddress = (uint32)memoryDestination;
96  *
97  * // move size, transfer count and request/operation mode
98  * chnCfg.moveSize = IfxDma_ChannelMoveSize_256bit;
99  * chnCfg.transferCount = (4 * MEMORY_TRANSFER_NUM_WORDS) / 32; // e.g. 1024 words require 128 * 256 bit moves
100  * chnCfg.requestMode = IfxDma_ChannelRequestMode_completeTransactionPerRequest;
101  * chnCfg.operationMode = IfxDma_ChannelOperationMode_continuous;
102  *
103  * // transfer configuration into DMA channel registers
104  * IfxDma_Dma_Channel chn;
105  * IfxDma_Dma_initChannel(&chn, &chnCfg);
106  *
107  * // start transfer and wait until it's finished
108  * IfxDma_Dma_startChannelTransaction(&chn);
109  * while( IfxDma_Dma_isChannelTransactionPending(&chn) == TRUE );
110  * \endcode
111  *
112  *
113  * \subsection IfxLld_Dma_Dma_Peripheral Peripheral-to-Memory Transfers
114  *
115  * The content of 8 ADC result registers should be transfered to a memory location in DSPR whenever
116  * an VADC autoscan has been finished. After the DMA transaction, an interrupt should be triggered
117  * so that the CPU can process the conversion results.
118  *
119  * We use following global variables:
120  * \code
121  * // buffer for autoscanned conversion result values
122  * #define NUM_SCANNED_CHANNELS 8
123  * static uint16 vadcResultBuffer[NUM_SCANNED_CHANNELS];
124  *
125  * // VADC handle
126  * IfxVadc_Adc vadc;
127  *
128  * // VADC group handle
129  * static IfxVadc_Adc_Group adcGroup;
130  *
131  * // DMA channel handle
132  * static IfxDma_Dma_Channel dmaChn;
133  * \endcode
134  *
135  *
136  * Create an interrupt handler for the DMA channel request:
137  * \code
138  * // priorities are normally defined in Ifx_IntPrioDef.h
139  * #define IFX_INTPRIO_DMA_CH0 1
140  *
141  * IFX_INTERRUPT(dmaCh0ISR, 0, IFX_INTPRIO_DMA_CH0)
142  * {
143  * // ...
144  * // do something with the conversion results in vadcResultBuffer[]
145  * // ...
146  *
147  * // re-init DMA channel destination address
148  * IfxDma_Dma_setChannelDestinationAddress(&dmaChn, ADDR_CPU_DSPR(IfxCpu_getCoreId(), &vadcResultBuffer[0]));
149  *
150  * // start new transaction
151  * IfxDma_Dma_setChannelTransferCount(&dmaChn, NUM_SCANNED_CHANNELS);
152  *
153  * {
154  * uint32 channels = 0xff; // all 8 channels
155  * uint32 mask = 0xff; // modify the selection of all channels
156  *
157  * // configure autoscan (single shot, not continuous scan)
158  * IfxVadc_Adc_setScan(&adcGroup, channels, mask, FALSE);
159  * }
160  * }
161  * \endcode
162  *
163  * ADC configuration:
164  * \code
165  * // create configuration
166  * IfxVadc_Adc_Config adcConfig;
167  * IfxVadc_Adc_initModuleConfig(&adcConfig, &MODULE_VADC);
168  *
169  * adcConfig.startupCalibration = TRUE;
170  *
171  * // initialize module
172  * // IfxVadc_Adc vadc; // declared globally
173  * IfxVadc_Adc_initModule(&vadc, &adcConfig);
174  *
175  * // create group config
176  * IfxVadc_Adc_GroupConfig adcGroupConfig;
177  * IfxVadc_Adc_initGroupConfig(&adcGroupConfig, &vadc);
178  *
179  * // initialize the group
180  * //IfxVadc_Adc_Group adcGroup; // defined globally
181  * adcGroupConfig.groupId = IfxVadc_GroupId_0;
182  * adcGroupConfig.master = adcGroupConfig.groupId;
183  *
184  * // enable all arbiter request sources
185  * adcGroupConfig.arbiter.requestSlotQueueEnabled = TRUE; // enable Queue mode
186  * adcGroupConfig.arbiter.requestSlotScanEnabled = TRUE; // enable Scan mode
187  * adcGroupConfig.arbiter.requestSlotBackgroundScanEnabled = TRUE; // enable Background scan
188  *
189  * // enable all gates in "always" mode (no edge detection)
190  * adcGroupConfig.queueRequest.triggerConfig.gatingMode = IfxVadc_GatingMode_always;
191  * adcGroupConfig.scanRequest.triggerConfig.gatingMode = IfxVadc_GatingMode_always;
192  * adcGroupConfig.backgroundScanRequest.triggerConfig.gatingMode = IfxVadc_GatingMode_always;
193  *
194  * IfxVadc_Adc_initGroup(&adcGroup, &adcGroupConfig);
195  *
196  * {
197  * // create channel config
198  * IfxVadc_Adc_ChannelConfig adcChannelConfig;
199  * IfxVadc_Adc_initChannelConfig(&adcChannelConfig, &adcGroup);
200  *
201  * // initialize the channels
202  * for(int i=0; i<NUM_SCANNED_CHANNELS; ++i) {
203  * adcChannelConfig.channelId = (IfxVadc_ChannelId)i;
204  * adcChannelConfig.resultRegister = IfxVadc_ChannelResult_0;
205  *
206  * // initialize the channel
207  * IfxVadc_Adc_Channel adcChannel;
208  * IfxVadc_Adc_initChannel(&adcChannel, &adcChannelConfig);
209  *
210  * IfxVadc_Adc_configureWaitForReadMode(&adcChannel, TRUE);
211  * }
212  * }
213  * adcGroup.group->RCR[0].B.SRGEN = 1; // interrupt when new result is available
214  *
215  * // send service request to DMA Channel 0
216  * IfxSrc_init((Ifx_SRC_SRCR*)&MODULE_SRC.VADC.G[0], IfxSrc_Tos_dma, 0);
217  * IfxSrc_enable((Ifx_SRC_SRCR*)&MODULE_SRC.VADC.G[0]);
218  * \endcode
219  *
220  * And finally the DMA channel configuration
221  * \code
222  * // create module config
223  * IfxDma_Dma_Config dmaConfig;
224  * IfxDma_Dma_initModuleConfig(&dmaConfig, &MODULE_DMA);
225  *
226  * // initialize module
227  * IfxDma_Dma dma;
228  * IfxDma_Dma_initModule(&dma, &dmaConfig);
229  *
230  * {
231  * // construct the channel configuration
232  * IfxDma_Dma_ChannelConfig chnCfg;
233  * IfxDma_Dma_initChannelConfig(&chnCfg, &dma);
234  *
235  * // select DMA channel which should be used
236  * chnCfg.channelId = IfxDma_ChannelId_0;
237  * chnCfg.hardwareRequestEnabled = TRUE; // will be triggered from VADC service request
238  *
239  * // interrupt configuration
240  * chnCfg.channelInterruptEnabled = TRUE; // service request from DMA after all words have been transfered
241  * chnCfg.channelInterruptPriority = IFX_INTPRIO_DMA_CH0;
242  * chnCfg.channelInterruptTypeOfService = (IfxSrc_Tos)IfxCpu_getCoreId();
243  *
244  * // source and destination address
245  * chnCfg.sourceAddress = (uint32)&adcGroup.group->RES[0]; // first result register
246  * chnCfg.sourceCircularBufferEnabled = TRUE;
247  * chnCfg.sourceAddressCircularRange = IfxDma_ChannelIncrementCircular_1; // keep this address
248  *
249  * chnCfg.destinationAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), &vadcResultBuffer[0]); // move into result buffer
250  * chnCfg.destinationAddressIncrementStep = IfxDma_ChannelIncrementStep_1; // increment once (=2 bytes) with each write
251  *
252  * // move size, transfer count and request/operation mode
253  * chnCfg.moveSize = IfxDma_ChannelMoveSize_16bit;
254  * chnCfg.transferCount = NUM_SCANNED_CHANNELS; // for the scanned channels
255  * chnCfg.requestMode = IfxDma_ChannelRequestMode_oneTransferPerRequest;
256  * chnCfg.operationMode = IfxDma_ChannelOperationMode_continuous; // hw request enable remains set after transaction
257  *
258  *
259  * // transfer configuration into DMA channel registers
260  * // IfxDma_Dma_Channel dmaChn; // declared globally
261  * IfxDma_Dma_initChannel(&dmaChn, &chnCfg);
262  *
263  * // configure IRQ handler which will be called after all result registers have been transfered
264  * IfxCpu_Irq_installInterruptHandler(&dmaCh0ISR, IFX_INTPRIO_DMA_CH0);
265  *
266  * // enable CPU interrupts
267  * IfxCpu_enableInterrupts();
268  * }
269  * \endcode
270  *
271  * In order to start the initial channel conversions, use:
272  * \code
273  * {
274  * uint32 channels = 0xff; // all 8 channels
275  * uint32 mask = 0xff; // modify the selection of all channels
276  *
277  * // configure and start autoscan (single shot, not continuous mode)
278  * IfxVadc_Adc_setScan(&adcGroup, channels, mask, FALSE);
279  * }
280  * \endcode
281  *
282  * DMA will transfer the results to DSPR during the autoscan (whenever a new result is availale), and
283  * invoke the dmaCh0ISR function once all channels have been converted.
284  *
285  * The ISR will re-configure the DMA channel and re-start the autoscan.
286  *
287  *
288  * \subsection IfxLld_Dma_Dma_LinkedList Linked Lists
289  *
290  * Linked lists allow to initiate multiple DMA transactions from independent transaction sets which are
291  * typically stored in a DSPR memory location, and fetched and executed from the DMA channel without
292  * further CPU interaction.
293  *
294  * Following example demonstrates, how 5 different transactions can be initiated from a single request.
295  * We copy the data of 5 CAN message objects to a DSPR location.
296  *
297  * Includes and global variables:
298  * \code
299  * #include <Dma/Dma/IfxDma_Dma.h>
300  * #include <Scu/Std/IfxScuWdt.h>
301  * #include <IfxCan_reg.h>
302  *
303  * // DMA channel handle
304  * IfxDma_Dma_Channel chn;
305  *
306  * // Linked List storage
307  * // IMPORTANT: it has to be aligned to an 64bit address, otherwise DMA can't read it
308  * #define NUM_LINKED_LIST_ITEMS 5
309  * __attribute__ ((aligned(64))) Ifx_DMA_CH linkedList[NUM_LINKED_LIST_ITEMS] ;
310  *
311  * // transfer these values to various CAN_MODATA[LH] registers via linked lists
312  * #define NUM_TRANSFERED_WORDS 2
313  * uint32 sourceBuffer[NUM_LINKED_LIST_ITEMS][NUM_TRANSFERED_WORDS];
314  *
315  * const uint32 destinationAddresses[NUM_LINKED_LIST_ITEMS] = {
316  * (uint32)&CAN_MODATAL0,
317  * (uint32)&CAN_MODATAL1,
318  * (uint32)&CAN_MODATAL2,
319  * (uint32)&CAN_MODATAL3,
320  * (uint32)&CAN_MODATAL4,
321  * };
322  * \endcode
323  *
324  * Following code to prepare CAN for this demo:
325  * \code
326  * // enable CAN (no Ifx LLD available yet)
327  * {
328  * uint32 passwd = IfxScuWdt_getCpuWatchdogPassword();
329  * IfxScuWdt_clearCpuEndinit(passwd);
330  *
331  * CAN_CLC.U = 0x0100;
332  * if( CAN_CLC.U ); // synch access
333  *
334  * // select f_clc as kernel clock
335  * CAN_MCR.B.CLKSEL = 1;
336  *
337  * // configure fractional divider
338  * CAN_FDR.U = 0x43ff;
339  *
340  * // wait until RAM has been initialized
341  * while( CAN_PANCTR.B.BUSY );
342  *
343  * IfxScuWdt_setCpuEndinit(passwd);
344  * }
345  * \endcode
346  *
347  *
348  * Build a linked list
349  * \code
350  * // create module config
351  * IfxDma_Dma_Config dmaConfig;
352  * IfxDma_Dma_initModuleConfig(&dmaConfig, &MODULE_DMA);
353  *
354  * // initialize module
355  * IfxDma_Dma dma;
356  * IfxDma_Dma_initModule(&dma, &dmaConfig);
357  *
358  * // initial channel configuration
359  * IfxDma_Dma_ChannelConfig cfg;
360  * IfxDma_Dma_initChannelConfig(&cfg, &dma);
361  *
362  * // following settings are used by all transactions
363  * cfg.transferCount = NUM_TRANSFERED_WORDS;
364  * cfg.requestMode = IfxDma_ChannelRequestMode_completeTransactionPerRequest;
365  * cfg.moveSize = IfxDma_ChannelMoveSize_32bit;
366  * cfg.shadowControl = IfxDma_ChannelShadow_linkedList;
367  *
368  * // generate linked list items
369  * for(int i=0; i<NUM_LINKED_LIST_ITEMS; ++i) {
370  * cfg.sourceAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), &sourceBuffer[i]);
371  * cfg.destinationAddress = destinationAddresses[i];
372  *
373  * // address to next transaction set
374  * cfg.shadowAddress = IFXCPU_GLB_ADDR_DSPR(IfxCpu_getCoreId(), (uint32)&linkedList[(i + 1) % NUM_LINKED_LIST_ITEMS]);
375  *
376  * // transfer first transaction set into DMA channel
377  * if( i == 0 ) {
378  * IfxDma_Dma_initChannel(&chn, &cfg);
379  * }
380  *
381  * // transfer into linked list storage
382  * IfxDma_Dma_initLinkedListEntry((void *)&linkedList[i], &cfg);
383  *
384  * if( i == 0 ) {
385  * // - trigger channel interrupt once the first transaction set has been loaded (again) into DMA channel
386  * linkedList[i].CHCSR.B.SIT = 1;
387  * } else {
388  * // - activate SCH (transaction request) for each entry, expect for the first one (linked list terminated here)
389  * linkedList[i].CHCSR.B.SCH = 1;
390  * }
391  * }
392  * \endcode
393  *
394  * The transfer can be started via software with:
395  * \code
396  * // clear service request flag
397  * (IfxDma_Dma_getSrcPointer(&chn))->B.CLRR = 1;
398  *
399  * // start linked list transaction
400  * IfxDma_Dma_startChannelTransaction(&chn);
401  *
402  * // wait for service request which is triggered at the end of linked list transfers
403  * while( !(IfxDma_Dma_getSrcPointer(&chn))->B.SRR );
404  * \endcode
405  *
406  * In order to synchronize with the end of linked list operations, it's recommended to poll the service request flag (triggered via linkedList[NUM_LINKED_LIST_ITEMS-1].CHCSR.B.SIT after the last word has been transfered), and not the transaction count as shown before, because a linked list will initiate multiple transactions.
407  *
408  * \defgroup IfxLld_Dma_Dma Dma
409  * \ingroup IfxLld_Dma
410  * \defgroup IfxLld_Dma_Dma_Data_Structures Data Structures
411  * \ingroup IfxLld_Dma_Dma
412  * \defgroup IfxLld_Dma_Dma_Module_Initialize Module Initialization
413  * \ingroup IfxLld_Dma_Dma
414  * \defgroup IfxLld_Dma_Dma_Channel_Initialize Channel Initialization
415  * \ingroup IfxLld_Dma_Dma
416  * \defgroup IfxLld_Dma_Dma_Linked_List Linked Lists
417  * \ingroup IfxLld_Dma_Dma
418  * \defgroup IfxLld_Dma_Dma_Channel_Transaction_Initiate Channel Transactions
419  * \ingroup IfxLld_Dma_Dma
420  */
421 
422 #ifndef IFXDMA_DMA_H
423 #define IFXDMA_DMA_H 1
424 
425 /******************************************************************************/
426 /*----------------------------------Includes----------------------------------*/
427 /******************************************************************************/
428 
429 #include "_Impl/IfxDma_cfg.h"
430 #include "Dma/Std/IfxDma.h"
431 
432 /******************************************************************************/
433 /*-----------------------------Data Structures--------------------------------*/
434 /******************************************************************************/
435 
436 /** \addtogroup IfxLld_Dma_Dma_Data_Structures
437  * \{ */
438 /** \brief DMA base address data structure (Module handle)
439  */
440 typedef struct
441 {
442  Ifx_DMA *dma; /**< \brief Specifies the pointer to the DMA registers */
443 } IfxDma_Dma;
444 
445 /** \} */
446 
447 /** \addtogroup IfxLld_Dma_Dma_Data_Structures
448  * \{ */
449 /** \brief Channel handle
450  */
451 typedef struct
452 {
453  Ifx_DMA *dma; /**< \brief Specifies the pointer to the DMA registers */
454  IfxDma_ChannelId channelId; /**< \brief Specifies the DMA channel */
455  Ifx_DMA_CH *channel; /**< \brief Specifies the pointer to DMA channel registers */
457 
458 /** \brief Configuration data structure of the channel
459  */
460 typedef struct
461 {
462  IfxDma_Dma *module; /**< \brief Specifies pointer to the IfxDma_Dma module handle */
463  IfxDma_ChannelId channelId; /**< \brief Specifies the channel being used */
464  uint32 sourceAddress; /**< \brief Source address for the DMA channel */
465  uint32 destinationAddress; /**< \brief Destination address for the DMA channel */
466  uint32 shadowAddress; /**< \brief Initial content of shadow address for the DMA channel */
467  uint32 readDataCrc; /**< \brief Checksum for read data of the channel */
468  uint32 sourceDestinationAddressCrc; /**< \brief Checksum for source and destination address of channel */
469  uint16 transferCount; /**< \brief Number of transfers in a transaction */
470  IfxDma_ChannelMove blockMode; /**< \brief Number of moves in a transfer */
471  IfxDma_ChannelRequestMode requestMode; /**< \brief A service request initiates a single transfer, or the complete transaction */
472  IfxDma_ChannelOperationMode operationMode; /**< \brief keep enable/disable the hardware channel request after a transaction */
473  IfxDma_ChannelMoveSize moveSize; /**< \brief Read/write data size */
474  IfxDma_ChannelPattern pattern; /**< \brief Pattern selection operation modes */
475  IfxDma_ChannelRequestSource requestSource; /**< \brief Request of channel transfer through hardware or daisy chain. channel transfer complete interrupt of previous channel will trigger the next channel request */
476  IfxDma_ChannelBusPriority busPriority; /**< \brief Bus priority selection */
477  boolean hardwareRequestEnabled; /**< \brief Enabling channel transaction via hardware request */
478  IfxDma_ChannelIncrementStep sourceAddressIncrementStep; /**< \brief Describes the address offset with which the source address should be modified after each move */
479  IfxDma_ChannelIncrementDirection sourceAddressIncrementDirection; /**< \brief Decides whether the source address offset after each move should be added or decremented from the exisiting address */
480  IfxDma_ChannelIncrementCircular sourceAddressCircularRange; /**< \brief Determines which part of the source address remains unchanged and therby not updated after each move */
481  IfxDma_ChannelIncrementStep destinationAddressIncrementStep; /**< \brief Describes the address offset with which the destination address should be modified after each move */
482  IfxDma_ChannelIncrementDirection destinationAddressIncrementDirection; /**< \brief Decides whether the destination address offset after each move should be added or decremented from the exisiting address */
483  IfxDma_ChannelIncrementCircular destinationAddressCircularRange; /**< \brief Determines which part of the destination address remains unchanged and therby not updated after each move */
484  IfxDma_ChannelShadow shadowControl; /**< \brief selects the shadow transfer mode */
485  boolean sourceCircularBufferEnabled; /**< \brief Enables/Disables the source circular buffering */
486  boolean destinationCircularBufferEnabled; /**< \brief Enables/Disables the destination circular buffering */
487  boolean timestampEnabled; /**< \brief Enables/Disables the appendage of the time stamp after end of the last DMA move in a transaction */
488  boolean wrapSourceInterruptEnabled; /**< \brief An interrupt should be triggered whenever source address is wrapped */
489  boolean wrapDestinationInterruptEnabled; /**< \brief An interrupt should be triggered whenever destination address is wrapped */
490  boolean channelInterruptEnabled; /**< \brief The channel transfer interrupt should be triggered. See also channelInterruptControl */
491  IfxDma_ChannelInterruptControl channelInterruptControl; /**< \brief The channel transfer interrupt can either be triggered depending on the interruptRaiseThreshold, or each time the transaction count is decremented */
492  uint8 interruptRaiseThreshold; /**< \brief The value of the transferCount at which the interrupt should be raised */
493  boolean transactionRequestLostInterruptEnabled; /**< \brief Enables/Disables the channel transaction request lost interrupt */
494  Ifx_Priority channelInterruptPriority; /**< \brief Priority of the channel interrupt trigger */
495  IfxSrc_Tos channelInterruptTypeOfService; /**< \brief Interrupt service provider */
497 
498 /** \brief Configuration data structure of the Module
499  */
500 typedef struct
501 {
502  Ifx_DMA *dma; /**< \brief Specifies the pointer to the DMA registers */
504 
505 /** \} */
506 
507 /** \addtogroup IfxLld_Dma_Dma_Module_Initialize
508  * \{ */
509 
510 /******************************************************************************/
511 /*-------------------------Global Function Prototypes-------------------------*/
512 /******************************************************************************/
513 
514 /** \brief initializes a DMA module handle based on the current configuration.
515  * Can be used in code where it's ensure that the DMA module is already initialized, and a DMA handle isn't globally available.
516  * \param dmaHandle pointer to the DMA module handle
517  * \param dma pointer to the DMA registers
518  * \return None
519  *
520  * \code
521  * IfxDma_Dma dma;
522  * IfxDma_Dma_createModuleHandle(&dma, &MODULE_DMA);
523  * \endcode
524  *
525  */
526 IFX_EXTERN void IfxDma_Dma_createModuleHandle(IfxDma_Dma *dmaHandle, Ifx_DMA *dma);
527 
528 /** \brief de-initialize the DMA module
529  * \param dma pointer to the DMA module handle
530  * \return None
531  */
533 
534 /** \brief Initialize the DMA module
535  * \param dma pointer to the DMA module handle
536  * \param config Pointer to configuration structure of the DMA module
537  * \return None
538  *
539  * See \ref IfxLld_Dma_Dma_Simple
540  *
541  */
543 
544 /** \brief initialize the DMA module configuration
545  * \param config Pointer to configuration structure of the DMA module
546  * \param dma pointer to the DMA registers
547  * \return None
548  *
549  * See \ref IfxLld_Dma_Dma_Simple
550  *
551  */
552 IFX_EXTERN void IfxDma_Dma_initModuleConfig(IfxDma_Dma_Config *config, Ifx_DMA *dma);
553 
554 /** \} */
555 
556 /** \addtogroup IfxLld_Dma_Dma_Channel_Initialize
557  * \{ */
558 
559 /******************************************************************************/
560 /*-------------------------Global Function Prototypes-------------------------*/
561 /******************************************************************************/
562 
563 /** \brief initialize the DMA channel
564  * \param channel pointer to the DMA base address and channel ID
565  * \param config pointer to the DMA default channel configuration structure
566  * \return None
567  *
568  * See \ref IfxLld_Dma_Dma_Simple
569  *
570  */
572 
573 /** \brief initialize the DMA module channel configuration
574  * \param config pointer to the DMA default channel configuration structure
575  * \param dma pointer to the DMA module handle
576  * \return None
577  *
578  * See \ref IfxLld_Dma_Dma_Simple
579  *
580  */
582 
583 /** \} */
584 
585 /** \addtogroup IfxLld_Dma_Dma_Linked_List
586  * \{ */
587 
588 /******************************************************************************/
589 /*-------------------------Inline Function Prototypes-------------------------*/
590 /******************************************************************************/
591 
592 /** \brief Returns the SRC pointer for given DMA channel
593  * \param channel pointer to the DMA base address and channel ID
594  * \return SRC pointer for given DMA channel
595  */
596 IFX_INLINE volatile Ifx_SRC_SRCR *IfxDma_Dma_getSrcPointer(IfxDma_Dma_Channel *channel);
597 
598 /******************************************************************************/
599 /*-------------------------Global Function Prototypes-------------------------*/
600 /******************************************************************************/
601 
602 /** \brief linked list functionality within the DMA module
603  * \param ptrToAddress pointer to the memory location where the linked list entry should be stored
604  * \param config pointer to the DMA default channel configuration structure
605  * \return None
606  *
607  * See \ref IfxLld_Dma_Dma_LinkedList
608  *
609  */
610 IFX_EXTERN void IfxDma_Dma_initLinkedListEntry(void *ptrToAddress, IfxDma_Dma_ChannelConfig *config);
611 
612 /** \} */
613 
614 /** \addtogroup IfxLld_Dma_Dma_Channel_Transaction_Initiate
615  * \{ */
616 
617 /******************************************************************************/
618 /*-------------------------Inline Function Prototypes-------------------------*/
619 /******************************************************************************/
620 
621 /** \brief Poll for an ongoing transaction
622  * \param channel pointer to the DMA base address and channel ID
623  * \return TRUE if a transaction request for the given channel is pending
624  *
625  * See \ref IfxLld_Dma_Dma_Simple
626  *
627  */
629 
630 /** \brief Re-initialize the destination address after a transaction
631  * \param channel pointer to the DMA base address and channel ID
632  * \param address is the Initial address of the destination pointer
633  * \return None
634  *
635  * See \ref IfxLld_Dma_Dma_Simple
636  *
637  */
639 
640 /** \brief Re-initialize the source address after a transaction
641  * \param channel pointer to the DMA base address and channel ID
642  * \param address is the Initial address of the source pointer
643  * \return None
644  *
645  * See \ref IfxLld_Dma_Dma_Simple
646  *
647  */
649 
650 /** \brief Re-initialize the transfer count after a transaction
651  * \param channel pointer to the DMA base address and channel ID
652  * \param transferCount value holds the DMA transfers within a transaction (1..16383; 0 handled like 1 transaction)
653  * \return None
654  *
655  * See \ref IfxLld_Dma_Dma_Simple
656  *
657  */
659 
660 /** \brief initiate the DMA move transaction
661  * \param channel pointer to the DMA base address and channel ID
662  * \return None
663  *
664  * See \ref IfxLld_Dma_Dma_Simple
665  *
666  */
668 
669 /** \brief Clear a channel transfer interrupt flag
670  * \param channel pointer to the DMA base address and channel ID
671  * \return None
672  */
674 
675 /** \brief Return a channel transfer interrupt flag
676  * \param channel pointer to the DMA base address and channel ID
677  * \return TRUE if the interrupt flag is set
678  * FALSE if the interrupt flag is not set
679  */
681 
682 /** \brief Return and clear a channel transfer interrupt flag
683  * The flag is automatically cleared with the call to this function
684  * \param channel pointer to the DMA base address and channel ID
685  * \return TRUE if the interrupt flag is set
686  * FALSE if the interrupt flag is not set
687  */
689 
690 /** \} */
691 
692 /******************************************************************************/
693 /*---------------------Inline Function Implementations------------------------*/
694 /******************************************************************************/
695 
697 {
698  return IfxDma_getSrcPointer(channel->dma, channel->channelId);
699 }
700 
701 
703 {
704  return IfxDma_isChannelTransactionPending(channel->dma, channel->channelId);
705 }
706 
707 
709 {
710  IfxDma_setChannelDestinationAddress(channel->dma, channel->channelId, (void *)address);
711 }
712 
713 
715 {
716  IfxDma_setChannelSourceAddress(channel->dma, channel->channelId, (void *)address);
717 }
718 
719 
721 {
722  IfxDma_setChannelTransferCount(channel->dma, channel->channelId, transferCount);
723 }
724 
725 
727 {
728  channel->channel->CHCSR.U = 0; // for linked lists: ensure that this memory location is initialized
729  IfxDma_startChannelTransaction(channel->dma, channel->channelId);
730 }
731 
732 
734 {
735  IfxDma_clearChannelInterrupt(channel->dma, channel->channelId);
736 }
737 
738 
740 {
741  return IfxDma_getChannelInterrupt(channel->dma, channel->channelId);
742 }
743 
744 
746 {
747  return IfxDma_getAndClearChannelInterrupt(channel->dma, channel->channelId);
748 }
749 
750 
751 #endif /* IFXDMA_DMA_H */