Krolyxon
Commit 3120783

Branches

Tags

Refs →

orion-rf.piolibdepsesp32-s3-n16r8Adafruit NeoPixelAdafruit_NeoPixel.cpp

3815 lines · 143 KB · C++

1/*!
2 * @file Adafruit_NeoPixel.cpp
3 *
4 * @mainpage Arduino Library for driving Adafruit NeoPixel addressable LEDs,
5 * FLORA RGB Smart Pixels and compatible devicess -- WS2811, WS2812, WS2812B,
6 * SK6812, etc.
7 *
8 * @section intro_sec Introduction
9 *
10 * This is the documentation for Adafruit's NeoPixel library for the
11 * Arduino platform, allowing a broad range of microcontroller boards
12 * (most AVR boards, many ARM devices, ESP8266 and ESP32, among others)
13 * to control Adafruit NeoPixels, FLORA RGB Smart Pixels and compatible
14 * devices -- WS2811, WS2812, WS2812B, SK6812, etc.
15 *
16 * Adafruit invests time and resources providing this open source code,
17 * please support Adafruit and open-source hardware by purchasing products
18 * from Adafruit!
19 *
20 * @section author Author
21 *
22 * Written by Phil "Paint Your Dragon" Burgess for Adafruit Industries,
23 * with contributions by PJRC, Michael Miller and other members of the
24 * open source community.
25 * Minor change in timing for CH32 @48MHz by Maxint-RD 20260126.
26 *
27 * @section license License
28 *
29 * This file is part of the Adafruit_NeoPixel library.
30 *
31 * Adafruit_NeoPixel is free software: you can redistribute it and/or
32 * modify it under the terms of the GNU Lesser General Public License as
33 * published by the Free Software Foundation, either version 3 of the
34 * License, or (at your option) any later version.
35 *
36 * Adafruit_NeoPixel is distributed in the hope that it will be useful,
37 * but WITHOUT ANY WARRANTY; without even the implied warranty of
38 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39 * GNU Lesser General Public License for more details.
40 *
41 * You should have received a copy of the GNU Lesser General Public
42 * License along with NeoPixel. If not, see
43 * <http://www.gnu.org/licenses/>.
44 *
45 */
46
47#include "Adafruit_NeoPixel.h"
48
49#if defined(TARGET_LPC1768)
50#include <time.h>
51#endif
52
53#if defined(NRF52) || defined(NRF52_SERIES)
54#include "nrf.h"
55
56// Interrupt is only disabled if there is no PWM device available
57// Note: Adafruit Bluefruit nrf52 does not use this option
58// #define NRF52_DISABLE_INT
59#endif
60
61#if defined(ARDUINO_ARCH_NRF52840)
62#if defined __has_include
63#if __has_include(<pinDefinitions.h>)
64#include <pinDefinitions.h>
65#endif
66#endif
67#endif
68
69#if defined(ARDUINO_ARCH_MBED)
70#include "mbed.h" // Needed for DigitalOut and PinName
71#endif
72
73/*!
74 @brief NeoPixel constructor when length, pin and pixel type are known
75 at compile-time.
76 @param n Number of NeoPixels in strand.
77 @param p Arduino pin number which will drive the NeoPixel data in.
78 @param t Pixel type -- add together NEO_* constants defined in
79 Adafruit_NeoPixel.h, for example NEO_GRB+NEO_KHZ800 for
80 NeoPixels expecting an 800 KHz (vs 400 KHz) data stream
81 with color bytes expressed in green, red, blue order per
82 pixel.
83 @return Adafruit_NeoPixel object. Call the begin() function before use.
84*/
85Adafruit_NeoPixel::Adafruit_NeoPixel(uint16_t n, int16_t p, neoPixelType t)
86 : begun(false), brightness(0), pixels(NULL), endTime(0) {
87 updateType(t);
88 updateLength(n);
89 setPin(p);
90
91#if defined(ESP32)
92#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
93 espInit();
94#endif
95#endif
96}
97
98/*!
99 @brief "Empty" NeoPixel constructor when length, pin and/or pixel type
100 are not known at compile-time, and must be initialized later with
101 updateType(), updateLength() and setPin().
102 @return Adafruit_NeoPixel object. Call the begin() function before use.
103 @note This function is deprecated, here only for old projects that
104 may still be calling it. New projects should instead use the
105 'new' keyword with the first constructor syntax (length, pin,
106 type).
107*/
108Adafruit_NeoPixel::Adafruit_NeoPixel()
109 :
110#if defined(NEO_KHZ400)
111 is800KHz(true),
112#endif
113 begun(false), numLEDs(0), numBytes(0), pin(-1), brightness(0),
114 pixels(NULL), rOffset(1), gOffset(0), bOffset(2), wOffset(1), endTime(0) {
115}
116
117/*!
118 @brief Deallocate Adafruit_NeoPixel object, set data pin back to INPUT.
119*/
120Adafruit_NeoPixel::~Adafruit_NeoPixel() {
121#ifdef ARDUINO_ARCH_ESP32
122 // Release RMT resources (RMT channels and led_data)
123 // by indirectly calling into espShow()
124 memset(pixels, 0, numBytes);
125 numLEDs = numBytes = 0;
126 show();
127#endif
128
129#if defined(ARDUINO_ARCH_RP2040)
130 // Release any PIO
131 rp2040releasePIO();
132#endif
133
134 free(pixels);
135 if (pin >= 0)
136 pinMode(pin, INPUT);
137}
138
139/*!
140 @brief Configure NeoPixel pin for output.
141 @returns False if we weren't able to claim resources required
142*/
143bool Adafruit_NeoPixel::begin(void) {
144 if (pin >= 0) {
145 pinMode(pin, OUTPUT);
146 digitalWrite(pin, LOW);
147 } else {
148 begun = false;
149 return false;
150 }
151
152#if defined(ARDUINO_ARCH_RP2040)
153 // if we're calling begin() again, unclaim any existing PIO resc.
154 rp2040releasePIO();
155 if (!rp2040claimPIO()) {
156 begun = false;
157 return false;
158 }
159
160#endif
161
162 begun = true;
163 return true;
164}
165
166/*!
167 @brief Change the length of a previously-declared Adafruit_NeoPixel
168 strip object. Old data is deallocated and new data is cleared.
169 Pin number and pixel format are unchanged.
170 @param n New length of strip, in pixels.
171 @note This function is deprecated, here only for old projects that
172 may still be calling it. New projects should instead use the
173 'new' keyword with the first constructor syntax (length, pin,
174 type).
175*/
176void Adafruit_NeoPixel::updateLength(uint16_t n) {
177 free(pixels); // Free existing data (if any)
178
179 // Allocate new data -- note: ALL PIXELS ARE CLEARED
180 numBytes = n * ((wOffset == rOffset) ? 3 : 4);
181 if ((pixels = (uint8_t *)malloc(numBytes))) {
182 memset(pixels, 0, numBytes);
183 numLEDs = n;
184 } else {
185 numLEDs = numBytes = 0;
186 }
187}
188
189/*!
190 @brief Change the pixel format of a previously-declared
191 Adafruit_NeoPixel strip object. If format changes from one of
192 the RGB variants to an RGBW variant (or RGBW to RGB), the old
193 data will be deallocated and new data is cleared. Otherwise,
194 the old data will remain in RAM and is not reordered to the
195 new format, so it's advisable to follow up with clear().
196 @param t Pixel type -- add together NEO_* constants defined in
197 Adafruit_NeoPixel.h, for example NEO_GRB+NEO_KHZ800 for
198 NeoPixels expecting an 800 KHz (vs 400 KHz) data stream
199 with color bytes expressed in green, red, blue order per
200 pixel.
201 @note This function is deprecated, here only for old projects that
202 may still be calling it. New projects should instead use the
203 'new' keyword with the first constructor syntax
204 (length, pin, type).
205*/
206void Adafruit_NeoPixel::updateType(neoPixelType t) {
207 bool oldThreeBytesPerPixel = (wOffset == rOffset); // false if RGBW
208
209 wOffset = (t >> 6) & 0b11; // See notes in header file
210 rOffset = (t >> 4) & 0b11; // regarding R/G/B/W offsets
211 gOffset = (t >> 2) & 0b11;
212 bOffset = t & 0b11;
213#if defined(NEO_KHZ400)
214 is800KHz = (t < 256); // 400 KHz flag is 1<<8
215#endif
216
217 // If bytes-per-pixel has changed (and pixel data was previously
218 // allocated), re-allocate to new size. Will clear any data.
219 if (pixels) {
220 bool newThreeBytesPerPixel = (wOffset == rOffset);
221 if (newThreeBytesPerPixel != oldThreeBytesPerPixel)
222 updateLength(numLEDs);
223 }
224}
225
226#if defined(ARDUINO_ARCH_CH32)
227
228// F_CPU is defined to SystemCoreClock (not constant number)
229#if SYSCLK_FREQ_144MHz_HSE == 144000000 || SYSCLK_FREQ_HSE == 144000000 || \
230 SYSCLK_FREQ_144MHz_HSI == 144000000 || SYSCLK_FREQ_HSI == 144000000
231#define CH32_F_CPU 144000000
232
233#elif SYSCLK_FREQ_120MHz_HSE == 120000000 || SYSCLK_FREQ_HSE == 120000000 || \
234 SYSCLK_FREQ_120MHz_HSI == 120000000 || SYSCLK_FREQ_HSI == 120000000
235#define CH32_F_CPU 120000000
236
237#elif SYSCLK_FREQ_96MHz_HSE == 96000000 || SYSCLK_FREQ_HSE == 96000000 || \
238 SYSCLK_FREQ_96MHz_HSI == 96000000 || SYSCLK_FREQ_HSI == 96000000
239#define CH32_F_CPU 96000000
240
241#elif SYSCLK_FREQ_72MHz_HSE == 72000000 || SYSCLK_FREQ_HSE == 72000000 || \
242 SYSCLK_FREQ_72MHz_HSI == 72000000 || SYSCLK_FREQ_HSI == 72000000
243#define CH32_F_CPU 72000000
244
245#elif SYSCLK_FREQ_56MHz_HSE == 56000000 || SYSCLK_FREQ_HSE == 56000000 || \
246 SYSCLK_FREQ_56MHz_HSI == 56000000 || SYSCLK_FREQ_HSI == 56000000
247#define CH32_F_CPU 56000000
248
249#elif SYSCLK_FREQ_48MHz_HSE == 48000000 || SYSCLK_FREQ_HSE == 48000000 || \
250 SYSCLK_FREQ_48MHz_HSI == 48000000 || SYSCLK_FREQ_HSI == 48000000
251#define CH32_F_CPU 48000000
252
253#endif
254
255static void ch32Show(GPIO_TypeDef *ch_port, uint32_t ch_pin, uint8_t *pixels,
256 uint32_t numBytes, bool is800KHz) {
257 // not support 400khz
258 if (!is800KHz)
259 return;
260
261 volatile uint32_t *set = &ch_port->BSHR;
262 volatile uint32_t *clr = &ch_port->BCR;
263
264 uint8_t *ptr = pixels;
265 uint8_t *end = ptr + numBytes;
266 uint8_t p = *ptr++;
267 uint8_t bitMask = 0x80;
268
269 // NVIC_DisableIRQ(SysTicK_IRQn);
270
271 while (1) {
272 if (p & bitMask) { // ONE
273 // High 800ns
274 *set = ch_pin;
275 __asm volatile("nop; nop; nop; nop; nop; nop; nop; nop;"
276 "nop; nop; nop; nop; nop; nop; nop; nop;"
277 "nop; nop; nop; nop; nop; nop; nop;"
278#if CH32_F_CPU >= 56000000
279 "nop; nop;"
280 "nop; nop; nop; nop; nop; nop; nop; nop;"
281 "nop; nop; nop; nop; nop; nop; nop; nop;"
282#endif
283#if CH32_F_CPU >= 72000000
284 "nop; nop; nop; nop; nop; nop; nop;"
285 "nop; nop; nop; nop; nop; nop;"
286#endif
287#if CH32_F_CPU >= 96000000
288 "nop; nop;"
289 "nop; nop; nop; nop; nop; nop; nop; nop;"
290 "nop; nop; nop; nop; nop; nop; nop; nop;"
291#endif
292#if CH32_F_CPU >= 120000000
293 "nop; nop; nop; nop; nop; nop; nop; nop;"
294 "nop; nop; nop; nop; nop; nop; nop; nop;"
295 "nop; nop; nop; nop; nop; nop; nop; nop;"
296#endif
297#if CH32_F_CPU >= 144000000
298 "nop; nop; nop; nop; nop; nop; nop; nop;"
299 "nop; nop; nop; nop; nop; nop; nop; nop;"
300#endif
301 );
302
303 // Low 450ns
304 *clr = ch_pin;
305 __asm volatile(
306 "nop; nop;"
307#if CH32_F_CPU >= 56000000
308 "nop; nop; nop; nop; nop; nop; nop;"
309 "nop; nop; nop; nop; nop; nop; nop; nop;"
310#endif
311#if CH32_F_CPU >= 72000000
312 "nop; nop; nop; nop; nop; nop; nop; nop; nop;"
313#endif
314#if CH32_F_CPU >= 96000000
315 "nop; nop; nop; nop; nop; nop;"
316#endif
317#if CH32_F_CPU >= 120000000
318 "nop; nop; nop; nop; nop;"
319 "nop; nop; nop; nop; nop; nop; nop; nop;"
320#endif
321#if CH32_F_CPU >= 144000000
322 "nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
323#endif
324 );
325 } else { // ZERO
326 // High 400ns
327 *set = ch_pin;
328 __asm volatile(
329 "nop; nop; nop; nop; nop; nop; nop; nop;"
330#if CH32_F_CPU >= 56000000
331 "nop; nop; nop; nop; nop; nop; nop; nop; nop;"
332#endif
333#if CH32_F_CPU >= 72000000
334 "nop; nop; nop; nop; nop; nop; nop;"
335#endif
336#if CH32_F_CPU >= 96000000
337 "nop; nop; nop; nop; nop; nop; nop; nop;"
338#endif
339#if CH32_F_CPU >= 120000000
340 "nop; nop; nop; "
341 "nop; nop; nop; nop; nop; nop; nop; nop;"
342#endif
343#if CH32_F_CPU >= 144000000
344 "nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
345#endif
346 );
347
348 // Low 850ns
349 *clr = ch_pin;
350 __asm volatile(
351 "nop; nop; nop; nop; nop; nop; nop; nop;"
352 "nop; nop; nop; nop;"
353#if CH32_F_CPU >= 56000000
354 "nop;"
355 "nop; nop; nop; nop; nop; nop; nop; nop;"
356 "nop; nop; nop; nop; nop; nop; nop; nop;"
357 "nop; nop; nop; nop; nop; nop; nop; nop;"
358#endif
359#if CH32_F_CPU >= 72000000
360 "nop; nop; nop;"
361 "nop; nop; nop; nop; nop; nop; nop; nop;"
362#endif
363#if CH32_F_CPU >= 96000000
364 "nop; nop; nop; nop; nop; nop; nop; nop;"
365 "nop; nop; nop; nop; nop; nop; nop; nop;"
366 "nop; nop; nop; nop; nop; nop;"
367#endif
368#if CH32_F_CPU >= 120000000
369 "nop; nop; nop; nop; nop; nop; nop; nop;"
370 "nop; nop; nop; nop; nop; nop; nop; nop;"
371 "nop; nop; nop; nop; nop; nop;"
372#endif
373#if CH32_F_CPU >= 144000000
374 "nop; nop; nop; nop;"
375 "nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"
376#endif
377 );
378 }
379
380 if (bitMask >>= 1) {
381 // Move on to the next pixel
382 asm("nop;");
383 } else {
384 if (ptr >= end) {
385 break;
386 }
387 p = *ptr++;
388 bitMask = 0x80;
389 }
390 }
391
392 // NVIC_EnableIRQ(SysTicK_IRQn);
393}
394#endif
395
396#if defined(ESP8266)
397// ESP8266 show() is external to enforce ICACHE_RAM_ATTR execution
398extern "C" IRAM_ATTR void espShow(uint16_t pin, uint8_t *pixels,
399 uint32_t numBytes, uint8_t type);
400#elif defined(ESP32)
401extern "C" void espShow(uint16_t pin, uint8_t *pixels, uint32_t numBytes,
402 uint8_t type);
403
404#endif // ESP8266
405
406#if defined(K210)
407#define KENDRYTE_K210 1
408#endif
409
410#if defined(KENDRYTE_K210)
411extern "C" void k210Show(uint8_t pin, uint8_t *pixels, uint32_t numBytes,
412 boolean is800KHz);
413#endif // KENDRYTE_K210
414
415#if defined(ARDUINO_ARCH_PSOC6)
416extern "C" void psoc6_show(uint8_t pin, uint8_t *pixels, uint32_t numBytes,
417 boolean is800KHz);
418#endif
419/*!
420 @brief Transmit pixel data in RAM to NeoPixels.
421 @note On most architectures, interrupts are temporarily disabled in
422 order to achieve the correct NeoPixel signal timing. This means
423 that the Arduino millis() and micros() functions, which require
424 interrupts, will lose small intervals of time whenever this
425 function is called (about 30 microseconds per RGB pixel, 40 for
426 RGBW pixels). There's no easy fix for this, but a few
427 specialized alternative or companion libraries exist that use
428 very device-specific peripherals to work around it.
429*/
430void Adafruit_NeoPixel::show(void) {
431
432 if (!pixels)
433 return;
434
435 // Data latch = 300+ microsecond pause in the output stream. Rather than
436 // put a delay at the end of the function, the ending time is noted and
437 // the function will simply hold off (if needed) on issuing the
438 // subsequent round of data until the latch time has elapsed. This
439 // allows the mainline code to start generating the next frame of data
440 // rather than stalling for the latch.
441 while (!canShow())
442 ;
443 // endTime is a private member (rather than global var) so that multiple
444 // instances on different pins can be quickly issued in succession (each
445 // instance doesn't delay the next).
446
447 // In order to make this code runtime-configurable to work with any pin,
448 // SBI/CBI instructions are eschewed in favor of full PORT writes via the
449 // OUT or ST instructions. It relies on two facts: that peripheral
450 // functions (such as PWM) take precedence on output pins, so our PORT-
451 // wide writes won't interfere, and that interrupts are globally disabled
452 // while data is being issued to the LEDs, so no other code will be
453 // accessing the PORT. The code takes an initial 'snapshot' of the PORT
454 // state, computes 'pin high' and 'pin low' values, and writes these back
455 // to the PORT register as needed.
456
457 // NRF52 may use PWM + DMA (if available), may not need to disable interrupt
458 // ESP32 may not disable interrupts because espShow() uses RMT which tries
459 // to acquire locks
460#if !(defined(NRF52) || defined(NRF52_SERIES) || defined(ESP32))
461 noInterrupts(); // Need 100% focus on instruction timing
462#endif
463
464#if defined(ARDUINO_ARCH_PSOC6)
465 psoc6_show(pin, pixels, numBytes, is800KHz);
466#endif
467
468#if defined(__AVR__)
469 // AVR MCUs -- ATmega & ATtiny (no XMEGA) ---------------------------------
470
471 volatile uint16_t i = numBytes; // Loop counter
472 volatile uint8_t *ptr = pixels, // Pointer to next byte
473 b = *ptr++, // Current byte value
474 hi, // PORT w/output bit set high
475 lo; // PORT w/output bit set low
476
477 // Hand-tuned assembly code issues data to the LED drivers at a specific
478 // rate. There's separate code for different CPU speeds (8, 12, 16 MHz)
479 // for both the WS2811 (400 KHz) and WS2812 (800 KHz) drivers. The
480 // datastream timing for the LED drivers allows a little wiggle room each
481 // way (listed in the datasheets), so the conditions for compiling each
482 // case are set up for a range of frequencies rather than just the exact
483 // 8, 12 or 16 MHz values, permitting use with some close-but-not-spot-on
484 // devices (e.g. 16.5 MHz DigiSpark). The ranges were arrived at based
485 // on the datasheet figures and have not been extensively tested outside
486 // the canonical 8/12/16 MHz speeds; there's no guarantee these will work
487 // close to the extremes (or possibly they could be pushed further).
488 // Keep in mind only one CPU speed case actually gets compiled; the
489 // resulting program isn't as massive as it might look from source here.
490
491// 8 MHz(ish) AVR ---------------------------------------------------------
492#if (F_CPU >= 7400000UL) && (F_CPU <= 9500000UL)
493
494#if defined(NEO_KHZ400) // 800 KHz check needed only if 400 KHz support enabled
495 if (is800KHz) {
496#endif
497
498 volatile uint8_t n1, n2 = 0; // First, next bits out
499
500 // Squeezing an 800 KHz stream out of an 8 MHz chip requires code
501 // specific to each PORT register.
502
503 // 10 instruction clocks per bit: HHxxxxxLLL
504 // OUT instructions: ^ ^ ^ (T=0,2,7)
505
506 // PORTD OUTPUT ----------------------------------------------------
507
508#if defined(PORTD)
509#if defined(PORTB) || defined(PORTC) || defined(PORTF)
510 if (port == &PORTD) {
511#endif // defined(PORTB/C/F)
512
513 hi = PORTD | pinMask;
514 lo = PORTD & ~pinMask;
515 n1 = lo;
516 if (b & 0x80)
517 n1 = hi;
518
519 // Dirty trick: RJMPs proceeding to the next instruction are used
520 // to delay two clock cycles in one instruction word (rather than
521 // using two NOPs). This was necessary in order to squeeze the
522 // loop down to exactly 64 words -- the maximum possible for a
523 // relative branch.
524
525 asm volatile(
526 "headD:"
527 "\n\t" // Clk Pseudocode
528 // Bit 7:
529 "out %[port] , %[hi]"
530 "\n\t" // 1 PORT = hi
531 "mov %[n2] , %[lo]"
532 "\n\t" // 1 n2 = lo
533 "out %[port] , %[n1]"
534 "\n\t" // 1 PORT = n1
535 "rjmp .+0"
536 "\n\t" // 2 nop nop
537 "sbrc %[byte] , 6"
538 "\n\t" // 1-2 if(b & 0x40)
539 "mov %[n2] , %[hi]"
540 "\n\t" // 0-1 n2 = hi
541 "out %[port] , %[lo]"
542 "\n\t" // 1 PORT = lo
543 "rjmp .+0"
544 "\n\t" // 2 nop nop
545 // Bit 6:
546 "out %[port] , %[hi]"
547 "\n\t" // 1 PORT = hi
548 "mov %[n1] , %[lo]"
549 "\n\t" // 1 n1 = lo
550 "out %[port] , %[n2]"
551 "\n\t" // 1 PORT = n2
552 "rjmp .+0"
553 "\n\t" // 2 nop nop
554 "sbrc %[byte] , 5"
555 "\n\t" // 1-2 if(b & 0x20)
556 "mov %[n1] , %[hi]"
557 "\n\t" // 0-1 n1 = hi
558 "out %[port] , %[lo]"
559 "\n\t" // 1 PORT = lo
560 "rjmp .+0"
561 "\n\t" // 2 nop nop
562 // Bit 5:
563 "out %[port] , %[hi]"
564 "\n\t" // 1 PORT = hi
565 "mov %[n2] , %[lo]"
566 "\n\t" // 1 n2 = lo
567 "out %[port] , %[n1]"
568 "\n\t" // 1 PORT = n1
569 "rjmp .+0"
570 "\n\t" // 2 nop nop
571 "sbrc %[byte] , 4"
572 "\n\t" // 1-2 if(b & 0x10)
573 "mov %[n2] , %[hi]"
574 "\n\t" // 0-1 n2 = hi
575 "out %[port] , %[lo]"
576 "\n\t" // 1 PORT = lo
577 "rjmp .+0"
578 "\n\t" // 2 nop nop
579 // Bit 4:
580 "out %[port] , %[hi]"
581 "\n\t" // 1 PORT = hi
582 "mov %[n1] , %[lo]"
583 "\n\t" // 1 n1 = lo
584 "out %[port] , %[n2]"
585 "\n\t" // 1 PORT = n2
586 "rjmp .+0"
587 "\n\t" // 2 nop nop
588 "sbrc %[byte] , 3"
589 "\n\t" // 1-2 if(b & 0x08)
590 "mov %[n1] , %[hi]"
591 "\n\t" // 0-1 n1 = hi
592 "out %[port] , %[lo]"
593 "\n\t" // 1 PORT = lo
594 "rjmp .+0"
595 "\n\t" // 2 nop nop
596 // Bit 3:
597 "out %[port] , %[hi]"
598 "\n\t" // 1 PORT = hi
599 "mov %[n2] , %[lo]"
600 "\n\t" // 1 n2 = lo
601 "out %[port] , %[n1]"
602 "\n\t" // 1 PORT = n1
603 "rjmp .+0"
604 "\n\t" // 2 nop nop
605 "sbrc %[byte] , 2"
606 "\n\t" // 1-2 if(b & 0x04)
607 "mov %[n2] , %[hi]"
608 "\n\t" // 0-1 n2 = hi
609 "out %[port] , %[lo]"
610 "\n\t" // 1 PORT = lo
611 "rjmp .+0"
612 "\n\t" // 2 nop nop
613 // Bit 2:
614 "out %[port] , %[hi]"
615 "\n\t" // 1 PORT = hi
616 "mov %[n1] , %[lo]"
617 "\n\t" // 1 n1 = lo
618 "out %[port] , %[n2]"
619 "\n\t" // 1 PORT = n2
620 "rjmp .+0"
621 "\n\t" // 2 nop nop
622 "sbrc %[byte] , 1"
623 "\n\t" // 1-2 if(b & 0x02)
624 "mov %[n1] , %[hi]"
625 "\n\t" // 0-1 n1 = hi
626 "out %[port] , %[lo]"
627 "\n\t" // 1 PORT = lo
628 "rjmp .+0"
629 "\n\t" // 2 nop nop
630 // Bit 1:
631 "out %[port] , %[hi]"
632 "\n\t" // 1 PORT = hi
633 "mov %[n2] , %[lo]"
634 "\n\t" // 1 n2 = lo
635 "out %[port] , %[n1]"
636 "\n\t" // 1 PORT = n1
637 "rjmp .+0"
638 "\n\t" // 2 nop nop
639 "sbrc %[byte] , 0"
640 "\n\t" // 1-2 if(b & 0x01)
641 "mov %[n2] , %[hi]"
642 "\n\t" // 0-1 n2 = hi
643 "out %[port] , %[lo]"
644 "\n\t" // 1 PORT = lo
645 "sbiw %[count], 1"
646 "\n\t" // 2 i-- (don't act on Z flag yet)
647 // Bit 0:
648 "out %[port] , %[hi]"
649 "\n\t" // 1 PORT = hi
650 "mov %[n1] , %[lo]"
651 "\n\t" // 1 n1 = lo
652 "out %[port] , %[n2]"
653 "\n\t" // 1 PORT = n2
654 "ld %[byte] , %a[ptr]+"
655 "\n\t" // 2 b = *ptr++
656 "sbrc %[byte] , 7"
657 "\n\t" // 1-2 if(b & 0x80)
658 "mov %[n1] , %[hi]"
659 "\n\t" // 0-1 n1 = hi
660 "out %[port] , %[lo]"
661 "\n\t" // 1 PORT = lo
662 "brne headD"
663 "\n" // 2 while(i) (Z flag set above)
664 : [byte] "+r"(b), [n1] "+r"(n1), [n2] "+r"(n2), [count] "+w"(i)
665 : [port] "I"(_SFR_IO_ADDR(PORTD)), [ptr] "e"(ptr), [hi] "r"(hi),
666 [lo] "r"(lo));
667
668#if defined(PORTB) || defined(PORTC) || defined(PORTF)
669 } else // other PORT(s)
670#endif // defined(PORTB/C/F)
671#endif // defined(PORTD)
672
673 // PORTB OUTPUT ----------------------------------------------------
674
675#if defined(PORTB)
676#if defined(PORTD) || defined(PORTC) || defined(PORTF)
677 if (port == &PORTB) {
678#endif // defined(PORTD/C/F)
679
680 // Same as above, just switched to PORTB and stripped of comments.
681 hi = PORTB | pinMask;
682 lo = PORTB & ~pinMask;
683 n1 = lo;
684 if (b & 0x80)
685 n1 = hi;
686
687 asm volatile(
688 "headB:"
689 "\n\t"
690 "out %[port] , %[hi]"
691 "\n\t"
692 "mov %[n2] , %[lo]"
693 "\n\t"
694 "out %[port] , %[n1]"
695 "\n\t"
696 "rjmp .+0"
697 "\n\t"
698 "sbrc %[byte] , 6"
699 "\n\t"
700 "mov %[n2] , %[hi]"
701 "\n\t"
702 "out %[port] , %[lo]"
703 "\n\t"
704 "rjmp .+0"
705 "\n\t"
706 "out %[port] , %[hi]"
707 "\n\t"
708 "mov %[n1] , %[lo]"
709 "\n\t"
710 "out %[port] , %[n2]"
711 "\n\t"
712 "rjmp .+0"
713 "\n\t"
714 "sbrc %[byte] , 5"
715 "\n\t"
716 "mov %[n1] , %[hi]"
717 "\n\t"
718 "out %[port] , %[lo]"
719 "\n\t"
720 "rjmp .+0"
721 "\n\t"
722 "out %[port] , %[hi]"
723 "\n\t"
724 "mov %[n2] , %[lo]"
725 "\n\t"
726 "out %[port] , %[n1]"
727 "\n\t"
728 "rjmp .+0"
729 "\n\t"
730 "sbrc %[byte] , 4"
731 "\n\t"
732 "mov %[n2] , %[hi]"
733 "\n\t"
734 "out %[port] , %[lo]"
735 "\n\t"
736 "rjmp .+0"
737 "\n\t"
738 "out %[port] , %[hi]"
739 "\n\t"
740 "mov %[n1] , %[lo]"
741 "\n\t"
742 "out %[port] , %[n2]"
743 "\n\t"
744 "rjmp .+0"
745 "\n\t"
746 "sbrc %[byte] , 3"
747 "\n\t"
748 "mov %[n1] , %[hi]"
749 "\n\t"
750 "out %[port] , %[lo]"
751 "\n\t"
752 "rjmp .+0"
753 "\n\t"
754 "out %[port] , %[hi]"
755 "\n\t"
756 "mov %[n2] , %[lo]"
757 "\n\t"
758 "out %[port] , %[n1]"
759 "\n\t"
760 "rjmp .+0"
761 "\n\t"
762 "sbrc %[byte] , 2"
763 "\n\t"
764 "mov %[n2] , %[hi]"
765 "\n\t"
766 "out %[port] , %[lo]"
767 "\n\t"
768 "rjmp .+0"
769 "\n\t"
770 "out %[port] , %[hi]"
771 "\n\t"
772 "mov %[n1] , %[lo]"
773 "\n\t"
774 "out %[port] , %[n2]"
775 "\n\t"
776 "rjmp .+0"
777 "\n\t"
778 "sbrc %[byte] , 1"
779 "\n\t"
780 "mov %[n1] , %[hi]"
781 "\n\t"
782 "out %[port] , %[lo]"
783 "\n\t"
784 "rjmp .+0"
785 "\n\t"
786 "out %[port] , %[hi]"
787 "\n\t"
788 "mov %[n2] , %[lo]"
789 "\n\t"
790 "out %[port] , %[n1]"
791 "\n\t"
792 "rjmp .+0"
793 "\n\t"
794 "sbrc %[byte] , 0"
795 "\n\t"
796 "mov %[n2] , %[hi]"
797 "\n\t"
798 "out %[port] , %[lo]"
799 "\n\t"
800 "sbiw %[count], 1"
801 "\n\t"
802 "out %[port] , %[hi]"
803 "\n\t"
804 "mov %[n1] , %[lo]"
805 "\n\t"
806 "out %[port] , %[n2]"
807 "\n\t"
808 "ld %[byte] , %a[ptr]+"
809 "\n\t"
810 "sbrc %[byte] , 7"
811 "\n\t"
812 "mov %[n1] , %[hi]"
813 "\n\t"
814 "out %[port] , %[lo]"
815 "\n\t"
816 "brne headB"
817 "\n"
818 : [byte] "+r"(b), [n1] "+r"(n1), [n2] "+r"(n2), [count] "+w"(i)
819 : [port] "I"(_SFR_IO_ADDR(PORTB)), [ptr] "e"(ptr), [hi] "r"(hi),
820 [lo] "r"(lo));
821
822#if defined(PORTD) || defined(PORTC) || defined(PORTF)
823 }
824#endif
825#if defined(PORTC) || defined(PORTF)
826 else
827#endif // defined(PORTC/F)
828#endif // defined(PORTB)
829
830 // PORTC OUTPUT ----------------------------------------------------
831
832#if defined(PORTC)
833#if defined(PORTD) || defined(PORTB) || defined(PORTF)
834 if (port == &PORTC) {
835#endif // defined(PORTD/B/F)
836
837 // Same as above, just switched to PORTC and stripped of comments.
838 hi = PORTC | pinMask;
839 lo = PORTC & ~pinMask;
840 n1 = lo;
841 if (b & 0x80)
842 n1 = hi;
843
844 asm volatile(
845 "headC:"
846 "\n\t"
847 "out %[port] , %[hi]"
848 "\n\t"
849 "mov %[n2] , %[lo]"
850 "\n\t"
851 "out %[port] , %[n1]"
852 "\n\t"
853 "rjmp .+0"
854 "\n\t"
855 "sbrc %[byte] , 6"
856 "\n\t"
857 "mov %[n2] , %[hi]"
858 "\n\t"
859 "out %[port] , %[lo]"
860 "\n\t"
861 "rjmp .+0"
862 "\n\t"
863 "out %[port] , %[hi]"
864 "\n\t"
865 "mov %[n1] , %[lo]"
866 "\n\t"
867 "out %[port] , %[n2]"
868 "\n\t"
869 "rjmp .+0"
870 "\n\t"
871 "sbrc %[byte] , 5"
872 "\n\t"
873 "mov %[n1] , %[hi]"
874 "\n\t"
875 "out %[port] , %[lo]"
876 "\n\t"
877 "rjmp .+0"
878 "\n\t"
879 "out %[port] , %[hi]"
880 "\n\t"
881 "mov %[n2] , %[lo]"
882 "\n\t"
883 "out %[port] , %[n1]"
884 "\n\t"
885 "rjmp .+0"
886 "\n\t"
887 "sbrc %[byte] , 4"
888 "\n\t"
889 "mov %[n2] , %[hi]"
890 "\n\t"
891 "out %[port] , %[lo]"
892 "\n\t"
893 "rjmp .+0"
894 "\n\t"
895 "out %[port] , %[hi]"
896 "\n\t"
897 "mov %[n1] , %[lo]"
898 "\n\t"
899 "out %[port] , %[n2]"
900 "\n\t"
901 "rjmp .+0"
902 "\n\t"
903 "sbrc %[byte] , 3"
904 "\n\t"
905 "mov %[n1] , %[hi]"
906 "\n\t"
907 "out %[port] , %[lo]"
908 "\n\t"
909 "rjmp .+0"
910 "\n\t"
911 "out %[port] , %[hi]"
912 "\n\t"
913 "mov %[n2] , %[lo]"
914 "\n\t"
915 "out %[port] , %[n1]"
916 "\n\t"
917 "rjmp .+0"
918 "\n\t"
919 "sbrc %[byte] , 2"
920 "\n\t"
921 "mov %[n2] , %[hi]"
922 "\n\t"
923 "out %[port] , %[lo]"
924 "\n\t"
925 "rjmp .+0"
926 "\n\t"
927 "out %[port] , %[hi]"
928 "\n\t"
929 "mov %[n1] , %[lo]"
930 "\n\t"
931 "out %[port] , %[n2]"
932 "\n\t"
933 "rjmp .+0"
934 "\n\t"
935 "sbrc %[byte] , 1"
936 "\n\t"
937 "mov %[n1] , %[hi]"
938 "\n\t"
939 "out %[port] , %[lo]"
940 "\n\t"
941 "rjmp .+0"
942 "\n\t"
943 "out %[port] , %[hi]"
944 "\n\t"
945 "mov %[n2] , %[lo]"
946 "\n\t"
947 "out %[port] , %[n1]"
948 "\n\t"
949 "rjmp .+0"
950 "\n\t"
951 "sbrc %[byte] , 0"
952 "\n\t"
953 "mov %[n2] , %[hi]"
954 "\n\t"
955 "out %[port] , %[lo]"
956 "\n\t"
957 "sbiw %[count], 1"
958 "\n\t"
959 "out %[port] , %[hi]"
960 "\n\t"
961 "mov %[n1] , %[lo]"
962 "\n\t"
963 "out %[port] , %[n2]"
964 "\n\t"
965 "ld %[byte] , %a[ptr]+"
966 "\n\t"
967 "sbrc %[byte] , 7"
968 "\n\t"
969 "mov %[n1] , %[hi]"
970 "\n\t"
971 "out %[port] , %[lo]"
972 "\n\t"
973 "brne headC"
974 "\n"
975 : [byte] "+r"(b), [n1] "+r"(n1), [n2] "+r"(n2), [count] "+w"(i)
976 : [port] "I"(_SFR_IO_ADDR(PORTC)), [ptr] "e"(ptr), [hi] "r"(hi),
977 [lo] "r"(lo));
978
979#if defined(PORTD) || defined(PORTB) || defined(PORTF)
980 }
981#endif // defined(PORTD/B/F)
982#if defined(PORTF)
983 else
984#endif
985#endif // defined(PORTC)
986
987 // PORTF OUTPUT ----------------------------------------------------
988
989#if defined(PORTF)
990#if defined(PORTD) || defined(PORTB) || defined(PORTC)
991 if (port == &PORTF) {
992#endif // defined(PORTD/B/C)
993
994 hi = PORTF | pinMask;
995 lo = PORTF & ~pinMask;
996 n1 = lo;
997 if (b & 0x80)
998 n1 = hi;
999
1000 asm volatile(
1001 "headF:"
1002 "\n\t"
1003 "out %[port] , %[hi]"
1004 "\n\t"
1005 "mov %[n2] , %[lo]"
1006 "\n\t"
1007 "out %[port] , %[n1]"
1008 "\n\t"
1009 "rjmp .+0"
1010 "\n\t"
1011 "sbrc %[byte] , 6"
1012 "\n\t"
1013 "mov %[n2] , %[hi]"
1014 "\n\t"
1015 "out %[port] , %[lo]"
1016 "\n\t"
1017 "rjmp .+0"
1018 "\n\t"
1019 "out %[port] , %[hi]"
1020 "\n\t"
1021 "mov %[n1] , %[lo]"
1022 "\n\t"
1023 "out %[port] , %[n2]"
1024 "\n\t"
1025 "rjmp .+0"
1026 "\n\t"
1027 "sbrc %[byte] , 5"
1028 "\n\t"
1029 "mov %[n1] , %[hi]"
1030 "\n\t"
1031 "out %[port] , %[lo]"
1032 "\n\t"
1033 "rjmp .+0"
1034 "\n\t"
1035 "out %[port] , %[hi]"
1036 "\n\t"
1037 "mov %[n2] , %[lo]"
1038 "\n\t"
1039 "out %[port] , %[n1]"
1040 "\n\t"
1041 "rjmp .+0"
1042 "\n\t"
1043 "sbrc %[byte] , 4"
1044 "\n\t"
1045 "mov %[n2] , %[hi]"
1046 "\n\t"
1047 "out %[port] , %[lo]"
1048 "\n\t"
1049 "rjmp .+0"
1050 "\n\t"
1051 "out %[port] , %[hi]"
1052 "\n\t"
1053 "mov %[n1] , %[lo]"
1054 "\n\t"
1055 "out %[port] , %[n2]"
1056 "\n\t"
1057 "rjmp .+0"
1058 "\n\t"
1059 "sbrc %[byte] , 3"
1060 "\n\t"
1061 "mov %[n1] , %[hi]"
1062 "\n\t"
1063 "out %[port] , %[lo]"
1064 "\n\t"
1065 "rjmp .+0"
1066 "\n\t"
1067 "out %[port] , %[hi]"
1068 "\n\t"
1069 "mov %[n2] , %[lo]"
1070 "\n\t"
1071 "out %[port] , %[n1]"
1072 "\n\t"
1073 "rjmp .+0"
1074 "\n\t"
1075 "sbrc %[byte] , 2"
1076 "\n\t"
1077 "mov %[n2] , %[hi]"
1078 "\n\t"
1079 "out %[port] , %[lo]"
1080 "\n\t"
1081 "rjmp .+0"
1082 "\n\t"
1083 "out %[port] , %[hi]"
1084 "\n\t"
1085 "mov %[n1] , %[lo]"
1086 "\n\t"
1087 "out %[port] , %[n2]"
1088 "\n\t"
1089 "rjmp .+0"
1090 "\n\t"
1091 "sbrc %[byte] , 1"
1092 "\n\t"
1093 "mov %[n1] , %[hi]"
1094 "\n\t"
1095 "out %[port] , %[lo]"
1096 "\n\t"
1097 "rjmp .+0"
1098 "\n\t"
1099 "out %[port] , %[hi]"
1100 "\n\t"
1101 "mov %[n2] , %[lo]"
1102 "\n\t"
1103 "out %[port] , %[n1]"
1104 "\n\t"
1105 "rjmp .+0"
1106 "\n\t"
1107 "sbrc %[byte] , 0"
1108 "\n\t"
1109 "mov %[n2] , %[hi]"
1110 "\n\t"
1111 "out %[port] , %[lo]"
1112 "\n\t"
1113 "sbiw %[count], 1"
1114 "\n\t"
1115 "out %[port] , %[hi]"
1116 "\n\t"
1117 "mov %[n1] , %[lo]"
1118 "\n\t"
1119 "out %[port] , %[n2]"
1120 "\n\t"
1121 "ld %[byte] , %a[ptr]+"
1122 "\n\t"
1123 "sbrc %[byte] , 7"
1124 "\n\t"
1125 "mov %[n1] , %[hi]"
1126 "\n\t"
1127 "out %[port] , %[lo]"
1128 "\n\t"
1129 "brne headF"
1130 "\n"
1131 : [byte] "+r"(b), [n1] "+r"(n1), [n2] "+r"(n2), [count] "+w"(i)
1132 : [port] "I"(_SFR_IO_ADDR(PORTF)), [ptr] "e"(ptr), [hi] "r"(hi),
1133 [lo] "r"(lo));
1134
1135#if defined(PORTD) || defined(PORTB) || defined(PORTC)
1136 }
1137#endif // defined(PORTD/B/C)
1138#endif // defined(PORTF)
1139
1140#if defined(NEO_KHZ400)
1141 } else { // end 800 KHz, do 400 KHz
1142
1143 // Timing is more relaxed; unrolling the inner loop for each bit is
1144 // not necessary. Still using the peculiar RJMPs as 2X NOPs, not out
1145 // of need but just to trim the code size down a little.
1146 // This 400-KHz-datastream-on-8-MHz-CPU code is not quite identical
1147 // to the 800-on-16 code later -- the hi/lo timing between WS2811 and
1148 // WS2812 is not simply a 2:1 scale!
1149
1150 // 20 inst. clocks per bit: HHHHxxxxxxLLLLLLLLLL
1151 // ST instructions: ^ ^ ^ (T=0,4,10)
1152
1153 volatile uint8_t next, bit;
1154
1155 hi = *port | pinMask;
1156 lo = *port & ~pinMask;
1157 next = lo;
1158 bit = 8;
1159
1160 asm volatile("head20%=:"
1161 "\n\t" // Clk Pseudocode (T = 0)
1162 "st %a[port], %[hi]"
1163 "\n\t" // 2 PORT = hi (T = 2)
1164 "sbrc %[byte] , 7"
1165 "\n\t" // 1-2 if(b & 128)
1166 "mov %[next], %[hi]"
1167 "\n\t" // 0-1 next = hi (T = 4)
1168 "st %a[port], %[next]"
1169 "\n\t" // 2 PORT = next (T = 6)
1170 "mov %[next] , %[lo]"
1171 "\n\t" // 1 next = lo (T = 7)
1172 "dec %[bit]"
1173 "\n\t" // 1 bit-- (T = 8)
1174 "breq nextbyte20%="
1175 "\n\t" // 1-2 if(bit == 0)
1176 "rol %[byte]"
1177 "\n\t" // 1 b <<= 1 (T = 10)
1178 "st %a[port], %[lo]"
1179 "\n\t" // 2 PORT = lo (T = 12)
1180 "rjmp .+0"
1181 "\n\t" // 2 nop nop (T = 14)
1182 "rjmp .+0"
1183 "\n\t" // 2 nop nop (T = 16)
1184 "rjmp .+0"
1185 "\n\t" // 2 nop nop (T = 18)
1186 "rjmp head20%="
1187 "\n\t" // 2 -> head20 (next bit out)
1188 "nextbyte20%=:"
1189 "\n\t" // (T = 10)
1190 "st %a[port], %[lo]"
1191 "\n\t" // 2 PORT = lo (T = 12)
1192 "nop"
1193 "\n\t" // 1 nop (T = 13)
1194 "ldi %[bit] , 8"
1195 "\n\t" // 1 bit = 8 (T = 14)
1196 "ld %[byte] , %a[ptr]+"
1197 "\n\t" // 2 b = *ptr++ (T = 16)
1198 "sbiw %[count], 1"
1199 "\n\t" // 2 i-- (T = 18)
1200 "brne head20%="
1201 "\n" // 2 if(i != 0) -> (next byte)
1202 : [port] "+e"(port), [byte] "+r"(b), [bit] "+r"(bit),
1203 [next] "+r"(next), [count] "+w"(i)
1204 : [hi] "r"(hi), [lo] "r"(lo), [ptr] "e"(ptr));
1205 }
1206#endif // NEO_KHZ400
1207
1208// 12 MHz(ish) AVR --------------------------------------------------------
1209#elif (F_CPU >= 11100000UL) && (F_CPU <= 14300000UL)
1210
1211#if defined(NEO_KHZ400) // 800 KHz check needed only if 400 KHz support enabled
1212 if (is800KHz) {
1213#endif
1214
1215 // In the 12 MHz case, an optimized 800 KHz datastream (no dead time
1216 // between bytes) requires a PORT-specific loop similar to the 8 MHz
1217 // code (but a little more relaxed in this case).
1218
1219 // 15 instruction clocks per bit: HHHHxxxxxxLLLLL
1220 // OUT instructions: ^ ^ ^ (T=0,4,10)
1221
1222 volatile uint8_t next;
1223
1224 // PORTD OUTPUT ----------------------------------------------------
1225
1226#if defined(PORTD)
1227#if defined(PORTB) || defined(PORTC) || defined(PORTF)
1228 if (port == &PORTD) {
1229#endif // defined(PORTB/C/F)
1230
1231 hi = PORTD | pinMask;
1232 lo = PORTD & ~pinMask;
1233 next = lo;
1234 if (b & 0x80)
1235 next = hi;
1236
1237 // Don't "optimize" the OUT calls into the bitTime subroutine;
1238 // we're exploiting the RCALL and RET as 3- and 4-cycle NOPs!
1239 asm volatile("headD:"
1240 "\n\t" // (T = 0)
1241 "out %[port], %[hi]"
1242 "\n\t" // (T = 1)
1243 "rcall bitTimeD"
1244 "\n\t" // Bit 7 (T = 15)
1245 "out %[port], %[hi]"
1246 "\n\t"
1247 "rcall bitTimeD"
1248 "\n\t" // Bit 6
1249 "out %[port], %[hi]"
1250 "\n\t"
1251 "rcall bitTimeD"
1252 "\n\t" // Bit 5
1253 "out %[port], %[hi]"
1254 "\n\t"
1255 "rcall bitTimeD"
1256 "\n\t" // Bit 4
1257 "out %[port], %[hi]"
1258 "\n\t"
1259 "rcall bitTimeD"
1260 "\n\t" // Bit 3
1261 "out %[port], %[hi]"
1262 "\n\t"
1263 "rcall bitTimeD"
1264 "\n\t" // Bit 2
1265 "out %[port], %[hi]"
1266 "\n\t"
1267 "rcall bitTimeD"
1268 "\n\t" // Bit 1
1269 // Bit 0:
1270 "out %[port] , %[hi]"
1271 "\n\t" // 1 PORT = hi (T = 1)
1272 "rjmp .+0"
1273 "\n\t" // 2 nop nop (T = 3)
1274 "ld %[byte] , %a[ptr]+"
1275 "\n\t" // 2 b = *ptr++ (T = 5)
1276 "out %[port] , %[next]"
1277 "\n\t" // 1 PORT = next (T = 6)
1278 "mov %[next] , %[lo]"
1279 "\n\t" // 1 next = lo (T = 7)
1280 "sbrc %[byte] , 7"
1281 "\n\t" // 1-2 if(b & 0x80) (T = 8)
1282 "mov %[next] , %[hi]"
1283 "\n\t" // 0-1 next = hi (T = 9)
1284 "nop"
1285 "\n\t" // 1 (T = 10)
1286 "out %[port] , %[lo]"
1287 "\n\t" // 1 PORT = lo (T = 11)
1288 "sbiw %[count], 1"
1289 "\n\t" // 2 i-- (T = 13)
1290 "brne headD"
1291 "\n\t" // 2 if(i != 0) -> (next byte)
1292 "rjmp doneD"
1293 "\n\t"
1294 "bitTimeD:"
1295 "\n\t" // nop nop nop (T = 4)
1296 "out %[port], %[next]"
1297 "\n\t" // 1 PORT = next (T = 5)
1298 "mov %[next], %[lo]"
1299 "\n\t" // 1 next = lo (T = 6)
1300 "rol %[byte]"
1301 "\n\t" // 1 b <<= 1 (T = 7)
1302 "sbrc %[byte], 7"
1303 "\n\t" // 1-2 if(b & 0x80) (T = 8)
1304 "mov %[next], %[hi]"
1305 "\n\t" // 0-1 next = hi (T = 9)
1306 "nop"
1307 "\n\t" // 1 (T = 10)
1308 "out %[port], %[lo]"
1309 "\n\t" // 1 PORT = lo (T = 11)
1310 "ret"
1311 "\n\t" // 4 nop nop nop nop (T = 15)
1312 "doneD:"
1313 "\n"
1314 : [byte] "+r"(b), [next] "+r"(next), [count] "+w"(i)
1315 : [port] "I"(_SFR_IO_ADDR(PORTD)), [ptr] "e"(ptr),
1316 [hi] "r"(hi), [lo] "r"(lo));
1317
1318#if defined(PORTB) || defined(PORTC) || defined(PORTF)
1319 } else // other PORT(s)
1320#endif // defined(PORTB/C/F)
1321#endif // defined(PORTD)
1322
1323 // PORTB OUTPUT ----------------------------------------------------
1324
1325#if defined(PORTB)
1326#if defined(PORTD) || defined(PORTC) || defined(PORTF)
1327 if (port == &PORTB) {
1328#endif // defined(PORTD/C/F)
1329
1330 hi = PORTB | pinMask;
1331 lo = PORTB & ~pinMask;
1332 next = lo;
1333 if (b & 0x80)
1334 next = hi;
1335
1336 // Same as above, just set for PORTB & stripped of comments
1337 asm volatile("headB:"
1338 "\n\t"
1339 "out %[port], %[hi]"
1340 "\n\t"
1341 "rcall bitTimeB"
1342 "\n\t"
1343 "out %[port], %[hi]"
1344 "\n\t"
1345 "rcall bitTimeB"
1346 "\n\t"
1347 "out %[port], %[hi]"
1348 "\n\t"
1349 "rcall bitTimeB"
1350 "\n\t"
1351 "out %[port], %[hi]"
1352 "\n\t"
1353 "rcall bitTimeB"
1354 "\n\t"
1355 "out %[port], %[hi]"
1356 "\n\t"
1357 "rcall bitTimeB"
1358 "\n\t"
1359 "out %[port], %[hi]"
1360 "\n\t"
1361 "rcall bitTimeB"
1362 "\n\t"
1363 "out %[port], %[hi]"
1364 "\n\t"
1365 "rcall bitTimeB"
1366 "\n\t"
1367 "out %[port] , %[hi]"
1368 "\n\t"
1369 "rjmp .+0"
1370 "\n\t"
1371 "ld %[byte] , %a[ptr]+"
1372 "\n\t"
1373 "out %[port] , %[next]"
1374 "\n\t"
1375 "mov %[next] , %[lo]"
1376 "\n\t"
1377 "sbrc %[byte] , 7"
1378 "\n\t"
1379 "mov %[next] , %[hi]"
1380 "\n\t"
1381 "nop"
1382 "\n\t"
1383 "out %[port] , %[lo]"
1384 "\n\t"
1385 "sbiw %[count], 1"
1386 "\n\t"
1387 "brne headB"
1388 "\n\t"
1389 "rjmp doneB"
1390 "\n\t"
1391 "bitTimeB:"
1392 "\n\t"
1393 "out %[port], %[next]"
1394 "\n\t"
1395 "mov %[next], %[lo]"
1396 "\n\t"
1397 "rol %[byte]"
1398 "\n\t"
1399 "sbrc %[byte], 7"
1400 "\n\t"
1401 "mov %[next], %[hi]"
1402 "\n\t"
1403 "nop"
1404 "\n\t"
1405 "out %[port], %[lo]"
1406 "\n\t"
1407 "ret"
1408 "\n\t"
1409 "doneB:"
1410 "\n"
1411 : [byte] "+r"(b), [next] "+r"(next), [count] "+w"(i)
1412 : [port] "I"(_SFR_IO_ADDR(PORTB)), [ptr] "e"(ptr),
1413 [hi] "r"(hi), [lo] "r"(lo));
1414
1415#if defined(PORTD) || defined(PORTC) || defined(PORTF)
1416 }
1417#endif
1418#if defined(PORTC) || defined(PORTF)
1419 else
1420#endif // defined(PORTC/F)
1421#endif // defined(PORTB)
1422
1423 // PORTC OUTPUT ----------------------------------------------------
1424
1425#if defined(PORTC)
1426#if defined(PORTD) || defined(PORTB) || defined(PORTF)
1427 if (port == &PORTC) {
1428#endif // defined(PORTD/B/F)
1429
1430 hi = PORTC | pinMask;
1431 lo = PORTC & ~pinMask;
1432 next = lo;
1433 if (b & 0x80)
1434 next = hi;
1435
1436 // Same as above, just set for PORTC & stripped of comments
1437 asm volatile("headC:"
1438 "\n\t"
1439 "out %[port], %[hi]"
1440 "\n\t"
1441 "rcall bitTimeC"
1442 "\n\t"
1443 "out %[port], %[hi]"
1444 "\n\t"
1445 "rcall bitTimeC"
1446 "\n\t"
1447 "out %[port], %[hi]"
1448 "\n\t"
1449 "rcall bitTimeC"
1450 "\n\t"
1451 "out %[port], %[hi]"
1452 "\n\t"
1453 "rcall bitTimeC"
1454 "\n\t"
1455 "out %[port], %[hi]"
1456 "\n\t"
1457 "rcall bitTimeC"
1458 "\n\t"
1459 "out %[port], %[hi]"
1460 "\n\t"
1461 "rcall bitTimeC"
1462 "\n\t"
1463 "out %[port], %[hi]"
1464 "\n\t"
1465 "rcall bitTimeC"
1466 "\n\t"
1467 "out %[port] , %[hi]"
1468 "\n\t"
1469 "rjmp .+0"
1470 "\n\t"
1471 "ld %[byte] , %a[ptr]+"
1472 "\n\t"
1473 "out %[port] , %[next]"
1474 "\n\t"
1475 "mov %[next] , %[lo]"
1476 "\n\t"
1477 "sbrc %[byte] , 7"
1478 "\n\t"
1479 "mov %[next] , %[hi]"
1480 "\n\t"
1481 "nop"
1482 "\n\t"
1483 "out %[port] , %[lo]"
1484 "\n\t"
1485 "sbiw %[count], 1"
1486 "\n\t"
1487 "brne headC"
1488 "\n\t"
1489 "rjmp doneC"
1490 "\n\t"
1491 "bitTimeC:"
1492 "\n\t"
1493 "out %[port], %[next]"
1494 "\n\t"
1495 "mov %[next], %[lo]"
1496 "\n\t"
1497 "rol %[byte]"
1498 "\n\t"
1499 "sbrc %[byte], 7"
1500 "\n\t"
1501 "mov %[next], %[hi]"
1502 "\n\t"
1503 "nop"
1504 "\n\t"
1505 "out %[port], %[lo]"
1506 "\n\t"
1507 "ret"
1508 "\n\t"
1509 "doneC:"
1510 "\n"
1511 : [byte] "+r"(b), [next] "+r"(next), [count] "+w"(i)
1512 : [port] "I"(_SFR_IO_ADDR(PORTC)), [ptr] "e"(ptr),
1513 [hi] "r"(hi), [lo] "r"(lo));
1514
1515#if defined(PORTD) || defined(PORTB) || defined(PORTF)
1516 }
1517#endif // defined(PORTD/B/F)
1518#if defined(PORTF)
1519 else
1520#endif
1521#endif // defined(PORTC)
1522
1523 // PORTF OUTPUT ----------------------------------------------------
1524
1525#if defined(PORTF)
1526#if defined(PORTD) || defined(PORTB) || defined(PORTC)
1527 if (port == &PORTF) {
1528#endif // defined(PORTD/B/C)
1529
1530 hi = PORTF | pinMask;
1531 lo = PORTF & ~pinMask;
1532 next = lo;
1533 if (b & 0x80)
1534 next = hi;
1535
1536 // Same as above, just set for PORTF & stripped of comments
1537 asm volatile("headF:"
1538 "\n\t"
1539 "out %[port], %[hi]"
1540 "\n\t"
1541 "rcall bitTimeC"
1542 "\n\t"
1543 "out %[port], %[hi]"
1544 "\n\t"
1545 "rcall bitTimeC"
1546 "\n\t"
1547 "out %[port], %[hi]"
1548 "\n\t"
1549 "rcall bitTimeC"
1550 "\n\t"
1551 "out %[port], %[hi]"
1552 "\n\t"
1553 "rcall bitTimeC"
1554 "\n\t"
1555 "out %[port], %[hi]"
1556 "\n\t"
1557 "rcall bitTimeC"
1558 "\n\t"
1559 "out %[port], %[hi]"
1560 "\n\t"
1561 "rcall bitTimeC"
1562 "\n\t"
1563 "out %[port], %[hi]"
1564 "\n\t"
1565 "rcall bitTimeC"
1566 "\n\t"
1567 "out %[port] , %[hi]"
1568 "\n\t"
1569 "rjmp .+0"
1570 "\n\t"
1571 "ld %[byte] , %a[ptr]+"
1572 "\n\t"
1573 "out %[port] , %[next]"
1574 "\n\t"
1575 "mov %[next] , %[lo]"
1576 "\n\t"
1577 "sbrc %[byte] , 7"
1578 "\n\t"
1579 "mov %[next] , %[hi]"
1580 "\n\t"
1581 "nop"
1582 "\n\t"
1583 "out %[port] , %[lo]"
1584 "\n\t"
1585 "sbiw %[count], 1"
1586 "\n\t"
1587 "brne headF"
1588 "\n\t"
1589 "rjmp doneC"
1590 "\n\t"
1591 "bitTimeC:"
1592 "\n\t"
1593 "out %[port], %[next]"
1594 "\n\t"
1595 "mov %[next], %[lo]"
1596 "\n\t"
1597 "rol %[byte]"
1598 "\n\t"
1599 "sbrc %[byte], 7"
1600 "\n\t"
1601 "mov %[next], %[hi]"
1602 "\n\t"
1603 "nop"
1604 "\n\t"
1605 "out %[port], %[lo]"
1606 "\n\t"
1607 "ret"
1608 "\n\t"
1609 "doneC:"
1610 "\n"
1611 : [byte] "+r"(b), [next] "+r"(next), [count] "+w"(i)
1612 : [port] "I"(_SFR_IO_ADDR(PORTF)), [ptr] "e"(ptr),
1613 [hi] "r"(hi), [lo] "r"(lo));
1614
1615#if defined(PORTD) || defined(PORTB) || defined(PORTC)
1616 }
1617#endif // defined(PORTD/B/C)
1618#endif // defined(PORTF)
1619
1620#if defined(NEO_KHZ400)
1621 } else { // 400 KHz
1622
1623 // 30 instruction clocks per bit: HHHHHHxxxxxxxxxLLLLLLLLLLLLLLL
1624 // ST instructions: ^ ^ ^ (T=0,6,15)
1625
1626 volatile uint8_t next, bit;
1627
1628 hi = *port | pinMask;
1629 lo = *port & ~pinMask;
1630 next = lo;
1631 bit = 8;
1632
1633 asm volatile("head30:"
1634 "\n\t" // Clk Pseudocode (T = 0)
1635 "st %a[port], %[hi]"
1636 "\n\t" // 2 PORT = hi (T = 2)
1637 "sbrc %[byte] , 7"
1638 "\n\t" // 1-2 if(b & 128)
1639 "mov %[next], %[hi]"
1640 "\n\t" // 0-1 next = hi (T = 4)
1641 "rjmp .+0"
1642 "\n\t" // 2 nop nop (T = 6)
1643 "st %a[port], %[next]"
1644 "\n\t" // 2 PORT = next (T = 8)
1645 "rjmp .+0"
1646 "\n\t" // 2 nop nop (T = 10)
1647 "rjmp .+0"
1648 "\n\t" // 2 nop nop (T = 12)
1649 "rjmp .+0"
1650 "\n\t" // 2 nop nop (T = 14)
1651 "nop"
1652 "\n\t" // 1 nop (T = 15)
1653 "st %a[port], %[lo]"
1654 "\n\t" // 2 PORT = lo (T = 17)
1655 "rjmp .+0"
1656 "\n\t" // 2 nop nop (T = 19)
1657 "dec %[bit]"
1658 "\n\t" // 1 bit-- (T = 20)
1659 "breq nextbyte30"
1660 "\n\t" // 1-2 if(bit == 0)
1661 "rol %[byte]"
1662 "\n\t" // 1 b <<= 1 (T = 22)
1663 "rjmp .+0"
1664 "\n\t" // 2 nop nop (T = 24)
1665 "rjmp .+0"
1666 "\n\t" // 2 nop nop (T = 26)
1667 "rjmp .+0"
1668 "\n\t" // 2 nop nop (T = 28)
1669 "rjmp head30"
1670 "\n\t" // 2 -> head30 (next bit out)
1671 "nextbyte30:"
1672 "\n\t" // (T = 22)
1673 "nop"
1674 "\n\t" // 1 nop (T = 23)
1675 "ldi %[bit] , 8"
1676 "\n\t" // 1 bit = 8 (T = 24)
1677 "ld %[byte] , %a[ptr]+"
1678 "\n\t" // 2 b = *ptr++ (T = 26)
1679 "sbiw %[count], 1"
1680 "\n\t" // 2 i-- (T = 28)
1681 "brne head30"
1682 "\n" // 1-2 if(i != 0) -> (next byte)
1683 : [port] "+e"(port), [byte] "+r"(b), [bit] "+r"(bit),
1684 [next] "+r"(next), [count] "+w"(i)
1685 : [hi] "r"(hi), [lo] "r"(lo), [ptr] "e"(ptr));
1686 }
1687#endif // NEO_KHZ400
1688
1689// 16 MHz(ish) AVR --------------------------------------------------------
1690#elif (F_CPU >= 15400000UL) && (F_CPU <= 19000000L)
1691
1692#if defined(NEO_KHZ400) // 800 KHz check needed only if 400 KHz support enabled
1693 if (is800KHz) {
1694#endif
1695
1696 // WS2811 and WS2812 have different hi/lo duty cycles; this is
1697 // similar but NOT an exact copy of the prior 400-on-8 code.
1698
1699 // 20 inst. clocks per bit: HHHHHxxxxxxxxLLLLLLL
1700 // ST instructions: ^ ^ ^ (T=0,5,13)
1701
1702 volatile uint8_t next, bit;
1703
1704 hi = *port | pinMask;
1705 lo = *port & ~pinMask;
1706 next = lo;
1707 bit = 8;
1708
1709 asm volatile("head20%=:"
1710 "\n\t" // Clk Pseudocode (T = 0)
1711 "st %a[port], %[hi]"
1712 "\n\t" // 2 PORT = hi (T = 2)
1713 "sbrc %[byte], 7"
1714 "\n\t" // 1-2 if(b & 128)
1715 "mov %[next], %[hi]"
1716 "\n\t" // 0-1 next = hi (T = 4)
1717 "dec %[bit]"
1718 "\n\t" // 1 bit-- (T = 5)
1719 "st %a[port], %[next]"
1720 "\n\t" // 2 PORT = next (T = 7)
1721 "mov %[next] , %[lo]"
1722 "\n\t" // 1 next = lo (T = 8)
1723 "breq nextbyte20%="
1724 "\n\t" // 1-2 if(bit == 0) (from dec above)
1725 "rol %[byte]"
1726 "\n\t" // 1 b <<= 1 (T = 10)
1727 "rjmp .+0"
1728 "\n\t" // 2 nop nop (T = 12)
1729 "nop"
1730 "\n\t" // 1 nop (T = 13)
1731 "st %a[port], %[lo]"
1732 "\n\t" // 2 PORT = lo (T = 15)
1733 "nop"
1734 "\n\t" // 1 nop (T = 16)
1735 "rjmp .+0"
1736 "\n\t" // 2 nop nop (T = 18)
1737 "rjmp head20%="
1738 "\n\t" // 2 -> head20 (next bit out)
1739 "nextbyte20%=:"
1740 "\n\t" // (T = 10)
1741 "ldi %[bit] , 8"
1742 "\n\t" // 1 bit = 8 (T = 11)
1743 "ld %[byte] , %a[ptr]+"
1744 "\n\t" // 2 b = *ptr++ (T = 13)
1745 "st %a[port], %[lo]"
1746 "\n\t" // 2 PORT = lo (T = 15)
1747 "nop"
1748 "\n\t" // 1 nop (T = 16)
1749 "sbiw %[count], 1"
1750 "\n\t" // 2 i-- (T = 18)
1751 "brne head20%="
1752 "\n" // 2 if(i != 0) -> (next byte)
1753 : [port] "+e"(port), [byte] "+r"(b), [bit] "+r"(bit),
1754 [next] "+r"(next), [count] "+w"(i)
1755 : [ptr] "e"(ptr), [hi] "r"(hi), [lo] "r"(lo));
1756
1757#if defined(NEO_KHZ400)
1758 } else { // 400 KHz
1759
1760 // The 400 KHz clock on 16 MHz MCU is the most 'relaxed' version.
1761
1762 // 40 inst. clocks per bit: HHHHHHHHxxxxxxxxxxxxLLLLLLLLLLLLLLLLLLLL
1763 // ST instructions: ^ ^ ^ (T=0,8,20)
1764
1765 volatile uint8_t next, bit;
1766
1767 hi = *port | pinMask;
1768 lo = *port & ~pinMask;
1769 next = lo;
1770 bit = 8;
1771
1772 asm volatile("head40%=:"
1773 "\n\t" // Clk Pseudocode (T = 0)
1774 "st %a[port], %[hi]"
1775 "\n\t" // 2 PORT = hi (T = 2)
1776 "sbrc %[byte] , 7"
1777 "\n\t" // 1-2 if(b & 128)
1778 "mov %[next] , %[hi]"
1779 "\n\t" // 0-1 next = hi (T = 4)
1780 "rjmp .+0"
1781 "\n\t" // 2 nop nop (T = 6)
1782 "rjmp .+0"
1783 "\n\t" // 2 nop nop (T = 8)
1784 "st %a[port], %[next]"
1785 "\n\t" // 2 PORT = next (T = 10)
1786 "rjmp .+0"
1787 "\n\t" // 2 nop nop (T = 12)
1788 "rjmp .+0"
1789 "\n\t" // 2 nop nop (T = 14)
1790 "rjmp .+0"
1791 "\n\t" // 2 nop nop (T = 16)
1792 "rjmp .+0"
1793 "\n\t" // 2 nop nop (T = 18)
1794 "rjmp .+0"
1795 "\n\t" // 2 nop nop (T = 20)
1796 "st %a[port], %[lo]"
1797 "\n\t" // 2 PORT = lo (T = 22)
1798 "nop"
1799 "\n\t" // 1 nop (T = 23)
1800 "mov %[next] , %[lo]"
1801 "\n\t" // 1 next = lo (T = 24)
1802 "dec %[bit]"
1803 "\n\t" // 1 bit-- (T = 25)
1804 "breq nextbyte40%="
1805 "\n\t" // 1-2 if(bit == 0)
1806 "rol %[byte]"
1807 "\n\t" // 1 b <<= 1 (T = 27)
1808 "nop"
1809 "\n\t" // 1 nop (T = 28)
1810 "rjmp .+0"
1811 "\n\t" // 2 nop nop (T = 30)
1812 "rjmp .+0"
1813 "\n\t" // 2 nop nop (T = 32)
1814 "rjmp .+0"
1815 "\n\t" // 2 nop nop (T = 34)
1816 "rjmp .+0"
1817 "\n\t" // 2 nop nop (T = 36)
1818 "rjmp .+0"
1819 "\n\t" // 2 nop nop (T = 38)
1820 "rjmp head40%="
1821 "\n\t" // 2 -> head40 (next bit out)
1822 "nextbyte40%=:"
1823 "\n\t" // (T = 27)
1824 "ldi %[bit] , 8"
1825 "\n\t" // 1 bit = 8 (T = 28)
1826 "ld %[byte] , %a[ptr]+"
1827 "\n\t" // 2 b = *ptr++ (T = 30)
1828 "rjmp .+0"
1829 "\n\t" // 2 nop nop (T = 32)
1830 "st %a[port], %[lo]"
1831 "\n\t" // 2 PORT = lo (T = 34)
1832 "rjmp .+0"
1833 "\n\t" // 2 nop nop (T = 36)
1834 "sbiw %[count], 1"
1835 "\n\t" // 2 i-- (T = 38)
1836 "brne head40%="
1837 "\n" // 1-2 if(i != 0) -> (next byte)
1838 : [port] "+e"(port), [byte] "+r"(b), [bit] "+r"(bit),
1839 [next] "+r"(next), [count] "+w"(i)
1840 : [ptr] "e"(ptr), [hi] "r"(hi), [lo] "r"(lo));
1841 }
1842#endif // NEO_KHZ400
1843
1844#else
1845#error "CPU SPEED NOT SUPPORTED"
1846#endif // end F_CPU ifdefs on __AVR__
1847
1848 // END AVR ----------------------------------------------------------------
1849
1850#elif defined(__arm__)
1851
1852 // ARM MCUs -- Teensy 3.0, 3.1, LC, Arduino Due, RP2040 -------------------
1853
1854#if defined(ARDUINO_ARCH_RP2040)
1855 // Use PIO
1856 rp2040Show(pixels, numBytes);
1857
1858#elif defined(TEENSYDUINO) && \
1859 defined(KINETISK) // Teensy 3.0, 3.1, 3.2, 3.5, 3.6
1860#define CYCLES_800_T0H (F_CPU / 4000000)
1861#define CYCLES_800_T1H (F_CPU / 1250000)
1862#define CYCLES_800 (F_CPU / 800000)
1863#define CYCLES_400_T0H (F_CPU / 2000000)
1864#define CYCLES_400_T1H (F_CPU / 833333)
1865#define CYCLES_400 (F_CPU / 400000)
1866
1867 uint8_t *p = pixels, *end = p + numBytes, pix, mask;
1868 volatile uint8_t *set = portSetRegister(pin), *clr = portClearRegister(pin);
1869 uint32_t cyc;
1870
1871 ARM_DEMCR |= ARM_DEMCR_TRCENA;
1872 ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
1873
1874#if defined(NEO_KHZ400) // 800 KHz check needed only if 400 KHz support enabled
1875 if (is800KHz) {
1876#endif
1877 cyc = ARM_DWT_CYCCNT + CYCLES_800;
1878 while (p < end) {
1879 pix = *p++;
1880 for (mask = 0x80; mask; mask >>= 1) {
1881 while (ARM_DWT_CYCCNT - cyc < CYCLES_800)
1882 ;
1883 cyc = ARM_DWT_CYCCNT;
1884 *set = 1;
1885 if (pix & mask) {
1886 while (ARM_DWT_CYCCNT - cyc < CYCLES_800_T1H)
1887 ;
1888 } else {
1889 while (ARM_DWT_CYCCNT - cyc < CYCLES_800_T0H)
1890 ;
1891 }
1892 *clr = 1;
1893 }
1894 }
1895 while (ARM_DWT_CYCCNT - cyc < CYCLES_800)
1896 ;
1897#if defined(NEO_KHZ400)
1898 } else { // 400 kHz bitstream
1899 cyc = ARM_DWT_CYCCNT + CYCLES_400;
1900 while (p < end) {
1901 pix = *p++;
1902 for (mask = 0x80; mask; mask >>= 1) {
1903 while (ARM_DWT_CYCCNT - cyc < CYCLES_400)
1904 ;
1905 cyc = ARM_DWT_CYCCNT;
1906 *set = 1;
1907 if (pix & mask) {
1908 while (ARM_DWT_CYCCNT - cyc < CYCLES_400_T1H)
1909 ;
1910 } else {
1911 while (ARM_DWT_CYCCNT - cyc < CYCLES_400_T0H)
1912 ;
1913 }
1914 *clr = 1;
1915 }
1916 }
1917 while (ARM_DWT_CYCCNT - cyc < CYCLES_400)
1918 ;
1919 }
1920#endif // NEO_KHZ400
1921
1922#elif defined(TEENSYDUINO) && (defined(__IMXRT1052__) || defined(__IMXRT1062__))
1923#define CYCLES_800_T0H (F_CPU_ACTUAL / 4000000)
1924#define CYCLES_800_T1H (F_CPU_ACTUAL / 1250000)
1925#define CYCLES_800 (F_CPU_ACTUAL / 800000)
1926#define CYCLES_400_T0H (F_CPU_ACTUAL / 2000000)
1927#define CYCLES_400_T1H (F_CPU_ACTUAL / 833333)
1928#define CYCLES_400 (F_CPU_ACTUAL / 400000)
1929
1930 uint8_t *p = pixels, *end = p + numBytes, pix, mask;
1931 volatile uint32_t *set = portSetRegister(pin),
1932 *clr = portClearRegister(pin);
1933 uint32_t cyc, msk = digitalPinToBitMask(pin);
1934
1935 ARM_DEMCR |= ARM_DEMCR_TRCENA;
1936 ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
1937
1938#if defined(NEO_KHZ400) // 800 KHz check needed only if 400 KHz support enabled
1939 if (is800KHz) {
1940#endif
1941 cyc = ARM_DWT_CYCCNT + CYCLES_800;
1942 while (p < end) {
1943 pix = *p++;
1944 for (mask = 0x80; mask; mask >>= 1) {
1945 while (ARM_DWT_CYCCNT - cyc < CYCLES_800)
1946 ;
1947 cyc = ARM_DWT_CYCCNT;
1948 *set = msk;
1949 if (pix & mask) {
1950 while (ARM_DWT_CYCCNT - cyc < CYCLES_800_T1H)
1951 ;
1952 } else {
1953 while (ARM_DWT_CYCCNT - cyc < CYCLES_800_T0H)
1954 ;
1955 }
1956 *clr = msk;
1957 }
1958 }
1959 while (ARM_DWT_CYCCNT - cyc < CYCLES_800)
1960 ;
1961#if defined(NEO_KHZ400)
1962 } else { // 400 kHz bitstream
1963 cyc = ARM_DWT_CYCCNT + CYCLES_400;
1964 while (p < end) {
1965 pix = *p++;
1966 for (mask = 0x80; mask; mask >>= 1) {
1967 while (ARM_DWT_CYCCNT - cyc < CYCLES_400)
1968 ;
1969 cyc = ARM_DWT_CYCCNT;
1970 *set = msk;
1971 if (pix & mask) {
1972 while (ARM_DWT_CYCCNT - cyc < CYCLES_400_T1H)
1973 ;
1974 } else {
1975 while (ARM_DWT_CYCCNT - cyc < CYCLES_400_T0H)
1976 ;
1977 }
1978 *clr = msk;
1979 }
1980 }
1981 while (ARM_DWT_CYCCNT - cyc < CYCLES_400)
1982 ;
1983 }
1984#endif // NEO_KHZ400
1985
1986#elif defined(TEENSYDUINO) && defined(__MKL26Z64__) // Teensy-LC
1987
1988#if F_CPU == 48000000
1989 uint8_t *p = pixels, pix, count, dly, bitmask = digitalPinToBitMask(pin);
1990 volatile uint8_t *reg = portSetRegister(pin);
1991 uint32_t num = numBytes;
1992 asm volatile("L%=_begin:"
1993 "\n\t"
1994 "ldrb %[pix], [%[p], #0]"
1995 "\n\t"
1996 "lsl %[pix], #24"
1997 "\n\t"
1998 "movs %[count], #7"
1999 "\n\t"
2000 "L%=_loop:"
2001 "\n\t"
2002 "lsl %[pix], #1"
2003 "\n\t"
2004 "bcs L%=_loop_one"
2005 "\n\t"
2006 "L%=_loop_zero:"
2007 "\n\t"
2008 "strb %[bitmask], [%[reg], #0]"
2009 "\n\t"
2010 "movs %[dly], #4"
2011 "\n\t"
2012 "L%=_loop_delay_T0H:"
2013 "\n\t"
2014 "sub %[dly], #1"
2015 "\n\t"
2016 "bne L%=_loop_delay_T0H"
2017 "\n\t"
2018 "strb %[bitmask], [%[reg], #4]"
2019 "\n\t"
2020 "movs %[dly], #13"
2021 "\n\t"
2022 "L%=_loop_delay_T0L:"
2023 "\n\t"
2024 "sub %[dly], #1"
2025 "\n\t"
2026 "bne L%=_loop_delay_T0L"
2027 "\n\t"
2028 "b L%=_next"
2029 "\n\t"
2030 "L%=_loop_one:"
2031 "\n\t"
2032 "strb %[bitmask], [%[reg], #0]"
2033 "\n\t"
2034 "movs %[dly], #13"
2035 "\n\t"
2036 "L%=_loop_delay_T1H:"
2037 "\n\t"
2038 "sub %[dly], #1"
2039 "\n\t"
2040 "bne L%=_loop_delay_T1H"
2041 "\n\t"
2042 "strb %[bitmask], [%[reg], #4]"
2043 "\n\t"
2044 "movs %[dly], #4"
2045 "\n\t"
2046 "L%=_loop_delay_T1L:"
2047 "\n\t"
2048 "sub %[dly], #1"
2049 "\n\t"
2050 "bne L%=_loop_delay_T1L"
2051 "\n\t"
2052 "nop"
2053 "\n\t"
2054 "L%=_next:"
2055 "\n\t"
2056 "sub %[count], #1"
2057 "\n\t"
2058 "bne L%=_loop"
2059 "\n\t"
2060 "lsl %[pix], #1"
2061 "\n\t"
2062 "bcs L%=_last_one"
2063 "\n\t"
2064 "L%=_last_zero:"
2065 "\n\t"
2066 "strb %[bitmask], [%[reg], #0]"
2067 "\n\t"
2068 "movs %[dly], #4"
2069 "\n\t"
2070 "L%=_last_delay_T0H:"
2071 "\n\t"
2072 "sub %[dly], #1"
2073 "\n\t"
2074 "bne L%=_last_delay_T0H"
2075 "\n\t"
2076 "strb %[bitmask], [%[reg], #4]"
2077 "\n\t"
2078 "movs %[dly], #10"
2079 "\n\t"
2080 "L%=_last_delay_T0L:"
2081 "\n\t"
2082 "sub %[dly], #1"
2083 "\n\t"
2084 "bne L%=_last_delay_T0L"
2085 "\n\t"
2086 "b L%=_repeat"
2087 "\n\t"
2088 "L%=_last_one:"
2089 "\n\t"
2090 "strb %[bitmask], [%[reg], #0]"
2091 "\n\t"
2092 "movs %[dly], #13"
2093 "\n\t"
2094 "L%=_last_delay_T1H:"
2095 "\n\t"
2096 "sub %[dly], #1"
2097 "\n\t"
2098 "bne L%=_last_delay_T1H"
2099 "\n\t"
2100 "strb %[bitmask], [%[reg], #4]"
2101 "\n\t"
2102 "movs %[dly], #1"
2103 "\n\t"
2104 "L%=_last_delay_T1L:"
2105 "\n\t"
2106 "sub %[dly], #1"
2107 "\n\t"
2108 "bne L%=_last_delay_T1L"
2109 "\n\t"
2110 "nop"
2111 "\n\t"
2112 "L%=_repeat:"
2113 "\n\t"
2114 "add %[p], #1"
2115 "\n\t"
2116 "sub %[num], #1"
2117 "\n\t"
2118 "bne L%=_begin"
2119 "\n\t"
2120 "L%=_done:"
2121 "\n\t"
2122 : [p] "+r"(p), [pix] "=&r"(pix), [count] "=&r"(count),
2123 [dly] "=&r"(dly), [num] "+r"(num)
2124 : [bitmask] "r"(bitmask), [reg] "r"(reg));
2125#else
2126#error "Sorry, only 48 MHz is supported, please set Tools > CPU Speed to 48 MHz"
2127#endif // F_CPU == 48000000
2128
2129 // Begin of support for nRF52 based boards -------------------------
2130
2131#elif defined(NRF52) || defined(NRF52_SERIES)
2132// [[[Begin of the Neopixel NRF52 EasyDMA implementation
2133// by the Hackerspace San Salvador]]]
2134// This technique uses the PWM peripheral on the NRF52. The PWM uses the
2135// EasyDMA feature included on the chip. This technique loads the duty
2136// cycle configuration for each cycle when the PWM is enabled. For this
2137// to work we need to store a 16 bit configuration for each bit of the
2138// RGB(W) values in the pixel buffer.
2139// Comparator values for the PWM were hand picked and are guaranteed to
2140// be 100% organic to preserve freshness and high accuracy. Current
2141// parameters are:
2142// * PWM Clock: 16Mhz
2143// * Minimum step time: 62.5ns
2144// * Time for zero in high (T0H): 0.31ms
2145// * Time for one in high (T1H): 0.75ms
2146// * Cycle time: 1.25us
2147// * Frequency: 800Khz
2148// For 400Khz we just double the calculated times.
2149// ---------- BEGIN Constants for the EasyDMA implementation -----------
2150// The PWM starts the duty cycle in LOW. To start with HIGH we
2151// need to set the 15th bit on each register.
2152
2153// WS2812 (rev A) timing is 0.35 and 0.7us
2154// #define MAGIC_T0H 5UL | (0x8000) // 0.3125us
2155// #define MAGIC_T1H 12UL | (0x8000) // 0.75us
2156
2157// WS2812B (rev B) timing is 0.4 and 0.8 us
2158#define MAGIC_T0H 6UL | (0x8000) // 0.375us
2159#define MAGIC_T1H 13UL | (0x8000) // 0.8125us
2160
2161// WS2811 (400 khz) timing is 0.5 and 1.2
2162#define MAGIC_T0H_400KHz 8UL | (0x8000) // 0.5us
2163#define MAGIC_T1H_400KHz 19UL | (0x8000) // 1.1875us
2164
2165// For 400Khz, we double value of CTOPVAL
2166#define CTOPVAL 20UL // 1.25us
2167#define CTOPVAL_400KHz 40UL // 2.5us
2168
2169// ---------- END Constants for the EasyDMA implementation -------------
2170//
2171// If there is no device available an alternative cycle-counter
2172// implementation is tried.
2173// The nRF52 runs with a fixed clock of 64Mhz. The alternative
2174// implementation is the same as the one used for the Teensy 3.0/1/2 but
2175// with the Nordic SDK HAL & registers syntax.
2176// The number of cycles was hand picked and is guaranteed to be 100%
2177// organic to preserve freshness and high accuracy.
2178// ---------- BEGIN Constants for cycle counter implementation ---------
2179#define CYCLES_800_T0H 18 // ~0.36 uS
2180#define CYCLES_800_T1H 41 // ~0.76 uS
2181#define CYCLES_800 71 // ~1.25 uS
2182
2183#define CYCLES_400_T0H 26 // ~0.50 uS
2184#define CYCLES_400_T1H 70 // ~1.26 uS
2185#define CYCLES_400 156 // ~2.50 uS
2186 // ---------- END of Constants for cycle counter implementation --------
2187
2188 // To support both the SoftDevice + Neopixels we use the EasyDMA
2189 // feature from the NRF25. However this technique implies to
2190 // generate a pattern and store it on the memory. The actual
2191 // memory used in bytes corresponds to the following formula:
2192 // totalMem = numBytes*8*2+(2*2)
2193 // The two additional bytes at the end are needed to reset the
2194 // sequence.
2195 //
2196 // If there is not enough memory, we will fall back to cycle counter
2197 // using DWT
2198 uint32_t pattern_size =
2199 numBytes * 8 * sizeof(uint16_t) + 2 * sizeof(uint16_t);
2200 uint16_t *pixels_pattern = NULL;
2201
2202 NRF_PWM_Type *pwm = NULL;
2203
2204 // Try to find a free PWM device, which is not enabled
2205 // and has no connected pins
2206 NRF_PWM_Type *PWM[] = {NRF_PWM0, NRF_PWM1, NRF_PWM2
2207#if defined(NRF_PWM3)
2208 ,
2209 NRF_PWM3
2210#endif
2211 };
2212
2213 for (unsigned int device = 0; device < (sizeof(PWM) / sizeof(PWM[0]));
2214 device++) {
2215 if ((PWM[device]->ENABLE == 0) &&
2216 (PWM[device]->PSEL.OUT[0] & PWM_PSEL_OUT_CONNECT_Msk) &&
2217 (PWM[device]->PSEL.OUT[1] & PWM_PSEL_OUT_CONNECT_Msk) &&
2218 (PWM[device]->PSEL.OUT[2] & PWM_PSEL_OUT_CONNECT_Msk) &&
2219 (PWM[device]->PSEL.OUT[3] & PWM_PSEL_OUT_CONNECT_Msk)) {
2220 pwm = PWM[device];
2221 break;
2222 }
2223 }
2224
2225 // only malloc if there is PWM device available
2226 if (pwm != NULL) {
2227#if defined(ARDUINO_NRF52_ADAFRUIT) // use thread-safe malloc
2228 pixels_pattern = (uint16_t *)rtos_malloc(pattern_size);
2229#else
2230 pixels_pattern = (uint16_t *)malloc(pattern_size);
2231#endif
2232 }
2233
2234 // Use the identified device to choose the implementation
2235 // If a PWM device is available use DMA
2236 if ((pixels_pattern != NULL) && (pwm != NULL)) {
2237 uint16_t pos = 0; // bit position
2238
2239 for (uint16_t n = 0; n < numBytes; n++) {
2240 uint8_t pix = pixels[n];
2241
2242 for (uint8_t mask = 0x80; mask > 0; mask >>= 1) {
2243#if defined(NEO_KHZ400)
2244 if (!is800KHz) {
2245 pixels_pattern[pos] =
2246 (pix & mask) ? MAGIC_T1H_400KHz : MAGIC_T0H_400KHz;
2247 } else
2248#endif
2249 {
2250 pixels_pattern[pos] = (pix & mask) ? MAGIC_T1H : MAGIC_T0H;
2251 }
2252
2253 pos++;
2254 }
2255 }
2256
2257 // Zero padding to indicate the end of que sequence
2258 pixels_pattern[pos++] = 0 | (0x8000); // Seq end
2259 pixels_pattern[pos++] = 0 | (0x8000); // Seq end
2260
2261 // Set the wave mode to count UP
2262 pwm->MODE = (PWM_MODE_UPDOWN_Up << PWM_MODE_UPDOWN_Pos);
2263
2264 // Set the PWM to use the 16MHz clock
2265 pwm->PRESCALER =
2266 (PWM_PRESCALER_PRESCALER_DIV_1 << PWM_PRESCALER_PRESCALER_Pos);
2267
2268 // Setting of the maximum count
2269 // but keeping it on 16Mhz allows for more granularity just
2270 // in case someone wants to do more fine-tuning of the timing.
2271#if defined(NEO_KHZ400)
2272 if (!is800KHz) {
2273 pwm->COUNTERTOP = (CTOPVAL_400KHz << PWM_COUNTERTOP_COUNTERTOP_Pos);
2274 } else
2275#endif
2276 {
2277 pwm->COUNTERTOP = (CTOPVAL << PWM_COUNTERTOP_COUNTERTOP_Pos);
2278 }
2279
2280 // Disable loops, we want the sequence to repeat only once
2281 pwm->LOOP = (PWM_LOOP_CNT_Disabled << PWM_LOOP_CNT_Pos);
2282
2283 // On the "Common" setting the PWM uses the same pattern for the
2284 // for supported sequences. The pattern is stored on half-word
2285 // of 16bits
2286 pwm->DECODER = (PWM_DECODER_LOAD_Common << PWM_DECODER_LOAD_Pos) |
2287 (PWM_DECODER_MODE_RefreshCount << PWM_DECODER_MODE_Pos);
2288
2289 // Pointer to the memory storing the patter
2290 pwm->SEQ[0].PTR = (uint32_t)(pixels_pattern) << PWM_SEQ_PTR_PTR_Pos;
2291
2292 // Calculation of the number of steps loaded from memory.
2293 pwm->SEQ[0].CNT = (pattern_size / sizeof(uint16_t))
2294 << PWM_SEQ_CNT_CNT_Pos;
2295
2296 // The following settings are ignored with the current config.
2297 pwm->SEQ[0].REFRESH = 0;
2298 pwm->SEQ[0].ENDDELAY = 0;
2299
2300 // The Neopixel implementation is a blocking algorithm. DMA
2301 // allows for non-blocking operation. To "simulate" a blocking
2302 // operation we enable the interruption for the end of sequence
2303 // and block the execution thread until the event flag is set by
2304 // the peripheral.
2305 // pwm->INTEN |= (PWM_INTEN_SEQEND0_Enabled<<PWM_INTEN_SEQEND0_Pos);
2306
2307// PSEL must be configured before enabling PWM
2308#if defined(ARDUINO_ARCH_NRF52840)
2309 pwm->PSEL.OUT[0] = g_APinDescription[pin].name;
2310#else
2311 pwm->PSEL.OUT[0] = g_ADigitalPinMap[pin];
2312#endif
2313
2314 // Enable the PWM
2315 pwm->ENABLE = 1;
2316
2317 // After all of this and many hours of reading the documentation
2318 // we are ready to start the sequence...
2319 pwm->EVENTS_SEQEND[0] = 0;
2320 pwm->TASKS_SEQSTART[0] = 1;
2321
2322 // But we have to wait for the flag to be set.
2323 while (!pwm->EVENTS_SEQEND[0]) {
2324#if defined(ARDUINO_NRF52_ADAFRUIT) || defined(ARDUINO_ARCH_NRF52840)
2325 yield();
2326#endif
2327 }
2328
2329 // Before leave we clear the flag for the event.
2330 pwm->EVENTS_SEQEND[0] = 0;
2331
2332 // We need to disable the device and disconnect
2333 // all the outputs before leave or the device will not
2334 // be selected on the next call.
2335 // TODO: Check if disabling the device causes performance issues.
2336 pwm->ENABLE = 0;
2337
2338 pwm->PSEL.OUT[0] = 0xFFFFFFFFUL;
2339
2340#if defined(ARDUINO_NRF52_ADAFRUIT) // use thread-safe free
2341 rtos_free(pixels_pattern);
2342#else
2343 free(pixels_pattern);
2344#endif
2345 } // End of DMA implementation
2346 // ---------------------------------------------------------------------
2347 else {
2348#ifndef ARDUINO_ARCH_NRF52840
2349// Fall back to DWT
2350#if defined(ARDUINO_NRF52_ADAFRUIT)
2351 // Bluefruit Feather 52 uses freeRTOS
2352 // Critical Section is used since it does not block SoftDevice execution
2353 taskENTER_CRITICAL();
2354#elif defined(NRF52_DISABLE_INT)
2355 // If you are using the Bluetooth SoftDevice we advise you to not
2356 // disable the interrupts. Disabling the interrupts even for short
2357 // periods of time causes the SoftDevice to stop working. Disable the
2358 // interrupts only in cases where you need high performance for the LEDs
2359 // and if you are not using the EasyDMA feature.
2360 __disable_irq();
2361#endif
2362
2363 NRF_GPIO_Type *nrf_port = (NRF_GPIO_Type *)digitalPinToPort(pin);
2364 uint32_t pinMask = digitalPinToBitMask(pin);
2365
2366 uint32_t CYCLES_X00 = CYCLES_800;
2367 uint32_t CYCLES_X00_T1H = CYCLES_800_T1H;
2368 uint32_t CYCLES_X00_T0H = CYCLES_800_T0H;
2369
2370#if defined(NEO_KHZ400)
2371 if (!is800KHz) {
2372 CYCLES_X00 = CYCLES_400;
2373 CYCLES_X00_T1H = CYCLES_400_T1H;
2374 CYCLES_X00_T0H = CYCLES_400_T0H;
2375 }
2376#endif
2377
2378 // Enable DWT in debug core
2379 CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
2380 DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
2381
2382 // Tries to re-send the frame if is interrupted by the SoftDevice.
2383 while (1) {
2384 uint8_t *p = pixels;
2385
2386 uint32_t cycStart = DWT->CYCCNT;
2387 uint32_t cyc = 0;
2388
2389 for (uint16_t n = 0; n < numBytes; n++) {
2390 uint8_t pix = *p++;
2391
2392 for (uint8_t mask = 0x80; mask; mask >>= 1) {
2393 while (DWT->CYCCNT - cyc < CYCLES_X00)
2394 ;
2395 cyc = DWT->CYCCNT;
2396
2397 nrf_port->OUTSET |= pinMask;
2398
2399 if (pix & mask) {
2400 while (DWT->CYCCNT - cyc < CYCLES_X00_T1H)
2401 ;
2402 } else {
2403 while (DWT->CYCCNT - cyc < CYCLES_X00_T0H)
2404 ;
2405 }
2406
2407 nrf_port->OUTCLR |= pinMask;
2408 }
2409 }
2410 while (DWT->CYCCNT - cyc < CYCLES_X00)
2411 ;
2412
2413 // If total time longer than 25%, resend the whole data.
2414 // Since we are likely to be interrupted by SoftDevice
2415 if ((DWT->CYCCNT - cycStart) <
2416 (8 * numBytes * ((CYCLES_X00 * 5) / 4))) {
2417 break;
2418 }
2419
2420 // re-send need 300us delay
2421 delayMicroseconds(300);
2422 }
2423
2424// Enable interrupts again
2425#if defined(ARDUINO_NRF52_ADAFRUIT)
2426 taskEXIT_CRITICAL();
2427#elif defined(NRF52_DISABLE_INT)
2428 __enable_irq();
2429#endif
2430#endif
2431 }
2432 // END of NRF52 implementation
2433
2434#elif defined(__SAMD21E17A__) || defined(__SAMD21G18A__) || \
2435 defined(__SAMD21E18A__) || defined(__SAMD21J18A__) || \
2436 defined(__SAMD11C14A__) || defined(__SAMD21G17A__)
2437 // Arduino Zero, Gemma/Trinket M0, SODAQ Autonomo
2438 // and others
2439 // Tried this with a timer/counter, couldn't quite get adequate
2440 // resolution. So yay, you get a load of goofball NOPs...
2441
2442 uint8_t *ptr, *end, p, bitMask, portNum;
2443 uint32_t pinMask;
2444
2445 portNum = g_APinDescription[pin].ulPort;
2446 pinMask = 1ul << g_APinDescription[pin].ulPin;
2447 ptr = pixels;
2448 end = ptr + numBytes;
2449 p = *ptr++;
2450 bitMask = 0x80;
2451
2452 volatile uint32_t *set = &(PORT->Group[portNum].OUTSET.reg),
2453 *clr = &(PORT->Group[portNum].OUTCLR.reg);
2454
2455#if defined(NEO_KHZ400) // 800 KHz check needed only if 400 KHz support enabled
2456 if (is800KHz) {
2457#endif
2458 for (;;) {
2459 *set = pinMask;
2460 asm("nop; nop; nop; nop; nop; nop; nop; nop;");
2461 if (p & bitMask) {
2462 asm("nop; nop; nop; nop; nop; nop; nop; nop;"
2463 "nop; nop; nop; nop; nop; nop; nop; nop;"
2464 "nop; nop; nop; nop;");
2465 *clr = pinMask;
2466 } else {
2467 *clr = pinMask;
2468 asm("nop; nop; nop; nop; nop; nop; nop; nop;"
2469 "nop; nop; nop; nop; nop; nop; nop; nop;"
2470 "nop; nop; nop; nop;");
2471 }
2472 if (bitMask >>= 1) {
2473 asm("nop; nop; nop; nop; nop; nop; nop; nop; nop;");
2474 } else {
2475 if (ptr >= end)
2476 break;
2477 p = *ptr++;
2478 bitMask = 0x80;
2479 }
2480 }
2481#if defined(NEO_KHZ400)
2482 } else { // 400 KHz bitstream
2483 for (;;) {
2484 *set = pinMask;
2485 asm("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;");
2486 if (p & bitMask) {
2487 asm("nop; nop; nop; nop; nop; nop; nop; nop;"
2488 "nop; nop; nop; nop; nop; nop; nop; nop;"
2489 "nop; nop; nop; nop; nop; nop; nop; nop;"
2490 "nop; nop; nop;");
2491 *clr = pinMask;
2492 } else {
2493 *clr = pinMask;
2494 asm("nop; nop; nop; nop; nop; nop; nop; nop;"
2495 "nop; nop; nop; nop; nop; nop; nop; nop;"
2496 "nop; nop; nop; nop; nop; nop; nop; nop;"
2497 "nop; nop; nop;");
2498 }
2499 asm("nop; nop; nop; nop; nop; nop; nop; nop;"
2500 "nop; nop; nop; nop; nop; nop; nop; nop;"
2501 "nop; nop; nop; nop; nop; nop; nop; nop;"
2502 "nop; nop; nop; nop; nop; nop; nop; nop;");
2503 if (bitMask >>= 1) {
2504 asm("nop; nop; nop; nop; nop; nop; nop;");
2505 } else {
2506 if (ptr >= end)
2507 break;
2508 p = *ptr++;
2509 bitMask = 0x80;
2510 }
2511 }
2512 }
2513#endif
2514
2515//----
2516#elif defined(XMC1100_XMC2GO) || defined(XMC1400_XMC2GO) || \
2517 defined(XMC1400_Arduino_Kit) || defined(XMC1100_H_BRIDGE2GO) || \
2518 defined(XMC1100_Boot_Kit) || defined(XMC1300_Boot_Kit)
2519
2520 // XMC1100/1200/1300 with ARM Cortex M0 are running with 32MHz, XMC1400 runs
2521 // with 48MHz so may not work Tried this with a timer/counter, couldn't
2522 // quite get adequate resolution. So yay, you get a load of goofball
2523 // NOPs...
2524
2525 uint8_t *ptr, *end, p, bitMask, portNum;
2526 uint32_t pinMask;
2527
2528 ptr = pixels;
2529 end = ptr + numBytes;
2530 p = *ptr++;
2531 bitMask = 0x80;
2532
2533 XMC_GPIO_PORT_t *XMC_port = mapping_port_pin[pin].port;
2534 uint8_t XMC_pin = mapping_port_pin[pin].pin;
2535
2536 uint32_t omrhigh = (uint32_t)XMC_GPIO_OUTPUT_LEVEL_HIGH << XMC_pin;
2537 uint32_t omrlow = (uint32_t)XMC_GPIO_OUTPUT_LEVEL_LOW << XMC_pin;
2538
2539#ifdef NEO_KHZ400 // 800 KHz check needed only if 400 KHz support enabled
2540 if (is800KHz) {
2541#endif
2542 for (;;) {
2543 XMC_port->OMR = omrhigh;
2544 asm("nop; nop; nop; nop;");
2545 if (p & bitMask) {
2546 asm("nop; nop; nop; nop; nop; nop; nop; nop;"
2547 "nop; nop;");
2548 XMC_port->OMR = omrlow;
2549 } else {
2550 XMC_port->OMR = omrlow;
2551 asm("nop; nop; nop; nop; nop; nop; nop; nop;"
2552 "nop; nop;");
2553 }
2554 if (bitMask >>= 1) {
2555 asm("nop; nop; nop; nop; nop;");
2556 } else {
2557 if (ptr >= end)
2558 break;
2559 p = *ptr++;
2560 bitMask = 0x80;
2561 }
2562 }
2563#ifdef NEO_KHZ400 // untested code
2564 } else { // 400 KHz bitstream
2565 for (;;) {
2566 XMC_port->OMR = omrhigh;
2567 asm("nop; nop; nop; nop; nop;");
2568 if (p & bitMask) {
2569 asm("nop; nop; nop; nop; nop; nop; nop; nop;"
2570 "nop; nop; nop; nop; nop;");
2571 XMC_port->OMR = omrlow;
2572 } else {
2573 XMC_port->OMR = omrlow;
2574 asm("nop; nop; nop; nop; nop; nop; nop; nop;"
2575 "nop; nop; nop; nop; nop;");
2576 }
2577 asm("nop; nop; nop; nop; nop; nop; nop; nop;"
2578 "nop; nop; nop; nop; nop; nop; nop; nop;");
2579 if (bitMask >>= 1) {
2580 asm("nop; nop; nop;");
2581 } else {
2582 if (ptr >= end)
2583 break;
2584 p = *ptr++;
2585 bitMask = 0x80;
2586 }
2587 }
2588 }
2589
2590#endif
2591//----
2592
2593//----
2594#elif defined(XMC4700_Relax_Kit) || defined(XMC4800_Relax_Kit)
2595
2596 // XMC4700 and XMC4800 with ARM Cortex M4 are running with 144MHz
2597 // Tried this with a timer/counter, couldn't quite get adequate
2598 // resolution. So yay, you get a load of goofball NOPs...
2599
2600 uint8_t *ptr, *end, p, bitMask, portNum;
2601 uint32_t pinMask;
2602
2603 ptr = pixels;
2604 end = ptr + numBytes;
2605 p = *ptr++;
2606 bitMask = 0x80;
2607
2608 XMC_GPIO_PORT_t *XMC_port = mapping_port_pin[pin].port;
2609 uint8_t XMC_pin = mapping_port_pin[pin].pin;
2610
2611 uint32_t omrhigh = (uint32_t)XMC_GPIO_OUTPUT_LEVEL_HIGH << XMC_pin;
2612 uint32_t omrlow = (uint32_t)XMC_GPIO_OUTPUT_LEVEL_LOW << XMC_pin;
2613
2614#ifdef NEO_KHZ400 // 800 KHz check needed only if 400 KHz support enabled
2615 if (is800KHz) {
2616#endif
2617
2618 for (;;) {
2619 XMC_port->OMR = omrhigh;
2620 asm("nop; nop; nop; nop; nop; nop; nop; nop;"
2621 "nop; nop; nop; nop; nop; nop; nop; nop;"
2622 "nop; nop; nop; nop; nop; nop; nop; nop;"
2623 "nop; nop; nop; nop; nop; nop; nop; nop;"
2624 "nop; nop; nop; nop; nop; nop; nop; nop;"
2625 "nop; nop; nop; nop; nop; nop; nop; nop;"
2626 "nop; nop; nop; nop;");
2627 if (p & bitMask) {
2628 asm("nop; nop; nop; nop; nop; nop; nop; nop;"
2629 "nop; nop; nop; nop; nop; nop; nop; nop;"
2630 "nop; nop; nop; nop; nop; nop; nop; nop;"
2631 "nop; nop; nop; nop; nop; nop; nop; nop;"
2632 "nop; nop; nop; nop; nop; nop; nop; nop;"
2633 "nop; nop; nop; nop; nop; nop; nop; nop;"
2634 "nop; nop; nop; nop; nop; nop; nop; nop;"
2635 "nop; nop; nop; nop; nop; nop; nop; nop;"
2636 "nop; nop; nop; nop; nop; nop; nop; nop;"
2637 "nop; nop; nop; nop; nop; nop; nop; nop;"
2638 "nop; nop; nop; nop; nop; nop; nop; nop;"
2639 "nop; nop; nop; nop; nop; nop; nop; nop;"
2640 "nop; nop; nop; nop; nop; nop; nop; nop;");
2641 XMC_port->OMR = omrlow;
2642 } else {
2643 XMC_port->OMR = omrlow;
2644 asm("nop; nop; nop; nop; nop; nop; nop; nop;"
2645 "nop; nop; nop; nop; nop; nop; nop; nop;"
2646 "nop; nop; nop; nop; nop; nop; nop; nop;"
2647 "nop; nop; nop; nop; nop; nop; nop; nop;"
2648 "nop; nop; nop; nop; nop; nop; nop; nop;"
2649 "nop; nop; nop; nop; nop; nop; nop; nop;"
2650 "nop; nop; nop; nop; nop; nop; nop; nop;"
2651 "nop; nop; nop; nop; nop; nop; nop; nop;"
2652 "nop; nop; nop; nop; nop; nop; nop; nop;"
2653 "nop; nop; nop; nop; nop; nop; nop; nop;"
2654 "nop; nop; nop; nop; nop; nop; nop; nop;"
2655 "nop; nop; nop; nop; nop; nop; nop; nop;"
2656 "nop; nop; nop; nop; nop; nop; nop; nop;");
2657 }
2658 if (bitMask >>= 1) {
2659 asm("nop; nop; nop; nop; nop; nop; nop; nop;"
2660 "nop; nop; nop; nop; nop; nop; nop; nop;"
2661 "nop; nop; nop; nop; nop; nop; nop; nop;"
2662 "nop; nop; nop; nop; nop; nop; nop; nop;"
2663 "nop; nop; nop; nop; nop; nop; nop; nop;"
2664 "nop; nop; nop; nop; nop; nop; nop; nop;"
2665 "nop; nop; nop; nop; nop; nop; nop; nop;"
2666 "nop; nop; nop; nop; nop; nop; nop; nop;"
2667 "nop; nop; nop; nop; nop; nop; nop; nop;"
2668 "nop; nop; nop; nop; nop; nop; nop; nop;"
2669 "nop; nop; nop; nop; nop; nop; nop; nop;");
2670 } else {
2671 if (ptr >= end)
2672 break;
2673 p = *ptr++;
2674 bitMask = 0x80;
2675 }
2676 }
2677
2678#ifdef NEO_KHZ400
2679 } else { // 400 KHz bitstream
2680 // ToDo!
2681 }
2682#endif
2683 //----
2684
2685#elif defined(__SAMD51__) // M4
2686
2687 uint8_t *ptr, *end, p, bitMask, portNum;
2688 uint32_t pinMask;
2689
2690 portNum = g_APinDescription[pin].ulPort;
2691 pinMask = 1ul << g_APinDescription[pin].ulPin;
2692 ptr = pixels;
2693 end = ptr + numBytes;
2694 p = *ptr++;
2695 bitMask = 0x80;
2696
2697 volatile uint32_t *set = &(PORT->Group[portNum].OUTSET.reg),
2698 *clr = &(PORT->Group[portNum].OUTCLR.reg);
2699
2700 // SAMD51 overclock-compatible timing is only a mild abomination.
2701 // It uses SysTick for a consistent clock reference regardless of
2702 // optimization / cache settings. That's the good news. The bad news,
2703 // since SysTick->VAL is a volatile type it's slow to access...and then,
2704 // with the SysTick interval that Arduino sets up (1 ms), this would
2705 // require a subtract and MOD operation for gauging elapsed time, and
2706 // all taken in combination that lacks adequate temporal resolution
2707 // for NeoPixel timing. So a kind of horrible thing is done here...
2708 // since interrupts are turned off anyway and it's generally accepted
2709 // by now that we're gonna lose track of time in the NeoPixel lib,
2710 // the SysTick timer is reconfigured for a period matching the NeoPixel
2711 // bit timing (either 800 or 400 KHz) and we watch SysTick->VAL very
2712 // closely (just a threshold, no subtract or MOD or anything) and that
2713 // seems to work just well enough. When finished, the SysTick
2714 // peripheral is set back to its original state.
2715
2716 uint32_t t0, t1, top, ticks, saveLoad = SysTick->LOAD,
2717 saveVal = SysTick->VAL;
2718
2719#if defined(NEO_KHZ400) // 800 KHz check needed only if 400 KHz support enabled
2720 if (is800KHz) {
2721#endif
2722 top = (uint32_t)(F_CPU * 0.00000125); // Bit hi + lo = 1.25 uS
2723 t0 = top - (uint32_t)(F_CPU * 0.00000040); // 0 = 0.4 uS hi
2724 t1 = top - (uint32_t)(F_CPU * 0.00000080); // 1 = 0.8 uS hi
2725#if defined(NEO_KHZ400)
2726 } else { // 400 KHz bitstream
2727 top = (uint32_t)(F_CPU * 0.00000250); // Bit hi + lo = 2.5 uS
2728 t0 = top - (uint32_t)(F_CPU * 0.00000050); // 0 = 0.5 uS hi
2729 t1 = top - (uint32_t)(F_CPU * 0.00000120); // 1 = 1.2 uS hi
2730 }
2731#endif
2732
2733 SysTick->LOAD = top; // Config SysTick for NeoPixel bit freq
2734 SysTick->VAL = top; // Set to start value (counts down)
2735 (void)SysTick->VAL; // Dummy read helps sync up 1st bit
2736
2737 for (;;) {
2738 *set = pinMask; // Set output high
2739 ticks = (p & bitMask) ? t1 : t0; // SysTick threshold,
2740 while (SysTick->VAL > ticks)
2741 ; // wait for it
2742 *clr = pinMask; // Set output low
2743 if (!(bitMask >>= 1)) { // Next bit for this byte...done?
2744 if (ptr >= end)
2745 break; // If last byte sent, exit loop
2746 p = *ptr++; // Fetch next byte
2747 bitMask = 0x80; // Reset bitmask
2748 }
2749 while (SysTick->VAL <= ticks)
2750 ; // Wait for rollover to 'top'
2751 }
2752
2753 SysTick->LOAD = saveLoad; // Restore SysTick rollover to 1 ms
2754 SysTick->VAL = saveVal; // Restore SysTick value
2755
2756#elif defined(ARDUINO_STM32_FEATHER) // FEATHER WICED (120MHz)
2757
2758 // Tried this with a timer/counter, couldn't quite get adequate
2759 // resolution. So yay, you get a load of goofball NOPs...
2760
2761 uint8_t *ptr, *end, p, bitMask;
2762 uint32_t pinMask;
2763
2764 pinMask = BIT(PIN_MAP[pin].gpio_bit);
2765 ptr = pixels;
2766 end = ptr + numBytes;
2767 p = *ptr++;
2768 bitMask = 0x80;
2769
2770 volatile uint16_t *set = &(PIN_MAP[pin].gpio_device->regs->BSRRL);
2771 volatile uint16_t *clr = &(PIN_MAP[pin].gpio_device->regs->BSRRH);
2772
2773#if defined(NEO_KHZ400) // 800 KHz check needed only if 400 KHz support enabled
2774 if (is800KHz) {
2775#endif
2776 for (;;) {
2777 if (p & bitMask) { // ONE
2778 // High 800ns
2779 *set = pinMask;
2780 asm("nop; nop; nop; nop; nop; nop; nop; nop;"
2781 "nop; nop; nop; nop; nop; nop; nop; nop;"
2782 "nop; nop; nop; nop; nop; nop; nop; nop;"
2783 "nop; nop; nop; nop; nop; nop; nop; nop;"
2784 "nop; nop; nop; nop; nop; nop; nop; nop;"
2785 "nop; nop; nop; nop; nop; nop; nop; nop;"
2786 "nop; nop; nop; nop; nop; nop; nop; nop;"
2787 "nop; nop; nop; nop; nop; nop; nop; nop;"
2788 "nop; nop; nop; nop; nop; nop; nop; nop;"
2789 "nop; nop; nop; nop; nop; nop; nop; nop;"
2790 "nop; nop; nop; nop; nop; nop; nop; nop;"
2791 "nop; nop; nop; nop; nop; nop;");
2792 // Low 450ns
2793 *clr = pinMask;
2794 asm("nop; nop; nop; nop; nop; nop; nop; nop;"
2795 "nop; nop; nop; nop; nop; nop; nop; nop;"
2796 "nop; nop; nop; nop; nop; nop; nop; nop;"
2797 "nop; nop; nop; nop; nop; nop; nop; nop;"
2798 "nop; nop; nop; nop; nop; nop;");
2799 } else { // ZERO
2800 // High 400ns
2801 *set = pinMask;
2802 asm("nop; nop; nop; nop; nop; nop; nop; nop;"
2803 "nop; nop; nop; nop; nop; nop; nop; nop;"
2804 "nop; nop; nop; nop; nop; nop; nop; nop;"
2805 "nop; nop; nop; nop; nop; nop; nop; nop;"
2806 "nop; nop; nop; nop; nop; nop; nop; nop;"
2807 "nop;");
2808 // Low 850ns
2809 *clr = pinMask;
2810 asm("nop; nop; nop; nop; nop; nop; nop; nop;"
2811 "nop; nop; nop; nop; nop; nop; nop; nop;"
2812 "nop; nop; nop; nop; nop; nop; nop; nop;"
2813 "nop; nop; nop; nop; nop; nop; nop; nop;"
2814 "nop; nop; nop; nop; nop; nop; nop; nop;"
2815 "nop; nop; nop; nop; nop; nop; nop; nop;"
2816 "nop; nop; nop; nop; nop; nop; nop; nop;"
2817 "nop; nop; nop; nop; nop; nop; nop; nop;"
2818 "nop; nop; nop; nop; nop; nop; nop; nop;"
2819 "nop; nop; nop; nop; nop; nop; nop; nop;"
2820 "nop; nop; nop; nop; nop; nop; nop; nop;"
2821 "nop; nop; nop; nop;");
2822 }
2823 if (bitMask >>= 1) {
2824 // Move on to the next pixel
2825 asm("nop;");
2826 } else {
2827 if (ptr >= end)
2828 break;
2829 p = *ptr++;
2830 bitMask = 0x80;
2831 }
2832 }
2833#if defined(NEO_KHZ400)
2834 } else { // 400 KHz bitstream
2835 // ToDo!
2836 }
2837#endif
2838
2839#elif defined(TARGET_LPC1768)
2840 uint8_t *ptr, *end, p, bitMask;
2841 ptr = pixels;
2842 end = ptr + numBytes;
2843 p = *ptr++;
2844 bitMask = 0x80;
2845
2846#if defined(NEO_KHZ400) // 800 KHz check needed only if 400 KHz support enabled
2847 if (is800KHz) {
2848#endif
2849 for (;;) {
2850 if (p & bitMask) {
2851 // data ONE high
2852 // min: 550 typ: 700 max: 5,500
2853 gpio_set(pin);
2854 time::delay_ns(550);
2855 // min: 450 typ: 600 max: 5,000
2856 gpio_clear(pin);
2857 time::delay_ns(450);
2858 } else {
2859 // data ZERO high
2860 // min: 200 typ: 350 max: 500
2861 gpio_set(pin);
2862 time::delay_ns(200);
2863 // data low
2864 // min: 450 typ: 600 max: 5,000
2865 gpio_clear(pin);
2866 time::delay_ns(450);
2867 }
2868 if (bitMask >>= 1) {
2869 // Move on to the next pixel
2870 asm("nop;");
2871 } else {
2872 if (ptr >= end)
2873 break;
2874 p = *ptr++;
2875 bitMask = 0x80;
2876 }
2877 }
2878#if defined(NEO_KHZ400)
2879 } else { // 400 KHz bitstream
2880 // ToDo!
2881 }
2882#endif
2883#elif defined(ARDUINO_ARCH_STM32) || \
2884 defined(ARDUINO_ARCH_ARDUINO_CORE_STM32) || defined(_PY32_DEF_)
2885 uint8_t *p = pixels, *end = p + numBytes, pix = *p++, mask = 0x80;
2886 uint32_t cyc;
2887 uint32_t saveLoad = SysTick->LOAD, saveVal = SysTick->VAL;
2888#if defined(NEO_KHZ400) // 800 KHz check needed only if 400 KHz support enabled
2889 if (is800KHz) {
2890#endif
2891 uint32_t top = (F_CPU / 800000); // 1.25µs
2892 uint32_t t0 = top - (F_CPU / 2500000); // 0.4µs
2893 uint32_t t1 = top - (F_CPU / 1250000); // 0.8µs
2894 SysTick->LOAD = top - 1; // Config SysTick for NeoPixel bit freq
2895 SysTick->VAL = 0; // Set to start value
2896 for (;;) {
2897 LL_GPIO_SetOutputPin(gpioPort, gpioPin);
2898 cyc = (pix & mask) ? t1 : t0;
2899 while (SysTick->VAL > cyc)
2900 ;
2901 LL_GPIO_ResetOutputPin(gpioPort, gpioPin);
2902 if (!(mask >>= 1)) {
2903 if (p >= end)
2904 break;
2905 pix = *p++;
2906 mask = 0x80;
2907 }
2908 while (SysTick->VAL <= cyc)
2909 ;
2910 }
2911#if defined(NEO_KHZ400)
2912 } else { // 400 kHz bitstream
2913 uint32_t top = (F_CPU / 400000); // 2.5µs
2914 uint32_t t0 = top - (F_CPU / 2000000); // 0.5µs
2915 uint32_t t1 = top - (F_CPU / 833333); // 1.2µs
2916 SysTick->LOAD = top - 1; // Config SysTick for NeoPixel bit freq
2917 SysTick->VAL = 0; // Set to start value
2918 for (;;) {
2919 LL_GPIO_SetOutputPin(gpioPort, gpioPin);
2920 cyc = (pix & mask) ? t1 : t0;
2921 while (SysTick->VAL > cyc)
2922 ;
2923 LL_GPIO_ResetOutputPin(gpioPort, gpioPin);
2924 if (!(mask >>= 1)) {
2925 if (p >= end)
2926 break;
2927 pix = *p++;
2928 mask = 0x80;
2929 }
2930 while (SysTick->VAL <= cyc)
2931 ;
2932 }
2933 }
2934#endif // NEO_KHZ400
2935 SysTick->LOAD = saveLoad; // Restore SysTick rollover to 1 ms
2936 SysTick->VAL = saveVal; // Restore SysTick value
2937#elif defined(NRF51)
2938 uint8_t *p = pixels, pix, count, mask;
2939 int32_t num = numBytes;
2940 unsigned int bitmask = (1 << g_ADigitalPinMap[pin]);
2941 // https://github.com/sandeepmistry/arduino-nRF5/blob/dc53980c8bac27898fca90d8ecb268e11111edc1/variants/BBCmicrobit/variant.cpp
2942
2943 // volatile unsigned int *reg = (unsigned int *)(0x50000000UL + 0x508);
2944 volatile uint32_t *reg =
2945 (uint32_t *)(NRF_GPIO_BASE + offsetof(NRF_GPIO_Type, OUTSET));
2946
2947 // https://github.com/sandeepmistry/arduino-nRF5/blob/dc53980c8bac27898fca90d8ecb268e11111edc1/cores/nRF5/SDK/components/device/nrf51.h
2948 // http://www.iot-programmer.com/index.php/books/27-micro-bit-iot-in-c/chapters-micro-bit-iot-in-c/47-micro-bit-iot-in-c-fast-memory-mapped-gpio?showall=1
2949 // https://github.com/Microsoft/pxt-neopixel/blob/master/sendbuffer.asm
2950
2951 asm volatile(
2952 // "cpsid i" ; disable irq
2953
2954 // b .start
2955 "b L%=_start"
2956 "\n\t"
2957 // .nextbit: ; C0
2958 "L%=_nextbit:"
2959 "\n\t" //; C0
2960 // str r1, [r3, #0] ; pin := hi C2
2961 "str %[bitmask], [%[reg], #0]"
2962 "\n\t" //; pin := hi C2
2963 // tst r6, r0 ; C3
2964 "tst %[mask], %[pix]"
2965 "\n\t" // ; C3
2966 // bne .islate ; C4
2967 "bne L%=_islate"
2968 "\n\t" //; C4
2969 // str r1, [r2, #0] ; pin := lo C6
2970 "str %[bitmask], [%[reg], #4]"
2971 "\n\t" //; pin := lo C6
2972 // .islate:
2973 "L%=_islate:"
2974 "\n\t"
2975 // lsrs r6, r6, #1 ; r6 >>= 1 C7
2976 "lsr %[mask], %[mask], #1"
2977 "\n\t" //; r6 >>= 1 C7
2978 // bne .justbit ; C8
2979 "bne L%=_justbit"
2980 "\n\t" //; C8
2981
2982 // ; not just a bit - need new byte
2983 // adds r4, #1 ; r4++ C9
2984 "add %[p], #1"
2985 "\n\t" //; r4++ C9
2986 // subs r5, #1 ; r5-- C10
2987 "sub %[num], #1"
2988 "\n\t" //; r5-- C10
2989 // bcc .stop ; if (r5<0) goto .stop C11
2990 "bcc L%=_stop"
2991 "\n\t" //; if (r5<0) goto .stop C11
2992 // .start:
2993 "L%=_start:"
2994 // movs r6, #0x80 ; reset mask C12
2995 "movs %[mask], #0x80"
2996 "\n\t" //; reset mask C12
2997 // nop ; C13
2998 "nop"
2999 "\n\t" //; C13
3000
3001 // .common: ; C13
3002 "L%=_common:"
3003 "\n\t" //; C13
3004 // str r1, [r2, #0] ; pin := lo C15
3005 "str %[bitmask], [%[reg], #4]"
3006 "\n\t" //; pin := lo C15
3007 // ; always re-load byte - it just fits with the cycles better this
3008 // way ldrb r0, [r4, #0] ; r0 := *r4 C17
3009 "ldrb %[pix], [%[p], #0]"
3010 "\n\t" //; r0 := *r4 C17
3011 // b .nextbit ; C20
3012 "b L%=_nextbit"
3013 "\n\t" //; C20
3014
3015 // .justbit: ; C10
3016 "L%=_justbit:"
3017 "\n\t" //; C10
3018 // ; no nops, branch taken is already 3 cycles
3019 // b .common ; C13
3020 "b L%=_common"
3021 "\n\t" //; C13
3022
3023 // .stop:
3024 "L%=_stop:"
3025 "\n\t"
3026 // str r1, [r2, #0] ; pin := lo
3027 "str %[bitmask], [%[reg], #4]"
3028 "\n\t" //; pin := lo
3029 // cpsie i ; enable irq
3030
3031 : [p] "+r"(p), [pix] "=&r"(pix), [count] "=&r"(count),
3032 [mask] "=&r"(mask), [num] "+r"(num)
3033 : [bitmask] "r"(bitmask), [reg] "r"(reg));
3034
3035#elif defined(__SAM3X8E__) // Arduino Due
3036
3037#define SCALE VARIANT_MCK / 2UL / 1000000UL
3038#define INST (2UL * F_CPU / VARIANT_MCK)
3039#define TIME_800_0 ((int)(0.40 * SCALE + 0.5) - (5 * INST))
3040#define TIME_800_1 ((int)(0.80 * SCALE + 0.5) - (5 * INST))
3041#define PERIOD_800 ((int)(1.25 * SCALE + 0.5) - (5 * INST))
3042#define TIME_400_0 ((int)(0.50 * SCALE + 0.5) - (5 * INST))
3043#define TIME_400_1 ((int)(1.20 * SCALE + 0.5) - (5 * INST))
3044#define PERIOD_400 ((int)(2.50 * SCALE + 0.5) - (5 * INST))
3045
3046 int pinMask, time0, time1, period, t;
3047 Pio *port;
3048 volatile WoReg *portSet, *portClear, *timeValue, *timeReset;
3049 uint8_t *p, *end, pix, mask;
3050
3051 pmc_set_writeprotect(false);
3052 pmc_enable_periph_clk((uint32_t)TC3_IRQn);
3053 TC_Configure(TC1, 0,
3054 TC_CMR_WAVE | TC_CMR_WAVSEL_UP | TC_CMR_TCCLKS_TIMER_CLOCK1);
3055 TC_Start(TC1, 0);
3056
3057 pinMask = g_APinDescription[pin].ulPin; // Don't 'optimize' these into
3058 port = g_APinDescription[pin].pPort; // declarations above. Want to
3059 portSet = &(port->PIO_SODR); // burn a few cycles after
3060 portClear = &(port->PIO_CODR); // starting timer to minimize
3061 timeValue = &(TC1->TC_CHANNEL[0].TC_CV); // the initial 'while'.
3062 timeReset = &(TC1->TC_CHANNEL[0].TC_CCR);
3063 p = pixels;
3064 end = p + numBytes;
3065 pix = *p++;
3066 mask = 0x80;
3067
3068#if defined(NEO_KHZ400) // 800 KHz check needed only if 400 KHz support enabled
3069 if (is800KHz) {
3070#endif
3071 time0 = TIME_800_0;
3072 time1 = TIME_800_1;
3073 period = PERIOD_800;
3074#if defined(NEO_KHZ400)
3075 } else { // 400 KHz bitstream
3076 time0 = TIME_400_0;
3077 time1 = TIME_400_1;
3078 period = PERIOD_400;
3079 }
3080#endif
3081
3082 for (t = time0;; t = time0) {
3083 if (pix & mask)
3084 t = time1;
3085 while (*timeValue < (unsigned)period)
3086 ;
3087 *portSet = pinMask;
3088 *timeReset = TC_CCR_CLKEN | TC_CCR_SWTRG;
3089 while (*timeValue < (unsigned)t)
3090 ;
3091 *portClear = pinMask;
3092 if (!(mask >>= 1)) { // This 'inside-out' loop logic utilizes
3093 if (p >= end)
3094 break; // idle time to minimize inter-byte delays.
3095 pix = *p++;
3096 mask = 0x80;
3097 }
3098 }
3099 while (*timeValue < (unsigned)period)
3100 ; // Wait for last bit
3101 TC_Stop(TC1, 0);
3102
3103// RENESAS including Arduino UNO R4 + STM32H7 Arduino Portenta H7 (Dual Core
3104// M7+M4) / Arduino Giga R1
3105#elif defined(ARDUINO_ARCH_RENESAS) || defined(ARDUINO_ARCH_RENESAS_UNO) || \
3106 defined(ARDUINO_ARCH_RENESAS_PORTENTA) || \
3107 defined(ARDUINO_ARCH_MBED_PORTENTA) || defined(ARDUINO_ARCH_MBED_GIGA)
3108
3109// Definition for a single channel clockless controller for RA4M1 (Cortex M4)
3110// See clockless.h for detailed info on how the template parameters are used.
3111#define ARM_DEMCR \
3112 (*(volatile uint32_t *)0xE000EDFC) // Debug Exception and Monitor Control
3113#define ARM_DEMCR_TRCENA (1 << 24) // Enable debugging & monitoring blocks
3114#define ARM_DWT_CTRL (*(volatile uint32_t *)0xE0001000) // DWT control register
3115#define ARM_DWT_CTRL_CYCCNTENA (1 << 0) // Enable cycle count
3116#define ARM_DWT_CYCCNT \
3117 (*(volatile uint32_t *)0xE0001004) // Cycle count register
3118
3119#if defined(ARDUINO_PORTENTA_H7_M7) || \
3120 (defined(ARDUINO_ARCH_MBED_GIGA) && defined(TARGET_M7))
3121#define F_CPU 480000000
3122#elif defined(ARDUINO_PORTENTA_H7_M4) || \
3123 (defined(ARDUINO_ARCH_MBED_GIGA) && defined(TARGET_M4))
3124#define F_CPU 240000000
3125#else
3126#define F_CPU 48000000
3127#endif
3128#define CYCLES_800_T0H (F_CPU / 4000000)
3129#define CYCLES_800_T1H (F_CPU / 1250000)
3130#define CYCLES_800 (F_CPU / 800000)
3131#define CYCLES_400_T0H (F_CPU / 2000000)
3132#define CYCLES_400_T1H (F_CPU / 833333)
3133#define CYCLES_400 (F_CPU / 400000)
3134
3135 uint8_t *p = pixels, *end = p + numBytes, pix, mask;
3136
3137// --- Platform-specific Pin Setup ---
3138#if defined(ARDUINO_ARCH_MBED_PORTENTA) || defined(ARDUINO_ARCH_MBED_GIGA)
3139 // Convert the Arduino pin number to an mbed PinName.
3140 mbed::DigitalOut dout(digitalPinToPinName(pin));
3141#else
3142 bsp_io_port_pin_t io_pin = g_pin_cfg[pin].pin;
3143// Macro to calculate the port base address for the given pin
3144#define PIN_IO_PORT_ADDR(pn) \
3145 (R_PORT0 + ((uint32_t)(R_PORT1 - R_PORT0) * ((pn) >> 8u)))
3146
3147 volatile uint16_t *set = &(PIN_IO_PORT_ADDR(io_pin)->POSR);
3148 volatile uint16_t *clr = &(PIN_IO_PORT_ADDR(io_pin)->PORR);
3149 uint16_t msk = (1U << (io_pin & 0xFF));
3150#endif
3151
3152 uint32_t cyc;
3153
3154 // Enable the cycle counter: ARM registers for precise timing.
3155 ARM_DEMCR |= ARM_DEMCR_TRCENA;
3156 ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
3157
3158#if defined(NEO_KHZ400) // 800 KHz check needed only if 400 KHz support enabled
3159 if (is800KHz) {
3160#endif
3161 cyc = ARM_DWT_CYCCNT + CYCLES_800;
3162 while (p < end) {
3163 pix = *p++;
3164 for (mask = 0x80; mask; mask >>= 1) {
3165 // Wait until the beginning of the next bit period.
3166 while (ARM_DWT_CYCCNT - cyc < CYCLES_800)
3167 ;
3168 cyc = ARM_DWT_CYCCNT;
3169 // Set the pin high:
3170#if defined(ARDUINO_ARCH_MBED_PORTENTA) || defined(ARDUINO_ARCH_MBED_GIGA)
3171 dout = 1;
3172#else
3173 *set = msk;
3174#endif
3175 // Keep the pin high for T1H or T0H depending on the data bit:
3176 if (pix & mask) {
3177 while (ARM_DWT_CYCCNT - cyc < CYCLES_800_T1H)
3178 ;
3179 } else {
3180 while (ARM_DWT_CYCCNT - cyc < CYCLES_800_T0H)
3181 ;
3182 }
3183 // Set the pin low:
3184#if defined(ARDUINO_ARCH_MBED_PORTENTA) || defined(ARDUINO_ARCH_MBED_GIGA)
3185 dout = 0;
3186#else
3187 *clr = msk;
3188#endif
3189 }
3190 }
3191 // Ensure the final low state lasts the full period.
3192 while (ARM_DWT_CYCCNT - cyc < CYCLES_800)
3193 ;
3194#if defined(NEO_KHZ400)
3195 } else { // 400 kHz bitstream
3196 cyc = ARM_DWT_CYCCNT + CYCLES_400;
3197 while (p < end) {
3198 pix = *p++;
3199 for (mask = 0x80; mask; mask >>= 1) {
3200 while (ARM_DWT_CYCCNT - cyc < CYCLES_400)
3201 ;
3202 cyc = ARM_DWT_CYCCNT;
3203 // Set the pin high:
3204#if defined(ARDUINO_ARCH_MBED_PORTENTA) || defined(ARDUINO_ARCH_MBED_GIGA)
3205 dout = 1;
3206#else
3207 *set = msk;
3208#endif
3209 if (pix & mask) {
3210 while (ARM_DWT_CYCCNT - cyc < CYCLES_400_T1H)
3211 ;
3212 } else {
3213 while (ARM_DWT_CYCCNT - cyc < CYCLES_400_T0H)
3214 ;
3215 }
3216 // Set the pin low:
3217#if defined(ARDUINO_ARCH_MBED_PORTENTA) || defined(ARDUINO_ARCH_MBED_GIGA)
3218 dout = 0;
3219#else
3220 *clr = msk;
3221#endif
3222 }
3223 }
3224 // Ensure the final low state lasts the full period.
3225 while (ARM_DWT_CYCCNT - cyc < CYCLES_400)
3226 ;
3227 }
3228#endif // NEO_KHZ400
3229
3230#endif // ARM
3231
3232 // END ARM ----------------------------------------------------------------
3233
3234#elif defined(ESP8266) || defined(ESP32)
3235
3236 // ESP8266 ----------------------------------------------------------------
3237
3238 // ESP8266 show() is external to enforce ICACHE_RAM_ATTR execution
3239 espShow(pin, pixels, numBytes, is800KHz);
3240
3241#elif defined(KENDRYTE_K210)
3242
3243 k210Show(pin, pixels, numBytes, is800KHz);
3244
3245#elif defined(__ARDUINO_ARC__)
3246
3247 // Arduino 101 -----------------------------------------------------------
3248
3249#define NOPx7 \
3250 { \
3251 __builtin_arc_nop(); \
3252 __builtin_arc_nop(); \
3253 __builtin_arc_nop(); \
3254 __builtin_arc_nop(); \
3255 __builtin_arc_nop(); \
3256 __builtin_arc_nop(); \
3257 __builtin_arc_nop(); \
3258 }
3259
3260 PinDescription *pindesc = &g_APinDescription[pin];
3261 register uint32_t loop =
3262 8 * numBytes; // one loop to handle all bytes and all bits
3263 register uint8_t *p = pixels;
3264 register uint32_t currByte = (uint32_t)(*p);
3265 register uint32_t currBit = 0x80 & currByte;
3266 register uint32_t bitCounter = 0;
3267 register uint32_t first = 1;
3268
3269 // The loop is unusual. Very first iteration puts all the way LOW to the
3270 // wire
3271 // - constant LOW does not affect NEOPIXEL, so there is no visible effect
3272 // displayed. During that very first iteration CPU caches instructions in
3273 // the loop. Because of the caching process, "CPU slows down". NEOPIXEL
3274 // pulse is very time sensitive that's why we let the CPU cache first and we
3275 // start regular pulse from 2nd iteration
3276 if (pindesc->ulGPIOType == SS_GPIO) {
3277 register uint32_t reg = pindesc->ulGPIOBase + SS_GPIO_SWPORTA_DR;
3278 uint32_t reg_val = __builtin_arc_lr((volatile uint32_t)reg);
3279 register uint32_t reg_bit_high = reg_val | (1 << pindesc->ulGPIOId);
3280 register uint32_t reg_bit_low = reg_val & ~(1 << pindesc->ulGPIOId);
3281
3282 loop += 1; // include first, special iteration
3283 while (loop--) {
3284 if (!first) {
3285 currByte <<= 1;
3286 bitCounter++;
3287 }
3288
3289 // 1 is >550ns high and >450ns low; 0 is 200..500ns high and >450ns
3290 // low
3291 __builtin_arc_sr(first ? reg_bit_low : reg_bit_high,
3292 (volatile uint32_t)reg);
3293 if (currBit) { // ~400ns HIGH (740ns overall)
3294 NOPx7 NOPx7
3295 }
3296 // ~340ns HIGH
3297 NOPx7 __builtin_arc_nop();
3298
3299 // 820ns LOW; per spec, max allowed low here is 5000ns */
3300 __builtin_arc_sr(reg_bit_low, (volatile uint32_t)reg);
3301 NOPx7 NOPx7
3302
3303 if (bitCounter >= 8) {
3304 bitCounter = 0;
3305 currByte = (uint32_t)(*++p);
3306 }
3307
3308 currBit = 0x80 & currByte;
3309 first = 0;
3310 }
3311 } else if (pindesc->ulGPIOType == SOC_GPIO) {
3312 register uint32_t reg = pindesc->ulGPIOBase + SOC_GPIO_SWPORTA_DR;
3313 uint32_t reg_val = MMIO_REG_VAL(reg);
3314 register uint32_t reg_bit_high = reg_val | (1 << pindesc->ulGPIOId);
3315 register uint32_t reg_bit_low = reg_val & ~(1 << pindesc->ulGPIOId);
3316
3317 loop += 1; // include first, special iteration
3318 while (loop--) {
3319 if (!first) {
3320 currByte <<= 1;
3321 bitCounter++;
3322 }
3323 MMIO_REG_VAL(reg) = first ? reg_bit_low : reg_bit_high;
3324 if (currBit) { // ~430ns HIGH (740ns overall)
3325 NOPx7 NOPx7 __builtin_arc_nop();
3326 }
3327 // ~310ns HIGH
3328 NOPx7
3329
3330 // 850ns LOW; per spec, max allowed low here is 5000ns */
3331 MMIO_REG_VAL(reg) = reg_bit_low;
3332 NOPx7 NOPx7
3333
3334 if (bitCounter >= 8) {
3335 bitCounter = 0;
3336 currByte = (uint32_t)(*++p);
3337 }
3338
3339 currBit = 0x80 & currByte;
3340 first = 0;
3341 }
3342 }
3343
3344#elif defined(ARDUINO_ARCH_CH32)
3345 ch32Show(gpioPort, gpioPin, pixels, numBytes, is800KHz);
3346#elif defined(ARDUINO_ARCH_RP2040) && defined(__riscv)
3347 rp2040Show(pixels, numBytes); // Use PIO
3348#else
3349#error Architecture not supported
3350#endif
3351
3352 // END ARCHITECTURE SELECT ------------------------------------------------
3353
3354#if !(defined(NRF52) || defined(NRF52_SERIES) || defined(ESP32))
3355 interrupts();
3356#endif
3357
3358 endTime = micros(); // Save EOD time for latch on next call
3359}
3360
3361/*!
3362 @brief Set/change the NeoPixel output pin number. Previous pin,
3363 if any, is set to INPUT and the new pin is set to OUTPUT.
3364 @param p Arduino pin number (-1 = no pin).
3365*/
3366void Adafruit_NeoPixel::setPin(int16_t p) {
3367 if (begun && (pin >= 0))
3368 pinMode(pin, INPUT); // Disable existing out pin
3369 pin = p;
3370 if (begun) {
3371 pinMode(p, OUTPUT);
3372 digitalWrite(p, LOW);
3373 }
3374#if defined(__AVR__)
3375 port = portOutputRegister(digitalPinToPort(p));
3376 pinMask = digitalPinToBitMask(p);
3377#endif
3378#if defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_ARDUINO_CORE_STM32)
3379 gpioPort = digitalPinToPort(p);
3380 gpioPin = STM_LL_GPIO_PIN(digitalPinToPinName(p));
3381#elif defined(_PY32_DEF_)
3382 gpioPort = digitalPinToPort(p);
3383 gpioPin = PY32_LL_GPIO_PIN(digitalPinToPinName(p));
3384#elif defined(ARDUINO_ARCH_CH32)
3385 PinName const pin_name = digitalPinToPinName(pin);
3386 gpioPort = get_GPIO_Port(CH_PORT(pin_name));
3387 gpioPin = CH_GPIO_PIN(pin_name);
3388#if defined(CH32V20x_D6)
3389 if (gpioPort == GPIOC &&
3390 ((*(volatile uint32_t *)0x40022030) & 0x0F000000) == 0) {
3391 gpioPin = gpioPin >> 13;
3392 }
3393#endif
3394#endif
3395}
3396
3397/*!
3398 @brief Set a pixel's color using separate red, green and blue
3399 components. If using RGBW pixels, white will be set to 0.
3400 @param n Pixel index, starting from 0.
3401 @param r Red brightness, 0 = minimum (off), 255 = maximum.
3402 @param g Green brightness, 0 = minimum (off), 255 = maximum.
3403 @param b Blue brightness, 0 = minimum (off), 255 = maximum.
3404*/
3405void Adafruit_NeoPixel::setPixelColor(uint16_t n, uint8_t r, uint8_t g,
3406 uint8_t b) {
3407
3408 if (n < numLEDs) {
3409 if (brightness) { // See notes in setBrightness()
3410 r = (r * brightness) >> 8;
3411 g = (g * brightness) >> 8;
3412 b = (b * brightness) >> 8;
3413 }
3414 uint8_t *p;
3415 if (wOffset == rOffset) { // Is an RGB-type strip
3416 p = &pixels[n * 3]; // 3 bytes per pixel
3417 } else { // Is a WRGB-type strip
3418 p = &pixels[n * 4]; // 4 bytes per pixel
3419 p[wOffset] = 0; // But only R,G,B passed -- set W to 0
3420 }
3421 p[rOffset] = r; // R,G,B always stored
3422 p[gOffset] = g;
3423 p[bOffset] = b;
3424 }
3425}
3426
3427/*!
3428 @brief Set a pixel's color using separate red, green, blue and white
3429 components (for RGBW NeoPixels only).
3430 @param n Pixel index, starting from 0.
3431 @param r Red brightness, 0 = minimum (off), 255 = maximum.
3432 @param g Green brightness, 0 = minimum (off), 255 = maximum.
3433 @param b Blue brightness, 0 = minimum (off), 255 = maximum.
3434 @param w White brightness, 0 = minimum (off), 255 = maximum, ignored
3435 if using RGB pixels.
3436*/
3437void Adafruit_NeoPixel::setPixelColor(uint16_t n, uint8_t r, uint8_t g,
3438 uint8_t b, uint8_t w) {
3439
3440 if (n < numLEDs) {
3441 if (brightness) { // See notes in setBrightness()
3442 r = (r * brightness) >> 8;
3443 g = (g * brightness) >> 8;
3444 b = (b * brightness) >> 8;
3445 w = (w * brightness) >> 8;
3446 }
3447 uint8_t *p;
3448 if (wOffset == rOffset) { // Is an RGB-type strip
3449 p = &pixels[n * 3]; // 3 bytes per pixel (ignore W)
3450 } else { // Is a WRGB-type strip
3451 p = &pixels[n * 4]; // 4 bytes per pixel
3452 p[wOffset] = w; // Store W
3453 }
3454 p[rOffset] = r; // Store R,G,B
3455 p[gOffset] = g;
3456 p[bOffset] = b;
3457 }
3458}
3459
3460/*!
3461 @brief Set a pixel's color using a 32-bit 'packed' RGB or RGBW value.
3462 @param n Pixel index, starting from 0.
3463 @param c 32-bit color value. Most significant byte is white (for RGBW
3464 pixels) or ignored (for RGB pixels), next is red, then green,
3465 and least significant byte is blue.
3466*/
3467void Adafruit_NeoPixel::setPixelColor(uint16_t n, uint32_t c) {
3468 if (n < numLEDs) {
3469 uint8_t *p, r = (uint8_t)(c >> 16), g = (uint8_t)(c >> 8),
3470 b = (uint8_t)c;
3471 if (brightness) { // See notes in setBrightness()
3472 r = (r * brightness) >> 8;
3473 g = (g * brightness) >> 8;
3474 b = (b * brightness) >> 8;
3475 }
3476 if (wOffset == rOffset) {
3477 p = &pixels[n * 3];
3478 } else {
3479 p = &pixels[n * 4];
3480 uint8_t w = (uint8_t)(c >> 24);
3481 p[wOffset] = brightness ? ((w * brightness) >> 8) : w;
3482 }
3483 p[rOffset] = r;
3484 p[gOffset] = g;
3485 p[bOffset] = b;
3486 }
3487}
3488
3489/*!
3490 @brief Fill all or part of the NeoPixel strip with a color.
3491 @param c 32-bit color value. Most significant byte is white (for
3492 RGBW pixels) or ignored (for RGB pixels), next is red,
3493 then green, and least significant byte is blue. If all
3494 arguments are unspecified, this will be 0 (off).
3495 @param first Index of first pixel to fill, starting from 0. Must be
3496 in-bounds, no clipping is performed. 0 if unspecified.
3497 @param count Number of pixels to fill, as a positive value. Passing
3498 0 or leaving unspecified will fill to end of strip.
3499*/
3500void Adafruit_NeoPixel::fill(uint32_t c, uint16_t first, uint16_t count) {
3501 uint16_t i, end;
3502
3503 if (first >= numLEDs) {
3504 return; // If first LED is past end of strip, nothing to do
3505 }
3506
3507 // Calculate the index ONE AFTER the last pixel to fill
3508 if (count == 0) {
3509 // Fill to end of strip
3510 end = numLEDs;
3511 } else {
3512 // Ensure that the loop won't go past the last pixel
3513 end = first + count;
3514 if (end > numLEDs)
3515 end = numLEDs;
3516 }
3517
3518 for (i = first; i < end; i++) {
3519 this->setPixelColor(i, c);
3520 }
3521}
3522
3523/*!
3524 @brief Convert hue, saturation and value into a packed 32-bit RGB color
3525 that can be passed to setPixelColor() or other RGB-compatible
3526 functions.
3527 @param hue An unsigned 16-bit value, 0 to 65535, representing one full
3528 loop of the color wheel, which allows 16-bit hues to "roll
3529 over" while still doing the expected thing (and allowing
3530 more precision than the wheel() function that was common to
3531 prior NeoPixel examples).
3532 @param sat Saturation, 8-bit value, 0 (min or pure grayscale) to 255
3533 (max or pure hue). Default of 255 if unspecified.
3534 @param val Value (brightness), 8-bit value, 0 (min / black / off) to
3535 255 (max or full brightness). Default of 255 if unspecified.
3536 @return Packed 32-bit RGB with the most significant byte set to 0 -- the
3537 white element of WRGB pixels is NOT utilized. Result is linearly
3538 but not perceptually correct, so you may want to pass the result
3539 through the gamma32() function (or your own gamma-correction
3540 operation) else colors may appear washed out. This is not done
3541 automatically by this function because coders may desire a more
3542 refined gamma-correction function than the simplified
3543 one-size-fits-all operation of gamma32(). Diffusing the LEDs also
3544 really seems to help when using low-saturation colors.
3545*/
3546uint32_t Adafruit_NeoPixel::ColorHSV(uint16_t hue, uint8_t sat, uint8_t val) {
3547
3548 uint8_t r, g, b;
3549
3550 // Remap 0-65535 to 0-1529. Pure red is CENTERED on the 64K rollover;
3551 // 0 is not the start of pure red, but the midpoint...a few values above
3552 // zero and a few below 65536 all yield pure red (similarly, 32768 is the
3553 // midpoint, not start, of pure cyan). The 8-bit RGB hexcone (256 values
3554 // each for red, green, blue) really only allows for 1530 distinct hues
3555 // (not 1536, more on that below), but the full unsigned 16-bit type was
3556 // chosen for hue so that one's code can easily handle a contiguous color
3557 // wheel by allowing hue to roll over in either direction.
3558 hue = (hue * 1530L + 32768) / 65536;
3559 // Because red is centered on the rollover point (the +32768 above,
3560 // essentially a fixed-point +0.5), the above actually yields 0 to 1530,
3561 // where 0 and 1530 would yield the same thing. Rather than apply a
3562 // costly modulo operator, 1530 is handled as a special case below.
3563
3564 // So you'd think that the color "hexcone" (the thing that ramps from
3565 // pure red, to pure yellow, to pure green and so forth back to red,
3566 // yielding six slices), and with each color component having 256
3567 // possible values (0-255), might have 1536 possible items (6*256),
3568 // but in reality there's 1530. This is because the last element in
3569 // each 256-element slice is equal to the first element of the next
3570 // slice, and keeping those in there this would create small
3571 // discontinuities in the color wheel. So the last element of each
3572 // slice is dropped...we regard only elements 0-254, with item 255
3573 // being picked up as element 0 of the next slice. Like this:
3574 // Red to not-quite-pure-yellow is: 255, 0, 0 to 255, 254, 0
3575 // Pure yellow to not-quite-pure-green is: 255, 255, 0 to 1, 255, 0
3576 // Pure green to not-quite-pure-cyan is: 0, 255, 0 to 0, 255, 254
3577 // and so forth. Hence, 1530 distinct hues (0 to 1529), and hence why
3578 // the constants below are not the multiples of 256 you might expect.
3579
3580 // Convert hue to R,G,B (nested ifs faster than divide+mod+switch):
3581 if (hue < 510) { // Red to Green-1
3582 b = 0;
3583 if (hue < 255) { // Red to Yellow-1
3584 r = 255;
3585 g = hue; // g = 0 to 254
3586 } else { // Yellow to Green-1
3587 r = 510 - hue; // r = 255 to 1
3588 g = 255;
3589 }
3590 } else if (hue < 1020) { // Green to Blue-1
3591 r = 0;
3592 if (hue < 765) { // Green to Cyan-1
3593 g = 255;
3594 b = hue - 510; // b = 0 to 254
3595 } else { // Cyan to Blue-1
3596 g = 1020 - hue; // g = 255 to 1
3597 b = 255;
3598 }
3599 } else if (hue < 1530) { // Blue to Red-1
3600 g = 0;
3601 if (hue < 1275) { // Blue to Magenta-1
3602 r = hue - 1020; // r = 0 to 254
3603 b = 255;
3604 } else { // Magenta to Red-1
3605 r = 255;
3606 b = 1530 - hue; // b = 255 to 1
3607 }
3608 } else { // Last 0.5 Red (quicker than % operator)
3609 r = 255;
3610 g = b = 0;
3611 }
3612
3613 // Apply saturation and value to R,G,B, pack into 32-bit result:
3614 uint32_t v1 = 1 + val; // 1 to 256; allows >>8 instead of /255
3615 uint16_t s1 = 1 + sat; // 1 to 256; same reason
3616 uint8_t s2 = 255 - sat; // 255 to 0
3617 return ((((((r * s1) >> 8) + s2) * v1) & 0xff00) << 8) |
3618 (((((g * s1) >> 8) + s2) * v1) & 0xff00) |
3619 (((((b * s1) >> 8) + s2) * v1) >> 8);
3620}
3621
3622/*!
3623 @brief Query the color of a previously-set pixel.
3624 @param n Index of pixel to read (0 = first).
3625 @return 'Packed' 32-bit RGB or WRGB value. Most significant byte is white
3626 (for RGBW pixels) or 0 (for RGB pixels), next is red, then green,
3627 and least significant byte is blue.
3628 @note If the strip brightness has been changed from the default value
3629 of 255, the color read from a pixel may not exactly match what
3630 was previously written with one of the setPixelColor() functions.
3631 This gets more pronounced at lower brightness levels.
3632*/
3633uint32_t Adafruit_NeoPixel::getPixelColor(uint16_t n) const {
3634 if (n >= numLEDs)
3635 return 0; // Out of bounds, return no color.
3636
3637 uint8_t *p;
3638
3639 if (wOffset == rOffset) { // Is RGB-type device
3640 p = &pixels[n * 3];
3641 if (brightness) {
3642 // Stored color was decimated by setBrightness(). Returned value
3643 // attempts to scale back to an approximation of the original 24-bit
3644 // value used when setting the pixel color, but there will always be
3645 // some error -- those bits are simply gone. Issue is most
3646 // pronounced at low brightness levels.
3647 return (((uint32_t)(p[rOffset] << 8) / brightness) << 16) |
3648 (((uint32_t)(p[gOffset] << 8) / brightness) << 8) |
3649 ((uint32_t)(p[bOffset] << 8) / brightness);
3650 } else {
3651 // No brightness adjustment has been made -- return 'raw' color
3652 return ((uint32_t)p[rOffset] << 16) | ((uint32_t)p[gOffset] << 8) |
3653 (uint32_t)p[bOffset];
3654 }
3655 } else { // Is RGBW-type device
3656 p = &pixels[n * 4];
3657 if (brightness) { // Return scaled color
3658 return (((uint32_t)(p[wOffset] << 8) / brightness) << 24) |
3659 (((uint32_t)(p[rOffset] << 8) / brightness) << 16) |
3660 (((uint32_t)(p[gOffset] << 8) / brightness) << 8) |
3661 ((uint32_t)(p[bOffset] << 8) / brightness);
3662 } else { // Return raw color
3663 return ((uint32_t)p[wOffset] << 24) | ((uint32_t)p[rOffset] << 16) |
3664 ((uint32_t)p[gOffset] << 8) | (uint32_t)p[bOffset];
3665 }
3666 }
3667}
3668
3669/*!
3670 @brief Adjust output brightness. Does not immediately affect what's
3671 currently displayed on the LEDs. The next call to show() will
3672 refresh the LEDs at this level.
3673 @param b Brightness setting, 0=minimum (off), 255=brightest.
3674 @note This was intended for one-time use in one's setup() function,
3675 not as an animation effect in itself. Because of the way this
3676 library "pre-multiplies" LED colors in RAM, changing the
3677 brightness is often a "lossy" operation -- what you write to
3678 pixels isn't necessary the same as what you'll read back.
3679 Repeated brightness changes using this function exacerbate the
3680 problem. Smart programs therefore treat the strip as a
3681 write-only resource, maintaining their own state to render each
3682 frame of an animation, not relying on read-modify-write.
3683*/
3684void Adafruit_NeoPixel::setBrightness(uint8_t b) {
3685 // Stored brightness value is different than what's passed.
3686 // This simplifies the actual scaling math later, allowing a fast
3687 // 8x8-bit multiply and taking the MSB. 'brightness' is a uint8_t,
3688 // adding 1 here may (intentionally) roll over...so 0 = max brightness
3689 // (color values are interpreted literally; no scaling), 1 = min
3690 // brightness (off), 255 = just below max brightness.
3691 uint8_t newBrightness = b + 1;
3692 if (newBrightness != brightness) { // Compare against prior value
3693 // Brightness has changed -- re-scale existing data in RAM,
3694 // This process is potentially "lossy," especially when increasing
3695 // brightness. The tight timing in the WS2811/WS2812 code means there
3696 // aren't enough free cycles to perform this scaling on the fly as data
3697 // is issued. So we make a pass through the existing color data in RAM
3698 // and scale it (subsequent graphics commands also work at this
3699 // brightness level). If there's a significant step up in brightness,
3700 // the limited number of steps (quantization) in the old data will be
3701 // quite visible in the re-scaled version. For a non-destructive
3702 // change, you'll need to re-render the full strip data. C'est la vie.
3703 uint8_t c,
3704 *ptr = pixels,
3705 oldBrightness = brightness - 1; // De-wrap old brightness value
3706 uint16_t scale;
3707 if (oldBrightness == 0)
3708 scale = 0; // Avoid /0
3709 else if (b == 255)
3710 scale = 65535 / oldBrightness;
3711 else
3712 scale = (((uint16_t)newBrightness << 8) - 1) / oldBrightness;
3713 for (uint16_t i = 0; i < numBytes; i++) {
3714 c = *ptr;
3715 *ptr++ = (c * scale) >> 8;
3716 }
3717 brightness = newBrightness;
3718 }
3719}
3720
3721/*!
3722 @brief Retrieve the last-set brightness value for the strip.
3723 @return Brightness value: 0 = minimum (off), 255 = maximum.
3724*/
3725uint8_t Adafruit_NeoPixel::getBrightness(void) const { return brightness - 1; }
3726
3727/*!
3728 @brief Fill the whole NeoPixel strip with 0 / black / off.
3729*/
3730void Adafruit_NeoPixel::clear(void) { memset(pixels, 0, numBytes); }
3731
3732// A 32-bit variant of gamma8() that applies the same function
3733// to all components of a packed RGB or WRGB value.
3734uint32_t Adafruit_NeoPixel::gamma32(uint32_t x) {
3735 uint8_t *y = (uint8_t *)&x;
3736 // All four bytes of a 32-bit value are filtered even if RGB (not WRGB),
3737 // to avoid a bunch of shifting and masking that would be necessary for
3738 // properly handling different endianisms (and each byte is a fairly
3739 // trivial operation, so it might not even be wasting cycles vs a check
3740 // and branch for the RGB case). In theory this might cause trouble *if*
3741 // someone's storing information in the unused most significant byte
3742 // of an RGB value, but this seems exceedingly rare and if it's
3743 // encountered in reality they can mask values going in or coming out.
3744 for (uint8_t i = 0; i < 4; i++)
3745 y[i] = gamma8(y[i]);
3746 return x; // Packed 32-bit return
3747}
3748
3749/*!
3750 @brief Fill NeoPixel strip with one or more cycles of hues.
3751 Everyone loves the rainbow swirl so much, now it's canon!
3752 @param first_hue Hue of first pixel, 0-65535, representing one full
3753 cycle of the color wheel. Each subsequent pixel will
3754 be offset to complete one or more cycles over the
3755 length of the strip.
3756 @param reps Number of cycles of the color wheel over the length
3757 of the strip. Default is 1. Negative values can be
3758 used to reverse the hue order.
3759 @param saturation Saturation (optional), 0-255 = gray to pure hue,
3760 default = 255.
3761 @param brightness Brightness/value (optional), 0-255 = off to max,
3762 default = 255. This is distinct and in combination
3763 with any configured global strip brightness.
3764 @param gammify If true (default), apply gamma correction to colors
3765 for better appearance.
3766*/
3767void Adafruit_NeoPixel::rainbow(uint16_t first_hue, int8_t reps,
3768 uint8_t saturation, uint8_t brightness,
3769 bool gammify) {
3770 for (uint16_t i = 0; i < numLEDs; i++) {
3771 uint16_t hue = first_hue + (i * reps * 65536) / numLEDs;
3772 uint32_t color = ColorHSV(hue, saturation, brightness);
3773 if (gammify)
3774 color = gamma32(color);
3775 setPixelColor(i, color);
3776 }
3777}
3778
3779/*!
3780 @brief Convert pixel color order from string (e.g. "BGR") to NeoPixel
3781 color order constant (e.g. NEO_BGR). This may be helpful for code
3782 that initializes from text configuration rather than compile-time
3783 constants.
3784 @param v Input string. Should be reasonably sanitized (a 3- or 4-
3785 character NUL-terminated string) or undefined behavior may
3786 result (output is still a valid NeoPixel order constant, but
3787 might not present as expected). Garbage in, garbage out.
3788 @return One of the NeoPixel color order constants (e.g. NEO_BGR).
3789 NEO_KHZ400 or NEO_KHZ800 bits are not included, nor needed (all
3790 NeoPixels actually support 800 KHz it's been found, and this is
3791 the default state if no KHZ bits set).
3792 @note This function is declared static in the class so it can be called
3793 without a NeoPixel object (since it's not likely been declared
3794 in the code yet). Use Adafruit_NeoPixel::str2order().
3795*/
3796neoPixelType Adafruit_NeoPixel::str2order(const char *v) {
3797 int8_t r = 0, g = 0, b = 0, w = -1;
3798 if (v) {
3799 char c;
3800 for (uint8_t i = 0; ((c = tolower(v[i]))); i++) {
3801 if (c == 'r')
3802 r = i;
3803 else if (c == 'g')
3804 g = i;
3805 else if (c == 'b')
3806 b = i;
3807 else if (c == 'w')
3808 w = i;
3809 }
3810 r &= 3;
3811 }
3812 if (w < 0)
3813 w = r; // If 'w' not specified, duplicate r bits
3814 return (w << 6) | (r << 4) | ((g & 3) << 2) | (b & 3);
3815}