⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sma_mem_test.c

📁 sharp的arm920t 7A400的评估板附带光盘Sharp KEVLH7A400 v0.3b Welcome to the SHARP KEV7A400 Evaluation board
💻 C
📖 第 1 页 / 共 3 页
字号:
/*********************************************************************** 
 * $Workfile:   SMA_mem_test.c  $ 
 * $Revision:   1.1  $ 
 * $Author:   KovitzP  $ 
 * $Date:   May 30 2002 17:36:22  $ 
 * 
 * Project: 
 * 
 * Description: 
 *     This file contains data, function and macro definitions for
 *     testing memory. These functions may be used with any chip
 *     that addresses memory sequentially.
 * 
 * 
 * Revision History: 
 * $Log:   //smaicnt2/pvcs/VM/CHIPS/archives/SOC/Source/SMA_mem_test.c-arc  $ 
 * 
 *    Rev 1.1   May 30 2002 17:36:22   KovitzP
 * Added random address testing.
 * 
 *    Rev 1.0   May 28 2002 13:15:16   KovitzP
 * Initial revision.
 * 
 * 
 *********************************************************************** 
 * 
 *  Copyright (c) 2002 Sharp Microelectronics of the Americas 
 * 
 *  All rights reserved 
 * 
 *  SHARP MICROELECTRONICS OF THE AMERICAS MAKES NO REPRESENTATION 
 *  OR WARRANTIES WITH RESPECT TO THE PERFORMANCE OF THIS SOFTWARE, 
 *  AND SPECIFICALLY DISCLAIMS ANY RESPONSIBILITY FOR ANY DAMAGES, 
 *  SPECIAL OR CONSEQUENTIAL, CONNECTED WITH THE USE OF THIS SOFTWARE. 
 * 
 *  SHARP MICROELECTRONICS OF THE AMERICAS PROVIDES THIS SOFTWARE SOLELY 
 *  FOR THE PURPOSE OF SOFTWARE DEVELOPMENT INCORPORATING THE USE OF A 
 *  SHARP MICROCONTROLLER OR SYSTEM-ON-CHIP PRODUCT. USE OF THIS SOURCE 
 *  FILE IMPLIES ACCEPTANCE OF THESE CONDITIONS. 
 * 
 **********************************************************************/ 
#include "SMA_mem_test.h"
#include "SMA_mls.h"
#ifndef NULL
#define NULL 0
#endif


#define MEM_ZEROS           0x00000000
#define MEM_CHECKERBOARD    0x55555555
#define MEM_CHECKERBOARDBAR 0xAAAAAAAA
#define MEM_ONES            0xFFFFFFFF
#define MEM_ADDR_UNIQ_8     0x01
#define MEM_ADDR_UNIQ_16    0x0102
#define MEM_ADDR_UNIQ_32    0x01020304

/*********************************************************************** 
 * 
 * Macro: MEM_TEST
 * 
 * Purpose: 
 *  generate memory test function bodies for 8, 16, and 32-bt accesses
 * 
 * Processing: 
 *  write zeros, read zeros, write checkerboard, read checkerboard,
 *  write checkerboardbar, read checkerboardbar, write all ones,
 *  read back all ones, write address-unique pattern, read back
 *  address unique pattern.
 *
 * Parameters: 
 *  bits:       The number of bits to generate code for
 *  start:      The start address
 *  end:        The end address
 *  log:        An array of error data log[0:max_err - 1]
 *  max_err:    The maximum number of errors before abort.
 * 
 * Outputs: 
 *  writes to the log array the address, intended value and 
 *  value read back for each error
 * 
 * Returns: 
 *  the number of errors found. 0 indicates the test passed.
 *  
 * Notes: 
 *  If log is NULL, no errors will be logged.
 *  The "returns" is not a left-hand side. It describes what the
 *  return statement returns.
 *
 *  Example usage:
 *
 * UNS_32 mem_test16(UNS_16 * start, UNS_16 * end, 
 *                 MEM_ERROR_T log, UNS_32 max_err)
 * {
 *     MEM_TEST(16,start,end,log,max_err);
 * }
 *
 * 
 **********************************************************************/ 
#define MEM_TEST(bits, start, end, log, max_err) \
{ \
    UNS_32 ret; \
    /* all zeros */ \
    mem_fill##bits (start,end,(UNS_##bits)MEM_ZEROS); \
    ret = mem_verify##bits (start,end,(UNS_##bits)MEM_ZEROS,log, max_err, "zeros"); \
    if (ret != 0) \
        return ret; \
    /* checkerboard */ \
    mem_fill##bits (start,end,(UNS_##bits)MEM_CHECKERBOARD); \
    ret = mem_verify##bits (start,end,(UNS_##bits)MEM_CHECKERBOARD,log,max_err,"checkerboard"); \
    if (ret != 0) \
        return ret; \
    /* checkerboardbar */ \
    mem_fill##bits (start,end,(UNS_##bits)MEM_CHECKERBOARDBAR); \
    ret = mem_verify##bits (start,end,(UNS_##bits)MEM_CHECKERBOARDBAR, \
                            log,max_err,"checkerboardbar"); \
    if (ret != 0) \
        return ret; \
    /* all ones */ \
    mem_fill##bits (start,end,(UNS_##bits)MEM_ONES); \
    ret = mem_verify##bits (start,end,(UNS_##bits)MEM_ONES,log, max_err,"all ones"); \
    if (ret != 0) \
        return ret; \
    /* address uniqueness */ \
    mem_fill_modify##bits (start,end,(UNS_##bits)MEM_ADDR_UNIQ_##bits); \
    ret = mem_verify_modify##bits (start,end,(UNS_##bits)MEM_ADDR_UNIQ_##bits, \
          log, max_err,"address uniqueness"); \
    return ret; \
}

/*********************************************************************** 
 * 
 * Macro: MEM_TEST_DATA_BUS
 * 
 * Purpose: 
 *  Test the data bus one bit at a time at the specified address
 *  Use this test to verify that all pins of an off-chip data bus
 *  are wired to a memory device.
 * 
 * Processing: 
 *  Write and then read back a single 1 at each bit of the data bus
 *  all other bits read 0. If either read back fails, fail the test.
 *
 * Parameters: 
 *  bits:   one of 8, 16 or 32
 *  addr:   the address to read
 * 
 * Outputs: None
 * 
 * Returns: 
 *  0 if the test passed. _BIT(failed_bit) if the test failed
 *  
 * Notes: 
 *  This macro is based on the function memTestDataBus from
 *  the file memtest.c version 1.0
 *
 *  The "returns" is not a left-hand side. It describes what the
 *  return statement returns.
 *
 *  Example usage:
 *
 * UNS_16 mem_test_data_bus16(UNS_16 * addr)
 * {
 *     MEM_TEST_DATA_BUS(16,addr);
 * }
 *
 * 
 **********************************************************************/ 
#define MEM_TEST_DATA_BUS(bits, addr) \
{ \
    UNS_##bits pattern; \
    for (pattern = 1; pattern != 0; pattern <<= 1) \
    { \
        *addr = pattern; \
        if (*addr != pattern) \
            return (pattern); \
    } \
    return (0); \
}

/*********************************************************************** 
 * 
 * Macro: MEM_TEST_ADDR_BUS
 * 
 * Purpose: 
 *  Test the address bus one bit at a time starting at the the specified
 *  base address address over the range of nbytes. Use this test to
 *  verify that all pins of an off-chip address bus are wired to a
 *  memory device.
 * 
 * Processing: 
 *  Write a pattern (0xAAAAAAAA) to memory at byte, halfword, or 
 *  word offsets, 0, 1, 2, 4, 8, 16..., etc. 
 *  Write a different pattern (0x55555555) at offset 0 
 *  Verify that the memory at locations 1, 2, 4, 8, 16,..etc are
 *  unchanged.
 *  Change the memory at offset 0 back to the original pattern.
 *  For each offset  1, 2, 4, 8, 16, ...etc:
 *    Change the memory at the offset to the different pattern.
 *    Verify that all memory at offsets not equal to the offset
 *    where memory was changed contain the orignal pattern.
 *    Change the memory at the changed offset back to the original
 *    pattern.
 *
 * Parameters: 
 *  bits:       one of 8, 16 or 32
 *  base_addr:  the address to read
 *  nbytes:     number of bytes in the address range.
 * 
 * Outputs: None
 * 
 * Returns: 
 *  0 if the test passed. _BIT(failed_address) if the test failed
 *  
 * Notes: 
 *  This macro is based on the function memTestAddressBus from
 *  the file memtest.c version 1.0
 *
 *  This macro assumes that (base_addr & (nbytes - 1)) == 0 if
 *  nbytes is the number of bytes in the address range to test.
 *
 *  The "returns" is not a left-hand side. It describes what the
 *  return statement returns.
 *
 *  Example usage:
 *
 * UNS_16 * mem_test_addr_bus16(UNS_16 * addr, UNS_32 nbytes)
 * {
 *     MEM_TEST_ADDR_BUS(16,addr,nbytes);
 * }
 *
 * 
 **********************************************************************/ 
#define MEM_TEST_ADDR_BUS(bits, base_addr, nbytes) \
{ \
    UNS_32 addr_mask = (nbytes - 1); \
    UNS_32 offset; \
    UNS_32 test_offset; \
\
    UNS_##bits pattern = (UNS_##bits) 0xAAAAAAAA; \
    UNS_##bits antipattern = (UNS_##bits) 0x55555555; \
\
    /* \
     * For each bit of the address bus, form an address with that bit set \
     * and all others clear. Assign the data stored at that address to \
     * the value kept in pattern. Note that since array index notation \
     * is being used, offset == 1 implies the least significant \
     * bit of the data bus no matter what the size is. \
     */ \
    for (offset = 1; (offset & addr_mask) != 0; offset <<= 1) \
        base_addr[offset] = pattern; \
\
    /* \
     * Write antipattern to the first memory location in the addres range \
     * tested and verify that the write did not change any of the writes \
     * of pattern to the addresses previously written. Note that since  \
     * array index notation is being used, offset == 1 implies the \
     * least significant bit of the data bus no matter what the size is. \
     */ \
    test_offset = 0; \
    base_addr[test_offset] = antipattern; \
    for (offset = 1; (offset & addr_mask) != 0; offset <<= 1) \
    { \
        if (base_addr[offset] != pattern) \
            return ((UNS_##bits *) &base_addr[offset]); \
    } \
\
    /* \
     * Write pattern to the first memory location in the addres range \
     * tested. Next, for each bit of the address bus, for an address \
     * with that bit set and all other clear. Set that offset to \
     * antipattern. Verify that all previously written values of \
     * pattern are unchanged. If any of the values are changed, \
     * return the address that was written as anti-pattern. \
     * Re-assign the value back to pattern prior to the next \
     * iteration of the loop to maintain the initial condition \
     * that memory at address offsets 0, 1, 2, 4, etc. contain pattern. \
     */ \
    base_addr[test_offset] = pattern; \
    for (test_offset = 1; (test_offset & addr_mask) != 0; \
            test_offset <<= 1) \
    { \
        base_addr[test_offset] = antipattern; \
\
        if (base_addr[0] != pattern) \
            return ((UNS_##bits *) &base_addr[test_offset]); \
        for (offset = 1; (offset & addr_mask) != 0; offset <<= 1) \
            if (base_addr[offset] != pattern && (offset != test_offset)) \
                return ((UNS_##bits *) &base_addr[test_offset]); \
\
        base_addr[test_offset] = pattern; \
    } \
    return (0); \
}

/*********************************************************************** 
 * 
 * Macro: MEM_TEST_RANDOM
 * 
 * Purpose: 
 *  Test memory for address uniquness.
 * 
 * Processing: 
 *  Write a simple pattern to a pseudo-random address and verify it.
 *
 * Parameters: 
 *  bits:       The number of bits in the data bus; must be 8, 16 or 32
 *  start:      The start address
 *  length:     The number of bytes to test
 *  log:        A pointer to an array of MEM_ERROR_T log entries.
 *              If log is NULL, then don't log errors
 *  max_err:    The number of errors that can occur before the test
 *              aborts
 *  test_name:  A pointer to a zero-terminated character string
 *              constant that names the test. 
 * 
 * Outputs: 
 *  Errors are logged in the log file.
 * 
 * Returns: 
 *  _ERROR if parameters are out of range
 *  or the number of errors detected (can be 0).
 *  
 * Notes: 
 *  This function works best if the length is a power of 2.
 *  Use this as a test for address uniqueness. The probability of
 *  two memory locations at aliased addresses having the same
 *  value is very low.
 * 
 **********************************************************************/ 
#define MEM_TEST_RANDOM(bits, start, length, log,max_err, test_name) \
{ \
    UNS_##bits pattern; \
    UNS_32 generators[MLS_MAXTAPS]; \
    UNS_32 mask; \
    UNS_32 reg, reg_len = 1; \
    UNS_32 err_count = 0; \
    volatile UNS_##bits read; \
\
    /* convert length to units of the data size */ \
    length /= sizeof(UNS_##bits); \
\
    if (length == 0) \
        return _ERROR; \
\
    /* handle the case of one element separately */ \
    if (length == 1) \
    { \
        *start = 0; \
        read = *start; \
        if (read != 0) \
        { \
            if (log != NULL) \
            { \
                log[err_count].test_name = test_name; \
                log[err_count].addr = start; \
                log[err_count].written = pattern; \
                log[err_count].read = read; \
            } \
            err_count++; \
        } \
        return err_count; \
\
    } \
\
    /* setup the MULS generator to make a sequence long enough */ \
    mls_setup(reg_len,generators,&mask); \
    while (mask < length - 1) \
    { \
        if (++reg_len > MLS_MAXREG) \
            return _ERROR; /* too big, can't do it. */ \
\
        mls_setup(reg_len,generators,&mask); \
    } \
\
    /* fill memory */ \
    pattern = 0; \
    reg = mask; \
    start[0] = pattern++; \
    while (reg >= length) \
    { \
        reg = mls_next_reg(reg, generators, mask); \
    } \
\
    do \
    { \
        start[reg] = pattern++; \
        do \
        { \
            reg = mls_next_reg(reg, generators, mask); \
        } while (reg >= length && reg != mask); \
    } while (reg != mask); \
\
    /* verify memory */ \
    pattern = 0; \
    reg = mask; \
    read = start[0]; \
    if (read != pattern) \
    { \
        if (log != NULL) \
        { \
            log[err_count].test_name = test_name; \
            log[err_count].addr = &start[0]; \
            log[err_count].written = pattern; \
            log[err_count].read = read; \
        } \
        err_count++; \
    } \
    if (err_count >= max_err) \
        return err_count; \
\
    while (reg >= length) \
    { \
        reg = mls_next_reg(reg, generators, mask); \
    } \
\
    pattern++; \
    do \
    { \
        read = start[reg]; \
        if (read != pattern) \
        { \
            if (log != NULL) \
            { \
                log[err_count].test_name = test_name; \
                log[err_count].addr = &start[reg]; \
                log[err_count].written = pattern; \
                log[err_count].read = read; \
            } \
            err_count++; \
        } \
\
        pattern++; \
        do \
        { \
            reg = mls_next_reg(reg, generators, mask); \
        } while (reg >= length && reg != mask); \
\
    } while (reg != mask && err_count < max_err); \
\
    return err_count; \
}

/*********************************************************************** 
 * 
 * Function: mem_fill8
 * 
 * Purpose: 
 *  fill the address range with an 8-bit pattern
 * 
 * Processing: 
 *
 * Parameters: 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -