1 ////////////////////////////////////////////////////////////////////////////////
2 /// @file     hal_dma.c
3 /// @author   AE TEAM
4 /// @brief    THIS FILE PROVIDES ALL THE DMA FIRMWARE FUNCTIONS.
5 ////////////////////////////////////////////////////////////////////////////////
6 /// @attention
7 ///
8 /// THE EXISTING FIRMWARE IS ONLY FOR REFERENCE, WHICH IS DESIGNED TO PROVIDE
9 /// CUSTOMERS WITH CODING INFORMATION ABOUT THEIR PRODUCTS SO THEY CAN SAVE
10 /// TIME. THEREFORE, MINDMOTION SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT OR
11 /// CONSEQUENTIAL DAMAGES ABOUT ANY CLAIMS ARISING OUT OF THE CONTENT OF SUCH
12 /// HARDWARE AND/OR THE USE OF THE CODING INFORMATION CONTAINED HEREIN IN
13 /// CONNECTION WITH PRODUCTS MADE BY CUSTOMERS.
14 ///
15 /// <H2><CENTER>&COPY; COPYRIGHT MINDMOTION </CENTER></H2>
16 ////////////////////////////////////////////////////////////////////////////////
17 
18 
19 
20 
21 
22 
23 // Define to prevent recursive inclusion
24 #define _HAL_DMA_C_
25 
26 // Files includes
27 #include "types.h"
28 #include "hal_dma.h"
29 
30 ////////////////////////////////////////////////////////////////////////////////
31 /// @addtogroup MM32_Hardware_Abstract_Layer
32 /// @{
33 
34 ////////////////////////////////////////////////////////////////////////////////
35 /// @addtogroup DMA_HAL
36 /// @{
37 
38 ////////////////////////////////////////////////////////////////////////////////
39 /// @addtogroup DMA_Exported_Functions
40 /// @{
41 
42 ////////////////////////////////////////////////////////////////////////////////
43 /// @brief  Deinitializes the DMA Channeln registers to their default reset
44 ///         values.
45 /// @param   select the DMA Channel.
46 /// @retval None.
47 ////////////////////////////////////////////////////////////////////////////////
DMA_DeInit(DMA_Channel_TypeDef * channel)48 void DMA_DeInit(DMA_Channel_TypeDef* channel)
49 {
50     channel->CCR &= ~DMA_CCR_EN;
51     channel->CCR   = 0;
52     channel->CNDTR = 0;
53     channel->CPAR  = 0;
54     channel->CMAR  = 0;
55     if((*(vu32*)&channel) >= (*(vu32*)DMA2_Channel1_BASE)) {
56         DMA2->IFCR |= (u32)0x0F << (((*(vu32*)&channel & (u32)0xff) - 8) / 5);
57     }
58     else {
59         DMA1->IFCR |= (u32)0x0F << (((*(vu32*)&channel & (u32)0xff) - 8) / 5);
60     }
61 }
62 
63 ////////////////////////////////////////////////////////////////////////////////
64 /// @brief  Initializes the DMA Channeln according to the specified
65 ///         parameters in the init_struct.
66 /// @param  select the DMA Channel.
67 /// @param  init_struct: pointer to a DMA_InitTypeDef structure that
68 ///         contains the configuration information for the specified DMA
69 ///         Channel.
70 /// @retval None.
71 ////////////////////////////////////////////////////////////////////////////////
DMA_Init(DMA_Channel_TypeDef * channel,DMA_InitTypeDef * init_struct)72 void DMA_Init(DMA_Channel_TypeDef* channel, DMA_InitTypeDef* init_struct)
73 {
74     MODIFY_REG(
75         channel->CCR,
76         (DMA_CCR_DIR | DMA_CCR_CIRC | DMA_CCR_PINC | DMA_CCR_MINC | DMA_CCR_PSIZE | DMA_CCR_MSIZE | DMA_CCR_PL | DMA_CCR_M2M),
77         ((u32)init_struct->DMA_DIR | (u32)init_struct->DMA_Mode | (u32)init_struct->DMA_PeripheralInc |
78          (u32)init_struct->DMA_MemoryInc | (u32)init_struct->DMA_PeripheralDataSize | (u32)init_struct->DMA_MemoryDataSize |
79          (u32)init_struct->DMA_Priority | (u32)init_struct->DMA_M2M));
80 
81     MODIFY_REG(channel->CCR, DMA_CCR_ARE, init_struct->DMA_Auto_reload);
82     channel->CNDTR = init_struct->DMA_BufferSize;
83     channel->CPAR  = init_struct->DMA_PeripheralBaseAddr;
84     channel->CMAR  = init_struct->DMA_MemoryBaseAddr;
85 }
86 
87 ////////////////////////////////////////////////////////////////////////////////
88 /// @brief  Fills each init_struct member with its default value.
89 /// @param  init_struct : pointer to a DMA_InitTypeDef structure which will
90 ///         be initialized.
91 /// @retval None.
92 ////////////////////////////////////////////////////////////////////////////////
DMA_StructInit(DMA_InitTypeDef * init_struct)93 void DMA_StructInit(DMA_InitTypeDef* init_struct)
94 {
95     init_struct->DMA_PeripheralBaseAddr = 0;
96     init_struct->DMA_MemoryBaseAddr     = 0;
97     init_struct->DMA_DIR                = DMA_DIR_PeripheralSRC;
98     init_struct->DMA_BufferSize         = 0;
99     init_struct->DMA_PeripheralInc      = DMA_PeripheralInc_Disable;
100     init_struct->DMA_MemoryInc          = DMA_MemoryInc_Disable;
101     init_struct->DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
102     init_struct->DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte;
103     init_struct->DMA_Mode               = DMA_Mode_Normal;
104     init_struct->DMA_Priority           = DMA_Priority_Low;
105     init_struct->DMA_M2M                = DMA_M2M_Disable;
106 
107     init_struct->DMA_Auto_reload         = DMA_Auto_Reload_Disable;
108 }
109 
110 ////////////////////////////////////////////////////////////////////////////////
111 /// @brief  Enables or disables the specified DMA Channeln.
112 /// @param  channel: select the DMA Channel.
113 /// @param  state: new state of the DMA Channeln.
114 ///         This parameter can be: ENABLE or DISABLE.
115 /// @retval None.
116 ////////////////////////////////////////////////////////////////////////////////
DMA_Cmd(DMA_Channel_TypeDef * channel,FunctionalState state)117 void DMA_Cmd(DMA_Channel_TypeDef* channel, FunctionalState state)
118 {
119     MODIFY_REG(channel->CCR, DMA_CCR_EN, state << DMA_CCR_EN_Pos);
120 }
121 
122 ////////////////////////////////////////////////////////////////////////////////
123 /// @brief  Enables or disables the specified DMA Channeln interrupts.
124 /// @param  channel: select the DMA Channel.
125 /// @param  it: specifies the DMA interrupts sources to be enabled
126 ///         or disabled.
127 ///         This parameter can be any combination of the following values:
128 ///    @arg DMA_IT_TC:  Transfer complete interrupt mask
129 ///    @arg DMA_IT_HT:  Half transfer interrupt mask
130 ///    @arg DMA_IT_TE:  Transfer error interrupt mask
131 /// @param  state: new state of the specified DMA interrupts.
132 ///         This parameter can be: ENABLE or DISABLE.
133 /// @retval None.
134 ////////////////////////////////////////////////////////////////////////////////
DMA_ITConfig(DMA_Channel_TypeDef * channel,DMA_Interrupt_EN_TypeDef it,FunctionalState state)135 void DMA_ITConfig(DMA_Channel_TypeDef* channel, DMA_Interrupt_EN_TypeDef it, FunctionalState state)
136 {
137     (state) ? (channel->CCR |= it) : (channel->CCR &= ~it);
138 }
139 
140 ////////////////////////////////////////////////////////////////////////////////
141 /// @brief  Sets the number of data units in the select the DMA Channel .
142 /// @param  channel: select the DMA Channel
143 /// @param  DataNumber: The number of data units in the current DMAy Channelx
144 ///         transfer.
145 /// @note   This function can only be used when the DMAy_Channelx is disabled.
146 /// @retval None.
147 ////////////////////////////////////////////////////////////////////////////////
DMA_SetCurrDataCounter(DMA_Channel_TypeDef * channel,u16 length)148 void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* channel, u16 length)
149 {
150     channel->CNDTR = length;
151 }
152 ////////////////////////////////////////////////////////////////////////////////
153 /// @brief  Returns the number of remaining data units in the current
154 ///         DMA Channeln transfer.
155 /// @param  channel: select the DMA Channel.
156 /// @retval The number of remaining data units in the current DMA Channeln
157 ///         transfer.
158 ////////////////////////////////////////////////////////////////////////////////
DMA_GetCurrDataCounter(DMA_Channel_TypeDef * channel)159 u16 DMA_GetCurrDataCounter(DMA_Channel_TypeDef* channel)
160 {
161     return channel->CNDTR;
162 }
163 
164 ////////////////////////////////////////////////////////////////////////////////
165 /// @brief  Checks whether the specified DMA Channeln flag is set or not.
166 /// @param  flag: specifies the flag to check.
167 ///         This parameter can be one of the following values:
168 ///    @arg DMA1_FLAG_GLn: DMA1 Channeln global flag(n = 1..7).
169 ///    @arg DMA1_FLAG_TCn: DMA1 Channeln transfer complete flag(n = 1..7).
170 ///    @arg DMA1_FLAG_HTn: DMA1 Channeln half transfer flag(n = 1..7).
171 ///    @arg DMA1_FLAG_TEn: DMA1 Channeln transfer error flag(n = 1..7).
172 ///    @arg DMA2_FLAG_GLn: DMA1 Channeln global flag(n = 1..5).
173 ///    @arg DMA2_FLAG_TCn: DMA1 Channeln transfer complete flag(n = 1..5).
174 ///    @arg DMA2_FLAG_HTn: DMA1 Channeln half transfer flag(n = 1..5).
175 ///    @arg DMA2_FLAG_TEn: DMA1 Channeln transfer error flag(n = 1..5).
176 /// @retval The new state of DMAy_FLAG (SET or RESET).
177 ////////////////////////////////////////////////////////////////////////////////
DMA_GetFlagStatus(DMA_Flags_TypeDef flag)178 FlagStatus DMA_GetFlagStatus(DMA_Flags_TypeDef flag)
179 {
180     if(flag >= DMA2_FLAG_GL1 ) {
181         return (DMA2->ISR & flag) ? SET : RESET;
182     }
183     return (DMA1->ISR & flag) ? SET : RESET;
184 }
185 
186 ////////////////////////////////////////////////////////////////////////////////
187 /// @brief  Clears the DMA Channeln's pending flags.
188 /// @param  flag: specifies the flag to clear.
189 ///         This parameter can be any combination (for the same DMA) of the
190 ///         following values:
191 ///    @arg DMA1_FLAG_GLn: DMA1 Channeln global flag(n = 1..7).
192 ///    @arg DMA1_FLAG_TCn: DMA1 Channeln transfer complete flag(n = 1..7).
193 ///    @arg DMA1_FLAG_HTn: DMA1 Channeln half transfer flag(n = 1..7).
194 ///    @arg DMA1_FLAG_TEn: DMA1 Channeln transfer error flag(n = 1..7).
195 ///    @arg DMA2_FLAG_GLn: DMA1 Channeln global flag(n = 1..5).
196 ///    @arg DMA2_FLAG_TCn: DMA1 Channeln transfer complete flag(n = 1..5).
197 ///    @arg DMA2_FLAG_HTn: DMA1 Channeln half transfer flag(n = 1..5).
198 ///    @arg DMA2_FLAG_TEn: DMA1 Channeln transfer error flag(n = 1..5).
199 /// @retval None.
200 ////////////////////////////////////////////////////////////////////////////////
DMA_ClearFlag(DMA_Flags_TypeDef flag)201 void DMA_ClearFlag(DMA_Flags_TypeDef flag)
202 {
203     if(flag >= DMA2_FLAG_GL1 ) {
204         DMA2->IFCR = flag;
205         return ;
206     }
207     DMA1->IFCR = flag;
208 }
209 
210 ////////////////////////////////////////////////////////////////////////////////
211 /// @brief  Checks whether the specified DMA Channeln interrupt has occurred or
212 /// not.
213 /// @param  it: specifies the DMA interrupt source to check.
214 ///         This parameter can be one of the following values:
215 ///    @arg DMA1_IT_GLn: DMA1 Channeln global interrupt(n = 1..7).
216 ///    @arg DMA1_IT_TCn: DMA1 Channeln transfer complete interrupt(n = 1..7).
217 ///    @arg DMA1_IT_HTn: DMA1 Channeln half transfer interrupt(n = 1..7).
218 ///    @arg DMA1_IT_TEn: DMA1 Channeln transfer error interrupt(n = 1..7).
219 ///    @arg DMA2_IT_GLn: DMA1 Channeln global flag(n = 1..5).
220 ///    @arg DMA2_IT_TCn: DMA1 Channeln transfer complete flag(n = 1..5).
221 ///    @arg DMA2_IT_HTn: DMA1 Channeln half transfer flag(n = 1..5).
222 ///    @arg DMA2_IT_TEn: DMA1 Channeln transfer error flag(n = 1..5).
223 /// @retval  The new state of DMAy_IT (SET or RESET).
224 ////////////////////////////////////////////////////////////////////////////////
DMA_GetITStatus(DMA_Interrupts_TypeDef it)225 ITStatus DMA_GetITStatus(DMA_Interrupts_TypeDef it)
226 {
227     if(it >= DMA2_IT_GL1 ) {
228         return (DMA2->ISR & it) ? SET : RESET;
229     }
230     return (DMA1->ISR & it) ? SET : RESET;
231 }
232 
233 ////////////////////////////////////////////////////////////////////////////////
234 /// @brief  Clears the DMA Channeln's interrupt pending bits.
235 /// @param  it: specifies the DMA interrupt pending bit to clear.
236 ///         This parameter can be any combination (for the same DMA) of the
237 ///         following values:
238 ///    @arg DMA1_IT_GLn: DMA1 Channeln global interrupt(n = 1..7).
239 ///    @arg DMA1_IT_TCn: DMA1 Channeln transfer complete interrupt(n = 1..7).
240 ///    @arg DMA1_IT_HTn: DMA1 Channeln half transfer interrupt(n = 1..7).
241 ///    @arg DMA1_IT_TEn: DMA1 Channeln transfer error interrupt(n = 1..7).
242 ///    @arg DMA2_IT_GLn: DMA1 Channeln global flag(n = 1..5).
243 ///    @arg DMA2_IT_TCn: DMA1 Channeln transfer complete flag(n = 1..5).
244 ///    @arg DMA2_IT_HTn: DMA1 Channeln half transfer flag(n = 1..5).
245 ///    @arg DMA2_IT_TEn: DMA1 Channeln transfer error flag(n = 1..5).
246 /// @retval None.
247 ////////////////////////////////////////////////////////////////////////////////
DMA_ClearITPendingBit(DMA_Interrupts_TypeDef it)248 void DMA_ClearITPendingBit(DMA_Interrupts_TypeDef it)
249 {
250     if(it >= DMA2_IT_GL1 ) {
251         DMA2->IFCR = it;
252         return ;
253     }
254     DMA1->IFCR = it;
255 }
256 
257 ////////////////////////////////////////////////////////////////////////////////
258 /// @brief  Set the DMA Channeln's Peripheral address.
259 /// @param  channel : where n can be 1 to 7 for DMA1 to select the DMA Channel.
260 /// @param  address : DMA Peripheral address.
261 /// @retval None.
262 ////////////////////////////////////////////////////////////////////////////////
exDMA_SetPeripheralAddress(DMA_Channel_TypeDef * channel,u32 address)263 void exDMA_SetPeripheralAddress(DMA_Channel_TypeDef* channel, u32 address)
264 {
265     channel->CPAR = address;
266 }
267 
268 ////////////////////////////////////////////////////////////////////////////////
269 /// @brief  Set the DMA Channeln's Peripheral address.
270 /// @param  channel : select the DMA Channel.
271 /// @param  length : Transmit lengths.
272 /// @retval None.
273 ////////////////////////////////////////////////////////////////////////////////
exDMA_SetTransmitLen(DMA_Channel_TypeDef * channel,u16 length)274 void exDMA_SetTransmitLen(DMA_Channel_TypeDef* channel, u16 length)
275 {
276     channel->CNDTR = length;
277 }
278 
279 ////////////////////////////////////////////////////////////////////////////////
280 /// @brief  Set the DMA Channeln's Peripheral address.
281 /// @param  channel :select the DMA Channel.
282 /// @param  address : DMA memery address.
283 /// @retval None.
284 ////////////////////////////////////////////////////////////////////////////////
exDMA_SetMemoryAddress(DMA_Channel_TypeDef * channel,u32 address)285 void exDMA_SetMemoryAddress(DMA_Channel_TypeDef* channel, u32 address)
286 {
287     channel->CMAR = address;
288 }
289 
290 ////////////////////////////////////////////////////////////////////////////////
291 /// @brief  Clears the DMA Channeln's interrupt pending bits.
292 /// @param  it: specifies the DMA interrupt pending bit to clear.
293 ///         This parameter can be any combination (for the same DMA) of the
294 ///         following values:
295 ///    @arg DMA1_IT_GLn: DMA1 Channeln global interrupt(n = 1..7).
296 ///    @arg DMA1_IT_TCn: DMA1 Channeln transfer complete interrupt(n = 1..7).
297 ///    @arg DMA1_IT_HTn: DMA1 Channeln half transfer interrupt(n = 1..7).
298 ///    @arg DMA1_IT_TEn: DMA1 Channeln transfer error interrupt(n = 1..7).
299 ///    @arg DMA2_IT_GLn: DMA1 Channeln global flag(n = 1..5).
300 ///    @arg DMA2_IT_TCn: DMA1 Channeln transfer complete flag(n = 1..5).
301 ///    @arg DMA2_IT_HTn: DMA1 Channeln half transfer flag(n = 1..5).
302 ///    @arg DMA2_IT_TEn: DMA1 Channeln transfer error flag(n = 1..5).
303 /// @retval None.
304 ////////////////////////////////////////////////////////////////////////////////
exDMA_ClearITPendingBit(DMA_Channel_TypeDef * channel,u32 it)305 void exDMA_ClearITPendingBit(DMA_Channel_TypeDef* channel, u32 it)
306 {
307     if(it >= DMA2_IT_GL1 ) {
308         DMA2->IFCR |= (u32)0x0F << (((*(vu32*)&channel & (u32)0xff) - 8) / 5);
309         DMA2->IFCR = it;
310         return ;
311     }
312     DMA1->IFCR |= (u32)0x0F << (((*(vu32*)&channel & (u32)0xff) - 8) / 5);
313     DMA1->IFCR = it;
314 }
315 /// @}
316 
317 /// @}
318 
319 /// @}
320