forked from Makuna/NeoPixelBus
Dynamic channels (#411)
This commit is contained in:
26
keywords.txt
26
keywords.txt
@@ -188,6 +188,13 @@ NeoEsp32I2s1Tm1814InvertedMethod KEYWORD1
|
||||
NeoEsp32I2s1800KbpsInvertedMethod KEYWORD1
|
||||
NeoEsp32I2s1400KbpsInvertedMethod KEYWORD1
|
||||
NeoEsp32I2s1Apa106InvertedMethod KEYWORD1
|
||||
NeoEsp32RmtNWs2811Method KEYWORD1
|
||||
NeoEsp32RmtNWs2812xMethod KEYWORD1
|
||||
NeoEsp32RmtNSk6812Method KEYWORD1
|
||||
NeoEsp32RmtNTm1814Method KEYWORD1
|
||||
NeoEsp32RmtNApa106Method KEYWORD1
|
||||
NeoEsp32RmtN800KbpsMethod KEYWORD1
|
||||
NeoEsp32RmtN400KbpsMethod KEYWORD1
|
||||
NeoEsp32Rmt0Ws2811Method KEYWORD1
|
||||
NeoEsp32Rmt0Ws2812xMethod KEYWORD1
|
||||
NeoEsp32Rmt0Sk6812Method KEYWORD1
|
||||
@@ -244,6 +251,13 @@ NeoEsp32Rmt7Tm1814Method KEYWORD1
|
||||
NeoEsp32Rmt7Apa106Method KEYWORD1
|
||||
NeoEsp32Rmt7800KbpsMethod KEYWORD1
|
||||
NeoEsp32Rmt7400KbpsMethod KEYWORD1
|
||||
NeoEsp32RmtNWs2811InvertedMethod KEYWORD1
|
||||
NeoEsp32RmtNWs2812xInvertedMethod KEYWORD1
|
||||
NeoEsp32RmtNSk6812InvertedMethod KEYWORD1
|
||||
NeoEsp32RmtNTm1814InvertedMethod KEYWORD1
|
||||
NeoEsp32RmtNApa106InvertedMethod KEYWORD1
|
||||
NeoEsp32RmtN800KbpsInvertedMethod KEYWORD1
|
||||
NeoEsp32RmtN400KbpsInvertedMethod KEYWORD1
|
||||
NeoEsp32Rmt0Ws2811InvertedMethod KEYWORD1
|
||||
NeoEsp32Rmt0Ws2812xInvertedMethod KEYWORD1
|
||||
NeoEsp32Rmt0Sk6812InvertedMethod KEYWORD1
|
||||
@@ -320,6 +334,12 @@ NeoEsp32BitBangLc8812InvertedMethod KEYWORD1
|
||||
NeoEsp32BitBangApa106InvertedMethod KEYWORD1
|
||||
NeoEsp32BitBang800KbpsInvertedMethod KEYWORD1
|
||||
NeoEsp32BitBang400KbpsInvertedMethod KEYWORD1
|
||||
NeoNrf52xPwmNWs2812xMethod KEYWORD1
|
||||
NeoNrf52xPwmNSk6812Method KEYWORD1
|
||||
NeoNrf52xPwmNTm1814Method KEYWORD1
|
||||
NeoNrf52xPwmN800KbpsMethod KEYWORD1
|
||||
NeoNrf52xPwmN400KbpsMethod KEYWORD1
|
||||
NeoNrf52xPwmNApa106Method KEYWORD1
|
||||
NeoNrf52xPwm0Ws2812xMethod KEYWORD1
|
||||
NeoNrf52xPwm0Sk6812Method KEYWORD1
|
||||
NeoNrf52xPwm0Tm1814Method KEYWORD1
|
||||
@@ -344,6 +364,12 @@ NeoNrf52xPwm3Tm1814Method KEYWORD1
|
||||
NeoNrf52xPwm3800KbpsMethod KEYWORD1
|
||||
NeoNrf52xPwm3400KbpsMethod KEYWORD1
|
||||
NeoNrf52xPwm3Apa106Method KEYWORD1
|
||||
NeoNrf52xPwmNWs2812xInvertedMethod KEYWORD1
|
||||
NeoNrf52xPwmNSk6812InvertedMethod KEYWORD1
|
||||
NeoNrf52xPwmNTm1814InvertedMethod KEYWORD1
|
||||
NeoNrf52xPwmN800KbpsInvertedMethod KEYWORD1
|
||||
NeoNrf52xPwmN400KbpsInvertedMethod KEYWORD1
|
||||
NeoNrf52xPwmNApa106InvertedMethod KEYWORD1
|
||||
NeoNrf52xPwm0Ws2812xInvertedMethod KEYWORD1
|
||||
NeoNrf52xPwm0Sk6812InvertedMethod KEYWORD1
|
||||
NeoNrf52xPwm0Tm1814InvertedMethod KEYWORD1
|
||||
|
@@ -85,6 +85,8 @@ License along with NeoPixel. If not, see
|
||||
#include "internal/NeoEase.h"
|
||||
#include "internal/NeoGamma.h"
|
||||
|
||||
#include "internal/NeoBusChannel.h"
|
||||
|
||||
#include "internal/DotStarGenericMethod.h"
|
||||
#include "internal/Lpd8806GenericMethod.h"
|
||||
#include "internal/Lpd6803GenericMethod.h"
|
||||
@@ -120,8 +122,6 @@ License along with NeoPixel. If not, see
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename T_COLOR_FEATURE, typename T_METHOD> class NeoPixelBus
|
||||
{
|
||||
public:
|
||||
@@ -135,6 +135,13 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
NeoPixelBus(uint16_t countPixels, uint8_t pin, NeoBusChannel channel) :
|
||||
_countPixels(countPixels),
|
||||
_state(0),
|
||||
_method(pin, countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize, channel)
|
||||
{
|
||||
}
|
||||
|
||||
NeoPixelBus(uint16_t countPixels, uint8_t pinClock, uint8_t pinData) :
|
||||
_countPixels(countPixels),
|
||||
_state(0),
|
||||
|
29
src/internal/NeoBusChannel.h
Normal file
29
src/internal/NeoBusChannel.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
// For those platforms/methods that support dynamic channel setting
|
||||
enum NeoBusChannel
|
||||
{
|
||||
NeoBusChannel_0,
|
||||
NeoBusChannel_1,
|
||||
NeoBusChannel_2,
|
||||
|
||||
// NRF52x has only 3 or 4 channels of PWM
|
||||
#if defined(ARDUINO_ARCH_NRF52840)
|
||||
|
||||
#if defined(NRF_PWM3)
|
||||
NeoBusChannel_3
|
||||
#endif
|
||||
|
||||
// ESP32 has either 8 or 4 channels (S2 has only 4)
|
||||
#elif defined(ARDUINO_ARCH_ESP32)
|
||||
|
||||
NeoBusChannel_3,
|
||||
|
||||
#if !defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||
NeoBusChannel_4,
|
||||
NeoBusChannel_5,
|
||||
NeoBusChannel_6,
|
||||
NeoBusChannel_7,
|
||||
#endif // CONFIG_IDF_TARGET_ESP32S2
|
||||
#endif // ARDUINO_ARCH_ESP32
|
||||
};
|
@@ -27,6 +27,7 @@ License along with NeoPixel. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
#include "NeoBusChannel.h"
|
||||
#include "NeoEsp32RmtMethod.h"
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
|
@@ -322,24 +322,32 @@ public:
|
||||
class NeoEsp32RmtChannel0
|
||||
{
|
||||
public:
|
||||
NeoEsp32RmtChannel0() {};
|
||||
|
||||
const static rmt_channel_t RmtChannelNumber = RMT_CHANNEL_0;
|
||||
};
|
||||
|
||||
class NeoEsp32RmtChannel1
|
||||
{
|
||||
public:
|
||||
NeoEsp32RmtChannel1() {};
|
||||
|
||||
const static rmt_channel_t RmtChannelNumber = RMT_CHANNEL_1;
|
||||
};
|
||||
|
||||
class NeoEsp32RmtChannel2
|
||||
{
|
||||
public:
|
||||
NeoEsp32RmtChannel2() {};
|
||||
|
||||
const static rmt_channel_t RmtChannelNumber = RMT_CHANNEL_2;
|
||||
};
|
||||
|
||||
class NeoEsp32RmtChannel3
|
||||
{
|
||||
public:
|
||||
NeoEsp32RmtChannel3() {};
|
||||
|
||||
const static rmt_channel_t RmtChannelNumber = RMT_CHANNEL_3;
|
||||
};
|
||||
|
||||
@@ -348,29 +356,50 @@ public:
|
||||
class NeoEsp32RmtChannel4
|
||||
{
|
||||
public:
|
||||
NeoEsp32RmtChannel4() {};
|
||||
|
||||
const static rmt_channel_t RmtChannelNumber = RMT_CHANNEL_4;
|
||||
};
|
||||
|
||||
class NeoEsp32RmtChannel5
|
||||
{
|
||||
public:
|
||||
NeoEsp32RmtChannel5() {};
|
||||
|
||||
const static rmt_channel_t RmtChannelNumber = RMT_CHANNEL_5;
|
||||
};
|
||||
|
||||
class NeoEsp32RmtChannel6
|
||||
{
|
||||
public:
|
||||
NeoEsp32RmtChannel6() {};
|
||||
|
||||
const static rmt_channel_t RmtChannelNumber = RMT_CHANNEL_6;
|
||||
};
|
||||
|
||||
class NeoEsp32RmtChannel7
|
||||
{
|
||||
public:
|
||||
NeoEsp32RmtChannel7() {};
|
||||
|
||||
const static rmt_channel_t RmtChannelNumber = RMT_CHANNEL_7;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// dynamic channel support
|
||||
class NeoEsp32RmtChannelN
|
||||
{
|
||||
public:
|
||||
NeoEsp32RmtChannelN(NeoBusChannel channel) :
|
||||
RmtChannelNumber(static_cast<rmt_channel_t>(channel))
|
||||
{
|
||||
}
|
||||
NeoEsp32RmtChannelN() = delete; // no default constructor
|
||||
|
||||
const rmt_channel_t RmtChannelNumber;
|
||||
};
|
||||
|
||||
template<typename T_SPEED, typename T_CHANNEL> class NeoEsp32RmtMethodBase
|
||||
{
|
||||
public:
|
||||
@@ -378,20 +407,24 @@ public:
|
||||
_sizeData(pixelCount * elementSize + settingsSize),
|
||||
_pin(pin)
|
||||
{
|
||||
_dataEditing = static_cast<uint8_t*>(malloc(_sizeData));
|
||||
memset(_dataEditing, 0x00, _sizeData);
|
||||
construct();
|
||||
}
|
||||
|
||||
_dataSending = static_cast<uint8_t*>(malloc(_sizeData));
|
||||
// no need to initialize it, it gets overwritten on every send
|
||||
NeoEsp32RmtMethodBase(uint8_t pin, uint16_t pixelCount, size_t elementSize, size_t settingsSize, NeoBusChannel channel) :
|
||||
_sizeData(pixelCount* elementSize + settingsSize),
|
||||
_pin(pin),
|
||||
_channel(channel)
|
||||
{
|
||||
construct();
|
||||
}
|
||||
|
||||
~NeoEsp32RmtMethodBase()
|
||||
{
|
||||
// wait until the last send finishes before destructing everything
|
||||
// arbitrary time out of 10 seconds
|
||||
ESP_ERROR_CHECK_WITHOUT_ABORT(rmt_wait_tx_done(T_CHANNEL::RmtChannelNumber, 10000 / portTICK_PERIOD_MS));
|
||||
ESP_ERROR_CHECK_WITHOUT_ABORT(rmt_wait_tx_done(_channel.RmtChannelNumber, 10000 / portTICK_PERIOD_MS));
|
||||
|
||||
ESP_ERROR_CHECK(rmt_driver_uninstall(T_CHANNEL::RmtChannelNumber));
|
||||
ESP_ERROR_CHECK(rmt_driver_uninstall(_channel.RmtChannelNumber));
|
||||
|
||||
free(_dataEditing);
|
||||
free(_dataSending);
|
||||
@@ -400,7 +433,7 @@ public:
|
||||
|
||||
bool IsReadyToUpdate() const
|
||||
{
|
||||
return (ESP_OK == rmt_wait_tx_done(T_CHANNEL::RmtChannelNumber, 0));
|
||||
return (ESP_OK == rmt_wait_tx_done(_channel.RmtChannelNumber, 0));
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
@@ -408,7 +441,7 @@ public:
|
||||
rmt_config_t config;
|
||||
|
||||
config.rmt_mode = RMT_MODE_TX;
|
||||
config.channel = T_CHANNEL::RmtChannelNumber;
|
||||
config.channel = _channel.RmtChannelNumber;
|
||||
config.gpio_num = static_cast<gpio_num_t>(_pin);
|
||||
config.mem_block_num = 1;
|
||||
config.tx_config.loop_en = false;
|
||||
@@ -422,8 +455,8 @@ public:
|
||||
config.clk_div = T_SPEED::RmtClockDivider;
|
||||
|
||||
ESP_ERROR_CHECK(rmt_config(&config));
|
||||
ESP_ERROR_CHECK(rmt_driver_install(T_CHANNEL::RmtChannelNumber, 0, ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_LEVEL1));
|
||||
ESP_ERROR_CHECK(rmt_translator_init(T_CHANNEL::RmtChannelNumber, T_SPEED::Translate));
|
||||
ESP_ERROR_CHECK(rmt_driver_install(_channel.RmtChannelNumber, 0, ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_LEVEL1));
|
||||
ESP_ERROR_CHECK(rmt_translator_init(_channel.RmtChannelNumber, T_SPEED::Translate));
|
||||
}
|
||||
|
||||
void Update(bool maintainBufferConsistency)
|
||||
@@ -431,10 +464,10 @@ public:
|
||||
// wait for not actively sending data
|
||||
// this will time out at 10 seconds, an arbitrarily long period of time
|
||||
// and do nothing if this happens
|
||||
if (ESP_OK == ESP_ERROR_CHECK_WITHOUT_ABORT(rmt_wait_tx_done(T_CHANNEL::RmtChannelNumber, 10000 / portTICK_PERIOD_MS)))
|
||||
if (ESP_OK == ESP_ERROR_CHECK_WITHOUT_ABORT(rmt_wait_tx_done(_channel.RmtChannelNumber, 10000 / portTICK_PERIOD_MS)))
|
||||
{
|
||||
// now start the RMT transmit with the editing buffer before we swap
|
||||
ESP_ERROR_CHECK_WITHOUT_ABORT(rmt_write_sample(T_CHANNEL::RmtChannelNumber, _dataEditing, _sizeData, false));
|
||||
ESP_ERROR_CHECK_WITHOUT_ABORT(rmt_write_sample(_channel.RmtChannelNumber, _dataEditing, _sizeData, false));
|
||||
|
||||
if (maintainBufferConsistency)
|
||||
{
|
||||
@@ -462,13 +495,32 @@ public:
|
||||
private:
|
||||
const size_t _sizeData; // Size of '_data*' buffers
|
||||
const uint8_t _pin; // output pin number
|
||||
const T_CHANNEL _channel; // holds instance for multi channel support
|
||||
|
||||
// Holds data stream which include LED color values and other settings as needed
|
||||
uint8_t* _dataEditing; // exposed for get and set
|
||||
uint8_t* _dataSending; // used for async send using RMT
|
||||
|
||||
|
||||
void construct()
|
||||
{
|
||||
_dataEditing = static_cast<uint8_t*>(malloc(_sizeData));
|
||||
memset(_dataEditing, 0x00, _sizeData);
|
||||
|
||||
_dataSending = static_cast<uint8_t*>(malloc(_sizeData));
|
||||
// no need to initialize it, it gets overwritten on every send
|
||||
}
|
||||
};
|
||||
|
||||
// normal
|
||||
typedef NeoEsp32RmtMethodBase<NeoEsp32RmtSpeedWs2811, NeoEsp32RmtChannelN> NeoEsp32RmtNWs2811Method;
|
||||
typedef NeoEsp32RmtMethodBase<NeoEsp32RmtSpeedWs2812x, NeoEsp32RmtChannelN> NeoEsp32RmtNWs2812xMethod;
|
||||
typedef NeoEsp32RmtMethodBase<NeoEsp32RmtSpeedSk6812, NeoEsp32RmtChannelN> NeoEsp32RmtNSk6812Method;
|
||||
typedef NeoEsp32RmtMethodBase<NeoEsp32RmtSpeedTm1814, NeoEsp32RmtChannelN> NeoEsp32RmtNTm1814Method;
|
||||
typedef NeoEsp32RmtMethodBase<NeoEsp32RmtSpeedApa106, NeoEsp32RmtChannelN> NeoEsp32RmtNApa106Method;
|
||||
typedef NeoEsp32RmtMethodBase<NeoEsp32RmtSpeed800Kbps, NeoEsp32RmtChannelN> NeoEsp32RmtN800KbpsMethod;
|
||||
typedef NeoEsp32RmtMethodBase<NeoEsp32RmtSpeed400Kbps, NeoEsp32RmtChannelN> NeoEsp32RmtN400KbpsMethod;
|
||||
|
||||
typedef NeoEsp32RmtMethodBase<NeoEsp32RmtSpeedWs2811, NeoEsp32RmtChannel0> NeoEsp32Rmt0Ws2811Method;
|
||||
typedef NeoEsp32RmtMethodBase<NeoEsp32RmtSpeedWs2812x, NeoEsp32RmtChannel0> NeoEsp32Rmt0Ws2812xMethod;
|
||||
typedef NeoEsp32RmtMethodBase<NeoEsp32RmtSpeedSk6812, NeoEsp32RmtChannel0> NeoEsp32Rmt0Sk6812Method;
|
||||
@@ -539,6 +591,14 @@ typedef NeoEsp32RmtMethodBase<NeoEsp32RmtSpeed400Kbps, NeoEsp32RmtChannel7> NeoE
|
||||
#endif
|
||||
|
||||
// inverted
|
||||
typedef NeoEsp32RmtMethodBase<NeoEsp32RmtInvertedSpeedWs2811, NeoEsp32RmtChannelN> NeoEsp32RmtNWs2811InvertedMethod;
|
||||
typedef NeoEsp32RmtMethodBase<NeoEsp32RmtInvertedSpeedWs2812x, NeoEsp32RmtChannelN> NeoEsp32RmtNWs2812xInvertedMethod;
|
||||
typedef NeoEsp32RmtMethodBase<NeoEsp32RmtInvertedSpeedSk6812, NeoEsp32RmtChannelN> NeoEsp32RmtNSk6812InvertedMethod;
|
||||
typedef NeoEsp32RmtMethodBase<NeoEsp32RmtInvertedSpeedTm1814, NeoEsp32RmtChannelN> NeoEsp32RmtNTm1814InvertedMethod;
|
||||
typedef NeoEsp32RmtMethodBase<NeoEsp32RmtInvertedSpeedApa106, NeoEsp32RmtChannelN> NeoEsp32RmtNApa106InvertedMethod;
|
||||
typedef NeoEsp32RmtMethodBase<NeoEsp32RmtInvertedSpeed800Kbps, NeoEsp32RmtChannelN> NeoEsp32RmtN800KbpsInvertedMethod;
|
||||
typedef NeoEsp32RmtMethodBase<NeoEsp32RmtInvertedSpeed400Kbps, NeoEsp32RmtChannelN> NeoEsp32RmtN400KbpsInvertedMethod;
|
||||
|
||||
typedef NeoEsp32RmtMethodBase<NeoEsp32RmtInvertedSpeedWs2811, NeoEsp32RmtChannel0> NeoEsp32Rmt0Ws2811InvertedMethod;
|
||||
typedef NeoEsp32RmtMethodBase<NeoEsp32RmtInvertedSpeedWs2812x, NeoEsp32RmtChannel0> NeoEsp32Rmt0Ws2812xInvertedMethod;
|
||||
typedef NeoEsp32RmtMethodBase<NeoEsp32RmtInvertedSpeedSk6812, NeoEsp32RmtChannel0> NeoEsp32Rmt0Sk6812InvertedMethod;
|
||||
|
@@ -229,6 +229,34 @@ public:
|
||||
};
|
||||
#endif
|
||||
|
||||
// dynamic channel support
|
||||
class NeoNrf52xPwmN
|
||||
{
|
||||
public:
|
||||
NeoNrf52xPwmN(NeoBusChannel channel)
|
||||
{
|
||||
NRF_PWM_Type* PWM[] = {
|
||||
NRF_PWM0,
|
||||
NRF_PWM1,
|
||||
NRF_PWM2
|
||||
#ifdef NRF_PWM3
|
||||
,NRF_PWM3
|
||||
#endif
|
||||
};
|
||||
_pwm = PWM[channel];
|
||||
}
|
||||
|
||||
inline NRF_PWM_Type* Pwm() const
|
||||
{
|
||||
return _pwm;
|
||||
}
|
||||
|
||||
protected:
|
||||
NRF_PWM_Type* _pwm;
|
||||
|
||||
NeoNrf52xPwmN() {};
|
||||
};
|
||||
|
||||
template<typename T_SPEED, typename T_BUS> class NeoNrf52xMethodBase
|
||||
{
|
||||
public:
|
||||
@@ -236,13 +264,15 @@ public:
|
||||
_sizeData(pixelCount * elementSize + settingsSize),
|
||||
_pin(pin)
|
||||
{
|
||||
pinMode(pin, OUTPUT);
|
||||
construct();
|
||||
}
|
||||
|
||||
_data = static_cast<uint8_t*>(malloc(_sizeData));
|
||||
memset(_data, 0, _sizeData);
|
||||
|
||||
_dmaBufferSize = c_dmaBytesPerDataByte * _sizeData + sizeof(nrf_pwm_values_common_t);
|
||||
_dmaBuffer = static_cast<nrf_pwm_values_common_t*>(malloc(_dmaBufferSize));
|
||||
NeoNrf52xMethodBase(uint8_t pin, uint16_t pixelCount, size_t elementSize, size_t settingsSize, NeoBusChannel channel) :
|
||||
_sizeData(pixelCount* elementSize + settingsSize),
|
||||
_pin(pin),
|
||||
_bus(channel)
|
||||
{
|
||||
construct();
|
||||
}
|
||||
|
||||
~NeoNrf52xMethodBase()
|
||||
@@ -262,7 +292,7 @@ public:
|
||||
|
||||
bool IsReadyToUpdate() const
|
||||
{
|
||||
return (T_BUS::Pwm()->EVENTS_STOPPED);
|
||||
return (_bus.Pwm()->EVENTS_STOPPED);
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
@@ -307,50 +337,62 @@ public:
|
||||
private:
|
||||
const size_t _sizeData; // Size of '_data' buffer below
|
||||
const uint8_t _pin; // output pin number
|
||||
const T_BUS _bus; // holds instance for multi channel support
|
||||
|
||||
uint8_t* _data; // Holds LED color values
|
||||
size_t _dmaBufferSize; // total size of _dmaBuffer
|
||||
nrf_pwm_values_common_t* _dmaBuffer; // Holds pixel data in native format for PWM hardware
|
||||
|
||||
void construct()
|
||||
{
|
||||
pinMode(_pin, OUTPUT);
|
||||
|
||||
_data = static_cast<uint8_t*>(malloc(_sizeData));
|
||||
memset(_data, 0, _sizeData);
|
||||
|
||||
_dmaBufferSize = c_dmaBytesPerDataByte * _sizeData + sizeof(nrf_pwm_values_common_t);
|
||||
_dmaBuffer = static_cast<nrf_pwm_values_common_t*>(malloc(_dmaBufferSize));
|
||||
}
|
||||
|
||||
void dmaInit()
|
||||
{
|
||||
// only use channel zero
|
||||
T_BUS::Pwm()->PSEL.OUT[0] = digitalPinToPinName(_pin);
|
||||
T_BUS::Pwm()->PSEL.OUT[1] = NC;
|
||||
T_BUS::Pwm()->PSEL.OUT[2] = NC;
|
||||
T_BUS::Pwm()->PSEL.OUT[3] = NC;
|
||||
_bus.Pwm()->PSEL.OUT[0] = digitalPinToPinName(_pin);
|
||||
_bus.Pwm()->PSEL.OUT[1] = NC;
|
||||
_bus.Pwm()->PSEL.OUT[2] = NC;
|
||||
_bus.Pwm()->PSEL.OUT[3] = NC;
|
||||
|
||||
T_BUS::Pwm()->ENABLE = 1;
|
||||
T_BUS::Pwm()->MODE = NRF_PWM_MODE_UP;
|
||||
T_BUS::Pwm()->PRESCALER = NRF_PWM_CLK_16MHz;
|
||||
T_BUS::Pwm()->COUNTERTOP = T_SPEED::CountTop;
|
||||
T_BUS::Pwm()->LOOP = 1; // single fire so events get set
|
||||
T_BUS::Pwm()->DECODER = NRF_PWM_LOAD_COMMON;
|
||||
_bus.Pwm()->ENABLE = 1;
|
||||
_bus.Pwm()->MODE = NRF_PWM_MODE_UP;
|
||||
_bus.Pwm()->PRESCALER = NRF_PWM_CLK_16MHz;
|
||||
_bus.Pwm()->COUNTERTOP = T_SPEED::CountTop;
|
||||
_bus.Pwm()->LOOP = 1; // single fire so events get set
|
||||
_bus.Pwm()->DECODER = NRF_PWM_LOAD_COMMON;
|
||||
|
||||
// sequence zero is the primary data with a BitReset entry on the end for
|
||||
// the delay repeating
|
||||
T_BUS::Pwm()->SEQ[0].PTR = reinterpret_cast<uint32_t>(_dmaBuffer);
|
||||
T_BUS::Pwm()->SEQ[0].CNT = _dmaBufferSize / sizeof(nrf_pwm_values_common_t);
|
||||
T_BUS::Pwm()->SEQ[0].REFRESH = 0; // ignored
|
||||
T_BUS::Pwm()->SEQ[0].ENDDELAY = T_SPEED::CountReset; // ignored still?
|
||||
_bus.Pwm()->SEQ[0].PTR = reinterpret_cast<uint32_t>(_dmaBuffer);
|
||||
_bus.Pwm()->SEQ[0].CNT = _dmaBufferSize / sizeof(nrf_pwm_values_common_t);
|
||||
_bus.Pwm()->SEQ[0].REFRESH = 0; // ignored
|
||||
_bus.Pwm()->SEQ[0].ENDDELAY = T_SPEED::CountReset; // ignored still?
|
||||
|
||||
// sequence one is pointing to the BitReset entry at the end of the primary data
|
||||
T_BUS::Pwm()->SEQ[1].PTR = reinterpret_cast<uint32_t>(_dmaBuffer + (T_BUS::Pwm()->SEQ[0].CNT - 1));
|
||||
T_BUS::Pwm()->SEQ[1].CNT = 1;
|
||||
T_BUS::Pwm()->SEQ[1].REFRESH = 0; // ignored
|
||||
T_BUS::Pwm()->SEQ[1].ENDDELAY = 0; // ignored
|
||||
_bus.Pwm()->SEQ[1].PTR = reinterpret_cast<uint32_t>(_dmaBuffer + (_bus.Pwm()->SEQ[0].CNT - 1));
|
||||
_bus.Pwm()->SEQ[1].CNT = 1;
|
||||
_bus.Pwm()->SEQ[1].REFRESH = 0; // ignored
|
||||
_bus.Pwm()->SEQ[1].ENDDELAY = 0; // ignored
|
||||
|
||||
// stop when the loop finishes
|
||||
T_BUS::Pwm()->SHORTS = PWM_SHORTS_LOOPSDONE_STOP_Msk;
|
||||
T_BUS::Pwm()->INTEN = 0;
|
||||
_bus.Pwm()->SHORTS = PWM_SHORTS_LOOPSDONE_STOP_Msk;
|
||||
_bus.Pwm()->INTEN = 0;
|
||||
|
||||
dmaResetEvents();
|
||||
}
|
||||
|
||||
void dmaDeinit()
|
||||
{
|
||||
T_BUS::Pwm()->ENABLE = 0;
|
||||
T_BUS::Pwm()->PSEL.OUT[0] = NC;
|
||||
_bus.Pwm()->ENABLE = 0;
|
||||
_bus.Pwm()->PSEL.OUT[0] = NC;
|
||||
}
|
||||
|
||||
void FillBuffer()
|
||||
@@ -380,20 +422,28 @@ private:
|
||||
|
||||
void dmaResetEvents()
|
||||
{
|
||||
T_BUS::Pwm()->EVENTS_LOOPSDONE = 0;
|
||||
T_BUS::Pwm()->EVENTS_SEQEND[0] = 0;
|
||||
T_BUS::Pwm()->EVENTS_SEQEND[1] = 0;
|
||||
T_BUS::Pwm()->EVENTS_STOPPED = 0;
|
||||
_bus.Pwm()->EVENTS_LOOPSDONE = 0;
|
||||
_bus.Pwm()->EVENTS_SEQEND[0] = 0;
|
||||
_bus.Pwm()->EVENTS_SEQEND[1] = 0;
|
||||
_bus.Pwm()->EVENTS_STOPPED = 0;
|
||||
}
|
||||
|
||||
void dmaStart()
|
||||
{
|
||||
dmaResetEvents();
|
||||
T_BUS::Pwm()->TASKS_SEQSTART[0] = 1;
|
||||
_bus.Pwm()->TASKS_SEQSTART[0] = 1;
|
||||
}
|
||||
};
|
||||
|
||||
// normal
|
||||
typedef NeoNrf52xMethodBase<NeoNrf52xPwmSpeedWs2811, NeoNrf52xPwmN> NeoNrf52xPwmNWs2811Method;
|
||||
typedef NeoNrf52xMethodBase<NeoNrf52xPwmSpeedWs2812x, NeoNrf52xPwmN> NeoNrf52xPwmNWs2812xMethod;
|
||||
typedef NeoNrf52xMethodBase<NeoNrf52xPwmSpeedSk6812, NeoNrf52xPwmN> NeoNrf52xPwmNSk6812Method;
|
||||
typedef NeoNrf52xMethodBase<NeoNrf52xPwmSpeedTm1814, NeoNrf52xPwmN> NeoNrf52xPwmNTm1814Method;
|
||||
typedef NeoNrf52xMethodBase<NeoNrf52xPwmSpeedApa106, NeoNrf52xPwmN> NeoNrf52xPwmNApa106Method;
|
||||
typedef NeoNrf52xMethodBase<NeoNrf52xPwmSpeed800Kbps, NeoNrf52xPwmN> NeoNrf52xPwmN800KbpsMethod;
|
||||
typedef NeoNrf52xMethodBase<NeoNrf52xPwmSpeed400Kbps, NeoNrf52xPwmN> NeoNrf52xPwmN400KbpsMethod;
|
||||
|
||||
typedef NeoNrf52xMethodBase<NeoNrf52xPwmSpeedWs2811, NeoNrf52xPwm0> NeoNrf52xPwm0Ws2811Method;
|
||||
typedef NeoNrf52xMethodBase<NeoNrf52xPwmSpeedWs2812x, NeoNrf52xPwm0> NeoNrf52xPwm0Ws2812xMethod;
|
||||
typedef NeoNrf52xMethodBase<NeoNrf52xPwmSpeedSk6812, NeoNrf52xPwm0> NeoNrf52xPwm0Sk6812Method;
|
||||
@@ -429,6 +479,14 @@ typedef NeoNrf52xMethodBase<NeoNrf52xPwmSpeed400Kbps, NeoNrf52xPwm3> NeoNrf52xPw
|
||||
#endif
|
||||
|
||||
// inverted
|
||||
typedef NeoNrf52xMethodBase<NeoNrf52xPwmInvertedSpeedWs2811, NeoNrf52xPwmN> NeoNrf52xPwmNWs2811InvertedMethod;
|
||||
typedef NeoNrf52xMethodBase<NeoNrf52xPwmInvertedSpeedWs2812x, NeoNrf52xPwmN> NeoNrf52xPwmNWs2812xInvertedMethod;
|
||||
typedef NeoNrf52xMethodBase<NeoNrf52xPwmInvertedSpeedSk6812, NeoNrf52xPwmN> NeoNrf52xPwmNSk6812InvertedMethod;
|
||||
typedef NeoNrf52xMethodBase<NeoNrf52xPwmInvertedSpeedTm1814, NeoNrf52xPwmN> NeoNrf52xPwmNTm1814InvertedMethod;
|
||||
typedef NeoNrf52xMethodBase<NeoNrf52xPwmInvertedSpeedApa106, NeoNrf52xPwmN> NeoNrf52xPwmNApa106InvertedMethod;
|
||||
typedef NeoNrf52xMethodBase<NeoNrf52xPwmInvertedSpeed800Kbps, NeoNrf52xPwmN> NeoNrf52xPwmN800KbpsInvertedMethod;
|
||||
typedef NeoNrf52xMethodBase<NeoNrf52xPwmInvertedSpeed400Kbps, NeoNrf52xPwmN> NeoNrf52xPwmN400KbpsInvertedMethod;
|
||||
|
||||
typedef NeoNrf52xMethodBase<NeoNrf52xPwmInvertedSpeedWs2811, NeoNrf52xPwm0> NeoNrf52xPwm0Ws2811InvertedMethod;
|
||||
typedef NeoNrf52xMethodBase<NeoNrf52xPwmInvertedSpeedWs2812x, NeoNrf52xPwm0> NeoNrf52xPwm0Ws2812xInvertedMethod;
|
||||
typedef NeoNrf52xMethodBase<NeoNrf52xPwmInvertedSpeedSk6812, NeoNrf52xPwm0> NeoNrf52xPwm0Sk6812InvertedMethod;
|
||||
|
Reference in New Issue
Block a user