diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 64ca0c9d3..86384ff3b 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -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 menuItemsToClickAfterStartup = new LinkedList(); + ButtonGroup boardsButtonGroup = new ButtonGroup(); - ButtonGroup cpuTypesButtonGroup = new ButtonGroup(); + Map buttonGroupsMap = new HashMap(); // 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 boards = targetPlatform.getBoards(); + + if (targetPlatform.getPreferences().get("name") == null || targetPlatform.getOrderedBoards().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.getOrderedBoards()) { 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 customMenuIDs = new LinkedList(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 getBoardPreferences() { TargetPlatform target = getTargetPlatform(); String board = Preferences.get("board"); - return target.getBoards().get(board); + Map boardPreferences = Maps.merge(target.getBoards().get(board), new LinkedHashMap()); + 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() { diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index 536b36a13..b5ad9941c 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -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 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(); + 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 boardPreferences = Base.getBoardPreferences(); + Map boardPreferences = Base.getBoardPreferences(); lineStatus.setBoardName(boardPreferences.get("name")); lineStatus.setSerialPort(Preferences.get("serial.port")); lineStatus.repaint(); diff --git a/app/src/processing/app/debug/TargetPlatform.java b/app/src/processing/app/debug/TargetPlatform.java index 9fcc51d43..ee14f304e 100644 --- a/app/src/processing/app/debug/TargetPlatform.java +++ b/app/src/processing/app/debug/TargetPlatform.java @@ -30,6 +30,7 @@ import java.util.List; import java.util.Map; import processing.app.helpers.PreferencesMap; +import processing.app.tools.MapWithSubkeys; import processing.core.PApplet; public class TargetPlatform { @@ -39,6 +40,7 @@ public class TargetPlatform { private List boardsOrder; private Map programmers; private PreferencesMap preferences; + private MapWithSubkeys customMenus; public TargetPlatform(String _name, File _folder) { System.out.println("TargetPlatform: constructor start, name: " + _name); @@ -55,9 +57,12 @@ public class TargetPlatform { PreferencesMap boardPreferences = new PreferencesMap(); boardPreferences.load(boardsFile); boards = boardPreferences.createFirstLevelMap(); + customMenus = MapWithSubkeys.createFrom(boards.get("menu")); + boards.remove("menu"); boardsOrder = readBoardsOrder(boardsFile); } } catch (Exception e) { + e.printStackTrace(); System.err.println("Error loading boards from boards.txt: " + e); } @@ -119,7 +124,11 @@ public class TargetPlatform { public Map getBoards() { return boards; } - + + public MapWithSubkeys getCustomMenus() { + return customMenus; + } + public List getOrderedBoards() { return boardsOrder; } diff --git a/app/src/processing/app/helpers/Maps.java b/app/src/processing/app/helpers/Maps.java new file mode 100644 index 000000000..439cb6bc5 --- /dev/null +++ b/app/src/processing/app/helpers/Maps.java @@ -0,0 +1,15 @@ +package processing.app.helpers; + +import java.util.Map; +import java.util.Map.Entry; + +public class Maps { + + public static Map merge(Map input, Map target) { + for (Entry entry : input.entrySet()) { + target.put(entry.getKey(), entry.getValue()); + } + return target; + } + +} diff --git a/app/src/processing/app/tools/MapWithSubkeys.java b/app/src/processing/app/tools/MapWithSubkeys.java new file mode 100644 index 000000000..c26c5f9bc --- /dev/null +++ b/app/src/processing/app/tools/MapWithSubkeys.java @@ -0,0 +1,66 @@ +package processing.app.tools; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +public class MapWithSubkeys { + + public static MapWithSubkeys createFrom(Map input) { + if (input == null) { + return null; + } + MapWithSubkeys target = new MapWithSubkeys(); + for (Entry 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 values; + private final Map maps; + + public MapWithSubkeys() { + this.values = new HashMap(); + this.maps = new HashMap(); + } + + public Collection getKeys() { + return values.keySet(); + } + + public Map getValues() { + return values; + } + + public String getValueOf(String key) { + return values.get(key); + } + + public MapWithSubkeys get(String key) { + if (!maps.containsKey(key)) { + put(key, null); + maps.put(key, new MapWithSubkeys()); + } + return maps.get(key); + } + + public void put(String key, String value) { + values.put(key, value); + } + +} diff --git a/app/test/processing/app/tools/MapWithSubkeysTest.java b/app/test/processing/app/tools/MapWithSubkeysTest.java new file mode 100644 index 000000000..a602e08f6 --- /dev/null +++ b/app/test/processing/app/tools/MapWithSubkeysTest.java @@ -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 input = new HashMap(); + 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 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 boards = cpu.getKeys(); + assertEquals(1, boards.size()); + assertTrue(boards.contains("nano")); + + Collection 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")); + } + +} diff --git a/app/test/processing/app/tools/test_partial_boards.txt b/app/test/processing/app/tools/test_partial_boards.txt new file mode 100644 index 000000000..ad873c375 --- /dev/null +++ b/app/test/processing/app/tools/test_partial_boards.txt @@ -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 \ No newline at end of file diff --git a/hardware/arduino/avr/boards.txt b/hardware/arduino/avr/boards.txt index b4b2cae17..2c46c97c0 100644 --- a/hardware/arduino/avr/boards.txt +++ b/hardware/arduino/avr/boards.txt @@ -1,5 +1,9 @@ # See: http://code.google.com/p/arduino/wiki/Platforms +menu.cpu=Processor +#FIXME +menu.speed=Speed + ############################################################## uno.name=Arduino Uno @@ -67,52 +71,45 @@ 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.bootloader.unlock_bits=0x3F +menu.cpu.nano.atmega328.bootloader.lock_bits=0x0F + +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.bootloader.unlock_bits=0x3F +menu.cpu.nano.atmega168.bootloader.lock_bits=0x0F + +menu.cpu.nano.atmega168.build.mcu=atmega168 + ############################################################## mega2560.name=Arduino Mega 2560 or Mega ADK @@ -190,52 +187,50 @@ 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 + +#FIXME +menu.speed.mini.16=16 MHz +menu.speed.mini.16.build.f_cpu=16000000L +menu.speed.mini.8=8 MHz +menu.speed.mini.8.build.f_cpu=8000000L + ############################################################## ethernet.name=Arduino Ethernet