From 03fc4d31d0fdfae8b0e770726cfbbbef03c3a111 Mon Sep 17 00:00:00 2001
From: Marcio Teixeira <marcio@alephobjects.com>
Date: Fri, 5 Oct 2018 15:06:11 -0600
Subject: [PATCH] Makefile support for 32-bit Archim board and new TMC library
 (#11997)

* Support new TMC library and 32-bit Archim board

- Added IS_MCU flag
  - When IS_MCU flag is 1, AVR compiler will be used
  - When IS_MCU flag is 0, ARM compiler will be used
- Added support for new TMC library
- Added support for a 32-bit Archim board, which could probably be used as a basis for other 32-bit boards.
---
 Marlin/Makefile | 417 +++++++++++++++++++++++++++---------------------
 1 file changed, 239 insertions(+), 178 deletions(-)

diff --git a/Marlin/Makefile b/Marlin/Makefile
index da3897e807..095944138f 100644
--- a/Marlin/Makefile
+++ b/Marlin/Makefile
@@ -89,8 +89,8 @@ WIRE               ?= 0
 # this defines if U8GLIB is needed (may require RELOC_WORKAROUND)
 U8GLIB             ?= 1
 
-# this defines whether to include the Trinamic TMC2630Stepper
-TMC2630            ?= 1
+# this defines whether to include the Trinamic TMCStepper library
+TMC                ?= 1
 
 ############
 # Try to automatically determine whether RELOC_WORKAROUND is needed based
@@ -103,7 +103,7 @@ CC_PATCHLEVEL:=$(shell $(CC) -dM -E - < /dev/null | grep __GNUC_PATCHLEVEL__ | c
 CC_VER:=$(shell echo $$(( $(CC_MAJ) * 10000 + $(CC_MIN) * 100 + $(CC_PATCHLEVEL) )))
 ifeq ($(shell test $(CC_VER) -lt 40901 && echo 1),1)
   @echo This version of GCC is likely broken. Enabling relocation workaround.
-	RELOC_WORKAROUND = 1
+  RELOC_WORKAROUND = 1
 endif
 
 ############################################################################
@@ -195,7 +195,7 @@ else ifeq ($(HARDWARE_MOTHERBOARD),49)
 else ifeq ($(HARDWARE_MOTHERBOARD),7)
 # Ultimaker (Older electronics. Pre 1.5.4. This is rare)
 else ifeq ($(HARDWARE_MOTHERBOARD),71)
-MCU ?= atmega1280
+  MCU ?= atmega1280
 # Azteeg X3
 else ifeq ($(HARDWARE_MOTHERBOARD),67)
 # Azteeg X3 Pro
@@ -265,9 +265,9 @@ else ifeq ($(HARDWARE_MOTHERBOARD),75)
 #
 
 else ifeq ($(HARDWARE_MOTHERBOARD),702)
-MCU              ?= atmega1281
+  MCU              ?= atmega1281
 else ifeq ($(HARDWARE_MOTHERBOARD),25)
-MCU              ?= atmega1281
+  MCU              ?= atmega1281
 
 #
 # Sanguinololu and Derivatives - ATmega644P, ATmega1284P
@@ -275,44 +275,44 @@ MCU              ?= atmega1281
 
 # Sanguinololu < 1.2
 else ifeq ($(HARDWARE_MOTHERBOARD),6)
-HARDWARE_VARIANT ?= Sanguino
-MCU              ?= atmega644p
+  HARDWARE_VARIANT ?= Sanguino
+  MCU              ?= atmega644p
 # Sanguinololu 1.2 and above
 else ifeq ($(HARDWARE_MOTHERBOARD),62)
-HARDWARE_VARIANT ?= Sanguino
-MCU              ?= atmega644p
+  HARDWARE_VARIANT ?= Sanguino
+  MCU              ?= atmega644p
 # Melzi
 else ifeq ($(HARDWARE_MOTHERBOARD),63)
-HARDWARE_VARIANT ?= Sanguino
-MCU              ?= atmega644p
+  HARDWARE_VARIANT ?= Sanguino
+  MCU              ?= atmega644p
 # Melzi with ATmega1284 (MaKr3d version)
 else ifeq ($(HARDWARE_MOTHERBOARD),66)
-HARDWARE_VARIANT ?= Sanguino
-MCU              ?= atmega1284p
+  HARDWARE_VARIANT ?= Sanguino
+  MCU              ?= atmega1284p
 # Melzi Creality3D board (for CR-10 etc)
 else ifeq ($(HARDWARE_MOTHERBOARD),89)
-HARDWARE_VARIANT ?= Sanguino
-MCU              ?= atmega1284p
+  HARDWARE_VARIANT ?= Sanguino
+  MCU              ?= atmega1284p
 # Melzi Malyan M150 board
 else ifeq ($(HARDWARE_MOTHERBOARD),92)
-HARDWARE_VARIANT ?= Sanguino
-MCU              ?= atmega1284p
+  HARDWARE_VARIANT ?= Sanguino
+  MCU              ?= atmega1284p
 # Tronxy X5S
 else ifeq ($(HARDWARE_MOTHERBOARD),505)
-HARDWARE_VARIANT ?= Sanguino
-MCU              ?= atmega1284p
+  HARDWARE_VARIANT ?= Sanguino
+  MCU              ?= atmega1284p
 # STB V1.1
 else ifeq ($(HARDWARE_MOTHERBOARD),64)
-HARDWARE_VARIANT ?= Sanguino
-MCU              ?= atmega1284p
+  HARDWARE_VARIANT ?= Sanguino
+  MCU              ?= atmega1284p
 # Azteeg X1
 else ifeq ($(HARDWARE_MOTHERBOARD),65)
-HARDWARE_VARIANT ?= Sanguino
-MCU              ?= atmega1284p
+  HARDWARE_VARIANT ?= Sanguino
+  MCU              ?= atmega1284p
 # Anet 1.0 (Melzi clone)
 else ifeq ($(HARDWARE_MOTHERBOARD),69)
-HARDWARE_VARIANT ?= Sanguino
-MCU              ?= atmega1284p
+  HARDWARE_VARIANT ?= Sanguino
+  MCU              ?= atmega1284p
 
 #
 # Other ATmega644P, ATmega644, ATmega1284P
@@ -320,52 +320,52 @@ MCU              ?= atmega1284p
 
 # Gen3 Monolithic Electronics
 else ifeq ($(HARDWARE_MOTHERBOARD),22)
-HARDWARE_VARIANT ?= Sanguino
-MCU              ?= atmega644p
+  HARDWARE_VARIANT ?= Sanguino
+  MCU              ?= atmega644p
 # Gen3+
 else ifeq ($(HARDWARE_MOTHERBOARD),9)
-HARDWARE_VARIANT ?= Sanguino
-MCU              ?= atmega644p
+  HARDWARE_VARIANT ?= Sanguino
+  MCU              ?= atmega644p
 # Gen6
 else ifeq ($(HARDWARE_MOTHERBOARD),5)
-HARDWARE_VARIANT ?= Gen6
-MCU              ?= atmega644p
+  HARDWARE_VARIANT ?= Gen6
+  MCU              ?= atmega644p
 # Gen6 deluxe
 else ifeq ($(HARDWARE_MOTHERBOARD),51)
-HARDWARE_VARIANT ?= Gen6
-MCU              ?= atmega644p
+  HARDWARE_VARIANT ?= Gen6
+  MCU              ?= atmega644p
 # Gen7 custom (Alfons3 Version)
 else ifeq ($(HARDWARE_MOTHERBOARD),10)
-HARDWARE_VARIANT ?= Gen7
-MCU              ?= atmega644
-F_CPU            ?= 20000000
+  HARDWARE_VARIANT ?= Gen7
+  MCU              ?= atmega644
+  F_CPU            ?= 20000000
 # Gen7 v1.1, v1.2
 else ifeq ($(HARDWARE_MOTHERBOARD),11)
-HARDWARE_VARIANT ?= Gen7
-MCU              ?= atmega644p
-F_CPU            ?= 20000000
+  HARDWARE_VARIANT ?= Gen7
+  MCU              ?= atmega644p
+  F_CPU            ?= 20000000
 # Gen7 v1.3
 else ifeq ($(HARDWARE_MOTHERBOARD),12)
-HARDWARE_VARIANT ?= Gen7
-MCU              ?= atmega644p
-F_CPU            ?= 20000000
+  HARDWARE_VARIANT ?= Gen7
+  MCU              ?= atmega644p
+  F_CPU            ?= 20000000
 # Gen7 v1.4
 else ifeq ($(HARDWARE_MOTHERBOARD),13)
-HARDWARE_VARIANT ?= Gen7
-MCU              ?= atmega1284p
-F_CPU            ?= 20000000
+  HARDWARE_VARIANT ?= Gen7
+  MCU              ?= atmega1284p
+  F_CPU            ?= 20000000
 # Alpha OMCA board
 else ifeq ($(HARDWARE_MOTHERBOARD),90)
-HARDWARE_VARIANT ?= SanguinoA
-MCU              ?= atmega644
+  HARDWARE_VARIANT ?= SanguinoA
+  MCU              ?= atmega644
 # Final OMCA board
 else ifeq ($(HARDWARE_MOTHERBOARD),91)
-HARDWARE_VARIANT ?= Sanguino
-MCU              ?= atmega644p
+  HARDWARE_VARIANT ?= Sanguino
+  MCU              ?= atmega644p
 # Sethi 3D_1
 else ifeq ($(HARDWARE_MOTHERBOARD),20)
-HARDWARE_VARIANT ?= Sanguino
-MCU              ?= atmega644p
+  HARDWARE_VARIANT ?= Sanguino
+  MCU              ?= atmega644p
 
 #
 # Teensyduino - AT90USB1286, AT90USB1286P
@@ -373,37 +373,43 @@ MCU              ?= atmega644p
 
 # Teensylu
 else ifeq ($(HARDWARE_MOTHERBOARD),8)
-HARDWARE_VARIANT ?= Teensy
-MCU              ?= at90usb1286
+  HARDWARE_VARIANT ?= Teensy
+  MCU              ?= at90usb1286
 # Printrboard (AT90USB1286)
 else ifeq ($(HARDWARE_MOTHERBOARD),81)
-HARDWARE_VARIANT ?= Teensy
-MCU              ?= at90usb1286
+  HARDWARE_VARIANT ?= Teensy
+  MCU              ?= at90usb1286
 # Printrboard Revision F (AT90USB1286)
 else ifeq ($(HARDWARE_MOTHERBOARD),811)
-HARDWARE_VARIANT ?= Teensy
-MCU              ?= at90usb1286
+  HARDWARE_VARIANT ?= Teensy
+  MCU              ?= at90usb1286
 # Brainwave (AT90USB646)
 else ifeq ($(HARDWARE_MOTHERBOARD),82)
-HARDWARE_VARIANT ?= Teensy
-MCU              ?= at90usb646
+  HARDWARE_VARIANT ?= Teensy
+  MCU              ?= at90usb646
 # Brainwave Pro (AT90USB1286)
 else ifeq ($(HARDWARE_MOTHERBOARD),83)
-HARDWARE_VARIANT ?= Teensy
-MCU              ?= at90usb1286
+  HARDWARE_VARIANT ?= Teensy
+  MCU              ?= at90usb1286
 # SAV Mk-I (AT90USB1286)
 else ifeq ($(HARDWARE_MOTHERBOARD),84)
-HARDWARE_VARIANT ?= Teensy
-MCU              ?= at90usb1286
+  HARDWARE_VARIANT ?= Teensy
+  MCU              ?= at90usb1286
 # Teensy++2.0 (AT90USB1286)
 else ifeq ($(HARDWARE_MOTHERBOARD),85)
-HARDWARE_VARIANT ?= Teensy
-MCU              ?= at90usb1286
+  HARDWARE_VARIANT ?= Teensy
+  MCU              ?= at90usb1286
 # 5DPrint D8 Driver Board
 else ifeq ($(HARDWARE_MOTHERBOARD),88)
-HARDWARE_VARIANT ?= Teensy
-MCU              ?= at90usb1286
+  HARDWARE_VARIANT ?= Teensy
+  MCU              ?= at90usb1286
 
+# UltiMachine Archim2 (with TMC2130 drivers)
+else ifeq ($(HARDWARE_MOTHERBOARD),1590)
+  HARDWARE_VARIANT ?= archim
+  MCPU              = cortex-m3
+  F_CPU             = 84000000L
+  IS_MCU            = 0
 endif
 
 # Be sure to regenerate speed_lookuptable.h with create_speed_lookuptable.py
@@ -411,9 +417,22 @@ endif
 # Set to 16Mhz if not yet set.
 F_CPU ?= 16000000
 
-# Set to arduino, ATmega2560 if not yet set.
-HARDWARE_VARIANT ?= arduino
-MCU ?= atmega2560
+# Set to microcontroller if IS_MCU not yet set
+IS_MCU ?= 1
+
+ifeq ($(IS_MCU),1)
+  # Set to arduino, ATmega2560 if not yet set.
+  HARDWARE_VARIANT ?= arduino
+  MCU ?= atmega2560
+
+  TOOL_PREFIX = avr
+  MCU_FLAGS   = -mmcu=$(MCU)
+  SIZE_FLAGS  = --mcu=$(MCU) -C
+else
+  TOOL_PREFIX = arm-none-eabi
+  CPU_FLAGS   = -mthumb -mcpu=$(MCPU)
+  SIZE_FLAGS  = -A
+endif
 
 # Arduino contained the main source code for the Arduino
 # Libraries, the "hardware variant" are for boards
@@ -434,19 +453,19 @@ VPATH = .
 VPATH += $(BUILD_DIR)
 VPATH += $(HARDWARE_SRC)
 
-# U8glib
-VPATH += $(ARDUINO_USER_DIR)/libraries/U8glib
-VPATH += $(ARDUINO_USER_DIR)/libraries/U8glib/clib
-
 ifeq ($(HARDWARE_VARIANT), $(filter $(HARDWARE_VARIANT),arduino Teensy Sanguino))
 VPATH += $(ARDUINO_INSTALL_DIR)/hardware/marlin/avr/libraries/LiquidCrystal/src
 VPATH += $(ARDUINO_INSTALL_DIR)/hardware/marlin/avr/libraries/SPI
 endif
 
-VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/cores/arduino
+ifeq ($(IS_MCU),1)
+  VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/cores/arduino
+
+  VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI
+  VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI/src
+  VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SoftwareSerial/src
+endif
 
-VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI
-VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI/src
 VPATH += $(ARDUINO_INSTALL_DIR)/libraries/LiquidCrystal/src
 ifeq ($(LIQUID_TWI2), 1)
 VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire
@@ -462,71 +481,89 @@ VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Adafruit_NeoPixel
 endif
 ifeq ($(U8GLIB), 1)
 VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib
-VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib/clib
+VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib/csrc
+VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib/cppsrc
+VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib/fntsrc
 endif
-ifeq ($(TMC2630), 1)
-VPATH += $(ARDUINO_INSTALL_DIR)/libraries/TMC2130Stepper/src
-VPATH += $(ARDUINO_INSTALL_DIR)/libraries/TMC2130Stepper/src/source
+ifeq ($(TMC), 1)
+VPATH += $(ARDUINO_INSTALL_DIR)/libraries/TMCStepper/src
+VPATH += $(ARDUINO_INSTALL_DIR)/libraries/TMCStepper/src/source
 endif
 
 ifeq ($(HARDWARE_VARIANT), arduino)
-HARDWARE_SUB_VARIANT ?= mega
-VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/variants/$(HARDWARE_SUB_VARIANT)
+  HARDWARE_SUB_VARIANT ?= mega
+  VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/variants/$(HARDWARE_SUB_VARIANT)
+else ifeq ($(HARDWARE_VARIANT), Sanguino)
+  VPATH += $(ARDUINO_INSTALL_DIR)/hardware/marlin/avr/variants/sanguino
+else ifeq ($(HARDWARE_VARIANT), archim)
+  VPATH   += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/system/libsam
+  VPATH   += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/system/CMSIS/CMSIS/Include/
+  VPATH   += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/system/CMSIS/Device/ATMEL/
+  VPATH   += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/cores/arduino
+  VPATH   += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/cores/arduino/avr
+  VPATH   += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/cores/arduino/USB
+  VPATH   += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/libraries/Wire/src
+  VPATH   += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/libraries/SPI/src
+  VPATH   += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/variants/archim
+  LDSCRIPT = $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/variants/archim/linker_scripts/gcc/flash.ld
+  LDLIBS   = $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/variants/archim/libsam_sam3x8e_gcc_rel.a
 else
-ifeq ($(HARDWARE_VARIANT), Sanguino)
-VPATH += $(ARDUINO_INSTALL_DIR)/hardware/marlin/avr/variants/sanguino
-else
-HARDWARE_SUB_VARIANT ?= standard
-VPATH += $(ARDUINO_INSTALL_DIR)/hardware/$(HARDWARE_VARIANT)/variants/$(HARDWARE_SUB_VARIANT)
-endif
+  HARDWARE_SUB_VARIANT ?= standard
+  VPATH += $(ARDUINO_INSTALL_DIR)/hardware/$(HARDWARE_VARIANT)/variants/$(HARDWARE_SUB_VARIANT)
 endif
+
 LIB_SRC = wiring.c \
-	wiring_analog.c wiring_digital.c \
-	wiring_pulse.c \
-	wiring_shift.c WInterrupts.c hooks.c
+  wiring_analog.c wiring_digital.c \
+  wiring_shift.c WInterrupts.c hooks.c
+
+ifeq ($(HARDWARE_VARIANT), archim)
+  LIB_ASRC += wiring_pulse_asm.S
+else
+  LIB_SRC += wiring_pulse.c
+endif
 
 ifeq ($(HARDWARE_VARIANT), Teensy)
-LIB_SRC = wiring.c
-VPATH += $(ARDUINO_INSTALL_DIR)/hardware/teensy/cores/teensy
+  LIB_SRC = wiring.c
+  VPATH += $(ARDUINO_INSTALL_DIR)/hardware/teensy/cores/teensy
 endif
 
-LIB_CXXSRC = WMath.cpp WString.cpp Print.cpp SPI.cpp Tone.cpp
+LIB_CXXSRC = WMath.cpp WString.cpp Print.cpp SPI.cpp
 
 ifeq ($(NEOPIXEL), 1)
-LIB_CXXSRC += Adafruit_NeoPixel.cpp
+  LIB_CXXSRC += Adafruit_NeoPixel.cpp
 endif
 
 ifeq ($(LIQUID_TWI2), 0)
-LIB_CXXSRC += LiquidCrystal.cpp
+  LIB_CXXSRC += LiquidCrystal.cpp
 else
-LIB_SRC += twi.c
-LIB_CXXSRC += Wire.cpp LiquidTWI2.cpp
+  LIB_SRC += twi.c
+  LIB_CXXSRC += Wire.cpp LiquidTWI2.cpp
 endif
 
 ifeq ($(WIRE), 1)
-LIB_SRC += twi.c
-LIB_CXXSRC += Wire.cpp
+  LIB_SRC += twi.c
+  LIB_CXXSRC += Wire.cpp
 endif
 
 ifeq ($(U8GLIB), 1)
-LIB_CXXSRC += U8glib.cpp
-LIB_SRC += u8g_ll_api.c u8g_bitmap.c u8g_clip.c u8g_com_null.c u8g_delay.c u8g_page.c u8g_pb.c u8g_pb16h1.c u8g_rect.c u8g_state.c u8g_font.c u8g_font_data.c
+  LIB_CXXSRC += U8glib.cpp
+  LIB_SRC += u8g_ll_api.c u8g_bitmap.c u8g_clip.c u8g_com_null.c u8g_delay.c u8g_page.c u8g_pb.c u8g_pb16h1.c u8g_rect.c u8g_state.c u8g_font.c u8g_font_6x13.c u8g_font_04b_03.c u8g_font_5x8.c
 endif
 
-ifeq ($(TMC2630), 1)
-LIB_CXXSRC += TMC2130Stepper.cpp TMC2130Stepper_COOLCONF.cpp TMC2130Stepper_DRV_STATUS.cpp TMC2130Stepper_IHOLD_IRUN.cpp TMC2130Stepper_CHOPCONF.cpp TMC2130Stepper_GCONF.cpp  TMC2130Stepper_PWMCONF.cpp SW_SPI.cpp
+ifeq ($(TMC), 1)
+  LIB_CXXSRC += TMCStepper.cpp COOLCONF.cpp DRV_STATUS.cpp IHOLD_IRUN.cpp CHOPCONF.cpp  GCONF.cpp PWMCONF.cpp DRV_CONF.cpp DRVCONF.cpp DRVCTRL.cpp DRVSTATUS.cpp ENCMODE.cpp  RAMP_STAT.cpp SGCSCONF.cpp SHORT_CONF.cpp SMARTEN.cpp SW_MODE.cpp SW_SPI.cpp TMC2130Stepper.cpp TMC2208Stepper.cpp TMC2660Stepper.cpp TMC5130Stepper.cpp TMC5160Stepper.cpp
 endif
 
 ifeq ($(RELOC_WORKAROUND), 1)
-LD_PREFIX=-nodefaultlibs
-LD_SUFFIX=-lm -lgcc -lc -lgcc
+  LD_PREFIX=-nodefaultlibs
+  LD_SUFFIX=-lm -lgcc -lc -lgcc
 endif
 
 #Check for Arduino 1.0.0 or higher and use the correct source files for that version
 ifeq ($(shell [ $(ARDUINO_VERSION) -ge 100 ] && echo true), true)
-LIB_CXXSRC += main.cpp
+  LIB_CXXSRC += main.cpp
 else
-LIB_SRC += pins_arduino.c main.c
+  LIB_SRC += pins_arduino.c main.c
 endif
 
 FORMAT = ihex
@@ -544,62 +581,77 @@ OPT = s
 DEFINES ?=
 
 # Program settings
-CC = $(AVR_TOOLS_PATH)avr-gcc
-CXX = $(AVR_TOOLS_PATH)avr-g++
-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)$(TOOL_PREFIX)-gcc
+CXX = $(AVR_TOOLS_PATH)$(TOOL_PREFIX)-g++
+OBJCOPY = $(AVR_TOOLS_PATH)$(TOOL_PREFIX)-objcopy
+OBJDUMP = $(AVR_TOOLS_PATH)$(TOOL_PREFIX)-objdump
+AR  = $(AVR_TOOLS_PATH)$(TOOL_PREFIX)-ar
+SIZE = $(AVR_TOOLS_PATH)$(TOOL_PREFIX)-size
+NM = $(AVR_TOOLS_PATH)$(TOOL_PREFIX)-nm
 AVRDUDE = avrdude
 REMOVE = rm -f
 MV = mv -f
 
 # Place -D or -U options here
-CDEFS    = -DF_CPU=$(F_CPU) ${addprefix -D , $(DEFINES)}
+CDEFS    = -DF_CPU=$(F_CPU) ${addprefix -D , $(DEFINES)} -DARDUINO=$(ARDUINO_VERSION)
 CXXDEFS  = $(CDEFS)
 
 ifeq ($(HARDWARE_VARIANT), Teensy)
-CDEFS  += -DUSB_SERIAL
-LIB_SRC    += usb.c pins_teensy.c
-LIB_CXXSRC += usb_api.cpp
+  CDEFS  += -DUSB_SERIAL
+  LIB_SRC    += usb.c pins_teensy.c
+  LIB_CXXSRC += usb_api.cpp
+
+else ifeq ($(HARDWARE_VARIANT), archim)
+  CDEFS      += -DARDUINO_SAM_ARCHIM -DARDUINO_ARCH_SAM -D__SAM3X8E__ -DUSB_VID=0x27b1 -DUSB_PID=0x0001 -DUSBCON '-DUSB_MANUFACTURER="UltiMachine"' '-DUSB_PRODUCT="Archim"'
+  LIB_CXXSRC += variant.cpp IPAddress.cpp Reset.cpp RingBuffer.cpp Stream.cpp UARTClass.cpp  USARTClass.cpp abi.cpp new.cpp watchdog.cpp CDC.cpp PluggableUSB.cpp  USBCore.cpp
+  LIB_SRC    += cortex_handlers.c iar_calls_sam3.c syscalls_sam3.c dtostrf.c itoa.c
 endif
 
 # Add all the source directories as include directories too
 CINCS = ${addprefix -I ,${VPATH}}
 CXXINCS = ${addprefix -I ,${VPATH}}
 
+# Silence warnings for library code (won't work for .h files, unfortunately)
+LIBWARN = -w -Wno-packed-bitfield-compat
+
 # Compiler flag to set the C/CPP Standard level.
 CSTANDARD = -std=gnu99
 CXXSTANDARD = -std=gnu++11
 CDEBUG = -g$(DEBUG)
-CWARN = -Wall -Wstrict-prototypes
-CTUNING = -w -fsigned-char -funsigned-bitfields -fpack-struct \
-	-fshort-enums -ffunction-sections -fdata-sections -flto \
-	-DARDUINO=$(ARDUINO_VERSION)
+CWARN   = -Wall -Wstrict-prototypes -Wno-packed-bitfield-compat -Wno-pragmas
+CXXWARN = -Wall                     -Wno-packed-bitfield-compat -Wno-pragmas
+CTUNING = -fsigned-char -funsigned-bitfields -fpack-struct -fno-exceptions \
+          -fshort-enums -ffunction-sections -fdata-sections
 ifneq ($(HARDWARE_MOTHERBOARD),)
-CTUNING += -DMOTHERBOARD=${HARDWARE_MOTHERBOARD}
+  CTUNING += -DMOTHERBOARD=${HARDWARE_MOTHERBOARD}
 endif
 #CEXTRA = -Wa,-adhlns=$(<:.c=.lst)
-CEXTRA = -fno-use-cxa-atexit -fno-threadsafe-statics
-
-CFLAGS := $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CEXTRA) $(CTUNING) $(CSTANDARD)
-CXXFLAGS :=         $(CDEFS) $(CINCS) -O$(OPT) -Wall    $(CEXTRA) $(CTUNING) $(CXXSTANDARD)
+CXXEXTRA = -fno-use-cxa-atexit -fno-threadsafe-statics -fno-rtti
+CFLAGS := $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CEXTRA)   $(CTUNING) $(CSTANDARD)
+CXXFLAGS :=         $(CDEFS) $(CINCS) -O$(OPT) $(CXXEXTRA) $(CTUNING) $(CXXSTANDARD)
+ASFLAGS :=          $(CDEFS)
 #ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
-LDFLAGS = -lm
-
+ifeq ($(HARDWARE_VARIANT), archim)
+  LD_PREFIX = -Wl,--gc-sections,-Map,Marlin.ino.map,--cref,--check-sections,--entry=Reset_Handler,--unresolved-symbols=report-all,--warn-common,--warn-section-align
+  LD_SUFFIX = $(LDLIBS)
+  LDFLAGS   = -lm -gcc -T$(LDSCRIPT) -u _sbrk -u link -u _close -u _fstat -u _isatty -u _lseek -u _read -u _write -u _exit -u kill -u _getpid
+else
+  LD_PREFIX = -Wl,--gc-sections,--relax
+  LDFLAGS   = -lm
+  CTUNING   += -flto
+endif
 
 # Programming support using avrdude. Settings and variables.
 AVRDUDE_PORT = $(UPLOAD_PORT)
 AVRDUDE_WRITE_FLASH = -Uflash:w:$(BUILD_DIR)/$(TARGET).hex:i
 ifeq ($(shell uname -s), Linux)
-AVRDUDE_CONF = /etc/avrdude/avrdude.conf
+  AVRDUDE_CONF = /etc/avrdude/avrdude.conf
 else
-AVRDUDE_CONF = $(ARDUINO_INSTALL_DIR)/hardware/tools/avr/etc/avrdude.conf
+  AVRDUDE_CONF = $(ARDUINO_INSTALL_DIR)/hardware/tools/avr/etc/avrdude.conf
 endif
 AVRDUDE_FLAGS = -D -C$(AVRDUDE_CONF) \
-	-p$(MCU) -P$(AVRDUDE_PORT) -c$(AVRDUDE_PROGRAMMER) \
-	-b$(UPLOAD_RATE)
+  -p$(MCU) -P$(AVRDUDE_PORT) -c$(AVRDUDE_PROGRAMMER) \
+  -b$(UPLOAD_RATE)
 
 # Since Marlin 2.0, the source files may be distributed into several
 # different directories, so it is necessary to find them recursively
@@ -619,17 +671,17 @@ LST = $(LIB_ASRC:.S=.lst) $(LIB_CXXSRC:.cpp=.lst) $(LIB_SRC:.c=.lst)
 
 # Combine all necessary flags and optional flags.
 # Add target processor to flags.
-ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
-ALL_CXXFLAGS = -mmcu=$(MCU) $(CXXFLAGS)
-ALL_ASFLAGS = -mmcu=$(MCU) -x assembler-with-cpp $(ASFLAGS)
+ALL_CFLAGS   = $(MCU_FLAGS) $(CPU_FLAGS) $(CFLAGS) -I.
+ALL_CXXFLAGS = $(MCU_FLAGS) $(CPU_FLAGS) $(CXXFLAGS)
+ALL_ASFLAGS  = $(MCU_FLAGS) $(CPU_FLAGS) $(ASFLAGS) -x assembler-with-cpp
 
 # set V=1 (eg, "make V=1") to print the full commands etc.
 ifneq ($V,1)
- Pecho=@echo
- P=@
+  Pecho=@echo
+  P=@
 else
- Pecho=@:
- P=
+  Pecho=@:
+  P=
 endif
 
 # Create required build hierarchy if it does not exist
@@ -639,9 +691,10 @@ $(shell mkdir -p $(dir $(OBJ)))
 # Default target.
 all: sizeafter
 
-build: elf hex
+build: elf hex bin
 
 elf: $(BUILD_DIR)/$(TARGET).elf
+bin: $(BUILD_DIR)/$(TARGET).bin
 hex: $(BUILD_DIR)/$(TARGET).hex
 eep: $(BUILD_DIR)/$(TARGET).eep
 lss: $(BUILD_DIR)/$(TARGET).lss
@@ -651,93 +704,101 @@ sym: $(BUILD_DIR)/$(TARGET).sym
 # Do not try to reset an Arduino if it's not one
 upload: $(BUILD_DIR)/$(TARGET).hex
 ifeq (${AVRDUDE_PROGRAMMER}, arduino)
-	stty hup < $(UPLOAD_PORT); true
+  stty hup < $(UPLOAD_PORT); true
 endif
-	$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)
+  $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)
 ifeq (${AVRDUDE_PROGRAMMER}, arduino)
-	stty -hup < $(UPLOAD_PORT); true
+  stty -hup < $(UPLOAD_PORT); true
 endif
 
-	# Display size of file.
+  # Display size of file.
 HEXSIZE = $(SIZE) --target=$(FORMAT) $(BUILD_DIR)/$(TARGET).hex
-ELFSIZE = $(SIZE) --mcu=$(MCU) -C $(BUILD_DIR)/$(TARGET).elf; \
+ELFSIZE = $(SIZE)  $(SIZE_FLAGS) $(BUILD_DIR)/$(TARGET).elf; \
           $(SIZE)  $(BUILD_DIR)/$(TARGET).elf
 sizebefore:
-	$P if [ -f $(BUILD_DIR)/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(HEXSIZE); echo; fi
+  $P if [ -f $(BUILD_DIR)/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(HEXSIZE); echo; fi
 
 sizeafter: build
-	$P if [ -f $(BUILD_DIR)/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi
+  $P if [ -f $(BUILD_DIR)/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi
 
 
 # Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
 COFFCONVERT=$(OBJCOPY) --debugging \
-	--change-section-address .data-0x800000 \
-	--change-section-address .bss-0x800000 \
-	--change-section-address .noinit-0x800000 \
-	--change-section-address .eeprom-0x810000
+  --change-section-address .data-0x800000 \
+  --change-section-address .bss-0x800000 \
+  --change-section-address .noinit-0x800000 \
+  --change-section-address .eeprom-0x810000
 
 
 coff: $(BUILD_DIR)/$(TARGET).elf
-	$(COFFCONVERT) -O coff-avr $(BUILD_DIR)/$(TARGET).elf $(TARGET).cof
+  $(COFFCONVERT) -O coff-avr $(BUILD_DIR)/$(TARGET).elf $(TARGET).cof
 
 
 extcoff: $(TARGET).elf
-	$(COFFCONVERT) -O coff-ext-avr $(BUILD_DIR)/$(TARGET).elf $(TARGET).cof
+  $(COFFCONVERT) -O coff-ext-avr $(BUILD_DIR)/$(TARGET).elf $(TARGET).cof
 
 
-.SUFFIXES: .elf .hex .eep .lss .sym
+.SUFFIXES: .elf .hex .eep .lss .sym .bin
 .PRECIOUS: .o
 
 .elf.hex:
-	$(Pecho) "  COPY  $@"
-	$P $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
+  $(Pecho) "  COPY  $@"
+  $P $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
+
+.elf.bin:
+  $(Pecho) "  COPY  $@"
+  $P $(OBJCOPY) -O binary -R .eeprom $< $@
 
 .elf.eep:
-	-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
-		--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
+  -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
+    --change-section-lma .eeprom=0 -O $(FORMAT) $< $@
 
 # Create extended listing file from ELF output file.
 .elf.lss:
-	$(OBJDUMP) -h -S $< > $@
+  $(OBJDUMP) -h -S $< > $@
 
 # Create a symbol table from ELF output file.
 .elf.sym:
-	$(NM) -n $< > $@
+  $(NM) -n $< > $@
 
-	# Link: create ELF output file from library.
+  # Link: create ELF output file from library.
 
 $(BUILD_DIR)/$(TARGET).elf: $(OBJ) Configuration.h
-	$(Pecho) "  CXX   $@"
-	$P $(CC) $(LD_PREFIX) $(ALL_CXXFLAGS) -Wl,--gc-sections,--relax -o $@ -L. $(OBJ) $(LDFLAGS) $(LD_SUFFIX)
+  $(Pecho) "  CXX   $@"
+  $P $(CC) $(LD_PREFIX) $(ALL_CXXFLAGS) -o $@ -L. $(OBJ) $(LDFLAGS) $(LD_SUFFIX)
 
 # Object files that were found in "src" will be stored in $(BUILD_DIR)
 # in directories that mirror the structure of "src"
 
 $(BUILD_DIR)/%.o: %.c Configuration.h Configuration_adv.h $(MAKEFILE)
-	$(Pecho) "  CC    $<"
-	$P $(CC) -MMD -c $(ALL_CFLAGS) $< -o $@
+  $(Pecho) "  CC    $<"
+  $P $(CC) -MMD -c $(ALL_CFLAGS) $(CWARN) $< -o $@
 
 $(BUILD_DIR)/%.o: %.cpp Configuration.h Configuration_adv.h $(MAKEFILE)
-	$(Pecho) "  CXX   $<"
-	$P $(CXX) -MMD -c $(ALL_CXXFLAGS) $< -o $@
+  $(Pecho) "  CXX   $<"
+  $P $(CXX) -MMD -c $(ALL_CXXFLAGS) $(CXXWARN) $< -o $@
 
 # Object files for Arduino libs will be created in $(BUILD_DIR)/arduino
 
 $(BUILD_DIR)/arduino/%.o: %.c Configuration.h Configuration_adv.h $(MAKEFILE)
-	$(Pecho) "  CC    $<"
-	$P $(CC) -MMD -c $(ALL_CFLAGS) $< -o $@
+  $(Pecho) "  CC    $<"
+  $P $(CC) -MMD -c $(ALL_CFLAGS) $(LIBWARN) $< -o $@
 
 $(BUILD_DIR)/arduino/%.o: %.cpp Configuration.h Configuration_adv.h $(MAKEFILE)
-	$(Pecho) "  CXX   $<"
-	$P $(CXX) -MMD -c $(ALL_CXXFLAGS) $< -o $@
+  $(Pecho) "  CXX   $<"
+  $P $(CXX) -MMD -c $(ALL_CXXFLAGS)  $(LIBWARN) $< -o $@
+
+$(BUILD_DIR)/arduino/%.o: %.S $(MAKEFILE)
+  $(Pecho) "  CXX   $<"
+  $P $(CXX) -MMD -c $(ALL_ASFLAGS) $< -o $@
 
 # Target: clean project.
 clean:
-	$(Pecho) "  RMDIR $(BUILD_DIR)/"
-	$P rm -rf $(BUILD_DIR)
+  $(Pecho) "  RMDIR $(BUILD_DIR)/"
+  $P rm -rf $(BUILD_DIR)
 
 
-.PHONY:	all build elf hex eep lss sym program coff extcoff clean depend sizebefore sizeafter
+.PHONY: all build elf hex eep lss sym program coff extcoff clean depend sizebefore sizeafter
 
 # Automaticaly include the dependency files created by gcc
 -include ${patsubst %.o, %.d, ${OBJ}}