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)48void 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)75void 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)92void 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)117void 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)139void 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)167void 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)180void 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)198void 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)215void 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)227uint8_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)243void 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)255void 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)267void 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)279void 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)291void 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)306void 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)321void 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)336void 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)348void 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)360void 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)372void 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)388void 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)400void 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)412void 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)428void 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