From 5349bdcbd7367dc649dff8e6a4e307879dd64a0a Mon Sep 17 00:00:00 2001 From: Craig Link Date: Sun, 21 Feb 2021 22:28:32 -0800 Subject: Add support for Seeed Wio Terminal --- src/led_sysdefs.h | 4 +++- src/platforms.h | 2 +- src/platforms/arm/d51/README.txt | 5 ++++- src/platforms/arm/d51/fastpin_arm_d51.h | 18 ++++++++++++++++++ 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/led_sysdefs.h b/src/led_sysdefs.h index 8ee568bf..d1b1ddab 100644 --- a/src/led_sysdefs.h +++ b/src/led_sysdefs.h @@ -26,8 +26,10 @@ #include "platforms/arm/sam/led_sysdefs_arm_sam.h" #elif defined(STM32F10X_MD) || defined(__STM32F1__) #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/platforms.h b/src/platforms.h index 7969c9e4..8953ceff 100644 --- a/src/platforms.h +++ b/src/platforms.h @@ -28,7 +28,7 @@ #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..40249071 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 WS8212B + diff --git a/src/platforms/arm/d51/fastpin_arm_d51.h b/src/platforms/arm/d51/fastpin_arm_d51.h index 9d31cedb..50e9afa9 100644 --- a/src/platforms/arm/d51/fastpin_arm_d51.h +++ b/src/platforms/arm/d51/fastpin_arm_d51.h @@ -127,6 +127,24 @@ _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(21, 17, 0); _FL_DEFPIN(22, 16, 0); +// 23..25 MISO/MOSI/SCK +_FL_DEFPIN(23, 0, 1); _FL_DEFPIN(24, 2, 1); _FL_DEFPIN(25, 3, 1); + +#define SPI_DATA 24 +#define SPI_CLOCK 25 + +#define HAS_HARDWARE_PIN_SUPPORT 1 + #endif -- cgit v1.2.3 From 56acf0ad701441f229e7d129db26c94b33d8b09b Mon Sep 17 00:00:00 2001 From: Craig Link Date: Thu, 25 Feb 2021 16:23:08 -0800 Subject: adjust PIN numbers for SPI to match GPIO --- src/platforms/arm/d51/README.txt | 2 +- src/platforms/arm/d51/fastpin_arm_d51.h | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/platforms/arm/d51/README.txt b/src/platforms/arm/d51/README.txt index 40249071..98b1adf2 100644 --- a/src/platforms/arm/d51/README.txt +++ b/src/platforms/arm/d51/README.txt @@ -3,5 +3,5 @@ FastLED updates for adafruit FEATHER M4 and fixes to ITSBITSY M4 compiles Tested on - FEATHER M4 with DOTSTAR and neopixel strips - - Seeed Wio Terminal and WS8212B + - Seeed Wio Terminal and WS2812B diff --git a/src/platforms/arm/d51/fastpin_arm_d51.h b/src/platforms/arm/d51/fastpin_arm_d51.h index 50e9afa9..4a7a79bc 100644 --- a/src/platforms/arm/d51/fastpin_arm_d51.h +++ b/src/platforms/arm/d51/fastpin_arm_d51.h @@ -136,12 +136,12 @@ _FL_DEFPIN( 0, 8, 1); _FL_DEFPIN( 1, 9, 1); _FL_DEFPIN( 2, 7, 0); _FL_DEFPIN( _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(21, 17, 0); _FL_DEFPIN(22, 16, 0); -// 23..25 MISO/MOSI/SCK -_FL_DEFPIN(23, 0, 1); _FL_DEFPIN(24, 2, 1); _FL_DEFPIN(25, 3, 1); +_FL_DEFPIN(12, 17, 0); _FL_DEFPIN(13, 16, 0); +// match GPIO pin nubers 9..11 MISO/MOSI/SCK +_FL_DEFPIN(9, 0, 1); _FL_DEFPIN(10, 2, 1); _FL_DEFPIN(11, 3, 1); -#define SPI_DATA 24 -#define SPI_CLOCK 25 +#define SPI_DATA 10 +#define SPI_CLOCK 11 #define HAS_HARDWARE_PIN_SUPPORT 1 -- cgit v1.2.3 From 29554f8e3661e1c2f449023c79d71599a37111df Mon Sep 17 00:00:00 2001 From: Craig Link Date: Sun, 28 Feb 2021 03:40:23 -0800 Subject: Add native SPI support for ARM D51 (and others) by providing a Ardunio.Core SPI wrapper Add support for Seeed Wio Terminal --- src/platforms/arm/d51/fastled_arm_d51.h | 1 + src/platforms/arm/d51/fastpin_arm_d51.h | 8 ++- src/platforms/arm/d51/led_sysdefs_arm_d51.h | 4 +- src/platforms/fastspi_ardunio_core.h | 103 ++++++++++++++++++++++++++++ 4 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 src/platforms/fastspi_ardunio_core.h 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 4a7a79bc..c2a34cc4 100644 --- a/src/platforms/arm/d51/fastpin_arm_d51.h +++ b/src/platforms/arm/d51/fastpin_arm_d51.h @@ -138,11 +138,13 @@ _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(9, 0, 1); _FL_DEFPIN(10, 2, 1); _FL_DEFPIN(11, 3, 1); +_FL_DEFPIN(PIN_SPI_MISO, 0, 1); _FL_DEFPIN(PIN_SPI_MOSI, 2, 1); _FL_DEFPIN(PIN_SPI_SCK, 3, 1); -#define SPI_DATA 10 -#define SPI_CLOCK 11 +#define SPI_DATA PIN_SPI_MOSI +#define SPI_CLOCK PIN_SPI_SCK + +#define ARDUNIO_CORE_SPI #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/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 + +template +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 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, len); } + + // write a single bit out, which bit from the passed in byte is determined by template parameter + template 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 void writePixels(PixelController 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 -- cgit v1.2.3 From 8b50709526756627dce90ab2a78f2acd830ac7ca Mon Sep 17 00:00:00 2001 From: Craig Link Date: Sun, 28 Feb 2021 03:40:23 -0800 Subject: Add native SPI support for ARM D51 (and others) by providing a Ardunio.Core SPI wrapper Add support for Seeed Wio Terminal Verified with Neopixel and Dotstar stripping using either SPI or GPIO pins --- src/fastspi.h | 5 ++ src/platforms/arm/d51/README.txt | 2 +- src/platforms/arm/d51/fastled_arm_d51.h | 1 + src/platforms/arm/d51/fastpin_arm_d51.h | 8 ++- src/platforms/arm/d51/led_sysdefs_arm_d51.h | 4 +- src/platforms/fastspi_ardunio_core.h | 103 ++++++++++++++++++++++++++++ 6 files changed, 116 insertions(+), 7 deletions(-) create mode 100644 src/platforms/fastspi_ardunio_core.h 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 : public AVRUSART1SP #endif +#elif defined(ARDUNIO_CORE_SPI) + +template +class SPIOutput : public ArdunioCoreSPIOutput {}; + #endif #else diff --git a/src/platforms/arm/d51/README.txt b/src/platforms/arm/d51/README.txt index 98b1adf2..036a02a6 100644 --- a/src/platforms/arm/d51/README.txt +++ b/src/platforms/arm/d51/README.txt @@ -3,5 +3,5 @@ FastLED updates for adafruit FEATHER M4 and fixes to ITSBITSY M4 compiles Tested on - FEATHER M4 with DOTSTAR and neopixel strips - - Seeed Wio Terminal and WS2812B + - 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 4a7a79bc..c2a34cc4 100644 --- a/src/platforms/arm/d51/fastpin_arm_d51.h +++ b/src/platforms/arm/d51/fastpin_arm_d51.h @@ -138,11 +138,13 @@ _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(9, 0, 1); _FL_DEFPIN(10, 2, 1); _FL_DEFPIN(11, 3, 1); +_FL_DEFPIN(PIN_SPI_MISO, 0, 1); _FL_DEFPIN(PIN_SPI_MOSI, 2, 1); _FL_DEFPIN(PIN_SPI_SCK, 3, 1); -#define SPI_DATA 10 -#define SPI_CLOCK 11 +#define SPI_DATA PIN_SPI_MOSI +#define SPI_CLOCK PIN_SPI_SCK + +#define ARDUNIO_CORE_SPI #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/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 + +template +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 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, len); } + + // write a single bit out, which bit from the passed in byte is determined by template parameter + template 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 void writePixels(PixelController 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 -- cgit v1.2.3