diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index cd4fa45..07b64bf 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -12,6 +12,7 @@ jobs: - "examples/arduino-blink" - "examples/arduino-external-libs" - "examples/arduino-internal-libs" + - "examples/arduino-move38-colorwheel" - "examples/arduino-own-src_dir" - "examples/assembly-blink" - "examples/digitstump-mouse" diff --git a/boards/move38_blink.json b/boards/move38_blink.json new file mode 100644 index 0000000..728cb9a --- /dev/null +++ b/boards/move38_blink.json @@ -0,0 +1,38 @@ +{ + "build": { + "core": "blinklib", + "extra_flags": "-DARDUINO_AVR_BLINK_168", + "f_cpu": "8000000L", + "mcu": "atmega168pb", + "variant": "standard", + "ldscript": "avr5-atmega168pb.xn", + "builtinbase": "0x1700" + }, + "bootloader": { + "file": "BlinkBIOS-168PB.hex", + "lfuse": "0x62", + "hfuse": "0xDF", + "efuse": "0xf8" + }, + "debug": { + "simavr_target": "atmega168p" + }, + "fuses" : { + "lfuse": "0x62", + "hfuse": "0xDF", + "efuse": "0xf8" + }, + "frameworks": [ + "arduino" + ], + "name": "Blink", + "upload": { + "maximum_ram_size": 1024, + "maximum_size": 5888, + "protocol": "usbtiny", + "require_upload_port": false, + "speed": 115200 + }, + "url": "https://move38.com/", + "vendor": "Move38" +} diff --git a/boards/move38_blink328.json b/boards/move38_blink328.json new file mode 100644 index 0000000..cd00476 --- /dev/null +++ b/boards/move38_blink328.json @@ -0,0 +1,38 @@ +{ + "build": { + "core": "blinklib", + "extra_flags": "-DARDUINO_AVR_BLINK_328", + "f_cpu": "8000000L", + "mcu": "atmega328pb", + "variant": "standard", + "ldscript": "avr5-atmega328.xn", + "builtinbase": "0x3900" + }, + "bootloader": { + "file": "BlinkBIOS-328PB.hex", + "lfuse": "0x62", + "hfuse": "0xD8", + "efuse": "0xff" + }, + "debug": { + "simavr_target": "atmega328p" + }, + "fuses" : { + "lfuse": "0x62", + "hfuse": "0xD8", + "efuse": "0xff" + }, + "frameworks": [ + "arduino" + ], + "name": "Blink328", + "upload": { + "maximum_ram_size": 1024, + "maximum_size": 5888, + "protocol": "usbtiny", + "require_upload_port": false, + "speed": 115200 + }, + "url": "https://move38.com/", + "vendor": "Move38" +} diff --git a/boards/move38_blinkmax.json b/boards/move38_blinkmax.json new file mode 100644 index 0000000..4c678a1 --- /dev/null +++ b/boards/move38_blinkmax.json @@ -0,0 +1,38 @@ +{ + "build": { + "core": "blinklib", + "extra_flags": "-DARDUINO_AVR_BLINK_328", + "f_cpu": "8000000L", + "mcu": "atmega328pb", + "variant": "standard", + "ldscript": "avr5-atmega328.xn", + "builtinbase": "0x3900" + }, + "bootloader": { + "file": "BlinkBIOS-328PB-MAX.hex", + "lfuse": "0x62", + "hfuse": "0xD8", + "efuse": "0xff" + }, + "debug": { + "simavr_target": "atmega328p" + }, + "fuses" : { + "lfuse": "0x62", + "hfuse": "0xD8", + "efuse": "0xff" + }, + "frameworks": [ + "arduino" + ], + "name": "BlinkMAX", + "upload": { + "maximum_ram_size": 2048, + "maximum_size": 7936, + "protocol": "usbtiny", + "require_upload_port": false, + "speed": 115200 + }, + "url": "https://move38.com/", + "vendor": "Move38" +} diff --git a/boards/move38_blinknfc.json b/boards/move38_blinknfc.json new file mode 100644 index 0000000..8893667 --- /dev/null +++ b/boards/move38_blinknfc.json @@ -0,0 +1,38 @@ +{ + "build": { + "core": "blinklib", + "extra_flags": "-DARDUINO_AVR_BLINK_328", + "f_cpu": "8000000L", + "mcu": "atmega328pb", + "variant": "standard", + "ldscript": "avr5-atmega328.xn", + "builtinbase": "0x3900" + }, + "bootloader": { + "file": "BlinkBIOS-328PB-MAX-NFC.hex", + "lfuse": "0x62", + "hfuse": "0xD8", + "efuse": "0xff" + }, + "debug": { + "simavr_target": "atmega328p" + }, + "fuses" : { + "lfuse": "0x62", + "hfuse": "0xD8", + "efuse": "0xff" + }, + "frameworks": [ + "arduino" + ], + "name": "BlinkNFC", + "upload": { + "maximum_ram_size": 2048, + "maximum_size": 7936, + "protocol": "usbtiny", + "require_upload_port": false, + "speed": 115200 + }, + "url": "https://move38.com/", + "vendor": "Move38" +} diff --git a/builder/frameworks/arduino.py b/builder/frameworks/arduino.py index 83444cf..9ecba0f 100644 --- a/builder/frameworks/arduino.py +++ b/builder/frameworks/arduino.py @@ -130,6 +130,20 @@ def get_bootloader_size(): ], ) +# +# Expand linker script to its full path +# Add special linker options +# Make bootloader file available as env variable +# (needs to be flashed in one go) +# +if build_core in ("blinklib"): + ldscript = board.get("build.ldscript") + env.Replace(LDSCRIPT_PATH=join(FRAMEWORK_DIR, "linkscripts", ldscript)) + env.Append( + LINKFLAGS=["-mrelax", "-nostartfiles"], + BOOTLOADER_FILE=join(FRAMEWORK_DIR, "bootloaders", board.get("bootloader.file")) + ) + # # Take into account bootloader size # diff --git a/builder/main.py b/builder/main.py index c8ac00b..d5ddb28 100644 --- a/builder/main.py +++ b/builder/main.py @@ -107,6 +107,9 @@ def _rpi_sysgpio(path, value): PROGSUFFIX=".elf", ) +# Some Arduino cores need to relocate their firmware to a different address +builtinbase = env.BoardConfig().get("build", {}).get("builtinbase", "") + env.Append( BUILDERS=dict( ElfToEep=Builder( @@ -133,7 +136,8 @@ def _rpi_sysgpio(path, value): ElfToHex=Builder( action=env.VerboseAction( " ".join( - ["$OBJCOPY", "-O", "ihex", "-R", ".eeprom", "$SOURCES", "$TARGET"] + ["$OBJCOPY", "-O", "ihex", "-R", ".eeprom", "$SOURCES", "$TARGET"] if builtinbase == "" else \ + ["$OBJCOPY", "--change-addresses", builtinbase, "-O", "ihex", "-R", ".eeprom", "$SOURCES", "$TARGET"] ), "Building $TARGET", ), diff --git a/examples/arduino-move38-colorwheel/.gitignore b/examples/arduino-move38-colorwheel/.gitignore new file mode 100644 index 0000000..3b8da3a --- /dev/null +++ b/examples/arduino-move38-colorwheel/.gitignore @@ -0,0 +1,2 @@ +.pio +.vscode \ No newline at end of file diff --git a/examples/arduino-move38-colorwheel/README.md b/examples/arduino-move38-colorwheel/README.md new file mode 100644 index 0000000..f9af0af Binary files /dev/null and b/examples/arduino-move38-colorwheel/README.md differ diff --git a/examples/arduino-move38-colorwheel/include/README b/examples/arduino-move38-colorwheel/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/examples/arduino-move38-colorwheel/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/examples/arduino-move38-colorwheel/lib/README b/examples/arduino-move38-colorwheel/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/examples/arduino-move38-colorwheel/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/examples/arduino-move38-colorwheel/platformio.ini b/examples/arduino-move38-colorwheel/platformio.ini new file mode 100644 index 0000000..cae66c1 --- /dev/null +++ b/examples/arduino-move38-colorwheel/platformio.ini @@ -0,0 +1,37 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env] +; global settings +platform = atmelavr +framework = arduino +; use USBtinyISP as programmer +; burn bootloader and firmware at the same time +upload_protocol = custom +upload_flags = + -C + ${platformio.packages_dir}/tool-avrdude/avrdude.conf + -p + $BOARD_MCU + -c + usbtiny +upload_command = avrdude $UPLOAD_FLAGS -U flash:w:$SOURCE:i -Uflash:w:"$BOOTLOADER_FILE":i + +[env:move38_blink] +board = move38_blink + +[env:move38_blink328] +board = move38_blink328 + +[env:move38_blinkmax] +board = move38_blinkmax + +[env:move38_blinknfc] +board = move38_blinknfc diff --git a/examples/arduino-move38-colorwheel/src/main.cpp b/examples/arduino-move38-colorwheel/src/main.cpp new file mode 100644 index 0000000..c35f3ee --- /dev/null +++ b/examples/arduino-move38-colorwheel/src/main.cpp @@ -0,0 +1,30 @@ +#include +// Spin around in goovy HSB color space +// HSB stands for Hue, Saturation, and Brightness +// https://en.wikipedia.org/wiki/HSL_and_HSV + +void setup() { + // No setup needed for this simple example! +} + +byte hue=0; + +Timer nextStep; + +void loop() { + + if (nextStep.isExpired()) { + + // Spin the hue while keeping color saturation and brightness at max + setColor( makeColorHSB( hue , 255 , 255 ) ); + + // Becuase we are using an 8-bit byte for the `hue` variable, + // this will automatically roll over from 255 back down to 0 + // (255 is 11111111 in binary, and 11111111 + 00000001 = 00000000) + hue++; + + nextStep.set(10); // Step to (slightly) different color 100 times per second - whole cycle will take 255 steps *10ms = ~2.5 seconds. + + } + +} diff --git a/examples/arduino-move38-colorwheel/test/README b/examples/arduino-move38-colorwheel/test/README new file mode 100644 index 0000000..9b1e87b --- /dev/null +++ b/examples/arduino-move38-colorwheel/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html diff --git a/platform.json b/platform.json index 0bd29fa..477ab09 100644 --- a/platform.json +++ b/platform.json @@ -49,6 +49,11 @@ "owner": "platformio", "version": "~2.0.3" }, + "framework-arduino-avr-blinklib": { + "type": "framework", + "optional": true, + "version": "https://github.com/maxgerhardt/pio-blinks-core.git" + }, "framework-arduino-avr-core13": { "type": "framework", "optional": true,