/**
* KKMulticopterFlashTool, a avrdude GUI for flashing KK boards and other
* equipment.
* Copyright (C) 2011 Christian Moll
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.lazyzero.kkMulticopterFlashTool;
import static lu.tudor.santec.i18n.Translatrix._;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.SplashScreen;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Properties;
import java.util.Vector;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import lu.tudor.santec.i18n.Translatrix;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
import avr8_burn_o_mat.AVR;
import avr8_burn_o_mat.AvrdudeConfigFile;
import avr8_burn_o_mat.AvrdudeControl;
import avr8_burn_o_mat.AvrdudeControl.FileFormat;
import avr8_burn_o_mat.AvrdudeProgrammer;
import avr8_burn_o_mat.InterfaceTextOutput;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import de.lazyzero.kkMulticopterFlashTool.gui.ColorTweaks;
import de.lazyzero.kkMulticopterFlashTool.gui.ControllerPanel;
import de.lazyzero.kkMulticopterFlashTool.gui.EEpromResetPanel;
import de.lazyzero.kkMulticopterFlashTool.gui.EEpromSettingsPanel;
import de.lazyzero.kkMulticopterFlashTool.gui.FirmwarePanel;
import de.lazyzero.kkMulticopterFlashTool.gui.ProgrammerPanel;
import de.lazyzero.kkMulticopterFlashTool.gui.SimonkEditorPanel;
import de.lazyzero.kkMulticopterFlashTool.gui.kkMenu;
import de.lazyzero.kkMulticopterFlashTool.utils.ArduinoUpload;
import de.lazyzero.kkMulticopterFlashTool.utils.ButtonsStateListener;
import de.lazyzero.kkMulticopterFlashTool.utils.FileCorruptException;
import de.lazyzero.kkMulticopterFlashTool.utils.Firmware;
import de.lazyzero.kkMulticopterFlashTool.utils.Icons;
import de.lazyzero.kkMulticopterFlashTool.utils.XmlReaderFirmwares;
import de.lazyzero.kkMulticopterFlashTool.utils.EEprom.EEprom;
import de.lazyzero.kkMulticopterFlashTool.utils.EEprom.EEpromListener;
/**
* @author Christian Moll
*
*/
public class KKMulticopterFlashTool extends JFrame implements
InterfaceTextOutput, PropertyChangeListener {
/**
*
*/
private static final long serialVersionUID = 1L;
public static String VERSION = "0.80";
private static boolean isBeta = true;
private static int betaVersion = 6;
public static final String MODE_CHANGED = "changed";
public static final String KKPLUSBOOT = "kkplusboot";
public static final String FLYCAM_BLACKBOARD = "flycam_black";
public static final String FLYCAM_BLACKBOARD_P = "flycam_blackp";
public static final String SMARTLCD = "smartlcd";
public static final String ESC = "esc";
public static final String ESCBOOTLOADER = "escp";
public static final String WIIESC = "wii_bl";
public static final String WIIESC_EEPROM = "wii_eeprom";
public static final Object WIIESC_BOOTLOADER = "wii_boot";
public static final String ESC_LIGHT = "esc_light";
public static final String OPENFLIGHT_V1 = "openflightV1";
public static final String OPENFLIGHT_V2 = "openflightV2";
public static final String OPENFLIGHT_V2_SM = "openflightSM";
public static final String OPENFLIGHTPROG = "openflightPROG";
public static final String i86 = "i86";
public static final String i86l = "i86l";
private static KKMulticopterFlashTool kk;
private Locale locale;
private JPanel mainPanel;
private Properties settings = new Properties();
public static File SETTINGS_FILE = new File(System.getProperty("user.dir"), "kkMulticopterFlashTool.properties");
public static File LOG_FILE = new File(System.getProperty("user.dir"), "kkLogging.txt");
private JFrame mainframe;
private Dimension preferredSize = new Dimension(830, 650);
private AvrdudeConfigFile avrConfig;
private AvrdudeProgrammer programmer;
private AvrdudeControl control;
private boolean forceFlashing = false;
private Vector<AvrdudeProgrammer> programmers;
private static Vector<AVR> avrs = new Vector<AVR>();
private AVR controller;
private JTextArea output;
private Color defaultFG;
private JScrollPane outputPane;
private ProgrammerPanel programmerPanel;
private ControllerPanel controllerPanel;
private FirmwarePanel firmwarePanel;
private LinkedHashMap<String,String> firmwareRepositoryURL = new LinkedHashMap<String,String>();
private Firmware firmware;
private XmlReaderFirmwares firmwareReader;
private boolean offlineMode;
private String mode;
private FileHandler logFile;
private Logger logger = Logger.getLogger(KKMulticopterFlashTool.class.getName());
private boolean enableTweak = true;
public static boolean ENABLE_PORT_CHECK = true;
private static boolean isPopupsEnabled;
private static int countdown;
private static boolean isHideDeprecated;
private static boolean isShowDailyTGYEnabled;
private static boolean isVerbose;
private JTabbedPane tabbedPane = new JTabbedPane();
//private TestPanel testPanel;
private JPanel programmingPanel;
private JPanel eepromPanel;
private Component eepromResetPanel;
private EEpromSettingsPanel eepromSettingsPanel;
protected boolean successful;
private Vector<ButtonsStateListener> listeners = new Vector<ButtonsStateListener>();
private boolean isNoLogging = false;
private boolean useDefaults = false;
private SimonkEditorPanel simonkEditorPanel;
public KKMulticopterFlashTool(String[] args) {
kk = this;
evaluateCommandlineOptions(args);
//check if the OS is Mac OS X
if (System.getProperty("os.name").toLowerCase().contains("mac")) {
SETTINGS_FILE = new File(System.getProperty("user.home")+"/Library/Preferences/","kkMulticopterFlashTool.properties");
LOG_FILE = new File(getTempFolder(),"kkLogging.txt");
}
if (!isNoLogging ) initLogger();
SplashScreen splash = SplashScreen.getSplashScreen();
if (splash==null) {
logger.log(Level.INFO, "Splash not loaded.");
}
logger.log(Level.INFO, System.getProperty("user.home"));
logger.log(Level.INFO, System.getProperty("os.name"));
loadSettings();
loadTranslation();
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
saveSettings();
}
});
firmwareReader = new XmlReaderFirmwares(firmwareRepositoryURL);
this.init();
if (enableTweak) ColorTweaks.tweakColors();
this.initGUI();
this.addPropertyChangeListener(this);
checkVersion();
}
private void evaluateCommandlineOptions(String[] args) {
Options options = new Options();
options.addOption("h", "help", false, "Show this help message.");
options.addOption("c", "color", false, "Use default colors of the Java VM.");
options.addOption("p", "portcheck", false, "Disable checking for port checking.");
options.addOption("n", "nologging", false, "Disable logging to file.");
options.addOption("d", "defaults", false, "Use default settings");
try {
CommandLineParser parser = new PosixParser();
CommandLine cmd = parser.parse(options, args);
if (cmd.hasOption("h")) {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp("KKmulticopter Flash Tool Version " + VERSION, options, true);
System.exit(0);
}
if (cmd.hasOption("c")) {
enableTweak = false;
}
if (cmd.hasOption("p")) {
ENABLE_PORT_CHECK = false;
}
if (cmd.hasOption("n")) {
isNoLogging = true;
}
if (cmd.hasOption("d")) {
useDefaults = true;
}
} catch (ParseException exp) {
}
}
private void initLogger() {
try {
logFile = new FileHandler(LOG_FILE.getAbsolutePath(), false);
logFile.setFormatter(new SimpleFormatter());
logFile.setLevel(Level.INFO);
logger.addHandler(logFile);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
logger.setLevel(Level.INFO);
}
private void checkVersion() {
logger.log(Level.INFO, "Check the version: " + VERSION + (isBeta?" beta "+betaVersion:"") + " online is version: " + firmwareReader.getActualVersion());
if (firmwareReader.getActualVersion()>Double.parseDouble(VERSION)) {
// JOptionPane.showMessageDialog(this, _("update"));
String[] choices = {_("downloads.download"), _("Cancel")};
String updateTitle = String.format(_("updateTitle"), Double.toString(firmwareReader.getActualVersion()));
String updateText = "<html>"+_("update") + "<br><br>" + _("updateChanges") + "<br>" + firmwareReader.getChangelog();
int result = JOptionPane.showOptionDialog(this, updateText, updateTitle ,
JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE,
null, choices, choices[0]);
if (result == 0) {
kkMenu.openURL("http://kkflashtool.de");
System.exit(0);
}
}
}
public void flashAVR() {
boolean abort = check4USBlinker();
if (!abort) {
new Thread(){
public void run(){
boolean notFailed = true;
boolean isUSBtiny = programmer.getType().equals("usbtiny")?true:false;
firmwarePanel.setButtonsEnabled(false);
updateButtons();
try {
control = new AvrdudeControl(KKMulticopterFlashTool.this, isUSBtiny);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
logger.log(Level.WARNING, e1.getMessage());
}
if(isVerbose) {
control.addAdditionalOption("-vvvvv ");
}
control.setPort(programmerPanel.getPort());
control.setProgrammer(programmer);
if (programmerPanel.useBaudRate()) {
control.addAdditionalOption("-b " + programmerPanel.getRate());
}
logger.log(Level.INFO, programmer.getType());
// if (!programmer.getType().equals("stk500v2")){
// if (!programmer.getType().equals("usbtiny")){
// control.addAdditionalOption("-B 8");
// logger.log(Level.INFO, "set additional Option -B 8");
// }
// }
//if (controller.getCaption().equals("m48pa")||controller.getCaption().equals("m168p")||controller.getCaption().equals("m328p")){
control.addAdditionalOption("-e");
logger.log(Level.INFO, "set additional Option -e");
// }
if (forceFlashing) {
control.addAdditionalOption("-F");
}
control.setDisableFuseCheck(false);
//import additionalOptions from firmware
control.addAndUpdateAdditionalOptions(firmware.getAdditionalOptions());
//for BL-ESC the fuses are null and the next step is skipped.
if (controller.getLfuse() != null && controller.getHfuse() != null) {
//write the fuses.
try {
logger.log(Level.INFO, "write fuses: ");
control.writeFuses(controller);
} catch (Exception e) {
notFailed = false;
e.printStackTrace();
logger.log(Level.WARNING, "error.writefuses");
err(_("error.writefuses"));
}
try {
Thread.sleep(1500);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
logger.log(Level.WARNING, e1.toString());
}
}
//TODO add code to manipulate fuses
//special code for enabling bootloader on simonk ESC
if (controller.getCaption().equals(ESCBOOTLOADER) && notFailed) {
logger.log(Level.INFO, "enable bootloader on simonk ESC: " + controller.getBootloaderAddress());
try {
control.readFuses(controller, getTempFolder());
logger.log(Level.INFO, "hfuse: " + Integer.toHexString(Integer.parseInt(controller.getHfuse())) + " lfuse: " + Integer.toHexString(Integer.parseInt(controller.getLfuse())));
if (controller.getBootloaderAddress()==512){
controller.changeFuseNibble(AVR.HFUSE, AVR.LOWER_NIBBLE, "a");
logger.log(Level.INFO, "fuses changed to: hfuse: " + Integer.toHexString(Integer.parseInt(controller.getHfuse())) + " lfuse: " + Integer.toHexString(Integer.parseInt(controller.getLfuse())));
}
//added a delay to test if avrispmkii will then work
try {
Thread.sleep(1500);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
logger.log(Level.WARNING, e1.toString());
}
logger.log(Level.INFO, "write new fuses: ");
control.writeFuses(controller);
} catch (Exception e) {
notFailed = false;
err(_("error.readhfuse"));
logger.log(Level.WARNING, "error.replacefuse");
e.printStackTrace();
}
//clean up
controller.setHfuse(null);
controller.setLfuse(null);
File fuseFile = new File(getTempFolder() + "/hfuse.hex");
boolean isDeleted = false;
if(fuseFile.exists() && fuseFile.isFile()){
isDeleted = fuseFile.delete();
logger.log(Level.INFO, "hfuse.hex deleted: " + isDeleted);
}
fuseFile = new File(getTempFolder() + "/lfuse.hex");
if(fuseFile.exists() && fuseFile.isFile()){
isDeleted = fuseFile.delete();
logger.log(Level.INFO, "lfuse.hex deleted: " + isDeleted);
}
try {
Thread.sleep(1500);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
logger.log(Level.WARNING, e1.toString());
}
}
try {
if (notFailed) {
logger.log(Level.INFO, "flash firmware");
//TODO add flashing of eeprom here.
try {
File file = firmware.getFile();
println(_("flash.file") + ": "
+ file.getAbsolutePath());
control.writeFlash(controller, file.getAbsolutePath(), FileFormat.INTEL_HEX);
if (isPopupsEnabled) {
JOptionPane.showMessageDialog(kk, _("flash.successfull"), _("info"), JOptionPane.INFORMATION_MESSAGE);
}
println(_("flash.successfull"));
} catch (FileCorruptException e) {
err(_("flash.abort") + " " +_("flash.filecorrupt"));
}
} else {
err(_("flash.abort"));
logger.log(Level.WARNING, "flash.abort");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
err(_("error.writeflash"));
logger.log(Level.WARNING, "error.writeflash");
}
firmwarePanel.setButtonsEnabled(true);
updateButtons();
}
}.start();
} else {
err(_("flash.abort"));
}
}
public void flashEEprom(final EEpromListener eepromListener) {
logger.info("WRITE the EEprom!!!");
clearText();
boolean abort = check4USBlinker();
if (!abort) {
new Thread(){
public void run(){
boolean isUSBtiny = programmer.getType().equals("usbtiny")?true:false;
try {
control = new AvrdudeControl(KKMulticopterFlashTool.this, isUSBtiny);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
logger.log(Level.WARNING, e1.getMessage());
}
if(isVerbose) {
control.addAdditionalOption("-vvvvv ");
}
control.setPort(programmerPanel.getPort());
control.setProgrammer(programmer);
if (programmerPanel.useBaudRate()) {
control.addAdditionalOption("-b " + programmerPanel.getRate());
}
logger.log(Level.INFO, programmer.getType());
// if (!programmer.getType().equals("usbtiny")){
// control.addAdditionalOption("-B 8");
// logger.log(Level.INFO, "set additional Option -B 8");
// }
if (forceFlashing) {
control.addAdditionalOption("-F");
}
control.setDisableFuseCheck(false);
logger.log(Level.INFO, "flash eeprom");
try {
if (controller.getCaption().equals(WIIESC_EEPROM)) {
File file = firmware.getFile();
println(_("flash.eeprom") + ": "
+ file.getAbsolutePath());
control.writeEEPROM(controller, file.getAbsolutePath(), FileFormat.AUTO_DETECT);
} else {
println(_("flash.eeprom") + ": "
+ EEprom.getDefaultOutputFile());
control.writeEEPROM(controller, EEprom.getDefaultOutputFile(), FileFormat.RAW);
eepromListener.EEpromState(EEpromListener.WROTE);
}
} catch (FileCorruptException e) {
err(_("flash.abort") + " " +_("flash.filecorrupt"));
eepromListener.EEpromState(EEpromListener.FILE_CORRUPT);
} catch (Exception e) {
if (eepromListener != null) {
eepromListener.EEpromState(EEpromListener.FLASH_FAILED);
}
err(_("flash.abort"));
logger.warning(e.getMessage());
// e.printStackTrace();
}
}
}.start();
} else {
err(_("flash.abort"));
}
}
public void readEEprom(final EEpromListener eepromListener) {
logger.info("READ the EEprom!!!");
clearText();
boolean abort = check4USBlinker();
if (!abort) {
new Thread(){
public void run(){
boolean isUSBtiny = programmer.getType().equals("usbtiny")?true:false;
try {
control = new AvrdudeControl(KKMulticopterFlashTool.this, isUSBtiny);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
logger.log(Level.WARNING, e1.getMessage());
}
control.setPort(programmerPanel.getPort());
control.setProgrammer(programmer);
if (programmerPanel.useBaudRate()) {
control.addAdditionalOption("-b " + programmerPanel.getRate());
}
logger.log(Level.INFO, programmer.getType());
if (!programmer.getType().equals("usbtiny")){
control.addAdditionalOption("-B 8");
logger.log(Level.INFO, "set additional Option -B 8");
}
if (forceFlashing) {
control.addAdditionalOption("-F");
}
control.setDisableFuseCheck(false);
logger.log(Level.INFO, "flash eeprom");
try {
println(_("read.eeprom") + ": "
+ EEprom.getDefaultInputFile());
control.readEEPROM(controller, EEprom.getDefaultInputFile(), FileFormat.RAW);
eepromListener.EEpromState(EEpromListener.READ);
} catch (Exception e) {
eepromListener.EEpromState(EEpromListener.FAILED);
err(_("read.abort"));
logger.warning(e.getMessage());
// e.printStackTrace();
}
}
}.start();
} else {
eepromListener.EEpromState(EEpromListener.FAILED);
err(_("read.abort"));
}
}
private boolean check4USBlinker() {
if (programmer.getId().equals("tgyusblinker") || programmer.getId().equals("arduinousblinker") || programmer.getId().equals("afrousb")) {
if (programmerPanel.getPort().equals("usb")) {
err(_("flash.LinkerWrongPort"));
return true;
}
}
return false;
}
public void loadSettings() {
try {
settings.load(new FileInputStream(SETTINGS_FILE));
firmwareRepositoryURL.put("firmwareRepositoryURL", settings.getProperty("firmwareRepositoryURL", "http://www.chrmoll.de/_media/firmwares.xml.zip"));
//check for depricated settings!!!
if (firmwareRepositoryURL.containsValue("http://www.chrmoll.de/_media/firmwares.xml")) {
firmwareRepositoryURL.put("firmwareRepositoryURL", "http://www.chrmoll.de/_media/firmwares.xml.zip");
}
firmwareRepositoryURL.put("tgydaily",settings.getProperty("tgydaily", "http://www.chrmoll.de/_media/tgy_daily.xml.zip"));
offlineMode = new Boolean(settings.getProperty("offlineMode","false"));
isPopupsEnabled = new Boolean(settings.getProperty("isPopupEnabled","true"));
isHideDeprecated = new Boolean(settings.getProperty("isHideDeprecated","false"));
isVerbose = new Boolean(settings.getProperty("isVerbose","false"));
isShowDailyTGYEnabled = new Boolean(settings.getProperty("isShowDailyTGYEnabled", "false"));
countdown = Integer.parseInt(settings.getProperty("countdown", "0"));
if (isOfflineMode()) {
mode = _("offline");
} else {
mode = _("online");
}
try {
this.setLocale((String) settings.getProperty("locale.language",
"en"), (String) settings.getProperty("locale.country",
"US"));
} catch (Exception e) {
}
} catch (Exception e) {
e.printStackTrace();
firmwareRepositoryURL.put("firmwareRepositoryURL", "http://www.chrmoll.de/_media/firmwares.xml.zip");
offlineMode = false;
saveSettings();
e.printStackTrace();
}
}
private void saveSettings() {
if (!useDefaults) {
try {
settings.put("locale.language", locale.getLanguage());
settings.put("locale.country", locale.getCountry());
settings.put("offlineMode", offlineMode+"");
settings.put("isPopupEnabled", isPopupsEnabled+"");
settings.put("isHideDeprecated", isHideDeprecated+"");
settings.put("isVerbose", isVerbose+"");
settings.put("isShowDailyTGYEnabled", isShowDailyTGYEnabled+"");
settings.put("countdown", countdown+"");
settings.put("programmer", programmer.getId());
settings.put("port", programmerPanel.getPort());
settings.put("rate", programmerPanel.getRate());
settings.put("defaultRate", programmerPanel.isDefaultRate()+"");
settings.put("controller", controller.getName());
Iterator<String> keys = firmwareRepositoryURL.keySet().iterator();
while (keys.hasNext()) {
String key = keys.next();
settings.put(key, firmwareRepositoryURL.get(key));
}
try {
settings.put("last.dir", firmware.getFile().getPath());
} catch (Exception e) {
// TODO: handle exception
}
settings.store(new FileOutputStream(SETTINGS_FILE), "");
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void init() {
avrConfig = new AvrdudeConfigFile();
try {
avrConfig.readAvrdudeConfigFile(AvrdudeConfigFile.getConfigFileByOS());
} catch (IOException e) {
JOptionPane.showMessageDialog(this, _("error.avrdudeconfig"));
e.printStackTrace();
}
programmers = avrConfig.getProgrammerList();
avrs.add(new AVR("HobbyKing KK2.1 and KK2.1.5", "64kB flash", "m644p", 2048, null, null));
avrs.add(new AVR("HobbyKing KK2.1 and KK2.1.5 (fuse restore)", "64kB flash", "m644p", 2048, "0xf7", "0xd7", "0xfc"));
avrs.add(new AVR("HobbyKing KK2.0", "32kB flash", "m324pa", 1024, null, null));
avrs.add(new AVR("HobbyKing KK2.0 (fuse restore)", "32kB flash", "m324pa", 1024, "0xf7", "0xd7", "0xfc"));
avrs.add(new AVR("HobbyKing KK2.0 (brown out of 2.7V)", "32kB flash", "m324pa", 1024, "0xf7", "0xd7", "0xfd"));
avrs.add(new AVR("HobbyKing KK2.0 (ATmega1284P)", "128kB flash", "m1284p", 4096, "0xd7", "0xd1", "0xfc"));//(Low=D7, High=D1, Ext=FC)
avrs.add(new AVR("atmega 8-based brushless ESC", "8kB flash", ESC, 512, null, null));
avrs.add(new AVR("atmega 8-based brushless ESC + enable Bootloader", "8kB flash", ESCBOOTLOADER, 512, null, null, 512));
avrs.add(new AVR("atmega 8-based brushless ESC (fuse restore, external clock", "8kB flash", ESCBOOTLOADER, 512, "0x3f", "0xca"));
avrs.add(new AVR("atmega 8-based brushless ESC (fuse restore, internal clock", "8kB flash", ESCBOOTLOADER, 512, "0x24", "0xda"));
avrs.add(new AVR("WiiESC", "8kB flash", WIIESC, 512, null, null));
avrs.add(new AVR("WiiESC Settings", "8kB flash", WIIESC_EEPROM, 512, null, null));
avrs.add(new AVR("EscLight", "8kB flash", ESC_LIGHT, 512, null, null));
avrs.add(new AVR("Orange RX3S V2/V3", "16kB flash", OPENFLIGHT_V2, 512, null, null));
avrs.add(new AVR("Orange RX3SM", "16kB flash", OPENFLIGHT_V2_SM, 512, null, null));
avrs.add(new AVR("Orange RX3S V1", "16kB flash", OPENFLIGHT_V1, 512, null, null));
avrs.add(new AVR("OpenFlight Programming Box", "8kB flash", OPENFLIGHTPROG, 512, null, null));
avrs.add(new AVR("KK Blackboard 168", "16kB flash", "m168", 512,"0xe2", "0xdd")); //Niall efuse:FF lfuse:E2 hfuse:DE
avrs.add(new AVR("KK Blackboard 168P/PA", "16kB flash", "m168p", 512, "0xe2", "0xdd"));
avrs.add(new AVR("KK Blackboard 328P", "32kB flash", "m328p", 1024, "0xe2", "0xd9"));
avrs.add(new AVR("KK Plus 5.5d/e", "16kB flash", "m168p", 512, "0xe2", "0xde"));
// avrs.add(new AVR("KK Plus 5.5d/e Bootloader restore", "16kB flash", KKPLUSBOOT, "0xe2", "0xde"));//Extended : 0xFF High: 0xDE Low: 0xE2
avrs.add(new AVR("HobbyKing Quadcopter Control Board V3", "32kB flash", "m328p", 1024, "0xe2", "0xd9"));
avrs.add(new AVR("HobbyKing Quadcopter Control Board V2/V2.1", "16kB flash", "m168p", 512, "0xe2", "0xdd"));
avrs.add(new AVR("HobbyKing Quadcopter Control Board V1", "4kB flash", "m48p", 256, "0xe2", "0xdd"));
avrs.add(new AVR("HobbyKing Hobbyking i86 or Eagle N6 V1", "16kB flash", i86, 512, "0xe2", "0xdd"));
avrs.add(new AVR("HobbyKing Hobbyking i86L or Eagle N6 V2", "16kB flash", i86l, 512, null, null));
avrs.add(new AVR("Flycam Blackboard", "16kB flash", FLYCAM_BLACKBOARD, 512, "0xe2", "0xdd"));//Extended : 0xFF High: 0xDE Low: 0xE2
avrs.add(new AVR("Flycam Blackboard (Goodluckbuy version)", "16kB flash", FLYCAM_BLACKBOARD_P, 512, "0xe2", "0xdd"));//Extended : 0xFF High: 0xDE Low: 0xE2
avrs.add(new AVR("Korean Blueboard", "16kB flash", "m168", 512, "0xe2", "0xdd"));
avrs.add(new AVR("Korean Redboard (without chip update)", "4kB flash", "m48", 256, "0xe2", "0xdd"));
avrs.add(new AVR("SmartLCD Pro", "4kB flash", SMARTLCD, 256, null, null));
// avrs.add(new AVR("atmega 48", "4kB flash", "m48", 256, "0xe2", "0xdd"));
// avrs.add(new AVR("atmega 48PA", "4kB flash", "m48p", 256, "0xe2", "0xdd"));
// avrs.add(new AVR("atmega 88", "8kB flash", "m88", 512, "0xe2", "0xdd"));
// avrs.add(new AVR("atmega 88P/PA", "8kB flash", "m88p", 512, "0xe2", "0xdd"));
// avrs.add(new AVR("atmega 168", "16kB flash", "m168", 512, "0xe2", "0xdd"));
// avrs.add(new AVR("atmega 168P/PA", "16kB flash", "m168p", 512, "0xe2", "0xdd"));
// avrs.add(new AVR("atmega 328P", "32kB flash", "m328p", 1024, "0xe2", "0xd9"));
// avrs.add(new AVR("atmega 328", "32kB flash", "m328", 1024, "0xe2", "0xd9"));
// avrs.add(new AVR(ArduinoUSBLinkerUploader.ARDUINO, "32kB flash", "m328", 1024, null, null));
}
private void initGUI() {
mainPanel = new JPanel();
// create the CellContraints
CellConstraints cc = new CellConstraints();
// create the Layout for Panel this
String panelColumns = "fill:pref:grow";
String panelRows = "3dlu,pref,3dlu,pref,3dlu,pref:grow";
FormLayout panelLayout = new FormLayout(panelColumns, panelRows);
mainPanel.setLayout(panelLayout);
programmingPanel = ceateProgrammingPanel();
eepromPanel = createEEpromPanel();
tabbedPane.add(programmingPanel);
programmerPanel = new ProgrammerPanel(this, programmers);
controllerPanel = new ControllerPanel(this, avrs);
simonkEditorPanel = new SimonkEditorPanel(this);
mainPanel.add(programmerPanel, cc.xy(1, 2));
mainPanel.add(controllerPanel, cc.xy(1, 4));
mainPanel.add(tabbedPane, cc.xy(1, 6));
logger.log(Level.INFO, "Set the port from the properties [usb]: " + settings.getProperty("port", "usb"));
programmerPanel.setPort(settings.getProperty("port", "usb"));
programmerPanel.setRate(settings.getProperty("rate", "19200"));
programmerPanel.setDefaultRate(new Boolean(settings.getProperty("defaultRate", "true")));
programmerPanel.setProgrammer(settings.getProperty("programmer",
"usbasp"));
controllerPanel.setController(settings.getProperty("controller",
"Blackboard"));
tabbedPane.addTab(_("programmingPanel.title"), programmingPanel);
tabbedPane.setBorder(new LineBorder(Color.WHITE));
tabbedPane.setMnemonicAt(0, KeyEvent.VK_1);
tabbedPane.addTab(_("simonkEditorPanel.title"), simonkEditorPanel);
tabbedPane.setMnemonicAt(1, KeyEvent.VK_2);
tabbedPane.setEnabledAt(tabbedPane.indexOfTab(_("simonkEditorPanel.title")), false);
tabbedPane.addTab(_("eepromPanel.title"), eepromPanel);
tabbedPane.setMnemonicAt(2, KeyEvent.VK_2);
tabbedPane.setEnabledAt(tabbedPane.indexOfTab(_("eepromPanel.title")), false);
tabbedPane.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent event) {
JTabbedPane sourceTabbedPane = (JTabbedPane) event.getSource();
if (sourceTabbedPane.getSelectedComponent().equals(eepromPanel)) {
logger.info("changed to eepromPanel");
eepromResetPanel.firePropertyChange(ControllerPanel.CONTROLLER_CHANGED, 0, 1);
} else if (sourceTabbedPane.getSelectedComponent().equals(programmingPanel)) {
logger.info("changed to programmingPanel");
}
}
});
mainframe = new JFrame(_("title") + " " + VERSION + (isBeta?" beta " + betaVersion:"") + " - " + mode);
// mainframe.setPreferredSize(preferredSize);
// mainframe.setSize(preferredSize);
// mainframe.add(tabbedPane);
mainframe.add(mainPanel);
mainframe.setJMenuBar((new kkMenu(this, firmwareReader)).getBar());
mainframe.setIconImage(Icons.getImage(Icons.app, 16));
mainframe.pack();
mainframe.setLocationRelativeTo(getRootPane());
mainframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
firmwarePanel.firePropertyChange(ControllerPanel.CONTROLLER_CHANGED, 0, 1);
}
private JPanel createEEpromPanel() {
JPanel panel = new JPanel();
CellConstraints cc = new CellConstraints();
// create the Layout for Panel this
String panelColumns = "pref:grow";
String panelRows = "pref,3dlu,fill:pref:grow,3dlu,pref";
FormLayout panelLayout = new FormLayout(panelColumns, panelRows);
panel.setLayout(panelLayout);
eepromResetPanel = new EEpromResetPanel(this);
eepromSettingsPanel = new EEpromSettingsPanel(this);
panel.add(eepromResetPanel, cc.xy(1, 1));
panel.add(eepromSettingsPanel, cc.xy(1, 3));
// TODO Auto-generated method stub
return panel;
}
private JPanel ceateProgrammingPanel() {
JPanel panel = new JPanel();
CellConstraints cc = new CellConstraints();
// create the Layout for Panel this
String panelColumns = "pref:grow";
String panelRows = "pref,3dlu,fill:pref";
FormLayout panelLayout = new FormLayout(panelColumns, panelRows);
panel.setLayout(panelLayout);
firmwarePanel = new FirmwarePanel(this, firmwareReader);
addButtonsStateListener(firmwarePanel);
output = new JTextArea();
output.setColumns(20);
output.setEditable(false);
output.setRows(15);
defaultFG = output.getForeground();
outputPane = new JScrollPane(output);
outputPane.setAutoscrolls(true);
outputPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
panel.add(firmwarePanel, cc.xy(1, 1));
panel.add(outputPane, cc.xy(1, 3));
// panel.setBorder(new LineBorder(Color.WHITE));
return panel;
}
private void checkTabVisibility() {
tabbedPane.setEnabledAt(tabbedPane.indexOfTab(_("eepromPanel.title")), false);
tabbedPane.setEnabledAt(tabbedPane.indexOfTab(_("simonkEditorPanel.title")), false);
if (controller.getCaption().equals(ESC) || controller.getCaption().equals(ESCBOOTLOADER)) {
tabbedPane.setEnabledAt(tabbedPane.indexOfTab(_("simonkEditorPanel.title")), true);
} else if (controller.getCaption().equals("m48") || controller.getCaption().equals("m48p")
|| controller.getCaption().equals("m168") || controller.getCaption().equals("m168p")
|| controller.getCaption().equals("m328p")){
tabbedPane.setEnabledAt(tabbedPane.indexOfTab(_("eepromPanel.title")), true);
}
}
public void setLocale(String language, String country) {
this.locale = new Locale(language, country);
logger.log(Level.INFO, language + "_" + country);
}
public Locale getLocale() {
return locale;
}
private void loadTranslation() {
// load the supported locales and the default locale
Translatrix
.loadSupportedLocales("de.lazyzero.kkMulticopterFlashTool.gui.resources.supportedLocales");
Translatrix.setLocale(Translatrix.getDefaultLocale());
// load resources for core package
@SuppressWarnings("rawtypes")
Vector<Locale> locales = new Vector<Locale>(Translatrix.getSupportedLocales());
if (locales.contains(locale)) {
Translatrix.setLocale(locale);
} else {
locale = Translatrix.getLocale();
}
Translatrix.addBundle("de.lazyzero.kkMulticopterFlashTool.gui.resources.translatrix");
}
public boolean restart() {
int response = JOptionPane.showConfirmDialog(mainframe,
_("restart.dialog"), _("restart.title"),
JOptionPane.YES_NO_OPTION);
if (response == 0)
return true;
return false;
}
/**
* @return the mainframe
*/
public JFrame getMainframe() {
return mainframe;
}
/**
* @return the settings
*/
public Properties getSettings() {
return settings;
}
/**
* @param args
*/
public static void main(String[] args) {
new KKMulticopterFlashTool(args);
kk.mainframe.setVisible(true);
kk.checkTabVisibility();
}
public void print(final String line) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
output.append(line);
}
});
}
public void println(final String line) {
logger.log(Level.INFO, line);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
output.append(line);
output.append("\n");
}
});
}
public void err(final String line) {
logger.log(Level.WARNING, line);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
output.setForeground(Color.red);
output.append(line);
output.append("\n");
}
});
if (isPopupsEnabled) {
JOptionPane.showMessageDialog(this, line, _("error"), JOptionPane.ERROR_MESSAGE);
}
}
public void clearText() {
output.setForeground(defaultFG);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
output.setText("");
}
});
}
@Override
public String getText() {
return output.getText();
}
/**
* @return the programmer
*/
public AvrdudeProgrammer getProgrammer() {
return programmer;
}
/**
* @param programmer
* the programmer to set
*/
public void setProgrammer(AvrdudeProgrammer programmer) {
this.programmer = programmer;
}
/**
* @return the controller
*/
public AVR getController() {
return controller;
}
/**
* @param controller
* the controller to set
*/
public void setController(AVR controller) {
this.controller = controller;
}
public void setFirmware(Firmware firmware) {
this.firmware = firmware;
}
public void setHexFile(File file, boolean clearContent) {
firmwarePanel.setHexFile(file, clearContent);
switch2ProgrammingTab();
}
public void switch2ProgrammingTab() {
tabbedPane.setSelectedIndex(tabbedPane.indexOfTab(_("programmingPanel.title")));
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(ControllerPanel.CONTROLLER_CHANGED)) {
firmwarePanel.firePropertyChange(ControllerPanel.CONTROLLER_CHANGED, 0, 1);
eepromResetPanel.firePropertyChange(ControllerPanel.CONTROLLER_CHANGED, 0, 1);
}
if (evt.getPropertyName().equals(MODE_CHANGED)) {
firmwarePanel.firePropertyChange(ControllerPanel.CONTROLLER_CHANGED, 0, 1);
if (isOfflineMode()) {
mode = _("offline");
} else {
mode = _("online");
}
this.mainframe.setTitle(_("title") + " " + VERSION + " - " + mode);
}
if (evt.getPropertyName().equals(ProgrammerPanel.PROGRAMMER_CHANGED)) {
//TODO Make controller dependent from Programmer.
}
checkTabVisibility();
}
public static String getTempFolder() {
String tmpdir;
if (System.getProperty("os.name").toLowerCase().contains("windows")) {
tmpdir = System.getProperty("user.dir")+"\\tmp\\";
} else if (System.getProperty("os.name").toLowerCase().contains("mac")) {
tmpdir = System.getProperty("user.home")+"/Library/Preferences/kkMulticopterFlashTool/";
} else {
tmpdir = System.getProperty("user.dir")+"/tmp/";
}
KKMulticopterFlashTool.getLogger().log(Level.INFO, tmpdir);
return tmpdir;
}
public static boolean isOfflineMode() {
try {
return kk.offlineMode;
} catch (Exception e) {
return false;
}
}
public static void setOfflineMode(boolean b) {
kk.offlineMode = b;
}
public Vector<Firmware> getFirmwares() {
return firmwareReader.getFirmwares();
}
public boolean isForceFlashing() {
return forceFlashing;
}
public void setForceFlashing(boolean forceFlashing) {
this.forceFlashing = forceFlashing;
}
public static Logger getLogger() {
try {
return kk.logger;
} catch (Exception e) {
return Logger.getLogger("Default-Logger");
}
}
public static Vector<AVR> getControllers() {
return avrs;
}
public void setSelectedTabIndex(int i) {
tabbedPane.setSelectedIndex(i);
}
public static KKMulticopterFlashTool getInstance() {
return kk;
}
public static void setPopupEnabled(boolean enablePopups) {
isPopupsEnabled = enablePopups;
}
public static boolean isPopupsEnabled() {
return isPopupsEnabled;
}
public static void setHideDeprecatedEnabled(boolean hideDeprecated) {
isHideDeprecated = hideDeprecated;
}
public static boolean isHideDecprecatedEnabled() {
return isHideDeprecated;
}
public static void setVerboseEnabled(boolean verbose) {
isVerbose = verbose;
}
public static boolean isVerboseEnabled() {
return isVerbose;
}
public static void setShowDailyTGYEnabled(boolean showDailyTGYEnabled) {
isShowDailyTGYEnabled = showDailyTGYEnabled;
}
public static boolean isShowDailyTGYEnabled() {
return isShowDailyTGYEnabled;
}
public static int getCountdown() {
System.out.println("Countdown is " + countdown);
return countdown;
}
public static void setCountdown(int value) {
countdown = value;
}
public void addButtonsStateListener(ButtonsStateListener myListener) {
listeners.add(myListener);
}
private void updateButtons() {
for (ButtonsStateListener listener : listeners) {
listener.updateButtons();
}
}
public void flashArduino(ArduinoUpload arduinoUpload, Firmware arduinoFirmware, String arduinoPort) {
programmerPanel.setProgrammer(arduinoUpload.getAvrProgrammer().getId());
programmerPanel.setPort(arduinoPort);
programmerPanel.setRate(arduinoUpload.getSpeed()+"");
programmerPanel.setDefaultRate(false);
setController(arduinoUpload.getAVR());
setFirmware(arduinoFirmware);
flashAVR();
firePropertyChange(ControllerPanel.CONTROLLER_CHANGED, false, false);
}
}