1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
|
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file stm32_dma.h
* @brief STM32 DMA helper driver header.
* @note This file requires definitions from the ST STM32 header file
* stm3232f10x.h.
*
* @addtogroup STM32_DMA
* @{
*/
#ifndef _STM32_DMA_H_
#define _STM32_DMA_H_
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/** @brief DMA1 identifier.*/
#define DMA1_ID 0
/** @brief DMA2 identifier.*/
#if STM32_HAS_DMA2 || defined(__DOXYGEN__)
#define DMA2_ID 1
#endif
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief STM32 DMA channel memory structure.
*/
typedef struct {
volatile uint32_t CCR;
volatile uint32_t CNDTR;
volatile uint32_t CPAR;
volatile uint32_t CMAR;
volatile uint32_t dummy;
} stm32_dma_channel_t;
/**
* @brief STM32 DMA subsystem memory structure.
* @note This structure has been redefined here because it is convenient to
* have the channels organized as an array, the ST header does not
* do that.
*/
typedef struct {
volatile uint32_t ISR;
volatile uint32_t IFCR;
stm32_dma_channel_t channels[7];
} stm32_dma_t;
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/** DMA1 registers block numeric address.*/
#define STM32_DMA1_BASE (AHBPERIPH_BASE + 0x0000)
/** Pointer to the DMA1 registers block.*/
#define STM32_DMA1 ((stm32_dma_t *)STM32_DMA1_BASE)
/** Pointer to the DMA1 channel 1 registers block.*/
#define STM32_DMA1_CH1 (&STM32_DMA1->channels[0])
/** Pointer to the DMA1 channel 2 registers block.*/
#define STM32_DMA1_CH2 (&STM32_DMA1->channels[1])
/** Pointer to the DMA1 channel 3 registers block.*/
#define STM32_DMA1_CH3 (&STM32_DMA1->channels[2])
/** Pointer to the DMA1 channel 4 registers block.*/
#define STM32_DMA1_CH4 (&STM32_DMA1->channels[3])
/** Pointer to the DMA1 channel 5 registers block.*/
#define STM32_DMA1_CH5 (&STM32_DMA1->channels[4])
/** Pointer to the DMA1 channel 6 registers block.*/
#define STM32_DMA1_CH6 (&STM32_DMA1->channels[5])
/** Pointer to the DMA1 channel 7 registers block.*/
#define STM32_DMA1_CH7 (&STM32_DMA1->channels[6])
#if STM32_HAS_DMA2 || defined(__DOXYGEN__)
/** DMA2 registers block numeric address.*/
#define STM32_DMA2_BASE (AHBPERIPH_BASE + 0x0400)
/** Pointer to the DMA2 registers block.*/
#define STM32_DMA2 ((stm32_dma_t *)STM32_DMA2_BASE)
/** Pointer to the DMA2 channel 1 registers block.*/
#define STM32_DMA2_CH1 (&STM32_DMA2->channels[0])
/** Pointer to the DMA2 channel 2 registers block.*/
#define STM32_DMA2_CH2 (&STM32_DMA2->channels[1])
/** Pointer to the DMA2 channel 3 registers block.*/
#define STM32_DMA2_CH3 (&STM32_DMA2->channels[2])
/** Pointer to the DMA2 channel 4 registers block.*/
#define STM32_DMA2_CH4 (&STM32_DMA2->channels[3])
/** Pointer to the DMA2 channel 5 registers block.*/
#define STM32_DMA2_CH5 (&STM32_DMA2->channels[4])
#endif
#define STM32_DMA_CHANNEL_1 0 /**< @brief DMA channel 1. */
#define STM32_DMA_CHANNEL_2 1 /**< @brief DMA channel 2. */
#define STM32_DMA_CHANNEL_3 2 /**< @brief DMA channel 3. */
#define STM32_DMA_CHANNEL_4 3 /**< @brief DMA channel 4. */
#define STM32_DMA_CHANNEL_5 4 /**< @brief DMA channel 5. */
#define STM32_DMA_CHANNEL_6 5 /**< @brief DMA channel 6. */
#define STM32_DMA_CHANNEL_7 6 /**< @brief DMA channel 7. */
/**
* @brief Associates a peripheral data register to a DMA channel.
*
* @param[in] dmachp dmachp to a stm32_dma_channel_t structure
* @param[in] cpar value to be written in the CPAR register
*
* @api
*/
#define dmaChannelSetPeripheral(dmachp, cpar) { \
(dmachp)->CPAR = (uint32_t)(cpar); \
}
/**
* @brief DMA channel setup by channel pointer.
* @note This macro does not change the CPAR register because that register
* value does not change frequently, it usually points to a peripheral
* data register.
*
* @param[in] dmachp dmachp to a stm32_dma_channel_t structure
* @param[in] cndtr value to be written in the CNDTR register
* @param[in] cmar value to be written in the CMAR register
* @param[in] ccr value to be written in the CCR register
*
* @api
*/
#define dmaChannelSetup(dmachp, cndtr, cmar, ccr) { \
(dmachp)->CNDTR = (uint32_t)(cndtr); \
(dmachp)->CMAR = (uint32_t)(cmar); \
(dmachp)->CCR = (uint32_t)(ccr); \
}
/**
* @brief DMA channel enable by channel pointer.
*
* @param[in] dmachp dmachp to a stm32_dma_channel_t structure
*
* @api
*/
#define dmaChannelEnable(dmachp) { \
(dmachp)->CCR |= DMA_CCR1_EN; \
}
/**
* @brief DMA channel disable by channel pointer.
*
* @param[in] dmachp dmachp to a stm32_dma_channel_t structure
*
* @api
*/
#define dmaChannelDisable(dmachp) { \
(dmachp)->CCR = 0; \
}
/**
* @brief DMA channel setup by channel ID.
* @note This macro does not change the CPAR register because that register
* value does not change frequently, it usually points to a peripheral
* data register.
* @note Channels are numbered from 0 to 6, use the appropriate macro
* as parameter.
*
* @param[in] dmap pointer to a stm32_dma_t structure
* @param[in] ch channel number
* @param[in] cndtr value to be written in the CNDTR register
* @param[in] cmar value to be written in the CMAR register
* @param[in] ccr value to be written in the CCR register
*
* @api
*/
#define dmaSetupChannel(dmap, ch, cndtr, cmar, ccr) { \
dmaChannelSetup(&(dmap)->channels[ch], (cndtr), (cmar), (ccr)); \
}
/**
* @brief DMA channel enable by channel ID.
* @note Channels are numbered from 0 to 6, use the appropriate macro
* as parameter.
*
* @param[in] dmap pointer to a stm32_dma_t structure
* @param[in] ch channel number
*
* @api
*/
#define dmaEnableChannel(dmap, ch) { \
dmaChannelEnable(&(dmap)->channels[ch]); \
}
/**
* @brief DMA channel disable by channel ID.
* @note Channels are numbered from 0 to 6, use the appropriate macro
* as parameter.
*
* @param[in] dmap pointer to a stm32_dma_t structure
* @param[in] ch channel number
*
* @api
*/
#define dmaDisableChannel(dmap, ch) { \
dmaChannelDisable(&(dmap)->channels[ch]); \
}
/**
* @brief DMA channel interrupt sources clear.
* @details Sets the appropriate CGIF bit into the IFCR register in order to
* withdraw all the pending interrupt bits from the ISR register.
* @note Channels are numbered from 0 to 6, use the appropriate macro
* as parameter.
*
* @param[in] dmap pointer to a stm32_dma_t structure
* @param[in] ch channel number
*
* @api
*/
#define dmaClearChannel(dmap, ch){ \
(dmap)->IFCR = 1 << ((ch) * 4); \
}
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void dmaInit(void);
void dmaEnable(uint32_t dma);
void dmaDisable(uint32_t dma);
#ifdef __cplusplus
}
#endif
#endif /* _STM32_DMA_H_ */
/** @} */
|