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