added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
bogdanm
Date:
Thu Oct 01 15:25:22 2015 +0300
Revision:
0:9b334a45a8ff
Child:
50:a417edff4437
Initial commit on mbed-dev

Replaces mbed-src (now inactive)

Who changed what in which revision?

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