Arduino  1.8.10
Adafruit_CPlay_NeoPixel クラス

Class that stores state and functions for neopixels on CircuitPlayground boards [詳解]

#include <Adafruit_CPlay_NeoPixel.h>

公開メンバ関数

 Adafruit_CPlay_NeoPixel (uint16_t n, uint8_t p=17, neoPixelType t=NEO_GRB+NEO_KHZ800)
 Constructor when length, pin and type are known at compile-time [詳解]
 
 Adafruit_CPlay_NeoPixel (void)
 via Michael Vogt/neophob: empty constructor is used when strand length isn't known at compile-time; situations where program config might be read from internal flash memory or an SD card, or arrive via serial command. If using this constructor, MUST follow up with updateType(), updateLength(), etc. to establish the strand type, length and pin number! [詳解]
 
 ~Adafruit_CPlay_NeoPixel ()
 
void begin (void)
 initialize necessary hardware to drive the pixels. [詳解]
 
void show (void)
 Write data to the neopixels [詳解]
 
void setPin (uint8_t p)
 Set the output pin number [詳解]
 
void setPixelColor (uint16_t n, uint8_t r, uint8_t g, uint8_t b)
 Set pixel color from separate R,G,B components: [詳解]
 
void setPixelColor (uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w)
 Set pixel color from separate R,G,B,W components: [詳解]
 
void setPixelColor (uint16_t n, uint32_t c)
 Set pixel color from 'packed' 32-bit RGB color: [詳解]
 
void setBrightness (uint8_t)
 Adjust output brightness; 0=darkest (off), 255=brightest. [詳解]
 
void clear ()
 set all neopixel data to 'off' in internal memory. [詳解]
 
void updateLength (uint16_t n)
 Set the number of pixels in the strip [詳解]
 
void updateType (neoPixelType t)
 set the type of neopixel we are using [詳解]
 
uint8_t * getPixels (void) const
 Returns pointer to pixels[] array. Pixel data is stored in device- native format and is not translated here. Application will need to be aware of specific pixel data format and handle colors appropriately. [詳解]
 
uint8_t getBrightness (void) const
 get the global brightness value [詳解]
 
uint8_t sine8 (uint8_t) const
 Get a sinusoidal value from a sine table [詳解]
 
uint8_t gamma8 (uint8_t) const
 Get a gamma-corrected value from a gamma table [詳解]
 
uint16_t numPixels (void) const
 get the number of pixels in the strip [詳解]
 
static uint32_t Color (uint8_t r, uint8_t g, uint8_t b, uint8_t w)
 Convert separate R,G,B,W into packed 32-bit WRGB color. [詳解]
 
uint32_t getPixelColor (uint16_t n) const
 Query color from previously-set pixel (returns packed 32-bit RGB value) [詳解]
 
bool canShow (void)
 check if enough time has elapsed and the pixels are ready to refresh. [詳解]
 

静的公開メンバ関数

static uint32_t Color (uint8_t r, uint8_t g, uint8_t b)
 Convert separate R,G,B into packed 32-bit RGB color. [詳解]
 

詳解

Class that stores state and functions for neopixels on CircuitPlayground boards

Adafruit_CPlay_NeoPixel.h105 行目に定義があります。

構築子と解体子

◆ Adafruit_CPlay_NeoPixel() [1/2]

Adafruit_CPlay_NeoPixel::Adafruit_CPlay_NeoPixel ( uint16_t  n,
uint8_t  p = 17,
neoPixelType  t = NEO_GRB + NEO_KHZ800 
)

Constructor when length, pin and type are known at compile-time

引数
nnumber of pixels
ppin the pixels are attached to
tthe type of neopixel. can be NEO_KHZ800 or NEO_KHZ400

Adafruit_CPlay_NeoPixel.cpp45 行目に定義があります。

45  :
46  begun(false), brightness(0), pixels(NULL), endTime(0)
47 {
48  updateType(t);
49  updateLength(n);
50  setPin(p);
51 }
void setPin(uint8_t p)
Set the output pin number
void updateType(neoPixelType t)
set the type of neopixel we are using
#define NULL
Definition: def.h:44
void updateLength(uint16_t n)
Set the number of pixels in the strip

◆ Adafruit_CPlay_NeoPixel() [2/2]

Adafruit_CPlay_NeoPixel::Adafruit_CPlay_NeoPixel ( void  )

via Michael Vogt/neophob: empty constructor is used when strand length isn't known at compile-time; situations where program config might be read from internal flash memory or an SD card, or arrive via serial command. If using this constructor, MUST follow up with updateType(), updateLength(), etc. to establish the strand type, length and pin number!

Adafruit_CPlay_NeoPixel.cpp68 行目に定義があります。

68  :
69  is800KHz(true),
70  begun(false), numLEDs(0), numBytes(0), pin(-1), brightness(0), pixels(NULL),
71  rOffset(1), gOffset(0), bOffset(2), wOffset(1), endTime(0)
72 {
73 }
#define NULL
Definition: def.h:44

◆ ~Adafruit_CPlay_NeoPixel()

Adafruit_CPlay_NeoPixel::~Adafruit_CPlay_NeoPixel ( )

Adafruit_CPlay_NeoPixel.cpp75 行目に定義があります。

75  {
76  if(pixels) free(pixels);
77  if(pin >= 0) pinMode(pin, INPUT);
78  pixels = NULL;
79 }
void pinMode(uint8_t, uint8_t)
void free(void *__ptr)
#define NULL
Definition: def.h:44
#define INPUT
Definition: Arduino.h:43

関数詳解

◆ begin()

void Adafruit_CPlay_NeoPixel::begin ( void  )

initialize necessary hardware to drive the pixels.

Adafruit_CPlay_NeoPixel.cpp86 行目に定義があります。

86  {
87  if(pin >= 0) {
88  pinMode(pin, OUTPUT);
89  digitalWrite(pin, LOW);
90  }
91  begun = true;
92 }
void pinMode(uint8_t, uint8_t)
void digitalWrite(uint8_t, uint8_t)
#define LOW
Definition: Arduino.h:41
#define OUTPUT
Definition: Arduino.h:44

◆ canShow()

bool Adafruit_CPlay_NeoPixel::canShow ( void  )
inline

check if enough time has elapsed and the pixels are ready to refresh.

戻り値
true if ready to show, false otherwise.

Adafruit_CPlay_NeoPixel.h144 行目に定義があります。

144 { return (micros() - endTime) >= 50L; }
unsigned long micros(void)
Definition: wiring.c:79

◆ clear()

void Adafruit_CPlay_NeoPixel::clear ( )

set all neopixel data to 'off' in internal memory.

覚え書き
this does not automatically update pixels. Update with show() after calling clear()

Adafruit_CPlay_NeoPixel.cpp707 行目に定義があります。

707  {
708  memset(pixels, 0, numBytes);
709 }
void * memset(void *, int, size_t)
Fill memory with a constant byte.

◆ Color() [1/2]

uint32_t Adafruit_CPlay_NeoPixel::Color ( uint8_t  r,
uint8_t  g,
uint8_t  b 
)
static

Convert separate R,G,B into packed 32-bit RGB color.

引数
rthe red component
gthe green component
bthe blue component
戻り値
the converted 32-bit color
覚え書き
Packed format is always RGB, regardless of LED strand color order.

Adafruit_CPlay_NeoPixel.cpp556 行目に定義があります。

556  {
557  return ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
558 }

◆ Color() [2/2]

uint32_t Adafruit_CPlay_NeoPixel::Color ( uint8_t  r,
uint8_t  g,
uint8_t  b,
uint8_t  w 
)

Convert separate R,G,B,W into packed 32-bit WRGB color.

引数
rthe red component
gthe green component
bthe blue component
wthe white component
戻り値
the converted 32-bit color
覚え書き
Packed format is always WRGB, regardless of LED strand color order.

Adafruit_CPlay_NeoPixel.cpp572 行目に定義があります。

572  {
573  return ((uint32_t)w << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
574 }

◆ gamma8()

uint8_t Adafruit_CPlay_NeoPixel::gamma8 ( uint8_t  x) const

Get a gamma-corrected value from a gamma table

引数
xa 0 to 255 value corresponding to an index to the gamma table
戻り値
An 8-bit gamma-corrected value back

Adafruit_CPlay_NeoPixel.cpp738 行目に定義があります。

738  {
739  return pgm_read_byte(&_gammaTable[x]); // 0-255 in, 0-255 out
740 }
#define pgm_read_byte(address_short)
Definition: pgmspace.h:1055

◆ getBrightness()

uint8_t Adafruit_CPlay_NeoPixel::getBrightness ( void  ) const

get the global brightness value

戻り値
the global brightness

Adafruit_CPlay_NeoPixel.cpp697 行目に定義があります。

697  {
698  return brightness - 1;
699 }

◆ getPixelColor()

uint32_t Adafruit_CPlay_NeoPixel::getPixelColor ( uint16_t  n) const

Query color from previously-set pixel (returns packed 32-bit RGB value)

引数
nthe number of the pixel to check
戻り値
the 32-bit color of the pixel
覚え書き
this does not read from the pixel itself. It just checks the value that was previously set.

Adafruit_CPlay_NeoPixel.cpp585 行目に定義があります。

585  {
586  if(n >= numLEDs) return 0; // Out of bounds, return no color.
587 
588  uint8_t *p;
589 
590  if(wOffset == rOffset) { // Is RGB-type device
591  p = &pixels[n * 3];
592  if(brightness) {
593  // Stored color was decimated by setBrightness(). Returned value
594  // attempts to scale back to an approximation of the original 24-bit
595  // value used when setting the pixel color, but there will always be
596  // some error -- those bits are simply gone. Issue is most
597  // pronounced at low brightness levels.
598  return (((uint32_t)(p[rOffset] << 8) / brightness) << 16) |
599  (((uint32_t)(p[gOffset] << 8) / brightness) << 8) |
600  ( (uint32_t)(p[bOffset] << 8) / brightness );
601  } else {
602  // No brightness adjustment has been made -- return 'raw' color
603  return ((uint32_t)p[rOffset] << 16) |
604  ((uint32_t)p[gOffset] << 8) |
605  (uint32_t)p[bOffset];
606  }
607  } else { // Is RGBW-type device
608  p = &pixels[n * 4];
609  if(brightness) { // Return scaled color
610  return (((uint32_t)(p[wOffset] << 8) / brightness) << 24) |
611  (((uint32_t)(p[rOffset] << 8) / brightness) << 16) |
612  (((uint32_t)(p[gOffset] << 8) / brightness) << 8) |
613  ( (uint32_t)(p[bOffset] << 8) / brightness );
614  } else { // Return raw color
615  return ((uint32_t)p[wOffset] << 24) |
616  ((uint32_t)p[rOffset] << 16) |
617  ((uint32_t)p[gOffset] << 8) |
618  (uint32_t)p[bOffset];
619  }
620  }
621 }

◆ getPixels()

uint8_t * Adafruit_CPlay_NeoPixel::getPixels ( void  ) const

Returns pointer to pixels[] array. Pixel data is stored in device- native format and is not translated here. Application will need to be aware of specific pixel data format and handle colors appropriately.

戻り値
pointer to the pixel array.

Adafruit_CPlay_NeoPixel.cpp632 行目に定義があります。

632  {
633  return pixels;
634 }

◆ numPixels()

uint16_t Adafruit_CPlay_NeoPixel::numPixels ( void  ) const

get the number of pixels in the strip

戻り値
the number of pixels

Adafruit_CPlay_NeoPixel.cpp643 行目に定義があります。

643  {
644  return numLEDs;
645 }

◆ setBrightness()

void Adafruit_CPlay_NeoPixel::setBrightness ( uint8_t  b)

Adjust output brightness; 0=darkest (off), 255=brightest.

引数
bthe brightness to set
戻り値
the number of pixels
覚え書き
This does NOT immediately affect what's currently displayed on the LEDs. The next call to show() will refresh the LEDs at this level. However, this process is potentially "lossy," especially when increasing brightness. The tight timing in the WS2811/WS2812 code means there aren't enough free cycles to perform this scaling on the fly as data is issued. So we make a pass through the existing color data in RAM and scale it (subsequent graphics commands also work at this brightness level). If there's a significant step up in brightness, the limited number of steps (quantization) in the old data will be quite visible in the re-scaled version. For a non-destructive change, you'll need to re-render the full strip data. C'est la vie.

Adafruit_CPlay_NeoPixel.cpp666 行目に定義があります。

666  {
667  // Stored brightness value is different than what's passed.
668  // This simplifies the actual scaling math later, allowing a fast
669  // 8x8-bit multiply and taking the MSB. 'brightness' is a uint8_t,
670  // adding 1 here may (intentionally) roll over...so 0 = max brightness
671  // (color values are interpreted literally; no scaling), 1 = min
672  // brightness (off), 255 = just below max brightness.
673  uint8_t newBrightness = b + 1;
674  if(newBrightness != brightness) { // Compare against prior value
675  // Brightness has changed -- re-scale existing data in RAM
676  uint8_t c,
677  *ptr = pixels,
678  oldBrightness = brightness - 1; // De-wrap old brightness value
679  uint16_t scale;
680  if(oldBrightness == 0) scale = 0; // Avoid /0
681  else if(b == 255) scale = 65535 / oldBrightness;
682  else scale = (((uint16_t)newBrightness << 8) - 1) / oldBrightness;
683  for(uint16_t i=0; i<numBytes; i++) {
684  c = *ptr;
685  *ptr++ = (c * scale) >> 8;
686  }
687  brightness = newBrightness;
688  }
689 }
uint8_t i

◆ setPin()

void Adafruit_CPlay_NeoPixel::setPin ( uint8_t  p)

Set the output pin number

引数
pthe pin number

Adafruit_CPlay_NeoPixel.cpp437 行目に定義があります。

437  {
438  if(begun && (pin >= 0)) pinMode(pin, INPUT);
439  pin = p;
440  if(begun) {
441  pinMode(p, OUTPUT);
442  digitalWrite(p, LOW);
443  }
444 #ifdef __AVR__
446  pinMask = digitalPinToBitMask(p);
447 #endif
448 }
#define digitalPinToBitMask(P)
Definition: Arduino.h:178
#define portOutputRegister(P)
Definition: Arduino.h:181
void pinMode(uint8_t, uint8_t)
void digitalWrite(uint8_t, uint8_t)
#define LOW
Definition: Arduino.h:41
#define OUTPUT
Definition: Arduino.h:44
#define digitalPinToPort(P)
Definition: Arduino.h:177
#define INPUT
Definition: Arduino.h:43

◆ setPixelColor() [1/3]

void Adafruit_CPlay_NeoPixel::setPixelColor ( uint16_t  n,
uint8_t  r,
uint8_t  g,
uint8_t  b 
)

Set pixel color from separate R,G,B components:

引数
nthe pixel number to set
rthe red component
gthe green component
bthe blue component

Adafruit_CPlay_NeoPixel.cpp459 行目に定義があります。

460  {
461 
462  if(n < numLEDs) {
463  if(brightness) { // See notes in setBrightness()
464  r = (r * brightness) >> 8;
465  g = (g * brightness) >> 8;
466  b = (b * brightness) >> 8;
467  }
468  uint8_t *p;
469  if(wOffset == rOffset) { // Is an RGB-type strip
470  p = &pixels[n * 3]; // 3 bytes per pixel
471  } else { // Is a WRGB-type strip
472  p = &pixels[n * 4]; // 4 bytes per pixel
473  p[wOffset] = 0; // But only R,G,B passed -- set W to 0
474  }
475  p[rOffset] = r; // R,G,B always stored
476  p[gOffset] = g;
477  p[bOffset] = b;
478  }
479 }

◆ setPixelColor() [2/3]

void Adafruit_CPlay_NeoPixel::setPixelColor ( uint16_t  n,
uint8_t  r,
uint8_t  g,
uint8_t  b,
uint8_t  w 
)

Set pixel color from separate R,G,B,W components:

引数
nthe pixel number to set
rthe red component
gthe green component
bthe blue component
wthe white component

Adafruit_CPlay_NeoPixel.cpp491 行目に定義があります。

492  {
493 
494  if(n < numLEDs) {
495  if(brightness) { // See notes in setBrightness()
496  r = (r * brightness) >> 8;
497  g = (g * brightness) >> 8;
498  b = (b * brightness) >> 8;
499  w = (w * brightness) >> 8;
500  }
501  uint8_t *p;
502  if(wOffset == rOffset) { // Is an RGB-type strip
503  p = &pixels[n * 3]; // 3 bytes per pixel (ignore W)
504  } else { // Is a WRGB-type strip
505  p = &pixels[n * 4]; // 4 bytes per pixel
506  p[wOffset] = w; // Store W
507  }
508  p[rOffset] = r; // Store R,G,B
509  p[gOffset] = g;
510  p[bOffset] = b;
511  }
512 }

◆ setPixelColor() [3/3]

void Adafruit_CPlay_NeoPixel::setPixelColor ( uint16_t  n,
uint32_t  c 
)

Set pixel color from 'packed' 32-bit RGB color:

引数
nthe pixel number to set
cthe packed 32-bit color data

Adafruit_CPlay_NeoPixel.cpp521 行目に定義があります。

521  {
522  if(n < numLEDs) {
523  uint8_t *p,
524  r = (uint8_t)(c >> 16),
525  g = (uint8_t)(c >> 8),
526  b = (uint8_t)c;
527  if(brightness) { // See notes in setBrightness()
528  r = (r * brightness) >> 8;
529  g = (g * brightness) >> 8;
530  b = (b * brightness) >> 8;
531  }
532  if(wOffset == rOffset) {
533  p = &pixels[n * 3];
534  } else {
535  p = &pixels[n * 4];
536  uint8_t w = (uint8_t)(c >> 24);
537  p[wOffset] = brightness ? ((w * brightness) >> 8) : w;
538  }
539  p[rOffset] = r;
540  p[gOffset] = g;
541  p[bOffset] = b;
542  }
543 }

◆ show()

void Adafruit_CPlay_NeoPixel::show ( void  )

Write data to the neopixels

覚え書き
this disables interrupts on the chip until the write is complete.

Adafruit_CPlay_NeoPixel.cpp142 行目に定義があります。

142  {
143 
144  if(!pixels) return;
145 
146  // Data latch = 50+ microsecond pause in the output stream. Rather than
147  // put a delay at the end of the function, the ending time is noted and
148  // the function will simply hold off (if needed) on issuing the
149  // subsequent round of data until the latch time has elapsed. This
150  // allows the mainline code to start generating the next frame of data
151  // rather than stalling for the latch.
152  while(!canShow());
153  // endTime is a private member (rather than global var) so that mutliple
154  // instances on different pins can be quickly issued in succession (each
155  // instance doesn't delay the next).
156 
157  // In order to make this code runtime-configurable to work with any pin,
158  // SBI/CBI instructions are eschewed in favor of full PORT writes via the
159  // OUT or ST instructions. It relies on two facts: that peripheral
160  // functions (such as PWM) take precedence on output pins, so our PORT-
161  // wide writes won't interfere, and that interrupts are globally disabled
162  // while data is being issued to the LEDs, so no other code will be
163  // accessing the PORT. The code takes an initial 'snapshot' of the PORT
164  // state, computes 'pin high' and 'pin low' values, and writes these back
165  // to the PORT register as needed.
166 
167  noInterrupts(); // Need 100% focus on instruction timing
168 
169 #ifdef __AVR__
170 // AVR MCUs -- ATmega & ATtiny (no XMEGA) ---------------------------------
171 
172  volatile uint16_t
173  i = numBytes; // Loop counter
174  volatile uint8_t
175  *ptr = pixels, // Pointer to next byte
176  b = *ptr++, // Current byte value
177  hi, // PORT w/output bit set high
178  lo; // PORT w/output bit set low
179 
180  // Hand-tuned assembly code issues data to the LED drivers at a specific
181  // rate. There's separate code for different CPU speeds (8, 12, 16 MHz)
182  // for both the WS2811 (400 KHz) and WS2812 (800 KHz) drivers. The
183  // datastream timing for the LED drivers allows a little wiggle room each
184  // way (listed in the datasheets), so the conditions for compiling each
185  // case are set up for a range of frequencies rather than just the exact
186  // 8, 12 or 16 MHz values, permitting use with some close-but-not-spot-on
187  // devices (e.g. 16.5 MHz DigiSpark). The ranges were arrived at based
188  // on the datasheet figures and have not been extensively tested outside
189  // the canonical 8/12/16 MHz speeds; there's no guarantee these will work
190  // close to the extremes (or possibly they could be pushed further).
191  // Keep in mind only one CPU speed case actually gets compiled; the
192  // resulting program isn't as massive as it might look from source here.
193 
194 // 8 MHz(ish) AVR ---------------------------------------------------------
195 #if (F_CPU >= 7400000UL) && (F_CPU <= 9500000UL)
196 
197  if(is800KHz) {
198 
199  volatile uint8_t n1, n2 = 0; // First, next bits out
200 
201  // Squeezing an 800 KHz stream out of an 8 MHz chip requires code
202  // specific to each PORT register. At present this is only written
203  // to work with pins on PORTD or PORTB, the most likely use case --
204  // this covers all the pins on the Adafruit Flora and the bulk of
205  // digital pins on the Arduino Pro 8 MHz (keep in mind, this code
206  // doesn't even get compiled for 16 MHz boards like the Uno, Mega,
207  // Leonardo, etc., so don't bother extending this out of hand).
208  // Additional PORTs could be added if you really need them, just
209  // duplicate the else and loop and change the PORT. Each add'l
210  // PORT will require about 150(ish) bytes of program space.
211 
212  // 10 instruction clocks per bit: HHxxxxxLLL
213  // OUT instructions: ^ ^ ^ (T=0,2,7)
214 
215 
216  // Same as above, just switched to PORTB and stripped of comments.
217  hi = PORTB | pinMask;
218  lo = PORTB & ~pinMask;
219  n1 = lo;
220  if(b & 0x80) n1 = hi;
221 
222  asm volatile(
223  "cp_headB:" "\n\t"
224  "out %[port] , %[hi]" "\n\t"
225  "mov %[n2] , %[lo]" "\n\t"
226  "out %[port] , %[n1]" "\n\t"
227  "rjmp .+0" "\n\t"
228  "sbrc %[byte] , 6" "\n\t"
229  "mov %[n2] , %[hi]" "\n\t"
230  "out %[port] , %[lo]" "\n\t"
231  "rjmp .+0" "\n\t"
232  "out %[port] , %[hi]" "\n\t"
233  "mov %[n1] , %[lo]" "\n\t"
234  "out %[port] , %[n2]" "\n\t"
235  "rjmp .+0" "\n\t"
236  "sbrc %[byte] , 5" "\n\t"
237  "mov %[n1] , %[hi]" "\n\t"
238  "out %[port] , %[lo]" "\n\t"
239  "rjmp .+0" "\n\t"
240  "out %[port] , %[hi]" "\n\t"
241  "mov %[n2] , %[lo]" "\n\t"
242  "out %[port] , %[n1]" "\n\t"
243  "rjmp .+0" "\n\t"
244  "sbrc %[byte] , 4" "\n\t"
245  "mov %[n2] , %[hi]" "\n\t"
246  "out %[port] , %[lo]" "\n\t"
247  "rjmp .+0" "\n\t"
248  "out %[port] , %[hi]" "\n\t"
249  "mov %[n1] , %[lo]" "\n\t"
250  "out %[port] , %[n2]" "\n\t"
251  "rjmp .+0" "\n\t"
252  "sbrc %[byte] , 3" "\n\t"
253  "mov %[n1] , %[hi]" "\n\t"
254  "out %[port] , %[lo]" "\n\t"
255  "rjmp .+0" "\n\t"
256  "out %[port] , %[hi]" "\n\t"
257  "mov %[n2] , %[lo]" "\n\t"
258  "out %[port] , %[n1]" "\n\t"
259  "rjmp .+0" "\n\t"
260  "sbrc %[byte] , 2" "\n\t"
261  "mov %[n2] , %[hi]" "\n\t"
262  "out %[port] , %[lo]" "\n\t"
263  "rjmp .+0" "\n\t"
264  "out %[port] , %[hi]" "\n\t"
265  "mov %[n1] , %[lo]" "\n\t"
266  "out %[port] , %[n2]" "\n\t"
267  "rjmp .+0" "\n\t"
268  "sbrc %[byte] , 1" "\n\t"
269  "mov %[n1] , %[hi]" "\n\t"
270  "out %[port] , %[lo]" "\n\t"
271  "rjmp .+0" "\n\t"
272  "out %[port] , %[hi]" "\n\t"
273  "mov %[n2] , %[lo]" "\n\t"
274  "out %[port] , %[n1]" "\n\t"
275  "rjmp .+0" "\n\t"
276  "sbrc %[byte] , 0" "\n\t"
277  "mov %[n2] , %[hi]" "\n\t"
278  "out %[port] , %[lo]" "\n\t"
279  "sbiw %[count], 1" "\n\t"
280  "out %[port] , %[hi]" "\n\t"
281  "mov %[n1] , %[lo]" "\n\t"
282  "out %[port] , %[n2]" "\n\t"
283  "ld %[byte] , %a[ptr]+" "\n\t"
284  "sbrc %[byte] , 7" "\n\t"
285  "mov %[n1] , %[hi]" "\n\t"
286  "out %[port] , %[lo]" "\n\t"
287  "brne cp_headB" "\n"
288  : [byte] "+r" (b), [n1] "+r" (n1), [n2] "+r" (n2), [count] "+w" (i)
289  : [port] "I" (_SFR_IO_ADDR(PORTB)), [ptr] "e" (ptr), [hi] "r" (hi),
290  [lo] "r" (lo));
291 
292  } else { // end 800 KHz, do 400 KHz
293 
294  // Timing is more relaxed; unrolling the inner loop for each bit is
295  // not necessary. Still using the peculiar RJMPs as 2X NOPs, not out
296  // of need but just to trim the code size down a little.
297  // This 400-KHz-datastream-on-8-MHz-CPU code is not quite identical
298  // to the 800-on-16 code later -- the hi/lo timing between WS2811 and
299  // WS2812 is not simply a 2:1 scale!
300 
301  // 20 inst. clocks per bit: HHHHxxxxxxLLLLLLLLLL
302  // ST instructions: ^ ^ ^ (T=0,4,10)
303 
304  volatile uint8_t next, bit;
305 
306  hi = *port | pinMask;
307  lo = *port & ~pinMask;
308  next = lo;
309  bit = 8;
310 
311  asm volatile(
312  "cp_head20:" "\n\t" // Clk Pseudocode (T = 0)
313  "st %a[port], %[hi]" "\n\t" // 2 PORT = hi (T = 2)
314  "sbrc %[byte] , 7" "\n\t" // 1-2 if(b & 128)
315  "mov %[next], %[hi]" "\n\t" // 0-1 next = hi (T = 4)
316  "st %a[port], %[next]" "\n\t" // 2 PORT = next (T = 6)
317  "mov %[next] , %[lo]" "\n\t" // 1 next = lo (T = 7)
318  "dec %[bit]" "\n\t" // 1 bit-- (T = 8)
319  "breq cp_nextbyte20" "\n\t" // 1-2 if(bit == 0)
320  "rol %[byte]" "\n\t" // 1 b <<= 1 (T = 10)
321  "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 12)
322  "rjmp .+0" "\n\t" // 2 nop nop (T = 14)
323  "rjmp .+0" "\n\t" // 2 nop nop (T = 16)
324  "rjmp .+0" "\n\t" // 2 nop nop (T = 18)
325  "rjmp cp_head20" "\n\t" // 2 -> head20 (next bit out)
326  "cp_nextbyte20:" "\n\t" // (T = 10)
327  "st %a[port], %[lo]" "\n\t" // 2 PORT = lo (T = 12)
328  "nop" "\n\t" // 1 nop (T = 13)
329  "ldi %[bit] , 8" "\n\t" // 1 bit = 8 (T = 14)
330  "ld %[byte] , %a[ptr]+" "\n\t" // 2 b = *ptr++ (T = 16)
331  "sbiw %[count], 1" "\n\t" // 2 i-- (T = 18)
332  "brne cp_head20" "\n" // 2 if(i != 0) -> (next byte)
333  : [port] "+e" (port),
334  [byte] "+r" (b),
335  [bit] "+r" (bit),
336  [next] "+r" (next),
337  [count] "+w" (i)
338  : [hi] "r" (hi),
339  [lo] "r" (lo),
340  [ptr] "e" (ptr));
341  }
342 
343 #else
344  #error "CPU SPEED NOT SUPPORTED"
345 #endif // end F_CPU ifdefs on __AVR__
346 
347 // END AVR ----------------------------------------------------------------
348 
349 #elif defined(__SAMD21G18A__) // Arduino Zero / CP Express
350 
351  // Tried this with a timer/counter, couldn't quite get adequate
352  // resolution. So yay, you get a load of goofball NOPs...
353 
354  uint8_t *ptr, *end, p, bitMask, portNum;
355  uint32_t pinMask;
356 
357  portNum = g_APinDescription[pin].ulPort;
358  pinMask = 1ul << g_APinDescription[pin].ulPin;
359  ptr = pixels;
360  end = ptr + numBytes;
361  p = *ptr++;
362  bitMask = 0x80;
363 
364  volatile uint32_t *set = &(PORT->Group[portNum].OUTSET.reg),
365  *clr = &(PORT->Group[portNum].OUTCLR.reg);
366 
367  if(is800KHz) {
368  for(;;) {
369  *set = pinMask;
370  asm("nop; nop; nop; nop; nop; nop; nop; nop;");
371  if(p & bitMask) {
372  asm("nop; nop; nop; nop; nop; nop; nop; nop;"
373  "nop; nop; nop; nop; nop; nop; nop; nop;"
374  "nop; nop; nop; nop;");
375  *clr = pinMask;
376  } else {
377  *clr = pinMask;
378  asm("nop; nop; nop; nop; nop; nop; nop; nop;"
379  "nop; nop; nop; nop; nop; nop; nop; nop;"
380  "nop; nop; nop; nop;");
381  }
382  if(bitMask >>= 1) {
383  asm("nop; nop; nop; nop; nop; nop; nop; nop; nop;");
384  } else {
385  if(ptr >= end) break;
386  p = *ptr++;
387  bitMask = 0x80;
388  }
389  }
390  } else { // 400 KHz bitstream
391  for(;;) {
392  *set = pinMask;
393  asm("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;");
394  if(p & bitMask) {
395  asm("nop; nop; nop; nop; nop; nop; nop; nop;"
396  "nop; nop; nop; nop; nop; nop; nop; nop;"
397  "nop; nop; nop; nop; nop; nop; nop; nop;"
398  "nop; nop; nop;");
399  *clr = pinMask;
400  } else {
401  *clr = pinMask;
402  asm("nop; nop; nop; nop; nop; nop; nop; nop;"
403  "nop; nop; nop; nop; nop; nop; nop; nop;"
404  "nop; nop; nop; nop; nop; nop; nop; nop;"
405  "nop; nop; nop;");
406  }
407  asm("nop; nop; nop; nop; nop; nop; nop; nop;"
408  "nop; nop; nop; nop; nop; nop; nop; nop;"
409  "nop; nop; nop; nop; nop; nop; nop; nop;"
410  "nop; nop; nop; nop; nop; nop; nop; nop;");
411  if(bitMask >>= 1) {
412  asm("nop; nop; nop; nop; nop; nop; nop;");
413  } else {
414  if(ptr >= end) break;
415  p = *ptr++;
416  bitMask = 0x80;
417  }
418  }
419  }
420 
421 #else
422  #error "CPU ARCHITECTURE NOT SUPPORTED"
423 #endif
424 
425 // END ARCHITECTURE SELECT ------------------------------------------------
426 
427  interrupts();
428  endTime = micros(); // Save EOD time for latch on next call
429 }
#define bit(b)
Definition: Arduino.h:123
#define interrupts()
Definition: Arduino.h:101
bool canShow(void)
check if enough time has elapsed and the pixels are ready to refresh.
#define _SFR_IO_ADDR(sfr)
Definition: sfr_defs.h:183
uint8_t i
#define noInterrupts()
Definition: Arduino.h:102
uint8_t byte
Definition: Arduino.h:126
#define PORTB
Definition: io1200.h:71
unsigned long micros(void)
Definition: wiring.c:79

◆ sine8()

uint8_t Adafruit_CPlay_NeoPixel::sine8 ( uint8_t  x) const

Get a sinusoidal value from a sine table

引数
xa 0 to 255 value corresponding to an index to the sine table
戻り値
An 8-bit sinusoidal value back

Adafruit_CPlay_NeoPixel.cpp731 行目に定義があります。

731  {
732  return pgm_read_byte(&_sineTable[x]); // 0-255 in, 0-255 out
733 }
#define pgm_read_byte(address_short)
Definition: pgmspace.h:1055

◆ updateLength()

void Adafruit_CPlay_NeoPixel::updateLength ( uint16_t  n)

Set the number of pixels in the strip

引数
nthe number of pixels in the strip

Adafruit_CPlay_NeoPixel.cpp100 行目に定義があります。

100  {
101  if(pixels) free(pixels); // Free existing data (if any)
102 
103  // Allocate new data -- note: ALL PIXELS ARE CLEARED
104  numBytes = n * ((wOffset == rOffset) ? 3 : 4);
105  if((pixels = (uint8_t *)malloc(numBytes))) {
106  memset(pixels, 0, numBytes);
107  numLEDs = n;
108  } else {
109  numLEDs = numBytes = 0;
110  }
111 }
void * memset(void *, int, size_t)
Fill memory with a constant byte.
void free(void *__ptr)
void * malloc(size_t __size) __ATTR_MALLOC__

◆ updateType()

void Adafruit_CPlay_NeoPixel::updateType ( neoPixelType  t)

set the type of neopixel we are using

引数
tthe type of neopixel. Can be NEO_KHZ800 or NEO_KHZ400

Adafruit_CPlay_NeoPixel.cpp119 行目に定義があります。

119  {
120  boolean oldThreeBytesPerPixel = (wOffset == rOffset); // false if RGBW
121 
122  wOffset = (t >> 6) & 0b11; // See notes in header file
123  rOffset = (t >> 4) & 0b11; // regarding R/G/B/W offsets
124  gOffset = (t >> 2) & 0b11;
125  bOffset = t & 0b11;
126  is800KHz = (t < 256); // 400 KHz flag is 1<<8
127 
128  // If bytes-per-pixel has changed (and pixel data was previously
129  // allocated), re-allocate to new size. Will clear any data.
130  if(pixels) {
131  boolean newThreeBytesPerPixel = (wOffset == rOffset);
132  if(newThreeBytesPerPixel != oldThreeBytesPerPixel) updateLength(numLEDs);
133  }
134 }
void updateLength(uint16_t n)
Set the number of pixels in the strip

このクラス詳解は次のファイルから抽出されました: