1 /*!
2  * @file        apm32f4xx_dmc.c
3  *
4  * @brief       This file contains all the functions for the DMC controler peripheral
5  *
6  * @version     V1.0.2
7  *
8  * @date        2022-06-23
9  *
10  * @attention
11  *
12  *  Copyright (C) 2021-2022 Geehy Semiconductor
13  *
14  *  You may not use this file except in compliance with the
15  *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
16  *
17  *  The program is only for reference, which is distributed in the hope
18  *  that it will be usefull and instructional for customers to develop
19  *  their software. Unless required by applicable law or agreed to in
20  *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
21  *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
22  *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
23  *  and limitations under the License.
24  */
25 
26 #include "apm32f4xx_dmc.h"
27 
28 /** @addtogroup APM32F4xx_StdPeriphDriver
29   @{
30 */
31 
32 /** @defgroup DMC_Driver
33   * @brief DMC driver modules
34   @{
35 */
36 
37 /** @defgroup DMC_Functions
38   @{
39 */
40 
41 /*!
42  * @brief     DMC controler configuration
43  *
44  * @param     dmcConfig: pointer to a DMC_Config_T structure
45  *
46  * @retval    None
47  */
DMC_Config(DMC_Config_T * dmcConfig)48 void DMC_Config(DMC_Config_T *dmcConfig)
49 {
50     DMC->SW_B.MCSW = 1;
51     while (!DMC->CTRL1_B.INIT);
52 
53     DMC->CFG_B.BAWCFG = dmcConfig->bankWidth;
54     DMC->CFG_B.RAWCFG = dmcConfig->rowWidth;
55     DMC->CFG_B.CAWCFG = dmcConfig->colWidth;
56 
57     DMC->CTRL2_B.CPHACFG = dmcConfig->clkPhase;
58 
59     DMC_ConfigTiming(&dmcConfig->timing);
60 
61     DMC->CTRL1_B.MODESET = 1;
62     while (!DMC->CTRL1_B.MODESET);
63 
64     DMC->CTRL2_B.RDDEN = 1;
65     DMC->CTRL2_B.RDDCFG = 7;
66 }
67 
68 /*!
69  * @brief     Fills each dmcConfig member with its default value
70  *
71  * @param     dmcConfig: pointer to a DMC_Config_T structure
72  *
73  * @retval    None
74  */
DMC_ConfigStructInit(DMC_Config_T * dmcConfig)75 void DMC_ConfigStructInit(DMC_Config_T *dmcConfig)
76 {
77     dmcConfig->bankWidth   = DMC_BANK_WIDTH_2;
78     dmcConfig->clkPhase    = DMC_CLK_PHASE_REVERSE;
79     dmcConfig->colWidth    = DMC_COL_WIDTH_10;
80     dmcConfig->rowWidth    = DMC_ROW_WIDTH_13;
81 
82     DMC_ConfigTimingStructInit(&dmcConfig->timing);
83 }
84 
85 /*!
86  * @brief     Timing configuration
87  *
88  * @param     timingConfig: pointer to a DMC_TimingConfig_T structure
89  *
90  * @retval    None
91  */
DMC_ConfigTiming(DMC_TimingConfig_T * timingConfig)92 void DMC_ConfigTiming(DMC_TimingConfig_T *timingConfig)
93 {
94     DMC->TIM0_B.RASMINTSEL = timingConfig->tRAS;
95     DMC->TIM0_B.DTIMSEL    = timingConfig->tRCD;
96     DMC->TIM0_B.PCPSEL     = timingConfig->tRP;
97     DMC->TIM0_B.WRTIMSEL   = timingConfig->tWR;
98     DMC->TIM0_B.ARPSEL     = timingConfig->tARP;
99     DMC->TIM0_B.ATACP      = timingConfig->tCMD;
100 
101     DMC->TIM0_B.CASLSEL0  =  timingConfig->latencyCAS & 0x03;
102     DMC->TIM0_B.ECASLSEL1 = (timingConfig->latencyCAS >> 2) & 0x01;
103 
104     DMC->TIM0_B.XSR0  =  timingConfig->tXSR & 0X0F;
105     DMC->TIM0_B.EXSR1 = (timingConfig->tXSR >> 4) & 0X1F;
106 
107     DMC->REF_B.RCYCCFG = timingConfig->tRFP;
108 }
109 
110 /*!
111  * @brief     Fills each config member with its default value
112  *
113  * @param     timingConfig: pointer to a DMC_TimingConfig_T structure
114  *
115  * @retval    None
116  */
DMC_ConfigTimingStructInit(DMC_TimingConfig_T * timingConfig)117 void DMC_ConfigTimingStructInit(DMC_TimingConfig_T *timingConfig)
118 {
119     timingConfig->latencyCAS = DMC_CAS_LATENCY_3;
120     timingConfig->tARP = DMC_AUTO_REFRESH_10;
121     timingConfig->tRAS = DMC_RAS_MINIMUM_5;
122     timingConfig->tCMD = DMC_ATA_CMD_7;
123     timingConfig->tRCD = DMC_DELAY_TIME_2;
124     timingConfig->tRP  = DMC_PRECHARGE_2;
125     timingConfig->tWR  = DMC_NEXT_PRECHARGE_2;
126     timingConfig->tXSR = 6;
127     timingConfig->tRFP = 0xC3;
128 }
129 
130 /*!
131  * @brief     Set number of bank bits
132  *
133  * @param     bankWidth: Specifies the bank bits number
134  *                       This parameter can be one of the following values:
135  *                         @arg DMC_BANK_WIDTH_1 : Set bank address widen to 1-bit
136  *                         @arg DMC_BANK_WIDTH_2 : Set bank address widen to 2-bit
137  * @retval    None
138  */
DMC_ConfigBankWidth(DMC_BANK_WIDTH_T bankWidth)139 void DMC_ConfigBankWidth(DMC_BANK_WIDTH_T bankWidth)
140 {
141     DMC->CFG_B.BAWCFG = bankWidth;
142 }
143 
144 /*!
145  * @brief     Set address bus width
146  *
147  * @param     rowWidth: Specifies the row address bits number
148  *                        This parameter can be one of the following values:
149  *                        @arg DMC_ROW_WIDTH_11 : Set row address width to 11-bit
150  *                        @arg DMC_ROW_WIDTH_12 : Set row address width to 12-bit
151  *                        @arg DMC_ROW_WIDTH_13 : Set row address width to 13-bit
152  *                        @arg DMC_ROW_WIDTH_14 : Set row address width to 14-bit
153  *                        @arg DMC_ROW_WIDTH_15 : Set row address width to 15-bit
154  *                        @arg DMC_ROW_WIDTH_16 : Set row address width to 16-bit
155  * @param     colWidth: Specifies the column address bits number
156  *                        This parameter can be one of the following values:
157  *                        @arg DMC_COL_WIDTH_8 : Set column address width to 8-bit
158  *                        @arg DMC_COL_WIDTH_9 : Set column address width to 9-bit
159  *                        @arg DMC_COL_WIDTH_10 : Set column address width to 10-bit
160  *                        @arg DMC_COL_WIDTH_11 : Set column address width to 11-bit
161  *                        @arg DMC_COL_WIDTH_12 : Set column address width to 12-bit
162  *                        @arg DMC_COL_WIDTH_13 : Set column address width to 13-bit
163  *                        @arg DMC_COL_WIDTH_14 : Set column address width to 14-bit
164  *                        @arg DMC_COL_WIDTH_15 : Set column address width to 15-bit
165  * @retval    None
166  */
DMC_ConfigAddrWidth(DMC_ROW_WIDTH_T rowWidth,DMC_COL_WIDTH_T colWidth)167 void DMC_ConfigAddrWidth(DMC_ROW_WIDTH_T rowWidth, DMC_COL_WIDTH_T colWidth)
168 {
169     DMC->CFG_B.RAWCFG = rowWidth;
170     DMC->CFG_B.CAWCFG = colWidth;
171 }
172 
173 /*!
174  * @brief     Set stable time after power up
175  *
176  * @param     stableTime: Numper of the clock, can be 0x0000 to 0xFFFF
177  *
178  * @retval    None
179  */
DMC_ConfigStableTimePowerup(uint16_t stableTime)180 void DMC_ConfigStableTimePowerup(uint16_t stableTime)
181 {
182     DMC->TIM1_B.STBTIM = stableTime;
183 }
184 
185 /*!
186  * @brief     Number of auto-refreshes during initialization
187  *
188  * @param     num: Number of auto-refreshes can 1 to 16
189  *                 This parameter can be one of the following values:
190  *                      @arg DMC_AUTO_REFRESH_1 : Set auto-refresh period to 1 clock
191  *                      @arg DMC_AUTO_REFRESH_2 : Set auto-refresh period to 2 clock
192  *                           ......                          ......
193  *                      @arg DMC_AUTO_REFRESH_15 : Set auto-refresh period to 15 clock
194  *                      @arg DMC_AUTO_REFRESH_16 : Set auto-refresh period to 16 clock
195  *
196  * @retval    None
197  */
DMC_ConfigAutoRefreshNumDuringInit(DMC_AUTO_REFRESH_T num)198 void DMC_ConfigAutoRefreshNumDuringInit(DMC_AUTO_REFRESH_T num)
199 {
200     DMC->TIM1_B.ARNUMCFG = num;
201 }
202 
203 /*!
204  * @brief     Number of DMC internal banks to be open at any time;
205  *
206  * @param     num:  Number of banks can 1 to 16
207  *                  This parameter can be one of the following values:
208  *                       @arg DMC_BANK_NUMBER_1 : Set 1 bank be opened
209  *                       @arg DMC_BANK_NUMBER_2 : Set 2 bank be opened
210  *                            ......                   ......
211  *                       @arg DMC_BANK_NUMBER_15 : Set 15 bank be opened
212  *                       @arg DMC_BANK_NUMBER_16 : Set 16 bank be opened
213  * @retval    None
214  */
DMC_ConfigOpenBank(DMC_BANK_NUMBER_T num)215 void DMC_ConfigOpenBank(DMC_BANK_NUMBER_T num)
216 {
217     DMC->CTRL1_B.BANKNUMCFG = num;
218 }
219 
220 /*!
221  * @brief     Read self-refresh status
222  *
223  * @param     None
224  *
225  * @retval    The status of self-refresh (SET or RESET)
226  */
DMC_ReadSelfRefreshStatus(void)227 uint8_t DMC_ReadSelfRefreshStatus(void)
228 {
229     uint8_t ret;
230 
231     ret = DMC->CTRL1_B.SRMFLG ? SET : RESET;
232 
233     return ret;
234 }
235 
236 /*!
237  * @brief     Set update mode bit
238  *
239  * @param     None
240  *
241  * @retval    None
242  */
DMC_EnableUpdateMode(void)243 void DMC_EnableUpdateMode(void)
244 {
245     DMC->CTRL1_B.MODESET = 1;
246 }
247 
248 /*!
249  * @brief     Enter power down mode
250  *
251  * @param     None
252  *
253  * @retval    None
254  */
DMC_EnterPowerdownMode(void)255 void DMC_EnterPowerdownMode(void)
256 {
257     DMC->CTRL1_B.PDMEN = 1;
258 }
259 
260 /*!
261  * @brief     Exit self-refresh mode
262  *
263  * @param     None
264  *
265  * @retval    None
266  */
DMC_EixtSlefRefreshMode(void)267 void DMC_EixtSlefRefreshMode(void)
268 {
269     DMC->CTRL1_B.SRMEN = 0;
270 }
271 
272 /*!
273  * @brief     Enter self-refresh mode
274  *
275  * @param     None
276  *
277  * @retval    None
278  */
DMC_EnterSlefRefreshMode(void)279 void DMC_EnterSlefRefreshMode(void)
280 {
281     DMC->CTRL1_B.SRMEN = 1;
282 }
283 
284 /*!
285  * @brief     Init DMC
286  *
287  * @param     None
288  *
289  * @retval    None
290  */
DMC_EnableInit(void)291 void DMC_EnableInit(void)
292 {
293     DMC->CTRL1_B.INIT = 1;
294 }
295 
296 /*!
297  * @brief     Set refresh type before enter self-refresh
298  *
299  * @param     refresh: Specifies the refresh type
300  *                The parameter can be one of following values:
301  *                @arg DMC_REFRESH_ROW_ONE: Refresh one row
302  *                @arg DMC_REFRESH_ROW_ALL: Refresh all row
303  *
304  * @retval    None
305  */
DMC_ConfigFullRefreshBeforeSR(DMC_REFRESH_T refresh)306 void DMC_ConfigFullRefreshBeforeSR(DMC_REFRESH_T refresh)
307 {
308     DMC->CTRL1_B.FRBSREN = refresh;
309 }
310 
311 /*!
312  * @brief     Set refresh type after exit self-refresh
313  *
314  * @param     refresh: Specifies the refresh type
315  *                The parameter can be one of following values:
316  *                @arg DMC_REFRESH_ROW_ONE: Refresh one row
317  *                @arg DMC_REFRESH_ROW_ALL: Refresh all row
318  *
319  * @retval    None
320  */
DMC_ConfigFullRefreshAfterSR(DMC_REFRESH_T refresh)321 void DMC_ConfigFullRefreshAfterSR(DMC_REFRESH_T refresh)
322 {
323     DMC->CTRL1_B.FRASREN = refresh;
324 }
325 
326 /*!
327  * @brief     Config precharge type
328  *
329  * @param     precharge: Specifies the precharge type
330  *                The parameter can be one of following values:
331  *                @arg DMC_PRECHARGE_IM:    Immediate precharge
332  *                @arg DMC_PRECHARGE_DELAY: Delayed precharge
333  *
334  * @retval    None
335  */
DMC_ConfigPrechargeType(DMC_PRECHARE_T precharge)336 void DMC_ConfigPrechargeType(DMC_PRECHARE_T precharge)
337 {
338     DMC->CTRL1_B.PCACFG = precharge;
339 }
340 
341 /*!
342  * @brief     Config refresh period
343  *
344  * @param     period:   Specifies the refresh period, can be 0x0000 to 0xFFFF
345  *
346  * @retval    None
347  */
DMC_ConfigRefreshPeriod(uint16_t period)348 void DMC_ConfigRefreshPeriod(uint16_t period)
349 {
350     DMC->REF_B.RCYCCFG = period;
351 }
352 
353 /*!
354  * @brief     Enable DMC controler
355  *
356  * @param     None
357  *
358  * @retval    None
359  */
DMC_Enable(void)360 void DMC_Enable(void)
361 {
362     DMC->SW_B.MCSW = 1;
363 }
364 
365 /*!
366  * @brief     Disable DMC controler
367  *
368  * @param     None
369  *
370  * @retval    None
371  */
DMC_Disable(void)372 void DMC_Disable(void)
373 {
374     DMC->SW_B.MCSW = 0;
375 }
376 
377 /*!
378  * @brief     Set DMC clock phase
379  *
380  * @param     clkPhase: Specifies clock phase
381  *                The parameter can be one of following values:
382  *                @arg DMC_CLK_PHASE_NORMAL: Clock phase is normal
383  *                @arg DMC_CLK_PHASE_REVERSE: Clock phase is reverse
384  *
385  * @retval    None
386  *
387  */
DMC_ConfigClockPhase(DMC_CLK_PHASE_T clkPhase)388 void DMC_ConfigClockPhase(DMC_CLK_PHASE_T clkPhase)
389 {
390     DMC->CTRL2_B.CPHACFG = clkPhase;
391 }
392 
393 /*!
394  * @brief     Enable Accelerate Module
395  *
396  * @param     None
397  *
398  * @retval    None
399  */
DMC_EnableAccelerateModule(void)400 void DMC_EnableAccelerateModule(void)
401 {
402     DMC->CTRL2_B.BUFFEN = BIT_SET;
403 }
404 
405 /*!
406  * @brief     Disable Accelerate Module
407  *
408  * @param     None
409  *
410  * @retval    None
411  */
DMC_DisableAccelerateModule(void)412 void DMC_DisableAccelerateModule(void)
413 {
414     DMC->CTRL2_B.BUFFEN = BIT_RESET;
415 }
416 
417 /*!
418  * @brief     Set DMC WRAP burst
419  *
420  * @param     burst: WRAP burst Type Selection
421  *                The parameter can be one of following values:
422  *                @arg DMC_WRAPB_4: wrap4 burst transfer
423  *                @arg DMC_WRAPB_8: wrap8 burst transfer
424  *
425  * @retval    None
426  *
427  */
DMC_ConfigWRAPB(DMC_WRPB_T burst)428 void DMC_ConfigWRAPB(DMC_WRPB_T burst)
429 {
430     DMC->CTRL2_B.WRPBSEL = burst;
431 }
432 
433 /**@} end of group DMC_Functions */
434 /**@} end of group DMC_Driver */
435 /**@} end of group APM32F4xx_StdPeriphDriver */
436