📄 sdram_test.c
字号:
/*******************************************************************
Analog Devices, Inc. All Rights Reserved.
This software is proprietary and confidential. By using this software
you agree to the terms of the associated Analog Devices License Agreement.
Project Name: Power_On_Self_Test
Hardware: ADSP-BF518F EZ-Board
Description: This file tests the SDRAM interface on the EZ-Board.
This EZ-Board contains 64MB of SDRAM which resides in the
range from 0x0 to 0x3ffffff.
The test DMAs blocks of 2KB at a time between internal
memory and SDRAM, then compares the data. It also takes
care to back up the SDRAM blocks before overwriting them
using core accesses to preserve the SDRAM contents.
Additionally each time the test is called, the data
pattern is changed between random, all 0x00, all 0x55,
all 0xaa, and all 0xff.
The test makes use of these 2KB data blocks:
L1 L1 L1 SDRAM
+----------+ +----------+ +----------+ +----------+
| out_buf | | in_buf | |backup_buf| | block_N |
+----------+ +----------+ +----------+ +----------+
The test performs these repeating steps:
- fills out_buf with a known pattern
- copies block_N to backup_buf using core acceses
- DMAs out_buf to block_N
- compares out_buf with block_N
- DMAs block N to in_buf
- compares in_buf to block_N
- restores backup_buf to block_N using core acceses
Note, the contents of this file cannot live in SDRAM or
else unexpected results may occur.
*******************************************************************/
/*******************************************************************
* include files
*******************************************************************/
#include <cdefBF518.h>
#include <ccblkfn.h>
#include <sys/exception.h>
#include <signal.h>
#include <stdlib.h>
/*******************************************************************
* global variables and defines
*******************************************************************/
#define SDRAM_START 0x00000000 /* start address of SDRAM */
#define SDRAM_END 0x03ffffff /* end of SDRAM */
#define SDRAM_SIZE_IN_BYTES 0x4000000 /* SDRAM is 64 MB */
#define BYTES_PER_DMA 0x800 /* 2 KB in each DMA */
#define NUMBER_OF_DMAS SDRAM_SIZE_IN_BYTES/BYTES_PER_DMA /* number of DMAs to test all SDRAM */
#define NUMBER_OF_DWORDS BYTES_PER_DMA/4 /* number of dwords in DMA */
#define DMA_XMODIFY 2 /* stride using 16-bit elements */
#define DMA_XCOUNT NUMBER_OF_DWORDS*DMA_XMODIFY /* number of 16-bit elements */
unsigned int *out_buf = NULL; /* contains the data we send out to SDRAM */
unsigned int *in_buf = NULL; /* stores the data we receive from SDRAM */
unsigned int *backup_buf = NULL; /* stores a backup of the SDRAM data we'll overwrite */
unsigned long curr_SDRAM_address = 0;
int direction_flag = 0;
int dma_done = 0;
bool bFailedVerify = false;
int nNumDMAWrites = 0;
int nNumDMAReads = 0;
enum /* data pattern */
{
RANDOM,
ALL_0S,
ALL_5S,
ALL_AS,
ALL_FS
};
/*******************************************************************
* function prototypes
*******************************************************************/
void Init_SDRAM(void);
void Init_MDMA(void);
void Enable_MDMA_Writes(void);
void Enable_MDMA_Reads(void);
EX_INTERRUPT_HANDLER(MDMA_ISR_WRITES);
EX_INTERRUPT_HANDLER(MDMA_ISR_READS);
/*******************************************************************
* Function: Enable_MDMA_Writes
* Description: enable MDMA0 and register ISR
*******************************************************************/
void Enable_MDMA_Writes(void)
{
register_handler(ik_ivg13, MDMA_ISR_WRITES);
*pMDMA_S0_CONFIG |= 0x1;
*pMDMA_D0_CONFIG |= 0x1;
}
/*******************************************************************
* Function: Enable_MDMA_Reads
* Description: enable MDMA1 and register ISR
*******************************************************************/
void Enable_MDMA_Reads(void)
{
register_handler(ik_ivg13, MDMA_ISR_READS);
*pMDMA_S1_CONFIG |= 0x1;
*pMDMA_D1_CONFIG |= 0x1;
}
/*******************************************************************
* Function: Init_MDMA
* Description: initialize MDMA registers
*******************************************************************/
void Init_MDMA(void)
{
/* MDMA0 used for transferring to SDRAM */
*pMDMA_D0_CONFIG = WNR | WDSIZE_16 | DI_EN;
*pMDMA_D0_START_ADDR = (void *)curr_SDRAM_address;
*pMDMA_D0_X_COUNT = DMA_XCOUNT;
*pMDMA_D0_X_MODIFY = DMA_XMODIFY;
*pMDMA_S0_CONFIG = WDSIZE_16;
*pMDMA_S0_START_ADDR = out_buf;
*pMDMA_S0_X_COUNT = DMA_XCOUNT;
*pMDMA_S0_X_MODIFY = DMA_XMODIFY;
/* MDMA1 used for transferring from SDRAM */
*pMDMA_D1_CONFIG = WNR | WDSIZE_16 | DI_EN;
*pMDMA_D1_START_ADDR = (void *)in_buf;
*pMDMA_D1_X_COUNT = DMA_XCOUNT;
*pMDMA_D1_X_MODIFY = DMA_XMODIFY;
*pMDMA_S1_CONFIG = WDSIZE_16;
*pMDMA_S1_START_ADDR = SDRAM_START;
*pMDMA_S1_X_COUNT = DMA_XCOUNT;
*pMDMA_S1_X_MODIFY = DMA_XMODIFY;
}
/*******************************************************************
* Function: Init_SDRAM
* Description: initialize SDRAM registers
*******************************************************************/
void Init_SDRAM(void)
{
/* initalize EBIU control registers to enable all banks */
*pEBIU_AMBCTL1 = 0xFFFFFF02;
ssync();
*pEBIU_AMGCTL = 0x00FF;
ssync();
/* check if already enabled */
if( SDRS != ((*pEBIU_SDSTAT) & SDRS) )
{
return;
}
/* SDRAM Refresh Rate Control Register */
*pEBIU_SDRRC = 0x0096;
/* SDRAM Memory Bank Control Register */
*pEBIU_SDBCTL = 0x0025;
/* SDRAM Memory Global Control Register */
*pEBIU_SDGCTL = 0x0091998d;
ssync();
}
/*******************************************************************
* Function: TEST_SDRAM
* Description: Main test routine will get launched from the POST
* framework.
*******************************************************************/
int TEST_SDRAM(void)
{
volatile unsigned int *pSrc32; /* ptr */
int nIndex = 0; /* temp index */
int bSuccess = 1; /* 1 indicates a pass, anything else is a fail */
static int nDataPattern = ALL_5S; /* we use different data patterns each time */
/* allocate storage for our buffers */
out_buf = malloc(sizeof(unsigned int) * NUMBER_OF_DWORDS);
in_buf = malloc(sizeof(unsigned int) * NUMBER_OF_DWORDS);
backup_buf = malloc(sizeof(unsigned int) * NUMBER_OF_DWORDS);
/* make sure storage was allocated correctly */
if( (in_buf == NULL) || (out_buf == NULL) || (backup_buf == NULL) )
return 0;
/* reset some global regs */
dma_done = 0;
nNumDMAWrites = 0;
nNumDMAReads = 0;
curr_SDRAM_address = 0;
direction_flag = 0;
srand(*pRTC_STAT); /* seed with the RTC value */
Init_SDRAM(); /* setup SDRAM */
Init_MDMA(); /* setup MDMA regs */
*pSIC_IMASK1 |= 0xc00; /* enable MDMA0 and MDMA1 */
/* fill our out_buf with some data */
for(nIndex = 0; nIndex < NUMBER_OF_DWORDS; nIndex++ )
{
switch (nDataPattern)
{
case RANDOM:
out_buf[nIndex] = rand();
break;
case ALL_0S:
out_buf[nIndex] = 0x00000000;
break;
case ALL_5S:
out_buf[nIndex] = 0x55555555;
break;
case ALL_AS:
out_buf[nIndex] = 0xaaaaaaaa;
break;
case ALL_FS:
out_buf[nIndex] = 0xffffffff;
break;
}
}
/* update type of data for next run */
nDataPattern++;
if (nDataPattern > ALL_FS)
nDataPattern = RANDOM;
/* backup the first block of SDRAM we'll overwrite using core accesses, subsequent
blocks will get backed up in the ISR */
for(nIndex = 0, pSrc32 = (unsigned int *)SDRAM_START; nIndex < NUMBER_OF_DWORDS; pSrc32++, nIndex++ )
{
backup_buf[nIndex] = *pSrc32;
}
/* enable MDMA writes */
Enable_MDMA_Writes();
/* wait for the test to finish or for a failure */
while( !dma_done && !bFailedVerify )
{
asm("nop;");
asm("nop;");
asm("nop;");
}
/* setup to ignore this interrupt */
interrupt(ik_ivg13, SIG_IGN);
/* disable SIC Level Interrupts */
*pSIC_IMASK1 &= (~(0xc00));
ssync();
/* free allocated memory and invalidate pointers */
free(out_buf);
free(in_buf);
free(backup_buf);
out_buf = NULL;
in_buf = NULL;
backup_buf = NULL;
if ( bFailedVerify )
return 0; /* return failure */
else
return 1; /* return pass */
}
/*******************************************************************
* Function: MDMA_ISR_WRITES
* Description: MDMA ISR that performs writes to SDRAM
*******************************************************************/
EX_INTERRUPT_HANDLER(MDMA_ISR_WRITES)
{
volatile unsigned int *pDst32 = (unsigned int *)curr_SDRAM_address;
int nIndex = 0;
/* acknowledge the DMA interrupt */
*pMDMA_D0_IRQ_STATUS |= 0x1;
/* increment the number of writes so far */
nNumDMAWrites += 1;
if( nNumDMAWrites <= NUMBER_OF_DMAS )
{
/* check each DWORD */
while( nIndex < NUMBER_OF_DWORDS )
{
unsigned long temp = pDst32[nIndex];
/* verify the DMA writes */
if(temp != out_buf[nIndex])
{
bFailedVerify = true;
break;
}
nIndex++;
}
/* enable DMA reads now */
Enable_MDMA_Reads();
}
else
{
}
}
/*******************************************************************
* Function: MDMA_ISR_READS
* Description: MDMA ISR that performs reads from SDRAM
*******************************************************************/
EX_INTERRUPT_HANDLER(MDMA_ISR_READS)
{
int nIndex = 0;
volatile unsigned int *pDst32 = (unsigned int *)curr_SDRAM_address;
volatile unsigned int *pSrc32 = (unsigned int *)curr_SDRAM_address;
/* acknowledge the DMA interrupt */
*pMDMA_D1_IRQ_STATUS |= 0x1;
/* increment the number of reads so far */
nNumDMAReads += 1;
/* if we have more DMAs to perform */
if( nNumDMAReads <= NUMBER_OF_DMAS )
{
/* check each DWORD */
while( nIndex < NUMBER_OF_DWORDS )
{
/* verify the DMA reads */
if(in_buf[nIndex] != out_buf[nIndex])
{
bFailedVerify = true;
break;
}
nIndex++;
}
/* restore the last block of SDRAM we overwrote using core accesses */
for(nIndex = 0; nIndex < NUMBER_OF_DWORDS; pSrc32++, nIndex++ )
{
*pSrc32 = backup_buf[nIndex];
}
/* backup the next block of SDRAM we'll overwrite using core accesses */
for(nIndex = 0; nIndex < NUMBER_OF_DWORDS; pSrc32++, nIndex++ )
{
backup_buf[nIndex] = *pSrc32;
}
/* setup for next block */
curr_SDRAM_address += BYTES_PER_DMA;
/* update to the next address */
*pMDMA_D0_START_ADDR = (void *)curr_SDRAM_address;
/* update to the next address */
*pMDMA_S1_START_ADDR = (void *)curr_SDRAM_address;
/* enable DMA writes now */
Enable_MDMA_Writes();
/* last one, disable DMA and set flag */
if (nNumDMAReads == NUMBER_OF_DMAS)
{
*pMDMA_D1_CONFIG &= ~(0x1);
*pMDMA_S1_CONFIG &= ~(0x1);
*pMDMA_D0_CONFIG &= ~(0x1);
*pMDMA_S0_CONFIG &= ~(0x1);
dma_done = 1;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -