mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
<>
Date:
Fri Oct 28 11:17:30 2016 +0100
Revision:
149:156823d33999
Parent:
targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/dma_api.c@144:ef7eb2e8f9f7
This updates the lib to the mbed lib v128

NOTE: This release includes a restructuring of the file and directory locations and thus some
include paths in your code may need updating accordingly.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 2 * @file dma_api.c
<> 144:ef7eb2e8f9f7 3 *******************************************************************************
<> 144:ef7eb2e8f9f7 4 * @section License
<> 144:ef7eb2e8f9f7 5 * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>
<> 144:ef7eb2e8f9f7 6 *******************************************************************************
<> 144:ef7eb2e8f9f7 7 *
<> 144:ef7eb2e8f9f7 8 * SPDX-License-Identifier: Apache-2.0
<> 144:ef7eb2e8f9f7 9 *
<> 144:ef7eb2e8f9f7 10 * Licensed under the Apache License, Version 2.0 (the "License"); you may
<> 144:ef7eb2e8f9f7 11 * not use this file except in compliance with the License.
<> 144:ef7eb2e8f9f7 12 * You may obtain a copy of the License at
<> 144:ef7eb2e8f9f7 13 *
<> 144:ef7eb2e8f9f7 14 * http://www.apache.org/licenses/LICENSE-2.0
<> 144:ef7eb2e8f9f7 15 *
<> 144:ef7eb2e8f9f7 16 * Unless required by applicable law or agreed to in writing, software
<> 144:ef7eb2e8f9f7 17 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
<> 144:ef7eb2e8f9f7 18 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
<> 144:ef7eb2e8f9f7 19 * See the License for the specific language governing permissions and
<> 144:ef7eb2e8f9f7 20 * limitations under the License.
<> 144:ef7eb2e8f9f7 21 *
<> 144:ef7eb2e8f9f7 22 ******************************************************************************/
<> 144:ef7eb2e8f9f7 23
<> 144:ef7eb2e8f9f7 24 #include <stdint.h>
<> 144:ef7eb2e8f9f7 25 #include "dma_api_HAL.h"
<> 144:ef7eb2e8f9f7 26 #include "em_device.h"
<> 144:ef7eb2e8f9f7 27 #include "em_cmu.h"
<> 144:ef7eb2e8f9f7 28
<> 144:ef7eb2e8f9f7 29 #ifdef DMA_PRESENT
<> 144:ef7eb2e8f9f7 30 #include "em_dma.h"
<> 144:ef7eb2e8f9f7 31 #endif
<> 144:ef7eb2e8f9f7 32
<> 144:ef7eb2e8f9f7 33 #ifdef LDMA_PRESENT
<> 144:ef7eb2e8f9f7 34 #include "em_ldma.h"
<> 144:ef7eb2e8f9f7 35 #endif
<> 144:ef7eb2e8f9f7 36
<> 144:ef7eb2e8f9f7 37 /** DMA control block array, requires proper alignment. */
<> 144:ef7eb2e8f9f7 38 #ifdef DMA_PRESENT
<> 144:ef7eb2e8f9f7 39 #if defined (__ICCARM__)
<> 144:ef7eb2e8f9f7 40 #pragma data_alignment=DMACTRL_ALIGNMENT
<> 144:ef7eb2e8f9f7 41 DMA_DESCRIPTOR_TypeDef dmaControlBlock[DMACTRL_CH_CNT * 2];
<> 144:ef7eb2e8f9f7 42
<> 144:ef7eb2e8f9f7 43 #elif defined (__CC_ARM)
<> 144:ef7eb2e8f9f7 44 DMA_DESCRIPTOR_TypeDef dmaControlBlock[DMACTRL_CH_CNT * 2] __attribute__ ((aligned(DMACTRL_ALIGNMENT)));
<> 144:ef7eb2e8f9f7 45
<> 144:ef7eb2e8f9f7 46 #elif defined (__GNUC__)
<> 144:ef7eb2e8f9f7 47 DMA_DESCRIPTOR_TypeDef dmaControlBlock[DMACTRL_CH_CNT * 2] __attribute__ ((aligned(DMACTRL_ALIGNMENT), section("dma")));
<> 144:ef7eb2e8f9f7 48
<> 144:ef7eb2e8f9f7 49 #else
<> 144:ef7eb2e8f9f7 50 #error Undefined toolkit, need to define alignment
<> 144:ef7eb2e8f9f7 51 #endif
<> 144:ef7eb2e8f9f7 52 #endif /* DMA_PRESENT */
<> 144:ef7eb2e8f9f7 53
<> 144:ef7eb2e8f9f7 54 uint32_t channels = 0; // Bit vector of taken channels
<> 144:ef7eb2e8f9f7 55 bool enabled = false;
<> 144:ef7eb2e8f9f7 56
<> 144:ef7eb2e8f9f7 57 void dma_init(void)
<> 144:ef7eb2e8f9f7 58 {
<> 144:ef7eb2e8f9f7 59 if (enabled) return;
<> 144:ef7eb2e8f9f7 60
<> 144:ef7eb2e8f9f7 61 #if defined DMA_PRESENT
<> 144:ef7eb2e8f9f7 62 CMU_ClockEnable(cmuClock_DMA, true);
<> 144:ef7eb2e8f9f7 63 CMU_ClockEnable(cmuClock_HFPER, true); // FIXME: DMA is clocked via HFCORECLK, why HFPERCLK?
<> 144:ef7eb2e8f9f7 64
<> 144:ef7eb2e8f9f7 65 DMA_Init_TypeDef dmaInit;
<> 144:ef7eb2e8f9f7 66
<> 144:ef7eb2e8f9f7 67 dmaInit.hprot = 0;
<> 144:ef7eb2e8f9f7 68 dmaInit.controlBlock = dmaControlBlock;
<> 144:ef7eb2e8f9f7 69 DMA_Init(&dmaInit);
<> 144:ef7eb2e8f9f7 70
<> 144:ef7eb2e8f9f7 71 #elif defined LDMA_PRESENT
<> 144:ef7eb2e8f9f7 72 CMU_ClockEnable(cmuClock_LDMA, true);
<> 144:ef7eb2e8f9f7 73
<> 144:ef7eb2e8f9f7 74 LDMA_Init_t ldmaInit;
<> 144:ef7eb2e8f9f7 75
<> 144:ef7eb2e8f9f7 76 ldmaInit.ldmaInitCtrlNumFixed = 0; /* All channels round-robin */
<> 144:ef7eb2e8f9f7 77 ldmaInit.ldmaInitCtrlSyncPrsClrEn = 0; /* Do not allow PRS to clear SYNCTRIG */
<> 144:ef7eb2e8f9f7 78 ldmaInit.ldmaInitCtrlSyncPrsSetEn = 0; /* Do not allow PRS to set SYNCTRIG */
<> 144:ef7eb2e8f9f7 79 ldmaInit.ldmaInitIrqPriority = 2; /* IRQ Priority */
<> 144:ef7eb2e8f9f7 80
<> 144:ef7eb2e8f9f7 81 LDMA_Init(&ldmaInit);
<> 144:ef7eb2e8f9f7 82 #else
<> 144:ef7eb2e8f9f7 83 #error "Unrecognized DMA peripheral"
<> 144:ef7eb2e8f9f7 84 #endif
<> 144:ef7eb2e8f9f7 85
<> 144:ef7eb2e8f9f7 86 enabled = true;
<> 144:ef7eb2e8f9f7 87 }
<> 144:ef7eb2e8f9f7 88
<> 144:ef7eb2e8f9f7 89 int dma_channel_allocate(uint32_t capabilities)
<> 144:ef7eb2e8f9f7 90 {
<> 144:ef7eb2e8f9f7 91 int i;
<> 144:ef7eb2e8f9f7 92 // Check if 2d copy is required
<> 144:ef7eb2e8f9f7 93 if (DMA_CAP_2DCOPY & capabilities) {
<> 144:ef7eb2e8f9f7 94 if (channels & 1) {
<> 144:ef7eb2e8f9f7 95 // Channel already in use
<> 144:ef7eb2e8f9f7 96 return DMA_ERROR_OUT_OF_CHANNELS;
<> 144:ef7eb2e8f9f7 97 } else {
<> 144:ef7eb2e8f9f7 98 channels |= 1 << 0;
<> 144:ef7eb2e8f9f7 99 return 0;
<> 144:ef7eb2e8f9f7 100 }
<> 144:ef7eb2e8f9f7 101 }
<> 144:ef7eb2e8f9f7 102 for (i = 1; i < DMA_CHAN_COUNT; i++) {
<> 144:ef7eb2e8f9f7 103 if ((channels & (1 << i)) == 0) {
<> 144:ef7eb2e8f9f7 104 // Channel available
<> 144:ef7eb2e8f9f7 105 channels |= 1 << i;
<> 144:ef7eb2e8f9f7 106 return i;
<> 144:ef7eb2e8f9f7 107 }
<> 144:ef7eb2e8f9f7 108 }
<> 144:ef7eb2e8f9f7 109 // Check if channel 0 is available
<> 144:ef7eb2e8f9f7 110 if ((channels & 1 ) == 0) {
<> 144:ef7eb2e8f9f7 111 channels |= 1 << 0;
<> 144:ef7eb2e8f9f7 112 return 0;
<> 144:ef7eb2e8f9f7 113 }
<> 144:ef7eb2e8f9f7 114 // Couldn't find a channel.
<> 144:ef7eb2e8f9f7 115 return DMA_ERROR_OUT_OF_CHANNELS;
<> 144:ef7eb2e8f9f7 116 }
<> 144:ef7eb2e8f9f7 117
<> 144:ef7eb2e8f9f7 118 int dma_channel_free(int channelid)
<> 144:ef7eb2e8f9f7 119 {
<> 144:ef7eb2e8f9f7 120 if( channelid >= 0 ) {
<> 144:ef7eb2e8f9f7 121 channels &= ~(1 << channelid);
<> 144:ef7eb2e8f9f7 122 }
<> 144:ef7eb2e8f9f7 123
<> 144:ef7eb2e8f9f7 124 return 0;
<> 144:ef7eb2e8f9f7 125 }
<> 144:ef7eb2e8f9f7 126
<> 144:ef7eb2e8f9f7 127 #ifdef LDMA_PRESENT
<> 144:ef7eb2e8f9f7 128
<> 144:ef7eb2e8f9f7 129 /* LDMA emlib API extensions */
<> 144:ef7eb2e8f9f7 130
<> 144:ef7eb2e8f9f7 131 typedef struct {
<> 144:ef7eb2e8f9f7 132 LDMAx_CBFunc_t callback;
<> 144:ef7eb2e8f9f7 133 void *userdata;
<> 144:ef7eb2e8f9f7 134 } LDMA_InternCallback_t;
<> 144:ef7eb2e8f9f7 135
<> 144:ef7eb2e8f9f7 136 static LDMA_InternCallback_t ldmaCallback[DMA_CHAN_COUNT];
<> 144:ef7eb2e8f9f7 137
<> 144:ef7eb2e8f9f7 138 void LDMAx_StartTransfer( int ch,
<> 144:ef7eb2e8f9f7 139 LDMA_TransferCfg_t *transfer,
<> 144:ef7eb2e8f9f7 140 LDMA_Descriptor_t *descriptor,
<> 144:ef7eb2e8f9f7 141 LDMAx_CBFunc_t cbFunc,
<> 144:ef7eb2e8f9f7 142 void *userData )
<> 144:ef7eb2e8f9f7 143 {
<> 144:ef7eb2e8f9f7 144 ldmaCallback[ch].callback = cbFunc;
<> 144:ef7eb2e8f9f7 145 ldmaCallback[ch].userdata = userData;
<> 144:ef7eb2e8f9f7 146
<> 144:ef7eb2e8f9f7 147 LDMA_StartTransfer(ch, transfer, descriptor);
<> 144:ef7eb2e8f9f7 148 }
<> 144:ef7eb2e8f9f7 149
<> 144:ef7eb2e8f9f7 150 void LDMA_IRQHandler( void )
<> 144:ef7eb2e8f9f7 151 {
<> 144:ef7eb2e8f9f7 152 uint32_t pending, chnum, chmask;
<> 144:ef7eb2e8f9f7 153
<> 144:ef7eb2e8f9f7 154 /* Get all pending and enabled interrupts */
<> 144:ef7eb2e8f9f7 155 pending = LDMA->IF;
<> 144:ef7eb2e8f9f7 156 pending &= LDMA->IEN;
<> 144:ef7eb2e8f9f7 157
<> 144:ef7eb2e8f9f7 158 /* Check for LDMA error */
<> 144:ef7eb2e8f9f7 159 if ( pending & LDMA_IF_ERROR )
<> 144:ef7eb2e8f9f7 160 {
<> 144:ef7eb2e8f9f7 161 /* Loop here to enable the debugger to see what has happened */
<> 144:ef7eb2e8f9f7 162 while (1)
<> 144:ef7eb2e8f9f7 163 ;
<> 144:ef7eb2e8f9f7 164 }
<> 144:ef7eb2e8f9f7 165
<> 144:ef7eb2e8f9f7 166 /* Iterate over all LDMA channels. */
<> 144:ef7eb2e8f9f7 167 for ( chnum = 0, chmask = 1;
<> 144:ef7eb2e8f9f7 168 chnum < DMA_CHAN_COUNT;
<> 144:ef7eb2e8f9f7 169 chnum++, chmask <<= 1 )
<> 144:ef7eb2e8f9f7 170 {
<> 144:ef7eb2e8f9f7 171 if ( pending & chmask )
<> 144:ef7eb2e8f9f7 172 {
<> 144:ef7eb2e8f9f7 173 /* Clear interrupt flag. */
<> 144:ef7eb2e8f9f7 174 LDMA->IFC = chmask;
<> 144:ef7eb2e8f9f7 175
<> 144:ef7eb2e8f9f7 176 /* Do more stuff here, execute callbacks etc. */
<> 144:ef7eb2e8f9f7 177 if ( ldmaCallback[chnum].callback )
<> 144:ef7eb2e8f9f7 178 {
<> 144:ef7eb2e8f9f7 179 ldmaCallback[chnum].callback(chnum, false, ldmaCallback[chnum].userdata);
<> 144:ef7eb2e8f9f7 180 }
<> 144:ef7eb2e8f9f7 181 }
<> 144:ef7eb2e8f9f7 182 }
<> 144:ef7eb2e8f9f7 183 }
<> 144:ef7eb2e8f9f7 184
<> 144:ef7eb2e8f9f7 185 /***************************************************************************//**
<> 144:ef7eb2e8f9f7 186 * @brief
<> 144:ef7eb2e8f9f7 187 * Check if LDMA channel is enabled.
<> 144:ef7eb2e8f9f7 188 *
<> 144:ef7eb2e8f9f7 189 * @param[in] ch
<> 144:ef7eb2e8f9f7 190 * LDMA channel to check.
<> 144:ef7eb2e8f9f7 191 *
<> 144:ef7eb2e8f9f7 192 * @return
<> 144:ef7eb2e8f9f7 193 * true if channel is enabled, false if not.
<> 144:ef7eb2e8f9f7 194 ******************************************************************************/
<> 144:ef7eb2e8f9f7 195 bool LDMAx_ChannelEnabled( int ch )
<> 144:ef7eb2e8f9f7 196 {
<> 144:ef7eb2e8f9f7 197 EFM_ASSERT(ch < DMA_CHAN_COUNT);
<> 144:ef7eb2e8f9f7 198 uint32_t chMask = 1 << ch;
<> 144:ef7eb2e8f9f7 199 return (bool)(LDMA->CHEN & chMask);
<> 144:ef7eb2e8f9f7 200 }
<> 144:ef7eb2e8f9f7 201
<> 144:ef7eb2e8f9f7 202 #endif /* LDMA_PRESENT */