DDR DIMM SPD Adapter for Raspberry Pi

All computer DDR memory today have little I2C EEPROMs to store vendor, configuration and module spec information.
This is done to allow computer to detect memory type, and configure memory interface to correct speeds and voltages according to
module spec. This mechanism is based on JEDEC Serial presence detection specification (SPD) which is available for download.

Sometimes it’s needed to modify SPD and there are rarely available software tools to do so in-system.
To overcome this issue design can be done stand-alone, with independent hardware to read/write EEPROM on memory module.
Raspberry Pi is one from hundreds of possible ways to do such, and it’s easy and widely popular linux platform, which
enables lot of engineers to customize and discover new uses of ARM embedded platform.

And since we don’t want to modify anything on DIMM modules directly, there is requirement to have standard DIMM sockets,
so user can easily interchange modules to perform SPD operations, without any damage risk or soldering.

DDR DIMM SPD Adapter for Raspberry Pi

Basic spec for this little project

  • Open-source project, managed via dev.xdevs.com and mercurial DVCS
  • Full-size DDR3/DDR4 UDIMM/RDIMM slots to support most of standard memory modules
  • Standard header for direct connection to Raspberry Pi host
  • I2C EEPROM interface connection for Raspberry Pi port
  • Fixed +3.3V voltage level for SPD power
  • Power switch to allow swapping modules without RPI power down.
  • I2C address switch to enable multiple adapters to be used with single RPI.
  • Onboard MCU (LPC11U37FBD64) for future development/standalone operation without RPI (e.g. automation usage)

Project file tree

All project files and documentation tracked by Mercurial DVCS.
It’s free and well maintained version control engine, with syntax similar to git and SVN.

Hardware design

Pretty simple design with low amount of parts. MCU section is optional and not required for operation with RPI.

PCB Layout is done for 4-layer FR4, with silkscreen on both sides for assembly aid. All parts except connectors, switches and solid capacitor
are SMD. Gerber files available for download as well

For DIY assembly or custom applications this can be simplified even more

This is as simple as it goes, two pull-up resistors for I2C bus, +3.3V power taken from RPI and power switch with LED.

Manufactured adapter (hand assembled board and bare PCB)

Required parts for Raspberry Pi only operation:

  • Power switch SW4 (2-position)
  • I2C pullup resistors R10,R9 (2.2kOhm, 0603 5%)
  • Bypass resistor R7 (0-10 ohm, 0603 5%)
  • Decoupling capacitors C3,C2 (0.1uF 0603 X7R)
  • Bulk capacitor C4 (100-560uF 6.3-16V 7mm diameter, pin pitch 4mm)
  • 2.54mm 26-pin header for RPI extension port P1.
  • DDR3 240-pin DIMM slot
  • DDR4 288-pin DIMM slot (if required)

All these components located in bottom right area.

Bottom side have only optional decorative 0603 LEDs.

Power, I2C, SPI and UART are routed from 26-pin header, which mates with Raspberry Pi expansion port just with straight ribbon cable.

Adressing for multiple adapters is set via 2-position switches and indicated by LEDs. It’s just usual A0,A1,A2 pin signaling for I2C EEPROMs.

Onboard MCU is NXP LPC11U37FBD64 with SWD header for debug/firmware development. SMD crystal is 12.000 MHz, to support UART and USB.

From top to bottom – DDR3 Corsair UDIMM, DDR adapter board, Raspberry Pi Model B with 2GB SD card and 26-pin 2.54mm cable.

Using DDR3 module and connections:

Using DDR4 RDIMM module and connections:

Software design

This is step-by-step tutorial how to get fresh Raspberry Pi up and running for this project:

I used minimal OS, as intention was only to use network-based connection to RPI via ssh.
OS Image can be downloaded from origin here: http://www.linuxsystems.it/raspbian-wheezy-armhf-raspberry-pi-minimal-image/
or from local mirror
It’s 120MB, so can take a little time to download.
To write image onto SD card you can use any imager tool.
For Win32 there is free Win32 Disk imager from gruemaster, tuxinator2009

The root password is raspberry.

Software setup

For accessing Raspberry Pi via network you will need to have network (eth0) configured properly.
If your network have DHCP service, usually enough just to add next line to /etc/network/interfaces

iface eth0 inet dhcp

If SD card is bigger than 1GB (which follows filesystem in linux image mentioned above), you may want to add extra
partition to use extra space.

Create new partition using fdisk, so final table can look like this:

[email protected]:/# fdisk /dev/mmcblk0
Command (m for help): p
Disk /dev/mmcblk0: 32.1 GB, 32127320064 bytes
        Device Boot      Start         End      Blocks   Id  System
/dev/mmcblk0p1            2048      104447       51200    b  W95 FAT32
/dev/mmcblk0p2          104448     1742847      819200   83  Linux
/dev/mmcblk0p3         1742848     1945599      101376   82  Linux swap / Solaris
/dev/mmcblk0p4         1945600    62748671    30401536   83  Linux

Then make ext4 filesystem in new partition.

[email protected]:/# mkfs.ext4 /dev/mmcblk0p4 -L ummspi2
mke2fs 1.42.5 (29-Jul-2012)
Filesystem label=ummspi2
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

Now make sure your /etc/fstab is updated:

[email protected]:/# cat /etc/fstab
# <file system> <mount point>   <type>          <options>               <dump>  <pass>
proc            /proc           proc            defaults                0       0
/dev/mmcblk0p1  /boot           vfat            defaults                0       0
/dev/mmcblk0p3  none            swap            sw                      0       0
*/dev/mmcblk0p4  /repo           ext4            defaults                0       0*
[email protected]:/#

Here I have /repo filesystem partition with ext4 Linux type.
Now we can mount it.

[email protected]:/# mount -a

And it’s ready to use:

[email protected]:/# df -h
Filesystem      Size  Used Avail Use% Mounted on
rootfs          788M  566M  222M  72% /
/dev/root       788M  566M  222M  72% /
devtmpfs        212M     0  212M   0% /dev
tmpfs            44M  180K   44M   1% /run
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           108M     0  108M   0% /run/shm
/dev/mmcblk0p1   50M   19M   32M  37% /boot
*/dev/mmcblk0p4   29G  172M   27G   1% /repo*

It’s usually good idea to update your OS packages prior to installation of new software.
Be aware, than if your memory storage is limited, then you may run out of space if new packages occupy too much size.
Aptitude is common way for updating:

[email protected]:~# aptitude update
Get: 1 http://archive.raspbian.org wheezy Release.gpg [490 B]
Get: 2 http://archive.raspbian.org wheezy Release [14.4 kB]
Get: 3 http://archive.raspbian.org wheezy/main Sources [6262 kB]
70% [3 Sources 4375 kB/6262 kB 70%].....79.8 kB/s 23s
Current status: 33 updates [+33], 77 new [+77].

And then run actual update.
Example output can be like below:

[email protected]:~# aptitude dist-upgrade
The following packages will be upgraded:
  apt apt-utils base-files dmsetup dpkg gnupg gpgv initscripts libapt-inst1.5 libapt-pkg-dev libapt-pkg4.12 libc-bin libc-dev-bin libc6 libc6-dev libdevmapper1.02.1 libgnutls26
  libssl1.0.0 linux-libc-dev locales lsb-base multiarch-support openssh-client openssh-server perl perl-base perl-modules ssh sysv-rc sysvinit sysvinit-utils tzdata wget
The following packages are RECOMMENDED but will NOT be installed:
  bcc gcc gcc-4.4 gcc-4.5 gcc-4.6 gcc-4.7 gnupg-curl libldap-2.4-2 manpages-dev psmisc
33 packages upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 35.5 MB of archives. After unpacking 234 kB will be freed.
Do you want to continue? [Y/n/?] Y
Setting up ssh (1:6.0p1-4+deb7u1) ...
Setting up perl (5.14.2-21+rpi2+deb7u1) ...
Current status: 0 updates [-33].

Also since i’m DOS-grown, prefer to use mcedit as default system editor. To change default nano to mcedit you can run

[email protected]:/etc/mercurial# update-alternatives —config editor
There are 3 choices for the alternative editor (providing /usr/bin/editor).

  Selection    Path               Priority   Status
  0            /bin/nano           40        auto mode
  1            /bin/nano           40        manual mode
  2            /usr/bin/mcedit     25        manual mode
  3            /usr/bin/vim.tiny   10        manual mode

DDR DIMM SPD Adapter for Raspberry Pi schematic

Press enter to keep the current choice[*], or type selection number: 2
update-alternatives: using /usr/bin/mcedit to provide /usr/bin/editor (editor) in manual mode

I usually prefer to keep all develpoment and project files in local repository, install mercurial so
we can develop our software and commit changes right away from Raspberry Pi system.

apt-get install mercurial
[email protected]:~# apt-get install mercurial
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
  ca-certificates mercurial-common openssl python python-minimal
Suggested packages:
  qct wish vim emacs kdiff3 kdiff3-qt kompare meld xxdiff tkcvs mgdiff python-mysqldb python-pygments python-openssl python-doc python-tk
The following NEW packages will be installed:
  ca-certificates mercurial mercurial-common openssl python python-minimal
0 upgraded, 6 newly installed, 0 to remove and 0 not upgraded.
Need to get 3514 kB of archives.
After this operation, 10.3 MB of additional disk space will be used.
Do you want to continue [Y/n]? Y
Get:1 http://archive.raspbian.org/raspbian/ wheezy/main python-minimal all 2.7.3-4+deb7u1 [42.8 kB]
Creating config file /etc/mercurial/hgrc.d/hgext.rc with new version
Processing triggers for ca-certificates ...
Updating certificates in /etc/ssl/certs... 158 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d....done.

For mercurial repostory system how-to you can reference official documentation or short article here.

Now it’s time to do actual software setup for accessing our I2C hardware.

1. Add to /etc/modules


1b. If your Linux kernel is 3.18 or newer, add next lines to */boot/config.txt. This is due to migration for new Device Tree method.


2. sudo apt-get install python-smbus

[email protected]:~# apt-get install python-smbus
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
Suggested packages:
The following NEW packages will be installed:
  i2c-tools python-smbus
0 upgraded, 2 newly installed, 0 to remove and 32 not upgraded.
Need to get 71.0 kB of archives.
After this operation, 317 kB of additional disk space will be used.
Do you want to continue [Y/n]? Y
Get:1 http://archive.raspbian.org/raspbian/ wheezy/main i2c-tools armhf 3.1.0-2 [59.5 kB]
Get:2 http://archive.raspbian.org/raspbian/ wheezy/main python-smbus armhf 3.1.0-2 [11.5 kB]
Fetched 71.0 kB in 1s (36.0 kB/s)
Selecting previously unselected package i2c-tools.
(Reading database ... 22286 files and directories currently installed.)
Unpacking i2c-tools (from .../i2c-tools_3.1.0-2_armhf.deb) ...
Selecting previously unselected package python-smbus.
Unpacking python-smbus (from .../python-smbus_3.1.0-2_armhf.deb) ...
Processing triggers for man-db ...
Setting up i2c-tools (3.1.0-2) ...
Setting up python-smbus (3.1.0-2) ...

3. sudo apt-get install i2c-tools

[email protected]:~# apt-get install i2c-tools
Reading package lists... Done
Building dependency tree
Reading state information... Done
i2c-tools is already the newest version.
i2c-tools set to manually installed.
0 upgraded, 0 newly installed, 0 to remove and 32 not upgraded.

4. Now we can connect adapter board and try i2c detect tool to see if I2C interface working.

i2cdetect -y 1

When no devices / memory modules installed there should be no devices present on any address.
Just like this:

[email protected]:~# i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

5. Minimalist linux builds may not have gcc compiler as well, so install it before you can compile/test own code.

apt-get install gcc
apt-get install make 

If you get errors like:

sudo: unable to resolve host raspberry-pi

Then add line to /etc/hosts raspberry-pi

6. If you have wiringPi library not installed, need to install it.
If you used OS image attached in this code repository, then you will need to install wiringPi library.

[email protected]:/rpdb/ddr4s/fw/wiringPi# ./build
wiringPi Build script
WiringPi Library
[Compile] wiringPi.c
[Compile] wiringSerial.c
[Compile] wiringShift.c
[Compile] wiringPiSPI.c
[Compile] wiringPiI2C.c
[Compile] drcSerial.c
[Link (Dynamic)]
[Install Headers]
[Install Dynamic Lib]
WiringPi Devices Library
[Compile] ds1302.c
[Compile] maxdetect.c
[Compile] piNes.c
[Compile] gertboard.c
[Compile] piFace.c
[Compile] lcd128x64.c
[Compile] lcd.c
[Compile] piGlow.c
[Link (Dynamic)]
[Install Headers]
[Install Dynamic Lib]
GPIO Utility
[Compile] gpio.c
gpio.c:85:12: warning: 'decodePin' defined but not used [-Wunused-function]
[Compile] extensions.c
[Compile] readall.c
All Done.
NOTE: This is wiringPi v2, and if you need to use the lcd, Piface,
  Gertboard, MaxDetext, etc. routines then you must change your
  compile scripts to add -lwiringPiDev

7. Running test GCC-compiled software in putty terminal connection to Raspberry Pi’s Debian Linux.


8. Usage:

  • /comp.sh* – compiler script to run gcc compiler with spd_prog_both.c to generate spd_prog main app executable (*nix)
  • /check.sh* – compiler script to run gcc compiler with checksum.c to generate checksum tool executable (*nix)
  • /spd_prog* – runs application to read/write DDR3/DDR4 SPD. It operates with plain binary files only.
  • /checksum* – runs tool to calculate and check CRC16 fields in DDR3/DDR4 plain binary file. It accepts filename with parameter -f [filename]

9. Check sum tool example:
DDR3 dump example:

$:/repo/ddr4s/fw/Pi$ ./checksum -f ddr3.bin 
/********************** xDevs.com DDR4s Project ************************/
 DDR3/DDR4 dump checksum check tool | calculates CRC16 for input binary  
 Usage: checksum -f [dump_filename] 
File DDR3 CRC16 = 600E | byte 126 = E | byte 127 = 60 
Calculated DDR3 CRC16 = 600E | byte 126 = E | byte 127 = 60 
CRC in dump is correct

DDR4 Dump example

$:/repo/ddr4s/fw/Pi$ ./checksum -f ddr4.bin 
/********************** xDevs.com DDR4s Project ************************/
 DDR3/DDR4 dump checksum check tool | calculates CRC16 for input binary  
 Usage: checksum -f [dump_filename] 
-i- DDR4 mode enabled, 512 bytes parsed 
File DDR4 CRC16 = E752 | byte 126 = 52 | byte 127 = E7 
File vendor section DDR4 CRC16 = 0 | byte 382 = 0 | byte 383 = 0 
Calculated DDR4 CRC16 = E752 | byte 126 = 52 | byte 127 = E7 
CRC in dump is correct
[email protected]:/repo/ddr4s/fw/Pi$ 

Source: DDR DIMM SPD Adapter for Raspberry Pi

Current Project / Post can also be found using:

  • rasnerrypi ddr3 ram adaptor
Scroll to Top
Read previous post:
Building a Raspberry Pi Cluster – Part 2

The Grand Finale In a previous post on Building a Raspberry Pi Cluster, I wrote about how we built a cluster...