diff --git a/HISTORY.md b/HISTORY.md index a373b71..e10c47b 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,7 +3,7 @@ A Makefile for Arduino Sketches The following is the rough list of changes that went into different versions. I tried to give credit whenever possible. If I have missed anyone, kindly add it to the list. -### 0.12.1 (in development) +### 0.13.0 (in development) - Add $OBJDIR to the list of configuration that gets printed. Fix issue #77 - Add support for specifying optimization level. Fix issue #81 - Add support for reseting "Micro" Arduino. Fix issue #80 (https://github.com/sej7278) @@ -13,6 +13,7 @@ The following is the rough list of changes that went into different versions. I - Improve avrdude and avrdude.conf path auto detection. Fix issue #48 - Move binary sketch size verification logic inside makefile. Fix issue #54 - Remove dependency on wait-connection-leonardo shell script. Fix issue #95 +- Add support for the Digilent chipKIT platform. (https://github.com/peplin) ### 0.12.0 (2013-06-20) - Fix "generated_assembly" target, which got broken earlier. Fix issue #76 (https://github.com/matthijskooijman) diff --git a/arduino-mk/Arduino.mk b/arduino-mk/Arduino.mk index 2fb9e3e..c2d1cfd 100644 --- a/arduino-mk/Arduino.mk +++ b/arduino-mk/Arduino.mk @@ -195,15 +195,6 @@ # # ######################################################################## -# Useful functions -# Returns the first argument (typically a directory), if the file or directory -# named by concatenating the first and optionally second argument -# (directory and optional filename) exists -dir_if_exists = $(if $(wildcard $(1)$(2)),$(1)) - -# For message printing: pad the right side of the first argument with spaces to -# the number of bytes indicated by the second argument. -space_pad_to = $(shell echo $(1) " " | head -c$(2)) arduino_output = # When output is not suppressed and we're in the top-level makefile, @@ -217,34 +208,36 @@ ifndef ARDUINO_QUIET endif endif -# Call with some text, and a prefix tag if desired (like [AUTODETECTED]), -show_config_info = $(call arduino_output,- $(call space_pad_to,$(2),20) $(1)) +######################################################################## +# Makefile distribution path +# -# Call with the name of the variable, a prefix tag if desired (like [AUTODETECTED]), -# and an explanation if desired (like (found in $$PATH) +# Call with the name of the variable, a prefix tag if desired (like +# [AUTODETECTED]), and an explanation if desired (like (found in $$PATH). This +# function definition is duplicated from Common.mk so that it is available +# before we import that Makefile. show_config_variable = $(call show_config_info,$(1) = $($(1)) $(3),$(2)) -# Just a nice simple visual separator -show_separator = $(call arduino_output,-------------------------) - -$(call show_separator) -$(call arduino_output,Arduino.mk Configuration:) - -######################################################################## -# -# Detect OS -ifeq ($(OS),Windows_NT) - CURRENT_OS = WINDOWS +ifndef ARDMK_DIR + # presume it's a level above the path to our own file + ARDMK_DIR := $(realpath $(dir $(realpath $(lastword $(MAKEFILE_LIST))))/..) + $(call show_config_variable,ARDMK_DIR,[COMPUTED],(relative to $(notdir $(lastword $(MAKEFILE_LIST))))) else - UNAME_S := $(shell uname -s) - ifeq ($(UNAME_S),Linux) - CURRENT_OS = LINUX - endif - ifeq ($(UNAME_S),Darwin) - CURRENT_OS = MAC - endif + $(call show_config_variable,ARDMK_DIR,[USER]) endif -$(call show_config_variable,CURRENT_OS,[AUTODETECTED]) + +ifdef ARDMK_DIR + ifndef ARDMK_PATH + ARDMK_PATH = $(ARDMK_DIR)/bin + $(call show_config_variable,ARDMK_PATH,[COMPUTED],(relative to ARDMK_DIR)) + else + $(call show_config_variable,ARDMK_PATH,[USER]) + endif +else + echo $(error "ARDMK_DIR is not defined") +endif + +include $(ARDMK_DIR)/arduino-mk/Common.mk ######################################################################## # @@ -292,20 +285,32 @@ endif ######################################################################## # Arduino Sketchbook folder # -ifndef ARDUINO_SKETCHBOOK - ifneq ($(wildcard $(HOME)/.arduino/preferences.txt),) - ARDUINO_SKETCHBOOK = $(shell grep --max-count=1 --regexp="sketchbook.path=" \ - $(HOME)/.arduino/preferences.txt | \ - sed -e 's/sketchbook.path=//' ) + +ifndef ARDUINO_PREFERENCES_PATH + + AUTO_ARDUINO_PREFERENCES := $(firstword \ + $(call dir_if_exists,$(HOME)/.arduino/preferences.txt) \ + $(call dir_if_exists,$(HOME)/Library/Arduino/preferences.txt) ) + ifdef AUTO_ARDUINO_PREFERENCES + ARDUINO_PREFERENCES_PATH = $(AUTO_ARDUINO_PREFERENCES) + $(call show_config_variable,ARDUINO_PREFERENCES_PATH,[AUTODETECTED]) + else + echo $(error "ARDUINO_PREFERENCES is not defined") endif - # on mac - ifneq ($(wildcard $(HOME)/Library/Arduino/preferences.txt),) - ARDUINO_SKETCHBOOK = $(shell grep --max-count=1 --regexp="sketchbook.path=" \ - $(HOME)/Library/Arduino/preferences.txt | \ - sed -e 's/sketchbook.path=//' ) +else + $(call show_config_variable,ARDUINO_PREFERENCES_PATH,[USER]) +endif + +ifndef ARDUINO_SKETCHBOOK + ifeq ($(ARDUINO_PREFERENCES_PATH),) + echo $(error No ARDUINO_PREFERENCES_PATH detected, cannot autodetect ARDUINO_SKETCHBOOK) endif + ARDUINO_SKETCHBOOK = $(shell grep --max-count=1 --regexp="sketchbook.path=" \ + $(ARDUINO_PREFERENCES_PATH) | \ + sed -e 's/sketchbook.path=//' ) + ifneq ($(ARDUINO_SKETCHBOOK),) $(call show_config_variable,ARDUINO_SKETCHBOOK,[AUTODETECTED],(from arduino preferences file)) else @@ -319,6 +324,35 @@ endif ######################################################################## # Arduino and system paths # + +ifndef CC_NAME +CC_NAME = avr-gcc +endif + +ifndef CXX_NAME +CXX_NAME = avr-g++ +endif + +ifndef OBJCOPY_NAME +OBJCOPY_NAME = avr-objcopy +endif + +ifndef OBJDUMP_NAME +OBJDUMP_NAME = avr-objdump +endif + +ifndef AR_NAME +AR_NAME = avr-ar +endif + +ifndef SIZE_NAME +SIZE_NAME = avr-size +endif + +ifndef NM_NAME +NM_NAME = avr-nm +endif + ifndef AVR_TOOLS_DIR BUNDLED_AVR_TOOLS_DIR := $(call dir_if_exists,$(ARDUINO_DIR)/hardware/tools/avr) @@ -327,7 +361,7 @@ ifndef AVR_TOOLS_DIR $(call show_config_variable,AVR_TOOLS_DIR,[BUNDLED],(in Arduino distribution)) # In Linux distribution of Arduino, the path to avrdude and avrdude.conf are different - # More details at https://github.com/sudar/Arduino-Makefile/issues/48 and + # More details at https://github.com/sudar/Arduino-Makefile/issues/48 and # https://groups.google.com/a/arduino.cc/d/msg/developers/D_m97jGr8Xs/uQTt28KO_8oJ ifeq ($(CURRENT_OS),LINUX) @@ -338,7 +372,7 @@ ifndef AVR_TOOLS_DIR ifndef AVRDUDE_CONF AVRDUDE_CONF = $(AVR_TOOLS_DIR)/../avrdude.conf endif - + else ifndef AVRDUDE_CONF @@ -349,10 +383,12 @@ ifndef AVR_TOOLS_DIR else - SYSTEMPATH_AVR_TOOLS_DIR := $(call dir_if_exists,$(abspath $(dir $(shell which avr-gcc))/..)) + SYSTEMPATH_AVR_TOOLS_DIR := $(call dir_if_exists,$(abspath $(dir $(shell which $(CC_NAME)))/..)) ifdef SYSTEMPATH_AVR_TOOLS_DIR - AVR_TOOLS_DIR = $(SYSTEMPATH_AVR_TOOLS_DIR) + AVR_TOOLS_DIR = $(SYSTEMPATH_AVR_TOOLS_DIR) $(call show_config_variable,AVR_TOOLS_DIR,[AUTODETECTED],(found in $$PATH)) + else + echo $(error No AVR tools directory found) endif # SYSTEMPATH_AVR_TOOLS_DIR endif # BUNDLED_AVR_TOOLS_DIR @@ -367,7 +403,12 @@ endif ARDUINO_LIB_PATH = $(ARDUINO_DIR)/libraries $(call show_config_variable,ARDUINO_LIB_PATH,[COMPUTED],(from ARDUINO_DIR)) -ARDUINO_CORE_PATH = $(ARDUINO_DIR)/hardware/arduino/cores/arduino +ifndef ARDUINO_CORE_PATH + ARDUINO_CORE_PATH = $(ARDUINO_DIR)/hardware/arduino/cores/arduino + $(call show_config_variable,ARDUINO_CORE_PATH,[DEFAULT]) +else + $(call show_config_variable,ARDUINO_CORE_PATH,[USER]) +endif # Third party hardware and core like ATtiny or ATmega 16 ifdef ALTERNATE_CORE @@ -414,29 +455,6 @@ else endif -######################################################################## -# Makefile distribution path -# -ifndef ARDMK_DIR - # presume it's a level above the path to our own file - ARDMK_DIR := $(realpath $(dir $(realpath $(lastword $(MAKEFILE_LIST))))/..) - $(call show_config_variable,ARDMK_DIR,[COMPUTED],(relative to $(notdir $(lastword $(MAKEFILE_LIST))))) -else - $(call show_config_variable,ARDMK_DIR,[USER]) -endif - -ifdef ARDMK_DIR - ifndef ARDMK_PATH - ARDMK_PATH = $(ARDMK_DIR)/bin - $(call show_config_variable,ARDMK_PATH,[COMPUTED],(relative to ARDMK_DIR)) - else - $(call show_config_variable,ARDMK_PATH,[USER]) - endif -else - echo $(error "ARDMK_DIR is not defined") -endif - - ######################################################################## # Miscellaneous # @@ -689,14 +707,14 @@ TARGETS = $(OBJDIR)/$(TARGET).* CORE_LIB = $(OBJDIR)/libcore.a # Names of executables -CC = $(AVR_TOOLS_PATH)/avr-gcc -CXX = $(AVR_TOOLS_PATH)/avr-g++ -AS = $(AVR_TOOLS_PATH)/avr-as -OBJCOPY = $(AVR_TOOLS_PATH)/avr-objcopy -OBJDUMP = $(AVR_TOOLS_PATH)/avr-objdump -AR = $(AVR_TOOLS_PATH)/avr-ar -SIZE = $(AVR_TOOLS_PATH)/avr-size -NM = $(AVR_TOOLS_PATH)/avr-nm +CC = $(AVR_TOOLS_PATH)/$(CC_NAME) +CXX = $(AVR_TOOLS_PATH)/$(CXX_NAME) +AS = $(AVR_TOOLS_PATH)/$(AS_NAME) +OBJCOPY = $(AVR_TOOLS_PATH)/$(OBJCOPY_NAME) +OBJDUMP = $(AVR_TOOLS_PATH)/$(OBJDUMP_NAME) +AR = $(AVR_TOOLS_PATH)/$(AR_NAME) +SIZE = $(AVR_TOOLS_PATH)/$(SIZE_NAME) +NM = $(AVR_TOOLS_PATH)/$(NM_NAME) REMOVE = rm -rf MV = mv -f CAT = cat @@ -743,8 +761,15 @@ else $(call show_config_variable,OPTIMIZATION_LEVEL,[USER]) endif +ifndef MCU_FLAG_NAME + MCU_FLAG_NAME = mmcu + $(call show_config_variable,MCU_FLAG_NAME,[DEFAULT]) +else + $(call show_config_variable,MCU_FLAG_NAME,[USER]) +endif + # Using += instead of =, so that CPPFLAGS can be set per sketch level -CPPFLAGS += -mmcu=$(MCU) -DF_CPU=$(F_CPU) -DARDUINO=$(ARDUINO_VERSION) \ +CPPFLAGS += -$(MCU_FLAG_NAME)=$(MCU) -DF_CPU=$(F_CPU) -DARDUINO=$(ARDUINO_VERSION) \ -I. -I$(ARDUINO_CORE_PATH) -I$(ARDUINO_VAR_PATH)/$(VARIANT) \ $(SYS_INCLUDES) $(USER_INCLUDES) -g -O$(OPTIMIZATION_LEVEL) -Wall \ -ffunction-sections -fdata-sections @@ -754,10 +779,17 @@ ifeq ($(VARIANT),leonardo) CPPFLAGS += -DUSB_VID=$(USB_VID) -DUSB_PID=$(USB_PID) endif -CFLAGS += -std=gnu99 $(EXTRA_FLAGS) $(EXTRA_CFLAGS) +ifndef CFLAGS_STD + CFLAGS_STD = -std=gnu99 + $(call show_config_variable,CFLAGS_STD,[DEFAULT]) +else + $(call show_config_variable,CFLAGS_STD,[USER]) +endif + +CFLAGS += $(EXTRA_FLAGS) $(EXTRA_CFLAGS) CXXFLAGS += -fno-exceptions $(EXTRA_FLAGS) $(EXTRA_CXXFLAGS) -ASFLAGS += -mmcu=$(MCU) -I. -x assembler-with-cpp -LDFLAGS += -mmcu=$(MCU) -Wl,--gc-sections -O$(OPTIMIZATION_LEVEL) $(EXTRA_FLAGS) $(EXTRA_CXXFLAGS) +ASFLAGS += -$(MCU_FLAG_NAME)=$(MCU) -I. -x assembler-with-cpp +LDFLAGS += -$(MCU_FLAG_NAME)=$(MCU) -Wl,--gc-sections -O$(OPTIMIZATION_LEVEL) $(EXTRA_FLAGS) $(EXTRA_CXXFLAGS) $(EXTRA_LDFLAGS) SIZEFLAGS ?= --mcu=$(MCU) -C # Returns the Arduino port (first wildcard expansion) if it exists, otherwise it errors. @@ -857,7 +889,7 @@ $(OBJDIR)/%.s: %.ino $(COMMON_DEPS) | $(OBJDIR) $(CXX) -x c++ -include Arduino.h -MMD -S -fverbose-asm $(CPPFLAGS) $(CXXFLAGS) $< -o $@ #$(OBJDIR)/%.lst: $(OBJDIR)/%.s -# $(AS) -mmcu=$(MCU) -alhnd $< > $@ +# $(AS) -$(MCU_FLAG_NAME)=$(MCU) -alhnd $< > $@ # core files $(OBJDIR)/%.o: $(ARDUINO_CORE_PATH)/%.c $(COMMON_DEPS) | $(OBJDIR) diff --git a/arduino-mk/Common.mk b/arduino-mk/Common.mk new file mode 100644 index 0000000..a94c37f --- /dev/null +++ b/arduino-mk/Common.mk @@ -0,0 +1,38 @@ +# Useful functions +# Returns the first argument (typically a directory), if the file or directory +# named by concatenating the first and optionally second argument +# (directory and optional filename) exists +dir_if_exists = $(if $(wildcard $(1)$(2)),$(1)) + +# For message printing: pad the right side of the first argument with spaces to +# the number of bytes indicated by the second argument. +space_pad_to = $(shell echo $(1) " " | head -c$(2)) + +# Call with some text, and a prefix tag if desired (like [AUTODETECTED]), +show_config_info = $(call arduino_output,- $(call space_pad_to,$(2),20) $(1)) + +# Call with the name of the variable, a prefix tag if desired (like [AUTODETECTED]), +# and an explanation if desired (like (found in $$PATH) +show_config_variable = $(call show_config_info,$(1) = $($(1)) $(3),$(2)) + +# Just a nice simple visual separator +show_separator = $(call arduino_output,-------------------------) + +$(call show_separator) +$(call arduino_output,Arduino.mk Configuration:) + +######################################################################## +# +# Detect OS +ifeq ($(OS),Windows_NT) + CURRENT_OS = WINDOWS +else + UNAME_S := $(shell uname -s) + ifeq ($(UNAME_S),Linux) + CURRENT_OS = LINUX + endif + ifeq ($(UNAME_S),Darwin) + CURRENT_OS = MAC + endif +endif +$(call show_config_variable,CURRENT_OS,[AUTODETECTED]) diff --git a/arduino-mk/chipKIT.mk b/arduino-mk/chipKIT.mk new file mode 100644 index 0000000..f861a2c --- /dev/null +++ b/arduino-mk/chipKIT.mk @@ -0,0 +1,96 @@ +# +# chipKIT extensions for Arduino Makefile +# System part (i.e. project independent) +# +# Copyright (C) 2011, 2012, 2013 Christopher Peplin +# , based on work that is Copyright Martin +# Oldfield +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 2.1 of the +# License, or (at your option) any later version. +# +# Modified by John Wallbank for Visual Studio +# +# Development changes, John Wallbank, +# +# - made inclusion of WProgram.h optional so that +# including it in the source doesn't mess up compile error line numbers +# - parameterised the routine used to reset the serial port +# + +######################################################################## +# Makefile distribution path +# + +# The show_config_variable is unavailable before we include the common makefile, +# so we defer logging the ARDMK_DIR info until it happens in Arduino.mk +ifndef ARDMK_DIR + # presume it's a level above the path to our own file + ARDMK_DIR := $(realpath $(dir $(realpath $(lastword $(MAKEFILE_LIST))))/..) +endif + +ifdef ARDMK_DIR + ifndef ARDMK_PATH + ARDMK_PATH = $(ARDMK_DIR)/bin + endif +else + echo $(error "ARDMK_DIR is not defined") +endif + +include $(ARDMK_DIR)/arduino-mk/Common.mk + +ifndef MPIDE_DIR + AUTO_MPIDE_DIR := $(firstword \ + $(call dir_if_exists,/usr/share/mpide) \ + $(call dir_if_exists,/Applications/Mpide.app/Contents/Resources/Java) ) + ifdef AUTO_MPIDE_DIR + MPIDE_DIR = $(AUTO_MPIDE_DIR) + $(call show_config_variable,MPIDE_DIR,[autodetected]) + else + echo $(error "mpide_dir is not defined") + endif +else + $(call show_config_variable,MPIDE_DIR,[USER]) +endif + +ifndef MPIDE_PREFERENCES_PATH + AUTO_MPIDE_PREFERENCES_PATH := $(firstword \ + $(call dir_if_exists,$(HOME)/.mpide/preferences.txt) \ + $(call dir_if_exists,$(HOME)/Library/Mpide/preferences.txt) ) + ifdef AUTO_MPIDE_PREFERENCES_PATH + MPIDE_PREFERENCES_PATH = $(AUTO_MPIDE_PREFERENCES_PATH) + $(call show_config_variable,MPIDE_PREFERENCES_PATH,[autodetected]) + else + echo $(error "MPIDE_PREFERENCES_PATH is not defined") + endif +endif + + +AVR_TOOLS_DIR = $(ARDUINO_DIR)/hardware/pic32/compiler/pic32-tools + +ALTERNATE_CORE = pic32 +ALTERNATE_CORE_PATH = $(MPIDE_DIR)/hardware/pic32 +ARDUINO_CORE_PATH = $(ALTERNATE_CORE_PATH)/cores/$(ALTERNATE_CORE) +ARDUINO_PREFERENCES_PATH = $(MPIDE_PREFERENCES_PATH) +ARDUINO_DIR = $(MPIDE_DIR) + +ARDUINO_VERSION = 23 + +CC_NAME = pic32-gcc +CXX_NAME = pic32-g++ +AR_NAME = pic32-ar +OBJDUMP_NAME = pic32-objdump +OBJCOPY_NAME = pic32-objcopy +SIZE_NAME = pic32-size + +LDSCRIPT = $(shell $(PARSE_BOARD_CMD) $(BOARD_TAG) ldscript) +LDSCRIPT_FILE = $(ARDUINO_CORE_PATH)/$(LDSCRIPT) + +MCU_FLAG_NAME=mprocessor +LDFLAGS += -T$(ARDUINO_CORE_PATH)/$(LDSCRIPT) +CPPFLAGS += -mno-smart-io -fno-short-double +CFLAGS_STD = + +include $(ARDMK_DIR)/arduino-mk/Arduino.mk diff --git a/examples/BlinkChipKIT/BlinkChipKIT.pde b/examples/BlinkChipKIT/BlinkChipKIT.pde new file mode 100644 index 0000000..1953c39 --- /dev/null +++ b/examples/BlinkChipKIT/BlinkChipKIT.pde @@ -0,0 +1,19 @@ +/* + Blink + Turns on an LED on for one second, then off for one second, repeatedly. + + This example code is in the public domain. + */ + +void setup() { + // initialize the digital pin as an output. + // Pin 13 has an LED connected on most Arduino boards: + pinMode(13, OUTPUT); +} + +void loop() { + digitalWrite(13, HIGH); // set the LED on + delay(1000); // wait for a second + digitalWrite(13, LOW); // set the LED off + delay(1000); // wait for a second +} diff --git a/examples/BlinkChipKIT/Makefile b/examples/BlinkChipKIT/Makefile new file mode 100644 index 0000000..f494075 --- /dev/null +++ b/examples/BlinkChipKIT/Makefile @@ -0,0 +1,6 @@ +BOARD_TAG = mega_pic32 +ARDUINO_PORT = /dev/cu.usb* +ARDUINO_LIBS = + +include ../../arduino-mk/chipKIT.mk +