Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FastLED/FastLED.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Guyer <sam.guyer@gmail.com>2021-04-29 17:44:07 +0300
committerSam Guyer <sam.guyer@gmail.com>2021-04-29 17:44:07 +0300
commit4b2d3339f8a1acd33621070e82d9685d506b177e (patch)
treec98e9ebb3ab086169c69673d75789355586d3c5d
parent65a76c512e51a2c000c60005552ce7cd5347c88b (diff)
parent2785f3d81dc360f021613268b2bc6ca69f578326 (diff)
Merge branch 'master' of https://github.com/FastLED/FastLED
-rw-r--r--.github/workflows/build.yml28
-rw-r--r--README.md7
-rwxr-xr-xci/ci-compile36
-rw-r--r--code_of_conduct.md134
-rw-r--r--examples/Cylon/Cylon.ino6
-rw-r--r--examples/DemoReel100/DemoReel100.ino5
-rw-r--r--examples/Fire2012/Fire2012.ino2
-rw-r--r--examples/Fire2012WithPalette/Fire2012WithPalette.ino4
-rw-r--r--examples/Multiple/ArrayOfLedArrays/ArrayOfLedArrays.ino12
-rw-r--r--examples/Multiple/MultipleStripsInOneArray/MultipleStripsInOneArray.ino12
-rw-r--r--examples/Multiple/OctoWS2811Demo/OctoWS2811Demo.ino8
-rw-r--r--examples/Multiple/ParallelOutputDemo/ParallelOutputDemo.ino14
-rw-r--r--examples/Noise/Noise.ino10
-rw-r--r--examples/NoisePlayground/NoisePlayground.ino14
-rw-r--r--examples/NoisePlusPalette/NoisePlusPalette.ino9
-rw-r--r--examples/RGBSetDemo/RGBSetDemo.ino2
-rw-r--r--examples/SmartMatrix/SmartMatrix.ino6
-rw-r--r--examples/TwinkleFox/TwinkleFox.ino4
-rw-r--r--examples/XYMatrix/XYMatrix.ino13
-rw-r--r--library.json2
-rw-r--r--library.properties2
-rw-r--r--release_notes.md15
-rw-r--r--src/FastLED.h6
-rw-r--r--src/colorutils.cpp20
-rw-r--r--src/fastspi.h5
-rw-r--r--src/hsv2rgb.cpp38
-rw-r--r--src/led_sysdefs.h6
-rw-r--r--src/lib8tion/trig8.h19
-rw-r--r--src/platforms.h4
-rw-r--r--src/platforms/arm/d51/README.txt5
-rw-r--r--src/platforms/arm/d51/fastled_arm_d51.h1
-rw-r--r--src/platforms/arm/d51/fastpin_arm_d51.h53
-rw-r--r--src/platforms/arm/d51/led_sysdefs_arm_d51.h4
-rw-r--r--src/platforms/arm/stm32/clockless_arm_stm32.h21
-rw-r--r--src/platforms/arm/stm32/fastpin_arm_stm32.h62
-rw-r--r--src/platforms/arm/stm32/led_sysdefs_arm_stm32.h13
-rw-r--r--src/platforms/avr/clockless_trinket.h17
-rw-r--r--src/platforms/avr/fastpin_avr.h33
-rw-r--r--src/platforms/avr/fastspi_avr.h159
-rw-r--r--src/platforms/avr/led_sysdefs_avr.h2
-rw-r--r--src/platforms/esp/32/clockless_i2s_esp32.h6
-rw-r--r--src/platforms/esp/32/clockless_rmt_esp32.cpp11
-rw-r--r--src/platforms/esp/32/clockless_rmt_esp32.h11
-rw-r--r--src/platforms/fastspi_ardunio_core.h103
44 files changed, 801 insertions, 143 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 00000000..d47e46b0
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,28 @@
+on:
+ push:
+ branches:
+ - master
+ pull_request:
+ branches:
+ - master
+
+name: build
+jobs:
+
+ build:
+ runs-on: ubuntu-20.04
+ steps:
+ - name: checkout code
+ uses: actions/checkout@v2
+
+ - name: install python
+ uses: actions/setup-python@v2
+ with:
+ python-version: '3.8'
+
+ - name: install platformio
+ run: |
+ pip install platformio==5.0.3
+
+ - name: build FastLED examples
+ run: ./ci/ci-compile
diff --git a/README.md b/README.md
index a945c5db..831baea1 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,11 @@
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/FastLED/public)
[![arduino-library-badge](https://www.ardu-badge.com/badge/FastLED.svg)](https://www.ardu-badge.com/FastLED)
+![build status](https://github.com/FastLED/FastLED/workflows/build/badge.svg)
IMPORTANT NOTE: For AVR based systems, avr-gcc 4.8.x is supported and tested. This means Arduino 1.6.5 and later.
-FastLED 3.3
+FastLED 3.4
===========
This is a library for easily & efficiently controlling a wide variety of LED chipsets, like the ones
@@ -23,7 +24,7 @@ We have multiple goals with this library:
## Getting help
-If you need help with using the library, please consider going to the reddit community first, which is at http://fastled.io/r (or https://reddit.com/r/FastLED) - there are hundreds of people in that group and many times you will get a quicker answer to your question there, as you will be likely to run into other people who have had the same issue. If you run into bugs with the library (compilation failures, the library doing the wrong thing), or if you'd like to request that we support a particular platform or LED chipset, then please open an issue at http://fastled.io/issues and we will try to figure out what is going wrong.
+If you need help with using the library, please consider going to the reddit community first, which is at http://fastled.io/r (or https://reddit.com/r/FastLED) - there are thousands of great people in that group and many times you will get a quicker answer to your question there, as you will be likely to run into other people who have had the same issue. If you run into bugs with the library (compilation failures, the library doing the wrong thing), or if you'd like to request that we support a particular platform or LED chipset, then please open an issue at http://fastled.io/issues and we will try to figure out what is going wrong.
## Simple example
@@ -68,7 +69,7 @@ Right now the library is supported on a variety of arduino compatable platforms.
* Arduino & compatibles - straight up arduino devices, uno, duo, leonardo, mega, nano, etc...
* Arduino Yún
* Adafruit Trinket & Gemma - Trinket Pro may be supported, but haven't tested to confirm yet
-* Teensy 2, Teensy++ 2, Teensy 3.0, Teensy 3.1/3.2, Teensy LC, Teensy 3.5, Teensy 3.6, and Teensy 4.0 - arduino compataible from pjrc.com with some extra goodies (note the teensy 3, 3.1, and LC are ARM, not AVR!)
+* Teensy 2, Teensy++ 2, Teensy 3.0, Teensy 3.1/3.2, Teensy LC, Teensy 3.5, Teensy 3.6, and Teensy 4.0 - arduino compatible from pjrc.com with some extra goodies (note the teensy LC, 3.2, 3.5, 3.6, 4.0 are ARM, not AVR!)
* Arduino Due and the digistump DigiX
* RFDuino
* SparkCore
diff --git a/ci/ci-compile b/ci/ci-compile
new file mode 100755
index 00000000..208a173a
--- /dev/null
+++ b/ci/ci-compile
@@ -0,0 +1,36 @@
+#!/bin/bash
+#
+# compile FastLED examples with platformio for various boards. This script
+# is usually run by the CI, but can also be run locally. Only dependency
+# is platformio.
+#
+# usage:
+# [BOARDS=boards] [EXAMPLES=examples] ./ci-compile
+#
+# e.g.
+# $ ./compile-ci
+# - compile all board/examples combinations
+#
+# $ BOARDS="esp32 esp01" EXAMPLES=Blink ./compile-ci
+# - compile only Blink example for the esp32 and esp8266 platforms
+#
+set -eou pipefail
+
+# List of examples that will be compiled by default
+EXAMPLES=${EXAMPLES:-"Blink ColorPalette ColorTemperature Cylon DemoReel100
+ Fire2012 FirstLight Multiple/MultipleStripsInOneArray
+ Multiple/ArrayOfLedArrays Noise NoisePlayground NoisePlusPalette Pacifica
+ Pride2015 RGBCalibrate RGBSetDemo TwinkleFox XYMatrix"}
+
+# list of boards to compile for by default
+BOARDS=${BOARDS:-"uno esp32dev esp01 yun digix teensy30"}
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
+BOARD_OPTS=$(for b in $BOARDS; do echo -n "--board $b "; done)
+
+cd "$DIR/.."
+
+for d in $EXAMPLES ; do
+ echo "*** building example $d for $BOARDS ***"
+ pio ci $BOARD_OPTS --lib=src "examples/$d/"*ino
+done
diff --git a/code_of_conduct.md b/code_of_conduct.md
new file mode 100644
index 00000000..d8e2efa4
--- /dev/null
+++ b/code_of_conduct.md
@@ -0,0 +1,134 @@
+
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, caste, color, religion, or sexual identity
+and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+ and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the
+ overall community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or
+ advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email
+ address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at
+[INSERT CONTACT METHOD].
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series
+of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior, harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within
+the community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 2.0, available at
+[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0].
+
+Community Impact Guidelines were inspired by
+[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
+
+For answers to common questions about this code of conduct, see the FAQ at
+[https://www.contributor-covenant.org/faq][FAQ]. Translations are available
+at [https://www.contributor-covenant.org/translations][translations].
+
+[homepage]: https://www.contributor-covenant.org
+[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html
+[Mozilla CoC]: https://github.com/mozilla/diversity
+[FAQ]: https://www.contributor-covenant.org/faq
+[translations]: https://www.contributor-covenant.org/translations
+
diff --git a/examples/Cylon/Cylon.ino b/examples/Cylon/Cylon.ino
index f51c3487..96d4949a 100644
--- a/examples/Cylon/Cylon.ino
+++ b/examples/Cylon/Cylon.ino
@@ -6,7 +6,7 @@
// For led chips like Neopixels, which have a data line, ground, and power, you just
// need to define DATA_PIN. For led chipsets that are SPI based (four wires - data, clock,
// ground, and power), like the LPD8806, define both DATA_PIN and CLOCK_PIN
-#define DATA_PIN 7
+#define DATA_PIN 2
#define CLOCK_PIN 13
// Define the array of leds
@@ -15,8 +15,8 @@ CRGB leds[NUM_LEDS];
void setup() {
Serial.begin(57600);
Serial.println("resetting");
- LEDS.addLeds<WS2812,DATA_PIN,RGB>(leds,NUM_LEDS);
- LEDS.setBrightness(84);
+ FastLED.addLeds<WS2812,DATA_PIN,RGB>(leds,NUM_LEDS);
+ FastLED.setBrightness(84);
}
void fadeall() { for(int i = 0; i < NUM_LEDS; i++) { leds[i].nscale8(250); } }
diff --git a/examples/DemoReel100/DemoReel100.ino b/examples/DemoReel100/DemoReel100.ino
index b4478735..fb91edfc 100644
--- a/examples/DemoReel100/DemoReel100.ino
+++ b/examples/DemoReel100/DemoReel100.ino
@@ -11,9 +11,6 @@ FASTLED_USING_NAMESPACE
//
// -Mark Kriegsman, December 2014
-#if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000)
-#warning "Requires FastLED 3.1 or later; check github for latest code."
-#endif
#define DATA_PIN 3
//#define CLK_PIN 4
@@ -117,7 +114,7 @@ void bpm()
void juggle() {
// eight colored dots, weaving in and out of sync with each other
fadeToBlackBy( leds, NUM_LEDS, 20);
- byte dothue = 0;
+ uint8_t dothue = 0;
for( int i = 0; i < 8; i++) {
leds[beatsin16( i+7, 0, NUM_LEDS-1 )] |= CHSV(dothue, 200, 255);
dothue += 32;
diff --git a/examples/Fire2012/Fire2012.ino b/examples/Fire2012/Fire2012.ino
index dec5cd7f..f008a956 100644
--- a/examples/Fire2012/Fire2012.ino
+++ b/examples/Fire2012/Fire2012.ino
@@ -72,7 +72,7 @@ void loop()
void Fire2012()
{
// Array of temperature readings at each simulation cell
- static byte heat[NUM_LEDS];
+ static uint8_t heat[NUM_LEDS];
// Step 1. Cool down every cell a little
for( int i = 0; i < NUM_LEDS; i++) {
diff --git a/examples/Fire2012WithPalette/Fire2012WithPalette.ino b/examples/Fire2012WithPalette/Fire2012WithPalette.ino
index e65a87fb..182a48ae 100644
--- a/examples/Fire2012WithPalette/Fire2012WithPalette.ino
+++ b/examples/Fire2012WithPalette/Fire2012WithPalette.ino
@@ -128,7 +128,7 @@ void loop()
void Fire2012WithPalette()
{
// Array of temperature readings at each simulation cell
- static byte heat[NUM_LEDS];
+ static uint8_t heat[NUM_LEDS];
// Step 1. Cool down every cell a little
for( int i = 0; i < NUM_LEDS; i++) {
@@ -150,7 +150,7 @@ void Fire2012WithPalette()
for( int j = 0; j < NUM_LEDS; j++) {
// Scale the heat value from 0-255 down to 0-240
// for best results with color palettes.
- byte colorindex = scale8( heat[j], 240);
+ uint8_t colorindex = scale8( heat[j], 240);
CRGB color = ColorFromPalette( gPal, colorindex);
int pixelnumber;
if( gReverseDirection ) {
diff --git a/examples/Multiple/ArrayOfLedArrays/ArrayOfLedArrays.ino b/examples/Multiple/ArrayOfLedArrays/ArrayOfLedArrays.ino
index 3b7a9c79..0189f49e 100644
--- a/examples/Multiple/ArrayOfLedArrays/ArrayOfLedArrays.ino
+++ b/examples/Multiple/ArrayOfLedArrays/ArrayOfLedArrays.ino
@@ -12,14 +12,14 @@ CRGB leds[NUM_STRIPS][NUM_LEDS_PER_STRIP];
// For mirroring strips, all the "special" stuff happens just in setup. We
// just addLeds multiple times, once for each strip
void setup() {
- // tell FastLED there's 60 NEOPIXEL leds on pin 10
- FastLED.addLeds<NEOPIXEL, 10>(leds[0], NUM_LEDS_PER_STRIP);
+ // tell FastLED there's 60 NEOPIXEL leds on pin 2
+ FastLED.addLeds<NEOPIXEL, 2>(leds[0], NUM_LEDS_PER_STRIP);
- // tell FastLED there's 60 NEOPIXEL leds on pin 11
- FastLED.addLeds<NEOPIXEL, 11>(leds[1], NUM_LEDS_PER_STRIP);
+ // tell FastLED there's 60 NEOPIXEL leds on pin 3
+ FastLED.addLeds<NEOPIXEL, 3>(leds[1], NUM_LEDS_PER_STRIP);
- // tell FastLED there's 60 NEOPIXEL leds on pin 12
- FastLED.addLeds<NEOPIXEL, 12>(leds[2], NUM_LEDS_PER_STRIP);
+ // tell FastLED there's 60 NEOPIXEL leds on pin 4
+ FastLED.addLeds<NEOPIXEL, 4>(leds[2], NUM_LEDS_PER_STRIP);
}
diff --git a/examples/Multiple/MultipleStripsInOneArray/MultipleStripsInOneArray.ino b/examples/Multiple/MultipleStripsInOneArray/MultipleStripsInOneArray.ino
index 15d58bcb..c4426ddb 100644
--- a/examples/Multiple/MultipleStripsInOneArray/MultipleStripsInOneArray.ino
+++ b/examples/Multiple/MultipleStripsInOneArray/MultipleStripsInOneArray.ino
@@ -13,14 +13,14 @@ CRGB leds[NUM_STRIPS * NUM_LEDS_PER_STRIP];
// For mirroring strips, all the "special" stuff happens just in setup. We
// just addLeds multiple times, once for each strip
void setup() {
- // tell FastLED there's 60 NEOPIXEL leds on pin 10, starting at index 0 in the led array
- FastLED.addLeds<NEOPIXEL, 10>(leds, 0, NUM_LEDS_PER_STRIP);
+ // tell FastLED there's 60 NEOPIXEL leds on pin 2, starting at index 0 in the led array
+ FastLED.addLeds<NEOPIXEL, 2>(leds, 0, NUM_LEDS_PER_STRIP);
- // tell FastLED there's 60 NEOPIXEL leds on pin 11, starting at index 60 in the led array
- FastLED.addLeds<NEOPIXEL, 11>(leds, NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP);
+ // tell FastLED there's 60 NEOPIXEL leds on pin 3, starting at index 60 in the led array
+ FastLED.addLeds<NEOPIXEL, 3>(leds, NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP);
- // tell FastLED there's 60 NEOPIXEL leds on pin 12, starting at index 120 in the led array
- FastLED.addLeds<NEOPIXEL, 12>(leds, 2 * NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP);
+ // tell FastLED there's 60 NEOPIXEL leds on pin 4, starting at index 120 in the led array
+ FastLED.addLeds<NEOPIXEL, 4>(leds, 2 * NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP);
}
diff --git a/examples/Multiple/OctoWS2811Demo/OctoWS2811Demo.ino b/examples/Multiple/OctoWS2811Demo/OctoWS2811Demo.ino
index d8d73fe2..68190fe4 100644
--- a/examples/Multiple/OctoWS2811Demo/OctoWS2811Demo.ino
+++ b/examples/Multiple/OctoWS2811Demo/OctoWS2811Demo.ino
@@ -11,8 +11,8 @@ CRGB leds[NUM_STRIPS * NUM_LEDS_PER_STRIP];
// OctoWS2811: 2,14,7,8,6,20,21,5
void setup() {
- LEDS.addLeds<OCTOWS2811>(leds, NUM_LEDS_PER_STRIP);
- LEDS.setBrightness(32);
+ FastLED.addLeds<OCTOWS2811>(leds, NUM_LEDS_PER_STRIP);
+ FastLED.setBrightness(32);
}
void loop() {
@@ -32,6 +32,6 @@ void loop() {
hue++;
- LEDS.show();
- LEDS.delay(10);
+ FastLED.show();
+ FastLED.delay(10);
}
diff --git a/examples/Multiple/ParallelOutputDemo/ParallelOutputDemo.ino b/examples/Multiple/ParallelOutputDemo/ParallelOutputDemo.ino
index 8c447b54..4cd5d628 100644
--- a/examples/Multiple/ParallelOutputDemo/ParallelOutputDemo.ino
+++ b/examples/Multiple/ParallelOutputDemo/ParallelOutputDemo.ino
@@ -24,13 +24,13 @@ void setup() {
delay(5000);
Serial.begin(57600);
Serial.println("Starting...");
- // LEDS.addLeds<WS2811_PORTA,NUM_STRIPS>(leds, NUM_LEDS_PER_STRIP);
- // LEDS.addLeds<WS2811_PORTB,NUM_STRIPS>(leds, NUM_LEDS_PER_STRIP);
- // LEDS.addLeds<WS2811_PORTD,NUM_STRIPS>(leds, NUM_LEDS_PER_STRIP).setCorrection(TypicalLEDStrip);
- LEDS.addLeds<WS2811_PORTDC,NUM_STRIPS>(leds, NUM_LEDS_PER_STRIP);
+ // FastLED.addLeds<WS2811_PORTA,NUM_STRIPS>(leds, NUM_LEDS_PER_STRIP);
+ // FastLED.addLeds<WS2811_PORTB,NUM_STRIPS>(leds, NUM_LEDS_PER_STRIP);
+ // FastLED.addLeds<WS2811_PORTD,NUM_STRIPS>(leds, NUM_LEDS_PER_STRIP).setCorrection(TypicalLEDStrip);
+ FastLED.addLeds<WS2811_PORTDC,NUM_STRIPS>(leds, NUM_LEDS_PER_STRIP);
// Teensy 4 parallel output example
- // LEDS.addLeds<NUM_STRIPS, WS2811, 1>(leds,NUM_LEDS_PER_STRIP);
+ // FastLED.addLeds<NUM_STRIPS, WS2811, 1>(leds,NUM_LEDS_PER_STRIP);
}
void loop() {
@@ -51,6 +51,6 @@ void loop() {
hue++;
- LEDS.show();
- // LEDS.delay(100);
+ FastLED.show();
+ // FastLED.delay(100);
}
diff --git a/examples/Noise/Noise.ino b/examples/Noise/Noise.ino
index e196e6bb..f11d75d7 100644
--- a/examples/Noise/Noise.ino
+++ b/examples/Noise/Noise.ino
@@ -7,8 +7,10 @@
// Params for width and height
const uint8_t kMatrixWidth = 16;
const uint8_t kMatrixHeight = 16;
+
#define MAX_DIMENSION ((kMatrixWidth>kMatrixHeight) ? kMatrixWidth : kMatrixHeight)
#define NUM_LEDS (kMatrixWidth * kMatrixHeight)
+
// Param for different pixel layouts
const bool kMatrixSerpentineLayout = true;
@@ -62,15 +64,15 @@ uint16_t speed = 20; // a nice starting speed, mixes well with a scale of 100
uint16_t scale = 311;
// This is the array that we keep our computed noise values in
-uint8_t noise[MAX_DIMENSION][MAX_DIMENSION];
+uint16_t noise[MAX_DIMENSION][MAX_DIMENSION];
void setup() {
// uncomment the following lines if you want to see FPS count information
// Serial.begin(38400);
// Serial.println("resetting!");
delay(3000);
- LEDS.addLeds<WS2811,5,RGB>(leds,NUM_LEDS);
- LEDS.setBrightness(96);
+ FastLED.addLeds<WS2811,2,RGB>(leds,NUM_LEDS);
+ FastLED.setBrightness(96);
// Initialize our coordinates to some random values
x = random16();
@@ -107,6 +109,6 @@ void loop() {
}
ihue+=1;
- LEDS.show();
+ FastLED.show();
// delay(10);
}
diff --git a/examples/NoisePlayground/NoisePlayground.ino b/examples/NoisePlayground/NoisePlayground.ino
index e2c7cb31..6c047324 100644
--- a/examples/NoisePlayground/NoisePlayground.ino
+++ b/examples/NoisePlayground/NoisePlayground.ino
@@ -1,9 +1,11 @@
#include <FastLED.h>
-#define kMatrixWidth 16
-#define kMatrixHeight 16
+// Params for width and height
+const uint8_t kMatrixWidth = 16;
+const uint8_t kMatrixHeight = 16;
#define NUM_LEDS (kMatrixWidth * kMatrixHeight)
+
// Param for different pixel layouts
#define kMatrixSerpentineLayout true
@@ -37,11 +39,11 @@ int y_speed=1111;
void loop() {
// fill the led array 2/16-bit noise values
- fill_2dnoise16(LEDS.leds(), kMatrixWidth, kMatrixHeight, kMatrixSerpentineLayout,
+ fill_2dnoise16(leds, kMatrixWidth, kMatrixHeight, kMatrixSerpentineLayout,
octaves,x,xscale,y,yscale,v_time,
hue_octaves,hxy,hue_scale,hxy,hue_scale,hue_time, false);
- LEDS.show();
+ FastLED.show();
// adjust the intra-frame time values
x += x_speed;
@@ -61,8 +63,8 @@ void setup() {
Serial.println("resetting!");
delay(3000);
- LEDS.addLeds<WS2811,6,GRB>(leds,NUM_LEDS);
- LEDS.setBrightness(96);
+ FastLED.addLeds<WS2811,2,GRB>(leds,NUM_LEDS);
+ FastLED.setBrightness(96);
hxy = (uint32_t)((uint32_t)random16() << 16) + (uint32_t)random16();
x = (uint32_t)((uint32_t)random16() << 16) + (uint32_t)random16();
diff --git a/examples/NoisePlusPalette/NoisePlusPalette.ino b/examples/NoisePlusPalette/NoisePlusPalette.ino
index e95e4128..4670cc38 100644
--- a/examples/NoisePlusPalette/NoisePlusPalette.ino
+++ b/examples/NoisePlusPalette/NoisePlusPalette.ino
@@ -5,8 +5,11 @@
#define LED_TYPE WS2811
#define COLOR_ORDER GRB
+// Params for width and height
const uint8_t kMatrixWidth = 16;
const uint8_t kMatrixHeight = 16;
+
+// Param for different pixel layouts
const bool kMatrixSerpentineLayout = true;
@@ -67,8 +70,8 @@ uint8_t colorLoop = 1;
void setup() {
delay(3000);
- LEDS.addLeds<LED_TYPE,LED_PIN,COLOR_ORDER>(leds,NUM_LEDS);
- LEDS.setBrightness(BRIGHTNESS);
+ FastLED.addLeds<LED_TYPE,LED_PIN,COLOR_ORDER>(leds,NUM_LEDS);
+ FastLED.setBrightness(BRIGHTNESS);
// Initialize our coordinates to some random values
x = random16();
@@ -163,7 +166,7 @@ void loop() {
// using the current palette
mapNoiseToLEDsUsingPalette();
- LEDS.show();
+ FastLED.show();
// delay(10);
}
diff --git a/examples/RGBSetDemo/RGBSetDemo.ino b/examples/RGBSetDemo/RGBSetDemo.ino
index 455fdccc..42478757 100644
--- a/examples/RGBSetDemo/RGBSetDemo.ino
+++ b/examples/RGBSetDemo/RGBSetDemo.ino
@@ -3,7 +3,7 @@
CRGBArray<NUM_LEDS> leds;
-void setup() { FastLED.addLeds<NEOPIXEL,6>(leds, NUM_LEDS); }
+void setup() { FastLED.addLeds<NEOPIXEL,2>(leds, NUM_LEDS); }
void loop(){
static uint8_t hue;
diff --git a/examples/SmartMatrix/SmartMatrix.ino b/examples/SmartMatrix/SmartMatrix.ino
index 50bcb811..e685cf67 100644
--- a/examples/SmartMatrix/SmartMatrix.ino
+++ b/examples/SmartMatrix/SmartMatrix.ino
@@ -63,8 +63,8 @@ void setup() {
// Serial.begin(38400);
// Serial.println("resetting!");
delay(3000);
- LEDS.addLeds<SMART_MATRIX>(leds,NUM_LEDS);
- LEDS.setBrightness(96);
+ FastLED.addLeds<SMART_MATRIX>(leds,NUM_LEDS);
+ FastLED.setBrightness(96);
// Initialize our coordinates to some random values
x = random16();
@@ -116,6 +116,6 @@ void loop() {
pSmartMatrix->fillCircle(circlex % 32,circley % 32,6,CRGB(CHSV(ihue+128,255,255)));
circlex += random16(2);
circley += random16(2);
- LEDS.show();
+ FastLED.show();
// delay(10);
}
diff --git a/examples/TwinkleFox/TwinkleFox.ino b/examples/TwinkleFox/TwinkleFox.ino
index 4821139b..89af25c5 100644
--- a/examples/TwinkleFox/TwinkleFox.ino
+++ b/examples/TwinkleFox/TwinkleFox.ino
@@ -1,9 +1,5 @@
#include "FastLED.h"
-#if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000)
-#warning "Requires FastLED 3.1 or later; check github for latest code."
-#endif
-
#define NUM_LEDS 100
#define LED_TYPE WS2811
diff --git a/examples/XYMatrix/XYMatrix.ino b/examples/XYMatrix/XYMatrix.ino
index 010ffe7c..cce1fbf3 100644
--- a/examples/XYMatrix/XYMatrix.ino
+++ b/examples/XYMatrix/XYMatrix.ino
@@ -15,7 +15,7 @@
// No error checking is performed on the ranges of x and y.
//
// XYsafe(x,y) takes x and y coordinates and returns an LED index number,
-// for use like this: leds[ XY(x,y) ] == CRGB::Red;
+// for use like this: leds[ XYsafe(x,y) ] == CRGB::Red;
// Error checking IS performed on the ranges of x and y, and an
// index of "-1" is returned. Special instructions below
// explain how to use this without having to do your own error
@@ -31,6 +31,7 @@ const uint8_t kMatrixHeight = 16;
// Param for different pixel layouts
const bool kMatrixSerpentineLayout = true;
const bool kMatrixVertical = false;
+
// Set 'kMatrixSerpentineLayout' to false if your pixels are
// laid out all running the same way, like this:
//
@@ -189,13 +190,13 @@ void loop()
FastLED.show();
}
-void DrawOneFrame( byte startHue8, int8_t yHueDelta8, int8_t xHueDelta8)
+void DrawOneFrame( uint8_t startHue8, int8_t yHueDelta8, int8_t xHueDelta8)
{
- byte lineStartHue = startHue8;
- for( byte y = 0; y < kMatrixHeight; y++) {
+ uint8_t lineStartHue = startHue8;
+ for( uint8_t y = 0; y < kMatrixHeight; y++) {
lineStartHue += yHueDelta8;
- byte pixelHue = lineStartHue;
- for( byte x = 0; x < kMatrixWidth; x++) {
+ uint8_t pixelHue = lineStartHue;
+ for( uint8_t x = 0; x < kMatrixWidth; x++) {
pixelHue += xHueDelta8;
leds[ XY(x, y)] = CHSV( pixelHue, 255, 255);
}
diff --git a/library.json b/library.json
index 7b1dd471..9e330204 100644
--- a/library.json
+++ b/library.json
@@ -33,7 +33,7 @@
"type": "git",
"url": "https://github.com/FastLED/FastLED.git"
},
- "version": "3.3.3",
+ "version": "3.4.0",
"license": "MIT",
"homepage": "http://fastled.io",
"frameworks": "arduino",
diff --git a/library.properties b/library.properties
index 2ebea658..fc8d17b1 100644
--- a/library.properties
+++ b/library.properties
@@ -1,5 +1,5 @@
name=FastLED
-version=3.3.3
+version=3.4.0
author=Daniel Garcia
maintainer=Daniel Garcia <dgarcia@fastled.io>
sentence=Multi-platform library for controlling dozens of different types of LEDs along with optimized math, effect, and noise functions.
diff --git a/release_notes.md b/release_notes.md
index 9c38eedf..e7eb7792 100644
--- a/release_notes.md
+++ b/release_notes.md
@@ -1,3 +1,18 @@
+FastLED 3.4.0
+=============
+
+* Improved reliability on ESP32 when wifi is active
+* Merged in contributed support for Adafruit boards: QT Py SAMD21, Circuit Playground Express, Circuit Playground Bluefruit, and ItsyBitsy nRF52840 Express
+* Merged in contributed support for SparkFun Artemis boards
+* Merged in contributed support for Arduino Nano Every / Arduino Uno Wifi Rev. 2
+* Merged in contributed support for Seeedstudio Odyssey and XIAO boards
+* Merged in contributed support for AVR chips ATmega1284, ATmega4809, and LGT8F328
+* XYMatrix example now supports 90-degree rotated orientation
+* Moved source code files into "src" subdirectory
+* Many small code cleanups and bug fixes
+* Released December 2020, with many thanks to everyone contributing to FastLED!
+
+
FastLED 3.3.3
=============
diff --git a/src/FastLED.h b/src/FastLED.h
index 0cc1acc4..042496fc 100644
--- a/src/FastLED.h
+++ b/src/FastLED.h
@@ -8,12 +8,12 @@
#define FASTLED_HAS_PRAGMA_MESSAGE
#endif
-#define FASTLED_VERSION 3003002
+#define FASTLED_VERSION 3004000
#ifndef FASTLED_INTERNAL
# ifdef FASTLED_HAS_PRAGMA_MESSAGE
-# pragma message "FastLED version 3.003.003"
+# pragma message "FastLED version 3.004.000"
# else
-# warning FastLED version 3.003.003 (Not really a warning, just telling you here.)
+# warning FastLED version 3.004.000 (Not really a warning, just telling you here.)
# endif
#endif
diff --git a/src/colorutils.cpp b/src/colorutils.cpp
index c40f4860..a1acaa5a 100644
--- a/src/colorutils.cpp
+++ b/src/colorutils.cpp
@@ -403,13 +403,29 @@ void blur2d( CRGB* leds, uint8_t width, uint8_t height, fract8 blur_amount)
blurColumns(leds, width, height, blur_amount);
}
-// blurRows: perform a blur1d on every row of a rectangular matrix
void blurRows( CRGB* leds, uint8_t width, uint8_t height, fract8 blur_amount)
{
- for( uint8_t row = 0; row < height; ++row) {
+/* for( uint8_t row = 0; row < height; row++) {
CRGB* rowbase = leds + (row * width);
blur1d( rowbase, width, blur_amount);
}
+*/
+ // blur rows same as columns, for irregular matrix
+ uint8_t keep = 255 - blur_amount;
+ uint8_t seep = blur_amount >> 1;
+ for( uint8_t row = 0; row < height; row++) {
+ CRGB carryover = CRGB::Black;
+ for( uint8_t i = 0; i < width; i++) {
+ CRGB cur = leds[XY(i,row)];
+ CRGB part = cur;
+ part.nscale8( seep);
+ cur.nscale8( keep);
+ cur += carryover;
+ if( i) leds[XY(i-1,row)] += part;
+ leds[XY(i,row)] = cur;
+ carryover = part;
+ }
+ }
}
// blurColumns: perform a blur1d on each column of a rectangular matrix
diff --git a/src/fastspi.h b/src/fastspi.h
index 2245ffe9..aeb2ad01 100644
--- a/src/fastspi.h
+++ b/src/fastspi.h
@@ -127,6 +127,11 @@ class SPIOutput<SPI_UART1_DATA, SPI_UART1_CLOCK, SPI_SPEED> : public AVRUSART1SP
#endif
+#elif defined(ARDUNIO_CORE_SPI)
+
+template<uint32_t SPI_SPEED>
+class SPIOutput<SPI_DATA, SPI_CLOCK, SPI_SPEED> : public ArdunioCoreSPIOutput<SPI_DATA, SPI_CLOCK, SPI_SPEED, SPI> {};
+
#endif
#else
diff --git a/src/hsv2rgb.cpp b/src/hsv2rgb.cpp
index 1fb8d56b..4585a544 100644
--- a/src/hsv2rgb.cpp
+++ b/src/hsv2rgb.cpp
@@ -440,21 +440,23 @@ void hsv2rgb_rainbow( const CHSV& hsv, CRGB& rgb)
if( sat == 0) {
r = 255; b = 255; g = 255;
} else {
+ uint8_t desat = 255 - sat;
+ desat = scale8_video( desat, desat);
+
+ uint8_t satscale = 255 - desat;
+ //satscale = sat; // uncomment to revert to pre-2021 saturation behavior
+
//nscale8x3_video( r, g, b, sat);
#if (FASTLED_SCALE8_FIXED==1)
- if( r ) r = scale8_LEAVING_R1_DIRTY( r, sat);
- if( g ) g = scale8_LEAVING_R1_DIRTY( g, sat);
- if( b ) b = scale8_LEAVING_R1_DIRTY( b, sat);
+ r = scale8_LEAVING_R1_DIRTY( r, satscale);
+ g = scale8_LEAVING_R1_DIRTY( g, satscale);
+ b = scale8_LEAVING_R1_DIRTY( b, satscale);
+ cleanup_R1();
#else
- if( r ) r = scale8_LEAVING_R1_DIRTY( r, sat) + 1;
- if( g ) g = scale8_LEAVING_R1_DIRTY( g, sat) + 1;
- if( b ) b = scale8_LEAVING_R1_DIRTY( b, sat) + 1;
+ if( r ) r = scale8( r, satscale) + 1;
+ if( g ) g = scale8( g, satscale) + 1;
+ if( b ) b = scale8( b, satscale) + 1;
#endif
- cleanup_R1();
-
- uint8_t desat = 255 - sat;
- desat = scale8( desat, desat);
-
uint8_t brightness_floor = desat;
r += brightness_floor;
g += brightness_floor;
@@ -471,15 +473,15 @@ void hsv2rgb_rainbow( const CHSV& hsv, CRGB& rgb)
} else {
// nscale8x3_video( r, g, b, val);
#if (FASTLED_SCALE8_FIXED==1)
- if( r ) r = scale8_LEAVING_R1_DIRTY( r, val);
- if( g ) g = scale8_LEAVING_R1_DIRTY( g, val);
- if( b ) b = scale8_LEAVING_R1_DIRTY( b, val);
+ r = scale8_LEAVING_R1_DIRTY( r, val);
+ g = scale8_LEAVING_R1_DIRTY( g, val);
+ b = scale8_LEAVING_R1_DIRTY( b, val);
+ cleanup_R1();
#else
- if( r ) r = scale8_LEAVING_R1_DIRTY( r, val) + 1;
- if( g ) g = scale8_LEAVING_R1_DIRTY( g, val) + 1;
- if( b ) b = scale8_LEAVING_R1_DIRTY( b, val) + 1;
+ if( r ) r = scale8( r, val) + 1;
+ if( g ) g = scale8( g, val) + 1;
+ if( b ) b = scale8( b, val) + 1;
#endif
- cleanup_R1();
}
}
diff --git a/src/led_sysdefs.h b/src/led_sysdefs.h
index 8ee568bf..5db322f8 100644
--- a/src/led_sysdefs.h
+++ b/src/led_sysdefs.h
@@ -24,10 +24,12 @@
#elif defined(__SAM3X8E__)
// Include sam/due headers
#include "platforms/arm/sam/led_sysdefs_arm_sam.h"
-#elif defined(STM32F10X_MD) || defined(__STM32F1__)
+#elif defined(STM32F10X_MD) || defined(__STM32F1__) || defined(STM32F2XX)
#include "platforms/arm/stm32/led_sysdefs_arm_stm32.h"
-#elif defined(__SAMD21G18A__) || defined(__SAMD21J18A__) || defined(__SAMD21E17A__) || defined(__SAMD21E18A__) || defined(__SAMD51G19A__) || defined(__SAMD51J19A__)
+#elif defined(__SAMD21G18A__) || defined(__SAMD21J18A__) || defined(__SAMD21E17A__) || defined(__SAMD21E18A__)
#include "platforms/arm/d21/led_sysdefs_arm_d21.h"
+#elif defined(__SAMD51G19A__) || defined(__SAMD51J19A__) || defined(__SAMD51P19A__)
+#include "platforms/arm/d51/led_sysdefs_arm_d51.h"
#elif defined(ESP8266)
#include "platforms/esp/8266/led_sysdefs_esp8266.h"
#elif defined(ESP32)
diff --git a/src/lib8tion/trig8.h b/src/lib8tion/trig8.h
index c5896ef8..bcb9f68a 100644
--- a/src/lib8tion/trig8.h
+++ b/src/lib8tion/trig8.h
@@ -16,9 +16,6 @@
#if defined(__AVR__)
#define sin16 sin16_avr
-#else
-#define sin16 sin16_C
-#endif
/// Fast 16-bit approximation of sin(x). This approximation never varies more than
/// 0.69% from the floating point value you'd get by doing
@@ -78,6 +75,9 @@ LIB8STATIC int16_t sin16_avr( uint16_t theta )
return y;
}
+#else
+#define sin16 sin16_C
+
/// Fast 16-bit approximation of sin(x). This approximation never varies more than
/// 0.69% from the floating point value you'd get by doing
///
@@ -109,6 +109,7 @@ LIB8STATIC int16_t sin16_C( uint16_t theta )
return y;
}
+#endif
/// Fast 16-bit approximation of cos(x). This approximation never varies more than
/// 0.69% from the floating point value you'd get by doing
@@ -139,15 +140,11 @@ LIB8STATIC int16_t cos16( uint16_t theta)
//
// On Arduino/AVR, this approximation is more than
// 20X faster than floating point sin(x) and cos(x)
+//
+const uint8_t b_m16_interleave[] = { 0, 49, 49, 41, 90, 27, 117, 10 };
#if defined(__AVR__) && !defined(LIB8_ATTINY)
#define sin8 sin8_avr
-#else
-#define sin8 sin8_C
-#endif
-
-
-const uint8_t b_m16_interleave[] = { 0, 49, 49, 41, 90, 27, 117, 10 };
/// Fast 8-bit approximation of sin(x). This approximation never varies more than
/// 2% from the floating point value you'd get by doing
@@ -206,6 +203,8 @@ LIB8STATIC uint8_t sin8_avr( uint8_t theta)
return y;
}
+#else
+#define sin8 sin8_C
/// Fast 8-bit approximation of sin(x). This approximation never varies more than
/// 2% from the floating point value you'd get by doing
@@ -243,6 +242,8 @@ LIB8STATIC uint8_t sin8_C( uint8_t theta)
return y;
}
+#endif
+
/// Fast 8-bit approximation of cos(x). This approximation never varies more than
/// 2% from the floating point value you'd get by doing
///
diff --git a/src/platforms.h b/src/platforms.h
index 7969c9e4..5351e2c1 100644
--- a/src/platforms.h
+++ b/src/platforms.h
@@ -24,11 +24,11 @@
#elif defined(__SAM3X8E__)
// Include sam/due headers
#include "platforms/arm/sam/fastled_arm_sam.h"
-#elif defined(STM32F10X_MD) || defined(__STM32F1__)
+#elif defined(STM32F10X_MD) || defined(__STM32F1__) || defined(STM32F2XX)
#include "platforms/arm/stm32/fastled_arm_stm32.h"
#elif defined(__SAMD21G18A__) || defined(__SAMD21J18A__) || defined(__SAMD21E17A__) || defined(__SAMD21E18A__)
#include "platforms/arm/d21/fastled_arm_d21.h"
-#elif defined(__SAMD51G19A__) || defined(__SAMD51J19A__)
+#elif defined(__SAMD51G19A__) || defined(__SAMD51J19A__) || defined(__SAMD51P19A__)
#include "platforms/arm/d51/fastled_arm_d51.h"
#elif defined(ESP8266)
#include "platforms/esp/8266/fastled_esp8266.h"
diff --git a/src/platforms/arm/d51/README.txt b/src/platforms/arm/d51/README.txt
index b00fb670..036a02a6 100644
--- a/src/platforms/arm/d51/README.txt
+++ b/src/platforms/arm/d51/README.txt
@@ -1,4 +1,7 @@
FastLED updates for adafruit FEATHER M4 and fixes to ITSBITSY M4 compiles
SAMD51
-only tested on FEATHER M4 with DOTSTAR and neopixel strips
+Tested on
+ - FEATHER M4 with DOTSTAR and neopixel strips
+ - Seeed Wio Terminal and WS2812B and APA102 LED strips using either SPI or GPIO pins
+
diff --git a/src/platforms/arm/d51/fastled_arm_d51.h b/src/platforms/arm/d51/fastled_arm_d51.h
index 0c14bf2f..912a9018 100644
--- a/src/platforms/arm/d51/fastled_arm_d51.h
+++ b/src/platforms/arm/d51/fastled_arm_d51.h
@@ -2,6 +2,7 @@
#define __INC_FASTLED_ARM_D51_H
#include "fastpin_arm_d51.h"
+#include "../../fastspi_ardunio_core.h"
#include "clockless_arm_d51.h"
#endif
diff --git a/src/platforms/arm/d51/fastpin_arm_d51.h b/src/platforms/arm/d51/fastpin_arm_d51.h
index 9d31cedb..6fb5682f 100644
--- a/src/platforms/arm/d51/fastpin_arm_d51.h
+++ b/src/platforms/arm/d51/fastpin_arm_d51.h
@@ -59,7 +59,7 @@ public:
#define _FL_IO(L) _RD32(GPIO ## L)
-#define _FL_DEFPIN(PIN, BIT, L) template<> class FastPin<PIN> : public _ARMPIN<PIN, BIT, 1 << BIT, L> {};
+#define _FL_DEFPIN(PIN, BIT, L) template<> class FastPin<PIN> : public _ARMPIN<PIN, BIT, 1ul << BIT, L> {};
// Actual pin definitions
#if defined(ADAFRUIT_ITSYBITSY_M4_EXPRESS)
@@ -127,6 +127,57 @@ _FL_DEFPIN(23, 22, 1); _FL_DEFPIN(24, 23, 1); _FL_DEFPIN(25, 17, 0);
#define SPI_CLOCK 25
#define HAS_HARDWARE_PIN_SUPPORT 1
+
+#elif defined(SEEED_WIO_TERMINAL)
+
+#define MAX_PIN 9
+// D0/A0-D8/A8
+_FL_DEFPIN( 0, 8, 1); _FL_DEFPIN( 1, 9, 1); _FL_DEFPIN( 2, 7, 0); _FL_DEFPIN( 3, 4, 1);
+_FL_DEFPIN( 4, 5, 1); _FL_DEFPIN( 5, 6, 1); _FL_DEFPIN( 6, 4, 0); _FL_DEFPIN( 7, 7, 1);
+_FL_DEFPIN( 8, 6, 0);
+// SDA/SCL
+_FL_DEFPIN(12, 17, 0); _FL_DEFPIN(13, 16, 0);
+// match GPIO pin nubers 9..11 MISO/MOSI/SCK
+_FL_DEFPIN(PIN_SPI_MISO, 0, 1); _FL_DEFPIN(PIN_SPI_MOSI, 2, 1); _FL_DEFPIN(PIN_SPI_SCK, 3, 1);
+
+#define SPI_DATA PIN_SPI_MOSI
+#define SPI_CLOCK PIN_SPI_SCK
+
+#define ARDUNIO_CORE_SPI
+#define HAS_HARDWARE_PIN_SUPPORT 1
+
+#elif defined(ADAFRUIT_MATRIXPORTAL_M4_EXPRESS)
+
+#define MAX_PIN 21
+// 0/1 - SERCOM/UART (Serial1)
+_FL_DEFPIN( 0, 1, 0); _FL_DEFPIN( 1, 0, 0);
+// 2..3 buttons
+_FL_DEFPIN( 2, 22, 1); _FL_DEFPIN( 3, 23, 1);
+// 4 neopixel
+_FL_DEFPIN( 4, 23, 0);
+// SDA/SCL
+_FL_DEFPIN( 5, 31, 1); _FL_DEFPIN( 6, 30, 1);
+// 7..12 RGBRGB pins
+_FL_DEFPIN( 7, 0, 1); _FL_DEFPIN( 8, 1, 1); _FL_DEFPIN( 9, 2, 1); _FL_DEFPIN(10, 3, 1);
+_FL_DEFPIN(11, 4, 1); _FL_DEFPIN(12, 5, 1);
+// 13 LED
+_FL_DEFPIN(13, 14, 0);
+// 14..21 Control pins
+_FL_DEFPIN(14, 6, 1); _FL_DEFPIN(15, 14, 1); _FL_DEFPIN(16, 12, 1); _FL_DEFPIN(17, 7, 1);
+_FL_DEFPIN(18, 8, 1); _FL_DEFPIN(19, 9, 1); _FL_DEFPIN(20, 15, 1); _FL_DEFPIN(21, 13, 1);
+// 22..26 Analog pins
+_FL_DEFPIN(22, 2, 1); _FL_DEFPIN(23, 5, 1); _FL_DEFPIN(24, 4, 1); _FL_DEFPIN(25, 6, 1);
+_FL_DEFPIN(26, 7, 1);
+// 34..36 ESP SPI
+_FL_DEFPIN(34, 16, 0); _FL_DEFPIN(35, 17, 0); _FL_DEFPIN(36, 19, 0);
+// 48..50 external SPI #2 on sercom 0
+_FL_DEFPIN(48, 5, 0); _FL_DEFPIN(49, 4, 0); _FL_DEFPIN(50, 7, 0);
+
+#define SPI_DATA 4
+#define SPI_CLOCK 7
+
+#define HAS_HARDWARE_PIN_SUPPORT 1
+
#endif
diff --git a/src/platforms/arm/d51/led_sysdefs_arm_d51.h b/src/platforms/arm/d51/led_sysdefs_arm_d51.h
index fd6a25e2..77726fa2 100644
--- a/src/platforms/arm/d51/led_sysdefs_arm_d51.h
+++ b/src/platforms/arm/d51/led_sysdefs_arm_d51.h
@@ -3,8 +3,6 @@
#define FASTLED_ARM
-// Note this is an M4, not an M0+, but this enables the shared m0clockless.h
-#define FASTLED_ARM_M0_PLUS
#ifndef INTERRUPT_THRESHOLD
#define INTERRUPT_THRESHOLD 1
@@ -12,7 +10,7 @@
// Default to allowing interrupts
#ifndef FASTLED_ALLOW_INTERRUPTS
-#define FASTLED_ALLOW_INTERRUPTS 0
+#define FASTLED_ALLOW_INTERRUPTS 1
#endif
#if FASTLED_ALLOW_INTERRUPTS == 1
diff --git a/src/platforms/arm/stm32/clockless_arm_stm32.h b/src/platforms/arm/stm32/clockless_arm_stm32.h
index 0ac8a5d4..d87b78c6 100644
--- a/src/platforms/arm/stm32/clockless_arm_stm32.h
+++ b/src/platforms/arm/stm32/clockless_arm_stm32.h
@@ -7,6 +7,13 @@ FASTLED_NAMESPACE_BEGIN
#define FASTLED_HAS_CLOCKLESS 1
+#if defined(STM32F2XX)
+// The photon runs faster than the others
+#define ADJ 8
+#else
+#define ADJ 20
+#endif
+
template <int DATA_PIN, int T1, int T2, int T3, EOrder RGB_ORDER = RGB, int XTRA0 = 0, bool FLIP = false, int WAIT_TIME = 50>
class ClocklessController : public CPixelLEDController<RGB_ORDER> {
typedef typename FastPin<DATA_PIN>::port_ptr_t data_ptr_t;
@@ -23,7 +30,7 @@ public:
mPort = FastPin<DATA_PIN>::port();
}
- virtual uint16_t getMaxRefreshRate() const { return 400; }
+ virtual uint16_t getMaxRefreshRate() const { return 400; }
protected:
virtual void showPixels(PixelController<RGB_ORDER> & pixels) {
@@ -39,28 +46,28 @@ protected:
template<int BITS> __attribute__ ((always_inline)) inline static void writeBits(register uint32_t & next_mark, register data_ptr_t port, register data_t hi, register data_t lo, register uint8_t & b) {
for(register uint32_t i = BITS-1; i > 0; --i) {
- while(_CYCCNT < (T1+T2+T3-20));
+ while(_CYCCNT < (T1+T2+T3-ADJ));
FastPin<DATA_PIN>::fastset(port, hi);
_CYCCNT = 4;
if(b&0x80) {
- while(_CYCCNT < (T1+T2-20));
+ while(_CYCCNT < (T1+T2-ADJ));
FastPin<DATA_PIN>::fastset(port, lo);
} else {
- while(_CYCCNT < (T1-10));
+ while(_CYCCNT < (T1-ADJ/2));
FastPin<DATA_PIN>::fastset(port, lo);
}
b <<= 1;
}
- while(_CYCCNT < (T1+T2+T3-20));
+ while(_CYCCNT < (T1+T2+T3-ADJ));
FastPin<DATA_PIN>::fastset(port, hi);
_CYCCNT = 4;
if(b&0x80) {
- while(_CYCCNT < (T1+T2-20));
+ while(_CYCCNT < (T1+T2-ADJ));
FastPin<DATA_PIN>::fastset(port, lo);
} else {
- while(_CYCCNT < (T1-10));
+ while(_CYCCNT < (T1-ADJ/2));
FastPin<DATA_PIN>::fastset(port, lo);
}
}
diff --git a/src/platforms/arm/stm32/fastpin_arm_stm32.h b/src/platforms/arm/stm32/fastpin_arm_stm32.h
index bc69912c..548fdc9d 100644
--- a/src/platforms/arm/stm32/fastpin_arm_stm32.h
+++ b/src/platforms/arm/stm32/fastpin_arm_stm32.h
@@ -35,9 +35,14 @@ public:
inline static void setOutput() { pinMode(PIN, OUTPUT); } // TODO: perform MUX config { _PDDR::r() |= _MASK; }
inline static void setInput() { pinMode(PIN, INPUT); } // TODO: preform MUX config { _PDDR::r() &= ~_MASK; }
+#if defined(STM32F2XX)
+ inline static void hi() __attribute__ ((always_inline)) { _GPIO::r()->BSRRL = _MASK; }
+ inline static void lo() __attribute__ ((always_inline)) { _GPIO::r()->BSRRH = _MASK; }
+#else
inline static void hi() __attribute__ ((always_inline)) { _GPIO::r()->BSRR = _MASK; }
inline static void lo() __attribute__ ((always_inline)) { _GPIO::r()->BRR = _MASK; }
// inline static void lo() __attribute__ ((always_inline)) { _GPIO::r()->BSRR = (_MASK<<16); }
+#endif
inline static void set(register port_t val) __attribute__ ((always_inline)) { _GPIO::r()->ODR = val; }
inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
@@ -51,25 +56,37 @@ public:
inline static port_t hival() __attribute__ ((always_inline)) { return _GPIO::r()->ODR | _MASK; }
inline static port_t loval() __attribute__ ((always_inline)) { return _GPIO::r()->ODR & ~_MASK; }
inline static port_ptr_t port() __attribute__ ((always_inline)) { return &_GPIO::r()->ODR; }
+
+#if defined(STM32F2XX)
+ inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &_GPIO::r()->BSRRL; }
+ inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &_GPIO::r()->BSRRH; }
+#else
inline static port_ptr_t sport() __attribute__ ((always_inline)) { return &_GPIO::r()->BSRR; }
inline static port_ptr_t cport() __attribute__ ((always_inline)) { return &_GPIO::r()->BRR; }
+#endif
+
inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; }
};
-#if defined(STM32F10X_MD)
+
#define _R(T) struct __gen_struct_ ## T
+#define _FL_DEFPIN(PIN, BIT, L) template<> class FastPin<PIN> : public _ARMPIN<PIN, BIT, 1 << BIT, _R(GPIO ## L)> {};
+
+#if defined(STM32F10X_MD)
#define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline volatile GPIO_TypeDef * r() { return T; } };
#define _FL_IO(L,C) _RD32(GPIO ## L); _FL_DEFINE_PORT3(L, C, _R(GPIO ## L));
+
#elif defined(__STM32F1__)
-#define _R(T) struct __gen_struct_ ## T
#define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline gpio_reg_map* r() { return T->regs; } };
-#define _FL_IO(L,C) _RD32(GPIO ## L); _FL_DEFINE_PORT3(L, C, _R(GPIO ## L));
+#define _FL_IO(L,C) _RD32(GPIO ## L); _FL_DEFINE_PORT3(L, C, _R(GPIO ## L));
+
+#elif defined(STM32F2XX)
+#define _RD32(T) struct __gen_struct_ ## T { static __attribute__((always_inline)) inline volatile GPIO_TypeDef * r() { return T; } };
+#define _FL_IO(L,C) _RD32(GPIO ## L);
#else
#error "Platform not supported"
#endif
-#define _FL_DEFPIN(PIN, BIT, L) template<> class FastPin<PIN> : public _ARMPIN<PIN, BIT, 1 << BIT, _R(GPIO ## L)> {};
-
#ifdef GPIOA
_FL_IO(A,0);
#endif
@@ -93,7 +110,36 @@ _FL_IO(G,6);
#endif
// Actual pin definitions
-#if defined(SPARK) // Sparkfun STM32F103 based board
+#if defined(STM32F2XX) // Photon Particle
+
+// https://github.com/focalintent/FastLED-Sparkcore/blob/master/firmware/fastpin_arm_stm32.h
+#define MAX_PIN 20
+_FL_DEFPIN(0, 7, B);
+_FL_DEFPIN(1, 6, B);
+_FL_DEFPIN(2, 5, B);
+_FL_DEFPIN(3, 4, B);
+_FL_DEFPIN(4, 3, B);
+_FL_DEFPIN(5, 15, A);
+_FL_DEFPIN(6, 14, A);
+_FL_DEFPIN(7, 13, A);
+_FL_DEFPIN(10, 5, C);
+_FL_DEFPIN(11, 3, C);
+_FL_DEFPIN(12, 2, C);
+_FL_DEFPIN(13, 5, A);
+_FL_DEFPIN(14, 6, A);
+_FL_DEFPIN(15, 7, A);
+_FL_DEFPIN(16, 4, A);
+_FL_DEFPIN(17, 0, A);
+_FL_DEFPIN(18, 10, A);
+_FL_DEFPIN(19, 9, A);
+_FL_DEFPIN(20, 7, C);
+
+#define SPI_DATA 15
+#define SPI_CLOCK 13
+
+#define HAS_HARDWARE_PIN_SUPPORT
+
+#elif defined(SPARK) // Sparkfun STM32F103 based board
#define MAX_PIN 19
_FL_DEFPIN(0, 7, B);
@@ -122,9 +168,7 @@ _FL_DEFPIN(19, 2, A);
#define HAS_HARDWARE_PIN_SUPPORT
-#endif // SPARK
-
-#if defined(__STM32F1__) // Generic STM32F103 aka "Blue Pill"
+#elif defined(__STM32F1__) // Generic STM32F103 aka "Blue Pill"
#define MAX_PIN 46
diff --git a/src/platforms/arm/stm32/led_sysdefs_arm_stm32.h b/src/platforms/arm/stm32/led_sysdefs_arm_stm32.h
index afcf1785..b58779ff 100644
--- a/src/platforms/arm/stm32/led_sysdefs_arm_stm32.h
+++ b/src/platforms/arm/stm32/led_sysdefs_arm_stm32.h
@@ -1,7 +1,7 @@
#ifndef __INC_LED_SYSDEFS_ARM_SAM_H
#define __INC_LED_SYSDEFS_ARM_SAM_H
-#if defined(STM32F10X_MD)
+#if defined(STM32F10X_MD) || defined(STM32F2XX)
#include <application.h>
@@ -55,7 +55,16 @@ typedef volatile uint8_t RwReg; /**< Read-Write 8-bit register (volatile u
#define FASTLED_NO_PINMAP
-#ifndef F_CPU
+#if defined(STM32F2XX)
+#define F_CPU 120000000
+#else
#define F_CPU 72000000
#endif
+
+#if defined(STM32F2XX)
+// Photon doesn't provide yield
+#define FASTLED_NEEDS_YIELD
+extern "C" void yield();
#endif
+
+#endif // defined(STM32F10X_MD) || defined(STM32F2XX)
diff --git a/src/platforms/avr/clockless_trinket.h b/src/platforms/avr/clockless_trinket.h
index 971a5a71..2cfbef0d 100644
--- a/src/platforms/avr/clockless_trinket.h
+++ b/src/platforms/avr/clockless_trinket.h
@@ -172,7 +172,8 @@ protected:
#define USE_ASM_MACROS
#if defined(__AVR_ATmega4809__)
-#define ASM_VAR_PORT "r" (((PORT_t*)FastPin<DATA_PIN>::port())->OUT)
+// Not used - place holder so existing ASM_VARS macro can remain the same
+#define ASM_VAR_PORT "r" (*FastPin<DATA_PIN>::port())
#else
#define ASM_VAR_PORT "M" (FastPin<DATA_PIN>::port() - 0x20)
#endif
@@ -204,12 +205,24 @@ protected:
[O1] "M" (RGB_BYTE1(RGB_ORDER)), \
[O2] "M" (RGB_BYTE2(RGB_ORDER)) \
: "cc" /* clobber registers */
-// Note: the code in the else in HI1/LO1 will be turned into an sts (2 cycle, 2 word) opcode
+
+#if defined(__AVR_ATmega4809__)
+
+// 1 cycle, write hi to the port
+#define HI1 do {*FastPin<DATA_PIN>::port()=hi;} while(0);
+// 1 cycle, write lo to the port
+#define LO1 do {*FastPin<DATA_PIN>::port()=lo;} while(0);
+
+#else
+
+// Note: the code in the else in HI1/LO1 will be turned into an sts (2 cycle, 2 word)
// 1 cycle, write hi to the port
#define HI1 FASTLED_SLOW_CLOCK_ADJUST if((int)(FastPin<DATA_PIN>::port())-0x20 < 64) { asm __volatile__("out %[PORT], %[hi]" ASM_VARS ); } else { *FastPin<DATA_PIN>::port()=hi; }
// 1 cycle, write lo to the port
#define LO1 if((int)(FastPin<DATA_PIN>::port())-0x20 < 64) { asm __volatile__("out %[PORT], %[lo]" ASM_VARS ); } else { *FastPin<DATA_PIN>::port()=lo; }
+#endif
+
// 2 cycles, sbrs on flipping the line to lo if we're pushing out a 0
#define QLO2(B, N) asm __volatile__("sbrs %[" #B "], " #N ASM_VARS ); LO1;
// load a byte from ram into the given var with the given offset
diff --git a/src/platforms/avr/fastpin_avr.h b/src/platforms/avr/fastpin_avr.h
index db2beeaf..741d3f34 100644
--- a/src/platforms/avr/fastpin_avr.h
+++ b/src/platforms/avr/fastpin_avr.h
@@ -37,6 +37,7 @@ public:
inline static port_t hival() __attribute__ ((always_inline)) { return _PORT::r() | _MASK; }
inline static port_t loval() __attribute__ ((always_inline)) { return _PORT::r() & ~_MASK; }
inline static port_ptr_t port() __attribute__ ((always_inline)) { return &_PORT::r(); }
+
inline static port_t mask() __attribute__ ((always_inline)) { return _MASK; }
};
@@ -46,15 +47,25 @@ public:
/// a custom type for each GPIO register with a single, static, aggressively inlined function that returns that specific GPIO register. A similar
/// trick is used a bit further below for the ARM GPIO registers (of which there are far more than on AVR!)
typedef volatile uint8_t & reg8_t;
+
#define _R(T) struct __gen_struct_ ## T
#define _RD8(T) struct __gen_struct_ ## T { static inline reg8_t r() { return T; }};
// Register name equivalent (using flat names)
-#if defined(AVR_ATtinyxy7) || defined(AVR_ATtinyxy6) || defined(AVR_ATtinyxy4) || defined(AVR_ATtinyxy2) || defined(__AVR_ATmega4809__)
+#if defined(AVR_ATtinyxy7) || defined(AVR_ATtinyxy6) || defined(AVR_ATtinyxy4) || defined(AVR_ATtinyxy2)
+
// ATtiny series 0/1 and ATmega series 0
#define _FL_IO(L,C) _RD8(PORT ## L ## _DIR); _RD8(PORT ## L ## _OUT); _RD8(PORT ## L ## _IN); _FL_DEFINE_PORT3(L, C, _R(PORT ## L ## _OUT));
#define _FL_DEFPIN(_PIN, BIT, L) template<> class FastPin<_PIN> : public _AVRPIN<_PIN, 1<<BIT, _R(PORT ## L ## _OUT), _R(PORT ## L ## _DIR), _R(PORT ## L ## _IN)> {};
+
+#elif defined(__AVR_ATmega4809__)
+
+// Leverage VPORTs instead of PORTs for faster access
+#define _FL_IO(L,C) _RD8(VPORT ## L ## _DIR); _RD8(VPORT ## L ## _OUT); _RD8(VPORT ## L ## _IN); _FL_DEFINE_PORT3(L, C, _R(VPORT ## L ## _OUT));
+#define _FL_DEFPIN(_PIN, BIT, L) template<> class FastPin<_PIN> : public _AVRPIN<_PIN, 1<<BIT, _R(VPORT ## L ## _OUT), _R(VPORT ## L ## _DIR), _R(VPORT ## L ## _IN)> {};
+
#else
+
// Others
#define _FL_IO(L,C) _RD8(DDR ## L); _RD8(PORT ## L); _RD8(PIN ## L); _FL_DEFINE_PORT3(L, C, _R(PORT ## L));
#define _FL_DEFPIN(_PIN, BIT, L) template<> class FastPin<_PIN> : public _AVRPIN<_PIN, 1<<BIT, _R(PORT ## L), _R(DDR ## L), _R(PIN ## L)> {};
@@ -215,15 +226,12 @@ _FL_DEFPIN(16, 1, D); _FL_DEFPIN(17, 0, D); _FL_DEFPIN(18, 2, A); _FL_DEFPIN(19,
_FL_DEFPIN(20, 4, D); _FL_DEFPIN(21, 5, D); _FL_DEFPIN(22, 2, A);
// To confirm for the SPI interfaces
-//#define SPI_DATA 18
-//#define SPI_CLOCK 13
-//#define SPI_SELECT 19
-//#define AVR_HARDWARE_SPI 1
+#define SPI_DATA 11
+#define SPI_CLOCK 13
+#define SPI_SELECT 8
+#define AVR_HARDWARE_SPI 1
#define HAS_HARDWARE_PIN_SUPPORT 1
-//#define SPI_UART0_DATA 1
-//#define SPI_UART0_CLOCK 4
-
#elif defined(__AVR_ATmega4809__)
#define MAX_PIN 21
@@ -234,11 +242,10 @@ _FL_DEFPIN(12, 1, E); _FL_DEFPIN(13, 2, E); _FL_DEFPIN(14, 3, D); _FL_DEFPIN(15,
_FL_DEFPIN(16, 1, D); _FL_DEFPIN(17, 0, D); _FL_DEFPIN(18, 2, A); _FL_DEFPIN(19, 3, A);
_FL_DEFPIN(20, 4, D); _FL_DEFPIN(21, 5, D);
-// To confirm for the SPI interfaces
-//#define SPI_DATA 18
-//#define SPI_CLOCK 13
-//#define SPI_SELECT 19
-//#define AVR_HARDWARE_SPI 1
+#define SPI_DATA 11
+#define SPI_CLOCK 13
+#define SPI_SELECT 8
+#define AVR_HARDWARE_SPI 1
#define HAS_HARDWARE_PIN_SUPPORT 1
//#define SPI_UART0_DATA 1
diff --git a/src/platforms/avr/fastspi_avr.h b/src/platforms/avr/fastspi_avr.h
index 245e4065..325a24b8 100644
--- a/src/platforms/avr/fastspi_avr.h
+++ b/src/platforms/avr/fastspi_avr.h
@@ -314,6 +314,165 @@ public:
#endif
+#if defined(SPI0_CTRLA)
+
+template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER>
+class AVRHardwareSPIOutput {
+ Selectable *m_pSelect;
+
+public:
+ AVRHardwareSPIOutput() { m_pSelect = NULL; }
+ AVRHardwareSPIOutput(Selectable *pSelect) { m_pSelect = pSelect; }
+ void setSelect(Selectable *pSelect) { m_pSelect = pSelect; }
+
+ void init() {
+ FastPin<_CLOCK_PIN>::setOutput();
+ FastPin<_DATA_PIN>::setOutput();
+
+ // Arduino Nano Every documentation lists SPI pins in ALT2 portmux position
+ PORTMUX_TWISPIROUTEA = PORTMUX_SPI01_bm;
+
+ // Set SPI master mode and clock scaler.
+ SPI0_CTRLA = SPI_MASTER_bm;
+ if(_SPI_CLOCK_DIVIDER >= 128) { SPI0_CTRLA |= SPI_PRESC1_bm|SPI_PRESC0_bm; }
+ else if (_SPI_CLOCK_DIVIDER >= 64) { SPI0_CTRLA |= SPI_PRESC1_bm; }
+ else if (_SPI_CLOCK_DIVIDER >= 32) { SPI0_CTRLA |= SPI_PRESC1_bm|SPI_CLK2X_bm; }
+ else if (_SPI_CLOCK_DIVIDER >= 16) { SPI0_CTRLA |= SPI_PRESC0_bm; }
+ else if (_SPI_CLOCK_DIVIDER >= 8) { SPI0_CTRLA |= SPI_PRESC0_bm|SPI_CLK2X_bm; }
+ else if (_SPI_CLOCK_DIVIDER >= 4) { /* default rate */ }
+ else { SPI0_CTRLA |= SPI_CLK2X_bm; }
+
+ // Set mode 0 and disable slave select.
+ SPI0_CTRLB = SPI_SSD_bm;
+
+ // Enable SPI.
+ SPI0_CTRLA |= SPI_ENABLE_bm;
+ }
+
+ void setSPIRate() {
+ SPI0_CTRLA &= ~ ( (1<<SPI_PRESC1_bp)|(1<<SPI_PRESC0_bp)|(1<<SPI_CLK2X_bp) ); // clear pre-scaler and clock multiplier bits
+
+ if(_SPI_CLOCK_DIVIDER >= 128) { SPI0_CTRLA |= SPI_PRESC1_bm|SPI_PRESC0_bm; }
+ else if (_SPI_CLOCK_DIVIDER >= 64) { SPI0_CTRLA |= SPI_PRESC1_bm; }
+ else if (_SPI_CLOCK_DIVIDER >= 32) { SPI0_CTRLA |= SPI_PRESC1_bm|SPI_CLK2X_bm; }
+ else if (_SPI_CLOCK_DIVIDER >= 16) { SPI0_CTRLA |= SPI_PRESC0_bm; }
+ else if (_SPI_CLOCK_DIVIDER >= 8) { SPI0_CTRLA |= SPI_PRESC0_bm|SPI_CLK2X_bm; }
+ else if (_SPI_CLOCK_DIVIDER >= 4) { /* default rate */ }
+ else { SPI0_CTRLA |= SPI_CLK2X_bm; }
+ }
+
+ static void stop() {
+ SPI0_CTRLA &= ~(SPI_ENABLE_bm);
+ }
+
+ static bool shouldWait(bool wait = false) __attribute__((always_inline)) {
+ static bool sWait=false;
+ if(sWait) {
+ sWait = wait; return true;
+ } else {
+ sWait = wait; return false;
+ }
+ }
+ static void wait() __attribute__((always_inline)) {
+ if(shouldWait()) {
+ while(!(SPI0_INTFLAGS & SPI_IF_bm));
+ }
+ }
+ static void waitFully() __attribute__((always_inline)) { wait(); }
+
+ static void writeWord(uint16_t w) __attribute__((always_inline)) { writeByte(w>>8); writeByte(w&0xFF); }
+
+ static void writeByte(uint8_t b) __attribute__((always_inline)) { wait(); SPI0_DATA=b; shouldWait(true); }
+ static void writeBytePostWait(uint8_t b) __attribute__((always_inline)) { SPI0_DATA=b; shouldWait(true); wait(); }
+ static void writeByteNoWait(uint8_t b) __attribute__((always_inline)) { SPI0_DATA=b; shouldWait(true); }
+
+
+ template <uint8_t BIT> inline static void writeBit(uint8_t b) {
+ if(b && (1 << BIT)) {
+ FastPin<_DATA_PIN>::hi();
+ } else {
+ FastPin<_DATA_PIN>::lo();
+ }
+
+ FastPin<_CLOCK_PIN>::hi();
+ FastPin<_CLOCK_PIN>::lo();
+ }
+
+ void enable_pins() { }
+ void disable_pins() { }
+
+ void select() {
+ if(m_pSelect != NULL) {
+ m_pSelect->select();
+ }
+ enable_pins();
+ setSPIRate();
+ }
+
+ void release() {
+ if(m_pSelect != NULL) {
+ m_pSelect->release();
+ }
+ disable_pins();
+ }
+
+ static void writeBytesValueRaw(uint8_t value, int len) {
+ while(len--) {
+ writeByte(value);
+ }
+ }
+
+ void writeBytesValue(uint8_t value, int len) {
+ //setSPIRate();
+ select();
+ while(len--) {
+ writeByte(value);
+ }
+ release();
+ }
+
+ // Write a block of n uint8_ts out
+ template <class D> void writeBytes(register uint8_t *data, int len) {
+ //setSPIRate();
+ uint8_t *end = data + len;
+ select();
+ while(data != end) {
+ // a slight touch of delay here helps optimize the timing of the status register check loop (not used on ARM)
+ writeByte(D::adjust(*data++)); delaycycles<3>();
+ }
+ release();
+ }
+
+ void writeBytes(register uint8_t *data, int len) { writeBytes<DATA_NOP>(data, len); }
+
+ // write a block of uint8_ts out in groups of three. len is the total number of uint8_ts to write out. The template
+ // parameters indicate how many uint8_ts to skip at the beginning and/or end of each grouping
+ template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) {
+ //setSPIRate();
+ int len = pixels.mLen;
+
+ select();
+ while(pixels.has(1)) {
+ if(FLAGS & FLAG_START_BIT) {
+ writeBit<0>(1);
+ writeBytePostWait(D::adjust(pixels.loadAndScale0()));
+ writeBytePostWait(D::adjust(pixels.loadAndScale1()));
+ writeBytePostWait(D::adjust(pixels.loadAndScale2()));
+ } else {
+ writeByte(D::adjust(pixels.loadAndScale0()));
+ writeByte(D::adjust(pixels.loadAndScale1()));
+ writeByte(D::adjust(pixels.loadAndScale2()));
+ }
+
+ pixels.advanceData();
+ pixels.stepDithering();
+ }
+ D::postBlock(len);
+ release();
+ }
+};
+
+#endif
#if defined(SPSR)
diff --git a/src/platforms/avr/led_sysdefs_avr.h b/src/platforms/avr/led_sysdefs_avr.h
index 05d6e5ed..888d75e5 100644
--- a/src/platforms/avr/led_sysdefs_avr.h
+++ b/src/platforms/avr/led_sysdefs_avr.h
@@ -56,7 +56,7 @@ extern volatile unsigned long timer0_millis;
};
// special defs for the tiny environments
-#if defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny167__) || defined(__AVR_ATtiny87__) || defined(__AVR_ATtinyX41__) || defined(__AVR_ATtiny841__) || defined(__AVR_ATtiny441__)
+#if defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny167__) || defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny88__) || defined(__AVR_ATtinyX41__) || defined(__AVR_ATtiny841__) || defined(__AVR_ATtiny441__)
#define LIB8_ATTINY 1
#define FASTLED_NEEDS_YIELD
#endif
diff --git a/src/platforms/esp/32/clockless_i2s_esp32.h b/src/platforms/esp/32/clockless_i2s_esp32.h
index d7af459d..5c7979cf 100644
--- a/src/platforms/esp/32/clockless_i2s_esp32.h
+++ b/src/platforms/esp/32/clockless_i2s_esp32.h
@@ -103,7 +103,13 @@ extern "C" {
#include "driver/gpio.h"
#include "driver/periph_ctrl.h"
#include "rom/lldesc.h"
+#include "esp_system.h" // Load ESP_IDF_VERSION_MAJOR if exists
+// ESP_IDF_VERSION_MAJOR is defined in ESP-IDF v3.3 or later
+#if defined(ESP_IDF_VERSION_MAJOR) && ESP_IDF_VERSION_MAJOR > 3
+#include "esp_intr_alloc.h"
+#else
#include "esp_intr.h"
+#endif
#include "esp_log.h"
#ifdef __cplusplus
diff --git a/src/platforms/esp/32/clockless_rmt_esp32.cpp b/src/platforms/esp/32/clockless_rmt_esp32.cpp
index c7691f69..0c729ff4 100644
--- a/src/platforms/esp/32/clockless_rmt_esp32.cpp
+++ b/src/platforms/esp/32/clockless_rmt_esp32.cpp
@@ -1,6 +1,8 @@
#ifdef ESP32
+#ifndef FASTLED_ESP32_I2S
+
#define FASTLED_INTERNAL
#include "FastLED.h"
@@ -331,10 +333,13 @@ void IRAM_ATTR ESP32RMTController::interruptHandler(void *arg)
uint32_t intr_st = RMT.int_st.val;
uint8_t channel;
- bool stuff_to_do = false;
for (channel = 0; channel < gMaxChannel; channel++) {
int tx_done_bit = channel * 3;
+ #ifdef CONFIG_IDF_TARGET_ESP32S2
+ int tx_next_bit = channel + 12;
+ #else
int tx_next_bit = channel + 24;
+ #endif
ESP32RMTController * pController = gOnChannel[channel];
if (pController != NULL) {
@@ -450,4 +455,6 @@ void ESP32RMTController::convertByte(uint32_t byteval)
}
}
-#endif
+#endif // ! FASTLED_ESP32_I2S
+
+#endif // ESP32
diff --git a/src/platforms/esp/32/clockless_rmt_esp32.h b/src/platforms/esp/32/clockless_rmt_esp32.h
index 3a10f9ca..2a8555ab 100644
--- a/src/platforms/esp/32/clockless_rmt_esp32.h
+++ b/src/platforms/esp/32/clockless_rmt_esp32.h
@@ -113,7 +113,12 @@ extern "C" {
#endif
#include "esp32-hal.h"
+// ESP_IDF_VERSION_MAJOR is defined in ESP-IDF v3.3 or later
+#if defined(ESP_IDF_VERSION_MAJOR) && ESP_IDF_VERSION_MAJOR > 3
+#include "esp_intr_alloc.h"
+#else
#include "esp_intr.h"
+#endif
#include "driver/gpio.h"
#include "driver/rmt.h"
#include "driver/periph_ctrl.h"
@@ -183,10 +188,14 @@ __attribute__ ((always_inline)) inline static uint32_t __clock_cycles() {
#define FASTLED_RMT_MAX_CONTROLLERS 32
#endif
-// -- Max RMT channel (default to 8)
+// -- Max RMT channel (default to 8 on ESP32 and 4 on ESP32-S2)
#ifndef FASTLED_RMT_MAX_CHANNELS
+#ifdef CONFIG_IDF_TARGET_ESP32S2
+#define FASTLED_RMT_MAX_CHANNELS 4
+#else
#define FASTLED_RMT_MAX_CHANNELS 8
#endif
+#endif
class ESP32RMTController
{
diff --git a/src/platforms/fastspi_ardunio_core.h b/src/platforms/fastspi_ardunio_core.h
new file mode 100644
index 00000000..a0f92288
--- /dev/null
+++ b/src/platforms/fastspi_ardunio_core.h
@@ -0,0 +1,103 @@
+#ifndef __INC_FASTSPI_ARDUNIO_CORE_H
+#define __INC_FASTSPI_ARDUNIO_CORE_H
+
+FASTLED_NAMESPACE_BEGIN
+
+#if defined(ARDUNIO_CORE_SPI)
+#include <SPI.h>
+
+template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_RATE, SPIClass & _SPIObject>
+class ArdunioCoreSPIOutput {
+
+public:
+ ArdunioCoreSPIOutput() {}
+
+ // set the object representing the selectable -- ignore for now
+ void setSelect(Selectable *pSelect) { /* TODO */ }
+
+ // initialize the SPI subssytem
+ void init() { _SPIObject.begin(); }
+
+ // latch the CS select
+ void inline select() __attribute__((always_inline)) {
+ // begin the SPI transaction
+ _SPIObject.beginTransaction(SPISettings(_SPI_CLOCK_RATE, MSBFIRST, SPI_MODE0));
+ }
+
+ // release the CS select
+ void inline release() __attribute__((always_inline)) {
+ _SPIObject.endTransaction();
+ }
+
+ // wait until all queued up data has been written
+ static void waitFully() { /* TODO */ }
+
+ // write a byte out via SPI (returns immediately on writing register) -
+ void inline writeByte(uint8_t b) __attribute__((always_inline)) {
+ _SPIObject.transfer(b);
+ }
+
+ // write a word out via SPI (returns immediately on writing register)
+ void inline writeWord(uint16_t w) __attribute__((always_inline)) {
+ _SPIObject.transfer16(w);
+ }
+
+ // A raw set of writing byte values, assumes setup/init/waiting done elsewhere
+ static void writeBytesValueRaw(uint8_t value, int len) {
+ while(len--) { _SPIObject.transfer(value); }
+ }
+
+ // A full cycle of writing a value for len bytes, including select, release, and waiting
+ void writeBytesValue(uint8_t value, int len) {
+ select(); writeBytesValueRaw(value, len); release();
+ }
+
+ // A full cycle of writing a value for len bytes, including select, release, and waiting
+ template <class D> void writeBytes(register uint8_t *data, int len) {
+ uint8_t *end = data + len;
+ select();
+ // could be optimized to write 16bit words out instead of 8bit bytes
+ while(data != end) {
+ writeByte(D::adjust(*data++));
+ }
+ D::postBlock(len);
+ waitFully();
+ release();
+ }
+
+ // A full cycle of writing a value for len bytes, including select, release, and waiting
+ void writeBytes(register uint8_t *data, int len) { writeBytes<DATA_NOP>(data, len); }
+
+ // write a single bit out, which bit from the passed in byte is determined by template parameter
+ template <uint8_t BIT> inline void writeBit(uint8_t b) {
+ // todo
+ }
+
+ // write a block of uint8_ts out in groups of three. len is the total number of uint8_ts to write out. The template
+ // parameters indicate how many uint8_ts to skip at the beginning and/or end of each grouping
+ template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) {
+ select();
+ int len = pixels.mLen;
+
+ while(pixels.has(1)) {
+ if(FLAGS & FLAG_START_BIT) {
+ writeBit<0>(1);
+ }
+ writeByte(D::adjust(pixels.loadAndScale0()));
+ writeByte(D::adjust(pixels.loadAndScale1()));
+ writeByte(D::adjust(pixels.loadAndScale2()));
+
+ pixels.advanceData();
+ pixels.stepDithering();
+ }
+ D::postBlock(len);
+ release();
+ }
+
+};
+
+
+#endif
+
+FASTLED_NAMESPACE_END
+#endif