• Overclocking Lab
  • My Arduino-based RAM SPD reader/writer (free and open source) (p.18)
2023/03/27 19:14:01
QuepAll

 
Description SMBus Controller
Location bus 0 (0x00), device 20 (0x14), function 0 (0x00)
Common header
Vendor ID 0x1022 (AMD)
Model ID 0x790B
Revision ID 0x51
PI 0x00
SubClass 0x05
BaseClass 0x0C
Cache Line 0x00
Latency 0x00
Header 0x80
PCI header
Subvendor ID 0x17AA (Lenovo)
Subsystem ID 0x3842
Int. Line 0x00
Int. Pin 0x00
PCI registers
    00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00 22 10 0B 79 03 04 20 02 51 00 05 0C 00 00 80 00
10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20 00 00 00 00 00 00 00 00 00 00 00 00 AA 17 42 38
30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
F0 7F 70 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 

2023/03/27 20:10:02
a213m
Based on your device info, your smbus should already be supported. AMD support was tested on AM4 system with SMBus RevID 0x61, and I implemented support for FCH controllers (0x790B) starting from revision 0x49, yours is 0x51, which is within the supported and tested range.
 
What does
spdrwcli.exe /find smbus
output? (Run it as admin).
2023/03/28 05:56:28
QuepAll
output:
SPD-RW - EEPROM SPD reader and writer
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Version 2.23.02.05
(C) 2021-2023 A213M
 
when run spdrwguildr.exe  as admin device-connect smbus looking for device - nothing found
2023/03/28 14:00:33
a213m
Thanks, check your PM.
2023/04/12 04:05:26
slowmouse
Hi ! . thank you for this program. I also do not have the ability to use smbus. Is it possible to do something with this?
 
Description SMBus Controller
Location bus 0 (0x00), device 31 (0x1F), function 4 (0x04)
Common header
 Vendor ID 0x8086 (Intel)
 Model ID 0x7A23
 Revision ID 0x11
 PI 0x00
 SubClass 0x05
 BaseClass 0x0C
 Cache Line 0x00
 Latency 0x00
 Header 0x00
PCI header
 Address 0 (memory) 0x0000004402018000
 Address 4 (port) 0x0000EFA0
 Subvendor ID 0x1458 (GIGABYTE)
 Subsystem ID 0x5001
 Int. Line 0xFF
 Int. Pin 0x03
PCI registers
  00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
 00 86 80 23 7A 03 00 80 02 11 00 05 0C 00 00 00 00
 10 04 80 01 02 44 00 00 00 00 00 00 00 00 00 00 00
 20 A1 EF 00 00 00 00 00 00 00 00 00 00 58 14 01 50
 30 00 00 00 00 00 00 00 00 00 00 00 00 FF 03 00 00
 40 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 50 01 04 00 00 01 01 00 00 00 00 00 00 00 00 00 00
 60 04 05 05 00 00 00 0A 0A 00 00 00 00 00 00 00 00
 70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 80 24 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 90 00 00 21 01 00 0C 00 00 1F 00 20 01 00 0E 00 00
 A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 F0 00 00 00 00 00 00 00 00 00 00 13 00 00 00 00 00

 
spdrwcli /find smbus
output is :
 
   SPD-RW - EEPROM SPD reader and writer
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Version 2.23.02.05
(C) 2021-2023 A213M
2023/04/12 04:15:27
a213m
slowmouse
Hi ! . thank you for this program. I also do not have the ability to use smbus. Is it possible to do something with this?
 
...
 Vendor ID 0x8086 (Intel)
 Model ID 0x7A23
 ...




Your hardware is not supported yet. I'll start working on Alder Lake & Raptor Lake platforms support soon when I get my Z790 board delivered, so stay tuned for updates. :)
2023/04/13 23:30:47
a213m
Ok, Intel 600 & 700 series confirmed to be working and will be supported in the next public release (no ETA yet, because I got a few other things to finish).
 

(Never mind the version numbers, I don't update them for test builds)
2023/04/14 02:14:26
slowmouse
Thank you for such great work !
2023/05/22 19:32:34
BEVANYANG
[引用=a213m] how can i contact you sir?I am interested in DDR4 DDR5 SPD programmers!
 
GitHub 上的官方项目仓库:

 
最新的二进制文件

 
最新固件:

 
 

指导:

第 1 部分 - 硬件

 
根据下面的示意图连接你的 Arduino + DIMM:
 

点击图片查看完整版。找到
 
该示意图显示了分为多个部分的模块:
  • Arduino section shows pins used on Nano V3 model. Use its 3.3V pin as a VCC source. If your Arduino doesn't have a dedicated 3.3V output, use a step-down 3.3V regulator, like LM7833. Pins labeled SA1_EN, HV_EN, and HV_FB can be assigned in "" file. 5V pin is required to power a 9V step-up converter (HV_SOURCE) and DDR5.
  • HV_CTL and one of 9V sources are needed to enable and detect 9V on SA0 for RSWP related operations. Use either a step-up/boost converter (HV_SOURCE), or a 9V battery (HV_SOURCE_ALT), not both!
  • SA1_CTL is used to switch pin SA1 on EEPROM between VCC and ground. This is needed because RSWP-supported EEPROMs used on DDR3 and DDR2 require different SA1 configurations to enable or disable RSWP. It is also used to prevent addressing conflicts when DDR5 is used.
 
Refer to your Arduino model pinout, on my Nano model SDA and SCL are A4 and A5, respectively:

 
Parts list:
  • Arduino: Nano V3 or any AVR-based model with I2C / TWI interface.
  • OK1: PC817 or any general purpose optocoupler with a maximum collector to emitter voltage above 10V and a diode current below 40mA and forward voltage below 5V.
  • R1, R2: Pull up resistor for I2C lines.
  • R3: Current limiting resistor for optocoupler diode, values between 390Ω and 560Ω work fine.
  • R4, R5: Voltage divider for HV feedback (HV_FB) on SA0. The values used will work for 5V and 3.3V Arduinos.
  • R6: Pull up resistor for SA1 pin.
  • D1: Any general purpose schottky diode.
  • C1: 6.3V, 560uF
 
EEPROM pins to DIMM pins guide:
 
DDR5:    VIN_BULK=1, HSCL=4, HSDA=5, HSA=148, PWR_EN=151, GND=6*
DDR4:    SA0=139,   SA1=140,   SA2=238,   GND=2*,   SDA=285,   SCL=141,  VDDSPD=284
DDR3:    SA0=117,   SA1=237,   SA2=119,   GND=2*,   SDA=238,   SCL=118,  VDDSPD=236
DDR2:    SA0=239,   SA1=240,   SA2=101,   GND=4*,   SDA=119,   SCL=120,  VDDSPD=238
DDR:      SA0=181,   SA1=182,   SA2=183,   GND=3*,   SDA=91,     SCL=92,    VDDSPD=184
SDRAM: SA0=165,   SA1=166,   SA2=167,   GND=1*,   SDA=82,     SCL=83,    VDDSPD=168
 
* There are multiple GND pins on DIMMs, the table shows just one of them for each RAM type.
 
DDR5 UDIMM pins locations:
 




DDR4 DIMM pins locations:



 
Obviously don't solder wires directly to DIMM contacts or motherboard solder points, get a spare slot from components resellers, like Digikey, or get a DIMM adapter, like the one pictured below. Those are cheap, and have pins labeled for easy identification.
 


 
 

Part 2 - Firmware


Upload to your Arduino once everything is assembled. Both files are required. Make sure the values in match the pins names you used if your pins differ from the ones in the guide.
 

Part 3 - Windows GUI application

 
Latest application can always be found here:
 

 
The application requires 4 or later to be installed. Supported OSs are Windows XP SP3 and up. The application is compiled for x86 architecture, so both 32 bit and 64 bit OSs are supported.
 
Once your device is assembled and tested, start the program. Click "Connect" toolbar button, make sure selected baud rate matches the one you programmed, select your device from the list, and click "Connect" to start working:
 

 
Click on the device identified by its serial port name and EEPROM address detected on its I2C bus to start working with it.
 
 

Part 4 - Windows Console application

 
The program can read and write bytes, and enable or disable write protection. The operation depends on its command line arguments. The supported arguments are:
 
  1. /help
  2. /find
  3. /scan <PORT>
  4. /read <PORT> <ADDRESS#> <filepath> /silent
  5. /write <PORT> <ADDRESS#> <FILEPATH> /silent
  6. /writeforce <PORT> <ADDRESS#> <FILEPATH> /silent
  7. /enablewriteprotection <PORT> <ADDRESS#>
  8. /enablewriteprotection <PORT> <ADDRESS#> <block#>
  9. /disablewriteprotection <PORT> <ADDRESS#>
  10. /enablepermanentwriteprotection <PORT> <ADDRESS#>
 
The parameters in CAPS are mandatory. Parameter <filepath> is optional when 
/read
switch is used, output will be printed to console only.
 
You'll need to know two parameters to work your DIMM - port name and EEPROM address. To find out what port your device is using, run this command:
 
spdrwcli.exe /find

 
If everything works, you'll get a port name your device is connected to:
 

 
 
 
Found Device on Serial Port: COM3

 
In my case it is COM3. If the program can't find any devices, make sure the sketch is properly uploaded to your Arduino and no other application is using your Arduino's serial port - that includes Arduino IDE Serial Monitor. Close it, if you have it open.
 
With a DDR4 DIMM present you'll want to scan your device for EEPROM addresses on I2C bus. With SA0-SA2 connected to ground, the address will be 80, however, it is still recommended to run this test to ensure the EEPROM is detected:
 
spdrwcli.exe /scan COM3

 
In most cases, if everything is fine, you'll see a device at address 80 detected:
 

 
 
 
Found EEPROM at address: 80

 
When I used DDR4 slots cut out of an old motherboard with both DIMMs populated, both were detected at addresses 80 and 82, even though I soldered wires to one slot only:
 

 
 
 
Found EEPROM at address: 80
Found EEPROM at address: 82

 
To read SPD from your DIMM, run:
 
spdrwcli.exe /read COM3 80

 
This will output SPD contents in HEX on screen. Plain and simple.
 

Reading EEPROM at address 80

000: 23 10 0C 02 84 19 00 08 00 00 00 03 01 03 00 00
010: 00 00 08 0C F4 1B 00 00 6C 6C 6C 11 00 74 20 08
020: 00 05 70 03 00 A8 1E 2B 2B 00 00 00 00 00 00 00
--edited on purpose--
1D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Read 512 bytes from EEPROM at address 80 on port COM3 in 1547 ms

 
To save SPD to file, add a file path at the end. File path can be absolute or relative. If file path has spaces in it, enclose it in "double quotes":
 
spdrwcli.exe /read COM3 80 C:\temp\spdoutput.bin

spdrwcli.exe /read COM3 80 "C:\temp\my ddr4 spd file.bin"

 

Reading EEPROM at address 80 to C:\temp\my ddr4 spd file.bin

000: 23 10 0C 02 84 19 00 08 00 00 00 03 01 03 00 00
--edited on purpose--
1F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Read 512 bytes from EEPROM at address 80 on port COM3 in 1562 ms to file "C:\temp\my ddr4 spd file.bin"

 
Edit your SPD in a HEX editor or any specialized program, like Thaiphoon Burner. 
 
To write your new SPD to DIMM, run:
 
spdrwcli.exe /write COM3 80 C:\temp\newspd.bin

 
EEPROMs have limited number of write cycles, sometimes between 10,000 and 1,000,000. By default, the program writes bytes only if they differ from existing values. By doing that, it first reads a byte and if it matches the input value, the write operation is skipped. Byte is written only it it needs to. If you want to force writes, regardless of existing SPD data, use 
/writeforce
switch instead of
/write
.
It will take a bit longer (5-10 s.) because of required delays after each write.
 

Writing "C:\temp\my ddr4 spd file.bin" (512 bytes) to EEPROM at address 80

000: 23 10 0C 02 84 19 00 08 00 00 00 03 01 03 00 00
010: 00 00 08 0C F4 1B 00 00 6C 6C 6C 11 00 74 20 08
020: 00 05 70 03 00 A8 1E 2B 2B 00 00 00 00 00 00 00
--edited on purpose--
1D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
1F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Written 512 bytes to EEPROM at address 80 on port COM3 in 7093 ms

 
Optionally, to hide progress you may add 
/silent
switch at the end after a file path is specified when using
/read
,
/write
, or
/writeforce
switches:
 
spdrwcli.exe /read COM3 80 C:\temp\spdoutput.bin /silent

spdrwcli.exe /write COM3 80 C:\temp\newspd.bin /silent

 
You may protect the entire EEPROM from writing with this command:
 
spdrwcli.exe /enablewriteprotection COM3

 
If the blocks weren't write-protected previously, you'll receive a response like this:
 

 
 
 
Block 0 is now read-only
Block 1 is now read-only
Block 2 is now read-only
Block 3 is now read-only

 
Or enable write protection on each individual block by specifying block number (0-3):
 
spdrwcli.exe /enablewriteprotection COM3 0

spdrwcli.exe /enablewriteprotection COM3 2

 
Each block specifies a section of 128 bytes. Block 0 is bytes at offset 0-127, block 1 is bytes 128-255, and so on.
 
Please note the address isn't used, only port number. That's because RSWP commands don't use addresses, all devices on the I2C bus will act simultaneously.
 
To clear write protection, run the following command:
 
spdrwcli.exe /disablewriteprotection COM3

 
Again, the device address isn't used.
 
Once write-protection is cleared, you'll see this response:
 

Write protection successfully disabled.

 
To enable permanent write protection, run this command:
spdrwcli.exe /enablepermanentwriteprotection COM3 80

 
Please note permanent protection can be enabled on most DDR3 and some DDR2 modules. DDR4 does not support permanent software write protection.
 
That's all for now.
 
我总是乐于接受建议和评论。随时报告任何错误或要求添加您希望在项目中看到的任何功能,无论它与硬件、固件还是应用程序相关。

[/引用]


2023/05/22 19:39:01
a213m
Well, you can post your question here, if it is related to the project, that's what the thread is for.
Otherwise send me a private message.
 
 

Use My Existing Forum Account

Use My Social Media Account