/// <summary> /// Reads the ZIF-socket (12 times). /// </summary> /// <param name="packageName">The message to shout.</param> /// <returns>The 12 <see cref="ZIFSocket"/>s.</returns> public virtual ZIFSocket[] ReadZIF(string packageName) { var package = new List <byte>(); for (var i = 0; i < 12; i++) { for (byte b = 0x01; b <= 0x05; b++) { package.Add(b); } } package.Add(0x07); // Write ZIF to Top Programmer buffer BulkDevice.SendPackage(5, package.ToArray(), "Writing 12 x ZIF to buffer."); // Read buffer var readBuffer = BulkDevice.RecievePackage(5, "Reading ZIF {0}.", packageName); var zifs = new List <ZIFSocket>(); for (var i = 0; i + 5 <= 60; i += 5) { var bytes = new List <byte>(); for (var j = i; j < i + 5; j++) { bytes.Add(readBuffer[j]); } zifs.Add(new ZIFSocket(ZIFType, bytes.ToArray())); } return(zifs.ToArray()); }
/// <summary> /// Sets the Vcc level (double version) /// </summary> /// <param name="rawLevel">The level represented as a voltage (double).</param> public virtual void SetVccLevel(double rawLevel) { string stringLevel; var level = TranslateVccLevel(rawLevel, out stringLevel); BulkDevice.SendPackage(4, new byte[] { 0x0e, 0x13, level, 0x00 }, "Vcc = {0}", stringLevel); }
/// <summary> /// Sets the Vpp level (double version) /// </summary> /// <param name="rawLevel">The level represented as a voltage (double).</param> internal virtual void SetVppLevel(double rawLevel) { string stringLevel; var level = TranslateVppLevel(rawLevel, out stringLevel); BulkDevice.SendPackage(4, new byte[] { 0x0e, 0x12, level, 0x00 }, "Vpp = {0}", stringLevel); }
/// <summary> /// Use by the other Apply...-methods. /// </summary> protected virtual void ApplyPropertyToPins(string name, byte propCode, ICollection <int> validPins, Func <Pin, int> translate = null, params Pin[] dilPins) { translate = translate ?? (x => x.Number); // Always start by clearing all pins BulkDevice.SendPackage(4, new byte[] { 0x0e, propCode, 0x00, 0x00 }, "All {0} pins cleared", name); foreach (var zifPin in dilPins.Select(translate)) { if (!validPins.Contains(zifPin)) { throw new U2PaException("Pin {0} is not a valid {1} pin.", zifPin, name); } BulkDevice.SendPackage(4, new byte[] { 0x0e, propCode, (byte)zifPin, 0x00 }, "{0} applied to pin {1}", name, zifPin); } }
/// <summary> /// Writes a <see cref="ZIFSocket"/>. /// </summary> /// <param name="zif">The ZIF to be written.</param> /// <param name="packageName">The meassage to shout.</param> public virtual void WriteZIF(ZIFSocket zif, string packageName) { var rawBytes = zif.ToTopBytes(); var package = new byte[] { 0x10, rawBytes[0], 0x11, rawBytes[1], 0x12, rawBytes[2], 0x13, rawBytes[3], 0x14, rawBytes[4], 0x0A, 0x15, 0xFF }; BulkDevice.SendPackage(5, package, "{0} written to ZIF.", packageName); }
/// <summary> /// Uploads the ictest.bin FPGA-program to the device. /// </summary> /// <param name="fileName">The name of the file.</param> /// <remarks> /// I don't fully understand all of the stuff going on in this method, as I have /// just used an USB-sniffer to see what TopWin6 does when uploading ictest.bin. /// </remarks> private void UpLoadFPGAProgramTopWin6Style(string fileName) { // Prelude of black magic BulkDevice.SendPackage(5, new byte[] { 0x0A, 0x1B, 0x00 }, "???"); BulkDevice.SendPackage(5, new byte[] { 0x0E, 0x21, 0x00, 0x00 }, "Start bitstream upload"); BulkDevice.SendPackage(5, new byte[] { 0x07 }, "Some kind of finish-up/execute command?"); BulkDevice.RecievePackage(5, "Some values that maby should be validated in some way"); var fpgaProgram = new FPGAProgram(fileName); var bytesToSend = PackFPGABytes(fpgaProgram.Payload).SelectMany(x => x).ToArray(); Shouter.ShoutLine(5, fpgaProgram.ToString()); BulkDevice.SendPackage(5, bytesToSend, "Uploading file: {0}", fileName); // Postlude of black magic BulkDevice.SendPackage(5, new byte[] { 0x0E, 0x12, 0x00, 0x00 }, "Set Vpp boost off"); BulkDevice.SendPackage(5, new byte[] { 0x1B }, "???"); // Why 2 times??? BulkDevice.SendPackage(5, new byte[] { 0x0E, 0x12, 0x00, 0x00 }, "Set Vpp boost off"); BulkDevice.SendPackage(5, new byte[] { 0x1B }, "???"); BulkDevice.SendPackage(5, new byte[] { 0x0E, 0x13, 0x32, 0x00 }, "Set Vcc = 5V"); BulkDevice.SendPackage(5, new byte[] { 0x1B }, "???"); BulkDevice.SendPackage(5, new byte[] { 0x0E, 0x15, 0x00, 0x00 }, "Clear all Vcc assignments"); // Why no 0x1B here??? BulkDevice.SendPackage(5, new byte[] { 0x0E, 0x17, 0x00, 0x00 }, "Clear all ??? assignments"); // Why no 0x1B here??? BulkDevice.SendPackage(5, new byte[] { 0x0A, 0x1D, 0x86 }, "???"); BulkDevice.SendPackage(5, new byte[] { 0x0E, 0x16, 0x00, 0x00 }, "Clear all Gnd assignments"); var clueless = new byte[] { 0x3E, 0x00, 0x3E, 0x01, 0x3E, 0x02, 0x3E, 0x03, 0x3E, 0x04, 0x3E, 0x05, 0x3E, 0x06, 0x3E, 0x07, 0x3E, 0x08, 0x3E, 0x09, 0x3E, 0x0A, 0x3E, 0x0B, 0x3E, 0x0C, 0x3E, 0x0D, 0x3E, 0x0E, 0x3E, 0x0F, 0x3E, 0x10, 0x3E, 0x11, 0x3E, 0x12, 0x3E, 0x13, 0x3E, 0x14, 0x3E, 0x15, 0x3E, 0x16, 0x3E, 0x17, 0x07 }; BulkDevice.SendPackage(5, clueless, "I´m clueless on this one atm"); BulkDevice.RecievePackage(5, "Properly answer to clueless that maby should be validated in some way"); // Again? BulkDevice.SendPackage(5, new byte[] { 0x0E, 0x12, 0x00, 0x00 }, "Set Vpp boost off"); BulkDevice.SendPackage(5, new byte[] { 0x1B }, "???"); // Again, again??? BulkDevice.SendPackage(5, new byte[] { 0x0E, 0x12, 0x00, 0x00 }, "Set Vpp boost off"); }
/// <summary> /// Removes all pin assingments from the physical device and /// disposes all unmanaged resources.<s /// </summary> public void Dispose() { DisposeSpecific(); SetVppLevel(0x00); SetVccLevel(0x00); ApplyVpp(); ApplyVcc(); ApplyGnd(); PullUpsEnable(false); // Remove all pin assignments if (BulkDevice == null) { return; } BulkDevice.Dispose(); }
/// <summary> /// Sets the Vcc level (byte version). /// </summary> /// <param name="level">The level represented as a raw byte.</param> internal virtual void SetVccLevel(byte level) { BulkDevice.SendPackage(4, new byte[] { 0x0e, 0x13, level, 0x00 }, "Vcc = {0}", level.ToString("X4")); }
/// <summary> /// Sets the Vpp level (byte version). /// </summary> /// <param name="level">The level represented as a raw byte.</param> public virtual void SetVppLevel(byte level) { BulkDevice.SendPackage(4, new byte[] { 0x0e, 0x12, level, 0x00 }, "Vpp = {0}", level.ToString("X4")); }
/// <summary> /// Do we enable pullups on the ZIF-pins? /// </summary> /// <param name="enable">True if enable.</param> public virtual void PullUpsEnable(bool enable) { BulkDevice.SendPackage(4, new byte[] { 0x0e, 0x28, (byte)(enable ? 0x01 : 0x00), 0x00 }, "PullUps are {0}", enable ? "enabled" : "disabled"); }
/// <summary> /// NOT WORKING YET! /// </summary> /// <param name="eprom"></param> /// <param name="bytes"></param> public void WriteEpromFast(Eprom eprom, IList <byte> bytes) { if (eprom.VppPins.Any(p => eprom.OutputEnable.Any(q => p.Number == q.Number))) { throw new U2PaException("Fast Programming Algoritm can't by used for this EPROM (yet)"); } var totalNumberOfAdresses = eprom.AddressPins.Length == 0 ? 0 : 1 << eprom.AddressPins.Length; var translator = eprom.GetPinTranslator(ZIFType); { var zif = new ZIFSocket(ZIFType); zif.SetAll(true); zif.Disable(eprom.Program, translator.ToZIF); WriteZIF(zif, "Apply 1 to all pins"); SetVccLevel(eprom.VccLevel); SetVppLevel(eprom.VppLevel); ApplyGnd(translator.ToZIF, eprom.GndPins); ApplyVcc(translator.ToZIF, eprom.VccPins); ApplyVpp(translator.ToZIF, eprom.VppPins); } using (var progress = new ProgressBar(Shouter, totalNumberOfAdresses)) { progress.Init(); foreach (var address in Enumerable.Range(0, totalNumberOfAdresses)) { var pulse = 1; while (pulse <= 32) { // Writing var writerZif = new ZIFSocket(40); writerZif.SetAll(true); writerZif.Disable(eprom.GndPins, translator.ToZIF); writerZif.Enable(eprom.Constants, translator.ToZIF); writerZif.Disable(eprom.ChipEnable, translator.ToZIF); writerZif.Disable(eprom.OutputEnable, translator.ToZIF); writerZif.Disable(eprom.Program, translator.ToZIF); eprom.SetAddress(writerZif, address); var data = eprom.DataPins.Length > 8 ? new[] { bytes[2 * address], bytes[2 * address + 1] } : new[] { bytes[address] }; eprom.SetData(writerZif, data); WriteZIF(writerZif, "Write address & d ata to ZIF"); writerZif.Enable(eprom.ChipEnable, translator.ToZIF); writerZif.Enable(eprom.Program, translator.ToZIF); WriteZIF(writerZif, "Start pulse E"); writerZif.Disable(eprom.ChipEnable, translator.ToZIF); writerZif.Disable(eprom.Program, translator.ToZIF); BulkDevice.Delay(pulse); WriteZIF(writerZif, "End pulse E"); // Reading var addressZif = new ZIFSocket(40); addressZif.SetAll(true); addressZif.Disable(eprom.GndPins, translator.ToZIF); addressZif.Enable(eprom.Constants, translator.ToZIF); addressZif.Enable(eprom.ChipEnable, translator.ToZIF); addressZif.Enable(eprom.OutputEnable, translator.ToZIF); addressZif.Disable(eprom.Program, translator.ToZIF); eprom.SetAddress(addressZif, address); WriteZIF(addressZif, "Write address"); var dataZifs = ReadZIF("Read data"); ZIFSocket resultZif; if (Tools.AnalyzeEpromReadSoundness(dataZifs, eprom, address, out resultZif) == ReadSoundness.SeemsToBeAOkay) { if (eprom.GetData(resultZif).SequenceEqual(data)) { // Data validates; now we overprogram writerZif.Enable(eprom.ChipEnable, translator.ToZIF); writerZif.Enable(eprom.Program, translator.ToZIF); WriteZIF(writerZif, "Overprogram"); BulkDevice.Delay(3 * pulse); writerZif.Disable(eprom.ChipEnable, translator.ToZIF); writerZif.Disable(eprom.Program, translator.ToZIF); WriteZIF(writerZif, "End pulse E"); break; } else { Console.WriteLine("Pulse: {0}", pulse); Console.WriteLine("Address: {0}", address.ToString("X4")); Console.WriteLine(eprom.GetData(writerZif).First()); Console.WriteLine(eprom.GetData(resultZif).First()); } } pulse *= 2; } if (pulse > 32) { progress.Shout("Address {0} doesn't validate! }};-(", address.ToString("X4")); } progress.Progress(); } } }
/// <summary> /// Writes an EPROM using the Classic Algorithm /// </summary> /// <param name="eprom">The EPROM type.</param> /// <param name="bytes">The bytes to write.</param> /// <param name="patch">Not used yet!</param> public void WriteEpromClassic(Eprom eprom, IList <byte> bytes, IList <int> patch = null) { var totalNumberOfAdresses = eprom.AddressPins.Length == 0 ? 0 : 1 << eprom.AddressPins.Length; var translator = eprom.GetPinTranslator(ZIFType); SetVccLevel(eprom.VccLevel); ApplyGnd(translator.ToZIF, eprom.GndPins); ApplyVcc(translator.ToZIF, eprom.VccPins); var initZif = new ZIFSocket(ZIFType); initZif.SetAll(true); initZif.Disable(eprom.GndPins, translator.ToZIF); initZif.Enable(eprom.Constants, translator.ToZIF); initZif.Disable(eprom.ChipEnable, translator.ToZIF); initZif.Disable(eprom.OutputEnable, translator.ToZIF); initZif.Disable(eprom.Program, translator.ToZIF); WriteZIF(initZif, "Apply 1 to all data and address pins"); SetVppLevel(eprom.VppLevel); ApplyVpp(translator.ToZIF, eprom.VppPins); PullUpsEnable(true); using (var progress = new ProgressBar(Shouter, totalNumberOfAdresses)) { progress.Init(); foreach (var address in Enumerable.Range(0, totalNumberOfAdresses)) { //if(patch != null) //{ // if(!patch.Contains(address)) // continue; // progress.Shout("Now patching address {0}", address); //} var zif = new ZIFSocket(40); // Pull up all pins zif.SetAll(true); zif.Disable(eprom.GndPins, translator.ToZIF); zif.Enable(eprom.Constants, translator.ToZIF); zif.Disable(eprom.Program, translator.ToZIF); zif.Disable(eprom.ChipEnable, translator.ToZIF); zif.Disable(eprom.OutputEnable, translator.ToZIF); // Set address and data eprom.SetAddress(zif, address); var data = eprom.DataPins.Length > 8 ? new[] { bytes[2 * address], bytes[2 * address + 1] } : new[] { bytes[address] }; eprom.SetData(zif, data); // Prepare ZIF without programming in order to let it stabilize // TODO: Do we really need to do this? WriteZIF(zif, "Write address & data to ZIF"); // In order to let the boost converter for manual Vcc // spin up to full output voltage. if (address == 0 && eprom.InitialProgDelay != 0) { BulkDevice.Delay(eprom.InitialProgDelay); } // Enter programming mode zif.Enable(eprom.Program, translator.ToZIF); zif.Enable(eprom.ChipEnable, translator.ToZIF); WriteZIF(zif, "Start pulse E"); // Exit programming mode after at least <pulse> ms zif.Disable(eprom.Program, translator.ToZIF); zif.Disable(eprom.ChipEnable, translator.ToZIF); BulkDevice.Delay(eprom.ProgPulse); WriteZIF(zif, "End pulse E"); progress.Progress(); } } }