I a looking to interface a MR2A16A 4 Mb 16-bit MRAM with an Arduino Mega. I am new to interfacing with memory chips and would like some advice from someone more experienced than myself. I am not looking for speed or a permanent implementation, I just want to be able to read and write to the chip for testing purposes.

From the datasheet it seems the MRAM uses the exact same timings and interface as a similar SRAM chip. I looked at the pinouts and I should have enough for the 18 address pins and the 16 data pins of the MRAM plus the 5 control pins.

Please let me know if:

  1. This is possible
  2. What advice/tips I need to proceed
  3. I would need any additional circuity to interface the chip
  • 2
    \$\begingroup\$ A parallel interface, such as the one on the device you have chosen is fast but difficult to wire up (takes lots of of wires and uses up lots of IO lines). An Arduino, is too slow (in clock speed and extra layers of Arduino code) to be able use anywhere near the full speed potential of that interface. I suggest you go with the SPI version MRAM device which will use many less lines (just 4). It will also be probably be comparable in speed to flipping GPIO on a parallel interface on an Arduino since it can use the SPI hardware and bypass some Arduino software layers. \$\endgroup\$
    – DKNguyen
    Mar 25, 2019 at 22:09
  • \$\begingroup\$ Thank you for the quick response, I was considering that and will definitely try it. While the more simple SPI version of the chip is sufficient for my application I will one day need to be able to interface with the more complicated parallel interface. \$\endgroup\$ Mar 26, 2019 at 20:35
  • \$\begingroup\$ I understand, but an Arduino is not the processor to do that on. Move up to a bare chip where you have an external memory controller and probably a custom PCB (noise issues) before you do that since even as a learning experience, it is a waste with an Arduino because you would almost never use such an interface with bit-blasted GPIO anyways. \$\endgroup\$
    – DKNguyen
    Mar 26, 2019 at 20:37
  • \$\begingroup\$ Ok, so this makes sense. I have also looked into using an FTDI development board with bit-blasting capability. Unfortunately I am having a hard time finding a solution that can handle the large interface. Would it be recommended to use shift registers to allow the FTDI device to interface with the memory chip? \$\endgroup\$ Mar 26, 2019 at 20:51
  • \$\begingroup\$ With regards to your latest question, are you just searching for ANY method to make use of a parallel-interface so you can learn? You don't care what's on the other end as long as the parallel interface is involved? It is difficult to find solutions that can handle parallel interfaces because they require so many pins. Normally you need BGAs (impractical for hobbiests to hand solder). They are available on QFP-208 processors but even then you are really scrounging for pins. \$\endgroup\$
    – DKNguyen
    Mar 26, 2019 at 20:54

3 Answers 3


The only thing that you have to do is perform logic level shifting. This is because the MR2A16A is a 3.3V powered device and looking at page 7 of the datasheet it shows the max input high voltage i.e. VIH. This is less than the max output voltage of the arduino (~5v) so you will risk damaging the MRAM if you don't level shift. As for the data pins since you have to read and write from them you would need bi-directional level shifting.For the address lines a simple unidirectional shifter would work. But with this many lines to apply level shifting on, it may be cumbersome.

The method of level shifting depends on the speed of your intended communications. Simple voltage dividers can work for slow signals but will not work for fast changing signals. There are ICs for this but it's entirely up o you if you get those or go DIY.

  • 1
    \$\begingroup\$ That is very helpful, I completely overlooked the logic leveling and appreciate the heads up. I intend to use some form of logic shifting solution that is readily available. \$\endgroup\$ Mar 26, 2019 at 20:38

Do you need your interface to go fast? If your software requires more than 100 KB/sec of bandwidth to RAM, you must make some particular considerations when designing your system to avoid a major bottleneck.

Firstly, try and write the function which you will use to access RAM, preferably in assembly. Using the GPIO port, you must set the address and R/W signal, then assert CS, then if writing you must drive valid data onto the data bus, and if reading you must ensure a particular minimum delay for a moment and then read data, and then you dessert CS. In particular, consider how you will transfer the address and data values from CPU registers to/from the GPIO registers. If your schematic does not connect the RAM buses to sequential GPIO pins, you will have to do a lot of bit swapping or use a lookup table to put the address and data bits on the right pins. Since every address and data value is unique, swapping pins within a bus doesn’t matter (unless your RAM is like SDRAM and increments the address during a burst). The best case is to connect, for example, A[7:0] to PA[7:0] and D[7:0] to PB[7:0]. Keep in mind that not all of the port groups have all 8 signals available, making the wider ports more valuable.

You must also make adequate consideration for all of the timing parameters of the RAM. Firstly, don’t violate the access time specification when reading. If your Arduino is running at 16 MHz, that makes for a 62.5ns cycle time, and say your RAM has a 100ns access time. AVR PORT operations can complete in 1 cycle, so obviously a good engineer would ensure that two or more cycles elapse between enabling and disabling the RAM’s CS pin. A speed-minded programmer might even think to assert CS, do a NOP, read the PIN register into a CPU register, then dessert CS. Unfortunately this approach would likely not work with the speeds I described. The pin state as read by the CPU is subject to at least one cycle of synchronization, and so it has one or more clock cycles of latency compared to what’s happening at the pins. You must make sure to compensate for this delay as well as all access, setup, and hold times when programming your read routine. Fortunately though, since the AVR has single-cycle I/O operations, you can dessert CS and then read the data bus immediately after (as long as interrupts are disabled), mitigating some of the additional NOPs you may have to put because of input latency. This issue only affects read operations, since write operations are unidirectional and therefore don’t suffer from the MCU’s input latency.

Another timing parameter to be aware of is the address setup time for write operations. Most RAMs say that you must make sure the address bus is valid before asserting CS and WR. If you have your CS pin and some of your address bus on the same port register, you can’t set the address and assert CS in the same operation, otherwise one of the address bits might lag the CS signal. Most RAMs work fine with a nanosecond or two violation of this type but it’s not good practice. For read operations, SRAMs typically allow you to change the address while CS is asserted as long as you wait the access time before reading the data bus. I don’t know if this is true of MRAMs.

If you are reading or writing sequential locations, consider writing a burst access function which loads or stores a few words of data. In addition to saving on function call overhead, if you have aligned data, you can skip changing some of the high-order address bits and save some time. And with SRAMs, as I said earlier, you usually don’t need to bring CS inactive for successive read accesses, so you can exploit this in your burst access function as well.

If you follow these simple rules, you’ll find that you can build fairly fast and reliable external RAM read and write functions. Obviously you can’t achieve the performance the intrinsic load and store operations, but 10 cycles is a reasonable goal if the access functions are inlined.


I found on Arduino forum this cool circuit diagram interfacing a MRAM 25H256 with an Arduino Nano. The author states is possible to do it using a logic level translator from Texas the TX801040. To use it , Adafruit's FRAM SPI library needs to be tweaked and remove the checks for the RDID. (MRAM doesn't have the RDID (read device ID) )

enter image description here

original post can be found here: https://forum.arduino.cc/t/struggling-to-interface-mram-with-arduino-nano/669526/2

  • 1
    \$\begingroup\$ Nice find! However, the question is specifically about interfacing to a 16-bit wide parallel MRAM, not one that has an SPI interface. \$\endgroup\$
    – StarCat
    Jan 28, 2023 at 9:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.