4 * This file is part of BeRTOS.
6 * Bertos is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 * As a special exception, you may use this file as part of a free software
21 * library without restriction. Specifically, if other files instantiate
22 * templates or use macros or inline functions from this file, or you compile
23 * this file and link it with other files to produce an executable, this
24 * file does not by itself cause the resulting executable to be covered by
25 * the GNU General Public License. This exception does not however
26 * invalidate any other reasons why the executable file might be covered by
27 * the GNU General Public License.
29 * Copyright 2011 Develer S.r.l. (http://www.develer.com/)
32 * \brief HSMCI driver implementation.
34 * \author Daniele Basile <asterix@develer.com>
37 #include "dmac_sam3.h"
39 #include "hsmci_sam3.h"
42 #include <drv/timer.h>
43 #include <drv/irq_cm3.h>
46 #include <cpu/power.h>
60 #define DMAC_CHANNEL_CNT 5
61 struct DmacCh dmac_ch[] =
68 .ctrla = &DMAC_CTRLA0,
69 .ctrlb = &DMAC_CTRLB0,
76 .ctrla = &DMAC_CTRLA1,
77 .ctrlb = &DMAC_CTRLB1,
84 .ctrla = &DMAC_CTRLA2,
85 .ctrlb = &DMAC_CTRLB2,
92 .ctrla = &DMAC_CTRLA3,
93 .ctrlb = &DMAC_CTRLB3,
100 .ctrla = &DMAC_CTRLA4,
101 .ctrlb = &DMAC_CTRLB4,
108 .ctrla = &DMAC_CTRLA5,
109 .ctrlb = &DMAC_CTRLB5,
113 void dmac_setSources(Dmac *dmac, uint8_t ch, uint32_t src, uint32_t dst, size_t transfer_size)
115 ASSERT(ch <= DMAC_CHANNEL_CNT);
119 *dmac_ch[ch].src = src;
120 *dmac_ch[ch].dst = dst;
121 *dmac_ch[ch].desc = 0;
122 dmac->transfer_size = transfer_size;
125 void dmac_configureDmac(Dmac *dmac, uint8_t ch, uint32_t cfg, uint32_t ctrla, uint32_t ctrlb)
127 ASSERT(ch <= DMAC_CHANNEL_CNT);
131 *dmac_ch[ch].cfg = cfg | DMAC_CFG_FIFOCFG_ALAP_CFG | (0x1 << DMAC_CFG_AHB_PROT_SHIFT);
132 *dmac_ch[ch].ctrla = ctrla | (dmac->transfer_size & DMAC_CTRLA_BTSIZE_MASK);
133 *dmac_ch[ch].ctrlb = ctrlb | BV(DMAC_CTRLB_IEN);
136 int dmac_start(Dmac *dmac, uint8_t ch)
138 ASSERT(ch <= DMAC_CHANNEL_CNT);
140 if (DMAC_CHSR & BV(ch))
142 dmac->errors |= DMAC_ERR_CH_ALREDY_ON;
150 bool dmac_isDone(Dmac *dmac, uint8_t ch)
153 return (DMAC_EBCISR |= BV(ch));
156 bool dmac_waitDone(Dmac *dmac, uint8_t ch)
159 while(!(DMAC_EBCISR |= BV(ch)))
165 static DECLARE_ISR(dmac_irq)
169 void dmac_init(Dmac *dmac)
174 DMAC_EBCIDR = 0x3FFFFF;
177 pmc_periphEnable(DMAC_ID);
178 DMAC_EN = BV(DMAC_EN_ENABLE);
179 sysirq_setHandler(INT_DMAC, dmac_irq);