📄 board_memories.c
字号:
sleep_time(50000); // --------- WAIT ---------
WRITE(AT91C_BASE_SDDRC, SDDRC_MR, AT91C_MODE_LMR_CMD); // Set MR JEDEC compliant : Load mode Register command
pSdram[19] = 0x5a5a5b5b; // Perform LMR burst=1, lat=2
WRITE(AT91C_BASE_SDDRC, SDDRC_MR, AT91C_MODE_NORMAL_CMD); // Set Normal mode : Any access to the DDRSDRAMC is decoded normally
pSdram[0] = 0x00000000; // Dummy read to access SDRAM : validate preceeding command
WRITE(AT91C_BASE_SDDRC, SDDRC_RTR, 781); // Set Refresh Timer (ex: ((64 x 10^-3)/8192) x 100 x 10^6 ) => 781 for 100 MHz
WRITE(AT91C_BASE_SDDRC, SDDRC_HS, AT91C_OVL); // High speed register : Optimization is disabled
sleep_time(50000); // --------- WAIT ---------
}
//------------------------------------------------------------------------------
/// Initialize and configure the DDRAM
//------------------------------------------------------------------------------
unsigned int dummy_read;
AT91S_SDDRC *ddrc = (AT91S_SDDRC *) AT91C_BASE_SDDRC;
void BOARD_ConfigureDdram(unsigned char ddrModel, unsigned char busWidth)
{
unsigned int i;
volatile unsigned int *pDdram = (unsigned int *) AT91C_EBI_DDRAM;
unsigned short ddrc_dbw = 0;
switch (busWidth) {
case 16:
ddrc_dbw = AT91C_B16MODE_16_BITS;
break;
case 32:
default:
ddrc_dbw = AT91C_B16MODE_32_BITS;
break;
}
AT91C_BASE_PMC->PMC_SCER = (0x1 << 2);
WRITE(AT91C_BASE_CCFG, CCFG_EBICSA, READ(AT91C_BASE_CCFG, CCFG_EBICSA) | AT91C_EBI_SUP_3V3); // WORKAROUND
//WRITE(AT91C_BASE_CCFG, CCFG_EBICSA, READ(AT91C_BASE_CCFG, CCFG_EBICSA) | AT91C_EBI_LP_STD_DRIVE);
// Memory Device Register
// Mobile DDRAM type | 16bit MODE
// 0x00000013
WRITE(AT91C_BASE_SDDRC, SDDRC_MDR, AT91C_MD_LP_DDR_SDRAM
| ddrc_dbw );
// Configuration Register
// Weak driver strength(1) | Disable DLL reset(0) | SDRAM CAS = 3 | row = 13 | column = 9
// 0x00000138
WRITE(AT91C_BASE_SDDRC, SDDRC_CR, AT91C_DIC_DS
| AT91C_DLL_RESET_DISABLED
| AT91C_CAS_3
| AT91C_NR_13
| AT91C_NC_DDR9_SDR8 );
// Timing 0 Parameter Register
// tmrd = 2 | twtr = 1 | trrd = 2 | trrd = 2 | trp = 3 | trc = 8 | twr = 2 | trcd = 3 | tras = 5
// 0x21238235
WRITE(AT91C_BASE_SDDRC, SDDRC_T0PR, AT91C_TMRD_2
| AT91C_TWTR_1
| AT91C_TRRD_2
| AT91C_TRP_3
| AT91C_TRC_8
| AT91C_TWR_2
| AT91C_TRCD_3
| AT91C_TRAS_5);
// Timing 1 Parameter Register
// txp = 4 | txsrd = 0xC | txsnr = 0xC | trfc = 9
// 0x040D0D09
WRITE(AT91C_BASE_SDDRC, SDDRC_T1PR, AT91C_TXP_4
| AT91C_TXSRD_12
| AT91C_TXSNR_12
| AT91C_TRFC_9 );
// Low-power Register
WRITE(AT91C_BASE_SDDRC, SDDRC_LPR, 0x00000000); // Low power register => Low-power is inhibited
// all bank refresh during self refresh (PASR = b000)
sleep_time(200); // --------- WAIT ---------
// ----------------------------------------------------------------------------
// NOP command
WRITE(AT91C_BASE_SDDRC, SDDRC_MR, AT91C_MODE_NOP_CMD);
pDdram[0] = 0x00000000; // Dummy write to access SDRAM : validate preceeding command
// Precharge All Banks command
WRITE(AT91C_BASE_SDDRC, SDDRC_MR, AT91C_MODE_PRCGALL_CMD);
pDdram[0] = 0x00000000; // Dummy write to access SDRAM : validate preceeding command
sleep_time(1000); // --------- WAIT ---------
for (i=0 ; i<2 ; i++)
{
// AutoRefresh command
WRITE(AT91C_BASE_SDDRC, SDDRC_MR, AT91C_MODE_RFSH_CMD);
pDdram[0] = 0x00000000; // Dummy write to access SDRAM : validate preceeding command
sleep_time(1000); // --------- WAIT ---------
}
sleep_time(200); // --------- WAIT ---------
// Mode Register Set command
WRITE(AT91C_BASE_SDDRC, SDDRC_MR, AT91C_MODE_LMR_CMD);
pDdram[0] = 0x00000000; // Dummy write to access SDRAM : validate preceeding command
sleep_time(200); // --------- WAIT ---------
// Extended Mode Register Set command
WRITE(AT91C_BASE_SDDRC, SDDRC_MR, AT91C_MODE_EXT_LMR_CMD);
dummy_read = *((unsigned long *)0x71000000); // Special read to access SDRAM
sleep_time(200); // --------- WAIT ---------
// Set Normal mode : Any access to the DDRSDRAMC is decoded normally
ddrc->SDDRC_MR = AT91C_MODE_NORMAL_CMD;//TODO
//WRITE(AT91C_BASE_SDDRC, SDDRC_MR, AT91C_MODE_NORMAL_CMD);
dummy_read = *((unsigned int *)AT91C_EBI_DDRAM); // Dummy read to access SDRAM : validate preceeding command
pDdram[0] = 0x00000000;
// Set Refresh Timer : ((64 x 10^-3)/8192) x 48 x 10^6 ---> 375 for 48 MHz
//WRITE(AT91C_BASE_SDDRC, SDDRC_RTR, 375);
// Set Refresh Timer : ((64 x 10^-3)/8192) x 100 x 10^6 ---> 781 for 100 MHz
WRITE(AT91C_BASE_SDDRC, SDDRC_RTR, 781);
// High speed register : Optimization is enabled
WRITE(AT91C_BASE_SDDRC, SDDRC_HS, 0x00);
sleep_time(200); // --------- WAIT ---------
}
//------------------------------------------------------------------------------
/// Initialize and configure the BCRAM
//------------------------------------------------------------------------------
void BOARD_ConfigureBcram(unsigned char busWidth)
{
volatile unsigned int *pBcram = (unsigned int *) AT91C_EBI_BCRAM;
// Configure EBI
AT91C_BASE_CCFG->CCFG_EBICSA |= AT91C_EBI_CS1A_BCRAMC;
// Configure A23 and A24 PIO as Periph A
AT91C_BASE_PIOD->PIO_PDR = AT91C_PIO_PD12 | AT91C_PIO_PD13;
AT91C_BASE_PIOD->PIO_ASR = AT91C_PIO_PD12 | AT91C_PIO_PD13;
// 2. The Cellular Ram memory type must be set in the BCRAMC Memory Device Register.
// -------------------------------------------------------------------------
// Burst CellularRAM Version 1.5
// (BCRAMC_MDR = 0x00000001)
AT91C_BASE_BCRAMC->BCRAMC_MDR = AT91C_BCRAMC_MD_BCRAM_V15;
// 3. Temperature compensated self refresh (TCSR) and partial array
// refresh (PAR) must be set in the BCRAMC Low Power register.
// -------------------------------------------------------------------------
// Low power register => Low-power is inhibited, Internal Temperature Sensor choosen
// PAR[2:0] : Partial Array Refresh = 000 (Full Array)
// TCR_TCSR[5:4] : Temperature Compensated Refresh/Self-refresh = 00 (Internal sensor or 70癈)
// LPCB[9:8] : Low Power Command Bit = 00 (Low power Feature inhibited)
// (BCRAMC_LPR = 0x00000000)
AT91C_BASE_BCRAMC->BCRAMC_LPR = AT91C_BCRAMC_PAR_FULL |
//AT91C_BCRAMC_TCR_INTERNAL_OR_70C |
AT91C_BCRAMC_LPCB_DISABLE;
// High Speed Register
// DA(0) Decode Cycle = 0 (No decode cycle added)
// (BCRAMC_HSR = 0x00000000)
AT91C_BASE_BCRAMC->BCRAMC_HSR = AT91C_BCRAMC_DA_DISABLE;
// 4. Asynchronous timings (TCKA, TCRE..) must be set in the BCRAMC Timing Register.
// -------------------------------------------------------------------------
// TCW[3:0] : Chip Enable to End of Write = 3
// TCRES[5:4] : Control Register Enable Setup = 2
// TCKA[11:8] : BCWE High to BCCK Valid = 0
// (BCRAMC_TPR = 0x00000023)
AT91C_BASE_BCRAMC->BCRAMC_TPR = AT91C_BCRAMC_TCW_3 |
AT91C_BCRAMC_TCRES_2 |
AT91C_BCRAMC_TCKA_0;
// 5. Cellular Ram features must be set in the HBCRAMC Configuration Register:
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -