Mateusz Kowalik / Application_danix

Fork of Application by Daniel Sygut

Committer:
Zaitsev
Date:
Thu Feb 15 14:29:23 2018 +0000
Revision:
15:2a20c3d2616e
Parent:
10:41552d038a69
j

Who changed what in which revision?

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