Thanks for the answers. Maybe I can do it now.
' Gambas module file
Export
Private Enum UNKNOWN = 0,
DIRECT_RAMBUS = 1,
RAMBUS = 2,
FPM_DRAM = 3,
EDO = 4,
PIPELINED_NIBBLE = 5,
SDR_SDRAM = 6,
MULTIPLEXED_ROM = 7,
DDR_SGRAM = 8,
DDR_SDRAM = 9,
DDR2_SDRAM = 10,
DDR3_SDRAM = 11,
DDR4_SDRAM = 12,
N_RAM_TYPES = 13
Private RAM_TYPE As Integer = UNKNOWN
Private ram_types As String[] = ["Unknown", "Direct Rambus",
"Rambus", "FPM DRAM", "EDO",
"Pipelined Nibble", "SDR SDRAM",
"Multiplexed ROM", "DDR SGRAM",
"DDR SDRAM", "DDR2 SDRAM",
"DDR3 SDRAM", "DDR4 SDRAM"]
Public Struct SPD_DATA
bytes[512] As Byte
dev[32] As String
spd_driver As Integer '/* 0 = eeprom, 1 = ee1004 */
spd_size As Integer
ram_type As String
vendor_bank As Integer
vendor_index As Integer
vendor_str As String
partno As String
' const Vendor *vendor;
' int dram_vendor_bank;
' int dram_vendor_index;
' const char *dram_vendor_str;
' const Vendor *dram_vendor;
' char partno[32];
form_factor As String
type_detail As String
dmi_mem_size As String
spd_rev As String '//bytes[1] >> 4
' int spd_rev_minor; // bytes[1] & 0xf
' int week, year;
manufacturer_date As String
' gboolean ddr4_no_ee1004;
' struct dmi_mem_socket *dmi_socket;
' int match_score
End Struct
Public MEMORY_SUPPORTED_VOLTAGE As String
Public MEMORY_SUPPORTED_CAS_LATENCIES As String
Public MEMORY_THERMAL_SENSOR As String
Public Sub main()
Dim fl As File
Dim bb As New Byte[512]
Dim AA As New Byte[512]
Dim s As String
Dim i As Integer
Dim bytes_used, bytes_free As Integer = 0
Dim spd_data As New SPD_DATA
Dim spd_size As Integer
fl = Open "/home/michal/Dokumenty/SPD/DDR RAM SPD HEX and BIN/DDR4/Ballistix Elite 4× 8 GB DDR-4000 (Micron E).SPD" For Read
'fl = Open "/home/michal/Dokumenty/SPD/DDR RAM SPD HEX and BIN/DDR3/KINGSTON-KVR16LS11S6-2-001-A00LF-800MHz.SPD" For Read
'/sys/bus/i2c/drivers/eeprom/" & Finfosys.ComboBox10.Text & "/eeprom
'fl = Open "/sys/bus/i2c/drivers/eeprom/0-0052/eeprom" For Read
bb.Read(fl, 0, Lof(fl))
'AA.Read(fl, 128, 140)
fl.Close
spd_size = read_spd("/home/michal/Dokumenty/SPD/DDR RAM SPD HEX and BIN/DDR4/Ballistix Elite 4× 8 GB DDR-4000 (Micron E).SPD")
'spd_size = read_spd("/home/michal/Dokumenty/SPD/DDR RAM SPD HEX and BIN/DDR3/KINGSTON-KVR16LS11S6-2-001-A00LF-800MHz.SPD")
'spd_size = read_spd("/sys/bus/i2c/drivers/eeprom/0-0052/eeprom")
RAM_TYPE = decode_ram_type(bb)
Select RAM_TYPE
Case SDR_SDRAM
Case DDR_SDRAM
Case DDR2_SDRAM
Case DDR3_SDRAM
With spd_data
.ram_type = ram_types[RAM_TYPE]
.partno = decode_ddr3_part_number(bb)
'.vendor_str = decode_ddr3_manufacturer(bb, SPD_DATA.vendor_str)
.form_factor = decode_ddr3_module_type(bb)
.type_detail = decode_ddr3_module_speed(bb)
.manufacturer_date = decode_ddr3_module_date(bb)
.dmi_mem_size = decode_ddr3_module_size(bb)
.spd_rev = decode_ddr3_spd_revision(bb)
MEMORY_SUPPORTED_VOLTAGE &= If(bb[6] = 4, "1.25V ", "") & If(bb[6] = 2, "1.35V ", "") & If(bb[6] = 1, "", "1.5V")
'MEMORY_THERMAL_SENSOR = If(bytes[32] = )
MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[15], 8), 1, 1) = 1, "18T ", "")
MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[15], 8), 2, 1) = 1, "17T ", "")
MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[15], 8), 3, 1) = 1, "16T ", "")
MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[15], 8), 4, 1) = 1, "15T ", "")
MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[15], 8), 5, 1) = 1, "14T ", "")
MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[15], 8), 6, 1) = 1, "13T ", "")
MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[15], 8), 7, 1) = 1, "12T ", "")
MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[14], 8), 1, 1) = 1, "11T ", "")
MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[14], 8), 2, 1) = 1, "10T ", "")
MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[14], 8), 3, 1) = 1, "9T ", "")
MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[14], 8), 4, 1) = 1, "8T ", "")
MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[14], 8), 5, 1) = 1, "7T ", "")
MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[14], 8), 6, 1) = 1, "6T ", "")
MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[14], 8), 7, 1) = 1, "5T ", "")
MEMORY_SUPPORTED_CAS_LATENCIES &= If(Mid$(Bin(bb[14], 8), 8, 1) = 1, "4T ", "")
End With
Case DDR4_SDRAM
With spd_data
.ram_type = ram_types[RAM_TYPE]
.form_factor = decode_ddr4_module_type(bb)
.type_detail = decode_ddr4_module_speed(bb)
.partno = decode_ddr4_part_number(bb)
.dmi_mem_size = decode_ddr4_module_size(bb)
End With
End Select
Print spd_data.ram_type
Print spd_data.partno
Print spd_data.form_factor
Print spd_data.type_detail
Print spd_data.manufacturer_date
Print SPD_DATA.spd_rev
Print MEMORY_SUPPORTED_VOLTAGE
Print MEMORY_SUPPORTED_CAS_LATENCIES
Print spd_size
Print SPD_DATA.dmi_mem_size
For i = 0 To bb.Count - 1
'
If bb[i] Then
bytes_used += 1
'Print "RAW:" & bb[i] & "|HEX: " & Hex(bb[i]) & " |Bin: " & Bin(bb[i], 8) & " |Int: " & CInt(bb[i])
Else
bytes_free += 1
'Print "RAW:" & bb[i] & "|HEX: " & Hex(bb[i]) & " |Bin: " & Bin(bb[i], 8) & " |Int: " & CInt(bb[i])
Endif
Next
'Print Subst("Bytes Used: &1 Bytes Free: &2 Bytes Total: &3", bytes_used, bytes_free, bytes_free + bytes_used)
'Print CInt(bb[32] & &H80&)
'Print bb[121] & &hF0&
's = Hex(bb[0], 2) & Hex(bb[1], 2) & Hex(bb[2], 2)
'Print "RAW:" & bb[6] & "|HEX: " & Hex(bb[6]) & " |Bin: " & Bin(bb[6], 8) & " |Int: " & CInt(bb[6])
'Print "RAW:" & bb[15] & "|HEX: " & Hex(bb[15]) & " |Bin: " & Bin(bb[15], 8) & " |Int: " & CInt(bb[15])
'Print "RAW:" & bb[31] & "|HEX: " & Hex(bb[32]) & " |Bin: " & Bin(bb[32], 8) & " |Int: " & CInt(bb[32])
'Print Hex$(15, 3)
'Print "HEX: " & Hex(bb[2], 2) & " |Bin: " & Bin(bb[2], 8) & " |Int: " & CInt(bb[2])
'Print "HEX: " & Hex(bb[3], 2) & " |Bin: " & Bin(bb[3], 8) & " |Int: " & CInt(bb[3])
'Print "HEX: " & Hex(bb[4], 2) & " |Bin: " & Bin(bb[4], 8) & " |Int: " & CInt(bb[4])
'Print "HEX: " & Hex(bb[5], 2) & " |Bin: " & Bin(bb[5], 8) & " |Int: " & CInt(bb[5])
'Print "HEX: " & Hex(bb[6], 2) & " |Bin: " & Bin(bb[6], 8) & " |Int: " & CInt(bb[6])
'Print Hex(bb[128], 2)
'Print bb.ToString(128, 20)
'Print Chr(bb[128]) & Chr(bb[129]) & Chr(bb[130]) & Chr(bb[131]) & Chr(bb[132]) & Chr(bb[133]) & Chr(bb[134]) & Chr(bb[135]) & Chr(bb[136]) & Chr(bb[137]) & Chr(bb[138]) & Chr(bb[139]) & Chr(bb[140])
'i = Val("&" & s)
'Print i
'Print s
End
Private Function decode_ddr3_spd_revision(bytes As Byte[]) As String
Return Mid(Hex(bytes[1]), 1, 1) & "." & Mid(Hex(bytes[1]), 2, 1)
End
' Version 0.0 00h
' Revision 0.5 05h
' Revision 1.0 10h
' Revision 1.1 11h
' Revision 1.2 12h
Private Function decode_ram_type(bytes As Byte[]) As Integer
If bytes[0] < 4 Then
Select bytes[2]
Case 1
Return DIRECT_RAMBUS
Case 17
Return RAMBUS
End Select
Else
Select bytes[2]
Case 1
Return FPM_DRAM
Case 2
Return EDO
Case 3
Return PIPELINED_NIBBLE
Case 4
Return SDR_SDRAM
Case 5
Return MULTIPLEXED_ROM
Case 6
Return DDR_SGRAM
Case 7
Return DDR_SDRAM
Case 8
Return DDR2_SDRAM
Case 11
Return DDR3_SDRAM
Case 12
Return DDR4_SDRAM
End Select
Return UNKNOWN
Endif
End
Private Function decode_ddr3_part_number(bytes As Byte[], Optional partnumber As String) As String
Dim i As Integer
For i = 128 To 145
partnumber &= Chr(bytes[i])
Next
Return partnumber
End
Private Function decode_ddr4_part_number(bytes As Byte[], Optional partnumber As String) As String
Dim i As Integer
For i = 329 To 348
partnumber &= Chr(bytes[i])
Next
Return partnumber
End
Private Function read_spd(spd_path As String) As Integer
Dim data_size As Integer = 0
data_size = Stat(spd_path).Size
Return data_size
End
Private Function decode_ddr3_module_type(bytes As Byte[]) As String
Dim type As String
Select bytes[3]
Case 01
type = "RDIMM (Registered Long DIMM)"
Case 02
type = "UDIMM (Unbuffered Long DIMM)"
Case 03
type = "SODIMM (Small Outline DIMM)"
Default
type = Null
End Select
Return type
End
Private Function decode_ddr4_module_type(bytes As Byte[]) As String
Dim type As String = "Unknown" ''Default Unknown if no detect
Select Hex(bytes[3], 2)
Case &h01
type = "RDIMM (Registered DIMM)"
Case "02"
type = "UDIMM (Unbuffered DIMM)"
Case "03"
type = "SODIMM (Small Outline Unbuffered DIMM)"
Case "04"
type = "LRDIMM (Load-Reduced DIMM)"
Case "05"
type = "Mini-RDIMM (Mini Registered DIMM)"
Case "06"
type = "Mini-UDIMM (Mini Unbuffered DIMM)"
Case "08"
type = "72b-SO-RDIMM (Small Outline Registered DIMM, 72-bit data bus)"
Case "09"
type = "72b-SO-UDIMM (Small Outline Unbuffered DIMM, 72-bit data bus)"
Case "0c"
type = "16b-SO-UDIMM (Small Outline Unbuffered DIMM, 16-bit data bus)"
Case "0d"
type = "32b-SO-UDIMM (Small Outline Unbuffered DIMM, 32-bit data bus)"
End Select
Return type
End
Private Function decode_ddr3_module_speed(bytes As Byte[]) As String
' Dim ctime As Float
' Dim ddrclk As Float
' Dim tbits, pcclk As Integer
' Dim mtb As Float = 0.125
'
' If (bytes[10] == 1 And bytes[11] == 8) Then mtb = 0.125
' If (bytes[10] == 1 And bytes[11] == 15) Then mtb = 0.0625
' ctime = mtb * bytes[12]
' ddrclk = 2 * (1000 / ctime)
'
' tbits = 64
' Select bytes[8]
' Case 1
' tbits = 16
' Case 4
' tbits = 32
' Case 3
' Case 0
' tbits = 64
' End Select
'
' pcclk = ddrclk * (tbits / 8)
' pcclk -= pcclk % 100
'
' Return Subst("DDR3-&1Mhz PC3-&2", CInt(ddrclk), pcclk)
Dim divisor As Integer = bytes[10]
Dim dividend As Integer = bytes[11]
Dim ratio As Integer = bytes[12]
If dividend = 0 And divisor = 0 And ratio = 0 Then
Return "DDR3-Unknown Mhz"
Else
Return Subst("DDR3-&1Mhz", ((2000 * dividend) / (divisor * ratio)))
Endif
End
Private Function decode_ddr4_module_speed(bytes As Byte[]) As String
Dim mincycle As Integer = bytes[18]
Dim fineadjust As Integer = Bytes[125]
Dim frequency As Integer
frequency = (2000000 / (mincycle * 125 + fineadjust))
Return Subst("DDR4-&1Mhz", frequency)
End
Private Function decode_ddr3_module_size(bytes As Byte[]) As String
Dim size As Integer
' Dim sdr_capacity As Integer = Lsl(256, Hex(bytes[4]) And &hF)
' Dim sdr_width As Integer = Lsl(4, Hex(bytes[7]) And &h7)
' Dim bus_width As Integer = Lsl(8, Hex(bytes[8]) And &h7)
' Dim ranks As Integer = 1 + Lsr(3, Hex(bytes[7]) And &h7)
' Print "sdr_capacity = " & Lsl(256, Bytes[4])
' Print "sdr_width = " & Lsl(4, bytes[7])
' Print "bus_width = " & Lsl(8, bytes[8])
' Print "ranks = " & (Lsr(3, bytes[7]) + 1)
' size = sdr_capacity / 8 * bus_width / sdr_width * ranks
size = ((Hex(bytes[4]) And &h0f) + 28) + ((Hex(bytes[8]) And &h7) + 3)
size -= (Hex(bytes[7]) And &h7) + 25
size = (Lsl(1, size)) * (Lsr(3, bytes[7] And &h1f) + 1)
Return Subst("Module size: &1", size / 1024)
End
Private Function decode_ddr4_module_size(bytes As Byte[]) As String
Dim size As Integer
size = Lsl(1, Hex(bytes[4]) And &h0f) + 8
size *= Lsl(1, Hex(bytes[13]) And &h07) + 3
size /= Lsl(1, Hex(bytes[12]) And &h07) + 2
size *= (Lsr(3, Hex(bytes[12]) And &h07) + 1)
size *= (Hex(bytes[6]) And &h03)
Return Subst("Module size: &1", size / 1024)
End
' static void decode_ddr4_module_size(unsigned char *bytes, dmi_mem_size *size) {
' int sdrcap = 256 << (bytes[4] & 15);
' int buswidth = 8 << (bytes[13] & 7);
' int sdrwidth = 4 << (bytes[12] & 7);
' int signal_loading = bytes[6] & 3;
' int lranks_per_dimm = ((bytes[12] >> 3) & 7) + 1;
'
' if (signal_loading == 2) lranks_per_dimm *= ((bytes[6] >> 4) & 7) + 1;
'
' *size = sdrcap / 8 * buswidth / sdrwidth * lranks_per_dimm;
' }
' gRAM.SPD[i].Type = MemoryTypeDdr4;
'
' gRAM.SPD[i].ModuleSize
' = (1 << ((spdbuf[4] & 0x0f) + 8 /* Mb */ - 3 /* MB */)) // SDRAM Capacity
' * (1 << ((spdbuf[13] & 0x07) + 3)) // Primary Bus Width
' / (1 << ((spdbuf[12] & 0x07) + 2)) // SDRAM Width
' * (((spdbuf[12] >> 3) & 0x07) + 1) // Logical Ranks per DIMM
' * (((spdbuf[6] & 0x03) == 2) ? (((spdbuf[6] >> 4) & 0x07) + 1) : 1);
Private Function decode_ddr3_module_date(bytes As Byte[]) As String
' Dim sweek As Long
' Dim syear As Long
' If bytes[120] = &h0 Or bytes[120] = &hff Or bytes[121] = &h0 Or bytes[121] = &ff Then
' Return
' Endif
' 'Lsr(3, (bytes[7] And &7))
' sweek = Lsr(4, Hex(bytes[121]) And &hf)
' sweek *= 10
' sweek += Hex(bytes[121]) And &hf
' syear = Lsr(4, Hex(bytes[120]) And &hf)
' syear *= 10
' syear += (Hex(bytes[120]) And &hf)
' syear += 2000
' Print Subst("Week: &1 Year: &2", sweek, syear)
Return Subst("Year &1-W&2", CInt(2000 + Hex(bytes[120])), Hex(bytes[121]))
End
' static void decode_ddr3_module_date(unsigned char *bytes, int *week, int *year) {
' if (bytes[120] == 0x0 || bytes[120] == 0xff ||
' bytes[121] == 0x0 || bytes[121] == 0xff) {
' return;
' }
' *week = (bytes[121]>>4) & 0xf;
' *week *= 10;
' *week += bytes[121] & 0xf;
' *year = (bytes[120]>>4) & 0xf;
' *year *= 10;
' *year += bytes[120] & 0xf;
' *year += 2000;
' }