Lumitronix_Iflex_Pro_Workshop
Library to interact with the iFlexPro
LumitronixIFlexBus.h
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2 LumitronixIFlex library
3 
4 Written by Michael C. Miller.
5 
6 I invest time and resources providing this open source code,
7 please support me by dontating (see https://github.com/Makuna)
8 
9 -------------------------------------------------------------------------
10 This file is part of the LUMITRONIX_iFlex_Workshop library.
11 
12 LumitronixIFlexBus is free software: you can redistribute it and/or modify
13 it under the terms of the GNU Lesser General Public License as
14 published by the Free Software Foundation, either version 3 of
15 the License, or (at your option) any later version.
16 
17 LumitronixIFlexBus is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU Lesser General Public License for more details.
21 
22 You should have received a copy of the GNU Lesser General Public
23 License along with LumitronixIFlex. If not, see
24 <http://www.gnu.org/licenses/>.
25 -------------------------------------------------------------------------*/
26 #pragma once
27 
28 #include <Arduino.h>
29 
30 // standard neo definitions
31 //
32 const uint8_t NEO_DIRTY = 0x80; // a change was made to pixel data that requires a show
33 const uint16_t PixelIndex_OutOfBounds = 0xffff;
34 
35 #include "internal/NeoUtil.h"
37 #include "internal/NeoSettings.h"
38 #include "internal/NeoColors.h"
40 #include "internal/NeoTopologies.h"
41 #include "internal/NeoBuffers.h"
42 #include "internal/NeoBusChannel.h"
43 #include "internal/NeoMethods.h"
44 
45 
46 template<typename T_COLOR_FEATURE, typename T_METHOD> class LumitronixIFlexBus
47 {
48 public:
49  // Constructor: number of LEDs, pin number
50  // NOTE: Pin Number maybe ignored due to hardware limitations of the method.
51 
52  LumitronixIFlexBus(uint16_t countPixels, uint8_t pin) :
53  _countPixels(countPixels),
54  _state(0),
55  _method(pin, countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize)
56  {
57  }
58 
59  LumitronixIFlexBus(uint16_t countPixels, uint8_t pin, NeoBusChannel channel) :
60  _countPixels(countPixels),
61  _state(0),
62  _method(pin, countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize, channel)
63  {
64  }
65 
66  LumitronixIFlexBus(uint16_t countPixels, uint8_t pinClock, uint8_t pinData) :
67  _countPixels(countPixels),
68  _state(0),
69  _method(pinClock, pinData, countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize)
70  {
71  }
72 
73  LumitronixIFlexBus(uint16_t countPixels, uint8_t pinClock, uint8_t pinData, uint8_t pinLatch, uint8_t pinOutputEnable = NOT_A_PIN) :
74  _countPixels(countPixels),
75  _state(0),
76  _method(pinClock, pinData, pinLatch, pinOutputEnable, countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize)
77  {
78  }
79 
80  LumitronixIFlexBus(uint16_t countPixels) :
81  _countPixels(countPixels),
82  _state(0),
83  _method(countPixels, T_COLOR_FEATURE::PixelSize, T_COLOR_FEATURE::SettingsSize)
84  {
85  }
86 
88  {
89  }
90 
92  {
93  Dirty(); // we assume you are playing with bits
95  }
96 
97  virtual void Begin()
98  {
99  _method.Initialize();
100  ClearTo(0);
101  }
102 
103  // used by DotStarSpiMethod/DotStarEsp32DmaSpiMethod if pins can be configured
104  void Begin(int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
105  {
106  _method.Initialize(sck, miso, mosi, ss);
107  ClearTo(0);
108  }
109 
110  // used by DotStarEsp32DmaSpiMethod if pins can be configured - reordered and extended version supporting quad SPI
111  void Begin(int8_t sck, int8_t dat0, int8_t dat1, int8_t dat2, int8_t dat3, int8_t ss)
112  {
113  _method.Initialize(sck, dat0, dat1, dat2, dat3, ss);
114  ClearTo(0);
115  }
116 
117  // used by DotStarEsp32DmaSpiMethod if pins can be configured - reordered and extended version supporting oct SPI
118  void Begin(int8_t sck, int8_t dat0, int8_t dat1, int8_t dat2, int8_t dat3, int8_t dat4, int8_t dat5, int8_t dat6, int8_t dat7, int8_t ss)
119  {
120  _method.Initialize(sck, dat0, dat1, dat2, dat3, dat4, dat5, dat6, dat7, ss);
121  ClearTo(0);
122  }
123 
124  void Show(bool maintainBufferConsistency = true)
125  {
126  if (!IsDirty() && !_method.AlwaysUpdate())
127  {
128  return;
129  }
130 
131  _method.Update(maintainBufferConsistency);
132 
133  ResetDirty();
134  }
135 
136  inline bool CanShow() const
137  {
138  return _method.IsReadyToUpdate();
139  };
140 
141  bool IsDirty() const
142  {
143  return (_state & NEO_DIRTY);
144  };
145 
146  void Dirty()
147  {
148  _state |= NEO_DIRTY;
149  };
150 
151  void ResetDirty()
152  {
153  _state &= ~NEO_DIRTY;
154  };
155 
156  uint8_t* Pixels()
157  {
158  return _pixels();
159  };
160 
161  size_t PixelsSize() const
162  {
163  return _method.getDataSize() - T_COLOR_FEATURE::SettingsSize;
164  };
165 
166  size_t PixelSize() const
167  {
168  return T_COLOR_FEATURE::PixelSize;
169  };
170 
171  uint16_t PixelCount() const
172  {
173  return _countPixels;
174  };
175 
176  void SetPixelColor(uint16_t indexPixel, typename T_COLOR_FEATURE::ColorObject color)
177  {
178  if (indexPixel < _countPixels)
179  {
180  T_COLOR_FEATURE::applyPixelColor(_pixels(), indexPixel, color);
181  Dirty();
182  }
183  };
184 
185  typename T_COLOR_FEATURE::ColorObject GetPixelColor(uint16_t indexPixel) const
186  {
187  if (indexPixel < _countPixels)
188  {
189  return T_COLOR_FEATURE::retrievePixelColor(_pixels(), indexPixel);
190  }
191  else
192  {
193  // Pixel # is out of bounds, this will get converted to a
194  // color object type initialized to 0 (black)
195  return 0;
196  }
197  };
198 
199  void ClearTo(typename T_COLOR_FEATURE::ColorObject color)
200  {
201  uint8_t temp[T_COLOR_FEATURE::PixelSize];
202  uint8_t* pixels = _pixels();
203 
204  T_COLOR_FEATURE::applyPixelColor(temp, 0, color);
205 
206  T_COLOR_FEATURE::replicatePixel(pixels, temp, _countPixels);
207 
208  Dirty();
209  };
210 
211  void ClearTo(typename T_COLOR_FEATURE::ColorObject color, uint16_t first, uint16_t last)
212  {
213  if (first < _countPixels &&
214  last < _countPixels &&
215  first <= last)
216  {
217  uint8_t temp[T_COLOR_FEATURE::PixelSize];
218  uint8_t* pixels = _pixels();
219  uint8_t* pFront = T_COLOR_FEATURE::getPixelAddress(pixels, first);
220 
221  T_COLOR_FEATURE::applyPixelColor(temp, 0, color);
222 
223  T_COLOR_FEATURE::replicatePixel(pFront, temp, last - first + 1);
224 
225  Dirty();
226  }
227  }
228 
229  void RotateLeft(uint16_t rotationCount)
230  {
231  if ((_countPixels - 1) >= rotationCount)
232  {
233  _rotateLeft(rotationCount, 0, _countPixels - 1);
234  }
235  }
236 
237  void RotateLeft(uint16_t rotationCount, uint16_t first, uint16_t last)
238  {
239  if (first < _countPixels &&
240  last < _countPixels &&
241  first < last &&
242  (last - first) >= rotationCount)
243  {
244  _rotateLeft(rotationCount, first, last);
245  }
246  }
247 
248  void ShiftLeft(uint16_t shiftCount)
249  {
250  if ((_countPixels - 1) >= shiftCount)
251  {
252  _shiftLeft(shiftCount, 0, _countPixels - 1);
253  Dirty();
254  }
255  }
256 
257  void ShiftLeft(uint16_t shiftCount, uint16_t first, uint16_t last)
258  {
259  if (first < _countPixels &&
260  last < _countPixels &&
261  first < last &&
262  (last - first) >= shiftCount)
263  {
264  _shiftLeft(shiftCount, first, last);
265  Dirty();
266  }
267  }
268 
269  void RotateRight(uint16_t rotationCount)
270  {
271  if ((_countPixels - 1) >= rotationCount)
272  {
273  _rotateRight(rotationCount, 0, _countPixels - 1);
274  }
275  }
276 
277  void RotateRight(uint16_t rotationCount, uint16_t first, uint16_t last)
278  {
279  if (first < _countPixels &&
280  last < _countPixels &&
281  first < last &&
282  (last - first) >= rotationCount)
283  {
284  _rotateRight(rotationCount, first, last);
285  }
286  }
287 
288  void ShiftRight(uint16_t shiftCount)
289  {
290  if ((_countPixels - 1) >= shiftCount)
291  {
292  _shiftRight(shiftCount, 0, _countPixels - 1);
293  Dirty();
294  }
295  }
296 
297  void ShiftRight(uint16_t shiftCount, uint16_t first, uint16_t last)
298  {
299  if (first < _countPixels &&
300  last < _countPixels &&
301  first < last &&
302  (last - first) >= shiftCount)
303  {
304  _shiftRight(shiftCount, first, last);
305  Dirty();
306  }
307  }
308 
309  void SwapPixelColor(uint16_t indexPixelOne, uint16_t indexPixelTwo)
310  {
311  auto colorOne = GetPixelColor(indexPixelOne);
312  auto colorTwo = GetPixelColor(indexPixelTwo);
313 
314  SetPixelColor(indexPixelOne, colorTwo);
315  SetPixelColor(indexPixelTwo, colorOne);
316  };
317 
318  void SetPixelSettings(const typename T_COLOR_FEATURE::SettingsObject& settings)
319  {
320  T_COLOR_FEATURE::applySettings(_method.getData(), _method.getDataSize(), settings);
321  Dirty();
322  };
323 
324  void SetMethodSettings(const typename T_METHOD::SettingsObject& settings)
325  {
326  _method.applySettings(settings);
327  Dirty();
328  };
329 
330  uint32_t CalcTotalMilliAmpere(const typename T_COLOR_FEATURE::ColorObject::SettingsObject& settings)
331  {
332  uint32_t total = 0; // in 1/10th milliamps
333 
334  for (uint16_t index = 0; index < _countPixels; index++)
335  {
336  auto color = GetPixelColor(index);
337  total += color.CalcTotalTenthMilliAmpere(settings);
338  }
339 
340  return total / 10; // return millamps
341  }
342 
343 protected:
344  const uint16_t _countPixels; // Number of RGB LEDs in strip
345 
346  uint8_t _state; // internal state
347  T_METHOD _method;
348 
349  uint8_t* _pixels()
350  {
351  // get pixels data within the data stream
352  return T_COLOR_FEATURE::pixels(_method.getData(), _method.getDataSize());
353  }
354 
355  const uint8_t* _pixels() const
356  {
357  // get pixels data within the data stream
358  return T_COLOR_FEATURE::pixels(_method.getData(), _method.getDataSize());
359  }
360 
361  void _rotateLeft(uint16_t rotationCount, uint16_t first, uint16_t last)
362  {
363  // store in temp
364  uint8_t temp[rotationCount * T_COLOR_FEATURE::PixelSize];
365  uint8_t* pixels = _pixels();
366 
367  uint8_t* pFront = T_COLOR_FEATURE::getPixelAddress(pixels, first);
368 
369  T_COLOR_FEATURE::movePixelsInc(temp, pFront, rotationCount);
370 
371  // shift data
372  _shiftLeft(rotationCount, first, last);
373 
374  // move temp back
375  pFront = T_COLOR_FEATURE::getPixelAddress(pixels, last - (rotationCount - 1));
376  T_COLOR_FEATURE::movePixelsInc(pFront, temp, rotationCount);
377 
378  Dirty();
379  }
380 
381  void _shiftLeft(uint16_t shiftCount, uint16_t first, uint16_t last)
382  {
383  uint16_t front = first + shiftCount;
384  uint16_t count = last - front + 1;
385 
386  uint8_t* pixels = _pixels();
387  uint8_t* pFirst = T_COLOR_FEATURE::getPixelAddress(pixels, first);
388  uint8_t* pFront = T_COLOR_FEATURE::getPixelAddress(pixels, front);
389 
390  T_COLOR_FEATURE::movePixelsInc(pFirst, pFront, count);
391 
392  // intentional no dirty
393  }
394 
395  void _rotateRight(uint16_t rotationCount, uint16_t first, uint16_t last)
396  {
397  // store in temp
398  uint8_t temp[rotationCount * T_COLOR_FEATURE::PixelSize];
399  uint8_t* pixels = _pixels();
400 
401  uint8_t* pFront = T_COLOR_FEATURE::getPixelAddress(pixels, last - (rotationCount - 1));
402 
403  T_COLOR_FEATURE::movePixelsDec(temp, pFront, rotationCount);
404 
405  // shift data
406  _shiftRight(rotationCount, first, last);
407 
408  // move temp back
409  pFront = T_COLOR_FEATURE::getPixelAddress(pixels, first);
410  T_COLOR_FEATURE::movePixelsDec(pFront, temp, rotationCount);
411 
412  Dirty();
413  }
414 
415  void _shiftRight(uint16_t shiftCount, uint16_t first, uint16_t last)
416  {
417  uint16_t front = first + shiftCount;
418  uint16_t count = last - front + 1;
419 
420  uint8_t* pixels = _pixels();
421  uint8_t* pFirst = T_COLOR_FEATURE::getPixelAddress(pixels, first);
422  uint8_t* pFront = T_COLOR_FEATURE::getPixelAddress(pixels, front);
423 
424  T_COLOR_FEATURE::movePixelsDec(pFront, pFirst, count);
425  // intentional no dirty
426  }
427 };
428 
429 
const uint16_t PixelIndex_OutOfBounds
Definition: LumitronixIFlexBus.h:33
const uint8_t NEO_DIRTY
Definition: LumitronixIFlexBus.h:32
NeoBusChannel
Definition: NeoBusChannel.h:12
Definition: LumitronixIFlexBus.h:47
void SetMethodSettings(const typename T_METHOD::SettingsObject &settings)
Definition: LumitronixIFlexBus.h:324
void _rotateRight(uint16_t rotationCount, uint16_t first, uint16_t last)
Definition: LumitronixIFlexBus.h:395
void RotateRight(uint16_t rotationCount)
Definition: LumitronixIFlexBus.h:269
LumitronixIFlexBus(uint16_t countPixels, uint8_t pin)
Definition: LumitronixIFlexBus.h:52
void ResetDirty()
Definition: LumitronixIFlexBus.h:151
bool IsDirty() const
Definition: LumitronixIFlexBus.h:141
void Dirty()
Definition: LumitronixIFlexBus.h:146
uint8_t * Pixels()
Definition: LumitronixIFlexBus.h:156
void _shiftRight(uint16_t shiftCount, uint16_t first, uint16_t last)
Definition: LumitronixIFlexBus.h:415
T_COLOR_FEATURE::ColorObject GetPixelColor(uint16_t indexPixel) const
Definition: LumitronixIFlexBus.h:185
void ShiftLeft(uint16_t shiftCount)
Definition: LumitronixIFlexBus.h:248
void SetPixelSettings(const typename T_COLOR_FEATURE::SettingsObject &settings)
Definition: LumitronixIFlexBus.h:318
LumitronixIFlexBus(uint16_t countPixels, uint8_t pinClock, uint8_t pinData, uint8_t pinLatch, uint8_t pinOutputEnable=NOT_A_PIN)
Definition: LumitronixIFlexBus.h:73
void ShiftRight(uint16_t shiftCount, uint16_t first, uint16_t last)
Definition: LumitronixIFlexBus.h:297
T_METHOD _method
Definition: LumitronixIFlexBus.h:347
void _shiftLeft(uint16_t shiftCount, uint16_t first, uint16_t last)
Definition: LumitronixIFlexBus.h:381
LumitronixIFlexBus(uint16_t countPixels, uint8_t pinClock, uint8_t pinData)
Definition: LumitronixIFlexBus.h:66
uint8_t * _pixels()
Definition: LumitronixIFlexBus.h:349
uint32_t CalcTotalMilliAmpere(const typename T_COLOR_FEATURE::ColorObject::SettingsObject &settings)
Definition: LumitronixIFlexBus.h:330
uint8_t _state
Definition: LumitronixIFlexBus.h:346
uint16_t PixelCount() const
Definition: LumitronixIFlexBus.h:171
void SwapPixelColor(uint16_t indexPixelOne, uint16_t indexPixelTwo)
Definition: LumitronixIFlexBus.h:309
bool CanShow() const
Definition: LumitronixIFlexBus.h:136
void ShiftRight(uint16_t shiftCount)
Definition: LumitronixIFlexBus.h:288
void RotateRight(uint16_t rotationCount, uint16_t first, uint16_t last)
Definition: LumitronixIFlexBus.h:277
void Begin(int8_t sck, int8_t dat0, int8_t dat1, int8_t dat2, int8_t dat3, int8_t ss)
Definition: LumitronixIFlexBus.h:111
const uint16_t _countPixels
Definition: LumitronixIFlexBus.h:344
const uint8_t * _pixels() const
Definition: LumitronixIFlexBus.h:355
void SetPixelColor(uint16_t indexPixel, typename T_COLOR_FEATURE::ColorObject color)
Definition: LumitronixIFlexBus.h:176
size_t PixelsSize() const
Definition: LumitronixIFlexBus.h:161
void ClearTo(typename T_COLOR_FEATURE::ColorObject color, uint16_t first, uint16_t last)
Definition: LumitronixIFlexBus.h:211
LumitronixIFlexBus(uint16_t countPixels)
Definition: LumitronixIFlexBus.h:80
void Show(bool maintainBufferConsistency=true)
Definition: LumitronixIFlexBus.h:124
virtual void Begin()
Definition: LumitronixIFlexBus.h:97
void Begin(int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
Definition: LumitronixIFlexBus.h:104
void RotateLeft(uint16_t rotationCount)
Definition: LumitronixIFlexBus.h:229
void ClearTo(typename T_COLOR_FEATURE::ColorObject color)
Definition: LumitronixIFlexBus.h:199
void Begin(int8_t sck, int8_t dat0, int8_t dat1, int8_t dat2, int8_t dat3, int8_t dat4, int8_t dat5, int8_t dat6, int8_t dat7, int8_t ss)
Definition: LumitronixIFlexBus.h:118
void RotateLeft(uint16_t rotationCount, uint16_t first, uint16_t last)
Definition: LumitronixIFlexBus.h:237
void ShiftLeft(uint16_t shiftCount, uint16_t first, uint16_t last)
Definition: LumitronixIFlexBus.h:257
LumitronixIFlexBus(uint16_t countPixels, uint8_t pin, NeoBusChannel channel)
Definition: LumitronixIFlexBus.h:59
~LumitronixIFlexBus()
Definition: LumitronixIFlexBus.h:87
void _rotateLeft(uint16_t rotationCount, uint16_t first, uint16_t last)
Definition: LumitronixIFlexBus.h:361
size_t PixelSize() const
Definition: LumitronixIFlexBus.h:166
Definition: NeoBufferContext.h:32