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