first attempt to integrate the ATF1502

This commit is contained in:
hneemann 2017-03-10 10:30:45 +01:00
parent 845ea28097
commit 75d28d663e
10 changed files with 372 additions and 12 deletions

View File

@ -0,0 +1,28 @@
package de.neemann.digital.builder.ATF1502;
import de.neemann.digital.builder.ExpressionToFileExporter;
import de.neemann.digital.gui.Main;
import java.io.*;
/**
* Created by hneemann on 10.03.17.
*/
public class CreateCHN implements ExpressionToFileExporter.PostProcess {
@Override
public File execute(File file) throws IOException {
File chnFile = Main.checkSuffix(file, "chn");
System.out.println("create chn from " + file);
try (Writer chn = new OutputStreamWriter(new FileOutputStream(chnFile), "UTF-8")) {
chn.write("1 4 1 0 \r\n"
+ "\r\n"
+ "ATF1502AS\r\n"
+ "10\r\n"
+ "1\r\n");
chn.write(chnFile.getPath());
}
return chnFile;
}
}

View File

@ -0,0 +1,100 @@
package de.neemann.digital.builder;
import de.neemann.digital.builder.jedec.FuseMapFillerException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
/**
* Used to create a output chain of files created
* Created by hneemann on 10.03.17.
*/
public class ExpressionToFileExporter {
private final ExpressionExporter exporter;
private final ArrayList<PostProcess> postProcesses;
/**
* Creates a new instance
*
* @param exporter the initial export to create the initial file
*/
public ExpressionToFileExporter(ExpressionExporter exporter) {
this.exporter = exporter;
postProcesses = new ArrayList<>();
}
/**
* @return the initial exporter
*/
public ExpressionExporter getExporter() {
return exporter;
}
/**
* Is delegated to exporter.getPinMap.
*
* @return the pin map
*/
public PinMap getPinMapping() {
return exporter.getPinMapping();
}
/**
* Is delegated to exporter.getBuilder.
*
* @return the builder
*/
public BuilderInterface getBuilder() {
return exporter.getBuilder();
}
/**
* Adds a processing step.
* All steps are executed after the initial fals has been created.
*
* @param postProcess the process to start
* @return this for chained calls
*/
public ExpressionToFileExporter addProcessingStep(PostProcess postProcess) {
postProcesses.add(postProcess);
return this;
}
/**
* Runs the export chain
*
* @param file the name of the initial file
* @throws IOException IOException
* @throws PinMapException PinMapException
* @throws FuseMapFillerException FuseMapFillerException
*/
public void export(File file) throws IOException, PinMapException, FuseMapFillerException {
try (OutputStream out = new FileOutputStream(file)) {
exporter.writeTo(out);
}
for (PostProcess p : postProcesses)
try {
file = p.execute(file);
} catch (IOException e) {
throw new IOException("post process error in " + p.toString(), e);
}
}
/**
* PostProcess is used to start further steps creating the final output file
*/
public interface PostProcess {
/**
* Execute a new process
*
* @param file the file to process
* @return the new file created or, if no file is created the given file is returned
* @throws IOException IOException
*/
File execute(File file) throws IOException;
}
}

View File

@ -0,0 +1,127 @@
package de.neemann.digital.builder.tt2;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* OSExecute is used to start external programs
* It is used to start external fitters like fit1502.exe
* <p>
* Created by hneemann on 10.03.17.
*/
public class OSExecute {
private final ProcessBuilder procesBuilder;
private File workingDir;
/**
* Creates a new instance
*
* @param args the program to start
*/
public OSExecute(String... args) {
procesBuilder = new ProcessBuilder(args);
}
/**
* Creates a new instance
*
* @param args the program to start
*/
public OSExecute(List<String> args) {
procesBuilder = new ProcessBuilder(args);
}
/**
* Sets the working directory
*
* @param workingDir the working directory
*/
public void setWorkingDir(File workingDir) {
this.workingDir = workingDir;
}
/**
* Starts the execution and waits for its completion.
*
* @return the console output of the of the started process
* @throws IOException IOException
*/
public String start() throws IOException {
if (workingDir != null)
procesBuilder.directory(workingDir);
procesBuilder.redirectErrorStream(true);
Process p = procesBuilder.start();
InputStream console = p.getInputStream();
StreamReader sr = new StreamReader(console);
sr.start();
try {
p.waitFor(30, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (p.isAlive()) {
p.destroy();
sr.interrupt();
throw new IOException("Process does not terminate!");
}
if (p.exitValue() != 0)
throw new IOException("got non zero exit value " + p.exitValue());
try {
sr.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (sr.getException() != null)
throw sr.getException();
return sr.toString();
}
private static final class StreamReader extends Thread {
private final InputStream console;
private final ByteArrayOutputStream baos;
private IOException exception;
private StreamReader(InputStream console) {
this.console = console;
baos = new ByteArrayOutputStream();
setDaemon(true);
}
@Override
public void run() {
try {
byte[] data = new byte[4096];
int l;
while ((l = console.read(data)) >= 0) {
baos.write(data, 0, l);
}
} catch (IOException e) {
exception = e;
}
}
private IOException getException() {
return exception;
}
@Override
public String toString() {
return baos.toString();
}
}
}

View File

@ -0,0 +1,59 @@
package de.neemann.digital.builder.tt2;
import de.neemann.digital.builder.ExpressionToFileExporter;
import de.neemann.digital.core.element.Keys;
import de.neemann.digital.gui.Main;
import de.neemann.digital.gui.Settings;
import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
/**
* Starts a fitter to create a JEDEC file.
* Created by hneemann on 10.03.17.
*/
public class StartFitter implements ExpressionToFileExporter.PostProcess {
private final JDialog parent;
private final File fitterExe;
/**
* Creates a new instance
*
* @param parent the parent dialog
*/
public StartFitter(JDialog parent) {
this.parent = parent;
this.fitterExe = Settings.getInstance().get(Keys.SETTINGS_ATF1502_FITTER);
}
@Override
public File execute(File file) throws IOException {
ArrayList<String> args = new ArrayList<>();
if (isLinux())
args.add("wine");
args.add(fitterExe.toString());
args.add(file.getName());
OSExecute execute = new OSExecute(args);
execute.setWorkingDir(file.getParentFile());
String message = execute.start();
SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(parent, message));
return Main.checkSuffix(file, "jed");
}
private boolean isLinux() {
String name = System.getProperty("os.name").toLowerCase();
return name.contains("linux");
}
@Override
public String toString() {
return "External fitter to create a JEDEC file";
}
}

View File

@ -6,6 +6,7 @@ import de.neemann.digital.core.memory.DataField;
import de.neemann.gui.language.Language;
import java.awt.*;
import java.io.File;
import java.util.Locale;
/**
@ -295,4 +296,10 @@ public final class Keys {
public static final Key<Boolean> LED_PERSISTENCE
= new Key<>("ledPersistence", false);
/**
* Fitter for the atf1502
*/
public static final Key<File> SETTINGS_ATF1502_FITTER
= new Key<>("atf1502Fitter", new File("fit1502.exe"));
}

View File

@ -32,6 +32,7 @@ public final class Settings implements AttributeListener {
INT_LIST.add(Keys.SETTINGS_IEEE_SHAPES);
INT_LIST.add(Keys.SETTINGS_LANGUAGE);
INT_LIST.add(Keys.SETTINGS_EXPRESSION_FORMAT);
INT_LIST.add(Keys.SETTINGS_ATF1502_FITTER);
}
private static final class SettingsHolder {

View File

@ -23,6 +23,7 @@ import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.text.JTextComponent;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.HashMap;
@ -42,6 +43,7 @@ public final class EditorFactory {
private EditorFactory() {
add(String.class, StringEditor.class);
add(Integer.class, IntegerEditor.class);
add(File.class, FileEditor.class);
add(Color.class, ColorEditor.class);
add(Boolean.class, BooleanEditor.class);
add(DataField.class, DataFieldEditor.class);
@ -251,6 +253,37 @@ public final class EditorFactory {
}
}
private final static class FileEditor extends LabelEditor<File> {
private final JPanel panel;
private final JTextField textField;
public FileEditor(File value, Key<File> key) {
panel = new JPanel(new BorderLayout());
textField = new JTextField(value.getPath(), 20);
JButton button = new JButton(new AbstractAction("...") {
@Override
public void actionPerformed(ActionEvent e) {
JFileChooser fc = new JFileChooser(FileEditor.this.getValue());
if (fc.showOpenDialog(panel) == JFileChooser.APPROVE_OPTION)
textField.setText(fc.getSelectedFile().getPath());
}
});
panel.add(textField, BorderLayout.CENTER);
panel.add(button, BorderLayout.EAST);
}
@Override
public JComponent getComponent(ElementAttributes attr) {
return panel;
}
@Override
public File getValue() {
return new File(textField.getText());
}
}
private final static class DataFieldEditor extends LabelEditor<DataField> {
private DataField data;

View File

@ -16,6 +16,7 @@ import de.neemann.digital.analyse.format.TruthTableFormatterLaTeX;
import de.neemann.digital.analyse.quinemc.BoolTableIntArray;
import de.neemann.digital.builder.ATF1502.ATF1502CuplExporter;
import de.neemann.digital.builder.ATF1502.ATF1502TT2Exporter;
import de.neemann.digital.builder.ATF1502.CreateCHN;
import de.neemann.digital.builder.*;
import de.neemann.digital.builder.Gal16v8.Gal16v8CuplExporter;
import de.neemann.digital.builder.Gal16v8.Gal16v8JEDECExporter;
@ -23,6 +24,7 @@ import de.neemann.digital.builder.Gal22v10.Gal22v10CuplExporter;
import de.neemann.digital.builder.Gal22v10.Gal22v10JEDECExporter;
import de.neemann.digital.builder.circuit.CircuitBuilder;
import de.neemann.digital.builder.jedec.FuseMapFillerException;
import de.neemann.digital.builder.tt2.StartFitter;
import de.neemann.digital.draw.elements.Circuit;
import de.neemann.digital.draw.shapes.ShapeFactory;
import de.neemann.digital.gui.Main;
@ -47,7 +49,6 @@ import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashSet;
@ -402,7 +403,7 @@ public class TableDialog extends JDialog {
@Override
public void actionPerformed(ActionEvent actionEvent) {
Gal16v8JEDECExporter jedecExporter = new Gal16v8JEDECExporter();
createHardware(jedecExporter, filename, "jed");
createHardware(new ExpressionToFileExporter(jedecExporter), filename, "jed");
new ShowStringDialog(parent, Lang.get("win_pinMapDialog"), jedecExporter.getPinMapping().toString()).setVisible(true);
}
}.setToolTip(Lang.get("menu_table_create_jedec_tt")).createJMenuItem());
@ -419,7 +420,7 @@ public class TableDialog extends JDialog {
@Override
public void actionPerformed(ActionEvent actionEvent) {
Gal22v10JEDECExporter jedecExporter = new Gal22v10JEDECExporter();
createHardware(jedecExporter, filename, "jed");
createHardware(new ExpressionToFileExporter(jedecExporter), filename, "jed");
new ShowStringDialog(parent, Lang.get("win_pinMapDialog"), jedecExporter.getPinMapping().toString()).setVisible(true);
}
}.setToolTip(Lang.get("menu_table_create_jedec_tt")).createJMenuItem());
@ -436,7 +437,10 @@ public class TableDialog extends JDialog {
atf1502.add(new ToolTipAction(Lang.get("menu_table_createTT2")) {
@Override
public void actionPerformed(ActionEvent actionEvent) {
createHardware(new ATF1502TT2Exporter(), filename, "tt2");
createHardware(
new ExpressionToFileExporter(new ATF1502TT2Exporter())
.addProcessingStep(new StartFitter(TableDialog.this))
.addProcessingStep(new CreateCHN()), filename, "tt2");
}
}.setToolTip(Lang.get("menu_table_createTT2_tt")).createJMenuItem());
hardware.add(atf1502);
@ -447,7 +451,7 @@ public class TableDialog extends JDialog {
return createMenu;
}
private void createHardware(ExpressionExporter expressionExporter, File filename, String suffix) {
private void createHardware(ExpressionToFileExporter expressionExporter, File filename, String suffix) {
if (filename == null)
filename = new File("circuit." + suffix);
else
@ -458,11 +462,9 @@ public class TableDialog extends JDialog {
fileChooser.setSelectedFile(filename);
if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
try {
try (OutputStream out = new FileOutputStream(Main.checkSuffix(fileChooser.getSelectedFile(), suffix))) {
expressionExporter.getPinMapping().addAll(pinMap);
new BuilderExpressionCreator(expressionExporter.getBuilder(), ExpressionModifier.IDENTITY).create();
expressionExporter.writeTo(out);
}
expressionExporter.getPinMapping().addAll(pinMap);
new BuilderExpressionCreator(expressionExporter.getBuilder(), ExpressionModifier.IDENTITY).create();
expressionExporter.export(Main.checkSuffix(fileChooser.getSelectedFile(), suffix));
} catch (ExpressionException | FormatterException | IOException | FuseMapFillerException | PinMapException e) {
new ErrorMessage(Lang.get("msg_errorDuringCalculation")).addCause(e).show(this);
}

View File

@ -524,6 +524,8 @@ Zur Analyse können Sie die Schaltung im Gatterschrittmodus ausführen.</string>
<string name="key_ledPersistence_tt">Die Schaltfrequenz in der Simulation kann nicht so hoch werden,
dass das menschliche Auge kein Flimmern mehr wahrnimmt. Um dennoch das Flackern zu unterdrücken, kann
bei den LEDs mit dieser Option ein "nachleuchten" eingeschaltet werden.</string>
<string name="key_atf1502Fitter">ATF1502 Fitter</string>
<string name="key_atf1502Fitter_tt">Pfad zum Fitter für den ATF1502. Geben Sie hier den vollen Pfad zur Datei fit1502.exe an. Diese Datei wird von ATMEL zu Verfügung gestellt.</string>
<string name="lib_Logic">Logisch</string>
<string name="lib_arithmetic">Arithmetik</string>

View File

@ -509,8 +509,9 @@ To analyse you can run the circuit in single gate step mode.</string>
<string name="key_ledPersistence">Avoid Flicker</string>
<string name="key_ledPersistence_tt">It is not possible to increase the frequency so much that the flickering disappears.
With this option you can stabilize the display by keeping the LEDs on until the common cathode goes down again.
This simulates a frequency above the critical flicker fusion frequency.
</string>
This simulates a frequency above the critical flicker fusion frequency.</string>
<string name="key_atf1502Fitter">ATF1502 Fitter</string>
<string name="key_atf1502Fitter_tt">Path to the fitter for the ATF1502. Enter the full path to the file fit1502.exe provided bei ATMEL.</string>
<string name="lib_Logic">Logic</string>
<string name="lib_arithmetic">Arithmetic</string>