diff --git a/examples/digistump/digitstump-blink/README.rst b/examples/digistump/digitstump-blink/README.rst new file mode 100644 index 00000000..699f2783 --- /dev/null +++ b/examples/digistump/digitstump-blink/README.rst @@ -0,0 +1,21 @@ +How to buid PlatformIO based project +==================================== + +1. `Install PlatformIO `_ +2. Download `source code with examples `_ +3. Extract ZIP archive +4. Run these commands: + +.. code-block:: bash + + # Change directory to example + > cd platformio-develop/examples/digistump/digitstump-blink + + # Process example project + > platformio run + + # Upload firmware + > platformio run --target upload + + # Clean build files + > platformio run --target clean diff --git a/examples/digistump/digitstump-blink/platformio.ini b/examples/digistump/digitstump-blink/platformio.ini new file mode 100644 index 00000000..89ac6161 --- /dev/null +++ b/examples/digistump/digitstump-blink/platformio.ini @@ -0,0 +1,33 @@ +# +# Project Configuration File +# +# A detailed documentation with the EXAMPLES is located here: +# http://docs.platformio.org/en/latest/projectconf.html +# + +# A sign `#` at the beginning of the line indicates a comment +# Comment lines are ignored. + +# Simple and base environment +# [env:mybaseenv] +# platform = %INSTALLED_PLATFORM_NAME_HERE% +# framework = +# board = +# +# Automatic targets - enable auto-uploading +# targets = upload + +[env:digispark-tiny] +platform = digistump +framework = arduino +board = digispark-tiny + +[env:digispark-pro32] +platform = digistump +framework = arduino +board = digispark-pro32 + +[env:digix] +platform = digistump +framework = arduino +board = digix diff --git a/examples/digistump/digitstump-blink/src/Blink.ino b/examples/digistump/digitstump-blink/src/Blink.ino new file mode 100644 index 00000000..b0db92b8 --- /dev/null +++ b/examples/digistump/digitstump-blink/src/Blink.ino @@ -0,0 +1,29 @@ +/* + Blink + Turns on an LED on for one second, then off for one second, repeatedly. + + Most Arduinos have an on-board LED you can control. On the Uno and + Leonardo, it is attached to digital pin 13. If you're unsure what + pin the on-board LED is connected to on your Arduino model, check + the documentation at http://arduino.cc + + This example code is in the public domain. + + modified 8 May 2014 + by Scott Fitzgerald + */ + + +// the setup function runs once when you press reset or power the board +void setup() { + // initialize digital pin 13 as an output. + pinMode(13, OUTPUT); +} + +// the loop function runs over and over again forever +void loop() { + digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level) + delay(1000); // wait for a second + digitalWrite(13, LOW); // turn the LED off by making the voltage LOW + delay(1000); // wait for a second +} diff --git a/platformio/boards/digistump.json b/platformio/boards/digistump.json new file mode 100644 index 00000000..7488579d --- /dev/null +++ b/platformio/boards/digistump.json @@ -0,0 +1,101 @@ +{ + "digispark-tiny": { + "build": { + "core": "digispark_tiny", + "extra_flags": "-DARDUINO_ARCH_AVR -DARDUINO_AVR_DIGISPARK", + "f_cpu": "16000000L", + "mcu": "attiny85", + "variant": "digispark_tiny" + }, + "name": "Digispark (Default - 16.5mhz)", + "platform": "digistump", + "upload": { + "disable_flushing": false, + "maximum_ram_size": 512, + "maximum_size": 14844, + "protocol": "usb", + "use_1200bps_touch": false, + "wait_for_upload_port": false + } + }, + "digispark-pro": { + "build": { + "core": "digispark_pro", + "extra_flags": "-DARDUINO_ARCH_AVR -DARDUINO_AVR_DIGISPARKPRO", + "f_cpu": "16000000L", + "mcu": "attiny167", + "variant": "digispark_pro" + }, + "name": "Digispark Pro (Default 16 Mhz)", + "platform": "digistump", + "upload": { + "disable_flushing": false, + "maximum_ram_size": 512, + "maximum_size": 14844, + "protocol": "usb", + "use_1200bps_touch": false, + "wait_for_upload_port": false + } + }, + "digispark-pro32": { + "build": { + "core": "digispark_pro", + "extra_flags": "-DARDUINO_ARCH_AVR -DARDUINO_AVR_DIGISPARKPRO", + "f_cpu": "16000000L", + "mcu": "attiny167", + "variant": "digispark_pro32" + }, + "name": "Digispark Pro (16 Mhz) (32 byte buffer)", + "platform": "digistump", + "upload": { + "disable_flushing": false, + "maximum_ram_size": 512, + "maximum_size": 14844, + "protocol": "usb", + "use_1200bps_touch": false, + "wait_for_upload_port": false + } + }, + "digispark-pro64": { + "build": { + "core": "digispark_pro", + "extra_flags": "-DARDUINO_ARCH_AVR -DARDUINO_AVR_DIGISPARKPRO", + "f_cpu": "16000000L", + "mcu": "attiny167", + "variant": "digispark_pro64" + }, + "name": "Digispark Pro (16 Mhz) (64 byte buffer)", + "platform": "digistump", + "upload": { + "disable_flushing": false, + "maximum_ram_size": 512, + "maximum_size": 14844, + "protocol": "usb", + "use_1200bps_touch": false, + "wait_for_upload_port": false + } + }, + "digix": { + "build": { + "core": "digispark_digix", + "extra_flags": "-w -D__SAM3X8E__ -DARDUINO_SAM_DIGIX -DARDUINO_ARCH_SAM", + "f_cpu": "84000000L", + "mcu": "cortex-m3", + "ldscript": "sam3x8e.ld", + "pid": "0x078A", + "usb_product": "Digistump DigiX", + "variant": "digispark_digix", + "vid": "0x16D0" + }, + "name": "Digistump DigiX", + "platform": "digistump", + "upload": { + "disable_flushing": false, + "maximum_ram_size": 28672, + "maximum_size": 524288, + "protocol": "sam-ba", + "use_1200bps_touch": true, + "wait_for_upload_port": true + } + } +} \ No newline at end of file diff --git a/platformio/builder/scripts/digistump.py b/platformio/builder/scripts/digistump.py new file mode 100644 index 00000000..8c053827 --- /dev/null +++ b/platformio/builder/scripts/digistump.py @@ -0,0 +1,196 @@ +# Copyright (C) Ivan Kravets +# See LICENSE for details. + +""" + Builder for Digistump boards +""" + +from os.path import join + +from SCons.Script import (COMMAND_LINE_TARGETS, AlwaysBuild, Builder, Default, + DefaultEnvironment) + +env = DefaultEnvironment() + +if env.get("BOARD_OPTIONS", {}).get("build", {}).get("mcu") != "cortex-m3": + env.Replace( + AR="avr-ar", + AS="avr-gcc", + CC="avr-gcc", + CXX="avr-g++", + OBJCOPY="avr-objcopy", + RANLIB="avr-ranlib", + SIZETOOL="avr-size", + + ARFLAGS=["rcs"], + + CPPFLAGS=[ + "-mmcu=$BOARD_MCU" + ], + + LINKFLAGS=[ + "-mmcu=$BOARD_MCU" + ], + + SIZEPRINTCMD='"$SIZETOOL" --mcu=$BOARD_MCU -C -d $SOURCES' + ) + +else: + env.Replace( + AR="arm-none-eabi-ar", + AS="arm-none-eabi-gcc", + CC="arm-none-eabi-gcc", + CXX="arm-none-eabi-g++", + OBJCOPY="arm-none-eabi-objcopy", + RANLIB="arm-none-eabi-ranlib", + SIZETOOL="arm-none-eabi-size", + + ARFLAGS=["rcs"], + + ASFLAGS=[ + "-mcpu=${BOARD_OPTIONS['build']['mcu']}", + "-mthumb" + # "-nostdlib" + ], + + CXXFLAGS=[ + "-fno-rtti", + ], + + CPPFLAGS=[ + "-mcpu=${BOARD_OPTIONS['build']['mcu']}", + "-mthumb", + "-ffunction-sections", # place each function in its own section + "-fdata-sections" + # "-nostdlib" + ], + + CPPDEFINES=[ + "printf=iprintf" + ], + + LINKFLAGS=[ + "-mcpu=cortex-m3", + "-mthumb", + "-Wl,--gc-sections", + "-Wl,--entry=Reset_Handler" + # "-nostartfiles", + # "-nostdlib", + ], + + SIZEPRINTCMD='"$SIZETOOL" -B -d $SOURCES' + ) + +env.Append( + BUILDERS=dict( + ElfToHex=Builder( + action=" ".join([ + "$OBJCOPY", + "-O", + "ihex", + "-R", + ".eeprom", + "$SOURCES", + "$TARGET"]), + suffix=".hex" + ) + ), + + ASFLAGS=[ + "-c", + "-g", # include debugging info (so errors include line numbers) + "-x", "assembler-with-cpp", + "-Wall" + ], + + CPPFLAGS=[ + "-g", # include debugging info (so errors include line numbers) + "-Os", # optimize for size + "-fdata-sections", + "-ffunction-sections", # place each function in its own section + "-Wall", + "-MMD" # output dependancy info + ], + + CPPDEFINES=[ + "F_CPU=$BOARD_F_CPU" + ], + + CXXFLAGS=[ + "-felide-constructors", + "-fno-exceptions" + ], + + LINKFLAGS=[ + "-Os", + "-Wl,--start-group" + + ] +) + +if env.get("BOARD_OPTIONS", {}).get("build", {}).get("mcu") == "cortex-m3": + env.Append( + UPLOADER=join("$PIOPACKAGES_DIR", "$PIOPACKAGE_UPLOADER", "bossac"), + UPLOADERFLAGS=[ + "--info", + "--debug", + "--port", "$UPLOAD_PORT", + "--erase", + "--write", + "--verify", + "--boot" + ], + UPLOADCMD='"$UPLOADER" $UPLOADERFLAGS $SOURCES' + ) +else: + env.Append( + UPLOADER=join("$PIOPACKAGES_DIR", "tool-avrdude", "avrdude"), + UPLOADERFLAGS=[ + "-q", # suppress progress output + "-D", # disable auto erase for flash memory + "-p", "$BOARD_MCU", + "-C", '"%s"' % join("$PIOPACKAGES_DIR", + "tool-avrdude", "avrdude.conf"), + "-c", "$UPLOAD_PROTOCOL", + "-b", "$UPLOAD_SPEED", + "-P", "$UPLOAD_PORT" + ], + UPLOADCMD='"$UPLOADER" $UPLOADERFLAGS -U flash:w:$SOURCES:i' + ) + +CORELIBS = env.ProcessGeneral() + +# +# Target: Build executable and linkable firmware +# + +target_elf = env.BuildFirmware(CORELIBS + ["m"]) + +# +# Target: Build the .hex file +# + +if "uploadlazy" in COMMAND_LINE_TARGETS: + target_hex = join("$BUILD_DIR", "firmware.hex") +else: + target_hex = env.ElfToHex(join("$BUILD_DIR", "firmware"), target_elf) + +# +# Target: Print binary size +# + +target_size = env.Alias("size", target_elf, "$SIZEPRINTCMD") +AlwaysBuild(target_size) + +# +# Target: Upload by default .hex file +# + +upload = env.Alias(["upload", "uploadlazy"], target_hex, ("$UPLOADCMD")) +AlwaysBuild(upload) + +# +# Target: Define targets +# + +Default([target_hex, target_size]) diff --git a/platformio/builder/scripts/frameworks/arduino.py b/platformio/builder/scripts/frameworks/arduino.py index c89b987f..d3a8117e 100644 --- a/platformio/builder/scripts/frameworks/arduino.py +++ b/platformio/builder/scripts/frameworks/arduino.py @@ -5,7 +5,7 @@ Build script for Arduino Framework (based on Wiring). """ -from os import listdir +from os import listdir, walk from os.path import isfile, join from SCons.Script import Import, Return @@ -13,37 +13,89 @@ from SCons.Script import Import, Return env = None Import("env") -env.Replace( - PLATFORMFW_DIR=join( +BOARD_OPTS = env.get("BOARD_OPTIONS", {}) +BOARD_BUILDOPTS = BOARD_OPTS.get("build", {}) + +# +# Determine framework directory +# based on development platform +# + +PLATFORMFW_DIR = join("$PIOPACKAGES_DIR", + "framework-arduino${PLATFORM.replace('atmel', '')}") + +if env.get("PLATFORM") == "digistump": + PLATFORMFW_DIR = join( "$PIOPACKAGES_DIR", - "framework-arduino${PLATFORM.replace('atmel', '')}") + "framework-arduino%s" % ( + "sam" if BOARD_BUILDOPTS.get("mcu") == "cortex-m3" else "avr") + ) + +env.Replace(PLATFORMFW_DIR=PLATFORMFW_DIR) + +# +# Base +# + +ARDUINO_VERSION = int( + open(join(env.subst("$PLATFORMFW_DIR"), + "version.txt")).read().replace(".", "").strip()) + +# usb flags +ARDUINO_USBDEFINES = [] +if "usb_product" in BOARD_BUILDOPTS: + ARDUINO_USBDEFINES = [ + "USB_VID=${BOARD_OPTIONS['build']['vid']}", + "USB_PID=${BOARD_OPTIONS['build']['pid']}", + 'USB_PRODUCT=\\"%s\\"' % (env.subst( + "${BOARD_OPTIONS['build']['usb_product']}").replace('"', "")) + ] + +if env.get("PLATFORM") == "teensy": + ARDUINO_USBDEFINES += [ + "ARDUINO=106", + "TEENSYDUINO=%d" % ARDUINO_VERSION + ] +else: + ARDUINO_USBDEFINES += ["ARDUINO=%d" % ARDUINO_VERSION] + +env.Append( + CPPDEFINES=ARDUINO_USBDEFINES, + + CPPPATH=[ + join("$BUILD_DIR", "FrameworkArduino") + ] ) -BOARD_BUILDOPTS = env.get("BOARD_OPTIONS", {}).get("build", {}) - - # # Atmel SAM platform # -if env.get("BOARD_OPTIONS", {}).get("platform", None) == "atmelsam": +if env.subst("${PLATFORMFW_DIR}")[-3:] == "sam": env.VariantDir( join("$BUILD_DIR", "FrameworkCMSISInc"), join("$PLATFORMFW_DIR", "system", "CMSIS", "CMSIS", "include") ) - env.VariantDir( - join("$BUILD_DIR", "FrameworkLibSamInc"), - join("$PLATFORMFW_DIR", "system", "libsam") - ) env.VariantDir( join("$BUILD_DIR", "FrameworkDeviceInc"), join("$PLATFORMFW_DIR", "system", "CMSIS", "Device", "ATMEL") ) + env.VariantDir( + join("$BUILD_DIR", "FrameworkLibSam"), + join("$PLATFORMFW_DIR", "system", "libsam") + ) + + env.VariantDir( + join("$BUILD_DIR", "FrameworkArduinoInc"), + join("$PLATFORMFW_DIR", "cores", "digix") + ) env.Append( CPPPATH=[ join("$BUILD_DIR", "FrameworkCMSISInc"), - join("$BUILD_DIR", "FrameworkLibSamInc"), - join("$BUILD_DIR", "FrameworkDeviceInc") + join("$BUILD_DIR", "FrameworkLibSam"), + join("$BUILD_DIR", "FrameworkLibSam", "include"), + join("$BUILD_DIR", "FrameworkDeviceInc"), + join("$BUILD_DIR", "FrameworkDeviceInc", "sam3xa", "include") ] ) env.Append( @@ -53,6 +105,25 @@ if env.get("BOARD_OPTIONS", {}).get("platform", None) == "atmelsam": ] ) + # search relative includes in lib SAM directories + core_dir = join(env.subst("$PLATFORMFW_DIR"), "system", "libsam") + for root, _, files in walk(core_dir): + for lib_file in files: + file_path = join(root, lib_file) + if not isfile(file_path): + continue + content = None + content_changed = False + with open(file_path) as fp: + content = fp.read() + if '#include "../' in content: + content_changed = True + content = content.replace('#include "../', '#include "') + if not content_changed: + continue + with open(file_path, "w") as fp: + fp.write(content) + # # Teensy platform # @@ -79,60 +150,39 @@ if BOARD_BUILDOPTS.get("core", None) == "teensy": fp.write(content) # -# Miscellaneous +# Target: Build Core Library # -ARDUINO_VERSION = int( - open(join(env.subst("$PLATFORMFW_DIR"), - "version.txt")).read().replace(".", "").strip()) -# usb flags -ARDUINO_USBDEFINES = [] -if "usb_product" in BOARD_BUILDOPTS: - ARDUINO_USBDEFINES = [ - "USB_VID=${BOARD_OPTIONS['build']['vid']}", - "USB_PID=${BOARD_OPTIONS['build']['pid']}", - 'USB_PRODUCT=\\"%s\\"' % (env.subst( - "${BOARD_OPTIONS['build']['usb_product']}").replace('"', "")) - ] - -if env.get("BOARD_OPTIONS", {}).get("platform", None) == "teensy": - ARDUINO_USBDEFINES += [ - "ARDUINO=106", - "TEENSYDUINO=%d" % ARDUINO_VERSION - ] -else: - ARDUINO_USBDEFINES += ["ARDUINO=%d" % ARDUINO_VERSION] - -env.Append( - CPPDEFINES=ARDUINO_USBDEFINES, - - CPPPATH=[ - join("$BUILD_DIR", "FrameworkArduino") - ] -) +libs = [] if "variant" in BOARD_BUILDOPTS: - env.VariantDir( - join("$BUILD_DIR", "FrameworkArduinoVariant"), - join("$PLATFORMFW_DIR", "variants", - "${BOARD_OPTIONS['build']['variant']}") - ) env.Append( CPPPATH=[ join("$BUILD_DIR", "FrameworkArduinoVariant") ] ) + libs.append(env.BuildLibrary( + join("$BUILD_DIR", "FrameworkArduinoVariant"), + join("$PLATFORMFW_DIR", "variants", + "${BOARD_OPTIONS['build']['variant']}") + )) -# -# Target: Build Core Library -# - -libs = [] - -libs.append(env.BuildLibrary( +envsafe = env.Clone() +libs.append(envsafe.BuildLibrary( join("$BUILD_DIR", "FrameworkArduino"), join("$PLATFORMFW_DIR", "cores", "${BOARD_OPTIONS['build']['core']}") )) +if env.subst("${PLATFORMFW_DIR}")[-3:] == "sam": + envsafe.Append( + CFLAGS=[ + "-std=gnu99" + ] + ) + libs.append(envsafe.BuildLibrary( + join("$BUILD_DIR", "SamLib"), + join("$PLATFORMFW_DIR", "system", "libsam", "source") + )) + Return("env libs") diff --git a/platformio/platforms/digistump.py b/platformio/platforms/digistump.py new file mode 100644 index 00000000..97e55674 --- /dev/null +++ b/platformio/platforms/digistump.py @@ -0,0 +1,61 @@ +# Copyright (C) Ivan Kravets +# See LICENSE for details. + +from platformio.platforms.base import BasePlatform +from platformio.util import get_boards + + +class DigistumpPlatform(BasePlatform): + + """ + An embedded platform for Digistump boards + (with Arduino Framework) + """ + + PACKAGES = { + + "toolchain-atmelavr": { + "default": True + }, + + "toolchain-gccarmnoneeabi": { + "default": True + }, + + "ldscripts": { + "default": True + }, + + "tool-bossac": { + "default": True + }, + + "tool-avrdude": { + "default": True + }, + + "framework-arduinoavr": { + "default": True + }, + + "framework-arduinosam": { + "default": True + } + } + + def run(self, variables, targets): + for v in variables: + if "BOARD=" not in v: + continue + _, board = v.split("=") + bdata = get_boards(board) + if bdata['build']['mcu'] == "cortex-m3": + tpackage = "toolchain-gccarmnoneeabi" + tuploader = "tool-bossac" + else: + tpackage = "toolchain-atmelavr" + tuploader = "tool-avrdude" + self.PACKAGES[tpackage]['alias'] = "toolchain" + self.PACKAGES[tuploader]['alias'] = "uploader" + break + return BasePlatform.run(self, variables, targets)