PropWare  3.0.0.229
C++ objects and CMake build system for Parallax Propeller
ws2812.h
Go to the documentation of this file.
1 
26 #pragma once
27 
28 #include <PropWare/PropWare.h>
29 #include <PropWare/gpio/pin.h>
30 
31 namespace PropWare {
32 
36 class WS2812 {
37 
38  public:
42  enum class Type {
43  RGB, GRB
45  };
46 
50  typedef enum {
51  BLACK = 0x000000,
52  RED = 0xFF0000,
53  GREEN = 0x00FF00,
54  BLUE = 0x0000FF,
55  WHITE = 0xFFFFFF,
56  CYAN = 0x00FFFF,
57  MAGENTA = 0xFF00FF,
58  YELLOW = 0xFFFF00,
59  CHARTREUSE = 0x7FFF00,
60  ORANGE = 0xFF6000,
61  AQUAMARINE = 0x7FFFD4,
62  PINK = 0xFF5F5F,
63  TURQUOISE = 0x3FE0C0,
64  REALWHITE = 0xC8FFFF,
65  INDIGO = 0x3F007F,
66  VIOLET = 0xBF7FBF,
67  MAROON = 0x320010,
68  BROWN = 0x0E0600,
69  CRIMSON = 0xDC283C
70  } Color;
71 
72  public:
82  static unsigned int to_color (const unsigned int red, const unsigned int green, const unsigned int blue) {
83  return ((red) << 16) | ((green) << 8) | (blue);
84  }
85 
86  static unsigned int scale (const unsigned int x, const unsigned int l) {
87  return x * l / 255;
88  }
89 
90  static unsigned int colorx (const unsigned int red, const unsigned int green, const unsigned int blue,
91  const unsigned int l) {
92  return (scale(red, l) << 16) | (scale(green, l) << 8) | scale(blue, l);
93  }
94 
95  public:
102  WS2812 (const Pin::Mask pinMask, const Type type)
103  : m_pin(pinMask, Pin::Dir::OUT),
104  m_type(type) {
105  this->m_pin.clear();
106  }
107 
113  void send (const unsigned int color) const {
114  this->send_array(&color, 1);
115  }
116 
123  void send_array (const unsigned int *buffer, const size_t length) const {
124  // Using local variables here saves 50 bytes relative to static class variables and even more compared to
125  // local statics. And bonus - no more ws2812.cpp needed, so importing becomes a lot easier
126  const unsigned int LONG_PULSE_WIDTH = (900 * MICROSECOND / 1000);
127  const unsigned int SHORT_PULSE_WIDTH = (350 * MICROSECOND / 1000);
128  const unsigned int RESET_DELAY = (50 * MICROSECOND);
129 
130  unsigned int clock = RESET_DELAY;
131  unsigned int t1 = 0;
132  unsigned int t2 = 0;
133  unsigned int colorbits = 0;
134  unsigned int bitCounter = 0;
135 
136  __asm__ volatile (
137  FC_START("Ws2812Start", "Ws2812End")
138  " add %[_clock], CNT \n\t"
139  " waitcnt %[_clock], #0 \n\t"
140 
141  "frame_loop%=: \n\t"
142  " rdlong %[_colorbits], %[_nextLed] \n\t"
143  " add %[_nextLed], #4 \n\t"
144 
145  "fix_colors%=: \n\t"
146  " tjz %[_swaprg], #" FC_ADDR("shift_out%=", "Ws2812Start") " \n\t"
147  " mov %[_t1], %[_colorbits] \n\t"
148  " mov %[_t2], %[_colorbits] \n\t"
149  " and %[_colorbits], #0xff \n\t"
150  " shr %[_t1], #8 \n\t"
151  " and %[_t1], %[_byte1] \n\t"
152  " or %[_colorbits], %[_t1] \n\t"
153  " shl %[_t2], #8 \n\t"
154  " and %[_t2], %[_byte2] \n\t"
155  " or %[_colorbits], %[_t2] \n\t"
156 
157  "shift_out%=: \n\t"
158  " shl %[_colorbits], #8 \n\t"
159  " mov %[_bitCounter], #24 \n\t"
160 
161  "shift_out.loop%=: \n\t"
162  " rcl %[_colorbits], #1 wc \n\t"
163  " if_c mov %[_clock], %[_longPulse] ' bit1hi \n\t"
164  " if_nc mov %[_clock], %[_shortPulse] ' bit0hi \n\t"
165  " or OUTA, %[_pinMask] \n\t"
166  " add %[_clock], CNT \n\t"
167  " if_c waitcnt %[_clock], %[_shortPulse] ' bit1lo \n\t"
168  " if_nc waitcnt %[_clock], %[_longPulse] ' bit0lo \n\t"
169  " andn OUTA, %[_pinMask] \n\t"
170  " waitcnt %[_clock], #0 \n\t"
171  " djnz %[_bitCounter], #" FC_ADDR("shift_out.loop%=", "Ws2812Start") " \n\t"
172  " djnz %[_nleds], #" FC_ADDR("frame_loop%=", "Ws2812Start") " \n\t"
173  FC_END("Ws2812End")
174  :[_clock] "+r"(clock),
175  [_t1] "+r"(t1),
176  [_t2] "+r"(t2),
177  [_colorbits] "+r"(colorbits),
178  [_bitCounter] "+r"(bitCounter),
179  [_nextLed] "+r"(buffer)
180  :[_pinMask] "r"(this->m_pin.get_mask()),
181  [_nleds] "r"(length),
182  [_swaprg] "r"(this->m_type),
183  [_byte1] "r"(BYTE_1),
184  [_byte2] "r"(BYTE_2),
185  [_shortPulse] "r"(SHORT_PULSE_WIDTH),
186  [_longPulse] "r"(LONG_PULSE_WIDTH),
187  [_resetDelay] "r"(RESET_DELAY));
188  }
189 
190  uint32_t wheel (unsigned int position) const {
191  uint32_t resultingColor;
192 
193  // Creates color from 0 to 255 position input
194  // -- colors transition r-g-b back to r
195 
196  // red range
197  if (position < 85)
198  resultingColor = to_color(255 - position * 3, position * 3, 0);
199 
200  // green range
201  else if (position < 170) {
202  position -= 85;
203  resultingColor = to_color(0, 255 - position * 3, position * 3);
204  }
205  // blue range
206  else {
207  position -= 170;
208  resultingColor = to_color(position * 3, 0, 255 - position * 3);
209  }
210 
211  return resultingColor;
212  }
213 
214  uint32_t wheel_dim (unsigned int position, unsigned int brightness) const {
215  uint32_t color;
216 
217  // Creates color from 0 to 255 position input
218  // -- colors transition r-g-b back to r
219 
220  // red range
221  if (position < 85)
222  color = colorx(255 - position * 3, position * 3, 0, brightness);
223 
224  // green range
225  else if (position < 170) {
226  position -= 85;
227  color = colorx(0, 255 - position * 3, position * 3, brightness);
228  }
229 
230  // blue range
231  else {
232  position -= 170;
233  color = colorx(position * 3, 0, 255 - position * 3, brightness);
234  }
235 
236  return color;
237  }
238 
244  Type get_type () const {
245  return this->m_type;
246  }
247 
248  private:
249  const Pin m_pin;
250  const Type m_type;
251 };
252 
253 }
PropWare::WS2812::send_array
void send_array(const unsigned int *buffer, const size_t length) const
Send a series of colors to a series of LEDs.
Definition: ws2812.h:123
PropWare::WS2812::get_type
Type get_type() const
Obtain the currently set RGB/GRB type.
Definition: ws2812.h:244
PropWare::Port::Mask
Mask
Definition: port.h:43
PropWare::WS2812::Type
Type
Support both types of multicolor LEDs, RGB and GRB.
Definition: ws2812.h:42
PropWare::WS2812
An easy-to-use, cheap, small, and bright multicolor LED capable of being strung together in a lengthy...
Definition: ws2812.h:36
PropWare::Pin
Utility class to handle general purpose I/O pins.
Definition: pin.h:36
PropWare::WS2812::Type::GRB
@ GRB
PropWare::WS2812::to_color
static unsigned int to_color(const unsigned int red, const unsigned int green, const unsigned int blue)
Convert RGB values to a color code.
Definition: ws2812.h:82
PropWare.h
PropWare::WS2812::WS2812
WS2812(const Pin::Mask pinMask, const Type type)
Construct an instance connected to the given output line.
Definition: ws2812.h:102
type
x
int x
Definition: 07 Box and Lines.c:13
PropWare::WS2812::send
void send(const unsigned int color) const
Send a given color to the first LED in line.
Definition: ws2812.h:113
PropWare::WS2812::Color
Color
Provide some common color codes.
Definition: ws2812.h:50
pin.h
PropWare
Generic definitions and functions for the Parallax Propeller.
Definition: runnable.h:33
PropWare::Port::clear
void clear() const
Clear selected output port (set it to 0)
Definition: port.h:249