added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
JojoS
Date:
Sat Sep 10 15:32:04 2016 +0000
Revision:
147:ba84b7dc41a7
Parent:
144:ef7eb2e8f9f7
added prescaler for 16 bit timers (solution as in LPC11xx), default prescaler 31 for max 28 ms period time

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 ) */