From 3f32563683a90d471c7ff97216b000e922851c72 Mon Sep 17 00:00:00 2001 From: John Whittington Date: Tue, 12 Jun 2018 13:59:58 +0100 Subject: [PATCH] Support for Arduino Due added Update HISTORY.md Add avr core emulation to C sources --- Arduino.mk | 39 ++++++++++++++---- HISTORY.md | 3 +- README.md | 10 ++--- Sam.mk | 75 +++++++++++++++++++++++++++------- examples/DueBlink/DueBlink.ino | 19 +++++++++ examples/DueBlink/Makefile | 19 +++++++++ tests/script/runtests.sh | 2 +- 7 files changed, 137 insertions(+), 30 deletions(-) create mode 100644 examples/DueBlink/DueBlink.ino create mode 100644 examples/DueBlink/Makefile diff --git a/Arduino.mk b/Arduino.mk index 8ef79c7..979a039 100644 --- a/Arduino.mk +++ b/Arduino.mk @@ -832,6 +832,7 @@ ifeq ($(strip $(NO_CORE)),) # USB Core if samd or sam ifeq ($(findstring sam, $(strip $(ARCHITECTURE))), sam) + CORE_C_SRCS += $(wildcard $(ARDUINO_CORE_PATH)/avr/*.c) # avr core emulation files CORE_C_SRCS += $(wildcard $(ARDUINO_CORE_PATH)/USB/*.c) CORE_CPP_SRCS += $(wildcard $(ARDUINO_CORE_PATH)/USB/*.cpp) endif @@ -841,11 +842,22 @@ ifeq ($(strip $(NO_CORE)),) $(call show_config_info,NO_CORE_MAIN_CPP set so core library will not include main.cpp,[MANUAL]) endif - # Put alt core variant file for M0 devices in OTHER_OJBS - ifdef ALT_CORE_CPP_SRCS - ALT_CORE_OBJ_FILES = $(ALT_CORE_C_SRCS:.c=.c.o) $(ALT_CORE_CPP_SRCS:.cpp=.cpp.o) $(ALT_CORE_AS_SRCS:.S=.S.o) - OTHER_OBJS := $(patsubst $(ALTERNATE_CORE_PATH)/variants/$(VARIANT)/%, \ - $(OBJDIR)/core/%,$(ALT_CORE_OBJ_FILES)) + # Add core files for sam devices in CORE_OJBS filtering specific paths + ifdef SAM_CORE_PATH + SAM_CORE_OBJ_FILES = $(SAM_CORE_C_SRCS:.c=.c.o) $(SAM_CORE_CPP_SRCS:.cpp=.cpp.o) $(SAM_CORE_AS_SRCS:.S=.S.o) + # variant core files + CORE_OBJS += $(patsubst $(SAM_CORE_PATH)/%, \ + $(OBJDIR)/core/%, $(filter $(SAM_CORE_PATH)/%, $(SAM_CORE_OBJ_FILES))) + # libsam on Due + ifdef SAM_LIBSAM_PATH + CORE_OBJS += $(patsubst $(SAM_LIBSAM_PATH)/source/%, \ + $(OBJDIR)/core/%, $(filter $(SAM_LIBSAM_PATH)/source/%, $(SAM_CORE_OBJ_FILES))) + endif + # chip sources on Due + ifdef SAM_SYSTEM_PATH + CORE_OBJS += $(patsubst $(SAM_SYSTEM_PATH)/source/%, \ + $(OBJDIR)/core/%, $(filter $(SAM_SYSTEM_PATH)/source/%, $(SAM_CORE_OBJ_FILES))) + endif endif CORE_OBJ_FILES = $(CORE_C_SRCS:.c=.c.o) $(CORE_CPP_SRCS:.cpp=.cpp.o) $(CORE_AS_SRCS:.S=.S.o) @@ -1324,19 +1336,28 @@ $(OBJDIR)/core/%.S.o: $(ARDUINO_CORE_PATH)/%.S $(COMMON_DEPS) | $(OBJDIR) @$(MKDIR) $(dir $@) $(CC) -MMD -c $(CPPFLAGS) $(ASFLAGS) $< -o $@ -# alt core files -$(OBJDIR)/core/%.c.o: $(ALTERNATE_CORE_PATH)/variants/$(VARIANT)/%.c $(COMMON_DEPS) | $(OBJDIR) +# sam core files +$(OBJDIR)/core/%.c.o: $(SAM_CORE_PATH)/%.c $(COMMON_DEPS) | $(OBJDIR) @$(MKDIR) $(dir $@) $(CC) -MMD -c $(CPPFLAGS) $(CFLAGS) $< -o $@ -$(OBJDIR)/core/%.cpp.o: $(ALTERNATE_CORE_PATH)/variants/$(VARIANT)/%.cpp $(COMMON_DEPS) | $(OBJDIR) +$(OBJDIR)/core/%.cpp.o: $(SAM_CORE_PATH)/%.cpp $(COMMON_DEPS) | $(OBJDIR) @$(MKDIR) $(dir $@) $(CXX) -MMD -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ -$(OBJDIR)/core/%.S.o: $(ALTERNATE_CORE_PATH)/variants/$(VARIANT)/%.S $(COMMON_DEPS) | $(OBJDIR) +$(OBJDIR)/core/%.S.o: $(SAM_CORE_PATH)/%.S $(COMMON_DEPS) | $(OBJDIR) @$(MKDIR) $(dir $@) $(CC) -MMD -c $(CPPFLAGS) $(ASFLAGS) $< -o $@ +# due specific sources from sam core as doesn't core doesn't have SystemInit startup file +$(OBJDIR)/core/%.c.o: $(SAM_LIBSAM_PATH)/source/%.c $(COMMON_DEPS) | $(OBJDIR) + @$(MKDIR) $(dir $@) + $(CC) -MMD -c $(CPPFLAGS) $(CFLAGS) $< -o $@ + +$(OBJDIR)/core/%.c.o: $(SAM_SYSTEM_PATH)/source/%.c $(COMMON_DEPS) | $(OBJDIR) + @$(MKDIR) $(dir $@) + $(CC) -MMD -c $(CPPFLAGS) $(CFLAGS) $< -o $@ + # various object conversions $(OBJDIR)/%.bin: $(OBJDIR)/%.elf $(COMMON_DEPS) @$(MKDIR) $(dir $@) diff --git a/HISTORY.md b/HISTORY.md index 12155b4..10b3e5e 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -20,7 +20,8 @@ I tried to give credit whenever possible. If I have missed anyone, kindly add it - New: Add template Makefile and project boilerplate initialise script, `ardmk-init`. (https://github.com/tuna-f1sh) - New: Support atmelice_isp JTAG tool as ISP programmer. (https://github.com/tuna-f1sh) - New: Compatibility with deprecated pgmspace.h API can now be disabled since it sometimes causes bogus compiler warnings (issue #546) -- New: Support Arduino ARM-based (SAM/SAMD) devices. (https://github.com/tuna-f1sh) +- New: Support Arduino ARM SAMD devices (Zero, M0 Pro, Feather M0). (https://github.com/tuna-f1sh) +- New: Support Arduino ARM SAM devices (Due). (https://github.com/tuna-f1sh) ### 1.6.0 (2017-07-11) - Fix: Allowed for SparkFun's weird usb pid/vid submenu shenanigans (issue #499). (https://github.com/sej7278) diff --git a/README.md b/README.md index f3b5e20..0787ade 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This is a very simple Makefile which knows how to build Arduino sketches. It def - Highly customizable - Supports all official AVR-based Arduino boards - Supports official ARM-based Arduino boards using Atmel SAM chip family - (Cortex M0) and includes on-device debugging targets. +and includes on-device debugging targets. - Supports chipKIT - Supports Teensy 3.x (via Teensyduino) - Works on all three major OS (Mac, Linux, Windows) @@ -318,14 +318,14 @@ For large Robotis projects, [libmaple](https://github.com/Rhoban/Maple) may be m ## Arduino ARM Boards For Arduino boards using ARM architechure, specifically the Atmel SAM series -(Arduino M0 [Pro], Zero, MKR1000, Feather M0, etc.), first +((SAM3X8E) Due; (SAMD21) Arduino M0 [Pro], Zero, MKR1000, Feather M0, etc.), first install the board support package from the IDE or other distribution channels. Define`ARDUINO_PACKAGE_DIR` as the root path containing the ARM support package (the manufacturer folder) and the `BOARD_TAG` (see `make show_boards` for help) within your project Makefile. Include 'Sam.mk' rather than - 'Arduino.mk' at the end of your file - see examples/ZeroBlink and - examples/MZeroBlink for example usage. + 'Arduino.mk' at the end of your file - see examples/ZeroBlink, + examples/MZeroBlink and examples/DueBlink for example usage. **Note**: The Arduino IDE does not install board support packages to the base Arduino installation directory (the directory that will work with AVR @@ -351,7 +351,7 @@ bootloaders. External CMSIS tools such as Atmel Ice will also work with this method. Black Magic Probe (BMP) support is also included using GDB for both uploading and debugging. -Native USB programing using Bossa (Zero, MKR1000, Feather style bootloaders) +Native USB programing using Bossa (Due, Zero, MKR1000, Feather style bootloaders) and avrdude (M0 bootloaders) is supported. The bootloaders on these devices requires a double press of the reset button or open/closing the serial port at 1200 BAUD. The automatic entry of the bootloader is attempted using diff --git a/Sam.mk b/Sam.mk index 8b93ee4..bbea32c 100644 --- a/Sam.mk +++ b/Sam.mk @@ -53,7 +53,7 @@ endif ifndef CORE_VER CORE_VER := $(wildcard $(ARDUINO_PACKAGE_DIR)/$(ARDMK_VENDOR)/hardware/$(ARCHITECTURE)/1.*) - ifdef CORE_VER + ifneq ($(CORE_VER),) CORE_VER := $(shell basename $(CORE_VER)) $(call show_config_variable,CORE_VER,[AUTODETECTED],(from ARDUINO_PACKAGE_DIR)) endif @@ -62,28 +62,42 @@ else endif ifndef CMSIS_VER - CMSIS_VER := $(shell basename $(wildcard $(ARDUINO_PACKAGE_DIR)/$(ARDMK_VENDOR)/tools/CMSIS/4.*)) - $(call show_config_variable,CMSIS_VER,[AUTODETECTED],(from ARDUINO_PACKAGE_DIR)) + CMSIS_VER := $(wildcard $(ARDUINO_PACKAGE_DIR)/$(ARDMK_VENDOR)/tools/CMSIS/4.*) + ifneq ($(CMSIS_VER),) + CMSIS_VER := $(shell basename $(CMSIS_VER)) + $(call show_config_variable,CMSIS_VER,[AUTODETECTED],(from ARDUINO_PACKAGE_DIR)) + endif else $(call show_config_variable,CMSIS_VER,[USER]) endif ifndef CMSIS_ATMEL_VER - CMSIS_ATMEL_VER := $(shell basename $(wildcard $(ARDUINO_PACKAGE_DIR)/$(ARDMK_VENDOR)/tools/CMSIS-Atmel/1.*)) - $(call show_config_variable,CMSIS_ATMEL_VER,[AUTODETECTED],(from ARDUINO_PACKAGE_DIR)) + CMSIS_ATMEL_VER := $(wildcard $(ARDUINO_PACKAGE_DIR)/$(ARDMK_VENDOR)/tools/CMSIS-Atmel/1.*) + ifneq ($(CMSIS_ATMEL_VER),) + CMSIS_ATMEL_VER := $(shell basename $(CMSIS_ATMEL_VER)) + $(call show_config_variable,CMSIS_ATMEL_VER,[AUTODETECTED],(from ARDUINO_PACKAGE_DIR)) + endif else $(call show_config_variable,CMSIS_ATMEL_VER,[USER]) endif ifndef CMSIS_DIR - CMSIS_DIR := $(ARDUINO_PACKAGE_DIR)/$(ARDMK_VENDOR)/tools/CMSIS/$(CMSIS_VER)/CMSIS + ifeq ($(findstring samd, $(strip $(ARCHITECTURE))), samd) + CMSIS_DIR := $(ARDUINO_PACKAGE_DIR)/$(ARDMK_VENDOR)/tools/CMSIS/$(CMSIS_VER)/CMSIS + else + CMSIS_DIR = $(ALTERNATE_CORE_PATH)/system/CMSIS/CMSIS + endif $(call show_config_variable,CMSIS_DIR,[AUTODETECTED],(from ARDUINO_PACKAGE_DIR)) else $(call show_config_variable,CMSIS_DIR,[USER]) endif ifndef CMSIS_ATMEL_DIR - CMSIS_ATMEL_DIR := $(ARDUINO_PACKAGE_DIR)/$(ARDMK_VENDOR)/tools/CMSIS-Atmel/$(CMSIS_ATMEL_VER)/CMSIS + ifeq ($(findstring samd, $(strip $(ARCHITECTURE))), samd) + CMSIS_ATMEL_DIR := $(ARDUINO_PACKAGE_DIR)/$(ARDMK_VENDOR)/tools/CMSIS-Atmel/$(CMSIS_ATMEL_VER)/CMSIS + else + CMSIS_ATMEL_DIR = $(ALTERNATE_CORE_PATH)/system/CMSIS + endif $(call show_config_variable,CMSIS_ATMEL_DIR,[AUTODETECTED],(from ARDUINO_PACKAGE_DIR)) else $(call show_config_variable,CMSIS_ATMEL_DIR,[USER]) @@ -129,9 +143,27 @@ ifndef VARIANT endif # grab any sources in the variant core path (variant.cpp defines pin/port mapping on SAM devices) -ALT_CORE_C_SRCS := $(wildcard $(ALTERNATE_CORE_PATH)/variants/$(VARIANT)/*.c) -ALT_CORE_CPP_SRCS := $(wildcard $(ALTERNATE_CORE_PATH)/variants/$(VARIANT)/*.cpp) -ALT_CORE_S_SRCS := $(wildcard $(ALTERNATE_CORE_PATH)/variants/$(VARIANT)/*.S) +ifndef SAM_CORE_PATH + SAM_CORE_PATH := $(ALTERNATE_CORE_PATH)/variants/$(VARIANT) +endif +SAM_CORE_C_SRCS := $(wildcard $(SAM_CORE_PATH)/*.c) +SAM_CORE_CPP_SRCS := $(wildcard $(SAM_CORE_PATH)/*.cpp) +SAM_CORE_S_SRCS := $(wildcard $(SAM_CORE_PATH)/*.S) + +# due/sam specific paths hard define chip type for SystemInit function in system_CHIP.c as not included in core like samd +ifeq ($(findstring arduino_due, $(strip $(VARIANT))), arduino_due) + ifndef SAM_SYSTEM_PATH + SAM_SYSTEM_PATH := $(CMSIS_ATMEL_DIR)/Device/ATMEL/sam3xa + endif + ifndef SAM_LIBSAM_PATH + SAM_LIBSAM_PATH := $(ALTERNATE_CORE_PATH)/system/libsam + endif + CPPFLAGS += -I$(SAM_SYSTEM_PATH)/include + CPPFLAGS += -I$(SAM_LIBSAM_PATH) + CPPFLAGS += -I$(SAM_LIBSAM_PATH)/include + SAM_CORE_C_SRCS += $(wildcard $(SAM_LIBSAM_PATH)/source/*.c) + SAM_CORE_C_SRCS += $(wildcard $(SAM_SYSTEM_PATH)/source/*.c) +endif # Use arm-toolchain from Arduino install if exists and user has not defined global version ifndef ARM_TOOLS_DIR @@ -160,7 +192,7 @@ ifndef CC_NAME endif ifndef CXX_NAME - CXX_NAME := $(call PARSE_BOARD,$(BOARD_TAG),build.command.g++) + CXX_NAME := $(call PARSE_BOARD,$(BOARD_TAG),build.command.g\+\+) ifndef CXX_NAME CXX_NAME := arm-none-eabi-g++ else @@ -330,6 +362,10 @@ endif ifndef BOSSA_OPTS BOSSA_OPTS += -d --info --erase --write --verify --reset + # Arduino Due forces RS-232 mode and boots from flash + ifeq ($(findstring arduino_due, $(strip $(VARIANT))), arduino_due) + BOSSA_OPTS += -U false -b + endif endif get_bootloader = $(shell $(RESET_CMD) | tail -1) @@ -340,7 +376,7 @@ ifndef ISP_PORT ifeq ($(CURRENT_OS), WINDOWS) BOSSA_OPTS += --port=$(COM_STYLE_MONITOR_PORT) else - BOSSA_OPTS += --port=$(call get_monitor_port) + BOSSA_OPTS += --port=$(notdir $(call get_monitor_port)) endif else BOSSA_OPTS += --port=$(ISP_PORT) @@ -460,11 +496,20 @@ CXXFLAGS += -fno-rtti -fno-threadsafe-statics -std=gnu++11 AMCU := $(call PARSE_BOARD,$(BOARD_TAG),build.mcu) BOARD_LINKER_SCRIPT := $(call PARSE_BOARD,$(BOARD_TAG),build.ldscript) OPENOCD_SCRIPT := $(call PARSE_BOARD,$(BOARD_TAG),build.openocdscript) -# TODO Hard defines Cortex M0 math lib - should be dynamic -LDFLAGS += --specs=nano.specs --specs=nosys.specs -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--start-group -L$(LIB_PATH) -larm_cortexM0l_math -lm LINKER_SCRIPTS := -T$(ALTERNATE_CORE_PATH)/variants/$(VARIANT)/$(BOARD_LINKER_SCRIPT) OTHER_LIBS := $(call PARSE_BOARD,$(BOARD_TAG),build.flags.libs) +# Due and SAMD boards have different flags/chip specific libs +ifeq ($(findstring arduino_due, $(strip $(VARIANT))), arduino_due) + CPPFLAGS += -Dprintf=iprintf -DARDUINO_SAM_DUE + LDFLAGS += -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--start-group -u _sbrk -u link -u _close -u _fstat -u _isatty -u _lseek -u _read -u _write -u _exit -u kill -u _getpid + LDFLAGS += -L$(LIB_PATH) -lm # -larm_cortexM3l_math # IDE doesn't include Cortex-M3 math lib on Due for some reason + OTHER_LIBS += $(ALTERNATE_CORE_PATH)/variants/$(VARIANT)/libsam_sam3x8e_gcc_rel.a +else + LDFLAGS += --specs=nano.specs --specs=nosys.specs -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--start-group + LDFLAGS += -larm_cortexM0l_math -L$(LIB_PATH) -lm +endif + # OpenOCD reset command only for now ifeq ($(strip $(UPLOAD_TOOL)), openocd) RESET_CMD = $(OPENOCD) $(OPENOCD_OPTS) -c "telnet_port disabled; init; targets; reset run; shutdown" @@ -479,3 +524,5 @@ endif $(call show_separator) $(call arduino_output,Arduino.mk Configuration:) include $(ARDMK_DIR)/Arduino.mk + +print-% : ; @echo $* = $($*) diff --git a/examples/DueBlink/DueBlink.ino b/examples/DueBlink/DueBlink.ino new file mode 100644 index 0000000..f9a59a9 --- /dev/null +++ b/examples/DueBlink/DueBlink.ino @@ -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/DueBlink/Makefile b/examples/DueBlink/Makefile new file mode 100644 index 0000000..8a7ad6e --- /dev/null +++ b/examples/DueBlink/Makefile @@ -0,0 +1,19 @@ +# Arduino Due uses SAM3X8E SAM chip +BOARD_TAG = arduino_due_x +ARCHITECTURE = sam + +# Define ARM toolchain dir if not using Arduino supplied +#ARM_TOOLS_DIR = /usr + +# Define AVR toolchain dir if not using Arduino supplied and using native port +#AVR_TOOLS_DIR = /usr + +# Define Arduino support package installation path where SAM device support has been installed +# Linux +#ARDUINO_PACKAGE_DIR := $(HOME)/.arduino15/packages +# macOS +#ARDUINO_PACKAGE_DIR := $(HOME)/Library/Arduino15/packages +# Windows +#ARDUINO_PACKAGE_DIR := "C:/Users/$(USER)/AppData/Local/Arduino15/packages" + +include ../../Sam.mk diff --git a/tests/script/runtests.sh b/tests/script/runtests.sh index 648a0cf..60ee73e 100755 --- a/tests/script/runtests.sh +++ b/tests/script/runtests.sh @@ -7,7 +7,7 @@ failures=() # These examples cannot be tested easily at the moment as they require # alternate cores. The MakefileExample doesn't actually contain any source code # to compile. -NON_TESTABLE_EXAMPLES=(ATtinyBlink MakefileExample TinySoftWareSerial BlinkOpenCM BlinkTeensy BlinkNetworkRPi BlinkInAVRC MZeroBlink ZeroBlink) +NON_TESTABLE_EXAMPLES=(ATtinyBlink MakefileExample TinySoftWareSerial BlinkOpenCM BlinkTeensy BlinkNetworkRPi BlinkInAVRC MZeroBlink ZeroBlink DueBlink) for dir in $TESTS_DIR/*/ do