public static void Example_FixCRC() { Device MyReader = new Device("COM3", 0x52, SpdSize.DDR4); // Read first 126 bytes byte[] spdHeader = Eeprom.ReadByte(MyReader, 0, 126); // Calculate CRC ushort crc = Spd.Crc16(spdHeader); // Get LSB (byte 127) and MSB (byte 128) byte CrcLsb = (byte)(crc & 0xff); // CRC LSB at 0x7e for 0-125 range or @ 0xfe for 128-253 range byte CrcMsb = (byte)(crc >> 8); // CRC MSB at 0x7f for 0-125 range or @ 0xff for 128-253 range // Compare calculated CRC against SPD data if (Eeprom.ReadByte(MyReader, 0x7e, 1)[0] == CrcLsb && Eeprom.ReadByte(MyReader, 0x7f, 1)[0] == CrcMsb) { // The checksum is correct, do nothing return; } else { // Write correct values to SPD Eeprom.UpdateByte(MyReader, 0x7e, CrcLsb); Eeprom.UpdateByte(MyReader, 0x7f, CrcMsb); } // Note: you'll have to do the same for 128-253 range, checksum bytes are 0xfe and 0xff }
/// <summary> /// Erase SPD contents (fill with 0xff's) /// </summary> public static void Example_EraseSPD() { Device MyReader = new Device(readerSettings, portName, 0x50, SpdSize.DDR4); for (ushort i = 0; i <= (int)MyReader.SpdSize; i++) { Eeprom.UpdateByte(MyReader, i, 0xff); Console.WriteLine(i.ToString()); } }
public static void Example_EraseSPD() { // Erase SPD contents (fill with 0xff's) Device MyReader = new Device("COM3", 0x50, SpdSize.DDR4); for (ushort i = 0; i <= (int)MyReader.SpdSize; i++) { Eeprom.UpdateByte(MyReader, i, 0xff); Console.WriteLine(i.ToString()); } }
static void ParseCommand(string[] args) { string mode = args[0]; if (mode == "/help") { ShowHelp(); return; } try { // Setup SerialPortSettings readerSettings = new SerialPortSettings( 115200, true, true, 8, Handshake.None, "\n", Parity.None, StopBits.One, true, 10); // Find if (mode == "/find") { // Find string[] devices = new Device(readerSettings).Find(); if (devices.Length > 0) { foreach (string portName in devices) { Console.WriteLine($"Found Device on Serial Port: {portName}\n"); } } else { throw new Exception("Nothing found"); } return; } // Other functions that require additional parameters if (mode != "/find" && args.Length >= 2) { // Init string portName = args[1]; if (!portName.StartsWith("COM")) { throw new Exception("Port name should start with \"COM\" followed by a number."); } Device reader = new Device(readerSettings, portName); if (!reader.Connect()) { throw new Exception($"Could not connect to the device on port {portName}."); } if (reader.GetFirmwareVersion() < SpdReaderWriterDll.Settings.MINVERSION) { throw new Exception($"The device on port {portName} requires its firmware to be updated."); } //if (!reader.Test()) { // throw new Exception($"The device on port {portName} does not respond."); //} // Scan if (mode == "/scan") { byte[] addresses = reader.Scan(); if (addresses.Length == 0) { throw new Exception("No EEPROM devices found."); } foreach (int location in addresses) { Console.WriteLine($"Found EEPROM at address: {location}"); } reader.Disconnect(); return; } // Test reversible write protection capabilities if (mode == "/enablewriteprotection" || mode == "/disablewriteprotection") { if (!reader.TestAdvancedFeatures()) { throw new Exception("Your device does not support write protection features."); } // Turn on write protection if (mode == "/enablewriteprotection") { int[] block; if (args.Length == 3) // Block # was specified { try { block = new[] { (Int32.Parse(args[2])) }; } catch { throw new Exception("Block number should be specified in decimal notation."); } } else // No block number specified, protect all available { if (Spd.GetRamType(reader) == RamType.DDR4) { block = new[] { 0, 1, 2, 3 }; } else // DDR3 + DDR2 { block = new[] { 0 }; } } reader.ResetAddressPins(); for (int i = 0; i < block.Length; i++) { if (Eeprom.SetWriteProtection(reader, i)) { Console.WriteLine($"Block {i} is now read-only"); } else { throw new Exception($"Unable to set write protection for block {i}. Either SA0 is not connected to HV, or the block is already read-only."); } } return; } // Disable write protection if (mode == "/disablewriteprotection") { reader.SetAddressPin(Pin.SA1, PinState.HIGH); if (Eeprom.ClearWriteProtection(reader)) { Console.WriteLine("Write protection successfully disabled."); } else { throw new Exception("Unable to clear write protection"); } reader.ResetAddressPins(); return; } } byte address; try { address = (byte)Int32.Parse(args[2]); } catch { throw new Exception("EEPROM address should be specified in decimal notation."); } reader.I2CAddress = address; reader.SpdSize = Spd.GetSpdSize(reader); if (!reader.ProbeAddress()) { throw new Exception($"EEPROM is not present at address {reader.I2CAddress}."); } string filePath = (args.Length >= 4) ? args[3] : ""; bool silent = (args.Length >= 5 && args[4] == "/silent") ? true : false; // Read SPD contents if (mode == "/read") { Console.Write($"Reading EEPROM at address {reader.I2CAddress} ({Spd.GetRamType(reader)})"); if (filePath != "") { Console.WriteLine($" to {filePath}"); } Console.WriteLine("\n"); int startTick = Environment.TickCount; byte[] spdDump = Eeprom.ReadByte(reader, 0, (int)reader.SpdSize); for (int i = 0; i < spdDump.Length; i++) { if (!silent) { ConsoleDisplayByte(i, spdDump[i]); } } Console.Write("\n\nRead {0} {1} from EEPROM at address {2} on port {3} in {4} ms", spdDump.Length, (spdDump.Length > 1) ? "bytes" : "byte", reader.I2CAddress, reader.PortName, Environment.TickCount - startTick ); if (filePath != "") { try { File.WriteAllBytes(filePath, spdDump); } catch { throw new Exception($"Unable to write to {filePath}"); } Console.Write($" to file \"{filePath}\""); } reader.Disconnect(); return; } // Write contents to EEPROM if (mode.StartsWith("/write")) { if (filePath.Length < 1) { throw new Exception("File path is mandatory for write mode."); } if (!File.Exists(filePath)) { throw new Exception($"File \"{filePath}\" not found."); } byte[] inputFile; try { inputFile = File.ReadAllBytes(filePath); } catch { throw new Exception($"Unable to read {filePath}"); } Console.WriteLine( "Writing \"{0}\" ({1} {2}) to EEPROM at address {3}\n", filePath, inputFile.Length, (inputFile.Length > 1) ? "bytes" : "byte", reader.I2CAddress); if (inputFile.Length > (int)reader.SpdSize) { throw new Exception($"File \"{filePath}\" is larger than {reader.SpdSize} bytes."); } int bytesWritten = 0; int startTick = Environment.TickCount; byte b; for (int i = 0; i != inputFile.Length; i++) { b = inputFile[i]; bool writeResult = (mode == "/writeforce") ? Eeprom.WriteByte(reader, (ushort)i, inputFile[i]) : Eeprom.UpdateByte(reader, (ushort)i, inputFile[i]); if (!writeResult) { throw new Exception($"Could not write byte {i} to EEPROM at address {reader.I2CAddress} on port {reader.PortName}."); } bytesWritten++; if (!silent) { ConsoleDisplayByte(i, b); } } reader.Disconnect(); Console.WriteLine( "\n\nWritten {0} {1} to EEPROM at address {2} on port {3} in {4} ms", bytesWritten, (bytesWritten > 1) ? "bytes" : "byte", reader.I2CAddress, reader.PortName, Environment.TickCount - startTick); return; } if (mode == "/enablepermanentwriteprotection") { if (Eeprom.SetPermanentWriteProtection(reader)) { Console.WriteLine($"Permanent write protection enabled on {reader.PortName}:{reader.I2CAddress}"); } else { throw new Exception($"Unable to set permanent write protection on {reader.PortName}:{reader.I2CAddress}"); } } } } catch (Exception e) { //Console.ForegroundColor = ConsoleColor.Red; #if DEBUG Console.WriteLine($"{e}\n"); #else Console.WriteLine($"{e.Message}\n"); #endif //Console.ForegroundColor = ConsoleColor.Gray; return; } Console.WriteLine("Unknown command line parameters.\n"); ShowHelp(); }
private void writeSpdToEeprom(object sender, EventArgs e) { DialogResult _writeConfirmation = MessageBox.Show( "Are you sure you want to write SPD to EEPROM?\n\nThis process is irreversible and you will not be able to restore old SPD, unless you have a backup copy.", "Write", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2); if (_writeConfirmation == DialogResult.No) { return; } Logger("Write started"); // Warn if CRC is invalid if (!crcValidChecksum) { DialogResult _crcConfirmation = MessageBox.Show( "The loaded SPD CRC is not valid!\n\nAre you sure you want to write this SPD?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); if (_crcConfirmation == DialogResult.No) { Logger("Invalid CRC - write aborted by user"); return; } } int start = Environment.TickCount; statusProgressBar.Value = 0; if (SpdContents.Length > 0) { statusProgressBar.Maximum = SpdContents.Length; for (int i = 0; i < SpdContents.Length; i++) { if (!Eeprom.UpdateByte(MySpdReader, i, SpdContents[i])) { string message = $"Could not write to offset 0x{i:X3} at {MySpdReader.PortName}:{MySpdReader.EepromAddress}"; Logger(message); string _question = "Do you want to clear write protection?\n\nClick 'Retry' to attempt to disable write protection and try again or 'Ignore' to continue."; DialogResult _result = MessageBox.Show($"{message}\n\n{_question}", "Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Warning); // Yes button pressed if (_result == DialogResult.Retry) { Logger("Attempting to clear write protection"); clearWriteProtection(this, null); Thread.Sleep(100); i--; // Decrement the value of i to retry writing the same byte after WP clear is attempted continue; } // Abort button pressed if (_result == DialogResult.Abort) { Logger("Could not write to EEPROM - write aborted by user"); statusProgressBar.Value = statusProgressBar.Maximum; return; } } // Redraw interface every N bytes written if (i % 16 == 0) { statusProgressBar.Value = i; Application.DoEvents(); } } statusProgressBar.Value = statusProgressBar.Maximum; if (currentFileName != "") { // Log filename if file was written to EEPROM Logger($"Written {currentFileName} ({SpdContents.Length} bytes) to {MySpdReader.PortName}:{MySpdReader.EepromAddress} in {Environment.TickCount - start} ms"); } else { Logger($"Written {SpdContents.Length} byte(s) to {MySpdReader.PortName}:{MySpdReader.EepromAddress} in {Environment.TickCount - start} ms"); } } }