1 main.c
1 #include "led.h" 2 3 #define BASE_ADDRESS (volatile datum *) 0x10000000 4 #define NUM_BYTES 0x10000 5 6 /********************************************************************** 7 * 8 * Function: main() 9 * 10 * Description: Test the second 64 KB bank of SRAM. 11 * 12 * Notes: 13 * 14 * Returns: 0 on success. 15 * Otherwise -1 indicates failure. 16 * 17 **********************************************************************/ 18 main(void) 19 { 20 if ((memTestDataBus(BASE_ADDRESS) != 0) || 21 (memTestAddressBus(BASE_ADDRESS, NUM_BYTES) != NULL) || 22 (memTestDevice(BASE_ADDRESS, NUM_BYTES) != NULL)) 23 { 24 toggleLed(LED_RED); 25 return (-1); 26 } 27 else 28 { 29 toggleLed(LED_GREEN); 30 return (0); 31 } 32 33 } /* main() */
1.1 Data bus test
1 // typedef unsigned char datum; /* Set the data bus width to 8 bits. */ 2 /********************************************************************** 3 * 4 * Function: memTestDataBus() 5 * 6 * Description: Test the data bus wiring in a memory region by 7 * performing a walking 1's test at a fixed address 8 * within that region. The address (and hence the 9 * memory region) is selected by the caller. 10 * 11 * Notes: 12 * 13 * Returns: 0 if the test succeeds. 14 * A non-zero result is the first pattern that failed. 15 * 16 **********************************************************************/ 17 datum 18 memTestDataBus(volatile datum * address) 19 { 20 datum pattern; 21 /* 22 * Perform a walking 1's test at the given address. 23 */ 24 for (pattern = 1; pattern != 0; pattern <<= 1) 25 { 26 /* 27 * Write the test pattern. 28 */ 29 *address = pattern; 30 /* 31 * Read it back (immediately is okay for this test). 32 */ 33 if (*address != pattern) 34 { 35 return (pattern); 36 } 37 } 38 return (0); 39 } /* memTestDataBus() */
1.2 Address bus test
1 /********************************************************************** 2 * 3 * Function: memTestAddressBus() 4 * 5 * Description: Test the address bus wiring in a memory region by 6 * performing a walking 1's test on the relevant bits 7 * of the address and checking for aliasing. This test 8 * will find single-bit address failures such as stuck 9 * -high, stuck-low, and shorted pins. The base address 10 * and size of the region are selected by the caller. 11 * 12 * Notes: For best results, the selected base address should 13 * have enough LSB 0's to guarantee single address bit 14 * changes. For example, to test a 64-Kbyte region, 15 * select a base address on a 64-Kbyte boundary. Also, 16 * select the region size as a power-of-two--if at all 17 * possible. 18 * 19 * Returns: NULL if the test succeeds. 20 * A non-zero result is the first address at which an 21 * aliasing problem was uncovered. By examining the 22 * contents of memory, it may be possible to gather 23 * additional information about the problem. 24 * 25 **********************************************************************/ 26 datum * memTestAddressBus(volatile datum * baseAddress, unsigned long nBytes) 27 { 28 unsigned long addressMask = (nBytes/sizeof(datum) - 1); 29 unsigned long offset; 30 unsigned long testOffset; 31 datum pattern = (datum) 0xAAAAAAAA; 32 datum antipattern = (datum) 0x55555555; 33 /* 34 * Write the default pattern at each of the power-of-two offsets. 35 */ 36 for (offset = 1; (offset & addressMask) != 0; offset <<= 1) 37 { 38 baseAddress[offset] = pattern; 39 } 40 /* 41 * Check for address bits stuck high. 42 */ 43 testOffset = 0; 44 baseAddress[testOffset] = antipattern; 45 for (offset = 1; (offset & addressMask) != 0; offset <<= 1) 46 { 47 if (baseAddress[offset] != pattern) 48 { 49 return ((datum *) &baseAddress[offset]); 50 } 51 } 52 baseAddress[testOffset] = pattern; 53 /* 54 * Check for address bits stuck low or shorted. 55 */ 56 for (testOffset = 1; (testOffset & addressMask) != 0; testOffset <<= 1) 57 { 58 baseAddress[testOffset] = antipattern; 59 if (baseAddress[0] != pattern) 60 { 61 return ((datum *) &baseAddress[testOffset]); 62 } 63 for (offset = 1; (offset & addressMask) != 0; offset <<= 1) 64 { 65 if ((baseAddress[offset] != pattern) && (offset != testOffset)) 66 { 67 return ((datum *) &baseAddress[testOffset]); 68 } 69 } 70 baseAddress[testOffset] = pattern; 71 } 72 return (NULL); 73 } /* memTestAddressBus() */
1.3 Device test
1 /********************************************************************** 2 * 3 * Function: memTestDevice() 4 * 5 * Description: Test the integrity of a physical memory device by 6 * performing an increment/decrement test over the 7 * entire region. In the process every storage bit 8 * in the device is tested as a zero and a one. The 9 * base address and the size of the region are 10 * selected by the caller. 11 * 12 * Notes: 13 * 14 * Returns: NULL if the test succeeds. Also, in that case, the 15 * entire memory region will be filled with zeros. 16 * 17 * A non-zero result is the first address at which an 18 * incorrect value was read back. By examining the 19 * contents of memory, it may be possible to gather 20 * additional information about the problem. 21 * 22 **********************************************************************/ 23 datum * memTestDevice(volatile datum * baseAddress, unsigned long nBytes) 24 { 25 unsigned long offset; 26 unsigned long nWords = nBytes / sizeof(datum); 27 datum pattern; 28 datum antipattern; 29 /* 30 * Fill memory with a known pattern. 31 */ 32 for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++) 33 { 34 baseAddress[offset] = pattern; 35 } 36 /* 37 * Check each location and invert it for the second pass. 38 */ 39 for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++) 40 { 41 if (baseAddress[offset] != pattern) 42 { 43 return ((datum *) &baseAddress[offset]); 44 } 45 antipattern = ~pattern; 46 baseAddress[offset] = antipattern; 47 } 48 /* 49 * Check each location for the inverted pattern and zero it. 50 */ 51 for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++) 52 { 53 antipattern = ~pattern; 54 if (baseAddress[offset] != antipattern) 55 { 56 return ((datum *) &baseAddress[offset]); 57 } 58 } 59 return (NULL); 60 } /* memTestDevice() */