From 8340a59fa12a1940453d784a0cc9eef6bed90f30 Mon Sep 17 00:00:00 2001 From: James Date: Tue, 15 Oct 2013 03:37:07 +0100 Subject: put_in_16b_before_killing --- src/sdram_test.c | 535 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 503 insertions(+), 32 deletions(-) diff --git a/src/sdram_test.c b/src/sdram_test.c index ba1be8d..9d08cc5 100644 --- a/src/sdram_test.c +++ b/src/sdram_test.c @@ -1,56 +1,527 @@ -#include +/************************************************************************** + * Copyright (c) 2009 Altera Corporation, San Jose, California, USA. * + * All rights reserved. All use of this software and documentation is * + * subject to the License Agreement located at the end of this file below.* + *************************************************************************/ +/************************************************************************** + * + * + * Description + *************** + * This is a test program which tests RAM memory. + * + * + * Requirements + **************** + * This is a "Hosted" application. According to the ANSI C standard, hosted + * applications can rely on numerous system-services (including properly- + * initialized device drivers and, in this case, STDOUT). + * + * When this program is compiled, code is added before main(), so that all + * devices are properly-initialized and all system-services (e.g. the + * library) are ready-to-use. In this hosted environment, all standard C + * programs will run. + * + * A hosted application (like this example) does not need to concern itself + * with initializing devices. As long as it only calls C Standard Library + * functions, a hosted application can run "as if on a workstation." + * + * An application runs in a hosted environment if it declares the function + * main(), which this application does. + * + * This software example requires a STDOUT component such as a UART or + * JTAG UART and 2 RAM components (one for running + * the program, and one for testing) Therefore it can run on the following + * hardware examples: + * + * Nios Development Board, Stratix II Edition: + * - Standard + * - Full Featured + * + * DSP Development Board, Stratix II Edition: + * - Standard + * - Full Featured + * + * Nios Development Board, Stratix Edition: + * - Standard + * - Full Featured + * + * Nios Development Board, Stratix Professional Edition: + * - Standard + * - Full Featured + * + * Nios Development Board, Cyclone Edition: + * - Standard + * - Full Featured + * + * Nios Development Board, Cyclone II Edition: + * - Standard + * - Full Featured + * + * Note: This example will not run on the Nios II Instruction Set Simulator + * + **************************************************************************/ + + #include -#include -#include +#include +#include +#include #include -#include +#include + +#include "sys/alt_stdio.h" #include "system.h" +/****************************************************************** +* Function: MenuHeader +* +* Purpose: Prints the menu header. +* +******************************************************************/ +static void MenuHeader(void) +{ + printf("\n\n"); + printf(" <----> Nios II Memory Test. <---->\n"); + printf("This software example tests the memory in your system to assure it\n"); + printf("is working properly. This test is destructive to the contents of\n"); + printf("the memory it tests. Assure the memory being tested does not contain\n"); + printf("the executable or data sections of this code or the exception address\n"); + printf("of the system.\n"); +} + +/****************************************************************** +* Function: GetInputString +* +* Purpose: Parses an input string for the character '\n'. Then +* returns the string, minus any '\r' characters it +* encounters. +* +******************************************************************/ +void GetInputString( char* entry, int size, FILE * stream ) +{ + int i; + int ch = 0; + + for(i = 0; (ch != '\n') && (i < size); ) + { + if( (ch = alt_getchar()) != '\r') + { + putchar(ch); + entry[i] = ch; + i++; + } + } +} + +/****************************************************************** +* Function: MemGetAddressRange +* +* Purpose: Gathers a range of memory from the user. +* +******************************************************************/ +static int MemGetAddressRange(int* base_address, int* end_address) +{ + + char line[12]; + char *pend; + + while(1) + { + /* Get the base address */ + printf("Base address to start memory test: (i.e. 0x800000)\n"); + printf(">"); + + GetInputString( line, sizeof(line), stdin ); + + /* Check the format to make sure it was entered as hex */ + + if((*base_address = strtol(line, &pend, 16)) < 0) + { + printf("%s\n", line); + printf(" -ERROR: Invalid base address entered. Address must be in the form '0x800000'\n\n"); + continue; + } + + /* Get the end address */ + printf("End Address:\n"); + printf(">"); + + GetInputString( line, sizeof(line), stdin ); + + /* Check the format to make sure it was entered as hex */ + if((*end_address = strtol(line, &pend, 16)) < 0) + { + printf(" -ERROR: Invalid end address entered. Address must be in the form '0x8FFFFF'\n\n"); + continue; + } + + /* Make sure end address is greater than base address. */ + if (*end_address <= *base_address) + { + printf(" -ERROR: End address must be greater than the start address\n\n"); + + continue; + } + break; + } -#define msleep(msec) usleep(1000*msec); + return(0); +} -pio_write (unsigned int data) +/****************************************************************** +* Function: MemTestDataBus +* +* Purpose: Tests that the data bus is connected with no +* stuck-at's, shorts, or open circuits. +* +******************************************************************/ +static int MemTestDataBus(unsigned int address) { - IOWR (PIO_0_BASE, 0, data); + unsigned int pattern; + unsigned int ret_code = 0x0; + + /* Perform a walking 1's test at the given address. */ + for (pattern = 1; pattern != 0; pattern <<= 1) + { + /* Write the test pattern. */ + IOWR_32DIRECT(address, 0, pattern); + + /* Read it back (immediately is okay for this test). */ + if (IORD_32DIRECT(address, 0) != pattern) + { + printf("Wrote %x got %x\n",pattern,IORD_32DIRECT(address, 0)); + ret_code = pattern; + break; + } + } + + return ret_code; } -static void -show (int v) + +/****************************************************************** +* Function: MemTestAddressBus +* +* Purpose: Tests that the address bus is connected with no +* stuck-at's, shorts, or open circuits. +* +******************************************************************/ +static int MemTestAddressBus(unsigned int memory_base, unsigned int nBytes) { - // int to seven segment lookup: MSB dp g f e d c b a LSB - const uint8_t lookup[10] = - { 0x3F, 0x6, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x7, 0x7F, 0x6F }; + unsigned int address_mask = (nBytes - 1); + unsigned int offset; + unsigned int test_offset; + + unsigned int pattern = 0xAAAAAAAA; + unsigned int antipattern = 0x55555555; + + unsigned int ret_code = 0x0; + + /* Write the default pattern at each of the power-of-two offsets. */ + for (offset = sizeof(unsigned int); (offset & address_mask) != 0; offset <<= 1) + { + IOWR_32DIRECT(memory_base, offset, pattern); + } + + /* Check for address bits stuck high. */ + test_offset = 0; + IOWR_32DIRECT(memory_base, test_offset, antipattern); + for (offset = sizeof(unsigned int); (offset & address_mask) != 0; offset <<= 1) + { + if (IORD_32DIRECT(memory_base, offset) != pattern) + { + ret_code = (memory_base+offset); + break; + } + } + + /* Check for address bits stuck low or shorted. */ + IOWR_32DIRECT(memory_base, test_offset, pattern); + for (test_offset = sizeof(unsigned int); (test_offset & address_mask) != 0; test_offset <<= 1) + { + if (!ret_code) + { + IOWR_32DIRECT(memory_base, test_offset, antipattern); + for (offset = sizeof(unsigned int); (offset & address_mask) != 0; offset <<= 1) + { + if ((IORD_32DIRECT(memory_base, offset) != pattern) && (offset != test_offset)) + { + ret_code = (memory_base + test_offset); + break; + } + } + IOWR_32DIRECT(memory_base, test_offset, pattern); + } + } + + return ret_code; +} + + +/****************************************************************** +* Function: MemTest8_16BitAccess +* +* Purpose: Tests that the memory at the specified base address +* can be read and written in both byte and half-word +* modes. +* +******************************************************************/ +static int MemTest8_16BitAccess(unsigned int memory_base) +{ + int ret_code = 0x0; + + /* Write 4 bytes */ + IOWR_8DIRECT(memory_base, 0, 0x0A); + IOWR_8DIRECT(memory_base, 1, 0x05); + IOWR_8DIRECT(memory_base, 2, 0xA0); + IOWR_8DIRECT(memory_base, 3, 0x50); - uint8_t pio = 0; + /* Read it back as one word */ + if(IORD_32DIRECT(memory_base, 0) != 0x50A0050A) + { + ret_code = memory_base; + } + + /* Read it back as two half-words */ + if (!ret_code) + { + if ((IORD_16DIRECT(memory_base, 2) != 0x50A0) || + (IORD_16DIRECT(memory_base, 0) != 0x050A)) + { + ret_code = memory_base; + } + } + + /* Read it back as 4 bytes */ + if (!ret_code) + { + if ((IORD_8DIRECT(memory_base, 3) != 0x50) || + (IORD_8DIRECT(memory_base, 2) != 0xA0) || + (IORD_8DIRECT(memory_base, 1) != 0x05) || + (IORD_8DIRECT(memory_base, 0) != 0x0A)) + { + ret_code = memory_base; + } + } + + /* Write 2 half-words */ + if (!ret_code) + { + IOWR_16DIRECT(memory_base, 0, 0x50A0); + IOWR_16DIRECT(memory_base, 2, 0x050A); + + /* Read it back as one word */ + if(IORD_32DIRECT(memory_base, 0) != 0x050A50A0) + { + ret_code = memory_base; + } + } - // show negative with DP - if (v < 0) + /* Read it back as two half-words */ + if (!ret_code) + { + if ((IORD_16DIRECT(memory_base, 2) != 0x050A) || + (IORD_16DIRECT(memory_base, 0) != 0x50A0)) { - pio |= 0x80; - v = -v; + ret_code = memory_base; } + } + + /* Read it back as 4 bytes */ + if (!ret_code) + { + if ((IORD_8DIRECT(memory_base, 3) != 0x05) || + (IORD_8DIRECT(memory_base, 2) != 0x0A) || + (IORD_8DIRECT(memory_base, 1) != 0x50) || + (IORD_8DIRECT(memory_base, 0) != 0xA0)) + { + ret_code = memory_base; + } + } + + return(ret_code); +} + + +/****************************************************************** +* Function: MemTestDevice +* +* Purpose: Tests that every bit in the memory device within the +* specified address range can store both a '1' and a '0'. +* +******************************************************************/ +static int MemTestDevice(unsigned int memory_base, unsigned int nBytes) +{ + unsigned int offset; + unsigned int pattern; + unsigned int antipattern; + unsigned int ret_code = 0x0; + + /* Fill memory with a known pattern. */ + for (pattern = 1, offset = 0; offset < nBytes; pattern++, offset+=4) + { + IOWR_32DIRECT(memory_base, offset, pattern); + } + + printf(" ."); - if (v > 9) - v = 9; + /* Check each location and invert it for the second pass. */ + for (pattern = 1, offset = 0; offset < nBytes; pattern++, offset+=4) + { + if (IORD_32DIRECT(memory_base, offset) != pattern) + { + ret_code = (memory_base + offset); + break; + } + antipattern = ~pattern; + IOWR_32DIRECT(memory_base, offset, antipattern); + } - pio |= lookup[v]; + printf(" ."); - pio_write (pio); + /* Check each location for the inverted pattern and zero it. */ + for (pattern = 1, offset = 0; offset < nBytes; pattern++, offset+=4) + { + antipattern = ~pattern; + if (IORD_32DIRECT(memory_base, offset) != antipattern) + { + ret_code = (memory_base + offset); + break; + } + IOWR_32DIRECT(memory_base, offset, 0x0); + } + return ret_code; } +/****************************************************************** +* Function: TestRam +* +* Purpose: Performs a full-test on the RAM specified. The tests +* run are: +* - MemTestDataBus +* - MemTestAddressBus +* - MemTest8_16BitAccess +* - MemTestDevice +* +******************************************************************/ +static void TestRam(void) +{ + + int memory_base, memory_end, memory_size; + int ret_code = 0x0; + + /* Find out what range of memory we are testing */ + MemGetAddressRange(&memory_base, &memory_end); + memory_size = (memory_end - memory_base); + + printf("\n"); + printf("Testing RAM from 0x%X to 0x%X\n", memory_base, (memory_base + memory_size)); + + /* Test Data Bus. */ + ret_code = MemTestDataBus(memory_base); + + if (ret_code) + printf(" -Data bus test failed at bit 0x%X", (int)ret_code); + else + printf(" -Data bus test passed\n"); + /* Test Address Bus. */ + if (!ret_code) + { + ret_code = MemTestAddressBus(memory_base, memory_size); + if (ret_code) + printf(" -Address bus test failed at address 0x%X", (int)ret_code); + else + printf(" -Address bus test passed\n"); + } + + /* Test byte and half-word access. */ + if (!ret_code) + { + ret_code = MemTest8_16BitAccess(memory_base); + if (ret_code) + printf(" -Byte and half-word access test failed at address 0x%X", (int)ret_code); + else + printf(" -Byte and half-word access test passed\n"); + } -int -main (void) + /* Test that each bit in the device can store both 1 and 0. */ + if (!ret_code) + { + printf(" -Testing each bit in memory device."); + ret_code = MemTestDevice(memory_base, memory_size); + if (ret_code) + printf(" failed at address 0x%X", (int)ret_code); + else + printf(" passed\n"); + } + + if (!ret_code) + printf("Memory at 0x%X Okay\n", memory_base); +} + +/****************************************************************** +* Function: main +* +* Purpose: Continually prints the menu and performs the actions +* requested by the user. +* +******************************************************************/ +int main(void) { - int i; - printf ("Working...\n"); - for (;;) { - for (i=-9;i<10;++i) { - printf("Showing %d\n",i); - show(i); - msleep(1000); + + int ch; + + /* Print the Header */ + MenuHeader(); + + while (1) + { + printf("\nPress enter to continue or 'q' to quit.\n"); + ch = alt_getchar(); + putchar(ch); + if(ch == 'q' || ch == 'Q') + { + printf( "\nExiting from Memory Test.\n"); + break; + } + else if (ch == '\n') + { + TestRam(); + } } - } - + return (0); } + + +/****************************************************************************** +* * +* License Agreement * +* * +* Copyright (c) 2004 Altera Corporation, San Jose, California, USA. * +* All rights reserved. * +* * +* Permission is hereby granted, free of charge, to any person obtaining a * +* copy of this software and associated documentation files (the "Software"), * +* to deal in the Software without restriction, including without limitation * +* the rights to use, copy, modify, merge, publish, distribute, sublicense, * +* and/or sell copies of the Software, and to permit persons to whom the * +* Software is furnished to do so, subject to the following conditions: * +* * +* The above copyright notice and this permission notice shall be included in * +* all copies or substantial portions of the Software. * +* * +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * +* DEALINGS IN THE SOFTWARE. * +* * +* This agreement shall be governed in all respects by the laws of the State * +* of California and by the laws of the United States of America. * +* Altera does not recommend, suggest or require that this reference design * +* file be used in conjunction or combination with any other product. * +******************************************************************************/ -- cgit v1.2.3