Merge pull request #84 from valeros/develop

Add support for Digistump and improve Atmel SAM development platforms
This commit is contained in:
Ivan Kravets
2015-02-17 21:26:53 +02:00
9 changed files with 565 additions and 67 deletions

View File

@ -57,7 +57,7 @@ platform = atmelavr
framework = arduino framework = arduino
board = yun board = yun
#[env:arduino_due] [env:arduino_due]
#platform = atmelsam platform = atmelsam
#framework = arduino framework = arduino
#board = due board = due

View File

@ -0,0 +1,21 @@
How to buid PlatformIO based project
====================================
1. `Install PlatformIO <http://docs.platformio.org/en/latest/installation.html>`_
2. Download `source code with examples <https://github.com/ivankravets/platformio/archive/develop.zip>`_
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

View File

@ -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

View File

@ -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
}

View File

@ -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
}
}
}

View File

@ -34,31 +34,38 @@ env.Replace(
"-mcpu=${BOARD_OPTIONS['build']['mcu']}" "-mcpu=${BOARD_OPTIONS['build']['mcu']}"
], ],
CCFLAGS=[ CPPFLAGS=[
"-g", # include debugging info (so errors include line numbers) "-g", # include debugging info (so errors include line numbers)
"-Os", # optimize for size "-Os", # optimize for size
"-Wall", # show warnings "-fdata-sections",
"-ffunction-sections", # place each function in its own section
"-Wall",
"-MMD", # output dependancy info
"-mcpu=${BOARD_OPTIONS['build']['mcu']}",
"-mthumb",
"-ffunction-sections", # place each function in its own section "-ffunction-sections", # place each function in its own section
"-fdata-sections", "-fdata-sections",
"-MMD", # output dependency info "-nostdlib"
"-mcpu=${BOARD_OPTIONS['build']['mcu']}",
"-mthumb"
], ],
CXXFLAGS=[ CXXFLAGS=[
"-fno-rtti", "-fno-rtti",
"-felide-constructors",
"-fno-exceptions" "-fno-exceptions"
], ],
CPPDEFINES=[ CPPDEFINES=[
"F_CPU=$BOARD_F_CPU" "F_CPU=$BOARD_F_CPU",
"printf=iprintf"
], ],
LINKFLAGS=[ LINKFLAGS=[
"-Os", "-Os",
"-Wl,--gc-sections", "-Wl,--gc-sections",
"-mcpu=${BOARD_OPTIONS['build']['mcu']}", "-mcpu=${BOARD_OPTIONS['build']['mcu']}",
"-mthumb" "-mthumb",
"-Wl,--entry=Reset_Handler",
"-Wl,--start-group"
], ],
SIZEPRINTCMD='"$SIZETOOL" -B -d $SOURCES', SIZEPRINTCMD='"$SIZETOOL" -B -d $SOURCES',

View File

@ -0,0 +1,196 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# 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])

View File

@ -5,7 +5,7 @@
Build script for Arduino Framework (based on Wiring). Build script for Arduino Framework (based on Wiring).
""" """
from os import listdir from os import listdir, walk
from os.path import isfile, join from os.path import isfile, join
from SCons.Script import Import, Return from SCons.Script import Import, Return
@ -13,37 +13,89 @@ from SCons.Script import Import, Return
env = None env = None
Import("env") Import("env")
env.Replace( BOARD_OPTS = env.get("BOARD_OPTIONS", {})
PLATFORMFW_DIR=join( 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", "$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 # Atmel SAM platform
# #
if env.get("BOARD_OPTIONS", {}).get("platform", None) == "atmelsam": if env.subst("${PLATFORMFW_DIR}")[-3:] == "sam":
env.VariantDir( env.VariantDir(
join("$BUILD_DIR", "FrameworkCMSISInc"), join("$BUILD_DIR", "FrameworkCMSISInc"),
join("$PLATFORMFW_DIR", "system", "CMSIS", "CMSIS", "include") join("$PLATFORMFW_DIR", "system", "CMSIS", "CMSIS", "include")
) )
env.VariantDir(
join("$BUILD_DIR", "FrameworkLibSamInc"),
join("$PLATFORMFW_DIR", "system", "libsam")
)
env.VariantDir( env.VariantDir(
join("$BUILD_DIR", "FrameworkDeviceInc"), join("$BUILD_DIR", "FrameworkDeviceInc"),
join("$PLATFORMFW_DIR", "system", "CMSIS", "Device", "ATMEL") 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( env.Append(
CPPPATH=[ CPPPATH=[
join("$BUILD_DIR", "FrameworkCMSISInc"), join("$BUILD_DIR", "FrameworkCMSISInc"),
join("$BUILD_DIR", "FrameworkLibSamInc"), join("$BUILD_DIR", "FrameworkLibSam"),
join("$BUILD_DIR", "FrameworkDeviceInc") join("$BUILD_DIR", "FrameworkLibSam", "include"),
join("$BUILD_DIR", "FrameworkDeviceInc"),
join("$BUILD_DIR", "FrameworkDeviceInc", "sam3xa", "include")
] ]
) )
env.Append( 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 # Teensy platform
# #
@ -79,60 +150,39 @@ if BOARD_BUILDOPTS.get("core", None) == "teensy":
fp.write(content) fp.write(content)
# #
# Miscellaneous # Target: Build Core Library
# #
ARDUINO_VERSION = int(
open(join(env.subst("$PLATFORMFW_DIR"),
"version.txt")).read().replace(".", "").strip())
# usb flags libs = []
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")
]
)
if "variant" in BOARD_BUILDOPTS: if "variant" in BOARD_BUILDOPTS:
env.VariantDir(
join("$BUILD_DIR", "FrameworkArduinoVariant"),
join("$PLATFORMFW_DIR", "variants",
"${BOARD_OPTIONS['build']['variant']}")
)
env.Append( env.Append(
CPPPATH=[ CPPPATH=[
join("$BUILD_DIR", "FrameworkArduinoVariant") join("$BUILD_DIR", "FrameworkArduinoVariant")
] ]
) )
libs.append(env.BuildLibrary(
join("$BUILD_DIR", "FrameworkArduinoVariant"),
join("$PLATFORMFW_DIR", "variants",
"${BOARD_OPTIONS['build']['variant']}")
))
# envsafe = env.Clone()
# Target: Build Core Library libs.append(envsafe.BuildLibrary(
#
libs = []
libs.append(env.BuildLibrary(
join("$BUILD_DIR", "FrameworkArduino"), join("$BUILD_DIR", "FrameworkArduino"),
join("$PLATFORMFW_DIR", "cores", "${BOARD_OPTIONS['build']['core']}") 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") Return("env libs")

View File

@ -0,0 +1,61 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# 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)