1
0
mirror of https://github.com/arduino/Arduino.git synced 2025-02-18 12:54:25 +01:00

Merge remote-tracking branch 'ffissore/boards-cputype' into ide-1.5.x

This commit is contained in:
Cristian Maglie 2012-11-04 00:31:41 +01:00
commit a64d58fbdb
9 changed files with 555 additions and 473 deletions

View File

@ -34,9 +34,11 @@ import javax.swing.filechooser.FileNameExtensionFilter;
import processing.app.debug.TargetPackage;
import processing.app.debug.TargetPlatform;
import processing.app.helpers.FileUtils;
import processing.app.helpers.Maps;
import processing.app.helpers.PreferencesMap;
import processing.app.helpers.filefilters.OnlyDirs;
import processing.app.helpers.filefilters.OnlyFilesWithExtension;
import processing.app.tools.MapWithSubkeys;
import processing.app.tools.ZipDeflater;
import processing.core.*;
import static processing.app.I18n._;
@ -1121,18 +1123,19 @@ public class Base {
editor.onBoardOrPortChange();
}
public void rebuildBoardsMenu(JMenu boardsMenu, final JMenu cpuTypeMenu, final Editor editor) {
public void rebuildBoardsMenu(JMenu toolsMenu, final Editor editor) {
JMenu boardsMenu = makeOrGetBoardMenu(toolsMenu, "Board");
String selPackage = Preferences.get("target_package");
String selPlatform = Preferences.get("target_platform");
String selBoard = Preferences.get("board");
String selBoardContainer = Preferences.get("board_container");
boardsMenu.removeAll();
boolean first = true;
List<JMenuItem> menuItemsToClickAfterStartup = new LinkedList<JMenuItem>();
ButtonGroup boardsButtonGroup = new ButtonGroup();
ButtonGroup cpuTypesButtonGroup = new ButtonGroup();
Map<String, ButtonGroup> buttonGroupsMap = new HashMap<String, ButtonGroup>();
// Cycle through all packages
for (TargetPackage targetPackage : packages.values()) {
@ -1142,115 +1145,160 @@ public class Base {
for (TargetPlatform targetPlatform : targetPackage.platforms()) {
String platformName = targetPlatform.getName();
Map<String, PreferencesMap> boards = targetPlatform.getBoards();
if (targetPlatform.getPreferences().get("name") == null || targetPlatform.getBoards().isEmpty()) {
continue;
}
// Add a title for each group of boards
if (!first)
if (!first) {
boardsMenu.add(new JSeparator());
first = false;
}
first = false;
JMenuItem separator = new JMenuItem(targetPlatform.getPreferences().get("name"));
separator.setEnabled(false);
boardsMenu.add(separator);
// For every platform cycle through all boards
for (String boardID : targetPlatform.getOrderedBoards()) {
for (final String boardID : targetPlatform.getBoards().keySet()) {
PreferencesMap boardAttributes = boards.get(boardID);
final String boardContainer = boardAttributes.get("container");
AbstractAction filterCPUTypeMenuAction = new AbstractAction() {
AbstractAction action = new AbstractAction(boardAttributes.get("name")) {
@Override
public void actionPerformed(ActionEvent e) {
Preferences.set("board_container", (String) getValue("board_container"));
cpuTypeMenu.setEnabled(true);
for (int i = 0; i < cpuTypeMenu.getItemCount(); i++) {
JMenuItem cpuTypeMenuItem = cpuTypeMenu.getItem(i);
boolean visible = boardContainer.equals(cpuTypeMenuItem.getAction().getValue("board_container"));
cpuTypeMenuItem.setVisible(visible);
}
JMenuItem selectSelectedOrFirstVisibleMenuItem = selectVisibleSelectedOrFirstMenuItem(cpuTypeMenu);
selectSelectedOrFirstVisibleMenuItem.doClick();
}
};
filterCPUTypeMenuAction.putValue("board_container", boardContainer);
@SuppressWarnings("serial")
final AbstractAction selectBoardAction = new AbstractAction(boardAttributes.get("cpu")) {
public void actionPerformed(ActionEvent actionevent) {
Preferences.set("target_package", (String) getValue("package"));
Preferences.set("target_platform", (String) getValue("platform"));
Preferences.set("board", (String) getValue("board"));
filterVisibilityOfSubsequentBoardMenus((String) getValue("board"), 1, e);
onBoardOrPortChange();
Sketch.buildSettingChanged();
rebuildImportMenu(Editor.importMenu, editor);
rebuildExamplesMenu(Editor.examplesMenu);
}
};
selectBoardAction.putValue("package", packageName);
selectBoardAction.putValue("platform", platformName);
selectBoardAction.putValue("board", boardID);
selectBoardAction.putValue("board_container", boardContainer);
if (boardContainer != null) {
findOrCreateBoardContainerMenu(boardsMenu, boardsButtonGroup, boardContainer, filterCPUTypeMenuAction);
JMenuItem item = new JRadioButtonMenuItem(selectBoardAction);
cpuTypesButtonGroup.add(item);
cpuTypeMenu.add(item);
} else {
AbstractAction selectBoardWithoutContainerAction = new AbstractAction(boardAttributes.get("name")) {
@Override
public void actionPerformed(ActionEvent e) {
cpuTypeMenu.setEnabled(false);
Preferences.unset("board_container");
selectBoardAction.actionPerformed(e);
};
action.putValue("properties", boardAttributes);
action.putValue("board", boardID);
action.putValue("package", packageName);
action.putValue("platform", platformName);
JRadioButtonMenuItem item = new JRadioButtonMenuItem(action);
boardsMenu.add(item);
boardsButtonGroup.add(item);
if (selBoard.equals(action.getValue("board")) && selPackage.equals(action.getValue("package"))
&& selPlatform.equals(action.getValue("platform"))) {
menuItemsToClickAfterStartup.add(item);
}
if (targetPlatform.getCustomMenus() != null) {
List<String> customMenuIDs = new LinkedList<String>(targetPlatform.getCustomMenus().getKeys());
for (int i = 0; i < customMenuIDs.size(); i++) {
final String customMenuID = customMenuIDs.get(i);
JMenu menu = makeOrGetBoardMenu(toolsMenu, _(targetPlatform.getCustomMenus().getValueOf(customMenuID)));
MapWithSubkeys customMenu = targetPlatform.getCustomMenus().get(customMenuID);
if (customMenu.getKeys().contains(boardID)) {
MapWithSubkeys boardCustomMenu = customMenu.get(boardID);
final int currentIndex = i + 1 + 1; //plus 1 to skip the first board menu, plus 1 to keep the custom menu next to this one
for (final String customMenuOption : boardCustomMenu.getKeys()) {
action = new AbstractAction(_(boardCustomMenu.getValueOf(customMenuOption))) {
@Override
public void actionPerformed(ActionEvent e) {
Preferences.set("target_package", (String) getValue("package"));
Preferences.set("target_platform", (String) getValue("platform"));
Preferences.set("board", (String) getValue("board"));
Preferences.set("custom_" + customMenuID, boardID + "_" + (String) getValue("custom_menu_option"));
filterVisibilityOfSubsequentBoardMenus((String) getValue("board"), currentIndex, e);
onBoardOrPortChange();
Sketch.buildSettingChanged();
rebuildImportMenu(Editor.importMenu, editor);
rebuildExamplesMenu(Editor.examplesMenu);
}
};
action.putValue("properties", boardCustomMenu.getValues());
action.putValue("board", boardID);
action.putValue("custom_menu_option", customMenuOption);
action.putValue("package", packageName);
action.putValue("platform", platformName);
if (!buttonGroupsMap.containsKey(customMenuID)) {
buttonGroupsMap.put(customMenuID, new ButtonGroup());
}
item = new JRadioButtonMenuItem(action);
menu.add(item);
buttonGroupsMap.get(customMenuID).add(item);
String selectedCustomMenuEntry = Preferences.get("custom_" + customMenuID);
if (selBoard.equals(boardID) && (boardID + "_" + customMenuOption).equals(selectedCustomMenuEntry)) {
menuItemsToClickAfterStartup.add(item);
}
}
}
@Override
public Object getValue(String key) {
return selectBoardAction.getValue(key);
}
@Override
public void putValue(String key, Object newValue) {
selectBoardAction.putValue(key, newValue);
}
};
JMenuItem item = new JRadioButtonMenuItem(selectBoardWithoutContainerAction);
boardsButtonGroup.add(item);
boardsMenu.add(item);
}
}
}
}
}
JMenuItem selectedBoardMenu = selectMenuItemByBoardContainer(boardsMenu, selBoardContainer);
if (selectedBoardMenu == null) {
selectedBoardMenu = selectMenuItemByBoardPackagePlatform(boardsMenu, selBoard, selPackage, selPlatform);
if (selectedBoardMenu == null) {
selectedBoardMenu = selectFirstEnabledMenuItem(boardsMenu);
if (menuItemsToClickAfterStartup.isEmpty()) {
menuItemsToClickAfterStartup.add(selectFirstEnabledMenuItem(boardsMenu));
}
for (JMenuItem menuItemToClick : menuItemsToClickAfterStartup) {
menuItemToClick.setSelected(true);
menuItemToClick.getAction().actionPerformed(new ActionEvent(this, -1, ""));
}
}
selectedBoardMenu.doClick();
}
if (cpuTypeMenu.isEnabled()) {
JMenuItem selectedCPUTypeMenu;
if (selBoard == null) {
selectedCPUTypeMenu = selectFirstEnabledMenuItem(cpuTypeMenu);
} else {
selectedCPUTypeMenu = selectMenuItemByBoardPackagePlatform(cpuTypeMenu, selBoard, selPackage, selPlatform);
if (selectedCPUTypeMenu == null) {
selectedCPUTypeMenu = selectFirstEnabledMenuItem(cpuTypeMenu);
private static void filterVisibilityOfSubsequentBoardMenus(String boardID, int fromIndex, ActionEvent originatingEvent) {
for (int i = fromIndex; i < Editor.boardsMenus.size(); i++) {
JMenu menu = Editor.boardsMenus.get(i);
for (int m = 0; m < menu.getItemCount(); m++) {
JMenuItem menuItem = menu.getItem(m);
menuItem.setVisible(menuItem.getAction().getValue("board").equals(boardID));
}
menu.setEnabled(ifThereAreVisibleItemsOn(menu));
if (menu.isEnabled()) {
JMenuItem visibleSelectedOrFirstMenuItem = selectVisibleSelectedOrFirstMenuItem(menu);
if (!visibleSelectedOrFirstMenuItem.isSelected()) {
visibleSelectedOrFirstMenuItem.setSelected(true);
visibleSelectedOrFirstMenuItem.getAction().actionPerformed(originatingEvent);
}
}
selectedCPUTypeMenu.doClick();
}
}
private static boolean ifThereAreVisibleItemsOn(JMenu menu) {
for (int i = 0; i < menu.getItemCount(); i++) {
if (menu.getItem(i).isVisible()) {
return true;
}
}
return false;
}
private JMenu makeOrGetBoardMenu(JMenu toolsMenu, String label) {
String i18nLabel = _(label);
for (JMenu menu : Editor.boardsMenus) {
if (i18nLabel.equals(menu.getText())) {
return menu;
}
}
JMenu menu = new JMenu(i18nLabel);
Editor.boardsMenus.add(menu);
toolsMenu.add(menu);
return menu;
}
private static JMenuItem selectVisibleSelectedOrFirstMenuItem(JMenu menu) {
JMenuItem firstVisible = null;
@ -1283,45 +1331,6 @@ public class Base {
throw new IllegalStateException("Menu has no enabled items");
}
private static JMenuItem selectMenuItemByBoardContainer(JMenu menu, String boardContainer) {
if (boardContainer == null) {
return null;
}
for (int i = 0; i < menu.getItemCount(); i++) {
JMenuItem item = menu.getItem(i);
if (item != null && item.getAction() != null && boardContainer.equals(item.getAction().getValue("board_container"))) {
return item;
}
}
return null;
}
private static JMenuItem selectMenuItemByBoardPackagePlatform(JMenu menu, String selBoard, String selPackage, String selPlatform) {
for (int i = 0; i < menu.getItemCount(); i++) {
JMenuItem item = menu.getItem(i);
if (item != null && item.getAction() != null && selBoard.equals(item.getAction().getValue("board"))
&& selPackage.equals(item.getAction().getValue("package")) && selPlatform.equals(item.getAction().getValue("platform"))) {
return item;
}
}
return null;
}
private JMenuItem findOrCreateBoardContainerMenu(JMenu boardsMenu, ButtonGroup boardsButtonGroup, String boardContainerName, AbstractAction boardMenuAction) {
for (int i = 0; i < boardsMenu.getItemCount(); i++ ) {
JMenuItem boardContainer = boardsMenu.getItem(i);
if (boardContainer != null && boardContainerName.equals(boardContainer.getText())) {
return boardContainer;
}
}
JMenuItem item = new JRadioButtonMenuItem(boardMenuAction);
item.setText(boardContainerName);
boardsButtonGroup.add(item);
boardsMenu.add(item);
return item;
}
public void rebuildProgrammerMenu(JMenu menu) {
menu.removeAll();
ButtonGroup group = new ButtonGroup();
@ -1809,10 +1818,22 @@ public class Base {
return getTargetPlatform(pack, Preferences.get("target_platform"));
}
static public PreferencesMap getBoardPreferences() {
static public Map<String, String> getBoardPreferences() {
TargetPlatform target = getTargetPlatform();
String board = Preferences.get("board");
return target.getBoards().get(board);
Map<String, String> boardPreferences = Maps.merge(target.getBoards().get(board), new LinkedHashMap<String, String>());
if (target.getCustomMenus() != null) {
for (String customMenuID : target.getCustomMenus().getKeys()) {
MapWithSubkeys boardCustomMenu = target.getCustomMenus().get(customMenuID).get(board);
String selectedCustomMenuEntry = Preferences.get("custom_" + customMenuID);
if (boardCustomMenu != null && selectedCustomMenuEntry != null && selectedCustomMenuEntry.startsWith(board)) {
String menuEntryId = selectedCustomMenuEntry.substring(selectedCustomMenuEntry.indexOf("_") + 1);
Maps.merge(boardCustomMenu.get(menuEntryId).getValues(), boardPreferences);
boardPreferences.put("name", boardPreferences.get("name") + ", " + boardCustomMenu.getValueOf(menuEntryId));
}
}
}
return boardPreferences;
}
static public File getSketchbookFolder() {

View File

@ -35,6 +35,7 @@ import java.awt.print.*;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.List;
import java.util.zip.*;
import javax.swing.*;
@ -95,9 +96,8 @@ public class Editor extends JFrame implements RunnerListener {
// these menus are shared so that the board and serial port selections
// are the same for all windows (since the board and serial port that are
// actually used are determined by the preferences, which are shared)
static JMenu boardsMenu;
static List<JMenu> boardsMenus;
static JMenu serialMenu;
static JMenu cpuTypeMenu;
static SerialMenuListener serialMenuListener;
static SerialMonitor serialMonitor;
@ -178,10 +178,13 @@ public class Editor extends JFrame implements RunnerListener {
// re-add the sub-menus that are shared by all windows
fileMenu.insert(sketchbookMenu, 2);
fileMenu.insert(examplesMenu, 3);
//sketchMenu.insert(importMenu, 4);
toolsMenu.insert(boardsMenu, numTools);
toolsMenu.insert(cpuTypeMenu, numTools + 1);
toolsMenu.insert(serialMenu, numTools + 2);
sketchMenu.insert(importMenu, 4);
int offset = 0;
for (JMenu menu : boardsMenus) {
toolsMenu.insert(menu, numTools + offset);
offset++;
}
toolsMenu.insert(serialMenu, numTools + offset);
}
// added for 1.0.5
@ -190,9 +193,10 @@ public class Editor extends JFrame implements RunnerListener {
// System.err.println("deactivate"); // not coming through
fileMenu.remove(sketchbookMenu);
fileMenu.remove(examplesMenu);
//sketchMenu.remove(importMenu);
toolsMenu.remove(boardsMenu);
toolsMenu.remove(cpuTypeMenu);
sketchMenu.remove(importMenu);
for (JMenu menu : boardsMenus) {
toolsMenu.remove(menu);
}
toolsMenu.remove(serialMenu);
}
});
@ -681,16 +685,13 @@ public class Editor extends JFrame implements RunnerListener {
// XXX: DAM: these should probably be implemented using the Tools plugin
// API, if possible (i.e. if it supports custom actions, etc.)
if (boardsMenu == null) {
boardsMenu = new JMenu(_("Board"));
cpuTypeMenu = new JMenu(_("Processor"));
base.rebuildBoardsMenu(boardsMenu, cpuTypeMenu, this);
if (boardsMenus == null) {
boardsMenus = new LinkedList<JMenu>();
base.rebuildBoardsMenu(toolsMenu, this);
//Debug: rebuild imports
importMenu.removeAll();
base.rebuildImportMenu(importMenu, this);
}
menu.add(boardsMenu);
menu.add(cpuTypeMenu);
if (serialMenuListener == null)
serialMenuListener = new SerialMenuListener();
@ -2660,7 +2661,7 @@ public class Editor extends JFrame implements RunnerListener {
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
protected void onBoardOrPortChange() {
Map<String, String> boardPreferences = Base.getBoardPreferences();
Map<String, String> boardPreferences = Base.getBoardPreferences();
lineStatus.setBoardName(boardPreferences.get("name"));
lineStatus.setSerialPort(Preferences.get("serial.port"));
lineStatus.repaint();

View File

@ -24,28 +24,25 @@
package processing.app.debug;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import processing.app.helpers.PreferencesMap;
import processing.core.PApplet;
import processing.app.tools.MapWithSubkeys;
public class TargetPlatform {
private String name;
private File folder;
private Map<String, PreferencesMap> boards;
private List<String> boardsOrder;
private Map<String, PreferencesMap> programmers;
private PreferencesMap preferences;
private MapWithSubkeys customMenus;
public TargetPlatform(String _name, File _folder) {
System.out.println("TargetPlatform: constructor start, name: " + _name);
name = _name;
folder = _folder;
boards = new HashMap<String, PreferencesMap>();
boardsOrder = new ArrayList<String>();
programmers = new HashMap<String, PreferencesMap>();
preferences = new PreferencesMap();
@ -55,9 +52,11 @@ public class TargetPlatform {
PreferencesMap boardPreferences = new PreferencesMap();
boardPreferences.load(boardsFile);
boards = boardPreferences.createFirstLevelMap();
boardsOrder = readBoardsOrder(boardsFile);
customMenus = MapWithSubkeys.createFrom(boards.get("menu"));
boards.remove("menu");
}
} catch (Exception e) {
e.printStackTrace();
System.err.println("Error loading boards from boards.txt: " + e);
}
@ -82,32 +81,6 @@ public class TargetPlatform {
}
}
/**
* Loads the ordered list of boards as they appears on the boards.txt file
*
* @param boardsFile
* @return
*/
private List<String> readBoardsOrder(File boardsFile) {
String[] strings = PApplet.loadStrings(boardsFile);
List<String> res = new ArrayList<String>();
String latestBoard = "-";
for (String s : strings) {
int dot = s.indexOf('.');
if (dot == -1)
continue;
String board = s.substring(0, dot);
if (board.equals(latestBoard))
continue;
if (!boards.containsKey(board))
continue;
latestBoard = board;
res.add(board);
}
return res;
}
public String getName() {
return name;
}
@ -119,9 +92,9 @@ public class TargetPlatform {
public Map<String, PreferencesMap> getBoards() {
return boards;
}
public List<String> getOrderedBoards() {
return boardsOrder;
public MapWithSubkeys getCustomMenus() {
return customMenus;
}
public Map<String, PreferencesMap> getProgrammers() {

View File

@ -0,0 +1,15 @@
package processing.app.helpers;
import java.util.Map;
import java.util.Map.Entry;
public class Maps {
public static <K, V> Map<K, V> merge(Map<K, V> input, Map<K, V> target) {
for (Entry<K, V> entry : input.entrySet()) {
target.put(entry.getKey(), entry.getValue());
}
return target;
}
}

View File

@ -28,25 +28,17 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
import java.util.*;
import processing.app.Base;
import processing.core.PApplet;
public class PreferencesMap extends HashMap<String, String> {
public class PreferencesMap extends LinkedHashMap<String, String> {
public PreferencesMap(Hashtable<String, String> table) {
public PreferencesMap(Map<String, String> table) {
super(table);
}
public PreferencesMap(PreferencesMap prefs) {
super(prefs);
}
public PreferencesMap() {
super();
}
@ -86,18 +78,18 @@ public class PreferencesMap extends HashMap<String, String> {
Set<String> keys = new HashSet<String>(keySet());
// Override keys that have OS specific versions
for (String k : keys) {
for (String key : keys) {
boolean replace = false;
if (Base.isLinux() && k.endsWith(".linux"))
if (Base.isLinux() && key.endsWith(".linux"))
replace = true;
if (Base.isWindows() && k.endsWith(".windows"))
if (Base.isWindows() && key.endsWith(".windows"))
replace = true;
if (Base.isMacOS() && k.endsWith(".macos"))
if (Base.isMacOS() && key.endsWith(".macos"))
replace = true;
if (replace) {
int dot = k.lastIndexOf('.');
String overridenKey = k.substring(0, dot);
put(overridenKey, get(k));
int dot = key.lastIndexOf('.');
String overridenKey = key.substring(0, dot);
put(overridenKey, get(key));
}
}
}
@ -129,7 +121,7 @@ public class PreferencesMap extends HashMap<String, String> {
* @return
*/
public Map<String, PreferencesMap> createFirstLevelMap() {
Map<String, PreferencesMap> res = new HashMap<String, PreferencesMap>();
Map<String, PreferencesMap> res = new LinkedHashMap<String, PreferencesMap>();
for (String key : keySet()) {
int dot = key.indexOf('.');
if (dot == -1)

View File

@ -0,0 +1,66 @@
package processing.app.tools;
import java.util.*;
import java.util.Map.Entry;
public class MapWithSubkeys {
public static MapWithSubkeys createFrom(Map<String, String> input) {
if (input == null) {
return null;
}
MapWithSubkeys target = new MapWithSubkeys();
for (Entry<String, String> entry : input.entrySet()) {
String[] entryParts = entry.getKey().split("\\.");
if (entryParts.length == 1) {
target.put(entryParts[0], entry.getValue());
} else if (entryParts.length == 3) {
target.get(entryParts[0]).get(entryParts[1]).put(entryParts[2], entry.getValue());
} else if (entryParts.length > 3) {
StringBuilder sb = new StringBuilder();
for (int i = 3; i < entryParts.length; i++) {
sb.append(entryParts[i]).append(".");
}
sb.deleteCharAt(sb.length() - 1);
String key = sb.toString();
target.get(entryParts[0]).get(entryParts[1]).get(entryParts[2]).put(key, entry.getValue());
}
}
return target;
}
private final Map<String, String> values;
private final Map<String, MapWithSubkeys> maps;
public MapWithSubkeys() {
this.values = new LinkedHashMap<String, String>();
this.maps = new LinkedHashMap<String, MapWithSubkeys>();
}
public Collection<String> getKeys() {
return values.keySet();
}
public Map<String, String> getValues() {
return values;
}
public String getValueOf(String key) {
return values.get(key);
}
public MapWithSubkeys get(String key) {
if (!maps.containsKey(key)) {
maps.put(key, new MapWithSubkeys());
}
if (!values.containsKey(key)) {
put(key, null);
}
return maps.get(key);
}
public void put(String key, String value) {
values.put(key, value);
}
}

View File

@ -0,0 +1,59 @@
package processing.app.tools;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
public class MapWithSubkeysTest {
private MapWithSubkeys map;
@Before
public void setup() throws Exception {
Map<String, String> input = new HashMap<String, String>();
BufferedReader reader = new BufferedReader(new InputStreamReader(MapWithSubkeysTest.class.getResourceAsStream("test_partial_boards.txt")));
String line = null;
while ((line = reader.readLine()) != null) {
String[] lineParts = line.split("=");
input.put(lineParts[0], lineParts[1]);
}
map = MapWithSubkeys.createFrom(input);
}
@Test
public void shouldListCustomMenusIDs() {
Collection<String> menusIDs = map.getKeys();
assertEquals(2, menusIDs.size());
assertTrue(menusIDs.contains("cpu"));
assertTrue(menusIDs.contains("speed"));
assertEquals("Processor", map.getValueOf("cpu"));
MapWithSubkeys cpu = map.get("cpu");
Collection<String> boards = cpu.getKeys();
assertEquals(1, boards.size());
assertTrue(boards.contains("nano"));
Collection<String> cpuNanoProcessors = cpu.get("nano").getKeys();
assertEquals(2, cpuNanoProcessors.size());
assertTrue(cpuNanoProcessors.contains("atmega168"));
assertTrue(cpuNanoProcessors.contains("atmega328"));
assertEquals("ATmega168", cpu.get("nano").getValueOf("atmega168"));
assertEquals("ATmega328", cpu.get("nano").getValueOf("atmega328"));
MapWithSubkeys atmega168Properties = cpu.get("nano").get("atmega168");
assertEquals(9, atmega168Properties.getKeys().size());
assertTrue(atmega168Properties.getKeys().contains("bootloader.high_fuses"));
}
}

View File

@ -0,0 +1,26 @@
cpu=Processor
cpu.nano.atmega328=ATmega328
cpu.nano.atmega328.upload.maximum_size=30720
cpu.nano.atmega328.upload.speed=57600
cpu.nano.atmega328.bootloader.low_fuses=0xFF
cpu.nano.atmega328.bootloader.high_fuses=0xDA
cpu.nano.atmega328.bootloader.extended_fuses=0x05
cpu.nano.atmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328.hex
cpu.nano.atmega328.bootloader.unlock_bits=0x3F
cpu.nano.atmega328.bootloader.lock_bits=0x0F
cpu.nano.atmega328.build.mcu=atmega328p
cpu.nano.atmega168=ATmega168
cpu.nano.atmega168.upload.maximum_size=14336
cpu.nano.atmega168.upload.speed=19200
cpu.nano.atmega168.bootloader.low_fuses=0xff
cpu.nano.atmega168.bootloader.high_fuses=0xdd
cpu.nano.atmega168.bootloader.extended_fuses=0x00
cpu.nano.atmega168.bootloader.file=atmega/ATmegaBOOT_168_diecimila.hex
cpu.nano.atmega168.bootloader.unlock_bits=0x3F
cpu.nano.atmega168.bootloader.lock_bits=0x0F
cpu.nano.atmega168.build.mcu=atmega168
speed=Speed
speed.nano.16=16 MHz
speed.nano.16.build.f_cpu=16000000L
speed.nano.8=8 MHz
speed.nano.8.build.f_cpu=8000000L

View File

@ -1,5 +1,7 @@
# See: http://code.google.com/p/arduino/wiki/Platforms
menu.cpu=Processor
##############################################################
uno.name=Arduino Uno
@ -23,101 +25,89 @@ uno.build.variant=standard
##############################################################
atmega328.name=Arduino Duemilanove w/ ATmega328
atmega328diecimila.name=Arduino Duemilanove or Diecimila
atmega328.upload.tool=avrdude
atmega328.upload.protocol=arduino
atmega328.upload.maximum_size=30720
atmega328.upload.speed=57600
atmega328diecimila.upload.tool=avrdude
atmega328diecimila.upload.protocol=arduino
atmega328.bootloader.tool=avrdude
atmega328.bootloader.low_fuses=0xFF
atmega328.bootloader.high_fuses=0xDA
atmega328.bootloader.extended_fuses=0x05
atmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328.hex
atmega328.bootloader.unlock_bits=0x3F
atmega328.bootloader.lock_bits=0x0F
atmega328diecimila.bootloader.tool=avrdude
atmega328diecimila.bootloader.low_fuses=0xFF
atmega328diecimila.bootloader.unlock_bits=0x3F
atmega328diecimila.bootloader.lock_bits=0x0F
atmega328.build.mcu=atmega328p
atmega328.build.f_cpu=16000000L
atmega328.build.core=arduino
atmega328.build.variant=standard
atmega328diecimila.build.f_cpu=16000000L
atmega328diecimila.build.core=arduino
atmega328diecimila.build.variant=standard
## Arduino Duemilanove or Diecimila w/ ATmega328
menu.cpu.atmega328diecimila.atmega328=ATmega328
menu.cpu.atmega328diecimila.atmega328.upload.maximum_size=30720
menu.cpu.atmega328diecimila.atmega328.upload.speed=57600
menu.cpu.atmega328diecimila.atmega328.bootloader.high_fuses=0xDA
menu.cpu.atmega328diecimila.atmega328.bootloader.extended_fuses=0x05
menu.cpu.atmega328diecimila.atmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328.hex
menu.cpu.atmega328diecimila.atmega328.build.mcu=atmega328p
## Arduino Duemilanove or Diecimila w/ ATmega168
menu.cpu.atmega328diecimila.atmega168=ATmega168
menu.cpu.atmega328diecimila.atmega168.upload.maximum_size=14336
menu.cpu.atmega328diecimila.atmega168.upload.speed=19200
menu.cpu.atmega328diecimila.atmega168.bootloader.high_fuses=0xdd
menu.cpu.atmega328diecimila.atmega168.bootloader.extended_fuses=0x00
menu.cpu.atmega328diecimila.atmega168.bootloader.file=atmega/ATmegaBOOT_168_diecimila.hex
menu.cpu.atmega328diecimila.atmega168.build.mcu=atmega168
##############################################################
diecimila.name=Arduino Diecimila or Duemilanove w/ ATmega168
diecimila.upload.tool=avrdude
diecimila.upload.protocol=arduino
diecimila.upload.maximum_size=14336
diecimila.upload.speed=19200
diecimila.bootloader.tool=avrdude
diecimila.bootloader.low_fuses=0xff
diecimila.bootloader.high_fuses=0xdd
diecimila.bootloader.extended_fuses=0x00
diecimila.bootloader.file=atmega/ATmegaBOOT_168_diecimila.hex
diecimila.bootloader.unlock_bits=0x3F
diecimila.bootloader.lock_bits=0x0F
diecimila.build.mcu=atmega168
diecimila.build.f_cpu=16000000L
diecimila.build.core=arduino
diecimila.build.variant=standard
##############################################################
nano328.name=Arduino Nano w/ ATmega328
nano328.cpu=ATmega328
nano328.container=Arduino Nano
nano328.upload.tool=avrdude
nano328.upload.protocol=arduino
nano328.upload.maximum_size=30720
nano328.upload.speed=57600
nano328.bootloader.tool=avrdude
nano328.bootloader.low_fuses=0xFF
nano328.bootloader.high_fuses=0xDA
nano328.bootloader.extended_fuses=0x05
nano328.bootloader.file=atmega/ATmegaBOOT_168_atmega328.hex
nano328.bootloader.unlock_bits=0x3F
nano328.bootloader.lock_bits=0x0F
nano328.build.mcu=atmega328p
nano328.build.f_cpu=16000000L
nano328.build.core=arduino
nano328.build.variant=eightanaloginputs
##############################################################
nano.name=Arduino Nano w/ ATmega168
nano.cpu=ATmega168
nano.container=Arduino Nano
nano.name=Arduino Nano
nano.upload.tool=avrdude
nano.upload.protocol=arduino
nano.upload.maximum_size=14336
nano.upload.speed=19200
nano.bootloader.tool=avrdude
nano.bootloader.low_fuses=0xff
nano.bootloader.high_fuses=0xdd
nano.bootloader.extended_fuses=0x00
nano.bootloader.file=atmega/ATmegaBOOT_168_diecimila.hex
nano.bootloader.unlock_bits=0x3F
nano.bootloader.lock_bits=0x0F
nano.build.mcu=atmega168
nano.build.f_cpu=16000000L
nano.build.core=arduino
nano.build.variant=eightanaloginputs
## Arduino Nano w/ ATmega328
menu.cpu.nano.atmega328=ATmega328
menu.cpu.nano.atmega328.upload.maximum_size=30720
menu.cpu.nano.atmega328.upload.speed=57600
menu.cpu.nano.atmega328.bootloader.low_fuses=0xFF
menu.cpu.nano.atmega328.bootloader.high_fuses=0xDA
menu.cpu.nano.atmega328.bootloader.extended_fuses=0x05
menu.cpu.nano.atmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328.hex
menu.cpu.nano.atmega328.build.mcu=atmega328p
## Arduino Nano w/ ATmega168
menu.cpu.nano.atmega168=ATmega168
menu.cpu.nano.atmega168.upload.maximum_size=14336
menu.cpu.nano.atmega168.upload.speed=19200
menu.cpu.nano.atmega168.bootloader.low_fuses=0xff
menu.cpu.nano.atmega168.bootloader.high_fuses=0xdd
menu.cpu.nano.atmega168.bootloader.extended_fuses=0x00
menu.cpu.nano.atmega168.bootloader.file=atmega/ATmegaBOOT_168_diecimila.hex
menu.cpu.nano.atmega168.build.mcu=atmega168
##############################################################
mega2560.name=Arduino Mega 2560 or Mega ADK
mega2560.cpu=2560 or ADK
mega2560.container=Arduino Mega
mega2560.upload.tool=avrdude
mega2560.upload.protocol=wiring
@ -141,7 +131,6 @@ mega2560.build.variant=mega
mega.name=Arduino Mega (ATmega1280)
mega.cpu=ATmega1280
mega.container=Arduino Mega
mega.upload.tool=avrdude
mega.upload.protocol=arduino
@ -190,52 +179,44 @@ leonardo.build.extra_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid}
##############################################################
mini328.name=Arduino Mini w/ ATmega328
mini328.cpu=ATmega328
mini328.container=Arduino Mini
mini328.upload.tool=avrdude
mini328.upload.protocol=arduino
mini328.upload.maximum_size=28672
mini328.upload.speed=115200
mini328.bootloader.tool=avrdude
mini328.bootloader.low_fuses=0xff
mini328.bootloader.high_fuses=0xd8
mini328.bootloader.extended_fuses=0x05
mini328.bootloader.file=optiboot/optiboot_atmega328-Mini.hex
mini328.bootloader.unlock_bits=0x3F
mini328.bootloader.lock_bits=0x0F
mini328.build.mcu=atmega328p
mini328.build.f_cpu=16000000L
mini328.build.core=arduino
mini328.build.variant=eightanaloginputs
##############################################################
mini.name=Arduino Mini w/ ATmega168
mini.cpu=ATmega168
mini.container=Arduino Mini
mini.name=Arduino Mini
mini.upload.tool=avrdude
mini.upload.protocol=arduino
mini.upload.maximum_size=14336
mini.upload.speed=19200
mini.bootloader.tool=avrdude
mini.bootloader.low_fuses=0xff
mini.bootloader.high_fuses=0xdd
mini.bootloader.extended_fuses=0x00
mini.bootloader.file=atmega/ATmegaBOOT_168_ng.hex
mini.bootloader.unlock_bits=0x3F
mini.bootloader.lock_bits=0x0F
mini.build.mcu=atmega168
mini.build.f_cpu=16000000L
mini.build.core=arduino
mini.build.variant=eightanaloginputs
## Arduino Mini w/ ATmega328
menu.cpu.mini.atmega328=ATmega328
menu.cpu.mini.atmega328.upload.maximum_size=28672
menu.cpu.mini.atmega328.upload.speed=115200
menu.cpu.mini.atmega328.bootloader.high_fuses=0xd8
menu.cpu.mini.atmega328.bootloader.extended_fuses=0x05
menu.cpu.mini.atmega328.bootloader.file=optiboot/optiboot_atmega328-Mini.hex
menu.cpu.mini.atmega328.build.mcu=atmega328p
## Arduino Mini w/ ATmega168
menu.cpu.mini.atmega168=ATmega168
menu.cpu.mini.atmega168.upload.maximum_size=14336
menu.cpu.mini.atmega168.upload.speed=19200
menu.cpu.mini.atmega168.bootloader.high_fuses=0xdd
menu.cpu.mini.atmega168.bootloader.extended_fuses=0x00
menu.cpu.mini.atmega168.bootloader.file=atmega/ATmegaBOOT_168_ng.hex
menu.cpu.mini.atmega168.build.mcu=atmega168
##############################################################
ethernet.name=Arduino Ethernet
@ -282,241 +263,189 @@ fio.build.variant=eightanaloginputs
##############################################################
bt328.name=Arduino BT w/ ATmega328
bt328.cpu=ATmega328
bt328.container=Arduino BT
bt328.upload.tool=avrdude
bt328.upload.protocol=arduino
bt328.upload.maximum_size=28672
bt328.upload.speed=19200
bt328.upload.disable_flushing=true
bt328.bootloader.tool=avrdude
bt328.bootloader.low_fuses=0xff
bt328.bootloader.high_fuses=0xd8
bt328.bootloader.extended_fuses=0x05
bt328.bootloader.file=bt/ATmegaBOOT_168_atmega328_bt.hex
bt328.bootloader.unlock_bits=0x3F
bt328.bootloader.lock_bits=0x0F
bt328.build.mcu=atmega328p
bt328.build.f_cpu=16000000L
bt328.build.core=arduino
bt328.build.variant=eightanaloginputs
##############################################################
bt.name=Arduino BT w/ ATmega168
bt.cpu=ATmega168
bt.container=Arduino BT
bt.name=Arduino BT
bt.upload.tool=avrdude
bt.upload.protocol=arduino
bt.upload.maximum_size=14336
bt.upload.speed=19200
bt.upload.disable_flushing=true
bt.bootloader.tool=avrdude
bt.bootloader.low_fuses=0xff
bt.bootloader.high_fuses=0xdd
bt.bootloader.extended_fuses=0x00
bt.bootloader.file=bt/ATmegaBOOT_168.hex
bt.bootloader.unlock_bits=0x3F
bt.bootloader.lock_bits=0x0F
bt.build.mcu=atmega168
bt.build.f_cpu=16000000L
bt.build.core=arduino
bt.build.variant=eightanaloginputs
##############################################################
## Arduino BT w/ ATmega328
menu.cpu.bt.atmega328=ATmega328
menu.cpu.bt.atmega328.upload.maximum_size=28672
lilypad328.name=LilyPad Arduino w/ ATmega328
lilypad328.cpu=ATmega328
lilypad328.container=LilyPad Arduino
menu.cpu.bt.atmega328.bootloader.high_fuses=0xd8
menu.cpu.bt.atmega328.bootloader.extended_fuses=0x05
menu.cpu.bt.atmega328.bootloader.file=bt/ATmegaBOOT_168_atmega328_bt.hex
lilypad328.upload.tool=avrdude
lilypad328.upload.protocol=arduino
lilypad328.upload.maximum_size=30720
lilypad328.upload.speed=57600
menu.cpu.bt.atmega328.build.mcu=atmega328p
lilypad328.bootloader.tool=avrdude
lilypad328.bootloader.low_fuses=0xFF
lilypad328.bootloader.high_fuses=0xDA
lilypad328.bootloader.extended_fuses=0x05
lilypad328.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex
lilypad328.bootloader.unlock_bits=0x3F
lilypad328.bootloader.lock_bits=0x0F
## Arduino BT w/ ATmega168
menu.cpu.bt.atmega168=ATmega168
menu.cpu.bt.atmega168.upload.maximum_size=14336
lilypad328.build.mcu=atmega328p
lilypad328.build.f_cpu=8000000L
lilypad328.build.core=arduino
lilypad328.build.variant=standard
menu.cpu.bt.atmega168.bootloader.high_fuses=0xdd
menu.cpu.bt.atmega168.bootloader.extended_fuses=0x00
menu.cpu.bt.atmega168.bootloader.file=bt/ATmegaBOOT_168.hex
menu.cpu.bt.atmega168.build.mcu=atmega168
##############################################################
lilypad.name=LilyPad Arduino w/ ATmega168
lilypad.cpu=ATmega168
lilypad.container=LilyPad Arduino
lilypad.name=LilyPad Arduino
lilypad.upload.tool=avrdude
lilypad.upload.protocol=arduino
lilypad.upload.maximum_size=14336
lilypad.upload.speed=19200
lilypad.bootloader.tool=avrdude
lilypad.bootloader.low_fuses=0xe2
lilypad.bootloader.high_fuses=0xdd
lilypad.bootloader.extended_fuses=0x00
lilypad.bootloader.file=lilypad/LilyPadBOOT_168.hex
lilypad.bootloader.unlock_bits=0x3F
lilypad.bootloader.lock_bits=0x0F
lilypad.build.mcu=atmega168
lilypad.build.f_cpu=8000000L
lilypad.build.core=arduino
lilypad.build.variant=standard
##############################################################
## LilyPad Arduino w/ ATmega328
menu.cpu.lilypad.atmega328=ATmega328
pro5v328.name=Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega328
pro5v328.cpu=ATmega328 (5V, 16 MHz)
pro5v328.container=Arduino Pro or Pro Mini
menu.cpu.lilypad.atmega328.upload.maximum_size=30720
menu.cpu.lilypad.atmega328.upload.speed=57600
pro5v328.upload.tool=avrdude
pro5v328.upload.protocol=arduino
pro5v328.upload.maximum_size=30720
pro5v328.upload.speed=57600
menu.cpu.lilypad.atmega328.bootloader.low_fuses=0xFF
menu.cpu.lilypad.atmega328.bootloader.high_fuses=0xDA
menu.cpu.lilypad.atmega328.bootloader.extended_fuses=0x05
menu.cpu.lilypad.atmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex
pro5v328.bootloader.tool=avrdude
pro5v328.bootloader.low_fuses=0xFF
pro5v328.bootloader.high_fuses=0xDA
pro5v328.bootloader.extended_fuses=0x05
pro5v328.bootloader.file=atmega/ATmegaBOOT_168_atmega328.hex
pro5v328.bootloader.unlock_bits=0x3F
pro5v328.bootloader.lock_bits=0x0F
menu.cpu.lilypad.atmega328.build.mcu=atmega328p
pro5v328.build.mcu=atmega328p
pro5v328.build.f_cpu=16000000L
pro5v328.build.core=arduino
pro5v328.build.variant=standard
## LilyPad Arduino w/ ATmega168
menu.cpu.lilypad.atmega168=ATmega168
menu.cpu.lilypad.atmega168.upload.maximum_size=14336
menu.cpu.lilypad.atmega168.upload.speed=19200
menu.cpu.lilypad.atmega168.bootloader.low_fuses=0xe2
menu.cpu.lilypad.atmega168.bootloader.high_fuses=0xdd
menu.cpu.lilypad.atmega168.bootloader.extended_fuses=0x00
menu.cpu.lilypad.atmega168.bootloader.file=lilypad/LilyPadBOOT_168.hex
menu.cpu.lilypad.atmega168.build.mcu=atmega168
##############################################################
pro5v.name=Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega168
pro5v.cpu=ATmega168 (5V, 16 MHz)
pro5v.container=Arduino Pro or Pro Mini
pro5v.upload.tool=avrdude
pro5v.upload.protocol=arduino
pro5v.upload.maximum_size=14336
pro5v.upload.speed=19200
pro5v.bootloader.tool=avrdude
pro5v.bootloader.low_fuses=0xff
pro5v.bootloader.high_fuses=0xdd
pro5v.bootloader.extended_fuses=0x00
pro5v.bootloader.file=atmega/ATmegaBOOT_168_diecimila.hex
pro5v.bootloader.unlock_bits=0x3F
pro5v.bootloader.lock_bits=0x0F
pro5v.build.mcu=atmega168
pro5v.build.f_cpu=16000000L
pro5v.build.core=arduino
pro5v.build.variant=standard
##############################################################
pro328.name=Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega328
pro328.cpu=ATmega328 (3.3V, 8 MHz)
pro328.container=Arduino Pro or Pro Mini
pro328.upload.tool=avrdude
pro328.upload.protocol=arduino
pro328.upload.maximum_size=30720
pro328.upload.speed=57600
pro328.bootloader.tool=avrdude
pro328.bootloader.low_fuses=0xFF
pro328.bootloader.high_fuses=0xDA
pro328.bootloader.extended_fuses=0x05
pro328.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex
pro328.bootloader.unlock_bits=0x3F
pro328.bootloader.lock_bits=0x0F
pro328.build.mcu=atmega328p
pro328.build.f_cpu=8000000L
pro328.build.core=arduino
pro328.build.variant=standard
##############################################################
pro.name=Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega168
pro.cpu=ATmega168 (3.3V, 8 MHz)
pro.container=Arduino Pro or Pro Mini
pro.name=Arduino Pro or Pro Mini
pro.upload.tool=avrdude
pro.upload.protocol=arduino
pro.upload.maximum_size=14336
pro.upload.speed=19200
pro.bootloader.tool=avrdude
pro.bootloader.low_fuses=0xc6
pro.bootloader.high_fuses=0xdd
pro.bootloader.extended_fuses=0x00
pro.bootloader.file=atmega/ATmegaBOOT_168_pro_8MHz.hex
pro.bootloader.unlock_bits=0x3F
pro.bootloader.lock_bits=0x0F
pro.build.mcu=atmega168
pro.build.f_cpu=8000000L
pro.build.core=arduino
pro.build.variant=standard
##############################################################
## Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega328
menu.cpu.pro.16MHzatmega328=ATmega328 (5V, 16 MHz)
atmega168.name=Arduino NG or older w/ ATmega168
atmega168.cpu=ATmega168
atmega168.container=Arduino NG or older
menu.cpu.pro.16MHzatmega328.upload.maximum_size=30720
menu.cpu.pro.16MHzatmega328.upload.speed=57600
atmega168.upload.tool=avrdude
atmega168.upload.protocol=arduino
atmega168.upload.maximum_size=14336
atmega168.upload.speed=19200
menu.cpu.pro.16MHzatmega328.bootloader.low_fuses=0xFF
menu.cpu.pro.16MHzatmega328.bootloader.high_fuses=0xDA
menu.cpu.pro.16MHzatmega328.bootloader.extended_fuses=0x05
menu.cpu.pro.16MHzatmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328.hex
atmega168.bootloader.tool=avrdude
atmega168.bootloader.low_fuses=0xff
atmega168.bootloader.high_fuses=0xdd
atmega168.bootloader.extended_fuses=0x00
atmega168.bootloader.file=atmega/ATmegaBOOT_168_ng.hex
atmega168.bootloader.unlock_bits=0x3F
atmega168.bootloader.lock_bits=0x0F
menu.cpu.pro.16MHzatmega328.build.mcu=atmega328p
menu.cpu.pro.16MHzatmega328.build.f_cpu=16000000L
atmega168.build.mcu=atmega168
atmega168.build.f_cpu=16000000L
atmega168.build.core=arduino
atmega168.build.variant=standard
## Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega328
menu.cpu.pro.8MHzatmega328=ATmega328 (3.3V, 8 MHz)
menu.cpu.pro.8MHzatmega328.upload.maximum_size=30720
menu.cpu.pro.8MHzatmega328.upload.speed=57600
menu.cpu.pro.8MHzatmega328.bootloader.low_fuses=0xFF
menu.cpu.pro.8MHzatmega328.bootloader.high_fuses=0xDA
menu.cpu.pro.8MHzatmega328.bootloader.extended_fuses=0x05
menu.cpu.pro.8MHzatmega328.bootloader.file=atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex
menu.cpu.pro.8MHzatmega328.build.mcu=atmega328p
menu.cpu.pro.8MHzatmega328.build.f_cpu=8000000L
## Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega168
menu.cpu.pro.16MHzatmega168=ATmega168 (5V, 16 MHz)
menu.cpu.pro.16MHzatmega168.upload.maximum_size=14336
menu.cpu.pro.16MHzatmega168.upload.speed=19200
menu.cpu.pro.16MHzatmega168.bootloader.low_fuses=0xff
menu.cpu.pro.16MHzatmega168.bootloader.high_fuses=0xdd
menu.cpu.pro.16MHzatmega168.bootloader.extended_fuses=0x00
menu.cpu.pro.16MHzatmega168.bootloader.file=atmega/ATmegaBOOT_168_diecimila.hex
menu.cpu.pro.16MHzatmega168.build.mcu=atmega168
menu.cpu.pro.16MHzatmega168.build.f_cpu=16000000L
## Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega168
menu.cpu.pro.8MHzatmega168=ATmega168 (3.3V, 8 MHz)
menu.cpu.pro.8MHzatmega168.upload.maximum_size=14336
menu.cpu.pro.8MHzatmega168.upload.speed=19200
menu.cpu.pro.8MHzatmega168.bootloader.low_fuses=0xc6
menu.cpu.pro.8MHzatmega168.bootloader.high_fuses=0xdd
menu.cpu.pro.8MHzatmega168.bootloader.extended_fuses=0x00
menu.cpu.pro.8MHzatmega168.bootloader.file=atmega/ATmegaBOOT_168_pro_8MHz.hex
menu.cpu.pro.8MHzatmega168.build.mcu=atmega168
menu.cpu.pro.8MHzatmega168.build.f_cpu=8000000L
##############################################################
atmega8.name=Arduino NG or older w/ ATmega8
atmega8.cpu=ATmega8
atmega8.container=Arduino NG or older
atmegang.name=Arduino NG or older
atmega8.upload.tool=avrdude
atmega8.upload.protocol=arduino
atmega8.upload.maximum_size=7168
atmega8.upload.speed=19200
atmegang.upload.tool=avrdude
atmegang.upload.protocol=arduino
atmegang.upload.speed=19200
atmega8.bootloader.tool=avrdude
atmega8.bootloader.low_fuses=0xdf
atmega8.bootloader.high_fuses=0xca
atmega8.bootloader.file=atmega8/ATmegaBOOT.hex
atmega8.bootloader.unlock_bits=0x3F
atmega8.bootloader.lock_bits=0x0F
atmegang.bootloader.tool=avrdude
atmegang.bootloader.unlock_bits=0x3F
atmegang.bootloader.lock_bits=0x0F
atmega8.build.mcu=atmega8
atmega8.build.f_cpu=16000000L
atmega8.build.core=arduino
atmega8.build.variant=standard
atmegang.build.mcu=atmegang
atmegang.build.f_cpu=16000000L
atmegang.build.core=arduino
atmegang.build.variant=standard
## Arduino NG or older w/ ATmega168
menu.cpu.atmegang.atmega168=ATmega168
menu.cpu.atmegang.atmega168.upload.maximum_size=14336
menu.cpu.atmegang.atmega168.bootloader.low_fuses=0xff
menu.cpu.atmegang.atmega168.bootloader.high_fuses=0xdd
menu.cpu.atmegang.atmega168.bootloader.extended_fuses=0x00
menu.cpu.atmegang.atmega168.bootloader.file=atmega/ATmegaBOOT_168_ng.hex
menu.cpu.atmegang.atmega168.build.mcu=atmega168
## Arduino NG or older w/ ATmega8
menu.cpu.atmegang.atmega8=ATmega8
menu.cpu.atmegang.atmega8.upload.maximum_size=7168
menu.cpu.atmegang.atmega8.bootloader.low_fuses=0xdf
menu.cpu.atmegang.atmega8.bootloader.high_fuses=0xca
menu.cpu.atmegang.atmega8.bootloader.file=atmegang/ATmegaBOOT.hex
menu.cpu.atmegang.atmega8.build.mcu=atmega8