I have an external circuit connected to my Arduino Mega 2560. The interface on my circuit facing the Mega is a 2K X 8 static RAM, and its support chips, connected to the 36 pin (18 X 2) XIO connector. The XRAM feature of Mega's CPU is brought out on ports A, C, & G which are labeled digital pins 22-41. The low-order address/data lines are demux'ed with a 74AHC573 octal latch. The 5 highest-order address lines are decoded to map the RAM to start at 0x8000.
The only purpose for the Mega is to load the RAM.
The problem I have is how do I get my program to access the external RAM space. Ideally, I would like to somehow declare or allocate the entire space from 0x8000 to 0x87FF as a 2K array of bytes. I have not been able to dope out how to force the assignment of an address or pointer to a specific number.
Admittedly my hardware skills exceed my software expertise so any help would be much appreciated.
I have an external RAM board for my Mega made by RuggedCircuits. This is one of their test programs:
/* This MegaRAM application is a production test that verifies that
* all RAM locations are unique and can store values.
*
* Assumptions:
*
* - MegaRAM plugged in to Arduino Mega 1280 or Mega 2560
*
* The behavior is as follows:
*
* - Each one of 4 banks of 32 kbytes each is filled with a pseudorandom sequence of numbers
* - The 4 banks are read back to verify the pseudorandom sequence
* - On success, the Arduino's LED is turned on steadily, with a brief pulse off every 3 seconds
* - On failure, the Arduino's LED blinks rapidly
* - The serial port is used for status information (38400 bps)
*
* This software is licensed under the GNU General Public License (GPL) Version
* 3 or later. This license is described at
* http://www.gnu.org/licenses/gpl.html
*
* Application Version 1.0 -- August 2011 Rugged Circuits LLC
* http://www.ruggedcircuits.com/html/megaram.html
*/
void setup(void)
{
DDRD |= _BV(7); // PD7 is BANKSEL
PORTD = 0x7F; // Select bank 0, pullups on everything else
/* Enable XMEM interface:
SRE (7) : Set to 1 to enable XMEM interface
SRL2-0 (6-4) : Set to 00x for wait state sector config: Low=N/A, High=0x2200-0xFFFF
SRW11:0 (3-2) : Set to 00 for no wait states in upper sector
SRW01:0 (1-0) : Set to 00 for no wait states in lower sector
*/
XMCRA = 0x80;
// Bus keeper, lower 7 bits of Port C used for upper address bits, bit 7 is under PIO control
XMCRB = _BV(XMBK) | _BV(XMM0);
DDRC |= _BV(7);
PORTC = 0x7F; // Enable pullups on port C, select bank 0
// PL7 is RAM chip enable, active high. Enable it now, and enable pullups on Port L.
DDRL |= _BV(7);
PORTL = 0xFF;
// Open up a serial channel
Serial.begin(115200);
// Enable on-board LED
pinMode(13, OUTPUT);
Serial.println("Memory test begins ...");
}
// Blink the Arduino LED quickly to indicate a memory test failure
void blinkfast(void)
{
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
delay(100);
}
// Provide information on which address failed. Then, sit in an infinite loop blinking
// the LED quickly.
void fail(uint8_t *addr, uint8_t expect, uint8_t got)
{
Serial.print("At address "); Serial.print((uint16_t)addr);
Serial.print(" expected "); Serial.print(expect, DEC);
Serial.print(" got "); Serial.print(got, DEC);
Serial.println();
while (1) {
blinkfast();
}
}
#define STARTADDR ((uint8_t *)0x8000)
#define COUNT (0x8000-1)
long seed=1234;
// Select one of four 32 kilobyte banks
void banksel(uint8_t bank)
{
switch (bank) {
case 0:
PORTD &= ~_BV(7);
PORTC &= ~_BV(7);
break;
case 1:
PORTD &= ~_BV(7);
PORTC |= _BV(7);
break;
case 2:
PORTD |= _BV(7);
PORTC &= ~_BV(7);
break;
default:
PORTD |= _BV(7);
PORTC |= _BV(7);
break;
}
}
// Fill the currently selected 32 kilobyte bank of memory with a random sequence
void bankfill(void)
{
uint8_t *addr;
uint16_t count;
for (addr=STARTADDR, count=COUNT; count; addr++, count--) {
*addr = (uint8_t)random(256);
if ((count & 0xFFFU) == 0) blinkfast();
}
}
// Check the currently selected 32 kilobyte bank of memory against expected values
// in each memory cell.
void bankcheck(void)
{
uint8_t expect;
uint8_t *addr;
uint16_t count;
for (addr=STARTADDR, count=COUNT; count; addr++, count--) {
expect = random(256);
if (*addr != expect) fail(addr,expect,*addr);
if ((count & 0xFFFU) == 0) blinkfast();
}
}
void loop(void)
{
uint8_t bank;
// Always start filling and checking with the same random seed
randomSeed(seed);
// Fill all 4 banks with random numbers
for (bank=0; bank < 4; bank++) {
Serial.print(" Filling bank "); Serial.print(bank, DEC); Serial.println(" ...");
banksel(bank); bankfill();
}
// Restore the initial random seed, then check all 4 banks against expected random numbers
randomSeed(seed);
for (bank=0; bank < 4; bank++) {
Serial.print(" Checking bank "); Serial.print(bank, DEC); Serial.println(" ...");
banksel(bank); bankcheck();
}
// If we got this far, there were no failures
Serial.println("Success!");
Serial.println();
// Keep the LED on mostly, and pulse off briefly every 3 seconds
while (1) {
digitalWrite(13, HIGH);
delay(3000);
digitalWrite(13, LOW);
delay(500);
}
}
// vim: syntax=cpp ai ts=2 sw=2 cindent expandtab
exit status 1
'reinterpret_cast' undeclared here (not in a function)
I read through various articles yesterday and today. But I can't figure out, how to change my code in a way to get that working..
I also tried XMEM lib.. no success..
What I want is a RAM[] array of 32768 bytes (uint8_t) in the external sram, that I can:
read with: value = RAM[address];
write with: RAM[address] = value;
I need help! I am NOT an c or c++ expert! I just try to get around.
Now it works - but what really is bad is a bad test program, that says all is ok, but in reality it isn't ok!!!
The test program supplied at above link is using the following test:
bool test() {
for (uint16_t i = 0; i<32768; ++i) {
extmem = i & 0xFF;
}*
for (uint16_t i = 0; i<32768; ++i) {*
_ if (extmem != (i & 0xFF))_ * return false;* * }* * return true;* } The problem here is and was in my case, that the data value is the SAME as the lower 8-bit of the address! Thats a bad idea with a multiplexed data/address bus. Now, I had a bad 74LS373 latch - and guess what - I read back the lower 8 address bits = same as extected data value => test program said all is ok! That took my hours to find that out! Before that I measured all pcb traces - all ok. Than I modified the test program: bool test() { * for (uint16_t i = 0; i<32768; ++i) { _ extmem = (i+1) & 0xFF; }_ for (uint16_t i = 0; i<32768; ++i) { _ if (extmem != ((i+1) & 0xFF)) return false; } return true; }* Now the expected value is address+1 - and yes - now the test program reported that it failed! Second 74LS373 was also bad - but third one was fine and now it runs as expected. thx, Peter_