added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
mbed_official
Date:
Fri Jan 15 07:45:16 2016 +0000
Revision:
50:a417edff4437
Parent:
0:9b334a45a8ff
Child:
144:ef7eb2e8f9f7
Synchronized with git revision 6010f32619bfcbb01cc73747d4ff9040863482d9

Full URL: https://github.com/mbedmicro/mbed/commit/6010f32619bfcbb01cc73747d4ff9040863482d9/

Remove doubling of buffer size in realiseEndpoint()

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
mbed_official 50:a417edff4437 4 * @version 4.2.1
bogdanm 0:9b334a45a8ff 5 *******************************************************************************
bogdanm 0:9b334a45a8ff 6 * @section License
mbed_official 50:a417edff4437 7 * <b>(C) Copyright 2015 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 #include "em_dma.h"
bogdanm 0:9b334a45a8ff 34 #if defined( DMA_PRESENT )
bogdanm 0:9b334a45a8ff 35
bogdanm 0:9b334a45a8ff 36 #include "em_cmu.h"
bogdanm 0:9b334a45a8ff 37 #include "em_assert.h"
mbed_official 50:a417edff4437 38 #include "em_bus.h"
bogdanm 0:9b334a45a8ff 39
bogdanm 0:9b334a45a8ff 40 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 41 * @addtogroup EM_Library
bogdanm 0:9b334a45a8ff 42 * @{
bogdanm 0:9b334a45a8ff 43 ******************************************************************************/
bogdanm 0:9b334a45a8ff 44
bogdanm 0:9b334a45a8ff 45 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 46 * @addtogroup DMA
bogdanm 0:9b334a45a8ff 47 * @brief Direct Memory Access (DMA) Peripheral API
bogdanm 0:9b334a45a8ff 48 * @details
bogdanm 0:9b334a45a8ff 49 * These DMA access functions provide basic support for the following
bogdanm 0:9b334a45a8ff 50 * types of DMA cycles:
bogdanm 0:9b334a45a8ff 51 *
bogdanm 0:9b334a45a8ff 52 * @li @b Basic, used for transferring data between memory and peripherals.
bogdanm 0:9b334a45a8ff 53 * @li @b Auto-request, used for transferring data between memory locations.
bogdanm 0:9b334a45a8ff 54 * @li @b Ping-pong, used for for continuous transfer of data between memory
bogdanm 0:9b334a45a8ff 55 * and peripherals, automatically toggling between primary and alternate
bogdanm 0:9b334a45a8ff 56 * descriptors.
bogdanm 0:9b334a45a8ff 57 * @li @b Memory @b scatter-gather, used for transferring a number of buffers
bogdanm 0:9b334a45a8ff 58 * between memory locations.
bogdanm 0:9b334a45a8ff 59 * @li @b Peripheral @b scatter-gather, used for transferring a number of
bogdanm 0:9b334a45a8ff 60 * buffers between memory and peripherals.
bogdanm 0:9b334a45a8ff 61 *
bogdanm 0:9b334a45a8ff 62 * A basic understanding of the DMA controller is assumed. Please refer to
mbed_official 50:a417edff4437 63 * the reference manual for further details.
bogdanm 0:9b334a45a8ff 64 *
bogdanm 0:9b334a45a8ff 65 * The term 'descriptor' is used as a synonym to the 'channel control data
bogdanm 0:9b334a45a8ff 66 * structure' term.
bogdanm 0:9b334a45a8ff 67 *
bogdanm 0:9b334a45a8ff 68 * In order to use the DMA controller, the initialization function must have
bogdanm 0:9b334a45a8ff 69 * been executed once (normally during system init):
bogdanm 0:9b334a45a8ff 70 * @verbatim
bogdanm 0:9b334a45a8ff 71 * DMA_Init();
bogdanm 0:9b334a45a8ff 72 * @endverbatim
bogdanm 0:9b334a45a8ff 73 *
bogdanm 0:9b334a45a8ff 74 * Then, normally a user of a DMA channel configures the channel:
bogdanm 0:9b334a45a8ff 75 * @verbatim
bogdanm 0:9b334a45a8ff 76 * DMA_CfgChannel();
bogdanm 0:9b334a45a8ff 77 * @endverbatim
bogdanm 0:9b334a45a8ff 78 *
bogdanm 0:9b334a45a8ff 79 * The channel configuration only has to be done once, if reusing the channel
bogdanm 0:9b334a45a8ff 80 * for the same purpose later.
bogdanm 0:9b334a45a8ff 81 *
bogdanm 0:9b334a45a8ff 82 * In order to set up a DMA cycle, the primary and/or alternate descriptor
bogdanm 0:9b334a45a8ff 83 * has to be set up as indicated below.
bogdanm 0:9b334a45a8ff 84 *
bogdanm 0:9b334a45a8ff 85 * For basic or auto-request cycles, use once on either primary or alternate
bogdanm 0:9b334a45a8ff 86 * descriptor:
bogdanm 0:9b334a45a8ff 87 * @verbatim
bogdanm 0:9b334a45a8ff 88 * DMA_CfgDescr();
bogdanm 0:9b334a45a8ff 89 * @endverbatim
bogdanm 0:9b334a45a8ff 90 *
bogdanm 0:9b334a45a8ff 91 * For ping-pong cycles, configure both primary or alternate descriptors:
bogdanm 0:9b334a45a8ff 92 * @verbatim
bogdanm 0:9b334a45a8ff 93 * DMA_CfgDescr(); // Primary descriptor config
bogdanm 0:9b334a45a8ff 94 * DMA_CfgDescr(); // Alternate descriptor config
bogdanm 0:9b334a45a8ff 95 * @endverbatim
bogdanm 0:9b334a45a8ff 96 *
bogdanm 0:9b334a45a8ff 97 * For scatter-gather cycles, the alternate descriptor array must be programmed:
bogdanm 0:9b334a45a8ff 98 * @verbatim
bogdanm 0:9b334a45a8ff 99 * // 'n' is the number of scattered buffers
bogdanm 0:9b334a45a8ff 100 * // 'descr' points to the start of the alternate descriptor array
bogdanm 0:9b334a45a8ff 101 *
bogdanm 0:9b334a45a8ff 102 * // Fill in 'cfg'
bogdanm 0:9b334a45a8ff 103 * DMA_CfgDescrScatterGather(descr, 0, cfg);
bogdanm 0:9b334a45a8ff 104 * // Fill in 'cfg'
bogdanm 0:9b334a45a8ff 105 * DMA_CfgDescrScatterGather(descr, 1, cfg);
bogdanm 0:9b334a45a8ff 106 * :
bogdanm 0:9b334a45a8ff 107 * // Fill in 'cfg'
bogdanm 0:9b334a45a8ff 108 * DMA_CfgDescrScatterGather(descr, n - 1, cfg);
bogdanm 0:9b334a45a8ff 109 * @endverbatim
bogdanm 0:9b334a45a8ff 110 *
bogdanm 0:9b334a45a8ff 111 * In many cases, the descriptor configuration only has to be done once, if
bogdanm 0:9b334a45a8ff 112 * re-using the channel for the same type of DMA cycles later.
bogdanm 0:9b334a45a8ff 113 *
bogdanm 0:9b334a45a8ff 114 * In order to activate the DMA cycle, use the respective DMA_Activate...()
bogdanm 0:9b334a45a8ff 115 * function.
bogdanm 0:9b334a45a8ff 116 *
bogdanm 0:9b334a45a8ff 117 * For ping-pong DMA cycles, use DMA_RefreshPingPong() from the callback to
bogdanm 0:9b334a45a8ff 118 * prepare the completed descriptor for reuse. Notice that the refresh must
bogdanm 0:9b334a45a8ff 119 * be done prior to the other active descriptor completes, otherwise the
bogdanm 0:9b334a45a8ff 120 * ping-pong DMA cycle will halt.
bogdanm 0:9b334a45a8ff 121 * @{
bogdanm 0:9b334a45a8ff 122 ******************************************************************************/
bogdanm 0:9b334a45a8ff 123
bogdanm 0:9b334a45a8ff 124 /*******************************************************************************
bogdanm 0:9b334a45a8ff 125 ************************** LOCAL FUNCTIONS ********************************
bogdanm 0:9b334a45a8ff 126 ******************************************************************************/
bogdanm 0:9b334a45a8ff 127
bogdanm 0:9b334a45a8ff 128 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
bogdanm 0:9b334a45a8ff 129
bogdanm 0:9b334a45a8ff 130 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 131 * @brief
bogdanm 0:9b334a45a8ff 132 * Prepare descriptor for DMA cycle.
bogdanm 0:9b334a45a8ff 133 *
bogdanm 0:9b334a45a8ff 134 * @details
bogdanm 0:9b334a45a8ff 135 * This function prepares the last pieces of configuration required to start a
bogdanm 0:9b334a45a8ff 136 * DMA cycle. Since the DMA controller itself modifies some parts of the
bogdanm 0:9b334a45a8ff 137 * descriptor during use, those parts need to be refreshed if reusing a
bogdanm 0:9b334a45a8ff 138 * descriptor configuration.
bogdanm 0:9b334a45a8ff 139 *
bogdanm 0:9b334a45a8ff 140 * @note
bogdanm 0:9b334a45a8ff 141 * If using this function on a descriptor already activated and in use by the
bogdanm 0:9b334a45a8ff 142 * DMA controller, the behaviour is undefined.
bogdanm 0:9b334a45a8ff 143 *
bogdanm 0:9b334a45a8ff 144 * @param[in] channel
bogdanm 0:9b334a45a8ff 145 * DMA channel to prepare for DMA cycle.
bogdanm 0:9b334a45a8ff 146 *
bogdanm 0:9b334a45a8ff 147 * @param[in] cycleCtrl
bogdanm 0:9b334a45a8ff 148 * DMA cycle type to prepare for.
bogdanm 0:9b334a45a8ff 149 *
bogdanm 0:9b334a45a8ff 150 * @param[in] primary
bogdanm 0:9b334a45a8ff 151 * @li true - prepare primary descriptor
bogdanm 0:9b334a45a8ff 152 * @li false - prepare alternate descriptor
bogdanm 0:9b334a45a8ff 153 *
bogdanm 0:9b334a45a8ff 154 * @param[in] useBurst
bogdanm 0:9b334a45a8ff 155 * The burst feature is only used on peripherals supporting DMA bursts.
bogdanm 0:9b334a45a8ff 156 * Bursts must not be used if the total length (as given by nMinus1) is
bogdanm 0:9b334a45a8ff 157 * less than the arbitration rate configured for the descriptor. Please
bogdanm 0:9b334a45a8ff 158 * refer to the reference manual for further details on burst usage.
bogdanm 0:9b334a45a8ff 159 *
bogdanm 0:9b334a45a8ff 160 * @param[in] dst
bogdanm 0:9b334a45a8ff 161 * Address to start location to transfer data to. If NULL, leave setting in
bogdanm 0:9b334a45a8ff 162 * descriptor as is.
bogdanm 0:9b334a45a8ff 163 *
bogdanm 0:9b334a45a8ff 164 * @param[in] src
bogdanm 0:9b334a45a8ff 165 * Address to start location to transfer data from. If NULL, leave setting in
bogdanm 0:9b334a45a8ff 166 * descriptor as is.
bogdanm 0:9b334a45a8ff 167 *
bogdanm 0:9b334a45a8ff 168 * @param[in] nMinus1
bogdanm 0:9b334a45a8ff 169 * Number of elements (minus 1) to transfer (<= 1023).
bogdanm 0:9b334a45a8ff 170 ******************************************************************************/
bogdanm 0:9b334a45a8ff 171 static void DMA_Prepare(unsigned int channel,
bogdanm 0:9b334a45a8ff 172 DMA_CycleCtrl_TypeDef cycleCtrl,
bogdanm 0:9b334a45a8ff 173 bool primary,
bogdanm 0:9b334a45a8ff 174 bool useBurst,
bogdanm 0:9b334a45a8ff 175 void *dst,
bogdanm 0:9b334a45a8ff 176 void *src,
bogdanm 0:9b334a45a8ff 177 unsigned int nMinus1)
bogdanm 0:9b334a45a8ff 178 {
bogdanm 0:9b334a45a8ff 179 DMA_DESCRIPTOR_TypeDef *descr;
bogdanm 0:9b334a45a8ff 180 DMA_DESCRIPTOR_TypeDef *primDescr;
bogdanm 0:9b334a45a8ff 181 DMA_CB_TypeDef *cb;
bogdanm 0:9b334a45a8ff 182 uint32_t inc;
bogdanm 0:9b334a45a8ff 183 uint32_t chBit;
bogdanm 0:9b334a45a8ff 184 uint32_t tmp;
bogdanm 0:9b334a45a8ff 185
bogdanm 0:9b334a45a8ff 186 primDescr = ((DMA_DESCRIPTOR_TypeDef *)(DMA->CTRLBASE)) + channel;
bogdanm 0:9b334a45a8ff 187
bogdanm 0:9b334a45a8ff 188 /* Find descriptor to configure */
bogdanm 0:9b334a45a8ff 189 if (primary)
bogdanm 0:9b334a45a8ff 190 {
bogdanm 0:9b334a45a8ff 191 descr = primDescr;
bogdanm 0:9b334a45a8ff 192 }
bogdanm 0:9b334a45a8ff 193 else
bogdanm 0:9b334a45a8ff 194 {
bogdanm 0:9b334a45a8ff 195 descr = ((DMA_DESCRIPTOR_TypeDef *)(DMA->ALTCTRLBASE)) + channel;
bogdanm 0:9b334a45a8ff 196 }
bogdanm 0:9b334a45a8ff 197
bogdanm 0:9b334a45a8ff 198 /* If callback defined, update info on whether callback is issued */
bogdanm 0:9b334a45a8ff 199 /* for primary or alternate descriptor. Mainly needed for ping-pong */
bogdanm 0:9b334a45a8ff 200 /* cycles. */
bogdanm 0:9b334a45a8ff 201 cb = (DMA_CB_TypeDef *)(primDescr->USER);
bogdanm 0:9b334a45a8ff 202 if (cb)
bogdanm 0:9b334a45a8ff 203 {
bogdanm 0:9b334a45a8ff 204 cb->primary = (uint8_t)primary;
bogdanm 0:9b334a45a8ff 205 }
bogdanm 0:9b334a45a8ff 206
bogdanm 0:9b334a45a8ff 207 if (src)
bogdanm 0:9b334a45a8ff 208 {
bogdanm 0:9b334a45a8ff 209 inc = (descr->CTRL & _DMA_CTRL_SRC_INC_MASK) >> _DMA_CTRL_SRC_INC_SHIFT;
bogdanm 0:9b334a45a8ff 210 if (inc == _DMA_CTRL_SRC_INC_NONE)
bogdanm 0:9b334a45a8ff 211 {
bogdanm 0:9b334a45a8ff 212 descr->SRCEND = src;
bogdanm 0:9b334a45a8ff 213 }
bogdanm 0:9b334a45a8ff 214 else
bogdanm 0:9b334a45a8ff 215 {
bogdanm 0:9b334a45a8ff 216 descr->SRCEND = (void *)((uint32_t)src + (nMinus1 << inc));
bogdanm 0:9b334a45a8ff 217 }
bogdanm 0:9b334a45a8ff 218 }
bogdanm 0:9b334a45a8ff 219
bogdanm 0:9b334a45a8ff 220 if (dst)
bogdanm 0:9b334a45a8ff 221 {
bogdanm 0:9b334a45a8ff 222 inc = (descr->CTRL & _DMA_CTRL_DST_INC_MASK) >> _DMA_CTRL_DST_INC_SHIFT;
bogdanm 0:9b334a45a8ff 223 if (inc == _DMA_CTRL_DST_INC_NONE)
bogdanm 0:9b334a45a8ff 224 {
bogdanm 0:9b334a45a8ff 225 descr->DSTEND = dst;
bogdanm 0:9b334a45a8ff 226 }
bogdanm 0:9b334a45a8ff 227 else
bogdanm 0:9b334a45a8ff 228 {
bogdanm 0:9b334a45a8ff 229 descr->DSTEND = (void *)((uint32_t)dst + (nMinus1 << inc));
bogdanm 0:9b334a45a8ff 230 }
bogdanm 0:9b334a45a8ff 231 }
bogdanm 0:9b334a45a8ff 232
bogdanm 0:9b334a45a8ff 233 chBit = 1 << channel;
bogdanm 0:9b334a45a8ff 234 if (useBurst)
bogdanm 0:9b334a45a8ff 235 {
bogdanm 0:9b334a45a8ff 236 DMA->CHUSEBURSTS = chBit;
bogdanm 0:9b334a45a8ff 237 }
bogdanm 0:9b334a45a8ff 238 else
bogdanm 0:9b334a45a8ff 239 {
bogdanm 0:9b334a45a8ff 240 DMA->CHUSEBURSTC = chBit;
bogdanm 0:9b334a45a8ff 241 }
bogdanm 0:9b334a45a8ff 242
bogdanm 0:9b334a45a8ff 243 if (primary)
bogdanm 0:9b334a45a8ff 244 {
bogdanm 0:9b334a45a8ff 245 DMA->CHALTC = chBit;
bogdanm 0:9b334a45a8ff 246 }
bogdanm 0:9b334a45a8ff 247 else
bogdanm 0:9b334a45a8ff 248 {
bogdanm 0:9b334a45a8ff 249 DMA->CHALTS = chBit;
bogdanm 0:9b334a45a8ff 250 }
bogdanm 0:9b334a45a8ff 251
bogdanm 0:9b334a45a8ff 252 /* Set cycle control */
mbed_official 50:a417edff4437 253 tmp = descr->CTRL & ~(_DMA_CTRL_CYCLE_CTRL_MASK | _DMA_CTRL_N_MINUS_1_MASK);
mbed_official 50:a417edff4437 254 tmp |= nMinus1 << _DMA_CTRL_N_MINUS_1_SHIFT;
mbed_official 50:a417edff4437 255 tmp |= (uint32_t)cycleCtrl << _DMA_CTRL_CYCLE_CTRL_SHIFT;
bogdanm 0:9b334a45a8ff 256 descr->CTRL = tmp;
bogdanm 0:9b334a45a8ff 257 }
bogdanm 0:9b334a45a8ff 258
bogdanm 0:9b334a45a8ff 259 /** @endcond */
bogdanm 0:9b334a45a8ff 260
bogdanm 0:9b334a45a8ff 261 /*******************************************************************************
bogdanm 0:9b334a45a8ff 262 ************************ INTERRUPT FUNCTIONS ******************************
bogdanm 0:9b334a45a8ff 263 ******************************************************************************/
bogdanm 0:9b334a45a8ff 264
bogdanm 0:9b334a45a8ff 265 #ifndef EXCLUDE_DEFAULT_DMA_IRQ_HANDLER
bogdanm 0:9b334a45a8ff 266
bogdanm 0:9b334a45a8ff 267 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 268 * @brief
bogdanm 0:9b334a45a8ff 269 * Interrupt handler for DMA cycle completion handling.
bogdanm 0:9b334a45a8ff 270 *
bogdanm 0:9b334a45a8ff 271 * @details
bogdanm 0:9b334a45a8ff 272 * Clears any pending flags and calls registered callback (if any).
bogdanm 0:9b334a45a8ff 273 *
bogdanm 0:9b334a45a8ff 274 * If using the default interrupt vector table setup provided, this function
bogdanm 0:9b334a45a8ff 275 * is automatically placed in the IRQ table due to weak linking. If taking
bogdanm 0:9b334a45a8ff 276 * control over the interrupt vector table in some other way, this interrupt
bogdanm 0:9b334a45a8ff 277 * handler must be installed in order to be able to support callback actions.
bogdanm 0:9b334a45a8ff 278 *
bogdanm 0:9b334a45a8ff 279 * In order for the user to implement a custom IRQ handler or run without
bogdanm 0:9b334a45a8ff 280 * a DMA IRQ handler, the user can define EXCLUDE_DEFAULT_DMA_IRQ_HANDLER
bogdanm 0:9b334a45a8ff 281 * with a \#define statement or with the compiler option -D.
bogdanm 0:9b334a45a8ff 282 *
bogdanm 0:9b334a45a8ff 283 ******************************************************************************/
bogdanm 0:9b334a45a8ff 284 void DMA_IRQHandler(void)
bogdanm 0:9b334a45a8ff 285 {
bogdanm 0:9b334a45a8ff 286 int channel;
bogdanm 0:9b334a45a8ff 287 DMA_CB_TypeDef *cb;
bogdanm 0:9b334a45a8ff 288 uint32_t pending;
bogdanm 0:9b334a45a8ff 289 uint32_t pendingPrio;
bogdanm 0:9b334a45a8ff 290 uint32_t prio;
bogdanm 0:9b334a45a8ff 291 uint32_t primaryCpy;
bogdanm 0:9b334a45a8ff 292 int i;
bogdanm 0:9b334a45a8ff 293
bogdanm 0:9b334a45a8ff 294 /* Get all pending and enabled interrupts */
bogdanm 0:9b334a45a8ff 295 pending = DMA->IF;
bogdanm 0:9b334a45a8ff 296 pending &= DMA->IEN;
bogdanm 0:9b334a45a8ff 297
bogdanm 0:9b334a45a8ff 298 /* Check for bus error */
bogdanm 0:9b334a45a8ff 299 if (pending & DMA_IF_ERR)
bogdanm 0:9b334a45a8ff 300 {
bogdanm 0:9b334a45a8ff 301 /* Loop here to enable the debugger to see what has happened */
bogdanm 0:9b334a45a8ff 302 while (1)
bogdanm 0:9b334a45a8ff 303 ;
bogdanm 0:9b334a45a8ff 304 }
bogdanm 0:9b334a45a8ff 305
bogdanm 0:9b334a45a8ff 306 /* Process all pending channel interrupts. First process channels */
bogdanm 0:9b334a45a8ff 307 /* defined with high priority, then those with default priority. */
bogdanm 0:9b334a45a8ff 308 prio = DMA->CHPRIS;
bogdanm 0:9b334a45a8ff 309 pendingPrio = pending & prio;
bogdanm 0:9b334a45a8ff 310 for (i = 0; i < 2; i++)
bogdanm 0:9b334a45a8ff 311 {
bogdanm 0:9b334a45a8ff 312 channel = 0;
bogdanm 0:9b334a45a8ff 313 /* Process pending interrupts within high/default priority group */
bogdanm 0:9b334a45a8ff 314 /* honouring priority within group. */
bogdanm 0:9b334a45a8ff 315 while (pendingPrio)
bogdanm 0:9b334a45a8ff 316 {
bogdanm 0:9b334a45a8ff 317 if (pendingPrio & 1)
bogdanm 0:9b334a45a8ff 318 {
bogdanm 0:9b334a45a8ff 319 DMA_DESCRIPTOR_TypeDef *descr = (DMA_DESCRIPTOR_TypeDef *)(DMA->CTRLBASE);
bogdanm 0:9b334a45a8ff 320 uint32_t chmask = 1 << channel;
bogdanm 0:9b334a45a8ff 321
bogdanm 0:9b334a45a8ff 322 /* Clear pending interrupt prior to invoking callback, in case it */
bogdanm 0:9b334a45a8ff 323 /* sets up another DMA cycle. */
bogdanm 0:9b334a45a8ff 324 DMA->IFC = chmask;
bogdanm 0:9b334a45a8ff 325
bogdanm 0:9b334a45a8ff 326 /* Normally, no point in enabling interrupt without callback, but */
bogdanm 0:9b334a45a8ff 327 /* check if callback is defined anyway. Callback info is always */
bogdanm 0:9b334a45a8ff 328 /* located in primary descriptor. */
bogdanm 0:9b334a45a8ff 329 cb = (DMA_CB_TypeDef *)(descr[channel].USER);
bogdanm 0:9b334a45a8ff 330 if (cb)
bogdanm 0:9b334a45a8ff 331 {
bogdanm 0:9b334a45a8ff 332 /* Toggle next-descriptor indicator always prior to invoking */
bogdanm 0:9b334a45a8ff 333 /* callback (in case callback reconfigurs something) */
bogdanm 0:9b334a45a8ff 334 primaryCpy = cb->primary;
bogdanm 0:9b334a45a8ff 335 cb->primary ^= 1;
bogdanm 0:9b334a45a8ff 336 if (cb->cbFunc)
bogdanm 0:9b334a45a8ff 337 {
bogdanm 0:9b334a45a8ff 338 cb->cbFunc(channel, (bool)primaryCpy, cb->userPtr);
bogdanm 0:9b334a45a8ff 339 }
bogdanm 0:9b334a45a8ff 340 }
bogdanm 0:9b334a45a8ff 341 }
bogdanm 0:9b334a45a8ff 342
bogdanm 0:9b334a45a8ff 343 pendingPrio >>= 1;
bogdanm 0:9b334a45a8ff 344 channel++;
bogdanm 0:9b334a45a8ff 345 }
bogdanm 0:9b334a45a8ff 346
bogdanm 0:9b334a45a8ff 347 /* On second iteration, process default priority channels */
bogdanm 0:9b334a45a8ff 348 pendingPrio = pending & ~prio;
bogdanm 0:9b334a45a8ff 349 }
bogdanm 0:9b334a45a8ff 350 }
bogdanm 0:9b334a45a8ff 351
bogdanm 0:9b334a45a8ff 352 #endif /* EXCLUDE_DEFAULT_DMA_IRQ_HANDLER */
bogdanm 0:9b334a45a8ff 353
bogdanm 0:9b334a45a8ff 354
bogdanm 0:9b334a45a8ff 355 /*******************************************************************************
bogdanm 0:9b334a45a8ff 356 ************************** GLOBAL FUNCTIONS *******************************
bogdanm 0:9b334a45a8ff 357 ******************************************************************************/
bogdanm 0:9b334a45a8ff 358
bogdanm 0:9b334a45a8ff 359 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 360 * @brief
bogdanm 0:9b334a45a8ff 361 * Activate DMA auto-request cycle (used for memory-memory transfers).
bogdanm 0:9b334a45a8ff 362 *
bogdanm 0:9b334a45a8ff 363 * @details
bogdanm 0:9b334a45a8ff 364 * Prior to activating the DMA cycle, the channel and descriptor to be used
bogdanm 0:9b334a45a8ff 365 * must have been properly configured.
bogdanm 0:9b334a45a8ff 366 *
bogdanm 0:9b334a45a8ff 367 * @note
bogdanm 0:9b334a45a8ff 368 * If using this function on a channel already activated and in use by the
bogdanm 0:9b334a45a8ff 369 * DMA controller, the behaviour is undefined.
bogdanm 0:9b334a45a8ff 370 *
bogdanm 0:9b334a45a8ff 371 * @param[in] channel
bogdanm 0:9b334a45a8ff 372 * DMA channel to activate DMA cycle for.
bogdanm 0:9b334a45a8ff 373 *
bogdanm 0:9b334a45a8ff 374 * @param[in] primary
bogdanm 0:9b334a45a8ff 375 * @li true - activate using primary descriptor
bogdanm 0:9b334a45a8ff 376 * @li false - activate using alternate descriptor
bogdanm 0:9b334a45a8ff 377 *
bogdanm 0:9b334a45a8ff 378 * @param[in] dst
bogdanm 0:9b334a45a8ff 379 * Address to start location to transfer data to. If NULL, leave setting in
bogdanm 0:9b334a45a8ff 380 * descriptor as is from a previous activation.
bogdanm 0:9b334a45a8ff 381 *
bogdanm 0:9b334a45a8ff 382 * @param[in] src
bogdanm 0:9b334a45a8ff 383 * Address to start location to transfer data from. If NULL, leave setting in
bogdanm 0:9b334a45a8ff 384 * descriptor as is from a previous activation.
bogdanm 0:9b334a45a8ff 385 *
bogdanm 0:9b334a45a8ff 386 * @param[in] nMinus1
bogdanm 0:9b334a45a8ff 387 * Number of DMA transfer elements (minus 1) to transfer (<= 1023). The
bogdanm 0:9b334a45a8ff 388 * size of the DMA transfer element (1, 2 or 4 bytes) is configured with
bogdanm 0:9b334a45a8ff 389 * DMA_CfgDescr().
bogdanm 0:9b334a45a8ff 390 ******************************************************************************/
bogdanm 0:9b334a45a8ff 391 void DMA_ActivateAuto(unsigned int channel,
bogdanm 0:9b334a45a8ff 392 bool primary,
bogdanm 0:9b334a45a8ff 393 void *dst,
bogdanm 0:9b334a45a8ff 394 void *src,
bogdanm 0:9b334a45a8ff 395 unsigned int nMinus1)
bogdanm 0:9b334a45a8ff 396 {
bogdanm 0:9b334a45a8ff 397 uint32_t chBit;
bogdanm 0:9b334a45a8ff 398
bogdanm 0:9b334a45a8ff 399 EFM_ASSERT(channel < DMA_CHAN_COUNT);
bogdanm 0:9b334a45a8ff 400 EFM_ASSERT(nMinus1 <= (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT));
bogdanm 0:9b334a45a8ff 401
bogdanm 0:9b334a45a8ff 402 DMA_Prepare(channel,
bogdanm 0:9b334a45a8ff 403 dmaCycleCtrlAuto,
bogdanm 0:9b334a45a8ff 404 primary,
bogdanm 0:9b334a45a8ff 405 false,
bogdanm 0:9b334a45a8ff 406 dst,
bogdanm 0:9b334a45a8ff 407 src,
bogdanm 0:9b334a45a8ff 408 nMinus1);
bogdanm 0:9b334a45a8ff 409
bogdanm 0:9b334a45a8ff 410 chBit = 1 << channel;
bogdanm 0:9b334a45a8ff 411 DMA->CHENS = chBit; /* Enable channel */
bogdanm 0:9b334a45a8ff 412 DMA->CHSWREQ = chBit; /* Activate with SW request */
bogdanm 0:9b334a45a8ff 413 }
bogdanm 0:9b334a45a8ff 414
bogdanm 0:9b334a45a8ff 415
bogdanm 0:9b334a45a8ff 416 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 417 * @brief
bogdanm 0:9b334a45a8ff 418 * Activate DMA basic cycle (used for memory-peripheral transfers).
bogdanm 0:9b334a45a8ff 419 *
bogdanm 0:9b334a45a8ff 420 * @details
bogdanm 0:9b334a45a8ff 421 * Prior to activating the DMA cycle, the channel and descriptor to be used
bogdanm 0:9b334a45a8ff 422 * must have been properly configured.
bogdanm 0:9b334a45a8ff 423 *
bogdanm 0:9b334a45a8ff 424 * @note
bogdanm 0:9b334a45a8ff 425 * If using this function on a channel already activated and in use by the
bogdanm 0:9b334a45a8ff 426 * DMA controller, the behaviour is undefined.
bogdanm 0:9b334a45a8ff 427 *
bogdanm 0:9b334a45a8ff 428 * @param[in] channel
bogdanm 0:9b334a45a8ff 429 * DMA channel to activate DMA cycle for.
bogdanm 0:9b334a45a8ff 430 *
bogdanm 0:9b334a45a8ff 431 * @param[in] primary
bogdanm 0:9b334a45a8ff 432 * @li true - activate using primary descriptor
bogdanm 0:9b334a45a8ff 433 * @li false - activate using alternate descriptor
bogdanm 0:9b334a45a8ff 434 *
bogdanm 0:9b334a45a8ff 435 * @param[in] useBurst
bogdanm 0:9b334a45a8ff 436 * The burst feature is only used on peripherals supporting DMA bursts.
bogdanm 0:9b334a45a8ff 437 * Bursts must not be used if the total length (as given by nMinus1) is
bogdanm 0:9b334a45a8ff 438 * less than the arbitration rate configured for the descriptor. Please
bogdanm 0:9b334a45a8ff 439 * refer to the reference manual for further details on burst usage.
bogdanm 0:9b334a45a8ff 440 *
bogdanm 0:9b334a45a8ff 441 * @param[in] dst
bogdanm 0:9b334a45a8ff 442 * Address to start location to transfer data to. If NULL, leave setting in
bogdanm 0:9b334a45a8ff 443 * descriptor as is from a previous activation.
bogdanm 0:9b334a45a8ff 444 *
bogdanm 0:9b334a45a8ff 445 * @param[in] src
bogdanm 0:9b334a45a8ff 446 * Address to start location to transfer data from. If NULL, leave setting in
bogdanm 0:9b334a45a8ff 447 * descriptor as is from a previous activation.
bogdanm 0:9b334a45a8ff 448 *
bogdanm 0:9b334a45a8ff 449 * @param[in] nMinus1
bogdanm 0:9b334a45a8ff 450 * Number of DMA transfer elements (minus 1) to transfer (<= 1023). The
bogdanm 0:9b334a45a8ff 451 * size of the DMA transfer element (1, 2 or 4 bytes) is configured with
bogdanm 0:9b334a45a8ff 452 * DMA_CfgDescr().
bogdanm 0:9b334a45a8ff 453 ******************************************************************************/
bogdanm 0:9b334a45a8ff 454 void DMA_ActivateBasic(unsigned int channel,
bogdanm 0:9b334a45a8ff 455 bool primary,
bogdanm 0:9b334a45a8ff 456 bool useBurst,
bogdanm 0:9b334a45a8ff 457 void *dst,
bogdanm 0:9b334a45a8ff 458 void *src,
bogdanm 0:9b334a45a8ff 459 unsigned int nMinus1)
bogdanm 0:9b334a45a8ff 460 {
bogdanm 0:9b334a45a8ff 461 EFM_ASSERT(channel < DMA_CHAN_COUNT);
bogdanm 0:9b334a45a8ff 462 EFM_ASSERT(nMinus1 <= (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT));
bogdanm 0:9b334a45a8ff 463
bogdanm 0:9b334a45a8ff 464 DMA_Prepare(channel,
bogdanm 0:9b334a45a8ff 465 dmaCycleCtrlBasic,
bogdanm 0:9b334a45a8ff 466 primary,
bogdanm 0:9b334a45a8ff 467 useBurst,
bogdanm 0:9b334a45a8ff 468 dst,
bogdanm 0:9b334a45a8ff 469 src,
bogdanm 0:9b334a45a8ff 470 nMinus1);
bogdanm 0:9b334a45a8ff 471
bogdanm 0:9b334a45a8ff 472 /* Enable channel, request signal is provided by peripheral device */
bogdanm 0:9b334a45a8ff 473 DMA->CHENS = 1 << channel;
bogdanm 0:9b334a45a8ff 474 }
bogdanm 0:9b334a45a8ff 475
bogdanm 0:9b334a45a8ff 476
bogdanm 0:9b334a45a8ff 477 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 478 * @brief
bogdanm 0:9b334a45a8ff 479 * Activate DMA ping-pong cycle (used for memory-peripheral transfers).
bogdanm 0:9b334a45a8ff 480 *
bogdanm 0:9b334a45a8ff 481 * @details
bogdanm 0:9b334a45a8ff 482 * Prior to activating the DMA cycle, the channel and both descriptors must
bogdanm 0:9b334a45a8ff 483 * have been properly configured. The primary descriptor is always the first
bogdanm 0:9b334a45a8ff 484 * descriptor to be used by the DMA controller.
bogdanm 0:9b334a45a8ff 485 *
bogdanm 0:9b334a45a8ff 486 * @note
bogdanm 0:9b334a45a8ff 487 * If using this function on a channel already activated and in use by the
bogdanm 0:9b334a45a8ff 488 * DMA controller, the behaviour is undefined.
bogdanm 0:9b334a45a8ff 489 *
bogdanm 0:9b334a45a8ff 490 * @param[in] channel
bogdanm 0:9b334a45a8ff 491 * DMA channel to activate DMA cycle for.
bogdanm 0:9b334a45a8ff 492 *
bogdanm 0:9b334a45a8ff 493 * @param[in] useBurst
bogdanm 0:9b334a45a8ff 494 * The burst feature is only used on peripherals supporting DMA bursts.
bogdanm 0:9b334a45a8ff 495 * Bursts must not be used if the total length (as given by nMinus1) is
bogdanm 0:9b334a45a8ff 496 * less than the arbitration rate configured for the descriptors. Please
bogdanm 0:9b334a45a8ff 497 * refer to the reference manual for further details on burst usage. Notice
bogdanm 0:9b334a45a8ff 498 * that this setting is used for both the primary and alternate descriptors.
bogdanm 0:9b334a45a8ff 499 *
bogdanm 0:9b334a45a8ff 500 * @param[in] primDst
bogdanm 0:9b334a45a8ff 501 * Address to start location to transfer data to, for primary descriptor.
bogdanm 0:9b334a45a8ff 502 * If NULL, leave setting in descriptor as is from a previous activation.
bogdanm 0:9b334a45a8ff 503 *
bogdanm 0:9b334a45a8ff 504 * @param[in] primSrc
bogdanm 0:9b334a45a8ff 505 * Address to start location to transfer data from, for primary descriptor.
bogdanm 0:9b334a45a8ff 506 * If NULL, leave setting in descriptor as is from a previous activation.
bogdanm 0:9b334a45a8ff 507 *
bogdanm 0:9b334a45a8ff 508 * @param[in] primNMinus1
bogdanm 0:9b334a45a8ff 509 * Number of DMA transfer elements (minus 1) to transfer (<= 1023), for
bogdanm 0:9b334a45a8ff 510 * primary descriptor. The size of the DMA transfer element (1, 2 or 4 bytes)
bogdanm 0:9b334a45a8ff 511 * is configured with DMA_CfgDescr().
bogdanm 0:9b334a45a8ff 512 *
bogdanm 0:9b334a45a8ff 513 * @param[in] altDst
bogdanm 0:9b334a45a8ff 514 * Address to start location to transfer data to, for alternate descriptor.
bogdanm 0:9b334a45a8ff 515 * If NULL, leave setting in descriptor as is from a previous activation.
bogdanm 0:9b334a45a8ff 516 *
bogdanm 0:9b334a45a8ff 517 * @param[in] altSrc
bogdanm 0:9b334a45a8ff 518 * Address to start location to transfer data from, for alternate descriptor.
bogdanm 0:9b334a45a8ff 519 * If NULL, leave setting in descriptor as is from a previous activation.
bogdanm 0:9b334a45a8ff 520 *
bogdanm 0:9b334a45a8ff 521 * @param[in] altNMinus1
bogdanm 0:9b334a45a8ff 522 * Number of DMA transfer elements (minus 1) to transfer (<= 1023), for
bogdanm 0:9b334a45a8ff 523 * alternate descriptor. The size of the DMA transfer element (1, 2 or 4 bytes)
bogdanm 0:9b334a45a8ff 524 * is configured with DMA_CfgDescr().
bogdanm 0:9b334a45a8ff 525 ******************************************************************************/
bogdanm 0:9b334a45a8ff 526 void DMA_ActivatePingPong(unsigned int channel,
bogdanm 0:9b334a45a8ff 527 bool useBurst,
bogdanm 0:9b334a45a8ff 528 void *primDst,
bogdanm 0:9b334a45a8ff 529 void *primSrc,
bogdanm 0:9b334a45a8ff 530 unsigned int primNMinus1,
bogdanm 0:9b334a45a8ff 531 void *altDst,
bogdanm 0:9b334a45a8ff 532 void *altSrc,
bogdanm 0:9b334a45a8ff 533 unsigned int altNMinus1)
bogdanm 0:9b334a45a8ff 534 {
bogdanm 0:9b334a45a8ff 535 EFM_ASSERT(channel < DMA_CHAN_COUNT);
bogdanm 0:9b334a45a8ff 536 EFM_ASSERT(primNMinus1 <= (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT));
bogdanm 0:9b334a45a8ff 537 EFM_ASSERT(altNMinus1 <= (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT));
bogdanm 0:9b334a45a8ff 538
bogdanm 0:9b334a45a8ff 539 /* Prepare alternate descriptor first */
bogdanm 0:9b334a45a8ff 540 DMA_Prepare(channel,
bogdanm 0:9b334a45a8ff 541 dmaCycleCtrlPingPong,
bogdanm 0:9b334a45a8ff 542 false,
bogdanm 0:9b334a45a8ff 543 useBurst,
bogdanm 0:9b334a45a8ff 544 altDst,
bogdanm 0:9b334a45a8ff 545 altSrc,
bogdanm 0:9b334a45a8ff 546 altNMinus1);
bogdanm 0:9b334a45a8ff 547
bogdanm 0:9b334a45a8ff 548 /* Prepare primary descriptor last in order to start cycle using it */
bogdanm 0:9b334a45a8ff 549 DMA_Prepare(channel,
bogdanm 0:9b334a45a8ff 550 dmaCycleCtrlPingPong,
bogdanm 0:9b334a45a8ff 551 true,
bogdanm 0:9b334a45a8ff 552 useBurst,
bogdanm 0:9b334a45a8ff 553 primDst,
bogdanm 0:9b334a45a8ff 554 primSrc,
bogdanm 0:9b334a45a8ff 555 primNMinus1);
bogdanm 0:9b334a45a8ff 556
bogdanm 0:9b334a45a8ff 557 /* Enable channel, request signal is provided by peripheral device */
bogdanm 0:9b334a45a8ff 558 DMA->CHENS = 1 << channel;
bogdanm 0:9b334a45a8ff 559 }
bogdanm 0:9b334a45a8ff 560
bogdanm 0:9b334a45a8ff 561
bogdanm 0:9b334a45a8ff 562 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 563 * @brief
bogdanm 0:9b334a45a8ff 564 * Activate DMA scatter-gather cycle (used for either memory-peripheral
bogdanm 0:9b334a45a8ff 565 * or memory-memory transfers).
bogdanm 0:9b334a45a8ff 566 *
bogdanm 0:9b334a45a8ff 567 * @details
bogdanm 0:9b334a45a8ff 568 * Prior to activating the DMA cycle, the array with alternate descriptors
bogdanm 0:9b334a45a8ff 569 * must have been properly configured. This function can be reused without
bogdanm 0:9b334a45a8ff 570 * reconfiguring the alternate descriptors, as long as @p count is the same.
bogdanm 0:9b334a45a8ff 571 *
bogdanm 0:9b334a45a8ff 572 * @note
bogdanm 0:9b334a45a8ff 573 * If using this function on a channel already activated and in use by the
bogdanm 0:9b334a45a8ff 574 * DMA controller, the behaviour is undefined.
bogdanm 0:9b334a45a8ff 575 *
bogdanm 0:9b334a45a8ff 576 * @param[in] channel
bogdanm 0:9b334a45a8ff 577 * DMA channel to activate DMA cycle for.
bogdanm 0:9b334a45a8ff 578 *
bogdanm 0:9b334a45a8ff 579 * @param[in] useBurst
bogdanm 0:9b334a45a8ff 580 * The burst feature is only used on peripherals supporting DMA bursts
bogdanm 0:9b334a45a8ff 581 * (and thus this parameter is ignored for memory scatter-gather cycles).
bogdanm 0:9b334a45a8ff 582 * This parameter determines if bursts should be enabled during DMA transfers
bogdanm 0:9b334a45a8ff 583 * using the alternate descriptors. Bursts must not be used if the total
bogdanm 0:9b334a45a8ff 584 * length (as given by nMinus1 for the alternate descriptor) is
bogdanm 0:9b334a45a8ff 585 * less than the arbitration rate configured for the descriptor. Please
bogdanm 0:9b334a45a8ff 586 * refer to the reference manual for further details on burst usage.
bogdanm 0:9b334a45a8ff 587 *
bogdanm 0:9b334a45a8ff 588 * @param[in,out] altDescr
bogdanm 0:9b334a45a8ff 589 * Pointer to start of array with prepared alternate descriptors. The last
bogdanm 0:9b334a45a8ff 590 * descriptor will have its cycle control type reprogrammed to basic type.
bogdanm 0:9b334a45a8ff 591 *
bogdanm 0:9b334a45a8ff 592 * @param[in] count
bogdanm 0:9b334a45a8ff 593 * Number of alternate descriptors in @p altDescr array. Maximum number of
bogdanm 0:9b334a45a8ff 594 * alternate descriptors is 256.
bogdanm 0:9b334a45a8ff 595 ******************************************************************************/
bogdanm 0:9b334a45a8ff 596 void DMA_ActivateScatterGather(unsigned int channel,
bogdanm 0:9b334a45a8ff 597 bool useBurst,
bogdanm 0:9b334a45a8ff 598 DMA_DESCRIPTOR_TypeDef *altDescr,
bogdanm 0:9b334a45a8ff 599 unsigned int count)
bogdanm 0:9b334a45a8ff 600 {
bogdanm 0:9b334a45a8ff 601 DMA_DESCRIPTOR_TypeDef *descr;
bogdanm 0:9b334a45a8ff 602 DMA_CB_TypeDef *cb;
bogdanm 0:9b334a45a8ff 603 uint32_t cycleCtrl;
bogdanm 0:9b334a45a8ff 604 uint32_t chBit;
bogdanm 0:9b334a45a8ff 605
bogdanm 0:9b334a45a8ff 606 EFM_ASSERT(channel < DMA_CHAN_COUNT);
bogdanm 0:9b334a45a8ff 607 EFM_ASSERT(altDescr);
bogdanm 0:9b334a45a8ff 608 EFM_ASSERT(count && (count <= 256));
bogdanm 0:9b334a45a8ff 609
bogdanm 0:9b334a45a8ff 610 /* We have to configure the primary descriptor properly in order to */
bogdanm 0:9b334a45a8ff 611 /* transfer one complete alternate descriptor from the alternate */
bogdanm 0:9b334a45a8ff 612 /* descriptor table into the actual alternate descriptor. */
bogdanm 0:9b334a45a8ff 613 descr = (DMA_DESCRIPTOR_TypeDef *)(DMA->CTRLBASE) + channel;
bogdanm 0:9b334a45a8ff 614
bogdanm 0:9b334a45a8ff 615 /* Set source end address to point to alternate descriptor array */
bogdanm 0:9b334a45a8ff 616 descr->SRCEND = (uint32_t *)altDescr + (count * 4) - 1;
bogdanm 0:9b334a45a8ff 617
bogdanm 0:9b334a45a8ff 618 /* The destination end address in the primary descriptor MUST point */
bogdanm 0:9b334a45a8ff 619 /* to the corresponding alternate descriptor in scatter-gather mode. */
bogdanm 0:9b334a45a8ff 620 descr->DSTEND = (uint32_t *)((DMA_DESCRIPTOR_TypeDef *)(DMA->ALTCTRLBASE) +
bogdanm 0:9b334a45a8ff 621 channel + 1) - 1;
bogdanm 0:9b334a45a8ff 622
bogdanm 0:9b334a45a8ff 623 /* The user field of the descriptor is used for callback configuration, */
bogdanm 0:9b334a45a8ff 624 /* and already configured when channel is configured. Do not modify it. */
bogdanm 0:9b334a45a8ff 625
bogdanm 0:9b334a45a8ff 626 /* Determine from alternate configuration whether this is a memory or */
bogdanm 0:9b334a45a8ff 627 /* peripheral scatter-gather, by looking at the first alternate descriptor. */
bogdanm 0:9b334a45a8ff 628 cycleCtrl = altDescr->CTRL & _DMA_CTRL_CYCLE_CTRL_MASK;
bogdanm 0:9b334a45a8ff 629 cycleCtrl &= ~(1 << _DMA_CTRL_CYCLE_CTRL_SHIFT);
bogdanm 0:9b334a45a8ff 630
mbed_official 50:a417edff4437 631 EFM_ASSERT((cycleCtrl == dmaCycleCtrlMemScatterGather)
mbed_official 50:a417edff4437 632 || (cycleCtrl == dmaCycleCtrlPerScatterGather));
bogdanm 0:9b334a45a8ff 633
bogdanm 0:9b334a45a8ff 634 /* Set last alternate descriptor to basic or auto-request cycle type in */
bogdanm 0:9b334a45a8ff 635 /* order to have dma_done signal asserted when complete. Otherwise interrupt */
bogdanm 0:9b334a45a8ff 636 /* will not be triggered when done. */
bogdanm 0:9b334a45a8ff 637 altDescr[count - 1].CTRL &= ~_DMA_CTRL_CYCLE_CTRL_MASK;
bogdanm 0:9b334a45a8ff 638 if (cycleCtrl == dmaCycleCtrlMemScatterGather)
bogdanm 0:9b334a45a8ff 639 {
mbed_official 50:a417edff4437 640 altDescr[count - 1].CTRL |= (uint32_t)dmaCycleCtrlAuto
mbed_official 50:a417edff4437 641 << _DMA_CTRL_CYCLE_CTRL_SHIFT;
bogdanm 0:9b334a45a8ff 642 }
bogdanm 0:9b334a45a8ff 643 else
bogdanm 0:9b334a45a8ff 644 {
mbed_official 50:a417edff4437 645 altDescr[count - 1].CTRL |= (uint32_t)dmaCycleCtrlBasic
mbed_official 50:a417edff4437 646 << _DMA_CTRL_CYCLE_CTRL_SHIFT;
bogdanm 0:9b334a45a8ff 647 }
bogdanm 0:9b334a45a8ff 648
bogdanm 0:9b334a45a8ff 649 /* If callback defined, update info on whether callback is issued for */
bogdanm 0:9b334a45a8ff 650 /* primary or alternate descriptor. Not really useful for scatter-gather, */
bogdanm 0:9b334a45a8ff 651 /* but do for consistency. Always set to alternate, since that is the last */
bogdanm 0:9b334a45a8ff 652 /* descriptor actually used. */
bogdanm 0:9b334a45a8ff 653 cb = (DMA_CB_TypeDef *)(descr->USER);
bogdanm 0:9b334a45a8ff 654 if (cb)
bogdanm 0:9b334a45a8ff 655 {
bogdanm 0:9b334a45a8ff 656 cb->primary = false;
bogdanm 0:9b334a45a8ff 657 }
bogdanm 0:9b334a45a8ff 658
bogdanm 0:9b334a45a8ff 659 /* Configure primary descriptor control word */
mbed_official 50:a417edff4437 660 descr->CTRL =((uint32_t)dmaDataInc4 << _DMA_CTRL_DST_INC_SHIFT)
mbed_official 50:a417edff4437 661 | ((uint32_t)dmaDataSize4 << _DMA_CTRL_DST_SIZE_SHIFT)
mbed_official 50:a417edff4437 662 | ((uint32_t)dmaDataInc4 << _DMA_CTRL_SRC_INC_SHIFT)
mbed_official 50:a417edff4437 663 | ((uint32_t)dmaDataSize4 << _DMA_CTRL_SRC_SIZE_SHIFT)
mbed_official 50:a417edff4437 664 /* Use same protection scheme as for alternate descriptors */
mbed_official 50:a417edff4437 665 | (altDescr->CTRL & _DMA_CTRL_SRC_PROT_CTRL_MASK)
mbed_official 50:a417edff4437 666 | ((uint32_t)dmaArbitrate4 << _DMA_CTRL_R_POWER_SHIFT)
mbed_official 50:a417edff4437 667 | (((count * 4) - 1) << _DMA_CTRL_N_MINUS_1_SHIFT)
mbed_official 50:a417edff4437 668 | (((uint32_t)useBurst & 1) << _DMA_CTRL_NEXT_USEBURST_SHIFT)
mbed_official 50:a417edff4437 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);
mbed_official 50:a417edff4437 734 BUS_RegBitWrite(&(DMA->IEN), channel, 1);
bogdanm 0:9b334a45a8ff 735 }
bogdanm 0:9b334a45a8ff 736 else
bogdanm 0:9b334a45a8ff 737 {
mbed_official 50:a417edff4437 738 BUS_RegBitWrite(&(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 */
mbed_official 50:a417edff4437 803 descr->CTRL = (cfg->dstInc << _DMA_CTRL_DST_INC_SHIFT)
mbed_official 50:a417edff4437 804 | (cfg->size << _DMA_CTRL_DST_SIZE_SHIFT)
mbed_official 50:a417edff4437 805 | (cfg->srcInc << _DMA_CTRL_SRC_INC_SHIFT)
mbed_official 50:a417edff4437 806 | (cfg->size << _DMA_CTRL_SRC_SIZE_SHIFT)
mbed_official 50:a417edff4437 807 | ((uint32_t)(cfg->hprot) << _DMA_CTRL_SRC_PROT_CTRL_SHIFT)
mbed_official 50:a417edff4437 808 | (cfg->arbRate << _DMA_CTRL_R_POWER_SHIFT)
mbed_official 50:a417edff4437 809 | (0 << _DMA_CTRL_N_MINUS_1_SHIFT) /* Set when activated */
mbed_official 50:a417edff4437 810 | (0 << _DMA_CTRL_NEXT_USEBURST_SHIFT) /* Set when activated */
mbed_official 50:a417edff4437 811 | DMA_CTRL_CYCLE_CTRL_INVALID; /* Set when activated */
bogdanm 0:9b334a45a8ff 812 }
bogdanm 0:9b334a45a8ff 813
bogdanm 0:9b334a45a8ff 814
bogdanm 0:9b334a45a8ff 815 #if defined( _DMA_LOOP0_MASK ) && defined( _DMA_LOOP1_MASK )
bogdanm 0:9b334a45a8ff 816 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 817 * @brief Configure DMA channel for Loop mode or 2D transfer.
bogdanm 0:9b334a45a8ff 818 *
bogdanm 0:9b334a45a8ff 819 * @details
bogdanm 0:9b334a45a8ff 820 * For 2D transfer, set cfg->enable to "false", and only configure nMinus1
bogdanm 0:9b334a45a8ff 821 * to same width as channel descriptor.
bogdanm 0:9b334a45a8ff 822 *
bogdanm 0:9b334a45a8ff 823 * @param[in] channel
bogdanm 0:9b334a45a8ff 824 * DMA channel to configure for.
bogdanm 0:9b334a45a8ff 825 *
bogdanm 0:9b334a45a8ff 826 * @param[in] cfg
bogdanm 0:9b334a45a8ff 827 * Configuration to use.
bogdanm 0:9b334a45a8ff 828 ******************************************************************************/
bogdanm 0:9b334a45a8ff 829 void DMA_CfgLoop(unsigned int channel, DMA_CfgLoop_TypeDef *cfg)
bogdanm 0:9b334a45a8ff 830 {
bogdanm 0:9b334a45a8ff 831 EFM_ASSERT(channel <= 1);
bogdanm 0:9b334a45a8ff 832 EFM_ASSERT(cfg->nMinus1 <= 1023);
bogdanm 0:9b334a45a8ff 833
bogdanm 0:9b334a45a8ff 834 /* Configure LOOP setting */
bogdanm 0:9b334a45a8ff 835 switch( channel )
bogdanm 0:9b334a45a8ff 836 {
bogdanm 0:9b334a45a8ff 837 case 0:
mbed_official 50:a417edff4437 838 DMA->LOOP0 = (cfg->enable << _DMA_LOOP0_EN_SHIFT)
mbed_official 50:a417edff4437 839 | (cfg->nMinus1 << _DMA_LOOP0_WIDTH_SHIFT);
bogdanm 0:9b334a45a8ff 840 break;
bogdanm 0:9b334a45a8ff 841 case 1:
mbed_official 50:a417edff4437 842 DMA->LOOP1 = (cfg->enable << _DMA_LOOP1_EN_SHIFT)
mbed_official 50:a417edff4437 843 | (cfg->nMinus1 << _DMA_LOOP1_WIDTH_SHIFT);
bogdanm 0:9b334a45a8ff 844 break;
bogdanm 0:9b334a45a8ff 845 }
bogdanm 0:9b334a45a8ff 846 }
bogdanm 0:9b334a45a8ff 847 #endif
bogdanm 0:9b334a45a8ff 848
bogdanm 0:9b334a45a8ff 849
bogdanm 0:9b334a45a8ff 850 #if defined( _DMA_RECT0_MASK )
bogdanm 0:9b334a45a8ff 851 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 852 * @brief Configure DMA channel 2D transfer properties.
bogdanm 0:9b334a45a8ff 853 *
bogdanm 0:9b334a45a8ff 854 * @param[in] channel
bogdanm 0:9b334a45a8ff 855 * DMA channel to configure for.
bogdanm 0:9b334a45a8ff 856 *
bogdanm 0:9b334a45a8ff 857 * @param[in] cfg
bogdanm 0:9b334a45a8ff 858 * Configuration to use.
bogdanm 0:9b334a45a8ff 859 ******************************************************************************/
bogdanm 0:9b334a45a8ff 860 void DMA_CfgRect(unsigned int channel, DMA_CfgRect_TypeDef *cfg)
bogdanm 0:9b334a45a8ff 861 {
bogdanm 0:9b334a45a8ff 862 (void)channel; /* Unused parameter */
bogdanm 0:9b334a45a8ff 863
bogdanm 0:9b334a45a8ff 864 EFM_ASSERT(channel == 0);
bogdanm 0:9b334a45a8ff 865 EFM_ASSERT(cfg->dstStride <= 2047);
bogdanm 0:9b334a45a8ff 866 EFM_ASSERT(cfg->srcStride <= 2047);
bogdanm 0:9b334a45a8ff 867 EFM_ASSERT(cfg->height <= 1023);
bogdanm 0:9b334a45a8ff 868
bogdanm 0:9b334a45a8ff 869 /* Configure rectangular/2D copy */
mbed_official 50:a417edff4437 870 DMA->RECT0 = (cfg->dstStride << _DMA_RECT0_DSTSTRIDE_SHIFT)
mbed_official 50:a417edff4437 871 | (cfg->srcStride << _DMA_RECT0_SRCSTRIDE_SHIFT)
mbed_official 50:a417edff4437 872 | (cfg->height << _DMA_RECT0_HEIGHT_SHIFT);
bogdanm 0:9b334a45a8ff 873 }
bogdanm 0:9b334a45a8ff 874 #endif
bogdanm 0:9b334a45a8ff 875
bogdanm 0:9b334a45a8ff 876
bogdanm 0:9b334a45a8ff 877 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 878 * @brief
bogdanm 0:9b334a45a8ff 879 * Configure an alternate DMA descriptor for use with scatter-gather DMA
bogdanm 0:9b334a45a8ff 880 * cycles.
bogdanm 0:9b334a45a8ff 881 *
bogdanm 0:9b334a45a8ff 882 * @details
bogdanm 0:9b334a45a8ff 883 * In scatter-gather mode, the alternate descriptors are located in one
bogdanm 0:9b334a45a8ff 884 * contiguous memory area. Each of the alternate descriptor must be fully
bogdanm 0:9b334a45a8ff 885 * configured prior to starting the scatter-gather DMA cycle.
bogdanm 0:9b334a45a8ff 886 *
bogdanm 0:9b334a45a8ff 887 * The DMA cycle is not activated by this function, please see
bogdanm 0:9b334a45a8ff 888 * DMA_ActivateScatterGather() to activate the DMA cycle. In some cases, the
bogdanm 0:9b334a45a8ff 889 * alternate configuration only has to be done once, and all subsequent
bogdanm 0:9b334a45a8ff 890 * transfers may be activated with the activate function.
bogdanm 0:9b334a45a8ff 891 *
bogdanm 0:9b334a45a8ff 892 * Notice that the DMA channel must also be configured, see DMA_CfgChannel().
bogdanm 0:9b334a45a8ff 893 *
bogdanm 0:9b334a45a8ff 894 * @param[in] descr
bogdanm 0:9b334a45a8ff 895 * Points to start of memory area holding the alternate descriptors.
bogdanm 0:9b334a45a8ff 896 *
bogdanm 0:9b334a45a8ff 897 * @param[in] indx
bogdanm 0:9b334a45a8ff 898 * Alternate descriptor index number to configure (numbered from 0).
bogdanm 0:9b334a45a8ff 899 *
bogdanm 0:9b334a45a8ff 900 * @param[in] cfg
bogdanm 0:9b334a45a8ff 901 * Configuration to use.
bogdanm 0:9b334a45a8ff 902 ******************************************************************************/
bogdanm 0:9b334a45a8ff 903 void DMA_CfgDescrScatterGather(DMA_DESCRIPTOR_TypeDef *descr,
bogdanm 0:9b334a45a8ff 904 unsigned int indx,
bogdanm 0:9b334a45a8ff 905 DMA_CfgDescrSGAlt_TypeDef *cfg)
bogdanm 0:9b334a45a8ff 906 {
bogdanm 0:9b334a45a8ff 907 uint32_t cycleCtrl;
bogdanm 0:9b334a45a8ff 908
bogdanm 0:9b334a45a8ff 909 EFM_ASSERT(descr);
bogdanm 0:9b334a45a8ff 910 EFM_ASSERT(cfg);
bogdanm 0:9b334a45a8ff 911
bogdanm 0:9b334a45a8ff 912 /* Point to selected entry in alternate descriptor table */
bogdanm 0:9b334a45a8ff 913 descr += indx;
bogdanm 0:9b334a45a8ff 914
bogdanm 0:9b334a45a8ff 915 if (cfg->srcInc == dmaDataIncNone)
bogdanm 0:9b334a45a8ff 916 {
bogdanm 0:9b334a45a8ff 917 descr->SRCEND = cfg->src;
bogdanm 0:9b334a45a8ff 918 }
bogdanm 0:9b334a45a8ff 919 else
bogdanm 0:9b334a45a8ff 920 {
mbed_official 50:a417edff4437 921 descr->SRCEND = (void *)((uint32_t)(cfg->src)
mbed_official 50:a417edff4437 922 + ((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 {
mbed_official 50:a417edff4437 931 descr->DSTEND = (void *)((uint32_t)(cfg->dst)
mbed_official 50:a417edff4437 932 + ((uint32_t)(cfg->nMinus1) << cfg->dstInc));
bogdanm 0:9b334a45a8ff 933 }
bogdanm 0:9b334a45a8ff 934
bogdanm 0:9b334a45a8ff 935 /* User definable part not used */
bogdanm 0:9b334a45a8ff 936 descr->USER = 0;
bogdanm 0:9b334a45a8ff 937
bogdanm 0:9b334a45a8ff 938 if (cfg->peripheral)
bogdanm 0:9b334a45a8ff 939 {
bogdanm 0:9b334a45a8ff 940 cycleCtrl = (uint32_t)dmaCycleCtrlPerScatterGather + 1;
bogdanm 0:9b334a45a8ff 941 }
bogdanm 0:9b334a45a8ff 942 else
bogdanm 0:9b334a45a8ff 943 {
bogdanm 0:9b334a45a8ff 944 cycleCtrl = (uint32_t)dmaCycleCtrlMemScatterGather + 1;
bogdanm 0:9b334a45a8ff 945 }
bogdanm 0:9b334a45a8ff 946
mbed_official 50:a417edff4437 947 descr->CTRL =(cfg->dstInc << _DMA_CTRL_DST_INC_SHIFT)
mbed_official 50:a417edff4437 948 | (cfg->size << _DMA_CTRL_DST_SIZE_SHIFT)
mbed_official 50:a417edff4437 949 | (cfg->srcInc << _DMA_CTRL_SRC_INC_SHIFT)
mbed_official 50:a417edff4437 950 | (cfg->size << _DMA_CTRL_SRC_SIZE_SHIFT)
mbed_official 50:a417edff4437 951 | ((uint32_t)(cfg->hprot) << _DMA_CTRL_SRC_PROT_CTRL_SHIFT)
mbed_official 50:a417edff4437 952 | (cfg->arbRate << _DMA_CTRL_R_POWER_SHIFT)
mbed_official 50:a417edff4437 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. */
mbed_official 50:a417edff4437 958 | (0 << _DMA_CTRL_NEXT_USEBURST_SHIFT)
mbed_official 50:a417edff4437 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 */
mbed_official 50:a417edff4437 1065 DMA->CONFIG = ((uint32_t)(init->hprot) << _DMA_CONFIG_CHPROT_SHIFT)
mbed_official 50:a417edff4437 1066 | DMA_CONFIG_EN;
bogdanm 0:9b334a45a8ff 1067 }
bogdanm 0:9b334a45a8ff 1068
bogdanm 0:9b334a45a8ff 1069
bogdanm 0:9b334a45a8ff 1070 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 1071 * @brief
bogdanm 0:9b334a45a8ff 1072 * Refresh a descriptor used in a DMA ping-pong cycle.
bogdanm 0:9b334a45a8ff 1073 *
bogdanm 0:9b334a45a8ff 1074 * @details
bogdanm 0:9b334a45a8ff 1075 * During a ping-pong DMA cycle, the DMA controller automatically alternates
bogdanm 0:9b334a45a8ff 1076 * between primary and alternate descriptors, when completing use of a
bogdanm 0:9b334a45a8ff 1077 * descriptor. While the other descriptor is in use by the DMA controller,
bogdanm 0:9b334a45a8ff 1078 * the SW should refresh the completed descriptor. This is typically done from
bogdanm 0:9b334a45a8ff 1079 * the callback defined for the ping-pong cycle.
bogdanm 0:9b334a45a8ff 1080 *
bogdanm 0:9b334a45a8ff 1081 * @param[in] channel
bogdanm 0:9b334a45a8ff 1082 * DMA channel to refresh ping-pong descriptor for.
bogdanm 0:9b334a45a8ff 1083 *
bogdanm 0:9b334a45a8ff 1084 * @param[in] primary
bogdanm 0:9b334a45a8ff 1085 * @li true - refresh primary descriptor
bogdanm 0:9b334a45a8ff 1086 * @li false - refresh alternate descriptor
bogdanm 0:9b334a45a8ff 1087 *
bogdanm 0:9b334a45a8ff 1088 * @param[in] useBurst
bogdanm 0:9b334a45a8ff 1089 * The burst feature is only used on peripherals supporting DMA bursts.
bogdanm 0:9b334a45a8ff 1090 * Bursts must not be used if the total length (as given by nMinus1) is
bogdanm 0:9b334a45a8ff 1091 * less than the arbitration rate configured for the descriptor. Please
bogdanm 0:9b334a45a8ff 1092 * refer to the reference manual for further details on burst usage.
bogdanm 0:9b334a45a8ff 1093 *
bogdanm 0:9b334a45a8ff 1094 * @param[in] dst
bogdanm 0:9b334a45a8ff 1095 * Address to start location to transfer data to. If NULL, leave setting in
bogdanm 0:9b334a45a8ff 1096 * descriptor as is.
bogdanm 0:9b334a45a8ff 1097 *
bogdanm 0:9b334a45a8ff 1098 * @param[in] src
bogdanm 0:9b334a45a8ff 1099 * Address to start location to transfer data from. If NULL, leave setting in
bogdanm 0:9b334a45a8ff 1100 * descriptor as is.
bogdanm 0:9b334a45a8ff 1101 *
bogdanm 0:9b334a45a8ff 1102 * @param[in] nMinus1
bogdanm 0:9b334a45a8ff 1103 * Number of DMA transfer elements (minus 1) to transfer (<= 1023). The
bogdanm 0:9b334a45a8ff 1104 * size of the DMA transfer element (1, 2 or 4 bytes) is configured with
bogdanm 0:9b334a45a8ff 1105 * DMA_CfgDescr().
bogdanm 0:9b334a45a8ff 1106 *
bogdanm 0:9b334a45a8ff 1107 * @param[in] stop
bogdanm 0:9b334a45a8ff 1108 * Indicate that the DMA ping-pong cycle shall stop @b after completing use
bogdanm 0:9b334a45a8ff 1109 * of this descriptor.
bogdanm 0:9b334a45a8ff 1110 ******************************************************************************/
bogdanm 0:9b334a45a8ff 1111 void DMA_RefreshPingPong(unsigned int channel,
bogdanm 0:9b334a45a8ff 1112 bool primary,
bogdanm 0:9b334a45a8ff 1113 bool useBurst,
bogdanm 0:9b334a45a8ff 1114 void *dst,
bogdanm 0:9b334a45a8ff 1115 void *src,
bogdanm 0:9b334a45a8ff 1116 unsigned int nMinus1,
bogdanm 0:9b334a45a8ff 1117 bool stop)
bogdanm 0:9b334a45a8ff 1118 {
bogdanm 0:9b334a45a8ff 1119 DMA_CycleCtrl_TypeDef cycleCtrl;
bogdanm 0:9b334a45a8ff 1120 DMA_DESCRIPTOR_TypeDef *descr;
bogdanm 0:9b334a45a8ff 1121 uint32_t inc;
bogdanm 0:9b334a45a8ff 1122 uint32_t chBit;
bogdanm 0:9b334a45a8ff 1123 uint32_t tmp;
bogdanm 0:9b334a45a8ff 1124
bogdanm 0:9b334a45a8ff 1125 EFM_ASSERT(channel < DMA_CHAN_COUNT);
bogdanm 0:9b334a45a8ff 1126 EFM_ASSERT(nMinus1 <= (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT));
bogdanm 0:9b334a45a8ff 1127
bogdanm 0:9b334a45a8ff 1128 /* The ping-pong DMA cycle may be stopped by issuing a basic cycle type */
bogdanm 0:9b334a45a8ff 1129 if (stop)
bogdanm 0:9b334a45a8ff 1130 {
bogdanm 0:9b334a45a8ff 1131 cycleCtrl = dmaCycleCtrlBasic;
bogdanm 0:9b334a45a8ff 1132 }
bogdanm 0:9b334a45a8ff 1133 else
bogdanm 0:9b334a45a8ff 1134 {
bogdanm 0:9b334a45a8ff 1135 cycleCtrl = dmaCycleCtrlPingPong;
bogdanm 0:9b334a45a8ff 1136 }
bogdanm 0:9b334a45a8ff 1137
bogdanm 0:9b334a45a8ff 1138 /* Find descriptor to configure */
bogdanm 0:9b334a45a8ff 1139 if (primary)
bogdanm 0:9b334a45a8ff 1140 {
bogdanm 0:9b334a45a8ff 1141 descr = ((DMA_DESCRIPTOR_TypeDef *)(DMA->CTRLBASE)) + channel;
bogdanm 0:9b334a45a8ff 1142 }
bogdanm 0:9b334a45a8ff 1143 else
bogdanm 0:9b334a45a8ff 1144 {
bogdanm 0:9b334a45a8ff 1145 descr = ((DMA_DESCRIPTOR_TypeDef *)(DMA->ALTCTRLBASE)) + channel;
bogdanm 0:9b334a45a8ff 1146 }
bogdanm 0:9b334a45a8ff 1147
bogdanm 0:9b334a45a8ff 1148 if (src)
bogdanm 0:9b334a45a8ff 1149 {
bogdanm 0:9b334a45a8ff 1150 inc = (descr->CTRL & _DMA_CTRL_SRC_INC_MASK) >> _DMA_CTRL_SRC_INC_SHIFT;
bogdanm 0:9b334a45a8ff 1151 if (inc == _DMA_CTRL_SRC_INC_NONE)
bogdanm 0:9b334a45a8ff 1152 {
bogdanm 0:9b334a45a8ff 1153 descr->SRCEND = src;
bogdanm 0:9b334a45a8ff 1154 }
bogdanm 0:9b334a45a8ff 1155 else
bogdanm 0:9b334a45a8ff 1156 {
bogdanm 0:9b334a45a8ff 1157 descr->SRCEND = (void *)((uint32_t)src + (nMinus1 << inc));
bogdanm 0:9b334a45a8ff 1158 }
bogdanm 0:9b334a45a8ff 1159 }
bogdanm 0:9b334a45a8ff 1160
bogdanm 0:9b334a45a8ff 1161 if (dst)
bogdanm 0:9b334a45a8ff 1162 {
bogdanm 0:9b334a45a8ff 1163 inc = (descr->CTRL & _DMA_CTRL_DST_INC_MASK) >> _DMA_CTRL_DST_INC_SHIFT;
bogdanm 0:9b334a45a8ff 1164 if (inc == _DMA_CTRL_DST_INC_NONE)
bogdanm 0:9b334a45a8ff 1165 {
bogdanm 0:9b334a45a8ff 1166 descr->DSTEND = dst;
bogdanm 0:9b334a45a8ff 1167 }
bogdanm 0:9b334a45a8ff 1168 else
bogdanm 0:9b334a45a8ff 1169 {
bogdanm 0:9b334a45a8ff 1170 descr->DSTEND = (void *)((uint32_t)dst + (nMinus1 << inc));
bogdanm 0:9b334a45a8ff 1171 }
bogdanm 0:9b334a45a8ff 1172 }
bogdanm 0:9b334a45a8ff 1173
bogdanm 0:9b334a45a8ff 1174 chBit = 1 << channel;
bogdanm 0:9b334a45a8ff 1175 if (useBurst)
bogdanm 0:9b334a45a8ff 1176 {
bogdanm 0:9b334a45a8ff 1177 DMA->CHUSEBURSTS = chBit;
bogdanm 0:9b334a45a8ff 1178 }
bogdanm 0:9b334a45a8ff 1179 else
bogdanm 0:9b334a45a8ff 1180 {
bogdanm 0:9b334a45a8ff 1181 DMA->CHUSEBURSTC = chBit;
bogdanm 0:9b334a45a8ff 1182 }
bogdanm 0:9b334a45a8ff 1183
bogdanm 0:9b334a45a8ff 1184 /* Set cycle control */
mbed_official 50:a417edff4437 1185 tmp = descr->CTRL & ~(_DMA_CTRL_CYCLE_CTRL_MASK | _DMA_CTRL_N_MINUS_1_MASK);
mbed_official 50:a417edff4437 1186 tmp |= nMinus1 << _DMA_CTRL_N_MINUS_1_SHIFT;
mbed_official 50:a417edff4437 1187 tmp |= cycleCtrl << _DMA_CTRL_CYCLE_CTRL_SHIFT;
bogdanm 0:9b334a45a8ff 1188 descr->CTRL = tmp;
bogdanm 0:9b334a45a8ff 1189 }
bogdanm 0:9b334a45a8ff 1190
bogdanm 0:9b334a45a8ff 1191
bogdanm 0:9b334a45a8ff 1192 /***************************************************************************//**
bogdanm 0:9b334a45a8ff 1193 * @brief
bogdanm 0:9b334a45a8ff 1194 * Reset the DMA controller.
bogdanm 0:9b334a45a8ff 1195 *
bogdanm 0:9b334a45a8ff 1196 * @details
bogdanm 0:9b334a45a8ff 1197 * This functions will disable the DMA controller and set it to a reset
bogdanm 0:9b334a45a8ff 1198 * state.
bogdanm 0:9b334a45a8ff 1199 *
bogdanm 0:9b334a45a8ff 1200 * @note
bogdanm 0:9b334a45a8ff 1201 * Notice that any ongoing transfers will be aborted.
bogdanm 0:9b334a45a8ff 1202 ******************************************************************************/
bogdanm 0:9b334a45a8ff 1203 void DMA_Reset(void)
bogdanm 0:9b334a45a8ff 1204 {
bogdanm 0:9b334a45a8ff 1205 int i;
bogdanm 0:9b334a45a8ff 1206
bogdanm 0:9b334a45a8ff 1207 /* Disable DMA interrupts */
bogdanm 0:9b334a45a8ff 1208 NVIC_DisableIRQ(DMA_IRQn);
bogdanm 0:9b334a45a8ff 1209
bogdanm 0:9b334a45a8ff 1210 /* Put the DMA controller into a known state, first disabling it. */
bogdanm 0:9b334a45a8ff 1211 DMA->CONFIG = _DMA_CONFIG_RESETVALUE;
bogdanm 0:9b334a45a8ff 1212 DMA->CHUSEBURSTC = _DMA_CHUSEBURSTC_MASK;
bogdanm 0:9b334a45a8ff 1213 DMA->CHREQMASKC = _DMA_CHREQMASKC_MASK;
bogdanm 0:9b334a45a8ff 1214 DMA->CHENC = _DMA_CHENC_MASK;
bogdanm 0:9b334a45a8ff 1215 DMA->CHALTC = _DMA_CHALTC_MASK;
bogdanm 0:9b334a45a8ff 1216 DMA->CHPRIC = _DMA_CHPRIC_MASK;
bogdanm 0:9b334a45a8ff 1217 DMA->ERRORC = DMA_ERRORC_ERRORC;
bogdanm 0:9b334a45a8ff 1218 DMA->IEN = _DMA_IEN_RESETVALUE;
bogdanm 0:9b334a45a8ff 1219 DMA->IFC = _DMA_IFC_MASK;
bogdanm 0:9b334a45a8ff 1220
bogdanm 0:9b334a45a8ff 1221 /* Clear channel control flags */
bogdanm 0:9b334a45a8ff 1222 for (i = 0; i < DMA_CHAN_COUNT; i++)
bogdanm 0:9b334a45a8ff 1223 {
bogdanm 0:9b334a45a8ff 1224 DMA->CH[i].CTRL = _DMA_CH_CTRL_RESETVALUE;
bogdanm 0:9b334a45a8ff 1225 }
bogdanm 0:9b334a45a8ff 1226 }
bogdanm 0:9b334a45a8ff 1227
bogdanm 0:9b334a45a8ff 1228
bogdanm 0:9b334a45a8ff 1229 /** @} (end addtogroup DMA) */
bogdanm 0:9b334a45a8ff 1230 /** @} (end addtogroup EM_Library) */
bogdanm 0:9b334a45a8ff 1231 #endif /* defined( DMA_PRESENT ) */