aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/platforms/STM32/stm32_dma.h
blob: 806f79c56de9d57726014af6f3fcc479f8f62e58 (plain)
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_ */

/** @} */