Embedded AM335x DDR2初始EMIF

Embedded AM335x DDR2初始EMIF,embedded,bare-metal,cortex-a8,Embedded,Bare Metal,Cortex A8,在一个裸机项目中,我在初始化德州仪器公司ICE评估板上DDR2内存的EMIF和DDR_PHY时遇到问题。 我根据StarterWare引导加载程序示例中的序列编写了一个init序列。然而,我无法让DDR工作 控制器贯穿整个过程,但DDR在调试器中执行的每一步看起来都是随机的。我正在监视0x8000000。使用调试器写入此区域也不起作用。状态寄存器显示PHY未就绪 我错过什么了吗?我是否有一个或另一个命令的错误顺序? 有人能提供建议吗 这是我的密码: { //! Switch to Syste

在一个裸机项目中,我在初始化德州仪器公司ICE评估板上DDR2内存的EMIF和DDR_PHY时遇到问题。 我根据StarterWare引导加载程序示例中的序列编写了一个init序列。然而,我无法让DDR工作

控制器贯穿整个过程,但DDR在调试器中执行的每一步看起来都是随机的。我正在监视0x8000000。使用调试器写入此区域也不起作用。状态寄存器显示PHY未就绪

我错过什么了吗?我是否有一个或另一个命令的错误顺序? 有人能提供建议吗

这是我的密码:

{
  //! Switch to System Mode
  asm("    swi     #1;");

  //! Enable EMIF
  CM_PER->EMIF_FW_CLKCTRL             |= 2;
  CM_PER->EMIF_CLKCTRL                |= 2;
  while (!(CM_PER->L3_CLKSTCTRL & ((1 << 4) | (1 << 2))));

  //! Phy init
  CONTROL_MODULE->VTP_CTRL            |=  (1 << 6);
  CONTROL_MODULE->VTP_CTRL            &= ~(1 << 0);
  CONTROL_MODULE->VTP_CTRL            |=  (1 << 0);;
  while (!(CONTROL_MODULE->VTP_CTRL & (1 << 5)));

  DDR_PHY->CMD[0].SLAVE_RATIO          = DDR_CONFIG_PHY_CMD0_SLAVE_RATIO;
  DDR_PHY->CMD[0].SLAVE_FORCE          = DDR_CONFIG_PHY_CMD0_SLAVE_FORCE;
  DDR_PHY->CMD[0].SLAVE_DELAY          = DDR_CONFIG_PHY_CMD0_SLAVE_DELAY;
  DDR_PHY->CMD[0].DLL_LOCK_DIFF        = DDR_CONFIG_PHY_CMD0_LOCK_DIFF;
  DDR_PHY->CMD[0].INVERT_CLKOUT        = DDR_CONFIG_PHY_CMD0_INVERT_CLKOUT;

  DDR_PHY->CMD[1].SLAVE_RATIO          = DDR_CONFIG_PHY_CMD1_SLAVE_RATIO;
  DDR_PHY->CMD[1].SLAVE_FORCE          = DDR_CONFIG_PHY_CMD1_SLAVE_FORCE;
  DDR_PHY->CMD[1].SLAVE_DELAY          = DDR_CONFIG_PHY_CMD1_SLAVE_DELAY;
  DDR_PHY->CMD[1].DLL_LOCK_DIFF        = DDR_CONFIG_PHY_CMD1_LOCK_DIFF;
  DDR_PHY->CMD[1].INVERT_CLKOUT        = DDR_CONFIG_PHY_CMD1_INVERT_CLKOUT;

  DDR_PHY->CMD[2].SLAVE_RATIO          = DDR_CONFIG_PHY_CMD2_SLAVE_RATIO;
  DDR_PHY->CMD[2].SLAVE_FORCE          = DDR_CONFIG_PHY_CMD2_SLAVE_FORCE;
  DDR_PHY->CMD[2].SLAVE_DELAY          = DDR_CONFIG_PHY_CMD2_SLAVE_DELAY;
  DDR_PHY->CMD[2].DLL_LOCK_DIFF        = DDR_CONFIG_PHY_CMD2_LOCK_DIFF;
  DDR_PHY->CMD[2].INVERT_CLKOUT        = DDR_CONFIG_PHY_CMD2_INVERT_CLKOUT;

  DDR_PHY->DATA[0].RD_DQS_SLAVE_RATIO  = DDR_CONFIG_PHY_DATA0_RD_DQS_SLAVE_RATIO;
  DDR_PHY->DATA[0].WR_DQS_SLAVE_RATIO  = DDR_CONFIG_PHY_DATA0_WR_DQS_SLAVE_RATIO;
  DDR_PHY->DATA[0].FIFO_WE_SLAVE_RATIO = DDR_CONFIG_PHY_DATA0_FIFO_WE_SLAVE_RATIO;
  DDR_PHY->DATA[0].WR_DATA_SLAVE_RATIO = DDR_CONFIG_PHY_DATA0_WR_DATA_SLAVE_RATIO;

  DDR_PHY->DATA[1].RD_DQS_SLAVE_RATIO  = DDR_CONFIG_PHY_DATA1_RD_DQS_SLAVE_RATIO;
  DDR_PHY->DATA[1].WR_DQS_SLAVE_RATIO  = DDR_CONFIG_PHY_DATA1_WR_DQS_SLAVE_RATIO;
  DDR_PHY->DATA[1].FIFO_WE_SLAVE_RATIO = DDR_CONFIG_PHY_DATA1_FIFO_WE_SLAVE_RATIO;
  DDR_PHY->DATA[1].WR_DATA_SLAVE_RATIO = DDR_CONFIG_PHY_DATA1_WR_DATA_SLAVE_RATIO;

  //! Set control registers
  CONTROL_MODULE->DDR_CMD0_IOCTRL      = DDR_CONFIG_CMD0_IOCTRL;
  CONTROL_MODULE->DDR_CMD1_IOCTRL      = DDR_CONFIG_CMD1_IOCTRL;
  CONTROL_MODULE->DDR_CMD2_IOCTRL      = DDR_CONFIG_CMD2_IOCTRL;
  CONTROL_MODULE->DDR_DATA0_IOCTRL     = DDR_CONFIG_DATA0_IOCTRL;
  CONTROL_MODULE->DDR_DATA1_IOCTRL     = DDR_CONFIG_DATA1_IOCTRL;
  CONTROL_MODULE->DDR_IO_CTRL         &= DDR_CONFIG_IOCTRL;
  CONTROL_MODULE->DDR_CKE_CTRL        |= DDR_CONFIG_CKE_CTRL;

  //! Set memory interface control registers
  EMIF0->DDR_PHY_CTRL_1                = DDR_CONFIG_PHY_CTRL_1;
  EMIF0->DDR_PHY_CTRL_1               |= DDR_CONFIG_DYN_PWRDN;
  EMIF0->DDR_PHY_CTRL_1_SHDW           = DDR_CONFIG_PHY_CTRL_1_SHDW;
  EMIF0->DDR_PHY_CTRL_1_SHDW          |= DDR_CONFIG_DYN_PWRDN_SHDW;
  EMIF0->DDR_PHY_CTRL_2                = DDR_CONFIG_PHY_CTRL_2;

  //! Set memory interface timing registers
  EMIF0->SDRAM_TIM_1                   = DDR_CONFIG_SD_TIM_1;
  EMIF0->SDRAM_TIM_1_SHDW              = DDR_CONFIG_SD_TIM_1_SHDW;
  EMIF0->SDRAM_TIM_2                   = DDR_CONFIG_SD_TIM_2;
  EMIF0->SDRAM_TIM_2_SHDW              = DDR_CONFIG_SD_TIM_2_SHDW;
  EMIF0->SDRAM_TIM_3                   = DDR_CONFIG_SD_TIM_3;
  EMIF0->SDRAM_TIM_3_SHDW              = DDR_CONFIG_SD_TIM_3_SHDW;

  EMIF0->SDRAM_CONFIG                  = DDR_CONFIG_SD_CONFIG_BEFORE;
  EMIF0->SDRAM_REF_CTRL                = DDR_CONFIG_SD_REF_CTRL_BEFORE;
  EMIF0->SDRAM_REF_CTRL_SHDW           = DDR_CONFIG_SD_REF_CTRL_SHDW_BEFORE;

  //! Wait for changes to take effect
  uint32_t ulDelay = DDR_CONFIG_DELAY_INTERVAL;
  while(ulDelay--);
  EMIF0->SDRAM_REF_CTRL                = DDR_CONFIG_SD_REF_CTRL_AFTER;
  EMIF0->SDRAM_REF_CTRL_SHDW           = DDR_CONFIG_SD_REF_CTRL_SHDW_AFTER;

  EMIF0->ZQ_CONFIG                     = DDR_CONFIG_ZQ;
  EMIF0->SDRAM_CONFIG                  = DDR_CONFIG_SD_CONFIG_AFTER;
  CONTROL_MODULE->CONTROL_EMIF_SDRAM_CONFIG = DDR_CONFIG_SD_CONFIG_AFTER;

  //! Switch to User Mode
  asm("    swi     #0;");
}

如果您从一个有效的现有项目中获取了此代码,则不太可能是序列问题。SD-RAM的定时和信令参数非常关键,并且在不同设备之间有所不同,定时相关参数的实际寄存器值将取决于处理器的时钟速度。因此,除非您的DDR2设备与原始项目中使用的部件相同,并且您以相同的速度运行处理器,否则参数不太可能正确

您需要仔细地将应用于内存控制器的设置与tour RAM部件数据表中提供的参数相匹配。这通常并不简单,因为RAM供应商通常从不同的引用中定义参数,并使用与处理器供应商不同的术语。通常最简单的方法是使用两者中的时序图来选择兼容的参数。

问题已解决

我经历了现有的初始化,发现了一个事实,很明显,一些寄存器不需要设置。在我的代码中,为了完整性,我仍然使用默认值设置它们。一般来说,如果我需要在以后的某个项目中配置它们,可能需要附加一个不同的RAM。我从来没有想过这样做会破坏一些东西。但它显然做到了。我从设置中取出所有不需要的寄存器,只对必要的寄存器进行了编程,结果成功了!另外,我放弃了两阶段的SDRAM\u控件和SDRAM\u REF\u CTRL设置,在延迟后将设置更改为最终值。我只是直接取了最后的值

此代码适用于:

  //! Switch to System Mode
  asm("    swi     #1;");

  //! Enable EMIF
  CM_PER->EMIF_CLKCTRL                 = 2;
  //! Poll for functional peripheral
  while (CM_PER->EMIF_CLKCTRL != 2);

  //! Enable VTP
  CONTROL_MODULE->VTP_CTRL             = 0;
  CONTROL_MODULE->VTP_CTRL             = 6;
  CONTROL_MODULE->VTP_CTRL            |=  (1 << 6);
  CONTROL_MODULE->VTP_CTRL            &= ~(1 << 0);
  CONTROL_MODULE->VTP_CTRL            |=  (1 << 0);
  //! Poll for VTP ready
  while (!(CONTROL_MODULE->VTP_CTRL & (1 << 5)));

  //! Configure DDR Phy command macros
  DDR_PHY->CMD[0].SLAVE_RATIO          = DDR_CONFIG_PHY_CMD0_SLAVE_RATIO;
  DDR_PHY->CMD[0].INVERT_CLKOUT        = DDR_CONFIG_PHY_CMD0_INVERT_CLKOUT;

  DDR_PHY->CMD[1].SLAVE_RATIO          = DDR_CONFIG_PHY_CMD1_SLAVE_RATIO;
  DDR_PHY->CMD[1].INVERT_CLKOUT        = DDR_CONFIG_PHY_CMD1_INVERT_CLKOUT;

  DDR_PHY->CMD[2].SLAVE_RATIO          = DDR_CONFIG_PHY_CMD2_SLAVE_RATIO;
  DDR_PHY->CMD[2].INVERT_CLKOUT        = DDR_CONFIG_PHY_CMD2_INVERT_CLKOUT;

  //! Configure DDR Phy data macros
  DDR_PHY->DATA[0].RD_DQS_SLAVE_RATIO[0]  = DDR_CONFIG_PHY_DATA0_RD_DQS_SLAVE_RATIO;
  DDR_PHY->DATA[0].WR_DQS_SLAVE_RATIO[0]  = DDR_CONFIG_PHY_DATA0_WR_DQS_SLAVE_RATIO;
  DDR_PHY->DATA[0].WRLVL_INIT_RATIO[0]    = DDR_CONFIG_PHY_DATA0_WRLVL_INIT_RATIO;
  DDR_PHY->DATA[0].GATELVL_INIT_RATIO[0]  = DDR_CONFIG_PHY_DATA0_GATELVL_INIT_RATIO;
  DDR_PHY->DATA[0].FIFO_WE_SLAVE_RATIO[0] = DDR_CONFIG_PHY_DATA0_FIFO_WE_SLAVE_RATIO;
  DDR_PHY->DATA[0].WR_DATA_SLAVE_RATIO[0] = DDR_CONFIG_PHY_DATA0_WR_DATA_SLAVE_RATIO;
  DDR_PHY->DATA[0].DLL_LOCK_DIFF          = DDR_CONFIG_PHY_DATA0_DLL_LOCK_DIFF;

  DDR_PHY->DATA[1].RD_DQS_SLAVE_RATIO[0]  = DDR_CONFIG_PHY_DATA1_RD_DQS_SLAVE_RATIO;
  DDR_PHY->DATA[1].WR_DQS_SLAVE_RATIO[0]  = DDR_CONFIG_PHY_DATA1_WR_DQS_SLAVE_RATIO;
  DDR_PHY->DATA[1].WRLVL_INIT_RATIO[0]    = DDR_CONFIG_PHY_DATA1_WRLVL_INIT_RATIO;
  DDR_PHY->DATA[1].GATELVL_INIT_RATIO[0]  = DDR_CONFIG_PHY_DATA1_GATELVL_INIT_RATIO;
  DDR_PHY->DATA[1].FIFO_WE_SLAVE_RATIO[0] = DDR_CONFIG_PHY_DATA1_FIFO_WE_SLAVE_RATIO;
  DDR_PHY->DATA[1].WR_DATA_SLAVE_RATIO[0] = DDR_CONFIG_PHY_DATA1_WR_DATA_SLAVE_RATIO;
  DDR_PHY->DATA[1].DLL_LOCK_DIFF          = DDR_CONFIG_PHY_DATA1_DLL_LOCK_DIFF;

  //! Set control registers
  CONTROL_MODULE->DDR_CMD0_IOCTRL      = DDR_CONFIG_CMD_IOCTRL;
  CONTROL_MODULE->DDR_CMD1_IOCTRL      = DDR_CONFIG_CMD_IOCTRL;
  CONTROL_MODULE->DDR_CMD2_IOCTRL      = DDR_CONFIG_CMD_IOCTRL;
  CONTROL_MODULE->DDR_DATA0_IOCTRL     = DDR_CONFIG_DATA_IOCTRL;
  CONTROL_MODULE->DDR_DATA1_IOCTRL     = DDR_CONFIG_DATA_IOCTRL;
  CONTROL_MODULE->DDR_IO_CTRL         &= DDR_CONFIG_IOCTRL;
  CONTROL_MODULE->DDR_CKE_CTRL        |= DDR_CONFIG_CKE_CTRL;

  //! Set memory interface control registers
  EMIF0->DDR_PHY_CTRL_1                = DDR_CONFIG_PHY_CTRL_1;
  EMIF0->DDR_PHY_CTRL_1_SHDW           = DDR_CONFIG_PHY_CTRL_1;
  EMIF0->DDR_PHY_CTRL_2                = DDR_CONFIG_PHY_CTRL_2;

  //! Set memory interface timing registers
  EMIF0->SDRAM_TIM_1                   = DDR_CONFIG_SD_TIM_1;
  EMIF0->SDRAM_TIM_1_SHDW              = DDR_CONFIG_SD_TIM_1;
  EMIF0->SDRAM_TIM_2                   = DDR_CONFIG_SD_TIM_2;
  EMIF0->SDRAM_TIM_2_SHDW              = DDR_CONFIG_SD_TIM_2;
  EMIF0->SDRAM_TIM_3                   = DDR_CONFIG_SD_TIM_3;
  EMIF0->SDRAM_TIM_3_SHDW              = DDR_CONFIG_SD_TIM_3;

  EMIF0->SDRAM_REF_CTRL                = DDR_CONFIG_SD_REF_CTRL;
  EMIF0->SDRAM_REF_CTRL_SHDW           = DDR_CONFIG_SD_REF_CTRL;

  EMIF0->SDRAM_CONFIG                  = DDR_CONFIG_SD_CONFIG;

  //! Poll for DDR Phy ready indicator
  while(!(EMIF0->STATUS & (1 << 2)));

  //! Switch to User Mode
  asm("    swi     #0;");
/!切换到系统模式
asm(“swi#1;”;
//! 启用EMIF
CM_PER->EMIF_CLKCTRL=2;
//! 功能外设轮询
而(每厘米->电磁干扰CLKCTRL!=2);
//! 启用VTP
控制模块->VTP\U CTRL=0;
控制模块->VTP\U CTRL=6;
控制模块->VTP\u CTRL |=(1 VTP\u CTRL&=~(1 VTP\u CTRL |=(1 VTP\u CTRL&(1 CMD[0])。从机比率=DDR\u配置\u物理\u CMD0从机比率;
DDR\u PHY->CMD[0]。反转\u CLKOUT=DDR\u CONFIG\u PHY\u CMD0\u反转\u CLKOUT;
DDR\u PHY->CMD[1]。从机\u比率=DDR\u配置\u PHY\u CMD1\u从机\u比率;
DDR\U PHY->CMD[1]。反转\U CLKOUT=DDR\U配置\U PHY\U CMD1\U反转\U CLKOUT;
DDR\u PHY->CMD[2]。从机\u比率=DDR\u配置\u PHY\u CMD2\u从机\u比率;
DDR\U PHY->CMD[2]。反转\U CLKOUT=DDR\U配置\U PHY\U CMD2\U反转\U CLKOUT;
//!配置DDR Phy数据宏
DDR\U PHY->数据[0]。RD\U DQS\U从属\U比率[0]=DDR\U配置\U PHY\U数据0\U RD\U DQS\U从属\U比率;
DDR\U PHY->DATA[0].WR\U DQS\U SLAVE\U RATIO[0]=DDR\U CONFIG\U PHY\U DATA0\U WR\U DQS\U SLAVE\U RATIO;
DDR\u PHY->DATA[0]。WRLVL\u INIT\u RATIO[0]=DDR\u CONFIG\u PHY\u DATA0\u WRLVL\u INIT\u RATIO;
DDR\u PHY->DATA[0]。网关初始化比率[0]=DDR\u配置\u PHY\u DATA0\u网关初始化比率;
DDR\U PHY->DATA[0]。FIFO\U WE\U SLAVE\U比率[0]=DDR\U配置\U PHY\U DATA0\U FIFO\U WE\U SLAVE\U比率;
DDR\U PHY->DATA[0].WR\U DATA\U SLAVE\U RATIO[0]=DDR\U CONFIG\U PHY\U DATA0\U WR\U DATA\U SLAVE\U RATIO;
DDR\u PHY->DATA[0]。DLL\u LOCK\u DIFF=DDR\u CONFIG\u PHY\u DATA0\u DLL\u LOCK\u DIFF;
DDR\U PHY->数据[1]。RD\U DQS\U从机\U比率[0]=DDR\U配置\U PHY\U数据1\U RD\U DQS\U从机\U比率;
DDR\U PHY->数据[1]。WR\U DQS\U从机\U比率[0]=DDR\U配置\U PHY\U数据1\U WR\U DQS\U从机\U比率;
DDR\u PHY->DATA[1]。WRLVL\u INIT\u RATIO[0]=DDR\u CONFIG\u PHY\u DATA1\u WRLVL\u INIT\u RATIO;
DDR\U PHY->DATA[1]。GATELVL\u INIT\u比率[0]=DDR\u CONFIG\u PHY\u DATA1\u GATELVL\u INIT\u比率;
DDR\U PHY->DATA[1]。FIFO\U WE\U SLAVE\U比率[0]=DDR\U配置\U PHY\U DATA\U FIFO\U WE\U SLAVE\U比率;
DDR\U PHY->DATA[1].WR\U DATA\U SLAVE\U RATIO[0]=DDR\U CONFIG\U PHY\U DATA\U WR\U DATA\U SLAVE\U RATIO;
DDR\u PHY->DATA[1].DLL\u LOCK\u DIFF=DDR\u CONFIG\u PHY\u DATA1\u DLL\u LOCK\u DIFF;
//!设置控制寄存器
控制模块->DDR\U CMD0\U IOCTRL=DDR\U配置\U CMD\U IOCTRL;
控制模块->DDR\U CMD1\U IOCTRL=DDR\U配置\U CMD\U IOCTRL;
控制模块->DDR\U CMD2\U IOCTRL=DDR\U配置\U CMD\U IOCTRL;
控制模块->DDR\U数据0\U IOCTRL=DDR\U配置\U数据\U IOCTRL;
控制模块->DDR\U数据1\U IOCTRL=DDR\U配置\U数据\U IOCTRL;
控制模块->DDR\U IO\U CTRL&=DDR\U配置\U IOCTRL;
控制模块->DDR\U CKE\U CTRL |=DDR\U配置\U CKE\U CTRL;
//!设置内存接口控制寄存器
EMIF0->DDR\u PHY\u CTRL\u 1=DDR\u CONFIG\u PHY\u CTRL\u 1;
EMIF0->DDR\U PHY\U CTRL\U 1\U SHDW=DDR\U CONFIG\U PHY\U CTRL\U 1;
EMIF0->DDR\u PHY\u CTRL\u 2=DDR\u CONFIG\u PHY\u CTRL\u 2;
//!设置内存接口定时寄存器
EMIF0->SDRAM\u TIMU 1=DDR\u配置\u SD\u TIMU 1;
EMIF0->SDRAM\u TIMU 1\u SHDW=DDR\u配置\u SD\u TIMU 1;
EMIF0->SDRAM\u TIMU 2=DDR\u配置\u SD\u TIMU 2;
EMIF0->SDRAM\u TIM\u 2\u SHDW=DDR\u CONFIG\u SD\u TIM\u 2;
EMIF0->SDRAM\u TIMU 3=DDR\u配置\u SD\u TIMU 3;
EMIF0->SDRAM\u TIM\u 3\u SHDW=DDR\u CONFIG\u SD\u TIM\u 3;
EMIF0->SDRAM\u REF\u CTRL=DDR\u CONFIG\u SD\u REF\u CTRL;
EMIF0->SDRAM\u REF\u CTRL\u SHDW=DDR\u CONFIG\u SD\u REF\u CTRL;
EMIF0->SDRAM\u CONFIG=DDR\u CONFIG\u SD\u CONFIG;
//!轮询DDR Phy就绪指示器

当(!(EMIF0->STATUS&(1)时,我正在编写原始示例的同一个评估板上工作。我完全不知道可能是什么问题。我检查了DDR DPLL设置是否相同。我还尝试了设置al
  //! Switch to System Mode
  asm("    swi     #1;");

  //! Enable EMIF
  CM_PER->EMIF_CLKCTRL                 = 2;
  //! Poll for functional peripheral
  while (CM_PER->EMIF_CLKCTRL != 2);

  //! Enable VTP
  CONTROL_MODULE->VTP_CTRL             = 0;
  CONTROL_MODULE->VTP_CTRL             = 6;
  CONTROL_MODULE->VTP_CTRL            |=  (1 << 6);
  CONTROL_MODULE->VTP_CTRL            &= ~(1 << 0);
  CONTROL_MODULE->VTP_CTRL            |=  (1 << 0);
  //! Poll for VTP ready
  while (!(CONTROL_MODULE->VTP_CTRL & (1 << 5)));

  //! Configure DDR Phy command macros
  DDR_PHY->CMD[0].SLAVE_RATIO          = DDR_CONFIG_PHY_CMD0_SLAVE_RATIO;
  DDR_PHY->CMD[0].INVERT_CLKOUT        = DDR_CONFIG_PHY_CMD0_INVERT_CLKOUT;

  DDR_PHY->CMD[1].SLAVE_RATIO          = DDR_CONFIG_PHY_CMD1_SLAVE_RATIO;
  DDR_PHY->CMD[1].INVERT_CLKOUT        = DDR_CONFIG_PHY_CMD1_INVERT_CLKOUT;

  DDR_PHY->CMD[2].SLAVE_RATIO          = DDR_CONFIG_PHY_CMD2_SLAVE_RATIO;
  DDR_PHY->CMD[2].INVERT_CLKOUT        = DDR_CONFIG_PHY_CMD2_INVERT_CLKOUT;

  //! Configure DDR Phy data macros
  DDR_PHY->DATA[0].RD_DQS_SLAVE_RATIO[0]  = DDR_CONFIG_PHY_DATA0_RD_DQS_SLAVE_RATIO;
  DDR_PHY->DATA[0].WR_DQS_SLAVE_RATIO[0]  = DDR_CONFIG_PHY_DATA0_WR_DQS_SLAVE_RATIO;
  DDR_PHY->DATA[0].WRLVL_INIT_RATIO[0]    = DDR_CONFIG_PHY_DATA0_WRLVL_INIT_RATIO;
  DDR_PHY->DATA[0].GATELVL_INIT_RATIO[0]  = DDR_CONFIG_PHY_DATA0_GATELVL_INIT_RATIO;
  DDR_PHY->DATA[0].FIFO_WE_SLAVE_RATIO[0] = DDR_CONFIG_PHY_DATA0_FIFO_WE_SLAVE_RATIO;
  DDR_PHY->DATA[0].WR_DATA_SLAVE_RATIO[0] = DDR_CONFIG_PHY_DATA0_WR_DATA_SLAVE_RATIO;
  DDR_PHY->DATA[0].DLL_LOCK_DIFF          = DDR_CONFIG_PHY_DATA0_DLL_LOCK_DIFF;

  DDR_PHY->DATA[1].RD_DQS_SLAVE_RATIO[0]  = DDR_CONFIG_PHY_DATA1_RD_DQS_SLAVE_RATIO;
  DDR_PHY->DATA[1].WR_DQS_SLAVE_RATIO[0]  = DDR_CONFIG_PHY_DATA1_WR_DQS_SLAVE_RATIO;
  DDR_PHY->DATA[1].WRLVL_INIT_RATIO[0]    = DDR_CONFIG_PHY_DATA1_WRLVL_INIT_RATIO;
  DDR_PHY->DATA[1].GATELVL_INIT_RATIO[0]  = DDR_CONFIG_PHY_DATA1_GATELVL_INIT_RATIO;
  DDR_PHY->DATA[1].FIFO_WE_SLAVE_RATIO[0] = DDR_CONFIG_PHY_DATA1_FIFO_WE_SLAVE_RATIO;
  DDR_PHY->DATA[1].WR_DATA_SLAVE_RATIO[0] = DDR_CONFIG_PHY_DATA1_WR_DATA_SLAVE_RATIO;
  DDR_PHY->DATA[1].DLL_LOCK_DIFF          = DDR_CONFIG_PHY_DATA1_DLL_LOCK_DIFF;

  //! Set control registers
  CONTROL_MODULE->DDR_CMD0_IOCTRL      = DDR_CONFIG_CMD_IOCTRL;
  CONTROL_MODULE->DDR_CMD1_IOCTRL      = DDR_CONFIG_CMD_IOCTRL;
  CONTROL_MODULE->DDR_CMD2_IOCTRL      = DDR_CONFIG_CMD_IOCTRL;
  CONTROL_MODULE->DDR_DATA0_IOCTRL     = DDR_CONFIG_DATA_IOCTRL;
  CONTROL_MODULE->DDR_DATA1_IOCTRL     = DDR_CONFIG_DATA_IOCTRL;
  CONTROL_MODULE->DDR_IO_CTRL         &= DDR_CONFIG_IOCTRL;
  CONTROL_MODULE->DDR_CKE_CTRL        |= DDR_CONFIG_CKE_CTRL;

  //! Set memory interface control registers
  EMIF0->DDR_PHY_CTRL_1                = DDR_CONFIG_PHY_CTRL_1;
  EMIF0->DDR_PHY_CTRL_1_SHDW           = DDR_CONFIG_PHY_CTRL_1;
  EMIF0->DDR_PHY_CTRL_2                = DDR_CONFIG_PHY_CTRL_2;

  //! Set memory interface timing registers
  EMIF0->SDRAM_TIM_1                   = DDR_CONFIG_SD_TIM_1;
  EMIF0->SDRAM_TIM_1_SHDW              = DDR_CONFIG_SD_TIM_1;
  EMIF0->SDRAM_TIM_2                   = DDR_CONFIG_SD_TIM_2;
  EMIF0->SDRAM_TIM_2_SHDW              = DDR_CONFIG_SD_TIM_2;
  EMIF0->SDRAM_TIM_3                   = DDR_CONFIG_SD_TIM_3;
  EMIF0->SDRAM_TIM_3_SHDW              = DDR_CONFIG_SD_TIM_3;

  EMIF0->SDRAM_REF_CTRL                = DDR_CONFIG_SD_REF_CTRL;
  EMIF0->SDRAM_REF_CTRL_SHDW           = DDR_CONFIG_SD_REF_CTRL;

  EMIF0->SDRAM_CONFIG                  = DDR_CONFIG_SD_CONFIG;

  //! Poll for DDR Phy ready indicator
  while(!(EMIF0->STATUS & (1 << 2)));

  //! Switch to User Mode
  asm("    swi     #0;");