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:
authorJason Tranchida <jtranchida@gmail.com>2021-11-15 09:43:44 +0300
committerJason Tranchida <jtranchida@gmail.com>2021-11-17 09:47:31 +0300
commit60fa753bfd6495f5163a1fedecd8240d5a723e47 (patch)
tree7a9f623fa9515bcb4d6837fd111ee59b8cab03cb
parentccd2c7b426179ad50e4e2c0d3f132954fc6aa72c (diff)
Add pin support for new ESP32 variants
* Add support for C3, S3, and H2 * Update pin definition mechanism to be to support multiple variants * Fix S2 mapping that were excluding base ESP32 pin masking
-rw-r--r--src/platforms/esp/32/clockless_block_esp32.h5
-rw-r--r--src/platforms/esp/32/clockless_i2s_esp32.h6
-rw-r--r--src/platforms/esp/32/clockless_rmt_esp32.h4
-rw-r--r--src/platforms/esp/32/fastpin_esp32.h167
-rw-r--r--src/platforms/esp/32/fastspi_esp32.h4
5 files changed, 119 insertions, 67 deletions
diff --git a/src/platforms/esp/32/clockless_block_esp32.h b/src/platforms/esp/32/clockless_block_esp32.h
index 45b7671c..3e3c139e 100644
--- a/src/platforms/esp/32/clockless_block_esp32.h
+++ b/src/platforms/esp/32/clockless_block_esp32.h
@@ -21,7 +21,10 @@ class InlineBlockClocklessController : public CPixelLEDController<RGB_ORDER, LAN
typedef typename FastPin<FIRST_PIN>::port_ptr_t data_ptr_t;
typedef typename FastPin<FIRST_PIN>::port_t data_t;
- data_t mPinMask;
+ // Verify that the pin is valid
+ static_assert(FastPin<FIRST_PIN>::validpin(), "Invalid pin specified");
+
+ data_t mPinMask;
data_ptr_t mPort;
CMinWait<WAIT_TIME> mWait;
diff --git a/src/platforms/esp/32/clockless_i2s_esp32.h b/src/platforms/esp/32/clockless_i2s_esp32.h
index 6306ccd2..dc4705bd 100644
--- a/src/platforms/esp/32/clockless_i2s_esp32.h
+++ b/src/platforms/esp/32/clockless_i2s_esp32.h
@@ -201,8 +201,8 @@ class ClocklessController : public CPixelLEDController<RGB_ORDER>
// -- Store the GPIO pin
gpio_num_t mPin;
- // -- This instantiation forces a check on the pin choice
- FastPin<DATA_PIN> mFastPin;
+ // -- Verify that the pin is valid
+ static_assert(FastPin<DATA_PIN>::validpin(), "Invalid pin specified");
// -- Save the pixel controller
PixelController<RGB_ORDER> * mPixels;
@@ -459,7 +459,7 @@ protected:
periph_module_enable(PERIPH_I2S1_MODULE);
interruptSource = ETS_I2S1_INTR_SOURCE;
i2s_base_pin_index = I2S1O_DATA_OUT0_IDX;
- }
+ #endif
// -- Reset everything
i2sReset();
diff --git a/src/platforms/esp/32/clockless_rmt_esp32.h b/src/platforms/esp/32/clockless_rmt_esp32.h
index 8f5690bb..73bcefbc 100644
--- a/src/platforms/esp/32/clockless_rmt_esp32.h
+++ b/src/platforms/esp/32/clockless_rmt_esp32.h
@@ -316,8 +316,8 @@ private:
// -- The actual controller object for ESP32
ESP32RMTController mRMTController;
- // -- This instantiation forces a check on the pin choice
- FastPin<DATA_PIN> mFastPin;
+ // -- Verify that the pin is valid
+ static_assert(FastPin<DATA_PIN>::validpin(), "Invalid pin specified");
public:
diff --git a/src/platforms/esp/32/fastpin_esp32.h b/src/platforms/esp/32/fastpin_esp32.h
index 7876b281..7c77a738 100644
--- a/src/platforms/esp/32/fastpin_esp32.h
+++ b/src/platforms/esp/32/fastpin_esp32.h
@@ -2,34 +2,45 @@
FASTLED_NAMESPACE_BEGIN
-template<uint8_t PIN, uint32_t MASK> class _ESPPIN {
+template<uint8_t PIN, uint32_t MASK, bool VALIDPIN> class _ESPPIN {
public:
typedef volatile uint32_t * port_ptr_t;
typedef uint32_t port_t;
- inline static void setOutput() { pinMode(PIN, OUTPUT); }
+ static constexpr bool validpin() { return VALIDPIN; }
+
+#ifndef GPIO_OUT1_REG
+ static constexpr uint32_t GPIO_REG = GPIO_OUT_REG;
+ static constexpr uint32_t GPIO_BIT_SET_REG = GPIO_OUT_W1TS_REG;
+ static constexpr uint32_t GPIO_BIT_CLEAR_REG = GPIO_OUT_W1TC_REG;
+ #else
+ static constexpr uint32_t GPIO_REG = PIN < 32 ? GPIO_OUT_REG : GPIO_OUT1_REG;
+ static constexpr uint32_t GPIO_BIT_SET_REG = PIN < 32 ? GPIO_OUT_W1TS_REG : GPIO_OUT1_W1TS_REG;
+ static constexpr uint32_t GPIO_BIT_CLEAR_REG = PIN < 32 ? GPIO_OUT_W1TC_REG : GPIO_OUT1_W1TC_REG;
+ #endif
+
+ inline static void setOutput() {
+ static_assert(validpin(), "Invalid pin specified");
+ pinMode(PIN, OUTPUT);
+ }
inline static void setInput() { pinMode(PIN, INPUT); }
inline static void hi() __attribute__ ((always_inline)) {
- if (PIN < 32) GPIO.out_w1ts = MASK;
- else GPIO.out1_w1ts.val = MASK;
+ *sport() = MASK;
}
inline static void lo() __attribute__ ((always_inline)) {
- if (PIN < 32) GPIO.out_w1tc = MASK;
- else GPIO.out1_w1tc.val = MASK;
+ *cport() = MASK;
}
inline static void set(register port_t val) __attribute__ ((always_inline)) {
- if (PIN < 32) GPIO.out = val;
- else GPIO.out1.val = val;
+ *port() = val;
}
inline static void strobe() __attribute__ ((always_inline)) { toggle(); toggle(); }
inline static void toggle() __attribute__ ((always_inline)) {
- if(PIN < 32) { GPIO.out ^= MASK; }
- else { GPIO.out1.val ^=MASK; }
+ *port() ^= MASK;
}
inline static void hi(register port_ptr_t port) __attribute__ ((always_inline)) { hi(); }
@@ -37,77 +48,111 @@ public:
inline static void fastset(register port_ptr_t port, register port_t val) __attribute__ ((always_inline)) { *port = val; }
inline static port_t hival() __attribute__ ((always_inline)) {
- if (PIN < 32) return GPIO.out | MASK;
- else return GPIO.out1.val | MASK;
+ return (*port()) | MASK;
}
inline static port_t loval() __attribute__ ((always_inline)) {
- if (PIN < 32) return GPIO.out & ~MASK;
- else return GPIO.out1.val & ~MASK;
+ return (*port()) & ~MASK;
}
inline static port_ptr_t port() __attribute__ ((always_inline)) {
- if (PIN < 32) return &GPIO.out;
- else return &GPIO.out1.val;
+ return (port_ptr_t)GPIO_REG;
}
inline static port_ptr_t sport() __attribute__ ((always_inline)) {
- if (PIN < 32) return &GPIO.out_w1ts;
- else return &GPIO.out1_w1ts.val;
+ return (port_ptr_t)GPIO_BIT_SET_REG;
}
inline static port_ptr_t cport() __attribute__ ((always_inline)) {
- if (PIN < 32) return &GPIO.out_w1tc;
- else return &GPIO.out1_w1tc.val;
+ return (port_ptr_t)GPIO_BIT_CLEAR_REG;
}
inline static port_t mask() __attribute__ ((always_inline)) { return MASK; }
inline static bool isset() __attribute__ ((always_inline)) {
- if (PIN < 32) return GPIO.out & MASK;
- else return GPIO.out1.val & MASK;
+ return (*port()) & MASK;
}
};
-#define _FL_DEFPIN(PIN) template<> class FastPin<PIN> : public _ESPPIN<PIN, ((PIN<32)?((uint32_t)1 << PIN):((uint32_t)1 << (PIN-32)))> {};
-
-_FL_DEFPIN(0);
-_FL_DEFPIN(1); // WARNING: Using TX causes flashiness when uploading
-_FL_DEFPIN(2);
-_FL_DEFPIN(3); // WARNING: Using RX causes flashiness when uploading
-_FL_DEFPIN(4);
-_FL_DEFPIN(5);
-
-// -- These pins are not safe to use:
-// _FL_DEFPIN(6,6); _FL_DEFPIN(7,7); _FL_DEFPIN(8,8);
-// _FL_DEFPIN(9,9); _FL_DEFPIN(10,10); _FL_DEFPIN(11,11);
-
-_FL_DEFPIN(12);
-_FL_DEFPIN(13);
-_FL_DEFPIN(14);
-_FL_DEFPIN(15);
-_FL_DEFPIN(16);
-_FL_DEFPIN(17);
-_FL_DEFPIN(18);
-_FL_DEFPIN(19);
-
-// No pin 20 : _FL_DEFPIN(20,20);
-
-_FL_DEFPIN(21); // Works, but note that GPIO21 is I2C SDA
-_FL_DEFPIN(22); // Works, but note that GPIO22 is I2C SCL
-_FL_DEFPIN(23);
-
-// No pin 24 : _FL_DEFPIN(24,24);
-
-_FL_DEFPIN(25);
-_FL_DEFPIN(26);
-_FL_DEFPIN(27);
-
-// No pin 28-31: _FL_DEFPIN(28,28); _FL_DEFPIN(29,29); _FL_DEFPIN(30,30); _FL_DEFPIN(31,31);
-
-// Need special handling for pins > 31
-_FL_DEFPIN(32);
-_FL_DEFPIN(33);
+#ifndef FASTLED_UNUSABLE_PIN_MASK
+
+#define _FL_BIT(B) (1ULL << B)
+
+#if CONFIG_IDF_TARGET_ESP32
+// 40 GPIO pins. ESPIDF defined 24, 28-31 as invalid and 34-39 as readonly
+// GPIO 6-11 used by default for SPI flash. GPIO 20 is invalid.
+// NOTE: GPIO 1 & 3 commonly used for UART and may cause flashes when uploading.
+#define FASTLED_UNUSABLE_PIN_MASK (0ULL | _FL_BIT(6) | _FL_BIT(7) | _FL_BIT(8) | _FL_BIT(9) | _FL_BIT(10) | _FL_BIT(20))
+
+#elif CONFIG_IDF_TARGET_ESP32C3
+// 22 GPIO pins. ESPIDF defines all pins as valid
+// GPIO 11-17 used by default for SPI flash
+// NOTE: GPIO 20-21 commonly used for UART and may cause flashes when uploading.
+#define FASTLED_UNUSABLE_PIN_MASK (0ULL | _FL_BIT(11) | _FL_BIT(12) | _FL_BIT(13) | _FL_BIT(14) | _FL_BIT(15) | _FL_BIT(16) | _FL_BIT(17))
+
+#elif CONFIG_IDF_TARGET_ESP32S2
+// 48 GPIO pins. ESPIDF defines 22-25, 47 as invalid and 46-47 as readonly.s
+// GPIO 27-32 used by default for SPI flash.
+// NOTE: GPIO 37 & 38 commonly used for UART and may cause flashes when uploading.
+#define FASTLED_UNUSABLE_PIN_MASK (0ULL | _FL_BIT(27) | _FL_BIT(28) | _FL_BIT(29) | _FL_BIT(30) | _FL_BIT(31) | _FL_BIT(32))
+
+#elif CONFIG_IDF_TARGET_ESP32S3
+// 49 GPIO pins. ESPIDF defineds 22-25 as invalid.
+// GPIO 27-32 used by default for SPI flash.
+// NOTE: GPIO 43 & 44 commonly used for UART and may cause flashes when uploading.
+#define FASTLED_UNUSABLE_PIN_MASK (0ULL | _FL_BIT(27) | _FL_BIT(28) | _FL_BIT(29) | _FL_BIT(30) | _FL_BIT(31) | _FL_BIT(32))
+
+#elif CONFIG_IDF_TARGET_ESP32H2
+// 22 GPIO pins. ESPIDF defines all pins as valid.
+// ESP32-H2 datasheet not yet available, when it is, mask the pins commonly used by SPI flash.
+#warning ESP32-H2 chip flash configuration not yet known. Only pins defined by ESP-IDF will be masked.
+#define FASTLED_UNUSABLE_PIN_MASK (0ULL)
+
+#else
+#warning Unknown ESP32 chip variant. Only pins defined by ESP-IDF will be masked.
+#define FASTLED_UNUSABLE_PIN_MASK (0ULL)
+#endif
+
+#endif
+
+
+
+// SOC GPIO mask was not added until version IDF version 4.3. Prior to this only ESP32 chip was supported, so only
+// the value for ESP32
+#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 3, 0) && !defined(SOC_GPIO_VALID_OUTPUT_GPIO_MASK)
+// 0~39 except from 24, 28~31 are valid
+#define SOC_GPIO_VALID_GPIO_MASK (0xFFFFFFFFFFULL & ~(0ULL | _FL_BIT(24) | _FL_BIT(28) | _FL_BIT(29) | _FL_BIT(30) | _FL_BIT(31)))
+// GPIO >= 34 are input only
+#define SOC_GPIO_VALID_OUTPUT_GPIO_MASK (SOC_GPIO_VALID_GPIO_MASK & ~(0ULL | _FL_BIT(34) | _FL_BIT(35) | _FL_BIT(36) | _FL_BIT(37) | _FL_BIT(38) | _FL_BIT(39)))
+
+#endif
+
+
+// Define mask of valid pins. Start with the list of valid output pins from ESPIDF and remove unusable pins
+#define _FL_VALID_PIN_MASK (uint64_t(SOC_GPIO_VALID_OUTPUT_GPIO_MASK) & ~FASTLED_UNUSABLE_PIN_MASK)
+
+#define _FL_PIN_VALID(PIN) ((_FL_VALID_PIN_MASK & (1ULL << PIN)) != 0)
+
+#define _FL_DEFPIN(PIN) template <> class FastPin<PIN> : public _ESPPIN<PIN, ((uint32_t)1 << (PIN % 32)), _FL_PIN_VALID(PIN)> {};
+
+// Define all possible pins. If the pin is not valid for a particular ESP32 variant, the pin number
+// will be shifted into the 192-255 range, in effect rendering it unusable.
+_FL_DEFPIN( 0); _FL_DEFPIN( 1); _FL_DEFPIN( 2); _FL_DEFPIN( 3);
+_FL_DEFPIN( 4); _FL_DEFPIN( 5); _FL_DEFPIN( 6); _FL_DEFPIN( 7);
+_FL_DEFPIN( 8); _FL_DEFPIN( 9); _FL_DEFPIN(10); _FL_DEFPIN(11);
+_FL_DEFPIN(12); _FL_DEFPIN(13); _FL_DEFPIN(14); _FL_DEFPIN(15);
+_FL_DEFPIN(16); _FL_DEFPIN(17); _FL_DEFPIN(18); _FL_DEFPIN(19);
+_FL_DEFPIN(20); _FL_DEFPIN(21); _FL_DEFPIN(22); _FL_DEFPIN(23);
+_FL_DEFPIN(24); _FL_DEFPIN(25); _FL_DEFPIN(26); _FL_DEFPIN(27);
+_FL_DEFPIN(28); _FL_DEFPIN(29); _FL_DEFPIN(30); _FL_DEFPIN(31);
+_FL_DEFPIN(32); _FL_DEFPIN(33); _FL_DEFPIN(34); _FL_DEFPIN(35);
+_FL_DEFPIN(36); _FL_DEFPIN(37); _FL_DEFPIN(38); _FL_DEFPIN(39);
+_FL_DEFPIN(40); _FL_DEFPIN(41); _FL_DEFPIN(42); _FL_DEFPIN(43);
+_FL_DEFPIN(44); _FL_DEFPIN(45); _FL_DEFPIN(46); _FL_DEFPIN(47);
+_FL_DEFPIN(48); _FL_DEFPIN(49); _FL_DEFPIN(50); _FL_DEFPIN(51);
+_FL_DEFPIN(52); _FL_DEFPIN(53); _FL_DEFPIN(54); _FL_DEFPIN(55);
+_FL_DEFPIN(56); _FL_DEFPIN(57); _FL_DEFPIN(58); _FL_DEFPIN(59);
+_FL_DEFPIN(60); _FL_DEFPIN(61); _FL_DEFPIN(62); _FL_DEFPIN(63);
#define HAS_HARDWARE_PIN_SUPPORT
diff --git a/src/platforms/esp/32/fastspi_esp32.h b/src/platforms/esp/32/fastspi_esp32.h
index 33d620fd..d69bc523 100644
--- a/src/platforms/esp/32/fastspi_esp32.h
+++ b/src/platforms/esp/32/fastspi_esp32.h
@@ -68,6 +68,10 @@ class ESP32SPIOutput {
Selectable *m_pSelect;
public:
+ // Verify that the pins are valid
+ static_assert(FastPin<DATA_PIN>::validpin(), "Invalid data pin specified");
+ static_assert(FastPin<CLOCK_PIN>::validpin(), "Invalid clock pin specified");
+
ESP32SPIOutput() { m_pSelect = NULL; }
ESP32SPIOutput(Selectable *pSelect) { m_pSelect = pSelect; }
void setSelect(Selectable *pSelect) { m_pSelect = pSelect; }