added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
<>
Date:
Fri Sep 02 15:07:44 2016 +0100
Revision:
144:ef7eb2e8f9f7
Parent:
50:a417edff4437
This updates the lib to the mbed lib v125

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 2 * @file em_dma.c
<> 144:ef7eb2e8f9f7 3 * @brief Direct memory access (DMA) module peripheral API
<> 144:ef7eb2e8f9f7 4 * @version 4.2.1
<> 144:ef7eb2e8f9f7 5 *******************************************************************************
<> 144:ef7eb2e8f9f7 6 * @section License
<> 144:ef7eb2e8f9f7 7 * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
<> 144:ef7eb2e8f9f7 8 *******************************************************************************
<> 144:ef7eb2e8f9f7 9 *
<> 144:ef7eb2e8f9f7 10 * Permission is granted to anyone to use this software for any purpose,
<> 144:ef7eb2e8f9f7 11 * including commercial applications, and to alter it and redistribute it
<> 144:ef7eb2e8f9f7 12 * freely, subject to the following restrictions:
<> 144:ef7eb2e8f9f7 13 *
<> 144:ef7eb2e8f9f7 14 * 1. The origin of this software must not be misrepresented; you must not
<> 144:ef7eb2e8f9f7 15 * claim that you wrote the original software.
<> 144:ef7eb2e8f9f7 16 * 2. Altered source versions must be plainly marked as such, and must not be
<> 144:ef7eb2e8f9f7 17 * misrepresented as being the original software.
<> 144:ef7eb2e8f9f7 18 * 3. This notice may not be removed or altered from any source distribution.
<> 144:ef7eb2e8f9f7 19 *
<> 144:ef7eb2e8f9f7 20 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
<> 144:ef7eb2e8f9f7 21 * obligation to support this Software. Silicon Labs is providing the
<> 144:ef7eb2e8f9f7 22 * Software "AS IS", with no express or implied warranties of any kind,
<> 144:ef7eb2e8f9f7 23 * including, but not limited to, any implied warranties of merchantability
<> 144:ef7eb2e8f9f7 24 * or fitness for any particular purpose or warranties against infringement
<> 144:ef7eb2e8f9f7 25 * of any proprietary rights of a third party.
<> 144:ef7eb2e8f9f7 26 *
<> 144:ef7eb2e8f9f7 27 * Silicon Labs will not be liable for any consequential, incidental, or
<> 144:ef7eb2e8f9f7 28 * special damages, or any other relief, or for any claim by any third party,
<> 144:ef7eb2e8f9f7 29 * arising from your use of this Software.
<> 144:ef7eb2e8f9f7 30 *
<> 144:ef7eb2e8f9f7 31 ******************************************************************************/
<> 144:ef7eb2e8f9f7 32
<> 144:ef7eb2e8f9f7 33 #include "em_dma.h"
<> 144:ef7eb2e8f9f7 34 #if defined( DMA_PRESENT )
<> 144:ef7eb2e8f9f7 35
<> 144:ef7eb2e8f9f7 36 #include "em_cmu.h"
<> 144:ef7eb2e8f9f7 37 #include "em_assert.h"
<> 144:ef7eb2e8f9f7 38 #include "em_bus.h"
<> 144:ef7eb2e8f9f7 39
<> 144:ef7eb2e8f9f7 40 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 41 * @addtogroup EM_Library
<> 144:ef7eb2e8f9f7 42 * @{
<> 144:ef7eb2e8f9f7 43 ******************************************************************************/
<> 144:ef7eb2e8f9f7 44
<> 144:ef7eb2e8f9f7 45 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 46 * @addtogroup DMA
<> 144:ef7eb2e8f9f7 47 * @brief Direct Memory Access (DMA) Peripheral API
<> 144:ef7eb2e8f9f7 48 * @details
<> 144:ef7eb2e8f9f7 49 * These DMA access functions provide basic support for the following
<> 144:ef7eb2e8f9f7 50 * types of DMA cycles:
<> 144:ef7eb2e8f9f7 51 *
<> 144:ef7eb2e8f9f7 52 * @li @b Basic, used for transferring data between memory and peripherals.
<> 144:ef7eb2e8f9f7 53 * @li @b Auto-request, used for transferring data between memory locations.
<> 144:ef7eb2e8f9f7 54 * @li @b Ping-pong, used for for continuous transfer of data between memory
<> 144:ef7eb2e8f9f7 55 * and peripherals, automatically toggling between primary and alternate
<> 144:ef7eb2e8f9f7 56 * descriptors.
<> 144:ef7eb2e8f9f7 57 * @li @b Memory @b scatter-gather, used for transferring a number of buffers
<> 144:ef7eb2e8f9f7 58 * between memory locations.
<> 144:ef7eb2e8f9f7 59 * @li @b Peripheral @b scatter-gather, used for transferring a number of
<> 144:ef7eb2e8f9f7 60 * buffers between memory and peripherals.
<> 144:ef7eb2e8f9f7 61 *
<> 144:ef7eb2e8f9f7 62 * A basic understanding of the DMA controller is assumed. Please refer to
<> 144:ef7eb2e8f9f7 63 * the reference manual for further details.
<> 144:ef7eb2e8f9f7 64 *
<> 144:ef7eb2e8f9f7 65 * The term 'descriptor' is used as a synonym to the 'channel control data
<> 144:ef7eb2e8f9f7 66 * structure' term.
<> 144:ef7eb2e8f9f7 67 *
<> 144:ef7eb2e8f9f7 68 * In order to use the DMA controller, the initialization function must have
<> 144:ef7eb2e8f9f7 69 * been executed once (normally during system init):
<> 144:ef7eb2e8f9f7 70 * @verbatim
<> 144:ef7eb2e8f9f7 71 * DMA_Init();
<> 144:ef7eb2e8f9f7 72 * @endverbatim
<> 144:ef7eb2e8f9f7 73 *
<> 144:ef7eb2e8f9f7 74 * Then, normally a user of a DMA channel configures the channel:
<> 144:ef7eb2e8f9f7 75 * @verbatim
<> 144:ef7eb2e8f9f7 76 * DMA_CfgChannel();
<> 144:ef7eb2e8f9f7 77 * @endverbatim
<> 144:ef7eb2e8f9f7 78 *
<> 144:ef7eb2e8f9f7 79 * The channel configuration only has to be done once, if reusing the channel
<> 144:ef7eb2e8f9f7 80 * for the same purpose later.
<> 144:ef7eb2e8f9f7 81 *
<> 144:ef7eb2e8f9f7 82 * In order to set up a DMA cycle, the primary and/or alternate descriptor
<> 144:ef7eb2e8f9f7 83 * has to be set up as indicated below.
<> 144:ef7eb2e8f9f7 84 *
<> 144:ef7eb2e8f9f7 85 * For basic or auto-request cycles, use once on either primary or alternate
<> 144:ef7eb2e8f9f7 86 * descriptor:
<> 144:ef7eb2e8f9f7 87 * @verbatim
<> 144:ef7eb2e8f9f7 88 * DMA_CfgDescr();
<> 144:ef7eb2e8f9f7 89 * @endverbatim
<> 144:ef7eb2e8f9f7 90 *
<> 144:ef7eb2e8f9f7 91 * For ping-pong cycles, configure both primary or alternate descriptors:
<> 144:ef7eb2e8f9f7 92 * @verbatim
<> 144:ef7eb2e8f9f7 93 * DMA_CfgDescr(); // Primary descriptor config
<> 144:ef7eb2e8f9f7 94 * DMA_CfgDescr(); // Alternate descriptor config
<> 144:ef7eb2e8f9f7 95 * @endverbatim
<> 144:ef7eb2e8f9f7 96 *
<> 144:ef7eb2e8f9f7 97 * For scatter-gather cycles, the alternate descriptor array must be programmed:
<> 144:ef7eb2e8f9f7 98 * @verbatim
<> 144:ef7eb2e8f9f7 99 * // 'n' is the number of scattered buffers
<> 144:ef7eb2e8f9f7 100 * // 'descr' points to the start of the alternate descriptor array
<> 144:ef7eb2e8f9f7 101 *
<> 144:ef7eb2e8f9f7 102 * // Fill in 'cfg'
<> 144:ef7eb2e8f9f7 103 * DMA_CfgDescrScatterGather(descr, 0, cfg);
<> 144:ef7eb2e8f9f7 104 * // Fill in 'cfg'
<> 144:ef7eb2e8f9f7 105 * DMA_CfgDescrScatterGather(descr, 1, cfg);
<> 144:ef7eb2e8f9f7 106 * :
<> 144:ef7eb2e8f9f7 107 * // Fill in 'cfg'
<> 144:ef7eb2e8f9f7 108 * DMA_CfgDescrScatterGather(descr, n - 1, cfg);
<> 144:ef7eb2e8f9f7 109 * @endverbatim
<> 144:ef7eb2e8f9f7 110 *
<> 144:ef7eb2e8f9f7 111 * In many cases, the descriptor configuration only has to be done once, if
<> 144:ef7eb2e8f9f7 112 * re-using the channel for the same type of DMA cycles later.
<> 144:ef7eb2e8f9f7 113 *
<> 144:ef7eb2e8f9f7 114 * In order to activate the DMA cycle, use the respective DMA_Activate...()
<> 144:ef7eb2e8f9f7 115 * function.
<> 144:ef7eb2e8f9f7 116 *
<> 144:ef7eb2e8f9f7 117 * For ping-pong DMA cycles, use DMA_RefreshPingPong() from the callback to
<> 144:ef7eb2e8f9f7 118 * prepare the completed descriptor for reuse. Notice that the refresh must
<> 144:ef7eb2e8f9f7 119 * be done prior to the other active descriptor completes, otherwise the
<> 144:ef7eb2e8f9f7 120 * ping-pong DMA cycle will halt.
<> 144:ef7eb2e8f9f7 121 * @{
<> 144:ef7eb2e8f9f7 122 ******************************************************************************/
<> 144:ef7eb2e8f9f7 123
<> 144:ef7eb2e8f9f7 124 /*******************************************************************************
<> 144:ef7eb2e8f9f7 125 ************************** LOCAL FUNCTIONS ********************************
<> 144:ef7eb2e8f9f7 126 ******************************************************************************/
<> 144:ef7eb2e8f9f7 127
<> 144:ef7eb2e8f9f7 128 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
<> 144:ef7eb2e8f9f7 129
<> 144:ef7eb2e8f9f7 130 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 131 * @brief
<> 144:ef7eb2e8f9f7 132 * Prepare descriptor for DMA cycle.
<> 144:ef7eb2e8f9f7 133 *
<> 144:ef7eb2e8f9f7 134 * @details
<> 144:ef7eb2e8f9f7 135 * This function prepares the last pieces of configuration required to start a
<> 144:ef7eb2e8f9f7 136 * DMA cycle. Since the DMA controller itself modifies some parts of the
<> 144:ef7eb2e8f9f7 137 * descriptor during use, those parts need to be refreshed if reusing a
<> 144:ef7eb2e8f9f7 138 * descriptor configuration.
<> 144:ef7eb2e8f9f7 139 *
<> 144:ef7eb2e8f9f7 140 * @note
<> 144:ef7eb2e8f9f7 141 * If using this function on a descriptor already activated and in use by the
<> 144:ef7eb2e8f9f7 142 * DMA controller, the behaviour is undefined.
<> 144:ef7eb2e8f9f7 143 *
<> 144:ef7eb2e8f9f7 144 * @param[in] channel
<> 144:ef7eb2e8f9f7 145 * DMA channel to prepare for DMA cycle.
<> 144:ef7eb2e8f9f7 146 *
<> 144:ef7eb2e8f9f7 147 * @param[in] cycleCtrl
<> 144:ef7eb2e8f9f7 148 * DMA cycle type to prepare for.
<> 144:ef7eb2e8f9f7 149 *
<> 144:ef7eb2e8f9f7 150 * @param[in] primary
<> 144:ef7eb2e8f9f7 151 * @li true - prepare primary descriptor
<> 144:ef7eb2e8f9f7 152 * @li false - prepare alternate descriptor
<> 144:ef7eb2e8f9f7 153 *
<> 144:ef7eb2e8f9f7 154 * @param[in] useBurst
<> 144:ef7eb2e8f9f7 155 * The burst feature is only used on peripherals supporting DMA bursts.
<> 144:ef7eb2e8f9f7 156 * Bursts must not be used if the total length (as given by nMinus1) is
<> 144:ef7eb2e8f9f7 157 * less than the arbitration rate configured for the descriptor. Please
<> 144:ef7eb2e8f9f7 158 * refer to the reference manual for further details on burst usage.
<> 144:ef7eb2e8f9f7 159 *
<> 144:ef7eb2e8f9f7 160 * @param[in] dst
<> 144:ef7eb2e8f9f7 161 * Address to start location to transfer data to. If NULL, leave setting in
<> 144:ef7eb2e8f9f7 162 * descriptor as is.
<> 144:ef7eb2e8f9f7 163 *
<> 144:ef7eb2e8f9f7 164 * @param[in] src
<> 144:ef7eb2e8f9f7 165 * Address to start location to transfer data from. If NULL, leave setting in
<> 144:ef7eb2e8f9f7 166 * descriptor as is.
<> 144:ef7eb2e8f9f7 167 *
<> 144:ef7eb2e8f9f7 168 * @param[in] nMinus1
<> 144:ef7eb2e8f9f7 169 * Number of elements (minus 1) to transfer (<= 1023).
<> 144:ef7eb2e8f9f7 170 ******************************************************************************/
<> 144:ef7eb2e8f9f7 171 static void DMA_Prepare(unsigned int channel,
<> 144:ef7eb2e8f9f7 172 DMA_CycleCtrl_TypeDef cycleCtrl,
<> 144:ef7eb2e8f9f7 173 bool primary,
<> 144:ef7eb2e8f9f7 174 bool useBurst,
<> 144:ef7eb2e8f9f7 175 void *dst,
<> 144:ef7eb2e8f9f7 176 void *src,
<> 144:ef7eb2e8f9f7 177 unsigned int nMinus1)
<> 144:ef7eb2e8f9f7 178 {
<> 144:ef7eb2e8f9f7 179 DMA_DESCRIPTOR_TypeDef *descr;
<> 144:ef7eb2e8f9f7 180 DMA_DESCRIPTOR_TypeDef *primDescr;
<> 144:ef7eb2e8f9f7 181 DMA_CB_TypeDef *cb;
<> 144:ef7eb2e8f9f7 182 uint32_t inc;
<> 144:ef7eb2e8f9f7 183 uint32_t chBit;
<> 144:ef7eb2e8f9f7 184 uint32_t tmp;
<> 144:ef7eb2e8f9f7 185
<> 144:ef7eb2e8f9f7 186 primDescr = ((DMA_DESCRIPTOR_TypeDef *)(DMA->CTRLBASE)) + channel;
<> 144:ef7eb2e8f9f7 187
<> 144:ef7eb2e8f9f7 188 /* Find descriptor to configure */
<> 144:ef7eb2e8f9f7 189 if (primary)
<> 144:ef7eb2e8f9f7 190 {
<> 144:ef7eb2e8f9f7 191 descr = primDescr;
<> 144:ef7eb2e8f9f7 192 }
<> 144:ef7eb2e8f9f7 193 else
<> 144:ef7eb2e8f9f7 194 {
<> 144:ef7eb2e8f9f7 195 descr = ((DMA_DESCRIPTOR_TypeDef *)(DMA->ALTCTRLBASE)) + channel;
<> 144:ef7eb2e8f9f7 196 }
<> 144:ef7eb2e8f9f7 197
<> 144:ef7eb2e8f9f7 198 /* If callback defined, update info on whether callback is issued */
<> 144:ef7eb2e8f9f7 199 /* for primary or alternate descriptor. Mainly needed for ping-pong */
<> 144:ef7eb2e8f9f7 200 /* cycles. */
<> 144:ef7eb2e8f9f7 201 cb = (DMA_CB_TypeDef *)(primDescr->USER);
<> 144:ef7eb2e8f9f7 202 if (cb)
<> 144:ef7eb2e8f9f7 203 {
<> 144:ef7eb2e8f9f7 204 cb->primary = (uint8_t)primary;
<> 144:ef7eb2e8f9f7 205 }
<> 144:ef7eb2e8f9f7 206
<> 144:ef7eb2e8f9f7 207 if (src)
<> 144:ef7eb2e8f9f7 208 {
<> 144:ef7eb2e8f9f7 209 inc = (descr->CTRL & _DMA_CTRL_SRC_INC_MASK) >> _DMA_CTRL_SRC_INC_SHIFT;
<> 144:ef7eb2e8f9f7 210 if (inc == _DMA_CTRL_SRC_INC_NONE)
<> 144:ef7eb2e8f9f7 211 {
<> 144:ef7eb2e8f9f7 212 descr->SRCEND = src;
<> 144:ef7eb2e8f9f7 213 }
<> 144:ef7eb2e8f9f7 214 else
<> 144:ef7eb2e8f9f7 215 {
<> 144:ef7eb2e8f9f7 216 descr->SRCEND = (void *)((uint32_t)src + (nMinus1 << inc));
<> 144:ef7eb2e8f9f7 217 }
<> 144:ef7eb2e8f9f7 218 }
<> 144:ef7eb2e8f9f7 219
<> 144:ef7eb2e8f9f7 220 if (dst)
<> 144:ef7eb2e8f9f7 221 {
<> 144:ef7eb2e8f9f7 222 inc = (descr->CTRL & _DMA_CTRL_DST_INC_MASK) >> _DMA_CTRL_DST_INC_SHIFT;
<> 144:ef7eb2e8f9f7 223 if (inc == _DMA_CTRL_DST_INC_NONE)
<> 144:ef7eb2e8f9f7 224 {
<> 144:ef7eb2e8f9f7 225 descr->DSTEND = dst;
<> 144:ef7eb2e8f9f7 226 }
<> 144:ef7eb2e8f9f7 227 else
<> 144:ef7eb2e8f9f7 228 {
<> 144:ef7eb2e8f9f7 229 descr->DSTEND = (void *)((uint32_t)dst + (nMinus1 << inc));
<> 144:ef7eb2e8f9f7 230 }
<> 144:ef7eb2e8f9f7 231 }
<> 144:ef7eb2e8f9f7 232
<> 144:ef7eb2e8f9f7 233 chBit = 1 << channel;
<> 144:ef7eb2e8f9f7 234 if (useBurst)
<> 144:ef7eb2e8f9f7 235 {
<> 144:ef7eb2e8f9f7 236 DMA->CHUSEBURSTS = chBit;
<> 144:ef7eb2e8f9f7 237 }
<> 144:ef7eb2e8f9f7 238 else
<> 144:ef7eb2e8f9f7 239 {
<> 144:ef7eb2e8f9f7 240 DMA->CHUSEBURSTC = chBit;
<> 144:ef7eb2e8f9f7 241 }
<> 144:ef7eb2e8f9f7 242
<> 144:ef7eb2e8f9f7 243 if (primary)
<> 144:ef7eb2e8f9f7 244 {
<> 144:ef7eb2e8f9f7 245 DMA->CHALTC = chBit;
<> 144:ef7eb2e8f9f7 246 }
<> 144:ef7eb2e8f9f7 247 else
<> 144:ef7eb2e8f9f7 248 {
<> 144:ef7eb2e8f9f7 249 DMA->CHALTS = chBit;
<> 144:ef7eb2e8f9f7 250 }
<> 144:ef7eb2e8f9f7 251
<> 144:ef7eb2e8f9f7 252 /* Set cycle control */
<> 144:ef7eb2e8f9f7 253 tmp = descr->CTRL & ~(_DMA_CTRL_CYCLE_CTRL_MASK | _DMA_CTRL_N_MINUS_1_MASK);
<> 144:ef7eb2e8f9f7 254 tmp |= nMinus1 << _DMA_CTRL_N_MINUS_1_SHIFT;
<> 144:ef7eb2e8f9f7 255 tmp |= (uint32_t)cycleCtrl << _DMA_CTRL_CYCLE_CTRL_SHIFT;
<> 144:ef7eb2e8f9f7 256 descr->CTRL = tmp;
<> 144:ef7eb2e8f9f7 257 }
<> 144:ef7eb2e8f9f7 258
<> 144:ef7eb2e8f9f7 259 /** @endcond */
<> 144:ef7eb2e8f9f7 260
<> 144:ef7eb2e8f9f7 261 /*******************************************************************************
<> 144:ef7eb2e8f9f7 262 ************************ INTERRUPT FUNCTIONS ******************************
<> 144:ef7eb2e8f9f7 263 ******************************************************************************/
<> 144:ef7eb2e8f9f7 264
<> 144:ef7eb2e8f9f7 265 #ifndef EXCLUDE_DEFAULT_DMA_IRQ_HANDLER
<> 144:ef7eb2e8f9f7 266
<> 144:ef7eb2e8f9f7 267 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 268 * @brief
<> 144:ef7eb2e8f9f7 269 * Interrupt handler for DMA cycle completion handling.
<> 144:ef7eb2e8f9f7 270 *
<> 144:ef7eb2e8f9f7 271 * @details
<> 144:ef7eb2e8f9f7 272 * Clears any pending flags and calls registered callback (if any).
<> 144:ef7eb2e8f9f7 273 *
<> 144:ef7eb2e8f9f7 274 * If using the default interrupt vector table setup provided, this function
<> 144:ef7eb2e8f9f7 275 * is automatically placed in the IRQ table due to weak linking. If taking
<> 144:ef7eb2e8f9f7 276 * control over the interrupt vector table in some other way, this interrupt
<> 144:ef7eb2e8f9f7 277 * handler must be installed in order to be able to support callback actions.
<> 144:ef7eb2e8f9f7 278 *
<> 144:ef7eb2e8f9f7 279 * In order for the user to implement a custom IRQ handler or run without
<> 144:ef7eb2e8f9f7 280 * a DMA IRQ handler, the user can define EXCLUDE_DEFAULT_DMA_IRQ_HANDLER
<> 144:ef7eb2e8f9f7 281 * with a \#define statement or with the compiler option -D.
<> 144:ef7eb2e8f9f7 282 *
<> 144:ef7eb2e8f9f7 283 ******************************************************************************/
<> 144:ef7eb2e8f9f7 284 void DMA_IRQHandler(void)
<> 144:ef7eb2e8f9f7 285 {
<> 144:ef7eb2e8f9f7 286 int channel;
<> 144:ef7eb2e8f9f7 287 DMA_CB_TypeDef *cb;
<> 144:ef7eb2e8f9f7 288 uint32_t pending;
<> 144:ef7eb2e8f9f7 289 uint32_t pendingPrio;
<> 144:ef7eb2e8f9f7 290 uint32_t prio;
<> 144:ef7eb2e8f9f7 291 uint32_t primaryCpy;
<> 144:ef7eb2e8f9f7 292 int i;
<> 144:ef7eb2e8f9f7 293
<> 144:ef7eb2e8f9f7 294 /* Get all pending and enabled interrupts */
<> 144:ef7eb2e8f9f7 295 pending = DMA->IF;
<> 144:ef7eb2e8f9f7 296 pending &= DMA->IEN;
<> 144:ef7eb2e8f9f7 297
<> 144:ef7eb2e8f9f7 298 /* Check for bus error */
<> 144:ef7eb2e8f9f7 299 if (pending & DMA_IF_ERR)
<> 144:ef7eb2e8f9f7 300 {
<> 144:ef7eb2e8f9f7 301 /* Loop here to enable the debugger to see what has happened */
<> 144:ef7eb2e8f9f7 302 while (1)
<> 144:ef7eb2e8f9f7 303 ;
<> 144:ef7eb2e8f9f7 304 }
<> 144:ef7eb2e8f9f7 305
<> 144:ef7eb2e8f9f7 306 /* Process all pending channel interrupts. First process channels */
<> 144:ef7eb2e8f9f7 307 /* defined with high priority, then those with default priority. */
<> 144:ef7eb2e8f9f7 308 prio = DMA->CHPRIS;
<> 144:ef7eb2e8f9f7 309 pendingPrio = pending & prio;
<> 144:ef7eb2e8f9f7 310 for (i = 0; i < 2; i++)
<> 144:ef7eb2e8f9f7 311 {
<> 144:ef7eb2e8f9f7 312 channel = 0;
<> 144:ef7eb2e8f9f7 313 /* Process pending interrupts within high/default priority group */
<> 144:ef7eb2e8f9f7 314 /* honouring priority within group. */
<> 144:ef7eb2e8f9f7 315 while (pendingPrio)
<> 144:ef7eb2e8f9f7 316 {
<> 144:ef7eb2e8f9f7 317 if (pendingPrio & 1)
<> 144:ef7eb2e8f9f7 318 {
<> 144:ef7eb2e8f9f7 319 DMA_DESCRIPTOR_TypeDef *descr = (DMA_DESCRIPTOR_TypeDef *)(DMA->CTRLBASE);
<> 144:ef7eb2e8f9f7 320 uint32_t chmask = 1 << channel;
<> 144:ef7eb2e8f9f7 321
<> 144:ef7eb2e8f9f7 322 /* Clear pending interrupt prior to invoking callback, in case it */
<> 144:ef7eb2e8f9f7 323 /* sets up another DMA cycle. */
<> 144:ef7eb2e8f9f7 324 DMA->IFC = chmask;
<> 144:ef7eb2e8f9f7 325
<> 144:ef7eb2e8f9f7 326 /* Normally, no point in enabling interrupt without callback, but */
<> 144:ef7eb2e8f9f7 327 /* check if callback is defined anyway. Callback info is always */
<> 144:ef7eb2e8f9f7 328 /* located in primary descriptor. */
<> 144:ef7eb2e8f9f7 329 cb = (DMA_CB_TypeDef *)(descr[channel].USER);
<> 144:ef7eb2e8f9f7 330 if (cb)
<> 144:ef7eb2e8f9f7 331 {
<> 144:ef7eb2e8f9f7 332 /* Toggle next-descriptor indicator always prior to invoking */
<> 144:ef7eb2e8f9f7 333 /* callback (in case callback reconfigurs something) */
<> 144:ef7eb2e8f9f7 334 primaryCpy = cb->primary;
<> 144:ef7eb2e8f9f7 335 cb->primary ^= 1;
<> 144:ef7eb2e8f9f7 336 if (cb->cbFunc)
<> 144:ef7eb2e8f9f7 337 {
<> 144:ef7eb2e8f9f7 338 cb->cbFunc(channel, (bool)primaryCpy, cb->userPtr);
<> 144:ef7eb2e8f9f7 339 }
<> 144:ef7eb2e8f9f7 340 }
<> 144:ef7eb2e8f9f7 341 }
<> 144:ef7eb2e8f9f7 342
<> 144:ef7eb2e8f9f7 343 pendingPrio >>= 1;
<> 144:ef7eb2e8f9f7 344 channel++;
<> 144:ef7eb2e8f9f7 345 }
<> 144:ef7eb2e8f9f7 346
<> 144:ef7eb2e8f9f7 347 /* On second iteration, process default priority channels */
<> 144:ef7eb2e8f9f7 348 pendingPrio = pending & ~prio;
<> 144:ef7eb2e8f9f7 349 }
<> 144:ef7eb2e8f9f7 350 }
<> 144:ef7eb2e8f9f7 351
<> 144:ef7eb2e8f9f7 352 #endif /* EXCLUDE_DEFAULT_DMA_IRQ_HANDLER */
<> 144:ef7eb2e8f9f7 353
<> 144:ef7eb2e8f9f7 354
<> 144:ef7eb2e8f9f7 355 /*******************************************************************************
<> 144:ef7eb2e8f9f7 356 ************************** GLOBAL FUNCTIONS *******************************
<> 144:ef7eb2e8f9f7 357 ******************************************************************************/
<> 144:ef7eb2e8f9f7 358
<> 144:ef7eb2e8f9f7 359 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 360 * @brief
<> 144:ef7eb2e8f9f7 361 * Activate DMA auto-request cycle (used for memory-memory transfers).
<> 144:ef7eb2e8f9f7 362 *
<> 144:ef7eb2e8f9f7 363 * @details
<> 144:ef7eb2e8f9f7 364 * Prior to activating the DMA cycle, the channel and descriptor to be used
<> 144:ef7eb2e8f9f7 365 * must have been properly configured.
<> 144:ef7eb2e8f9f7 366 *
<> 144:ef7eb2e8f9f7 367 * @note
<> 144:ef7eb2e8f9f7 368 * If using this function on a channel already activated and in use by the
<> 144:ef7eb2e8f9f7 369 * DMA controller, the behaviour is undefined.
<> 144:ef7eb2e8f9f7 370 *
<> 144:ef7eb2e8f9f7 371 * @param[in] channel
<> 144:ef7eb2e8f9f7 372 * DMA channel to activate DMA cycle for.
<> 144:ef7eb2e8f9f7 373 *
<> 144:ef7eb2e8f9f7 374 * @param[in] primary
<> 144:ef7eb2e8f9f7 375 * @li true - activate using primary descriptor
<> 144:ef7eb2e8f9f7 376 * @li false - activate using alternate descriptor
<> 144:ef7eb2e8f9f7 377 *
<> 144:ef7eb2e8f9f7 378 * @param[in] dst
<> 144:ef7eb2e8f9f7 379 * Address to start location to transfer data to. If NULL, leave setting in
<> 144:ef7eb2e8f9f7 380 * descriptor as is from a previous activation.
<> 144:ef7eb2e8f9f7 381 *
<> 144:ef7eb2e8f9f7 382 * @param[in] src
<> 144:ef7eb2e8f9f7 383 * Address to start location to transfer data from. If NULL, leave setting in
<> 144:ef7eb2e8f9f7 384 * descriptor as is from a previous activation.
<> 144:ef7eb2e8f9f7 385 *
<> 144:ef7eb2e8f9f7 386 * @param[in] nMinus1
<> 144:ef7eb2e8f9f7 387 * Number of DMA transfer elements (minus 1) to transfer (<= 1023). The
<> 144:ef7eb2e8f9f7 388 * size of the DMA transfer element (1, 2 or 4 bytes) is configured with
<> 144:ef7eb2e8f9f7 389 * DMA_CfgDescr().
<> 144:ef7eb2e8f9f7 390 ******************************************************************************/
<> 144:ef7eb2e8f9f7 391 void DMA_ActivateAuto(unsigned int channel,
<> 144:ef7eb2e8f9f7 392 bool primary,
<> 144:ef7eb2e8f9f7 393 void *dst,
<> 144:ef7eb2e8f9f7 394 void *src,
<> 144:ef7eb2e8f9f7 395 unsigned int nMinus1)
<> 144:ef7eb2e8f9f7 396 {
<> 144:ef7eb2e8f9f7 397 uint32_t chBit;
<> 144:ef7eb2e8f9f7 398
<> 144:ef7eb2e8f9f7 399 EFM_ASSERT(channel < DMA_CHAN_COUNT);
<> 144:ef7eb2e8f9f7 400 EFM_ASSERT(nMinus1 <= (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT));
<> 144:ef7eb2e8f9f7 401
<> 144:ef7eb2e8f9f7 402 DMA_Prepare(channel,
<> 144:ef7eb2e8f9f7 403 dmaCycleCtrlAuto,
<> 144:ef7eb2e8f9f7 404 primary,
<> 144:ef7eb2e8f9f7 405 false,
<> 144:ef7eb2e8f9f7 406 dst,
<> 144:ef7eb2e8f9f7 407 src,
<> 144:ef7eb2e8f9f7 408 nMinus1);
<> 144:ef7eb2e8f9f7 409
<> 144:ef7eb2e8f9f7 410 chBit = 1 << channel;
<> 144:ef7eb2e8f9f7 411 DMA->CHENS = chBit; /* Enable channel */
<> 144:ef7eb2e8f9f7 412 DMA->CHSWREQ = chBit; /* Activate with SW request */
<> 144:ef7eb2e8f9f7 413 }
<> 144:ef7eb2e8f9f7 414
<> 144:ef7eb2e8f9f7 415
<> 144:ef7eb2e8f9f7 416 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 417 * @brief
<> 144:ef7eb2e8f9f7 418 * Activate DMA basic cycle (used for memory-peripheral transfers).
<> 144:ef7eb2e8f9f7 419 *
<> 144:ef7eb2e8f9f7 420 * @details
<> 144:ef7eb2e8f9f7 421 * Prior to activating the DMA cycle, the channel and descriptor to be used
<> 144:ef7eb2e8f9f7 422 * must have been properly configured.
<> 144:ef7eb2e8f9f7 423 *
<> 144:ef7eb2e8f9f7 424 * @note
<> 144:ef7eb2e8f9f7 425 * If using this function on a channel already activated and in use by the
<> 144:ef7eb2e8f9f7 426 * DMA controller, the behaviour is undefined.
<> 144:ef7eb2e8f9f7 427 *
<> 144:ef7eb2e8f9f7 428 * @param[in] channel
<> 144:ef7eb2e8f9f7 429 * DMA channel to activate DMA cycle for.
<> 144:ef7eb2e8f9f7 430 *
<> 144:ef7eb2e8f9f7 431 * @param[in] primary
<> 144:ef7eb2e8f9f7 432 * @li true - activate using primary descriptor
<> 144:ef7eb2e8f9f7 433 * @li false - activate using alternate descriptor
<> 144:ef7eb2e8f9f7 434 *
<> 144:ef7eb2e8f9f7 435 * @param[in] useBurst
<> 144:ef7eb2e8f9f7 436 * The burst feature is only used on peripherals supporting DMA bursts.
<> 144:ef7eb2e8f9f7 437 * Bursts must not be used if the total length (as given by nMinus1) is
<> 144:ef7eb2e8f9f7 438 * less than the arbitration rate configured for the descriptor. Please
<> 144:ef7eb2e8f9f7 439 * refer to the reference manual for further details on burst usage.
<> 144:ef7eb2e8f9f7 440 *
<> 144:ef7eb2e8f9f7 441 * @param[in] dst
<> 144:ef7eb2e8f9f7 442 * Address to start location to transfer data to. If NULL, leave setting in
<> 144:ef7eb2e8f9f7 443 * descriptor as is from a previous activation.
<> 144:ef7eb2e8f9f7 444 *
<> 144:ef7eb2e8f9f7 445 * @param[in] src
<> 144:ef7eb2e8f9f7 446 * Address to start location to transfer data from. If NULL, leave setting in
<> 144:ef7eb2e8f9f7 447 * descriptor as is from a previous activation.
<> 144:ef7eb2e8f9f7 448 *
<> 144:ef7eb2e8f9f7 449 * @param[in] nMinus1
<> 144:ef7eb2e8f9f7 450 * Number of DMA transfer elements (minus 1) to transfer (<= 1023). The
<> 144:ef7eb2e8f9f7 451 * size of the DMA transfer element (1, 2 or 4 bytes) is configured with
<> 144:ef7eb2e8f9f7 452 * DMA_CfgDescr().
<> 144:ef7eb2e8f9f7 453 ******************************************************************************/
<> 144:ef7eb2e8f9f7 454 void DMA_ActivateBasic(unsigned int channel,
<> 144:ef7eb2e8f9f7 455 bool primary,
<> 144:ef7eb2e8f9f7 456 bool useBurst,
<> 144:ef7eb2e8f9f7 457 void *dst,
<> 144:ef7eb2e8f9f7 458 void *src,
<> 144:ef7eb2e8f9f7 459 unsigned int nMinus1)
<> 144:ef7eb2e8f9f7 460 {
<> 144:ef7eb2e8f9f7 461 EFM_ASSERT(channel < DMA_CHAN_COUNT);
<> 144:ef7eb2e8f9f7 462 EFM_ASSERT(nMinus1 <= (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT));
<> 144:ef7eb2e8f9f7 463
<> 144:ef7eb2e8f9f7 464 DMA_Prepare(channel,
<> 144:ef7eb2e8f9f7 465 dmaCycleCtrlBasic,
<> 144:ef7eb2e8f9f7 466 primary,
<> 144:ef7eb2e8f9f7 467 useBurst,
<> 144:ef7eb2e8f9f7 468 dst,
<> 144:ef7eb2e8f9f7 469 src,
<> 144:ef7eb2e8f9f7 470 nMinus1);
<> 144:ef7eb2e8f9f7 471
<> 144:ef7eb2e8f9f7 472 /* Enable channel, request signal is provided by peripheral device */
<> 144:ef7eb2e8f9f7 473 DMA->CHENS = 1 << channel;
<> 144:ef7eb2e8f9f7 474 }
<> 144:ef7eb2e8f9f7 475
<> 144:ef7eb2e8f9f7 476
<> 144:ef7eb2e8f9f7 477 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 478 * @brief
<> 144:ef7eb2e8f9f7 479 * Activate DMA ping-pong cycle (used for memory-peripheral transfers).
<> 144:ef7eb2e8f9f7 480 *
<> 144:ef7eb2e8f9f7 481 * @details
<> 144:ef7eb2e8f9f7 482 * Prior to activating the DMA cycle, the channel and both descriptors must
<> 144:ef7eb2e8f9f7 483 * have been properly configured. The primary descriptor is always the first
<> 144:ef7eb2e8f9f7 484 * descriptor to be used by the DMA controller.
<> 144:ef7eb2e8f9f7 485 *
<> 144:ef7eb2e8f9f7 486 * @note
<> 144:ef7eb2e8f9f7 487 * If using this function on a channel already activated and in use by the
<> 144:ef7eb2e8f9f7 488 * DMA controller, the behaviour is undefined.
<> 144:ef7eb2e8f9f7 489 *
<> 144:ef7eb2e8f9f7 490 * @param[in] channel
<> 144:ef7eb2e8f9f7 491 * DMA channel to activate DMA cycle for.
<> 144:ef7eb2e8f9f7 492 *
<> 144:ef7eb2e8f9f7 493 * @param[in] useBurst
<> 144:ef7eb2e8f9f7 494 * The burst feature is only used on peripherals supporting DMA bursts.
<> 144:ef7eb2e8f9f7 495 * Bursts must not be used if the total length (as given by nMinus1) is
<> 144:ef7eb2e8f9f7 496 * less than the arbitration rate configured for the descriptors. Please
<> 144:ef7eb2e8f9f7 497 * refer to the reference manual for further details on burst usage. Notice
<> 144:ef7eb2e8f9f7 498 * that this setting is used for both the primary and alternate descriptors.
<> 144:ef7eb2e8f9f7 499 *
<> 144:ef7eb2e8f9f7 500 * @param[in] primDst
<> 144:ef7eb2e8f9f7 501 * Address to start location to transfer data to, for primary descriptor.
<> 144:ef7eb2e8f9f7 502 * If NULL, leave setting in descriptor as is from a previous activation.
<> 144:ef7eb2e8f9f7 503 *
<> 144:ef7eb2e8f9f7 504 * @param[in] primSrc
<> 144:ef7eb2e8f9f7 505 * Address to start location to transfer data from, for primary descriptor.
<> 144:ef7eb2e8f9f7 506 * If NULL, leave setting in descriptor as is from a previous activation.
<> 144:ef7eb2e8f9f7 507 *
<> 144:ef7eb2e8f9f7 508 * @param[in] primNMinus1
<> 144:ef7eb2e8f9f7 509 * Number of DMA transfer elements (minus 1) to transfer (<= 1023), for
<> 144:ef7eb2e8f9f7 510 * primary descriptor. The size of the DMA transfer element (1, 2 or 4 bytes)
<> 144:ef7eb2e8f9f7 511 * is configured with DMA_CfgDescr().
<> 144:ef7eb2e8f9f7 512 *
<> 144:ef7eb2e8f9f7 513 * @param[in] altDst
<> 144:ef7eb2e8f9f7 514 * Address to start location to transfer data to, for alternate descriptor.
<> 144:ef7eb2e8f9f7 515 * If NULL, leave setting in descriptor as is from a previous activation.
<> 144:ef7eb2e8f9f7 516 *
<> 144:ef7eb2e8f9f7 517 * @param[in] altSrc
<> 144:ef7eb2e8f9f7 518 * Address to start location to transfer data from, for alternate descriptor.
<> 144:ef7eb2e8f9f7 519 * If NULL, leave setting in descriptor as is from a previous activation.
<> 144:ef7eb2e8f9f7 520 *
<> 144:ef7eb2e8f9f7 521 * @param[in] altNMinus1
<> 144:ef7eb2e8f9f7 522 * Number of DMA transfer elements (minus 1) to transfer (<= 1023), for
<> 144:ef7eb2e8f9f7 523 * alternate descriptor. The size of the DMA transfer element (1, 2 or 4 bytes)
<> 144:ef7eb2e8f9f7 524 * is configured with DMA_CfgDescr().
<> 144:ef7eb2e8f9f7 525 ******************************************************************************/
<> 144:ef7eb2e8f9f7 526 void DMA_ActivatePingPong(unsigned int channel,
<> 144:ef7eb2e8f9f7 527 bool useBurst,
<> 144:ef7eb2e8f9f7 528 void *primDst,
<> 144:ef7eb2e8f9f7 529 void *primSrc,
<> 144:ef7eb2e8f9f7 530 unsigned int primNMinus1,
<> 144:ef7eb2e8f9f7 531 void *altDst,
<> 144:ef7eb2e8f9f7 532 void *altSrc,
<> 144:ef7eb2e8f9f7 533 unsigned int altNMinus1)
<> 144:ef7eb2e8f9f7 534 {
<> 144:ef7eb2e8f9f7 535 EFM_ASSERT(channel < DMA_CHAN_COUNT);
<> 144:ef7eb2e8f9f7 536 EFM_ASSERT(primNMinus1 <= (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT));
<> 144:ef7eb2e8f9f7 537 EFM_ASSERT(altNMinus1 <= (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT));
<> 144:ef7eb2e8f9f7 538
<> 144:ef7eb2e8f9f7 539 /* Prepare alternate descriptor first */
<> 144:ef7eb2e8f9f7 540 DMA_Prepare(channel,
<> 144:ef7eb2e8f9f7 541 dmaCycleCtrlPingPong,
<> 144:ef7eb2e8f9f7 542 false,
<> 144:ef7eb2e8f9f7 543 useBurst,
<> 144:ef7eb2e8f9f7 544 altDst,
<> 144:ef7eb2e8f9f7 545 altSrc,
<> 144:ef7eb2e8f9f7 546 altNMinus1);
<> 144:ef7eb2e8f9f7 547
<> 144:ef7eb2e8f9f7 548 /* Prepare primary descriptor last in order to start cycle using it */
<> 144:ef7eb2e8f9f7 549 DMA_Prepare(channel,
<> 144:ef7eb2e8f9f7 550 dmaCycleCtrlPingPong,
<> 144:ef7eb2e8f9f7 551 true,
<> 144:ef7eb2e8f9f7 552 useBurst,
<> 144:ef7eb2e8f9f7 553 primDst,
<> 144:ef7eb2e8f9f7 554 primSrc,
<> 144:ef7eb2e8f9f7 555 primNMinus1);
<> 144:ef7eb2e8f9f7 556
<> 144:ef7eb2e8f9f7 557 /* Enable channel, request signal is provided by peripheral device */
<> 144:ef7eb2e8f9f7 558 DMA->CHENS = 1 << channel;
<> 144:ef7eb2e8f9f7 559 }
<> 144:ef7eb2e8f9f7 560
<> 144:ef7eb2e8f9f7 561
<> 144:ef7eb2e8f9f7 562 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 563 * @brief
<> 144:ef7eb2e8f9f7 564 * Activate DMA scatter-gather cycle (used for either memory-peripheral
<> 144:ef7eb2e8f9f7 565 * or memory-memory transfers).
<> 144:ef7eb2e8f9f7 566 *
<> 144:ef7eb2e8f9f7 567 * @details
<> 144:ef7eb2e8f9f7 568 * Prior to activating the DMA cycle, the array with alternate descriptors
<> 144:ef7eb2e8f9f7 569 * must have been properly configured. This function can be reused without
<> 144:ef7eb2e8f9f7 570 * reconfiguring the alternate descriptors, as long as @p count is the same.
<> 144:ef7eb2e8f9f7 571 *
<> 144:ef7eb2e8f9f7 572 * @note
<> 144:ef7eb2e8f9f7 573 * If using this function on a channel already activated and in use by the
<> 144:ef7eb2e8f9f7 574 * DMA controller, the behaviour is undefined.
<> 144:ef7eb2e8f9f7 575 *
<> 144:ef7eb2e8f9f7 576 * @param[in] channel
<> 144:ef7eb2e8f9f7 577 * DMA channel to activate DMA cycle for.
<> 144:ef7eb2e8f9f7 578 *
<> 144:ef7eb2e8f9f7 579 * @param[in] useBurst
<> 144:ef7eb2e8f9f7 580 * The burst feature is only used on peripherals supporting DMA bursts
<> 144:ef7eb2e8f9f7 581 * (and thus this parameter is ignored for memory scatter-gather cycles).
<> 144:ef7eb2e8f9f7 582 * This parameter determines if bursts should be enabled during DMA transfers
<> 144:ef7eb2e8f9f7 583 * using the alternate descriptors. Bursts must not be used if the total
<> 144:ef7eb2e8f9f7 584 * length (as given by nMinus1 for the alternate descriptor) is
<> 144:ef7eb2e8f9f7 585 * less than the arbitration rate configured for the descriptor. Please
<> 144:ef7eb2e8f9f7 586 * refer to the reference manual for further details on burst usage.
<> 144:ef7eb2e8f9f7 587 *
<> 144:ef7eb2e8f9f7 588 * @param[in,out] altDescr
<> 144:ef7eb2e8f9f7 589 * Pointer to start of array with prepared alternate descriptors. The last
<> 144:ef7eb2e8f9f7 590 * descriptor will have its cycle control type reprogrammed to basic type.
<> 144:ef7eb2e8f9f7 591 *
<> 144:ef7eb2e8f9f7 592 * @param[in] count
<> 144:ef7eb2e8f9f7 593 * Number of alternate descriptors in @p altDescr array. Maximum number of
<> 144:ef7eb2e8f9f7 594 * alternate descriptors is 256.
<> 144:ef7eb2e8f9f7 595 ******************************************************************************/
<> 144:ef7eb2e8f9f7 596 void DMA_ActivateScatterGather(unsigned int channel,
<> 144:ef7eb2e8f9f7 597 bool useBurst,
<> 144:ef7eb2e8f9f7 598 DMA_DESCRIPTOR_TypeDef *altDescr,
<> 144:ef7eb2e8f9f7 599 unsigned int count)
<> 144:ef7eb2e8f9f7 600 {
<> 144:ef7eb2e8f9f7 601 DMA_DESCRIPTOR_TypeDef *descr;
<> 144:ef7eb2e8f9f7 602 DMA_CB_TypeDef *cb;
<> 144:ef7eb2e8f9f7 603 uint32_t cycleCtrl;
<> 144:ef7eb2e8f9f7 604 uint32_t chBit;
<> 144:ef7eb2e8f9f7 605
<> 144:ef7eb2e8f9f7 606 EFM_ASSERT(channel < DMA_CHAN_COUNT);
<> 144:ef7eb2e8f9f7 607 EFM_ASSERT(altDescr);
<> 144:ef7eb2e8f9f7 608 EFM_ASSERT(count && (count <= 256));
<> 144:ef7eb2e8f9f7 609
<> 144:ef7eb2e8f9f7 610 /* We have to configure the primary descriptor properly in order to */
<> 144:ef7eb2e8f9f7 611 /* transfer one complete alternate descriptor from the alternate */
<> 144:ef7eb2e8f9f7 612 /* descriptor table into the actual alternate descriptor. */
<> 144:ef7eb2e8f9f7 613 descr = (DMA_DESCRIPTOR_TypeDef *)(DMA->CTRLBASE) + channel;
<> 144:ef7eb2e8f9f7 614
<> 144:ef7eb2e8f9f7 615 /* Set source end address to point to alternate descriptor array */
<> 144:ef7eb2e8f9f7 616 descr->SRCEND = (uint32_t *)altDescr + (count * 4) - 1;
<> 144:ef7eb2e8f9f7 617
<> 144:ef7eb2e8f9f7 618 /* The destination end address in the primary descriptor MUST point */
<> 144:ef7eb2e8f9f7 619 /* to the corresponding alternate descriptor in scatter-gather mode. */
<> 144:ef7eb2e8f9f7 620 descr->DSTEND = (uint32_t *)((DMA_DESCRIPTOR_TypeDef *)(DMA->ALTCTRLBASE) +
<> 144:ef7eb2e8f9f7 621 channel + 1) - 1;
<> 144:ef7eb2e8f9f7 622
<> 144:ef7eb2e8f9f7 623 /* The user field of the descriptor is used for callback configuration, */
<> 144:ef7eb2e8f9f7 624 /* and already configured when channel is configured. Do not modify it. */
<> 144:ef7eb2e8f9f7 625
<> 144:ef7eb2e8f9f7 626 /* Determine from alternate configuration whether this is a memory or */
<> 144:ef7eb2e8f9f7 627 /* peripheral scatter-gather, by looking at the first alternate descriptor. */
<> 144:ef7eb2e8f9f7 628 cycleCtrl = altDescr->CTRL & _DMA_CTRL_CYCLE_CTRL_MASK;
<> 144:ef7eb2e8f9f7 629 cycleCtrl &= ~(1 << _DMA_CTRL_CYCLE_CTRL_SHIFT);
<> 144:ef7eb2e8f9f7 630
<> 144:ef7eb2e8f9f7 631 EFM_ASSERT((cycleCtrl == dmaCycleCtrlMemScatterGather)
<> 144:ef7eb2e8f9f7 632 || (cycleCtrl == dmaCycleCtrlPerScatterGather));
<> 144:ef7eb2e8f9f7 633
<> 144:ef7eb2e8f9f7 634 /* Set last alternate descriptor to basic or auto-request cycle type in */
<> 144:ef7eb2e8f9f7 635 /* order to have dma_done signal asserted when complete. Otherwise interrupt */
<> 144:ef7eb2e8f9f7 636 /* will not be triggered when done. */
<> 144:ef7eb2e8f9f7 637 altDescr[count - 1].CTRL &= ~_DMA_CTRL_CYCLE_CTRL_MASK;
<> 144:ef7eb2e8f9f7 638 if (cycleCtrl == dmaCycleCtrlMemScatterGather)
<> 144:ef7eb2e8f9f7 639 {
<> 144:ef7eb2e8f9f7 640 altDescr[count - 1].CTRL |= (uint32_t)dmaCycleCtrlAuto
<> 144:ef7eb2e8f9f7 641 << _DMA_CTRL_CYCLE_CTRL_SHIFT;
<> 144:ef7eb2e8f9f7 642 }
<> 144:ef7eb2e8f9f7 643 else
<> 144:ef7eb2e8f9f7 644 {
<> 144:ef7eb2e8f9f7 645 altDescr[count - 1].CTRL |= (uint32_t)dmaCycleCtrlBasic
<> 144:ef7eb2e8f9f7 646 << _DMA_CTRL_CYCLE_CTRL_SHIFT;
<> 144:ef7eb2e8f9f7 647 }
<> 144:ef7eb2e8f9f7 648
<> 144:ef7eb2e8f9f7 649 /* If callback defined, update info on whether callback is issued for */
<> 144:ef7eb2e8f9f7 650 /* primary or alternate descriptor. Not really useful for scatter-gather, */
<> 144:ef7eb2e8f9f7 651 /* but do for consistency. Always set to alternate, since that is the last */
<> 144:ef7eb2e8f9f7 652 /* descriptor actually used. */
<> 144:ef7eb2e8f9f7 653 cb = (DMA_CB_TypeDef *)(descr->USER);
<> 144:ef7eb2e8f9f7 654 if (cb)
<> 144:ef7eb2e8f9f7 655 {
<> 144:ef7eb2e8f9f7 656 cb->primary = false;
<> 144:ef7eb2e8f9f7 657 }
<> 144:ef7eb2e8f9f7 658
<> 144:ef7eb2e8f9f7 659 /* Configure primary descriptor control word */
<> 144:ef7eb2e8f9f7 660 descr->CTRL =((uint32_t)dmaDataInc4 << _DMA_CTRL_DST_INC_SHIFT)
<> 144:ef7eb2e8f9f7 661 | ((uint32_t)dmaDataSize4 << _DMA_CTRL_DST_SIZE_SHIFT)
<> 144:ef7eb2e8f9f7 662 | ((uint32_t)dmaDataInc4 << _DMA_CTRL_SRC_INC_SHIFT)
<> 144:ef7eb2e8f9f7 663 | ((uint32_t)dmaDataSize4 << _DMA_CTRL_SRC_SIZE_SHIFT)
<> 144:ef7eb2e8f9f7 664 /* Use same protection scheme as for alternate descriptors */
<> 144:ef7eb2e8f9f7 665 | (altDescr->CTRL & _DMA_CTRL_SRC_PROT_CTRL_MASK)
<> 144:ef7eb2e8f9f7 666 | ((uint32_t)dmaArbitrate4 << _DMA_CTRL_R_POWER_SHIFT)
<> 144:ef7eb2e8f9f7 667 | (((count * 4) - 1) << _DMA_CTRL_N_MINUS_1_SHIFT)
<> 144:ef7eb2e8f9f7 668 | (((uint32_t)useBurst & 1) << _DMA_CTRL_NEXT_USEBURST_SHIFT)
<> 144:ef7eb2e8f9f7 669 | cycleCtrl;
<> 144:ef7eb2e8f9f7 670
<> 144:ef7eb2e8f9f7 671 chBit = 1 << channel;
<> 144:ef7eb2e8f9f7 672
<> 144:ef7eb2e8f9f7 673 /* Start with primary descriptor */
<> 144:ef7eb2e8f9f7 674 DMA->CHALTC = chBit;
<> 144:ef7eb2e8f9f7 675
<> 144:ef7eb2e8f9f7 676 /* Enable channel */
<> 144:ef7eb2e8f9f7 677 DMA->CHENS = chBit;
<> 144:ef7eb2e8f9f7 678
<> 144:ef7eb2e8f9f7 679 /* Send request if memory scatter-gather, otherwise request signal is */
<> 144:ef7eb2e8f9f7 680 /* provided by peripheral. */
<> 144:ef7eb2e8f9f7 681 if (cycleCtrl == dmaCycleCtrlMemScatterGather)
<> 144:ef7eb2e8f9f7 682 {
<> 144:ef7eb2e8f9f7 683 DMA->CHSWREQ = chBit;
<> 144:ef7eb2e8f9f7 684 }
<> 144:ef7eb2e8f9f7 685 }
<> 144:ef7eb2e8f9f7 686
<> 144:ef7eb2e8f9f7 687
<> 144:ef7eb2e8f9f7 688 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 689 * @brief
<> 144:ef7eb2e8f9f7 690 * Configure a DMA channel.
<> 144:ef7eb2e8f9f7 691 *
<> 144:ef7eb2e8f9f7 692 * @details
<> 144:ef7eb2e8f9f7 693 * Configure miscellaneous issues for a DMA channel. This function is typically
<> 144:ef7eb2e8f9f7 694 * used once to setup a channel for a certain type of use.
<> 144:ef7eb2e8f9f7 695 *
<> 144:ef7eb2e8f9f7 696 * @note
<> 144:ef7eb2e8f9f7 697 * If using this function on a channel already in use by the DMA controller,
<> 144:ef7eb2e8f9f7 698 * the behaviour is undefined.
<> 144:ef7eb2e8f9f7 699 *
<> 144:ef7eb2e8f9f7 700 * @param[in] channel
<> 144:ef7eb2e8f9f7 701 * DMA channel to configure.
<> 144:ef7eb2e8f9f7 702 *
<> 144:ef7eb2e8f9f7 703 * @param[in] cfg
<> 144:ef7eb2e8f9f7 704 * Configuration to use.
<> 144:ef7eb2e8f9f7 705 ******************************************************************************/
<> 144:ef7eb2e8f9f7 706 void DMA_CfgChannel(unsigned int channel, DMA_CfgChannel_TypeDef *cfg)
<> 144:ef7eb2e8f9f7 707 {
<> 144:ef7eb2e8f9f7 708 DMA_DESCRIPTOR_TypeDef *descr;
<> 144:ef7eb2e8f9f7 709
<> 144:ef7eb2e8f9f7 710 EFM_ASSERT(channel < DMA_CHAN_COUNT);
<> 144:ef7eb2e8f9f7 711 EFM_ASSERT(cfg);
<> 144:ef7eb2e8f9f7 712
<> 144:ef7eb2e8f9f7 713 /* Always keep callback configuration reference in primary descriptor */
<> 144:ef7eb2e8f9f7 714 descr = (DMA_DESCRIPTOR_TypeDef *)(DMA->CTRLBASE);
<> 144:ef7eb2e8f9f7 715 descr[channel].USER = (uint32_t)(cfg->cb);
<> 144:ef7eb2e8f9f7 716
<> 144:ef7eb2e8f9f7 717 /* Set to specified priority for channel */
<> 144:ef7eb2e8f9f7 718 if (cfg->highPri)
<> 144:ef7eb2e8f9f7 719 {
<> 144:ef7eb2e8f9f7 720 DMA->CHPRIS = 1 << channel;
<> 144:ef7eb2e8f9f7 721 }
<> 144:ef7eb2e8f9f7 722 else
<> 144:ef7eb2e8f9f7 723 {
<> 144:ef7eb2e8f9f7 724 DMA->CHPRIC = 1 << channel;
<> 144:ef7eb2e8f9f7 725 }
<> 144:ef7eb2e8f9f7 726
<> 144:ef7eb2e8f9f7 727 /* Set DMA signal source select */
<> 144:ef7eb2e8f9f7 728 DMA->CH[channel].CTRL = cfg->select;
<> 144:ef7eb2e8f9f7 729
<> 144:ef7eb2e8f9f7 730 /* Enable/disable interrupt as specified */
<> 144:ef7eb2e8f9f7 731 if (cfg->enableInt)
<> 144:ef7eb2e8f9f7 732 {
<> 144:ef7eb2e8f9f7 733 DMA->IFC = (1 << channel);
<> 144:ef7eb2e8f9f7 734 BUS_RegBitWrite(&(DMA->IEN), channel, 1);
<> 144:ef7eb2e8f9f7 735 }
<> 144:ef7eb2e8f9f7 736 else
<> 144:ef7eb2e8f9f7 737 {
<> 144:ef7eb2e8f9f7 738 BUS_RegBitWrite(&(DMA->IEN), channel, 0);
<> 144:ef7eb2e8f9f7 739 }
<> 144:ef7eb2e8f9f7 740 }
<> 144:ef7eb2e8f9f7 741
<> 144:ef7eb2e8f9f7 742
<> 144:ef7eb2e8f9f7 743 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 744 * @brief
<> 144:ef7eb2e8f9f7 745 * Configure DMA descriptor for auto-request, basic or ping-pong DMA cycles.
<> 144:ef7eb2e8f9f7 746 *
<> 144:ef7eb2e8f9f7 747 * @details
<> 144:ef7eb2e8f9f7 748 * This function is used for configuration of a descriptor for the following
<> 144:ef7eb2e8f9f7 749 * DMA cycle types:
<> 144:ef7eb2e8f9f7 750 *
<> 144:ef7eb2e8f9f7 751 * @li auto-request - used for memory/memory transfer
<> 144:ef7eb2e8f9f7 752 * @li basic - used for a peripheral/memory transfer
<> 144:ef7eb2e8f9f7 753 * @li ping-pong - used for a ping-pong based peripheral/memory transfer
<> 144:ef7eb2e8f9f7 754 * style providing time to refresh one descriptor while the other is
<> 144:ef7eb2e8f9f7 755 * in use.
<> 144:ef7eb2e8f9f7 756 *
<> 144:ef7eb2e8f9f7 757 * The DMA cycle is not activated, please see DMA_ActivateAuto(),
<> 144:ef7eb2e8f9f7 758 * DMA_ActivateBasic() or DMA_ActivatePingPong() to activate the DMA cycle.
<> 144:ef7eb2e8f9f7 759 * In many cases, the configuration only has to be done once, and all
<> 144:ef7eb2e8f9f7 760 * subsequent cycles may be activated with the activate function.
<> 144:ef7eb2e8f9f7 761 *
<> 144:ef7eb2e8f9f7 762 * For ping-pong DMA cycles, this function must be used both on the primary
<> 144:ef7eb2e8f9f7 763 * and the alternate descriptor prior to activating the DMA cycle.
<> 144:ef7eb2e8f9f7 764 *
<> 144:ef7eb2e8f9f7 765 * Notice that the DMA channel must also be configured, see DMA_CfgChannel().
<> 144:ef7eb2e8f9f7 766 *
<> 144:ef7eb2e8f9f7 767 * @note
<> 144:ef7eb2e8f9f7 768 * If using this function on a descriptor already activated and in use by
<> 144:ef7eb2e8f9f7 769 * the DMA controller, the behaviour is undefined.
<> 144:ef7eb2e8f9f7 770 *
<> 144:ef7eb2e8f9f7 771 * @param[in] channel
<> 144:ef7eb2e8f9f7 772 * DMA channel to configure for.
<> 144:ef7eb2e8f9f7 773 *
<> 144:ef7eb2e8f9f7 774 * @param[in] primary
<> 144:ef7eb2e8f9f7 775 * @li true - configure primary descriptor
<> 144:ef7eb2e8f9f7 776 * @li false - configure alternate descriptor
<> 144:ef7eb2e8f9f7 777 *
<> 144:ef7eb2e8f9f7 778 * @param[in] cfg
<> 144:ef7eb2e8f9f7 779 * Configuration to use.
<> 144:ef7eb2e8f9f7 780 ******************************************************************************/
<> 144:ef7eb2e8f9f7 781 void DMA_CfgDescr(unsigned int channel,
<> 144:ef7eb2e8f9f7 782 bool primary,
<> 144:ef7eb2e8f9f7 783 DMA_CfgDescr_TypeDef *cfg)
<> 144:ef7eb2e8f9f7 784 {
<> 144:ef7eb2e8f9f7 785 DMA_DESCRIPTOR_TypeDef *descr;
<> 144:ef7eb2e8f9f7 786
<> 144:ef7eb2e8f9f7 787 EFM_ASSERT(channel < DMA_CHAN_COUNT);
<> 144:ef7eb2e8f9f7 788 EFM_ASSERT(cfg);
<> 144:ef7eb2e8f9f7 789
<> 144:ef7eb2e8f9f7 790 /* Find descriptor to configure */
<> 144:ef7eb2e8f9f7 791 if (primary)
<> 144:ef7eb2e8f9f7 792 {
<> 144:ef7eb2e8f9f7 793 descr = (DMA_DESCRIPTOR_TypeDef *)DMA->CTRLBASE;
<> 144:ef7eb2e8f9f7 794 }
<> 144:ef7eb2e8f9f7 795 else
<> 144:ef7eb2e8f9f7 796 {
<> 144:ef7eb2e8f9f7 797 descr = (DMA_DESCRIPTOR_TypeDef *)DMA->ALTCTRLBASE;
<> 144:ef7eb2e8f9f7 798 }
<> 144:ef7eb2e8f9f7 799 descr += channel;
<> 144:ef7eb2e8f9f7 800
<> 144:ef7eb2e8f9f7 801 /* Prepare the descriptor */
<> 144:ef7eb2e8f9f7 802 /* Source/destination end addresses set when started */
<> 144:ef7eb2e8f9f7 803 descr->CTRL = (cfg->dstInc << _DMA_CTRL_DST_INC_SHIFT)
<> 144:ef7eb2e8f9f7 804 | (cfg->size << _DMA_CTRL_DST_SIZE_SHIFT)
<> 144:ef7eb2e8f9f7 805 | (cfg->srcInc << _DMA_CTRL_SRC_INC_SHIFT)
<> 144:ef7eb2e8f9f7 806 | (cfg->size << _DMA_CTRL_SRC_SIZE_SHIFT)
<> 144:ef7eb2e8f9f7 807 | ((uint32_t)(cfg->hprot) << _DMA_CTRL_SRC_PROT_CTRL_SHIFT)
<> 144:ef7eb2e8f9f7 808 | (cfg->arbRate << _DMA_CTRL_R_POWER_SHIFT)
<> 144:ef7eb2e8f9f7 809 | (0 << _DMA_CTRL_N_MINUS_1_SHIFT) /* Set when activated */
<> 144:ef7eb2e8f9f7 810 | (0 << _DMA_CTRL_NEXT_USEBURST_SHIFT) /* Set when activated */
<> 144:ef7eb2e8f9f7 811 | DMA_CTRL_CYCLE_CTRL_INVALID; /* Set when activated */
<> 144:ef7eb2e8f9f7 812 }
<> 144:ef7eb2e8f9f7 813
<> 144:ef7eb2e8f9f7 814
<> 144:ef7eb2e8f9f7 815 #if defined( _DMA_LOOP0_MASK ) && defined( _DMA_LOOP1_MASK )
<> 144:ef7eb2e8f9f7 816 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 817 * @brief Configure DMA channel for Loop mode or 2D transfer.
<> 144:ef7eb2e8f9f7 818 *
<> 144:ef7eb2e8f9f7 819 * @details
<> 144:ef7eb2e8f9f7 820 * For 2D transfer, set cfg->enable to "false", and only configure nMinus1
<> 144:ef7eb2e8f9f7 821 * to same width as channel descriptor.
<> 144:ef7eb2e8f9f7 822 *
<> 144:ef7eb2e8f9f7 823 * @param[in] channel
<> 144:ef7eb2e8f9f7 824 * DMA channel to configure for.
<> 144:ef7eb2e8f9f7 825 *
<> 144:ef7eb2e8f9f7 826 * @param[in] cfg
<> 144:ef7eb2e8f9f7 827 * Configuration to use.
<> 144:ef7eb2e8f9f7 828 ******************************************************************************/
<> 144:ef7eb2e8f9f7 829 void DMA_CfgLoop(unsigned int channel, DMA_CfgLoop_TypeDef *cfg)
<> 144:ef7eb2e8f9f7 830 {
<> 144:ef7eb2e8f9f7 831 EFM_ASSERT(channel <= 1);
<> 144:ef7eb2e8f9f7 832 EFM_ASSERT(cfg->nMinus1 <= 1023);
<> 144:ef7eb2e8f9f7 833
<> 144:ef7eb2e8f9f7 834 /* Configure LOOP setting */
<> 144:ef7eb2e8f9f7 835 switch( channel )
<> 144:ef7eb2e8f9f7 836 {
<> 144:ef7eb2e8f9f7 837 case 0:
<> 144:ef7eb2e8f9f7 838 DMA->LOOP0 = (cfg->enable << _DMA_LOOP0_EN_SHIFT)
<> 144:ef7eb2e8f9f7 839 | (cfg->nMinus1 << _DMA_LOOP0_WIDTH_SHIFT);
<> 144:ef7eb2e8f9f7 840 break;
<> 144:ef7eb2e8f9f7 841 case 1:
<> 144:ef7eb2e8f9f7 842 DMA->LOOP1 = (cfg->enable << _DMA_LOOP1_EN_SHIFT)
<> 144:ef7eb2e8f9f7 843 | (cfg->nMinus1 << _DMA_LOOP1_WIDTH_SHIFT);
<> 144:ef7eb2e8f9f7 844 break;
<> 144:ef7eb2e8f9f7 845 }
<> 144:ef7eb2e8f9f7 846 }
<> 144:ef7eb2e8f9f7 847 #endif
<> 144:ef7eb2e8f9f7 848
<> 144:ef7eb2e8f9f7 849
<> 144:ef7eb2e8f9f7 850 #if defined( _DMA_RECT0_MASK )
<> 144:ef7eb2e8f9f7 851 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 852 * @brief Configure DMA channel 2D transfer properties.
<> 144:ef7eb2e8f9f7 853 *
<> 144:ef7eb2e8f9f7 854 * @param[in] channel
<> 144:ef7eb2e8f9f7 855 * DMA channel to configure for.
<> 144:ef7eb2e8f9f7 856 *
<> 144:ef7eb2e8f9f7 857 * @param[in] cfg
<> 144:ef7eb2e8f9f7 858 * Configuration to use.
<> 144:ef7eb2e8f9f7 859 ******************************************************************************/
<> 144:ef7eb2e8f9f7 860 void DMA_CfgRect(unsigned int channel, DMA_CfgRect_TypeDef *cfg)
<> 144:ef7eb2e8f9f7 861 {
<> 144:ef7eb2e8f9f7 862 (void)channel; /* Unused parameter */
<> 144:ef7eb2e8f9f7 863
<> 144:ef7eb2e8f9f7 864 EFM_ASSERT(channel == 0);
<> 144:ef7eb2e8f9f7 865 EFM_ASSERT(cfg->dstStride <= 2047);
<> 144:ef7eb2e8f9f7 866 EFM_ASSERT(cfg->srcStride <= 2047);
<> 144:ef7eb2e8f9f7 867 EFM_ASSERT(cfg->height <= 1023);
<> 144:ef7eb2e8f9f7 868
<> 144:ef7eb2e8f9f7 869 /* Configure rectangular/2D copy */
<> 144:ef7eb2e8f9f7 870 DMA->RECT0 = (cfg->dstStride << _DMA_RECT0_DSTSTRIDE_SHIFT)
<> 144:ef7eb2e8f9f7 871 | (cfg->srcStride << _DMA_RECT0_SRCSTRIDE_SHIFT)
<> 144:ef7eb2e8f9f7 872 | (cfg->height << _DMA_RECT0_HEIGHT_SHIFT);
<> 144:ef7eb2e8f9f7 873 }
<> 144:ef7eb2e8f9f7 874 #endif
<> 144:ef7eb2e8f9f7 875
<> 144:ef7eb2e8f9f7 876
<> 144:ef7eb2e8f9f7 877 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 878 * @brief
<> 144:ef7eb2e8f9f7 879 * Configure an alternate DMA descriptor for use with scatter-gather DMA
<> 144:ef7eb2e8f9f7 880 * cycles.
<> 144:ef7eb2e8f9f7 881 *
<> 144:ef7eb2e8f9f7 882 * @details
<> 144:ef7eb2e8f9f7 883 * In scatter-gather mode, the alternate descriptors are located in one
<> 144:ef7eb2e8f9f7 884 * contiguous memory area. Each of the alternate descriptor must be fully
<> 144:ef7eb2e8f9f7 885 * configured prior to starting the scatter-gather DMA cycle.
<> 144:ef7eb2e8f9f7 886 *
<> 144:ef7eb2e8f9f7 887 * The DMA cycle is not activated by this function, please see
<> 144:ef7eb2e8f9f7 888 * DMA_ActivateScatterGather() to activate the DMA cycle. In some cases, the
<> 144:ef7eb2e8f9f7 889 * alternate configuration only has to be done once, and all subsequent
<> 144:ef7eb2e8f9f7 890 * transfers may be activated with the activate function.
<> 144:ef7eb2e8f9f7 891 *
<> 144:ef7eb2e8f9f7 892 * Notice that the DMA channel must also be configured, see DMA_CfgChannel().
<> 144:ef7eb2e8f9f7 893 *
<> 144:ef7eb2e8f9f7 894 * @param[in] descr
<> 144:ef7eb2e8f9f7 895 * Points to start of memory area holding the alternate descriptors.
<> 144:ef7eb2e8f9f7 896 *
<> 144:ef7eb2e8f9f7 897 * @param[in] indx
<> 144:ef7eb2e8f9f7 898 * Alternate descriptor index number to configure (numbered from 0).
<> 144:ef7eb2e8f9f7 899 *
<> 144:ef7eb2e8f9f7 900 * @param[in] cfg
<> 144:ef7eb2e8f9f7 901 * Configuration to use.
<> 144:ef7eb2e8f9f7 902 ******************************************************************************/
<> 144:ef7eb2e8f9f7 903 void DMA_CfgDescrScatterGather(DMA_DESCRIPTOR_TypeDef *descr,
<> 144:ef7eb2e8f9f7 904 unsigned int indx,
<> 144:ef7eb2e8f9f7 905 DMA_CfgDescrSGAlt_TypeDef *cfg)
<> 144:ef7eb2e8f9f7 906 {
<> 144:ef7eb2e8f9f7 907 uint32_t cycleCtrl;
<> 144:ef7eb2e8f9f7 908
<> 144:ef7eb2e8f9f7 909 EFM_ASSERT(descr);
<> 144:ef7eb2e8f9f7 910 EFM_ASSERT(cfg);
<> 144:ef7eb2e8f9f7 911
<> 144:ef7eb2e8f9f7 912 /* Point to selected entry in alternate descriptor table */
<> 144:ef7eb2e8f9f7 913 descr += indx;
<> 144:ef7eb2e8f9f7 914
<> 144:ef7eb2e8f9f7 915 if (cfg->srcInc == dmaDataIncNone)
<> 144:ef7eb2e8f9f7 916 {
<> 144:ef7eb2e8f9f7 917 descr->SRCEND = cfg->src;
<> 144:ef7eb2e8f9f7 918 }
<> 144:ef7eb2e8f9f7 919 else
<> 144:ef7eb2e8f9f7 920 {
<> 144:ef7eb2e8f9f7 921 descr->SRCEND = (void *)((uint32_t)(cfg->src)
<> 144:ef7eb2e8f9f7 922 + ((uint32_t)(cfg->nMinus1) << cfg->srcInc));
<> 144:ef7eb2e8f9f7 923 }
<> 144:ef7eb2e8f9f7 924
<> 144:ef7eb2e8f9f7 925 if (cfg->dstInc == dmaDataIncNone)
<> 144:ef7eb2e8f9f7 926 {
<> 144:ef7eb2e8f9f7 927 descr->DSTEND = cfg->dst;
<> 144:ef7eb2e8f9f7 928 }
<> 144:ef7eb2e8f9f7 929 else
<> 144:ef7eb2e8f9f7 930 {
<> 144:ef7eb2e8f9f7 931 descr->DSTEND = (void *)((uint32_t)(cfg->dst)
<> 144:ef7eb2e8f9f7 932 + ((uint32_t)(cfg->nMinus1) << cfg->dstInc));
<> 144:ef7eb2e8f9f7 933 }
<> 144:ef7eb2e8f9f7 934
<> 144:ef7eb2e8f9f7 935 /* User definable part not used */
<> 144:ef7eb2e8f9f7 936 descr->USER = 0;
<> 144:ef7eb2e8f9f7 937
<> 144:ef7eb2e8f9f7 938 if (cfg->peripheral)
<> 144:ef7eb2e8f9f7 939 {
<> 144:ef7eb2e8f9f7 940 cycleCtrl = (uint32_t)dmaCycleCtrlPerScatterGather + 1;
<> 144:ef7eb2e8f9f7 941 }
<> 144:ef7eb2e8f9f7 942 else
<> 144:ef7eb2e8f9f7 943 {
<> 144:ef7eb2e8f9f7 944 cycleCtrl = (uint32_t)dmaCycleCtrlMemScatterGather + 1;
<> 144:ef7eb2e8f9f7 945 }
<> 144:ef7eb2e8f9f7 946
<> 144:ef7eb2e8f9f7 947 descr->CTRL =(cfg->dstInc << _DMA_CTRL_DST_INC_SHIFT)
<> 144:ef7eb2e8f9f7 948 | (cfg->size << _DMA_CTRL_DST_SIZE_SHIFT)
<> 144:ef7eb2e8f9f7 949 | (cfg->srcInc << _DMA_CTRL_SRC_INC_SHIFT)
<> 144:ef7eb2e8f9f7 950 | (cfg->size << _DMA_CTRL_SRC_SIZE_SHIFT)
<> 144:ef7eb2e8f9f7 951 | ((uint32_t)(cfg->hprot) << _DMA_CTRL_SRC_PROT_CTRL_SHIFT)
<> 144:ef7eb2e8f9f7 952 | (cfg->arbRate << _DMA_CTRL_R_POWER_SHIFT)
<> 144:ef7eb2e8f9f7 953 | ((uint32_t)(cfg->nMinus1) << _DMA_CTRL_N_MINUS_1_SHIFT)
<> 144:ef7eb2e8f9f7 954 /* Never set next useburst bit, since the descriptor used after the */
<> 144:ef7eb2e8f9f7 955 /* alternate descriptor is the primary descriptor which operates on */
<> 144:ef7eb2e8f9f7 956 /* memory. If the alternate descriptors need to have useBurst set, this */
<> 144:ef7eb2e8f9f7 957 /* done when setting up the primary descriptor, ie when activating. */
<> 144:ef7eb2e8f9f7 958 | (0 << _DMA_CTRL_NEXT_USEBURST_SHIFT)
<> 144:ef7eb2e8f9f7 959 | (cycleCtrl << _DMA_CTRL_CYCLE_CTRL_SHIFT);
<> 144:ef7eb2e8f9f7 960 }
<> 144:ef7eb2e8f9f7 961
<> 144:ef7eb2e8f9f7 962
<> 144:ef7eb2e8f9f7 963 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 964 * @brief
<> 144:ef7eb2e8f9f7 965 * Enable or disable a DMA channel.
<> 144:ef7eb2e8f9f7 966 *
<> 144:ef7eb2e8f9f7 967 * @details
<> 144:ef7eb2e8f9f7 968 * Use this function to explicitly enable or disable a DMA channel. A DMA
<> 144:ef7eb2e8f9f7 969 * channel is automatically disabled when the DMA controller has finished a
<> 144:ef7eb2e8f9f7 970 * transaction.
<> 144:ef7eb2e8f9f7 971 *
<> 144:ef7eb2e8f9f7 972 * @param[in] channel
<> 144:ef7eb2e8f9f7 973 * DMA channel to enable or disable.
<> 144:ef7eb2e8f9f7 974 *
<> 144:ef7eb2e8f9f7 975 * @param[in] enable
<> 144:ef7eb2e8f9f7 976 * If 'true' the channel will be enabled. If 'false' the channel will be
<> 144:ef7eb2e8f9f7 977 * disabled.
<> 144:ef7eb2e8f9f7 978 ******************************************************************************/
<> 144:ef7eb2e8f9f7 979 void DMA_ChannelEnable(unsigned int channel, bool enable)
<> 144:ef7eb2e8f9f7 980 {
<> 144:ef7eb2e8f9f7 981 EFM_ASSERT(channel < DMA_CHAN_COUNT);
<> 144:ef7eb2e8f9f7 982
<> 144:ef7eb2e8f9f7 983 if (enable)
<> 144:ef7eb2e8f9f7 984 {
<> 144:ef7eb2e8f9f7 985 DMA->CHENS = 1<<channel;
<> 144:ef7eb2e8f9f7 986 }
<> 144:ef7eb2e8f9f7 987 else
<> 144:ef7eb2e8f9f7 988 {
<> 144:ef7eb2e8f9f7 989 DMA->CHENC = 1<<channel;
<> 144:ef7eb2e8f9f7 990 }
<> 144:ef7eb2e8f9f7 991 }
<> 144:ef7eb2e8f9f7 992
<> 144:ef7eb2e8f9f7 993
<> 144:ef7eb2e8f9f7 994 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 995 * @brief
<> 144:ef7eb2e8f9f7 996 * Check if DMA channel is enabled.
<> 144:ef7eb2e8f9f7 997 *
<> 144:ef7eb2e8f9f7 998 * @details
<> 144:ef7eb2e8f9f7 999 * The DMA channel is disabled when the DMA controller has finished a DMA
<> 144:ef7eb2e8f9f7 1000 * cycle.
<> 144:ef7eb2e8f9f7 1001 *
<> 144:ef7eb2e8f9f7 1002 * @param[in] channel
<> 144:ef7eb2e8f9f7 1003 * DMA channel to check.
<> 144:ef7eb2e8f9f7 1004 *
<> 144:ef7eb2e8f9f7 1005 * @return
<> 144:ef7eb2e8f9f7 1006 * true if channel is enabled, false if not.
<> 144:ef7eb2e8f9f7 1007 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1008 bool DMA_ChannelEnabled(unsigned int channel)
<> 144:ef7eb2e8f9f7 1009 {
<> 144:ef7eb2e8f9f7 1010 EFM_ASSERT(channel < DMA_CHAN_COUNT);
<> 144:ef7eb2e8f9f7 1011
<> 144:ef7eb2e8f9f7 1012 return (bool)((DMA->CHENS >> channel) & 1);
<> 144:ef7eb2e8f9f7 1013 }
<> 144:ef7eb2e8f9f7 1014
<> 144:ef7eb2e8f9f7 1015
<> 144:ef7eb2e8f9f7 1016 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1017 * @brief
<> 144:ef7eb2e8f9f7 1018 * Initializes DMA controller.
<> 144:ef7eb2e8f9f7 1019 *
<> 144:ef7eb2e8f9f7 1020 * @details
<> 144:ef7eb2e8f9f7 1021 * This function will reset and prepare the DMA controller for use. Although
<> 144:ef7eb2e8f9f7 1022 * it may be used several times, it is normally only used during system
<> 144:ef7eb2e8f9f7 1023 * init. If reused during normal operation, notice that any ongoing DMA
<> 144:ef7eb2e8f9f7 1024 * transfers will be aborted. When completed, the DMA controller is in
<> 144:ef7eb2e8f9f7 1025 * an enabled state.
<> 144:ef7eb2e8f9f7 1026 *
<> 144:ef7eb2e8f9f7 1027 * @note
<> 144:ef7eb2e8f9f7 1028 * Must be invoked before using the DMA controller.
<> 144:ef7eb2e8f9f7 1029 *
<> 144:ef7eb2e8f9f7 1030 * @param[in] init
<> 144:ef7eb2e8f9f7 1031 * Pointer to a structure containing DMA init information.
<> 144:ef7eb2e8f9f7 1032 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1033 void DMA_Init(DMA_Init_TypeDef *init)
<> 144:ef7eb2e8f9f7 1034 {
<> 144:ef7eb2e8f9f7 1035 EFM_ASSERT(init);
<> 144:ef7eb2e8f9f7 1036
<> 144:ef7eb2e8f9f7 1037 /* Make sure control block is properly aligned */
<> 144:ef7eb2e8f9f7 1038 #if (DMA_CHAN_COUNT <= 4)
<> 144:ef7eb2e8f9f7 1039 EFM_ASSERT(!((uint32_t)(init->controlBlock) & (128 - 1)));
<> 144:ef7eb2e8f9f7 1040 #elif (DMA_CHAN_COUNT <= 8) || (DMA_CHAN_COUNT <= 12)
<> 144:ef7eb2e8f9f7 1041 EFM_ASSERT(!((uint32_t)(init->controlBlock) & (256 - 1)));
<> 144:ef7eb2e8f9f7 1042 #else
<> 144:ef7eb2e8f9f7 1043 #error "Unsupported DMA channel count (em_dma.c)."
<> 144:ef7eb2e8f9f7 1044 #endif
<> 144:ef7eb2e8f9f7 1045
<> 144:ef7eb2e8f9f7 1046 /* Make sure DMA clock is enabled prior to accessing DMA module */
<> 144:ef7eb2e8f9f7 1047 CMU_ClockEnable(cmuClock_DMA, true);
<> 144:ef7eb2e8f9f7 1048
<> 144:ef7eb2e8f9f7 1049 /* Make sure DMA controller is set to a known reset state */
<> 144:ef7eb2e8f9f7 1050 DMA_Reset();
<> 144:ef7eb2e8f9f7 1051
<> 144:ef7eb2e8f9f7 1052 /* Clear/enable DMA interrupts */
<> 144:ef7eb2e8f9f7 1053 NVIC_ClearPendingIRQ(DMA_IRQn);
<> 144:ef7eb2e8f9f7 1054 NVIC_EnableIRQ(DMA_IRQn);
<> 144:ef7eb2e8f9f7 1055
<> 144:ef7eb2e8f9f7 1056 /* Enable bus error interrupt */
<> 144:ef7eb2e8f9f7 1057 DMA->IEN = DMA_IEN_ERR;
<> 144:ef7eb2e8f9f7 1058
<> 144:ef7eb2e8f9f7 1059 /* Set pointer to control block, notice that this ptr must have been */
<> 144:ef7eb2e8f9f7 1060 /* properly aligned, according to requirements defined in the reference */
<> 144:ef7eb2e8f9f7 1061 /* manual. */
<> 144:ef7eb2e8f9f7 1062 DMA->CTRLBASE = (uint32_t)(init->controlBlock);
<> 144:ef7eb2e8f9f7 1063
<> 144:ef7eb2e8f9f7 1064 /* Configure and enable the DMA controller */
<> 144:ef7eb2e8f9f7 1065 DMA->CONFIG = ((uint32_t)(init->hprot) << _DMA_CONFIG_CHPROT_SHIFT)
<> 144:ef7eb2e8f9f7 1066 | DMA_CONFIG_EN;
<> 144:ef7eb2e8f9f7 1067 }
<> 144:ef7eb2e8f9f7 1068
<> 144:ef7eb2e8f9f7 1069
<> 144:ef7eb2e8f9f7 1070 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1071 * @brief
<> 144:ef7eb2e8f9f7 1072 * Refresh a descriptor used in a DMA ping-pong cycle.
<> 144:ef7eb2e8f9f7 1073 *
<> 144:ef7eb2e8f9f7 1074 * @details
<> 144:ef7eb2e8f9f7 1075 * During a ping-pong DMA cycle, the DMA controller automatically alternates
<> 144:ef7eb2e8f9f7 1076 * between primary and alternate descriptors, when completing use of a
<> 144:ef7eb2e8f9f7 1077 * descriptor. While the other descriptor is in use by the DMA controller,
<> 144:ef7eb2e8f9f7 1078 * the SW should refresh the completed descriptor. This is typically done from
<> 144:ef7eb2e8f9f7 1079 * the callback defined for the ping-pong cycle.
<> 144:ef7eb2e8f9f7 1080 *
<> 144:ef7eb2e8f9f7 1081 * @param[in] channel
<> 144:ef7eb2e8f9f7 1082 * DMA channel to refresh ping-pong descriptor for.
<> 144:ef7eb2e8f9f7 1083 *
<> 144:ef7eb2e8f9f7 1084 * @param[in] primary
<> 144:ef7eb2e8f9f7 1085 * @li true - refresh primary descriptor
<> 144:ef7eb2e8f9f7 1086 * @li false - refresh alternate descriptor
<> 144:ef7eb2e8f9f7 1087 *
<> 144:ef7eb2e8f9f7 1088 * @param[in] useBurst
<> 144:ef7eb2e8f9f7 1089 * The burst feature is only used on peripherals supporting DMA bursts.
<> 144:ef7eb2e8f9f7 1090 * Bursts must not be used if the total length (as given by nMinus1) is
<> 144:ef7eb2e8f9f7 1091 * less than the arbitration rate configured for the descriptor. Please
<> 144:ef7eb2e8f9f7 1092 * refer to the reference manual for further details on burst usage.
<> 144:ef7eb2e8f9f7 1093 *
<> 144:ef7eb2e8f9f7 1094 * @param[in] dst
<> 144:ef7eb2e8f9f7 1095 * Address to start location to transfer data to. If NULL, leave setting in
<> 144:ef7eb2e8f9f7 1096 * descriptor as is.
<> 144:ef7eb2e8f9f7 1097 *
<> 144:ef7eb2e8f9f7 1098 * @param[in] src
<> 144:ef7eb2e8f9f7 1099 * Address to start location to transfer data from. If NULL, leave setting in
<> 144:ef7eb2e8f9f7 1100 * descriptor as is.
<> 144:ef7eb2e8f9f7 1101 *
<> 144:ef7eb2e8f9f7 1102 * @param[in] nMinus1
<> 144:ef7eb2e8f9f7 1103 * Number of DMA transfer elements (minus 1) to transfer (<= 1023). The
<> 144:ef7eb2e8f9f7 1104 * size of the DMA transfer element (1, 2 or 4 bytes) is configured with
<> 144:ef7eb2e8f9f7 1105 * DMA_CfgDescr().
<> 144:ef7eb2e8f9f7 1106 *
<> 144:ef7eb2e8f9f7 1107 * @param[in] stop
<> 144:ef7eb2e8f9f7 1108 * Indicate that the DMA ping-pong cycle shall stop @b after completing use
<> 144:ef7eb2e8f9f7 1109 * of this descriptor.
<> 144:ef7eb2e8f9f7 1110 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1111 void DMA_RefreshPingPong(unsigned int channel,
<> 144:ef7eb2e8f9f7 1112 bool primary,
<> 144:ef7eb2e8f9f7 1113 bool useBurst,
<> 144:ef7eb2e8f9f7 1114 void *dst,
<> 144:ef7eb2e8f9f7 1115 void *src,
<> 144:ef7eb2e8f9f7 1116 unsigned int nMinus1,
<> 144:ef7eb2e8f9f7 1117 bool stop)
<> 144:ef7eb2e8f9f7 1118 {
<> 144:ef7eb2e8f9f7 1119 DMA_CycleCtrl_TypeDef cycleCtrl;
<> 144:ef7eb2e8f9f7 1120 DMA_DESCRIPTOR_TypeDef *descr;
<> 144:ef7eb2e8f9f7 1121 uint32_t inc;
<> 144:ef7eb2e8f9f7 1122 uint32_t chBit;
<> 144:ef7eb2e8f9f7 1123 uint32_t tmp;
<> 144:ef7eb2e8f9f7 1124
<> 144:ef7eb2e8f9f7 1125 EFM_ASSERT(channel < DMA_CHAN_COUNT);
<> 144:ef7eb2e8f9f7 1126 EFM_ASSERT(nMinus1 <= (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT));
<> 144:ef7eb2e8f9f7 1127
<> 144:ef7eb2e8f9f7 1128 /* The ping-pong DMA cycle may be stopped by issuing a basic cycle type */
<> 144:ef7eb2e8f9f7 1129 if (stop)
<> 144:ef7eb2e8f9f7 1130 {
<> 144:ef7eb2e8f9f7 1131 cycleCtrl = dmaCycleCtrlBasic;
<> 144:ef7eb2e8f9f7 1132 }
<> 144:ef7eb2e8f9f7 1133 else
<> 144:ef7eb2e8f9f7 1134 {
<> 144:ef7eb2e8f9f7 1135 cycleCtrl = dmaCycleCtrlPingPong;
<> 144:ef7eb2e8f9f7 1136 }
<> 144:ef7eb2e8f9f7 1137
<> 144:ef7eb2e8f9f7 1138 /* Find descriptor to configure */
<> 144:ef7eb2e8f9f7 1139 if (primary)
<> 144:ef7eb2e8f9f7 1140 {
<> 144:ef7eb2e8f9f7 1141 descr = ((DMA_DESCRIPTOR_TypeDef *)(DMA->CTRLBASE)) + channel;
<> 144:ef7eb2e8f9f7 1142 }
<> 144:ef7eb2e8f9f7 1143 else
<> 144:ef7eb2e8f9f7 1144 {
<> 144:ef7eb2e8f9f7 1145 descr = ((DMA_DESCRIPTOR_TypeDef *)(DMA->ALTCTRLBASE)) + channel;
<> 144:ef7eb2e8f9f7 1146 }
<> 144:ef7eb2e8f9f7 1147
<> 144:ef7eb2e8f9f7 1148 if (src)
<> 144:ef7eb2e8f9f7 1149 {
<> 144:ef7eb2e8f9f7 1150 inc = (descr->CTRL & _DMA_CTRL_SRC_INC_MASK) >> _DMA_CTRL_SRC_INC_SHIFT;
<> 144:ef7eb2e8f9f7 1151 if (inc == _DMA_CTRL_SRC_INC_NONE)
<> 144:ef7eb2e8f9f7 1152 {
<> 144:ef7eb2e8f9f7 1153 descr->SRCEND = src;
<> 144:ef7eb2e8f9f7 1154 }
<> 144:ef7eb2e8f9f7 1155 else
<> 144:ef7eb2e8f9f7 1156 {
<> 144:ef7eb2e8f9f7 1157 descr->SRCEND = (void *)((uint32_t)src + (nMinus1 << inc));
<> 144:ef7eb2e8f9f7 1158 }
<> 144:ef7eb2e8f9f7 1159 }
<> 144:ef7eb2e8f9f7 1160
<> 144:ef7eb2e8f9f7 1161 if (dst)
<> 144:ef7eb2e8f9f7 1162 {
<> 144:ef7eb2e8f9f7 1163 inc = (descr->CTRL & _DMA_CTRL_DST_INC_MASK) >> _DMA_CTRL_DST_INC_SHIFT;
<> 144:ef7eb2e8f9f7 1164 if (inc == _DMA_CTRL_DST_INC_NONE)
<> 144:ef7eb2e8f9f7 1165 {
<> 144:ef7eb2e8f9f7 1166 descr->DSTEND = dst;
<> 144:ef7eb2e8f9f7 1167 }
<> 144:ef7eb2e8f9f7 1168 else
<> 144:ef7eb2e8f9f7 1169 {
<> 144:ef7eb2e8f9f7 1170 descr->DSTEND = (void *)((uint32_t)dst + (nMinus1 << inc));
<> 144:ef7eb2e8f9f7 1171 }
<> 144:ef7eb2e8f9f7 1172 }
<> 144:ef7eb2e8f9f7 1173
<> 144:ef7eb2e8f9f7 1174 chBit = 1 << channel;
<> 144:ef7eb2e8f9f7 1175 if (useBurst)
<> 144:ef7eb2e8f9f7 1176 {
<> 144:ef7eb2e8f9f7 1177 DMA->CHUSEBURSTS = chBit;
<> 144:ef7eb2e8f9f7 1178 }
<> 144:ef7eb2e8f9f7 1179 else
<> 144:ef7eb2e8f9f7 1180 {
<> 144:ef7eb2e8f9f7 1181 DMA->CHUSEBURSTC = chBit;
<> 144:ef7eb2e8f9f7 1182 }
<> 144:ef7eb2e8f9f7 1183
<> 144:ef7eb2e8f9f7 1184 /* Set cycle control */
<> 144:ef7eb2e8f9f7 1185 tmp = descr->CTRL & ~(_DMA_CTRL_CYCLE_CTRL_MASK | _DMA_CTRL_N_MINUS_1_MASK);
<> 144:ef7eb2e8f9f7 1186 tmp |= nMinus1 << _DMA_CTRL_N_MINUS_1_SHIFT;
<> 144:ef7eb2e8f9f7 1187 tmp |= cycleCtrl << _DMA_CTRL_CYCLE_CTRL_SHIFT;
<> 144:ef7eb2e8f9f7 1188 descr->CTRL = tmp;
<> 144:ef7eb2e8f9f7 1189 }
<> 144:ef7eb2e8f9f7 1190
<> 144:ef7eb2e8f9f7 1191
<> 144:ef7eb2e8f9f7 1192 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 1193 * @brief
<> 144:ef7eb2e8f9f7 1194 * Reset the DMA controller.
<> 144:ef7eb2e8f9f7 1195 *
<> 144:ef7eb2e8f9f7 1196 * @details
<> 144:ef7eb2e8f9f7 1197 * This functions will disable the DMA controller and set it to a reset
<> 144:ef7eb2e8f9f7 1198 * state.
<> 144:ef7eb2e8f9f7 1199 *
<> 144:ef7eb2e8f9f7 1200 * @note
<> 144:ef7eb2e8f9f7 1201 * Notice that any ongoing transfers will be aborted.
<> 144:ef7eb2e8f9f7 1202 ******************************************************************************/
<> 144:ef7eb2e8f9f7 1203 void DMA_Reset(void)
<> 144:ef7eb2e8f9f7 1204 {
<> 144:ef7eb2e8f9f7 1205 int i;
<> 144:ef7eb2e8f9f7 1206
<> 144:ef7eb2e8f9f7 1207 /* Disable DMA interrupts */
<> 144:ef7eb2e8f9f7 1208 NVIC_DisableIRQ(DMA_IRQn);
<> 144:ef7eb2e8f9f7 1209
<> 144:ef7eb2e8f9f7 1210 /* Put the DMA controller into a known state, first disabling it. */
<> 144:ef7eb2e8f9f7 1211 DMA->CONFIG = _DMA_CONFIG_RESETVALUE;
<> 144:ef7eb2e8f9f7 1212 DMA->CHUSEBURSTC = _DMA_CHUSEBURSTC_MASK;
<> 144:ef7eb2e8f9f7 1213 DMA->CHREQMASKC = _DMA_CHREQMASKC_MASK;
<> 144:ef7eb2e8f9f7 1214 DMA->CHENC = _DMA_CHENC_MASK;
<> 144:ef7eb2e8f9f7 1215 DMA->CHALTC = _DMA_CHALTC_MASK;
<> 144:ef7eb2e8f9f7 1216 DMA->CHPRIC = _DMA_CHPRIC_MASK;
<> 144:ef7eb2e8f9f7 1217 DMA->ERRORC = DMA_ERRORC_ERRORC;
<> 144:ef7eb2e8f9f7 1218 DMA->IEN = _DMA_IEN_RESETVALUE;
<> 144:ef7eb2e8f9f7 1219 DMA->IFC = _DMA_IFC_MASK;
<> 144:ef7eb2e8f9f7 1220
<> 144:ef7eb2e8f9f7 1221 /* Clear channel control flags */
<> 144:ef7eb2e8f9f7 1222 for (i = 0; i < DMA_CHAN_COUNT; i++)
<> 144:ef7eb2e8f9f7 1223 {
<> 144:ef7eb2e8f9f7 1224 DMA->CH[i].CTRL = _DMA_CH_CTRL_RESETVALUE;
<> 144:ef7eb2e8f9f7 1225 }
<> 144:ef7eb2e8f9f7 1226 }
<> 144:ef7eb2e8f9f7 1227
<> 144:ef7eb2e8f9f7 1228
<> 144:ef7eb2e8f9f7 1229 /** @} (end addtogroup DMA) */
<> 144:ef7eb2e8f9f7 1230 /** @} (end addtogroup EM_Library) */
<> 144:ef7eb2e8f9f7 1231 #endif /* defined( DMA_PRESENT ) */