#pragma once /// @file fastspi.h /// Serial peripheral interface (SPI) definitions per platform #ifndef __INC_FASTSPI_H #define __INC_FASTSPI_H #include "FastLED.h" #include "controller.h" #include "lib8tion.h" #include "fastspi_bitbang.h" #include "fl/int.h" #if defined(FASTLED_TEENSY3) && (F_CPU > 48000000) #define DATA_RATE_MHZ(X) (((48000000L / 1000000L) / X)) #define DATA_RATE_KHZ(X) (((48000000L / 1000L) / X)) #elif defined(FASTLED_TEENSY4) || (defined(ESP32) && defined(FASTLED_ALL_PINS_HARDWARE_SPI)) || (defined(ESP8266) && defined(FASTLED_ALL_PINS_HARDWARE_SPI) || defined(FASTLED_STUB_IMPL)) // just use clocks #define DATA_RATE_MHZ(X) (1000000 * (X)) #define DATA_RATE_KHZ(X) (1000 * (X)) #else /// Convert data rate from megahertz (MHz) to clock cycles per bit #define DATA_RATE_MHZ(X) ((F_CPU / 1000000L) / X) /// Convert data rate from kilohertz (KHz) to clock cycles per bit #define DATA_RATE_KHZ(X) ((F_CPU / 1000L) / X) #endif ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // External SPI template definition with partial instantiation(s) to map to hardware SPI ports on platforms/builds where the pin // mappings are known at compile time. // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// FASTLED_NAMESPACE_BEGIN #if defined(FASTLED_STUB_IMPL) template class SPIOutput : public fl::StubSPIOutput {}; #else #if !defined(FASTLED_ALL_PINS_HARDWARE_SPI) /// Hardware SPI output template class SPIOutput : public AVRSoftwareSPIOutput<_DATA_PIN, _CLOCK_PIN, _SPI_CLOCK_DIVIDER> {}; #endif /// Software SPI output template class SoftwareSPIOutput : public AVRSoftwareSPIOutput<_DATA_PIN, _CLOCK_PIN, _SPI_CLOCK_DIVIDER> {}; #ifndef FASTLED_FORCE_SOFTWARE_SPI #if defined(NRF51) && defined(FASTLED_ALL_PINS_HARDWARE_SPI) template class SPIOutput : public NRF51SPIOutput<_DATA_PIN, _CLOCK_PIN, _SPI_CLOCK_DIVIDER> {}; #endif #if defined(NRF52_SERIES) && defined(FASTLED_ALL_PINS_HARDWARE_SPI) template class SPIOutput : public NRF52SPIOutput<_DATA_PIN, _CLOCK_PIN, _SPI_CLOCK_DIVIDER> {}; #endif #if defined(FASTLED_APOLLO3) && defined(FASTLED_ALL_PINS_HARDWARE_SPI) template class SPIOutput : public APOLLO3HardwareSPIOutput<_DATA_PIN, _CLOCK_PIN, _SPI_CLOCK_DIVIDER> {}; #endif #if defined(ESP32) && defined(FASTLED_ALL_PINS_HARDWARE_SPI) template class SPIOutput : public ESP32SPIOutput<_DATA_PIN, _CLOCK_PIN, _SPI_CLOCK_DIVIDER> {}; #endif #if defined(ESP8266) && defined(FASTLED_ALL_PINS_HARDWARE_SPI) template class SPIOutput : public ESP8266SPIOutput<_DATA_PIN, _CLOCK_PIN, _SPI_CLOCK_DIVIDER> {}; #endif #if defined(SPI_DATA) && defined(SPI_CLOCK) #if defined(FASTLED_TEENSY3) && defined(ARM_HARDWARE_SPI) template class SPIOutput : public ARMHardwareSPIOutput {}; #if defined(SPI2_DATA) template class SPIOutput : public ARMHardwareSPIOutput {}; template class SPIOutput : public ARMHardwareSPIOutput {}; template class SPIOutput : public ARMHardwareSPIOutput {}; #endif #elif defined(FASTLED_TEENSY4) && defined(ARM_HARDWARE_SPI) template class SPIOutput : public Teensy4HardwareSPIOutput {}; template class SPIOutput : public Teensy4HardwareSPIOutput {}; template class SPIOutput : public Teensy4HardwareSPIOutput {}; #elif defined(FASTLED_TEENSYLC) && defined(ARM_HARDWARE_SPI) #define DECLARE_SPI0(__DATA,__CLOCK) template\ class SPIOutput<__DATA, __CLOCK, SPI_SPEED> : public ARMHardwareSPIOutput<__DATA, __CLOCK, SPI_SPEED, 0x40076000> {}; #define DECLARE_SPI1(__DATA,__CLOCK) template\ class SPIOutput<__DATA, __CLOCK, SPI_SPEED> : public ARMHardwareSPIOutput<__DATA, __CLOCK, SPI_SPEED, 0x40077000> {}; DECLARE_SPI0(7,13); DECLARE_SPI0(8,13); DECLARE_SPI0(11,13); DECLARE_SPI0(12,13); DECLARE_SPI0(7,14); DECLARE_SPI0(8,14); DECLARE_SPI0(11,14); DECLARE_SPI0(12,14); DECLARE_SPI1(0,20); DECLARE_SPI1(1,20); DECLARE_SPI1(21,20); #elif defined(__SAM3X8E__) template class SPIOutput : public SAMHardwareSPIOutput {}; #elif defined(AVR_HARDWARE_SPI) template class SPIOutput : public AVRHardwareSPIOutput {}; #if defined(SPI_UART0_DATA) template class SPIOutput : public AVRUSART0SPIOutput {}; #endif #if defined(SPI_UART1_DATA) template class SPIOutput : public AVRUSART1SPIOutput {}; #endif #elif defined(ARDUNIO_CORE_SPI) template class SPIOutput : public ArdunioCoreSPIOutput {}; #endif #else # if !defined(FASTLED_INTERNAL) && !defined(FASTLED_ALL_PINS_HARDWARE_SPI) && !defined(ESP32) # ifdef FASTLED_HAS_PRAGMA_MESSAGE # pragma message "WARNING: The SPI pins you chose have not been marked as hardware accelerated within the code base. All SPI access will default to bitbanged output. Consult the data sheet for hardware spi pins designed for efficient SPI transfer, typically via DMA / MOSI / SCK / SS pin" # else # warning "The SPI pins you chose have not been marked as hardware accelerated within the code base. All SPI access will default to bitbanged output. Consult the data sheet for hardware spi pins designed for efficient SPI transfer, typically via DMA / MOSI / SCK / SS pins" # endif # endif #endif // #if defined(USART_DATA) && defined(USART_CLOCK) // template // class AVRSPIOutput : public AVRUSARTSPIOutput {}; // #endif #else # if !defined(FASTLED_INTERNAL) && !defined(FASTLED_ALL_PINS_HARDWARE_SPI) # ifdef FASTLED_HAS_PRAGMA_MESSAGE # pragma message "Forcing software SPI - no hardware accelerated SPI for you!" # else # warning "Forcing software SPI - no hardware accelerated SPI for you!" # endif # endif #endif #endif // !defined(FASTLED_STUB_IMPL) FASTLED_NAMESPACE_END #endif