First commit.
This commit is contained in:
115
.pio/libdeps/local/FastLED/platforms/arm/nrf52/arbiter_nrf52.h
Normal file
115
.pio/libdeps/local/FastLED/platforms/arm/nrf52/arbiter_nrf52.h
Normal file
@ -0,0 +1,115 @@
|
||||
#ifndef __INC_ARBITER_NRF52
|
||||
#define __INC_ARBITER_NRF52
|
||||
|
||||
#if defined(NRF52_SERIES)
|
||||
|
||||
#include "led_sysdefs_arm_nrf52.h"
|
||||
|
||||
//FASTLED_NAMESPACE_BEGIN
|
||||
|
||||
typedef void (*FASTLED_NRF52_PWM_INTERRUPT_HANDLER)();
|
||||
|
||||
// a trick learned from other embedded projects ..
|
||||
// use the enum as an index to a statically-allocated array
|
||||
// to store unique information for that instance.
|
||||
// also provides a count of how many instances were enabled.
|
||||
//
|
||||
// See led_sysdefs_arm_nrf52.h for selection....
|
||||
//
|
||||
typedef enum _FASTLED_NRF52_ENABLED_PWM_INSTANCE {
|
||||
#if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE0)
|
||||
FASTLED_NRF52_PWM0_INSTANCE_IDX,
|
||||
#endif
|
||||
#if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE1)
|
||||
FASTLED_NRF52_PWM1_INSTANCE_IDX,
|
||||
#endif
|
||||
#if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE2)
|
||||
FASTLED_NRF52_PWM2_INSTANCE_IDX,
|
||||
#endif
|
||||
#if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE3)
|
||||
FASTLED_NRF52_PWM3_INSTANCE_IDX,
|
||||
#endif
|
||||
FASTLED_NRF52_PWM_INSTANCE_COUNT
|
||||
} FASTLED_NRF52_ENABLED_PWM_INSTANCES;
|
||||
|
||||
static_assert(FASTLED_NRF52_PWM_INSTANCE_COUNT > 0, "Instance count must be greater than zero -- define FASTLED_NRF52_ENABLE_PWM_INSTNACE[n] (replace `[n]` with digit)");
|
||||
|
||||
template <uint32_t _PWM_ID>
|
||||
class PWM_Arbiter {
|
||||
|
||||
private:
|
||||
static_assert(_PWM_ID < 32, "PWM_ID over 31 breaks current arbitration bitmask");
|
||||
//const uint32_t _ACQUIRE_MASK = (1u << _PWM_ID) ;
|
||||
//const uint32_t _CLEAR_MASK = ~((uint32_t)(1u << _PWM_ID));
|
||||
static uint32_t s_PwmInUse;
|
||||
static NRF_PWM_Type * const s_PWM;
|
||||
static IRQn_Type const s_PWM_IRQ;
|
||||
static FASTLED_NRF52_PWM_INTERRUPT_HANDLER volatile s_Isr;
|
||||
|
||||
public:
|
||||
static void isr_handler() {
|
||||
return s_Isr();
|
||||
}
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static bool isAcquired() {
|
||||
return (0u != (s_PwmInUse & 1u)); // _ACQUIRE_MASK
|
||||
}
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static void acquire(FASTLED_NRF52_PWM_INTERRUPT_HANDLER isr) {
|
||||
while (!tryAcquire(isr));
|
||||
}
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static bool tryAcquire(FASTLED_NRF52_PWM_INTERRUPT_HANDLER isr) {
|
||||
uint32_t oldValue = __sync_fetch_and_or(&s_PwmInUse, 1u); // _ACQUIRE_MASK
|
||||
if (0u == (oldValue & 1u)) { // _ACQUIRE_MASK
|
||||
s_Isr = isr;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static void releaseFromIsr() {
|
||||
uint32_t oldValue = __sync_fetch_and_and(&s_PwmInUse, ~1u); // _CLEAR_MASK
|
||||
if (0u == (oldValue & 1u)) { // _ACQUIRE_MASK
|
||||
// TODO: This should never be true... indicates was not held.
|
||||
// Assert here?
|
||||
(void)oldValue;
|
||||
}
|
||||
return;
|
||||
}
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static NRF_PWM_Type * getPWM() {
|
||||
return s_PWM;
|
||||
}
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static IRQn_Type getIRQn() { return s_PWM_IRQ; }
|
||||
};
|
||||
template <uint32_t _PWM_ID> NRF_PWM_Type * const PWM_Arbiter<_PWM_ID>::s_PWM =
|
||||
#if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE0)
|
||||
(_PWM_ID == 0 ? NRF_PWM0 :
|
||||
#endif
|
||||
#if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE1)
|
||||
(_PWM_ID == 1 ? NRF_PWM1 :
|
||||
#endif
|
||||
#if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE2)
|
||||
(_PWM_ID == 2 ? NRF_PWM2 :
|
||||
#endif
|
||||
#if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE3)
|
||||
(_PWM_ID == 3 ? NRF_PWM3 :
|
||||
#endif
|
||||
(NRF_PWM_Type*)-1
|
||||
#if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE0)
|
||||
)
|
||||
#endif
|
||||
#if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE1)
|
||||
)
|
||||
#endif
|
||||
#if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE2)
|
||||
)
|
||||
#endif
|
||||
#if defined(FASTLED_NRF52_ENABLE_PWM_INSTANCE3)
|
||||
)
|
||||
#endif
|
||||
;
|
||||
template <uint32_t _PWM_ID> IRQn_Type const PWM_Arbiter<_PWM_ID>::s_PWM_IRQ = ((IRQn_Type)((uint8_t)((uint32_t)(s_PWM) >> 12)));
|
||||
template <uint32_t _PWM_ID> uint32_t PWM_Arbiter<_PWM_ID>::s_PwmInUse = 0;
|
||||
template <uint32_t _PWM_ID> FASTLED_NRF52_PWM_INTERRUPT_HANDLER volatile PWM_Arbiter<_PWM_ID>::s_Isr = NULL;
|
||||
|
||||
//FASTLED_NAMESPACE_END
|
||||
|
||||
#endif // NRF52_SERIES
|
||||
#endif // __INC_ARBITER_NRF52
|
@ -0,0 +1,391 @@
|
||||
#ifndef __INC_CLOCKLESS_ARM_NRF52
|
||||
#define __INC_CLOCKLESS_ARM_NRF52
|
||||
|
||||
#if defined(NRF52_SERIES)
|
||||
|
||||
|
||||
//FASTLED_NAMESPACE_BEGIN
|
||||
|
||||
#define FASTLED_HAS_CLOCKLESS 1
|
||||
#define FASTLED_NRF52_MAXIMUM_PIXELS_PER_STRING 144 // TODO: Figure out how to safely let this be calller-defined....
|
||||
|
||||
// nRF52810 has a single PWM peripheral (PWM0)
|
||||
// nRF52832 has three PWM peripherals (PWM0, PWM1, PWM2)
|
||||
// nRF52840 has four PWM peripherals (PWM0, PWM1, PWM2, PWM3)
|
||||
// NOTE: Update platforms.cpp in root of FastLED library if this changes
|
||||
#define FASTLED_NRF52_PWM_ID 0
|
||||
|
||||
|
||||
extern uint32_t isrCount;
|
||||
|
||||
|
||||
template <uint8_t _DATA_PIN, int _T1, int _T2, int _T3, EOrder _RGB_ORDER = RGB, int _XTRA0 = 0, bool _FLIP = false, int _WAIT_TIME_MICROSECONDS = 10>
|
||||
class ClocklessController : public CPixelLEDController<_RGB_ORDER> {
|
||||
static_assert(FASTLED_NRF52_MAXIMUM_PIXELS_PER_STRING > 0, "Maximum string length must be positive value (FASTLED_NRF52_MAXIMUM_PIXELS_PER_STRING)");
|
||||
static_assert(_T1 > 0 , "negative values are not allowed");
|
||||
static_assert(_T2 > 0 , "negative values are not allowed");
|
||||
static_assert(_T3 > 0 , "negative values are not allowed");
|
||||
static_assert(_T1 < (0x8000u-2u), "_T1 must fit in 15 bits");
|
||||
static_assert(_T2 < (0x8000u-2u), "_T2 must fit in 15 bits");
|
||||
static_assert(_T3 < (0x8000u-2u), "_T3 must fit in 15 bits");
|
||||
static_assert(_T1 < (0x8000u-2u), "_T0H must fit in 15 bits");
|
||||
static_assert(_T1+_T2 < (0x8000u-2u), "_T1H must fit in 15 bits");
|
||||
static_assert(_T1+_T2+_T3 < (0x8000u-2u), "_TOP must fit in 15 bits");
|
||||
static_assert(_T1+_T2+_T3 <= PWM_COUNTERTOP_COUNTERTOP_Msk, "_TOP too large for peripheral");
|
||||
|
||||
private:
|
||||
static const bool _INITIALIZE_PIN_HIGH = (_FLIP ? 1 : 0);
|
||||
static const uint16_t _POLARITY_BIT = (_FLIP ? 0 : 0x8000);
|
||||
|
||||
static const uint8_t _BITS_PER_PIXEL = (8 + _XTRA0) * 3; // NOTE: 3 means RGB only...
|
||||
static const uint16_t _PWM_BUFFER_COUNT = (_BITS_PER_PIXEL * FASTLED_NRF52_MAXIMUM_PIXELS_PER_STRING);
|
||||
static const uint8_t _T0H = ((uint16_t)(_T1 ));
|
||||
static const uint8_t _T1H = ((uint16_t)(_T1+_T2 ));
|
||||
static const uint8_t _TOP = ((uint16_t)(_T1+_T2+_T3));
|
||||
|
||||
// may as well be static, as can only attach one LED string per _DATA_PIN....
|
||||
static uint16_t s_SequenceBuffer[_PWM_BUFFER_COUNT];
|
||||
static uint16_t s_SequenceBufferValidElements;
|
||||
static volatile uint32_t s_SequenceBufferInUse;
|
||||
static CMinWait<_WAIT_TIME_MICROSECONDS> mWait; // ensure data has time to latch
|
||||
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static void startPwmPlayback_InitializePinState() {
|
||||
FastPin<_DATA_PIN>::setOutput();
|
||||
if (_INITIALIZE_PIN_HIGH) {
|
||||
FastPin<_DATA_PIN>::hi();
|
||||
} else {
|
||||
FastPin<_DATA_PIN>::lo();
|
||||
}
|
||||
}
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static void startPwmPlayback_InitializePwmInstance(NRF_PWM_Type * pwm) {
|
||||
|
||||
// Pins must be set before enabling the peripheral
|
||||
pwm->PSEL.OUT[0] = FastPin<_DATA_PIN>::nrf_pin();
|
||||
pwm->PSEL.OUT[1] = NRF_PWM_PIN_NOT_CONNECTED;
|
||||
pwm->PSEL.OUT[2] = NRF_PWM_PIN_NOT_CONNECTED;
|
||||
pwm->PSEL.OUT[3] = NRF_PWM_PIN_NOT_CONNECTED;
|
||||
nrf_pwm_enable(pwm);
|
||||
nrf_pwm_configure(pwm, NRF_PWM_CLK_16MHz, NRF_PWM_MODE_UP, _TOP);
|
||||
nrf_pwm_decoder_set(pwm, NRF_PWM_LOAD_COMMON, NRF_PWM_STEP_AUTO);
|
||||
|
||||
// clear any prior shorts / interrupt enable bits
|
||||
nrf_pwm_shorts_set(pwm, 0);
|
||||
nrf_pwm_int_set(pwm, 0);
|
||||
// clear all prior events
|
||||
nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_STOPPED);
|
||||
nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_SEQSTARTED0);
|
||||
nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_SEQSTARTED1);
|
||||
nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_SEQEND0);
|
||||
nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_SEQEND1);
|
||||
nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_PWMPERIODEND);
|
||||
nrf_pwm_event_clear(pwm, NRF_PWM_EVENT_LOOPSDONE);
|
||||
}
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static void startPwmPlayback_ConfigurePwmSequence(NRF_PWM_Type * pwm) {
|
||||
// config is easy, using SEQ0, no loops...
|
||||
nrf_pwm_sequence_t sequenceConfig;
|
||||
sequenceConfig.values.p_common = &(s_SequenceBuffer[0]);
|
||||
sequenceConfig.length = s_SequenceBufferValidElements;
|
||||
sequenceConfig.repeats = 0; // send the data once, and only once
|
||||
sequenceConfig.end_delay = 0; // no extra delay at the end of SEQ[0] / SEQ[1]
|
||||
nrf_pwm_sequence_set(pwm, 0, &sequenceConfig);
|
||||
nrf_pwm_sequence_set(pwm, 1, &sequenceConfig);
|
||||
nrf_pwm_loop_set(pwm, 0);
|
||||
|
||||
}
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static void startPwmPlayback_EnableInterruptsAndShortcuts(NRF_PWM_Type * pwm) {
|
||||
IRQn_Type irqn = PWM_Arbiter<FASTLED_NRF52_PWM_ID>::getIRQn();
|
||||
// TODO: check API results...
|
||||
uint32_t result;
|
||||
|
||||
result = sd_nvic_SetPriority(irqn, configMAX_SYSCALL_INTERRUPT_PRIORITY);
|
||||
(void)result;
|
||||
result = sd_nvic_EnableIRQ(irqn);
|
||||
(void)result;
|
||||
|
||||
// shortcuts prevent (up to) 4-cycle delay from interrupt handler to next action
|
||||
uint32_t shortsToEnable = 0;
|
||||
shortsToEnable |= NRF_PWM_SHORT_SEQEND0_STOP_MASK; ///< SEQEND[0] --> STOP task.
|
||||
shortsToEnable |= NRF_PWM_SHORT_SEQEND1_STOP_MASK; ///< SEQEND[1] --> STOP task.
|
||||
//shortsToEnable |= NRF_PWM_SHORT_LOOPSDONE_SEQSTART0_MASK; ///< LOOPSDONE --> SEQSTART[0] task.
|
||||
//shortsToEnable |= NRF_PWM_SHORT_LOOPSDONE_SEQSTART1_MASK; ///< LOOPSDONE --> SEQSTART[1] task.
|
||||
shortsToEnable |= NRF_PWM_SHORT_LOOPSDONE_STOP_MASK; ///< LOOPSDONE --> STOP task.
|
||||
nrf_pwm_shorts_set(pwm, shortsToEnable);
|
||||
|
||||
// mark which events should cause interrupts...
|
||||
uint32_t interruptsToEnable = 0;
|
||||
interruptsToEnable |= NRF_PWM_INT_SEQEND0_MASK;
|
||||
interruptsToEnable |= NRF_PWM_INT_SEQEND1_MASK;
|
||||
interruptsToEnable |= NRF_PWM_INT_LOOPSDONE_MASK;
|
||||
interruptsToEnable |= NRF_PWM_INT_STOPPED_MASK;
|
||||
nrf_pwm_int_set(pwm, interruptsToEnable);
|
||||
|
||||
}
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static void startPwmPlayback_StartTask(NRF_PWM_Type * pwm) {
|
||||
nrf_pwm_task_trigger(pwm, NRF_PWM_TASK_SEQSTART0);
|
||||
}
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static void spinAcquireSequenceBuffer() {
|
||||
while (!tryAcquireSequenceBuffer());
|
||||
}
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static bool tryAcquireSequenceBuffer() {
|
||||
return __sync_bool_compare_and_swap(&s_SequenceBufferInUse, 0, 1);
|
||||
}
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static void releaseSequenceBuffer() {
|
||||
uint32_t tmp = __sync_val_compare_and_swap(&s_SequenceBufferInUse, 1, 0);
|
||||
if (tmp != 1) {
|
||||
// TODO: Error / Assert / log ?
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
static void isr_handler() {
|
||||
NRF_PWM_Type * pwm = PWM_Arbiter<FASTLED_NRF52_PWM_ID>::getPWM();
|
||||
IRQn_Type irqn = PWM_Arbiter<FASTLED_NRF52_PWM_ID>::getIRQn();
|
||||
|
||||
// Currently, only use SEQUENCE 0, so only event
|
||||
// of consequence is LOOPSDONE ...
|
||||
if (nrf_pwm_event_check(pwm,NRF_PWM_EVENT_STOPPED)) {
|
||||
nrf_pwm_event_clear(pwm,NRF_PWM_EVENT_STOPPED);
|
||||
|
||||
// update the minimum time to next call
|
||||
mWait.mark();
|
||||
// mark the sequence as no longer in use -- pointer, comparator, exchange value
|
||||
releaseSequenceBuffer();
|
||||
// prevent further interrupts from PWM events
|
||||
nrf_pwm_int_set(pwm, 0);
|
||||
// disable PWM interrupts - None of the PWM IRQs are shared
|
||||
// with other peripherals, avoiding complexity of shared IRQs.
|
||||
sd_nvic_DisableIRQ(irqn);
|
||||
// disable the PWM instance
|
||||
nrf_pwm_disable(pwm);
|
||||
// may take up to 4 cycles for writes to propagate (APB bus @ 16MHz)
|
||||
asm __volatile__ ( "NOP; NOP; NOP; NOP;" );
|
||||
// release the PWM arbiter to be re-used by another LED string
|
||||
PWM_Arbiter<FASTLED_NRF52_PWM_ID>::releaseFromIsr();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual void init() {
|
||||
FASTLED_NRF52_DEBUGPRINT("Clockless Timings:\n");
|
||||
FASTLED_NRF52_DEBUGPRINT(" T0H == %d", _T0H);
|
||||
FASTLED_NRF52_DEBUGPRINT(" T1H == %d", _T1H);
|
||||
FASTLED_NRF52_DEBUGPRINT(" TOP == %d\n", _TOP);
|
||||
// to avoid pin initialization from causing first LED to have invalid color,
|
||||
// call mWait.mark() to ensure data latches before color data gets sent.
|
||||
startPwmPlayback_InitializePinState();
|
||||
mWait.mark();
|
||||
|
||||
}
|
||||
virtual uint16_t getMaxRefreshRate() const { return 800; }
|
||||
|
||||
virtual void showPixels(PixelController<_RGB_ORDER> & pixels) {
|
||||
// wait for the only sequence buffer to become available
|
||||
spinAcquireSequenceBuffer();
|
||||
prepareSequenceBuffers(pixels);
|
||||
// ensure any prior data had time to latch
|
||||
mWait.wait();
|
||||
startPwmPlayback(s_SequenceBufferValidElements);
|
||||
return;
|
||||
}
|
||||
|
||||
template<uint8_t _BIT>
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static void WriteBitToSequence(uint8_t byte, uint16_t * e) {
|
||||
*e = _POLARITY_BIT | (((byte & (1u << _BIT)) == 0) ? _T0H : _T1H);
|
||||
}
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static void prepareSequenceBuffers(PixelController<_RGB_ORDER> & pixels) {
|
||||
s_SequenceBufferValidElements = 0;
|
||||
int32_t remainingSequenceElements = _PWM_BUFFER_COUNT;
|
||||
uint16_t * e = s_SequenceBuffer;
|
||||
uint32_t size_needed = pixels.size(); // count of pixels
|
||||
size_needed *= (8 + _XTRA0); // bits per pixel
|
||||
size_needed *= 2; // each bit takes two bytes
|
||||
|
||||
if (size_needed > _PWM_BUFFER_COUNT) {
|
||||
// TODO: assert()?
|
||||
return;
|
||||
}
|
||||
|
||||
while (pixels.has(1) && (remainingSequenceElements >= _BITS_PER_PIXEL)) {
|
||||
uint8_t b0 = pixels.loadAndScale0();
|
||||
WriteBitToSequence<7>(b0, e); e++;
|
||||
WriteBitToSequence<6>(b0, e); e++;
|
||||
WriteBitToSequence<5>(b0, e); e++;
|
||||
WriteBitToSequence<4>(b0, e); e++;
|
||||
WriteBitToSequence<3>(b0, e); e++;
|
||||
WriteBitToSequence<2>(b0, e); e++;
|
||||
WriteBitToSequence<1>(b0, e); e++;
|
||||
WriteBitToSequence<0>(b0, e); e++;
|
||||
if (_XTRA0 > 0) {
|
||||
for (int i = 0; i < _XTRA0; i++) {
|
||||
WriteBitToSequence<0>(0,e); e++;
|
||||
}
|
||||
}
|
||||
uint8_t b1 = pixels.loadAndScale1();
|
||||
WriteBitToSequence<7>(b1, e); e++;
|
||||
WriteBitToSequence<6>(b1, e); e++;
|
||||
WriteBitToSequence<5>(b1, e); e++;
|
||||
WriteBitToSequence<4>(b1, e); e++;
|
||||
WriteBitToSequence<3>(b1, e); e++;
|
||||
WriteBitToSequence<2>(b1, e); e++;
|
||||
WriteBitToSequence<1>(b1, e); e++;
|
||||
WriteBitToSequence<0>(b1, e); e++;
|
||||
if (_XTRA0 > 0) {
|
||||
for (int i = 0; i < _XTRA0; i++) {
|
||||
WriteBitToSequence<0>(0,e); e++;
|
||||
}
|
||||
}
|
||||
uint8_t b2 = pixels.loadAndScale2();
|
||||
WriteBitToSequence<7>(b2, e); e++;
|
||||
WriteBitToSequence<6>(b2, e); e++;
|
||||
WriteBitToSequence<5>(b2, e); e++;
|
||||
WriteBitToSequence<4>(b2, e); e++;
|
||||
WriteBitToSequence<3>(b2, e); e++;
|
||||
WriteBitToSequence<2>(b2, e); e++;
|
||||
WriteBitToSequence<1>(b2, e); e++;
|
||||
WriteBitToSequence<0>(b2, e); e++;
|
||||
if (_XTRA0 > 0) {
|
||||
for (int i = 0; i < _XTRA0; i++) {
|
||||
WriteBitToSequence<0>(0,e); e++;
|
||||
}
|
||||
}
|
||||
|
||||
// advance pixel and sequence pointers
|
||||
s_SequenceBufferValidElements += _BITS_PER_PIXEL;
|
||||
remainingSequenceElements -= _BITS_PER_PIXEL;
|
||||
pixels.advanceData();
|
||||
pixels.stepDithering();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static void startPwmPlayback(uint16_t bytesToSend) {
|
||||
PWM_Arbiter<FASTLED_NRF52_PWM_ID>::acquire(isr_handler);
|
||||
NRF_PWM_Type * pwm = PWM_Arbiter<FASTLED_NRF52_PWM_ID>::getPWM();
|
||||
|
||||
// mark the sequence as being in-use
|
||||
__sync_fetch_and_or(&s_SequenceBufferInUse, 1);
|
||||
|
||||
startPwmPlayback_InitializePinState();
|
||||
startPwmPlayback_InitializePwmInstance(pwm);
|
||||
startPwmPlayback_ConfigurePwmSequence(pwm);
|
||||
startPwmPlayback_EnableInterruptsAndShortcuts(pwm);
|
||||
startPwmPlayback_StartTask(pwm);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static uint16_t* getRawSequenceBuffer() { return s_SequenceBuffer; }
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static uint16_t getRawSequenceBufferSize() { return _PWM_BUFFER_COUNT; }
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static uint16_t getSequenceBufferInUse() { return s_SequenceBufferInUse; }
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static void sendRawSequenceBuffer(uint16_t bytesToSend) {
|
||||
mWait.wait(); // ensure min time between updates
|
||||
startPwmPlayback(bytesToSend);
|
||||
}
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static void sendRawBytes(uint8_t * arrayOfBytes, uint16_t bytesToSend) {
|
||||
// wait for sequence buffer to be available
|
||||
while (s_SequenceBufferInUse != 0);
|
||||
|
||||
s_SequenceBufferValidElements = 0;
|
||||
int32_t remainingSequenceElements = _PWM_BUFFER_COUNT;
|
||||
uint16_t * e = s_SequenceBuffer;
|
||||
uint8_t * nextByte = arrayOfBytes;
|
||||
for (uint16_t bytesRemain = bytesToSend;
|
||||
(remainingSequenceElements >= 8) && (bytesRemain > 0);
|
||||
bytesRemain--,
|
||||
remainingSequenceElements -= 8,
|
||||
s_SequenceBufferValidElements += 8
|
||||
) {
|
||||
uint8_t b = *nextByte;
|
||||
WriteBitToSequence<7,false>(b, e); e++;
|
||||
WriteBitToSequence<6,false>(b, e); e++;
|
||||
WriteBitToSequence<5,false>(b, e); e++;
|
||||
WriteBitToSequence<4,false>(b, e); e++;
|
||||
WriteBitToSequence<3,false>(b, e); e++;
|
||||
WriteBitToSequence<2,false>(b, e); e++;
|
||||
WriteBitToSequence<1,false>(b, e); e++;
|
||||
WriteBitToSequence<0,false>(b, e); e++;
|
||||
if (_XTRA0 > 0) {
|
||||
for (int i = 0; i < _XTRA0; i++) {
|
||||
WriteBitToSequence<0,_FLIP>(0,e); e++;
|
||||
}
|
||||
}
|
||||
}
|
||||
mWait.wait(); // ensure min time between updates
|
||||
|
||||
startPwmPlayback(s_SequenceBufferValidElements);
|
||||
}
|
||||
#endif // 0
|
||||
|
||||
};
|
||||
|
||||
template <uint8_t _DATA_PIN, int _T1, int _T2, int _T3, EOrder _RGB_ORDER, int _XTRA0, bool _FLIP, int _WAIT_TIME_MICROSECONDS>
|
||||
uint16_t ClocklessController<_DATA_PIN, _T1, _T2, _T3, _RGB_ORDER, _XTRA0, _FLIP, _WAIT_TIME_MICROSECONDS>::s_SequenceBufferValidElements = 0;
|
||||
template <uint8_t _DATA_PIN, int _T1, int _T2, int _T3, EOrder _RGB_ORDER, int _XTRA0, bool _FLIP, int _WAIT_TIME_MICROSECONDS>
|
||||
uint32_t volatile ClocklessController<_DATA_PIN, _T1, _T2, _T3, _RGB_ORDER, _XTRA0, _FLIP, _WAIT_TIME_MICROSECONDS>::s_SequenceBufferInUse = 0;
|
||||
template <uint8_t _DATA_PIN, int _T1, int _T2, int _T3, EOrder _RGB_ORDER, int _XTRA0, bool _FLIP, int _WAIT_TIME_MICROSECONDS>
|
||||
uint16_t ClocklessController<_DATA_PIN, _T1, _T2, _T3, _RGB_ORDER, _XTRA0, _FLIP, _WAIT_TIME_MICROSECONDS>::s_SequenceBuffer[_PWM_BUFFER_COUNT];
|
||||
template <uint8_t _DATA_PIN, int _T1, int _T2, int _T3, EOrder _RGB_ORDER, int _XTRA0, bool _FLIP, int _WAIT_TIME_MICROSECONDS>
|
||||
CMinWait<_WAIT_TIME_MICROSECONDS> ClocklessController<_DATA_PIN, _T1, _T2, _T3, _RGB_ORDER, _XTRA0, _FLIP, _WAIT_TIME_MICROSECONDS>::mWait;
|
||||
|
||||
/* nrf_pwm solution
|
||||
//
|
||||
// When the nRF52 softdevice (e.g., BLE) is enabled, the CPU can be pre-empted
|
||||
// at any time for radio interrupts. These interrupts cannot be disabled.
|
||||
// The problem is, even simple BLE advertising interrupts may take **`348μs`**
|
||||
// (per softdevice 1.40, see http://infocenter.nordicsemi.com/pdf/S140_SDS_v1.3.pdf)
|
||||
//
|
||||
// The nRF52 chips have a decent Easy-DMA-enabled PWM peripheral.
|
||||
//
|
||||
// The major downside:
|
||||
// [] The PWM peripheral has a fixed input buffer size at 16 bits per clock cycle.
|
||||
// (each clockless protocol bit == 2 bytes)
|
||||
//
|
||||
// The major upsides include:
|
||||
// [] Fully asynchronous, freeing CPU for other tasks
|
||||
// [] Softdevice interrupts do not affect PWM clocked output (reliable clocking)
|
||||
//
|
||||
// The initial solution generally does the following for showPixels():
|
||||
// [] wait for a sequence buffer to become available
|
||||
// [] prepare the entire LED string's sequence (see `prepareSequenceBuffers()`)
|
||||
// [] ensures minimum wait time from prior sequence's end
|
||||
//
|
||||
// Options after initial solution working:
|
||||
// []
|
||||
|
||||
// TODO: Double-buffers, so one can be doing DMA while the second
|
||||
// buffer is being prepared.
|
||||
// TODO: Pool of buffers, so can keep N-1 active in DMA, while
|
||||
// preparing data in the final buffer?
|
||||
// Write another class similar to PWM_Arbiter, only for
|
||||
// tracking use of sequence buffers?
|
||||
// TODO: Use volatile variable to track buffers that the
|
||||
// prior DMA operation is finished with, so can fill
|
||||
// in those buffers with newly-prepared data...
|
||||
// apis to send the pre-generated buffer. This would be essentially asynchronous,
|
||||
// and result in efficient run time if the pixels are either (a) static, or
|
||||
// (b) cycle through a limited number of options whose converted results can
|
||||
// be cached and re-used. While simple, this method takes lots of extra RAM...
|
||||
// 16 bits for every full clock (high/low) cycle.
|
||||
//
|
||||
// Clockless chips typically send 24 bits (3x 8-bit) per pixel.
|
||||
// One odd clockless chip sends 36 bits (3x 12-bit) per pixel.
|
||||
// Each bit requires a 16-bit sequence entry for the PWM peripheral.
|
||||
// This gives approximately:
|
||||
// 24 bpp 36 bpp
|
||||
// ==========================================
|
||||
// 1 pixel 48 bytes 72 bytes
|
||||
// 32 pixels 1,536 bytes 2,304 bytes
|
||||
// 64 pixels 3,072 bytes 4,608 bytes
|
||||
//
|
||||
//
|
||||
// UPDATE: this is the method I'm choosing, to get _SOMETHING_
|
||||
// clockless working... 3k RAM for 64 pixels is acceptable
|
||||
// for a first release, as it allows re-use of FASTLED
|
||||
// color correction, dithering, etc. ....
|
||||
*/
|
||||
|
||||
//FASTLED_NAMESPACE_END
|
||||
|
||||
#endif // NRF52_SERIES
|
||||
#endif // __INC_CLOCKLESS_ARM_NRF52
|
@ -0,0 +1,11 @@
|
||||
#ifndef __INC_FASTLED_ARM_NRF52_H
|
||||
#define __INC_FASTLED_ARM_NRF52_H
|
||||
|
||||
#include "led_sysdefs_arm_nrf52.h"
|
||||
#include "arbiter_nrf52.h"
|
||||
#include "fastpin_arm_nrf52.h"
|
||||
#include "fastspi_arm_nrf52.h"
|
||||
#include "clockless_arm_nrf52.h"
|
||||
|
||||
#endif // #ifndef __INC_FASTLED_ARM_NRF52_H
|
||||
|
@ -0,0 +1,331 @@
|
||||
#ifndef __FASTPIN_ARM_NRF52_H
|
||||
#define __FASTPIN_ARM_NRF52_H
|
||||
|
||||
|
||||
/*
|
||||
//
|
||||
// Background:
|
||||
// ===========
|
||||
// the nRF52 has more than 32 ports, and thus must support
|
||||
// two distinct GPIO port registers.
|
||||
//
|
||||
// For the nRF52 series, the structure to control the port is
|
||||
// `NRF_GPIO_Type`, with separate addresses mapped for set, clear, etc.
|
||||
// The two ports are defined as NRF_P0 and NRF_P1.
|
||||
// An example declaration for the ports is:
|
||||
// #define NRF_P0_BASE 0x50000000UL
|
||||
// #define NRF_P1_BASE 0x50000300UL
|
||||
// #define NRF_P0 ((NRF_GPIO_Type*)NRF_P0_BASE)
|
||||
// #define NRF_P1 ((NRF_GPIO_Type*)NRF_P1_BASE)
|
||||
//
|
||||
// Therefore, ideally, the _FL_DEFPIN() macro would simply
|
||||
// conditionally pass either NRF_P0 or NRF_P1 to the underlying
|
||||
// FastPin<> template class class.
|
||||
//
|
||||
// The "pin" provided to the FastLED<> template (and which
|
||||
// the _FL_DEFPIN() macro specializes for valid pins) is NOT
|
||||
// the microcontroller port.pin, but the Arduino digital pin.
|
||||
// Some boards have an identity mapping (e.g., nRF52832 Feather)
|
||||
// but most do not. Therefore, the _FL_DEFPIN() macro
|
||||
// must translate the Arduino pin to the mcu port.pin.
|
||||
//
|
||||
//
|
||||
// Difficulties:
|
||||
// =============
|
||||
// The goal is to avoid any such lookups, using compile-time
|
||||
// optimized functions for speed, in line with FastLED's
|
||||
// overall design goals. This means constexpr, compile-time
|
||||
// and aggressive inlining of functions....
|
||||
//
|
||||
// Right away, this precludes the use of g_ADigitalPinMap,
|
||||
// which is not constexpr, and thus not available for
|
||||
// preprocessor/compile-time optimizations. Therefore,
|
||||
// we have to specialize FastPin<uint8_t PIN>, given a
|
||||
// compile-time value for PIN, into at least a PORT and
|
||||
// a BITMASK for the port.
|
||||
//
|
||||
// Arduino compiles using C++11 for at least Feather nRF52840 Express.
|
||||
// C++11 is very restrictive about template parameters.
|
||||
// Template parameters can only be:
|
||||
// 1. a type (as most people expect)
|
||||
// 2. a template
|
||||
// 3. a constexpr native integer type
|
||||
//
|
||||
// Therefore, attempts to use `NRF_GPIO_Type *` as a
|
||||
// template parameter will fail....
|
||||
//
|
||||
// Solution:
|
||||
// =========
|
||||
// The solution chosen is to define a unique structure for each port,
|
||||
// whose SOLE purpose is to have a static inline function that
|
||||
// returns the `NRF_GPIO_Type *` that is needed.
|
||||
//
|
||||
// Thus, while it's illegal to pass `NRF_P0` as a template
|
||||
// parameter, it's perfectly legal to pass `__generated_struct_NRF_P0`,
|
||||
// and have the template call a well-known `static inline` function
|
||||
// that returns `NRF_P0` ... which is itself a compile-time constant.
|
||||
//
|
||||
// Note that additional magic can be applied that will automatically
|
||||
// generate the structures. If you want to add that to this platform,
|
||||
// check out the KL26 platform files for a starting point.
|
||||
//
|
||||
*/
|
||||
|
||||
// manually define two structures, to avoid fighting with preprocessor macros
|
||||
struct __generated_struct_NRF_P0 {
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE constexpr static uintptr_t r() {
|
||||
return NRF_P0_BASE;
|
||||
}
|
||||
};
|
||||
// Not all NRF52 chips have two ports. Only define if P1 is present.
|
||||
#if defined(NRF_P1_BASE)
|
||||
struct __generated_struct_NRF_P1 {
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE constexpr static uintptr_t r() {
|
||||
return NRF_P1_BASE;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
// The actual class template can then use a typename, for what is essentially a constexpr NRF_GPIO_Type*
|
||||
template <uint32_t _MASK, typename _PORT, uint8_t _PORT_NUMBER, uint8_t _PIN_NUMBER> class _ARMPIN {
|
||||
public:
|
||||
typedef volatile uint32_t * port_ptr_t;
|
||||
typedef uint32_t port_t;
|
||||
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static void setOutput() {
|
||||
// OK for this to be more than one instruction, as unusual to quickly switch input/output modes
|
||||
nrf_gpio_cfg(
|
||||
nrf_pin(),
|
||||
NRF_GPIO_PIN_DIR_OUTPUT, // set pin as output
|
||||
NRF_GPIO_PIN_INPUT_DISCONNECT, // disconnect the input buffering
|
||||
NRF_GPIO_PIN_NOPULL, // neither pull-up nor pull-down resistors enabled
|
||||
NRF_GPIO_PIN_H0H1, // high drive mode required for faster speeds
|
||||
NRF_GPIO_PIN_NOSENSE // pin sense level disabled
|
||||
);
|
||||
}
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static void setInput() {
|
||||
// OK for this to be more than one instruction, as unusual to quickly switch input/output modes
|
||||
nrf_gpio_cfg(
|
||||
nrf_pin(),
|
||||
NRF_GPIO_PIN_DIR_INPUT, // set pin as input
|
||||
NRF_GPIO_PIN_INPUT_DISCONNECT, // disconnect the input buffering
|
||||
NRF_GPIO_PIN_NOPULL, // neither pull-up nor pull-down resistors enabled
|
||||
NRF_GPIO_PIN_H0H1, // high drive mode required for faster speeds
|
||||
NRF_GPIO_PIN_NOSENSE // pin sense level disabled
|
||||
);
|
||||
}
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static void hi() { (reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUTSET = _MASK; } // sets _MASK in the SET OUTPUT register (output set high)
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static void lo() { (reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUTCLR = _MASK; } // sets _MASK in the CLEAR OUTPUT register (output set low)
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static void toggle() { (reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUT ^= _MASK; } // toggles _MASK bits in the OUTPUT GPIO port directly
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static void strobe() { toggle(); toggle(); } // BUGBUG -- Is this used by FastLED? Without knowing (for example) SPI Speed?
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static port_t hival() { return (reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUT | _MASK; } // sets all _MASK bit(s) in the OUTPUT GPIO port to 1
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static port_t loval() { return (reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUT & ~_MASK; } // sets all _MASK bit(s) in the OUTPUT GPIO port to 0
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static port_ptr_t port() { return &((reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUT); } // gets raw pointer to OUTPUT GPIO port
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static port_ptr_t cport() { return &((reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUTCLR); } // gets raw pointer to SET DIRECTION GPIO port
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static port_ptr_t sport() { return &((reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUTSET); } // gets raw pointer to CLEAR DIRECTION GPIO port
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static port_t mask() { return _MASK; } // gets the value of _MASK
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static void hi (register port_ptr_t port) { hi(); } // sets _MASK in the SET OUTPUT register (output set high)
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static void lo (register port_ptr_t port) { lo(); } // sets _MASK in the CLEAR OUTPUT register (output set low)
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static void set(register port_t val ) { (reinterpret_cast<NRF_GPIO_Type*>(_PORT::r()))->OUT = val; } // sets entire port's value (optimization used by FastLED)
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static void fastset(register port_ptr_t port, register port_t val) { *port = val; }
|
||||
constexpr static uint32_t nrf_pin2() { return NRF_GPIO_PIN_MAP(_PORT_NUMBER, _PIN_NUMBER); }
|
||||
constexpr static bool LowSpeedOnlyRecommended() {
|
||||
// only allow one function body.
|
||||
#undef _FASTLED_NRF52_LOW_SPEED_ONLY_BOARD_DETECT
|
||||
|
||||
// unique cases for each board / processor package / module?
|
||||
#if defined(NRF52810_XXAA) && defined(NRF52810_PACKAGE_QFN48)
|
||||
#if defined(_FASTLED_NRF52_LOW_SPEED_ONLY_BOARD_DETECT)
|
||||
#error "Multiple board match"
|
||||
#endif
|
||||
#define _FASTLED_NRF52_LOW_SPEED_ONLY_BOARD_DETECT 1
|
||||
static_assert(_PORT_NUMBER == 0, "nRF52810 only has one port");
|
||||
return (
|
||||
(_PIN_NUMBER == 25) ||
|
||||
(_PIN_NUMBER == 26) ||
|
||||
(_PIN_NUMBER == 27) ||
|
||||
(_PIN_NUMBER == 28) ||
|
||||
(_PIN_NUMBER == 29)
|
||||
);
|
||||
#endif
|
||||
#if defined(NRF52810_XXAA) && defined(NRF52810_PACKAGE_QFN32)
|
||||
#if defined(_FASTLED_NRF52_LOW_SPEED_ONLY_BOARD_DETECT)
|
||||
#error "Multiple board match"
|
||||
#endif
|
||||
#define _FASTLED_NRF52_LOW_SPEED_ONLY_BOARD_DETECT 1
|
||||
static_assert(_PORT_NUMBER == 0, "nRF52810 only has one port");
|
||||
if (_PORT_NUMBER == 0) {
|
||||
if (
|
||||
(_PIN_NUMBER == 26) ||
|
||||
(_PIN_NUMBER == 27)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
#if defined(NRF52832_XXAA) || defined(NRF52832_XXAB)
|
||||
#if defined(_FASTLED_NRF52_LOW_SPEED_ONLY_BOARD_DETECT)
|
||||
#error "Multiple board match"
|
||||
#endif
|
||||
#define _FASTLED_NRF52_LOW_SPEED_ONLY_BOARD_DETECT 1
|
||||
static_assert(_PORT_NUMBER == 0, "nRF52832 only has one port");
|
||||
// data sheets shows the same pins in both QFN48 and WLCSP package
|
||||
// are recommended as low-speed only:
|
||||
return (
|
||||
(_PIN_NUMBER == 22) ||
|
||||
(_PIN_NUMBER == 23) ||
|
||||
(_PIN_NUMBER == 24) ||
|
||||
(_PIN_NUMBER == 25) ||
|
||||
(_PIN_NUMBER == 26) ||
|
||||
(_PIN_NUMBER == 27) ||
|
||||
(_PIN_NUMBER == 28) ||
|
||||
(_PIN_NUMBER == 29) ||
|
||||
(_PIN_NUMBER == 30) ||
|
||||
(_PIN_NUMBER == 31)
|
||||
);
|
||||
#endif
|
||||
#if defined(NRF52840_XXAA) && defined(NRF52840_PACKAGE_aQFN73)
|
||||
#if defined(_FASTLED_NRF52_LOW_SPEED_ONLY_BOARD_DETECT)
|
||||
#error "Multiple board match"
|
||||
#endif
|
||||
#define _FASTLED_NRF52_LOW_SPEED_ONLY_BOARD_DETECT 1
|
||||
static_assert(_PORT_NUMBER == 0 || _PORT_NUMBER == 1, "nRF52840 only has two ports");
|
||||
return
|
||||
(
|
||||
(
|
||||
(_PORT_NUMBER == 0) &&
|
||||
(
|
||||
(_PIN_NUMBER == 2) ||
|
||||
(_PIN_NUMBER == 3) ||
|
||||
(_PIN_NUMBER == 9) ||
|
||||
(_PIN_NUMBER == 10) ||
|
||||
(_PIN_NUMBER == 11) ||
|
||||
(_PIN_NUMBER == 12) ||
|
||||
(_PIN_NUMBER == 14) ||
|
||||
(_PIN_NUMBER == 28) ||
|
||||
(_PIN_NUMBER == 29) ||
|
||||
(_PIN_NUMBER == 30) ||
|
||||
(_PIN_NUMBER == 31)
|
||||
)
|
||||
)
|
||||
||
|
||||
(
|
||||
(_PORT_NUMBER == 1) &&
|
||||
(
|
||||
(_PIN_NUMBER == 2) ||
|
||||
(_PIN_NUMBER == 3) ||
|
||||
(_PIN_NUMBER == 4) ||
|
||||
(_PIN_NUMBER == 5) ||
|
||||
(_PIN_NUMBER == 6) ||
|
||||
(_PIN_NUMBER == 7) ||
|
||||
(_PIN_NUMBER == 10) ||
|
||||
(_PIN_NUMBER == 13) ||
|
||||
(_PIN_NUMBER == 15)
|
||||
)
|
||||
)
|
||||
);
|
||||
#endif
|
||||
#if false && defined(NRF52840_XXAA) && (defined(NRF52840_PACKAGE_aQFN73) || defined(ARDUINO_NRF52840_FEATHER))
|
||||
// Adafruit nRF52840 feather uses RAYTAC MDBT50Q module, which is aQFN73
|
||||
// See https://cdn-learn.adafruit.com/assets/assets/000/068/544/original/Raytac_MDBT50Q.pdf
|
||||
#if defined(_FASTLED_NRF52_LOW_SPEED_ONLY_BOARD_DETECT)
|
||||
#error "Multiple board match"
|
||||
#endif
|
||||
#define _FASTLED_NRF52_LOW_SPEED_ONLY_BOARD_DETECT 1
|
||||
static_assert(_PORT_NUMBER == 0 || _PORT_NUMBER == 1, "nRF52840 only has two ports");
|
||||
return
|
||||
(
|
||||
(
|
||||
(_PORT_NUMBER == 0) &&
|
||||
(
|
||||
(_PIN_NUMBER == 2) ||
|
||||
(_PIN_NUMBER == 3) ||
|
||||
(_PIN_NUMBER == 9) ||
|
||||
(_PIN_NUMBER == 10) ||
|
||||
(_PIN_NUMBER == 28) ||
|
||||
(_PIN_NUMBER == 29) ||
|
||||
(_PIN_NUMBER == 30) ||
|
||||
(_PIN_NUMBER == 31)
|
||||
)
|
||||
)
|
||||
||
|
||||
(
|
||||
(_PORT_NUMBER == 1) &&
|
||||
(
|
||||
(_PIN_NUMBER == 1) ||
|
||||
(_PIN_NUMBER == 2) ||
|
||||
(_PIN_NUMBER == 3) ||
|
||||
(_PIN_NUMBER == 4) ||
|
||||
(_PIN_NUMBER == 5) ||
|
||||
(_PIN_NUMBER == 6) ||
|
||||
(_PIN_NUMBER == 7) ||
|
||||
(_PIN_NUMBER == 10) ||
|
||||
(_PIN_NUMBER == 11) ||
|
||||
(_PIN_NUMBER == 12) ||
|
||||
(_PIN_NUMBER == 13) ||
|
||||
(_PIN_NUMBER == 14) ||
|
||||
(_PIN_NUMBER == 15)
|
||||
)
|
||||
)
|
||||
);
|
||||
#endif
|
||||
#if !defined(_FASTLED_NRF52_LOW_SPEED_ONLY_BOARD_DETECT)
|
||||
#warning "Unknown board / package, ... caller must determine pins that support high-speed"
|
||||
return false; // choosing default to be FALSE, to allow users to ATTEMPT to use high-speed on pins where support is not known
|
||||
#endif
|
||||
}
|
||||
// Expose the nrf pin (port/pin combined), port, and pin as properties (e.g., for setting up SPI)
|
||||
|
||||
FASTLED_NRF52_INLINE_ATTRIBUTE static uint32_t nrf_pin() { return NRF_GPIO_PIN_MAP(_PORT_NUMBER, _PIN_NUMBER); }
|
||||
};
|
||||
|
||||
//
|
||||
// BOARD_PIN can be either the pin portion of a port.pin, or the combined NRF_GPIO_PIN_MAP() number.
|
||||
// For example both the following two defines refer to P1.15 (pin 47) as Arduino pin 3:
|
||||
// _FL_DEFPIN(3, 15, 1);
|
||||
// _FL_DEFPIN(3, 47, 1);
|
||||
//
|
||||
// Similarly, the following defines are all equivalent:
|
||||
// _DEFPIN_ARM_IDENTITY_P1(47);
|
||||
// _FL_DEFPIN(47, 15, 1);
|
||||
// _FL_DEFPIN(47, 47, 1);
|
||||
//
|
||||
|
||||
#define _FL_DEFPIN(ARDUINO_PIN, BOARD_PIN, BOARD_PORT) \
|
||||
template<> class FastPin<ARDUINO_PIN> : \
|
||||
public _ARMPIN< \
|
||||
1u << (BOARD_PIN & 31u), \
|
||||
__generated_struct_NRF_P ## BOARD_PORT, \
|
||||
(BOARD_PIN / 32), \
|
||||
BOARD_PIN & 31u \
|
||||
> \
|
||||
{}
|
||||
|
||||
#define _DEFPIN_ARM_IDENTITY_P0(ARDUINO_PIN) \
|
||||
template<> class FastPin<ARDUINO_PIN> : \
|
||||
public _ARMPIN< \
|
||||
1u << (ARDUINO_PIN & 31u), \
|
||||
__generated_struct_NRF_P0, \
|
||||
0, \
|
||||
(ARDUINO_PIN & 31u) + 0 \
|
||||
> \
|
||||
{}
|
||||
|
||||
#define _DEFPIN_ARM_IDENTITY_P1(ARDUINO_PIN) \
|
||||
template<> class FastPin<ARDUINO_PIN> : \
|
||||
public _ARMPIN< \
|
||||
1u << (ARDUINO_PIN & 31u), \
|
||||
__generated_struct_NRF_P1, \
|
||||
1, \
|
||||
(ARDUINO_PIN & 31u) + 32 \
|
||||
> \
|
||||
{}
|
||||
|
||||
// The actual pin definitions are in a separate header file...
|
||||
#include "fastpin_arm_nrf52_variants.h"
|
||||
|
||||
#define HAS_HARDWARE_PIN_SUPPORT
|
||||
|
||||
#endif // #ifndef __FASTPIN_ARM_NRF52_H
|
@ -0,0 +1,579 @@
|
||||
#ifndef __FASTPIN_ARM_NRF52_VARIANTS_H
|
||||
#define __FASTPIN_ARM_NRF52_VARIANTS_H
|
||||
|
||||
// use this to determine if found variant or not (avoid multiple boards at once)
|
||||
#undef __FASTPIN_ARM_NRF52_VARIANT_FOUND
|
||||
|
||||
// Adafruit Bluefruit nRF52832 Feather
|
||||
// From https://www.adafruit.com/package_adafruit_index.json
|
||||
#if defined (ARDUINO_NRF52832_FEATHER)
|
||||
#if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND)
|
||||
#error "Cannot define more than one board at a time"
|
||||
#else
|
||||
#define __FASTPIN_ARM_NRF52_VARIANT_FOUND
|
||||
#endif
|
||||
#warning "Adafruit Bluefruit nRF52832 Feather is an untested board -- test and let use know your results via https://github.com/FastLED/FastLED/issues"
|
||||
_DEFPIN_ARM_IDENTITY_P0( 0); // xtal 1
|
||||
_DEFPIN_ARM_IDENTITY_P0( 1); // xtal 2
|
||||
_DEFPIN_ARM_IDENTITY_P0( 2); // a0
|
||||
_DEFPIN_ARM_IDENTITY_P0( 3); // a1
|
||||
_DEFPIN_ARM_IDENTITY_P0( 4); // a2
|
||||
_DEFPIN_ARM_IDENTITY_P0( 5); // a3
|
||||
_DEFPIN_ARM_IDENTITY_P0( 6); // TXD
|
||||
_DEFPIN_ARM_IDENTITY_P0( 7); // GPIO #7
|
||||
_DEFPIN_ARM_IDENTITY_P0( 8); // RXD
|
||||
_DEFPIN_ARM_IDENTITY_P0( 9); // NFC1
|
||||
_DEFPIN_ARM_IDENTITY_P0(10); // NFC2
|
||||
_DEFPIN_ARM_IDENTITY_P0(11); // GPIO #11
|
||||
_DEFPIN_ARM_IDENTITY_P0(12); // SCK
|
||||
_DEFPIN_ARM_IDENTITY_P0(13); // MOSI
|
||||
_DEFPIN_ARM_IDENTITY_P0(14); // MISO
|
||||
_DEFPIN_ARM_IDENTITY_P0(15); // GPIO #15
|
||||
_DEFPIN_ARM_IDENTITY_P0(16); // GPIO #16
|
||||
_DEFPIN_ARM_IDENTITY_P0(17); // LED #1 (red)
|
||||
_DEFPIN_ARM_IDENTITY_P0(18); // SWO
|
||||
_DEFPIN_ARM_IDENTITY_P0(19); // LED #2 (blue)
|
||||
_DEFPIN_ARM_IDENTITY_P0(20); // DFU
|
||||
// _DEFPIN_ARM_IDENTITY_P0(21); // Reset -- not valid to use for FastLED?
|
||||
// _DEFPIN_ARM_IDENTITY_P0(22); // Factory Reset -- not vaild to use for FastLED?
|
||||
// _DEFPIN_ARM_IDENTITY_P0(23); // N/A
|
||||
// _DEFPIN_ARM_IDENTITY_P0(24); // N/A
|
||||
_DEFPIN_ARM_IDENTITY_P0(25); // SDA
|
||||
_DEFPIN_ARM_IDENTITY_P0(26); // SCL
|
||||
_DEFPIN_ARM_IDENTITY_P0(27); // GPIO #27
|
||||
_DEFPIN_ARM_IDENTITY_P0(28); // A4
|
||||
_DEFPIN_ARM_IDENTITY_P0(29); // A5
|
||||
_DEFPIN_ARM_IDENTITY_P0(30); // A6
|
||||
_DEFPIN_ARM_IDENTITY_P0(31); // A7
|
||||
#endif // defined (ARDUINO_NRF52832_FEATHER)
|
||||
|
||||
// Adafruit Bluefruit nRF52840 Feather Express
|
||||
// From https://www.adafruit.com/package_adafruit_index.json
|
||||
#if defined (ARDUINO_NRF52840_FEATHER)
|
||||
#if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND)
|
||||
#error "Cannot define more than one board at a time"
|
||||
#else
|
||||
#define __FASTPIN_ARM_NRF52_VARIANT_FOUND
|
||||
#endif
|
||||
|
||||
#define MAX_PIN (33u) // 34 if wanting to use NFC1 test point
|
||||
|
||||
// Arduino pins 0..7
|
||||
_FL_DEFPIN( 0, 25, 0); // D0 is P0.25 -- UART TX
|
||||
//_FL_DEFPIN( 1, 24, 0); // D1 is P0.24 -- UART RX
|
||||
_FL_DEFPIN( 2, 10, 0); // D2 is P0.10 -- NFC2
|
||||
_FL_DEFPIN( 3, 47, 1); // D3 is P1.15 -- PIN_LED1 (red)
|
||||
_FL_DEFPIN( 4, 42, 1); // D4 is P1.10 -- PIN_LED2 (blue)
|
||||
_FL_DEFPIN( 5, 40, 1); // D5 is P1.08 -- SPI/SS
|
||||
_FL_DEFPIN( 6, 7, 0); // D6 is P0.07
|
||||
_FL_DEFPIN( 7, 34, 1); // D7 is P1.02 -- PIN_DFU (Button)
|
||||
|
||||
// Arduino pins 8..15
|
||||
_FL_DEFPIN( 8, 16, 0); // D8 is P0.16 -- PIN_NEOPIXEL
|
||||
_FL_DEFPIN( 9, 26, 0); // D9 is P0.26
|
||||
_FL_DEFPIN(10, 27, 0); // D10 is P0.27
|
||||
_FL_DEFPIN(11, 6, 0); // D11 is P0.06
|
||||
_FL_DEFPIN(12, 8, 0); // D12 is P0.08
|
||||
_FL_DEFPIN(13, 41, 1); // D13 is P1.09
|
||||
_FL_DEFPIN(14, 4, 0); // D14 is P0.04 -- A0
|
||||
_FL_DEFPIN(15, 5, 0); // D15 is P0.05 -- A1
|
||||
|
||||
// Arduino pins 16..23
|
||||
_FL_DEFPIN(16, 30, 0); // D16 is P0.30 -- A2
|
||||
_FL_DEFPIN(17, 28, 0); // D17 is P0.28 -- A3
|
||||
_FL_DEFPIN(18, 2, 0); // D18 is P0.02 -- A4
|
||||
_FL_DEFPIN(19, 3, 0); // D19 is P0.03 -- A5
|
||||
//_FL_DEFPIN(20, 29, 0); // D20 is P0.29 -- A6 -- Connected to battery!
|
||||
//_FL_DEFPIN(21, 31, 0); // D21 is P0.31 -- A7 -- AREF
|
||||
_FL_DEFPIN(22, 12, 0); // D22 is P0.12 -- SDA
|
||||
_FL_DEFPIN(23, 11, 0); // D23 is P0.11 -- SCL
|
||||
|
||||
// Arduino pins 24..31
|
||||
_FL_DEFPIN(24, 15, 0); // D24 is P0.15 -- PIN_SPI_MISO
|
||||
_FL_DEFPIN(25, 13, 0); // D25 is P0.13 -- PIN_SPI_MOSI
|
||||
_FL_DEFPIN(26, 14, 0); // D26 is P0.14 -- PIN_SPI_SCK
|
||||
//_FL_DEFPIN(27, 19, 0); // D27 is P0.19 -- PIN_QSPI_SCK
|
||||
//_FL_DEFPIN(28, 20, 0); // D28 is P0.20 -- PIN_QSPI_CS
|
||||
//_FL_DEFPIN(29, 17, 0); // D29 is P0.17 -- PIN_QSPI_DATA0
|
||||
//_FL_DEFPIN(30, 22, 0); // D30 is P0.22 -- PIN_QSPI_DATA1
|
||||
//_FL_DEFPIN(31, 23, 0); // D31 is P0.23 -- PIN_QSPI_DATA2
|
||||
|
||||
// Arduino pins 32..34
|
||||
//_FL_DEFPIN(32, 21, 0); // D32 is P0.21 -- PIN_QSPI_DATA3
|
||||
//_FL_DEFPIN(33, 9, 0); // D33 is NFC1, only accessible via test point
|
||||
#endif // defined (ARDUINO_NRF52840_FEATHER)
|
||||
|
||||
// Adafruit Bluefruit nRF52840 Metro Express
|
||||
// From https://www.adafruit.com/package_adafruit_index.json
|
||||
#if defined (ARDUINO_NRF52840_METRO)
|
||||
#if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND)
|
||||
#error "Cannot define more than one board at a time"
|
||||
#else
|
||||
#define __FASTPIN_ARM_NRF52_VARIANT_FOUND
|
||||
#endif
|
||||
#warning "Adafruit Bluefruit nRF52840 Metro Express is an untested board -- test and let use know your results via https://github.com/FastLED/FastLED/issues"
|
||||
|
||||
_FL_DEFPIN( 0, 25, 0); // D0 is P0.25 (UART TX)
|
||||
_FL_DEFPIN( 1, 24, 0); // D1 is P0.24 (UART RX)
|
||||
_FL_DEFPIN( 2, 10, 1); // D2 is P1.10
|
||||
_FL_DEFPIN( 3, 4, 1); // D3 is P1.04
|
||||
_FL_DEFPIN( 4, 11, 1); // D4 is P1.11
|
||||
_FL_DEFPIN( 5, 12, 1); // D5 is P1.12
|
||||
_FL_DEFPIN( 6, 14, 1); // D6 is P1.14
|
||||
_FL_DEFPIN( 7, 26, 0); // D7 is P0.26
|
||||
_FL_DEFPIN( 8, 27, 0); // D8 is P0.27
|
||||
_FL_DEFPIN( 9, 12, 0); // D9 is P0.12
|
||||
_FL_DEFPIN(10, 6, 0); // D10 is P0.06
|
||||
_FL_DEFPIN(11, 8, 0); // D11 is P0.08
|
||||
_FL_DEFPIN(12, 9, 1); // D12 is P1.09
|
||||
_FL_DEFPIN(13, 14, 0); // D13 is P0.14
|
||||
_FL_DEFPIN(14, 4, 0); // D14 is P0.04 (A0)
|
||||
_FL_DEFPIN(15, 5, 0); // D15 is P0.05 (A1)
|
||||
_FL_DEFPIN(16, 28, 0); // D16 is P0.28 (A2)
|
||||
_FL_DEFPIN(17, 30, 0); // D17 is P0.30 (A3)
|
||||
_FL_DEFPIN(18, 2, 0); // D18 is P0.02 (A4)
|
||||
_FL_DEFPIN(19, 3, 0); // D19 is P0.03 (A5)
|
||||
_FL_DEFPIN(20, 29, 0); // D20 is P0.29 (A6, battery)
|
||||
_FL_DEFPIN(21, 31, 0); // D21 is P0.31 (A7, ARef)
|
||||
_FL_DEFPIN(22, 15, 0); // D22 is P0.15 (SDA)
|
||||
_FL_DEFPIN(23, 16, 0); // D23 is P0.16 (SCL)
|
||||
_FL_DEFPIN(24, 11, 0); // D24 is P0.11 (SPI MISO)
|
||||
_FL_DEFPIN(25, 8, 1); // D25 is P1.08 (SPI MOSI)
|
||||
_FL_DEFPIN(26, 7, 0); // D26 is P0.07 (SPI SCK )
|
||||
//_FL_DEFPIN(27, 19, 0); // D27 is P0.19 (QSPI CLK )
|
||||
//_FL_DEFPIN(28, 20, 0); // D28 is P0.20 (QSPI CS )
|
||||
//_FL_DEFPIN(29, 17, 0); // D29 is P0.17 (QSPI Data 0)
|
||||
//_FL_DEFPIN(30, 23, 0); // D30 is P0.23 (QSPI Data 1)
|
||||
//_FL_DEFPIN(31, 22, 0); // D31 is P0.22 (QSPI Data 2)
|
||||
//_FL_DEFPIN(32, 21, 0); // D32 is P0.21 (QSPI Data 3)
|
||||
_FL_DEFPIN(33, 13, 1); // D33 is P1.13 LED1
|
||||
_FL_DEFPIN(34, 15, 1); // D34 is P1.15 LED2
|
||||
_FL_DEFPIN(35, 13, 0); // D35 is P0.13 NeoPixel
|
||||
_FL_DEFPIN(36, 0, 1); // D36 is P1.02 Switch
|
||||
_FL_DEFPIN(37, 0, 1); // D37 is P1.00 SWO/DFU
|
||||
_FL_DEFPIN(38, 9, 0); // D38 is P0.09 NFC1
|
||||
_FL_DEFPIN(39, 10, 0); // D39 is P0.10 NFC2
|
||||
#endif // defined (ARDUINO_NRF52840_METRO)
|
||||
|
||||
// Adafruit Bluefruit on nRF52840DK PCA10056
|
||||
// From https://www.adafruit.com/package_adafruit_index.json
|
||||
#if defined (ARDUINO_NRF52840_PCA10056)
|
||||
#if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND)
|
||||
#error "Cannot define more than one board at a time"
|
||||
#else
|
||||
#define __FASTPIN_ARM_NRF52_VARIANT_FOUND
|
||||
#endif
|
||||
#warning "Adafruit Bluefruit on nRF52840DK PCA10056 is an untested board -- test and let use know your results via https://github.com/FastLED/FastLED/issues"
|
||||
|
||||
#if defined(USE_ARDUINO_PIN_NUMBERING)
|
||||
/* pca10056_schematic_and_pcb.pdf
|
||||
Page 3 shows the Arduino Pin to GPIO Px.xx mapping
|
||||
*/
|
||||
_FL_DEFPIN( 0, 1, 1); // D0 is P1.01
|
||||
_FL_DEFPIN( 1, 2, 1); // D1 is P1.02
|
||||
_FL_DEFPIN( 2, 3, 1); // D2 is P1.03
|
||||
_FL_DEFPIN( 3, 4, 1); // D3 is P1.04
|
||||
_FL_DEFPIN( 4, 5, 1); // D4 is P1.05
|
||||
_FL_DEFPIN( 5, 6, 1); // D5 is P1.06
|
||||
_FL_DEFPIN( 6, 7, 1); // D6 is P1.07 (BUTTON1 option)
|
||||
_FL_DEFPIN( 7, 8, 1); // D7 is P1.08 (BUTTON2 option)
|
||||
_FL_DEFPIN( 8, 10, 1); // D8 is P1.10
|
||||
_FL_DEFPIN( 9, 11, 1); // D9 is P1.11
|
||||
_FL_DEFPIN(10, 12, 1); // D10 is P1.12
|
||||
_FL_DEFPIN(11, 13, 1); // D11 is P1.13
|
||||
_FL_DEFPIN(12, 14, 1); // D12 is P1.14
|
||||
_FL_DEFPIN(13, 15, 1); // D13 is P1.15
|
||||
_FL_DEFPIN(14, 0, 0); // D14 is P0.00 (if SB4 bridged)
|
||||
_FL_DEFPIN(15, 1, 0); // D15 is P0.01 (if SB3 bridged)
|
||||
_FL_DEFPIN(16, 5, 0); // D16 is P0.05 (aka AIN3, aka UART RTS)
|
||||
_FL_DEFPIN(17, 6, 0); // D17 is P0.06 (UART TxD)
|
||||
_FL_DEFPIN(18, 7, 0); // D18 is P0.07 (UART CTS default)
|
||||
_FL_DEFPIN(19, 8, 0); // D19 is P0.08 (UART RxD)
|
||||
_FL_DEFPIN(20, 9, 0); // D20 is P0.09 (NFC1)
|
||||
_FL_DEFPIN(21, 10, 0); // D21 is P0.10 (NFC2)
|
||||
_FL_DEFPIN(22, 11, 0); // D22 is P0.11 (TRACEDATA2 / BUTTON1 default)
|
||||
_FL_DEFPIN(23, 12, 0); // D23 is P0.12 (TRACEDATA1 / BUTTON2 default)
|
||||
_FL_DEFPIN(24, 13, 0); // D24 is P0.13 (LED1)
|
||||
_FL_DEFPIN(25, 14, 0); // D25 is P0.14 (LED2)
|
||||
_FL_DEFPIN(26, 15, 0); // D26 is P0.15 (LED3)
|
||||
_FL_DEFPIN(27, 16, 0); // D27 is P0.16 (LED4)
|
||||
_FL_DEFPIN(28, 17, 0); // D28 is P0.17 (QSPI !CS , unless SB13 cut)
|
||||
// _FL_DEFPIN(29, 18, 0); // D29 is P0.18 (RESET)
|
||||
_FL_DEFPIN(30, 19, 0); // D30 is P0.19 (QSPI CLK , unless SB11 cut)
|
||||
_FL_DEFPIN(31, 20, 0); // D31 is P0.20 (QSPI DIO0, unless SB12 cut)
|
||||
_FL_DEFPIN(32, 21, 0); // D32 is P0.21 (QSPI DIO1, unless SB14 cut)
|
||||
_FL_DEFPIN(33, 22, 0); // D33 is P0.22 (QSPI DIO2, unless SB15 cut)
|
||||
_FL_DEFPIN(34, 23, 0); // D34 is P0.23 (QSPI DIO3, unless SB10 cut)
|
||||
_FL_DEFPIN(35, 24, 0); // D35 is P0.24 (BUTTON3)
|
||||
_FL_DEFPIN(36, 25, 0); // D36 is P0.25 (BUTTON4)
|
||||
_FL_DEFPIN(37, 00, 1); // D37 is P1.00 (TRACEDATA0 / SWO)
|
||||
_FL_DEFPIN(38, 09, 1); // D38 is P1.09 (TRACEDATA3)
|
||||
//_FL_DEFPIN(??, 2, 0); // D?? is P0.02 (AREF, aka AIN0)
|
||||
//_FL_DEFPIN(??, 3, 0); // D?? is P0.03 (A0, aka AIN1)
|
||||
//_FL_DEFPIN(??, 4, 0); // D?? is P0.04 (A1, aka AIN2, aka UART CTS option)
|
||||
//_FL_DEFPIN(??, 28, 0); // D?? is P0.28 (A2, aka AIN4)
|
||||
//_FL_DEFPIN(??, 29, 0); // D?? is P0.29 (A3, aka AIN5)
|
||||
//_FL_DEFPIN(??, 30, 0); // D?? is P0.30 (A4, aka AIN6)
|
||||
//_FL_DEFPIN(??, 31, 0); // D?? is P0.31 (A5, aka AIN7)
|
||||
|
||||
#else
|
||||
/* 48 pins, defined using natural mapping in Adafruit's variant.cpp (!) */
|
||||
_DEFPIN_ARM_IDENTITY_P0( 0); // P0.00 (XL1 .. ensure SB4 bridged, SB2 cut)
|
||||
_DEFPIN_ARM_IDENTITY_P0( 1); // P0.01 (XL2 .. ensure SB3 bridged, SB1 cut)
|
||||
_DEFPIN_ARM_IDENTITY_P0( 2); // P0.02 (AIN0)
|
||||
_DEFPIN_ARM_IDENTITY_P0( 3); // P0.03 (AIN1)
|
||||
_DEFPIN_ARM_IDENTITY_P0( 4); // P0.04 (AIN2 / UART CTS option)
|
||||
_DEFPIN_ARM_IDENTITY_P0( 5); // P0.05 (AIN3 / UART RTS)
|
||||
_DEFPIN_ARM_IDENTITY_P0( 6); // P0.06 (UART TxD)
|
||||
_DEFPIN_ARM_IDENTITY_P0( 7); // P0.07 (TRACECLK / UART CTS default)
|
||||
_DEFPIN_ARM_IDENTITY_P0( 8); // P0.08 (UART RxD)
|
||||
_DEFPIN_ARM_IDENTITY_P0( 9); // P0.09 (NFC1)
|
||||
_DEFPIN_ARM_IDENTITY_P0(10); // P0.10 (NFC2)
|
||||
_DEFPIN_ARM_IDENTITY_P0(11); // P0.11 (TRACEDATA2 / BUTTON1 default)
|
||||
_DEFPIN_ARM_IDENTITY_P0(12); // P0.12 (TRACEDATA1 / BUTTON2 default)
|
||||
_DEFPIN_ARM_IDENTITY_P0(13); // P0.13 (LED1)
|
||||
_DEFPIN_ARM_IDENTITY_P0(14); // P0.14 (LED2)
|
||||
_DEFPIN_ARM_IDENTITY_P0(15); // P0.15 (LED3)
|
||||
_DEFPIN_ARM_IDENTITY_P0(16); // P0.16 (LED4)
|
||||
//_DEFPIN_ARM_IDENTITY_P0(17); // P0.17 (QSPI !CS )
|
||||
//_DEFPIN_ARM_IDENTITY_P0(18); // P0.18 (RESET)
|
||||
//_DEFPIN_ARM_IDENTITY_P0(19); // P0.19 (QSPI CLK )
|
||||
//_DEFPIN_ARM_IDENTITY_P0(20); // P0.20 (QSPI DIO0)
|
||||
//_DEFPIN_ARM_IDENTITY_P0(21); // P0.21 (QSPI DIO1)
|
||||
//_DEFPIN_ARM_IDENTITY_P0(22); // P0.22 (QSPI DIO2)
|
||||
//_DEFPIN_ARM_IDENTITY_P0(23); // P0.23 (QSPI DIO3)
|
||||
_DEFPIN_ARM_IDENTITY_P0(24); // P0.24 (BUTTON3)
|
||||
_DEFPIN_ARM_IDENTITY_P0(25); // P0.25 (BUTTON4)
|
||||
_DEFPIN_ARM_IDENTITY_P0(26); // P0.26
|
||||
_DEFPIN_ARM_IDENTITY_P0(27); // P0.27
|
||||
_DEFPIN_ARM_IDENTITY_P0(28); // P0.28 (AIN4)
|
||||
_DEFPIN_ARM_IDENTITY_P0(29); // P0.29 (AIN5)
|
||||
_DEFPIN_ARM_IDENTITY_P0(30); // P0.30 (AIN6)
|
||||
_DEFPIN_ARM_IDENTITY_P0(31); // P0.31 (AIN7)
|
||||
_DEFPIN_ARM_IDENTITY_P0(32); // P1.00 (SWO / TRACEDATA0)
|
||||
_DEFPIN_ARM_IDENTITY_P0(33); // P1.01
|
||||
_DEFPIN_ARM_IDENTITY_P0(34); // P1.02
|
||||
_DEFPIN_ARM_IDENTITY_P0(35); // P1.03
|
||||
_DEFPIN_ARM_IDENTITY_P0(36); // P1.04
|
||||
_DEFPIN_ARM_IDENTITY_P0(37); // P1.05
|
||||
_DEFPIN_ARM_IDENTITY_P0(38); // P1.06
|
||||
_DEFPIN_ARM_IDENTITY_P0(39); // P1.07 (BUTTON1 option)
|
||||
_DEFPIN_ARM_IDENTITY_P0(40); // P1.08 (BUTTON2 option)
|
||||
_DEFPIN_ARM_IDENTITY_P0(41); // P1.09 (TRACEDATA3)
|
||||
_DEFPIN_ARM_IDENTITY_P0(42); // P1.10
|
||||
_DEFPIN_ARM_IDENTITY_P0(43); // P1.11
|
||||
_DEFPIN_ARM_IDENTITY_P0(44); // P1.12
|
||||
_DEFPIN_ARM_IDENTITY_P0(45); // P1.13
|
||||
_DEFPIN_ARM_IDENTITY_P0(46); // P1.14
|
||||
_DEFPIN_ARM_IDENTITY_P0(47); // P1.15
|
||||
#endif
|
||||
#endif // defined (ARDUINO_NRF52840_PCA10056)
|
||||
|
||||
// Electronut labs bluey
|
||||
// See https://github.com/sandeepmistry/arduino-nRF5/blob/master/variants/bluey/variant.cpp
|
||||
#if defined(ARDUINO_ELECTRONUT_BLUEY)
|
||||
#if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND)
|
||||
#error "Cannot define more than one board at a time"
|
||||
#else
|
||||
#define __FASTPIN_ARM_NRF52_VARIANT_FOUND
|
||||
#endif
|
||||
#warning "Electronut labs bluey is an untested board -- test and let use know your results via https://github.com/FastLED/FastLED/issues"
|
||||
|
||||
_FL_DEFPIN( 0, 26, 0); // D0 is P0.26
|
||||
_FL_DEFPIN( 1, 27, 0); // D1 is P0.27
|
||||
_FL_DEFPIN( 2, 22, 0); // D2 is P0.22 (SPI SS )
|
||||
_FL_DEFPIN( 3, 23, 0); // D3 is P0.23 (SPI MOSI)
|
||||
_FL_DEFPIN( 4, 24, 0); // D4 is P0.24 (SPI MISO, also A3)
|
||||
_FL_DEFPIN( 5, 25, 0); // D5 is P0.25 (SPI SCK )
|
||||
_FL_DEFPIN( 6, 16, 0); // D6 is P0.16 (Button)
|
||||
_FL_DEFPIN( 7, 19, 0); // D7 is P0.19 (R)
|
||||
_FL_DEFPIN( 8, 18, 0); // D8 is P0.18 (G)
|
||||
_FL_DEFPIN( 9, 17, 0); // D9 is P0.17 (B)
|
||||
_FL_DEFPIN(10, 11, 0); // D10 is P0.11 (SCL)
|
||||
_FL_DEFPIN(11, 12, 0); // D11 is P0.12 (DRDYn)
|
||||
_FL_DEFPIN(12, 13, 0); // D12 is P0.13 (SDA)
|
||||
_FL_DEFPIN(13, 14, 0); // D13 is P0.17 (INT)
|
||||
_FL_DEFPIN(14, 15, 0); // D14 is P0.15 (INT1)
|
||||
_FL_DEFPIN(15, 20, 0); // D15 is P0.20 (INT2)
|
||||
_FL_DEFPIN(16, 2, 0); // D16 is P0.02 (A0)
|
||||
_FL_DEFPIN(17, 3, 0); // D17 is P0.03 (A1)
|
||||
_FL_DEFPIN(18, 4, 0); // D18 is P0.04 (A2)
|
||||
_FL_DEFPIN(19, 24, 0); // D19 is P0.24 (A3, also D4/SPI MISO) -- is this right?
|
||||
_FL_DEFPIN(20, 29, 0); // D20 is P0.29 (A4)
|
||||
_FL_DEFPIN(21, 30, 0); // D21 is P0.30 (A5)
|
||||
_FL_DEFPIN(22, 31, 0); // D22 is P0.31 (A6)
|
||||
_FL_DEFPIN(23, 8, 0); // D23 is P0.08 (RX)
|
||||
_FL_DEFPIN(24, 6, 0); // D24 is P0.06 (TX)
|
||||
_FL_DEFPIN(25, 5, 0); // D25 is P0.05 (RTS)
|
||||
_FL_DEFPIN(26, 7, 0); // D26 is P0.07 (CTS)
|
||||
#endif // defined(ARDUINO_ELECTRONUT_BLUEY)
|
||||
|
||||
// Electronut labs hackaBLE
|
||||
// See https://github.com/sandeepmistry/arduino-nRF5/blob/master/variants/hackaBLE/variant.cpp
|
||||
#if defined(ARDUINO_ELECTRONUT_HACKABLE)
|
||||
#if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND)
|
||||
#error "Cannot define more than one board at a time"
|
||||
#else
|
||||
#define __FASTPIN_ARM_NRF52_VARIANT_FOUND
|
||||
#endif
|
||||
#warning "Electronut labs hackaBLE is an untested board -- test and let use know your results via https://github.com/FastLED/FastLED/issues"
|
||||
_FL_DEFPIN( 0, 14, 0); // D0 is P0.14 (RX)
|
||||
_FL_DEFPIN( 1, 13, 0); // D1 is P0.13 (TX)
|
||||
_FL_DEFPIN( 2, 12, 0); // D2 is P0.12
|
||||
_FL_DEFPIN( 3, 11, 0); // D3 is P0.11 (SPI MOSI)
|
||||
_FL_DEFPIN( 4, 8, 0); // D4 is P0.08 (SPI MISO)
|
||||
_FL_DEFPIN( 5, 7, 0); // D5 is P0.07 (SPI SCK )
|
||||
_FL_DEFPIN( 6, 6, 0); // D6 is P0.06
|
||||
_FL_DEFPIN( 7, 27, 0); // D7 is P0.27
|
||||
_FL_DEFPIN( 8, 26, 0); // D8 is P0.26
|
||||
_FL_DEFPIN( 9, 25, 0); // D9 is P0.25
|
||||
_FL_DEFPIN(10, 5, 0); // D10 is P0.05 (A3)
|
||||
_FL_DEFPIN(11, 4, 0); // D11 is P0.04 (A2)
|
||||
_FL_DEFPIN(12, 3, 0); // D12 is P0.03 (A1)
|
||||
_FL_DEFPIN(13, 2, 0); // D13 is P0.02 (A0 / AREF)
|
||||
_FL_DEFPIN(14, 23, 0); // D14 is P0.23
|
||||
_FL_DEFPIN(15, 22, 0); // D15 is P0.22
|
||||
_FL_DEFPIN(16, 18, 0); // D16 is P0.18
|
||||
_FL_DEFPIN(17, 16, 0); // D17 is P0.16
|
||||
_FL_DEFPIN(18, 15, 0); // D18 is P0.15
|
||||
_FL_DEFPIN(19, 24, 0); // D19 is P0.24
|
||||
_FL_DEFPIN(20, 28, 0); // D20 is P0.28 (A4)
|
||||
_FL_DEFPIN(21, 29, 0); // D21 is P0.29 (A5)
|
||||
_FL_DEFPIN(22, 30, 0); // D22 is P0.30 (A6)
|
||||
_FL_DEFPIN(23, 31, 0); // D23 is P0.31 (A7)
|
||||
_FL_DEFPIN(24, 19, 0); // D24 is P0.19 (RED LED)
|
||||
_FL_DEFPIN(25, 20, 0); // D25 is P0.20 (GREEN LED)
|
||||
_FL_DEFPIN(26, 17, 0); // D26 is P0.17 (BLUE LED)
|
||||
#endif // defined(ARDUINO_ELECTRONUT_HACKABLE)
|
||||
|
||||
// Electronut labs hackaBLE_v2
|
||||
// See https://github.com/sandeepmistry/arduino-nRF5/blob/master/variants/hackaBLE_v2/variant.cpp
|
||||
// (32 pins, natural mapping)
|
||||
#if defined(ARDUINO_ELECTRONUT_hackaBLE_v2)
|
||||
#if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND)
|
||||
#error "Cannot define more than one board at a time"
|
||||
#else
|
||||
#define __FASTPIN_ARM_NRF52_VARIANT_FOUND
|
||||
#endif
|
||||
#warning "Electronut labs hackaBLE_v2 is an untested board -- test and let use know your results via https://github.com/FastLED/FastLED/issues"
|
||||
_DEFPIN_ARM_IDENTITY_P0( 0); // P0.00
|
||||
_DEFPIN_ARM_IDENTITY_P0( 1); // P0.01
|
||||
_DEFPIN_ARM_IDENTITY_P0( 2); // P0.02 (A0 / SDA / AREF)
|
||||
_DEFPIN_ARM_IDENTITY_P0( 3); // P0.03 (A1 / SCL )
|
||||
_DEFPIN_ARM_IDENTITY_P0( 4); // P0.04 (A2)
|
||||
_DEFPIN_ARM_IDENTITY_P0( 5); // P0.05 (A3)
|
||||
_DEFPIN_ARM_IDENTITY_P0( 6); // P0.06
|
||||
_DEFPIN_ARM_IDENTITY_P0( 7); // P0.07 (RX)
|
||||
_DEFPIN_ARM_IDENTITY_P0( 8); // P0.08 (TX)
|
||||
_DEFPIN_ARM_IDENTITY_P0( 9); // P0.09
|
||||
_DEFPIN_ARM_IDENTITY_P0(10); // P0.10
|
||||
_DEFPIN_ARM_IDENTITY_P0(11); // P0.11 (SPI MISO)
|
||||
_DEFPIN_ARM_IDENTITY_P0(12); // P0.12 (SPI MOSI)
|
||||
_DEFPIN_ARM_IDENTITY_P0(13); // P0.13 (SPI SCK )
|
||||
_DEFPIN_ARM_IDENTITY_P0(14); // P0.14 (SPI SS )
|
||||
_DEFPIN_ARM_IDENTITY_P0(15); // P0.15
|
||||
_DEFPIN_ARM_IDENTITY_P0(16); // P0.16
|
||||
_DEFPIN_ARM_IDENTITY_P0(17); // P0.17 (BLUE LED)
|
||||
_DEFPIN_ARM_IDENTITY_P0(18); // P0.18
|
||||
_DEFPIN_ARM_IDENTITY_P0(19); // P0.19 (RED LED)
|
||||
_DEFPIN_ARM_IDENTITY_P0(20); // P0.20 (GREEN LED)
|
||||
// _DEFPIN_ARM_IDENTITY_P0(21); // P0.21 (RESET)
|
||||
_DEFPIN_ARM_IDENTITY_P0(22); // P0.22
|
||||
_DEFPIN_ARM_IDENTITY_P0(23); // P0.23
|
||||
_DEFPIN_ARM_IDENTITY_P0(24); // P0.24
|
||||
_DEFPIN_ARM_IDENTITY_P0(25); // P0.25
|
||||
_DEFPIN_ARM_IDENTITY_P0(26); // P0.26
|
||||
_DEFPIN_ARM_IDENTITY_P0(27); // P0.27
|
||||
_DEFPIN_ARM_IDENTITY_P0(28); // P0.28 (A4)
|
||||
_DEFPIN_ARM_IDENTITY_P0(29); // P0.29 (A5)
|
||||
_DEFPIN_ARM_IDENTITY_P0(30); // P0.30 (A6)
|
||||
_DEFPIN_ARM_IDENTITY_P0(31); // P0.31 (A7)
|
||||
#endif // defined(ARDUINO_ELECTRONUT_hackaBLE_v2)
|
||||
|
||||
// RedBear Blend 2
|
||||
// See https://github.com/sandeepmistry/arduino-nRF5/blob/master/variants/RedBear_Blend2/variant.cpp
|
||||
#if defined(ARDUINO_RB_BLEND_2)
|
||||
#if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND)
|
||||
#error "Cannot define more than one board at a time"
|
||||
#else
|
||||
#define __FASTPIN_ARM_NRF52_VARIANT_FOUND
|
||||
#endif
|
||||
#warning "RedBear Blend 2 is an untested board -- test and let use know your results via https://github.com/FastLED/FastLED/issues"
|
||||
_FL_DEFPIN( 0, 11, 0); // D0 is P0.11
|
||||
_FL_DEFPIN( 1, 12, 0); // D1 is P0.12
|
||||
_FL_DEFPIN( 2, 13, 0); // D2 is P0.13
|
||||
_FL_DEFPIN( 3, 14, 0); // D3 is P0.14
|
||||
_FL_DEFPIN( 4, 15, 0); // D4 is P0.15
|
||||
_FL_DEFPIN( 5, 16, 0); // D5 is P0.16
|
||||
_FL_DEFPIN( 6, 17, 0); // D6 is P0.17
|
||||
_FL_DEFPIN( 7, 18, 0); // D7 is P0.18
|
||||
_FL_DEFPIN( 8, 19, 0); // D8 is P0.19
|
||||
_FL_DEFPIN( 9, 20, 0); // D9 is P0.20
|
||||
_FL_DEFPIN(10, 22, 0); // D10 is P0.22 (SPI SS )
|
||||
_FL_DEFPIN(11, 23, 0); // D11 is P0.23 (SPI MOSI)
|
||||
_FL_DEFPIN(12, 24, 0); // D12 is P0.24 (SPI MISO)
|
||||
_FL_DEFPIN(13, 25, 0); // D13 is P0.25 (SPI SCK / LED)
|
||||
_FL_DEFPIN(14, 3, 0); // D14 is P0.03 (A0)
|
||||
_FL_DEFPIN(15, 4, 0); // D15 is P0.04 (A1)
|
||||
_FL_DEFPIN(16, 28, 0); // D16 is P0.28 (A2)
|
||||
_FL_DEFPIN(17, 29, 0); // D17 is P0.29 (A3)
|
||||
_FL_DEFPIN(18, 30, 0); // D18 is P0.30 (A4)
|
||||
_FL_DEFPIN(19, 31, 0); // D19 is P0.31 (A5)
|
||||
_FL_DEFPIN(20, 26, 0); // D20 is P0.26 (SDA)
|
||||
_FL_DEFPIN(21, 27, 0); // D21 is P0.27 (SCL)
|
||||
_FL_DEFPIN(22, 8, 0); // D22 is P0.08 (RX)
|
||||
_FL_DEFPIN(23, 6, 0); // D23 is P0.06 (TX)
|
||||
_FL_DEFPIN(24, 2, 0); // D24 is P0.02 (AREF)
|
||||
#endif // defined(ARDUINO_RB_BLEND_2)
|
||||
|
||||
// RedBear BLE Nano 2
|
||||
// See https://github.com/sandeepmistry/arduino-nRF5/blob/master/variants/RedBear_BLENano2/variant.cpp
|
||||
#if defined(ARDUINO_RB_BLE_NANO_2)
|
||||
#if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND)
|
||||
#error "Cannot define more than one board at a time"
|
||||
#else
|
||||
#define __FASTPIN_ARM_NRF52_VARIANT_FOUND
|
||||
#endif
|
||||
#warning "RedBear BLE Nano 2 is an untested board -- test and let use know your results via https://github.com/FastLED/FastLED/issues"
|
||||
_FL_DEFPIN( 0, 30, 0); // D0 is P0.30 (A0 / RX)
|
||||
_FL_DEFPIN( 1, 29, 0); // D1 is P0.29 (A1 / TX)
|
||||
_FL_DEFPIN( 2, 28, 0); // D2 is P0.28 (A2 / SDA)
|
||||
_FL_DEFPIN( 3, 2, 0); // D3 is P0.02 (A3 / SCL)
|
||||
_FL_DEFPIN( 4, 5, 0); // D4 is P0.05 (A4)
|
||||
_FL_DEFPIN( 5, 4, 0); // D5 is P0.04 (A5)
|
||||
_FL_DEFPIN( 6, 3, 0); // D6 is P0.03 (SPI SS )
|
||||
_FL_DEFPIN( 7, 6, 0); // D7 is P0.06 (SPI MOSI)
|
||||
_FL_DEFPIN( 8, 7, 0); // D8 is P0.07 (SPI MISO)
|
||||
_FL_DEFPIN( 9, 8, 0); // D9 is P0.08 (SPI SCK )
|
||||
// _FL_DEFPIN(10, 21, 0); // D10 is P0.21 (RESET)
|
||||
_FL_DEFPIN(13, 11, 0); // D11 is P0.11 (LED)
|
||||
#endif // defined(ARDUINO_RB_BLE_NANO_2)
|
||||
|
||||
// Nordic Semiconductor nRF52 DK
|
||||
// See https://github.com/sandeepmistry/arduino-nRF5/blob/master/variants/nRF52DK/variant.cpp
|
||||
#if defined(ARDUINO_NRF52_DK)
|
||||
#if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND)
|
||||
#error "Cannot define more than one board at a time"
|
||||
#else
|
||||
#define __FASTPIN_ARM_NRF52_VARIANT_FOUND
|
||||
#endif
|
||||
#warning "Nordic Semiconductor nRF52 DK is an untested board -- test and let use know your results via https://github.com/FastLED/FastLED/issues"
|
||||
_FL_DEFPIN( 0, 11, 0); // D0 is P0.11
|
||||
_FL_DEFPIN( 1, 12, 0); // D1 is P0.12
|
||||
_FL_DEFPIN( 2, 13, 0); // D2 is P0.13 (BUTTON1)
|
||||
_FL_DEFPIN( 3, 14, 0); // D3 is P0.14 (BUTTON2)
|
||||
_FL_DEFPIN( 4, 15, 0); // D4 is P0.15 (BUTTON3)
|
||||
_FL_DEFPIN( 5, 16, 0); // D5 is P0.16 (BUTTON4)
|
||||
_FL_DEFPIN( 6, 17, 0); // D6 is P0.17 (LED1)
|
||||
_FL_DEFPIN( 7, 18, 0); // D7 is P0.18 (LED2)
|
||||
_FL_DEFPIN( 8, 19, 0); // D8 is P0.19 (LED3)
|
||||
_FL_DEFPIN( 9, 20, 0); // D9 is P0.20 (LED4)
|
||||
_FL_DEFPIN(10, 22, 0); // D10 is P0.22 (SPI SS )
|
||||
_FL_DEFPIN(11, 23, 0); // D11 is P0.23 (SPI MOSI)
|
||||
_FL_DEFPIN(12, 24, 0); // D12 is P0.24 (SPI MISO)
|
||||
_FL_DEFPIN(13, 25, 0); // D13 is P0.25 (SPI SCK / LED)
|
||||
_FL_DEFPIN(14, 3, 0); // D14 is P0.03 (A0)
|
||||
_FL_DEFPIN(15, 4, 0); // D15 is P0.04 (A1)
|
||||
_FL_DEFPIN(16, 28, 0); // D16 is P0.28 (A2)
|
||||
_FL_DEFPIN(17, 29, 0); // D17 is P0.29 (A3)
|
||||
_FL_DEFPIN(18, 30, 0); // D18 is P0.30 (A4)
|
||||
_FL_DEFPIN(19, 31, 0); // D19 is P0.31 (A5)
|
||||
_FL_DEFPIN(20, 5, 0); // D20 is P0.05 (A6)
|
||||
_FL_DEFPIN(21, 2, 0); // D21 is P0.02 (A7 / AREF)
|
||||
_FL_DEFPIN(22, 26, 0); // D22 is P0.26 (SDA)
|
||||
_FL_DEFPIN(23, 27, 0); // D23 is P0.27 (SCL)
|
||||
_FL_DEFPIN(24, 8, 0); // D24 is P0.08 (RX)
|
||||
_FL_DEFPIN(25, 6, 0); // D25 is P0.06 (TX)
|
||||
#endif // defined(ARDUINO_NRF52_DK)
|
||||
|
||||
// Taida Century nRF52 mini board
|
||||
// https://github.com/sandeepmistry/arduino-nRF5/blob/master/variants/Taida_Century_nRF52_minidev/variant.cpp
|
||||
#if defined(ARDUINO_STCT_NRF52_minidev)
|
||||
#if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND)
|
||||
#error "Cannot define more than one board at a time"
|
||||
#else
|
||||
#define __FASTPIN_ARM_NRF52_VARIANT_FOUND
|
||||
#endif
|
||||
#warning "Taida Century nRF52 mini board is an untested board -- test and let use know your results via https://github.com/FastLED/FastLED/issues"
|
||||
//_FL_DEFPIN( 0, 25, 0); // D0 is P0.xx (near radio!)
|
||||
//_FL_DEFPIN( 1, 26, 0); // D1 is P0.xx (near radio!)
|
||||
//_FL_DEFPIN( 2, 27, 0); // D2 is P0.xx (near radio!)
|
||||
//_FL_DEFPIN( 3, 28, 0); // D3 is P0.xx (near radio!)
|
||||
//_FL_DEFPIN( 4, 29, 0); // D4 is P0.xx (Not connected, near radio!)
|
||||
//_FL_DEFPIN( 5, 30, 0); // D5 is P0.xx (LED1, near radio!)
|
||||
//_FL_DEFPIN( 6, 31, 0); // D6 is P0.xx (LED2, near radio!)
|
||||
_FL_DEFPIN( 7, 2, 0); // D7 is P0.xx (SDA)
|
||||
_FL_DEFPIN( 8, 3, 0); // D8 is P0.xx (SCL)
|
||||
_FL_DEFPIN( 9, 4, 0); // D9 is P0.xx (BUTTON1 / NFC1)
|
||||
_FL_DEFPIN(10, 5, 0); // D10 is P0.xx
|
||||
//_FL_DEFPIN(11, 0, 0); // D11 is P0.xx (Not connected)
|
||||
//_FL_DEFPIN(12, 1, 0); // D12 is P0.xx (Not connected)
|
||||
_FL_DEFPIN(13, 6, 0); // D13 is P0.xx
|
||||
_FL_DEFPIN(14, 7, 0); // D14 is P0.xx
|
||||
_FL_DEFPIN(15, 8, 0); // D15 is P0.xx
|
||||
//_FL_DEFPIN(16, 9, 0); // D16 is P0.xx (Not connected)
|
||||
//_FL_DEFPIN(17, 10, 0); // D17 is P0.xx (NFC2, Not connected)
|
||||
_FL_DEFPIN(18, 11, 0); // D18 is P0.xx (RXD)
|
||||
_FL_DEFPIN(19, 12, 0); // D19 is P0.xx (TXD)
|
||||
_FL_DEFPIN(20, 13, 0); // D20 is P0.xx (SPI SS )
|
||||
_FL_DEFPIN(21, 14, 0); // D21 is P0.xx (SPI MISO)
|
||||
_FL_DEFPIN(22, 15, 0); // D22 is P0.xx (SPI MOSI)
|
||||
_FL_DEFPIN(23, 16, 0); // D23 is P0.xx (SPI SCK )
|
||||
_FL_DEFPIN(24, 17, 0); // D24 is P0.xx (A0)
|
||||
_FL_DEFPIN(25, 18, 0); // D25 is P0.xx (A1)
|
||||
_FL_DEFPIN(26, 19, 0); // D26 is P0.xx (A2)
|
||||
_FL_DEFPIN(27, 20, 0); // D27 is P0.xx (A3)
|
||||
//_FL_DEFPIN(28, 22, 0); // D28 is P0.xx (A4, near radio!)
|
||||
//_FL_DEFPIN(29, 23, 0); // D29 is P0.xx (A5, near radio!)
|
||||
_FL_DEFPIN(30, 24, 0); // D30 is P0.xx
|
||||
// _FL_DEFPIN(31, 21, 0); // D31 is P0.21 (RESET)
|
||||
#endif // defined(ARDUINO_STCT_NRF52_minidev)
|
||||
|
||||
// Generic nRF52832
|
||||
// See https://github.com/sandeepmistry/arduino-nRF5/blob/master/boards.txt
|
||||
#if defined(ARDUINO_GENERIC) && (\
|
||||
defined(NRF52832_XXAA) || defined(NRF52832_XXAB)\
|
||||
)
|
||||
#if defined(__FASTPIN_ARM_NRF52_VARIANT_FOUND)
|
||||
#error "Cannot define more than one board at a time"
|
||||
#else
|
||||
#define __FASTPIN_ARM_NRF52_VARIANT_FOUND
|
||||
#endif
|
||||
#warning "Using `generic` NRF52832 board is an untested configuration -- test and let use know your results via https://github.com/FastLED/FastLED/issues"
|
||||
|
||||
_DEFPIN_ARM_IDENTITY_P0( 0); // P0.00 ( UART RX
|
||||
_DEFPIN_ARM_IDENTITY_P0( 1); // P0.01 (A0, UART TX)
|
||||
_DEFPIN_ARM_IDENTITY_P0( 2); // P0.02 (A1)
|
||||
_DEFPIN_ARM_IDENTITY_P0( 3); // P0.03 (A2)
|
||||
_DEFPIN_ARM_IDENTITY_P0( 4); // P0.04 (A3)
|
||||
_DEFPIN_ARM_IDENTITY_P0( 5); // P0.05 (A4)
|
||||
_DEFPIN_ARM_IDENTITY_P0( 6); // P0.06 (A5)
|
||||
_DEFPIN_ARM_IDENTITY_P0( 7); // P0.07
|
||||
_DEFPIN_ARM_IDENTITY_P0( 8); // P0.08
|
||||
_DEFPIN_ARM_IDENTITY_P0( 9); // P0.09
|
||||
_DEFPIN_ARM_IDENTITY_P0(10); // P0.10
|
||||
_DEFPIN_ARM_IDENTITY_P0(11); // P0.11
|
||||
_DEFPIN_ARM_IDENTITY_P0(12); // P0.12
|
||||
_DEFPIN_ARM_IDENTITY_P0(13); // P0.13 (LED)
|
||||
_DEFPIN_ARM_IDENTITY_P0(14); // P0.14
|
||||
_DEFPIN_ARM_IDENTITY_P0(15); // P0.15
|
||||
_DEFPIN_ARM_IDENTITY_P0(16); // P0.16
|
||||
_DEFPIN_ARM_IDENTITY_P0(17); // P0.17
|
||||
_DEFPIN_ARM_IDENTITY_P0(18); // P0.18
|
||||
_DEFPIN_ARM_IDENTITY_P0(19); // P0.19
|
||||
_DEFPIN_ARM_IDENTITY_P0(20); // P0.20 (I2C SDA)
|
||||
_DEFPIN_ARM_IDENTITY_P0(21); // P0.21 (I2C SCL)
|
||||
_DEFPIN_ARM_IDENTITY_P0(22); // P0.22 (SPI MISO)
|
||||
_DEFPIN_ARM_IDENTITY_P0(23); // P0.23 (SPI MOSI)
|
||||
_DEFPIN_ARM_IDENTITY_P0(24); // P0.24 (SPI SCK )
|
||||
_DEFPIN_ARM_IDENTITY_P0(25); // P0.25 (SPI SS )
|
||||
_DEFPIN_ARM_IDENTITY_P0(26); // P0.26
|
||||
_DEFPIN_ARM_IDENTITY_P0(27); // P0.27
|
||||
_DEFPIN_ARM_IDENTITY_P0(28); // P0.28
|
||||
_DEFPIN_ARM_IDENTITY_P0(29); // P0.29
|
||||
_DEFPIN_ARM_IDENTITY_P0(30); // P0.30
|
||||
_DEFPIN_ARM_IDENTITY_P0(31); // P0.31
|
||||
#endif // defined(ARDUINO_GENERIC)
|
||||
|
||||
|
||||
#endif // __FASTPIN_ARM_NRF52_VARIANTS_H
|
@ -0,0 +1,341 @@
|
||||
#ifndef __FASTSPI_ARM_NRF52_H
|
||||
#define __FASTSPI_ARM_NRF52_H
|
||||
|
||||
|
||||
#ifndef FASTLED_FORCE_SOFTWARE_SPI
|
||||
|
||||
#include <nrf_spim.h>
|
||||
|
||||
#define FASTLED_ALL_PINS_HARDWARE_SPI
|
||||
|
||||
|
||||
// NRF52810 has SPIM0: Frequencies from 125kbps to 8Mbps
|
||||
// NRF52832 adds SPIM1, SPIM2 (same frequencies)
|
||||
// NRF52840 adds SPIM3 (same frequencies), adds SPIM3 that can be @ up to 32Mbps frequency(!)
|
||||
#if !defined(FASTLED_NRF52_SPIM)
|
||||
#define FASTLED_NRF52_SPIM NRF_SPIM0
|
||||
#endif
|
||||
|
||||
/* This class is slightly simpler than fastpin, as it can rely on fastpin
|
||||
* to handle the mapping to the underlying PN.XX board-level pins...
|
||||
*/
|
||||
|
||||
/// SPI_CLOCK_DIVIDER is number of CPU clock cycles per SPI transmission bit?
|
||||
template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER>
|
||||
class NRF52SPIOutput {
|
||||
|
||||
private:
|
||||
// static variables -- always using same SPIM instance
|
||||
static bool s_InUse;
|
||||
static bool s_NeedToWait; // a data transfer was started, and completion event was not cleared.
|
||||
|
||||
/*
|
||||
// TODO -- Workaround nRF52840 errata #198, which relates to
|
||||
// contention between SPIM3 and CPU over AHB.
|
||||
// The workaround is to ensure the SPIM TX buffer
|
||||
// is on a different / dedicated RAM block.
|
||||
// This also avoids AHB contention generally, so
|
||||
// should be applied to all supported boards.
|
||||
//
|
||||
// But... how to allocate m_Buffer[] to be at a
|
||||
// specific memory range? Also, might need to
|
||||
// avoid use of single-transaction writeBytes()
|
||||
// as cannot control where that memory lies....
|
||||
*/
|
||||
static uint8_t s_BufferIndex;
|
||||
static uint8_t s_Buffer[2][2]; // 2x two-byte buffers, allows one buffer currently being sent, and a second one being prepped to send.
|
||||
|
||||
// This allows saving the configuration of the SPIM instance
|
||||
// upon select(), and restoring the configuration upon release().
|
||||
struct spim_config {
|
||||
uint32_t inten;
|
||||
uint32_t shorts;
|
||||
uint32_t sck_pin;
|
||||
uint32_t mosi_pin;
|
||||
uint32_t miso_pin;
|
||||
uint32_t frequency;
|
||||
// data pointers, RX/TX counts not saved as would only hide bugs
|
||||
uint32_t config; // mode & bit order
|
||||
uint32_t orc;
|
||||
|
||||
#if false // additional configuration to save/restore for SPIM3
|
||||
uint32_t csn_pin;
|
||||
uint32_t csn_polarity; // CSNPOL
|
||||
uint32_t csn_duration; // IFTIMING.CSNDUR
|
||||
uint32_t rx_delay; // IFTIMING.RXDELAY
|
||||
uint32_t dcx_pin; // PSELDCX
|
||||
uint32_t dcx_config; // DCXCNT
|
||||
#endif
|
||||
|
||||
} m_SpiSavedConfig;
|
||||
void saveSpimConfig() {
|
||||
m_SpiSavedConfig.inten = FASTLED_NRF52_SPIM->INTENSET;
|
||||
m_SpiSavedConfig.shorts = FASTLED_NRF52_SPIM->SHORTS;
|
||||
m_SpiSavedConfig.sck_pin = FASTLED_NRF52_SPIM->PSEL.SCK;
|
||||
m_SpiSavedConfig.mosi_pin = FASTLED_NRF52_SPIM->PSEL.MOSI;
|
||||
m_SpiSavedConfig.miso_pin = FASTLED_NRF52_SPIM->PSEL.MISO;
|
||||
m_SpiSavedConfig.frequency = FASTLED_NRF52_SPIM->FREQUENCY;
|
||||
m_SpiSavedConfig.config = FASTLED_NRF52_SPIM->CONFIG;
|
||||
m_SpiSavedConfig.orc = FASTLED_NRF52_SPIM->ORC;
|
||||
|
||||
#if false // additional configuration to save/restore for SPIM3
|
||||
m_SpiSavedConfig.csn_pin = FASTLED_NRF52_SPIM->PSEL.CSN;
|
||||
m_SpiSavedConfig.csn_polarity = FASTLED_NRF52_SPIM->CSNPOL;
|
||||
m_SpiSavedConfig.csn_duration = FASTLED_NRF52_SPIM->IFTIMING.CSNDUR;
|
||||
m_SpiSavedConfig.dcx_pin = FASTLED_NRF52_SPIM->PSELDCX;
|
||||
m_SpiSavedConfig.dcx_config = FASTLED_NRF52_SPIM->DCXCNT;
|
||||
#endif
|
||||
}
|
||||
void restoreSpimConfig() {
|
||||
// 0. ASSERT() the SPIM instance is not enabled
|
||||
|
||||
FASTLED_NRF52_SPIM->INTENCLR = 0xFFFFFFFF;
|
||||
FASTLED_NRF52_SPIM->INTENSET = m_SpiSavedConfig.inten;
|
||||
FASTLED_NRF52_SPIM->SHORTS = m_SpiSavedConfig.shorts;
|
||||
FASTLED_NRF52_SPIM->PSEL.SCK = m_SpiSavedConfig.sck_pin;
|
||||
FASTLED_NRF52_SPIM->PSEL.MOSI = m_SpiSavedConfig.mosi_pin;
|
||||
FASTLED_NRF52_SPIM->PSEL.MISO = m_SpiSavedConfig.miso_pin;
|
||||
FASTLED_NRF52_SPIM->FREQUENCY = m_SpiSavedConfig.frequency;
|
||||
FASTLED_NRF52_SPIM->CONFIG = m_SpiSavedConfig.config;
|
||||
FASTLED_NRF52_SPIM->ORC = m_SpiSavedConfig.orc;
|
||||
|
||||
#if false // additional configuration to save/restore for SPIM3
|
||||
FASTLED_NRF52_SPIM->PSEL.CSN = m_SpiSavedConfig.csn_pin;
|
||||
FASTLED_NRF52_SPIM->CSNPOL = m_SpiSavedConfig.csn_polarity;
|
||||
FASTLED_NRF52_SPIM->IFTIMING.CSNDUR = m_SpiSavedConfig.csn_duration;
|
||||
FASTLED_NRF52_SPIM->PSELDCX = m_SpiSavedConfig.dcx_pin;
|
||||
FASTLED_NRF52_SPIM->DCXCNT = m_SpiSavedConfig.dcx_config;
|
||||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
NRF52SPIOutput() {}
|
||||
|
||||
// Low frequency GPIO is for signals with a frequency up to 10 kHz. Lowest speed SPIM is 125kbps.
|
||||
static_assert(!FastPin<_DATA_PIN>::LowSpeedOnlyRecommended(), "Invalid (low-speed only) pin specified");
|
||||
static_assert(!FastPin<_CLOCK_PIN>::LowSpeedOnlyRecommended(), "Invalid (low-speed only) pin specified");
|
||||
|
||||
/// initialize the SPI subssytem
|
||||
void init() {
|
||||
// 0. ASSERT() the SPIM instance is not enabled / in use
|
||||
//ASSERT(m_SPIM->ENABLE != (SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos));
|
||||
|
||||
// 1. set pins to output/H0H1 drive/etc.
|
||||
FastPin<_DATA_PIN>::setOutput();
|
||||
FastPin<_CLOCK_PIN>::setOutput();
|
||||
|
||||
// 2. Configure SPIMx
|
||||
nrf_spim_configure(
|
||||
FASTLED_NRF52_SPIM,
|
||||
NRF_SPIM_MODE_0,
|
||||
NRF_SPIM_BIT_ORDER_MSB_FIRST
|
||||
);
|
||||
nrf_spim_frequency_set(
|
||||
FASTLED_NRF52_SPIM,
|
||||
NRF_SPIM_FREQ_4M // BUGBUG -- use _SPI_CLOCK_DIVIDER to determine frequency
|
||||
);
|
||||
nrf_spim_pins_set(
|
||||
FASTLED_NRF52_SPIM,
|
||||
FastPin<_CLOCK_PIN>::nrf_pin(),
|
||||
FastPin<_DATA_PIN>::nrf_pin(),
|
||||
NRF_SPIM_PIN_NOT_CONNECTED
|
||||
);
|
||||
|
||||
// 4. Ensure events are cleared
|
||||
nrf_spim_event_clear(FASTLED_NRF52_SPIM, NRF_SPIM_EVENT_END);
|
||||
nrf_spim_event_clear(FASTLED_NRF52_SPIM, NRF_SPIM_EVENT_STARTED);
|
||||
|
||||
// 5. Enable the SPIM instance
|
||||
nrf_spim_enable(FASTLED_NRF52_SPIM);
|
||||
}
|
||||
|
||||
/// latch the CS select
|
||||
void select() {
|
||||
//ASSERT(!s_InUse);
|
||||
saveSpimConfig();
|
||||
s_InUse = true;
|
||||
init();
|
||||
}
|
||||
|
||||
/// release the CS select
|
||||
void release() {
|
||||
//ASSERT(s_InUse);
|
||||
waitFully();
|
||||
s_InUse = false;
|
||||
restoreSpimConfig();
|
||||
}
|
||||
|
||||
/// wait until all queued up data has been written
|
||||
static void waitFully() {
|
||||
if (!s_NeedToWait) return;
|
||||
// else, need to wait for END event
|
||||
while(!FASTLED_NRF52_SPIM->EVENTS_END) {};
|
||||
s_NeedToWait = 0;
|
||||
// only use two events in this code...
|
||||
nrf_spim_event_clear(FASTLED_NRF52_SPIM, NRF_SPIM_EVENT_END);
|
||||
nrf_spim_event_clear(FASTLED_NRF52_SPIM, NRF_SPIM_EVENT_STARTED);
|
||||
return;
|
||||
}
|
||||
// wait only until we can add a new transaction into the registers
|
||||
// (caller must still waitFully() before actually starting this next transaction)
|
||||
static void wait() {
|
||||
if (!s_NeedToWait) return;
|
||||
while (!FASTLED_NRF52_SPIM->EVENTS_STARTED) {};
|
||||
// leave the event set here... caller must waitFully() and start next transaction
|
||||
return;
|
||||
}
|
||||
|
||||
/// write a byte out via SPI (returns immediately on writing register)
|
||||
static void writeByte(uint8_t b) {
|
||||
wait();
|
||||
// cannot use pointer to stack, so copy to m_buffer[]
|
||||
uint8_t i = (s_BufferIndex ? 1u : 0u);
|
||||
s_BufferIndex = !s_BufferIndex; // 1 <==> 0 swap
|
||||
|
||||
s_Buffer[i][0u] = b; // cannot use the stack location, so copy to a more permanent buffer...
|
||||
nrf_spim_tx_buffer_set(
|
||||
FASTLED_NRF52_SPIM,
|
||||
&(s_Buffer[i][0u]),
|
||||
1
|
||||
);
|
||||
|
||||
waitFully();
|
||||
nrf_spim_task_trigger(
|
||||
FASTLED_NRF52_SPIM,
|
||||
NRF_SPIM_TASK_START
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/// write a word out via SPI (returns immediately on writing register)
|
||||
static void writeWord(uint16_t w) {
|
||||
wait();
|
||||
// cannot use pointer to stack, so copy to m_buffer[]
|
||||
uint8_t i = (s_BufferIndex ? 1u : 0u);
|
||||
s_BufferIndex = !s_BufferIndex; // 1 <==> 0 swap
|
||||
|
||||
s_Buffer[i][0u] = (w >> 8u); // cannot use the stack location, so copy to a more permanent buffer...
|
||||
s_Buffer[i][1u] = (w & 0xFFu); // cannot use the stack location, so copy to a more permanent buffer...
|
||||
nrf_spim_tx_buffer_set(
|
||||
FASTLED_NRF52_SPIM,
|
||||
&(s_Buffer[i][0u]),
|
||||
2
|
||||
);
|
||||
|
||||
waitFully();
|
||||
nrf_spim_task_trigger(
|
||||
FASTLED_NRF52_SPIM,
|
||||
NRF_SPIM_TASK_START
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/// A raw set of writing byte values, assumes setup/init/waiting done elsewhere (static for use by adjustment classes)
|
||||
static void writeBytesValueRaw(uint8_t value, int len) {
|
||||
while (len--) { writeByte(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);
|
||||
waitFully();
|
||||
release();
|
||||
}
|
||||
|
||||
/// A full cycle of writing a raw block of data out, including select, release, and waiting
|
||||
void writeBytes(uint8_t *data, int len) {
|
||||
// This is a special-case, with no adjustment of the bytes... write them directly...
|
||||
select();
|
||||
wait();
|
||||
nrf_spim_tx_buffer_set(
|
||||
FASTLED_NRF52_SPIM,
|
||||
data,
|
||||
len
|
||||
);
|
||||
waitFully();
|
||||
nrf_spim_task_trigger(
|
||||
FASTLED_NRF52_SPIM,
|
||||
NRF_SPIM_TASK_START
|
||||
);
|
||||
waitFully();
|
||||
release();
|
||||
}
|
||||
|
||||
/// A full cycle of writing a raw block of data out, including select, release, and waiting
|
||||
template<class D> void writeBytes(uint8_t *data, int len) {
|
||||
uint8_t * end = data + len;
|
||||
select();
|
||||
wait();
|
||||
while(data != end) {
|
||||
writeByte(D::adjust(*data++));
|
||||
}
|
||||
D::postBlock(len);
|
||||
waitFully();
|
||||
release();
|
||||
}
|
||||
/// specialization for DATA_NOP ...
|
||||
//template<DATA_NOP> void writeBytes(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 <uint8_t BIT> inline static void writeBit(uint8_t b) {
|
||||
// SPIM instance must be finished transmitting and then disabled
|
||||
waitFully();
|
||||
nrf_spim_disable(FASTLED_NRF52_SPIM);
|
||||
// set the data pin to appropriate state
|
||||
if (b & (1 << BIT)) {
|
||||
FastPin<_DATA_PIN>::hi();
|
||||
} else {
|
||||
FastPin<_DATA_PIN>::lo();
|
||||
}
|
||||
// delay 1/2 cycle per SPI bit
|
||||
delaycycles<_SPI_CLOCK_DIVIDER/2>();
|
||||
FastPin<_CLOCK_PIN>::toggle();
|
||||
delaycycles<_SPI_CLOCK_DIVIDER/2>();
|
||||
FastPin<_CLOCK_PIN>::toggle();
|
||||
// re-enable the SPIM instance
|
||||
nrf_spim_enable(FASTLED_NRF52_SPIM);
|
||||
}
|
||||
|
||||
/// write out pixel data from the given PixelController object, including select, release, and waiting
|
||||
template <uint8_t FLAGS, class D, EOrder RGB_ORDER> void writePixels(PixelController<RGB_ORDER> pixels) {
|
||||
select();
|
||||
int len = pixels.mLen;
|
||||
// TODO: If user indicates a pre-allocated double-buffer,
|
||||
// then process all the pixels at once into that buffer,
|
||||
// then use the non-templated WriteBytes(data, len) function
|
||||
// to write the entire buffer as a single SPI transaction.
|
||||
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);
|
||||
waitFully();
|
||||
release();
|
||||
}
|
||||
};
|
||||
|
||||
// Static member definition and initialization using templates.
|
||||
// see https://stackoverflow.com/questions/3229883/static-member-initialization-in-a-class-template#answer-3229919
|
||||
template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER>
|
||||
bool NRF52SPIOutput<_DATA_PIN, _CLOCK_PIN, _SPI_CLOCK_DIVIDER>::s_InUse = false;
|
||||
template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER>
|
||||
bool NRF52SPIOutput<_DATA_PIN, _CLOCK_PIN, _SPI_CLOCK_DIVIDER>::s_NeedToWait = false;
|
||||
template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER>
|
||||
uint8_t NRF52SPIOutput<_DATA_PIN, _CLOCK_PIN, _SPI_CLOCK_DIVIDER>::s_BufferIndex = 0;
|
||||
template <uint8_t _DATA_PIN, uint8_t _CLOCK_PIN, uint32_t _SPI_CLOCK_DIVIDER>
|
||||
uint8_t NRF52SPIOutput<_DATA_PIN, _CLOCK_PIN, _SPI_CLOCK_DIVIDER>::s_Buffer[2][2] = {{0,0},{0,0}};
|
||||
|
||||
#endif // #ifndef FASTLED_FORCE_SOFTWARE_SPI
|
||||
|
||||
|
||||
|
||||
#endif // #ifndef __FASTPIN_ARM_NRF52_H
|
@ -0,0 +1,58 @@
|
||||
#ifndef __LED_SYSDEFS_ARM_NRF52
|
||||
#define __LED_SYSDEFS_ARM_NRF52
|
||||
|
||||
#define FASTLED_ARM
|
||||
|
||||
#ifndef F_CPU
|
||||
#define F_CPU 64000000 // the NRF52 series has a 64MHz CPU
|
||||
#endif
|
||||
|
||||
// even though CPU is at 64MHz, use the 8MHz-defined timings because...
|
||||
// PWM module runs at 16MHz
|
||||
// SPI0..2 runs at 8MHz
|
||||
#define CLOCKLESS_FREQUENCY 16000000 // the NRF52 has EasyDMA for PWM module at 16MHz
|
||||
|
||||
#ifndef F_TIMER
|
||||
#define F_TIMER 16000000 // the NRF52 timer is 16MHz, even though CPU is 64MHz
|
||||
#endif
|
||||
|
||||
#if !defined(FASTLED_USE_PROGMEM)
|
||||
#define FASTLED_USE_PROGMEM 0 // nRF52 series have flat memory model
|
||||
#endif
|
||||
|
||||
#if !defined(FASTLED_ALLOW_INTERRUPTS)
|
||||
#define FASTLED_ALLOW_INTERRUPTS 1
|
||||
#endif
|
||||
|
||||
// Use PWM instance 0
|
||||
// See clockless_arm_nrf52.h and (in root of library) platforms.cpp
|
||||
#define FASTLED_NRF52_ENABLE_PWM_INSTANCE0
|
||||
|
||||
#if defined(FASTLED_NRF52_NEVER_INLINE)
|
||||
#define FASTLED_NRF52_INLINE_ATTRIBUTE __attribute__((always_inline)) inline
|
||||
#else
|
||||
#define FASTLED_NRF52_INLINE_ATTRIBUTE __attribute__((always_inline)) inline
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#include <nrf.h>
|
||||
#include <nrf_spim.h> // for FastSPI
|
||||
#include <nrf_pwm.h> // for Clockless
|
||||
#include <nrf_nvic.h> // for Clockless / anything else using interrupts
|
||||
typedef __I uint32_t RoReg;
|
||||
typedef __IO uint32_t RwReg;
|
||||
|
||||
#define cli() __disable_irq()
|
||||
#define sei() __enable_irq()
|
||||
|
||||
#define FASTLED_NRF52_DEBUGPRINT(format, ...)
|
||||
//#define FASTLED_NRF52_DEBUGPRINT(format, ...)\
|
||||
// do {\
|
||||
// FastLED_NRF52_DebugPrint(format, ##__VA_ARGS__);\
|
||||
// } while(0);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // __LED_SYSDEFS_ARM_NRF52
|
Reference in New Issue
Block a user