mbed library sources. Supersedes mbed-src.

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

Committer:
AnnaBridge
Date:
Thu Aug 31 17:27:04 2017 +0100
Revision:
172:7d866c31b3c5
This updates the lib to the mbed lib v 150

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AnnaBridge 172:7d866c31b3c5 1 /* mbed Microcontroller Library
AnnaBridge 172:7d866c31b3c5 2 * Copyright (c) 2015-2016 Nuvoton
AnnaBridge 172:7d866c31b3c5 3 *
AnnaBridge 172:7d866c31b3c5 4 * Licensed under the Apache License, Version 2.0 (the "License");
AnnaBridge 172:7d866c31b3c5 5 * you may not use this file except in compliance with the License.
AnnaBridge 172:7d866c31b3c5 6 * You may obtain a copy of the License at
AnnaBridge 172:7d866c31b3c5 7 *
AnnaBridge 172:7d866c31b3c5 8 * http://www.apache.org/licenses/LICENSE-2.0
AnnaBridge 172:7d866c31b3c5 9 *
AnnaBridge 172:7d866c31b3c5 10 * Unless required by applicable law or agreed to in writing, software
AnnaBridge 172:7d866c31b3c5 11 * distributed under the License is distributed on an "AS IS" BASIS,
AnnaBridge 172:7d866c31b3c5 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
AnnaBridge 172:7d866c31b3c5 13 * See the License for the specific language governing permissions and
AnnaBridge 172:7d866c31b3c5 14 * limitations under the License.
AnnaBridge 172:7d866c31b3c5 15 */
AnnaBridge 172:7d866c31b3c5 16
AnnaBridge 172:7d866c31b3c5 17 #include "dma_api.h"
AnnaBridge 172:7d866c31b3c5 18 #include "string.h"
AnnaBridge 172:7d866c31b3c5 19 #include "cmsis.h"
AnnaBridge 172:7d866c31b3c5 20 #include "mbed_assert.h"
AnnaBridge 172:7d866c31b3c5 21 #include "PeripheralNames.h"
AnnaBridge 172:7d866c31b3c5 22 #include "nu_modutil.h"
AnnaBridge 172:7d866c31b3c5 23 #include "nu_bitutil.h"
AnnaBridge 172:7d866c31b3c5 24 #include "dma.h"
AnnaBridge 172:7d866c31b3c5 25
AnnaBridge 172:7d866c31b3c5 26 #define NU_PDMA_CH_MAX PDMA_CH_MAX /* Specify maximum channels of PDMA */
AnnaBridge 172:7d866c31b3c5 27 #define NU_PDMA_CH_Pos 0 /* Specify first channel number of PDMA */
AnnaBridge 172:7d866c31b3c5 28 #define NU_PDMA_CH_Msk (((1 << NU_PDMA_CH_MAX) - 1) << NU_PDMA_CH_Pos)
AnnaBridge 172:7d866c31b3c5 29
AnnaBridge 172:7d866c31b3c5 30 struct nu_dma_chn_s {
AnnaBridge 172:7d866c31b3c5 31 void (*handler)(uint32_t, uint32_t);
AnnaBridge 172:7d866c31b3c5 32 uint32_t id;
AnnaBridge 172:7d866c31b3c5 33 uint32_t event;
AnnaBridge 172:7d866c31b3c5 34 };
AnnaBridge 172:7d866c31b3c5 35
AnnaBridge 172:7d866c31b3c5 36 static int dma_inited = 0;
AnnaBridge 172:7d866c31b3c5 37 static uint32_t dma_chn_mask = 0;
AnnaBridge 172:7d866c31b3c5 38 static struct nu_dma_chn_s dma_chn_arr[NU_PDMA_CH_MAX];
AnnaBridge 172:7d866c31b3c5 39
AnnaBridge 172:7d866c31b3c5 40 static void pdma_vec(void);
AnnaBridge 172:7d866c31b3c5 41 static const struct nu_modinit_s dma_modinit = {DMA_0, PDMA_MODULE, 0, 0, PDMA_RST, PDMA_IRQn, (void *) pdma_vec};
AnnaBridge 172:7d866c31b3c5 42
AnnaBridge 172:7d866c31b3c5 43
AnnaBridge 172:7d866c31b3c5 44 void dma_init(void)
AnnaBridge 172:7d866c31b3c5 45 {
AnnaBridge 172:7d866c31b3c5 46 if (dma_inited) {
AnnaBridge 172:7d866c31b3c5 47 return;
AnnaBridge 172:7d866c31b3c5 48 }
AnnaBridge 172:7d866c31b3c5 49
AnnaBridge 172:7d866c31b3c5 50 dma_inited = 1;
AnnaBridge 172:7d866c31b3c5 51 dma_chn_mask = ~NU_PDMA_CH_Msk;
AnnaBridge 172:7d866c31b3c5 52 memset(dma_chn_arr, 0x00, sizeof (dma_chn_arr));
AnnaBridge 172:7d866c31b3c5 53
AnnaBridge 172:7d866c31b3c5 54 // Reset this module
AnnaBridge 172:7d866c31b3c5 55 SYS_ResetModule(dma_modinit.rsetidx);
AnnaBridge 172:7d866c31b3c5 56
AnnaBridge 172:7d866c31b3c5 57 // Enable IP clock
AnnaBridge 172:7d866c31b3c5 58 CLK_EnableModuleClock(dma_modinit.clkidx);
AnnaBridge 172:7d866c31b3c5 59
AnnaBridge 172:7d866c31b3c5 60 PDMA_Open(0);
AnnaBridge 172:7d866c31b3c5 61
AnnaBridge 172:7d866c31b3c5 62 NVIC_SetVector(dma_modinit.irq_n, (uint32_t) dma_modinit.var);
AnnaBridge 172:7d866c31b3c5 63 NVIC_EnableIRQ(dma_modinit.irq_n);
AnnaBridge 172:7d866c31b3c5 64 }
AnnaBridge 172:7d866c31b3c5 65
AnnaBridge 172:7d866c31b3c5 66 int dma_channel_allocate(uint32_t capabilities)
AnnaBridge 172:7d866c31b3c5 67 {
AnnaBridge 172:7d866c31b3c5 68 if (! dma_inited) {
AnnaBridge 172:7d866c31b3c5 69 dma_init();
AnnaBridge 172:7d866c31b3c5 70 }
AnnaBridge 172:7d866c31b3c5 71
AnnaBridge 172:7d866c31b3c5 72 int i = nu_cto(dma_chn_mask);
AnnaBridge 172:7d866c31b3c5 73 if (i != 32) {
AnnaBridge 172:7d866c31b3c5 74 dma_chn_mask |= 1 << i;
AnnaBridge 172:7d866c31b3c5 75 memset(dma_chn_arr + i - NU_PDMA_CH_Pos, 0x00, sizeof (struct nu_dma_chn_s));
AnnaBridge 172:7d866c31b3c5 76 return i;
AnnaBridge 172:7d866c31b3c5 77 }
AnnaBridge 172:7d866c31b3c5 78
AnnaBridge 172:7d866c31b3c5 79 // No channel available
AnnaBridge 172:7d866c31b3c5 80 return DMA_ERROR_OUT_OF_CHANNELS;
AnnaBridge 172:7d866c31b3c5 81 }
AnnaBridge 172:7d866c31b3c5 82
AnnaBridge 172:7d866c31b3c5 83 int dma_channel_free(int channelid)
AnnaBridge 172:7d866c31b3c5 84 {
AnnaBridge 172:7d866c31b3c5 85 if (channelid != DMA_ERROR_OUT_OF_CHANNELS) {
AnnaBridge 172:7d866c31b3c5 86 dma_chn_mask &= ~(1 << channelid);
AnnaBridge 172:7d866c31b3c5 87 }
AnnaBridge 172:7d866c31b3c5 88
AnnaBridge 172:7d866c31b3c5 89 return 0;
AnnaBridge 172:7d866c31b3c5 90 }
AnnaBridge 172:7d866c31b3c5 91
AnnaBridge 172:7d866c31b3c5 92 void dma_set_handler(int channelid, uint32_t handler, uint32_t id, uint32_t event)
AnnaBridge 172:7d866c31b3c5 93 {
AnnaBridge 172:7d866c31b3c5 94 MBED_ASSERT(dma_chn_mask & (1 << channelid));
AnnaBridge 172:7d866c31b3c5 95
AnnaBridge 172:7d866c31b3c5 96 dma_chn_arr[channelid - NU_PDMA_CH_Pos].handler = (void (*)(uint32_t, uint32_t)) handler;
AnnaBridge 172:7d866c31b3c5 97 dma_chn_arr[channelid - NU_PDMA_CH_Pos].id = id;
AnnaBridge 172:7d866c31b3c5 98 dma_chn_arr[channelid - NU_PDMA_CH_Pos].event = event;
AnnaBridge 172:7d866c31b3c5 99
AnnaBridge 172:7d866c31b3c5 100 // Set interrupt vector if someone has removed it.
AnnaBridge 172:7d866c31b3c5 101 NVIC_SetVector(dma_modinit.irq_n, (uint32_t) dma_modinit.var);
AnnaBridge 172:7d866c31b3c5 102 NVIC_EnableIRQ(dma_modinit.irq_n);
AnnaBridge 172:7d866c31b3c5 103 }
AnnaBridge 172:7d866c31b3c5 104
AnnaBridge 172:7d866c31b3c5 105 PDMA_T *dma_modbase(void)
AnnaBridge 172:7d866c31b3c5 106 {
AnnaBridge 172:7d866c31b3c5 107 return (PDMA_T *) NU_MODBASE(dma_modinit.modname);
AnnaBridge 172:7d866c31b3c5 108 }
AnnaBridge 172:7d866c31b3c5 109
AnnaBridge 172:7d866c31b3c5 110 static void pdma_vec(void)
AnnaBridge 172:7d866c31b3c5 111 {
AnnaBridge 172:7d866c31b3c5 112 uint32_t intsts = PDMA_GET_INT_STATUS();
AnnaBridge 172:7d866c31b3c5 113
AnnaBridge 172:7d866c31b3c5 114 // Abort
AnnaBridge 172:7d866c31b3c5 115 if (intsts & PDMA_INTSTS_ABTIF_Msk) {
AnnaBridge 172:7d866c31b3c5 116 uint32_t abtsts = PDMA_GET_ABORT_STS();
AnnaBridge 172:7d866c31b3c5 117 // Clear all Abort flags
AnnaBridge 172:7d866c31b3c5 118 PDMA_CLR_ABORT_FLAG(abtsts);
AnnaBridge 172:7d866c31b3c5 119
AnnaBridge 172:7d866c31b3c5 120 while (abtsts) {
AnnaBridge 172:7d866c31b3c5 121 int chn_id = nu_ctz(abtsts) - PDMA_ABTSTS_ABTIF0_Pos + NU_PDMA_CH_Pos;
AnnaBridge 172:7d866c31b3c5 122 if (dma_chn_mask & (1 << chn_id)) {
AnnaBridge 172:7d866c31b3c5 123 struct nu_dma_chn_s *dma_chn = dma_chn_arr + chn_id - NU_PDMA_CH_Pos;
AnnaBridge 172:7d866c31b3c5 124 if (dma_chn->handler && (dma_chn->event & DMA_EVENT_ABORT)) {
AnnaBridge 172:7d866c31b3c5 125 dma_chn->handler(dma_chn->id, DMA_EVENT_ABORT);
AnnaBridge 172:7d866c31b3c5 126 }
AnnaBridge 172:7d866c31b3c5 127 }
AnnaBridge 172:7d866c31b3c5 128 abtsts &= ~(1 << (chn_id - NU_PDMA_CH_Pos + PDMA_ABTSTS_ABTIF0_Pos));
AnnaBridge 172:7d866c31b3c5 129 }
AnnaBridge 172:7d866c31b3c5 130 }
AnnaBridge 172:7d866c31b3c5 131
AnnaBridge 172:7d866c31b3c5 132 // Transfer done
AnnaBridge 172:7d866c31b3c5 133 if (intsts & PDMA_INTSTS_TDIF_Msk) {
AnnaBridge 172:7d866c31b3c5 134 uint32_t tdsts = PDMA_GET_TD_STS();
AnnaBridge 172:7d866c31b3c5 135 // Clear all transfer done flags
AnnaBridge 172:7d866c31b3c5 136 PDMA_CLR_TD_FLAG(tdsts);
AnnaBridge 172:7d866c31b3c5 137
AnnaBridge 172:7d866c31b3c5 138 while (tdsts) {
AnnaBridge 172:7d866c31b3c5 139 int chn_id = nu_ctz(tdsts) - PDMA_TDSTS_TDIF0_Pos + NU_PDMA_CH_Pos;
AnnaBridge 172:7d866c31b3c5 140 if (dma_chn_mask & (1 << chn_id)) {
AnnaBridge 172:7d866c31b3c5 141 struct nu_dma_chn_s *dma_chn = dma_chn_arr + chn_id - NU_PDMA_CH_Pos;
AnnaBridge 172:7d866c31b3c5 142 if (dma_chn->handler && (dma_chn->event & DMA_EVENT_TRANSFER_DONE)) {
AnnaBridge 172:7d866c31b3c5 143 dma_chn->handler(dma_chn->id, DMA_EVENT_TRANSFER_DONE);
AnnaBridge 172:7d866c31b3c5 144 }
AnnaBridge 172:7d866c31b3c5 145 }
AnnaBridge 172:7d866c31b3c5 146 tdsts &= ~(1 << (chn_id - NU_PDMA_CH_Pos + PDMA_TDSTS_TDIF0_Pos));
AnnaBridge 172:7d866c31b3c5 147 }
AnnaBridge 172:7d866c31b3c5 148 }
AnnaBridge 172:7d866c31b3c5 149
AnnaBridge 172:7d866c31b3c5 150 // Timeout
AnnaBridge 172:7d866c31b3c5 151 uint32_t reqto = intsts & (PDMA_INTSTS_REQTOF0_Msk | PDMA_INTSTS_REQTOF1_Msk);
AnnaBridge 172:7d866c31b3c5 152 if (reqto) {
AnnaBridge 172:7d866c31b3c5 153 // Clear all Timeout flags
AnnaBridge 172:7d866c31b3c5 154 PDMA->INTSTS = reqto;
AnnaBridge 172:7d866c31b3c5 155
AnnaBridge 172:7d866c31b3c5 156 while (reqto) {
AnnaBridge 172:7d866c31b3c5 157 int chn_id = nu_ctz(reqto) - PDMA_INTSTS_REQTOF0_Pos + NU_PDMA_CH_Pos;
AnnaBridge 172:7d866c31b3c5 158 if (dma_chn_mask & (1 << chn_id)) {
AnnaBridge 172:7d866c31b3c5 159 struct nu_dma_chn_s *dma_chn = dma_chn_arr + chn_id - NU_PDMA_CH_Pos;
AnnaBridge 172:7d866c31b3c5 160 if (dma_chn->handler && (dma_chn->event & DMA_EVENT_TIMEOUT)) {
AnnaBridge 172:7d866c31b3c5 161 dma_chn->handler(dma_chn->id, DMA_EVENT_TIMEOUT);
AnnaBridge 172:7d866c31b3c5 162 }
AnnaBridge 172:7d866c31b3c5 163 }
AnnaBridge 172:7d866c31b3c5 164 reqto &= ~(1 << (chn_id - NU_PDMA_CH_Pos + PDMA_INTSTS_REQTOF0_Pos));
AnnaBridge 172:7d866c31b3c5 165 }
AnnaBridge 172:7d866c31b3c5 166 }
AnnaBridge 172:7d866c31b3c5 167 }