We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello, I am trying to check if addresses bus and data bus are well configured in my external RAM memory. I have done this algorithm
#include <XC164.h> #define low_adress 0x400000; #define high_adress 0x410000; #define high_data 0xFF; #define low_data 0x00; void main (void) { static double idata j,i,k; int xhuge *DIR; DIR = 0x400000; /* DATA BUS TEST */ for (j = low_adress; j <= high_adress; j++) { *DIR = 0x55; // I write 0101 0101 if (*DIR != 0x55) P3^3 = 1; // If what I have read is diferent to what I have written, I switch on an alarm *DIR = 0xAA; // I write 1010 1010 if (*DIR != 0xAA) P3^3 = 1; // If what I have read is diferent to what I have written, I switch on an alarm DIR++; } /* ADRESSES BUS TEST */ DIR = 0x400000; for (i = low_adress; i < high_adress; i = i + 0xFF;) { for (k = low_data; k < high_data ; k++) { *DIR = k; DIR++; } }
but the compiler throws errors. My RAM memory is mapped from 0x400000 to 0x410000 (64kB). Why does the compiler throw this errors?
Build target 'Target 1' assembling START_V2.A66... compiling PruebaRA.c... PRUEBARA.C(17): error C25: syntax error near '=' PRUEBARA.C(17): error C25: syntax error near ';' PRUEBARA.C(17): error C25: syntax error near ')' PRUEBARA.C(20): error C25: syntax error near 'if' PRUEBARA.C(20): error C25: syntax error near 'P3' PRUEBARA.C(20): error C25: syntax error near '=' PRUEBARA.C(22): error C25: syntax error near 'if' PRUEBARA.C(22): error C25: syntax error near 'P3' PRUEBARA.C(22): error C25: syntax error near '=' PRUEBARA.C(24): error C25: syntax error near '}' PRUEBARA.C(29): error C25: syntax error near 'for' PRUEBARA.C(29): error C7: compilation aborted Target not created
looks ok as long as no component of your program is mapped to 0x400000.
Soon I will do the test.
Tamir, "MY_OUT" has been set. => The data test its ok! :-D Now, I am going to do the adresses test. Thanks for your help. I write here the used program if someone need it:
#include <XC164.h> #include <intrins.h> typedef unsigned char U8; // Set the data bus width to 8 bits. U8 memTestDataBus(volatile U8 * address); volatile U8 *pointer; sbit MY_OUT = P1L^0; void main (void) { DP1L = 0x0001; // load direction register pointer = 0x400000; // the pointer points at 0x400000 adress if (memTestDataBus(pointer) == 0) MY_OUT = 1; // if the result of the test is ok toggle MY_OUT to 5V while (1) { ; } } /////////////////////////////////////////////////////////////////////// U8 memTestDataBus(volatile U8 * address) { U8 pattern; for (pattern = 1; pattern != 0; pattern <<= 1) { //Write the test pattern. *address = pattern; //Read it back (immediately is okay for this test). if (*address != pattern) { return (pattern); } } return (0); } /* memTestDataBus() */ /////////////////////////////////////////////////////////////////////////
But are you aware that the memTestDataBus() only tests if there exists working memory at one specific little byte. It does not test all cells of the memory. An external loop is needed to step "pointer" to all RAM addresses and test them one-by-one. But once more: the test is destructive, so if it tests a RAM cell that contains critical data, your program will crash.
Another interesting thing is that memory constructs that doesn't multiplex address and data can pass such a memory test since a write followed by a read may pick up the old signal states. Capacitances on the signals will make it possible to write out in the air, and then read back the same value. In such cases, it is good to write a test pattern to one address, and a dummy pattern to another address and then read back the test pattern from the original address. If reading air, you will get the dummy pattern instead of the test pattern.
John, Have you read Per's comments AND the article whose address that I posted above? obviously you didn't, because both address a critical mistake in your code...
Per, as it is written in Tamirs article toverify if the program writes well or not, is only needed any adress and probe that all posible datas are well written. Although, the program is destructive, at first the memory doesn't contain any critical data.
Ups, I didn't read the last post of Tamir. It seems that I donÂ't understand well the article.
The code a number of bit patterns, so (unless you have capacitive "memory" from a non-multiplexed memory interface) it does test that no data line is shorted to plus, to ground or to a neighbour.
That is a good test.
But it does not test each individual memory address of the memory. The loop in the function steps through test patterns, not memory addresses. Think about it - you specify a pointer, but not a memory size. How would the function know how many memory addresses to test?
That loop is your responsibility. The reason for this is that it allows you to find - and be able to report - each and every memory cell that fails.
But there are another problem that isn't tested. And that is errors with the address lines, giving aliasing between memory cells. Let's say that one address line is shorted. You think that you write to address x. But because of the short, you write to memory cell (x | pattern) or (x & pattern).
Because of this, a full memory test should not just test individual memory cells one-by-one, but it should also try to find aliasing. An example (assuming that 'base' is the start address of the memory, and that the memory has a size 2^n and that 'base' has the n lowest bits zero: - Clear all memory to zero. - write 1 at address (base+0) - write 2 at (base+1) - write 3 at (base+2) - write 4 at (base+4) - write 5 at (base+8) - write 6 at (base+16) ... - walk through the memory and verify that all memory cells are zero, with the explicit exception of the addresses you wrote above.
Each of the above writes sets one address line high, and writes a value. If an address line is shorted low, that specific write will write to the wrong address. If an address line is shorted high, all but one of the writes will write to the wrong address. If two address lines are shorted together, two of the above writes will write to the wrong address.
But for the fourth time: If call memTestDataBus() on a memory address that stores critical data used by memTestDataBus() or by main() or by an interrupt (unless you have turned off interrupts) your program will fail badly.
memTestDataBus() can be modified to work better by storing the original value of a data cell before testing it, and putting back the original value before returning.
That will not help if you have interrupts enabled. And it will not work if you test the memory addresss used for the parameter 'address' or the loop variable 'pattern' or the new temp variable used to store the original value of the cell. Making sure that the temp value, 'pattern' and 'address' are stored in register variables would also be needed to make memTestDataBus() reasonably useable.