libopencm3
A free/libre/open-source firmware library for various ARM Cortex-M3 microcontrollers.
dma_common_l1f013.c
Go to the documentation of this file.
1/** @defgroup dma_file DMA peripheral API
2@ingroup peripheral_apis
3@brief DMA library for the multi channel controller found in F0/1/3 & L/G parts.
4
5@author @htmlonly &copy; @endhtmlonly 2010 Thomas Otto <tommi@viadmin.org>
6
7This library supports the DMA Control System in the STM32 series of ARM Cortex
8Microcontrollers by ST Microelectronics.
9
10Up to two DMA controllers are supported. 12 DMA channels are allocated 7 to
11the first DMA controller and 5 to the second. Each channel is connected to
12between 3 and 6 hardware peripheral DMA signals in a logical OR arrangement.
13
14DMA transfers can be configured to occur between peripheral and memory in
15any combination including memory to memory. Circular mode transfers are
16also supported in transfers involving a peripheral. An arbiter is provided
17to resolve priority DMA requests. Transfers can be made with 8, 16 or 32 bit
18words.
19
20LGPL License Terms @ref lgpl_license
21 */
22/*
23 * This file is part of the libopencm3 project.
24 *
25 * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org>
26 *
27 * This library is free software: you can redistribute it and/or modify
28 * it under the terms of the GNU Lesser General Public License as published by
29 * the Free Software Foundation, either version 3 of the License, or
30 * (at your option) any later version.
31 *
32 * This library is distributed in the hope that it will be useful,
33 * but WITHOUT ANY WARRANTY; without even the implied warranty of
34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35 * GNU Lesser General Public License for more details.
36 *
37 * You should have received a copy of the GNU Lesser General Public License
38 * along with this library. If not, see <http://www.gnu.org/licenses/>.
39 */
40
41/**@{*/
42
44
45/*---------------------------------------------------------------------------*/
46/** @brief DMA Channel Reset
47
48The channel is disabled and configuration registers are cleared.
49
50@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
51@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
52*/
53
54void dma_channel_reset(uint32_t dma, uint8_t channel)
55{
56 /* Disable channel and reset config bits. */
57 DMA_CCR(dma, channel) = 0;
58 /* Reset data transfer number. */
59 DMA_CNDTR(dma, channel) = 0;
60 /* Reset peripheral address. */
61 DMA_CPAR(dma, channel) = 0;
62 /* Reset memory address. */
63 DMA_CMAR(dma, channel) = 0;
64 /* Reset interrupt flags. */
65 DMA_IFCR(dma) |= DMA_IFCR_CIF(channel);
66}
67
68/*---------------------------------------------------------------------------*/
69/** @brief DMA Channel Clear Interrupt Flag
70
71The interrupt flag for the channel is cleared. More than one interrupt for the
72same channel may be cleared by using the logical OR of the interrupt flags.
73
74@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
75@param[in] channel unsigned int8. Channel number: @ref dma_ch
76@param[in] interrupts unsigned int32. Logical OR of interrupt numbers: @ref
77dma_if_offset
78*/
79
80void dma_clear_interrupt_flags(uint32_t dma, uint8_t channel,
81 uint32_t interrupts)
82{
83/* Get offset to interrupt flag location in channel field */
84 uint32_t flags = (interrupts << DMA_FLAG_OFFSET(channel));
85 DMA_IFCR(dma) = flags;
86}
87
88/*---------------------------------------------------------------------------*/
89/** @brief DMA Channel Read Interrupt Flag
90
91The interrupt flag for the channel is returned.
92
93@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
94@param[in] channel unsigned int8. Channel number: @ref dma_ch
95@param[in] interrupt unsigned int32. Interrupt number: @ref dma_if_offset
96@returns bool interrupt flag is set.
97*/
98
99bool dma_get_interrupt_flag(uint32_t dma, uint8_t channel, uint32_t interrupt)
100{
101/* get offset to interrupt flag location in channel field. */
102 uint32_t flag = (interrupt << DMA_FLAG_OFFSET(channel));
103 return ((DMA_ISR(dma) & flag) > 0);
104}
105
106/*---------------------------------------------------------------------------*/
107/** @brief DMA Channel Enable Memory to Memory Transfers
108
109Memory to memory transfers do not require a trigger to activate each transfer.
110Transfers begin immediately the channel has been enabled, and proceed without
111intervention.
112
113@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
114@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
115*/
116
117void dma_enable_mem2mem_mode(uint32_t dma, uint8_t channel)
118{
119 DMA_CCR(dma, channel) |= DMA_CCR_MEM2MEM;
120 DMA_CCR(dma, channel) &= ~DMA_CCR_CIRC;
121}
122
123/*---------------------------------------------------------------------------*/
124/** @brief DMA Channel Set Priority
125
126Channel Priority has four levels: low to very high. This has precedence over the
127hardware priority.
128
129@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
130@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
131@param[in] prio unsigned int32. Priority level @ref dma_ch_pri.
132*/
133
134void dma_set_priority(uint32_t dma, uint8_t channel, uint32_t prio)
135{
136 DMA_CCR(dma, channel) &= ~(DMA_CCR_PL_MASK);
137 DMA_CCR(dma, channel) |= prio;
138}
139
140/*---------------------------------------------------------------------------*/
141/** @brief DMA Channel Set Memory Word Width
142
143Set the memory word width 8 bits, 16 bits, or 32 bits. Refer to datasheet for
144alignment information if the source and destination widths do not match.
145
146@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
147@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
148@param[in] mem_size unsigned int32. Memory word width @ref dma_ch_memwidth.
149*/
150
151void dma_set_memory_size(uint32_t dma, uint8_t channel, uint32_t mem_size)
152{
153
154 DMA_CCR(dma, channel) &= ~(DMA_CCR_MSIZE_MASK);
155 DMA_CCR(dma, channel) |= mem_size;
156}
157
158/*---------------------------------------------------------------------------*/
159/** @brief DMA Channel Set Peripheral Word Width
160
161Set the peripheral word width 8 bits, 16 bits, or 32 bits. Refer to datasheet
162for alignment information if the source and destination widths do not match, or
163if the peripheral does not support byte or half-word writes.
164
165@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
166@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
167@param[in] peripheral_size unsigned int32. Peripheral word width @ref
168dma_ch_perwidth.
169*/
170
171void dma_set_peripheral_size(uint32_t dma, uint8_t channel,
172 uint32_t peripheral_size)
173{
174 DMA_CCR(dma, channel) &= ~(DMA_CCR_PSIZE_MASK);
175 DMA_CCR(dma, channel) |= peripheral_size;
176}
177
178/*---------------------------------------------------------------------------*/
179/** @brief DMA Channel Enable Memory Increment after Transfer
180
181Following each transfer the current memory address is incremented by
1821, 2 or 4 depending on the data size set in @ref dma_set_memory_size. The
183value held by the base memory address register is unchanged.
184
185@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
186@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
187*/
188
189void dma_enable_memory_increment_mode(uint32_t dma, uint8_t channel)
190{
191 DMA_CCR(dma, channel) |= DMA_CCR_MINC;
192}
193
194/*---------------------------------------------------------------------------*/
195/** @brief DMA Channel Disable Memory Increment after Transfer
196
197@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
198@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
199*/
200
201void dma_disable_memory_increment_mode(uint32_t dma, uint8_t channel)
202{
203 DMA_CCR(dma, channel) &= ~DMA_CCR_MINC;
204}
205
206/*---------------------------------------------------------------------------*/
207/** @brief DMA Channel Enable Peripheral Increment after Transfer
208
209Following each transfer the current peripheral address is incremented by
2101, 2 or 4 depending on the data size set in @ref dma_set_peripheral_size. The
211value held by the base peripheral address register is unchanged.
212
213@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
214@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
215*/
216
217void dma_enable_peripheral_increment_mode(uint32_t dma, uint8_t channel)
218{
219 DMA_CCR(dma, channel) |= DMA_CCR_PINC;
220}
221
222/*---------------------------------------------------------------------------*/
223/** @brief DMA Channel Disable Peripheral Increment after Transfer
224
225@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
226@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
227*/
228
229void dma_disable_peripheral_increment_mode(uint32_t dma, uint8_t channel)
230{
231 DMA_CCR(dma, channel) &= ~DMA_CCR_PINC;
232}
233
234/*---------------------------------------------------------------------------*/
235/** @brief DMA Channel Enable Memory Circular Mode
236
237After the number of bytes/words to be transferred has been completed, the
238original transfer block size, memory and peripheral base addresses are
239reloaded and the process repeats.
240
241@note This cannot be used with memory to memory mode, which is explicitly
242disabled here.
243
244@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
245@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
246*/
247
248void dma_enable_circular_mode(uint32_t dma, uint8_t channel)
249{
250 DMA_CCR(dma, channel) |= DMA_CCR_CIRC;
251 DMA_CCR(dma, channel) &= ~DMA_CCR_MEM2MEM;
252}
253
254/*---------------------------------------------------------------------------*/
255/** @brief DMA Channel Enable Transfers from a Peripheral
256
257The data direction is set to read from a peripheral.
258
259@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
260@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
261*/
262
263void dma_set_read_from_peripheral(uint32_t dma, uint8_t channel)
264{
265 DMA_CCR(dma, channel) &= ~DMA_CCR_DIR;
266}
267
268/*---------------------------------------------------------------------------*/
269/** @brief DMA Channel Enable Transfers from Memory
270
271The data direction is set to read from memory.
272
273@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
274@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
275*/
276
277void dma_set_read_from_memory(uint32_t dma, uint8_t channel)
278{
279 DMA_CCR(dma, channel) |= DMA_CCR_DIR;
280}
281
282/*---------------------------------------------------------------------------*/
283/** @brief DMA Channel Enable Interrupt on Transfer Error
284
285@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
286@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
287*/
288
289void dma_enable_transfer_error_interrupt(uint32_t dma, uint8_t channel)
290{
291 DMA_CCR(dma, channel) |= DMA_CCR_TEIE;
292}
293
294/*---------------------------------------------------------------------------*/
295/** @brief DMA Channel Disable Interrupt on Transfer Error
296
297@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
298@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
299*/
300
301void dma_disable_transfer_error_interrupt(uint32_t dma, uint8_t channel)
302{
303 DMA_CCR(dma, channel) &= ~DMA_CCR_TEIE;
304}
305
306/*---------------------------------------------------------------------------*/
307/** @brief DMA Channel Enable Interrupt on Transfer Half Complete
308
309@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
310@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
311*/
312
313void dma_enable_half_transfer_interrupt(uint32_t dma, uint8_t channel)
314{
315 DMA_CCR(dma, channel) |= DMA_CCR_HTIE;
316}
317
318/*---------------------------------------------------------------------------*/
319/** @brief DMA Channel Disable Interrupt on Transfer Half Complete
320
321@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
322@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
323*/
324
325void dma_disable_half_transfer_interrupt(uint32_t dma, uint8_t channel)
326{
327 DMA_CCR(dma, channel) &= ~DMA_CCR_HTIE;
328}
329
330/*---------------------------------------------------------------------------*/
331/** @brief DMA Channel Enable Interrupt on Transfer Complete
332
333@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
334@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
335*/
336
337void dma_enable_transfer_complete_interrupt(uint32_t dma, uint8_t channel)
338{
339 DMA_CCR(dma, channel) |= DMA_CCR_TCIE;
340}
341
342/*---------------------------------------------------------------------------*/
343/** @brief DMA Channel Disable Interrupt on Transfer Complete
344
345@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
346@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
347*/
348
349void dma_disable_transfer_complete_interrupt(uint32_t dma, uint8_t channel)
350{
351 DMA_CCR(dma, channel) &= ~DMA_CCR_TCIE;
352}
353
354/*---------------------------------------------------------------------------*/
355/** @brief DMA Channel Enable
356
357@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
358@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
359*/
360
361void dma_enable_channel(uint32_t dma, uint8_t channel)
362{
363 DMA_CCR(dma, channel) |= DMA_CCR_EN;
364}
365
366/*---------------------------------------------------------------------------*/
367/** @brief DMA Channel Disable
368
369@note The DMA channel registers retain their values when the channel is
370disabled.
371
372@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
373@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
374*/
375
376void dma_disable_channel(uint32_t dma, uint8_t channel)
377{
378 DMA_CCR(dma, channel) &= ~DMA_CCR_EN;
379}
380
381/*---------------------------------------------------------------------------*/
382/** @brief DMA Channel Set the Peripheral Address
383
384Set the address of the peripheral register to or from which data is to be
385transferred. Refer to the documentation for the specific peripheral.
386
387@note The DMA channel must be disabled before setting this address. This
388function has no effect if the channel is enabled.
389
390@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
391@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
392@param[in] address unsigned int32. Peripheral Address.
393*/
394
395void dma_set_peripheral_address(uint32_t dma, uint8_t channel, uint32_t address)
396{
397 if (!(DMA_CCR(dma, channel) & DMA_CCR_EN)) {
398 DMA_CPAR(dma, channel) = (uint32_t) address;
399 }
400}
401
402/*---------------------------------------------------------------------------*/
403/** @brief DMA Channel Set the Base Memory Address
404
405@note The DMA channel must be disabled before setting this address. This
406function has no effect if the channel is enabled.
407
408@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
409@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
410@param[in] address unsigned int32. Memory Initial Address.
411*/
412
413void dma_set_memory_address(uint32_t dma, uint8_t channel, uint32_t address)
414{
415 if (!(DMA_CCR(dma, channel) & DMA_CCR_EN)) {
416 DMA_CMAR(dma, channel) = (uint32_t) address;
417 }
418}
419
420/*---------------------------------------------------------------------------*/
421/** @brief DMA Channel Get the Transfer Block Size
422
423@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
424@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
425@returns unsigned int16. Number of remaining data words to transfer (65535
426maximum).
427*/
428
429uint16_t dma_get_number_of_data(uint32_t dma, uint8_t channel)
430{
431 return DMA_CNDTR(dma, channel);
432}
433
434/*---------------------------------------------------------------------------*/
435/** @brief DMA Channel Set the Transfer Block Size
436
437@note The DMA channel must be disabled before setting this count value. The
438count is not changed if the channel is enabled.
439
440@param[in] dma unsigned int32. DMA controller base address: DMA1 or DMA2
441@param[in] channel unsigned int8. Channel number: 1-7 for DMA1 or 1-5 for DMA2
442@param[in] number unsigned int16. Number of data words to transfer (65535
443maximum).
444*/
445
446void dma_set_number_of_data(uint32_t dma, uint8_t channel, uint16_t number)
447{
448 DMA_CNDTR(dma, channel) = number;
449}
450/**@}*/
451
#define DMA_CCR_PINC
#define DMA_CCR_HTIE
#define DMA_CNDTR(dma_base, channel)
#define DMA_CCR_TEIE
#define DMA_CCR_CIRC
#define DMA_FLAG_OFFSET(channel)
#define DMA_IFCR_CIF(channel)
#define DMA_CCR_MEM2MEM
#define DMA_ISR(dma_base)
#define DMA_IFCR(dma_base)
#define DMA_CCR_DIR
#define DMA_CCR(dma_base, channel)
#define DMA_CCR_MINC
#define DMA_CCR_PL_MASK
#define DMA_CCR_TCIE
#define DMA_CMAR(dma_base, channel)
#define DMA_CCR_EN
#define DMA_CCR_MSIZE_MASK
#define DMA_CPAR(dma_base, channel)
#define DMA_CCR_PSIZE_MASK
void dma_set_read_from_memory(uint32_t dma, uint8_t channel)
DMA Channel Enable Transfers from Memory.
void dma_disable_transfer_complete_interrupt(uint32_t dma, uint8_t channel)
DMA Channel Disable Interrupt on Transfer Complete.
void dma_set_priority(uint32_t dma, uint8_t channel, uint32_t prio)
DMA Channel Set Priority.
void dma_enable_transfer_complete_interrupt(uint32_t dma, uint8_t channel)
DMA Channel Enable Interrupt on Transfer Complete.
void dma_set_memory_address(uint32_t dma, uint8_t channel, uint32_t address)
DMA Channel Set the Base Memory Address.
bool dma_get_interrupt_flag(uint32_t dma, uint8_t channel, uint32_t interrupt)
DMA Channel Read Interrupt Flag.
void dma_disable_memory_increment_mode(uint32_t dma, uint8_t channel)
DMA Channel Disable Memory Increment after Transfer.
void dma_set_number_of_data(uint32_t dma, uint8_t channel, uint16_t number)
DMA Channel Set the Transfer Block Size.
uint16_t dma_get_number_of_data(uint32_t dma, uint8_t channel)
DMA Channel Get the Transfer Block Size.
void dma_enable_memory_increment_mode(uint32_t dma, uint8_t channel)
DMA Channel Enable Memory Increment after Transfer.
void dma_disable_transfer_error_interrupt(uint32_t dma, uint8_t channel)
DMA Channel Disable Interrupt on Transfer Error.
void dma_set_read_from_peripheral(uint32_t dma, uint8_t channel)
DMA Channel Enable Transfers from a Peripheral.
void dma_disable_channel(uint32_t dma, uint8_t channel)
DMA Channel Disable.
void dma_disable_half_transfer_interrupt(uint32_t dma, uint8_t channel)
DMA Channel Disable Interrupt on Transfer Half Complete.
void dma_enable_peripheral_increment_mode(uint32_t dma, uint8_t channel)
DMA Channel Enable Peripheral Increment after Transfer.
void dma_enable_channel(uint32_t dma, uint8_t channel)
DMA Channel Enable.
void dma_enable_circular_mode(uint32_t dma, uint8_t channel)
DMA Channel Enable Memory Circular Mode.
void dma_enable_transfer_error_interrupt(uint32_t dma, uint8_t channel)
DMA Channel Enable Interrupt on Transfer Error.
void dma_channel_reset(uint32_t dma, uint8_t channel)
DMA Channel Reset.
void dma_disable_peripheral_increment_mode(uint32_t dma, uint8_t channel)
DMA Channel Disable Peripheral Increment after Transfer.
void dma_clear_interrupt_flags(uint32_t dma, uint8_t channel, uint32_t interrupts)
DMA Channel Clear Interrupt Flag.
void dma_enable_mem2mem_mode(uint32_t dma, uint8_t channel)
DMA Channel Enable Memory to Memory Transfers.
void dma_enable_half_transfer_interrupt(uint32_t dma, uint8_t channel)
DMA Channel Enable Interrupt on Transfer Half Complete.
void dma_set_peripheral_size(uint32_t dma, uint8_t channel, uint32_t peripheral_size)
DMA Channel Set Peripheral Word Width.
void dma_set_peripheral_address(uint32_t dma, uint8_t channel, uint32_t address)
DMA Channel Set the Peripheral Address.
void dma_set_memory_size(uint32_t dma, uint8_t channel, uint32_t mem_size)
DMA Channel Set Memory Word Width.